]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
bnxt_en: Report FEC settings to ethtool.
authorMichael Chan <michael.chan@broadcom.com>
Sun, 27 Sep 2020 17:42:17 +0000 (13:42 -0400)
committerDavid S. Miller <davem@davemloft.net>
Sun, 27 Sep 2020 20:35:46 +0000 (13:35 -0700)
Implement .get_fecparam() method to report the configured and active FEC
settings.  Also report the supported and advertised FEC settings to
the .get_link_ksettings() method.

Reviewed-by: Vasundhara Volam <vasundhara-v.volam@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/broadcom/bnxt/bnxt.h
drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c

index a76ae6a68ca2cf45e19272ea68ef17ef35528136..ab3b36deaf6649e49c91e01d5c7de51e3aa9fad7 100644 (file)
@@ -8960,9 +8960,10 @@ static int bnxt_update_link(struct bnxt *bp, bool chng_link_state)
        }
 
        link_info->fec_cfg = PORT_PHY_QCFG_RESP_FEC_CFG_FEC_NONE_SUPPORTED;
-       if (bp->hwrm_spec_code >= 0x10504)
+       if (bp->hwrm_spec_code >= 0x10504) {
                link_info->fec_cfg = le16_to_cpu(resp->fec_cfg);
-
+               link_info->active_fec_sig_mode = resp->active_fec_signal_mode;
+       }
        /* TODO: need to add more logic to report VF link */
        if (chng_link_state) {
                if (link_info->phy_link_status == BNXT_LINK_LINK)
index fbbc30288fa643e809c6bff45c687e662295b269..8a4c842ad06dcdf71c39fb69395dacbca828b912 100644 (file)
@@ -1215,10 +1215,26 @@ struct bnxt_link_info {
        u16                     force_pam4_link_speed;
        u32                     preemphasis;
        u8                      module_status;
+       u8                      active_fec_sig_mode;
        u16                     fec_cfg;
+#define BNXT_FEC_NONE          PORT_PHY_QCFG_RESP_FEC_CFG_FEC_NONE_SUPPORTED
+#define BNXT_FEC_AUTONEG_CAP   PORT_PHY_QCFG_RESP_FEC_CFG_FEC_AUTONEG_SUPPORTED
 #define BNXT_FEC_AUTONEG       PORT_PHY_QCFG_RESP_FEC_CFG_FEC_AUTONEG_ENABLED
+#define BNXT_FEC_ENC_BASE_R_CAP        \
+       PORT_PHY_QCFG_RESP_FEC_CFG_FEC_CLAUSE74_SUPPORTED
 #define BNXT_FEC_ENC_BASE_R    PORT_PHY_QCFG_RESP_FEC_CFG_FEC_CLAUSE74_ENABLED
-#define BNXT_FEC_ENC_RS                PORT_PHY_QCFG_RESP_FEC_CFG_FEC_CLAUSE91_ENABLED
+#define BNXT_FEC_ENC_RS_CAP    \
+       PORT_PHY_QCFG_RESP_FEC_CFG_FEC_CLAUSE91_SUPPORTED
+#define BNXT_FEC_ENC_LLRS_CAP  \
+       (PORT_PHY_QCFG_RESP_FEC_CFG_FEC_RS272_1XN_SUPPORTED |   \
+        PORT_PHY_QCFG_RESP_FEC_CFG_FEC_RS272_IEEE_SUPPORTED)
+#define BNXT_FEC_ENC_RS                \
+       (PORT_PHY_QCFG_RESP_FEC_CFG_FEC_CLAUSE91_ENABLED |      \
+        PORT_PHY_QCFG_RESP_FEC_CFG_FEC_RS544_1XN_ENABLED |     \
+        PORT_PHY_QCFG_RESP_FEC_CFG_FEC_RS544_IEEE_ENABLED)
+#define BNXT_FEC_ENC_LLRS      \
+       (PORT_PHY_QCFG_RESP_FEC_CFG_FEC_RS272_1XN_ENABLED |     \
+        PORT_PHY_QCFG_RESP_FEC_CFG_FEC_RS272_IEEE_ENABLED)
 
        /* copy of requested setting from ethtool cmd */
        u8                      autoneg;
index 4fdb672a47a0e7576115f92561f43569a50c55e2..3dc5d084db350b2c2e28313b6ea168a9b463f7e0 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/ctype.h>
 #include <linux/stringify.h>
 #include <linux/ethtool.h>
+#include <linux/linkmode.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/etherdevice.h>
@@ -1533,6 +1534,27 @@ u32 _bnxt_fw_to_ethtool_adv_spds(u16 fw_speeds, u8 fw_pause)
                (fw_speeds) |= BNXT_LINK_PAM4_SPEED_MSK_200GB;          \
 }
 
+static void bnxt_fw_to_ethtool_advertised_fec(struct bnxt_link_info *link_info,
+                               struct ethtool_link_ksettings *lk_ksettings)
+{
+       u16 fec_cfg = link_info->fec_cfg;
+
+       if ((fec_cfg & BNXT_FEC_NONE) || !(fec_cfg & BNXT_FEC_AUTONEG)) {
+               linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_NONE_BIT,
+                                lk_ksettings->link_modes.advertising);
+               return;
+       }
+       if (fec_cfg & BNXT_FEC_ENC_BASE_R)
+               linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_BASER_BIT,
+                                lk_ksettings->link_modes.advertising);
+       if (fec_cfg & BNXT_FEC_ENC_RS)
+               linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_RS_BIT,
+                                lk_ksettings->link_modes.advertising);
+       if (fec_cfg & BNXT_FEC_ENC_LLRS)
+               linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_LLRS_BIT,
+                                lk_ksettings->link_modes.advertising);
+}
+
 static void bnxt_fw_to_ethtool_advertised_spds(struct bnxt_link_info *link_info,
                                struct ethtool_link_ksettings *lk_ksettings)
 {
@@ -1545,6 +1567,7 @@ static void bnxt_fw_to_ethtool_advertised_spds(struct bnxt_link_info *link_info,
        BNXT_FW_TO_ETHTOOL_SPDS(fw_speeds, fw_pause, lk_ksettings, advertising);
        fw_speeds = link_info->advertising_pam4;
        BNXT_FW_TO_ETHTOOL_PAM4_SPDS(fw_speeds, lk_ksettings, advertising);
+       bnxt_fw_to_ethtool_advertised_fec(link_info, lk_ksettings);
 }
 
 static 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,
        BNXT_FW_TO_ETHTOOL_PAM4_SPDS(fw_speeds, lk_ksettings, lp_advertising);
 }
 
