1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2017-2018 Broadcom
11 #include <rte_ethdev_driver.h>
12 #include <rte_malloc.h>
13 #include <rte_cycles.h>
14 #include <rte_byteorder.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"
23 int bnxt_rcv_msg_from_vf(struct bnxt *bp, uint16_t vf_id, void *msg)
25 struct rte_pmd_bnxt_mb_event_param ret_param;
27 ret_param.retval = RTE_PMD_BNXT_MB_EVENT_PROCEED;
28 ret_param.vf_id = vf_id;
31 _rte_eth_dev_callback_process(bp->eth_dev, RTE_ETH_EVENT_VF_MBOX,
34 /* Default to approve */
35 if (ret_param.retval == RTE_PMD_BNXT_MB_EVENT_PROCEED)
36 ret_param.retval = RTE_PMD_BNXT_MB_EVENT_NOOP_ACK;
38 return ret_param.retval == RTE_PMD_BNXT_MB_EVENT_NOOP_ACK ?
42 int rte_pmd_bnxt_set_tx_loopback(uint16_t port, uint8_t on)
44 struct rte_eth_dev *eth_dev;
48 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
53 eth_dev = &rte_eth_devices[port];
54 if (!is_bnxt_supported(eth_dev))
57 bp = (struct bnxt *)eth_dev->data->dev_private;
61 "Attempt to set Tx loopback on non-PF port %d!\n",
67 bp->pf.evb_mode = BNXT_EVB_MODE_VEB;
69 bp->pf.evb_mode = BNXT_EVB_MODE_VEPA;
71 rc = bnxt_hwrm_pf_evb_mode(bp);
77 rte_pmd_bnxt_set_all_queues_drop_en_cb(struct bnxt_vnic_info *vnic, void *onptr)
80 vnic->bd_stall = !(*on);
83 int rte_pmd_bnxt_set_all_queues_drop_en(uint16_t port, uint8_t on)
85 struct rte_eth_dev *eth_dev;
90 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
95 eth_dev = &rte_eth_devices[port];
96 if (!is_bnxt_supported(eth_dev))
99 bp = (struct bnxt *)eth_dev->data->dev_private;
103 "Attempt to set all queues drop on non-PF port!\n");
107 if (bp->vnic_info == NULL)
111 for (i = 0; i < bp->nr_vnics; i++) {
112 bp->vnic_info[i].bd_stall = !on;
113 rc = bnxt_hwrm_vnic_cfg(bp, &bp->vnic_info[i]);
115 PMD_DRV_LOG(ERR, "Failed to update PF VNIC %d.\n", i);
120 /* Stall all active VFs */
121 for (i = 0; i < bp->pf.active_vfs; i++) {
122 rc = bnxt_hwrm_func_vf_vnic_query_and_config(bp, i,
123 rte_pmd_bnxt_set_all_queues_drop_en_cb, &on,
126 PMD_DRV_LOG(ERR, "Failed to update VF VNIC %d.\n", i);
134 int rte_pmd_bnxt_set_vf_mac_addr(uint16_t port, uint16_t vf,
135 struct rte_ether_addr *mac_addr)
137 struct rte_eth_dev *dev;
138 struct rte_eth_dev_info dev_info;
142 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
144 dev = &rte_eth_devices[port];
145 if (!is_bnxt_supported(dev))
148 rte_eth_dev_info_get(port, &dev_info);
149 bp = (struct bnxt *)dev->data->dev_private;
151 if (vf >= dev_info.max_vfs || mac_addr == NULL)
156 "Attempt to set VF %d mac address on non-PF port %d!\n",
161 rc = bnxt_hwrm_func_vf_mac(bp, vf, (uint8_t *)mac_addr);
166 int rte_pmd_bnxt_set_vf_rate_limit(uint16_t port, uint16_t vf,
167 uint16_t tx_rate, uint64_t q_msk)
169 struct rte_eth_dev *eth_dev;
170 struct rte_eth_dev_info dev_info;
172 uint16_t tot_rate = 0;
176 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
178 eth_dev = &rte_eth_devices[port];
179 if (!is_bnxt_supported(eth_dev))
182 rte_eth_dev_info_get(port, &dev_info);
183 bp = (struct bnxt *)eth_dev->data->dev_private;
185 if (!bp->pf.active_vfs)
188 if (vf >= bp->pf.max_vfs)
191 /* Add up the per queue BW and configure MAX BW of the VF */
192 for (idx = 0; idx < 64; idx++) {
193 if ((1ULL << idx) & q_msk)
197 /* Requested BW can't be greater than link speed */
198 if (tot_rate > eth_dev->data->dev_link.link_speed) {
199 PMD_DRV_LOG(ERR, "Rate > Link speed. Set to %d\n", tot_rate);
203 /* Requested BW already configured */
204 if (tot_rate == bp->pf.vf_info[vf].max_tx_rate)
207 rc = bnxt_hwrm_func_bw_cfg(bp, vf, tot_rate,
208 HWRM_FUNC_CFG_INPUT_ENABLES_MAX_BW);
211 bp->pf.vf_info[vf].max_tx_rate = tot_rate;
216 int rte_pmd_bnxt_set_vf_mac_anti_spoof(uint16_t port, uint16_t vf, uint8_t on)
218 struct rte_eth_dev_info dev_info;
219 struct rte_eth_dev *dev;
224 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
229 dev = &rte_eth_devices[port];
230 if (!is_bnxt_supported(dev))
233 rte_eth_dev_info_get(port, &dev_info);
234 bp = (struct bnxt *)dev->data->dev_private;
238 "Attempt to set mac spoof on non-PF port %d!\n", port);
242 if (vf >= dev_info.max_vfs)
245 /* Prev setting same as new setting. */
246 if (on == bp->pf.vf_info[vf].mac_spoof_en)
249 func_flags = bp->pf.vf_info[vf].func_cfg_flags;
250 func_flags &= ~(HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_ENABLE |
251 HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_DISABLE);
255 HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_ENABLE;
258 HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_DISABLE;
260 rc = bnxt_hwrm_func_cfg_vf_set_flags(bp, vf, func_flags);
262 bp->pf.vf_info[vf].mac_spoof_en = on;
263 bp->pf.vf_info[vf].func_cfg_flags = func_flags;
269 int rte_pmd_bnxt_set_vf_vlan_anti_spoof(uint16_t port, uint16_t vf, uint8_t on)
271 struct rte_eth_dev_info dev_info;
272 struct rte_eth_dev *dev;
276 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
281 dev = &rte_eth_devices[port];
282 if (!is_bnxt_supported(dev))
285 rte_eth_dev_info_get(port, &dev_info);
286 bp = (struct bnxt *)dev->data->dev_private;
290 "Attempt to set VLAN spoof on non-PF port %d!\n", port);
294 if (vf >= dev_info.max_vfs)
297 rc = bnxt_hwrm_func_cfg_vf_set_vlan_anti_spoof(bp, vf, on);
299 bp->pf.vf_info[vf].vlan_spoof_en = on;
301 if (bnxt_hwrm_cfa_vlan_antispoof_cfg(bp,
302 bp->pf.first_vf_id + vf,
303 bp->pf.vf_info[vf].vlan_count,
304 bp->pf.vf_info[vf].vlan_as_table))
308 PMD_DRV_LOG(ERR, "Failed to update VF VNIC %d.\n", vf);
315 rte_pmd_bnxt_set_vf_vlan_stripq_cb(struct bnxt_vnic_info *vnic, void *onptr)
318 vnic->vlan_strip = *on;
322 rte_pmd_bnxt_set_vf_vlan_stripq(uint16_t port, uint16_t vf, uint8_t on)
324 struct rte_eth_dev *dev;
325 struct rte_eth_dev_info dev_info;
329 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
331 dev = &rte_eth_devices[port];
332 if (!is_bnxt_supported(dev))
335 rte_eth_dev_info_get(port, &dev_info);
336 bp = (struct bnxt *)dev->data->dev_private;
338 if (vf >= dev_info.max_vfs)
343 "Attempt to set VF %d stripq on non-PF port %d!\n",
348 rc = bnxt_hwrm_func_vf_vnic_query_and_config(bp, vf,
349 rte_pmd_bnxt_set_vf_vlan_stripq_cb, &on,
352 PMD_DRV_LOG(ERR, "Failed to update VF VNIC %d.\n", vf);
357 int rte_pmd_bnxt_set_vf_rxmode(uint16_t port, uint16_t vf,
358 uint16_t rx_mask, uint8_t on)
360 struct rte_eth_dev *dev;
361 struct rte_eth_dev_info dev_info;
366 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
368 dev = &rte_eth_devices[port];
369 if (!is_bnxt_supported(dev))
372 rte_eth_dev_info_get(port, &dev_info);
373 bp = (struct bnxt *)dev->data->dev_private;
378 if (vf >= bp->pdev->max_vfs)
381 if (rx_mask & ETH_VMDQ_ACCEPT_UNTAG) {
382 PMD_DRV_LOG(ERR, "Currently cannot toggle this setting\n");
386 /* Is this really the correct mapping? VFd seems to think it is. */
387 if (rx_mask & ETH_VMDQ_ACCEPT_HASH_UC)
388 flag |= BNXT_VNIC_INFO_PROMISC;
390 if (rx_mask & ETH_VMDQ_ACCEPT_BROADCAST)
391 flag |= BNXT_VNIC_INFO_BCAST;
392 if (rx_mask & ETH_VMDQ_ACCEPT_MULTICAST)
393 flag |= BNXT_VNIC_INFO_ALLMULTI | BNXT_VNIC_INFO_MCAST;
396 bp->pf.vf_info[vf].l2_rx_mask |= flag;
398 bp->pf.vf_info[vf].l2_rx_mask &= ~flag;
400 rc = bnxt_hwrm_func_vf_vnic_query_and_config(bp, vf,
401 vf_vnic_set_rxmask_cb,
402 &bp->pf.vf_info[vf].l2_rx_mask,
403 bnxt_set_rx_mask_no_vlan);
405 PMD_DRV_LOG(ERR, "bnxt_hwrm_func_vf_vnic_set_rxmask failed\n");
410 static int bnxt_set_vf_table(struct bnxt *bp, uint16_t vf)
414 struct bnxt_vnic_info vnic;
418 "Attempt to set VLAN table on non-PF port!\n");
422 if (vf >= bp->pdev->max_vfs)
425 dflt_vnic = bnxt_hwrm_func_qcfg_vf_dflt_vnic_id(bp, vf);
427 /* This simply indicates there's no driver loaded.
428 * This is not an error.
430 PMD_DRV_LOG(ERR, "Unable to get default VNIC for VF %d\n", vf);
432 memset(&vnic, 0, sizeof(vnic));
433 vnic.fw_vnic_id = dflt_vnic;
434 if (bnxt_hwrm_vnic_qcfg(bp, &vnic,
435 bp->pf.first_vf_id + vf) == 0) {
436 if (bnxt_hwrm_cfa_l2_set_rx_mask(bp, &vnic,
437 bp->pf.vf_info[vf].vlan_count,
438 bp->pf.vf_info[vf].vlan_table))
448 int rte_pmd_bnxt_set_vf_vlan_filter(uint16_t port, uint16_t vlan,
449 uint64_t vf_mask, uint8_t vlan_on)
451 struct bnxt_vlan_table_entry *ve;
452 struct bnxt_vlan_antispoof_table_entry *vase;
453 struct rte_eth_dev *dev;
459 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
461 dev = &rte_eth_devices[port];
462 if (!is_bnxt_supported(dev))
465 bp = (struct bnxt *)dev->data->dev_private;
469 for (i = 0; vf_mask; i++, vf_mask >>= 1) {
470 cnt = bp->pf.vf_info[i].vlan_count;
471 if ((vf_mask & 1) == 0)
474 if (bp->pf.vf_info[i].vlan_table == NULL) {
478 if (bp->pf.vf_info[i].vlan_as_table == NULL) {
483 /* First, search for a duplicate... */
484 for (j = 0; j < cnt; j++) {
485 if (rte_be_to_cpu_16(
486 bp->pf.vf_info[i].vlan_table[j].vid) == vlan)
490 /* Now check that there's space */
491 if (cnt == getpagesize() / sizeof(struct
492 bnxt_vlan_antispoof_table_entry)) {
494 "VLAN anti-spoof table is full\n");
496 "VF %d cannot add VLAN %u\n",
502 /* cnt is one less than vlan_count */
503 cnt = bp->pf.vf_info[i].vlan_count++;
505 * And finally, add to the
508 vase = &bp->pf.vf_info[i].vlan_as_table[cnt];
509 // TODO: Hardcoded TPID
510 vase->tpid = rte_cpu_to_be_16(0x8100);
511 vase->vid = rte_cpu_to_be_16(vlan);
512 vase->mask = rte_cpu_to_be_16(0xfff);
513 ve = &bp->pf.vf_info[i].vlan_table[cnt];
514 /* TODO: Hardcoded TPID */
515 ve->tpid = rte_cpu_to_be_16(0x8100);
516 ve->vid = rte_cpu_to_be_16(vlan);
519 for (j = 0; j < cnt; j++) {
520 if (rte_be_to_cpu_16(
521 bp->pf.vf_info[i].vlan_table[j].vid) != vlan)
523 memmove(&bp->pf.vf_info[i].vlan_table[j],
524 &bp->pf.vf_info[i].vlan_table[j + 1],
525 getpagesize() - ((j + 1) *
526 sizeof(struct bnxt_vlan_table_entry)));
527 memmove(&bp->pf.vf_info[i].vlan_as_table[j],
528 &bp->pf.vf_info[i].vlan_as_table[j + 1],
529 getpagesize() - ((j + 1) * sizeof(struct
530 bnxt_vlan_antispoof_table_entry)));
532 cnt = --bp->pf.vf_info[i].vlan_count;
535 bnxt_set_vf_table(bp, i);
541 int rte_pmd_bnxt_get_vf_stats(uint16_t port,
543 struct rte_eth_stats *stats)
545 struct rte_eth_dev *dev;
546 struct rte_eth_dev_info dev_info;
549 dev = &rte_eth_devices[port];
550 if (!is_bnxt_supported(dev))
553 rte_eth_dev_info_get(port, &dev_info);
554 bp = (struct bnxt *)dev->data->dev_private;
556 if (vf_id >= dev_info.max_vfs)
561 "Attempt to get VF %d stats on non-PF port %d!\n",
566 return bnxt_hwrm_func_qstats(bp, bp->pf.first_vf_id + vf_id, stats);
569 int rte_pmd_bnxt_reset_vf_stats(uint16_t port,
572 struct rte_eth_dev *dev;
573 struct rte_eth_dev_info dev_info;
576 dev = &rte_eth_devices[port];
577 if (!is_bnxt_supported(dev))
580 rte_eth_dev_info_get(port, &dev_info);
581 bp = (struct bnxt *)dev->data->dev_private;
583 if (vf_id >= dev_info.max_vfs)
588 "Attempt to reset VF %d stats on non-PF port %d!\n",
593 return bnxt_hwrm_func_clr_stats(bp, bp->pf.first_vf_id + vf_id);
596 int rte_pmd_bnxt_get_vf_rx_status(uint16_t port, uint16_t vf_id)
598 struct rte_eth_dev *dev;
599 struct rte_eth_dev_info dev_info;
602 dev = &rte_eth_devices[port];
603 if (!is_bnxt_supported(dev))
606 rte_eth_dev_info_get(port, &dev_info);
607 bp = (struct bnxt *)dev->data->dev_private;
609 if (vf_id >= dev_info.max_vfs)
614 "Attempt to query VF %d RX stats on non-PF port %d!\n",
619 return bnxt_vf_vnic_count(bp, vf_id);
622 int rte_pmd_bnxt_get_vf_tx_drop_count(uint16_t port, uint16_t vf_id,
625 struct rte_eth_dev *dev;
626 struct rte_eth_dev_info dev_info;
629 dev = &rte_eth_devices[port];
630 if (!is_bnxt_supported(dev))
633 rte_eth_dev_info_get(port, &dev_info);
634 bp = (struct bnxt *)dev->data->dev_private;
636 if (vf_id >= dev_info.max_vfs)
641 "Attempt to query VF %d TX drops on non-PF port %d!\n",
646 return bnxt_hwrm_func_qstats_tx_drop(bp, bp->pf.first_vf_id + vf_id,
650 int rte_pmd_bnxt_mac_addr_add(uint16_t port, struct rte_ether_addr *addr,
653 struct rte_eth_dev *dev;
654 struct rte_eth_dev_info dev_info;
656 struct bnxt_filter_info *filter;
657 struct bnxt_vnic_info vnic;
658 struct rte_ether_addr dflt_mac;
661 dev = &rte_eth_devices[port];
662 if (!is_bnxt_supported(dev))
665 rte_eth_dev_info_get(port, &dev_info);
666 bp = (struct bnxt *)dev->data->dev_private;
668 if (vf_id >= dev_info.max_vfs)
673 "Attempt to config VF %d MAC on non-PF port %d!\n",
678 /* If the VF currently uses a random MAC, update default to this one */
679 if (bp->pf.vf_info[vf_id].random_mac) {
680 if (rte_pmd_bnxt_get_vf_rx_status(port, vf_id) <= 0)
681 bnxt_hwrm_func_vf_mac(bp, vf_id, (uint8_t *)addr);
684 /* query the default VNIC id used by the function */
685 rc = bnxt_hwrm_func_qcfg_vf_dflt_vnic_id(bp, vf_id);
689 memset(&vnic, 0, sizeof(struct bnxt_vnic_info));
690 vnic.fw_vnic_id = rte_le_to_cpu_16(rc);
691 rc = bnxt_hwrm_vnic_qcfg(bp, &vnic, bp->pf.first_vf_id + vf_id);
695 STAILQ_FOREACH(filter, &bp->pf.vf_info[vf_id].filter, next) {
697 HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX &&
699 (HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR |
700 HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR_MASK) &&
701 memcmp(addr, filter->l2_addr, ETHER_ADDR_LEN) == 0) {
702 bnxt_hwrm_clear_l2_filter(bp, filter);
708 filter = bnxt_alloc_vf_filter(bp, vf_id);
710 filter->fw_l2_filter_id = UINT64_MAX;
711 filter->flags = HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX;
712 filter->enables = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR |
713 HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR_MASK;
714 memcpy(filter->l2_addr, addr, ETHER_ADDR_LEN);
715 memset(filter->l2_addr_mask, 0xff, ETHER_ADDR_LEN);
717 /* Do not add a filter for the default MAC */
718 if (bnxt_hwrm_func_qcfg_vf_default_mac(bp, vf_id, &dflt_mac) ||
719 memcmp(filter->l2_addr, dflt_mac.addr_bytes, ETHER_ADDR_LEN))
720 rc = bnxt_hwrm_set_l2_filter(bp, vnic.fw_vnic_id, filter);
727 rte_pmd_bnxt_set_vf_vlan_insert(uint16_t port, uint16_t vf,
730 struct rte_eth_dev *dev;
731 struct rte_eth_dev_info dev_info;
735 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
737 dev = &rte_eth_devices[port];
738 if (!is_bnxt_supported(dev))
741 rte_eth_dev_info_get(port, &dev_info);
742 bp = (struct bnxt *)dev->data->dev_private;
744 if (vf >= dev_info.max_vfs)
749 "Attempt to set VF %d vlan insert on non-PF port %d!\n",
754 bp->pf.vf_info[vf].dflt_vlan = vlan_id;
755 if (bnxt_hwrm_func_qcfg_current_vf_vlan(bp, vf) ==
756 bp->pf.vf_info[vf].dflt_vlan)
759 rc = bnxt_hwrm_set_vf_vlan(bp, vf);
764 int rte_pmd_bnxt_set_vf_persist_stats(uint16_t port, uint16_t vf, uint8_t on)
766 struct rte_eth_dev_info dev_info;
767 struct rte_eth_dev *dev;
772 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
777 dev = &rte_eth_devices[port];
778 rte_eth_dev_info_get(port, &dev_info);
779 bp = (struct bnxt *)dev->data->dev_private;
783 "Attempt to set persist stats on non-PF port %d!\n",
788 if (vf >= dev_info.max_vfs)
791 /* Prev setting same as new setting. */
792 if (on == bp->pf.vf_info[vf].persist_stats)
795 func_flags = bp->pf.vf_info[vf].func_cfg_flags;
799 HWRM_FUNC_CFG_INPUT_FLAGS_NO_AUTOCLEAR_STATISTIC;
802 ~HWRM_FUNC_CFG_INPUT_FLAGS_NO_AUTOCLEAR_STATISTIC;
804 rc = bnxt_hwrm_func_cfg_vf_set_flags(bp, vf, func_flags);
806 bp->pf.vf_info[vf].persist_stats = on;
807 bp->pf.vf_info[vf].func_cfg_flags = func_flags;