New upstream version 17.11.5
[deb_dpdk.git] / drivers / net / sfc / sfc_rx.c
index 7816393..238aa5e 100644 (file)
@@ -814,7 +814,7 @@ sfc_rx_mbuf_data_alignment(struct rte_mempool *mb_pool)
 
        order = MIN(order, rte_bsf32(data_off));
 
-       return 1u << (order - 1);
+       return 1u << order;
 }
 
 static uint16_t
@@ -1028,6 +1028,7 @@ sfc_rx_qfini(struct sfc_adapter *sa, unsigned int sw_index)
        struct sfc_rxq *rxq;
 
        SFC_ASSERT(sw_index < sa->rxq_count);
+       sa->eth_dev->data->rx_queues[sw_index] = NULL;
 
        rxq_info = &sa->rxq_info[sw_index];
 
@@ -1095,6 +1096,41 @@ sfc_efx_to_rte_hash_type(efx_rx_hash_type_t efx_hash_types)
 #endif
 
 #if EFSYS_OPT_RX_SCALE
+static int
+sfc_rx_process_adv_conf_rss(struct sfc_adapter *sa,
+                           struct rte_eth_rss_conf *conf)
+{
+       efx_rx_hash_type_t efx_hash_types = sa->rss_hash_types;
+
+       if (sa->rss_support != EFX_RX_SCALE_EXCLUSIVE) {
+               if ((conf->rss_hf != 0 && conf->rss_hf != SFC_RSS_OFFLOADS) ||
+                   conf->rss_key != NULL)
+                       return EINVAL;
+       }
+
+       if (conf->rss_hf != 0) {
+               if ((conf->rss_hf & ~SFC_RSS_OFFLOADS) != 0) {
+                       sfc_err(sa, "unsupported hash functions requested");
+                       return EINVAL;
+               }
+
+               efx_hash_types = sfc_rte_to_efx_hash_type(conf->rss_hf);
+       }
+
+       if (conf->rss_key != NULL) {
+               if (conf->rss_key_len != sizeof(sa->rss_key)) {
+                       sfc_err(sa, "RSS key size is wrong (should be %lu)",
+                               sizeof(sa->rss_key));
+                       return EINVAL;
+               }
+               rte_memcpy(sa->rss_key, conf->rss_key, sizeof(sa->rss_key));
+       }
+
+       sa->rss_hash_types = efx_hash_types;
+
+       return 0;
+}
+
 static int
 sfc_rx_rss_config(struct sfc_adapter *sa)
 {
@@ -1305,7 +1341,7 @@ sfc_rx_configure(struct sfc_adapter *sa)
                goto fail_check_mode;
 
        if (nb_rx_queues == sa->rxq_count)
-               goto done;
+               goto configure_rss;
 
        if (sa->rxq_info == NULL) {
                rc = ENOMEM;
@@ -1342,21 +1378,28 @@ sfc_rx_configure(struct sfc_adapter *sa)
                sa->rxq_count++;
        }
 
+configure_rss:
 #if EFSYS_OPT_RX_SCALE
        sa->rss_channels = (dev_conf->rxmode.mq_mode == ETH_MQ_RX_RSS) ?
                           MIN(sa->rxq_count, EFX_MAXRSS) : 0;
 
        if (sa->rss_channels > 0) {
+               struct rte_eth_rss_conf *adv_conf_rss;
                unsigned int sw_index;
 
                for (sw_index = 0; sw_index < EFX_RSS_TBL_SIZE; ++sw_index)
                        sa->rss_tbl[sw_index] = sw_index % sa->rss_channels;
+
+               adv_conf_rss = &dev_conf->rx_adv_conf.rss_conf;
+               rc = sfc_rx_process_adv_conf_rss(sa, adv_conf_rss);
+               if (rc != 0)
+                       goto fail_rx_process_adv_conf_rss;
        }
 #endif
 
-done:
        return 0;
 
+fail_rx_process_adv_conf_rss:
 fail_rx_qinit_info:
 fail_rxqs_realloc:
 fail_rxqs_alloc: