@@ -293,35 +293,131 @@ nfp_net_set_fec_link_mode(struct nfp_eth_table_port *eth_port,
293293 }
294294}
295295
296- static const u16 nfp_eth_media_table [] = {
297- [NFP_MEDIA_1000BASE_CX ] = ETHTOOL_LINK_MODE_1000baseKX_Full_BIT ,
298- [NFP_MEDIA_1000BASE_KX ] = ETHTOOL_LINK_MODE_1000baseKX_Full_BIT ,
299- [NFP_MEDIA_10GBASE_KX4 ] = ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT ,
300- [NFP_MEDIA_10GBASE_KR ] = ETHTOOL_LINK_MODE_10000baseKR_Full_BIT ,
301- [NFP_MEDIA_10GBASE_CX4 ] = ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT ,
302- [NFP_MEDIA_10GBASE_CR ] = ETHTOOL_LINK_MODE_10000baseCR_Full_BIT ,
303- [NFP_MEDIA_10GBASE_SR ] = ETHTOOL_LINK_MODE_10000baseSR_Full_BIT ,
304- [NFP_MEDIA_10GBASE_ER ] = ETHTOOL_LINK_MODE_10000baseER_Full_BIT ,
305- [NFP_MEDIA_25GBASE_KR ] = ETHTOOL_LINK_MODE_25000baseKR_Full_BIT ,
306- [NFP_MEDIA_25GBASE_KR_S ] = ETHTOOL_LINK_MODE_25000baseKR_Full_BIT ,
307- [NFP_MEDIA_25GBASE_CR ] = ETHTOOL_LINK_MODE_25000baseCR_Full_BIT ,
308- [NFP_MEDIA_25GBASE_CR_S ] = ETHTOOL_LINK_MODE_25000baseCR_Full_BIT ,
309- [NFP_MEDIA_25GBASE_SR ] = ETHTOOL_LINK_MODE_25000baseSR_Full_BIT ,
310- [NFP_MEDIA_40GBASE_CR4 ] = ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT ,
311- [NFP_MEDIA_40GBASE_KR4 ] = ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT ,
312- [NFP_MEDIA_40GBASE_SR4 ] = ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT ,
313- [NFP_MEDIA_40GBASE_LR4 ] = ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT ,
314- [NFP_MEDIA_50GBASE_KR ] = ETHTOOL_LINK_MODE_50000baseKR_Full_BIT ,
315- [NFP_MEDIA_50GBASE_SR ] = ETHTOOL_LINK_MODE_50000baseSR_Full_BIT ,
316- [NFP_MEDIA_50GBASE_CR ] = ETHTOOL_LINK_MODE_50000baseCR_Full_BIT ,
317- [NFP_MEDIA_50GBASE_LR ] = ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT ,
318- [NFP_MEDIA_50GBASE_ER ] = ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT ,
319- [NFP_MEDIA_50GBASE_FR ] = ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT ,
320- [NFP_MEDIA_100GBASE_KR4 ] = ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT ,
321- [NFP_MEDIA_100GBASE_SR4 ] = ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT ,
322- [NFP_MEDIA_100GBASE_CR4 ] = ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT ,
323- [NFP_MEDIA_100GBASE_KP4 ] = ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT ,
324- [NFP_MEDIA_100GBASE_CR10 ] = ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT ,
296+ static const struct nfp_eth_media_link_mode {
297+ u16 ethtool_link_mode ;
298+ u16 speed ;
299+ } nfp_eth_media_table [NFP_MEDIA_LINK_MODES_NUMBER ] = {
300+ [NFP_MEDIA_1000BASE_CX ] = {
301+ .ethtool_link_mode = ETHTOOL_LINK_MODE_1000baseKX_Full_BIT ,
302+ .speed = NFP_SPEED_1G ,
303+ },
304+ [NFP_MEDIA_1000BASE_KX ] = {
305+ .ethtool_link_mode = ETHTOOL_LINK_MODE_1000baseKX_Full_BIT ,
306+ .speed = NFP_SPEED_1G ,
307+ },
308+ [NFP_MEDIA_10GBASE_KX4 ] = {
309+ .ethtool_link_mode = ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT ,
310+ .speed = NFP_SPEED_10G ,
311+ },
312+ [NFP_MEDIA_10GBASE_KR ] = {
313+ .ethtool_link_mode = ETHTOOL_LINK_MODE_10000baseKR_Full_BIT ,
314+ .speed = NFP_SPEED_10G ,
315+ },
316+ [NFP_MEDIA_10GBASE_CX4 ] = {
317+ .ethtool_link_mode = ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT ,
318+ .speed = NFP_SPEED_10G ,
319+ },
320+ [NFP_MEDIA_10GBASE_CR ] = {
321+ .ethtool_link_mode = ETHTOOL_LINK_MODE_10000baseCR_Full_BIT ,
322+ .speed = NFP_SPEED_10G ,
323+ },
324+ [NFP_MEDIA_10GBASE_SR ] = {
325+ .ethtool_link_mode = ETHTOOL_LINK_MODE_10000baseSR_Full_BIT ,
326+ .speed = NFP_SPEED_10G ,
327+ },
328+ [NFP_MEDIA_10GBASE_ER ] = {
329+ .ethtool_link_mode = ETHTOOL_LINK_MODE_10000baseER_Full_BIT ,
330+ .speed = NFP_SPEED_10G ,
331+ },
332+ [NFP_MEDIA_25GBASE_KR ] = {
333+ .ethtool_link_mode = ETHTOOL_LINK_MODE_25000baseKR_Full_BIT ,
334+ .speed = NFP_SPEED_25G ,
335+ },
336+ [NFP_MEDIA_25GBASE_KR_S ] = {
337+ .ethtool_link_mode = ETHTOOL_LINK_MODE_25000baseKR_Full_BIT ,
338+ .speed = NFP_SPEED_25G ,
339+ },
340+ [NFP_MEDIA_25GBASE_CR ] = {
341+ .ethtool_link_mode = ETHTOOL_LINK_MODE_25000baseCR_Full_BIT ,
342+ .speed = NFP_SPEED_25G ,
343+ },
344+ [NFP_MEDIA_25GBASE_CR_S ] = {
345+ .ethtool_link_mode = ETHTOOL_LINK_MODE_25000baseCR_Full_BIT ,
346+ .speed = NFP_SPEED_25G ,
347+ },
348+ [NFP_MEDIA_25GBASE_SR ] = {
349+ .ethtool_link_mode = ETHTOOL_LINK_MODE_25000baseSR_Full_BIT ,
350+ .speed = NFP_SPEED_25G ,
351+ },
352+ [NFP_MEDIA_40GBASE_CR4 ] = {
353+ .ethtool_link_mode = ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT ,
354+ .speed = NFP_SPEED_40G ,
355+ },
356+ [NFP_MEDIA_40GBASE_KR4 ] = {
357+ .ethtool_link_mode = ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT ,
358+ .speed = NFP_SPEED_40G ,
359+ },
360+ [NFP_MEDIA_40GBASE_SR4 ] = {
361+ .ethtool_link_mode = ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT ,
362+ .speed = NFP_SPEED_40G ,
363+ },
364+ [NFP_MEDIA_40GBASE_LR4 ] = {
365+ .ethtool_link_mode = ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT ,
366+ .speed = NFP_SPEED_40G ,
367+ },
368+ [NFP_MEDIA_50GBASE_KR ] = {
369+ .ethtool_link_mode = ETHTOOL_LINK_MODE_50000baseKR_Full_BIT ,
370+ .speed = NFP_SPEED_50G ,
371+ },
372+ [NFP_MEDIA_50GBASE_SR ] = {
373+ .ethtool_link_mode = ETHTOOL_LINK_MODE_50000baseSR_Full_BIT ,
374+ .speed = NFP_SPEED_50G ,
375+ },
376+ [NFP_MEDIA_50GBASE_CR ] = {
377+ .ethtool_link_mode = ETHTOOL_LINK_MODE_50000baseCR_Full_BIT ,
378+ .speed = NFP_SPEED_50G ,
379+ },
380+ [NFP_MEDIA_50GBASE_LR ] = {
381+ .ethtool_link_mode = ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT ,
382+ .speed = NFP_SPEED_50G ,
383+ },
384+ [NFP_MEDIA_50GBASE_ER ] = {
385+ .ethtool_link_mode = ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT ,
386+ .speed = NFP_SPEED_50G ,
387+ },
388+ [NFP_MEDIA_50GBASE_FR ] = {
389+ .ethtool_link_mode = ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT ,
390+ .speed = NFP_SPEED_50G ,
391+ },
392+ [NFP_MEDIA_100GBASE_KR4 ] = {
393+ .ethtool_link_mode = ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT ,
394+ .speed = NFP_SPEED_100G ,
395+ },
396+ [NFP_MEDIA_100GBASE_SR4 ] = {
397+ .ethtool_link_mode = ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT ,
398+ .speed = NFP_SPEED_100G ,
399+ },
400+ [NFP_MEDIA_100GBASE_CR4 ] = {
401+ .ethtool_link_mode = ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT ,
402+ .speed = NFP_SPEED_100G ,
403+ },
404+ [NFP_MEDIA_100GBASE_KP4 ] = {
405+ .ethtool_link_mode = ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT ,
406+ .speed = NFP_SPEED_100G ,
407+ },
408+ [NFP_MEDIA_100GBASE_CR10 ] = {
409+ .ethtool_link_mode = ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT ,
410+ .speed = NFP_SPEED_100G ,
411+ },
412+ };
413+
414+ static const unsigned int nfp_eth_speed_map [NFP_SUP_SPEED_NUMBER ] = {
415+ [NFP_SPEED_1G ] = SPEED_1000 ,
416+ [NFP_SPEED_10G ] = SPEED_10000 ,
417+ [NFP_SPEED_25G ] = SPEED_25000 ,
418+ [NFP_SPEED_40G ] = SPEED_40000 ,
419+ [NFP_SPEED_50G ] = SPEED_50000 ,
420+ [NFP_SPEED_100G ] = SPEED_100000 ,
325421};
326422
327423static void nfp_add_media_link_mode (struct nfp_port * port ,
@@ -334,8 +430,12 @@ static void nfp_add_media_link_mode(struct nfp_port *port,
334430 };
335431 struct nfp_cpp * cpp = port -> app -> cpp ;
336432
337- if (nfp_eth_read_media (cpp , & ethm ))
433+ if (nfp_eth_read_media (cpp , & ethm )) {
434+ bitmap_fill (port -> speed_bitmap , NFP_SUP_SPEED_NUMBER );
338435 return ;
436+ }
437+
438+ bitmap_zero (port -> speed_bitmap , NFP_SUP_SPEED_NUMBER );
339439
340440 for (u32 i = 0 ; i < 2 ; i ++ ) {
341441 supported_modes [i ] = le64_to_cpu (ethm .supported_modes [i ]);
@@ -344,20 +444,26 @@ static void nfp_add_media_link_mode(struct nfp_port *port,
344444
345445 for (u32 i = 0 ; i < NFP_MEDIA_LINK_MODES_NUMBER ; i ++ ) {
346446 if (i < 64 ) {
347- if (supported_modes [0 ] & BIT_ULL (i ))
348- __set_bit (nfp_eth_media_table [i ],
447+ if (supported_modes [0 ] & BIT_ULL (i )) {
448+ __set_bit (nfp_eth_media_table [i ]. ethtool_link_mode ,
349449 cmd -> link_modes .supported );
450+ __set_bit (nfp_eth_media_table [i ].speed ,
451+ port -> speed_bitmap );
452+ }
350453
351454 if (advertised_modes [0 ] & BIT_ULL (i ))
352- __set_bit (nfp_eth_media_table [i ],
455+ __set_bit (nfp_eth_media_table [i ]. ethtool_link_mode ,
353456 cmd -> link_modes .advertising );
354457 } else {
355- if (supported_modes [1 ] & BIT_ULL (i - 64 ))
356- __set_bit (nfp_eth_media_table [i ],
458+ if (supported_modes [1 ] & BIT_ULL (i - 64 )) {
459+ __set_bit (nfp_eth_media_table [i ]. ethtool_link_mode ,
357460 cmd -> link_modes .supported );
461+ __set_bit (nfp_eth_media_table [i ].speed ,
462+ port -> speed_bitmap );
463+ }
358464
359465 if (advertised_modes [1 ] & BIT_ULL (i - 64 ))
360- __set_bit (nfp_eth_media_table [i ],
466+ __set_bit (nfp_eth_media_table [i ]. ethtool_link_mode ,
361467 cmd -> link_modes .advertising );
362468 }
363469 }
@@ -468,6 +574,22 @@ nfp_net_set_link_ksettings(struct net_device *netdev,
468574
469575 if (cmd -> base .speed != SPEED_UNKNOWN ) {
470576 u32 speed = cmd -> base .speed / eth_port -> lanes ;
577+ bool is_supported = false;
578+
579+ for (u32 i = 0 ; i < NFP_SUP_SPEED_NUMBER ; i ++ ) {
580+ if (cmd -> base .speed == nfp_eth_speed_map [i ] &&
581+ test_bit (i , port -> speed_bitmap )) {
582+ is_supported = true;
583+ break ;
584+ }
585+ }
586+
587+ if (!is_supported ) {
588+ netdev_err (netdev , "Speed %u is not supported.\n" ,
589+ cmd -> base .speed );
590+ err = - EINVAL ;
591+ goto err_bad_set ;
592+ }
471593
472594 if (req_aneg ) {
473595 netdev_err (netdev , "Speed changing is not allowed when working on autoneg mode.\n" );
0 commit comments