net/i40e: fix RSS key initialization
[dpdk.git] / drivers / net / i40e / i40e_ethdev.c
index 538aea4..7030eb1 100644 (file)
@@ -1728,9 +1728,6 @@ eth_i40e_dev_uninit(struct rte_eth_dev *dev)
        /* uninitialize pf host driver */
        i40e_pf_host_uninit(dev);
 
-       rte_free(dev->data->mac_addrs);
-       dev->data->mac_addrs = NULL;
-
        /* disable uio intr before callback unregister */
        rte_intr_disable(intr_handle);
 
@@ -1787,6 +1784,10 @@ i40e_dev_configure(struct rte_eth_dev *dev)
        ad->tx_simple_allowed = true;
        ad->tx_vec_allowed = true;
 
+       /* Only legacy filter API needs the following fdir config. So when the
+        * legacy filter API is deprecated, the following codes should also be
+        * removed.
+        */
        if (dev->data->dev_conf.fdir_conf.mode == RTE_FDIR_MODE_PERFECT) {
                ret = i40e_fdir_setup(pf);
                if (ret != I40E_SUCCESS) {
@@ -1844,7 +1845,11 @@ err_dcb:
        rte_free(pf->vmdq);
        pf->vmdq = NULL;
 err:
-       /* need to release fdir resource if exists */
+       /* Need to release fdir resource if exists.
+        * Only legacy filter API needs the following fdir config. So when the
+        * legacy filter API is deprecated, the following code should also be
+        * removed.
+        */
        i40e_fdir_teardown(pf);
        return ret;
 }
@@ -2482,6 +2487,11 @@ i40e_dev_close(struct rte_eth_dev *dev)
        i40e_pf_disable_irq0(hw);
        rte_intr_disable(intr_handle);
 
+       /*
+        * Only legacy filter API needs the following fdir config. So when the
+        * legacy filter API is deprecated, the following code should also be
+        * removed.
+        */
        i40e_fdir_teardown(pf);
 
        /* shutdown and destroy the HMC */
@@ -2574,6 +2584,10 @@ i40e_dev_promiscuous_disable(struct rte_eth_dev *dev)
        if (status != I40E_SUCCESS)
                PMD_DRV_LOG(ERR, "Failed to disable unicast promiscuous");
 
+       /* must remain in all_multicast mode */
+       if (dev->data->all_multicast == 1)
+               return;
+
        status = i40e_aq_set_vsi_multicast_promiscuous(hw, vsi->seid,
                                                        false, NULL);
        if (status != I40E_SUCCESS)
@@ -5358,7 +5372,7 @@ i40e_enable_pf_lb(struct i40e_pf *pf)
        int ret;
 
        /* Use the FW API if FW >= v5.0 */
-       if (hw->aq.fw_maj_ver < 5) {
+       if (hw->aq.fw_maj_ver < 5 && hw->mac.type != I40E_MAC_X722) {
                PMD_INIT_LOG(ERR, "FW < v5.0, cannot enable loopback");
                return;
        }
@@ -5629,7 +5643,7 @@ i40e_vsi_setup(struct i40e_pf *pf,
                ctxt.flags = I40E_AQ_VSI_TYPE_VF;
 
                /* Use the VEB configuration if FW >= v5.0 */
-               if (hw->aq.fw_maj_ver >= 5) {
+               if (hw->aq.fw_maj_ver >= 5 || hw->mac.type == I40E_MAC_X722) {
                        /* Configure switch ID */
                        ctxt.info.valid_sections |=
                        rte_cpu_to_le_16(I40E_AQ_VSI_PROP_SWITCH_VALID);
@@ -11595,6 +11609,32 @@ i40e_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)
        return 0;
 }
 
+/**
+ * This function is used to check if the register is valid.
+ * Below is the valid registers list for X722 only:
+ * 0x2b800--0x2bb00
+ * 0x38700--0x38a00
+ * 0x3d800--0x3db00
+ * 0x208e00--0x209000
+ * 0x20be00--0x20c000
+ * 0x263c00--0x264000
+ * 0x265c00--0x266000
+ */
+static inline int i40e_valid_regs(enum i40e_mac_type type, uint32_t reg_offset)
+{
+       if ((type != I40E_MAC_X722) &&
+           ((reg_offset >= 0x2b800 && reg_offset <= 0x2bb00) ||
+            (reg_offset >= 0x38700 && reg_offset <= 0x38a00) ||
+            (reg_offset >= 0x3d800 && reg_offset <= 0x3db00) ||
+            (reg_offset >= 0x208e00 && reg_offset <= 0x209000) ||
+            (reg_offset >= 0x20be00 && reg_offset <= 0x20c000) ||
+            (reg_offset >= 0x263c00 && reg_offset <= 0x264000) ||
+            (reg_offset >= 0x265c00 && reg_offset <= 0x266000)))
+               return 0;
+       else
+               return 1;
+}
+
 static int i40e_get_regs(struct rte_eth_dev *dev,
                         struct rte_dev_reg_info *regs)
 {
@@ -11636,8 +11676,11 @@ static int i40e_get_regs(struct rte_eth_dev *dev,
                                reg_offset = arr_idx * reg_info->stride1 +
                                        arr_idx2 * reg_info->stride2;
                                reg_offset += reg_info->base_addr;
-                               ptr_data[reg_offset >> 2] =
-                                       I40E_READ_REG(hw, reg_offset);
+                               if (!i40e_valid_regs(hw->mac.type, reg_offset))
+                                       ptr_data[reg_offset >> 2] = 0;
+                               else
+                                       ptr_data[reg_offset >> 2] =
+                                               I40E_READ_REG(hw, reg_offset);
                        }
        }
 
@@ -12538,16 +12581,19 @@ i40e_rss_conf_init(struct i40e_rte_flow_rss_conf *out,
        if (in->key_len > RTE_DIM(out->key) ||
            in->queue_num > RTE_DIM(out->queue))
                return -EINVAL;
+       if (!in->key && in->key_len)
+               return -EINVAL;
        out->conf = (struct rte_flow_action_rss){
                .func = in->func,
                .level = in->level,
                .types = in->types,
                .key_len = in->key_len,
                .queue_num = in->queue_num,
-               .key = memcpy(out->key, in->key, in->key_len),
                .queue = memcpy(out->queue, in->queue,
                                sizeof(*in->queue) * in->queue_num),
        };
+       if (in->key)
+               out->conf.key = memcpy(out->key, in->key, in->key_len);
        return 0;
 }