i40evf: Fix link up issue when queues are disabled
authorAvinash Dayanand <avinash.dayanand@intel.com>
Tue, 23 Jan 2018 16:50:55 +0000 (08:50 -0800)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Wed, 14 Feb 2018 17:43:21 +0000 (09:43 -0800)
One of the previous patch fixes the link up issue by ignoring it if
i40evf is not in __I40EVF_RUNNING state. However this doesn't fix the
race condition when queues are disabled esp for ADq on VF. Hence check
if all queues are enabled before starting all queues.

Signed-off-by: Avinash Dayanand <avinash.dayanand@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/i40evf/i40evf.h
drivers/net/ethernet/intel/i40evf/i40evf_main.c
drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c

index b6991e8014d89736ae92cc8f081954a07b4dbfc9..89ce2f9a0fbe655b1465374be1d95e449c9b610c 100644 (file)
@@ -240,6 +240,7 @@ struct i40evf_adapter {
 #define I40EVF_FLAG_ALLMULTI_ON                        BIT(14)
 #define I40EVF_FLAG_LEGACY_RX                  BIT(15)
 #define I40EVF_FLAG_REINIT_ITR_NEEDED          BIT(16)
+#define I40EVF_FLAG_QUEUES_DISABLED            BIT(17)
 /* duplicates for common code */
 #define I40E_FLAG_DCB_ENABLED                  0
 #define I40E_FLAG_RX_CSUM_ENABLED              I40EVF_FLAG_RX_CSUM_ENABLED
index 34fd6c553879ac074a4619226ce16af69e5a12df..0776b07477a23b08a32018371b3922c81ca89e3d 100644 (file)
@@ -1913,6 +1913,7 @@ continue_reset:
        i40evf_free_all_rx_resources(adapter);
        i40evf_free_all_tx_resources(adapter);
 
+       adapter->flags |= I40EVF_FLAG_QUEUES_DISABLED;
        /* kill and reinit the admin queue */
        i40evf_shutdown_adminq(hw);
        adapter->current_op = VIRTCHNL_OP_UNKNOWN;
index 0700f0afe2d3cd13f1c926a2dd09e0bcef0c5a7a..e8dcc31fcbf208cc37fd78065dc10a26a70c6de2 100644 (file)
@@ -1017,14 +1017,25 @@ void i40evf_virtchnl_completion(struct i40evf_adapter *adapter,
                        if (adapter->link_up == link_up)
                                break;
 
-                       /* If we get link up message and start queues before
-                        * our queues are configured it will trigger a TX hang.
-                        * In that case, just ignore the link status message,
-                        * we'll get another one after we enable queues and
-                        * actually prepared to send traffic.
-                        */
-                       if (link_up && adapter->state != __I40EVF_RUNNING)
-                               break;
+                       if (link_up) {
+                               /* If we get link up message and start queues
+                                * before our queues are configured it will
+                                * trigger a TX hang. In that case, just ignore
+                                * the link status message,we'll get another one
+                                * after we enable queues and actually prepared
+                                * to send traffic.
+                                */
+                               if (adapter->state != __I40EVF_RUNNING)
+                                       break;
+
+                               /* For ADq enabled VF, we reconfigure VSIs and
+                                * re-allocate queues. Hence wait till all
+                                * queues are enabled.
+                                */
+                               if (adapter->flags &
+                                   I40EVF_FLAG_QUEUES_DISABLED)
+                                       break;
+                       }
 
                        adapter->link_up = link_up;
                        if (link_up) {
@@ -1108,6 +1119,7 @@ void i40evf_virtchnl_completion(struct i40evf_adapter *adapter,
        case VIRTCHNL_OP_ENABLE_QUEUES:
                /* enable transmits */
                i40evf_irq_enable(adapter, true);
+               adapter->flags &= ~I40EVF_FLAG_QUEUES_DISABLED;
                break;
        case VIRTCHNL_OP_DISABLE_QUEUES:
                i40evf_free_all_tx_resources(adapter);