net/i40e: fix flow director Rx resource defect
[dpdk.git] / drivers / net / i40e / i40e_ethdev.c
index c9551b0..ba9f8a9 100644 (file)
@@ -33,6 +33,7 @@
 #include "base/i40e_type.h"
 #include "base/i40e_register.h"
 #include "base/i40e_dcb.h"
+#include "base/i40e_diag.h"
 #include "i40e_ethdev.h"
 #include "i40e_rxtx.h"
 #include "i40e_pf.h"
@@ -1056,7 +1057,6 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
                return 0;
        }
        i40e_set_default_ptype_table(dev);
-       i40e_set_default_pctype_table(dev);
        pci_dev = RTE_ETH_DEV_TO_PCI(dev);
        intr_handle = &pci_dev->intr_handle;
 
@@ -1102,6 +1102,8 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
                return ret;
        }
 
+       i40e_set_default_pctype_table(dev);
+
        /*
         * To work around the NVM issue, initialize registers
         * for packet type of QinQ by software.
@@ -1312,6 +1314,10 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
        /* initialize queue region configuration */
        i40e_init_queue_region_conf(dev);
 
+       /* initialize rss configuration from rte_flow */
+       memset(&pf->rss_info, 0,
+               sizeof(struct i40e_rte_flow_rss_conf));
+
        return 0;
 
 err_init_fdir_filter_list:
@@ -1996,6 +2002,7 @@ i40e_dev_start(struct rte_eth_dev *dev)
 
        /* Enable all queues which have been configured */
        ret = i40e_dev_switch_queues(pf, TRUE);
