net/hns3: fix rollback in PF init
[dpdk.git] / drivers / net / hns3 / hns3_mbx.c
index 597a2d1..97692ec 100644 (file)
@@ -1,5 +1,5 @@
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2018-2019 HiSilicon Limited.
+ * Copyright(c) 2018-2021 HiSilicon Limited.
  */
 
 #include <ethdev_driver.h>
@@ -40,36 +40,14 @@ hns3_resp_to_errno(uint16_t resp_code)
        return -EIO;
 }
 
-static void
-hns3_poll_all_sync_msg(void)
-{
-       struct rte_eth_dev *eth_dev;
-       struct hns3_adapter *adapter;
-       const char *name;
-       uint16_t port_id;
-
-       RTE_ETH_FOREACH_DEV(port_id) {
-               eth_dev = &rte_eth_devices[port_id];
-               name = eth_dev->device->driver->name;
-               if (strcmp(name, "net_hns3") && strcmp(name, "net_hns3_vf"))
-                       continue;
-               adapter = eth_dev->data->dev_private;
-               if (!adapter || adapter->hw.adapter_state == HNS3_NIC_CLOSED)
-                       continue;
-               /* Synchronous msg, the mbx_resp.req_msg_data is non-zero */
-               if (adapter->hw.mbx_resp.req_msg_data)
-                       hns3_dev_handle_mbx_msg(&adapter->hw);
-       }
-}
-
 static int
 hns3_get_mbx_resp(struct hns3_hw *hw, uint16_t code0, uint16_t code1,
                  uint8_t *resp_data, uint16_t resp_len)
 {
 #define HNS3_MAX_RETRY_MS      500
+#define HNS3_WAIT_RESP_US      100
        struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
        struct hns3_mbx_resp_status *mbx_resp;
-       bool in_irq = false;
        uint64_t now;
        uint64_t end;
 
@@ -96,26 +74,19 @@ hns3_get_mbx_resp(struct hns3_hw *hw, uint16_t code0, uint16_t code1,
                        return -EIO;
                }
 
-               /*
-                * The mbox response is running on the interrupt thread.
-                * Sending mbox in the interrupt thread cannot wait for the
-                * response, so polling the mbox response on the irq thread.
-                */
-               if (pthread_equal(hw->irq_thread_id, pthread_self())) {
-                       in_irq = true;
-                       hns3_poll_all_sync_msg();
-               } else {
-                       rte_delay_ms(HNS3_POLL_RESPONE_MS);
-               }
+               hns3_dev_handle_mbx_msg(hw);
+               rte_delay_us(HNS3_WAIT_RESP_US);
+
                now = get_timeofday_ms();
        }
        hw->mbx_resp.req_msg_data = 0;
        if (now >= end) {
                hw->mbx_resp.lost++;
                hns3_err(hw,
-                        "VF could not get mbx(%u,%u) head(%u) tail(%u) lost(%u) from PF in_irq:%d",
+                        "VF could not get mbx(%u,%u) head(%u) tail(%u) "
+                        "lost(%u) from PF",
                         code0, code1, hw->mbx_resp.head, hw->mbx_resp.tail,
-                        hw->mbx_resp.lost, in_irq);
+                        hw->mbx_resp.lost);
                return -ETIME;
        }
        rte_io_rmb();
@@ -171,6 +142,7 @@ hns3_send_mbx_msg(struct hns3_hw *hw, uint16_t code, uint16_t subcode,
                hw->mbx_resp.head++;
                ret = hns3_cmd_send(hw, &desc, 1);
                if (ret) {
+                       hw->mbx_resp.head--;
                        rte_spinlock_unlock(&hw->mbx_resp.lock);
                        hns3_err(hw, "VF failed(=%d) to send mbx message to PF",
                                 ret);
@@ -205,6 +177,7 @@ hns3_mbx_handler(struct hns3_hw *hw)
 {
        enum hns3_reset_level reset_level;
        uint8_t link_status, link_duplex;
+       uint8_t support_push_lsc;
        uint32_t link_speed;
        uint16_t *msg_q;
        uint8_t opcode;
@@ -224,6 +197,8 @@ hns3_mbx_handler(struct hns3_hw *hw)
                        link_duplex = (uint8_t)rte_le_to_cpu_16(msg_q[4]);
                        hns3vf_update_link_status(hw, link_status, link_speed,
                                                  link_duplex);
+                       support_push_lsc = (*(uint8_t *)&msg_q[5]) & 1u;
+                       hns3vf_update_push_lsc_cap(hw, support_push_lsc);
                        break;
                case HNS3_MBX_ASSERTING_RESET:
                        /* PF has asserted reset hence VF should go in pending
@@ -312,7 +287,7 @@ hns3_handle_link_change_event(struct hns3_hw *hw,
        if (!req->msg[LINK_STATUS_OFFSET])
                hns3_link_fail_parse(hw, req->msg[LINK_FAIL_CODE_OFFSET]);
 
-       hns3_update_link_status_and_event(hw);
+       hns3_update_linkstatus_and_event(hw, true);
 }
 
 static void
@@ -368,9 +343,13 @@ hns3_dev_handle_mbx_msg(struct hns3_hw *hw)
        uint8_t *temp;
        int i;
 
+       rte_spinlock_lock(&hw->cmq.crq.lock);
+
        while (!hns3_cmd_crq_empty(hw)) {
-               if (__atomic_load_n(&hw->reset.disable_cmd, __ATOMIC_RELAXED))
+               if (__atomic_load_n(&hw->reset.disable_cmd, __ATOMIC_RELAXED)) {
+                       rte_spinlock_unlock(&hw->cmq.crq.lock);
                        return;
+               }
 
                desc = &crq->desc[crq->next_to_use];
                req = (struct hns3_mbx_pf_to_vf_cmd *)desc->data;
@@ -441,4 +420,6 @@ hns3_dev_handle_mbx_msg(struct hns3_hw *hw)
 
        /* Write back CMDQ_RQ header pointer, IMP need this pointer */
        hns3_write_dev(hw, HNS3_CMDQ_RX_HEAD_REG, crq->next_to_use);
+
+       rte_spinlock_unlock(&hw->cmq.crq.lock);
 }