@@ -603,16 +603,18 @@ static void ptys2ethtool_supported_link(struct mlx5_core_dev *mdev,
603
603
__ETHTOOL_LINK_MODE_MASK_NBITS );
604
604
}
605
605
606
- static void ptys2ethtool_adver_link (struct mlx5_core_dev * mdev ,
607
- unsigned long * advertising_modes ,
608
- u32 eth_proto_cap )
606
+ static void ptys2ethtool_adver_link (unsigned long * advertising_modes ,
607
+ u32 eth_proto_cap , bool ext )
609
608
{
610
609
unsigned long proto_cap = eth_proto_cap ;
611
610
struct ptys2ethtool_config * table ;
612
611
u32 max_size ;
613
612
int proto ;
614
613
615
- mlx5e_ethtool_get_speed_arr (mdev , & table , & max_size );
614
+ table = ext ? ptys2ext_ethtool_table : ptys2legacy_ethtool_table ;
615
+ max_size = ext ? ARRAY_SIZE (ptys2ext_ethtool_table ) :
616
+ ARRAY_SIZE (ptys2legacy_ethtool_table );
617
+
616
618
for_each_set_bit (proto , & proto_cap , max_size )
617
619
bitmap_or (advertising_modes , advertising_modes ,
618
620
table [proto ].advertised ,
@@ -794,12 +796,12 @@ static void get_supported(struct mlx5_core_dev *mdev, u32 eth_proto_cap,
794
796
ethtool_link_ksettings_add_link_mode (link_ksettings , supported , Pause );
795
797
}
796
798
797
- static void get_advertising (struct mlx5_core_dev * mdev , u32 eth_proto_cap ,
798
- u8 tx_pause , u8 rx_pause ,
799
- struct ethtool_link_ksettings * link_ksettings )
799
+ static void get_advertising (u32 eth_proto_cap , u8 tx_pause , u8 rx_pause ,
800
+ struct ethtool_link_ksettings * link_ksettings ,
801
+ bool ext )
800
802
{
801
803
unsigned long * advertising = link_ksettings -> link_modes .advertising ;
802
- ptys2ethtool_adver_link (mdev , advertising , eth_proto_cap );
804
+ ptys2ethtool_adver_link (advertising , eth_proto_cap , ext );
803
805
804
806
if (rx_pause )
805
807
ethtool_link_ksettings_add_link_mode (link_ksettings , advertising , Pause );
@@ -854,8 +856,9 @@ static void get_lp_advertising(struct mlx5_core_dev *mdev, u32 eth_proto_lp,
854
856
struct ethtool_link_ksettings * link_ksettings )
855
857
{
856
858
unsigned long * lp_advertising = link_ksettings -> link_modes .lp_advertising ;
859
+ bool ext = MLX5_CAP_PCAM_FEATURE (mdev , ptys_extended_ethernet );
857
860
858
- ptys2ethtool_adver_link (mdev , lp_advertising , eth_proto_lp );
861
+ ptys2ethtool_adver_link (lp_advertising , eth_proto_lp , ext );
859
862
}
860
863
861
864
int mlx5e_ethtool_get_link_ksettings (struct mlx5e_priv * priv ,
@@ -872,6 +875,7 @@ int mlx5e_ethtool_get_link_ksettings(struct mlx5e_priv *priv,
872
875
u8 an_disable_admin ;
873
876
u8 an_status ;
874
877
u8 connector_type ;
878
+ bool admin_ext ;
875
879
bool ext ;
876
880
int err ;
877
881
@@ -886,6 +890,19 @@ int mlx5e_ethtool_get_link_ksettings(struct mlx5e_priv *priv,
886
890
eth_proto_capability );
887
891
eth_proto_admin = MLX5_GET_ETH_PROTO (ptys_reg , out , ext ,
888
892
eth_proto_admin );
893
+ /* Fields: eth_proto_admin and ext_eth_proto_admin are
894
+ * mutually exclusive. Hence try reading legacy advertising
895
+ * when extended advertising is zero.
896
+ * admin_ext indicates how eth_proto_admin should be
897
+ * interpreted
898
+ */
899
+ admin_ext = ext ;
900
+ if (ext && !eth_proto_admin ) {
901
+ eth_proto_admin = MLX5_GET_ETH_PROTO (ptys_reg , out , false,
902
+ eth_proto_admin );
903
+ admin_ext = false;
904
+ }
905
+
889
906
eth_proto_oper = MLX5_GET_ETH_PROTO (ptys_reg , out , ext ,
890
907
eth_proto_oper );
891
908
eth_proto_lp = MLX5_GET (ptys_reg , out , eth_proto_lp_advertise );
@@ -899,7 +916,8 @@ int mlx5e_ethtool_get_link_ksettings(struct mlx5e_priv *priv,
899
916
ethtool_link_ksettings_zero_link_mode (link_ksettings , advertising );
900
917
901
918
get_supported (mdev , eth_proto_cap , link_ksettings );
902
- get_advertising (mdev , eth_proto_admin , tx_pause , rx_pause , link_ksettings );
919
+ get_advertising (eth_proto_admin , tx_pause , rx_pause , link_ksettings ,
920
+ admin_ext );
903
921
get_speed_duplex (priv -> netdev , eth_proto_oper , link_ksettings );
904
922
905
923
eth_proto_oper = eth_proto_oper ? eth_proto_oper : eth_proto_cap ;
@@ -1001,16 +1019,13 @@ int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv,
1001
1019
MLX5E_PTYS_EXT ||
1002
1020
link_ksettings -> link_modes .advertising [1 ]);
1003
1021
ext_supported = MLX5_CAP_PCAM_FEATURE (mdev , ptys_extended_ethernet );
1004
-
1005
- /*when ptys_extended_ethernet is set legacy link modes are deprecated */
1006
- if (ext_requested != ext_supported )
1007
- return - EPROTONOSUPPORT ;
1022
+ ext_requested &= ext_supported ;
1008
1023
1009
1024
speed = link_ksettings -> base .speed ;
1010
1025
ethtool2ptys_adver_func = ext_requested ?
1011
1026
mlx5e_ethtool2ptys_ext_adver_link :
1012
1027
mlx5e_ethtool2ptys_adver_link ;
1013
- err = mlx5_port_query_eth_proto (mdev , 1 , ext_supported , & eproto );
1028
+ err = mlx5_port_query_eth_proto (mdev , 1 , ext_requested , & eproto );
1014
1029
if (err ) {
1015
1030
netdev_err (priv -> netdev , "%s: query port eth proto failed: %d\n" ,
1016
1031
__func__ , err );
@@ -1038,7 +1053,7 @@ int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv,
1038
1053
if (!an_changes && link_modes == eproto .admin )
1039
1054
goto out ;
1040
1055
1041
- mlx5_port_set_eth_ptys (mdev , an_disable , link_modes , ext_supported );
1056
+ mlx5_port_set_eth_ptys (mdev , an_disable , link_modes , ext_requested );
1042
1057
mlx5_toggle_port_link (mdev );
1043
1058
1044
1059
out :
0 commit comments