xref: /dpdk/drivers/net/ena/ena_rss.c (revision e99981af34632ecce3bac82d05db97b08308f9b5)
134d5e97eSMichal Krawczyk /* SPDX-License-Identifier: BSD-3-Clause
234d5e97eSMichal Krawczyk  * Copyright (c) 2020 Amazon.com, Inc. or its affiliates.
334d5e97eSMichal Krawczyk  * All rights reserved.
434d5e97eSMichal Krawczyk  */
534d5e97eSMichal Krawczyk 
634d5e97eSMichal Krawczyk #include "ena_ethdev.h"
734d5e97eSMichal Krawczyk #include "ena_logs.h"
834d5e97eSMichal Krawczyk 
934d5e97eSMichal Krawczyk #include <ena_admin_defs.h>
1034d5e97eSMichal Krawczyk 
1134d5e97eSMichal Krawczyk #define TEST_BIT(val, bit_shift) ((val) & (1UL << (bit_shift)))
1234d5e97eSMichal Krawczyk 
1334d5e97eSMichal Krawczyk #define ENA_HF_RSS_ALL_L2	(ENA_ADMIN_RSS_L3_SA | ENA_ADMIN_RSS_L3_DA)
1434d5e97eSMichal Krawczyk #define ENA_HF_RSS_ALL_L3	(ENA_ADMIN_RSS_L3_SA | ENA_ADMIN_RSS_L3_DA)
1534d5e97eSMichal Krawczyk #define ENA_HF_RSS_ALL_L4	(ENA_ADMIN_RSS_L4_SP | ENA_ADMIN_RSS_L4_DP)
1634d5e97eSMichal Krawczyk #define ENA_HF_RSS_ALL_L3_L4	(ENA_HF_RSS_ALL_L3 | ENA_HF_RSS_ALL_L4)
1734d5e97eSMichal Krawczyk #define ENA_HF_RSS_ALL_L2_L3_L4	(ENA_HF_RSS_ALL_L2 | ENA_HF_RSS_ALL_L3_L4)
1834d5e97eSMichal Krawczyk 
1934d5e97eSMichal Krawczyk enum ena_rss_hash_fields {
2034d5e97eSMichal Krawczyk 	ENA_HF_RSS_TCP4		= ENA_HF_RSS_ALL_L3_L4,
2134d5e97eSMichal Krawczyk 	ENA_HF_RSS_UDP4		= ENA_HF_RSS_ALL_L3_L4,
2234d5e97eSMichal Krawczyk 	ENA_HF_RSS_TCP6		= ENA_HF_RSS_ALL_L3_L4,
2334d5e97eSMichal Krawczyk 	ENA_HF_RSS_UDP6		= ENA_HF_RSS_ALL_L3_L4,
2434d5e97eSMichal Krawczyk 	ENA_HF_RSS_IP4		= ENA_HF_RSS_ALL_L3,
2534d5e97eSMichal Krawczyk 	ENA_HF_RSS_IP6		= ENA_HF_RSS_ALL_L3,
2634d5e97eSMichal Krawczyk 	ENA_HF_RSS_IP4_FRAG	= ENA_HF_RSS_ALL_L3,
2734d5e97eSMichal Krawczyk 	ENA_HF_RSS_NOT_IP	= ENA_HF_RSS_ALL_L2,
2834d5e97eSMichal Krawczyk 	ENA_HF_RSS_TCP6_EX	= ENA_HF_RSS_ALL_L3_L4,
2934d5e97eSMichal Krawczyk 	ENA_HF_RSS_IP6_EX	= ENA_HF_RSS_ALL_L3,
3034d5e97eSMichal Krawczyk };
3134d5e97eSMichal Krawczyk 
3234d5e97eSMichal Krawczyk static int ena_fill_indirect_table_default(struct ena_com_dev *ena_dev,
3334d5e97eSMichal Krawczyk 					   size_t tbl_size,
3434d5e97eSMichal Krawczyk 					   size_t queue_num);
3534d5e97eSMichal Krawczyk static uint64_t ena_admin_hf_to_eth_hf(enum ena_admin_flow_hash_proto proto,
3634d5e97eSMichal Krawczyk 				       uint16_t field);
3734d5e97eSMichal Krawczyk static uint16_t ena_eth_hf_to_admin_hf(enum ena_admin_flow_hash_proto proto,
3834d5e97eSMichal Krawczyk 				       uint64_t rss_hf);
3934d5e97eSMichal Krawczyk static int ena_set_hash_fields(struct ena_com_dev *ena_dev, uint64_t rss_hf);
4034d5e97eSMichal Krawczyk static int ena_rss_hash_set(struct ena_com_dev *ena_dev,
4134d5e97eSMichal Krawczyk 			    struct rte_eth_rss_conf *rss_conf,
4234d5e97eSMichal Krawczyk 			    bool default_allowed);
4334d5e97eSMichal Krawczyk static void ena_reorder_rss_hash_key(uint8_t *reordered_key,
4434d5e97eSMichal Krawczyk 				     uint8_t *key,
4534d5e97eSMichal Krawczyk 				     size_t key_size);
4634d5e97eSMichal Krawczyk static int ena_get_rss_hash_key(struct ena_com_dev *ena_dev, uint8_t *rss_key);
4734d5e97eSMichal Krawczyk 
4834d5e97eSMichal Krawczyk void ena_rss_key_fill(void *key, size_t size)
4934d5e97eSMichal Krawczyk {
5034d5e97eSMichal Krawczyk 	static bool key_generated;
5134d5e97eSMichal Krawczyk 	static uint8_t default_key[ENA_HASH_KEY_SIZE];
5234d5e97eSMichal Krawczyk 	size_t i;
5334d5e97eSMichal Krawczyk 
5434d5e97eSMichal Krawczyk 	if (!key_generated) {
5524499495SDavid Marchand 		for (i = 0; i < RTE_DIM(default_key); ++i)
5634d5e97eSMichal Krawczyk 			default_key[i] = rte_rand() & 0xff;
5734d5e97eSMichal Krawczyk 		key_generated = true;
5834d5e97eSMichal Krawczyk 	}
5934d5e97eSMichal Krawczyk 
6024499495SDavid Marchand 	RTE_ASSERT(size <= sizeof(default_key));
6124499495SDavid Marchand 	rte_memcpy(key, default_key, RTE_MIN(size, sizeof(default_key)));
6234d5e97eSMichal Krawczyk }
6334d5e97eSMichal Krawczyk 
6434d5e97eSMichal Krawczyk int ena_rss_reta_update(struct rte_eth_dev *dev,
6534d5e97eSMichal Krawczyk 			struct rte_eth_rss_reta_entry64 *reta_conf,
6634d5e97eSMichal Krawczyk 			uint16_t reta_size)
6734d5e97eSMichal Krawczyk {
6834d5e97eSMichal Krawczyk 	struct ena_adapter *adapter = dev->data->dev_private;
6934d5e97eSMichal Krawczyk 	struct ena_com_dev *ena_dev = &adapter->ena_dev;
7034d5e97eSMichal Krawczyk 	int rc, i;
7134d5e97eSMichal Krawczyk 	u16 entry_value;
7234d5e97eSMichal Krawczyk 	int conf_idx;
7334d5e97eSMichal Krawczyk 	int idx;
7434d5e97eSMichal Krawczyk 
7534d5e97eSMichal Krawczyk 	if (reta_size == 0 || reta_conf == NULL)
7634d5e97eSMichal Krawczyk 		return -EINVAL;
7734d5e97eSMichal Krawczyk 
78295968d1SFerruh Yigit 	if (!(dev->data->dev_conf.rxmode.offloads & RTE_ETH_RX_OFFLOAD_RSS_HASH)) {
79*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR,
80*e99981afSDavid Marchand 			"RSS was not configured for the PMD");
8134d5e97eSMichal Krawczyk 		return -ENOTSUP;
8234d5e97eSMichal Krawczyk 	}
8334d5e97eSMichal Krawczyk 
8434d5e97eSMichal Krawczyk 	if (reta_size > ENA_RX_RSS_TABLE_SIZE) {
85*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(WARNING,
86*e99981afSDavid Marchand 			"Requested indirection table size (%d) is bigger than supported: %d",
8734d5e97eSMichal Krawczyk 			reta_size, ENA_RX_RSS_TABLE_SIZE);
8834d5e97eSMichal Krawczyk 		return -EINVAL;
8934d5e97eSMichal Krawczyk 	}
9034d5e97eSMichal Krawczyk 
91e3595539SStanislaw Kardach 	/* Prevent RETA table structure update races */
92e3595539SStanislaw Kardach 	rte_spinlock_lock(&adapter->admin_lock);
9334d5e97eSMichal Krawczyk 	for (i = 0 ; i < reta_size ; i++) {
9434d5e97eSMichal Krawczyk 		/* Each reta_conf is for 64 entries.
9534d5e97eSMichal Krawczyk 		 * To support 128 we use 2 conf of 64.
9634d5e97eSMichal Krawczyk 		 */
97295968d1SFerruh Yigit 		conf_idx = i / RTE_ETH_RETA_GROUP_SIZE;
98295968d1SFerruh Yigit 		idx = i % RTE_ETH_RETA_GROUP_SIZE;
9934d5e97eSMichal Krawczyk 		if (TEST_BIT(reta_conf[conf_idx].mask, idx)) {
10034d5e97eSMichal Krawczyk 			entry_value =
10134d5e97eSMichal Krawczyk 				ENA_IO_RXQ_IDX(reta_conf[conf_idx].reta[idx]);
10234d5e97eSMichal Krawczyk 
10334d5e97eSMichal Krawczyk 			rc = ena_com_indirect_table_fill_entry(ena_dev, i,
10434d5e97eSMichal Krawczyk 				entry_value);
10534d5e97eSMichal Krawczyk 			if (unlikely(rc != 0)) {
106*e99981afSDavid Marchand 				PMD_DRV_LOG_LINE(ERR,
107*e99981afSDavid Marchand 					"Cannot fill indirection table");
108195e0f24SDavid Marchand 				rte_spinlock_unlock(&adapter->admin_lock);
10934d5e97eSMichal Krawczyk 				return rc;
11034d5e97eSMichal Krawczyk 			}
11134d5e97eSMichal Krawczyk 		}
11234d5e97eSMichal Krawczyk 	}
11334d5e97eSMichal Krawczyk 
114e3595539SStanislaw Kardach 	rc = ena_mp_indirect_table_set(adapter);
11534d5e97eSMichal Krawczyk 	rte_spinlock_unlock(&adapter->admin_lock);
11634d5e97eSMichal Krawczyk 	if (unlikely(rc != 0)) {
117*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR, "Cannot set the indirection table");
11834d5e97eSMichal Krawczyk 		return rc;
11934d5e97eSMichal Krawczyk 	}
12034d5e97eSMichal Krawczyk 
121*e99981afSDavid Marchand 	PMD_DRV_LOG_LINE(DEBUG, "RSS configured %d entries for port %d",
12234d5e97eSMichal Krawczyk 		reta_size, dev->data->port_id);
12334d5e97eSMichal Krawczyk 
12434d5e97eSMichal Krawczyk 	return 0;
12534d5e97eSMichal Krawczyk }
12634d5e97eSMichal Krawczyk 
12734d5e97eSMichal Krawczyk /* Query redirection table. */
12834d5e97eSMichal Krawczyk int ena_rss_reta_query(struct rte_eth_dev *dev,
12934d5e97eSMichal Krawczyk 		       struct rte_eth_rss_reta_entry64 *reta_conf,
13034d5e97eSMichal Krawczyk 		       uint16_t reta_size)
13134d5e97eSMichal Krawczyk {
132e3595539SStanislaw Kardach 	uint32_t indirect_table[ENA_RX_RSS_TABLE_SIZE];
13334d5e97eSMichal Krawczyk 	struct ena_adapter *adapter = dev->data->dev_private;
13434d5e97eSMichal Krawczyk 	int rc;
13534d5e97eSMichal Krawczyk 	int i;
13634d5e97eSMichal Krawczyk 	int reta_conf_idx;
13734d5e97eSMichal Krawczyk 	int reta_idx;
13834d5e97eSMichal Krawczyk 
1397a4edfd7SFerruh Yigit 	if (reta_size == 0 || reta_conf == NULL)
14034d5e97eSMichal Krawczyk 		return -EINVAL;
14134d5e97eSMichal Krawczyk 
142295968d1SFerruh Yigit 	if (!(dev->data->dev_conf.rxmode.offloads & RTE_ETH_RX_OFFLOAD_RSS_HASH)) {
143*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR,
144*e99981afSDavid Marchand 			"RSS was not configured for the PMD");
14534d5e97eSMichal Krawczyk 		return -ENOTSUP;
14634d5e97eSMichal Krawczyk 	}
14734d5e97eSMichal Krawczyk 
14834d5e97eSMichal Krawczyk 	rte_spinlock_lock(&adapter->admin_lock);
149e3595539SStanislaw Kardach 	rc = ena_mp_indirect_table_get(adapter, indirect_table);
15034d5e97eSMichal Krawczyk 	rte_spinlock_unlock(&adapter->admin_lock);
15134d5e97eSMichal Krawczyk 	if (unlikely(rc != 0)) {
152*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR, "Cannot get indirection table");
15334d5e97eSMichal Krawczyk 		return rc;
15434d5e97eSMichal Krawczyk 	}
15534d5e97eSMichal Krawczyk 
15634d5e97eSMichal Krawczyk 	for (i = 0 ; i < reta_size ; i++) {
157295968d1SFerruh Yigit 		reta_conf_idx = i / RTE_ETH_RETA_GROUP_SIZE;
158295968d1SFerruh Yigit 		reta_idx = i % RTE_ETH_RETA_GROUP_SIZE;
15934d5e97eSMichal Krawczyk 		if (TEST_BIT(reta_conf[reta_conf_idx].mask, reta_idx))
16034d5e97eSMichal Krawczyk 			reta_conf[reta_conf_idx].reta[reta_idx] =
16134d5e97eSMichal Krawczyk 				ENA_IO_RXQ_IDX_REV(indirect_table[i]);
16234d5e97eSMichal Krawczyk 	}
16334d5e97eSMichal Krawczyk 
16434d5e97eSMichal Krawczyk 	return 0;
16534d5e97eSMichal Krawczyk }
16634d5e97eSMichal Krawczyk 
16734d5e97eSMichal Krawczyk static int ena_fill_indirect_table_default(struct ena_com_dev *ena_dev,
16834d5e97eSMichal Krawczyk 					   size_t tbl_size,
16934d5e97eSMichal Krawczyk 					   size_t queue_num)
17034d5e97eSMichal Krawczyk {
17134d5e97eSMichal Krawczyk 	size_t i;
17234d5e97eSMichal Krawczyk 	int rc;
17334d5e97eSMichal Krawczyk 	uint16_t val;
17434d5e97eSMichal Krawczyk 
17534d5e97eSMichal Krawczyk 	for (i = 0; i < tbl_size; ++i) {
17634d5e97eSMichal Krawczyk 		val = i % queue_num;
17734d5e97eSMichal Krawczyk 		rc = ena_com_indirect_table_fill_entry(ena_dev, i,
17834d5e97eSMichal Krawczyk 			ENA_IO_RXQ_IDX(val));
17934d5e97eSMichal Krawczyk 		if (unlikely(rc != 0)) {
180*e99981afSDavid Marchand 			PMD_DRV_LOG_LINE(DEBUG,
181*e99981afSDavid Marchand 				"Failed to set %zu indirection table entry with val %" PRIu16 "",
18234d5e97eSMichal Krawczyk 				i, val);
18334d5e97eSMichal Krawczyk 			return rc;
18434d5e97eSMichal Krawczyk 		}
18534d5e97eSMichal Krawczyk 	}
18634d5e97eSMichal Krawczyk 
18734d5e97eSMichal Krawczyk 	return 0;
18834d5e97eSMichal Krawczyk }
18934d5e97eSMichal Krawczyk 
19034d5e97eSMichal Krawczyk static uint64_t ena_admin_hf_to_eth_hf(enum ena_admin_flow_hash_proto proto,
19134d5e97eSMichal Krawczyk 				       uint16_t fields)
19234d5e97eSMichal Krawczyk {
19334d5e97eSMichal Krawczyk 	uint64_t rss_hf = 0;
19434d5e97eSMichal Krawczyk 
19534d5e97eSMichal Krawczyk 	/* If no fields are activated, then RSS is disabled for this proto */
19634d5e97eSMichal Krawczyk 	if ((fields & ENA_HF_RSS_ALL_L2_L3_L4) == 0)
19734d5e97eSMichal Krawczyk 		return 0;
19834d5e97eSMichal Krawczyk 
19934d5e97eSMichal Krawczyk 	/* Convert proto to ETH flag */
20034d5e97eSMichal Krawczyk 	switch (proto) {
20134d5e97eSMichal Krawczyk 	case ENA_ADMIN_RSS_TCP4:
202295968d1SFerruh Yigit 		rss_hf |= RTE_ETH_RSS_NONFRAG_IPV4_TCP;
20334d5e97eSMichal Krawczyk 		break;
20434d5e97eSMichal Krawczyk 	case ENA_ADMIN_RSS_UDP4:
205295968d1SFerruh Yigit 		rss_hf |= RTE_ETH_RSS_NONFRAG_IPV4_UDP;
20634d5e97eSMichal Krawczyk 		break;
20734d5e97eSMichal Krawczyk 	case ENA_ADMIN_RSS_TCP6:
208295968d1SFerruh Yigit 		rss_hf |= RTE_ETH_RSS_NONFRAG_IPV6_TCP;
20934d5e97eSMichal Krawczyk 		break;
21034d5e97eSMichal Krawczyk 	case ENA_ADMIN_RSS_UDP6:
211295968d1SFerruh Yigit 		rss_hf |= RTE_ETH_RSS_NONFRAG_IPV6_UDP;
21234d5e97eSMichal Krawczyk 		break;
21334d5e97eSMichal Krawczyk 	case ENA_ADMIN_RSS_IP4:
214295968d1SFerruh Yigit 		rss_hf |= RTE_ETH_RSS_IPV4;
21534d5e97eSMichal Krawczyk 		break;
21634d5e97eSMichal Krawczyk 	case ENA_ADMIN_RSS_IP6:
217295968d1SFerruh Yigit 		rss_hf |= RTE_ETH_RSS_IPV6;
21834d5e97eSMichal Krawczyk 		break;
21934d5e97eSMichal Krawczyk 	case ENA_ADMIN_RSS_IP4_FRAG:
220295968d1SFerruh Yigit 		rss_hf |= RTE_ETH_RSS_FRAG_IPV4;
22134d5e97eSMichal Krawczyk 		break;
22234d5e97eSMichal Krawczyk 	case ENA_ADMIN_RSS_NOT_IP:
223295968d1SFerruh Yigit 		rss_hf |= RTE_ETH_RSS_L2_PAYLOAD;
22434d5e97eSMichal Krawczyk 		break;
22534d5e97eSMichal Krawczyk 	case ENA_ADMIN_RSS_TCP6_EX:
226295968d1SFerruh Yigit 		rss_hf |= RTE_ETH_RSS_IPV6_TCP_EX;
22734d5e97eSMichal Krawczyk 		break;
22834d5e97eSMichal Krawczyk 	case ENA_ADMIN_RSS_IP6_EX:
229295968d1SFerruh Yigit 		rss_hf |= RTE_ETH_RSS_IPV6_EX;
23034d5e97eSMichal Krawczyk 		break;
23134d5e97eSMichal Krawczyk 	default:
23234d5e97eSMichal Krawczyk 		break;
23334d5e97eSMichal Krawczyk 	};
23434d5e97eSMichal Krawczyk 
23534d5e97eSMichal Krawczyk 	/* Check if only DA or SA is being used for L3. */
23634d5e97eSMichal Krawczyk 	switch (fields & ENA_HF_RSS_ALL_L3) {
23734d5e97eSMichal Krawczyk 	case ENA_ADMIN_RSS_L3_SA:
238295968d1SFerruh Yigit 		rss_hf |= RTE_ETH_RSS_L3_SRC_ONLY;
23934d5e97eSMichal Krawczyk 		break;
24034d5e97eSMichal Krawczyk 	case ENA_ADMIN_RSS_L3_DA:
241295968d1SFerruh Yigit 		rss_hf |= RTE_ETH_RSS_L3_DST_ONLY;
24234d5e97eSMichal Krawczyk 		break;
24334d5e97eSMichal Krawczyk 	default:
24434d5e97eSMichal Krawczyk 		break;
24534d5e97eSMichal Krawczyk 	};
24634d5e97eSMichal Krawczyk 
24734d5e97eSMichal Krawczyk 	/* Check if only DA or SA is being used for L4. */
24834d5e97eSMichal Krawczyk 	switch (fields & ENA_HF_RSS_ALL_L4) {
24934d5e97eSMichal Krawczyk 	case ENA_ADMIN_RSS_L4_SP:
250295968d1SFerruh Yigit 		rss_hf |= RTE_ETH_RSS_L4_SRC_ONLY;
25134d5e97eSMichal Krawczyk 		break;
25234d5e97eSMichal Krawczyk 	case ENA_ADMIN_RSS_L4_DP:
253295968d1SFerruh Yigit 		rss_hf |= RTE_ETH_RSS_L4_DST_ONLY;
25434d5e97eSMichal Krawczyk 		break;
25534d5e97eSMichal Krawczyk 	default:
25634d5e97eSMichal Krawczyk 		break;
25734d5e97eSMichal Krawczyk 	};
25834d5e97eSMichal Krawczyk 
25934d5e97eSMichal Krawczyk 	return rss_hf;
26034d5e97eSMichal Krawczyk }
26134d5e97eSMichal Krawczyk 
26234d5e97eSMichal Krawczyk static uint16_t ena_eth_hf_to_admin_hf(enum ena_admin_flow_hash_proto proto,
26334d5e97eSMichal Krawczyk 				       uint64_t rss_hf)
26434d5e97eSMichal Krawczyk {
26534d5e97eSMichal Krawczyk 	uint16_t fields_mask = 0;
26634d5e97eSMichal Krawczyk 
26734d5e97eSMichal Krawczyk 	/* L2 always uses source and destination addresses. */
26834d5e97eSMichal Krawczyk 	fields_mask = ENA_ADMIN_RSS_L2_DA | ENA_ADMIN_RSS_L2_SA;
26934d5e97eSMichal Krawczyk 
27034d5e97eSMichal Krawczyk 	/* Determine which fields of L3 should be used. */
271295968d1SFerruh Yigit 	switch (rss_hf & (RTE_ETH_RSS_L3_SRC_ONLY | RTE_ETH_RSS_L3_DST_ONLY)) {
272295968d1SFerruh Yigit 	case RTE_ETH_RSS_L3_DST_ONLY:
27334d5e97eSMichal Krawczyk 		fields_mask |= ENA_ADMIN_RSS_L3_DA;
27434d5e97eSMichal Krawczyk 		break;
275295968d1SFerruh Yigit 	case RTE_ETH_RSS_L3_SRC_ONLY:
27634d5e97eSMichal Krawczyk 		fields_mask |= ENA_ADMIN_RSS_L3_SA;
27734d5e97eSMichal Krawczyk 		break;
27834d5e97eSMichal Krawczyk 	default:
27934d5e97eSMichal Krawczyk 		/*
28034d5e97eSMichal Krawczyk 		 * If SRC nor DST aren't set, it means both of them should be
28134d5e97eSMichal Krawczyk 		 * used.
28234d5e97eSMichal Krawczyk 		 */
28334d5e97eSMichal Krawczyk 		fields_mask |= ENA_HF_RSS_ALL_L3;
28434d5e97eSMichal Krawczyk 	}
28534d5e97eSMichal Krawczyk 
28634d5e97eSMichal Krawczyk 	/* Determine which fields of L4 should be used. */
287295968d1SFerruh Yigit 	switch (rss_hf & (RTE_ETH_RSS_L4_SRC_ONLY | RTE_ETH_RSS_L4_DST_ONLY)) {
288295968d1SFerruh Yigit 	case RTE_ETH_RSS_L4_DST_ONLY:
28934d5e97eSMichal Krawczyk 		fields_mask |= ENA_ADMIN_RSS_L4_DP;
29034d5e97eSMichal Krawczyk 		break;
291295968d1SFerruh Yigit 	case RTE_ETH_RSS_L4_SRC_ONLY:
29234d5e97eSMichal Krawczyk 		fields_mask |= ENA_ADMIN_RSS_L4_SP;
29334d5e97eSMichal Krawczyk 		break;
29434d5e97eSMichal Krawczyk 	default:
29534d5e97eSMichal Krawczyk 		/*
29634d5e97eSMichal Krawczyk 		 * If SRC nor DST aren't set, it means both of them should be
29734d5e97eSMichal Krawczyk 		 * used.
29834d5e97eSMichal Krawczyk 		 */
29934d5e97eSMichal Krawczyk 		fields_mask |= ENA_HF_RSS_ALL_L4;
30034d5e97eSMichal Krawczyk 	}
30134d5e97eSMichal Krawczyk 
30234d5e97eSMichal Krawczyk 	/* Return appropriate hash fields. */
30334d5e97eSMichal Krawczyk 	switch (proto) {
30434d5e97eSMichal Krawczyk 	case ENA_ADMIN_RSS_TCP4:
30534d5e97eSMichal Krawczyk 		return ENA_HF_RSS_TCP4 & fields_mask;
30634d5e97eSMichal Krawczyk 	case ENA_ADMIN_RSS_UDP4:
30734d5e97eSMichal Krawczyk 		return ENA_HF_RSS_UDP4 & fields_mask;
30834d5e97eSMichal Krawczyk 	case ENA_ADMIN_RSS_TCP6:
30934d5e97eSMichal Krawczyk 		return ENA_HF_RSS_TCP6 & fields_mask;
31034d5e97eSMichal Krawczyk 	case ENA_ADMIN_RSS_UDP6:
31134d5e97eSMichal Krawczyk 		return ENA_HF_RSS_UDP6 & fields_mask;
31234d5e97eSMichal Krawczyk 	case ENA_ADMIN_RSS_IP4:
31334d5e97eSMichal Krawczyk 		return ENA_HF_RSS_IP4 & fields_mask;
31434d5e97eSMichal Krawczyk 	case ENA_ADMIN_RSS_IP6:
31534d5e97eSMichal Krawczyk 		return ENA_HF_RSS_IP6 & fields_mask;
31634d5e97eSMichal Krawczyk 	case ENA_ADMIN_RSS_IP4_FRAG:
31734d5e97eSMichal Krawczyk 		return ENA_HF_RSS_IP4_FRAG & fields_mask;
31834d5e97eSMichal Krawczyk 	case ENA_ADMIN_RSS_NOT_IP:
31934d5e97eSMichal Krawczyk 		return ENA_HF_RSS_NOT_IP & fields_mask;
32034d5e97eSMichal Krawczyk 	case ENA_ADMIN_RSS_TCP6_EX:
32134d5e97eSMichal Krawczyk 		return ENA_HF_RSS_TCP6_EX & fields_mask;
32234d5e97eSMichal Krawczyk 	case ENA_ADMIN_RSS_IP6_EX:
32334d5e97eSMichal Krawczyk 		return ENA_HF_RSS_IP6_EX & fields_mask;
32434d5e97eSMichal Krawczyk 	default:
32534d5e97eSMichal Krawczyk 		break;
32634d5e97eSMichal Krawczyk 	}
32734d5e97eSMichal Krawczyk 
32834d5e97eSMichal Krawczyk 	return 0;
32934d5e97eSMichal Krawczyk }
33034d5e97eSMichal Krawczyk 
33134d5e97eSMichal Krawczyk static int ena_set_hash_fields(struct ena_com_dev *ena_dev, uint64_t rss_hf)
33234d5e97eSMichal Krawczyk {
33334d5e97eSMichal Krawczyk 	struct ena_admin_proto_input selected_fields[ENA_ADMIN_RSS_PROTO_NUM] = {};
33434d5e97eSMichal Krawczyk 	int rc, i;
33534d5e97eSMichal Krawczyk 
33634d5e97eSMichal Krawczyk 	/* Turn on appropriate fields for each requested packet type */
337295968d1SFerruh Yigit 	if ((rss_hf & RTE_ETH_RSS_NONFRAG_IPV4_TCP) != 0)
33834d5e97eSMichal Krawczyk 		selected_fields[ENA_ADMIN_RSS_TCP4].fields =
33934d5e97eSMichal Krawczyk 			ena_eth_hf_to_admin_hf(ENA_ADMIN_RSS_TCP4, rss_hf);
34034d5e97eSMichal Krawczyk 
341295968d1SFerruh Yigit 	if ((rss_hf & RTE_ETH_RSS_NONFRAG_IPV4_UDP) != 0)
34234d5e97eSMichal Krawczyk 		selected_fields[ENA_ADMIN_RSS_UDP4].fields =
34334d5e97eSMichal Krawczyk 			ena_eth_hf_to_admin_hf(ENA_ADMIN_RSS_UDP4, rss_hf);
34434d5e97eSMichal Krawczyk 
345295968d1SFerruh Yigit 	if ((rss_hf & RTE_ETH_RSS_NONFRAG_IPV6_TCP) != 0)
34634d5e97eSMichal Krawczyk 		selected_fields[ENA_ADMIN_RSS_TCP6].fields =
34734d5e97eSMichal Krawczyk 			ena_eth_hf_to_admin_hf(ENA_ADMIN_RSS_TCP6, rss_hf);
34834d5e97eSMichal Krawczyk 
349295968d1SFerruh Yigit 	if ((rss_hf & RTE_ETH_RSS_NONFRAG_IPV6_UDP) != 0)
35034d5e97eSMichal Krawczyk 		selected_fields[ENA_ADMIN_RSS_UDP6].fields =
35134d5e97eSMichal Krawczyk 			ena_eth_hf_to_admin_hf(ENA_ADMIN_RSS_UDP6, rss_hf);
35234d5e97eSMichal Krawczyk 
353295968d1SFerruh Yigit 	if ((rss_hf & RTE_ETH_RSS_IPV4) != 0)
35434d5e97eSMichal Krawczyk 		selected_fields[ENA_ADMIN_RSS_IP4].fields =
35534d5e97eSMichal Krawczyk 			ena_eth_hf_to_admin_hf(ENA_ADMIN_RSS_IP4, rss_hf);
35634d5e97eSMichal Krawczyk 
357295968d1SFerruh Yigit 	if ((rss_hf & RTE_ETH_RSS_IPV6) != 0)
35834d5e97eSMichal Krawczyk 		selected_fields[ENA_ADMIN_RSS_IP6].fields =
35934d5e97eSMichal Krawczyk 			ena_eth_hf_to_admin_hf(ENA_ADMIN_RSS_IP6, rss_hf);
36034d5e97eSMichal Krawczyk 
361295968d1SFerruh Yigit 	if ((rss_hf & RTE_ETH_RSS_FRAG_IPV4) != 0)
36234d5e97eSMichal Krawczyk 		selected_fields[ENA_ADMIN_RSS_IP4_FRAG].fields =
36334d5e97eSMichal Krawczyk 			ena_eth_hf_to_admin_hf(ENA_ADMIN_RSS_IP4_FRAG, rss_hf);
36434d5e97eSMichal Krawczyk 
365295968d1SFerruh Yigit 	if ((rss_hf & RTE_ETH_RSS_L2_PAYLOAD) != 0)
36634d5e97eSMichal Krawczyk 		selected_fields[ENA_ADMIN_RSS_NOT_IP].fields =
36734d5e97eSMichal Krawczyk 			ena_eth_hf_to_admin_hf(ENA_ADMIN_RSS_NOT_IP, rss_hf);
36834d5e97eSMichal Krawczyk 
369295968d1SFerruh Yigit 	if ((rss_hf & RTE_ETH_RSS_IPV6_TCP_EX) != 0)
37034d5e97eSMichal Krawczyk 		selected_fields[ENA_ADMIN_RSS_TCP6_EX].fields =
37134d5e97eSMichal Krawczyk 			ena_eth_hf_to_admin_hf(ENA_ADMIN_RSS_TCP6_EX, rss_hf);
37234d5e97eSMichal Krawczyk 
373295968d1SFerruh Yigit 	if ((rss_hf & RTE_ETH_RSS_IPV6_EX) != 0)
37434d5e97eSMichal Krawczyk 		selected_fields[ENA_ADMIN_RSS_IP6_EX].fields =
37534d5e97eSMichal Krawczyk 			ena_eth_hf_to_admin_hf(ENA_ADMIN_RSS_IP6_EX, rss_hf);
37634d5e97eSMichal Krawczyk 
37734d5e97eSMichal Krawczyk 	/* Try to write them to the device */
37834d5e97eSMichal Krawczyk 	for (i = 0; i < ENA_ADMIN_RSS_PROTO_NUM; i++) {
37934d5e97eSMichal Krawczyk 		rc = ena_com_fill_hash_ctrl(ena_dev,
38034d5e97eSMichal Krawczyk 			(enum ena_admin_flow_hash_proto)i,
38134d5e97eSMichal Krawczyk 			selected_fields[i].fields);
38234d5e97eSMichal Krawczyk 		if (unlikely(rc != 0)) {
383*e99981afSDavid Marchand 			PMD_DRV_LOG_LINE(DEBUG,
384*e99981afSDavid Marchand 				"Failed to set ENA HF %d with fields %" PRIu16 "",
38534d5e97eSMichal Krawczyk 				i, selected_fields[i].fields);
38634d5e97eSMichal Krawczyk 			return rc;
38734d5e97eSMichal Krawczyk 		}
38834d5e97eSMichal Krawczyk 	}
38934d5e97eSMichal Krawczyk 
39034d5e97eSMichal Krawczyk 	return 0;
39134d5e97eSMichal Krawczyk }
39234d5e97eSMichal Krawczyk 
39334d5e97eSMichal Krawczyk static int ena_rss_hash_set(struct ena_com_dev *ena_dev,
39434d5e97eSMichal Krawczyk 			    struct rte_eth_rss_conf *rss_conf,
39534d5e97eSMichal Krawczyk 			    bool default_allowed)
39634d5e97eSMichal Krawczyk {
39734d5e97eSMichal Krawczyk 	uint8_t hw_rss_key[ENA_HASH_KEY_SIZE];
39834d5e97eSMichal Krawczyk 	uint8_t *rss_key;
39934d5e97eSMichal Krawczyk 	int rc;
40034d5e97eSMichal Krawczyk 
40134d5e97eSMichal Krawczyk 	if (rss_conf->rss_key != NULL) {
40234d5e97eSMichal Krawczyk 		/* Reorder the RSS key bytes for the hardware requirements. */
40334d5e97eSMichal Krawczyk 		ena_reorder_rss_hash_key(hw_rss_key, rss_conf->rss_key,
40434d5e97eSMichal Krawczyk 			ENA_HASH_KEY_SIZE);
40534d5e97eSMichal Krawczyk 		rss_key = hw_rss_key;
40634d5e97eSMichal Krawczyk 	} else {
40734d5e97eSMichal Krawczyk 		rss_key = NULL;
40834d5e97eSMichal Krawczyk 	}
40934d5e97eSMichal Krawczyk 
41034d5e97eSMichal Krawczyk 	/* If the rss_key is NULL, then the randomized key will be used. */
41134d5e97eSMichal Krawczyk 	rc = ena_com_fill_hash_function(ena_dev, ENA_ADMIN_TOEPLITZ,
41234d5e97eSMichal Krawczyk 		rss_key, ENA_HASH_KEY_SIZE, 0);
41334d5e97eSMichal Krawczyk 	if (rc != 0 && !(default_allowed && rc == ENA_COM_UNSUPPORTED)) {
414*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR,
415*e99981afSDavid Marchand 			"Failed to set RSS hash function in the device");
41634d5e97eSMichal Krawczyk 		return rc;
41734d5e97eSMichal Krawczyk 	}
41834d5e97eSMichal Krawczyk 
41934d5e97eSMichal Krawczyk 	rc = ena_set_hash_fields(ena_dev, rss_conf->rss_hf);
42034d5e97eSMichal Krawczyk 	if (rc == ENA_COM_UNSUPPORTED) {
42134d5e97eSMichal Krawczyk 		if (rss_conf->rss_key == NULL && !default_allowed) {
422*e99981afSDavid Marchand 			PMD_DRV_LOG_LINE(ERR,
423*e99981afSDavid Marchand 				"Setting RSS hash fields is not supported");
42434d5e97eSMichal Krawczyk 			return -ENOTSUP;
42534d5e97eSMichal Krawczyk 		}
426*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(WARNING,
427*e99981afSDavid Marchand 			"Setting RSS hash fields is not supported. Using default values: 0x%"PRIx64,
42834d5e97eSMichal Krawczyk 			(uint64_t)(ENA_ALL_RSS_HF));
42934d5e97eSMichal Krawczyk 	} else if (rc != 0)  {
430*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR, "Failed to set RSS hash fields");
43134d5e97eSMichal Krawczyk 		return rc;
43234d5e97eSMichal Krawczyk 	}
43334d5e97eSMichal Krawczyk 
43434d5e97eSMichal Krawczyk 	return 0;
43534d5e97eSMichal Krawczyk }
43634d5e97eSMichal Krawczyk 
43734d5e97eSMichal Krawczyk /* ENA HW interprets the RSS key in reverse bytes order. Because of that, the
43834d5e97eSMichal Krawczyk  * key must be processed upon interaction with ena_com layer.
43934d5e97eSMichal Krawczyk  */
44034d5e97eSMichal Krawczyk static void ena_reorder_rss_hash_key(uint8_t *reordered_key,
44134d5e97eSMichal Krawczyk 				     uint8_t *key,
44234d5e97eSMichal Krawczyk 				     size_t key_size)
44334d5e97eSMichal Krawczyk {
44434d5e97eSMichal Krawczyk 	size_t i, rev_i;
44534d5e97eSMichal Krawczyk 
44634d5e97eSMichal Krawczyk 	for (i = 0, rev_i = key_size - 1; i < key_size; ++i, --rev_i)
44734d5e97eSMichal Krawczyk 		reordered_key[i] = key[rev_i];
44834d5e97eSMichal Krawczyk }
44934d5e97eSMichal Krawczyk 
45034d5e97eSMichal Krawczyk static int ena_get_rss_hash_key(struct ena_com_dev *ena_dev, uint8_t *rss_key)
45134d5e97eSMichal Krawczyk {
45234d5e97eSMichal Krawczyk 	uint8_t hw_rss_key[ENA_HASH_KEY_SIZE];
45334d5e97eSMichal Krawczyk 	int rc;
45434d5e97eSMichal Krawczyk 
45534d5e97eSMichal Krawczyk 	/* The default RSS hash key cannot be retrieved from the HW. Unless it's
45634d5e97eSMichal Krawczyk 	 * explicitly set, this operation shouldn't be supported.
45734d5e97eSMichal Krawczyk 	 */
45834d5e97eSMichal Krawczyk 	if (ena_dev->rss.hash_key == NULL) {
459*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(WARNING,
460*e99981afSDavid Marchand 			"Retrieving default RSS hash key is not supported");
46134d5e97eSMichal Krawczyk 		return -ENOTSUP;
46234d5e97eSMichal Krawczyk 	}
46334d5e97eSMichal Krawczyk 
46434d5e97eSMichal Krawczyk 	rc = ena_com_get_hash_key(ena_dev, hw_rss_key);
46534d5e97eSMichal Krawczyk 	if (rc != 0)
46634d5e97eSMichal Krawczyk 		return rc;
46734d5e97eSMichal Krawczyk 
46834d5e97eSMichal Krawczyk 	ena_reorder_rss_hash_key(rss_key, hw_rss_key, ENA_HASH_KEY_SIZE);
46934d5e97eSMichal Krawczyk 
47034d5e97eSMichal Krawczyk 	return 0;
47134d5e97eSMichal Krawczyk }
47234d5e97eSMichal Krawczyk 
47334d5e97eSMichal Krawczyk int ena_rss_configure(struct ena_adapter *adapter)
47434d5e97eSMichal Krawczyk {
47534d5e97eSMichal Krawczyk 	struct rte_eth_rss_conf *rss_conf;
47634d5e97eSMichal Krawczyk 	struct ena_com_dev *ena_dev;
47734d5e97eSMichal Krawczyk 	int rc;
47834d5e97eSMichal Krawczyk 
47934d5e97eSMichal Krawczyk 	ena_dev = &adapter->ena_dev;
48034d5e97eSMichal Krawczyk 	rss_conf = &adapter->edev_data->dev_conf.rx_adv_conf.rss_conf;
48134d5e97eSMichal Krawczyk 
48234d5e97eSMichal Krawczyk 	if (adapter->edev_data->nb_rx_queues == 0)
48334d5e97eSMichal Krawczyk 		return 0;
48434d5e97eSMichal Krawczyk 
48534d5e97eSMichal Krawczyk 	/* Restart the indirection table. The number of queues could change
48634d5e97eSMichal Krawczyk 	 * between start/stop calls, so it must be reinitialized with default
48734d5e97eSMichal Krawczyk 	 * values.
48834d5e97eSMichal Krawczyk 	 */
48934d5e97eSMichal Krawczyk 	rc = ena_fill_indirect_table_default(ena_dev, ENA_RX_RSS_TABLE_SIZE,
49034d5e97eSMichal Krawczyk 		adapter->edev_data->nb_rx_queues);
49134d5e97eSMichal Krawczyk 	if (unlikely(rc != 0)) {
492*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR,
493*e99981afSDavid Marchand 			"Failed to fill indirection table with default values");
49434d5e97eSMichal Krawczyk 		return rc;
49534d5e97eSMichal Krawczyk 	}
49634d5e97eSMichal Krawczyk 
49734d5e97eSMichal Krawczyk 	rc = ena_com_indirect_table_set(ena_dev);
49834d5e97eSMichal Krawczyk 	if (unlikely(rc != 0 && rc != ENA_COM_UNSUPPORTED)) {
499*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR,
500*e99981afSDavid Marchand 			"Failed to set indirection table in the device");
50134d5e97eSMichal Krawczyk 		return rc;
50234d5e97eSMichal Krawczyk 	}
50334d5e97eSMichal Krawczyk 
50434d5e97eSMichal Krawczyk 	rc = ena_rss_hash_set(ena_dev, rss_conf, true);
50534d5e97eSMichal Krawczyk 	if (unlikely(rc != 0)) {
506*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR, "Failed to set RSS hash");
50734d5e97eSMichal Krawczyk 		return rc;
50834d5e97eSMichal Krawczyk 	}
50934d5e97eSMichal Krawczyk 
510*e99981afSDavid Marchand 	PMD_DRV_LOG_LINE(DEBUG, "RSS configured for port %d",
51134d5e97eSMichal Krawczyk 		adapter->edev_data->port_id);
51234d5e97eSMichal Krawczyk 
51334d5e97eSMichal Krawczyk 	return 0;
51434d5e97eSMichal Krawczyk }
51534d5e97eSMichal Krawczyk 
51634d5e97eSMichal Krawczyk int ena_rss_hash_update(struct rte_eth_dev *dev,
51734d5e97eSMichal Krawczyk 			struct rte_eth_rss_conf *rss_conf)
51834d5e97eSMichal Krawczyk {
51934d5e97eSMichal Krawczyk 	struct ena_adapter *adapter = dev->data->dev_private;
52034d5e97eSMichal Krawczyk 	int rc;
52134d5e97eSMichal Krawczyk 
52234d5e97eSMichal Krawczyk 	rte_spinlock_lock(&adapter->admin_lock);
52334d5e97eSMichal Krawczyk 	rc = ena_rss_hash_set(&adapter->ena_dev, rss_conf, false);
52434d5e97eSMichal Krawczyk 	rte_spinlock_unlock(&adapter->admin_lock);
52534d5e97eSMichal Krawczyk 	if (unlikely(rc != 0)) {
526*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR, "Failed to set RSS hash");
52734d5e97eSMichal Krawczyk 		return rc;
52834d5e97eSMichal Krawczyk 	}
52934d5e97eSMichal Krawczyk 
53034d5e97eSMichal Krawczyk 	return 0;
53134d5e97eSMichal Krawczyk }
53234d5e97eSMichal Krawczyk 
53334d5e97eSMichal Krawczyk int ena_rss_hash_conf_get(struct rte_eth_dev *dev,
53434d5e97eSMichal Krawczyk 			  struct rte_eth_rss_conf *rss_conf)
53534d5e97eSMichal Krawczyk {
53634d5e97eSMichal Krawczyk 	struct ena_adapter *adapter = dev->data->dev_private;
53734d5e97eSMichal Krawczyk 	struct ena_com_dev *ena_dev = &adapter->ena_dev;
53834d5e97eSMichal Krawczyk 	enum ena_admin_flow_hash_proto proto;
53934d5e97eSMichal Krawczyk 	uint64_t rss_hf = 0;
54034d5e97eSMichal Krawczyk 	int rc, i;
54134d5e97eSMichal Krawczyk 	uint16_t admin_hf;
54234d5e97eSMichal Krawczyk 	static bool warn_once;
54334d5e97eSMichal Krawczyk 
544295968d1SFerruh Yigit 	if (!(dev->data->dev_conf.rxmode.offloads & RTE_ETH_RX_OFFLOAD_RSS_HASH)) {
545*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR, "RSS was not configured for the PMD");
54634d5e97eSMichal Krawczyk 		return -ENOTSUP;
54734d5e97eSMichal Krawczyk 	}
54834d5e97eSMichal Krawczyk 
54934d5e97eSMichal Krawczyk 	if (rss_conf->rss_key != NULL) {
55034d5e97eSMichal Krawczyk 		rc = ena_get_rss_hash_key(ena_dev, rss_conf->rss_key);
55134d5e97eSMichal Krawczyk 		if (unlikely(rc != 0)) {
552*e99981afSDavid Marchand 			PMD_DRV_LOG_LINE(ERR,
553*e99981afSDavid Marchand 				"Cannot retrieve RSS hash key, err: %d",
55434d5e97eSMichal Krawczyk 				rc);
55534d5e97eSMichal Krawczyk 			return rc;
55634d5e97eSMichal Krawczyk 		}
55734d5e97eSMichal Krawczyk 	}
55834d5e97eSMichal Krawczyk 
55934d5e97eSMichal Krawczyk 	for (i = 0; i < ENA_ADMIN_RSS_PROTO_NUM; ++i) {
56034d5e97eSMichal Krawczyk 		proto = (enum ena_admin_flow_hash_proto)i;
56134d5e97eSMichal Krawczyk 		rte_spinlock_lock(&adapter->admin_lock);
56234d5e97eSMichal Krawczyk 		rc = ena_com_get_hash_ctrl(ena_dev, proto, &admin_hf);
56334d5e97eSMichal Krawczyk 		rte_spinlock_unlock(&adapter->admin_lock);
56434d5e97eSMichal Krawczyk 		if (rc == ENA_COM_UNSUPPORTED) {
56534d5e97eSMichal Krawczyk 			/* As some devices may support only reading rss hash
56634d5e97eSMichal Krawczyk 			 * key and not the hash ctrl, we want to notify the
56734d5e97eSMichal Krawczyk 			 * caller that this feature is only partially supported
56834d5e97eSMichal Krawczyk 			 * and do not return an error - the caller could be
56934d5e97eSMichal Krawczyk 			 * interested only in the key value.
57034d5e97eSMichal Krawczyk 			 */
57134d5e97eSMichal Krawczyk 			if (!warn_once) {
572*e99981afSDavid Marchand 				PMD_DRV_LOG_LINE(WARNING,
573*e99981afSDavid Marchand 					"Reading hash control from the device is not supported. .rss_hf will contain a default value.");
57434d5e97eSMichal Krawczyk 				warn_once = true;
57534d5e97eSMichal Krawczyk 			}
57634d5e97eSMichal Krawczyk 			rss_hf = ENA_ALL_RSS_HF;
57734d5e97eSMichal Krawczyk 			break;
57834d5e97eSMichal Krawczyk 		} else if (rc != 0) {
579*e99981afSDavid Marchand 			PMD_DRV_LOG_LINE(ERR,
580*e99981afSDavid Marchand 				"Failed to retrieve hash ctrl for proto: %d with err: %d",
58134d5e97eSMichal Krawczyk 				i, rc);
58234d5e97eSMichal Krawczyk 			return rc;
58334d5e97eSMichal Krawczyk 		}
58434d5e97eSMichal Krawczyk 
58534d5e97eSMichal Krawczyk 		rss_hf |= ena_admin_hf_to_eth_hf(proto, admin_hf);
58634d5e97eSMichal Krawczyk 	}
58734d5e97eSMichal Krawczyk 
58834d5e97eSMichal Krawczyk 	rss_conf->rss_hf = rss_hf;
58934d5e97eSMichal Krawczyk 	return 0;
59034d5e97eSMichal Krawczyk }
591