Skip to content

Commit

Permalink
i40e: Error handling for link event
Browse files Browse the repository at this point in the history
There exists an intermittent bug which causes the 'Link Detected'
field reported by the 'ethtool <iface>' command to be 'Yes' when
in fact, there is no link. This patch fixes the problem by
enabling temporary link polling when i40e_get_link_status returns
an error. This causes the driver to remember that an admin queue
command failed and polls, until the function returns with a success.

Change-Id: I64c69b008db4017b8729f3fc27b8f65c8fe2eaa0
Signed-off-by: Harshitha Ramamurthy <harshitha.ramamurthy@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
  • Loading branch information
Harshitha Ramamurthy authored and Jeff Kirsher committed Feb 19, 2017
1 parent 5cb2590 commit ae13670
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 2 deletions.
1 change: 1 addition & 0 deletions drivers/net/ethernet/intel/i40e/i40e.h
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,7 @@ struct i40e_pf {
#define I40E_FLAG_HAVE_CRT_RETIMER BIT_ULL(52)
#define I40E_FLAG_PTP_L4_CAPABLE BIT_ULL(53)
#define I40E_FLAG_WOL_MC_MAGIC_PKT_WAKE BIT_ULL(54)
#define I40E_FLAG_TEMP_LINK_POLLING BIT_ULL(55)

/* tracks features that get auto disabled by errors */
u64 auto_disable_flags;
Expand Down
14 changes: 12 additions & 2 deletions drivers/net/ethernet/intel/i40e/i40e_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -6353,7 +6353,16 @@ static void i40e_link_event(struct i40e_pf *pf)
old_link = (pf->hw.phy.link_info_old.link_info & I40E_AQ_LINK_UP);

status = i40e_get_link_status(&pf->hw, &new_link);
if (status) {

/* On success, disable temp link polling */
if (status == I40E_SUCCESS) {
if (pf->flags & I40E_FLAG_TEMP_LINK_POLLING)
pf->flags &= ~I40E_FLAG_TEMP_LINK_POLLING;
} else {
/* Enable link polling temporarily until i40e_get_link_status
* returns I40E_SUCCESS
*/
pf->flags |= I40E_FLAG_TEMP_LINK_POLLING;
dev_dbg(&pf->pdev->dev, "couldn't get link state, status: %d\n",
status);
return;
Expand Down Expand Up @@ -6405,7 +6414,8 @@ static void i40e_watchdog_subtask(struct i40e_pf *pf)
return;
pf->service_timer_previous = jiffies;

if (pf->flags & I40E_FLAG_LINK_POLLING_ENABLED)
if ((pf->flags & I40E_FLAG_LINK_POLLING_ENABLED) ||
(pf->flags & I40E_FLAG_TEMP_LINK_POLLING))
i40e_link_event(pf);

/* Update the stats for active netdevs so the network stack
Expand Down

0 comments on commit ae13670

Please sign in to comment.