8
8
* the Free Software Foundation.
9
9
*/
10
10
11
+ #include <linux/bitops.h>
11
12
#include <linux/ctype.h>
12
13
#include <linux/stringify.h>
13
14
#include <linux/ethtool.h>
@@ -1730,86 +1731,6 @@ bnxt_get_link_mode(struct bnxt_link_info *link_info)
1730
1731
return link_mode ;
1731
1732
}
1732
1733
1733
- #define BNXT_FW_TO_ETHTOOL_SPDS (fw_speeds , lk_ksettings , name ) \
1734
- { \
1735
- if ((fw_speeds) & BNXT_LINK_SPEED_MSK_100MB) \
1736
- ethtool_link_ksettings_add_link_mode(lk_ksettings, name,\
1737
- 100baseT_Full); \
1738
- if ((fw_speeds) & BNXT_LINK_SPEED_MSK_1GB) \
1739
- ethtool_link_ksettings_add_link_mode(lk_ksettings, name,\
1740
- 1000baseT_Full); \
1741
- if ((fw_speeds) & BNXT_LINK_SPEED_MSK_10GB) \
1742
- ethtool_link_ksettings_add_link_mode(lk_ksettings, name,\
1743
- 10000baseT_Full); \
1744
- if ((fw_speeds) & BNXT_LINK_SPEED_MSK_25GB) \
1745
- ethtool_link_ksettings_add_link_mode(lk_ksettings, name,\
1746
- 25000baseCR_Full); \
1747
- if ((fw_speeds) & BNXT_LINK_SPEED_MSK_40GB) \
1748
- ethtool_link_ksettings_add_link_mode(lk_ksettings, name,\
1749
- 40000baseCR4_Full);\
1750
- if ((fw_speeds) & BNXT_LINK_SPEED_MSK_50GB) \
1751
- ethtool_link_ksettings_add_link_mode(lk_ksettings, name,\
1752
- 50000baseCR2_Full);\
1753
- if ((fw_speeds) & BNXT_LINK_SPEED_MSK_100GB) \
1754
- ethtool_link_ksettings_add_link_mode(lk_ksettings, name,\
1755
- 100000baseCR4_Full);\
1756
- }
1757
-
1758
- #define BNXT_ETHTOOL_TO_FW_SPDS (fw_speeds , lk_ksettings , name ) \
1759
- { \
1760
- if (ethtool_link_ksettings_test_link_mode(lk_ksettings, name, \
1761
- 100baseT_Full) || \
1762
- ethtool_link_ksettings_test_link_mode(lk_ksettings, name, \
1763
- 100baseT_Half)) \
1764
- (fw_speeds) |= BNXT_LINK_SPEED_MSK_100MB; \
1765
- if (ethtool_link_ksettings_test_link_mode(lk_ksettings, name, \
1766
- 1000baseT_Full) || \
1767
- ethtool_link_ksettings_test_link_mode(lk_ksettings, name, \
1768
- 1000baseT_Half)) \
1769
- (fw_speeds) |= BNXT_LINK_SPEED_MSK_1GB; \
1770
- if (ethtool_link_ksettings_test_link_mode(lk_ksettings, name, \
1771
- 10000baseT_Full)) \
1772
- (fw_speeds) |= BNXT_LINK_SPEED_MSK_10GB; \
1773
- if (ethtool_link_ksettings_test_link_mode(lk_ksettings, name, \
1774
- 25000baseCR_Full)) \
1775
- (fw_speeds) |= BNXT_LINK_SPEED_MSK_25GB; \
1776
- if (ethtool_link_ksettings_test_link_mode(lk_ksettings, name, \
1777
- 40000baseCR4_Full)) \
1778
- (fw_speeds) |= BNXT_LINK_SPEED_MSK_40GB; \
1779
- if (ethtool_link_ksettings_test_link_mode(lk_ksettings, name, \
1780
- 50000baseCR2_Full)) \
1781
- (fw_speeds) |= BNXT_LINK_SPEED_MSK_50GB; \
1782
- if (ethtool_link_ksettings_test_link_mode(lk_ksettings, name, \
1783
- 100000baseCR4_Full)) \
1784
- (fw_speeds) |= BNXT_LINK_SPEED_MSK_100GB; \
1785
- }
1786
-
1787
- #define BNXT_FW_TO_ETHTOOL_PAM4_SPDS (fw_speeds , lk_ksettings , name ) \
1788
- { \
1789
- if ((fw_speeds) & BNXT_LINK_PAM4_SPEED_MSK_50GB) \
1790
- ethtool_link_ksettings_add_link_mode(lk_ksettings, name,\
1791
- 50000baseCR_Full); \
1792
- if ((fw_speeds) & BNXT_LINK_PAM4_SPEED_MSK_100GB) \
1793
- ethtool_link_ksettings_add_link_mode(lk_ksettings, name,\
1794
- 100000baseCR2_Full);\
1795
- if ((fw_speeds) & BNXT_LINK_PAM4_SPEED_MSK_200GB) \
1796
- ethtool_link_ksettings_add_link_mode(lk_ksettings, name,\
1797
- 200000baseCR4_Full);\
1798
- }
1799
-
1800
- #define BNXT_ETHTOOL_TO_FW_PAM4_SPDS (fw_speeds , lk_ksettings , name ) \
1801
- { \
1802
- if (ethtool_link_ksettings_test_link_mode(lk_ksettings, name, \
1803
- 50000baseCR_Full)) \
1804
- (fw_speeds) |= BNXT_LINK_PAM4_SPEED_MSK_50GB; \
1805
- if (ethtool_link_ksettings_test_link_mode(lk_ksettings, name, \
1806
- 100000baseCR2_Full)) \
1807
- (fw_speeds) |= BNXT_LINK_PAM4_SPEED_MSK_100GB; \
1808
- if (ethtool_link_ksettings_test_link_mode(lk_ksettings, name, \
1809
- 200000baseCR4_Full)) \
1810
- (fw_speeds) |= BNXT_LINK_PAM4_SPEED_MSK_200GB; \
1811
- }
1812
-
1813
1734
static void bnxt_get_ethtool_modes (struct bnxt_link_info * link_info ,
1814
1735
struct ethtool_link_ksettings * lk_ksettings )
1815
1736
{
@@ -1843,6 +1764,133 @@ static void bnxt_get_ethtool_modes(struct bnxt_link_info *link_info,
1843
1764
lk_ksettings -> link_modes .lp_advertising );
1844
1765
}
1845
1766
1767
+ static const u16 bnxt_nrz_speed_masks [] = {
1768
+ [BNXT_LINK_SPEED_100MB_IDX ] = BNXT_LINK_SPEED_MSK_100MB ,
1769
+ [BNXT_LINK_SPEED_1GB_IDX ] = BNXT_LINK_SPEED_MSK_1GB ,
1770
+ [BNXT_LINK_SPEED_10GB_IDX ] = BNXT_LINK_SPEED_MSK_10GB ,
1771
+ [BNXT_LINK_SPEED_25GB_IDX ] = BNXT_LINK_SPEED_MSK_25GB ,
1772
+ [BNXT_LINK_SPEED_40GB_IDX ] = BNXT_LINK_SPEED_MSK_40GB ,
1773
+ [BNXT_LINK_SPEED_50GB_IDX ] = BNXT_LINK_SPEED_MSK_50GB ,
1774
+ [BNXT_LINK_SPEED_100GB_IDX ] = BNXT_LINK_SPEED_MSK_100GB ,
1775
+ [__BNXT_LINK_SPEED_END - 1 ] = 0 /* make any legal speed a valid index */
1776
+ };
1777
+
1778
+ static const u16 bnxt_pam4_speed_masks [] = {
1779
+ [BNXT_LINK_SPEED_50GB_IDX ] = BNXT_LINK_PAM4_SPEED_MSK_50GB ,
1780
+ [BNXT_LINK_SPEED_100GB_IDX ] = BNXT_LINK_PAM4_SPEED_MSK_100GB ,
1781
+ [BNXT_LINK_SPEED_200GB_IDX ] = BNXT_LINK_PAM4_SPEED_MSK_200GB ,
1782
+ };
1783
+
1784
+ static enum bnxt_link_speed_indices
1785
+ bnxt_encoding_speed_idx (u8 sig_mode , u16 speed_msk )
1786
+ {
1787
+ const u16 * speeds ;
1788
+ int idx , len ;
1789
+
1790
+ switch (sig_mode ) {
1791
+ case BNXT_SIG_MODE_NRZ :
1792
+ speeds = bnxt_nrz_speed_masks ;
1793
+ len = ARRAY_SIZE (bnxt_nrz_speed_masks );
1794
+ break ;
1795
+ case BNXT_SIG_MODE_PAM4 :
1796
+ speeds = bnxt_pam4_speed_masks ;
1797
+ len = ARRAY_SIZE (bnxt_pam4_speed_masks );
1798
+ break ;
1799
+ default :
1800
+ return BNXT_LINK_SPEED_UNKNOWN ;
1801
+ }
1802
+
1803
+ for (idx = 0 ; idx < len ; idx ++ ) {
1804
+ if (speeds [idx ] == speed_msk )
1805
+ return idx ;
1806
+ }
1807
+
1808
+ return BNXT_LINK_SPEED_UNKNOWN ;
1809
+ }
1810
+
1811
+ #define BNXT_FW_SPEED_MSK_BITS 16
1812
+
1813
+ static void
1814
+ __bnxt_get_ethtool_speeds (unsigned long fw_mask , enum bnxt_media_type media ,
1815
+ u8 sig_mode , unsigned long * et_mask )
1816
+ {
1817
+ enum ethtool_link_mode_bit_indices link_mode ;
1818
+ enum bnxt_link_speed_indices speed ;
1819
+ u8 bit ;
1820
+
1821
+ for_each_set_bit (bit , & fw_mask , BNXT_FW_SPEED_MSK_BITS ) {
1822
+ speed = bnxt_encoding_speed_idx (sig_mode , 1 << bit );
1823
+ if (!speed )
1824
+ continue ;
1825
+
1826
+ link_mode = bnxt_link_modes [speed ][sig_mode ][media ];
1827
+ if (!link_mode )
1828
+ continue ;
1829
+
1830
+ linkmode_set_bit (link_mode , et_mask );
1831
+ }
1832
+ }
1833
+
1834
+ static void
1835
+ bnxt_get_ethtool_speeds (unsigned long fw_mask , enum bnxt_media_type media ,
1836
+ u8 sig_mode , unsigned long * et_mask )
1837
+ {
1838
+ if (media ) {
1839
+ __bnxt_get_ethtool_speeds (fw_mask , media , sig_mode , et_mask );
1840
+ return ;
1841
+ }
1842
+
1843
+ /* list speeds for all media if unknown */
1844
+ for (media = 1 ; media < __BNXT_MEDIA_END ; media ++ )
1845
+ __bnxt_get_ethtool_speeds (fw_mask , media , sig_mode , et_mask );
1846
+ }
1847
+
1848
+ static void bnxt_update_speed (u32 * delta , bool installed_media , u16 * speeds ,
1849
+ u16 speed_msk , const unsigned long * et_mask ,
1850
+ enum ethtool_link_mode_bit_indices mode )
1851
+ {
1852
+ bool mode_desired = linkmode_test_bit (mode , et_mask );
1853
+
1854
+ if (!mode )
1855
+ return ;
1856
+
1857
+ /* enabled speeds for installed media should override */
1858
+ if (installed_media && mode_desired ) {
1859
+ * speeds |= speed_msk ;
1860
+ * delta |= speed_msk ;
1861
+ return ;
1862
+ }
1863
+
1864
+ /* many to one mapping, only allow one change per fw_speed bit */
1865
+ if (!(* delta & speed_msk ) && (mode_desired == !(* speeds & speed_msk ))) {
1866
+ * speeds ^= speed_msk ;
1867
+ * delta |= speed_msk ;
1868
+ }
1869
+ }
1870
+
1871
+ static void bnxt_set_ethtool_speeds (struct bnxt_link_info * link_info ,
1872
+ const unsigned long * et_mask )
1873
+ {
1874
+ enum bnxt_media_type media = bnxt_get_media (link_info );
1875
+ u32 delta_pam4 = 0 ;
1876
+ u32 delta_nrz = 0 ;
1877
+ int i , m ;
1878
+
1879
+ for (i = 1 ; i < __BNXT_LINK_SPEED_END ; i ++ ) {
1880
+ /* accept any legal media from user */
1881
+ for (m = 1 ; m < __BNXT_MEDIA_END ; m ++ ) {
1882
+ bnxt_update_speed (& delta_nrz , m == media ,
1883
+ & link_info -> advertising ,
1884
+ bnxt_nrz_speed_masks [i ], et_mask ,
1885
+ bnxt_link_modes [i ][BNXT_SIG_MODE_NRZ ][m ]);
1886
+ bnxt_update_speed (& delta_pam4 , m == media ,
1887
+ & link_info -> advertising_pam4 ,
1888
+ bnxt_pam4_speed_masks [i ], et_mask ,
1889
+ bnxt_link_modes [i ][BNXT_SIG_MODE_PAM4 ][m ]);
1890
+ }
1891
+ }
1892
+ }
1893
+
1846
1894
static void bnxt_fw_to_ethtool_advertised_fec (struct bnxt_link_info * link_info ,
1847
1895
struct ethtool_link_ksettings * lk_ksettings )
1848
1896
{
@@ -1864,26 +1912,6 @@ static void bnxt_fw_to_ethtool_advertised_fec(struct bnxt_link_info *link_info,
1864
1912
lk_ksettings -> link_modes .advertising );
1865
1913
}
1866
1914
1867
- static void bnxt_fw_to_ethtool_advertised_spds (struct bnxt_link_info * link_info ,
1868
- struct ethtool_link_ksettings * lk_ksettings )
1869
- {
1870
- u16 fw_speeds = link_info -> advertising ;
1871
-
1872
- BNXT_FW_TO_ETHTOOL_SPDS (fw_speeds , lk_ksettings , advertising );
1873
- fw_speeds = link_info -> advertising_pam4 ;
1874
- BNXT_FW_TO_ETHTOOL_PAM4_SPDS (fw_speeds , lk_ksettings , advertising );
1875
- }
1876
-
1877
- static void bnxt_fw_to_ethtool_lp_adv (struct bnxt_link_info * link_info ,
1878
- struct ethtool_link_ksettings * lk_ksettings )
1879
- {
1880
- u16 fw_speeds = link_info -> lp_auto_link_speeds ;
1881
-
1882
- BNXT_FW_TO_ETHTOOL_SPDS (fw_speeds , lk_ksettings , lp_advertising );
1883
- fw_speeds = link_info -> lp_auto_pam4_link_speeds ;
1884
- BNXT_FW_TO_ETHTOOL_PAM4_SPDS (fw_speeds , lk_ksettings , lp_advertising );
1885
- }
1886
-
1887
1915
static void bnxt_fw_to_ethtool_support_fec (struct bnxt_link_info * link_info ,
1888
1916
struct ethtool_link_ksettings * lk_ksettings )
1889
1917
{
@@ -1905,16 +1933,6 @@ static void bnxt_fw_to_ethtool_support_fec(struct bnxt_link_info *link_info,
1905
1933
lk_ksettings -> link_modes .supported );
1906
1934
}
1907
1935
1908
- static void bnxt_fw_to_ethtool_support_spds (struct bnxt_link_info * link_info ,
1909
- struct ethtool_link_ksettings * lk_ksettings )
1910
- {
1911
- u16 fw_speeds = link_info -> support_speeds ;
1912
-
1913
- BNXT_FW_TO_ETHTOOL_SPDS (fw_speeds , lk_ksettings , supported );
1914
- fw_speeds = link_info -> support_pam4_speeds ;
1915
- BNXT_FW_TO_ETHTOOL_PAM4_SPDS (fw_speeds , lk_ksettings , supported );
1916
- }
1917
-
1918
1936
u32 bnxt_fw_to_ethtool_speed (u16 fw_link_speed )
1919
1937
{
1920
1938
switch (fw_link_speed ) {
@@ -1968,7 +1986,9 @@ static int bnxt_get_link_ksettings(struct net_device *dev,
1968
1986
enum ethtool_link_mode_bit_indices link_mode ;
1969
1987
struct bnxt * bp = netdev_priv (dev );
1970
1988
struct bnxt_link_info * link_info ;
1989
+ enum bnxt_media_type media ;
1971
1990
1991
+ ethtool_link_ksettings_zero_link_mode (lk_ksettings , lp_advertising );
1972
1992
ethtool_link_ksettings_zero_link_mode (lk_ksettings , advertising );
1973
1993
ethtool_link_ksettings_zero_link_mode (lk_ksettings , supported );
1974
1994
base -> duplex = DUPLEX_UNKNOWN ;
@@ -1977,7 +1997,13 @@ static int bnxt_get_link_ksettings(struct net_device *dev,
1977
1997
1978
1998
mutex_lock (& bp -> link_lock );
1979
1999
bnxt_get_ethtool_modes (link_info , lk_ksettings );
1980
- bnxt_fw_to_ethtool_support_spds (link_info , lk_ksettings );
2000
+ media = bnxt_get_media (link_info );
2001
+ bnxt_get_ethtool_speeds (link_info -> support_speeds ,
2002
+ media , BNXT_SIG_MODE_NRZ ,
2003
+ lk_ksettings -> link_modes .supported );
2004
+ bnxt_get_ethtool_speeds (link_info -> support_pam4_speeds ,
2005
+ media , BNXT_SIG_MODE_PAM4 ,
2006
+ lk_ksettings -> link_modes .supported );
1981
2007
bnxt_fw_to_ethtool_support_fec (link_info , lk_ksettings );
1982
2008
link_mode = bnxt_get_link_mode (link_info );
1983
2009
if (link_mode != BNXT_LINK_MODE_UNKNOWN )
@@ -1986,13 +2012,24 @@ static int bnxt_get_link_ksettings(struct net_device *dev,
1986
2012
bnxt_get_default_speeds (lk_ksettings , link_info );
1987
2013
1988
2014
if (link_info -> autoneg ) {
1989
- bnxt_fw_to_ethtool_advertised_spds (link_info , lk_ksettings );
1990
2015
bnxt_fw_to_ethtool_advertised_fec (link_info , lk_ksettings );
1991
2016
linkmode_set_bit (ETHTOOL_LINK_MODE_Autoneg_BIT ,
1992
2017
lk_ksettings -> link_modes .advertising );
1993
2018
base -> autoneg = AUTONEG_ENABLE ;
1994
- if (link_info -> phy_link_status == BNXT_LINK_LINK )
1995
- bnxt_fw_to_ethtool_lp_adv (link_info , lk_ksettings );
2019
+ bnxt_get_ethtool_speeds (link_info -> advertising ,
2020
+ media , BNXT_SIG_MODE_NRZ ,
2021
+ lk_ksettings -> link_modes .advertising );
2022
+ bnxt_get_ethtool_speeds (link_info -> advertising_pam4 ,
2023
+ media , BNXT_SIG_MODE_PAM4 ,
2024
+ lk_ksettings -> link_modes .advertising );
2025
+ if (link_info -> phy_link_status == BNXT_LINK_LINK ) {
2026
+ bnxt_get_ethtool_speeds (link_info -> lp_auto_link_speeds ,
2027
+ media , BNXT_SIG_MODE_NRZ ,
2028
+ lk_ksettings -> link_modes .lp_advertising );
2029
+ bnxt_get_ethtool_speeds (link_info -> lp_auto_pam4_link_speeds ,
2030
+ media , BNXT_SIG_MODE_PAM4 ,
2031
+ lk_ksettings -> link_modes .lp_advertising );
2032
+ }
1996
2033
} else {
1997
2034
base -> autoneg = AUTONEG_DISABLE ;
1998
2035
}
@@ -2156,12 +2193,8 @@ static int bnxt_set_link_ksettings(struct net_device *dev,
2156
2193
2157
2194
mutex_lock (& bp -> link_lock );
2158
2195
if (base -> autoneg == AUTONEG_ENABLE ) {
2159
- link_info -> advertising = 0 ;
2160
- link_info -> advertising_pam4 = 0 ;
2161
- BNXT_ETHTOOL_TO_FW_SPDS (link_info -> advertising , lk_ksettings ,
2162
- advertising );
2163
- BNXT_ETHTOOL_TO_FW_PAM4_SPDS (link_info -> advertising_pam4 ,
2164
- lk_ksettings , advertising );
2196
+ bnxt_set_ethtool_speeds (link_info ,
2197
+ lk_ksettings -> link_modes .advertising );
2165
2198
link_info -> autoneg |= BNXT_AUTONEG_SPEED ;
2166
2199
if (!link_info -> advertising && !link_info -> advertising_pam4 ) {
2167
2200
link_info -> advertising = link_info -> support_auto_speeds ;
0 commit comments