+
        if (ret != I40E_SUCCESS) {
                PMD_DRV_LOG(ERR, "Failed to enable VSI");
                goto err_up;
@@ -2025,7 +2032,7 @@ i40e_dev_start(struct rte_eth_dev *dev)
        /* Enable mac loopback mode */
        if (dev->data->dev_conf.lpbk_mode == I40E_AQ_LB_MODE_NONE ||
            dev->data->dev_conf.lpbk_mode == I40E_AQ_LB_PHY_LOCAL) {
-               ret = i40e_aq_set_lb_modes(hw, dev->data->dev_conf.lpbk_mode, NULL);
+               ret = i40e_diag_set_loopback(hw, dev->data->dev_conf.lpbk_mode);
                if (ret != I40E_SUCCESS) {
                        PMD_DRV_LOG(ERR, "fail to set loopback link");
                        goto err_up;
@@ -2138,9 +2145,6 @@ i40e_dev_stop(struct rte_eth_dev *dev)
        /* reset hierarchy commit */
        pf->tm_conf.committed = false;
 
-       /* Remove all the queue region configuration */
-       i40e_flush_queue_region_all_conf(dev, hw, pf, 0);
-
        hw->adapter_stopped = 1;
 }
 
@@ -2518,6 +2522,22 @@ i40e_read_stats_registers(struct i40e_pf *pf, struct i40e_hw *hw)
                            pf->offset_loaded,
                            &pf->internal_stats_offset.rx_broadcast,
                            &pf->internal_stats.rx_broadcast);
+       /* Get total internal tx packet count */
+       i40e_stat_update_48(hw, I40E_GLV_UPTCH(hw->port),
+                           I40E_GLV_UPTCL(hw->port),
+                           pf->offset_loaded,
+                           &pf->internal_stats_offset.tx_unicast,
+                           &pf->internal_stats.tx_unicast);
+       i40e_stat_update_48(hw, I40E_GLV_MPTCH(hw->port),
+                           I40E_GLV_MPTCL(hw->port),
+                           pf->offset_loaded,
+                           &pf->internal_stats_offset.tx_multicast,
+                           &pf->internal_stats.tx_multicast);
+       i40e_stat_update_48(hw, I40E_GLV_BPTCH(hw->port),
+                           I40E_GLV_BPTCL(hw->port),
+                           pf->offset_loaded,
+                           &pf->internal_stats_offset.tx_broadcast,
+                           &pf->internal_stats.tx_broadcast);
 
        /* exclude CRC size */
        pf->internal_stats.rx_bytes -= (pf->internal_stats.rx_unicast +
@@ -2547,16 +2567,32 @@ i40e_read_stats_registers(struct i40e_pf *pf, struct i40e_hw *hw)
        ns->eth.rx_bytes -= (ns->eth.rx_unicast + ns->eth.rx_multicast +
                ns->eth.rx_broadcast) * ETHER_CRC_LEN;
 
-       /* Workaround: it is possible I40E_GLV_GORCH[H/L] is updated before
-        * I40E_GLPRT_GORCH[H/L], so there is a small window that cause negtive
+       /* exclude internal rx bytes
+        * Workaround: it is possible I40E_GLV_GORCH[H/L] is updated before
+        * I40E_GLPRT_GORCH[H/L], so there is a small window that cause negative
         * value.
+        * same to I40E_GLV_UPRC[H/L], I40E_GLV_MPRC[H/L], I40E_GLV_BPRC[H/L].
         */
        if (ns->eth.rx_bytes < pf->internal_stats.rx_bytes)
                ns->eth.rx_bytes = 0;
-       /* exlude internal rx bytes */
        else
                ns->eth.rx_bytes -= pf->internal_stats.rx_bytes;
 
+       if (ns->eth.rx_unicast < pf->internal_stats.rx_unicast)
+               ns->eth.rx_unicast = 0;
+       else
+               ns->eth.rx_unicast -= pf->internal_stats.rx_unicast;
+
+       if (ns->eth.rx_multicast < pf->internal_stats.rx_multicast)
+               ns->eth.rx_multicast = 0;
+       else
+               ns->eth.rx_multicast -= pf->internal_stats.rx_multicast;
+
+       if (ns->eth.rx_broadcast < pf->internal_stats.rx_broadcast)
+               ns->eth.rx_broadcast = 0;
+       else
+               ns->eth.rx_broadcast -= pf->internal_stats.rx_broadcast;
+
        i40e_stat_update_32(hw, I40E_GLPRT_RDPC(hw->port),
                            pf->offset_loaded, &os->eth.rx_discards,
                            &ns->eth.rx_discards);
@@ -2585,12 +2621,32 @@ i40e_read_stats_registers(struct i40e_pf *pf, struct i40e_hw *hw)
        ns->eth.tx_bytes -= (ns->eth.tx_unicast + ns->eth.tx_multicast +
                ns->eth.tx_broadcast) * ETHER_CRC_LEN;
 
-       /* exclude internal tx bytes */
+       /* exclude internal tx bytes
+        * Workaround: it is possible I40E_GLV_GOTCH[H/L] is updated before
+        * I40E_GLPRT_GOTCH[H/L], so there is a small window that cause negative
+        * value.
+        * same to I40E_GLV_UPTC[H/L], I40E_GLV_MPTC[H/L], I40E_GLV_BPTC[H/L].
+        */
        if (ns->eth.tx_bytes < pf->internal_stats.tx_bytes)
                ns->eth.tx_bytes = 0;
        else
                ns->eth.tx_bytes -= pf->internal_stats.tx_bytes;
 
+       if (ns->eth.tx_unicast < pf->internal_stats.tx_unicast)
+               ns->eth.tx_unicast = 0;
+       else
+               ns->eth.tx_unicast -= pf->internal_stats.tx_unicast;
+
+       if (ns->eth.tx_multicast < pf->internal_stats.tx_multicast)
+               ns->eth.tx_multicast = 0;
+       else
+               ns->eth.tx_multicast -= pf->internal_stats.tx_multicast;
+
+       if (ns->eth.tx_broadcast < pf->internal_stats.tx_broadcast)
+               ns->eth.tx_broadcast = 0;
+       else
+               ns->eth.tx_broadcast -= pf->internal_stats.tx_broadcast;
+
        /* GLPRT_TEPC not supported */
 
        /* additional port specific stats */
@@ -3665,6 +3721,7 @@ i40e_get_rss_lut(struct i40e_vsi *vsi, uint8_t *lut, uint16_t lut_size)
 {
        struct i40e_pf *pf = I40E_VSI_TO_PF(vsi);
        struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
+       uint32_t reg;
        int ret;
 
        if (!lut)
@@ -3681,14 +3738,22 @@ i40e_get_rss_lut(struct i40e_vsi *vsi, uint8_t *lut, uint16_t lut_size)
                uint32_t *lut_dw = (uint32_t *)lut;
                uint16_t i, lut_size_dw = lut_size / 4;
 
-               for (i = 0; i < lut_size_dw; i++)
-                       lut_dw[i] = I40E_READ_REG(hw, I40E_PFQF_HLUT(i));
+               if (vsi->type == I40E_VSI_SRIOV) {
+                       for (i = 0; i <= lut_size_dw; i++) {
+                               reg = I40E_VFQF_HLUT1(i, vsi->user_param);
+                               lut_dw[i] = i40e_read_rx_ctl(hw, reg);
+                       }
+               } else {
+                       for (i = 0; i < lut_size_dw; i++)
+                               lut_dw[i] = I40E_READ_REG(hw,
+                                                         I40E_PFQF_HLUT(i));
+               }
        }
 
        return 0;
 }
 
-static int
+int
 i40e_set_rss_lut(struct i40e_vsi *vsi, uint8_t *lut, uint16_t lut_size)
 {
        struct i40e_pf *pf;
@@ -3712,8 +3777,17 @@ i40e_set_rss_lut(struct i40e_vsi *vsi, uint8_t *lut, uint16_t lut_size)
                uint32_t *lut_dw = (uint32_t *)lut;
                uint16_t i, lut_size_dw = lut_size / 4;
 
-               for (i = 0; i < lut_size_dw; i++)
-                       I40E_WRITE_REG(hw, I40E_PFQF_HLUT(i), lut_dw[i]);
+               if (vsi->type == I40E_VSI_SRIOV) {
+                       for (i = 0; i < lut_size_dw; i++)
+                               I40E_WRITE_REG(
+                                       hw,
+                                       I40E_VFQF_HLUT1(i, vsi->user_param),
+                                       lut_dw[i]);
+               } else {
+                       for (i = 0; i < lut_size_dw; i++)
+                               I40E_WRITE_REG(hw, I40E_PFQF_HLUT(i),
+                                              lut_dw[i]);
+               }
                I40E_WRITE_FLUSH(hw);
        }
 
@@ -6048,7 +6122,7 @@ i40e_dev_handle_aq_msg(struct rte_eth_dev *dev)
                        ret = i40e_dev_link_update(dev, 0);
                        if (!ret)
                                _rte_eth_dev_callback_process(dev,
-                                       RTE_ETH_EVENT_INTR_LSC, NULL, NULL);
+                                       RTE_ETH_EVENT_INTR_LSC, NULL);
                        break;
                default:
                        PMD_DRV_LOG(DEBUG, "Request %u is not supported yet",
@@ -6750,17 +6824,20 @@ i40e_pf_disable_rss(struct i40e_pf *pf)
        I40E_WRITE_FLUSH(hw);
 }
 
