Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

i40e: Error handling for link event

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>

authored by

Harshitha Ramamurthy and committed by
Jeff Kirsher
ae136708 5cb25901

+13 -2
+1
drivers/net/ethernet/intel/i40e/i40e.h
··· 349 349 #define I40E_FLAG_HAVE_CRT_RETIMER BIT_ULL(52) 350 350 #define I40E_FLAG_PTP_L4_CAPABLE BIT_ULL(53) 351 351 #define I40E_FLAG_WOL_MC_MAGIC_PKT_WAKE BIT_ULL(54) 352 + #define I40E_FLAG_TEMP_LINK_POLLING BIT_ULL(55) 352 353 353 354 /* tracks features that get auto disabled by errors */ 354 355 u64 auto_disable_flags;
+12 -2
drivers/net/ethernet/intel/i40e/i40e_main.c
··· 6353 6353 old_link = (pf->hw.phy.link_info_old.link_info & I40E_AQ_LINK_UP); 6354 6354 6355 6355 status = i40e_get_link_status(&pf->hw, &new_link); 6356 - if (status) { 6356 + 6357 + /* On success, disable temp link polling */ 6358 + if (status == I40E_SUCCESS) { 6359 + if (pf->flags & I40E_FLAG_TEMP_LINK_POLLING) 6360 + pf->flags &= ~I40E_FLAG_TEMP_LINK_POLLING; 6361 + } else { 6362 + /* Enable link polling temporarily until i40e_get_link_status 6363 + * returns I40E_SUCCESS 6364 + */ 6365 + pf->flags |= I40E_FLAG_TEMP_LINK_POLLING; 6357 6366 dev_dbg(&pf->pdev->dev, "couldn't get link state, status: %d\n", 6358 6367 status); 6359 6368 return; ··· 6414 6405 return; 6415 6406 pf->service_timer_previous = jiffies; 6416 6407 6417 - if (pf->flags & I40E_FLAG_LINK_POLLING_ENABLED) 6408 + if ((pf->flags & I40E_FLAG_LINK_POLLING_ENABLED) || 6409 + (pf->flags & I40E_FLAG_TEMP_LINK_POLLING)) 6418 6410 i40e_link_event(pf); 6419 6411 6420 6412 /* Update the stats for active netdevs so the network stack