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