@@ -173,6 +173,54 @@ static void nfp_net_get_drvinfo(struct net_device *netdev,
173173 drvinfo -> regdump_len = NFP_NET_CFG_BAR_SZ ;
174174}
175175
176+ /**
177+ * nfp_net_get_link_ksettings - Get Link Speed settings
178+ * @netdev: network interface device structure
179+ * @cmd: ethtool command
180+ *
181+ * Reports speed settings based on info in the BAR provided by the fw.
182+ */
183+ static int
184+ nfp_net_get_link_ksettings (struct net_device * netdev ,
185+ struct ethtool_link_ksettings * cmd )
186+ {
187+ static const u32 ls_to_ethtool [] = {
188+ [NFP_NET_CFG_STS_LINK_RATE_UNSUPPORTED ] = 0 ,
189+ [NFP_NET_CFG_STS_LINK_RATE_UNKNOWN ] = SPEED_UNKNOWN ,
190+ [NFP_NET_CFG_STS_LINK_RATE_1G ] = SPEED_1000 ,
191+ [NFP_NET_CFG_STS_LINK_RATE_10G ] = SPEED_10000 ,
192+ [NFP_NET_CFG_STS_LINK_RATE_25G ] = SPEED_25000 ,
193+ [NFP_NET_CFG_STS_LINK_RATE_40G ] = SPEED_40000 ,
194+ [NFP_NET_CFG_STS_LINK_RATE_50G ] = SPEED_50000 ,
195+ [NFP_NET_CFG_STS_LINK_RATE_100G ] = SPEED_100000 ,
196+ };
197+ struct nfp_net * nn = netdev_priv (netdev );
198+ u32 sts , ls ;
199+
200+ ethtool_link_ksettings_add_link_mode (cmd , supported , FIBRE );
201+ cmd -> base .port = PORT_OTHER ;
202+ cmd -> base .speed = SPEED_UNKNOWN ;
203+ cmd -> base .duplex = DUPLEX_UNKNOWN ;
204+
205+ if (!netif_carrier_ok (netdev ))
206+ return 0 ;
207+
208+ sts = nn_readl (nn , NFP_NET_CFG_STS );
209+
210+ ls = FIELD_GET (NFP_NET_CFG_STS_LINK_RATE , sts );
211+ if (ls == NFP_NET_CFG_STS_LINK_RATE_UNSUPPORTED )
212+ return - EOPNOTSUPP ;
213+
214+ if (ls == NFP_NET_CFG_STS_LINK_RATE_UNKNOWN ||
215+ ls >= ARRAY_SIZE (ls_to_ethtool ))
216+ return 0 ;
217+
218+ cmd -> base .speed = ls_to_ethtool [sts ];
219+ cmd -> base .duplex = DUPLEX_FULL ;
220+
221+ return 0 ;
222+ }
223+
176224static void nfp_net_get_ringparam (struct net_device * netdev ,
177225 struct ethtool_ringparam * ring )
178226{
@@ -814,6 +862,7 @@ static const struct ethtool_ops nfp_net_ethtool_ops = {
814862 .set_coalesce = nfp_net_set_coalesce ,
815863 .get_channels = nfp_net_get_channels ,
816864 .set_channels = nfp_net_set_channels ,
865+ .get_link_ksettings = nfp_net_get_link_ksettings ,
817866};
818867
819868void nfp_net_set_ethtool_ops (struct net_device * netdev )
0 commit comments