i40e: Wrong 'Advertised FEC modes' after set FEC to AUTO
authorJaroslaw Gawin <jaroslawx.gawin@intel.com>
Fri, 20 Sep 2019 09:17:17 +0000 (02:17 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 31 Dec 2019 15:44:23 +0000 (16:44 +0100)
[ Upstream commit e42b7e9cefca9dd008cbafffca97285cf264f72d ]

Fix display of parameters "Configured FEC encodings:" and "Advertised
FEC modes:" in ethtool.  Implemented by setting proper FEC bits in
“advertising” bitmask of link_modes struct and “fec” bitmask in
ethtool_fecparam struct. Without this patch wrong FEC settings
can be shown.

Signed-off-by: Jaroslaw Gawin <jaroslawx.gawin@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/ethernet/intel/i40e/i40e_common.c
drivers/net/ethernet/intel/i40e/i40e_ethtool.c

index 7560f06..3160b5b 100644 (file)
@@ -2571,9 +2571,16 @@ noinline_for_stack i40e_status i40e_update_link_info(struct i40e_hw *hw)
                if (status)
                        return status;
 
-               hw->phy.link_info.req_fec_info =
-                       abilities.fec_cfg_curr_mod_ext_info &
-                       (I40E_AQ_REQUEST_FEC_KR | I40E_AQ_REQUEST_FEC_RS);
+               if (abilities.fec_cfg_curr_mod_ext_info &
+                   I40E_AQ_ENABLE_FEC_AUTO)
+                       hw->phy.link_info.req_fec_info =
+                               (I40E_AQ_REQUEST_FEC_KR |
+                                I40E_AQ_REQUEST_FEC_RS);
+               else
+                       hw->phy.link_info.req_fec_info =
+                               abilities.fec_cfg_curr_mod_ext_info &
+                               (I40E_AQ_REQUEST_FEC_KR |
+                                I40E_AQ_REQUEST_FEC_RS);
 
                memcpy(hw->phy.link_info.module_type, &abilities.module_type,
                       sizeof(hw->phy.link_info.module_type));
index 41e1240..b577e6a 100644 (file)
@@ -722,7 +722,14 @@ static void i40e_get_settings_link_up_fec(u8 req_fec_info,
        ethtool_link_ksettings_add_link_mode(ks, supported, FEC_RS);
        ethtool_link_ksettings_add_link_mode(ks, supported, FEC_BASER);
 
-       if (I40E_AQ_SET_FEC_REQUEST_RS & req_fec_info) {
+       if ((I40E_AQ_SET_FEC_REQUEST_RS & req_fec_info) &&
+           (I40E_AQ_SET_FEC_REQUEST_KR & req_fec_info)) {
+               ethtool_link_ksettings_add_link_mode(ks, advertising,
+                                                    FEC_NONE);
+               ethtool_link_ksettings_add_link_mode(ks, advertising,
+                                                    FEC_BASER);
+               ethtool_link_ksettings_add_link_mode(ks, advertising, FEC_RS);
+       } else if (I40E_AQ_SET_FEC_REQUEST_RS & req_fec_info) {
                ethtool_link_ksettings_add_link_mode(ks, advertising, FEC_RS);
        } else if (I40E_AQ_SET_FEC_REQUEST_KR & req_fec_info) {
                ethtool_link_ksettings_add_link_mode(ks, advertising,
@@ -730,12 +737,6 @@ static void i40e_get_settings_link_up_fec(u8 req_fec_info,
        } else {
                ethtool_link_ksettings_add_link_mode(ks, advertising,
                                                     FEC_NONE);
-               if (I40E_AQ_SET_FEC_AUTO & req_fec_info) {
-                       ethtool_link_ksettings_add_link_mode(ks, advertising,
-                                                            FEC_RS);
-                       ethtool_link_ksettings_add_link_mode(ks, advertising,
-                                                            FEC_BASER);
-               }
        }
 }
 
@@ -1437,6 +1438,7 @@ static int i40e_get_fec_param(struct net_device *netdev,
        struct i40e_hw *hw = &pf->hw;
        i40e_status status = 0;
        int err = 0;
+       u8 fec_cfg;
 
        /* Get the current phy config */
        memset(&abilities, 0, sizeof(abilities));
@@ -1448,18 +1450,16 @@ static int i40e_get_fec_param(struct net_device *netdev,
        }
 
        fecparam->fec = 0;
-       if (abilities.fec_cfg_curr_mod_ext_info & I40E_AQ_SET_FEC_AUTO)
+       fec_cfg = abilities.fec_cfg_curr_mod_ext_info;
+       if (fec_cfg & I40E_AQ_SET_FEC_AUTO)
                fecparam->fec |= ETHTOOL_FEC_AUTO;
-       if ((abilities.fec_cfg_curr_mod_ext_info &
-            I40E_AQ_SET_FEC_REQUEST_RS) ||
-           (abilities.fec_cfg_curr_mod_ext_info &
-            I40E_AQ_SET_FEC_ABILITY_RS))
+       else if (fec_cfg & (I40E_AQ_SET_FEC_REQUEST_RS |
+                I40E_AQ_SET_FEC_ABILITY_RS))
                fecparam->fec |= ETHTOOL_FEC_RS;
-       if ((abilities.fec_cfg_curr_mod_ext_info &
-            I40E_AQ_SET_FEC_REQUEST_KR) ||
-           (abilities.fec_cfg_curr_mod_ext_info & I40E_AQ_SET_FEC_ABILITY_KR))
+       else if (fec_cfg & (I40E_AQ_SET_FEC_REQUEST_KR |
+                I40E_AQ_SET_FEC_ABILITY_KR))
                fecparam->fec |= ETHTOOL_FEC_BASER;
-       if (abilities.fec_cfg_curr_mod_ext_info == 0)
+       if (fec_cfg == 0)
                fecparam->fec |= ETHTOOL_FEC_OFF;
 
        if (hw->phy.link_info.fec_info & I40E_AQ_CONFIG_FEC_KR_ENA)