+static void bnxt_fw_to_ethtool_support_fec(struct bnxt_link_info *link_info,
+                               struct ethtool_link_ksettings *lk_ksettings)
+{
+       u16 fec_cfg = link_info->fec_cfg;
+
+       if (fec_cfg & BNXT_FEC_NONE) {
+               linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_NONE_BIT,
+                                lk_ksettings->link_modes.supported);
+               return;
+       }
+       if (fec_cfg & BNXT_FEC_ENC_BASE_R_CAP)
+               linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_BASER_BIT,
+                                lk_ksettings->link_modes.supported);
+       if (fec_cfg & BNXT_FEC_ENC_RS_CAP)
+               linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_RS_BIT,
+                                lk_ksettings->link_modes.supported);
+       if (fec_cfg & BNXT_FEC_ENC_LLRS_CAP)
+               linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_LLRS_BIT,
+                                lk_ksettings->link_modes.supported);
+}
+
 static void bnxt_fw_to_ethtool_support_spds(struct bnxt_link_info *link_info,
                                struct ethtool_link_ksettings *lk_ksettings)
 {
@@ -1579,6 +1623,7 @@ static void bnxt_fw_to_ethtool_support_spds(struct bnxt_link_info *link_info,
            link_info->support_pam4_auto_speeds)
                ethtool_link_ksettings_add_link_mode(lk_ksettings, supported,
                                                     Autoneg);
+       bnxt_fw_to_ethtool_support_fec(link_info, lk_ksettings);
 }
 
 u32 bnxt_fw_to_ethtool_speed(u16 fw_link_speed)
@@ -1836,6 +1881,49 @@ set_setting_exit:
        return rc;
 }
 
+static int bnxt_get_fecparam(struct net_device *dev,
+                            struct ethtool_fecparam *fec)
+{
+       struct bnxt *bp = netdev_priv(dev);
+       struct bnxt_link_info *link_info;
+       u8 active_fec;
+       u16 fec_cfg;
+
+       link_info = &bp->link_info;
+       fec_cfg = link_info->fec_cfg;
+       active_fec = link_info->active_fec_sig_mode &
+                    PORT_PHY_QCFG_RESP_ACTIVE_FEC_MASK;
+       if (fec_cfg & BNXT_FEC_NONE) {
+               fec->fec = ETHTOOL_FEC_NONE;
+               fec->active_fec = ETHTOOL_FEC_NONE;
+               return 0;
+       }
+       if (fec_cfg & BNXT_FEC_AUTONEG)
+               fec->fec |= ETHTOOL_FEC_AUTO;
+       if (fec_cfg & BNXT_FEC_ENC_BASE_R)
+               fec->fec |= ETHTOOL_FEC_BASER;
+       if (fec_cfg & BNXT_FEC_ENC_RS)
+               fec->fec |= ETHTOOL_FEC_RS;
+       if (fec_cfg & BNXT_FEC_ENC_LLRS)
+               fec->fec |= ETHTOOL_FEC_LLRS;
+
+       switch (active_fec) {
+       case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_CLAUSE74_ACTIVE:
+               fec->active_fec |= ETHTOOL_FEC_BASER;
+               break;
+       case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_CLAUSE91_ACTIVE:
+       case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_RS544_1XN_ACTIVE:
+       case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_RS544_IEEE_ACTIVE:
+               fec->active_fec |= ETHTOOL_FEC_RS;
+               break;
+       case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_RS272_1XN_ACTIVE:
+       case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_RS272_IEEE_ACTIVE:
+               fec->active_fec |= ETHTOOL_FEC_LLRS;
+               break;
+       }
+       return 0;
+}
+
 static void bnxt_get_pauseparam(struct net_device *dev,
                                struct ethtool_pauseparam *epause)
 {
@@ -3741,6 +3829,7 @@ const struct ethtool_ops bnxt_ethtool_ops = {
                                     ETHTOOL_COALESCE_USE_ADAPTIVE_RX,
        .get_link_ksettings     = bnxt_get_link_ksettings,
        .set_link_ksettings     = bnxt_set_link_ksettings,
+       .get_fecparam           = bnxt_get_fecparam,
        .get_pause_stats        = bnxt_get_pause_stats,
        .get_pauseparam         = bnxt_get_pauseparam,
        .set_pauseparam         = bnxt_set_pauseparam,