xref: /dpdk/drivers/net/bnxt/rte_pmd_bnxt.c (revision e99981af34632ecce3bac82d05db97b08308f9b5)
1fd710bb1SScott Branden /* SPDX-License-Identifier: BSD-3-Clause
2e6e8f03eSRandy Schacher  * Copyright(c) 2017-2023 Broadcom
349947a13SAjit Khaparde  * All rights reserved.
449947a13SAjit Khaparde  */
549947a13SAjit Khaparde 
649947a13SAjit Khaparde #include <inttypes.h>
749947a13SAjit Khaparde #include <stdbool.h>
836735a93SAjit Khaparde #include <unistd.h>
949947a13SAjit Khaparde 
101acb7f54SDavid Marchand #include <dev_driver.h>
11df96fd0dSBruce Richardson #include <ethdev_driver.h>
1249947a13SAjit Khaparde #include <rte_malloc.h>
1349947a13SAjit Khaparde #include <rte_cycles.h>
1449947a13SAjit Khaparde #include <rte_byteorder.h>
1549947a13SAjit Khaparde 
1649947a13SAjit Khaparde #include "bnxt.h"
1749947a13SAjit Khaparde #include "bnxt_filter.h"
1849947a13SAjit Khaparde #include "bnxt_hwrm.h"
1949947a13SAjit Khaparde #include "bnxt_vnic.h"
2049947a13SAjit Khaparde #include "rte_pmd_bnxt.h"
2149947a13SAjit Khaparde #include "hsi_struct_def_dpdk.h"
2249947a13SAjit Khaparde 
2320c8f79dSAjit Khaparde int bnxt_rcv_msg_from_vf(struct bnxt *bp, uint16_t vf_id, void *msg)
2420c8f79dSAjit Khaparde {
25ef17b12eSAjit Khaparde 	struct rte_pmd_bnxt_mb_event_param ret_param;
2620c8f79dSAjit Khaparde 
27ef17b12eSAjit Khaparde 	ret_param.retval = RTE_PMD_BNXT_MB_EVENT_PROCEED;
28ef17b12eSAjit Khaparde 	ret_param.vf_id = vf_id;
29ef17b12eSAjit Khaparde 	ret_param.msg = msg;
3020c8f79dSAjit Khaparde 
315723fbedSFerruh Yigit 	rte_eth_dev_callback_process(bp->eth_dev, RTE_ETH_EVENT_VF_MBOX,
32cebe3d7bSThomas Monjalon 				     &ret_param);
3320c8f79dSAjit Khaparde 
3420c8f79dSAjit Khaparde 	/* Default to approve */
35ef17b12eSAjit Khaparde 	if (ret_param.retval == RTE_PMD_BNXT_MB_EVENT_PROCEED)
36ef17b12eSAjit Khaparde 		ret_param.retval = RTE_PMD_BNXT_MB_EVENT_NOOP_ACK;
3720c8f79dSAjit Khaparde 
38ef17b12eSAjit Khaparde 	return ret_param.retval == RTE_PMD_BNXT_MB_EVENT_NOOP_ACK ?
39ef17b12eSAjit Khaparde 		true : false;
4020c8f79dSAjit Khaparde }
4120c8f79dSAjit Khaparde 
42f8244c63SZhiyong Yang int rte_pmd_bnxt_set_tx_loopback(uint16_t port, uint8_t on)
4349947a13SAjit Khaparde {
4449947a13SAjit Khaparde 	struct rte_eth_dev *eth_dev;
4549947a13SAjit Khaparde 	struct bnxt *bp;
4649947a13SAjit Khaparde 	int rc;
4749947a13SAjit Khaparde 
4849947a13SAjit Khaparde 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
4949947a13SAjit Khaparde 
5049947a13SAjit Khaparde 	if (on > 1)
5149947a13SAjit Khaparde 		return -EINVAL;
5249947a13SAjit Khaparde 
5349947a13SAjit Khaparde 	eth_dev = &rte_eth_devices[port];
5449947a13SAjit Khaparde 	if (!is_bnxt_supported(eth_dev))
5549947a13SAjit Khaparde 		return -ENOTSUP;
5649947a13SAjit Khaparde 
5778466c95SStephen Hemminger 	bp = eth_dev->data->dev_private;
5849947a13SAjit Khaparde 
5949947a13SAjit Khaparde 	if (!BNXT_PF(bp)) {
60*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR,
61*e99981afSDavid Marchand 			"Attempt to set Tx loopback on non-PF port %d!",
6249947a13SAjit Khaparde 			port);
6349947a13SAjit Khaparde 		return -ENOTSUP;
6449947a13SAjit Khaparde 	}
6549947a13SAjit Khaparde 
6649947a13SAjit Khaparde 	if (on)
67e8fe0e06SAjit Khaparde 		bp->pf->evb_mode = BNXT_EVB_MODE_VEB;
6849947a13SAjit Khaparde 	else
69e8fe0e06SAjit Khaparde 		bp->pf->evb_mode = BNXT_EVB_MODE_VEPA;
7049947a13SAjit Khaparde 
7149947a13SAjit Khaparde 	rc = bnxt_hwrm_pf_evb_mode(bp);
7249947a13SAjit Khaparde 
7349947a13SAjit Khaparde 	return rc;
7449947a13SAjit Khaparde }
7549947a13SAjit Khaparde 
7649947a13SAjit Khaparde static void
7749947a13SAjit Khaparde rte_pmd_bnxt_set_all_queues_drop_en_cb(struct bnxt_vnic_info *vnic, void *onptr)
7849947a13SAjit Khaparde {
7949947a13SAjit Khaparde 	uint8_t *on = onptr;
8049947a13SAjit Khaparde 	vnic->bd_stall = !(*on);
8149947a13SAjit Khaparde }
8249947a13SAjit Khaparde 
83f8244c63SZhiyong Yang int rte_pmd_bnxt_set_all_queues_drop_en(uint16_t port, uint8_t on)
8449947a13SAjit Khaparde {
8549947a13SAjit Khaparde 	struct rte_eth_dev *eth_dev;
8649947a13SAjit Khaparde 	struct bnxt *bp;
8749947a13SAjit Khaparde 	uint32_t i;
884a671fdeSOlivier Matz 	int rc = -EINVAL;
8949947a13SAjit Khaparde 
9049947a13SAjit Khaparde 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
9149947a13SAjit Khaparde 
9249947a13SAjit Khaparde 	if (on > 1)
9349947a13SAjit Khaparde 		return -EINVAL;
9449947a13SAjit Khaparde 
9549947a13SAjit Khaparde 	eth_dev = &rte_eth_devices[port];
9649947a13SAjit Khaparde 	if (!is_bnxt_supported(eth_dev))
9749947a13SAjit Khaparde 		return -ENOTSUP;
9849947a13SAjit Khaparde 
9978466c95SStephen Hemminger 	bp = eth_dev->data->dev_private;
10049947a13SAjit Khaparde 
10149947a13SAjit Khaparde 	if (!BNXT_PF(bp)) {
102*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR,
103*e99981afSDavid Marchand 			"Attempt to set all queues drop on non-PF port!");
10449947a13SAjit Khaparde 		return -ENOTSUP;
10549947a13SAjit Khaparde 	}
10649947a13SAjit Khaparde 
10749947a13SAjit Khaparde 	if (bp->vnic_info == NULL)
10849947a13SAjit Khaparde 		return -ENODEV;
10949947a13SAjit Khaparde 
11049947a13SAjit Khaparde 	/* Stall PF */
11149947a13SAjit Khaparde 	for (i = 0; i < bp->nr_vnics; i++) {
11249947a13SAjit Khaparde 		bp->vnic_info[i].bd_stall = !on;
11349947a13SAjit Khaparde 		rc = bnxt_hwrm_vnic_cfg(bp, &bp->vnic_info[i]);
11449947a13SAjit Khaparde 		if (rc) {
115*e99981afSDavid Marchand 			PMD_DRV_LOG_LINE(ERR, "Failed to update PF VNIC %d.", i);
11649947a13SAjit Khaparde 			return rc;
11749947a13SAjit Khaparde 		}
11849947a13SAjit Khaparde 	}
11949947a13SAjit Khaparde 
12049947a13SAjit Khaparde 	/* Stall all active VFs */
121e8fe0e06SAjit Khaparde 	for (i = 0; i < bp->pf->active_vfs; i++) {
12249947a13SAjit Khaparde 		rc = bnxt_hwrm_func_vf_vnic_query_and_config(bp, i,
12349947a13SAjit Khaparde 				rte_pmd_bnxt_set_all_queues_drop_en_cb, &on,
12449947a13SAjit Khaparde 				bnxt_hwrm_vnic_cfg);
12549947a13SAjit Khaparde 		if (rc) {
126*e99981afSDavid Marchand 			PMD_DRV_LOG_LINE(ERR, "Failed to update VF VNIC %d.", i);
12749947a13SAjit Khaparde 			break;
12849947a13SAjit Khaparde 		}
12949947a13SAjit Khaparde 	}
13049947a13SAjit Khaparde 
13149947a13SAjit Khaparde 	return rc;
13249947a13SAjit Khaparde }
13349947a13SAjit Khaparde 
134f8244c63SZhiyong Yang int rte_pmd_bnxt_set_vf_mac_addr(uint16_t port, uint16_t vf,
1356d13ea8eSOlivier Matz 				struct rte_ether_addr *mac_addr)
13649947a13SAjit Khaparde {
13749947a13SAjit Khaparde 	struct rte_eth_dev *dev;
13849947a13SAjit Khaparde 	struct rte_eth_dev_info dev_info;
13949947a13SAjit Khaparde 	struct bnxt *bp;
14049947a13SAjit Khaparde 	int rc;
14149947a13SAjit Khaparde 
14249947a13SAjit Khaparde 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
14349947a13SAjit Khaparde 
14449947a13SAjit Khaparde 	dev = &rte_eth_devices[port];
14549947a13SAjit Khaparde 	if (!is_bnxt_supported(dev))
14649947a13SAjit Khaparde 		return -ENOTSUP;
14749947a13SAjit Khaparde 
14874c69f32SIvan Ilchenko 	rc = rte_eth_dev_info_get(port, &dev_info);
14974c69f32SIvan Ilchenko 	if (rc != 0) {
150*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR,
151*e99981afSDavid Marchand 			"Error during getting device (port %u) info: %s",
15274c69f32SIvan Ilchenko 			port, strerror(-rc));
15374c69f32SIvan Ilchenko 
15474c69f32SIvan Ilchenko 		return rc;
15574c69f32SIvan Ilchenko 	}
15674c69f32SIvan Ilchenko 
15778466c95SStephen Hemminger 	bp = dev->data->dev_private;
15849947a13SAjit Khaparde 
15949947a13SAjit Khaparde 	if (vf >= dev_info.max_vfs || mac_addr == NULL)
16049947a13SAjit Khaparde 		return -EINVAL;
16149947a13SAjit Khaparde 
16249947a13SAjit Khaparde 	if (!BNXT_PF(bp)) {
163*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR,
164*e99981afSDavid Marchand 			"Attempt to set VF %d mac address on non-PF port %d!",
16549947a13SAjit Khaparde 			vf, port);
16649947a13SAjit Khaparde 		return -ENOTSUP;
16749947a13SAjit Khaparde 	}
16849947a13SAjit Khaparde 
16949947a13SAjit Khaparde 	rc = bnxt_hwrm_func_vf_mac(bp, vf, (uint8_t *)mac_addr);
17049947a13SAjit Khaparde 
17149947a13SAjit Khaparde 	return rc;
17249947a13SAjit Khaparde }
17336735a93SAjit Khaparde 
174f8244c63SZhiyong Yang int rte_pmd_bnxt_set_vf_rate_limit(uint16_t port, uint16_t vf,
1753a26e41eSSatha Rao 				uint32_t tx_rate, uint64_t q_msk)
17636735a93SAjit Khaparde {
17736735a93SAjit Khaparde 	struct rte_eth_dev *eth_dev;
17836735a93SAjit Khaparde 	struct rte_eth_dev_info dev_info;
17936735a93SAjit Khaparde 	struct bnxt *bp;
1803a26e41eSSatha Rao 	uint32_t tot_rate = 0;
18136735a93SAjit Khaparde 	uint64_t idx;
18236735a93SAjit Khaparde 	int rc;
18336735a93SAjit Khaparde 
18436735a93SAjit Khaparde 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
18536735a93SAjit Khaparde 
18636735a93SAjit Khaparde 	eth_dev = &rte_eth_devices[port];
18736735a93SAjit Khaparde 	if (!is_bnxt_supported(eth_dev))
18836735a93SAjit Khaparde 		return -ENOTSUP;
18936735a93SAjit Khaparde 
19074c69f32SIvan Ilchenko 	rc = rte_eth_dev_info_get(port, &dev_info);
19174c69f32SIvan Ilchenko 	if (rc != 0) {
192*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR,
193*e99981afSDavid Marchand 			"Error during getting device (port %u) info: %s",
19474c69f32SIvan Ilchenko 			port, strerror(-rc));
19574c69f32SIvan Ilchenko 
19674c69f32SIvan Ilchenko 		return rc;
19774c69f32SIvan Ilchenko 	}
19878466c95SStephen Hemminger 	bp = eth_dev->data->dev_private;
19936735a93SAjit Khaparde 
200e8fe0e06SAjit Khaparde 	if (!bp->pf->active_vfs)
20136735a93SAjit Khaparde 		return -EINVAL;
20236735a93SAjit Khaparde 
203e8fe0e06SAjit Khaparde 	if (vf >= bp->pf->max_vfs)
20436735a93SAjit Khaparde 		return -EINVAL;
20536735a93SAjit Khaparde 
20636735a93SAjit Khaparde 	/* Add up the per queue BW and configure MAX BW of the VF */
20736735a93SAjit Khaparde 	for (idx = 0; idx < 64; idx++) {
20836735a93SAjit Khaparde 		if ((1ULL << idx) & q_msk)
20936735a93SAjit Khaparde 			tot_rate += tx_rate;
21036735a93SAjit Khaparde 	}
21136735a93SAjit Khaparde 
21236735a93SAjit Khaparde 	/* Requested BW can't be greater than link speed */
21336735a93SAjit Khaparde 	if (tot_rate > eth_dev->data->dev_link.link_speed) {
214*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR, "Rate > Link speed. Set to %d", tot_rate);
21536735a93SAjit Khaparde 		return -EINVAL;
21636735a93SAjit Khaparde 	}
21736735a93SAjit Khaparde 
21836735a93SAjit Khaparde 	/* Requested BW already configured */
219e8fe0e06SAjit Khaparde 	if (tot_rate == bp->pf->vf_info[vf].max_tx_rate)
22036735a93SAjit Khaparde 		return 0;
22136735a93SAjit Khaparde 
22236735a93SAjit Khaparde 	rc = bnxt_hwrm_func_bw_cfg(bp, vf, tot_rate,
22336735a93SAjit Khaparde 				HWRM_FUNC_CFG_INPUT_ENABLES_MAX_BW);
22436735a93SAjit Khaparde 
22536735a93SAjit Khaparde 	if (!rc)
226e8fe0e06SAjit Khaparde 		bp->pf->vf_info[vf].max_tx_rate = tot_rate;
22736735a93SAjit Khaparde 
22836735a93SAjit Khaparde 	return rc;
22936735a93SAjit Khaparde }
23036735a93SAjit Khaparde 
231f8244c63SZhiyong Yang int rte_pmd_bnxt_set_vf_mac_anti_spoof(uint16_t port, uint16_t vf, uint8_t on)
23236735a93SAjit Khaparde {
23336735a93SAjit Khaparde 	struct rte_eth_dev_info dev_info;
23436735a93SAjit Khaparde 	struct rte_eth_dev *dev;
23536735a93SAjit Khaparde 	uint32_t func_flags;
23636735a93SAjit Khaparde 	struct bnxt *bp;
23736735a93SAjit Khaparde 	int rc;
23836735a93SAjit Khaparde 
23936735a93SAjit Khaparde 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
24036735a93SAjit Khaparde 
24136735a93SAjit Khaparde 	if (on > 1)
24236735a93SAjit Khaparde 		return -EINVAL;
24336735a93SAjit Khaparde 
24436735a93SAjit Khaparde 	dev = &rte_eth_devices[port];
24536735a93SAjit Khaparde 	if (!is_bnxt_supported(dev))
24636735a93SAjit Khaparde 		return -ENOTSUP;
24736735a93SAjit Khaparde 
24874c69f32SIvan Ilchenko 	rc = rte_eth_dev_info_get(port, &dev_info);
24974c69f32SIvan Ilchenko 	if (rc != 0) {
250*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR,
251*e99981afSDavid Marchand 			"Error during getting device (port %u) info: %s",
25274c69f32SIvan Ilchenko 			port, strerror(-rc));
25374c69f32SIvan Ilchenko 
25474c69f32SIvan Ilchenko 		return rc;
25574c69f32SIvan Ilchenko 	}
25678466c95SStephen Hemminger 	bp = dev->data->dev_private;
25736735a93SAjit Khaparde 
25836735a93SAjit Khaparde 	if (!BNXT_PF(bp)) {
259*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR,
260*e99981afSDavid Marchand 			"Attempt to set mac spoof on non-PF port %d!", port);
26136735a93SAjit Khaparde 		return -EINVAL;
26236735a93SAjit Khaparde 	}
26336735a93SAjit Khaparde 
26436735a93SAjit Khaparde 	if (vf >= dev_info.max_vfs)
26536735a93SAjit Khaparde 		return -EINVAL;
26636735a93SAjit Khaparde 
26736735a93SAjit Khaparde 	/* Prev setting same as new setting. */
268e8fe0e06SAjit Khaparde 	if (on == bp->pf->vf_info[vf].mac_spoof_en)
26936735a93SAjit Khaparde 		return 0;
27036735a93SAjit Khaparde 
271e8fe0e06SAjit Khaparde 	func_flags = bp->pf->vf_info[vf].func_cfg_flags;
27244bec709SAjit Khaparde 	func_flags &= ~(HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_ENABLE |
27344bec709SAjit Khaparde 	    HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_DISABLE);
27436735a93SAjit Khaparde 
27536735a93SAjit Khaparde 	if (on)
27636735a93SAjit Khaparde 		func_flags |=
27736735a93SAjit Khaparde 			HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_ENABLE;
27836735a93SAjit Khaparde 	else
27936735a93SAjit Khaparde 		func_flags |=
28036735a93SAjit Khaparde 			HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_DISABLE;
28136735a93SAjit Khaparde 
28244bec709SAjit Khaparde 	rc = bnxt_hwrm_func_cfg_vf_set_flags(bp, vf, func_flags);
28344bec709SAjit Khaparde 	if (!rc) {
284e8fe0e06SAjit Khaparde 		bp->pf->vf_info[vf].mac_spoof_en = on;
285e8fe0e06SAjit Khaparde 		bp->pf->vf_info[vf].func_cfg_flags = func_flags;
28644bec709SAjit Khaparde 	}
28736735a93SAjit Khaparde 
28836735a93SAjit Khaparde 	return rc;
28936735a93SAjit Khaparde }
29036735a93SAjit Khaparde 
291f8244c63SZhiyong Yang int rte_pmd_bnxt_set_vf_vlan_anti_spoof(uint16_t port, uint16_t vf, uint8_t on)
29236735a93SAjit Khaparde {
29336735a93SAjit Khaparde 	struct rte_eth_dev_info dev_info;
29436735a93SAjit Khaparde 	struct rte_eth_dev *dev;
29536735a93SAjit Khaparde 	struct bnxt *bp;
29636735a93SAjit Khaparde 	int rc;
29736735a93SAjit Khaparde 
29836735a93SAjit Khaparde 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
29936735a93SAjit Khaparde 
30036735a93SAjit Khaparde 	if (on > 1)
30136735a93SAjit Khaparde 		return -EINVAL;
30236735a93SAjit Khaparde 
30336735a93SAjit Khaparde 	dev = &rte_eth_devices[port];
30436735a93SAjit Khaparde 	if (!is_bnxt_supported(dev))
30536735a93SAjit Khaparde 		return -ENOTSUP;
30636735a93SAjit Khaparde 
30774c69f32SIvan Ilchenko 	rc = rte_eth_dev_info_get(port, &dev_info);
30874c69f32SIvan Ilchenko 	if (rc != 0) {
309*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR,
310*e99981afSDavid Marchand 			"Error during getting device (port %u) info: %s",
31174c69f32SIvan Ilchenko 			port, strerror(-rc));
31274c69f32SIvan Ilchenko 
31374c69f32SIvan Ilchenko 		return rc;
31474c69f32SIvan Ilchenko 	}
31578466c95SStephen Hemminger 	bp = dev->data->dev_private;
31636735a93SAjit Khaparde 
31736735a93SAjit Khaparde 	if (!BNXT_PF(bp)) {
318*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR,
319*e99981afSDavid Marchand 			"Attempt to set VLAN spoof on non-PF port %d!", port);
32036735a93SAjit Khaparde 		return -EINVAL;
32136735a93SAjit Khaparde 	}
32236735a93SAjit Khaparde 
32336735a93SAjit Khaparde 	if (vf >= dev_info.max_vfs)
32436735a93SAjit Khaparde 		return -EINVAL;
32536735a93SAjit Khaparde 
32636735a93SAjit Khaparde 	rc = bnxt_hwrm_func_cfg_vf_set_vlan_anti_spoof(bp, vf, on);
32736735a93SAjit Khaparde 	if (!rc) {
328e8fe0e06SAjit Khaparde 		bp->pf->vf_info[vf].vlan_spoof_en = on;
32936735a93SAjit Khaparde 		if (on) {
330910242bcSAjit Khaparde 			if (bnxt_hwrm_cfa_vlan_antispoof_cfg(bp,
331e8fe0e06SAjit Khaparde 				bp->pf->first_vf_id + vf,
332e8fe0e06SAjit Khaparde 				bp->pf->vf_info[vf].vlan_count,
333e8fe0e06SAjit Khaparde 				bp->pf->vf_info[vf].vlan_as_table))
33436735a93SAjit Khaparde 				rc = -1;
33536735a93SAjit Khaparde 		}
33636735a93SAjit Khaparde 	} else {
337*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR, "Failed to update VF VNIC %d.", vf);
33836735a93SAjit Khaparde 	}
33936735a93SAjit Khaparde 
34036735a93SAjit Khaparde 	return rc;
34136735a93SAjit Khaparde }
34236735a93SAjit Khaparde 
34336735a93SAjit Khaparde static void
34436735a93SAjit Khaparde rte_pmd_bnxt_set_vf_vlan_stripq_cb(struct bnxt_vnic_info *vnic, void *onptr)
34536735a93SAjit Khaparde {
34636735a93SAjit Khaparde 	uint8_t *on = onptr;
34736735a93SAjit Khaparde 	vnic->vlan_strip = *on;
34836735a93SAjit Khaparde }
34936735a93SAjit Khaparde 
35036735a93SAjit Khaparde int
351f8244c63SZhiyong Yang rte_pmd_bnxt_set_vf_vlan_stripq(uint16_t port, uint16_t vf, uint8_t on)
35236735a93SAjit Khaparde {
35336735a93SAjit Khaparde 	struct rte_eth_dev *dev;
35436735a93SAjit Khaparde 	struct rte_eth_dev_info dev_info;
35536735a93SAjit Khaparde 	struct bnxt *bp;
35636735a93SAjit Khaparde 	int rc;
35736735a93SAjit Khaparde 
35836735a93SAjit Khaparde 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
35936735a93SAjit Khaparde 
36036735a93SAjit Khaparde 	dev = &rte_eth_devices[port];
36136735a93SAjit Khaparde 	if (!is_bnxt_supported(dev))
36236735a93SAjit Khaparde 		return -ENOTSUP;
36336735a93SAjit Khaparde 
36474c69f32SIvan Ilchenko 	rc = rte_eth_dev_info_get(port, &dev_info);
36574c69f32SIvan Ilchenko 	if (rc != 0) {
366*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR,
367*e99981afSDavid Marchand 			"Error during getting device (port %u) info: %s",
36874c69f32SIvan Ilchenko 			port, strerror(-rc));
36974c69f32SIvan Ilchenko 
37074c69f32SIvan Ilchenko 		return rc;
37174c69f32SIvan Ilchenko 	}
37278466c95SStephen Hemminger 	bp = dev->data->dev_private;
37336735a93SAjit Khaparde 
37436735a93SAjit Khaparde 	if (vf >= dev_info.max_vfs)
37536735a93SAjit Khaparde 		return -EINVAL;
37636735a93SAjit Khaparde 
37736735a93SAjit Khaparde 	if (!BNXT_PF(bp)) {
378*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR,
379*e99981afSDavid Marchand 			"Attempt to set VF %d stripq on non-PF port %d!",
38036735a93SAjit Khaparde 			vf, port);
38136735a93SAjit Khaparde 		return -ENOTSUP;
38236735a93SAjit Khaparde 	}
38336735a93SAjit Khaparde 
38436735a93SAjit Khaparde 	rc = bnxt_hwrm_func_vf_vnic_query_and_config(bp, vf,
38536735a93SAjit Khaparde 				rte_pmd_bnxt_set_vf_vlan_stripq_cb, &on,
38636735a93SAjit Khaparde 				bnxt_hwrm_vnic_cfg);
38736735a93SAjit Khaparde 	if (rc)
388*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR, "Failed to update VF VNIC %d.", vf);
38936735a93SAjit Khaparde 
39036735a93SAjit Khaparde 	return rc;
39136735a93SAjit Khaparde }
39236735a93SAjit Khaparde 
393f8244c63SZhiyong Yang int rte_pmd_bnxt_set_vf_rxmode(uint16_t port, uint16_t vf,
3944cfe399fSAjit Khaparde 				uint16_t rx_mask, uint8_t on)
3954cfe399fSAjit Khaparde {
3964cfe399fSAjit Khaparde 	struct rte_eth_dev *dev;
3974cfe399fSAjit Khaparde 	struct rte_eth_dev_info dev_info;
3984cfe399fSAjit Khaparde 	uint16_t flag = 0;
3994cfe399fSAjit Khaparde 	struct bnxt *bp;
4004cfe399fSAjit Khaparde 	int rc;
4014cfe399fSAjit Khaparde 
4024cfe399fSAjit Khaparde 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
4034cfe399fSAjit Khaparde 
4044cfe399fSAjit Khaparde 	dev = &rte_eth_devices[port];
4054cfe399fSAjit Khaparde 	if (!is_bnxt_supported(dev))
4064cfe399fSAjit Khaparde 		return -ENOTSUP;
4074cfe399fSAjit Khaparde 
40874c69f32SIvan Ilchenko 	rc = rte_eth_dev_info_get(port, &dev_info);
40974c69f32SIvan Ilchenko 	if (rc != 0) {
410*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR,
411*e99981afSDavid Marchand 			"Error during getting device (port %u) info: %s",
41274c69f32SIvan Ilchenko 			port, strerror(-rc));
41374c69f32SIvan Ilchenko 
41474c69f32SIvan Ilchenko 		return rc;
41574c69f32SIvan Ilchenko 	}
41678466c95SStephen Hemminger 	bp = dev->data->dev_private;
4174cfe399fSAjit Khaparde 
418e8fe0e06SAjit Khaparde 	if (!bp->pf->vf_info)
4194cfe399fSAjit Khaparde 		return -EINVAL;
4204cfe399fSAjit Khaparde 
4214cfe399fSAjit Khaparde 	if (vf >= bp->pdev->max_vfs)
4224cfe399fSAjit Khaparde 		return -EINVAL;
4234cfe399fSAjit Khaparde 
424295968d1SFerruh Yigit 	if (rx_mask & RTE_ETH_VMDQ_ACCEPT_UNTAG) {
425*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR, "Currently cannot toggle this setting");
4264cfe399fSAjit Khaparde 		return -ENOTSUP;
4274cfe399fSAjit Khaparde 	}
4284cfe399fSAjit Khaparde 
4290714ee90SAjit Khaparde 	/* Is this really the correct mapping?  VFd seems to think it is. */
430295968d1SFerruh Yigit 	if (rx_mask & RTE_ETH_VMDQ_ACCEPT_HASH_UC)
4310714ee90SAjit Khaparde 		flag |= BNXT_VNIC_INFO_PROMISC;
4324cfe399fSAjit Khaparde 
433295968d1SFerruh Yigit 	if (rx_mask & RTE_ETH_VMDQ_ACCEPT_BROADCAST)
4344cfe399fSAjit Khaparde 		flag |= BNXT_VNIC_INFO_BCAST;
435295968d1SFerruh Yigit 	if (rx_mask & RTE_ETH_VMDQ_ACCEPT_MULTICAST)
4360714ee90SAjit Khaparde 		flag |= BNXT_VNIC_INFO_ALLMULTI | BNXT_VNIC_INFO_MCAST;
4374cfe399fSAjit Khaparde 
4384cfe399fSAjit Khaparde 	if (on)
439e8fe0e06SAjit Khaparde 		bp->pf->vf_info[vf].l2_rx_mask |= flag;
4404cfe399fSAjit Khaparde 	else
441e8fe0e06SAjit Khaparde 		bp->pf->vf_info[vf].l2_rx_mask &= ~flag;
4424cfe399fSAjit Khaparde 
4434cfe399fSAjit Khaparde 	rc = bnxt_hwrm_func_vf_vnic_query_and_config(bp, vf,
4444cfe399fSAjit Khaparde 					vf_vnic_set_rxmask_cb,
445e8fe0e06SAjit Khaparde 					&bp->pf->vf_info[vf].l2_rx_mask,
4464cfe399fSAjit Khaparde 					bnxt_set_rx_mask_no_vlan);
4474cfe399fSAjit Khaparde 	if (rc)
448*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR, "bnxt_hwrm_func_vf_vnic_set_rxmask failed");
4494cfe399fSAjit Khaparde 
4504cfe399fSAjit Khaparde 	return rc;
4514cfe399fSAjit Khaparde }
4524cfe399fSAjit Khaparde 
453910242bcSAjit Khaparde static int bnxt_set_vf_table(struct bnxt *bp, uint16_t vf)
454910242bcSAjit Khaparde {
455910242bcSAjit Khaparde 	int rc = 0;
456910242bcSAjit Khaparde 	int dflt_vnic;
457910242bcSAjit Khaparde 	struct bnxt_vnic_info vnic;
458910242bcSAjit Khaparde 
459910242bcSAjit Khaparde 	if (!BNXT_PF(bp)) {
460*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR,
461*e99981afSDavid Marchand 			"Attempt to set VLAN table on non-PF port!");
462910242bcSAjit Khaparde 		return -EINVAL;
463910242bcSAjit Khaparde 	}
464910242bcSAjit Khaparde 
465910242bcSAjit Khaparde 	if (vf >= bp->pdev->max_vfs)
466910242bcSAjit Khaparde 		return -EINVAL;
467910242bcSAjit Khaparde 
468910242bcSAjit Khaparde 	dflt_vnic = bnxt_hwrm_func_qcfg_vf_dflt_vnic_id(bp, vf);
469910242bcSAjit Khaparde 	if (dflt_vnic < 0) {
470910242bcSAjit Khaparde 		/* This simply indicates there's no driver loaded.
471910242bcSAjit Khaparde 		 * This is not an error.
472910242bcSAjit Khaparde 		 */
473*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR, "Unable to get default VNIC for VF %d", vf);
474910242bcSAjit Khaparde 	} else {
475910242bcSAjit Khaparde 		memset(&vnic, 0, sizeof(vnic));
476910242bcSAjit Khaparde 		vnic.fw_vnic_id = dflt_vnic;
477910242bcSAjit Khaparde 		if (bnxt_hwrm_vnic_qcfg(bp, &vnic,
478e8fe0e06SAjit Khaparde 					bp->pf->first_vf_id + vf) == 0) {
479910242bcSAjit Khaparde 			if (bnxt_hwrm_cfa_l2_set_rx_mask(bp, &vnic,
480e8fe0e06SAjit Khaparde 						bp->pf->vf_info[vf].vlan_count,
481e8fe0e06SAjit Khaparde 						bp->pf->vf_info[vf].vlan_table))
482910242bcSAjit Khaparde 				rc = -1;
483910242bcSAjit Khaparde 		} else {
484910242bcSAjit Khaparde 			rc = -1;
485910242bcSAjit Khaparde 		}
486910242bcSAjit Khaparde 	}
487910242bcSAjit Khaparde 
488910242bcSAjit Khaparde 	return rc;
489910242bcSAjit Khaparde }
490910242bcSAjit Khaparde 
491f8244c63SZhiyong Yang int rte_pmd_bnxt_set_vf_vlan_filter(uint16_t port, uint16_t vlan,
49236735a93SAjit Khaparde 				    uint64_t vf_mask, uint8_t vlan_on)
49336735a93SAjit Khaparde {
49436735a93SAjit Khaparde 	struct bnxt_vlan_table_entry *ve;
495910242bcSAjit Khaparde 	struct bnxt_vlan_antispoof_table_entry *vase;
49636735a93SAjit Khaparde 	struct rte_eth_dev *dev;
49736735a93SAjit Khaparde 	struct bnxt *bp;
49836735a93SAjit Khaparde 	uint16_t cnt;
49936735a93SAjit Khaparde 	int rc = 0;
50036735a93SAjit Khaparde 	int i, j;
50136735a93SAjit Khaparde 
50236735a93SAjit Khaparde 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
50336735a93SAjit Khaparde 
50436735a93SAjit Khaparde 	dev = &rte_eth_devices[port];
50536735a93SAjit Khaparde 	if (!is_bnxt_supported(dev))
50636735a93SAjit Khaparde 		return -ENOTSUP;
50736735a93SAjit Khaparde 
50878466c95SStephen Hemminger 	bp = dev->data->dev_private;
509e8fe0e06SAjit Khaparde 	if (!bp->pf->vf_info)
51036735a93SAjit Khaparde 		return -EINVAL;
51136735a93SAjit Khaparde 
51236735a93SAjit Khaparde 	for (i = 0; vf_mask; i++, vf_mask >>= 1) {
513e8fe0e06SAjit Khaparde 		cnt = bp->pf->vf_info[i].vlan_count;
51431ded672SAjit Khaparde 		if ((vf_mask & 1)  == 0)
51531ded672SAjit Khaparde 			continue;
51631ded672SAjit Khaparde 
517e8fe0e06SAjit Khaparde 		if (bp->pf->vf_info[i].vlan_table == NULL) {
51836735a93SAjit Khaparde 			rc = -1;
51936735a93SAjit Khaparde 			continue;
52036735a93SAjit Khaparde 		}
521e8fe0e06SAjit Khaparde 		if (bp->pf->vf_info[i].vlan_as_table == NULL) {
522910242bcSAjit Khaparde 			rc = -1;
523910242bcSAjit Khaparde 			continue;
524910242bcSAjit Khaparde 		}
52536735a93SAjit Khaparde 		if (vlan_on) {
52636735a93SAjit Khaparde 			/* First, search for a duplicate... */
52736735a93SAjit Khaparde 			for (j = 0; j < cnt; j++) {
52836735a93SAjit Khaparde 				if (rte_be_to_cpu_16(
529e8fe0e06SAjit Khaparde 				   bp->pf->vf_info[i].vlan_table[j].vid) ==
530e8fe0e06SAjit Khaparde 				    vlan)
53136735a93SAjit Khaparde 					break;
53236735a93SAjit Khaparde 			}
53336735a93SAjit Khaparde 			if (j == cnt) {
53436735a93SAjit Khaparde 				/* Now check that there's space */
535910242bcSAjit Khaparde 				if (cnt == getpagesize() / sizeof(struct
536910242bcSAjit Khaparde 				    bnxt_vlan_antispoof_table_entry)) {
537*e99981afSDavid Marchand 					PMD_DRV_LOG_LINE(ERR,
538*e99981afSDavid Marchand 					     "VLAN anti-spoof table is full");
539*e99981afSDavid Marchand 					PMD_DRV_LOG_LINE(ERR,
540*e99981afSDavid Marchand 						"VF %d cannot add VLAN %u",
541910242bcSAjit Khaparde 						i, vlan);
54236735a93SAjit Khaparde 					rc = -1;
54336735a93SAjit Khaparde 					continue;
54436735a93SAjit Khaparde 				}
54536735a93SAjit Khaparde 
54631ded672SAjit Khaparde 				/* cnt is one less than vlan_count */
547e8fe0e06SAjit Khaparde 				cnt = bp->pf->vf_info[i].vlan_count++;
54836735a93SAjit Khaparde 				/*
54936735a93SAjit Khaparde 				 * And finally, add to the
55036735a93SAjit Khaparde 				 * end of the table
55136735a93SAjit Khaparde 				 */
552e8fe0e06SAjit Khaparde 				vase = &bp->pf->vf_info[i].vlan_as_table[cnt];
553910242bcSAjit Khaparde 				// TODO: Hardcoded TPID
554910242bcSAjit Khaparde 				vase->tpid = rte_cpu_to_be_16(0x8100);
555910242bcSAjit Khaparde 				vase->vid = rte_cpu_to_be_16(vlan);
556910242bcSAjit Khaparde 				vase->mask = rte_cpu_to_be_16(0xfff);
557e8fe0e06SAjit Khaparde 				ve = &bp->pf->vf_info[i].vlan_table[cnt];
55836735a93SAjit Khaparde 				/* TODO: Hardcoded TPID */
55936735a93SAjit Khaparde 				ve->tpid = rte_cpu_to_be_16(0x8100);
56036735a93SAjit Khaparde 				ve->vid = rte_cpu_to_be_16(vlan);
56136735a93SAjit Khaparde 			}
56236735a93SAjit Khaparde 		} else {
56331ded672SAjit Khaparde 			for (j = 0; j < cnt; j++) {
56436735a93SAjit Khaparde 				if (rte_be_to_cpu_16(
565e8fe0e06SAjit Khaparde 				   bp->pf->vf_info[i].vlan_table[j].vid) !=
566e8fe0e06SAjit Khaparde 				    vlan)
56736735a93SAjit Khaparde 					continue;
568e8fe0e06SAjit Khaparde 				memmove(&bp->pf->vf_info[i].vlan_table[j],
569e8fe0e06SAjit Khaparde 					&bp->pf->vf_info[i].vlan_table[j + 1],
57031ded672SAjit Khaparde 					getpagesize() - ((j + 1) *
57136735a93SAjit Khaparde 					sizeof(struct bnxt_vlan_table_entry)));
572e8fe0e06SAjit Khaparde 				memmove(&bp->pf->vf_info[i].vlan_as_table[j],
573e8fe0e06SAjit Khaparde 					&bp->pf->vf_info[i].vlan_as_table[j + 1],
574910242bcSAjit Khaparde 					getpagesize() - ((j + 1) * sizeof(struct
575910242bcSAjit Khaparde 					bnxt_vlan_antispoof_table_entry)));
57636735a93SAjit Khaparde 				j--;
577e8fe0e06SAjit Khaparde 				cnt = --bp->pf->vf_info[i].vlan_count;
57836735a93SAjit Khaparde 			}
57936735a93SAjit Khaparde 		}
580910242bcSAjit Khaparde 		bnxt_set_vf_table(bp, i);
58136735a93SAjit Khaparde 	}
58236735a93SAjit Khaparde 
58336735a93SAjit Khaparde 	return rc;
58436735a93SAjit Khaparde }
585dd46c6bbSAjit Khaparde 
586f8244c63SZhiyong Yang int rte_pmd_bnxt_get_vf_stats(uint16_t port,
587dd46c6bbSAjit Khaparde 			      uint16_t vf_id,
588dd46c6bbSAjit Khaparde 			      struct rte_eth_stats *stats)
589dd46c6bbSAjit Khaparde {
590dd46c6bbSAjit Khaparde 	struct rte_eth_dev *dev;
591dd46c6bbSAjit Khaparde 	struct rte_eth_dev_info dev_info;
592dd46c6bbSAjit Khaparde 	struct bnxt *bp;
59374c69f32SIvan Ilchenko 	int rc;
594dd46c6bbSAjit Khaparde 
595dd46c6bbSAjit Khaparde 	dev = &rte_eth_devices[port];
596dd46c6bbSAjit Khaparde 	if (!is_bnxt_supported(dev))
597dd46c6bbSAjit Khaparde 		return -ENOTSUP;
598dd46c6bbSAjit Khaparde 
59974c69f32SIvan Ilchenko 	rc = rte_eth_dev_info_get(port, &dev_info);
60074c69f32SIvan Ilchenko 	if (rc != 0) {
601*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR,
602*e99981afSDavid Marchand 			"Error during getting device (port %u) info: %s",
60374c69f32SIvan Ilchenko 			port, strerror(-rc));
60474c69f32SIvan Ilchenko 
60574c69f32SIvan Ilchenko 		return rc;
60674c69f32SIvan Ilchenko 	}
60778466c95SStephen Hemminger 	bp = dev->data->dev_private;
608dd46c6bbSAjit Khaparde 
609dd46c6bbSAjit Khaparde 	if (vf_id >= dev_info.max_vfs)
610dd46c6bbSAjit Khaparde 		return -EINVAL;
611dd46c6bbSAjit Khaparde 
612dd46c6bbSAjit Khaparde 	if (!BNXT_PF(bp)) {
613*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR,
614*e99981afSDavid Marchand 			"Attempt to get VF %d stats on non-PF port %d!",
615dd46c6bbSAjit Khaparde 			vf_id, port);
616dd46c6bbSAjit Khaparde 		return -ENOTSUP;
617dd46c6bbSAjit Khaparde 	}
618dd46c6bbSAjit Khaparde 
619e8fe0e06SAjit Khaparde 	return bnxt_hwrm_func_qstats(bp, bp->pf->first_vf_id + vf_id, stats,
6205f9374deSAjit Khaparde 				     NULL);
621dd46c6bbSAjit Khaparde }
622dd46c6bbSAjit Khaparde 
623f8244c63SZhiyong Yang int rte_pmd_bnxt_reset_vf_stats(uint16_t port,
624dd46c6bbSAjit Khaparde 				uint16_t vf_id)
625dd46c6bbSAjit Khaparde {
626dd46c6bbSAjit Khaparde 	struct rte_eth_dev *dev;
627dd46c6bbSAjit Khaparde 	struct rte_eth_dev_info dev_info;
628dd46c6bbSAjit Khaparde 	struct bnxt *bp;
62974c69f32SIvan Ilchenko 	int rc;
630dd46c6bbSAjit Khaparde 
631dd46c6bbSAjit Khaparde 	dev = &rte_eth_devices[port];
632dd46c6bbSAjit Khaparde 	if (!is_bnxt_supported(dev))
633dd46c6bbSAjit Khaparde 		return -ENOTSUP;
634dd46c6bbSAjit Khaparde 
63574c69f32SIvan Ilchenko 	rc = rte_eth_dev_info_get(port, &dev_info);
63674c69f32SIvan Ilchenko 	if (rc != 0) {
637*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR,
638*e99981afSDavid Marchand 			"Error during getting device (port %u) info: %s",
63974c69f32SIvan Ilchenko 			port, strerror(-rc));
64074c69f32SIvan Ilchenko 
64174c69f32SIvan Ilchenko 		return rc;
64274c69f32SIvan Ilchenko 	}
64378466c95SStephen Hemminger 	bp = dev->data->dev_private;
644dd46c6bbSAjit Khaparde 
645dd46c6bbSAjit Khaparde 	if (vf_id >= dev_info.max_vfs)
646dd46c6bbSAjit Khaparde 		return -EINVAL;
647dd46c6bbSAjit Khaparde 
648dd46c6bbSAjit Khaparde 	if (!BNXT_PF(bp)) {
649*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR,
650*e99981afSDavid Marchand 			"Attempt to reset VF %d stats on non-PF port %d!",
651dd46c6bbSAjit Khaparde 			vf_id, port);
652dd46c6bbSAjit Khaparde 		return -ENOTSUP;
653dd46c6bbSAjit Khaparde 	}
654dd46c6bbSAjit Khaparde 
655e8fe0e06SAjit Khaparde 	return bnxt_hwrm_func_clr_stats(bp, bp->pf->first_vf_id + vf_id);
656dd46c6bbSAjit Khaparde }
657dd46c6bbSAjit Khaparde 
658f8244c63SZhiyong Yang int rte_pmd_bnxt_get_vf_rx_status(uint16_t port, uint16_t vf_id)
659ff63ebbbSAjit Khaparde {
660ff63ebbbSAjit Khaparde 	struct rte_eth_dev *dev;
661ff63ebbbSAjit Khaparde 	struct rte_eth_dev_info dev_info;
662ff63ebbbSAjit Khaparde 	struct bnxt *bp;
66374c69f32SIvan Ilchenko 	int rc;
664ff63ebbbSAjit Khaparde 
665ff63ebbbSAjit Khaparde 	dev = &rte_eth_devices[port];
666ff63ebbbSAjit Khaparde 	if (!is_bnxt_supported(dev))
667ff63ebbbSAjit Khaparde 		return -ENOTSUP;
668ff63ebbbSAjit Khaparde 
66974c69f32SIvan Ilchenko 	rc = rte_eth_dev_info_get(port, &dev_info);
67074c69f32SIvan Ilchenko 	if (rc != 0) {
671*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR,
672*e99981afSDavid Marchand 			"Error during getting device (port %u) info: %s",
67374c69f32SIvan Ilchenko 			port, strerror(-rc));
67474c69f32SIvan Ilchenko 
67574c69f32SIvan Ilchenko 		return rc;
67674c69f32SIvan Ilchenko 	}
67778466c95SStephen Hemminger 	bp = dev->data->dev_private;
678ff63ebbbSAjit Khaparde 
679ff63ebbbSAjit Khaparde 	if (vf_id >= dev_info.max_vfs)
680ff63ebbbSAjit Khaparde 		return -EINVAL;
681ff63ebbbSAjit Khaparde 
682ff63ebbbSAjit Khaparde 	if (!BNXT_PF(bp)) {
683*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR,
684*e99981afSDavid Marchand 			"Attempt to query VF %d RX stats on non-PF port %d!",
685ff63ebbbSAjit Khaparde 			vf_id, port);
686ff63ebbbSAjit Khaparde 		return -ENOTSUP;
687ff63ebbbSAjit Khaparde 	}
688ff63ebbbSAjit Khaparde 
6897301ea4bSAjit Khaparde 	return bnxt_vf_vnic_count(bp, vf_id);
690ff63ebbbSAjit Khaparde }
691ff63ebbbSAjit Khaparde 
692f8244c63SZhiyong Yang int rte_pmd_bnxt_get_vf_tx_drop_count(uint16_t port, uint16_t vf_id,
693dd46c6bbSAjit Khaparde 				      uint64_t *count)
694dd46c6bbSAjit Khaparde {
695dd46c6bbSAjit Khaparde 	struct rte_eth_dev *dev;
696dd46c6bbSAjit Khaparde 	struct rte_eth_dev_info dev_info;
697dd46c6bbSAjit Khaparde 	struct bnxt *bp;
69874c69f32SIvan Ilchenko 	int rc;
699dd46c6bbSAjit Khaparde 
700dd46c6bbSAjit Khaparde 	dev = &rte_eth_devices[port];
701dd46c6bbSAjit Khaparde 	if (!is_bnxt_supported(dev))
702dd46c6bbSAjit Khaparde 		return -ENOTSUP;
703dd46c6bbSAjit Khaparde 
70474c69f32SIvan Ilchenko 	rc = rte_eth_dev_info_get(port, &dev_info);
70574c69f32SIvan Ilchenko 	if (rc != 0) {
706*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR,
707*e99981afSDavid Marchand 			"Error during getting device (port %u) info: %s",
70874c69f32SIvan Ilchenko 			port, strerror(-rc));
70974c69f32SIvan Ilchenko 
71074c69f32SIvan Ilchenko 		return rc;
71174c69f32SIvan Ilchenko 	}
71278466c95SStephen Hemminger 	bp = dev->data->dev_private;
713dd46c6bbSAjit Khaparde 
714dd46c6bbSAjit Khaparde 	if (vf_id >= dev_info.max_vfs)
715dd46c6bbSAjit Khaparde 		return -EINVAL;
716dd46c6bbSAjit Khaparde 
717dd46c6bbSAjit Khaparde 	if (!BNXT_PF(bp)) {
718*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR,
719*e99981afSDavid Marchand 			"Attempt to query VF %d TX drops on non-PF port %d!",
720dd46c6bbSAjit Khaparde 			vf_id, port);
721dd46c6bbSAjit Khaparde 		return -ENOTSUP;
722dd46c6bbSAjit Khaparde 	}
723dd46c6bbSAjit Khaparde 
724e8fe0e06SAjit Khaparde 	return bnxt_hwrm_func_qstats_tx_drop(bp, bp->pf->first_vf_id + vf_id,
725dd46c6bbSAjit Khaparde 					     count);
726dd46c6bbSAjit Khaparde }
7277a5b0874SAjit Khaparde 
7286d13ea8eSOlivier Matz int rte_pmd_bnxt_mac_addr_add(uint16_t port, struct rte_ether_addr *addr,
7297a5b0874SAjit Khaparde 				uint32_t vf_id)
7307a5b0874SAjit Khaparde {
7317a5b0874SAjit Khaparde 	struct rte_eth_dev *dev;
7327a5b0874SAjit Khaparde 	struct rte_eth_dev_info dev_info;
7337a5b0874SAjit Khaparde 	struct bnxt *bp;
7347a5b0874SAjit Khaparde 	struct bnxt_filter_info *filter;
7357a5b0874SAjit Khaparde 	struct bnxt_vnic_info vnic;
7366d13ea8eSOlivier Matz 	struct rte_ether_addr dflt_mac;
7377a5b0874SAjit Khaparde 	int rc;
7387a5b0874SAjit Khaparde 
7397a5b0874SAjit Khaparde 	dev = &rte_eth_devices[port];
7407a5b0874SAjit Khaparde 	if (!is_bnxt_supported(dev))
7417a5b0874SAjit Khaparde 		return -ENOTSUP;
7427a5b0874SAjit Khaparde 
74374c69f32SIvan Ilchenko 	rc = rte_eth_dev_info_get(port, &dev_info);
74474c69f32SIvan Ilchenko 	if (rc != 0) {
745*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR,
746*e99981afSDavid Marchand 			"Error during getting device (port %u) info: %s",
74774c69f32SIvan Ilchenko 			port, strerror(-rc));
74874c69f32SIvan Ilchenko 
74974c69f32SIvan Ilchenko 		return rc;
75074c69f32SIvan Ilchenko 	}
75178466c95SStephen Hemminger 	bp = dev->data->dev_private;
7527a5b0874SAjit Khaparde 
7537a5b0874SAjit Khaparde 	if (vf_id >= dev_info.max_vfs)
7547a5b0874SAjit Khaparde 		return -EINVAL;
7557a5b0874SAjit Khaparde 
7567a5b0874SAjit Khaparde 	if (!BNXT_PF(bp)) {
757*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR,
758*e99981afSDavid Marchand 			"Attempt to config VF %d MAC on non-PF port %d!",
7597a5b0874SAjit Khaparde 			vf_id, port);
7607a5b0874SAjit Khaparde 		return -ENOTSUP;
7617a5b0874SAjit Khaparde 	}
7627a5b0874SAjit Khaparde 
7637a5b0874SAjit Khaparde 	/* If the VF currently uses a random MAC, update default to this one */
764e8fe0e06SAjit Khaparde 	if (bp->pf->vf_info[vf_id].random_mac) {
7657a5b0874SAjit Khaparde 		if (rte_pmd_bnxt_get_vf_rx_status(port, vf_id) <= 0)
7668159471aSAjit Khaparde 			bnxt_hwrm_func_vf_mac(bp, vf_id, (uint8_t *)addr);
7677a5b0874SAjit Khaparde 	}
7687a5b0874SAjit Khaparde 
7697a5b0874SAjit Khaparde 	/* query the default VNIC id used by the function */
7707a5b0874SAjit Khaparde 	rc = bnxt_hwrm_func_qcfg_vf_dflt_vnic_id(bp, vf_id);
7717a5b0874SAjit Khaparde 	if (rc < 0)
7727a5b0874SAjit Khaparde 		goto exit;
7737a5b0874SAjit Khaparde 
7747a5b0874SAjit Khaparde 	memset(&vnic, 0, sizeof(struct bnxt_vnic_info));
7757a5b0874SAjit Khaparde 	vnic.fw_vnic_id = rte_le_to_cpu_16(rc);
776e8fe0e06SAjit Khaparde 	rc = bnxt_hwrm_vnic_qcfg(bp, &vnic, bp->pf->first_vf_id + vf_id);
7777a5b0874SAjit Khaparde 	if (rc < 0)
7787a5b0874SAjit Khaparde 		goto exit;
7797a5b0874SAjit Khaparde 
780e8fe0e06SAjit Khaparde 	STAILQ_FOREACH(filter, &bp->pf->vf_info[vf_id].filter, next) {
7817a5b0874SAjit Khaparde 		if (filter->flags ==
7827a5b0874SAjit Khaparde 		    HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX &&
7837a5b0874SAjit Khaparde 		    filter->enables ==
7847a5b0874SAjit Khaparde 		    (HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR |
7857a5b0874SAjit Khaparde 		     HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR_MASK) &&
78635b2d13fSOlivier Matz 		    memcmp(addr, filter->l2_addr, RTE_ETHER_ADDR_LEN) == 0) {
7875ef3b79fSAjit Khaparde 			bnxt_hwrm_clear_l2_filter(bp, filter);
7887a5b0874SAjit Khaparde 			break;
7897a5b0874SAjit Khaparde 		}
7907a5b0874SAjit Khaparde 	}
7917a5b0874SAjit Khaparde 
7927a5b0874SAjit Khaparde 	if (filter == NULL)
7937a5b0874SAjit Khaparde 		filter = bnxt_alloc_vf_filter(bp, vf_id);
7947a5b0874SAjit Khaparde 
7957a5b0874SAjit Khaparde 	filter->fw_l2_filter_id = UINT64_MAX;
7967a5b0874SAjit Khaparde 	filter->flags = HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX;
7977a5b0874SAjit Khaparde 	filter->enables = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR |
7987a5b0874SAjit Khaparde 			HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR_MASK;
79935b2d13fSOlivier Matz 	memcpy(filter->l2_addr, addr, RTE_ETHER_ADDR_LEN);
80035b2d13fSOlivier Matz 	memset(filter->l2_addr_mask, 0xff, RTE_ETHER_ADDR_LEN);
8017a5b0874SAjit Khaparde 
8027a5b0874SAjit Khaparde 	/* Do not add a filter for the default MAC */
8037a5b0874SAjit Khaparde 	if (bnxt_hwrm_func_qcfg_vf_default_mac(bp, vf_id, &dflt_mac) ||
80435b2d13fSOlivier Matz 	    memcmp(filter->l2_addr, dflt_mac.addr_bytes, RTE_ETHER_ADDR_LEN))
8055ef3b79fSAjit Khaparde 		rc = bnxt_hwrm_set_l2_filter(bp, vnic.fw_vnic_id, filter);
8067a5b0874SAjit Khaparde 
8077a5b0874SAjit Khaparde exit:
8087a5b0874SAjit Khaparde 	return rc;
8097a5b0874SAjit Khaparde }
81018c2854bSAjit Khaparde 
81118c2854bSAjit Khaparde int
812f8244c63SZhiyong Yang rte_pmd_bnxt_set_vf_vlan_insert(uint16_t port, uint16_t vf,
81318c2854bSAjit Khaparde 		uint16_t vlan_id)
81418c2854bSAjit Khaparde {
81518c2854bSAjit Khaparde 	struct rte_eth_dev *dev;
81618c2854bSAjit Khaparde 	struct rte_eth_dev_info dev_info;
81718c2854bSAjit Khaparde 	struct bnxt *bp;
81818c2854bSAjit Khaparde 	int rc;
81918c2854bSAjit Khaparde 
82018c2854bSAjit Khaparde 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
82118c2854bSAjit Khaparde 
82218c2854bSAjit Khaparde 	dev = &rte_eth_devices[port];
82318c2854bSAjit Khaparde 	if (!is_bnxt_supported(dev))
82418c2854bSAjit Khaparde 		return -ENOTSUP;
82518c2854bSAjit Khaparde 
82674c69f32SIvan Ilchenko 	rc = rte_eth_dev_info_get(port, &dev_info);
82774c69f32SIvan Ilchenko 	if (rc != 0) {
828*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR,
829*e99981afSDavid Marchand 			"Error during getting device (port %u) info: %s",
83074c69f32SIvan Ilchenko 			port, strerror(-rc));
83174c69f32SIvan Ilchenko 
83274c69f32SIvan Ilchenko 		return rc;
83374c69f32SIvan Ilchenko 	}
83478466c95SStephen Hemminger 	bp = dev->data->dev_private;
83518c2854bSAjit Khaparde 
83618c2854bSAjit Khaparde 	if (vf >= dev_info.max_vfs)
83718c2854bSAjit Khaparde 		return -EINVAL;
83818c2854bSAjit Khaparde 
83918c2854bSAjit Khaparde 	if (!BNXT_PF(bp)) {
840*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR,
841*e99981afSDavid Marchand 			"Attempt to set VF %d vlan insert on non-PF port %d!",
84218c2854bSAjit Khaparde 			vf, port);
84318c2854bSAjit Khaparde 		return -ENOTSUP;
84418c2854bSAjit Khaparde 	}
84518c2854bSAjit Khaparde 
846e8fe0e06SAjit Khaparde 	bp->pf->vf_info[vf].dflt_vlan = vlan_id;
84718c2854bSAjit Khaparde 	if (bnxt_hwrm_func_qcfg_current_vf_vlan(bp, vf) ==
848e8fe0e06SAjit Khaparde 	    bp->pf->vf_info[vf].dflt_vlan)
84918c2854bSAjit Khaparde 		return 0;
85018c2854bSAjit Khaparde 
85118c2854bSAjit Khaparde 	rc = bnxt_hwrm_set_vf_vlan(bp, vf);
85218c2854bSAjit Khaparde 
85318c2854bSAjit Khaparde 	return rc;
85418c2854bSAjit Khaparde }
85544bec709SAjit Khaparde 
856f8244c63SZhiyong Yang int rte_pmd_bnxt_set_vf_persist_stats(uint16_t port, uint16_t vf, uint8_t on)
85744bec709SAjit Khaparde {
85844bec709SAjit Khaparde 	struct rte_eth_dev_info dev_info;
85944bec709SAjit Khaparde 	struct rte_eth_dev *dev;
86044bec709SAjit Khaparde 	uint32_t func_flags;
86144bec709SAjit Khaparde 	struct bnxt *bp;
86244bec709SAjit Khaparde 	int rc;
86344bec709SAjit Khaparde 
86444bec709SAjit Khaparde 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
86544bec709SAjit Khaparde 
86644bec709SAjit Khaparde 	if (on > 1)
86744bec709SAjit Khaparde 		return -EINVAL;
86844bec709SAjit Khaparde 
86944bec709SAjit Khaparde 	dev = &rte_eth_devices[port];
87074c69f32SIvan Ilchenko 	rc = rte_eth_dev_info_get(port, &dev_info);
87174c69f32SIvan Ilchenko 	if (rc != 0) {
872*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR,
873*e99981afSDavid Marchand 			"Error during getting device (port %u) info: %s",
87474c69f32SIvan Ilchenko 			port, strerror(-rc));
87574c69f32SIvan Ilchenko 
87674c69f32SIvan Ilchenko 		return rc;
87774c69f32SIvan Ilchenko 	}
87878466c95SStephen Hemminger 	bp = dev->data->dev_private;
87944bec709SAjit Khaparde 
88044bec709SAjit Khaparde 	if (!BNXT_PF(bp)) {
881*e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR,
882*e99981afSDavid Marchand 			"Attempt to set persist stats on non-PF port %d!",
88344bec709SAjit Khaparde 			port);
88444bec709SAjit Khaparde 		return -EINVAL;
88544bec709SAjit Khaparde 	}
88644bec709SAjit Khaparde 
88744bec709SAjit Khaparde 	if (vf >= dev_info.max_vfs)
88844bec709SAjit Khaparde 		return -EINVAL;
88944bec709SAjit Khaparde 
89044bec709SAjit Khaparde 	/* Prev setting same as new setting. */
891e8fe0e06SAjit Khaparde 	if (on == bp->pf->vf_info[vf].persist_stats)
89244bec709SAjit Khaparde 		return 0;
89344bec709SAjit Khaparde 
894e8fe0e06SAjit Khaparde 	func_flags = bp->pf->vf_info[vf].func_cfg_flags;
89544bec709SAjit Khaparde 
89644bec709SAjit Khaparde 	if (on)
89744bec709SAjit Khaparde 		func_flags |=
89844bec709SAjit Khaparde 			HWRM_FUNC_CFG_INPUT_FLAGS_NO_AUTOCLEAR_STATISTIC;
89944bec709SAjit Khaparde 	else
90044bec709SAjit Khaparde 		func_flags &=
90144bec709SAjit Khaparde 			~HWRM_FUNC_CFG_INPUT_FLAGS_NO_AUTOCLEAR_STATISTIC;
90244bec709SAjit Khaparde 
90344bec709SAjit Khaparde 	rc = bnxt_hwrm_func_cfg_vf_set_flags(bp, vf, func_flags);
90444bec709SAjit Khaparde 	if (!rc) {
905e8fe0e06SAjit Khaparde 		bp->pf->vf_info[vf].persist_stats = on;
906e8fe0e06SAjit Khaparde 		bp->pf->vf_info[vf].func_cfg_flags = func_flags;
90744bec709SAjit Khaparde 	}
90844bec709SAjit Khaparde 
90944bec709SAjit Khaparde 	return rc;
91044bec709SAjit Khaparde }
911