]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
i40e: Error handling for link event
authorHarshitha Ramamurthy <harshitha.ramamurthy@intel.com>
Mon, 12 Dec 2016 23:44:16 +0000 (15:44 -0800)
committerJack Vogel <jack.vogel@oracle.com>
Sat, 10 Jun 2017 01:57:02 +0000 (18:57 -0700)
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>
Orabug: 26132523
(cherry picked from commit ae13670824d5adadc95a881ebfaa6fa8735218f0)
Signed-off-by: Jack Vogel <jack.vogel@oracle.com>
Reviewed-by: Brian Maly <brian.maly@oracle.com>
drivers/net/ethernet/intel/i40e/i40e.h
drivers/net/ethernet/intel/i40e/i40e_main.c

index b858a825d2b6d954325a2825e0796ddaa4b4895b..c4603dc1004135d15d371672840a7a259699c68f 100644 (file)
@@ -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;
index f53d883b8b6d5a6188b3b98aede1f742659fee09..cde77b5c80b5308863f8dea2d583c619cc785b7a 100644 (file)
@@ -6308,7 +6308,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;
@@ -6360,7 +6369,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