Skip to content

Commit

Permalink
i40e: Check and correct speed values for link on open
Browse files Browse the repository at this point in the history
If our card has been put in an unstable state due to
other drivers interacting with it, speed settings
might be incorrect. If incorrect, forcefully reset them
on open to known default values.

Signed-off-by: Jan Sokolowski <jan.sokolowski@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
  • Loading branch information
Jan Sokolowski authored and Jeff Kirsher committed Aug 30, 2018
1 parent cdec214 commit e78d9a3
Showing 1 changed file with 24 additions and 3 deletions.
27 changes: 24 additions & 3 deletions drivers/net/ethernet/intel/i40e/i40e_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -6570,6 +6570,24 @@ static i40e_status i40e_force_link_state(struct i40e_pf *pf, bool is_up)
struct i40e_hw *hw = &pf->hw;
i40e_status err;
u64 mask;
u8 speed;

/* Card might've been put in an unstable state by other drivers
* and applications, which causes incorrect speed values being
* set on startup. In order to clear speed registers, we call
* get_phy_capabilities twice, once to get initial state of
* available speeds, and once to get current PHY config.
*/
err = i40e_aq_get_phy_capabilities(hw, false, true, &abilities,
NULL);
if (err) {
dev_err(&pf->pdev->dev,
"failed to get phy cap., ret = %s last_status = %s\n",
i40e_stat_str(hw, err),
i40e_aq_str(hw, hw->aq.asq_last_status));
return err;
}
speed = abilities.link_speed;

/* Get the current phy config */
err = i40e_aq_get_phy_capabilities(hw, false, false, &abilities,
Expand All @@ -6583,9 +6601,9 @@ static i40e_status i40e_force_link_state(struct i40e_pf *pf, bool is_up)
}

/* If link needs to go up, but was not forced to go down,
* no need for a flap
* and its speed values are OK, no need for a flap
*/
if (is_up && abilities.phy_type != 0)
if (is_up && abilities.phy_type != 0 && abilities.link_speed != 0)
return I40E_SUCCESS;

/* To force link we need to set bits for all supported PHY types,
Expand All @@ -6597,7 +6615,10 @@ static i40e_status i40e_force_link_state(struct i40e_pf *pf, bool is_up)
config.phy_type_ext = is_up ? (u8)((mask >> 32) & 0xff) : 0;
/* Copy the old settings, except of phy_type */
config.abilities = abilities.abilities;
config.link_speed = abilities.link_speed;
if (abilities.link_speed != 0)
config.link_speed = abilities.link_speed;
else
config.link_speed = speed;
config.eee_capability = abilities.eee_capability;
config.eeer = abilities.eeer_val;
config.low_power_ctrl = abilities.d3_lpan;
Expand Down

0 comments on commit e78d9a3

Please sign in to comment.