doc: support IPsec Multi-buffer lib v0.54
[dpdk.git] / drivers / net / hns3 / hns3_ethdev.c
index bab4312..a09ac08 100644 (file)
@@ -607,16 +607,19 @@ hns3_vlan_offload_set(struct rte_eth_dev *dev, int mask)
        rxmode = &dev->data->dev_conf.rxmode;
        tmp_mask = (unsigned int)mask;
        if (tmp_mask & ETH_VLAN_FILTER_MASK) {
-               /* Enable or disable VLAN filter */
-               enable = rxmode->offloads & DEV_RX_OFFLOAD_VLAN_FILTER ?
-                   true : false;
+               /* ignore vlan filter configuration during promiscuous mode */
+               if (!dev->data->promiscuous) {
+                       /* Enable or disable VLAN filter */
+                       enable = rxmode->offloads & DEV_RX_OFFLOAD_VLAN_FILTER ?
+                                true : false;
 
-               ret = hns3_enable_vlan_filter(hns, enable);
-               if (ret) {
-                       rte_spinlock_unlock(&hw->lock);
-                       hns3_err(hw, "failed to %s rx filter, ret = %d",
-                                enable ? "enable" : "disable", ret);
-                       return ret;
+                       ret = hns3_enable_vlan_filter(hns, enable);
+                       if (ret) {
+                               rte_spinlock_unlock(&hw->lock);
+                               hns3_err(hw, "failed to %s rx filter, ret = %d",
+                                        enable ? "enable" : "disable", ret);
+                               return ret;
+                       }
                }
        }
 
@@ -1002,14 +1005,16 @@ hns3_restore_vlan_conf(struct hns3_adapter *hns)
        bool enable;
        int ret;
 
-       /* restore vlan filter states */
-       offloads = hw->data->dev_conf.rxmode.offloads;
-       enable = offloads & DEV_RX_OFFLOAD_VLAN_FILTER ? true : false;
-       ret = hns3_enable_vlan_filter(hns, enable);
-       if (ret) {
-               hns3_err(hw, "failed to restore vlan rx filter conf, ret = %d",
-                        ret);
-               return ret;
+       if (!hw->data->promiscuous) {
+               /* restore vlan filter states */
+               offloads = hw->data->dev_conf.rxmode.offloads;
+               enable = offloads & DEV_RX_OFFLOAD_VLAN_FILTER ? true : false;
+               ret = hns3_enable_vlan_filter(hns, enable);
+               if (ret) {
+                       hns3_err(hw, "failed to restore vlan rx filter conf, "
+                                "ret = %d", ret);
+                       return ret;
+               }
        }
 
        ret = hns3_set_vlan_rx_offload_cfg(hns, &pf->vtag_config.rx_vcfg);
@@ -1054,6 +1059,13 @@ hns3_dev_configure_vlan(struct rte_eth_dev *dev)
                return ret;
        }
 
+       /*
+        * If pvid config is not set in rte_eth_conf, driver needn't to set
+        * VLAN pvid related configuration to hardware.
+        */
+       if (txmode->pvid == 0 && txmode->hw_vlan_insert_pvid == 0)
+               return 0;
+
        /* Apply pvid setting */
        ret = hns3_vlan_pvid_set(dev, txmode->pvid,
                                 txmode->hw_vlan_insert_pvid);
@@ -2059,8 +2071,8 @@ hns3_configure_all_mc_mac_addr(struct hns3_adapter *hns, bool del)
                        err = ret;
                        rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
                                              addr);
-                       hns3_dbg(hw, "%s mc mac addr: %s failed",
-                                del ? "Remove" : "Restore", mac_str);
+                       hns3_dbg(hw, "%s mc mac addr: %s failed for pf: ret = %d",
+                                del ? "Remove" : "Restore", mac_str, ret);
                }
        }
        return err;
@@ -2224,7 +2236,8 @@ hns3_init_ring_with_vector(struct hns3_hw *hw)
         * Rx interrupt.
         */
        vec = hw->num_msi - 1; /* vector 0 for misc interrupt, not for queue */