-static int
+int
 i40e_set_rss_key(struct i40e_vsi *vsi, uint8_t *key, uint8_t key_len)
 {
        struct i40e_pf *pf = I40E_VSI_TO_PF(vsi);
        struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
+       uint16_t key_idx = (vsi->type == I40E_VSI_SRIOV) ?
+                          I40E_VFQF_HKEY_MAX_INDEX :
+                          I40E_PFQF_HKEY_MAX_INDEX;
        int ret = 0;
 
        if (!key || key_len == 0) {
                PMD_DRV_LOG(DEBUG, "No key to be configured");
                return 0;
-       } else if (key_len != (I40E_PFQF_HKEY_MAX_INDEX + 1) *
+       } else if (key_len != (key_idx + 1) *
                sizeof(uint32_t)) {
                PMD_DRV_LOG(ERR, "Invalid key length %u", key_len);
                return -EINVAL;
@@ -6777,8 +6854,18 @@ i40e_set_rss_key(struct i40e_vsi *vsi, uint8_t *key, uint8_t key_len)
                uint32_t *hash_key = (uint32_t *)key;
                uint16_t i;
 
-               for (i = 0; i <= I40E_PFQF_HKEY_MAX_INDEX; i++)
-                       i40e_write_rx_ctl(hw, I40E_PFQF_HKEY(i), hash_key[i]);
+               if (vsi->type == I40E_VSI_SRIOV) {
+                       for (i = 0; i <= I40E_VFQF_HKEY_MAX_INDEX; i++)
+                               I40E_WRITE_REG(
+                                       hw,
+                                       I40E_VFQF_HKEY1(i, vsi->user_param),
+                                       hash_key[i]);
+
+               } else {
+                       for (i = 0; i <= I40E_PFQF_HKEY_MAX_INDEX; i++)
+                               I40E_WRITE_REG(hw, I40E_PFQF_HKEY(i),
+                                              hash_key[i]);
+               }
                I40E_WRITE_FLUSH(hw);
        }
 
@@ -6790,6 +6877,7 @@ i40e_get_rss_key(struct i40e_vsi *vsi, uint8_t *key, uint8_t *key_len)
 {
        struct i40e_pf *pf = I40E_VSI_TO_PF(vsi);
        struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
+       uint32_t reg;
        int ret;
 
        if (!key || !key_len)
@@ -6806,11 +6894,22 @@ i40e_get_rss_key(struct i40e_vsi *vsi, uint8_t *key, uint8_t *key_len)
                uint32_t *key_dw = (uint32_t *)key;
                uint16_t i;
 
-               for (i = 0; i <= I40E_PFQF_HKEY_MAX_INDEX; i++)
-                       key_dw[i] = i40e_read_rx_ctl(hw, I40E_PFQF_HKEY(i));
+               if (vsi->type == I40E_VSI_SRIOV) {
+                       for (i = 0; i <= I40E_VFQF_HKEY_MAX_INDEX; i++) {
+                               reg = I40E_VFQF_HKEY1(i, vsi->user_param);
+                               key_dw[i] = i40e_read_rx_ctl(hw, reg);
+                       }
+                       *key_len = (I40E_VFQF_HKEY_MAX_INDEX + 1) *
+                                  sizeof(uint32_t);
+               } else {
+                       for (i = 0; i <= I40E_PFQF_HKEY_MAX_INDEX; i++) {
+                               reg = I40E_PFQF_HKEY(i);
+                               key_dw[i] = i40e_read_rx_ctl(hw, reg);
+                       }
+                       *key_len = (I40E_PFQF_HKEY_MAX_INDEX + 1) *
+                                  sizeof(uint32_t);
+               }
        }
-       *key_len = (I40E_PFQF_HKEY_MAX_INDEX + 1) * sizeof(uint32_t);
-
        return 0;
 }
 
