1111#include <linux/ctype.h>
1212#include <linux/stringify.h>
1313#include <linux/ethtool.h>
14+ #include <linux/linkmode.h>
1415#include <linux/interrupt.h>
1516#include <linux/pci.h>
1617#include <linux/etherdevice.h>
@@ -1533,6 +1534,27 @@ u32 _bnxt_fw_to_ethtool_adv_spds(u16 fw_speeds, u8 fw_pause)
15331534 (fw_speeds) |= BNXT_LINK_PAM4_SPEED_MSK_200GB; \
15341535}
15351536
1537+ static void bnxt_fw_to_ethtool_advertised_fec (struct bnxt_link_info * link_info ,
1538+ struct ethtool_link_ksettings * lk_ksettings )
1539+ {
1540+ u16 fec_cfg = link_info -> fec_cfg ;
1541+
1542+ if ((fec_cfg & BNXT_FEC_NONE ) || !(fec_cfg & BNXT_FEC_AUTONEG )) {
1543+ linkmode_set_bit (ETHTOOL_LINK_MODE_FEC_NONE_BIT ,
1544+ lk_ksettings -> link_modes .advertising );
1545+ return ;
1546+ }
1547+ if (fec_cfg & BNXT_FEC_ENC_BASE_R )
1548+ linkmode_set_bit (ETHTOOL_LINK_MODE_FEC_BASER_BIT ,
1549+ lk_ksettings -> link_modes .advertising );
1550+ if (fec_cfg & BNXT_FEC_ENC_RS )
1551+ linkmode_set_bit (ETHTOOL_LINK_MODE_FEC_RS_BIT ,
1552+ lk_ksettings -> link_modes .advertising );
1553+ if (fec_cfg & BNXT_FEC_ENC_LLRS )
1554+ linkmode_set_bit (ETHTOOL_LINK_MODE_FEC_LLRS_BIT ,
1555+ lk_ksettings -> link_modes .advertising );
1556+ }
1557+
15361558static void bnxt_fw_to_ethtool_advertised_spds (struct bnxt_link_info * link_info ,
15371559 struct ethtool_link_ksettings * lk_ksettings )
15381560{
@@ -1545,6 +1567,7 @@ static void bnxt_fw_to_ethtool_advertised_spds(struct bnxt_link_info *link_info,
15451567 BNXT_FW_TO_ETHTOOL_SPDS (fw_speeds , fw_pause , lk_ksettings , advertising );
15461568 fw_speeds = link_info -> advertising_pam4 ;
15471569 BNXT_FW_TO_ETHTOOL_PAM4_SPDS (fw_speeds , lk_ksettings , advertising );
1570+ bnxt_fw_to_ethtool_advertised_fec (link_info , lk_ksettings );
15481571}
15491572
15501573static void bnxt_fw_to_ethtool_lp_adv (struct bnxt_link_info * link_info ,
@@ -1562,6 +1585,27 @@ static void bnxt_fw_to_ethtool_lp_adv(struct bnxt_link_info *link_info,
15621585 BNXT_FW_TO_ETHTOOL_PAM4_SPDS (fw_speeds , lk_ksettings , lp_advertising );
15631586}
15641587
1588+ static void bnxt_fw_to_ethtool_support_fec (struct bnxt_link_info * link_info ,
1589+ struct ethtool_link_ksettings * lk_ksettings )
1590+ {
1591+ u16 fec_cfg = link_info -> fec_cfg ;
1592+
1593+ if (fec_cfg & BNXT_FEC_NONE ) {
1594+ linkmode_set_bit (ETHTOOL_LINK_MODE_FEC_NONE_BIT ,
1595+ lk_ksettings -> link_modes .supported );
1596+ return ;
1597+ }
1598+ if (fec_cfg & BNXT_FEC_ENC_BASE_R_CAP )
1599+ linkmode_set_bit (ETHTOOL_LINK_MODE_FEC_BASER_BIT ,
1600+ lk_ksettings -> link_modes .supported );
1601+ if (fec_cfg & BNXT_FEC_ENC_RS_CAP )
1602+ linkmode_set_bit (ETHTOOL_LINK_MODE_FEC_RS_BIT ,
1603+ lk_ksettings -> link_modes .supported );
1604+ if (fec_cfg & BNXT_FEC_ENC_LLRS_CAP )
1605+ linkmode_set_bit (ETHTOOL_LINK_MODE_FEC_LLRS_BIT ,
1606+ lk_ksettings -> link_modes .supported );
1607+ }
1608+
15651609static void bnxt_fw_to_ethtool_support_spds (struct bnxt_link_info * link_info ,
15661610 struct ethtool_link_ksettings * lk_ksettings )
15671611{
@@ -1579,6 +1623,7 @@ static void bnxt_fw_to_ethtool_support_spds(struct bnxt_link_info *link_info,
15791623 link_info -> support_pam4_auto_speeds )
15801624 ethtool_link_ksettings_add_link_mode (lk_ksettings , supported ,
15811625 Autoneg );
1626+ bnxt_fw_to_ethtool_support_fec (link_info , lk_ksettings );
15821627}
15831628
15841629u32 bnxt_fw_to_ethtool_speed (u16 fw_link_speed )
@@ -1836,6 +1881,49 @@ static int bnxt_set_link_ksettings(struct net_device *dev,
18361881 return rc ;
18371882}
18381883
1884+ static int bnxt_get_fecparam (struct net_device * dev ,
1885+ struct ethtool_fecparam * fec )
1886+ {
1887+ struct bnxt * bp = netdev_priv (dev );
1888+ struct bnxt_link_info * link_info ;
1889+ u8 active_fec ;
1890+ u16 fec_cfg ;
1891+
1892+ link_info = & bp -> link_info ;
1893+ fec_cfg = link_info -> fec_cfg ;
1894+ active_fec = link_info -> active_fec_sig_mode &
1895+ PORT_PHY_QCFG_RESP_ACTIVE_FEC_MASK ;
1896+ if (fec_cfg & BNXT_FEC_NONE ) {
1897+ fec -> fec = ETHTOOL_FEC_NONE ;
1898+ fec -> active_fec = ETHTOOL_FEC_NONE ;
1899+ return 0 ;
1900+ }
1901+ if (fec_cfg & BNXT_FEC_AUTONEG )
1902+ fec -> fec |= ETHTOOL_FEC_AUTO ;
1903+ if (fec_cfg & BNXT_FEC_ENC_BASE_R )
1904+ fec -> fec |= ETHTOOL_FEC_BASER ;
1905+ if (fec_cfg & BNXT_FEC_ENC_RS )
1906+ fec -> fec |= ETHTOOL_FEC_RS ;
1907+ if (fec_cfg & BNXT_FEC_ENC_LLRS )
1908+ fec -> fec |= ETHTOOL_FEC_LLRS ;
1909+
1910+ switch (active_fec ) {
1911+ case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_CLAUSE74_ACTIVE :
1912+ fec -> active_fec |= ETHTOOL_FEC_BASER ;
1913+ break ;
1914+ case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_CLAUSE91_ACTIVE :
1915+ case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_RS544_1XN_ACTIVE :
1916+ case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_RS544_IEEE_ACTIVE :
1917+ fec -> active_fec |= ETHTOOL_FEC_RS ;
1918+ break ;
1919+ case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_RS272_1XN_ACTIVE :
1920+ case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_RS272_IEEE_ACTIVE :
1921+ fec -> active_fec |= ETHTOOL_FEC_LLRS ;
1922+ break ;
1923+ }
1924+ return 0 ;
1925+ }
1926+
18391927static void bnxt_get_pauseparam (struct net_device * dev ,
18401928 struct ethtool_pauseparam * epause )
18411929{
@@ -3741,6 +3829,7 @@ const struct ethtool_ops bnxt_ethtool_ops = {
37413829 ETHTOOL_COALESCE_USE_ADAPTIVE_RX ,
37423830 .get_link_ksettings = bnxt_get_link_ksettings ,
37433831 .set_link_ksettings = bnxt_set_link_ksettings ,
3832+ .get_fecparam = bnxt_get_fecparam ,
37443833 .get_pause_stats = bnxt_get_pause_stats ,
37453834 .get_pauseparam = bnxt_get_pauseparam ,
37463835 .set_pauseparam = bnxt_set_pauseparam ,
0 commit comments