-       hw->intr_tqps_num = vec - 1; /* the last interrupt is reserved */
+       /* vec - 1: the last interrupt is reserved */
+       hw->intr_tqps_num = vec > hw->tqps_num ? hw->tqps_num : vec - 1;
        for (i = 0; i < hw->intr_tqps_num; i++) {
                /*
                 * Set gap limiter and rate limiter configuration of queue's
@@ -2503,9 +2516,18 @@ hns3_fw_version_get(struct rte_eth_dev *eth_dev, char *fw_version,
 {
        struct hns3_adapter *hns = eth_dev->data->dev_private;
        struct hns3_hw *hw = &hns->hw;
+       uint32_t version = hw->fw_version;
        int ret;
 
-       ret = snprintf(fw_version, fw_size, "0x%08x", hw->fw_version);
+       ret = snprintf(fw_version, fw_size, "%lu.%lu.%lu.%lu",
+                      hns3_get_field(version, HNS3_FW_VERSION_BYTE3_M,
+                                     HNS3_FW_VERSION_BYTE3_S),
+                      hns3_get_field(version, HNS3_FW_VERSION_BYTE2_M,
+                                     HNS3_FW_VERSION_BYTE2_S),
+                      hns3_get_field(version, HNS3_FW_VERSION_BYTE1_M,
+                                     HNS3_FW_VERSION_BYTE1_S),
+                      hns3_get_field(version, HNS3_FW_VERSION_BYTE0_M,
+                                     HNS3_FW_VERSION_BYTE0_S));
        ret += 1; /* add the size of '\0' */
        if (fw_size < (uint32_t)ret)
                return ret;
@@ -2604,7 +2626,6 @@ hns3_query_pf_resource(struct hns3_hw *hw)
        struct hns3_pf *pf = &hns->pf;
        struct hns3_pf_res_cmd *req;
        struct hns3_cmd_desc desc;
-       uint16_t num_msi;
        int ret;
 
        hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_QUERY_PF_RSRC, true);
@@ -2636,9 +2657,9 @@ hns3_query_pf_resource(struct hns3_hw *hw)
 
        pf->dv_buf_size = roundup(pf->dv_buf_size, HNS3_BUF_SIZE_UNIT);
 
-       num_msi = hns3_get_field(rte_le_to_cpu_16(req->pf_intr_vector_number),
-                                HNS3_VEC_NUM_M, HNS3_VEC_NUM_S);
-       hw->num_msi = (num_msi > hw->tqps_num + 1) ? hw->tqps_num + 1 : num_msi;
+       hw->num_msi =
+           hns3_get_field(rte_le_to_cpu_16(req->pf_intr_vector_number),
+                          HNS3_VEC_NUM_M, HNS3_VEC_NUM_S);
 
        return 0;
 }