@@ -8038,14 +8137,17 @@ i40e_get_hash_filter_global_config(struct i40e_hw *hw,
                (reg & I40E_GLQF_CTL_HTOEP_MASK) ? "Toeplitz" : "Simple XOR");
 
        /*
-        * We work only with lowest 32 bits which is not correct, but to work
-        * properly the valid_bit_mask size should be increased up to 64 bits
-        * and this will brake ABI. This modification will be done in next
-        * release
+        * As i40e supports less than 64 flow types, only first 64 bits need to
+        * be checked.
         */
-       g_cfg->valid_bit_mask[0] = (uint32_t)adapter->flow_types_mask;
+       for (i = 1; i < RTE_SYM_HASH_MASK_ARRAY_SIZE; i++) {
+               g_cfg->valid_bit_mask[i] = 0ULL;
+               g_cfg->sym_hash_enable_mask[i] = 0ULL;
+       }
+
+       g_cfg->valid_bit_mask[0] = adapter->flow_types_mask;
 
-       for (i = RTE_ETH_FLOW_UNKNOWN + 1; i < UINT32_BIT; i++) {
+       for (i = RTE_ETH_FLOW_UNKNOWN + 1; i < UINT64_BIT; i++) {
                if (!adapter->pctypes_tbl[i])
                        continue;
                for (j = I40E_FILTER_PCTYPE_INVALID + 1;
@@ -8054,7 +8156,7 @@ i40e_get_hash_filter_global_config(struct i40e_hw *hw,
                                reg = i40e_read_rx_ctl(hw, I40E_GLQF_HSYM(j));
                                if (reg & I40E_GLQF_HSYM_SYMH_ENA_MASK) {
                                        g_cfg->sym_hash_enable_mask[0] |=
-                                                               (1UL << i);
+                                                               (1ULL << i);
                                }
                        }
                }
@@ -8068,7 +8170,7 @@ i40e_hash_global_config_check(const struct i40e_adapter *adapter,
                              const struct rte_eth_hash_global_conf *g_cfg)
 {
        uint32_t i;
-       uint32_t mask0, i40e_mask = adapter->flow_types_mask;
+       uint64_t mask0, i40e_mask = adapter->flow_types_mask;
 
        if (g_cfg->hash_func != RTE_ETH_HASH_FUNCTION_TOEPLITZ &&
                g_cfg->hash_func != RTE_ETH_HASH_FUNCTION_SIMPLE_XOR &&
@@ -8079,7 +8181,7 @@ i40e_hash_global_config_check(const struct i40e_adapter *adapter,
        }
 
        /*
-        * As i40e supports less than 32 flow types, only first 32 bits need to
+        * As i40e supports less than 64 flow types, only first 64 bits need to
         * be checked.
         */
        mask0 = g_cfg->valid_bit_mask[0];
@@ -8115,23 +8217,20 @@ i40e_set_hash_filter_global_config(struct i40e_hw *hw,
        int ret;
        uint16_t i, j;
        uint32_t reg;
-       /*
-        * We work only with lowest 32 bits which is not correct, but to work
-        * properly the valid_bit_mask size should be increased up to 64 bits
-        * and this will brake ABI. This modification will be done in next
-        * release
-        */
-       uint32_t mask0 = g_cfg->valid_bit_mask[0] &
-                                       (uint32_t)adapter->flow_types_mask;
+       uint64_t mask0 = g_cfg->valid_bit_mask[0] & adapter->flow_types_mask;
 
        /* Check the input parameters */
        ret = i40e_hash_global_config_check(adapter, g_cfg);
        if (ret < 0)
                return ret;
 
-       for (i = RTE_ETH_FLOW_UNKNOWN + 1; mask0 && i < UINT32_BIT; i++) {
+       /*
+        * As i40e supports less than 64 flow types, only first 64 bits need to
+        * be configured.
+        */
+       for (i = RTE_ETH_FLOW_UNKNOWN + 1; mask0 && i < UINT64_BIT; i++) {
                if (mask0 & (1UL << i)) {
-                       reg = (g_cfg->sym_hash_enable_mask[0] & (1UL << i)) ?
+                       reg = (g_cfg->sym_hash_enable_mask[0] & (1ULL << i)) ?
                                        I40E_GLQF_HSYM_SYMH_ENA_MASK : 0;
 
                        for (j = I40E_FILTER_PCTYPE_INVALID + 1;
@@ -10872,14 +10971,43 @@ static void i40e_set_default_mac_addr(struct rte_eth_dev *dev,
                                      struct ether_addr *mac_addr)
 {
        struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+       struct i40e_vsi *vsi = pf->main_vsi;
+       struct i40e_mac_filter_info mac_filter;
+       struct i40e_mac_filter *f;
+       int ret;
 
        if (!is_valid_assigned_ether_addr(mac_addr)) {
                PMD_DRV_LOG(ERR, "Tried to set invalid MAC address.");
                return;
        }
 
-       /* Flags: 0x3 updates port address */
-       i40e_aq_mac_address_write(hw, 0x3, mac_addr->addr_bytes, NULL);
+       TAILQ_FOREACH(f, &vsi->mac_list, next) {
+               if (is_same_ether_addr(&pf->dev_addr, &f->mac_info.mac_addr))
+                       break;
+       }
+
+       if (f == NULL) {
+               PMD_DRV_LOG(ERR, "Failed to find filter for default mac");
+               return;
+       }
+
+       mac_filter = f->mac_info;
+       ret = i40e_vsi_delete_mac(vsi, &mac_filter.mac_addr);
+       if (ret != I40E_SUCCESS) {
+               PMD_DRV_LOG(ERR, "Failed to delete mac filter");
+               return;
+       }
+       memcpy(&mac_filter.mac_addr, mac_addr, ETH_ADDR_LEN);
+       ret = i40e_vsi_add_mac(vsi, &mac_filter);
+       if (ret != I40E_SUCCESS) {
+               PMD_DRV_LOG(ERR, "Failed to add mac filter");
+               return;
+       }
+       memcpy(&pf->dev_addr, mac_addr, ETH_ADDR_LEN);
+
+       i40e_aq_mac_address_write(hw, I40E_AQC_WRITE_TYPE_LAA_WOL,
+                                 mac_addr->addr_bytes, NULL);
 }
 
 static int
@@ -10997,12 +11125,23 @@ i40e_tunnel_filter_restore(struct i40e_pf *pf)
        }
 }
 
+/* Restore rss filter */
+static inline void
+i40e_rss_filter_restore(struct i40e_pf *pf)
+{
+       struct i40e_rte_flow_rss_conf *conf =
+                                       &pf->rss_info;
+       if (conf->num)
+               i40e_config_rss_filter(pf, conf, TRUE);
+}
+
 static void
 i40e_filter_restore(struct i40e_pf *pf)
 {
        i40e_ethertype_filter_restore(pf);
        i40e_tunnel_filter_restore(pf);
        i40e_fdir_filter_restore(pf);
+       i40e_rss_filter_restore(pf);
 }
 
 static bool
@@ -11457,6 +11596,82 @@ i40e_cloud_filter_qinq_create(struct i40e_pf *pf)
        return ret;
 }
 
+int
+i40e_config_rss_filter(struct i40e_pf *pf,
+               struct i40e_rte_flow_rss_conf *conf, bool add)
+{
+       struct i40e_hw *hw = I40E_PF_TO_HW(pf);
+       uint32_t i, lut = 0;
+       uint16_t j, num;
+       struct rte_eth_rss_conf rss_conf = conf->rss_conf;
+       struct i40e_rte_flow_rss_conf *rss_info = &pf->rss_info;
+
+       if (!add) {
+               if (memcmp(conf, rss_info,
+                       sizeof(struct i40e_rte_flow_rss_conf)) == 0) {
+                       i40e_pf_disable_rss(pf);
+                       memset(rss_info, 0,
+                               sizeof(struct i40e_rte_flow_rss_conf));
+                       return 0;
+               }
+               return -EINVAL;
+       }
+
+       if (rss_info->num)
+               return -EINVAL;
+
+       /* If both VMDQ and RSS enabled, not all of PF queues are configured.
+        * It's necessary to calculate the actual PF queues that are configured.
+        */
+       if (pf->dev_data->dev_conf.rxmode.mq_mode & ETH_MQ_RX_VMDQ_FLAG)
+               num = i40e_pf_calc_configured_queues_num(pf);
+       else
+               num = pf->dev_data->nb_rx_queues;
+
+       num = RTE_MIN(num, conf->num);
+       PMD_DRV_LOG(INFO, "Max of contiguous %u PF queues are configured",
+                       num);
+
+       if (num == 0) {
+               PMD_DRV_LOG(ERR, "No PF queues are configured to enable RSS");
+               return -ENOTSUP;
+       }
+
+       /* Fill in redirection table */
+       for (i = 0, j = 0; i < hw->func_caps.rss_table_size; i++, j++) {
+               if (j == num)
+                       j = 0;
+               lut = (lut << 8) | (conf->queue[j] & ((0x1 <<
+                       hw->func_caps.rss_table_entry_width) - 1));
+               if ((i & 3) == 3)
+                       I40E_WRITE_REG(hw, I40E_PFQF_HLUT(i >> 2), lut);
+       }
+
+       if ((rss_conf.rss_hf & pf->adapter->flow_types_mask) == 0) {
+               i40e_pf_disable_rss(pf);
+               return 0;
+       }
+       if (rss_conf.rss_key == NULL || rss_conf.rss_key_len <
+               (I40E_PFQF_HKEY_MAX_INDEX + 1) * sizeof(uint32_t)) {
+               /* Random default keys */
+               static uint32_t rss_key_default[] = {0x6b793944,
+                       0x23504cb5, 0x5bea75b6, 0x309f4f12, 0x3dc0a2b8,
+                       0x024ddcdf, 0x339b8ca0, 0x4c4af64a, 0x34fac605,
+                       0x55d85839, 0x3a58997d, 0x2ec938e1, 0x66031581};
+
+               rss_conf.rss_key = (uint8_t *)rss_key_default;
+               rss_conf.rss_key_len = (I40E_PFQF_HKEY_MAX_INDEX + 1) *
+                                                       sizeof(uint32_t);
+       }
+
+       return i40e_hw_rss_hash_set(pf, &rss_conf);
+
+       rte_memcpy(rss_info,
+               conf, sizeof(struct i40e_rte_flow_rss_conf));
+
+       return 0;
+}
+
 RTE_INIT(i40e_init_log);
 static void
 i40e_init_log(void)