From: Alan Brady <alan.br...@intel.com>

[ Upstream commit e0346f9fcb6c636d2f870e6666de8781413f34ea ]

If we receive the link status message from PF with link up before queues
are actually enabled, it will trigger a TX hang.  This fixes the issue
by ignoring a link up message if the VF state is not yet in RUNNING
state.

Signed-off-by: Alan Brady <alan.br...@intel.com>
Tested-by: Andrew Bowers <andrewx.bow...@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirs...@intel.com>
Signed-off-by: Sasha Levin <alexander.le...@microsoft.com>
---
 .../net/ethernet/intel/i40evf/i40evf_virtchnl.c    | 35 ++++++++++++++--------
 1 file changed, 23 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c 
b/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c
index 46c8b8a3907c..23635f5a2388 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c
@@ -965,23 +965,34 @@ void i40evf_virtchnl_completion(struct i40evf_adapter 
*adapter,
        if (v_opcode == VIRTCHNL_OP_EVENT) {
                struct virtchnl_pf_event *vpe =
                        (struct virtchnl_pf_event *)msg;
+               bool link_up = vpe->event_data.link_event.link_status;
                switch (vpe->event) {
                case VIRTCHNL_EVENT_LINK_CHANGE:
                        adapter->link_speed =
                                vpe->event_data.link_event.link_speed;
-                       if (adapter->link_up !=
-                           vpe->event_data.link_event.link_status) {
-                               adapter->link_up =
-                                       vpe->event_data.link_event.link_status;
-                               if (adapter->link_up) {
-                                       netif_tx_start_all_queues(netdev);
-                                       netif_carrier_on(netdev);
-                               } else {
-                                       netif_tx_stop_all_queues(netdev);
-                                       netif_carrier_off(netdev);
-                               }
-                               i40evf_print_link_message(adapter);
+
+                       /* we've already got the right link status, bail */
+                       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;
+
+                       adapter->link_up = link_up;
+                       if (link_up) {
+                               netif_tx_start_all_queues(netdev);
+                               netif_carrier_on(netdev);
+                       } else {
+                               netif_tx_stop_all_queues(netdev);
+                               netif_carrier_off(netdev);
                        }
+                       i40evf_print_link_message(adapter);
                        break;
                case VIRTCHNL_EVENT_RESET_IMPENDING:
                        dev_info(&adapter->pdev->dev, "PF reset warning 
received\n");
-- 
2.15.1

Reply via email to