@@ -3830,16 +3851,43 @@ hns3_clear_all_vfs_promisc_mode(struct hns3_hw *hw)
 static int
 hns3_dev_promiscuous_enable(struct rte_eth_dev *dev)
 {
+       bool allmulti = dev->data->all_multicast ? true : false;
        struct hns3_adapter *hns = dev->data->dev_private;
        struct hns3_hw *hw = &hns->hw;
+       uint64_t offloads;
+       int err;
        int ret;
 
        rte_spinlock_lock(&hw->lock);
        ret = hns3_set_promisc_mode(hw, true, true);
-       rte_spinlock_unlock(&hw->lock);
-       if (ret)
-               hns3_err(hw, "Failed to enable promiscuous mode, ret = %d",
+       if (ret) {
+               rte_spinlock_unlock(&hw->lock);
+               hns3_err(hw, "failed to enable promiscuous mode, ret = %d",
                         ret);
+               return ret;
+       }
+
+       /*
+        * When promiscuous mode was enabled, disable the vlan filter to let
+        * all packets coming in in the receiving direction.
+        */
+       offloads = dev->data->dev_conf.rxmode.offloads;
+       if (offloads & DEV_RX_OFFLOAD_VLAN_FILTER) {
+               ret = hns3_enable_vlan_filter(hns, false);
+               if (ret) {
+                       hns3_err(hw, "failed to enable promiscuous mode due to "
+                                    "failure to disable vlan filter, ret = %d",
+                                ret);
+                       err = hns3_set_promisc_mode(hw, false, allmulti);
+                       if (err)
+                               hns3_err(hw, "failed to restore promiscuous "
+                                        "status after disable vlan filter "
+                                        "failed during enabling promiscuous "
+                                        "mode, ret = %d", ret);
+               }
+       }
+
+       rte_spinlock_unlock(&hw->lock);
 
        return ret;
 }
@@ -3850,15 +3898,36 @@ hns3_dev_promiscuous_disable(struct rte_eth_dev *dev)
        bool allmulti = dev->data->all_multicast ? true : false;
        struct hns3_adapter *hns = dev->data->dev_private;
        struct hns3_hw *hw = &hns->hw;
+       uint64_t offloads;
+       int err;
        int ret;
 
        /* If now in all_multicast mode, must remain in all_multicast mode. */
        rte_spinlock_lock(&hw->lock);
        ret = hns3_set_promisc_mode(hw, false, allmulti);
-       rte_spinlock_unlock(&hw->lock);
-       if (ret)
-               hns3_err(hw, "Failed to disable promiscuous mode, ret = %d",
+       if (ret) {
+               rte_spinlock_unlock(&hw->lock);
+               hns3_err(hw, "failed to disable promiscuous mode, ret = %d",
                         ret);
+               return ret;
+       }
+       /* when promiscuous mode was disabled, restore the vlan filter status */
+       offloads = dev->data->dev_conf.rxmode.offloads;
+       if (offloads & DEV_RX_OFFLOAD_VLAN_FILTER) {
+               ret = hns3_enable_vlan_filter(hns, true);
+               if (ret) {
+                       hns3_err(hw, "failed to disable promiscuous mode due to"
+                                " failure to restore vlan filter, ret = %d",
+                                ret);
+                       err = hns3_set_promisc_mode(hw, true, true);
+                       if (err)
+                               hns3_err(hw, "failed to restore promiscuous "
+                                        "status after enabling vlan filter "
+                                        "failed during disabling promiscuous "
+                                        "mode, ret = %d", ret);
+               }
+       }
+       rte_spinlock_unlock(&hw->lock);
 
        return ret;
 }
@@ -3877,7 +3946,7 @@ hns3_dev_allmulticast_enable(struct rte_eth_dev *dev)
        ret = hns3_set_promisc_mode(hw, false, true);
        rte_spinlock_unlock(&hw->lock);
        if (ret)
-               hns3_err(hw, "Failed to enable allmulticast mode, ret = %d",
+               hns3_err(hw, "failed to enable allmulticast mode, ret = %d",
                         ret);
 
        return ret;
@@ -3898,7 +3967,7 @@ hns3_dev_allmulticast_disable(struct rte_eth_dev *dev)
        ret = hns3_set_promisc_mode(hw, false, false);
        rte_spinlock_unlock(&hw->lock);
        if (ret)
-               hns3_err(hw, "Failed to disable allmulticast mode, ret =  %d",
+               hns3_err(hw, "failed to disable allmulticast mode, ret = %d",
                         ret);
 
        return ret;
@@ -3909,11 +3978,21 @@ hns3_dev_promisc_restore(struct hns3_adapter *hns)
 {
        struct hns3_hw *hw = &hns->hw;
        bool allmulti = hw->data->all_multicast ? true : false;
+       int ret;
 
-       if (hw->data->promiscuous)
-               return hns3_set_promisc_mode(hw, true, true);
+       if (hw->data->promiscuous) {
+               ret = hns3_set_promisc_mode(hw, true, true);
+               if (ret)
+                       hns3_err(hw, "failed to restore promiscuous mode, "
+                                "ret = %d", ret);
+               return ret;
+       }
 
-       return hns3_set_promisc_mode(hw, false, allmulti);
+       ret = hns3_set_promisc_mode(hw, false, allmulti);
+       if (ret)
+               hns3_err(hw, "failed to restore allmulticast mode, ret = %d",
+                        ret);
+       return ret;
 }
 
 static int
@@ -5254,9 +5333,21 @@ hns3_dev_init(struct rte_eth_dev *eth_dev)
        struct hns3_adapter *hns = eth_dev->data->dev_private;
        struct hns3_hw *hw = &hns->hw;
        uint16_t device_id = pci_dev->id.device_id;
+       uint8_t revision;
        int ret;
 
        PMD_INIT_FUNC_TRACE();
+
+       /* Get PCI revision id */
+       ret = rte_pci_read_config(pci_dev, &revision, HNS3_PCI_REVISION_ID_LEN,
+                                 HNS3_PCI_REVISION_ID);
+       if (ret != HNS3_PCI_REVISION_ID_LEN) {
+               PMD_INIT_LOG(ERR, "Failed to read pci revision id, ret = %d",
+                            ret);
+               return -EIO;
+       }
+       hw->revision = revision;
+
        eth_dev->process_private = (struct hns3_process_private *)
            rte_zmalloc_socket("hns3_filter_list",
                               sizeof(struct hns3_process_private),