Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2017-2023 Broadcom
3 : : * All rights reserved.
4 : : */
5 : :
6 : : #include <inttypes.h>
7 : : #include <stdbool.h>
8 : : #include <unistd.h>
9 : :
10 : : #include <dev_driver.h>
11 : : #include <ethdev_driver.h>
12 : : #include <rte_malloc.h>
13 : : #include <rte_cycles.h>
14 : : #include <rte_byteorder.h>
15 : :
16 : : #include "bnxt.h"
17 : : #include "bnxt_filter.h"
18 : : #include "bnxt_hwrm.h"
19 : : #include "bnxt_vnic.h"
20 : : #include "rte_pmd_bnxt.h"
21 : : #include "hsi_struct_def_dpdk.h"
22 : :
23 : 0 : int bnxt_rcv_msg_from_vf(struct bnxt *bp, uint16_t vf_id, void *msg)
24 : : {
25 : : struct rte_pmd_bnxt_mb_event_param ret_param;
26 : :
27 : 0 : ret_param.retval = RTE_PMD_BNXT_MB_EVENT_PROCEED;
28 : 0 : ret_param.vf_id = vf_id;
29 : 0 : ret_param.msg = msg;
30 : :
31 : 0 : rte_eth_dev_callback_process(bp->eth_dev, RTE_ETH_EVENT_VF_MBOX,
32 : : &ret_param);
33 : :
34 : : /* Default to approve */
35 [ # # ]: 0 : if (ret_param.retval == RTE_PMD_BNXT_MB_EVENT_PROCEED)
36 : 0 : ret_param.retval = RTE_PMD_BNXT_MB_EVENT_NOOP_ACK;
37 : :
38 : 0 : return ret_param.retval == RTE_PMD_BNXT_MB_EVENT_NOOP_ACK ?
39 : 0 : true : false;
40 : : }
41 : :
42 : 0 : int rte_pmd_bnxt_set_tx_loopback(uint16_t port, uint8_t on)
43 : : {
44 : : struct rte_eth_dev *eth_dev;
45 : : struct bnxt *bp;
46 : : int rc;
47 : :
48 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
49 : :
50 [ # # ]: 0 : if (on > 1)
51 : : return -EINVAL;
52 : :
53 : 0 : eth_dev = &rte_eth_devices[port];
54 [ # # ]: 0 : if (!is_bnxt_supported(eth_dev))
55 : : return -ENOTSUP;
56 : :
57 : 0 : bp = eth_dev->data->dev_private;
58 : :
59 [ # # ]: 0 : if (!BNXT_PF(bp)) {
60 : 0 : PMD_DRV_LOG_LINE(ERR,
61 : : "Attempt to set Tx loopback on non-PF port %d!",
62 : : port);
63 : 0 : return -ENOTSUP;
64 : : }
65 : :
66 [ # # ]: 0 : if (on)
67 : 0 : bp->pf->evb_mode = BNXT_EVB_MODE_VEB;
68 : : else
69 : 0 : bp->pf->evb_mode = BNXT_EVB_MODE_VEPA;
70 : :
71 : 0 : rc = bnxt_hwrm_pf_evb_mode(bp);
72 : :
73 : 0 : return rc;
74 : : }
75 : :
76 : : static void
77 : 0 : rte_pmd_bnxt_set_all_queues_drop_en_cb(struct bnxt_vnic_info *vnic, void *onptr)
78 : : {
79 : : uint8_t *on = onptr;
80 : 0 : vnic->bd_stall = !(*on);
81 : 0 : }
82 : :
83 : 0 : int rte_pmd_bnxt_set_all_queues_drop_en(uint16_t port, uint8_t on)
84 : : {
85 : : struct rte_eth_dev *eth_dev;
86 : : struct bnxt *bp;
87 : : uint32_t i;
88 : : int rc = -EINVAL;
89 : :
90 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
91 : :
92 [ # # ]: 0 : if (on > 1)
93 : : return -EINVAL;
94 : :
95 : 0 : eth_dev = &rte_eth_devices[port];
96 [ # # ]: 0 : if (!is_bnxt_supported(eth_dev))
97 : : return -ENOTSUP;
98 : :
99 : 0 : bp = eth_dev->data->dev_private;
100 : :
101 [ # # ]: 0 : if (!BNXT_PF(bp)) {
102 : 0 : PMD_DRV_LOG_LINE(ERR,
103 : : "Attempt to set all queues drop on non-PF port!");
104 : 0 : return -ENOTSUP;
105 : : }
106 : :
107 [ # # ]: 0 : if (bp->vnic_info == NULL)
108 : : return -ENODEV;
109 : :
110 : : /* Stall PF */
111 [ # # ]: 0 : for (i = 0; i < bp->nr_vnics; i++) {
112 : 0 : bp->vnic_info[i].bd_stall = !on;
113 : 0 : rc = bnxt_hwrm_vnic_cfg(bp, &bp->vnic_info[i]);
114 [ # # ]: 0 : if (rc) {
115 : 0 : PMD_DRV_LOG_LINE(ERR, "Failed to update PF VNIC %d.", i);
116 : 0 : return rc;
117 : : }
118 : : }
119 : :
120 : : /* Stall all active VFs */
121 [ # # ]: 0 : for (i = 0; i < bp->pf->active_vfs; i++) {
122 : 0 : rc = bnxt_hwrm_func_vf_vnic_query_and_config(bp, i,
123 : : rte_pmd_bnxt_set_all_queues_drop_en_cb, &on,
124 : : bnxt_hwrm_vnic_cfg);
125 [ # # ]: 0 : if (rc) {
126 : 0 : PMD_DRV_LOG_LINE(ERR, "Failed to update VF VNIC %d.", i);
127 : 0 : break;
128 : : }
129 : : }
130 : :
131 : : return rc;
132 : : }
133 : :
134 : 0 : int rte_pmd_bnxt_set_vf_mac_addr(uint16_t port, uint16_t vf,
135 : : struct rte_ether_addr *mac_addr)
136 : : {
137 : : struct rte_eth_dev *dev;
138 : : struct rte_eth_dev_info dev_info;
139 : : struct bnxt *bp;
140 : : int rc;
141 : :
142 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
143 : :
144 : 0 : dev = &rte_eth_devices[port];
145 [ # # ]: 0 : if (!is_bnxt_supported(dev))
146 : : return -ENOTSUP;
147 : :
148 : 0 : rc = rte_eth_dev_info_get(port, &dev_info);
149 [ # # ]: 0 : if (rc != 0) {
150 : 0 : PMD_DRV_LOG_LINE(ERR,
151 : : "Error during getting device (port %u) info: %s",
152 : : port, strerror(-rc));
153 : :
154 : 0 : return rc;
155 : : }
156 : :
157 : 0 : bp = dev->data->dev_private;
158 : :
159 [ # # # # ]: 0 : if (vf >= dev_info.max_vfs || mac_addr == NULL)
160 : : return -EINVAL;
161 : :
162 [ # # ]: 0 : if (!BNXT_PF(bp)) {
163 : 0 : PMD_DRV_LOG_LINE(ERR,
164 : : "Attempt to set VF %d mac address on non-PF port %d!",
165 : : vf, port);
166 : 0 : return -ENOTSUP;
167 : : }
168 : :
169 : 0 : rc = bnxt_hwrm_func_vf_mac(bp, vf, (uint8_t *)mac_addr);
170 : :
171 : 0 : return rc;
172 : : }
173 : :
174 : 0 : int rte_pmd_bnxt_set_vf_rate_limit(uint16_t port, uint16_t vf,
175 : : uint32_t tx_rate, uint64_t q_msk)
176 : : {
177 : : struct rte_eth_dev *eth_dev;
178 : : struct rte_eth_dev_info dev_info;
179 : : struct bnxt *bp;
180 : : uint32_t tot_rate = 0;
181 : : uint64_t idx;
182 : : int rc;
183 : :
184 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
185 : :
186 : 0 : eth_dev = &rte_eth_devices[port];
187 [ # # ]: 0 : if (!is_bnxt_supported(eth_dev))
188 : : return -ENOTSUP;
189 : :
190 : 0 : rc = rte_eth_dev_info_get(port, &dev_info);
191 [ # # ]: 0 : if (rc != 0) {
192 : 0 : PMD_DRV_LOG_LINE(ERR,
193 : : "Error during getting device (port %u) info: %s",
194 : : port, strerror(-rc));
195 : :
196 : 0 : return rc;
197 : : }
198 : 0 : bp = eth_dev->data->dev_private;
199 : :
200 [ # # ]: 0 : if (!bp->pf->active_vfs)
201 : : return -EINVAL;
202 : :
203 [ # # ]: 0 : if (vf >= bp->pf->max_vfs)
204 : : return -EINVAL;
205 : :
206 : : /* Add up the per queue BW and configure MAX BW of the VF */
207 [ # # ]: 0 : for (idx = 0; idx < 64; idx++) {
208 [ # # ]: 0 : if ((1ULL << idx) & q_msk)
209 : 0 : tot_rate += tx_rate;
210 : : }
211 : :
212 : : /* Requested BW can't be greater than link speed */
213 [ # # ]: 0 : if (tot_rate > eth_dev->data->dev_link.link_speed) {
214 : 0 : PMD_DRV_LOG_LINE(ERR, "Rate > Link speed. Set to %d", tot_rate);
215 : 0 : return -EINVAL;
216 : : }
217 : :
218 : : /* Requested BW already configured */
219 [ # # ]: 0 : if (tot_rate == bp->pf->vf_info[vf].max_tx_rate)
220 : : return 0;
221 : :
222 : 0 : rc = bnxt_hwrm_func_bw_cfg(bp, vf, tot_rate,
223 : : HWRM_FUNC_CFG_INPUT_ENABLES_MAX_BW);
224 : :
225 [ # # ]: 0 : if (!rc)
226 : 0 : bp->pf->vf_info[vf].max_tx_rate = tot_rate;
227 : :
228 : : return rc;
229 : : }
230 : :
231 : 0 : int rte_pmd_bnxt_set_vf_mac_anti_spoof(uint16_t port, uint16_t vf, uint8_t on)
232 : : {
233 : : struct rte_eth_dev_info dev_info;
234 : : struct rte_eth_dev *dev;
235 : : uint32_t func_flags;
236 : : struct bnxt *bp;
237 : : int rc;
238 : :
239 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
240 : :
241 [ # # ]: 0 : if (on > 1)
242 : : return -EINVAL;
243 : :
244 : 0 : dev = &rte_eth_devices[port];
245 [ # # ]: 0 : if (!is_bnxt_supported(dev))
246 : : return -ENOTSUP;
247 : :
248 : 0 : rc = rte_eth_dev_info_get(port, &dev_info);
249 [ # # ]: 0 : if (rc != 0) {
250 : 0 : PMD_DRV_LOG_LINE(ERR,
251 : : "Error during getting device (port %u) info: %s",
252 : : port, strerror(-rc));
253 : :
254 : 0 : return rc;
255 : : }
256 : 0 : bp = dev->data->dev_private;
257 : :
258 [ # # ]: 0 : if (!BNXT_PF(bp)) {
259 : 0 : PMD_DRV_LOG_LINE(ERR,
260 : : "Attempt to set mac spoof on non-PF port %d!", port);
261 : 0 : return -EINVAL;
262 : : }
263 : :
264 [ # # ]: 0 : if (vf >= dev_info.max_vfs)
265 : : return -EINVAL;
266 : :
267 : : /* Prev setting same as new setting. */
268 [ # # ]: 0 : if (on == bp->pf->vf_info[vf].mac_spoof_en)
269 : : return 0;
270 : :
271 : 0 : func_flags = bp->pf->vf_info[vf].func_cfg_flags;
272 : 0 : func_flags &= ~(HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_ENABLE |
273 : : HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_DISABLE);
274 : :
275 [ # # ]: 0 : if (on)
276 : 0 : func_flags |=
277 : : HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_ENABLE;
278 : : else
279 : 0 : func_flags |=
280 : : HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_DISABLE;
281 : :
282 : 0 : rc = bnxt_hwrm_func_cfg_vf_set_flags(bp, vf, func_flags);
283 [ # # ]: 0 : if (!rc) {
284 : 0 : bp->pf->vf_info[vf].mac_spoof_en = on;
285 : 0 : bp->pf->vf_info[vf].func_cfg_flags = func_flags;
286 : : }
287 : :
288 : : return rc;
289 : : }
290 : :
291 : 0 : int rte_pmd_bnxt_set_vf_vlan_anti_spoof(uint16_t port, uint16_t vf, uint8_t on)
292 : : {
293 : : struct rte_eth_dev_info dev_info;
294 : : struct rte_eth_dev *dev;
295 : : struct bnxt *bp;
296 : : int rc;
297 : :
298 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
299 : :
300 [ # # ]: 0 : if (on > 1)
301 : : return -EINVAL;
302 : :
303 : 0 : dev = &rte_eth_devices[port];
304 [ # # ]: 0 : if (!is_bnxt_supported(dev))
305 : : return -ENOTSUP;
306 : :
307 : 0 : rc = rte_eth_dev_info_get(port, &dev_info);
308 [ # # ]: 0 : if (rc != 0) {
309 : 0 : PMD_DRV_LOG_LINE(ERR,
310 : : "Error during getting device (port %u) info: %s",
311 : : port, strerror(-rc));
312 : :
313 : 0 : return rc;
314 : : }
315 : 0 : bp = dev->data->dev_private;
316 : :
317 [ # # ]: 0 : if (!BNXT_PF(bp)) {
318 : 0 : PMD_DRV_LOG_LINE(ERR,
319 : : "Attempt to set VLAN spoof on non-PF port %d!", port);
320 : 0 : return -EINVAL;
321 : : }
322 : :
323 [ # # ]: 0 : if (vf >= dev_info.max_vfs)
324 : : return -EINVAL;
325 : :
326 : 0 : rc = bnxt_hwrm_func_cfg_vf_set_vlan_anti_spoof(bp, vf, on);
327 [ # # ]: 0 : if (!rc) {
328 : 0 : bp->pf->vf_info[vf].vlan_spoof_en = on;
329 [ # # ]: 0 : if (on) {
330 [ # # ]: 0 : if (bnxt_hwrm_cfa_vlan_antispoof_cfg(bp,
331 : 0 : bp->pf->first_vf_id + vf,
332 : 0 : bp->pf->vf_info[vf].vlan_count,
333 : : bp->pf->vf_info[vf].vlan_as_table))
334 : : rc = -1;
335 : : }
336 : : } else {
337 : 0 : PMD_DRV_LOG_LINE(ERR, "Failed to update VF VNIC %d.", vf);
338 : : }
339 : :
340 : : return rc;
341 : : }
342 : :
343 : : static void
344 : 0 : rte_pmd_bnxt_set_vf_vlan_stripq_cb(struct bnxt_vnic_info *vnic, void *onptr)
345 : : {
346 : : uint8_t *on = onptr;
347 : 0 : vnic->vlan_strip = *on;
348 : 0 : }
349 : :
350 : : int
351 : 0 : rte_pmd_bnxt_set_vf_vlan_stripq(uint16_t port, uint16_t vf, uint8_t on)
352 : : {
353 : : struct rte_eth_dev *dev;
354 : : struct rte_eth_dev_info dev_info;
355 : : struct bnxt *bp;
356 : : int rc;
357 : :
358 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
359 : :
360 : 0 : dev = &rte_eth_devices[port];
361 [ # # ]: 0 : if (!is_bnxt_supported(dev))
362 : : return -ENOTSUP;
363 : :
364 : 0 : rc = rte_eth_dev_info_get(port, &dev_info);
365 [ # # ]: 0 : if (rc != 0) {
366 : 0 : PMD_DRV_LOG_LINE(ERR,
367 : : "Error during getting device (port %u) info: %s",
368 : : port, strerror(-rc));
369 : :
370 : 0 : return rc;
371 : : }
372 : 0 : bp = dev->data->dev_private;
373 : :
374 [ # # ]: 0 : if (vf >= dev_info.max_vfs)
375 : : return -EINVAL;
376 : :
377 [ # # ]: 0 : if (!BNXT_PF(bp)) {
378 : 0 : PMD_DRV_LOG_LINE(ERR,
379 : : "Attempt to set VF %d stripq on non-PF port %d!",
380 : : vf, port);
381 : 0 : return -ENOTSUP;
382 : : }
383 : :
384 : 0 : rc = bnxt_hwrm_func_vf_vnic_query_and_config(bp, vf,
385 : : rte_pmd_bnxt_set_vf_vlan_stripq_cb, &on,
386 : : bnxt_hwrm_vnic_cfg);
387 [ # # ]: 0 : if (rc)
388 : 0 : PMD_DRV_LOG_LINE(ERR, "Failed to update VF VNIC %d.", vf);
389 : :
390 : : return rc;
391 : : }
392 : :
393 : 0 : int rte_pmd_bnxt_set_vf_rxmode(uint16_t port, uint16_t vf,
394 : : uint16_t rx_mask, uint8_t on)
395 : : {
396 : : struct rte_eth_dev *dev;
397 : : struct rte_eth_dev_info dev_info;
398 : : uint16_t flag = 0;
399 : : struct bnxt *bp;
400 : : int rc;
401 : :
402 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
403 : :
404 : 0 : dev = &rte_eth_devices[port];
405 [ # # ]: 0 : if (!is_bnxt_supported(dev))
406 : : return -ENOTSUP;
407 : :
408 : 0 : rc = rte_eth_dev_info_get(port, &dev_info);
409 [ # # ]: 0 : if (rc != 0) {
410 : 0 : PMD_DRV_LOG_LINE(ERR,
411 : : "Error during getting device (port %u) info: %s",
412 : : port, strerror(-rc));
413 : :
414 : 0 : return rc;
415 : : }
416 : 0 : bp = dev->data->dev_private;
417 : :
418 [ # # ]: 0 : if (!bp->pf->vf_info)
419 : : return -EINVAL;
420 : :
421 [ # # ]: 0 : if (vf >= bp->pdev->max_vfs)
422 : : return -EINVAL;
423 : :
424 [ # # ]: 0 : if (rx_mask & RTE_ETH_VMDQ_ACCEPT_UNTAG) {
425 : 0 : PMD_DRV_LOG_LINE(ERR, "Currently cannot toggle this setting");
426 : 0 : return -ENOTSUP;
427 : : }
428 : :
429 : : /* Is this really the correct mapping? VFd seems to think it is. */
430 [ # # ]: 0 : if (rx_mask & RTE_ETH_VMDQ_ACCEPT_HASH_UC)
431 : : flag |= BNXT_VNIC_INFO_PROMISC;
432 : :
433 [ # # ]: 0 : if (rx_mask & RTE_ETH_VMDQ_ACCEPT_BROADCAST)
434 : 0 : flag |= BNXT_VNIC_INFO_BCAST;
435 [ # # ]: 0 : if (rx_mask & RTE_ETH_VMDQ_ACCEPT_MULTICAST)
436 : 0 : flag |= BNXT_VNIC_INFO_ALLMULTI | BNXT_VNIC_INFO_MCAST;
437 : :
438 [ # # ]: 0 : if (on)
439 : 0 : bp->pf->vf_info[vf].l2_rx_mask |= flag;
440 : : else
441 : 0 : bp->pf->vf_info[vf].l2_rx_mask &= ~flag;
442 : :
443 : 0 : rc = bnxt_hwrm_func_vf_vnic_query_and_config(bp, vf,
444 : : vf_vnic_set_rxmask_cb,
445 : 0 : &bp->pf->vf_info[vf].l2_rx_mask,
446 : : bnxt_set_rx_mask_no_vlan);
447 [ # # ]: 0 : if (rc)
448 : 0 : PMD_DRV_LOG_LINE(ERR, "bnxt_hwrm_func_vf_vnic_set_rxmask failed");
449 : :
450 : : return rc;
451 : : }
452 : :
453 : 0 : static int bnxt_set_vf_table(struct bnxt *bp, uint16_t vf)
454 : : {
455 : : int rc = 0;
456 : : int dflt_vnic;
457 : : struct bnxt_vnic_info vnic;
458 : :
459 [ # # ]: 0 : if (!BNXT_PF(bp)) {
460 : 0 : PMD_DRV_LOG_LINE(ERR,
461 : : "Attempt to set VLAN table on non-PF port!");
462 : 0 : return -EINVAL;
463 : : }
464 : :
465 [ # # ]: 0 : if (vf >= bp->pdev->max_vfs)
466 : : return -EINVAL;
467 : :
468 : 0 : dflt_vnic = bnxt_hwrm_func_qcfg_vf_dflt_vnic_id(bp, vf);
469 [ # # ]: 0 : if (dflt_vnic < 0) {
470 : : /* This simply indicates there's no driver loaded.
471 : : * This is not an error.
472 : : */
473 : 0 : PMD_DRV_LOG_LINE(ERR, "Unable to get default VNIC for VF %d", vf);
474 : : } else {
475 : : memset(&vnic, 0, sizeof(vnic));
476 : 0 : vnic.fw_vnic_id = dflt_vnic;
477 [ # # ]: 0 : if (bnxt_hwrm_vnic_qcfg(bp, &vnic,
478 : 0 : bp->pf->first_vf_id + vf) == 0) {
479 [ # # ]: 0 : if (bnxt_hwrm_cfa_l2_set_rx_mask(bp, &vnic,
480 : 0 : bp->pf->vf_info[vf].vlan_count,
481 : 0 : bp->pf->vf_info[vf].vlan_table))
482 : : rc = -1;
483 : : } else {
484 : : rc = -1;
485 : : }
486 : : }
487 : :
488 : : return rc;
489 : : }
490 : :
491 : 0 : int rte_pmd_bnxt_set_vf_vlan_filter(uint16_t port, uint16_t vlan,
492 : : uint64_t vf_mask, uint8_t vlan_on)
493 : : {
494 : : struct bnxt_vlan_table_entry *ve;
495 : : struct bnxt_vlan_antispoof_table_entry *vase;
496 : : struct rte_eth_dev *dev;
497 : : struct bnxt *bp;
498 : : uint16_t cnt;
499 : : int rc = 0;
500 : : int i, j;
501 : :
502 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
503 : :
504 : 0 : dev = &rte_eth_devices[port];
505 [ # # ]: 0 : if (!is_bnxt_supported(dev))
506 : : return -ENOTSUP;
507 : :
508 : 0 : bp = dev->data->dev_private;
509 [ # # ]: 0 : if (!bp->pf->vf_info)
510 : : return -EINVAL;
511 : :
512 [ # # ]: 0 : for (i = 0; vf_mask; i++, vf_mask >>= 1) {
513 : 0 : cnt = bp->pf->vf_info[i].vlan_count;
514 [ # # ]: 0 : if ((vf_mask & 1) == 0)
515 : 0 : continue;
516 : :
517 [ # # ]: 0 : if (bp->pf->vf_info[i].vlan_table == NULL) {
518 : : rc = -1;
519 : 0 : continue;
520 : : }
521 [ # # ]: 0 : if (bp->pf->vf_info[i].vlan_as_table == NULL) {
522 : : rc = -1;
523 : 0 : continue;
524 : : }
525 [ # # ]: 0 : if (vlan_on) {
526 : : /* First, search for a duplicate... */
527 [ # # ]: 0 : for (j = 0; j < cnt; j++) {
528 [ # # ]: 0 : if (rte_be_to_cpu_16(
529 [ # # ]: 0 : bp->pf->vf_info[i].vlan_table[j].vid) ==
530 : : vlan)
531 : : break;
532 : : }
533 [ # # ]: 0 : if (j == cnt) {
534 : : /* Now check that there's space */
535 [ # # ]: 0 : if (cnt == getpagesize() / sizeof(struct
536 : : bnxt_vlan_antispoof_table_entry)) {
537 : 0 : PMD_DRV_LOG_LINE(ERR,
538 : : "VLAN anti-spoof table is full");
539 : 0 : PMD_DRV_LOG_LINE(ERR,
540 : : "VF %d cannot add VLAN %u",
541 : : i, vlan);
542 : : rc = -1;
543 : 0 : continue;
544 : : }
545 : :
546 : : /* cnt is one less than vlan_count */
547 : 0 : cnt = bp->pf->vf_info[i].vlan_count++;
548 : : /*
549 : : * And finally, add to the
550 : : * end of the table
551 : : */
552 : 0 : vase = &bp->pf->vf_info[i].vlan_as_table[cnt];
553 : : // TODO: Hardcoded TPID
554 : 0 : vase->tpid = rte_cpu_to_be_16(0x8100);
555 [ # # ]: 0 : vase->vid = rte_cpu_to_be_16(vlan);
556 : 0 : vase->mask = rte_cpu_to_be_16(0xfff);
557 : 0 : ve = &bp->pf->vf_info[i].vlan_table[cnt];
558 : : /* TODO: Hardcoded TPID */
559 : 0 : ve->tpid = rte_cpu_to_be_16(0x8100);
560 [ # # ]: 0 : ve->vid = rte_cpu_to_be_16(vlan);
561 : : }
562 : : } else {
563 [ # # ]: 0 : for (j = 0; j < cnt; j++) {
564 [ # # ]: 0 : if (rte_be_to_cpu_16(
565 [ # # ]: 0 : bp->pf->vf_info[i].vlan_table[j].vid) !=
566 : : vlan)
567 : 0 : continue;
568 : 0 : memmove(&bp->pf->vf_info[i].vlan_table[j],
569 : 0 : &bp->pf->vf_info[i].vlan_table[j + 1],
570 : 0 : getpagesize() - ((j + 1) *
571 : : sizeof(struct bnxt_vlan_table_entry)));
572 : 0 : memmove(&bp->pf->vf_info[i].vlan_as_table[j],
573 : 0 : &bp->pf->vf_info[i].vlan_as_table[j + 1],
574 : 0 : getpagesize() - ((j + 1) * sizeof(struct
575 : : bnxt_vlan_antispoof_table_entry)));
576 : 0 : j--;
577 : 0 : cnt = --bp->pf->vf_info[i].vlan_count;
578 : : }
579 : : }
580 : 0 : bnxt_set_vf_table(bp, i);
581 : : }
582 : :
583 : : return rc;
584 : : }
585 : :
586 : 0 : int rte_pmd_bnxt_get_vf_stats(uint16_t port,
587 : : uint16_t vf_id,
588 : : struct rte_eth_stats *stats)
589 : : {
590 : : struct rte_eth_dev *dev;
591 : : struct rte_eth_dev_info dev_info;
592 : : struct bnxt *bp;
593 : : int rc;
594 : :
595 : 0 : dev = &rte_eth_devices[port];
596 [ # # ]: 0 : if (!is_bnxt_supported(dev))
597 : : return -ENOTSUP;
598 : :
599 : 0 : rc = rte_eth_dev_info_get(port, &dev_info);
600 [ # # ]: 0 : if (rc != 0) {
601 : 0 : PMD_DRV_LOG_LINE(ERR,
602 : : "Error during getting device (port %u) info: %s",
603 : : port, strerror(-rc));
604 : :
605 : 0 : return rc;
606 : : }
607 : 0 : bp = dev->data->dev_private;
608 : :
609 [ # # ]: 0 : if (vf_id >= dev_info.max_vfs)
610 : : return -EINVAL;
611 : :
612 [ # # ]: 0 : if (!BNXT_PF(bp)) {
613 : 0 : PMD_DRV_LOG_LINE(ERR,
614 : : "Attempt to get VF %d stats on non-PF port %d!",
615 : : vf_id, port);
616 : 0 : return -ENOTSUP;
617 : : }
618 : :
619 : 0 : return bnxt_hwrm_func_qstats(bp, bp->pf->first_vf_id + vf_id, stats,
620 : : NULL);
621 : : }
622 : :
623 : 0 : int rte_pmd_bnxt_reset_vf_stats(uint16_t port,
624 : : uint16_t vf_id)
625 : : {
626 : : struct rte_eth_dev *dev;
627 : : struct rte_eth_dev_info dev_info;
628 : : struct bnxt *bp;
629 : : int rc;
630 : :
631 : 0 : dev = &rte_eth_devices[port];
632 [ # # ]: 0 : if (!is_bnxt_supported(dev))
633 : : return -ENOTSUP;
634 : :
635 : 0 : rc = rte_eth_dev_info_get(port, &dev_info);
636 [ # # ]: 0 : if (rc != 0) {
637 : 0 : PMD_DRV_LOG_LINE(ERR,
638 : : "Error during getting device (port %u) info: %s",
639 : : port, strerror(-rc));
640 : :
641 : 0 : return rc;
642 : : }
643 : 0 : bp = dev->data->dev_private;
644 : :
645 [ # # ]: 0 : if (vf_id >= dev_info.max_vfs)
646 : : return -EINVAL;
647 : :
648 [ # # ]: 0 : if (!BNXT_PF(bp)) {
649 : 0 : PMD_DRV_LOG_LINE(ERR,
650 : : "Attempt to reset VF %d stats on non-PF port %d!",
651 : : vf_id, port);
652 : 0 : return -ENOTSUP;
653 : : }
654 : :
655 : 0 : return bnxt_hwrm_func_clr_stats(bp, bp->pf->first_vf_id + vf_id);
656 : : }
657 : :
658 : 0 : int rte_pmd_bnxt_get_vf_rx_status(uint16_t port, uint16_t vf_id)
659 : : {
660 : : struct rte_eth_dev *dev;
661 : : struct rte_eth_dev_info dev_info;
662 : : struct bnxt *bp;
663 : : int rc;
664 : :
665 : 0 : dev = &rte_eth_devices[port];
666 [ # # ]: 0 : if (!is_bnxt_supported(dev))
667 : : return -ENOTSUP;
668 : :
669 : 0 : rc = rte_eth_dev_info_get(port, &dev_info);
670 [ # # ]: 0 : if (rc != 0) {
671 : 0 : PMD_DRV_LOG_LINE(ERR,
672 : : "Error during getting device (port %u) info: %s",
673 : : port, strerror(-rc));
674 : :
675 : 0 : return rc;
676 : : }
677 : 0 : bp = dev->data->dev_private;
678 : :
679 [ # # ]: 0 : if (vf_id >= dev_info.max_vfs)
680 : : return -EINVAL;
681 : :
682 [ # # ]: 0 : if (!BNXT_PF(bp)) {
683 : 0 : PMD_DRV_LOG_LINE(ERR,
684 : : "Attempt to query VF %d RX stats on non-PF port %d!",
685 : : vf_id, port);
686 : 0 : return -ENOTSUP;
687 : : }
688 : :
689 : 0 : return bnxt_vf_vnic_count(bp, vf_id);
690 : : }
691 : :
692 : 0 : int rte_pmd_bnxt_get_vf_tx_drop_count(uint16_t port, uint16_t vf_id,
693 : : uint64_t *count)
694 : : {
695 : : struct rte_eth_dev *dev;
696 : : struct rte_eth_dev_info dev_info;
697 : : struct bnxt *bp;
698 : : int rc;
699 : :
700 : 0 : dev = &rte_eth_devices[port];
701 [ # # ]: 0 : if (!is_bnxt_supported(dev))
702 : : return -ENOTSUP;
703 : :
704 : 0 : rc = rte_eth_dev_info_get(port, &dev_info);
705 [ # # ]: 0 : if (rc != 0) {
706 : 0 : PMD_DRV_LOG_LINE(ERR,
707 : : "Error during getting device (port %u) info: %s",
708 : : port, strerror(-rc));
709 : :
710 : 0 : return rc;
711 : : }
712 : 0 : bp = dev->data->dev_private;
713 : :
714 [ # # ]: 0 : if (vf_id >= dev_info.max_vfs)
715 : : return -EINVAL;
716 : :
717 [ # # ]: 0 : if (!BNXT_PF(bp)) {
718 : 0 : PMD_DRV_LOG_LINE(ERR,
719 : : "Attempt to query VF %d TX drops on non-PF port %d!",
720 : : vf_id, port);
721 : 0 : return -ENOTSUP;
722 : : }
723 : :
724 : 0 : return bnxt_hwrm_func_qstats_tx_drop(bp, bp->pf->first_vf_id + vf_id,
725 : : count);
726 : : }
727 : :
728 : 0 : int rte_pmd_bnxt_mac_addr_add(uint16_t port, struct rte_ether_addr *addr,
729 : : uint32_t vf_id)
730 : : {
731 : : struct rte_eth_dev *dev;
732 : : struct rte_eth_dev_info dev_info;
733 : : struct bnxt *bp;
734 : : struct bnxt_filter_info *filter;
735 : : struct bnxt_vnic_info vnic;
736 : : struct rte_ether_addr dflt_mac;
737 : : int rc;
738 : :
739 : 0 : dev = &rte_eth_devices[port];
740 [ # # ]: 0 : if (!is_bnxt_supported(dev))
741 : : return -ENOTSUP;
742 : :
743 : 0 : rc = rte_eth_dev_info_get(port, &dev_info);
744 [ # # ]: 0 : if (rc != 0) {
745 : 0 : PMD_DRV_LOG_LINE(ERR,
746 : : "Error during getting device (port %u) info: %s",
747 : : port, strerror(-rc));
748 : :
749 : 0 : return rc;
750 : : }
751 : 0 : bp = dev->data->dev_private;
752 : :
753 [ # # ]: 0 : if (vf_id >= dev_info.max_vfs)
754 : : return -EINVAL;
755 : :
756 [ # # ]: 0 : if (!BNXT_PF(bp)) {
757 : 0 : PMD_DRV_LOG_LINE(ERR,
758 : : "Attempt to config VF %d MAC on non-PF port %d!",
759 : : vf_id, port);
760 : 0 : return -ENOTSUP;
761 : : }
762 : :
763 : : /* If the VF currently uses a random MAC, update default to this one */
764 [ # # ]: 0 : if (bp->pf->vf_info[vf_id].random_mac) {
765 [ # # ]: 0 : if (rte_pmd_bnxt_get_vf_rx_status(port, vf_id) <= 0)
766 : 0 : bnxt_hwrm_func_vf_mac(bp, vf_id, (uint8_t *)addr);
767 : : }
768 : :
769 : : /* query the default VNIC id used by the function */
770 : 0 : rc = bnxt_hwrm_func_qcfg_vf_dflt_vnic_id(bp, vf_id);
771 [ # # ]: 0 : if (rc < 0)
772 : 0 : goto exit;
773 : :
774 : : memset(&vnic, 0, sizeof(struct bnxt_vnic_info));
775 : 0 : vnic.fw_vnic_id = rte_le_to_cpu_16(rc);
776 : 0 : rc = bnxt_hwrm_vnic_qcfg(bp, &vnic, bp->pf->first_vf_id + vf_id);
777 [ # # ]: 0 : if (rc < 0)
778 : 0 : goto exit;
779 : :
780 [ # # ]: 0 : STAILQ_FOREACH(filter, &bp->pf->vf_info[vf_id].filter, next) {
781 : 0 : if (filter->flags ==
782 [ # # ]: 0 : HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX &&
783 : : filter->enables ==
784 : : (HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR |
785 : 0 : HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR_MASK) &&
786 [ # # ]: 0 : memcmp(addr, filter->l2_addr, RTE_ETHER_ADDR_LEN) == 0) {
787 : 0 : bnxt_hwrm_clear_l2_filter(bp, filter);
788 : 0 : break;
789 : : }
790 : : }
791 : :
792 [ # # ]: 0 : if (filter == NULL)
793 : 0 : filter = bnxt_alloc_vf_filter(bp, vf_id);
794 : :
795 : 0 : filter->fw_l2_filter_id = UINT64_MAX;
796 : 0 : filter->flags = HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX;
797 : 0 : filter->enables = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR |
798 : : HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR_MASK;
799 : 0 : memcpy(filter->l2_addr, addr, RTE_ETHER_ADDR_LEN);
800 : 0 : memset(filter->l2_addr_mask, 0xff, RTE_ETHER_ADDR_LEN);
801 : :
802 : : /* Do not add a filter for the default MAC */
803 [ # # ]: 0 : if (bnxt_hwrm_func_qcfg_vf_default_mac(bp, vf_id, &dflt_mac) ||
804 [ # # ]: 0 : memcmp(filter->l2_addr, dflt_mac.addr_bytes, RTE_ETHER_ADDR_LEN))
805 : 0 : rc = bnxt_hwrm_set_l2_filter(bp, vnic.fw_vnic_id, filter);
806 : :
807 : 0 : exit:
808 : : return rc;
809 : : }
810 : :
811 : : int
812 : 0 : rte_pmd_bnxt_set_vf_vlan_insert(uint16_t port, uint16_t vf,
813 : : uint16_t vlan_id)
814 : : {
815 : : struct rte_eth_dev *dev;
816 : : struct rte_eth_dev_info dev_info;
817 : : struct bnxt *bp;
818 : : int rc;
819 : :
820 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
821 : :
822 : 0 : dev = &rte_eth_devices[port];
823 [ # # ]: 0 : if (!is_bnxt_supported(dev))
824 : : return -ENOTSUP;
825 : :
826 : 0 : rc = rte_eth_dev_info_get(port, &dev_info);
827 [ # # ]: 0 : if (rc != 0) {
828 : 0 : PMD_DRV_LOG_LINE(ERR,
829 : : "Error during getting device (port %u) info: %s",
830 : : port, strerror(-rc));
831 : :
832 : 0 : return rc;
833 : : }
834 : 0 : bp = dev->data->dev_private;
835 : :
836 [ # # ]: 0 : if (vf >= dev_info.max_vfs)
837 : : return -EINVAL;
838 : :
839 [ # # ]: 0 : if (!BNXT_PF(bp)) {
840 : 0 : PMD_DRV_LOG_LINE(ERR,
841 : : "Attempt to set VF %d vlan insert on non-PF port %d!",
842 : : vf, port);
843 : 0 : return -ENOTSUP;
844 : : }
845 : :
846 : 0 : bp->pf->vf_info[vf].dflt_vlan = vlan_id;
847 : 0 : if (bnxt_hwrm_func_qcfg_current_vf_vlan(bp, vf) ==
848 [ # # ]: 0 : bp->pf->vf_info[vf].dflt_vlan)
849 : : return 0;
850 : :
851 : 0 : rc = bnxt_hwrm_set_vf_vlan(bp, vf);
852 : :
853 : 0 : return rc;
854 : : }
855 : :
856 : 0 : int rte_pmd_bnxt_set_vf_persist_stats(uint16_t port, uint16_t vf, uint8_t on)
857 : : {
858 : : struct rte_eth_dev_info dev_info;
859 : : struct rte_eth_dev *dev;
860 : : uint32_t func_flags;
861 : : struct bnxt *bp;
862 : : int rc;
863 : :
864 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
865 : :
866 [ # # ]: 0 : if (on > 1)
867 : : return -EINVAL;
868 : :
869 : : dev = &rte_eth_devices[port];
870 : 0 : rc = rte_eth_dev_info_get(port, &dev_info);
871 [ # # ]: 0 : if (rc != 0) {
872 : 0 : PMD_DRV_LOG_LINE(ERR,
873 : : "Error during getting device (port %u) info: %s",
874 : : port, strerror(-rc));
875 : :
876 : 0 : return rc;
877 : : }
878 : 0 : bp = dev->data->dev_private;
879 : :
880 [ # # ]: 0 : if (!BNXT_PF(bp)) {
881 : 0 : PMD_DRV_LOG_LINE(ERR,
882 : : "Attempt to set persist stats on non-PF port %d!",
883 : : port);
884 : 0 : return -EINVAL;
885 : : }
886 : :
887 [ # # ]: 0 : if (vf >= dev_info.max_vfs)
888 : : return -EINVAL;
889 : :
890 : : /* Prev setting same as new setting. */
891 [ # # ]: 0 : if (on == bp->pf->vf_info[vf].persist_stats)
892 : : return 0;
893 : :
894 : 0 : func_flags = bp->pf->vf_info[vf].func_cfg_flags;
895 : :
896 [ # # ]: 0 : if (on)
897 : 0 : func_flags |=
898 : : HWRM_FUNC_CFG_INPUT_FLAGS_NO_AUTOCLEAR_STATISTIC;
899 : : else
900 : 0 : func_flags &=
901 : : ~HWRM_FUNC_CFG_INPUT_FLAGS_NO_AUTOCLEAR_STATISTIC;
902 : :
903 : 0 : rc = bnxt_hwrm_func_cfg_vf_set_flags(bp, vf, func_flags);
904 [ # # ]: 0 : if (!rc) {
905 : 0 : bp->pf->vf_info[vf].persist_stats = on;
906 : 0 : bp->pf->vf_info[vf].func_cfg_flags = func_flags;
907 : : }
908 : :
909 : : return rc;
910 : : }
|