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