net/hns3: fix link status change from firmware
authorHuisong Li <lihuisong@huawei.com>
Wed, 3 Feb 2021 12:23:48 +0000 (20:23 +0800)
committerFerruh Yigit <ferruh.yigit@intel.com>
Thu, 4 Feb 2021 17:19:37 +0000 (18:19 +0100)
When the hardware link status changes, the firmware proactively
reports the link status change message, and then driver update
link status. This feature is lack of a switch to control in PF
driver. Otherwise, this feature does not take effect when the
kernel PF driver that supports the feature is not loaded.

Fixes: 109e4dd1bd7a ("net/hns3: get link state change through mailbox")
Cc: stable@dpdk.org
Signed-off-by: Huisong Li <lihuisong@huawei.com>
Signed-off-by: Lijun Ou <oulijun@huawei.com>
drivers/net/hns3/hns3_cmd.h
drivers/net/hns3/hns3_ethdev.c

index dc97a1a..ad5e188 100644 (file)
@@ -206,6 +206,9 @@ enum hns3_opcode_type {
        /* Clear hardware state command */
        HNS3_OPC_CLEAR_HW_STATE         = 0x700B,
 
+       /* Firmware stats command */
+       HNS3_OPC_FIRMWARE_COMPAT_CFG    = 0x701A,
+
        /* SFP command */
        HNS3_OPC_SFP_GET_SPEED          = 0x7104,
 
@@ -633,6 +636,13 @@ enum hns3_promisc_type {
        HNS3_BROADCAST  = 3,
 };
 
+#define HNS3_LINK_EVENT_REPORT_EN_B    0
+#define HNS3_NCSI_ERROR_REPORT_EN_B    1
+struct hns3_firmware_compat_cmd {
+       uint32_t compat;
+       uint8_t rsv[20];
+};
+
 #define HNS3_MAC_TX_EN_B               6
 #define HNS3_MAC_RX_EN_B               7
 #define HNS3_MAC_PAD_TX_B              11
index 8c57b63..f93870d 100644 (file)
@@ -3918,6 +3918,26 @@ hns3_buffer_alloc(struct hns3_hw *hw)
        return ret;
 }
 
+static int
+hns3_firmware_compat_config(struct hns3_hw *hw, bool is_init)
+{
+       struct hns3_firmware_compat_cmd *req;
+       struct hns3_cmd_desc desc;
+       uint32_t compat = 0;
+
+       hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_FIRMWARE_COMPAT_CFG, false);
+       req = (struct hns3_firmware_compat_cmd *)desc.data;
+
+       if (is_init) {
+               hns3_set_bit(compat, HNS3_LINK_EVENT_REPORT_EN_B, 1);
+               hns3_set_bit(compat, HNS3_NCSI_ERROR_REPORT_EN_B, 0);
+       }
+
+       req->compat = rte_cpu_to_le_32(compat);
+
+       return hns3_cmd_send(hw, &desc, 1);
+}
+
 static int
 hns3_mac_init(struct hns3_hw *hw)
 {
@@ -4610,6 +4630,15 @@ hns3_init_hardware(struct hns3_adapter *hns)
                goto err_mac_init;
        }
 
+       /*
+        * Requiring firmware to enable some features, driver can
+        * still work without it.
+        */
+       ret = hns3_firmware_compat_config(hw, true);
+       if (ret)
+               PMD_INIT_LOG(WARNING, "firmware compatible features not "
+                            "supported, ret = %d.", ret);
+
        return 0;
 
 err_mac_init:
@@ -4746,6 +4775,7 @@ hns3_init_pf(struct rte_eth_dev *eth_dev)
 err_enable_intr:
        hns3_fdir_filter_uninit(hns);
 err_fdir:
+       (void)hns3_firmware_compat_config(hw, false);
        hns3_uninit_umv_space(hw);
 err_init_hw:
        hns3_tqp_stats_uninit(hw);
@@ -4780,6 +4810,7 @@ hns3_uninit_pf(struct rte_eth_dev *eth_dev)
        (void)hns3_config_gro(hw, false);
        hns3_promisc_uninit(hw);
        hns3_fdir_filter_uninit(hns);
+       (void)hns3_firmware_compat_config(hw, false);
        hns3_uninit_umv_space(hw);
        hns3_tqp_stats_uninit(hw);
        hns3_pf_disable_irq0(hw);