Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2014-2023 Broadcom
3 : : * All rights reserved.
4 : : */
5 : :
6 : : #include <inttypes.h>
7 : :
8 : : #include <rte_memzone.h>
9 : : #include <rte_malloc.h>
10 : :
11 : : #include "bnxt.h"
12 : : #include "bnxt_rxq.h"
13 : : #include "bnxt_rxr.h"
14 : : #include "bnxt_ring.h"
15 : : #include "bnxt_vnic.h"
16 : : #include "hsi_struct_def_dpdk.h"
17 : : #include "bnxt_hwrm.h"
18 : :
19 : : /* Macros to manipulate vnic bitmaps*/
20 : : #define BNXT_VNIC_BITMAP_SIZE 64
21 : : #define BNXT_VNIC_BITMAP_SET(b, i) ((b[(i) / BNXT_VNIC_BITMAP_SIZE]) |= \
22 : : (1UL << ((BNXT_VNIC_BITMAP_SIZE - 1) - \
23 : : ((i) % BNXT_VNIC_BITMAP_SIZE))))
24 : :
25 : : #define BNXT_VNIC_BITMAP_RESET(b, i) ((b[(i) / BNXT_VNIC_BITMAP_SIZE]) &= \
26 : : (~(1UL << ((BNXT_VNIC_BITMAP_SIZE - 1) - \
27 : : ((i) % BNXT_VNIC_BITMAP_SIZE)))))
28 : :
29 : : #define BNXT_VNIC_BITMAP_GET(b, i) (((b[(i) / BNXT_VNIC_BITMAP_SIZE]) >> \
30 : : ((BNXT_VNIC_BITMAP_SIZE - 1) - \
31 : : ((i) % BNXT_VNIC_BITMAP_SIZE))) & 1)
32 : :
33 : : /*
34 : : * VNIC Functions
35 : : */
36 : :
37 : 0 : void bnxt_prandom_bytes(void *dest_ptr, size_t len)
38 : : {
39 : : char *dest = (char *)dest_ptr;
40 : : uint64_t rb;
41 : :
42 [ # # ]: 0 : while (len) {
43 : 0 : rb = rte_rand();
44 [ # # ]: 0 : if (len >= 8) {
45 : : memcpy(dest, &rb, 8);
46 : 0 : len -= 8;
47 : 0 : dest += 8;
48 : : } else {
49 : : memcpy(dest, &rb, len);
50 : : dest += len;
51 : : len = 0;
52 : : }
53 : : }
54 : 0 : }
55 : :
56 : 0 : static void bnxt_init_vnics(struct bnxt *bp)
57 : : {
58 : : struct bnxt_vnic_info *vnic;
59 : : uint16_t max_vnics;
60 : : int i;
61 : :
62 : 0 : max_vnics = bp->max_vnics;
63 : 0 : STAILQ_INIT(&bp->free_vnic_list);
64 [ # # ]: 0 : for (i = 0; i < max_vnics; i++) {
65 : 0 : vnic = &bp->vnic_info[i];
66 : 0 : vnic->fw_vnic_id = (uint16_t)HWRM_NA_SIGNATURE;
67 : 0 : vnic->rss_rule = (uint16_t)HWRM_NA_SIGNATURE;
68 : 0 : vnic->cos_rule = (uint16_t)HWRM_NA_SIGNATURE;
69 : 0 : vnic->lb_rule = (uint16_t)HWRM_NA_SIGNATURE;
70 : 0 : vnic->hash_mode =
71 : : HWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_DEFAULT;
72 : 0 : vnic->prev_hash_mode =
73 : : HWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_DEFAULT;
74 : 0 : vnic->rx_queue_cnt = 0;
75 : :
76 : 0 : STAILQ_INIT(&vnic->filter);
77 : 0 : STAILQ_INIT(&vnic->flow_list);
78 : 0 : STAILQ_INSERT_TAIL(&bp->free_vnic_list, vnic, next);
79 : : }
80 : 0 : }
81 : :
82 : 0 : struct bnxt_vnic_info *bnxt_alloc_vnic(struct bnxt *bp)
83 : : {
84 : : struct bnxt_vnic_info *vnic;
85 : :
86 : : /* Find the 1st unused vnic from the free_vnic_list pool*/
87 : 0 : vnic = STAILQ_FIRST(&bp->free_vnic_list);
88 [ # # ]: 0 : if (!vnic) {
89 : 0 : PMD_DRV_LOG(ERR, "No more free VNIC resources\n");
90 : 0 : return NULL;
91 : : }
92 [ # # ]: 0 : STAILQ_REMOVE_HEAD(&bp->free_vnic_list, next);
93 : : return vnic;
94 : : }
95 : :
96 : 0 : void bnxt_free_all_vnics(struct bnxt *bp)
97 : : {
98 : : struct bnxt_vnic_info *vnic;
99 : : unsigned int i;
100 : :
101 [ # # ]: 0 : if (bp->vnic_info == NULL)
102 : : return;
103 : :
104 [ # # ]: 0 : for (i = 0; i < bp->max_vnics; i++) {
105 : 0 : vnic = &bp->vnic_info[i];
106 : 0 : STAILQ_INSERT_TAIL(&bp->free_vnic_list, vnic, next);
107 [ # # ]: 0 : if (vnic->ref_cnt) {
108 : : /* clean up the default vnic details */
109 : 0 : bnxt_vnic_rss_action_free(bp, i);
110 : : }
111 : :
112 : 0 : vnic->rx_queue_cnt = 0;
113 : : }
114 : : }
115 : :
116 : 0 : void bnxt_free_vnic_attributes(struct bnxt *bp)
117 : : {
118 : : struct bnxt_vnic_info *vnic;
119 : : unsigned int i;
120 : :
121 [ # # ]: 0 : if (bp->vnic_info == NULL)
122 : : return;
123 : :
124 [ # # ]: 0 : for (i = 0; i < bp->max_vnics; i++) {
125 : 0 : vnic = &bp->vnic_info[i];
126 : 0 : vnic->rss_hash_key = NULL;
127 : 0 : vnic->rss_table = NULL;
128 : : }
129 : 0 : rte_memzone_free(bp->vnic_rss_mz);
130 : 0 : bp->vnic_rss_mz = NULL;
131 : : }
132 : :
133 : 0 : int bnxt_alloc_vnic_attributes(struct bnxt *bp, bool reconfig)
134 : : {
135 : : struct bnxt_vnic_info *vnic;
136 : 0 : struct rte_pci_device *pdev = bp->pdev;
137 : : const struct rte_memzone *mz;
138 : : char mz_name[RTE_MEMZONE_NAMESIZE];
139 : : uint32_t entry_length;
140 : : size_t rss_table_size;
141 : : int i;
142 : : rte_iova_t mz_phys_addr;
143 : :
144 : : entry_length = HW_HASH_KEY_SIZE;
145 : :
146 [ # # ]: 0 : if (BNXT_CHIP_P5_P7(bp))
147 : : rss_table_size = BNXT_RSS_TBL_SIZE_P5 *
148 : : 2 * sizeof(*vnic->rss_table);
149 : : else
150 : : rss_table_size = HW_HASH_INDEX_SIZE * sizeof(*vnic->rss_table);
151 : :
152 : 0 : entry_length = RTE_CACHE_LINE_ROUNDUP(entry_length + rss_table_size);
153 : :
154 : 0 : snprintf(mz_name, RTE_MEMZONE_NAMESIZE,
155 : : "bnxt_" PCI_PRI_FMT "_vnicattr", pdev->addr.domain,
156 : 0 : pdev->addr.bus, pdev->addr.devid, pdev->addr.function);
157 : 0 : mz_name[RTE_MEMZONE_NAMESIZE - 1] = 0;
158 : 0 : mz = rte_memzone_lookup(mz_name);
159 [ # # ]: 0 : if (mz == NULL) {
160 : 0 : mz = rte_memzone_reserve_aligned(mz_name,
161 : 0 : entry_length * bp->max_vnics,
162 : 0 : bp->eth_dev->device->numa_node,
163 : : RTE_MEMZONE_2MB |
164 : : RTE_MEMZONE_SIZE_HINT_ONLY |
165 : : RTE_MEMZONE_IOVA_CONTIG,
166 : : BNXT_PAGE_SIZE);
167 [ # # ]: 0 : if (mz == NULL) {
168 : 0 : PMD_DRV_LOG(ERR,
169 : : "Cannot allocate vnic_attributes memory\n");
170 : 0 : return -ENOMEM;
171 : : }
172 : : }
173 : 0 : bp->vnic_rss_mz = mz;
174 [ # # ]: 0 : for (i = 0; i < bp->max_vnics; i++) {
175 : 0 : uint32_t offset = entry_length * i;
176 : :
177 : 0 : vnic = &bp->vnic_info[i];
178 : :
179 : 0 : mz_phys_addr = mz->iova + offset;
180 : :
181 : : /* Allocate rss table and hash key */
182 : 0 : vnic->rss_table = (void *)((char *)mz->addr + offset);
183 : 0 : vnic->rss_table_dma_addr = mz_phys_addr;
184 [ # # ]: 0 : memset(vnic->rss_table, -1, entry_length);
185 : :
186 : 0 : vnic->rss_hash_key = (void *)((char *)vnic->rss_table + rss_table_size);
187 : 0 : vnic->rss_hash_key_dma_addr = vnic->rss_table_dma_addr + rss_table_size;
188 [ # # ]: 0 : if (!reconfig) {
189 : 0 : bnxt_prandom_bytes(vnic->rss_hash_key, HW_HASH_KEY_SIZE);
190 : 0 : memcpy(bp->rss_conf.rss_key, vnic->rss_hash_key, HW_HASH_KEY_SIZE);
191 : : } else {
192 : 0 : memcpy(vnic->rss_hash_key, bp->rss_conf.rss_key, HW_HASH_KEY_SIZE);
193 : : }
194 : : }
195 : :
196 : : return 0;
197 : : }
198 : :
199 : 0 : void bnxt_free_vnic_mem(struct bnxt *bp)
200 : : {
201 : : struct bnxt_vnic_info *vnic;
202 : : uint16_t max_vnics, i;
203 : :
204 [ # # ]: 0 : if (bp->vnic_info == NULL)
205 : : return;
206 : :
207 : 0 : max_vnics = bp->max_vnics;
208 [ # # ]: 0 : for (i = 0; i < max_vnics; i++) {
209 : 0 : vnic = &bp->vnic_info[i];
210 [ # # ]: 0 : if (vnic->fw_vnic_id != (uint16_t)HWRM_NA_SIGNATURE) {
211 : 0 : PMD_DRV_LOG(ERR, "VNIC is not freed yet!\n");
212 : : /* TODO Call HWRM to free VNIC */
213 : : }
214 : : }
215 : :
216 : 0 : rte_free(bp->vnic_info);
217 : 0 : bp->vnic_info = NULL;
218 : : }
219 : :
220 : 0 : int bnxt_alloc_vnic_mem(struct bnxt *bp)
221 : : {
222 : : struct bnxt_vnic_info *vnic_mem;
223 : : uint16_t max_vnics;
224 : :
225 : 0 : max_vnics = bp->max_vnics;
226 : : /* Allocate memory for VNIC pool and filter pool */
227 : 0 : vnic_mem = rte_zmalloc("bnxt_vnic_info",
228 : : max_vnics * sizeof(struct bnxt_vnic_info), 0);
229 [ # # ]: 0 : if (vnic_mem == NULL) {
230 : 0 : PMD_DRV_LOG(ERR, "Failed to alloc memory for %d VNICs",
231 : : max_vnics);
232 : 0 : return -ENOMEM;
233 : : }
234 : 0 : bp->vnic_info = vnic_mem;
235 : 0 : bnxt_init_vnics(bp);
236 : 0 : return 0;
237 : : }
238 : :
239 : 0 : int bnxt_vnic_grp_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic)
240 : : {
241 : 0 : uint32_t size = sizeof(*vnic->fw_grp_ids) * bp->max_ring_grps;
242 : : uint32_t i;
243 : :
244 : 0 : vnic->fw_grp_ids = rte_zmalloc("vnic_fw_grp_ids", size, 0);
245 [ # # ]: 0 : if (!vnic->fw_grp_ids) {
246 : 0 : PMD_DRV_LOG(ERR,
247 : : "Failed to alloc %d bytes for group ids\n",
248 : : size);
249 : 0 : return -ENOMEM;
250 : : }
251 : :
252 : : /* Initialize to invalid ring id */
253 [ # # ]: 0 : for (i = 0; i < bp->max_ring_grps; i++)
254 : 0 : vnic->fw_grp_ids[i] = INVALID_HW_RING_ID;
255 : :
256 : : return 0;
257 : : }
258 : :
259 : 0 : uint32_t bnxt_rte_to_hwrm_hash_types(uint64_t rte_type)
260 : : {
261 : : uint32_t hwrm_type = 0;
262 : :
263 [ # # ]: 0 : if (rte_type & RTE_ETH_RSS_IPV4_CHKSUM)
264 : : hwrm_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4;
265 [ # # ]: 0 : if (rte_type & RTE_ETH_RSS_L4_CHKSUM)
266 : : hwrm_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4 |
267 : : HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6;
268 [ # # ]: 0 : if ((rte_type & RTE_ETH_RSS_IPV4) ||
269 : : (rte_type & RTE_ETH_RSS_ECPRI))
270 : 0 : hwrm_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4;
271 [ # # ]: 0 : if (rte_type & RTE_ETH_RSS_ECPRI)
272 : 0 : hwrm_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4;
273 [ # # ]: 0 : if (rte_type & RTE_ETH_RSS_NONFRAG_IPV4_TCP)
274 : 0 : hwrm_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4;
275 [ # # ]: 0 : if (rte_type & RTE_ETH_RSS_NONFRAG_IPV4_UDP)
276 : 0 : hwrm_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4;
277 [ # # ]: 0 : if (rte_type & RTE_ETH_RSS_IPV6)
278 : 0 : hwrm_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6;
279 [ # # ]: 0 : if (rte_type & RTE_ETH_RSS_NONFRAG_IPV6_TCP)
280 : 0 : hwrm_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6;
281 [ # # ]: 0 : if (rte_type & RTE_ETH_RSS_NONFRAG_IPV6_UDP)
282 : 0 : hwrm_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6;
283 [ # # ]: 0 : if (rte_type & RTE_ETH_RSS_ESP)
284 : 0 : hwrm_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_ESP_SPI_IPV4 |
285 : : HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_ESP_SPI_IPV6;
286 [ # # ]: 0 : if (rte_type & RTE_ETH_RSS_AH)
287 : 0 : hwrm_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_AH_SPI_IPV4 |
288 : : HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_AH_SPI_IPV6;
289 : :
290 : 0 : return hwrm_type;
291 : : }
292 : :
293 : 0 : int bnxt_rte_to_hwrm_hash_level(struct bnxt *bp, uint64_t hash_f, uint32_t lvl)
294 : : {
295 : : uint32_t mode = HWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_DEFAULT;
296 : 0 : bool l3 = (hash_f & (RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_ECPRI));
297 : 0 : bool l4 = (hash_f & (RTE_ETH_RSS_NONFRAG_IPV4_UDP |
298 : : RTE_ETH_RSS_NONFRAG_IPV6_UDP |
299 : : RTE_ETH_RSS_NONFRAG_IPV4_TCP |
300 : : RTE_ETH_RSS_NONFRAG_IPV6_TCP));
301 : 0 : bool l3_only = l3 && !l4;
302 : : bool l3_and_l4 = l3 && l4;
303 : 0 : bool cksum = !!(hash_f &
304 : : (RTE_ETH_RSS_IPV4_CHKSUM | RTE_ETH_RSS_L4_CHKSUM));
305 : :
306 : : /* If FW has not advertised capability to configure outer/inner
307 : : * RSS hashing , just log a message. HW will work in default RSS mode.
308 : : */
309 [ # # # # : 0 : if ((BNXT_CHIP_P5(bp) && BNXT_VNIC_OUTER_RSS_UNSUPPORTED(bp)) ||
# # # # #
# # # #
# ]
310 [ # # ]: 0 : (!BNXT_CHIP_P5(bp) && !(bp->vnic_cap_flags & BNXT_VNIC_CAP_OUTER_RSS))) {
311 [ # # ]: 0 : if (lvl)
312 : 0 : PMD_DRV_LOG(INFO,
313 : : "Given RSS level is unsupported, using default RSS level\n");
314 : 0 : return mode;
315 : : }
316 : :
317 [ # # # ]: 0 : switch (lvl) {
318 : 0 : case BNXT_RSS_LEVEL_INNERMOST:
319 : : /* Irrespective of what RTE says, FW always does 4 tuple */
320 [ # # ]: 0 : if (l3_and_l4 || l4 || l3_only || cksum)
321 : : mode = BNXT_HASH_MODE_INNERMOST;
322 : : break;
323 : 0 : case BNXT_RSS_LEVEL_OUTERMOST:
324 : : /* Irrespective of what RTE says, FW always does 4 tuple */
325 [ # # ]: 0 : if (l3_and_l4 || l4 || l3_only || cksum)
326 : : mode = BNXT_HASH_MODE_OUTERMOST;
327 : : break;
328 : : default:
329 : : mode = BNXT_HASH_MODE_DEFAULT;
330 : : break;
331 : : }
332 : :
333 : 0 : return mode;
334 : : }
335 : :
336 : 0 : uint64_t bnxt_hwrm_to_rte_rss_level(struct bnxt *bp, uint32_t mode)
337 : : {
338 : : uint64_t rss_level = 0;
339 : :
340 : : /* If FW has not advertised capability to configure inner/outer RSS
341 : : * return default hash mode.
342 : : */
343 [ # # # # : 0 : if ((BNXT_CHIP_P5(bp) && BNXT_VNIC_OUTER_RSS_UNSUPPORTED(bp)) ||
# # # # #
# # # #
# ]
344 [ # # ]: 0 : (!BNXT_CHIP_P5(bp) && !(bp->vnic_cap_flags & BNXT_VNIC_CAP_OUTER_RSS)))
345 : : return RTE_ETH_RSS_LEVEL_PMD_DEFAULT;
346 : :
347 : 0 : if (mode == HWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_OUTERMOST_2 ||
348 [ # # # ]: 0 : mode == HWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_OUTERMOST_4)
349 : : rss_level |= RTE_ETH_RSS_LEVEL_OUTERMOST;
350 : : else if (mode == HWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_INNERMOST_2 ||
351 : : mode == HWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_INNERMOST_4)
352 : : rss_level |= RTE_ETH_RSS_LEVEL_INNERMOST;
353 : : else
354 : : rss_level |= RTE_ETH_RSS_LEVEL_PMD_DEFAULT;
355 : :
356 : : return rss_level;
357 : : }
358 : :
359 : : static
360 : 0 : int32_t bnxt_vnic_populate_rss_table_p5(struct bnxt *bp,
361 : : struct bnxt_vnic_info *vnic)
362 : : {
363 : : uint32_t ctx_idx = 0, rss_idx = 0, cnt = 0;
364 : : uint32_t q_id = -1;
365 : : struct bnxt_rx_queue *rxq;
366 : 0 : uint16_t *ring_tbl = vnic->rss_table;
367 : 0 : uint8_t *rx_queue_state = bp->eth_dev->data->rx_queue_state;
368 : : uint16_t ring_id;
369 : :
370 : : /* For P5 platform */
371 [ # # ]: 0 : for (ctx_idx = 0; ctx_idx < vnic->num_lb_ctxts; ctx_idx++) {
372 [ # # ]: 0 : for (rss_idx = 0; rss_idx < BNXT_RSS_ENTRIES_PER_CTX_P5;
373 : 0 : rss_idx++) {
374 : : /* Find next active ring. */
375 [ # # ]: 0 : for (cnt = 0; cnt < BNXT_VNIC_MAX_QUEUE_SIZE; cnt++) {
376 [ # # ]: 0 : if (++q_id == bp->rx_nr_rings)
377 : : q_id = 0; /* reset the q_id */
378 [ # # ]: 0 : if (BNXT_VNIC_BITMAP_GET(vnic->queue_bitmap,
379 : 0 : q_id) &&
380 [ # # ]: 0 : rx_queue_state[q_id] !=
381 : : RTE_ETH_QUEUE_STATE_STOPPED)
382 : : break;
383 : : }
384 : :
385 : : /* no active queues exit */
386 [ # # ]: 0 : if (cnt == BNXT_VNIC_MAX_QUEUE_SIZE)
387 : : return 0;
388 : :
389 : 0 : rxq = bp->rx_queues[q_id];
390 : 0 : ring_id = rxq->rx_ring->rx_ring_struct->fw_ring_id;
391 : 0 : *ring_tbl++ = rte_cpu_to_le_16(ring_id);
392 : 0 : ring_id = rxq->cp_ring->cp_ring_struct->fw_ring_id;
393 : 0 : *ring_tbl++ = rte_cpu_to_le_16(ring_id);
394 : : }
395 : : }
396 : : return 0;
397 : : }
398 : :
399 : : static
400 : 0 : int32_t bnxt_vnic_populate_rss_table_p4(struct bnxt *bp,
401 : : struct bnxt_vnic_info *vnic)
402 : : {
403 : : uint32_t rss_idx = 0, cnt = 0;
404 : : uint32_t q_id = -1;
405 : 0 : uint16_t *ring_tbl = vnic->rss_table;
406 : 0 : uint8_t *rx_queue_state = bp->eth_dev->data->rx_queue_state;
407 : : uint16_t ring_id;
408 : :
409 : : /* For Wh+ platform */
410 [ # # ]: 0 : for (rss_idx = 0; rss_idx < bnxt_rss_hash_tbl_size(bp); rss_idx++) {
411 : : /* Find next active ring. */
412 [ # # ]: 0 : for (cnt = 0; cnt < BNXT_VNIC_MAX_QUEUE_SIZE; cnt++) {
413 [ # # ]: 0 : if (++q_id == bp->rx_nr_rings)
414 : : q_id = 0; /* reset the q_id */
415 [ # # ]: 0 : if (BNXT_VNIC_BITMAP_GET(vnic->queue_bitmap,
416 : 0 : q_id) &&
417 [ # # ]: 0 : rx_queue_state[q_id] !=
418 : : RTE_ETH_QUEUE_STATE_STOPPED)
419 : : break;
420 : : }
421 : :
422 : : /* no active queues exit */
423 [ # # ]: 0 : if (cnt == BNXT_VNIC_MAX_QUEUE_SIZE)
424 : : return 0;
425 : :
426 : 0 : ring_id = vnic->fw_grp_ids[q_id];
427 : 0 : *ring_tbl++ = rte_cpu_to_le_16(ring_id);
428 : : }
429 : : return 0;
430 : : }
431 : :
432 : : static
433 : 0 : int32_t bnxt_vnic_populate_rss_table(struct bnxt *bp,
434 : : struct bnxt_vnic_info *vnic)
435 : : {
436 : : /* RSS table population is different for p4 and p5, p7 platforms */
437 [ # # ]: 0 : if (BNXT_CHIP_P5_P7(bp))
438 : 0 : return bnxt_vnic_populate_rss_table_p5(bp, vnic);
439 : :
440 : 0 : return bnxt_vnic_populate_rss_table_p4(bp, vnic);
441 : : }
442 : :
443 : : static void
444 : 0 : bnxt_vnic_queue_delete(struct bnxt *bp, uint16_t vnic_idx)
445 : : {
446 : 0 : struct bnxt_vnic_info *vnic = &bp->vnic_info[vnic_idx];
447 : :
448 [ # # ]: 0 : if (bnxt_hwrm_vnic_free(bp, vnic))
449 : 0 : PMD_DRV_LOG(ERR, "Failed to delete queue\n");
450 : :
451 [ # # ]: 0 : if (vnic->fw_grp_ids) {
452 : 0 : rte_free(vnic->fw_grp_ids);
453 : 0 : vnic->fw_grp_ids = NULL;
454 : : }
455 : :
456 : 0 : vnic->rx_queue_cnt = 0;
457 [ # # ]: 0 : if (bp->nr_vnics)
458 : 0 : bp->nr_vnics--;
459 : :
460 : : /* reset the queue_bitmap */
461 : 0 : memset(vnic->queue_bitmap, 0, sizeof(vnic->queue_bitmap));
462 : 0 : }
463 : :
464 : : static struct bnxt_vnic_info*
465 : 0 : bnxt_vnic_queue_create(struct bnxt *bp, int32_t vnic_id, uint16_t q_index)
466 : : {
467 : 0 : struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
468 : 0 : uint8_t *rx_queue_state = bp->eth_dev->data->rx_queue_state;
469 : 0 : uint64_t rx_offloads = dev_conf->rxmode.offloads;
470 : : struct bnxt_vnic_info *vnic;
471 : : struct bnxt_rx_queue *rxq = NULL;
472 : : int32_t rc = -EINVAL;
473 : : uint16_t saved_mru = 0;
474 : :
475 : 0 : vnic = &bp->vnic_info[vnic_id];
476 [ # # ]: 0 : if (vnic->rx_queue_cnt) {
477 : 0 : PMD_DRV_LOG(ERR, "invalid queue configuration %d\n", vnic_id);
478 : 0 : return NULL;
479 : : }
480 : :
481 : : /* set the queue_bitmap */
482 : 0 : BNXT_VNIC_BITMAP_SET(vnic->queue_bitmap, q_index);
483 : :
484 : 0 : rxq = bp->rx_queues[q_index];
485 [ # # ]: 0 : if (rx_queue_state[q_index] == RTE_ETH_QUEUE_STATE_STOPPED)
486 : 0 : rxq->rx_started = 0;
487 : : else
488 : 0 : rxq->rx_started = 1;
489 : :
490 : 0 : vnic->rx_queue_cnt++;
491 : 0 : vnic->start_grp_id = q_index;
492 : 0 : vnic->end_grp_id = q_index + 1;
493 : 0 : vnic->func_default = 0; /* This is not a default VNIC. */
494 : 0 : bp->nr_vnics++;
495 : :
496 : : /* Allocate vnic group for p4 platform */
497 : 0 : rc = bnxt_vnic_grp_alloc(bp, vnic);
498 [ # # ]: 0 : if (rc) {
499 : 0 : PMD_DRV_LOG(DEBUG, "Failed to allocate vnic groups\n");
500 : 0 : goto cleanup;
501 : : }
502 : :
503 : : /* populate the fw group table */
504 : 0 : bnxt_vnic_ring_grp_populate(bp, vnic);
505 : 0 : bnxt_vnic_rules_init(vnic);
506 : :
507 : 0 : rc = bnxt_hwrm_vnic_alloc(bp, vnic);
508 [ # # ]: 0 : if (rc) {
509 : 0 : PMD_DRV_LOG(DEBUG, "Failed to allocate vnic %d\n", q_index);
510 : 0 : goto cleanup;
511 : : }
512 : :
513 : : /* store the mru so we can set it to zero in hw */
514 [ # # ]: 0 : if (rxq->rx_started == 0) {
515 : 0 : saved_mru = vnic->mru;
516 : 0 : vnic->mru = 0;
517 : : }
518 : :
519 : 0 : rc = bnxt_hwrm_vnic_cfg(bp, vnic);
520 [ # # ]: 0 : if (rxq->rx_started == 0)
521 : 0 : vnic->mru = saved_mru;
522 : :
523 [ # # ]: 0 : if (rc) {
524 : 0 : PMD_DRV_LOG(DEBUG, "Failed to configure vnic %d\n", q_index);
525 : 0 : goto cleanup;
526 : : }
527 : :
528 : 0 : rc = bnxt_hwrm_vnic_tpa_cfg(bp, vnic,
529 : : (rx_offloads & RTE_ETH_RX_OFFLOAD_TCP_LRO) ?
530 : 0 : true : false);
531 [ # # ]: 0 : if (rc)
532 : 0 : PMD_DRV_LOG(DEBUG, "Failed to configure TPA on this vnic %d\n", q_index);
533 : :
534 : 0 : rc = bnxt_hwrm_vnic_plcmode_cfg(bp, vnic);
535 [ # # ]: 0 : if (rc) {
536 : 0 : PMD_DRV_LOG(DEBUG, "Failed to configure vnic plcmode %d\n",
537 : : q_index);
538 : 0 : goto cleanup;
539 : : }
540 : :
541 : 0 : vnic->ref_cnt++;
542 : 0 : return vnic;
543 : :
544 : 0 : cleanup:
545 : 0 : bnxt_vnic_queue_delete(bp, vnic_id);
546 : 0 : return NULL;
547 : : }
548 : :
549 : : static inline int32_t
550 : : bnxt_vnic_queue_db_lookup(struct bnxt *bp, uint64_t *q_list)
551 : : {
552 : : /* lookup in the database to check if it is in use */
553 : 0 : return rte_hash_lookup(bp->vnic_queue_db.rss_q_db,
554 : : (const void *)q_list);
555 : : }
556 : :
557 : : static inline int32_t
558 : : bnxt_vnic_queue_db_del(struct bnxt *bp, uint64_t *q_list)
559 : : {
560 : 0 : return rte_hash_del_key(bp->vnic_queue_db.rss_q_db,
561 : : (const void *)q_list);
562 : : }
563 : :
564 : : static int32_t
565 : 0 : bnxt_vnic_queue_db_add(struct bnxt *bp, uint64_t *q_list)
566 : : {
567 : : struct bnxt_vnic_info *vnic_info;
568 : : int32_t vnic_id, rc = -1;
569 : :
570 : 0 : vnic_id = rte_hash_add_key(bp->vnic_queue_db.rss_q_db,
571 : : (const void *)q_list);
572 : :
573 [ # # # # ]: 0 : if (vnic_id < 0 || vnic_id >= bp->max_vnics) {
574 : 0 : PMD_DRV_LOG(DEBUG, "unable to assign vnic index %d\n",
575 : : vnic_id);
576 : 0 : return rc;
577 : : }
578 : :
579 : 0 : vnic_info = &bp->vnic_info[vnic_id];
580 [ # # ]: 0 : if (vnic_info->fw_vnic_id != INVALID_HW_RING_ID) {
581 : 0 : PMD_DRV_LOG(DEBUG, "Invalid ring id for %d.\n", vnic_id);
582 : 0 : return rc;
583 : : }
584 : : return vnic_id;
585 : : }
586 : :
587 : : /* Function to validate the incoming rss configuration */
588 : : static
589 : 0 : int32_t bnxt_vnic_queue_db_rss_validate(struct bnxt *bp,
590 : : struct bnxt_vnic_rss_info *rss_info,
591 : : int32_t *vnic_idx)
592 : : {
593 : 0 : struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
594 : : int32_t rc = -EINVAL;
595 : : uint32_t idx = 0;
596 : : int32_t out_idx;
597 : :
598 [ # # ]: 0 : if (!(dev_conf->rxmode.mq_mode & RTE_ETH_MQ_RX_RSS)) {
599 : 0 : PMD_DRV_LOG(ERR, "Error Rss is not supported on this port\n");
600 : 0 : return rc;
601 : : }
602 : :
603 : : /* rss queue is zero then use the default vnic */
604 [ # # ]: 0 : if (rss_info->queue_num == 0) {
605 : 0 : *vnic_idx = 0;
606 : 0 : return 0;
607 : : }
608 : :
609 : : /* Check to see if the queues id are in supported range */
610 [ # # ]: 0 : if (rss_info->queue_num > bp->rx_nr_rings) {
611 : 0 : PMD_DRV_LOG(ERR, "Error unsupported queue num.\n");
612 : 0 : return rc;
613 : : }
614 : :
615 : : /* validate the queue ids are in correct range */
616 [ # # ]: 0 : for (idx = 0; idx < BNXT_VNIC_MAX_QUEUE_SIZE; idx++) {
617 [ # # ]: 0 : if (BNXT_VNIC_BITMAP_GET(rss_info->queue_list, idx)) {
618 [ # # ]: 0 : if (idx >= bp->rx_nr_rings) {
619 : 0 : PMD_DRV_LOG(ERR,
620 : : "Error %d beyond support size %u\n",
621 : : idx, bp->rx_nr_rings);
622 : 0 : return rc;
623 : : }
624 : : }
625 : : }
626 : :
627 : : /* check if the vnic already exist */
628 : 0 : out_idx = bnxt_vnic_queue_db_lookup(bp, rss_info->queue_list);
629 [ # # # # ]: 0 : if (out_idx < 0 || out_idx >= bp->max_vnics)
630 : : return -ENOENT; /* entry not found */
631 : :
632 : : /* found an entry */
633 : 0 : *vnic_idx = out_idx;
634 : 0 : return 0;
635 : : }
636 : :
637 : : static void
638 : 0 : bnxt_vnic_rss_delete(struct bnxt *bp, uint16_t q_index)
639 : : {
640 : : struct bnxt_vnic_info *vnic;
641 : :
642 : 0 : vnic = &bp->vnic_info[q_index];
643 [ # # ]: 0 : if (vnic->rx_queue_cnt >= 1)
644 : 0 : bnxt_hwrm_vnic_ctx_free(bp, vnic);
645 : :
646 [ # # ]: 0 : if (vnic->fw_vnic_id != INVALID_HW_RING_ID)
647 : 0 : bnxt_hwrm_vnic_free(bp, vnic);
648 : :
649 [ # # ]: 0 : if (vnic->fw_grp_ids) {
650 : 0 : rte_free(vnic->fw_grp_ids);
651 : 0 : vnic->fw_grp_ids = NULL;
652 : : }
653 : :
654 : : /* Update the vnic details for all the rx queues */
655 : 0 : vnic->rx_queue_cnt = 0;
656 [ # # ]: 0 : memset(vnic->queue_bitmap, 0, sizeof(vnic->queue_bitmap));
657 : :
658 [ # # ]: 0 : if (bp->nr_vnics)
659 : 0 : bp->nr_vnics--;
660 : 0 : }
661 : :
662 : : /* The validation of the rss_info should be done before calling this function*/
663 : :
664 : : static struct bnxt_vnic_info *
665 : 0 : bnxt_vnic_rss_create(struct bnxt *bp,
666 : : struct bnxt_vnic_rss_info *rss_info,
667 : : uint16_t vnic_id)
668 : : {
669 : 0 : struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
670 : 0 : uint8_t *rx_queue_state = bp->eth_dev->data->rx_queue_state;
671 : 0 : uint64_t rx_offloads = dev_conf->rxmode.offloads;
672 : : struct bnxt_vnic_info *vnic;
673 : : struct bnxt_rx_queue *rxq = NULL;
674 : : uint32_t idx, nr_ctxs, config_rss = 0;
675 : : uint16_t saved_mru = 0;
676 : : uint16_t active_q_cnt = 0;
677 : : int16_t first_q = -1;
678 : : int16_t end_q = -1;
679 : : int32_t rc = 0;
680 : :
681 : : /* Assign the vnic to be used for this rss configuration */
682 : 0 : vnic = &bp->vnic_info[vnic_id];
683 : :
684 : : /* Update the vnic details for all the rx queues */
685 [ # # ]: 0 : for (idx = 0; idx < BNXT_VNIC_MAX_QUEUE_SIZE; idx++) {
686 [ # # ]: 0 : if (BNXT_VNIC_BITMAP_GET(rss_info->queue_list, idx)) {
687 : 0 : rxq = bp->rx_queues[idx];
688 [ # # ]: 0 : if (rx_queue_state[idx] ==
689 : : RTE_ETH_QUEUE_STATE_STOPPED) {
690 : 0 : rxq->rx_started = 0;
691 : : } else {
692 : 0 : rxq->rx_started = 1;
693 : 0 : active_q_cnt++;
694 : : }
695 : 0 : vnic->rx_queue_cnt++;
696 : :
697 : : /* Update the queue list */
698 : 0 : BNXT_VNIC_BITMAP_SET(vnic->queue_bitmap, idx);
699 [ # # ]: 0 : if (first_q == -1)
700 : 0 : first_q = idx;
701 : 0 : end_q = idx;
702 : : }
703 : : }
704 : 0 : vnic->start_grp_id = first_q;
705 : 0 : vnic->end_grp_id = end_q + 1;
706 : 0 : vnic->func_default = 0; /* This is not a default VNIC. */
707 : 0 : bp->nr_vnics++;
708 : :
709 : : /* Allocate vnic group for p4 platform */
710 : 0 : rc = bnxt_vnic_grp_alloc(bp, vnic);
711 [ # # ]: 0 : if (rc) {
712 : 0 : PMD_DRV_LOG(ERR, "Failed to allocate vnic groups\n");
713 : 0 : goto fail_cleanup;
714 : : }
715 : :
716 : : /* populate the fw group table */
717 : 0 : bnxt_vnic_ring_grp_populate(bp, vnic);
718 : 0 : bnxt_vnic_rules_init(vnic);
719 : :
720 : : /* Allocate the vnic in the firmware */
721 : 0 : rc = bnxt_hwrm_vnic_alloc(bp, vnic);
722 [ # # ]: 0 : if (rc) {
723 : 0 : PMD_DRV_LOG(ERR, "Failed to allocate vnic %d\n", idx);
724 : 0 : goto fail_cleanup;
725 : : }
726 : :
727 : : /* Allocate the vnic rss context */
728 : : /* RSS table size in P5 is 512. Cap max Rx rings to same value */
729 : 0 : nr_ctxs = bnxt_rss_ctxts(bp);
730 [ # # ]: 0 : for (idx = 0; idx < nr_ctxs; idx++) {
731 : 0 : rc = bnxt_hwrm_vnic_ctx_alloc(bp, vnic, idx);
732 [ # # ]: 0 : if (rc)
733 : : break;
734 : : }
735 [ # # ]: 0 : if (rc) {
736 : 0 : PMD_DRV_LOG(ERR,
737 : : "HWRM ctx %d alloc failure rc: %x\n", idx, rc);
738 : 0 : goto fail_cleanup;
739 : : }
740 : 0 : vnic->num_lb_ctxts = nr_ctxs;
741 : :
742 : 0 : saved_mru = vnic->mru;
743 [ # # ]: 0 : if (!active_q_cnt)
744 : 0 : vnic->mru = 0;
745 : :
746 : : /* configure the vnic details in firmware */
747 : 0 : rc = bnxt_hwrm_vnic_cfg(bp, vnic);
748 : 0 : vnic->mru = saved_mru;
749 [ # # ]: 0 : if (rc) {
750 : 0 : PMD_DRV_LOG(ERR, "Failed to configure vnic %d\n", idx);
751 : 0 : goto fail_cleanup;
752 : : }
753 : :
754 : 0 : rc = bnxt_hwrm_vnic_tpa_cfg(bp, vnic,
755 : : (rx_offloads & RTE_ETH_RX_OFFLOAD_TCP_LRO) ?
756 : 0 : true : false);
757 [ # # ]: 0 : if (rc)
758 : 0 : PMD_DRV_LOG(DEBUG, "Failed to configure TPA on this vnic %d\n", idx);
759 : :
760 : 0 : rc = bnxt_hwrm_vnic_plcmode_cfg(bp, vnic);
761 [ # # ]: 0 : if (rc) {
762 : 0 : PMD_DRV_LOG(ERR, "Failed to configure vnic plcmode %d\n",
763 : : idx);
764 : 0 : goto fail_cleanup;
765 : : }
766 : :
767 : : /* Remove unsupported types */
768 : 0 : rss_info->rss_types &= bnxt_eth_rss_support(bp);
769 : :
770 : : /* If only unsupported type(s) are specified then quit */
771 [ # # ]: 0 : if (rss_info->rss_types == 0) {
772 : 0 : PMD_DRV_LOG(ERR,
773 : : "Unsupported RSS hash type(s)\n");
774 : 0 : goto fail_cleanup;
775 : : }
776 : :
777 : : /* hwrm_type conversion */
778 : 0 : vnic->hash_type = bnxt_rte_to_hwrm_hash_types(rss_info->rss_types);
779 : 0 : vnic->hash_mode = bnxt_rte_to_hwrm_hash_level(bp, rss_info->rss_types,
780 : : rss_info->rss_level);
781 : :
782 : : /* configure the key */
783 [ # # ]: 0 : if (!rss_info->key_len)
784 : : /* If hash key has not been specified, use random hash key.*/
785 : 0 : bnxt_prandom_bytes(vnic->rss_hash_key, HW_HASH_KEY_SIZE);
786 : : else
787 : 0 : memcpy(vnic->rss_hash_key, rss_info->key, rss_info->key_len);
788 : :
789 : : /* Prepare the indirection table */
790 : 0 : bnxt_vnic_populate_rss_table(bp, vnic);
791 : :
792 : : /* check to see if there is at least one queue that is active */
793 [ # # ]: 0 : for (idx = vnic->start_grp_id; idx < vnic->end_grp_id; idx++) {
794 [ # # ]: 0 : if (bnxt_vnic_queue_id_is_valid(vnic, idx) &&
795 [ # # ]: 0 : bp->rx_queues[idx]->rx_started) {
796 : : config_rss = 1;
797 : : break;
798 : : }
799 : : }
800 : :
801 : : /* configure the rss table */
802 [ # # ]: 0 : if (config_rss) {
803 : 0 : rc = bnxt_hwrm_vnic_rss_cfg(bp, vnic);
804 [ # # ]: 0 : if (rc) {
805 : 0 : memset(vnic->rss_hash_key, 0, HW_HASH_KEY_SIZE);
806 : 0 : PMD_DRV_LOG(ERR,
807 : : "Failed to configure vnic rss details %d\n",
808 : : idx);
809 : 0 : goto fail_cleanup;
810 : : }
811 : : }
812 : :
813 : 0 : vnic->ref_cnt++;
814 : 0 : return vnic;
815 : :
816 : 0 : fail_cleanup:
817 : 0 : bnxt_vnic_rss_delete(bp, idx);
818 : 0 : return NULL;
819 : : }
820 : :
821 : : int32_t
822 : 0 : bnxt_vnic_rss_queue_status_update(struct bnxt *bp, struct bnxt_vnic_info *vnic)
823 : : {
824 [ # # ]: 0 : if (vnic->fw_vnic_id == INVALID_HW_RING_ID)
825 : : return 0;
826 : :
827 [ # # # # ]: 0 : if (!(vnic->rss_table && vnic->hash_type))
828 : : return 0;
829 : :
830 : : /* Prepare the indirection table */
831 : 0 : bnxt_vnic_populate_rss_table(bp, vnic);
832 : :
833 : : /* configure the rss table */
834 [ # # ]: 0 : if (bnxt_hwrm_vnic_rss_cfg(bp, vnic)) {
835 : 0 : PMD_DRV_LOG(DEBUG, "Failed to update vnic rss details\n");
836 : 0 : return -EINVAL;
837 : : }
838 : : return 0;
839 : : }
840 : :
841 : : static int32_t
842 : 0 : bnxt_vnic_rss_hash_algo_update(struct bnxt *bp,
843 : : struct bnxt_vnic_info *vnic,
844 : : struct bnxt_vnic_rss_info *rss_info)
845 : : {
846 : 0 : uint8_t old_rss_hash_key[HW_HASH_KEY_SIZE] = { 0 };
847 : : uint32_t hash_type;
848 : : uint8_t hash_mode;
849 : : uint8_t ring_mode;
850 : : uint32_t apply = 0;
851 : : int rc;
852 : :
853 : : /* validate key length */
854 [ # # ]: 0 : if (rss_info->key_len != 0 && rss_info->key_len != HW_HASH_KEY_SIZE) {
855 : 0 : PMD_DRV_LOG(ERR,
856 : : "Invalid hashkey length, should be %d bytes\n",
857 : : HW_HASH_KEY_SIZE);
858 : 0 : return -EINVAL;
859 : : }
860 : :
861 : : /* Remove unsupported types */
862 : 0 : rss_info->rss_types &= bnxt_eth_rss_support(bp);
863 : :
864 : : /* If only unsupported type(s) are specified then quit */
865 [ # # ]: 0 : if (!rss_info->rss_types) {
866 : 0 : PMD_DRV_LOG(ERR,
867 : : "Unsupported RSS hash type\n");
868 : 0 : return -EINVAL;
869 : : }
870 : :
871 : : /* hwrm_type conversion */
872 : 0 : hash_type = bnxt_rte_to_hwrm_hash_types(rss_info->rss_types);
873 : 0 : hash_mode = bnxt_rte_to_hwrm_hash_level(bp, rss_info->rss_types,
874 : : rss_info->rss_level);
875 : 0 : ring_mode = vnic->ring_select_mode;
876 : :
877 : : /* For P7 chips update the hash_type if hash_type not explicitly passed.
878 : : * TODO: For P5 chips.
879 : : */
880 [ # # ]: 0 : if (BNXT_CHIP_P7(bp) &&
881 [ # # ]: 0 : hash_mode == BNXT_HASH_MODE_DEFAULT && !hash_type)
882 : 0 : vnic->hash_type = HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4 |
883 : : HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6;
884 : :
885 : 0 : rc = bnxt_rte_flow_to_hwrm_ring_select_mode(rss_info->rss_func,
886 : : rss_info->rss_types,
887 : : bp,
888 : : vnic);
889 [ # # ]: 0 : if (rc)
890 : : return -EINVAL;
891 : :
892 [ # # ]: 0 : if (vnic->hash_mode != hash_mode ||
893 [ # # ]: 0 : vnic->hash_type != hash_type ||
894 [ # # ]: 0 : vnic->ring_select_mode != ring_mode) {
895 : : apply = 1;
896 : 0 : vnic->hash_mode = hash_mode;
897 : 0 : vnic->hash_type = hash_type;
898 : : }
899 : : /* Store the old hash key before programming the new one. It will
900 : : * be used to restore the old hash key when HWRM_VNIC_RSS_CFG
901 : : * fails.
902 : : */
903 : 0 : memcpy(old_rss_hash_key, vnic->rss_hash_key, HW_HASH_KEY_SIZE);
904 [ # # # # ]: 0 : if (rss_info->key_len != 0 && memcmp(rss_info->key, vnic->rss_hash_key,
905 : : HW_HASH_KEY_SIZE)) {
906 : : apply = 1;
907 : : memcpy(vnic->rss_hash_key, rss_info->key, HW_HASH_KEY_SIZE);
908 : : }
909 : :
910 [ # # ]: 0 : if (apply) {
911 [ # # ]: 0 : if (bnxt_hwrm_vnic_rss_cfg(bp, vnic)) {
912 : 0 : memcpy(vnic->rss_hash_key, old_rss_hash_key, HW_HASH_KEY_SIZE);
913 : 0 : PMD_DRV_LOG(ERR, "Error configuring vnic RSS config\n");
914 : 0 : return -EINVAL;
915 : : }
916 : 0 : PMD_DRV_LOG(INFO, "Rss config successfully applied\n");
917 : : }
918 : : return 0;
919 : : }
920 : :
921 : 0 : int32_t bnxt_vnic_queue_db_deinit(struct bnxt *bp)
922 : : {
923 : 0 : rte_hash_free(bp->vnic_queue_db.rss_q_db);
924 : 0 : return 0;
925 : : }
926 : :
927 : 0 : int32_t bnxt_vnic_queue_db_init(struct bnxt *bp)
928 : : {
929 : 0 : struct rte_hash_parameters hash_tbl_params = {0};
930 : 0 : char hash_tbl_name[64] = {0};
931 : :
932 : : /* choose the least supported value */
933 [ # # ]: 0 : if (bp->rx_nr_rings > BNXT_VNIC_MAX_QUEUE_SIZE)
934 : 0 : bp->vnic_queue_db.num_queues = BNXT_VNIC_MAX_QUEUE_SIZE;
935 : : else
936 : 0 : bp->vnic_queue_db.num_queues = bp->rx_nr_rings;
937 : :
938 : : /* create the hash table for the rss hash entries */
939 : 0 : snprintf(hash_tbl_name, sizeof(hash_tbl_name),
940 : 0 : "bnxt_rss_hash_%d", bp->eth_dev->data->port_id);
941 : 0 : hash_tbl_params.name = hash_tbl_name;
942 : 0 : hash_tbl_params.entries = (bp->max_vnics > BNXT_VNIC_MAX_SUPPORTED_ID) ?
943 : 0 : BNXT_VNIC_MAX_SUPPORTED_ID : bp->max_vnics;
944 : 0 : hash_tbl_params.key_len = BNXT_VNIC_MAX_QUEUE_SZ_IN_8BITS;
945 : 0 : hash_tbl_params.socket_id = rte_socket_id();
946 : 0 : bp->vnic_queue_db.rss_q_db = rte_hash_create(&hash_tbl_params);
947 [ # # ]: 0 : if (bp->vnic_queue_db.rss_q_db == NULL) {
948 : 0 : PMD_DRV_LOG(ERR, "Failed to create rss hash tbl\n");
949 : 0 : return -ENOMEM;
950 : : }
951 : : return 0;
952 : : }
953 : :
954 : 0 : void bnxt_vnic_queue_db_update_dlft_vnic(struct bnxt *bp)
955 : : {
956 : : struct bnxt_vnic_info *dflt_vnic;
957 : : uint64_t bitmap[BNXT_VNIC_MAX_QUEUE_SZ_IN_64BITS];
958 : : uint32_t idx;
959 : : int32_t vnic_id;
960 : :
961 : : /* populate all the queue ids in the default vnic */
962 : : memset(bitmap, 0, sizeof(bitmap));
963 [ # # ]: 0 : for (idx = 0; idx < bp->vnic_queue_db.num_queues; idx++)
964 : 0 : BNXT_VNIC_BITMAP_SET(bitmap, idx);
965 : :
966 : 0 : vnic_id = bnxt_vnic_queue_db_add(bp, bitmap);
967 [ # # ]: 0 : if (vnic_id < 0) {
968 : 0 : PMD_DRV_LOG(ERR, "Unable to alloc vnic for default rss\n");
969 : 0 : return;
970 : : }
971 : :
972 : 0 : dflt_vnic = bnxt_vnic_queue_db_get_vnic(bp, vnic_id);
973 [ # # ]: 0 : if (dflt_vnic == NULL) {
974 : 0 : PMD_DRV_LOG(ERR, "Invalid vnic for default rss %d\n", vnic_id);
975 : 0 : return;
976 : : }
977 : : /* Update the default vnic structure */
978 : 0 : bp->vnic_queue_db.dflt_vnic_id = vnic_id;
979 : 0 : memcpy(dflt_vnic->queue_bitmap, bitmap, sizeof(bitmap));
980 : 0 : dflt_vnic->rx_queue_cnt = bp->vnic_queue_db.num_queues;
981 : 0 : dflt_vnic->ref_cnt++;
982 : : }
983 : :
984 : 0 : int32_t bnxt_vnic_queue_action_alloc(struct bnxt *bp,
985 : : uint16_t q_index,
986 : : uint16_t *vnic_idx,
987 : : uint16_t *vnicid)
988 : : {
989 : 0 : uint64_t queue_list[BNXT_VNIC_MAX_QUEUE_SZ_IN_64BITS] = {0};
990 : : struct bnxt_vnic_info *vnic_info;
991 : : int32_t idx;
992 : : int32_t rc = -EINVAL;
993 : :
994 : : /* validate the given queue id */
995 [ # # # # ]: 0 : if (q_index >= bp->rx_nr_rings || q_index >= BNXT_VNIC_MAX_QUEUE_SIZE) {
996 : 0 : PMD_DRV_LOG(ERR, "invalid queue id should be less than %d\n",
997 : : bp->rx_nr_rings);
998 : 0 : return rc;
999 : : }
1000 : :
1001 : : /* Populate the queue list */
1002 : 0 : BNXT_VNIC_BITMAP_SET(queue_list, q_index);
1003 : :
1004 : : /* check to see if the q_index is already in use */
1005 : : idx = bnxt_vnic_queue_db_lookup(bp, queue_list);
1006 [ # # ]: 0 : if (idx < 0) {
1007 : : /* Assign the vnic slot */
1008 : 0 : idx = bnxt_vnic_queue_db_add(bp, queue_list);
1009 [ # # ]: 0 : if (idx < 0) {
1010 : 0 : PMD_DRV_LOG(DEBUG, "Unable to alloc vnic for queue\n");
1011 : 0 : return rc;
1012 : : }
1013 : :
1014 : : /* Allocate a new one */
1015 : 0 : vnic_info = bnxt_vnic_queue_create(bp, idx, q_index);
1016 [ # # ]: 0 : if (!vnic_info) {
1017 : 0 : PMD_DRV_LOG(ERR, "failed to create vnic - %d\n",
1018 : : q_index);
1019 : : bnxt_vnic_queue_db_del(bp, queue_list);
1020 : 0 : return rc; /* failed */
1021 : : }
1022 : : } else {
1023 : 0 : vnic_info = bnxt_vnic_queue_db_get_vnic(bp, idx);
1024 [ # # ]: 0 : if (vnic_info == NULL) {
1025 : 0 : PMD_DRV_LOG(ERR, "Unable to lookup vnic for queue %d\n",
1026 : : q_index);
1027 : 0 : return rc;
1028 : : }
1029 : : /* increment the reference count and return the vnic id */
1030 : 0 : vnic_info->ref_cnt++;
1031 : : }
1032 : 0 : *vnic_idx = (uint16_t)idx;
1033 : 0 : *vnicid = vnic_info->fw_vnic_id;
1034 : 0 : return 0;
1035 : : }
1036 : :
1037 : : int32_t
1038 : 0 : bnxt_vnic_queue_action_free(struct bnxt *bp, uint16_t vnic_id)
1039 : : {
1040 : : struct bnxt_vnic_info *vnic_info;
1041 : : int32_t rc = -EINVAL;
1042 : 0 : int32_t vnic_idx = vnic_id, idx;
1043 : :
1044 : : /* validate the given vnic idx */
1045 [ # # ]: 0 : if (vnic_idx >= bp->max_vnics) {
1046 : 0 : PMD_DRV_LOG(ERR, "invalid vnic idx %d\n", vnic_idx);
1047 : 0 : return rc;
1048 : : }
1049 : :
1050 : : /* validate the vnic info */
1051 : 0 : vnic_info = &bp->vnic_info[vnic_idx];
1052 [ # # ]: 0 : if (!vnic_info->rx_queue_cnt) {
1053 : 0 : PMD_DRV_LOG(ERR, "Invalid vnic idx, no queues being used\n");
1054 : 0 : return rc;
1055 : : }
1056 [ # # ]: 0 : if (vnic_info->ref_cnt) {
1057 : 0 : vnic_info->ref_cnt--;
1058 [ # # ]: 0 : if (!vnic_info->ref_cnt) {
1059 : : idx = bnxt_vnic_queue_db_del(bp,
1060 : 0 : vnic_info->queue_bitmap);
1061 : : /* Check to ensure there is no corruption */
1062 [ # # ]: 0 : if (idx != vnic_idx)
1063 : 0 : PMD_DRV_LOG(ERR, "bad vnic idx %d\n", vnic_idx);
1064 : :
1065 : 0 : bnxt_vnic_queue_delete(bp, vnic_idx);
1066 : : }
1067 : : }
1068 : : return 0;
1069 : : }
1070 : :
1071 : : int32_t
1072 : 0 : bnxt_vnic_rss_action_alloc(struct bnxt *bp,
1073 : : struct bnxt_vnic_rss_info *rss_info,
1074 : : uint16_t *vnic_idx,
1075 : : uint16_t *vnicid)
1076 : : {
1077 : : struct bnxt_vnic_info *vnic_info = NULL;
1078 : : int32_t rc = -EINVAL;
1079 : : int32_t idx;
1080 : :
1081 : : /* validate the given parameters */
1082 : 0 : rc = bnxt_vnic_queue_db_rss_validate(bp, rss_info, &idx);
1083 [ # # ]: 0 : if (rc == -EINVAL) {
1084 : 0 : PMD_DRV_LOG(ERR, "Failed to apply the rss action.\n");
1085 : 0 : return rc;
1086 [ # # ]: 0 : } else if (rc == -ENOENT) {
1087 : : /* Allocate a new entry */
1088 : 0 : idx = bnxt_vnic_queue_db_add(bp, rss_info->queue_list);
1089 [ # # ]: 0 : if (idx < 0) {
1090 : 0 : PMD_DRV_LOG(DEBUG, "Unable to alloc vnic for rss\n");
1091 : 0 : return rc;
1092 : : }
1093 : : /* create the rss vnic */
1094 : 0 : vnic_info = bnxt_vnic_rss_create(bp, rss_info, idx);
1095 [ # # ]: 0 : if (!vnic_info) {
1096 : 0 : PMD_DRV_LOG(ERR, "Failed to create rss action.\n");
1097 : : bnxt_vnic_queue_db_del(bp, rss_info->queue_list);
1098 : 0 : return rc;
1099 : : }
1100 : : } else {
1101 : 0 : vnic_info = bnxt_vnic_queue_db_get_vnic(bp, idx);
1102 [ # # ]: 0 : if (vnic_info == NULL) {
1103 : 0 : PMD_DRV_LOG(ERR, "Unable to lookup vnic for idx %d\n",
1104 : : idx);
1105 : 0 : return rc;
1106 : : }
1107 : : /* increment the reference count and return the vnic id */
1108 : 0 : vnic_info->ref_cnt++;
1109 : :
1110 : : /* check configuration has changed then update hash details */
1111 : 0 : rc = bnxt_vnic_rss_hash_algo_update(bp, vnic_info, rss_info);
1112 [ # # ]: 0 : if (rc) {
1113 : 0 : PMD_DRV_LOG(ERR, "Failed to update the rss action.\n");
1114 : 0 : return rc;
1115 : : }
1116 : : }
1117 : 0 : *vnic_idx = idx;
1118 : 0 : *vnicid = vnic_info->fw_vnic_id;
1119 : 0 : return 0;
1120 : : }
1121 : :
1122 : : /* Delete the vnic associated with the given rss action index */
1123 : : int32_t
1124 : 0 : bnxt_vnic_rss_action_free(struct bnxt *bp, uint16_t vnic_id)
1125 : : {
1126 : : uint64_t bitmap[BNXT_VNIC_MAX_QUEUE_SZ_IN_64BITS];
1127 : : struct bnxt_vnic_info *vnic_info;
1128 : : int32_t rc = -EINVAL;
1129 : : uint64_t *q_list;
1130 : : int32_t idx = 0;
1131 : :
1132 : : /* validate the given vnic id */
1133 [ # # ]: 0 : if (vnic_id >= bp->max_vnics) {
1134 : 0 : PMD_DRV_LOG(ERR, "invalid vnic id %d\n", vnic_id);
1135 : 0 : return rc;
1136 : : }
1137 : :
1138 : : /* validate vnic info */
1139 : 0 : vnic_info = &bp->vnic_info[vnic_id];
1140 [ # # ]: 0 : if (!vnic_info->rx_queue_cnt) {
1141 : 0 : PMD_DRV_LOG(ERR, "Invalid vnic id, not using any queues\n");
1142 : 0 : return rc;
1143 : : }
1144 : :
1145 [ # # ]: 0 : if (vnic_info->ref_cnt) {
1146 : 0 : vnic_info->ref_cnt--;
1147 [ # # ]: 0 : if (!vnic_info->ref_cnt) {
1148 [ # # ]: 0 : if (bp->vnic_queue_db.dflt_vnic_id == vnic_id) {
1149 : : /* in case of default queue, list can be
1150 : : * changed by reta config so need a list
1151 : : * with all queues populated.
1152 : : */
1153 : : memset(bitmap, 0, sizeof(bitmap));
1154 : 0 : for (idx = 0;
1155 [ # # ]: 0 : idx < bp->vnic_queue_db.num_queues;
1156 : 0 : idx++)
1157 : 0 : BNXT_VNIC_BITMAP_SET(bitmap, idx);
1158 : : q_list = bitmap;
1159 : : } else {
1160 : 0 : q_list = vnic_info->queue_bitmap;
1161 : : }
1162 : : idx = bnxt_vnic_queue_db_del(bp, q_list);
1163 : :
1164 : : /* check to ensure there is no corruption */
1165 [ # # ]: 0 : if (idx != vnic_id)
1166 : 0 : PMD_DRV_LOG(ERR, "bad vnic idx %d\n", vnic_id);
1167 : 0 : bnxt_vnic_rss_delete(bp, vnic_id);
1168 : : }
1169 : : }
1170 : : return 0;
1171 : : }
1172 : :
1173 : : int32_t
1174 : 0 : bnxt_vnic_reta_config_update(struct bnxt *bp,
1175 : : struct bnxt_vnic_info *vnic_info,
1176 : : struct rte_eth_rss_reta_entry64 *reta_conf,
1177 : : uint16_t reta_size)
1178 : : {
1179 : 0 : uint64_t l_bitmap[BNXT_VNIC_MAX_QUEUE_SZ_IN_64BITS] = {0};
1180 : : uint16_t i, sft, idx;
1181 : : uint16_t q_id;
1182 : :
1183 [ # # ]: 0 : for (i = 0; i < reta_size; i++) {
1184 : 0 : idx = i / RTE_ETH_RETA_GROUP_SIZE;
1185 : 0 : sft = i % RTE_ETH_RETA_GROUP_SIZE;
1186 : :
1187 [ # # ]: 0 : if (!(reta_conf[idx].mask & (1ULL << sft)))
1188 : 0 : continue;
1189 : :
1190 : 0 : q_id = reta_conf[idx].reta[sft];
1191 [ # # ]: 0 : if (q_id >= bp->vnic_queue_db.num_queues ||
1192 [ # # ]: 0 : !bp->eth_dev->data->rx_queues[q_id]) {
1193 : 0 : PMD_DRV_LOG(ERR, "Queue id %d is invalid\n", q_id);
1194 : 0 : return -EINVAL;
1195 : : }
1196 : 0 : BNXT_VNIC_BITMAP_SET(l_bitmap, q_id);
1197 : : }
1198 : : /* update the queue bitmap after the validation */
1199 : 0 : memcpy(vnic_info->queue_bitmap, l_bitmap, sizeof(l_bitmap));
1200 : 0 : return 0;
1201 : : }
1202 : :
1203 : : int32_t
1204 : 0 : bnxt_vnic_queue_id_is_valid(struct bnxt_vnic_info *vnic_info,
1205 : : uint16_t queue_id)
1206 : : {
1207 [ # # ]: 0 : if (BNXT_VNIC_BITMAP_GET(vnic_info->queue_bitmap, queue_id))
1208 : 0 : return 1;
1209 : : return 0;
1210 : : }
1211 : :
1212 : : void
1213 : 0 : bnxt_vnic_ring_grp_populate(struct bnxt *bp, struct bnxt_vnic_info *vnic)
1214 : : {
1215 : : uint32_t i;
1216 : :
1217 : : /* check if ring group is supported */
1218 [ # # ]: 0 : if (!BNXT_HAS_RING_GRPS(bp))
1219 : : return;
1220 : :
1221 : : /* map ring groups to this vnic */
1222 [ # # ]: 0 : for (i = vnic->start_grp_id; i < vnic->end_grp_id; i++)
1223 [ # # ]: 0 : if (bnxt_vnic_queue_id_is_valid(vnic, i) &&
1224 [ # # ]: 0 : bp->rx_queues[i]->rx_started)
1225 : 0 : vnic->fw_grp_ids[i] = bp->grp_info[i].fw_grp_id;
1226 : :
1227 : 0 : vnic->dflt_ring_grp = bp->grp_info[vnic->start_grp_id].fw_grp_id;
1228 : : }
1229 : :
1230 : : void
1231 : 0 : bnxt_vnic_rules_init(struct bnxt_vnic_info *vnic)
1232 : : {
1233 : 0 : vnic->rss_rule = (uint16_t)HWRM_NA_SIGNATURE;
1234 : 0 : vnic->cos_rule = (uint16_t)HWRM_NA_SIGNATURE;
1235 : 0 : vnic->lb_rule = (uint16_t)HWRM_NA_SIGNATURE;
1236 : 0 : }
1237 : :
1238 : : int32_t
1239 : 0 : bnxt_vnic_mru_config(struct bnxt *bp, uint16_t new_mtu)
1240 : : {
1241 : : struct bnxt_vnic_info *vnic;
1242 : : uint16_t size = 0;
1243 : : int32_t rc = 0;
1244 : : uint32_t i;
1245 : :
1246 [ # # ]: 0 : for (i = 0; i < bp->max_vnics; i++) {
1247 : 0 : vnic = &bp->vnic_info[i];
1248 [ # # ]: 0 : if (vnic->fw_vnic_id == INVALID_VNIC_ID)
1249 : 0 : continue;
1250 : :
1251 : 0 : vnic->mru = BNXT_VNIC_MRU(new_mtu);
1252 : 0 : rc = bnxt_hwrm_vnic_cfg(bp, vnic);
1253 [ # # ]: 0 : if (rc)
1254 : : break;
1255 : :
1256 [ # # ]: 0 : size = rte_pktmbuf_data_room_size(bp->rx_queues[0]->mb_pool);
1257 : 0 : size -= RTE_PKTMBUF_HEADROOM;
1258 : :
1259 [ # # ]: 0 : if (size < new_mtu) {
1260 : 0 : rc = bnxt_hwrm_vnic_plcmode_cfg(bp, vnic);
1261 [ # # ]: 0 : if (rc)
1262 : : break;
1263 : : }
1264 : : }
1265 : 0 : return rc;
1266 : : }
1267 : :
1268 : : struct bnxt_vnic_info *
1269 : 0 : bnxt_vnic_queue_db_get_vnic(struct bnxt *bp, uint16_t vnic_idx)
1270 : : {
1271 : : struct bnxt_vnic_info *vnic_info;
1272 : :
1273 [ # # ]: 0 : if (vnic_idx >= bp->max_vnics) {
1274 : 0 : PMD_DRV_LOG(ERR, "invalid vnic index %u\n", vnic_idx);
1275 : 0 : return NULL;
1276 : : }
1277 : 0 : vnic_info = &bp->vnic_info[vnic_idx];
1278 : 0 : return vnic_info;
1279 : : }
1280 : :
1281 : : struct bnxt_vnic_info *
1282 : 0 : bnxt_vnic_queue_id_get_next(struct bnxt *bp, uint16_t queue_id,
1283 : : uint16_t *vnic_idx)
1284 : : {
1285 : : struct bnxt_vnic_info *vnic = NULL;
1286 : 0 : uint16_t i = *vnic_idx;
1287 : :
1288 [ # # ]: 0 : while (i < bp->max_vnics) {
1289 : 0 : vnic = &bp->vnic_info[i];
1290 [ # # # # ]: 0 : if (vnic->ref_cnt && BNXT_VNIC_BITMAP_GET(vnic->queue_bitmap,
1291 : : queue_id)) {
1292 : : /* found a vnic that has the queue id */
1293 : 0 : *vnic_idx = i;
1294 : 0 : return vnic;
1295 : : }
1296 : 0 : i++;
1297 : : }
1298 : : return NULL;
1299 : : }
1300 : :
1301 : : void
1302 : 0 : bnxt_vnic_tpa_cfg(struct bnxt *bp, uint16_t queue_id, bool flag)
1303 : : {
1304 : : struct bnxt_vnic_info *vnic = NULL;
1305 : 0 : uint16_t vnic_idx = 0;
1306 : :
1307 : 0 : while ((vnic = bnxt_vnic_queue_id_get_next(bp, queue_id,
1308 [ # # ]: 0 : &vnic_idx)) != NULL) {
1309 : 0 : bnxt_hwrm_vnic_tpa_cfg(bp, vnic, flag);
1310 : 0 : vnic_idx++;
1311 : : }
1312 : 0 : }
1313 : :
1314 : : inline struct bnxt_vnic_info *
1315 : 0 : bnxt_get_default_vnic(struct bnxt *bp)
1316 : : {
1317 : 0 : return &bp->vnic_info[bp->vnic_queue_db.dflt_vnic_id];
1318 : : }
1319 : :
1320 : 0 : uint8_t _bnxt_rte_to_hwrm_ring_select_mode(enum rte_eth_hash_function hash_f)
1321 : : {
1322 : : /* If RTE_ETH_HASH_FUNCTION_DEFAULT || RTE_ETH_HASH_FUNCTION_TOEPLITZ */
1323 : : uint8_t mode = HWRM_VNIC_RSS_CFG_INPUT_RING_SELECT_MODE_TOEPLITZ;
1324 : :
1325 [ # # ]: 0 : if (hash_f == RTE_ETH_HASH_FUNCTION_SIMPLE_XOR)
1326 : : mode = HWRM_VNIC_RSS_CFG_INPUT_RING_SELECT_MODE_XOR;
1327 : :
1328 : 0 : return mode;
1329 : : }
1330 : :
1331 : 0 : int bnxt_rte_flow_to_hwrm_ring_select_mode(enum rte_eth_hash_function hash_f,
1332 : : uint64_t types, struct bnxt *bp,
1333 : : struct bnxt_vnic_info *vnic)
1334 : : {
1335 [ # # ]: 0 : if (hash_f != RTE_ETH_HASH_FUNCTION_TOEPLITZ &&
1336 : : hash_f != RTE_ETH_HASH_FUNCTION_DEFAULT) {
1337 [ # # ]: 0 : if (hash_f == RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ ||
1338 [ # # # # ]: 0 : (!BNXT_CHIP_P7(bp) && hash_f == RTE_ETH_HASH_FUNCTION_SIMPLE_XOR)) {
1339 : 0 : PMD_DRV_LOG(ERR, "Unsupported hash function\n");
1340 : 0 : return -ENOTSUP;
1341 : : }
1342 : : }
1343 : :
1344 [ # # ]: 0 : if (types & RTE_ETH_RSS_IPV4_CHKSUM || types & RTE_ETH_RSS_L4_CHKSUM) {
1345 [ # # # # ]: 0 : if ((bp->vnic_cap_flags & BNXT_VNIC_CAP_CHKSM_MODE) &&
1346 : : (hash_f == RTE_ETH_HASH_FUNCTION_DEFAULT ||
1347 : : hash_f == RTE_ETH_HASH_FUNCTION_TOEPLITZ)) {
1348 : : /* Checksum mode cannot with hash func makes no sense */
1349 : 0 : vnic->ring_select_mode =
1350 : : HWRM_VNIC_RSS_CFG_INPUT_RING_SELECT_MODE_TOEPLITZ_CHECKSUM;
1351 : 0 : vnic->hash_f_local = RTE_ETH_HASH_FUNCTION_TOEPLITZ;
1352 : : /* shadow copy types as !hash_f is always true with default func */
1353 : 0 : vnic->rss_types_local = types;
1354 : 0 : return 0;
1355 : : }
1356 : 0 : PMD_DRV_LOG(ERR, "Hash function not supported with checksun type\n");
1357 : 0 : return -ENOTSUP;
1358 : : }
1359 : :
1360 : 0 : vnic->ring_select_mode = _bnxt_rte_to_hwrm_ring_select_mode(hash_f);
1361 : 0 : vnic->hash_f_local = hash_f;
1362 : : /* shadow copy types as !hash_f is always true with default func */
1363 : 0 : vnic->rss_types_local = types;
1364 : 0 : return 0;
1365 : : }
1366 : :
1367 : 0 : int bnxt_rte_eth_to_hwrm_ring_select_mode(struct bnxt *bp, uint64_t types,
1368 : : struct bnxt_vnic_info *vnic)
1369 : : {
1370 : : /* If the config update comes via ethdev, there is no way to
1371 : : * specify anything for hash function.
1372 : : * So its either TOEPLITZ or the Checksum mode.
1373 : : * Note that checksum mode is not supported on older devices.
1374 : : */
1375 [ # # ]: 0 : if (types == RTE_ETH_RSS_IPV4_CHKSUM) {
1376 [ # # ]: 0 : if (bp->vnic_cap_flags & BNXT_VNIC_CAP_CHKSM_MODE)
1377 : : vnic->ring_select_mode =
1378 : : HWRM_VNIC_RSS_CFG_INPUT_RING_SELECT_MODE_TOEPLITZ_CHECKSUM;
1379 : : else
1380 : : return -ENOTSUP;
1381 : : }
1382 : :
1383 : : /* Older devices can support TOEPLITZ only.
1384 : : * Thor2 supports other hash functions, but can't change using this path.
1385 : : */
1386 : 0 : vnic->ring_select_mode =
1387 : : HWRM_VNIC_RSS_CFG_INPUT_RING_SELECT_MODE_TOEPLITZ;
1388 : 0 : vnic->hash_f_local =
1389 : : HWRM_VNIC_RSS_CFG_INPUT_RING_SELECT_MODE_TOEPLITZ;
1390 : 0 : return 0;
1391 : : }
1392 : :
1393 : 0 : void bnxt_hwrm_rss_to_rte_hash_conf(struct bnxt_vnic_info *vnic,
1394 : : uint64_t *rss_conf)
1395 : : {
1396 : : uint32_t hash_types;
1397 : :
1398 : : /* check for local shadow rte types */
1399 [ # # ]: 0 : if (vnic->rss_types_local != 0) {
1400 : 0 : *rss_conf = vnic->rss_types_local;
1401 : 0 : return;
1402 : : }
1403 : :
1404 : 0 : hash_types = vnic->hash_type;
1405 : 0 : *rss_conf = 0;
1406 [ # # ]: 0 : if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4)
1407 : 0 : *rss_conf |= RTE_ETH_RSS_IPV4;
1408 [ # # ]: 0 : if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4)
1409 : 0 : *rss_conf |= RTE_ETH_RSS_NONFRAG_IPV4_TCP;
1410 [ # # ]: 0 : if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4)
1411 : 0 : *rss_conf |= RTE_ETH_RSS_NONFRAG_IPV4_UDP;
1412 [ # # ]: 0 : if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6)
1413 : 0 : *rss_conf |= RTE_ETH_RSS_IPV6;
1414 [ # # ]: 0 : if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6)
1415 : 0 : *rss_conf |= RTE_ETH_RSS_NONFRAG_IPV6_TCP;
1416 [ # # ]: 0 : if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6)
1417 : 0 : *rss_conf |= RTE_ETH_RSS_NONFRAG_IPV6_UDP;
1418 [ # # ]: 0 : if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_AH_SPI_IPV6 ||
1419 : : hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_AH_SPI_IPV4)
1420 : 0 : *rss_conf |= RTE_ETH_RSS_AH;
1421 [ # # ]: 0 : if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_ESP_SPI_IPV6 ||
1422 : : hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_ESP_SPI_IPV4)
1423 : 0 : *rss_conf |= RTE_ETH_RSS_ESP;
1424 : : }
|