xref: /dpdk/drivers/net/bnxt/bnxt_ethdev.c (revision 7d32c003ac175d7ac8669dc11684c75cc7eb56b8)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2014-2023 Broadcom
3  * All rights reserved.
4  */
5 
6 #include <inttypes.h>
7 #include <stdalign.h>
8 #include <stdbool.h>
9 
10 #include <dev_driver.h>
11 #include <ethdev_driver.h>
12 #include <ethdev_pci.h>
13 #include <rte_malloc.h>
14 #include <rte_cycles.h>
15 #include <rte_alarm.h>
16 #include <rte_kvargs.h>
17 #include <rte_vect.h>
18 
19 #include "bnxt.h"
20 #include "bnxt_filter.h"
21 #include "bnxt_hwrm.h"
22 #include "bnxt_irq.h"
23 #include "bnxt_reps.h"
24 #include "bnxt_ring.h"
25 #include "bnxt_rxq.h"
26 #include "bnxt_rxr.h"
27 #include "bnxt_stats.h"
28 #include "bnxt_txq.h"
29 #include "bnxt_txr.h"
30 #include "bnxt_vnic.h"
31 #include "hsi_struct_def_dpdk.h"
32 #include "bnxt_nvm_defs.h"
33 #include "bnxt_tf_common.h"
34 #include "ulp_flow_db.h"
35 #include "rte_pmd_bnxt.h"
36 #include "bnxt_ulp_utils.h"
37 
38 #define DRV_MODULE_NAME		"bnxt"
39 static const char bnxt_version[] =
40 	"Broadcom NetXtreme driver " DRV_MODULE_NAME;
41 
42 /*
43  * The set of PCI devices this driver supports
44  */
45 static const struct rte_pci_id bnxt_pci_id_map[] = {
46 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM,
47 			 BROADCOM_DEV_ID_STRATUS_NIC_VF1) },
48 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM,
49 			 BROADCOM_DEV_ID_STRATUS_NIC_VF2) },
50 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_STRATUS_NIC) },
51 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57414_VF) },
52 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57304_VF) },
53 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_NS2) },
54 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57406_VF) },
55 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57407_MF) },
56 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_5741X_VF) },
57 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_5731X_VF) },
58 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57417_MF) },
59 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57412) },
60 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57414) },
61 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57416_RJ45) },
62 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57417_RJ45) },
63 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57412_MF) },
64 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57317_RJ45) },
65 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57417_SFP) },
66 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57416_SFP) },
67 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57317_SFP) },
68 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57414_MF) },
69 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57416_MF) },
70 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_58802) },
71 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_58804) },
72 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_58808) },
73 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_58802_VF) },
74 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57508) },
75 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57504) },
76 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57502) },
77 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57500_VF1) },
78 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57500_VF2) },
79 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57508_MF1) },
80 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57504_MF1) },
81 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57502_MF1) },
82 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57508_MF2) },
83 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57504_MF2) },
84 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57502_MF2) },
85 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_58812) },
86 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_58814) },
87 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_58818) },
88 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_58818_VF) },
89 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57608) },
90 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57604) },
91 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57602) },
92 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57601) },
93 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_5760X_VF) },
94 	{ .vendor_id = 0, /* sentinel */ },
95 };
96 
97 #define BNXT_DEVARG_FLOW_XSTAT	"flow-xstat"
98 #define BNXT_DEVARG_MAX_NUM_KFLOWS  "max-num-kflows"
99 #define BNXT_DEVARG_REPRESENTOR	"representor"
100 #define BNXT_DEVARG_REP_BASED_PF  "rep-based-pf"
101 #define BNXT_DEVARG_REP_IS_PF  "rep-is-pf"
102 #define BNXT_DEVARG_REP_Q_R2F  "rep-q-r2f"
103 #define BNXT_DEVARG_REP_Q_F2R  "rep-q-f2r"
104 #define BNXT_DEVARG_REP_FC_R2F  "rep-fc-r2f"
105 #define BNXT_DEVARG_REP_FC_F2R  "rep-fc-f2r"
106 #define BNXT_DEVARG_APP_ID	"app-id"
107 #define BNXT_DEVARG_IEEE_1588	"ieee-1588"
108 #define BNXT_DEVARG_CQE_MODE	"cqe-mode"
109 #define BNXT_DEVARG_MPC		"mpc"
110 
111 static const char *const bnxt_dev_args[] = {
112 	BNXT_DEVARG_REPRESENTOR,
113 	BNXT_DEVARG_FLOW_XSTAT,
114 	BNXT_DEVARG_MAX_NUM_KFLOWS,
115 	BNXT_DEVARG_REP_BASED_PF,
116 	BNXT_DEVARG_REP_IS_PF,
117 	BNXT_DEVARG_REP_Q_R2F,
118 	BNXT_DEVARG_REP_Q_F2R,
119 	BNXT_DEVARG_REP_FC_R2F,
120 	BNXT_DEVARG_REP_FC_F2R,
121 	BNXT_DEVARG_APP_ID,
122 	BNXT_DEVARG_IEEE_1588,
123 	BNXT_DEVARG_CQE_MODE,
124 	BNXT_DEVARG_MPC,
125 	NULL
126 };
127 
128 #define BNXT_SPEEDS_SUPP_SPEED_LANES (RTE_ETH_LINK_SPEED_10G | \
129 				      RTE_ETH_LINK_SPEED_25G | \
130 				      RTE_ETH_LINK_SPEED_40G | \
131 				      RTE_ETH_LINK_SPEED_50G | \
132 				      RTE_ETH_LINK_SPEED_100G | \
133 				      RTE_ETH_LINK_SPEED_200G | \
134 				      RTE_ETH_LINK_SPEED_400G)
135 
136 static const struct rte_eth_speed_lanes_capa speed_lanes_capa_tbl[] = {
137 	{ RTE_ETH_SPEED_NUM_10G, RTE_BIT32(1) },
138 	{ RTE_ETH_SPEED_NUM_25G, RTE_BIT32(1) },
139 	{ RTE_ETH_SPEED_NUM_40G, RTE_BIT32(4) },
140 	{ RTE_ETH_SPEED_NUM_50G, RTE_BIT32(1) | RTE_BIT32(2) },
141 	{ RTE_ETH_SPEED_NUM_100G, RTE_BIT32(1) | RTE_BIT32(2) | RTE_BIT32(4) },
142 	{ RTE_ETH_SPEED_NUM_200G, RTE_BIT32(2) | RTE_BIT32(4) },
143 	{ RTE_ETH_SPEED_NUM_400G, RTE_BIT32(4) | RTE_BIT32(8) },
144 };
145 
146 /*
147  * cqe-mode = an non-negative 8-bit number
148  */
149 #define BNXT_DEVARG_CQE_MODE_INVALID(val)		((val) > 1)
150 
151 /*
152  * mpc = an non-negative 8-bit number
153  */
154 #define BNXT_DEVARG_MPC_INVALID(val)			((val) > 1)
155 
156 /*
157  * app-id = an non-negative 8-bit number
158  */
159 #define BNXT_DEVARG_APP_ID_INVALID(val)			((val) > 255)
160 
161 /*
162  * ieee-1588 = an non-negative 8-bit number
163  */
164 #define BNXT_DEVARG_IEEE_1588_INVALID(val)			((val) > 255)
165 
166 /*
167  * flow_xstat == false to disable the feature
168  * flow_xstat == true to enable the feature
169  */
170 #define	BNXT_DEVARG_FLOW_XSTAT_INVALID(flow_xstat)	((flow_xstat) > 1)
171 
172 /*
173  * rep_is_pf == false to indicate VF representor
174  * rep_is_pf == true to indicate PF representor
175  */
176 #define	BNXT_DEVARG_REP_IS_PF_INVALID(rep_is_pf)	((rep_is_pf) > 1)
177 
178 /*
179  * rep_based_pf == Physical index of the PF
180  */
181 #define	BNXT_DEVARG_REP_BASED_PF_INVALID(rep_based_pf)	((rep_based_pf) > 15)
182 /*
183  * rep_q_r2f == Logical COS Queue index for the rep to endpoint direction
184  */
185 #define	BNXT_DEVARG_REP_Q_R2F_INVALID(rep_q_r2f)	((rep_q_r2f) > 3)
186 
187 /*
188  * rep_q_f2r == Logical COS Queue index for the endpoint to rep direction
189  */
190 #define	BNXT_DEVARG_REP_Q_F2R_INVALID(rep_q_f2r)	((rep_q_f2r) > 3)
191 
192 /*
193  * rep_fc_r2f == Flow control for the representor to endpoint direction
194  */
195 #define BNXT_DEVARG_REP_FC_R2F_INVALID(rep_fc_r2f)	((rep_fc_r2f) > 1)
196 
197 /*
198  * rep_fc_f2r == Flow control for the endpoint to representor direction
199  */
200 #define BNXT_DEVARG_REP_FC_F2R_INVALID(rep_fc_f2r)	((rep_fc_f2r) > 1)
201 
202 int bnxt_cfa_code_dynfield_offset = -1;
203 unsigned long mpc;
204 
205 /*
206  * max_num_kflows must be >= 32
207  * and must be a power-of-2 supported value
208  * return: 1 -> invalid
209  *         0 -> valid
210  */
211 static int bnxt_devarg_max_num_kflow_invalid(uint16_t max_num_kflows)
212 {
213 	if (max_num_kflows < 32 || !rte_is_power_of_2(max_num_kflows))
214 		return 1;
215 	return 0;
216 }
217 
218 static int bnxt_vlan_offload_set_op(struct rte_eth_dev *dev, int mask);
219 static int bnxt_dev_uninit(struct rte_eth_dev *eth_dev);
220 static int bnxt_init_resources(struct bnxt *bp, bool reconfig_dev);
221 static int bnxt_uninit_resources(struct bnxt *bp, bool reconfig_dev);
222 static void bnxt_cancel_fw_health_check(struct bnxt *bp);
223 static int bnxt_restore_vlan_filters(struct bnxt *bp);
224 static void bnxt_dev_recover(void *arg);
225 static void bnxt_free_error_recovery_info(struct bnxt *bp);
226 static void bnxt_free_rep_info(struct bnxt *bp);
227 static int bnxt_check_fw_ready(struct bnxt *bp);
228 static bool bnxt_enable_ulp(struct bnxt *bp);
229 
230 int is_bnxt_in_error(struct bnxt *bp)
231 {
232 	if (bp->flags & BNXT_FLAG_FATAL_ERROR)
233 		return -EIO;
234 	if (bp->flags & BNXT_FLAG_FW_RESET)
235 		return -EBUSY;
236 
237 	return 0;
238 }
239 
240 /***********************/
241 
242 /*
243  * High level utility functions
244  */
245 
246 uint16_t bnxt_rss_ctxts(const struct bnxt *bp)
247 {
248 	unsigned int num_rss_rings = RTE_MIN(bp->rx_nr_rings,
249 					     BNXT_RSS_TBL_SIZE_P5);
250 
251 	if (!BNXT_CHIP_P5_P7(bp))
252 		return 1;
253 
254 	return RTE_ALIGN_MUL_CEIL(num_rss_rings,
255 				  BNXT_RSS_ENTRIES_PER_CTX_P5) /
256 				  BNXT_RSS_ENTRIES_PER_CTX_P5;
257 }
258 
259 uint16_t bnxt_rss_hash_tbl_size(const struct bnxt *bp)
260 {
261 	if (!BNXT_CHIP_P5_P7(bp))
262 		return HW_HASH_INDEX_SIZE;
263 
264 	return bnxt_rss_ctxts(bp) * BNXT_RSS_ENTRIES_PER_CTX_P5;
265 }
266 
267 static void bnxt_free_parent_info(struct bnxt *bp)
268 {
269 	rte_free(bp->parent);
270 	bp->parent = NULL;
271 }
272 
273 static void bnxt_free_pf_info(struct bnxt *bp)
274 {
275 	rte_free(bp->pf);
276 	bp->pf = NULL;
277 }
278 
279 static void bnxt_free_link_info(struct bnxt *bp)
280 {
281 	rte_free(bp->link_info);
282 	bp->link_info = NULL;
283 }
284 
285 static void bnxt_free_leds_info(struct bnxt *bp)
286 {
287 	if (BNXT_VF(bp))
288 		return;
289 
290 	rte_free(bp->leds);
291 	bp->leds = NULL;
292 }
293 
294 static void bnxt_free_flow_stats_info(struct bnxt *bp)
295 {
296 	rte_free(bp->flow_stat);
297 	bp->flow_stat = NULL;
298 }
299 
300 static void bnxt_free_cos_queues(struct bnxt *bp)
301 {
302 	rte_free(bp->rx_cos_queue);
303 	bp->rx_cos_queue = NULL;
304 	rte_free(bp->tx_cos_queue);
305 	bp->tx_cos_queue = NULL;
306 }
307 
308 static void bnxt_free_mem(struct bnxt *bp, bool reconfig)
309 {
310 	bnxt_free_filter_mem(bp);
311 	bnxt_free_vnic_attributes(bp);
312 	bnxt_free_vnic_mem(bp);
313 
314 	/* tx/rx rings are configured as part of *_queue_setup callbacks.
315 	 * If the number of rings change across fw update,
316 	 * we don't have much choice except to warn the user.
317 	 */
318 	if (!reconfig) {
319 		bnxt_free_stats(bp);
320 		bnxt_free_tx_rings(bp);
321 		bnxt_free_rx_rings(bp);
322 	}
323 	bnxt_free_async_cp_ring(bp);
324 	bnxt_free_rxtx_nq_ring(bp);
325 
326 	rte_free(bp->grp_info);
327 	bp->grp_info = NULL;
328 }
329 
330 static int bnxt_alloc_parent_info(struct bnxt *bp)
331 {
332 	bp->parent = rte_zmalloc("bnxt_parent_info",
333 				 sizeof(struct bnxt_parent_info), 0);
334 	if (bp->parent == NULL)
335 		return -ENOMEM;
336 
337 	return 0;
338 }
339 
340 static int bnxt_alloc_pf_info(struct bnxt *bp)
341 {
342 	bp->pf = rte_zmalloc("bnxt_pf_info", sizeof(struct bnxt_pf_info), 0);
343 	if (bp->pf == NULL)
344 		return -ENOMEM;
345 
346 	return 0;
347 }
348 
349 static int bnxt_alloc_link_info(struct bnxt *bp)
350 {
351 	bp->link_info =
352 		rte_zmalloc("bnxt_link_info", sizeof(struct bnxt_link_info), 0);
353 	if (bp->link_info == NULL)
354 		return -ENOMEM;
355 
356 	return 0;
357 }
358 
359 static int bnxt_alloc_leds_info(struct bnxt *bp)
360 {
361 	if (BNXT_VF(bp))
362 		return 0;
363 
364 	bp->leds = rte_zmalloc("bnxt_leds",
365 			       BNXT_MAX_LED * sizeof(struct bnxt_led_info),
366 			       0);
367 	if (bp->leds == NULL)
368 		return -ENOMEM;
369 
370 	return 0;
371 }
372 
373 static int bnxt_alloc_cos_queues(struct bnxt *bp)
374 {
375 	bp->rx_cos_queue =
376 		rte_zmalloc("bnxt_rx_cosq",
377 			    BNXT_COS_QUEUE_COUNT *
378 			    sizeof(struct bnxt_cos_queue_info),
379 			    0);
380 	if (bp->rx_cos_queue == NULL)
381 		return -ENOMEM;
382 
383 	bp->tx_cos_queue =
384 		rte_zmalloc("bnxt_tx_cosq",
385 			    BNXT_COS_QUEUE_COUNT *
386 			    sizeof(struct bnxt_cos_queue_info),
387 			    0);
388 	if (bp->tx_cos_queue == NULL)
389 		return -ENOMEM;
390 
391 	return 0;
392 }
393 
394 static int bnxt_alloc_flow_stats_info(struct bnxt *bp)
395 {
396 	bp->flow_stat = rte_zmalloc("bnxt_flow_xstat",
397 				    sizeof(struct bnxt_flow_stat_info), 0);
398 	if (bp->flow_stat == NULL)
399 		return -ENOMEM;
400 
401 	return 0;
402 }
403 
404 static int bnxt_alloc_mem(struct bnxt *bp, bool reconfig)
405 {
406 	int rc;
407 
408 	rc = bnxt_alloc_ring_grps(bp);
409 	if (rc)
410 		goto alloc_mem_err;
411 
412 	rc = bnxt_alloc_async_ring_struct(bp);
413 	if (rc)
414 		goto alloc_mem_err;
415 
416 	rc = bnxt_alloc_vnic_mem(bp);
417 	if (rc)
418 		goto alloc_mem_err;
419 
420 	rc = bnxt_alloc_vnic_attributes(bp, reconfig);
421 	if (rc)
422 		goto alloc_mem_err;
423 
424 	rc = bnxt_alloc_filter_mem(bp);
425 	if (rc)
426 		goto alloc_mem_err;
427 
428 	rc = bnxt_alloc_async_cp_ring(bp);
429 	if (rc)
430 		goto alloc_mem_err;
431 
432 	rc = bnxt_alloc_rxtx_nq_ring(bp);
433 	if (rc)
434 		goto alloc_mem_err;
435 
436 	if (BNXT_FLOW_XSTATS_EN(bp)) {
437 		rc = bnxt_alloc_flow_stats_info(bp);
438 		if (rc)
439 			goto alloc_mem_err;
440 	}
441 
442 	return 0;
443 
444 alloc_mem_err:
445 	bnxt_free_mem(bp, reconfig);
446 	return rc;
447 }
448 
449 static int bnxt_setup_one_vnic(struct bnxt *bp, uint16_t vnic_id)
450 {
451 	struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
452 	struct bnxt_vnic_info *vnic = &bp->vnic_info[vnic_id];
453 	uint64_t rx_offloads = dev_conf->rxmode.offloads;
454 	struct bnxt_rx_queue *rxq;
455 	unsigned int j;
456 	int rc;
457 
458 	rc = bnxt_vnic_grp_alloc(bp, vnic);
459 	if (rc)
460 		goto err_out;
461 
462 	PMD_DRV_LOG_LINE(DEBUG, "vnic[%d] = %p vnic->fw_grp_ids = %p",
463 		    vnic_id, vnic, vnic->fw_grp_ids);
464 
465 	/* populate the fw group table */
466 	bnxt_vnic_ring_grp_populate(bp, vnic);
467 	bnxt_vnic_rules_init(vnic);
468 
469 	rc = bnxt_hwrm_vnic_alloc(bp, vnic);
470 	if (rc)
471 		goto err_out;
472 
473 	/* Alloc RSS context only if RSS mode is enabled */
474 	if (dev_conf->rxmode.mq_mode & RTE_ETH_MQ_RX_RSS) {
475 		int j, nr_ctxs = bnxt_rss_ctxts(bp);
476 
477 		/* RSS table size in P5 is 512.
478 		 * Cap max Rx rings to same value
479 		 */
480 		if (bp->rx_nr_rings > BNXT_RSS_TBL_SIZE_P5) {
481 			PMD_DRV_LOG_LINE(ERR, "RxQ cnt %d > reta_size %d",
482 				    bp->rx_nr_rings, BNXT_RSS_TBL_SIZE_P5);
483 			goto err_out;
484 		}
485 
486 		rc = 0;
487 		for (j = 0; j < nr_ctxs; j++) {
488 			rc = bnxt_hwrm_vnic_ctx_alloc(bp, vnic, j);
489 			if (rc)
490 				break;
491 		}
492 		if (rc) {
493 			PMD_DRV_LOG_LINE(ERR,
494 				    "HWRM vnic %d ctx %d alloc failure rc: %x",
495 				    vnic_id, j, rc);
496 			goto err_out;
497 		}
498 		vnic->num_lb_ctxts = nr_ctxs;
499 	}
500 
501 	/*
502 	 * Firmware sets pf pair in default vnic cfg. If the VLAN strip
503 	 * setting is not available at this time, it will not be
504 	 * configured correctly in the CFA.
505 	 */
506 	if (rx_offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP)
507 		vnic->vlan_strip = true;
508 	else
509 		vnic->vlan_strip = false;
510 
511 	rc = bnxt_hwrm_vnic_cfg(bp, vnic);
512 	if (rc)
513 		goto err_out;
514 
515 	rc = bnxt_set_hwrm_vnic_filters(bp, vnic);
516 	if (rc)
517 		goto err_out;
518 
519 	for (j = 0; j < bp->rx_num_qs_per_vnic; j++) {
520 		rxq = bp->eth_dev->data->rx_queues[j];
521 
522 		PMD_DRV_LOG_LINE(DEBUG,
523 			    "rxq[%d]->vnic=%p vnic->fw_grp_ids=%p",
524 			    j, rxq->vnic, rxq->vnic->fw_grp_ids);
525 
526 		if (BNXT_HAS_RING_GRPS(bp) && rxq->rx_deferred_start)
527 			vnic->fw_grp_ids[j] = INVALID_HW_RING_ID;
528 	}
529 
530 	PMD_DRV_LOG_LINE(DEBUG, "vnic->rx_queue_cnt = %d", vnic->rx_queue_cnt);
531 
532 	rc = bnxt_vnic_rss_configure(bp, vnic);
533 	if (rc)
534 		goto err_out;
535 
536 	bnxt_hwrm_vnic_plcmode_cfg(bp, vnic);
537 
538 	rc = bnxt_hwrm_vnic_tpa_cfg(bp, vnic,
539 				    (rx_offloads & RTE_ETH_RX_OFFLOAD_TCP_LRO) ?
540 				    true : false);
541 	if (rc)
542 		goto err_out;
543 
544 	return 0;
545 err_out:
546 	PMD_DRV_LOG_LINE(ERR, "HWRM vnic %d cfg failure rc: %x",
547 		    vnic_id, rc);
548 	return rc;
549 }
550 
551 static int bnxt_register_fc_ctx_mem(struct bnxt *bp)
552 {
553 	int rc = 0;
554 
555 	rc = bnxt_hwrm_ctx_rgtr(bp, bp->flow_stat->rx_fc_in_tbl.dma,
556 				&bp->flow_stat->rx_fc_in_tbl.ctx_id);
557 	if (rc)
558 		return rc;
559 
560 	PMD_DRV_LOG_LINE(DEBUG,
561 		    "rx_fc_in_tbl.va = %p rx_fc_in_tbl.dma = %p"
562 		    " rx_fc_in_tbl.ctx_id = %d",
563 		    bp->flow_stat->rx_fc_in_tbl.va,
564 		    (void *)((uintptr_t)bp->flow_stat->rx_fc_in_tbl.dma),
565 		    bp->flow_stat->rx_fc_in_tbl.ctx_id);
566 
567 	rc = bnxt_hwrm_ctx_rgtr(bp, bp->flow_stat->rx_fc_out_tbl.dma,
568 				&bp->flow_stat->rx_fc_out_tbl.ctx_id);
569 	if (rc)
570 		return rc;
571 
572 	PMD_DRV_LOG_LINE(DEBUG,
573 		    "rx_fc_out_tbl.va = %p rx_fc_out_tbl.dma = %p"
574 		    " rx_fc_out_tbl.ctx_id = %d",
575 		    bp->flow_stat->rx_fc_out_tbl.va,
576 		    (void *)((uintptr_t)bp->flow_stat->rx_fc_out_tbl.dma),
577 		    bp->flow_stat->rx_fc_out_tbl.ctx_id);
578 
579 	rc = bnxt_hwrm_ctx_rgtr(bp, bp->flow_stat->tx_fc_in_tbl.dma,
580 				&bp->flow_stat->tx_fc_in_tbl.ctx_id);
581 	if (rc)
582 		return rc;
583 
584 	PMD_DRV_LOG_LINE(DEBUG,
585 		    "tx_fc_in_tbl.va = %p tx_fc_in_tbl.dma = %p"
586 		    " tx_fc_in_tbl.ctx_id = %d",
587 		    bp->flow_stat->tx_fc_in_tbl.va,
588 		    (void *)((uintptr_t)bp->flow_stat->tx_fc_in_tbl.dma),
589 		    bp->flow_stat->tx_fc_in_tbl.ctx_id);
590 
591 	rc = bnxt_hwrm_ctx_rgtr(bp, bp->flow_stat->tx_fc_out_tbl.dma,
592 				&bp->flow_stat->tx_fc_out_tbl.ctx_id);
593 	if (rc)
594 		return rc;
595 
596 	PMD_DRV_LOG_LINE(DEBUG,
597 		    "tx_fc_out_tbl.va = %p tx_fc_out_tbl.dma = %p"
598 		    " tx_fc_out_tbl.ctx_id = %d",
599 		    bp->flow_stat->tx_fc_out_tbl.va,
600 		    (void *)((uintptr_t)bp->flow_stat->tx_fc_out_tbl.dma),
601 		    bp->flow_stat->tx_fc_out_tbl.ctx_id);
602 
603 	memset(bp->flow_stat->rx_fc_out_tbl.va,
604 	       0,
605 	       bp->flow_stat->rx_fc_out_tbl.size);
606 	rc = bnxt_hwrm_cfa_counter_cfg(bp, BNXT_DIR_RX,
607 				       CFA_COUNTER_CFG_IN_COUNTER_TYPE_FC,
608 				       bp->flow_stat->rx_fc_out_tbl.ctx_id,
609 				       bp->flow_stat->max_fc,
610 				       true);
611 	if (rc)
612 		return rc;
613 
614 	memset(bp->flow_stat->tx_fc_out_tbl.va,
615 	       0,
616 	       bp->flow_stat->tx_fc_out_tbl.size);
617 	rc = bnxt_hwrm_cfa_counter_cfg(bp, BNXT_DIR_TX,
618 				       CFA_COUNTER_CFG_IN_COUNTER_TYPE_FC,
619 				       bp->flow_stat->tx_fc_out_tbl.ctx_id,
620 				       bp->flow_stat->max_fc,
621 				       true);
622 
623 	return rc;
624 }
625 
626 static int bnxt_alloc_ctx_mem_buf(struct bnxt *bp, char *type, size_t size,
627 				  struct bnxt_ctx_mem_buf_info *ctx)
628 {
629 	if (!ctx)
630 		return -EINVAL;
631 
632 	ctx->va = rte_zmalloc_socket(type, size, 0,
633 				     bp->eth_dev->device->numa_node);
634 	if (ctx->va == NULL)
635 		return -ENOMEM;
636 	rte_mem_lock_page(ctx->va);
637 	ctx->size = size;
638 	ctx->dma = rte_mem_virt2iova(ctx->va);
639 	if (ctx->dma == RTE_BAD_IOVA)
640 		return -ENOMEM;
641 
642 	return 0;
643 }
644 
645 static int bnxt_init_fc_ctx_mem(struct bnxt *bp)
646 {
647 	struct rte_pci_device *pdev = bp->pdev;
648 	char type[RTE_MEMZONE_NAMESIZE];
649 	uint16_t max_fc;
650 	int rc = 0;
651 
652 	max_fc = bp->flow_stat->max_fc;
653 
654 	sprintf(type, "bnxt_rx_fc_in_" PCI_PRI_FMT, pdev->addr.domain,
655 		pdev->addr.bus, pdev->addr.devid, pdev->addr.function);
656 	/* 4 bytes for each counter-id */
657 	rc = bnxt_alloc_ctx_mem_buf(bp, type,
658 				    max_fc * 4,
659 				    &bp->flow_stat->rx_fc_in_tbl);
660 	if (rc)
661 		return rc;
662 
663 	sprintf(type, "bnxt_rx_fc_out_" PCI_PRI_FMT, pdev->addr.domain,
664 		pdev->addr.bus, pdev->addr.devid, pdev->addr.function);
665 	/* 16 bytes for each counter - 8 bytes pkt_count, 8 bytes byte_count */
666 	rc = bnxt_alloc_ctx_mem_buf(bp, type,
667 				    max_fc * 16,
668 				    &bp->flow_stat->rx_fc_out_tbl);
669 	if (rc)
670 		return rc;
671 
672 	sprintf(type, "bnxt_tx_fc_in_" PCI_PRI_FMT, pdev->addr.domain,
673 		pdev->addr.bus, pdev->addr.devid, pdev->addr.function);
674 	/* 4 bytes for each counter-id */
675 	rc = bnxt_alloc_ctx_mem_buf(bp, type,
676 				    max_fc * 4,
677 				    &bp->flow_stat->tx_fc_in_tbl);
678 	if (rc)
679 		return rc;
680 
681 	sprintf(type, "bnxt_tx_fc_out_" PCI_PRI_FMT, pdev->addr.domain,
682 		pdev->addr.bus, pdev->addr.devid, pdev->addr.function);
683 	/* 16 bytes for each counter - 8 bytes pkt_count, 8 bytes byte_count */
684 	rc = bnxt_alloc_ctx_mem_buf(bp, type,
685 				    max_fc * 16,
686 				    &bp->flow_stat->tx_fc_out_tbl);
687 	if (rc)
688 		return rc;
689 
690 	rc = bnxt_register_fc_ctx_mem(bp);
691 
692 	return rc;
693 }
694 
695 static int bnxt_init_ctx_mem(struct bnxt *bp)
696 {
697 	int rc = 0;
698 
699 	if (!(bp->fw_cap & BNXT_FW_CAP_ADV_FLOW_COUNTERS) ||
700 	    !(BNXT_PF(bp) || BNXT_VF_IS_TRUSTED(bp)) ||
701 	    !BNXT_FLOW_XSTATS_EN(bp))
702 		return 0;
703 
704 	rc = bnxt_hwrm_cfa_counter_qcaps(bp, &bp->flow_stat->max_fc);
705 	if (rc)
706 		return rc;
707 
708 	rc = bnxt_init_fc_ctx_mem(bp);
709 
710 	return rc;
711 }
712 
713 static inline bool bnxt_force_link_config(struct bnxt *bp)
714 {
715 	uint16_t subsystem_device_id = bp->pdev->id.subsystem_device_id;
716 
717 	switch (subsystem_device_id) {
718 	case BROADCOM_DEV_957508_N2100:
719 	case BROADCOM_DEV_957414_N225:
720 		return true;
721 	default:
722 		return false;
723 	}
724 }
725 
726 static int bnxt_validate_speed_lanes_change(struct bnxt *bp)
727 {
728 	struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
729 	struct rte_eth_link *link = &bp->eth_dev->data->dev_link;
730 	uint32_t curr_speed_bit;
731 	int rc;
732 
733 	/* Check if speed x lanes combo is supported */
734 	if (dev_conf->link_speeds)  {
735 		rc = bnxt_parse_eth_link_speed_v2(bp);
736 		if (rc == 0)
737 			return -EINVAL;
738 	}
739 
740 	/* convert to speedbit flag */
741 	curr_speed_bit = rte_eth_speed_bitflag((uint32_t)link->link_speed, 1);
742 
743 	/* check if speed and lanes have changed */
744 	if (dev_conf->link_speeds != curr_speed_bit ||
745 	    bp->link_info->active_lanes != bp->link_info->pmd_speed_lanes)
746 		return 1;
747 
748 	return 0;
749 }
750 
751 static int bnxt_update_phy_setting(struct bnxt *bp)
752 {
753 	struct rte_eth_link new;
754 	int rc, rc1 = 0;
755 
756 	rc = bnxt_get_hwrm_link_config(bp, &new);
757 	if (rc) {
758 		PMD_DRV_LOG_LINE(ERR, "Failed to get link settings");
759 		return rc;
760 	}
761 
762 	/* Validate speeds2 requirements */
763 	if (BNXT_LINK_SPEEDS_V2(bp)) {
764 		rc1 = bnxt_validate_speed_lanes_change(bp);
765 		if (rc1 == -EINVAL) {
766 			PMD_DRV_LOG_LINE(ERR, "Failed to set correct lanes");
767 			return rc1;
768 		}
769 	}
770 
771 	/*
772 	 * Device is not obliged link down in certain scenarios, even
773 	 * when forced. When FW does not allow any user other than BMC
774 	 * to shutdown the port, bnxt_get_hwrm_link_config() call always
775 	 * returns link up. Force phy update always in that case.
776 	 */
777 	if (!new.link_status || bnxt_force_link_config(bp) || rc1 == 1) {
778 		rc = bnxt_set_hwrm_link_config(bp, true);
779 		if (rc) {
780 			PMD_DRV_LOG_LINE(ERR, "Failed to update PHY settings");
781 			return rc;
782 		}
783 	}
784 
785 	return rc;
786 }
787 
788 static void bnxt_free_prev_ring_stats(struct bnxt *bp)
789 {
790 	/* tpa v2 devices use ext variant local struct */
791 	if (BNXT_TPA_V2_P7(bp)) {
792 		rte_free(bp->prev_rx_ring_stats_ext);
793 		rte_free(bp->prev_tx_ring_stats_ext);
794 		bp->prev_rx_ring_stats_ext = NULL;
795 		bp->prev_tx_ring_stats_ext = NULL;
796 		return;
797 	}
798 	rte_free(bp->prev_rx_ring_stats);
799 	rte_free(bp->prev_tx_ring_stats);
800 	bp->prev_rx_ring_stats = NULL;
801 	bp->prev_tx_ring_stats = NULL;
802 }
803 
804 static int bnxt_alloc_prev_ring_ext_stats(struct bnxt *bp)
805 {
806 	bp->prev_rx_ring_stats_ext = rte_zmalloc("bnxt_prev_rx_ring_stats_ext",
807 						 sizeof(struct bnxt_ring_stats_ext) *
808 						 bp->rx_cp_nr_rings,
809 						 0);
810 	if (bp->prev_rx_ring_stats_ext == NULL)
811 		return -ENOMEM;
812 
813 	bp->prev_tx_ring_stats_ext = rte_zmalloc("bnxt_prev_tx_ring_stats_ext",
814 						 sizeof(struct bnxt_ring_stats_ext) *
815 						 bp->tx_cp_nr_rings,
816 						 0);
817 
818 	if (bp->tx_cp_nr_rings > 0 && bp->prev_tx_ring_stats_ext == NULL)
819 		goto error;
820 
821 	return 0;
822 
823 error:
824 	bnxt_free_prev_ring_stats(bp);
825 	return -ENOMEM;
826 }
827 
828 static int bnxt_alloc_prev_ring_stats(struct bnxt *bp)
829 {
830 	if (BNXT_TPA_V2_P7(bp))
831 		return bnxt_alloc_prev_ring_ext_stats(bp);
832 
833 	bp->prev_rx_ring_stats =  rte_zmalloc("bnxt_prev_rx_ring_stats",
834 					      sizeof(struct bnxt_ring_stats) *
835 					      bp->rx_cp_nr_rings,
836 					      0);
837 	if (bp->prev_rx_ring_stats == NULL)
838 		return -ENOMEM;
839 
840 	bp->prev_tx_ring_stats = rte_zmalloc("bnxt_prev_tx_ring_stats",
841 					     sizeof(struct bnxt_ring_stats) *
842 					     bp->tx_cp_nr_rings,
843 					     0);
844 	if (bp->tx_cp_nr_rings > 0 && bp->prev_tx_ring_stats == NULL)
845 		goto error;
846 
847 	return 0;
848 
849 error:
850 	bnxt_free_prev_ring_stats(bp);
851 	return -ENOMEM;
852 }
853 
854 static int bnxt_start_nic(struct bnxt *bp)
855 {
856 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(bp->eth_dev);
857 	struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
858 	uint32_t intr_vector = 0;
859 	uint32_t queue_id, base = BNXT_MISC_VEC_ID;
860 	uint32_t vec = BNXT_MISC_VEC_ID;
861 	unsigned int i, j;
862 	int rc;
863 
864 	if (bp->eth_dev->data->mtu > RTE_ETHER_MTU)
865 		bp->flags |= BNXT_FLAG_JUMBO;
866 	else
867 		bp->flags &= ~BNXT_FLAG_JUMBO;
868 
869 	/* P5 does not support ring groups.
870 	 * But we will use the array to save RSS context IDs.
871 	 */
872 	if (BNXT_CHIP_P5_P7(bp))
873 		bp->max_ring_grps = BNXT_MAX_RSS_CTXTS_P5;
874 
875 	rc = bnxt_vnic_queue_db_init(bp);
876 	if (rc) {
877 		PMD_DRV_LOG_LINE(ERR, "could not allocate vnic db");
878 		goto err_out;
879 	}
880 
881 	rc = bnxt_alloc_hwrm_rings(bp);
882 	if (rc) {
883 		PMD_DRV_LOG_LINE(ERR, "HWRM ring alloc failure rc: %x", rc);
884 		goto err_out;
885 	}
886 
887 	rc = bnxt_alloc_all_hwrm_ring_grps(bp);
888 	if (rc) {
889 		PMD_DRV_LOG_LINE(ERR, "HWRM ring grp alloc failure: %x", rc);
890 		goto err_out;
891 	}
892 
893 	if (!(bp->vnic_cap_flags & BNXT_VNIC_CAP_COS_CLASSIFY))
894 		goto skip_cosq_cfg;
895 
896 	for (j = 0, i = 0; i < BNXT_COS_QUEUE_COUNT; i++) {
897 		if (bp->rx_cos_queue[i].id != 0xff) {
898 			struct bnxt_vnic_info *vnic = &bp->vnic_info[j++];
899 
900 			if (!vnic) {
901 				PMD_DRV_LOG_LINE(ERR,
902 					    "Num pools more than FW profile");
903 				rc = -EINVAL;
904 				goto err_out;
905 			}
906 			vnic->cos_queue_id = bp->rx_cos_queue[i].id;
907 			bp->rx_cosq_cnt++;
908 		}
909 	}
910 
911 skip_cosq_cfg:
912 	rc = bnxt_mq_rx_configure(bp);
913 	if (rc) {
914 		PMD_DRV_LOG_LINE(ERR, "MQ mode configure failure rc: %x", rc);
915 		goto err_out;
916 	}
917 
918 	for (j = 0; j < bp->rx_nr_rings; j++) {
919 		struct bnxt_rx_queue *rxq = bp->rx_queues[j];
920 
921 		if (!rxq->rx_deferred_start) {
922 			__rte_assume(j < RTE_MAX_QUEUES_PER_PORT);
923 			bp->eth_dev->data->rx_queue_state[j] =
924 				RTE_ETH_QUEUE_STATE_STARTED;
925 			rxq->rx_started = true;
926 		}
927 	}
928 
929 	/* setup the default vnic details*/
930 	bnxt_vnic_queue_db_update_dlft_vnic(bp);
931 
932 	/* VNIC configuration */
933 	for (i = 0; i < bp->nr_vnics; i++) {
934 		rc = bnxt_setup_one_vnic(bp, i);
935 		if (rc)
936 			goto err_out;
937 	}
938 
939 	for (j = 0; j < bp->tx_nr_rings; j++) {
940 		struct bnxt_tx_queue *txq = bp->tx_queues[j];
941 
942 		if (!txq->tx_deferred_start) {
943 			__rte_assume(j < RTE_MAX_QUEUES_PER_PORT);
944 			bp->eth_dev->data->tx_queue_state[j] =
945 				RTE_ETH_QUEUE_STATE_STARTED;
946 			txq->tx_started = true;
947 		}
948 	}
949 
950 	rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, &bp->vnic_info[0], 0, NULL);
951 	if (rc) {
952 		PMD_DRV_LOG_LINE(ERR,
953 			"HWRM cfa l2 rx mask failure rc: %x", rc);
954 		goto err_out;
955 	}
956 
957 	/* check and configure queue intr-vector mapping */
958 	if ((rte_intr_cap_multiple(intr_handle) ||
959 	     !RTE_ETH_DEV_SRIOV(bp->eth_dev).active) &&
960 	    bp->eth_dev->data->dev_conf.intr_conf.rxq != 0) {
961 		intr_vector = bp->eth_dev->data->nb_rx_queues;
962 		PMD_DRV_LOG_LINE(DEBUG, "intr_vector = %d", intr_vector);
963 		if (intr_vector > bp->rx_cp_nr_rings) {
964 			PMD_DRV_LOG_LINE(ERR, "At most %d intr queues supported",
965 					bp->rx_cp_nr_rings);
966 			return -ENOTSUP;
967 		}
968 		rc = rte_intr_efd_enable(intr_handle, intr_vector);
969 		if (rc)
970 			return rc;
971 	}
972 
973 	if (rte_intr_dp_is_en(intr_handle)) {
974 		if (rte_intr_vec_list_alloc(intr_handle, "intr_vec",
975 					bp->eth_dev->data->nb_rx_queues)) {
976 			PMD_DRV_LOG_LINE(ERR, "Failed to allocate %d rx_queues"
977 				" intr_vec", bp->eth_dev->data->nb_rx_queues);
978 			rc = -ENOMEM;
979 			goto err_out;
980 		}
981 		PMD_DRV_LOG_LINE(DEBUG, "intr_handle->nb_efd = %d "
982 			    "intr_handle->max_intr = %d",
983 			    rte_intr_nb_efd_get(intr_handle),
984 			    rte_intr_max_intr_get(intr_handle));
985 		for (queue_id = 0; queue_id < bp->eth_dev->data->nb_rx_queues;
986 		     queue_id++) {
987 			rte_intr_vec_list_index_set(intr_handle,
988 					queue_id, vec + BNXT_RX_VEC_START);
989 			if (vec < base + rte_intr_nb_efd_get(intr_handle)
990 			    - 1)
991 				vec++;
992 		}
993 	}
994 
995 	/* enable uio/vfio intr/eventfd mapping */
996 	rc = rte_intr_enable(intr_handle);
997 #ifndef RTE_EXEC_ENV_FREEBSD
998 	/* In FreeBSD OS, nic_uio driver does not support interrupts */
999 	if (rc)
1000 		goto err_out;
1001 #endif
1002 
1003 	rc = bnxt_update_phy_setting(bp);
1004 	if (rc)
1005 		goto err_out;
1006 
1007 	bp->mark_table = rte_zmalloc("bnxt_mark_table", BNXT_MARK_TABLE_SZ, 0);
1008 	if (!bp->mark_table)
1009 		PMD_DRV_LOG_LINE(ERR, "Allocation of mark table failed");
1010 
1011 	return 0;
1012 
1013 err_out:
1014 	/* Some of the error status returned by FW may not be from errno.h */
1015 	if (rc > 0)
1016 		rc = -EIO;
1017 
1018 	return rc;
1019 }
1020 
1021 static int bnxt_shutdown_nic(struct bnxt *bp)
1022 {
1023 	bnxt_free_all_hwrm_resources(bp);
1024 	bnxt_free_all_filters(bp);
1025 	bnxt_free_all_vnics(bp);
1026 	bnxt_vnic_queue_db_deinit(bp);
1027 	return 0;
1028 }
1029 
1030 /*
1031  * Device configuration and status function
1032  */
1033 
1034 static uint32_t bnxt_get_speed_capabilities_v2(struct bnxt *bp)
1035 {
1036 	uint32_t link_speed = 0;
1037 	uint32_t speed_capa = 0;
1038 
1039 	if (bp->link_info == NULL)
1040 		return 0;
1041 
1042 	link_speed = bp->link_info->support_speeds2;
1043 
1044 	if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_1GB)
1045 		speed_capa |= RTE_ETH_LINK_SPEED_1G;
1046 	if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_10GB)
1047 		speed_capa |= RTE_ETH_LINK_SPEED_10G;
1048 	if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_25GB)
1049 		speed_capa |= RTE_ETH_LINK_SPEED_25G;
1050 	if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_40GB)
1051 		speed_capa |= RTE_ETH_LINK_SPEED_40G;
1052 	if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_50GB)
1053 		speed_capa |= RTE_ETH_LINK_SPEED_50G;
1054 	if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_100GB)
1055 		speed_capa |= RTE_ETH_LINK_SPEED_100G;
1056 	if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_50GB_PAM4_56)
1057 		speed_capa |= RTE_ETH_LINK_SPEED_50G;
1058 	if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_100GB_PAM4_56)
1059 		speed_capa |= RTE_ETH_LINK_SPEED_100G;
1060 	if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_200GB_PAM4_56)
1061 		speed_capa |= RTE_ETH_LINK_SPEED_200G;
1062 	if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_400GB_PAM4_56)
1063 		speed_capa |= RTE_ETH_LINK_SPEED_400G;
1064 	if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_100GB_PAM4_112)
1065 		speed_capa |= RTE_ETH_LINK_SPEED_100G;
1066 	if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_200GB_PAM4_112)
1067 		speed_capa |= RTE_ETH_LINK_SPEED_200G;
1068 	if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_400GB_PAM4_112)
1069 		speed_capa |= RTE_ETH_LINK_SPEED_400G;
1070 
1071 	if (bp->link_info->auto_mode ==
1072 	    HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_NONE)
1073 		speed_capa |= RTE_ETH_LINK_SPEED_FIXED;
1074 
1075 	return speed_capa;
1076 }
1077 
1078 uint32_t bnxt_get_speed_capabilities(struct bnxt *bp)
1079 {
1080 	uint32_t pam4_link_speed = 0;
1081 	uint32_t link_speed = 0;
1082 	uint32_t speed_capa = 0;
1083 
1084 	if (bp->link_info == NULL)
1085 		return 0;
1086 
1087 	/* P7 uses speeds_v2 */
1088 	if (BNXT_LINK_SPEEDS_V2(bp))
1089 		return bnxt_get_speed_capabilities_v2(bp);
1090 
1091 	link_speed = bp->link_info->support_speeds;
1092 
1093 	/* If PAM4 is configured, use PAM4 supported speed */
1094 	if (bp->link_info->support_pam4_speeds > 0)
1095 		pam4_link_speed = bp->link_info->support_pam4_speeds;
1096 
1097 	if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_100MB)
1098 		speed_capa |= RTE_ETH_LINK_SPEED_100M;
1099 	if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_100MBHD)
1100 		speed_capa |= RTE_ETH_LINK_SPEED_100M_HD;
1101 	if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_1GB)
1102 		speed_capa |= RTE_ETH_LINK_SPEED_1G;
1103 	if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_2_5GB)
1104 		speed_capa |= RTE_ETH_LINK_SPEED_2_5G;
1105 	if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_10GB)
1106 		speed_capa |= RTE_ETH_LINK_SPEED_10G;
1107 	if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_20GB)
1108 		speed_capa |= RTE_ETH_LINK_SPEED_20G;
1109 	if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_25GB)
1110 		speed_capa |= RTE_ETH_LINK_SPEED_25G;
1111 	if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_40GB)
1112 		speed_capa |= RTE_ETH_LINK_SPEED_40G;
1113 	if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_50GB)
1114 		speed_capa |= RTE_ETH_LINK_SPEED_50G;
1115 	if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_100GB)
1116 		speed_capa |= RTE_ETH_LINK_SPEED_100G;
1117 	if (pam4_link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_PAM4_SPEEDS_50G)
1118 		speed_capa |= RTE_ETH_LINK_SPEED_50G;
1119 	if (pam4_link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_PAM4_SPEEDS_100G)
1120 		speed_capa |= RTE_ETH_LINK_SPEED_100G;
1121 	if (pam4_link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_PAM4_SPEEDS_200G)
1122 		speed_capa |= RTE_ETH_LINK_SPEED_200G;
1123 
1124 	if (bp->link_info->auto_mode ==
1125 	    HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_NONE)
1126 		speed_capa |= RTE_ETH_LINK_SPEED_FIXED;
1127 
1128 	return speed_capa;
1129 }
1130 
1131 uint64_t bnxt_eth_rss_support(struct bnxt *bp)
1132 {
1133 	uint64_t support;
1134 
1135 	support = RTE_ETH_RSS_IPV4 |
1136 		  RTE_ETH_RSS_NONFRAG_IPV4_TCP |
1137 		  RTE_ETH_RSS_NONFRAG_IPV4_UDP |
1138 		  RTE_ETH_RSS_IPV6 |
1139 		  RTE_ETH_RSS_NONFRAG_IPV6_TCP |
1140 		  RTE_ETH_RSS_NONFRAG_IPV6_UDP |
1141 		  RTE_ETH_RSS_LEVEL_MASK;
1142 
1143 	if (bp->vnic_cap_flags & BNXT_VNIC_CAP_CHKSM_MODE)
1144 		support |= RTE_ETH_RSS_IPV4_CHKSUM |
1145 			   RTE_ETH_RSS_L4_CHKSUM;
1146 	if (bp->vnic_cap_flags & BNXT_VNIC_CAP_IPV6_FLOW_LABEL_MODE)
1147 		support |= RTE_ETH_RSS_IPV6_FLOW_LABEL;
1148 	if (bp->vnic_cap_flags & BNXT_VNIC_CAP_AH_SPI_CAP)
1149 		support |= RTE_ETH_RSS_AH;
1150 	if (bp->vnic_cap_flags & BNXT_VNIC_CAP_ESP_SPI_CAP)
1151 		support |= RTE_ETH_RSS_ESP;
1152 
1153 	return support;
1154 }
1155 
1156 static int bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev,
1157 				struct rte_eth_dev_info *dev_info)
1158 {
1159 	struct rte_pci_device *pdev = RTE_DEV_TO_PCI(eth_dev->device);
1160 	struct bnxt *bp = eth_dev->data->dev_private;
1161 	uint16_t max_vnics, i, j, vpool, vrxq;
1162 	unsigned int max_rx_rings;
1163 	int rc;
1164 
1165 	rc = is_bnxt_in_error(bp);
1166 	if (rc)
1167 		return rc;
1168 
1169 	/* MAC Specifics */
1170 	dev_info->max_mac_addrs = RTE_MIN(bp->max_l2_ctx, RTE_ETH_NUM_RECEIVE_MAC_ADDR);
1171 	dev_info->max_hash_mac_addrs = 0;
1172 
1173 	/* PF/VF specifics */
1174 	if (BNXT_PF(bp))
1175 		dev_info->max_vfs = pdev->max_vfs;
1176 
1177 	max_rx_rings = bnxt_max_rings(bp);
1178 	/* For the sake of symmetry, max_rx_queues = max_tx_queues */
1179 	dev_info->max_rx_queues = max_rx_rings;
1180 	dev_info->max_tx_queues = max_rx_rings;
1181 	dev_info->reta_size = bnxt_rss_hash_tbl_size(bp);
1182 	dev_info->hash_key_size = HW_HASH_KEY_SIZE;
1183 	max_vnics = bp->max_vnics;
1184 
1185 	/* MTU specifics */
1186 	dev_info->min_mtu = RTE_ETHER_MIN_MTU;
1187 	dev_info->max_mtu = BNXT_MAX_MTU;
1188 
1189 	/* Fast path specifics */
1190 	dev_info->min_rx_bufsize = 1;
1191 	dev_info->max_rx_pktlen = BNXT_MAX_PKT_LEN;
1192 
1193 	dev_info->rx_offload_capa = bnxt_get_rx_port_offloads(bp);
1194 	dev_info->tx_queue_offload_capa = RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE;
1195 	dev_info->tx_offload_capa = bnxt_get_tx_port_offloads(bp) |
1196 				    dev_info->tx_queue_offload_capa;
1197 	dev_info->flow_type_rss_offloads = bnxt_eth_rss_support(bp);
1198 	dev_info->rss_algo_capa = RTE_ETH_HASH_ALGO_CAPA_MASK(DEFAULT) |
1199 				  RTE_ETH_HASH_ALGO_CAPA_MASK(TOEPLITZ);
1200 
1201 	if (BNXT_CHIP_P7(bp))
1202 		dev_info->rss_algo_capa |= RTE_ETH_HASH_ALGO_CAPA_MASK(SIMPLE_XOR);
1203 
1204 	dev_info->speed_capa = bnxt_get_speed_capabilities(bp);
1205 	dev_info->dev_capa = RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP |
1206 			     RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP;
1207 	dev_info->dev_capa &= ~RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP;
1208 
1209 	dev_info->default_rxconf = (struct rte_eth_rxconf) {
1210 		.rx_thresh = {
1211 			.pthresh = 8,
1212 			.hthresh = 8,
1213 			.wthresh = 0,
1214 		},
1215 		.rx_free_thresh = 32,
1216 		.rx_drop_en = BNXT_DEFAULT_RX_DROP_EN,
1217 	};
1218 
1219 	dev_info->default_txconf = (struct rte_eth_txconf) {
1220 		.tx_thresh = {
1221 			.pthresh = 32,
1222 			.hthresh = 0,
1223 			.wthresh = 0,
1224 		},
1225 		.tx_free_thresh = 32,
1226 		.tx_rs_thresh = 32,
1227 	};
1228 
1229 	dev_info->rx_desc_lim.nb_min = BNXT_MIN_RING_DESC;
1230 	dev_info->rx_desc_lim.nb_max = BNXT_MAX_RX_RING_DESC;
1231 	dev_info->tx_desc_lim.nb_min = BNXT_MIN_RING_DESC;
1232 	dev_info->tx_desc_lim.nb_max = BNXT_MAX_TX_RING_DESC;
1233 
1234 	if (BNXT_PF(bp) || BNXT_VF_IS_TRUSTED(bp)) {
1235 		dev_info->switch_info.name = eth_dev->device->name;
1236 		dev_info->switch_info.domain_id = bp->switch_domain_id;
1237 		dev_info->switch_info.port_id =
1238 				BNXT_PF(bp) ? BNXT_SWITCH_PORT_ID_PF :
1239 				    BNXT_SWITCH_PORT_ID_TRUSTED_VF;
1240 	}
1241 
1242 	/*
1243 	 * TODO: default_rxconf, default_txconf, rx_desc_lim, and tx_desc_lim
1244 	 *       need further investigation.
1245 	 */
1246 
1247 	/* VMDq resources */
1248 	vpool = 64; /* RTE_ETH_64_POOLS */
1249 	vrxq = 128; /* RTE_ETH_VMDQ_DCB_NUM_QUEUES */
1250 	for (i = 0; i < 4; vpool >>= 1, i++) {
1251 		if (max_vnics > vpool) {
1252 			for (j = 0; j < 5; vrxq >>= 1, j++) {
1253 				if (dev_info->max_rx_queues > vrxq) {
1254 					if (vpool > vrxq)
1255 						vpool = vrxq;
1256 					goto found;
1257 				}
1258 			}
1259 			/* Not enough resources to support VMDq */
1260 			break;
1261 		}
1262 	}
1263 	/* Not enough resources to support VMDq */
1264 	vpool = 0;
1265 	vrxq = 0;
1266 found:
1267 	dev_info->max_vmdq_pools = vpool;
1268 	dev_info->vmdq_queue_num = vrxq;
1269 
1270 	dev_info->vmdq_pool_base = 0;
1271 	dev_info->vmdq_queue_base = 0;
1272 
1273 	dev_info->rx_seg_capa.max_nseg = BNXT_MAX_BUFFER_SPLIT_SEGS;
1274 	dev_info->rx_seg_capa.multi_pools = BNXT_MULTI_POOL_BUF_SPLIT_CAP;
1275 	dev_info->rx_seg_capa.offset_allowed = BNXT_BUF_SPLIT_OFFSET_CAP;
1276 	dev_info->rx_seg_capa.offset_align_log2 = BNXT_BUF_SPLIT_ALIGN_CAP;
1277 
1278 	dev_info->err_handle_mode = RTE_ETH_ERROR_HANDLE_MODE_PROACTIVE;
1279 
1280 	return 0;
1281 }
1282 
1283 /* Configure the device based on the configuration provided */
1284 static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev)
1285 {
1286 	struct bnxt *bp = eth_dev->data->dev_private;
1287 	uint64_t rx_offloads = eth_dev->data->dev_conf.rxmode.offloads;
1288 	struct rte_eth_rss_conf *rss_conf = &eth_dev->data->dev_conf.rx_adv_conf.rss_conf;
1289 	int rc;
1290 
1291 	bp->rx_queues = (void *)eth_dev->data->rx_queues;
1292 	bp->tx_queues = (void *)eth_dev->data->tx_queues;
1293 	bp->tx_nr_rings = eth_dev->data->nb_tx_queues;
1294 	bp->rx_nr_rings = eth_dev->data->nb_rx_queues;
1295 
1296 	rc = is_bnxt_in_error(bp);
1297 	if (rc)
1298 		return rc;
1299 
1300 	if (BNXT_VF(bp) && (bp->flags & BNXT_FLAG_NEW_RM)) {
1301 		rc = bnxt_hwrm_check_vf_rings(bp);
1302 		if (rc) {
1303 			PMD_DRV_LOG_LINE(ERR, "HWRM insufficient resources");
1304 			return -ENOSPC;
1305 		}
1306 
1307 		/* If a resource has already been allocated - in this case
1308 		 * it is the async completion ring, free it. Reallocate it after
1309 		 * resource reservation. This will ensure the resource counts
1310 		 * are calculated correctly.
1311 		 */
1312 
1313 		pthread_mutex_lock(&bp->def_cp_lock);
1314 
1315 		if (!BNXT_HAS_NQ(bp) && bp->async_cp_ring) {
1316 			bnxt_disable_int(bp);
1317 			bnxt_free_cp_ring(bp, bp->async_cp_ring);
1318 		}
1319 
1320 		rc = bnxt_hwrm_func_reserve_vf_resc(bp, false);
1321 		if (rc) {
1322 			PMD_DRV_LOG_LINE(ERR, "HWRM resource alloc fail:%x", rc);
1323 			pthread_mutex_unlock(&bp->def_cp_lock);
1324 			return -ENOSPC;
1325 		}
1326 
1327 		if (!BNXT_HAS_NQ(bp) && bp->async_cp_ring) {
1328 			rc = bnxt_alloc_async_cp_ring(bp);
1329 			if (rc) {
1330 				pthread_mutex_unlock(&bp->def_cp_lock);
1331 				return rc;
1332 			}
1333 			bnxt_enable_int(bp);
1334 		}
1335 
1336 		pthread_mutex_unlock(&bp->def_cp_lock);
1337 	}
1338 
1339 	/* Inherit new configurations */
1340 	if (eth_dev->data->nb_rx_queues > bp->max_rx_rings ||
1341 	    eth_dev->data->nb_tx_queues > bp->max_tx_rings ||
1342 	    eth_dev->data->nb_rx_queues + eth_dev->data->nb_tx_queues
1343 		+ BNXT_NUM_ASYNC_CPR(bp) > bp->max_cp_rings ||
1344 	    eth_dev->data->nb_rx_queues + eth_dev->data->nb_tx_queues >
1345 	    bp->max_stat_ctx)
1346 		goto resource_error;
1347 
1348 	if (BNXT_HAS_RING_GRPS(bp) &&
1349 	    (uint32_t)(eth_dev->data->nb_rx_queues) > bp->max_ring_grps)
1350 		goto resource_error;
1351 
1352 	if (!(eth_dev->data->dev_conf.rxmode.mq_mode & RTE_ETH_MQ_RX_RSS) &&
1353 	    bp->max_vnics < eth_dev->data->nb_rx_queues)
1354 		goto resource_error;
1355 
1356 	bp->rx_cp_nr_rings = bp->rx_nr_rings;
1357 	bp->tx_cp_nr_rings = bp->tx_nr_rings;
1358 
1359 	if (eth_dev->data->dev_conf.rxmode.mq_mode & RTE_ETH_MQ_RX_RSS_FLAG)
1360 		rx_offloads |= RTE_ETH_RX_OFFLOAD_RSS_HASH;
1361 	eth_dev->data->dev_conf.rxmode.offloads = rx_offloads;
1362 
1363 	/* application provides the hash key to program */
1364 	if (rss_conf->rss_key != NULL) {
1365 		if (rss_conf->rss_key_len != HW_HASH_KEY_SIZE)
1366 			PMD_DRV_LOG_LINE(WARNING, "port %u RSS key len must be %d bytes long",
1367 				    eth_dev->data->port_id, HW_HASH_KEY_SIZE);
1368 		else
1369 			memcpy(bp->rss_conf.rss_key, rss_conf->rss_key, HW_HASH_KEY_SIZE);
1370 	}
1371 	bp->rss_conf.rss_key_len = HW_HASH_KEY_SIZE;
1372 	bp->rss_conf.rss_hf = rss_conf->rss_hf;
1373 
1374 	bnxt_mtu_set_op(eth_dev, eth_dev->data->mtu);
1375 
1376 	return 0;
1377 
1378 resource_error:
1379 	PMD_DRV_LOG_LINE(ERR,
1380 		    "Insufficient resources to support requested config");
1381 	PMD_DRV_LOG_LINE(ERR,
1382 		    "Num Queues Requested: Tx %d, Rx %d",
1383 		    eth_dev->data->nb_tx_queues,
1384 		    eth_dev->data->nb_rx_queues);
1385 	PMD_DRV_LOG_LINE(ERR,
1386 		    "MAX: TxQ %d, RxQ %d, CQ %d Stat %d, Grp %d, Vnic %d",
1387 		    bp->max_tx_rings, bp->max_rx_rings, bp->max_cp_rings,
1388 		    bp->max_stat_ctx, bp->max_ring_grps, bp->max_vnics);
1389 	return -ENOSPC;
1390 }
1391 
1392 void bnxt_print_link_info(struct rte_eth_dev *eth_dev)
1393 {
1394 	struct rte_eth_link *link = &eth_dev->data->dev_link;
1395 	struct bnxt *bp = eth_dev->data->dev_private;
1396 
1397 	if (link->link_status)
1398 		PMD_DRV_LOG_LINE(DEBUG, "Port %d Link Up - speed %u Mbps - %s Lanes - %d",
1399 			eth_dev->data->port_id,
1400 			(uint32_t)link->link_speed,
1401 			(link->link_duplex == RTE_ETH_LINK_FULL_DUPLEX) ?
1402 			("full-duplex") : ("half-duplex"),
1403 			(uint16_t)bp->link_info->active_lanes);
1404 	else
1405 		PMD_DRV_LOG_LINE(INFO, "Port %d Link Down", eth_dev->data->port_id);
1406 }
1407 
1408 /*
1409  * Determine whether the current configuration requires support for scattered
1410  * receive; return 1 if scattered receive is required and 0 if not.
1411  */
1412 static int bnxt_scattered_rx(struct rte_eth_dev *eth_dev)
1413 {
1414 	uint32_t overhead = BNXT_MAX_PKT_LEN - BNXT_MAX_MTU;
1415 	uint16_t buf_size;
1416 	int i;
1417 
1418 	if (eth_dev->data->dev_conf.rxmode.offloads & RTE_ETH_RX_OFFLOAD_SCATTER)
1419 		return 1;
1420 
1421 	if (eth_dev->data->dev_conf.rxmode.offloads & RTE_ETH_RX_OFFLOAD_TCP_LRO)
1422 		return 1;
1423 
1424 	for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
1425 		struct bnxt_rx_queue *rxq = eth_dev->data->rx_queues[i];
1426 
1427 		buf_size = (uint16_t)(rte_pktmbuf_data_room_size(rxq->mb_pool) -
1428 				      RTE_PKTMBUF_HEADROOM);
1429 		if (eth_dev->data->mtu + overhead > buf_size)
1430 			return 1;
1431 	}
1432 	return 0;
1433 }
1434 
1435 static eth_rx_burst_t
1436 bnxt_receive_function(struct rte_eth_dev *eth_dev)
1437 {
1438 	struct bnxt *bp = eth_dev->data->dev_private;
1439 
1440 #if defined(RTE_ARCH_X86) || defined(RTE_ARCH_ARM64)
1441 	/* Vector mode receive cannot be enabled if scattered rx is in use. */
1442 	if (eth_dev->data->scattered_rx)
1443 		goto use_scalar_rx;
1444 
1445 	/*
1446 	 * Vector mode receive cannot be enabled if Truflow is enabled or if
1447 	 * asynchronous completions and receive completions can be placed in
1448 	 * the same completion ring.
1449 	 */
1450 	if ((BNXT_TRUFLOW_EN(bp) && !BNXT_CHIP_P7(bp)) ||
1451 	    !BNXT_NUM_ASYNC_CPR(bp))
1452 		goto use_scalar_rx;
1453 
1454 	/*
1455 	 * Vector mode receive cannot be enabled if any receive offloads outside
1456 	 * a limited subset have been enabled.
1457 	 */
1458 	if (eth_dev->data->dev_conf.rxmode.offloads &
1459 		~(RTE_ETH_RX_OFFLOAD_VLAN_STRIP |
1460 		  RTE_ETH_RX_OFFLOAD_KEEP_CRC |
1461 		  RTE_ETH_RX_OFFLOAD_IPV4_CKSUM |
1462 		  RTE_ETH_RX_OFFLOAD_UDP_CKSUM |
1463 		  RTE_ETH_RX_OFFLOAD_TCP_CKSUM |
1464 		  RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM |
1465 		  RTE_ETH_RX_OFFLOAD_OUTER_UDP_CKSUM |
1466 		  RTE_ETH_RX_OFFLOAD_RSS_HASH |
1467 		  RTE_ETH_RX_OFFLOAD_VLAN_FILTER))
1468 		goto use_scalar_rx;
1469 
1470 	if (bp->ieee_1588)
1471 		goto use_scalar_rx;
1472 
1473 #if defined(RTE_ARCH_X86)
1474 	if (rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_256 &&
1475 	    rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX2) == 1) {
1476 		PMD_DRV_LOG_LINE(INFO,
1477 			    "Using AVX2 vector mode receive for port %d",
1478 			    eth_dev->data->port_id);
1479 		bp->flags |= BNXT_FLAG_RX_VECTOR_PKT_MODE;
1480 		if (bnxt_compressed_rx_cqe_mode_enabled(bp))
1481 			return bnxt_crx_pkts_vec_avx2;
1482 		return bnxt_recv_pkts_vec_avx2;
1483 	}
1484 #endif
1485 	if (rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_128) {
1486 		PMD_DRV_LOG_LINE(INFO,
1487 			    "Using SSE vector mode receive for port %d",
1488 			    eth_dev->data->port_id);
1489 		bp->flags |= BNXT_FLAG_RX_VECTOR_PKT_MODE;
1490 		if (bnxt_compressed_rx_cqe_mode_enabled(bp)) {
1491 #if defined(RTE_ARCH_ARM64)
1492 			goto use_scalar_rx;
1493 #else
1494 			return bnxt_crx_pkts_vec;
1495 #endif
1496 		}
1497 		return bnxt_recv_pkts_vec;
1498 	}
1499 
1500 use_scalar_rx:
1501 	PMD_DRV_LOG_LINE(INFO, "Vector mode receive disabled for port %d",
1502 		    eth_dev->data->port_id);
1503 	PMD_DRV_LOG_LINE(INFO,
1504 		    "Port %d scatter: %d rx offload: %" PRIX64,
1505 		    eth_dev->data->port_id,
1506 		    eth_dev->data->scattered_rx,
1507 		    eth_dev->data->dev_conf.rxmode.offloads);
1508 #endif
1509 	bp->flags &= ~BNXT_FLAG_RX_VECTOR_PKT_MODE;
1510 	return bnxt_recv_pkts;
1511 }
1512 
1513 static eth_tx_burst_t
1514 bnxt_transmit_function(__rte_unused struct rte_eth_dev *eth_dev)
1515 {
1516 #if defined(RTE_ARCH_X86) || defined(RTE_ARCH_ARM64)
1517 	uint64_t offloads = eth_dev->data->dev_conf.txmode.offloads;
1518 	struct bnxt *bp = eth_dev->data->dev_private;
1519 
1520 	/*
1521 	 * Vector mode transmit can be enabled only if not using scatter rx
1522 	 * or tx offloads.
1523 	 */
1524 	if (eth_dev->data->scattered_rx ||
1525 	    (offloads & ~RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE) ||
1526 	    (BNXT_TRUFLOW_EN(bp) && !BNXT_CHIP_P7(bp)) ||
1527 	    bp->ieee_1588)
1528 		goto use_scalar_tx;
1529 
1530 #if defined(RTE_ARCH_X86)
1531 	if (rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_256 &&
1532 	    rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX2) == 1) {
1533 		PMD_DRV_LOG_LINE(INFO,
1534 			    "Using AVX2 vector mode transmit for port %d",
1535 			    eth_dev->data->port_id);
1536 		return bnxt_xmit_pkts_vec_avx2;
1537 	}
1538 #endif
1539 	if (rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_128) {
1540 		PMD_DRV_LOG_LINE(INFO,
1541 			    "Using SSE vector mode transmit for port %d",
1542 			    eth_dev->data->port_id);
1543 		return bnxt_xmit_pkts_vec;
1544 	}
1545 
1546 use_scalar_tx:
1547 	PMD_DRV_LOG_LINE(INFO, "Vector mode transmit disabled for port %d",
1548 		    eth_dev->data->port_id);
1549 	PMD_DRV_LOG_LINE(INFO,
1550 		    "Port %d scatter: %d tx offload: %" PRIX64,
1551 		    eth_dev->data->port_id,
1552 		    eth_dev->data->scattered_rx,
1553 		    offloads);
1554 #endif
1555 	return bnxt_xmit_pkts;
1556 }
1557 
1558 static int bnxt_handle_if_change_status(struct bnxt *bp)
1559 {
1560 	int rc;
1561 
1562 	/* Since fw has undergone a reset and lost all contexts,
1563 	 * set fatal flag to not issue hwrm during cleanup
1564 	 */
1565 	bp->flags |= BNXT_FLAG_FATAL_ERROR;
1566 	bnxt_uninit_resources(bp, true);
1567 
1568 	/* clear fatal flag so that re-init happens */
1569 	bp->flags &= ~BNXT_FLAG_FATAL_ERROR;
1570 
1571 	rc = bnxt_check_fw_ready(bp);
1572 	if (rc)
1573 		return rc;
1574 
1575 	rc = bnxt_init_resources(bp, true);
1576 
1577 	bp->flags &= ~BNXT_FLAG_IF_CHANGE_HOT_FW_RESET_DONE;
1578 
1579 	return rc;
1580 }
1581 
1582 static int bnxt_dev_set_link_up_op(struct rte_eth_dev *eth_dev)
1583 {
1584 	struct bnxt *bp = eth_dev->data->dev_private;
1585 	int rc = 0;
1586 
1587 	if (!BNXT_SINGLE_PF(bp))
1588 		return -ENOTSUP;
1589 
1590 	if (!bp->link_info->link_up)
1591 		rc = bnxt_set_hwrm_link_config(bp, true);
1592 	if (!rc)
1593 		eth_dev->data->dev_link.link_status = 1;
1594 
1595 	bnxt_print_link_info(eth_dev);
1596 	return rc;
1597 }
1598 
1599 static int bnxt_dev_set_link_down_op(struct rte_eth_dev *eth_dev)
1600 {
1601 	struct bnxt *bp = eth_dev->data->dev_private;
1602 
1603 	if (!BNXT_SINGLE_PF(bp))
1604 		return -ENOTSUP;
1605 
1606 	eth_dev->data->dev_link.link_status = 0;
1607 	bnxt_set_hwrm_link_config(bp, false);
1608 	bp->link_info->link_up = 0;
1609 
1610 	return 0;
1611 }
1612 
1613 static void bnxt_free_switch_domain(struct bnxt *bp)
1614 {
1615 	int rc = 0;
1616 
1617 	if (!(BNXT_PF(bp) || BNXT_VF_IS_TRUSTED(bp)))
1618 		return;
1619 
1620 	rc = rte_eth_switch_domain_free(bp->switch_domain_id);
1621 	if (rc)
1622 		PMD_DRV_LOG_LINE(ERR, "free switch domain:%d fail: %d",
1623 			    bp->switch_domain_id, rc);
1624 }
1625 
1626 static void bnxt_ptp_get_current_time(void *arg)
1627 {
1628 	struct bnxt *bp = arg;
1629 	struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
1630 	int rc;
1631 
1632 	rc = is_bnxt_in_error(bp);
1633 	if (rc)
1634 		return;
1635 
1636 	if (!ptp)
1637 		return;
1638 
1639 	rte_spinlock_lock(&ptp->ptp_lock);
1640 	ptp->old_time = ptp->current_time;
1641 	bnxt_hwrm_port_ts_query(bp, BNXT_PTP_FLAGS_CURRENT_TIME,
1642 				&ptp->current_time);
1643 	rte_spinlock_unlock(&ptp->ptp_lock);
1644 	rc = rte_eal_alarm_set(US_PER_S, bnxt_ptp_get_current_time, (void *)bp);
1645 	if (rc != 0) {
1646 		PMD_DRV_LOG_LINE(ERR, "Failed to re-schedule PTP alarm");
1647 		bp->flags2 &= ~BNXT_FLAGS2_PTP_ALARM_SCHEDULED;
1648 	}
1649 }
1650 
1651 static int bnxt_schedule_ptp_alarm(struct bnxt *bp)
1652 {
1653 	struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
1654 	int rc;
1655 
1656 	if (bp->flags2 & BNXT_FLAGS2_PTP_ALARM_SCHEDULED)
1657 		return 0;
1658 
1659 	rte_spinlock_lock(&ptp->ptp_lock);
1660 	bnxt_hwrm_port_ts_query(bp, BNXT_PTP_FLAGS_CURRENT_TIME,
1661 				&ptp->current_time);
1662 	ptp->old_time = ptp->current_time;
1663 	rte_spinlock_unlock(&ptp->ptp_lock);
1664 
1665 
1666 	rc = rte_eal_alarm_set(US_PER_S, bnxt_ptp_get_current_time, (void *)bp);
1667 	return rc;
1668 }
1669 
1670 static void bnxt_cancel_ptp_alarm(struct bnxt *bp)
1671 {
1672 	if (bp->flags2 & BNXT_FLAGS2_PTP_ALARM_SCHEDULED) {
1673 		rte_eal_alarm_cancel(bnxt_ptp_get_current_time, (void *)bp);
1674 		bp->flags2 &= ~BNXT_FLAGS2_PTP_ALARM_SCHEDULED;
1675 	}
1676 }
1677 
1678 static void bnxt_ptp_stop(struct bnxt *bp)
1679 {
1680 	bnxt_cancel_ptp_alarm(bp);
1681 	bp->flags2 &= ~BNXT_FLAGS2_PTP_TIMESYNC_ENABLED;
1682 }
1683 
1684 static int bnxt_ptp_start(struct bnxt *bp)
1685 {
1686 	int rc;
1687 
1688 	rc = bnxt_schedule_ptp_alarm(bp);
1689 	if (rc != 0) {
1690 		PMD_DRV_LOG_LINE(ERR, "Failed to schedule PTP alarm");
1691 	} else {
1692 		bp->flags2 |= BNXT_FLAGS2_PTP_TIMESYNC_ENABLED;
1693 		bp->flags2 |= BNXT_FLAGS2_PTP_ALARM_SCHEDULED;
1694 	}
1695 
1696 	return rc;
1697 }
1698 
1699 static int bnxt_dev_stop(struct rte_eth_dev *eth_dev)
1700 {
1701 	struct bnxt *bp = eth_dev->data->dev_private;
1702 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
1703 	struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
1704 	struct rte_eth_link link;
1705 	uint16_t i;
1706 	int ret;
1707 
1708 	eth_dev->data->dev_started = 0;
1709 
1710 	/* Prevent crashes when queues are still in use */
1711 	bnxt_stop_rxtx(eth_dev);
1712 
1713 	bnxt_disable_int(bp);
1714 
1715 	/* disable uio/vfio intr/eventfd mapping */
1716 	rte_intr_disable(intr_handle);
1717 
1718 	/* Stop the child representors for this device */
1719 	ret = bnxt_rep_stop_all(bp);
1720 	if (ret != 0)
1721 		return ret;
1722 
1723 	/* delete the bnxt ULP port details */
1724 	if (bnxt_enable_ulp(bp))
1725 		bnxt_ulp_port_deinit(bp);
1726 
1727 	bnxt_cancel_fw_health_check(bp);
1728 
1729 	if (BNXT_P5_PTP_TIMESYNC_ENABLED(bp))
1730 		bnxt_cancel_ptp_alarm(bp);
1731 
1732 	/* Do not bring link down during reset recovery */
1733 	if (!is_bnxt_in_error(bp)) {
1734 		bnxt_dev_set_link_down_op(eth_dev);
1735 		/* Wait for link to be reset */
1736 		if (BNXT_SINGLE_PF(bp))
1737 			rte_delay_ms(500);
1738 		/* clear the recorded link status */
1739 		memset(&link, 0, sizeof(link));
1740 		rte_eth_linkstatus_set(eth_dev, &link);
1741 	}
1742 
1743 	/* Clean queue intr-vector mapping */
1744 	rte_intr_efd_disable(intr_handle);
1745 	rte_intr_vec_list_free(intr_handle);
1746 
1747 	bnxt_hwrm_port_clr_stats(bp);
1748 	bnxt_free_tx_mbufs(bp);
1749 	bnxt_free_rx_mbufs(bp);
1750 	/* Process any remaining notifications in default completion queue */
1751 	bnxt_int_handler(eth_dev);
1752 
1753 	if (mpc != 0)
1754 		bnxt_mpc_close(bp);
1755 
1756 	bnxt_shutdown_nic(bp);
1757 	bnxt_hwrm_if_change(bp, false);
1758 
1759 	bnxt_free_prev_ring_stats(bp);
1760 	rte_free(bp->mark_table);
1761 	bp->mark_table = NULL;
1762 
1763 	bp->flags &= ~BNXT_FLAG_RX_VECTOR_PKT_MODE;
1764 	bp->rx_cosq_cnt = 0;
1765 	/* All filters are deleted on a port stop. */
1766 	if (BNXT_FLOW_XSTATS_EN(bp))
1767 		bp->flow_stat->flow_count = 0;
1768 
1769 	eth_dev->data->scattered_rx = 0;
1770 
1771 	for (i = 0; i < eth_dev->data->nb_rx_queues; i++)
1772 		eth_dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
1773 	for (i = 0; i < eth_dev->data->nb_tx_queues; i++)
1774 		eth_dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
1775 
1776 	return 0;
1777 }
1778 
1779 /* Unload the driver, release resources */
1780 int bnxt_dev_stop_op(struct rte_eth_dev *eth_dev)
1781 {
1782 	struct bnxt *bp = eth_dev->data->dev_private;
1783 
1784 	pthread_mutex_lock(&bp->err_recovery_lock);
1785 	if (bp->flags & BNXT_FLAG_FW_RESET) {
1786 		PMD_DRV_LOG_LINE(ERR,
1787 			    "Adapter recovering from error..Please retry");
1788 		pthread_mutex_unlock(&bp->err_recovery_lock);
1789 		return -EAGAIN;
1790 	}
1791 	pthread_mutex_unlock(&bp->err_recovery_lock);
1792 
1793 	return bnxt_dev_stop(eth_dev);
1794 }
1795 
1796 int bnxt_dev_start_op(struct rte_eth_dev *eth_dev)
1797 {
1798 	struct bnxt *bp = eth_dev->data->dev_private;
1799 	uint64_t rx_offloads = eth_dev->data->dev_conf.rxmode.offloads;
1800 	int vlan_mask = 0;
1801 	int rc, retry_cnt = BNXT_IF_CHANGE_RETRY_COUNT;
1802 
1803 	if (bp->rx_cp_nr_rings > RTE_ETHDEV_QUEUE_STAT_CNTRS)
1804 		PMD_DRV_LOG_LINE(ERR,
1805 			    "RxQ cnt %d > RTE_ETHDEV_QUEUE_STAT_CNTRS %d",
1806 			    bp->rx_cp_nr_rings, RTE_ETHDEV_QUEUE_STAT_CNTRS);
1807 
1808 	do {
1809 		rc = bnxt_hwrm_if_change(bp, true);
1810 		if (rc == 0 || rc != -EAGAIN)
1811 			break;
1812 
1813 		rte_delay_ms(BNXT_IF_CHANGE_RETRY_INTERVAL);
1814 	} while (retry_cnt--);
1815 
1816 	if (rc)
1817 		return rc;
1818 
1819 	if (bp->flags & BNXT_FLAG_IF_CHANGE_HOT_FW_RESET_DONE) {
1820 		rc = bnxt_handle_if_change_status(bp);
1821 		if (rc)
1822 			return rc;
1823 	}
1824 
1825 	bnxt_enable_int(bp);
1826 
1827 	eth_dev->data->scattered_rx = bnxt_scattered_rx(eth_dev);
1828 
1829 	rc = bnxt_start_nic(bp);
1830 	if (rc)
1831 		goto error;
1832 
1833 	if (mpc != 0) {
1834 		rc = bnxt_mpc_open(bp);
1835 		if (rc != 0)
1836 			PMD_DRV_LOG_LINE(DEBUG, "MPC open failed");
1837 	}
1838 
1839 	rc = bnxt_alloc_prev_ring_stats(bp);
1840 	if (rc)
1841 		goto error;
1842 
1843 	eth_dev->data->dev_started = 1;
1844 
1845 	bnxt_link_update_op(eth_dev, 0);
1846 
1847 	if (rx_offloads & RTE_ETH_RX_OFFLOAD_VLAN_FILTER)
1848 		vlan_mask |= RTE_ETH_VLAN_FILTER_MASK;
1849 	if (rx_offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP)
1850 		vlan_mask |= RTE_ETH_VLAN_STRIP_MASK;
1851 	rc = bnxt_vlan_offload_set_op(eth_dev, vlan_mask);
1852 	if (rc)
1853 		goto error;
1854 
1855 	/* Initialize bnxt ULP port details */
1856 	if (bnxt_enable_ulp(bp)) {
1857 		if (BNXT_CHIP_P7(bp)) {
1858 			/* Need to release the Fid from AFM control */
1859 			rc = bnxt_hwrm_release_afm_func(bp, bp->fw_fid,
1860 							bp->fw_fid,
1861 							HWRM_CFA_RELEASE_AFM_FUNC_INPUT_TYPE_RFID,
1862 							0);
1863 			if (rc) {
1864 				PMD_DRV_LOG_LINE(ERR,
1865 						 "Failed in hwrm release afm func:%u rc=%d",
1866 						 bp->fw_fid, rc);
1867 				goto error;
1868 			}
1869 			PMD_DRV_LOG_LINE(DEBUG, "Released RFID:%d", bp->fw_fid);
1870 		}
1871 
1872 		rc = bnxt_ulp_port_init(bp);
1873 		if (rc)
1874 			goto error;
1875 	}
1876 
1877 	eth_dev->rx_pkt_burst = bnxt_receive_function(eth_dev);
1878 	eth_dev->tx_pkt_burst = bnxt_transmit_function(eth_dev);
1879 
1880 	bnxt_schedule_fw_health_check(bp);
1881 
1882 	if (BNXT_P5_PTP_TIMESYNC_ENABLED(bp))
1883 		bnxt_schedule_ptp_alarm(bp);
1884 
1885 	return 0;
1886 
1887 error:
1888 	bnxt_dev_stop(eth_dev);
1889 	return rc;
1890 }
1891 
1892 static void
1893 bnxt_uninit_locks(struct bnxt *bp)
1894 {
1895 	pthread_mutex_destroy(&bp->flow_lock);
1896 	pthread_mutex_destroy(&bp->def_cp_lock);
1897 	pthread_mutex_destroy(&bp->health_check_lock);
1898 	pthread_mutex_destroy(&bp->err_recovery_lock);
1899 	if (bp->rep_info)
1900 		pthread_mutex_destroy(&bp->rep_info->vfr_start_lock);
1901 }
1902 
1903 static void bnxt_drv_uninit(struct bnxt *bp)
1904 {
1905 	bnxt_free_leds_info(bp);
1906 	bnxt_free_cos_queues(bp);
1907 	bnxt_free_link_info(bp);
1908 	bnxt_free_parent_info(bp);
1909 	bnxt_uninit_locks(bp);
1910 	bnxt_free_rep_info(bp);
1911 
1912 	rte_memzone_free((const struct rte_memzone *)bp->tx_mem_zone);
1913 	bp->tx_mem_zone = NULL;
1914 	rte_memzone_free((const struct rte_memzone *)bp->rx_mem_zone);
1915 	bp->rx_mem_zone = NULL;
1916 
1917 	bnxt_free_vf_info(bp);
1918 	bnxt_free_pf_info(bp);
1919 
1920 	rte_free(bp->grp_info);
1921 	bp->grp_info = NULL;
1922 }
1923 
1924 static int bnxt_dev_close_op(struct rte_eth_dev *eth_dev)
1925 {
1926 	struct bnxt *bp = eth_dev->data->dev_private;
1927 	int ret = 0;
1928 
1929 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
1930 		return 0;
1931 
1932 	pthread_mutex_lock(&bp->err_recovery_lock);
1933 	if (bp->flags & BNXT_FLAG_FW_RESET) {
1934 		PMD_DRV_LOG_LINE(ERR,
1935 			    "Adapter recovering from error...Please retry");
1936 		pthread_mutex_unlock(&bp->err_recovery_lock);
1937 		return -EAGAIN;
1938 	}
1939 	pthread_mutex_unlock(&bp->err_recovery_lock);
1940 
1941 	/* cancel the recovery handler before remove dev */
1942 	rte_eal_alarm_cancel(bnxt_dev_reset_and_resume, (void *)bp);
1943 	rte_eal_alarm_cancel(bnxt_dev_recover, (void *)bp);
1944 	bnxt_cancel_fc_thread(bp);
1945 	rte_eal_alarm_cancel(bnxt_handle_vf_cfg_change, (void *)bp);
1946 
1947 	if (eth_dev->data->dev_started)
1948 		ret = bnxt_dev_stop(eth_dev);
1949 
1950 	bnxt_uninit_resources(bp, false);
1951 
1952 	bnxt_drv_uninit(bp);
1953 
1954 	return ret;
1955 }
1956 
1957 static void bnxt_mac_addr_remove_op(struct rte_eth_dev *eth_dev,
1958 				    uint32_t index)
1959 {
1960 	struct bnxt *bp = eth_dev->data->dev_private;
1961 	uint64_t pool_mask = eth_dev->data->mac_pool_sel[index];
1962 	struct bnxt_vnic_info *vnic;
1963 	struct bnxt_filter_info *filter, *temp_filter;
1964 	uint32_t i;
1965 
1966 	if (is_bnxt_in_error(bp))
1967 		return;
1968 
1969 	/*
1970 	 * Loop through all VNICs from the specified filter flow pools to
1971 	 * remove the corresponding MAC addr filter
1972 	 */
1973 	for (i = 0; i < bp->nr_vnics; i++) {
1974 		if (!(pool_mask & (1ULL << i)))
1975 			continue;
1976 
1977 		vnic = &bp->vnic_info[i];
1978 		filter = STAILQ_FIRST(&vnic->filter);
1979 		while (filter) {
1980 			temp_filter = STAILQ_NEXT(filter, next);
1981 			if (filter->mac_index == index) {
1982 				STAILQ_REMOVE(&vnic->filter, filter,
1983 						bnxt_filter_info, next);
1984 				bnxt_hwrm_clear_l2_filter(bp, filter);
1985 				bnxt_free_filter(bp, filter);
1986 			}
1987 			filter = temp_filter;
1988 		}
1989 	}
1990 }
1991 
1992 static int bnxt_add_mac_filter(struct bnxt *bp, struct bnxt_vnic_info *vnic,
1993 			       struct rte_ether_addr *mac_addr, uint32_t index,
1994 			       uint32_t pool)
1995 {
1996 	struct bnxt_filter_info *filter;
1997 	int rc = 0;
1998 
1999 	/* Attach requested MAC address to the new l2_filter */
2000 	STAILQ_FOREACH(filter, &vnic->filter, next) {
2001 		if (filter->mac_index == index) {
2002 			PMD_DRV_LOG_LINE(DEBUG,
2003 				    "MAC addr already existed for pool %d",
2004 				    pool);
2005 			return 0;
2006 		}
2007 	}
2008 
2009 	filter = bnxt_alloc_filter(bp);
2010 	if (!filter) {
2011 		PMD_DRV_LOG_LINE(ERR, "L2 filter alloc failed");
2012 		return -ENODEV;
2013 	}
2014 
2015 	/* bnxt_alloc_filter copies default MAC to filter->l2_addr. So,
2016 	 * if the MAC that's been programmed now is a different one, then,
2017 	 * copy that addr to filter->l2_addr
2018 	 */
2019 	if (mac_addr)
2020 		memcpy(filter->l2_addr, mac_addr, RTE_ETHER_ADDR_LEN);
2021 	filter->flags |= HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_OUTERMOST;
2022 
2023 	rc = bnxt_hwrm_set_l2_filter(bp, vnic->fw_vnic_id, filter);
2024 	if (!rc) {
2025 		filter->mac_index = index;
2026 		if (filter->mac_index == 0)
2027 			STAILQ_INSERT_HEAD(&vnic->filter, filter, next);
2028 		else
2029 			STAILQ_INSERT_TAIL(&vnic->filter, filter, next);
2030 	} else {
2031 		bnxt_free_filter(bp, filter);
2032 	}
2033 
2034 	return rc;
2035 }
2036 
2037 static int bnxt_mac_addr_add_op(struct rte_eth_dev *eth_dev,
2038 				struct rte_ether_addr *mac_addr,
2039 				uint32_t index, uint32_t pool)
2040 {
2041 	struct bnxt *bp = eth_dev->data->dev_private;
2042 	struct bnxt_vnic_info *vnic = &bp->vnic_info[pool];
2043 	int rc = 0;
2044 
2045 	rc = is_bnxt_in_error(bp);
2046 	if (rc)
2047 		return rc;
2048 
2049 	if (BNXT_VF(bp) && !BNXT_VF_IS_TRUSTED(bp)) {
2050 		PMD_DRV_LOG_LINE(ERR, "Cannot add MAC address to a VF interface");
2051 		return -ENOTSUP;
2052 	}
2053 
2054 	if (!vnic) {
2055 		PMD_DRV_LOG_LINE(ERR, "VNIC not found for pool %d!", pool);
2056 		return -EINVAL;
2057 	}
2058 
2059 	/* Filter settings will get applied when port is started */
2060 	if (!eth_dev->data->dev_started)
2061 		return 0;
2062 
2063 	rc = bnxt_add_mac_filter(bp, vnic, mac_addr, index, pool);
2064 
2065 	return rc;
2066 }
2067 
2068 int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete)
2069 {
2070 	int rc = 0;
2071 	struct bnxt *bp = eth_dev->data->dev_private;
2072 	struct rte_eth_link new;
2073 	int cnt = wait_to_complete ? BNXT_MAX_LINK_WAIT_CNT :
2074 			BNXT_MIN_LINK_WAIT_CNT;
2075 
2076 	rc = is_bnxt_in_error(bp);
2077 	if (rc)
2078 		return rc;
2079 
2080 	memset(&new, 0, sizeof(new));
2081 
2082 	if (bp->link_info == NULL)
2083 		goto out;
2084 
2085 	/* Only single function PF can bring the phy down.
2086 	 * In certain scenarios, device is not obliged link down even when forced.
2087 	 * When port is stopped, report link down in those cases.
2088 	 */
2089 	if (!eth_dev->data->dev_started &&
2090 	    (!BNXT_SINGLE_PF(bp) || bnxt_force_link_config(bp)))
2091 		goto out;
2092 
2093 	do {
2094 		/* Retrieve link info from hardware */
2095 		rc = bnxt_get_hwrm_link_config(bp, &new);
2096 		if (rc) {
2097 			new.link_speed = RTE_ETH_LINK_SPEED_100M;
2098 			new.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
2099 			PMD_DRV_LOG_LINE(ERR,
2100 				"Failed to retrieve link rc = 0x%x!", rc);
2101 			goto out;
2102 		}
2103 
2104 		if (!wait_to_complete || new.link_status)
2105 			break;
2106 
2107 		rte_delay_ms(BNXT_LINK_WAIT_INTERVAL);
2108 	} while (cnt--);
2109 
2110 out:
2111 	/* Timed out or success */
2112 	if (new.link_status != eth_dev->data->dev_link.link_status ||
2113 	    new.link_speed != eth_dev->data->dev_link.link_speed) {
2114 		rte_eth_linkstatus_set(eth_dev, &new);
2115 		bnxt_print_link_info(eth_dev);
2116 	}
2117 
2118 	return rc;
2119 }
2120 
2121 static int bnxt_promiscuous_enable_op(struct rte_eth_dev *eth_dev)
2122 {
2123 	struct bnxt *bp = eth_dev->data->dev_private;
2124 	struct bnxt_vnic_info *vnic;
2125 	uint32_t old_flags;
2126 	int rc;
2127 
2128 	rc = is_bnxt_in_error(bp);
2129 	if (rc)
2130 		return rc;
2131 
2132 	/* Filter settings will get applied when port is started */
2133 	if (!eth_dev->data->dev_started)
2134 		return 0;
2135 
2136 	if (bp->vnic_info == NULL)
2137 		return 0;
2138 
2139 	vnic = bnxt_get_default_vnic(bp);
2140 
2141 	old_flags = vnic->flags;
2142 	vnic->flags |= BNXT_VNIC_INFO_PROMISC;
2143 	rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
2144 	if (rc != 0)
2145 		vnic->flags = old_flags;
2146 
2147 	return rc;
2148 }
2149 
2150 static int bnxt_promiscuous_disable_op(struct rte_eth_dev *eth_dev)
2151 {
2152 	struct bnxt *bp = eth_dev->data->dev_private;
2153 	struct bnxt_vnic_info *vnic;
2154 	uint32_t old_flags;
2155 	int rc;
2156 
2157 	rc = is_bnxt_in_error(bp);
2158 	if (rc)
2159 		return rc;
2160 
2161 	/* Filter settings will get applied when port is started */
2162 	if (!eth_dev->data->dev_started)
2163 		return 0;
2164 
2165 	if (bp->vnic_info == NULL)
2166 		return 0;
2167 
2168 	vnic = bnxt_get_default_vnic(bp);
2169 
2170 	old_flags = vnic->flags;
2171 	vnic->flags &= ~BNXT_VNIC_INFO_PROMISC;
2172 	rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
2173 	if (rc != 0)
2174 		vnic->flags = old_flags;
2175 
2176 	return rc;
2177 }
2178 
2179 static int bnxt_allmulticast_enable_op(struct rte_eth_dev *eth_dev)
2180 {
2181 	struct bnxt *bp = eth_dev->data->dev_private;
2182 	struct bnxt_vnic_info *vnic;
2183 	uint32_t old_flags;
2184 	int rc;
2185 
2186 	rc = is_bnxt_in_error(bp);
2187 	if (rc)
2188 		return rc;
2189 
2190 	/* Filter settings will get applied when port is started */
2191 	if (!eth_dev->data->dev_started)
2192 		return 0;
2193 
2194 	if (bp->vnic_info == NULL)
2195 		return 0;
2196 
2197 	vnic = bnxt_get_default_vnic(bp);
2198 
2199 	old_flags = vnic->flags;
2200 	vnic->flags |= BNXT_VNIC_INFO_ALLMULTI;
2201 	rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
2202 	if (rc != 0)
2203 		vnic->flags = old_flags;
2204 
2205 	return rc;
2206 }
2207 
2208 static int bnxt_allmulticast_disable_op(struct rte_eth_dev *eth_dev)
2209 {
2210 	struct bnxt *bp = eth_dev->data->dev_private;
2211 	struct bnxt_vnic_info *vnic;
2212 	uint32_t old_flags;
2213 	int rc;
2214 
2215 	rc = is_bnxt_in_error(bp);
2216 	if (rc)
2217 		return rc;
2218 
2219 	/* Filter settings will get applied when port is started */
2220 	if (!eth_dev->data->dev_started)
2221 		return 0;
2222 
2223 	if (bp->vnic_info == NULL)
2224 		return 0;
2225 
2226 	vnic = bnxt_get_default_vnic(bp);
2227 
2228 	old_flags = vnic->flags;
2229 	vnic->flags &= ~BNXT_VNIC_INFO_ALLMULTI;
2230 	rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
2231 	if (rc != 0)
2232 		vnic->flags = old_flags;
2233 
2234 	return rc;
2235 }
2236 
2237 /* Return bnxt_rx_queue pointer corresponding to a given rxq. */
2238 static struct bnxt_rx_queue *bnxt_qid_to_rxq(struct bnxt *bp, uint16_t qid)
2239 {
2240 	if (qid >= bp->rx_nr_rings)
2241 		return NULL;
2242 
2243 	return bp->eth_dev->data->rx_queues[qid];
2244 }
2245 
2246 /* Return rxq corresponding to a given rss table ring/group ID. */
2247 static uint16_t bnxt_rss_to_qid(struct bnxt *bp, uint16_t fwr)
2248 {
2249 	struct bnxt_rx_queue *rxq;
2250 	unsigned int i;
2251 
2252 	if (!BNXT_HAS_RING_GRPS(bp)) {
2253 		for (i = 0; i < bp->rx_nr_rings; i++) {
2254 			rxq = bp->eth_dev->data->rx_queues[i];
2255 			if (rxq->rx_ring->rx_ring_struct->fw_ring_id == fwr)
2256 				return rxq->index;
2257 		}
2258 	} else {
2259 		for (i = 0; i < bp->rx_nr_rings; i++) {
2260 			if (bp->grp_info[i].fw_grp_id == fwr)
2261 				return i;
2262 		}
2263 	}
2264 
2265 	return INVALID_HW_RING_ID;
2266 }
2267 
2268 static int bnxt_reta_update_op(struct rte_eth_dev *eth_dev,
2269 			    struct rte_eth_rss_reta_entry64 *reta_conf,
2270 			    uint16_t reta_size)
2271 {
2272 	struct bnxt *bp = eth_dev->data->dev_private;
2273 	struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
2274 	struct bnxt_vnic_info *vnic = bnxt_get_default_vnic(bp);
2275 	uint16_t tbl_size = bnxt_rss_hash_tbl_size(bp);
2276 	uint16_t idx, sft;
2277 	int i, rc;
2278 
2279 	rc = is_bnxt_in_error(bp);
2280 	if (rc)
2281 		return rc;
2282 
2283 	if (!vnic->rss_table)
2284 		return -EINVAL;
2285 
2286 	if (!(dev_conf->rxmode.mq_mode & RTE_ETH_MQ_RX_RSS_FLAG))
2287 		return -EINVAL;
2288 
2289 	if (reta_size != tbl_size) {
2290 		PMD_DRV_LOG_LINE(ERR, "The configured hash table lookup size "
2291 			"(%d) must equal the size supported by the hardware "
2292 			"(%d)", reta_size, tbl_size);
2293 		return -EINVAL;
2294 	}
2295 
2296 	if (bnxt_vnic_reta_config_update(bp, vnic, reta_conf, reta_size)) {
2297 		PMD_DRV_LOG_LINE(ERR, "Error in setting the reta config");
2298 		return -EINVAL;
2299 	}
2300 	for (i = 0; i < reta_size; i++) {
2301 		struct bnxt_rx_queue *rxq;
2302 
2303 		idx = i / RTE_ETH_RETA_GROUP_SIZE;
2304 		sft = i % RTE_ETH_RETA_GROUP_SIZE;
2305 
2306 		if (!(reta_conf[idx].mask & (1ULL << sft)))
2307 			continue;
2308 
2309 		rxq = bnxt_qid_to_rxq(bp, reta_conf[idx].reta[sft]);
2310 		if (!rxq) {
2311 			PMD_DRV_LOG_LINE(ERR, "Invalid ring in reta_conf");
2312 			return -EINVAL;
2313 		}
2314 
2315 		if (BNXT_CHIP_P5_P7(bp)) {
2316 			vnic->rss_table[i * 2] =
2317 				rxq->rx_ring->rx_ring_struct->fw_ring_id;
2318 			vnic->rss_table[i * 2 + 1] =
2319 				rxq->cp_ring->cp_ring_struct->fw_ring_id;
2320 		} else {
2321 			vnic->rss_table[i] =
2322 			    vnic->fw_grp_ids[reta_conf[idx].reta[sft]];
2323 		}
2324 	}
2325 	rc = bnxt_hwrm_vnic_rss_cfg(bp, vnic);
2326 	return rc;
2327 }
2328 
2329 static int bnxt_reta_query_op(struct rte_eth_dev *eth_dev,
2330 			      struct rte_eth_rss_reta_entry64 *reta_conf,
2331 			      uint16_t reta_size)
2332 {
2333 	struct bnxt *bp = eth_dev->data->dev_private;
2334 	struct bnxt_vnic_info *vnic = bnxt_get_default_vnic(bp);
2335 	uint16_t tbl_size = bnxt_rss_hash_tbl_size(bp);
2336 	uint16_t idx, sft, i;
2337 	int rc;
2338 
2339 	rc = is_bnxt_in_error(bp);
2340 	if (rc)
2341 		return rc;
2342 
2343 	if (!vnic)
2344 		return -EINVAL;
2345 	if (!vnic->rss_table)
2346 		return -EINVAL;
2347 
2348 	if (reta_size != tbl_size) {
2349 		PMD_DRV_LOG_LINE(ERR, "The configured hash table lookup size "
2350 			"(%d) must equal the size supported by the hardware "
2351 			"(%d)", reta_size, tbl_size);
2352 		return -EINVAL;
2353 	}
2354 
2355 	for (idx = 0, i = 0; i < reta_size; i++) {
2356 		idx = i / RTE_ETH_RETA_GROUP_SIZE;
2357 		sft = i % RTE_ETH_RETA_GROUP_SIZE;
2358 
2359 		if (reta_conf[idx].mask & (1ULL << sft)) {
2360 			uint16_t qid;
2361 
2362 			if (BNXT_CHIP_P5_P7(bp))
2363 				qid = bnxt_rss_to_qid(bp,
2364 						      vnic->rss_table[i * 2]);
2365 			else
2366 				qid = bnxt_rss_to_qid(bp, vnic->rss_table[i]);
2367 
2368 			if (qid == INVALID_HW_RING_ID) {
2369 				PMD_DRV_LOG_LINE(ERR, "Inv. entry in rss table.");
2370 				return -EINVAL;
2371 			}
2372 			reta_conf[idx].reta[sft] = qid;
2373 		}
2374 	}
2375 
2376 	return 0;
2377 }
2378 
2379 static int bnxt_rss_hash_update_op(struct rte_eth_dev *eth_dev,
2380 				   struct rte_eth_rss_conf *rss_conf)
2381 {
2382 	struct bnxt *bp = eth_dev->data->dev_private;
2383 	struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
2384 	struct bnxt_vnic_info *vnic;
2385 	int rc;
2386 
2387 	rc = is_bnxt_in_error(bp);
2388 	if (rc)
2389 		return rc;
2390 
2391 	/*
2392 	 * If RSS enablement were different than dev_configure,
2393 	 * then return -EINVAL
2394 	 */
2395 	if (dev_conf->rxmode.mq_mode & RTE_ETH_MQ_RX_RSS_FLAG) {
2396 		if (!rss_conf->rss_hf)
2397 			PMD_DRV_LOG_LINE(ERR, "Hash type NONE");
2398 	} else {
2399 		if (rss_conf->rss_hf & bnxt_eth_rss_support(bp))
2400 			return -EINVAL;
2401 	}
2402 
2403 	/* Update the default RSS VNIC(s) */
2404 	vnic = bnxt_get_default_vnic(bp);
2405 	vnic->hash_type = bnxt_rte_to_hwrm_hash_types(rss_conf->rss_hf);
2406 	vnic->hash_mode =
2407 		bnxt_rte_to_hwrm_hash_level(bp, rss_conf->rss_hf,
2408 					    RTE_ETH_RSS_LEVEL(rss_conf->rss_hf));
2409 	rc = bnxt_rte_eth_to_hwrm_ring_select_mode(bp, rss_conf->rss_hf, vnic);
2410 	if (rc != 0)
2411 		return rc;
2412 
2413 	/* Cache the hash function */
2414 	bp->rss_conf.rss_hf = rss_conf->rss_hf;
2415 
2416 	/* Cache the hash function */
2417 	bp->rss_conf.rss_hf = rss_conf->rss_hf;
2418 
2419 	/*
2420 	 * If hashkey is not specified, use the previously configured
2421 	 * hashkey
2422 	 */
2423 	if (!rss_conf->rss_key)
2424 		goto rss_config;
2425 
2426 	if (rss_conf->rss_key_len != HW_HASH_KEY_SIZE) {
2427 		PMD_DRV_LOG_LINE(ERR,
2428 			    "Invalid hashkey length, should be %d bytes",
2429 			    HW_HASH_KEY_SIZE);
2430 		return -EINVAL;
2431 	}
2432 	memcpy(vnic->rss_hash_key, rss_conf->rss_key, rss_conf->rss_key_len);
2433 
2434 	/* Cache the hash key */
2435 	memcpy(bp->rss_conf.rss_key, rss_conf->rss_key, HW_HASH_KEY_SIZE);
2436 
2437 rss_config:
2438 	rc = bnxt_hwrm_vnic_rss_cfg(bp, vnic);
2439 	return rc;
2440 }
2441 
2442 static int bnxt_rss_hash_conf_get_op(struct rte_eth_dev *eth_dev,
2443 				     struct rte_eth_rss_conf *rss_conf)
2444 {
2445 	struct bnxt *bp = eth_dev->data->dev_private;
2446 	struct bnxt_vnic_info *vnic = bnxt_get_default_vnic(bp);
2447 	int len, rc;
2448 
2449 	rc = is_bnxt_in_error(bp);
2450 	if (rc)
2451 		return rc;
2452 
2453 	/* Return the RSS configuration of the default VNIC. */
2454 	if (vnic && vnic->rss_hash_key) {
2455 		if (rss_conf->rss_key) {
2456 			len = rss_conf->rss_key_len <= HW_HASH_KEY_SIZE ?
2457 			      rss_conf->rss_key_len : HW_HASH_KEY_SIZE;
2458 			memcpy(rss_conf->rss_key, vnic->rss_hash_key, len);
2459 		}
2460 		bnxt_hwrm_rss_to_rte_hash_conf(vnic, &rss_conf->rss_hf);
2461 		rss_conf->rss_hf |=
2462 			bnxt_hwrm_to_rte_rss_level(bp, vnic->hash_mode);
2463 	} else {
2464 		rss_conf->rss_hf = 0;
2465 	}
2466 	return 0;
2467 }
2468 
2469 static int bnxt_flow_ctrl_get_op(struct rte_eth_dev *dev,
2470 			       struct rte_eth_fc_conf *fc_conf)
2471 {
2472 	struct bnxt *bp = dev->data->dev_private;
2473 	struct rte_eth_link link_info;
2474 	int rc;
2475 
2476 	rc = is_bnxt_in_error(bp);
2477 	if (rc)
2478 		return rc;
2479 
2480 	rc = bnxt_get_hwrm_link_config(bp, &link_info);
2481 	if (rc)
2482 		return rc;
2483 
2484 	memset(fc_conf, 0, sizeof(*fc_conf));
2485 	if (bp->link_info->auto_pause)
2486 		fc_conf->autoneg = 1;
2487 	switch (bp->link_info->pause) {
2488 	case 0:
2489 		fc_conf->mode = RTE_ETH_FC_NONE;
2490 		break;
2491 	case HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX:
2492 		fc_conf->mode = RTE_ETH_FC_TX_PAUSE;
2493 		break;
2494 	case HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX:
2495 		fc_conf->mode = RTE_ETH_FC_RX_PAUSE;
2496 		break;
2497 	case (HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX |
2498 			HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX):
2499 		fc_conf->mode = RTE_ETH_FC_FULL;
2500 		break;
2501 	}
2502 	return 0;
2503 }
2504 
2505 static int bnxt_flow_ctrl_set_op(struct rte_eth_dev *dev,
2506 			       struct rte_eth_fc_conf *fc_conf)
2507 {
2508 	struct bnxt *bp = dev->data->dev_private;
2509 	int rc;
2510 
2511 	rc = is_bnxt_in_error(bp);
2512 	if (rc)
2513 		return rc;
2514 
2515 	if (!BNXT_SINGLE_PF(bp)) {
2516 		PMD_DRV_LOG_LINE(ERR,
2517 			    "Flow Control Settings cannot be modified on VF or on shared PF");
2518 		return -ENOTSUP;
2519 	}
2520 
2521 	switch (fc_conf->mode) {
2522 	case RTE_ETH_FC_NONE:
2523 		bp->link_info->auto_pause = 0;
2524 		bp->link_info->force_pause = 0;
2525 		break;
2526 	case RTE_ETH_FC_RX_PAUSE:
2527 		if (fc_conf->autoneg) {
2528 			bp->link_info->auto_pause =
2529 					HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_RX;
2530 			bp->link_info->force_pause = 0;
2531 		} else {
2532 			bp->link_info->auto_pause = 0;
2533 			bp->link_info->force_pause =
2534 					HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_RX;
2535 		}
2536 		break;
2537 	case RTE_ETH_FC_TX_PAUSE:
2538 		if (fc_conf->autoneg) {
2539 			bp->link_info->auto_pause =
2540 					HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_TX;
2541 			bp->link_info->force_pause = 0;
2542 		} else {
2543 			bp->link_info->auto_pause = 0;
2544 			bp->link_info->force_pause =
2545 					HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_TX;
2546 		}
2547 		break;
2548 	case RTE_ETH_FC_FULL:
2549 		if (fc_conf->autoneg) {
2550 			bp->link_info->auto_pause =
2551 					HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_TX |
2552 					HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_RX;
2553 			bp->link_info->force_pause = 0;
2554 		} else {
2555 			bp->link_info->auto_pause = 0;
2556 			bp->link_info->force_pause =
2557 					HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_TX |
2558 					HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_RX;
2559 		}
2560 		break;
2561 	}
2562 	return bnxt_set_hwrm_link_config(bp, true);
2563 }
2564 
2565 /* Add UDP tunneling port */
2566 int
2567 bnxt_udp_tunnel_port_add_op(struct rte_eth_dev *eth_dev,
2568 			 struct rte_eth_udp_tunnel *udp_tunnel)
2569 {
2570 	struct bnxt *bp = eth_dev->data->dev_private;
2571 	uint16_t tunnel_type = 0;
2572 	int rc = 0;
2573 
2574 	rc = is_bnxt_in_error(bp);
2575 	if (rc)
2576 		return rc;
2577 
2578 	switch (udp_tunnel->prot_type) {
2579 	case RTE_ETH_TUNNEL_TYPE_VXLAN:
2580 		if (bp->vxlan_port_cnt) {
2581 			PMD_DRV_LOG_LINE(ERR, "Tunnel Port %d already programmed",
2582 				udp_tunnel->udp_port);
2583 			if (bp->vxlan_port != udp_tunnel->udp_port) {
2584 				PMD_DRV_LOG_LINE(ERR, "Only one port allowed");
2585 				return -ENOSPC;
2586 			}
2587 			bp->vxlan_port_cnt++;
2588 			return 0;
2589 		}
2590 		tunnel_type =
2591 			HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN;
2592 		break;
2593 	case RTE_ETH_TUNNEL_TYPE_GENEVE:
2594 		if (bp->geneve_port_cnt) {
2595 			PMD_DRV_LOG_LINE(ERR, "Tunnel Port %d already programmed",
2596 				udp_tunnel->udp_port);
2597 			if (bp->geneve_port != udp_tunnel->udp_port) {
2598 				PMD_DRV_LOG_LINE(ERR, "Only one port allowed");
2599 				return -ENOSPC;
2600 			}
2601 			bp->geneve_port_cnt++;
2602 			return 0;
2603 		}
2604 		tunnel_type =
2605 			HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_GENEVE;
2606 		break;
2607 	case RTE_ETH_TUNNEL_TYPE_ECPRI:
2608 		if (bp->ecpri_port_cnt) {
2609 			PMD_DRV_LOG_LINE(ERR, "Tunnel Port %d already programmed",
2610 				udp_tunnel->udp_port);
2611 			if (bp->ecpri_port != udp_tunnel->udp_port) {
2612 				PMD_DRV_LOG_LINE(ERR, "Only one port allowed");
2613 				return -ENOSPC;
2614 			}
2615 			bp->ecpri_port_cnt++;
2616 			return 0;
2617 		}
2618 		tunnel_type =
2619 			HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_ECPRI;
2620 		break;
2621 	default:
2622 		PMD_DRV_LOG_LINE(ERR, "Tunnel type is not supported");
2623 		return -ENOTSUP;
2624 	}
2625 	rc = bnxt_hwrm_tunnel_dst_port_alloc(bp, udp_tunnel->udp_port,
2626 					     tunnel_type);
2627 
2628 	if (rc != 0)
2629 		return rc;
2630 
2631 	if (tunnel_type ==
2632 	    HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN)
2633 		bp->vxlan_port_cnt++;
2634 
2635 	if (tunnel_type ==
2636 	    HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_GENEVE)
2637 		bp->geneve_port_cnt++;
2638 
2639 	if (tunnel_type ==
2640 	    HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_ECPRI)
2641 		bp->ecpri_port_cnt++;
2642 
2643 	return rc;
2644 }
2645 
2646 int
2647 bnxt_udp_tunnel_port_del_op(struct rte_eth_dev *eth_dev,
2648 			 struct rte_eth_udp_tunnel *udp_tunnel)
2649 {
2650 	struct bnxt *bp = eth_dev->data->dev_private;
2651 	uint16_t tunnel_type = 0;
2652 	uint16_t port = 0;
2653 	int rc = 0;
2654 
2655 	rc = is_bnxt_in_error(bp);
2656 	if (rc)
2657 		return rc;
2658 
2659 	switch (udp_tunnel->prot_type) {
2660 	case RTE_ETH_TUNNEL_TYPE_VXLAN:
2661 		if (!bp->vxlan_port_cnt) {
2662 			PMD_DRV_LOG_LINE(ERR, "No Tunnel port configured yet");
2663 			return -EINVAL;
2664 		}
2665 		if (bp->vxlan_port != udp_tunnel->udp_port) {
2666 			PMD_DRV_LOG_LINE(ERR, "Req Port: %d. Configured port: %d",
2667 				udp_tunnel->udp_port, bp->vxlan_port);
2668 			return -EINVAL;
2669 		}
2670 		if (--bp->vxlan_port_cnt)
2671 			return 0;
2672 
2673 		tunnel_type =
2674 			HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_VXLAN;
2675 		port = bp->vxlan_fw_dst_port_id;
2676 		break;
2677 	case RTE_ETH_TUNNEL_TYPE_GENEVE:
2678 		if (!bp->geneve_port_cnt) {
2679 			PMD_DRV_LOG_LINE(ERR, "No Tunnel port configured yet");
2680 			return -EINVAL;
2681 		}
2682 		if (bp->geneve_port != udp_tunnel->udp_port) {
2683 			PMD_DRV_LOG_LINE(ERR, "Req Port: %d. Configured port: %d",
2684 				udp_tunnel->udp_port, bp->geneve_port);
2685 			return -EINVAL;
2686 		}
2687 		if (--bp->geneve_port_cnt)
2688 			return 0;
2689 
2690 		tunnel_type =
2691 			HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_GENEVE;
2692 		port = bp->geneve_fw_dst_port_id;
2693 		break;
2694 	case RTE_ETH_TUNNEL_TYPE_ECPRI:
2695 		if (!bp->ecpri_port_cnt) {
2696 			PMD_DRV_LOG_LINE(ERR, "No Tunnel port configured yet");
2697 			return -EINVAL;
2698 		}
2699 		if (bp->ecpri_port != udp_tunnel->udp_port) {
2700 			PMD_DRV_LOG_LINE(ERR, "Req Port: %d. Configured port: %d",
2701 				udp_tunnel->udp_port, bp->ecpri_port);
2702 			return -EINVAL;
2703 		}
2704 		if (--bp->ecpri_port_cnt)
2705 			return 0;
2706 
2707 		tunnel_type =
2708 			HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_ECPRI;
2709 		port = bp->ecpri_fw_dst_port_id;
2710 		break;
2711 	default:
2712 		PMD_DRV_LOG_LINE(ERR, "Tunnel type is not supported");
2713 		return -ENOTSUP;
2714 	}
2715 
2716 	rc = bnxt_hwrm_tunnel_dst_port_free(bp, port, tunnel_type);
2717 	return rc;
2718 }
2719 
2720 static int bnxt_del_vlan_filter(struct bnxt *bp, uint16_t vlan_id)
2721 {
2722 	struct bnxt_filter_info *filter;
2723 	struct bnxt_vnic_info *vnic;
2724 	int rc = 0;
2725 	uint32_t chk = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN;
2726 
2727 	vnic = bnxt_get_default_vnic(bp);
2728 	filter = STAILQ_FIRST(&vnic->filter);
2729 	while (filter) {
2730 		/* Search for this matching MAC+VLAN filter */
2731 		if (bnxt_vlan_filter_exists(bp, filter, chk, vlan_id)) {
2732 			/* Delete the filter */
2733 			rc = bnxt_hwrm_clear_l2_filter(bp, filter);
2734 			if (rc)
2735 				return rc;
2736 			STAILQ_REMOVE(&vnic->filter, filter,
2737 				      bnxt_filter_info, next);
2738 			bnxt_free_filter(bp, filter);
2739 			PMD_DRV_LOG_LINE(INFO,
2740 				    "Deleted vlan filter for %d",
2741 				    vlan_id);
2742 			return 0;
2743 		}
2744 		filter = STAILQ_NEXT(filter, next);
2745 	}
2746 	return -ENOENT;
2747 }
2748 
2749 static int bnxt_add_vlan_filter(struct bnxt *bp, uint16_t vlan_id)
2750 {
2751 	struct bnxt_filter_info *filter;
2752 	struct bnxt_vnic_info *vnic;
2753 	int rc = 0;
2754 	uint32_t en = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN |
2755 		HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN_MASK;
2756 	uint32_t chk = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN;
2757 
2758 	/* Implementation notes on the use of VNIC in this command:
2759 	 *
2760 	 * By default, these filters belong to default vnic for the function.
2761 	 * Once these filters are set up, only destination VNIC can be modified.
2762 	 * If the destination VNIC is not specified in this command,
2763 	 * then the HWRM shall only create an l2 context id.
2764 	 */
2765 
2766 	vnic = bnxt_get_default_vnic(bp);
2767 	filter = STAILQ_FIRST(&vnic->filter);
2768 	/* Check if the VLAN has already been added */
2769 	while (filter) {
2770 		if (bnxt_vlan_filter_exists(bp, filter, chk, vlan_id))
2771 			return -EEXIST;
2772 
2773 		filter = STAILQ_NEXT(filter, next);
2774 	}
2775 
2776 	/* No match found. Alloc a fresh filter and issue the L2_FILTER_ALLOC
2777 	 * command to create MAC+VLAN filter with the right flags, enables set.
2778 	 */
2779 	filter = bnxt_alloc_filter(bp);
2780 	if (!filter) {
2781 		PMD_DRV_LOG_LINE(ERR,
2782 			    "MAC/VLAN filter alloc failed");
2783 		return -ENOMEM;
2784 	}
2785 	/* MAC + VLAN ID filter */
2786 	/* If l2_ivlan == 0 and l2_ivlan_mask != 0, only
2787 	 * untagged packets are received
2788 	 *
2789 	 * If l2_ivlan != 0 and l2_ivlan_mask != 0, untagged
2790 	 * packets and only the programmed vlan's packets are received
2791 	 */
2792 	filter->l2_ivlan = vlan_id;
2793 	filter->l2_ivlan_mask = 0x0FFF;
2794 	filter->enables |= en;
2795 	filter->flags |= HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_OUTERMOST;
2796 
2797 	rc = bnxt_hwrm_set_l2_filter(bp, vnic->fw_vnic_id, filter);
2798 	if (rc) {
2799 		/* Free the newly allocated filter as we were
2800 		 * not able to create the filter in hardware.
2801 		 */
2802 		bnxt_free_filter(bp, filter);
2803 		return rc;
2804 	}
2805 
2806 	filter->mac_index = 0;
2807 	/* Add this new filter to the list */
2808 	if (vlan_id == 0)
2809 		STAILQ_INSERT_HEAD(&vnic->filter, filter, next);
2810 	else
2811 		STAILQ_INSERT_TAIL(&vnic->filter, filter, next);
2812 
2813 	PMD_DRV_LOG_LINE(INFO,
2814 		    "Added Vlan filter for %d", vlan_id);
2815 	return rc;
2816 }
2817 
2818 static int bnxt_vlan_filter_set_op(struct rte_eth_dev *eth_dev,
2819 		uint16_t vlan_id, int on)
2820 {
2821 	struct bnxt *bp = eth_dev->data->dev_private;
2822 	int rc;
2823 
2824 	rc = is_bnxt_in_error(bp);
2825 	if (rc)
2826 		return rc;
2827 
2828 	if (!eth_dev->data->dev_started) {
2829 		PMD_DRV_LOG_LINE(ERR, "port must be started before setting vlan");
2830 		return -EINVAL;
2831 	}
2832 
2833 	/* These operations apply to ALL existing MAC/VLAN filters */
2834 	if (on)
2835 		return bnxt_add_vlan_filter(bp, vlan_id);
2836 	else
2837 		return bnxt_del_vlan_filter(bp, vlan_id);
2838 }
2839 
2840 static int bnxt_del_dflt_mac_filter(struct bnxt *bp,
2841 				    struct bnxt_vnic_info *vnic)
2842 {
2843 	struct bnxt_filter_info *filter;
2844 	int rc;
2845 
2846 	filter = STAILQ_FIRST(&vnic->filter);
2847 	while (filter) {
2848 		if (filter->mac_index == 0 &&
2849 		    !memcmp(filter->l2_addr, bp->mac_addr,
2850 			    RTE_ETHER_ADDR_LEN)) {
2851 			rc = bnxt_hwrm_clear_l2_filter(bp, filter);
2852 			if (!rc) {
2853 				STAILQ_REMOVE(&vnic->filter, filter,
2854 					      bnxt_filter_info, next);
2855 				bnxt_free_filter(bp, filter);
2856 			}
2857 			return rc;
2858 		}
2859 		filter = STAILQ_NEXT(filter, next);
2860 	}
2861 	return 0;
2862 }
2863 
2864 static int
2865 bnxt_config_vlan_hw_filter(struct bnxt *bp, uint64_t rx_offloads)
2866 {
2867 	struct bnxt_vnic_info *vnic;
2868 	unsigned int i;
2869 	int rc;
2870 
2871 	vnic = bnxt_get_default_vnic(bp);
2872 	if (!(rx_offloads & RTE_ETH_RX_OFFLOAD_VLAN_FILTER)) {
2873 		/* Remove any VLAN filters programmed */
2874 		for (i = 0; i < RTE_ETHER_MAX_VLAN_ID; i++)
2875 			bnxt_del_vlan_filter(bp, i);
2876 
2877 		rc = bnxt_add_mac_filter(bp, vnic, NULL, 0, 0);
2878 		if (rc)
2879 			return rc;
2880 	} else {
2881 		/* Default filter will allow packets that match the
2882 		 * dest mac. So, it has to be deleted, otherwise, we
2883 		 * will endup receiving vlan packets for which the
2884 		 * filter is not programmed, when hw-vlan-filter
2885 		 * configuration is ON
2886 		 */
2887 		bnxt_del_dflt_mac_filter(bp, vnic);
2888 		/* This filter will allow only untagged packets */
2889 		bnxt_add_vlan_filter(bp, 0);
2890 	}
2891 	PMD_DRV_LOG_LINE(DEBUG, "VLAN Filtering: %d",
2892 		    !!(rx_offloads & RTE_ETH_RX_OFFLOAD_VLAN_FILTER));
2893 
2894 	return 0;
2895 }
2896 
2897 static int bnxt_free_one_vnic(struct bnxt *bp, uint16_t vnic_id)
2898 {
2899 	struct bnxt_vnic_info *vnic = &bp->vnic_info[vnic_id];
2900 	unsigned int i;
2901 	int rc;
2902 
2903 	/* Destroy vnic filters and vnic */
2904 	if (bp->eth_dev->data->dev_conf.rxmode.offloads &
2905 	    RTE_ETH_RX_OFFLOAD_VLAN_FILTER) {
2906 		for (i = 0; i < RTE_ETHER_MAX_VLAN_ID; i++)
2907 			bnxt_del_vlan_filter(bp, i);
2908 	}
2909 	bnxt_del_dflt_mac_filter(bp, vnic);
2910 
2911 	rc = bnxt_hwrm_vnic_ctx_free(bp, vnic);
2912 	if (rc)
2913 		return rc;
2914 
2915 	rc = bnxt_hwrm_vnic_free(bp, vnic);
2916 	if (rc)
2917 		return rc;
2918 
2919 	rte_free(vnic->fw_grp_ids);
2920 	vnic->fw_grp_ids = NULL;
2921 
2922 	vnic->rx_queue_cnt = 0;
2923 
2924 	return 0;
2925 }
2926 
2927 static int
2928 bnxt_config_vlan_hw_stripping(struct bnxt *bp, uint64_t rx_offloads)
2929 {
2930 	struct bnxt_vnic_info *vnic = bnxt_get_default_vnic(bp);
2931 	int rc;
2932 
2933 	/* Destroy, recreate and reconfigure the default vnic */
2934 	rc = bnxt_free_one_vnic(bp, bp->vnic_queue_db.dflt_vnic_id);
2935 	if (rc)
2936 		return rc;
2937 
2938 	/* setup the default vnic details*/
2939 	bnxt_vnic_queue_db_update_dlft_vnic(bp);
2940 
2941 	rc = bnxt_setup_one_vnic(bp, bp->vnic_queue_db.dflt_vnic_id);
2942 	if (rc)
2943 		return rc;
2944 
2945 	if (bp->eth_dev->data->dev_conf.rxmode.offloads &
2946 	    RTE_ETH_RX_OFFLOAD_VLAN_FILTER) {
2947 		rc = bnxt_add_vlan_filter(bp, 0);
2948 		if (rc)
2949 			return rc;
2950 		rc = bnxt_restore_vlan_filters(bp);
2951 		if (rc)
2952 			return rc;
2953 	} else {
2954 		rc = bnxt_add_mac_filter(bp, vnic, NULL, 0, 0);
2955 		if (rc)
2956 			return rc;
2957 	}
2958 
2959 	rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
2960 	if (rc)
2961 		return rc;
2962 
2963 	PMD_DRV_LOG_LINE(DEBUG, "VLAN Strip Offload: %d",
2964 		    !!(rx_offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP));
2965 
2966 	return rc;
2967 }
2968 
2969 static int
2970 bnxt_vlan_offload_set_op(struct rte_eth_dev *dev, int mask)
2971 {
2972 	uint64_t rx_offloads = dev->data->dev_conf.rxmode.offloads;
2973 	struct bnxt *bp = dev->data->dev_private;
2974 	int rc = 0;
2975 
2976 	rc = is_bnxt_in_error(bp);
2977 	if (rc)
2978 		return rc;
2979 
2980 	/* Filter settings will get applied when port is started */
2981 	if (!dev->data->dev_started)
2982 		return 0;
2983 
2984 	/* For P7 platform, cannot support if truflow is enabled */
2985 	if (BNXT_TRUFLOW_EN(bp) && BNXT_CHIP_P7(bp))
2986 		return rc;
2987 
2988 	if (mask & RTE_ETH_VLAN_FILTER_MASK) {
2989 		/* Enable or disable VLAN filtering */
2990 		rc = bnxt_config_vlan_hw_filter(bp, rx_offloads);
2991 		if (rc)
2992 			return rc;
2993 	}
2994 
2995 	if (mask & RTE_ETH_VLAN_STRIP_MASK) {
2996 		/* Enable or disable VLAN stripping */
2997 		rc = bnxt_config_vlan_hw_stripping(bp, rx_offloads);
2998 		if (rc)
2999 			return rc;
3000 	}
3001 
3002 	if (mask & RTE_ETH_VLAN_EXTEND_MASK) {
3003 		if (rx_offloads & RTE_ETH_RX_OFFLOAD_VLAN_EXTEND)
3004 			PMD_DRV_LOG_LINE(DEBUG, "Extend VLAN supported");
3005 		else
3006 			PMD_DRV_LOG_LINE(INFO, "Extend VLAN unsupported");
3007 	}
3008 
3009 	return 0;
3010 }
3011 
3012 static int
3013 bnxt_vlan_tpid_set_op(struct rte_eth_dev *dev, enum rte_vlan_type vlan_type,
3014 		      uint16_t tpid)
3015 {
3016 	struct bnxt *bp = dev->data->dev_private;
3017 	int qinq = dev->data->dev_conf.rxmode.offloads &
3018 		   RTE_ETH_RX_OFFLOAD_VLAN_EXTEND;
3019 
3020 	if (vlan_type != RTE_ETH_VLAN_TYPE_INNER &&
3021 	    vlan_type != RTE_ETH_VLAN_TYPE_OUTER) {
3022 		PMD_DRV_LOG_LINE(ERR,
3023 			    "Unsupported vlan type.");
3024 		return -EINVAL;
3025 	}
3026 	if (!qinq) {
3027 		PMD_DRV_LOG_LINE(ERR,
3028 			    "QinQ not enabled. Needs to be ON as we can "
3029 			    "accelerate only outer vlan");
3030 		return -EINVAL;
3031 	}
3032 
3033 	if (vlan_type == RTE_ETH_VLAN_TYPE_OUTER) {
3034 		switch (tpid) {
3035 		case RTE_ETHER_TYPE_QINQ:
3036 			bp->outer_tpid_bd =
3037 				TX_BD_LONG_CFA_META_VLAN_TPID_TPID88A8;
3038 				break;
3039 		case RTE_ETHER_TYPE_VLAN:
3040 			bp->outer_tpid_bd =
3041 				TX_BD_LONG_CFA_META_VLAN_TPID_TPID8100;
3042 				break;
3043 		case RTE_ETHER_TYPE_QINQ1:
3044 			bp->outer_tpid_bd =
3045 				TX_BD_LONG_CFA_META_VLAN_TPID_TPID9100;
3046 				break;
3047 		case RTE_ETHER_TYPE_QINQ2:
3048 			bp->outer_tpid_bd =
3049 				TX_BD_LONG_CFA_META_VLAN_TPID_TPID9200;
3050 				break;
3051 		case RTE_ETHER_TYPE_QINQ3:
3052 			bp->outer_tpid_bd =
3053 				 TX_BD_LONG_CFA_META_VLAN_TPID_TPID9300;
3054 				break;
3055 		default:
3056 			PMD_DRV_LOG_LINE(ERR, "Invalid TPID: %x", tpid);
3057 			return -EINVAL;
3058 		}
3059 		bp->outer_tpid_bd |= tpid;
3060 		PMD_DRV_LOG_LINE(INFO, "outer_tpid_bd = %x", bp->outer_tpid_bd);
3061 	} else if (vlan_type == RTE_ETH_VLAN_TYPE_INNER) {
3062 		PMD_DRV_LOG_LINE(ERR,
3063 			    "Can accelerate only outer vlan in QinQ");
3064 		return -EINVAL;
3065 	}
3066 
3067 	return 0;
3068 }
3069 
3070 static int
3071 bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev,
3072 			     struct rte_ether_addr *addr)
3073 {
3074 	struct bnxt *bp = dev->data->dev_private;
3075 	/* Default Filter is tied to VNIC 0 */
3076 	struct bnxt_vnic_info *vnic = bnxt_get_default_vnic(bp);
3077 	int rc;
3078 
3079 	rc = is_bnxt_in_error(bp);
3080 	if (rc)
3081 		return rc;
3082 
3083 	if (BNXT_VF(bp) && !BNXT_VF_IS_TRUSTED(bp))
3084 		return -EPERM;
3085 
3086 	if (rte_is_zero_ether_addr(addr))
3087 		return -EINVAL;
3088 
3089 	/* Filter settings will get applied when port is started */
3090 	if (!dev->data->dev_started)
3091 		return 0;
3092 
3093 	/* Check if the requested MAC is already added */
3094 	if (memcmp(addr, bp->mac_addr, RTE_ETHER_ADDR_LEN) == 0)
3095 		return 0;
3096 
3097 	/* Destroy filter and re-create it */
3098 	bnxt_del_dflt_mac_filter(bp, vnic);
3099 
3100 	memcpy(bp->mac_addr, addr, RTE_ETHER_ADDR_LEN);
3101 	if (dev->data->dev_conf.rxmode.offloads & RTE_ETH_RX_OFFLOAD_VLAN_FILTER) {
3102 		/* This filter will allow only untagged packets */
3103 		rc = bnxt_add_vlan_filter(bp, 0);
3104 	} else {
3105 		rc = bnxt_add_mac_filter(bp, vnic, addr, 0, 0);
3106 	}
3107 
3108 	PMD_DRV_LOG_LINE(DEBUG, "Set MAC addr");
3109 	return rc;
3110 }
3111 
3112 static int
3113 bnxt_dev_set_mc_addr_list_op(struct rte_eth_dev *eth_dev,
3114 			  struct rte_ether_addr *mc_addr_set,
3115 			  uint32_t nb_mc_addr)
3116 {
3117 	struct bnxt *bp = eth_dev->data->dev_private;
3118 	struct bnxt_vnic_info *vnic;
3119 	uint32_t i = 0;
3120 	int rc;
3121 
3122 	rc = is_bnxt_in_error(bp);
3123 	if (rc)
3124 		return rc;
3125 
3126 	vnic = bnxt_get_default_vnic(bp);
3127 
3128 	bp->nb_mc_addr = nb_mc_addr;
3129 
3130 	if (nb_mc_addr > BNXT_MAX_MC_ADDRS) {
3131 		PMD_DRV_LOG_LINE(INFO, "Number of Mcast MACs added (%u) exceeded Max supported (%u)",
3132 			    nb_mc_addr, BNXT_MAX_MC_ADDRS);
3133 		PMD_DRV_LOG_LINE(INFO, "Turning on Mcast promiscuous mode");
3134 		vnic->flags |= BNXT_VNIC_INFO_ALLMULTI;
3135 		goto allmulti;
3136 	}
3137 
3138 	/* TODO Check for Duplicate mcast addresses */
3139 	if (vnic->flags & BNXT_VNIC_INFO_ALLMULTI) {
3140 		PMD_DRV_LOG_LINE(INFO, "Turning off Mcast promiscuous mode");
3141 		vnic->flags &= ~BNXT_VNIC_INFO_ALLMULTI;
3142 	}
3143 	for (i = 0; i < nb_mc_addr; i++)
3144 		rte_ether_addr_copy(&mc_addr_set[i], &bp->mcast_addr_list[i]);
3145 
3146 	if (bp->nb_mc_addr)
3147 		vnic->flags |= BNXT_VNIC_INFO_MCAST;
3148 	else
3149 		vnic->flags &= ~BNXT_VNIC_INFO_MCAST;
3150 
3151 allmulti:
3152 	rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
3153 	if (rc == -ENOSPC && (vnic->flags & BNXT_VNIC_INFO_MCAST)) {
3154 		/* If MCAST addition failed because FW ran out of
3155 		 * multicast filters, enable all multicast mode.
3156 		 */
3157 		vnic->flags &= ~BNXT_VNIC_INFO_MCAST;
3158 		vnic->flags |= BNXT_VNIC_INFO_ALLMULTI;
3159 		goto allmulti;
3160 	}
3161 
3162 	return rc;
3163 }
3164 
3165 static int
3166 bnxt_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size)
3167 {
3168 	struct bnxt *bp = dev->data->dev_private;
3169 	uint8_t fw_major = (bp->fw_ver >> 24) & 0xff;
3170 	uint8_t fw_minor = (bp->fw_ver >> 16) & 0xff;
3171 	uint8_t fw_updt = (bp->fw_ver >> 8) & 0xff;
3172 	uint8_t fw_rsvd = bp->fw_ver & 0xff;
3173 	int ret;
3174 
3175 	ret = snprintf(fw_version, fw_size, "%d.%d.%d.%d",
3176 			fw_major, fw_minor, fw_updt, fw_rsvd);
3177 	if (ret < 0)
3178 		return -EINVAL;
3179 
3180 	ret += 1; /* add the size of '\0' */
3181 	if (fw_size < (size_t)ret)
3182 		return ret;
3183 	else
3184 		return 0;
3185 }
3186 
3187 static void
3188 bnxt_rxq_info_get_op(struct rte_eth_dev *dev, uint16_t queue_id,
3189 	struct rte_eth_rxq_info *qinfo)
3190 {
3191 	struct bnxt *bp = dev->data->dev_private;
3192 	struct bnxt_rx_queue *rxq;
3193 
3194 	if (is_bnxt_in_error(bp))
3195 		return;
3196 
3197 	rxq = dev->data->rx_queues[queue_id];
3198 
3199 	qinfo->mp = rxq->mb_pool;
3200 	qinfo->scattered_rx = dev->data->scattered_rx;
3201 	qinfo->nb_desc = rxq->nb_rx_desc;
3202 
3203 	qinfo->conf.rx_free_thresh = rxq->rx_free_thresh;
3204 	qinfo->conf.rx_drop_en = rxq->drop_en;
3205 	qinfo->conf.rx_deferred_start = rxq->rx_deferred_start;
3206 	qinfo->conf.offloads = dev->data->dev_conf.rxmode.offloads;
3207 }
3208 
3209 static void
3210 bnxt_txq_info_get_op(struct rte_eth_dev *dev, uint16_t queue_id,
3211 	struct rte_eth_txq_info *qinfo)
3212 {
3213 	struct bnxt *bp = dev->data->dev_private;
3214 	struct bnxt_tx_queue *txq;
3215 
3216 	if (is_bnxt_in_error(bp))
3217 		return;
3218 
3219 	txq = dev->data->tx_queues[queue_id];
3220 
3221 	qinfo->nb_desc = txq->nb_tx_desc;
3222 
3223 	qinfo->conf.tx_thresh.pthresh = txq->pthresh;
3224 	qinfo->conf.tx_thresh.hthresh = txq->hthresh;
3225 	qinfo->conf.tx_thresh.wthresh = txq->wthresh;
3226 
3227 	qinfo->conf.tx_free_thresh = txq->tx_free_thresh;
3228 	qinfo->conf.tx_rs_thresh = 0;
3229 	qinfo->conf.tx_deferred_start = txq->tx_deferred_start;
3230 	qinfo->conf.offloads = txq->offloads;
3231 }
3232 
3233 static const struct {
3234 	eth_rx_burst_t pkt_burst;
3235 	const char *info;
3236 } bnxt_rx_burst_info[] = {
3237 	{bnxt_recv_pkts,		"Scalar"},
3238 #if defined(RTE_ARCH_X86)
3239 	{bnxt_crx_pkts_vec,		"Vector SSE"},
3240 	{bnxt_recv_pkts_vec,		"Vector SSE"},
3241 #endif
3242 #if defined(RTE_ARCH_X86) && defined(CC_AVX2_SUPPORT)
3243 	{bnxt_crx_pkts_vec_avx2,	"Vector AVX2"},
3244 	{bnxt_recv_pkts_vec_avx2,	"Vector AVX2"},
3245 #endif
3246 #if defined(RTE_ARCH_ARM64)
3247 	{bnxt_recv_pkts_vec,		"Vector Neon"},
3248 #endif
3249 };
3250 
3251 static int
3252 bnxt_rx_burst_mode_get(struct rte_eth_dev *dev, __rte_unused uint16_t queue_id,
3253 		       struct rte_eth_burst_mode *mode)
3254 {
3255 	eth_rx_burst_t pkt_burst = dev->rx_pkt_burst;
3256 	size_t i;
3257 
3258 	for (i = 0; i < RTE_DIM(bnxt_rx_burst_info); i++) {
3259 		if (pkt_burst == bnxt_rx_burst_info[i].pkt_burst) {
3260 			snprintf(mode->info, sizeof(mode->info), "%s",
3261 				 bnxt_rx_burst_info[i].info);
3262 			return 0;
3263 		}
3264 	}
3265 
3266 	return -EINVAL;
3267 }
3268 
3269 static const struct {
3270 	eth_tx_burst_t pkt_burst;
3271 	const char *info;
3272 } bnxt_tx_burst_info[] = {
3273 	{bnxt_xmit_pkts,		"Scalar"},
3274 #if defined(RTE_ARCH_X86)
3275 	{bnxt_xmit_pkts_vec,		"Vector SSE"},
3276 	{bnxt_xmit_pkts_vec_avx2,	"Vector AVX2"},
3277 #endif
3278 #if defined(RTE_ARCH_ARM64)
3279 	{bnxt_xmit_pkts_vec,		"Vector Neon"},
3280 #endif
3281 };
3282 
3283 static int
3284 bnxt_tx_burst_mode_get(struct rte_eth_dev *dev, __rte_unused uint16_t queue_id,
3285 		       struct rte_eth_burst_mode *mode)
3286 {
3287 	eth_tx_burst_t pkt_burst = dev->tx_pkt_burst;
3288 	size_t i;
3289 
3290 	for (i = 0; i < RTE_DIM(bnxt_tx_burst_info); i++) {
3291 		if (pkt_burst == bnxt_tx_burst_info[i].pkt_burst) {
3292 			snprintf(mode->info, sizeof(mode->info), "%s",
3293 				 bnxt_tx_burst_info[i].info);
3294 			return 0;
3295 		}
3296 	}
3297 
3298 	return -EINVAL;
3299 }
3300 
3301 int bnxt_mtu_set_op(struct rte_eth_dev *eth_dev, uint16_t new_mtu)
3302 {
3303 	struct bnxt *bp = eth_dev->data->dev_private;
3304 	uint32_t rc = 0;
3305 
3306 	rc = is_bnxt_in_error(bp);
3307 	if (rc)
3308 		return rc;
3309 
3310 	/* Return if port is active */
3311 	if (eth_dev->data->dev_started) {
3312 		PMD_DRV_LOG_LINE(ERR, "Stop port before changing MTU");
3313 		return -EBUSY;
3314 	}
3315 
3316 	/* Exit if receive queues are not configured yet */
3317 	if (!eth_dev->data->nb_rx_queues)
3318 		return -ENOTSUP;
3319 
3320 	/* Is there a change in mtu setting? */
3321 	if (eth_dev->data->mtu == new_mtu)
3322 		return rc;
3323 
3324 	if (new_mtu > RTE_ETHER_MTU)
3325 		bp->flags |= BNXT_FLAG_JUMBO;
3326 	else
3327 		bp->flags &= ~BNXT_FLAG_JUMBO;
3328 
3329 	rc = bnxt_vnic_mru_config(bp, new_mtu);
3330 	if (rc) {
3331 		PMD_DRV_LOG_LINE(ERR, "failed to update mtu in vnic context");
3332 		return rc;
3333 	}
3334 
3335 	if (bnxt_hwrm_config_host_mtu(bp))
3336 		PMD_DRV_LOG_LINE(WARNING, "Failed to configure host MTU");
3337 
3338 	PMD_DRV_LOG_LINE(INFO, "New MTU is %d", new_mtu);
3339 
3340 	return rc;
3341 }
3342 
3343 static int
3344 bnxt_vlan_pvid_set_op(struct rte_eth_dev *dev, uint16_t pvid, int on)
3345 {
3346 	struct bnxt *bp = dev->data->dev_private;
3347 	uint16_t vlan = bp->vlan;
3348 	int rc;
3349 
3350 	rc = is_bnxt_in_error(bp);
3351 	if (rc)
3352 		return rc;
3353 
3354 	if (!BNXT_SINGLE_PF(bp)) {
3355 		PMD_DRV_LOG_LINE(ERR, "PVID cannot be modified on VF or on shared PF");
3356 		return -ENOTSUP;
3357 	}
3358 	bp->vlan = on ? pvid : 0;
3359 
3360 	rc = bnxt_hwrm_set_default_vlan(bp, 0, 0);
3361 	if (rc)
3362 		bp->vlan = vlan;
3363 	return rc;
3364 }
3365 
3366 static int
3367 bnxt_dev_led_on_op(struct rte_eth_dev *dev)
3368 {
3369 	struct bnxt *bp = dev->data->dev_private;
3370 	int rc;
3371 
3372 	rc = is_bnxt_in_error(bp);
3373 	if (rc)
3374 		return rc;
3375 
3376 	return bnxt_hwrm_port_led_cfg(bp, true);
3377 }
3378 
3379 static int
3380 bnxt_dev_led_off_op(struct rte_eth_dev *dev)
3381 {
3382 	struct bnxt *bp = dev->data->dev_private;
3383 	int rc;
3384 
3385 	rc = is_bnxt_in_error(bp);
3386 	if (rc)
3387 		return rc;
3388 
3389 	return bnxt_hwrm_port_led_cfg(bp, false);
3390 }
3391 
3392 static uint32_t
3393 bnxt_rx_queue_count_op(void *rx_queue)
3394 {
3395 	struct bnxt *bp;
3396 	struct bnxt_cp_ring_info *cpr;
3397 	uint32_t desc = 0, raw_cons, cp_ring_size;
3398 	struct bnxt_rx_queue *rxq;
3399 	struct rx_pkt_cmpl *rxcmp;
3400 	int rc;
3401 
3402 	rxq = rx_queue;
3403 	bp = rxq->bp;
3404 
3405 	rc = is_bnxt_in_error(bp);
3406 	if (rc)
3407 		return rc;
3408 
3409 	cpr = rxq->cp_ring;
3410 	raw_cons = cpr->cp_raw_cons;
3411 	cp_ring_size = cpr->cp_ring_struct->ring_size;
3412 
3413 	while (1) {
3414 		uint32_t agg_cnt, cons, cmpl_type;
3415 
3416 		cons = RING_CMP(cpr->cp_ring_struct, raw_cons);
3417 		rxcmp = (struct rx_pkt_cmpl *)&cpr->cp_desc_ring[cons];
3418 
3419 		if (!bnxt_cpr_cmp_valid(rxcmp, raw_cons, cp_ring_size))
3420 			break;
3421 
3422 		cmpl_type = CMP_TYPE(rxcmp);
3423 
3424 		switch (cmpl_type) {
3425 		case CMPL_BASE_TYPE_RX_L2:
3426 		case CMPL_BASE_TYPE_RX_L2_V2:
3427 			agg_cnt = BNXT_RX_L2_AGG_BUFS(rxcmp);
3428 			raw_cons = raw_cons + CMP_LEN(cmpl_type) + agg_cnt;
3429 			desc++;
3430 			break;
3431 
3432 		case CMPL_BASE_TYPE_RX_TPA_END:
3433 			if (BNXT_CHIP_P5_P7(rxq->bp)) {
3434 				struct rx_tpa_v2_end_cmpl_hi *p5_tpa_end;
3435 
3436 				p5_tpa_end = (void *)rxcmp;
3437 				agg_cnt = BNXT_TPA_END_AGG_BUFS_TH(p5_tpa_end);
3438 			} else {
3439 				struct rx_tpa_end_cmpl *tpa_end;
3440 
3441 				tpa_end = (void *)rxcmp;
3442 				agg_cnt = BNXT_TPA_END_AGG_BUFS(tpa_end);
3443 			}
3444 
3445 			raw_cons = raw_cons + CMP_LEN(cmpl_type) + agg_cnt;
3446 			desc++;
3447 			break;
3448 
3449 		default:
3450 			raw_cons += CMP_LEN(cmpl_type);
3451 		}
3452 	}
3453 
3454 	return desc;
3455 }
3456 
3457 static int
3458 bnxt_rx_descriptor_status_op(void *rx_queue, uint16_t offset)
3459 {
3460 	struct bnxt_rx_queue *rxq = rx_queue;
3461 	struct bnxt_cp_ring_info *cpr;
3462 	struct bnxt_rx_ring_info *rxr;
3463 	uint32_t desc, raw_cons, cp_ring_size;
3464 	struct bnxt *bp = rxq->bp;
3465 	struct rx_pkt_cmpl *rxcmp;
3466 	int rc;
3467 
3468 	rc = is_bnxt_in_error(bp);
3469 	if (rc)
3470 		return rc;
3471 
3472 	if (offset >= rxq->nb_rx_desc)
3473 		return -EINVAL;
3474 
3475 	rxr = rxq->rx_ring;
3476 	cpr = rxq->cp_ring;
3477 	cp_ring_size = cpr->cp_ring_struct->ring_size;
3478 
3479 	/*
3480 	 * For the vector receive case, the completion at the requested
3481 	 * offset can be indexed directly.
3482 	 */
3483 #if defined(RTE_ARCH_X86) || defined(RTE_ARCH_ARM64)
3484 	if (bp->flags & BNXT_FLAG_RX_VECTOR_PKT_MODE) {
3485 		struct rx_pkt_cmpl *rxcmp;
3486 		uint32_t cons;
3487 
3488 		/* Check status of completion descriptor. */
3489 		raw_cons = cpr->cp_raw_cons +
3490 			   offset * CMP_LEN(CMPL_BASE_TYPE_RX_L2);
3491 		cons = RING_CMP(cpr->cp_ring_struct, raw_cons);
3492 		rxcmp = (struct rx_pkt_cmpl *)&cpr->cp_desc_ring[cons];
3493 
3494 		if (bnxt_cpr_cmp_valid(rxcmp, raw_cons, cp_ring_size))
3495 			return RTE_ETH_RX_DESC_DONE;
3496 
3497 		/* Check whether rx desc has an mbuf attached. */
3498 		cons = RING_CMP(rxr->rx_ring_struct, raw_cons / 2);
3499 		if (cons >= rxq->rxrearm_start &&
3500 		    cons < rxq->rxrearm_start + rxq->rxrearm_nb) {
3501 			return RTE_ETH_RX_DESC_UNAVAIL;
3502 		}
3503 
3504 		return RTE_ETH_RX_DESC_AVAIL;
3505 	}
3506 #endif
3507 
3508 	/*
3509 	 * For the non-vector receive case, scan the completion ring to
3510 	 * locate the completion descriptor for the requested offset.
3511 	 */
3512 	raw_cons = cpr->cp_raw_cons;
3513 	desc = 0;
3514 	while (1) {
3515 		uint32_t agg_cnt, cons, cmpl_type;
3516 
3517 		cons = RING_CMP(cpr->cp_ring_struct, raw_cons);
3518 		rxcmp = (struct rx_pkt_cmpl *)&cpr->cp_desc_ring[cons];
3519 
3520 		if (!bnxt_cpr_cmp_valid(rxcmp, raw_cons, cp_ring_size))
3521 			break;
3522 
3523 		cmpl_type = CMP_TYPE(rxcmp);
3524 
3525 		switch (cmpl_type) {
3526 		case CMPL_BASE_TYPE_RX_L2:
3527 		case CMPL_BASE_TYPE_RX_L2_V2:
3528 			if (desc == offset) {
3529 				cons = rxcmp->opaque;
3530 				if (rxr->rx_buf_ring[cons])
3531 					return RTE_ETH_RX_DESC_DONE;
3532 				else
3533 					return RTE_ETH_RX_DESC_UNAVAIL;
3534 			}
3535 			agg_cnt = BNXT_RX_L2_AGG_BUFS(rxcmp);
3536 			raw_cons = raw_cons + CMP_LEN(cmpl_type) + agg_cnt;
3537 			desc++;
3538 			break;
3539 
3540 		case CMPL_BASE_TYPE_RX_TPA_END:
3541 			if (desc == offset)
3542 				return RTE_ETH_RX_DESC_DONE;
3543 
3544 			if (BNXT_CHIP_P5_P7(rxq->bp)) {
3545 				struct rx_tpa_v2_end_cmpl_hi *p5_tpa_end;
3546 
3547 				p5_tpa_end = (void *)rxcmp;
3548 				agg_cnt = BNXT_TPA_END_AGG_BUFS_TH(p5_tpa_end);
3549 			} else {
3550 				struct rx_tpa_end_cmpl *tpa_end;
3551 
3552 				tpa_end = (void *)rxcmp;
3553 				agg_cnt = BNXT_TPA_END_AGG_BUFS(tpa_end);
3554 			}
3555 
3556 			raw_cons = raw_cons + CMP_LEN(cmpl_type) + agg_cnt;
3557 			desc++;
3558 			break;
3559 
3560 		default:
3561 			raw_cons += CMP_LEN(cmpl_type);
3562 		}
3563 	}
3564 
3565 	return RTE_ETH_RX_DESC_AVAIL;
3566 }
3567 
3568 static int
3569 bnxt_tx_descriptor_status_op(void *tx_queue, uint16_t offset)
3570 {
3571 	struct bnxt_tx_queue *txq = (struct bnxt_tx_queue *)tx_queue;
3572 	struct bnxt_cp_ring_info *cpr = txq->cp_ring;
3573 	uint32_t ring_mask, raw_cons, nb_tx_pkts = 0;
3574 	struct cmpl_base *cp_desc_ring;
3575 	int rc;
3576 
3577 	rc = is_bnxt_in_error(txq->bp);
3578 	if (rc)
3579 		return rc;
3580 
3581 	if (offset >= txq->nb_tx_desc)
3582 		return -EINVAL;
3583 
3584 	/* Return "desc done" if descriptor is available for use. */
3585 	if (bnxt_tx_bds_in_hw(txq) <= offset)
3586 		return RTE_ETH_TX_DESC_DONE;
3587 
3588 	raw_cons = cpr->cp_raw_cons;
3589 	cp_desc_ring = cpr->cp_desc_ring;
3590 	ring_mask = cpr->cp_ring_struct->ring_mask;
3591 
3592 	/* Check to see if hw has posted a completion for the descriptor. */
3593 	while (1) {
3594 		struct tx_cmpl *txcmp;
3595 		uint32_t cons;
3596 
3597 		cons = RING_CMPL(ring_mask, raw_cons);
3598 		txcmp = (struct tx_cmpl *)&cp_desc_ring[cons];
3599 
3600 		if (!bnxt_cpr_cmp_valid(txcmp, raw_cons, ring_mask + 1))
3601 			break;
3602 
3603 		if (CMP_TYPE(txcmp) == TX_CMPL_TYPE_TX_L2)
3604 			nb_tx_pkts += rte_le_to_cpu_32(txcmp->opaque);
3605 
3606 		if (nb_tx_pkts > offset)
3607 			return RTE_ETH_TX_DESC_DONE;
3608 
3609 		raw_cons = NEXT_RAW_CMP(raw_cons);
3610 	}
3611 
3612 	/* Descriptor is pending transmit, not yet completed by hardware. */
3613 	return RTE_ETH_TX_DESC_FULL;
3614 }
3615 
3616 int
3617 bnxt_flow_ops_get_op(struct rte_eth_dev *dev,
3618 		     const struct rte_flow_ops **ops)
3619 {
3620 	struct bnxt *bp = dev->data->dev_private;
3621 	int ret = 0;
3622 
3623 	if (!bp)
3624 		return -EIO;
3625 
3626 	if (rte_eth_dev_is_repr(dev)) {
3627 		struct bnxt_representor *vfr = dev->data->dev_private;
3628 		bp = vfr->parent_dev->data->dev_private;
3629 		/* parent is deleted while children are still valid */
3630 		if (!bp) {
3631 			PMD_DRV_LOG_LINE(DEBUG, "BNXT Port:%d VFR Error",
3632 				    dev->data->port_id);
3633 			return -EIO;
3634 		}
3635 	}
3636 
3637 	ret = is_bnxt_in_error(bp);
3638 	if (ret)
3639 		return ret;
3640 
3641 	/* PMD supports thread-safe flow operations.  rte_flow API
3642 	 * functions can avoid mutex for multi-thread safety.
3643 	 */
3644 	dev->data->dev_flags |= RTE_ETH_DEV_FLOW_OPS_THREAD_SAFE;
3645 
3646 	if (bnxt_enable_ulp(bp))
3647 		*ops = &bnxt_ulp_rte_flow_ops;
3648 	else
3649 		*ops = &bnxt_flow_ops;
3650 
3651 	return ret;
3652 }
3653 
3654 static const uint32_t *
3655 bnxt_dev_supported_ptypes_get_op(struct rte_eth_dev *dev,
3656 				 size_t *no_of_elements)
3657 {
3658 	static const uint32_t ptypes[] = {
3659 		RTE_PTYPE_L2_ETHER_VLAN,
3660 		RTE_PTYPE_L3_IPV4_EXT_UNKNOWN,
3661 		RTE_PTYPE_L3_IPV6_EXT_UNKNOWN,
3662 		RTE_PTYPE_L4_ICMP,
3663 		RTE_PTYPE_L4_TCP,
3664 		RTE_PTYPE_L4_UDP,
3665 		RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN,
3666 		RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN,
3667 		RTE_PTYPE_INNER_L4_ICMP,
3668 		RTE_PTYPE_INNER_L4_TCP,
3669 		RTE_PTYPE_INNER_L4_UDP,
3670 	};
3671 
3672 	if (!dev->rx_pkt_burst)
3673 		return NULL;
3674 
3675 	*no_of_elements = RTE_DIM(ptypes);
3676 	return ptypes;
3677 }
3678 
3679 static int bnxt_map_regs(struct bnxt *bp, uint32_t *reg_arr, int count,
3680 			 int reg_win)
3681 {
3682 	uint32_t reg_base = *reg_arr & 0xfffff000;
3683 	uint32_t win_off;
3684 	int i;
3685 
3686 	for (i = 0; i < count; i++) {
3687 		if ((reg_arr[i] & 0xfffff000) != reg_base)
3688 			return -ERANGE;
3689 	}
3690 	win_off = BNXT_GRCPF_REG_WINDOW_BASE_OUT + (reg_win - 1) * 4;
3691 	rte_write32(reg_base, (uint8_t *)bp->bar0 + win_off);
3692 	return 0;
3693 }
3694 
3695 static int bnxt_map_ptp_regs(struct bnxt *bp)
3696 {
3697 	struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
3698 	uint32_t *reg_arr;
3699 	int rc, i;
3700 
3701 	reg_arr = ptp->rx_regs;
3702 	rc = bnxt_map_regs(bp, reg_arr, BNXT_PTP_RX_REGS, 5);
3703 	if (rc)
3704 		return rc;
3705 
3706 	reg_arr = ptp->tx_regs;
3707 	rc = bnxt_map_regs(bp, reg_arr, BNXT_PTP_TX_REGS, 6);
3708 	if (rc)
3709 		return rc;
3710 
3711 	for (i = 0; i < BNXT_PTP_RX_REGS; i++)
3712 		ptp->rx_mapped_regs[i] = 0x5000 + (ptp->rx_regs[i] & 0xfff);
3713 
3714 	for (i = 0; i < BNXT_PTP_TX_REGS; i++)
3715 		ptp->tx_mapped_regs[i] = 0x6000 + (ptp->tx_regs[i] & 0xfff);
3716 
3717 	return 0;
3718 }
3719 
3720 static void bnxt_unmap_ptp_regs(struct bnxt *bp)
3721 {
3722 	rte_write32(0, (uint8_t *)bp->bar0 +
3723 			 BNXT_GRCPF_REG_WINDOW_BASE_OUT + 16);
3724 	rte_write32(0, (uint8_t *)bp->bar0 +
3725 			 BNXT_GRCPF_REG_WINDOW_BASE_OUT + 20);
3726 }
3727 
3728 static uint64_t bnxt_cc_read(struct bnxt *bp)
3729 {
3730 	uint64_t ns;
3731 
3732 	ns = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
3733 			      BNXT_GRCPF_REG_SYNC_TIME));
3734 	ns |= (uint64_t)(rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
3735 					  BNXT_GRCPF_REG_SYNC_TIME + 4))) << 32;
3736 	return ns;
3737 }
3738 
3739 static int bnxt_get_tx_ts(struct bnxt *bp, uint64_t *ts)
3740 {
3741 	struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
3742 	uint32_t fifo;
3743 
3744 	fifo = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
3745 				ptp->tx_mapped_regs[BNXT_PTP_TX_FIFO]));
3746 	if (fifo & BNXT_PTP_TX_FIFO_EMPTY)
3747 		return -EAGAIN;
3748 
3749 	fifo = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
3750 				ptp->tx_mapped_regs[BNXT_PTP_TX_FIFO]));
3751 	*ts = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
3752 				ptp->tx_mapped_regs[BNXT_PTP_TX_TS_L]));
3753 	*ts |= (uint64_t)rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
3754 				ptp->tx_mapped_regs[BNXT_PTP_TX_TS_H])) << 32;
3755 	rte_read32((uint8_t *)bp->bar0 + ptp->tx_mapped_regs[BNXT_PTP_TX_SEQ]);
3756 
3757 	return 0;
3758 }
3759 
3760 static int bnxt_clr_rx_ts(struct bnxt *bp, uint64_t *last_ts)
3761 {
3762 	struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
3763 	struct bnxt_pf_info *pf = bp->pf;
3764 	uint16_t port_id;
3765 	int i = 0;
3766 	uint32_t fifo;
3767 
3768 	if (!ptp || (bp->flags & BNXT_FLAG_CHIP_P5))
3769 		return -EINVAL;
3770 
3771 	port_id = pf->port_id;
3772 	fifo = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
3773 				ptp->rx_mapped_regs[BNXT_PTP_RX_FIFO]));
3774 	while ((fifo & BNXT_PTP_RX_FIFO_PENDING) && (i < BNXT_PTP_RX_PND_CNT)) {
3775 		rte_write32(1 << port_id, (uint8_t *)bp->bar0 +
3776 			    ptp->rx_mapped_regs[BNXT_PTP_RX_FIFO_ADV]);
3777 		fifo = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
3778 					ptp->rx_mapped_regs[BNXT_PTP_RX_FIFO]));
3779 		*last_ts = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
3780 					ptp->rx_mapped_regs[BNXT_PTP_RX_TS_L]));
3781 		*last_ts |= (uint64_t)rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
3782 					ptp->rx_mapped_regs[BNXT_PTP_RX_TS_H])) << 32;
3783 		i++;
3784 	}
3785 
3786 	if (i >= BNXT_PTP_RX_PND_CNT)
3787 		return -EBUSY;
3788 
3789 	return 0;
3790 }
3791 
3792 static int bnxt_get_rx_ts(struct bnxt *bp, uint64_t *ts)
3793 {
3794 	struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
3795 	struct bnxt_pf_info *pf = bp->pf;
3796 	uint16_t port_id;
3797 	uint32_t fifo;
3798 
3799 	fifo = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
3800 				ptp->rx_mapped_regs[BNXT_PTP_RX_FIFO]));
3801 	if (!(fifo & BNXT_PTP_RX_FIFO_PENDING))
3802 		return -EAGAIN;
3803 
3804 	port_id = pf->port_id;
3805 	rte_write32(1 << port_id, (uint8_t *)bp->bar0 +
3806 	       ptp->rx_mapped_regs[BNXT_PTP_RX_FIFO_ADV]);
3807 
3808 	fifo = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
3809 				   ptp->rx_mapped_regs[BNXT_PTP_RX_FIFO]));
3810 	if (fifo & BNXT_PTP_RX_FIFO_PENDING)
3811 		return bnxt_clr_rx_ts(bp, ts);
3812 
3813 	*ts = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
3814 				ptp->rx_mapped_regs[BNXT_PTP_RX_TS_L]));
3815 	*ts |= (uint64_t)rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
3816 				ptp->rx_mapped_regs[BNXT_PTP_RX_TS_H])) << 32;
3817 
3818 	return 0;
3819 }
3820 
3821 static int
3822 bnxt_timesync_write_time(struct rte_eth_dev *dev, const struct timespec *ts)
3823 {
3824 	uint64_t ns;
3825 	struct bnxt *bp = dev->data->dev_private;
3826 	struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
3827 
3828 	if (!ptp)
3829 		return -ENOTSUP;
3830 
3831 	ns = rte_timespec_to_ns(ts);
3832 	/* Set the timecounters to a new value. */
3833 	ptp->tc.nsec = ns;
3834 	ptp->tx_tstamp_tc.nsec = ns;
3835 	ptp->rx_tstamp_tc.nsec = ns;
3836 
3837 	return 0;
3838 }
3839 
3840 static int
3841 bnxt_timesync_read_time(struct rte_eth_dev *dev, struct timespec *ts)
3842 {
3843 	struct bnxt *bp = dev->data->dev_private;
3844 	struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
3845 	uint64_t ns, systime_cycles = 0;
3846 	int rc = 0;
3847 
3848 	if (!ptp)
3849 		return -ENOTSUP;
3850 
3851 	/* TODO Revisit for Thor 2 */
3852 	if (BNXT_CHIP_P5(bp))
3853 		rc = bnxt_hwrm_port_ts_query(bp, BNXT_PTP_FLAGS_CURRENT_TIME,
3854 					     &systime_cycles);
3855 	else
3856 		systime_cycles = bnxt_cc_read(bp);
3857 
3858 	ns = rte_timecounter_update(&ptp->tc, systime_cycles);
3859 	*ts = rte_ns_to_timespec(ns);
3860 
3861 	return rc;
3862 }
3863 static int
3864 bnxt_timesync_enable(struct rte_eth_dev *dev)
3865 {
3866 	struct bnxt *bp = dev->data->dev_private;
3867 	struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
3868 	uint32_t shift = 0;
3869 	int rc;
3870 
3871 	if (!ptp)
3872 		return -ENOTSUP;
3873 
3874 	ptp->rx_filter = 1;
3875 	ptp->tx_tstamp_en = 1;
3876 	ptp->filter_all = 1;
3877 	ptp->rxctl = BNXT_PTP_MSG_EVENTS;
3878 
3879 	rc = bnxt_hwrm_ptp_cfg(bp);
3880 	if (rc)
3881 		return rc;
3882 
3883 	rte_spinlock_init(&ptp->ptp_lock);
3884 	bp->ptp_all_rx_tstamp = 1;
3885 	memset(&ptp->tc, 0, sizeof(struct rte_timecounter));
3886 	memset(&ptp->rx_tstamp_tc, 0, sizeof(struct rte_timecounter));
3887 	memset(&ptp->tx_tstamp_tc, 0, sizeof(struct rte_timecounter));
3888 
3889 	ptp->tc.cc_mask = BNXT_CYCLECOUNTER_MASK;
3890 	ptp->tc.cc_shift = shift;
3891 	ptp->tc.nsec_mask = (1ULL << shift) - 1;
3892 
3893 	ptp->rx_tstamp_tc.cc_mask = BNXT_CYCLECOUNTER_MASK;
3894 	ptp->rx_tstamp_tc.cc_shift = shift;
3895 	ptp->rx_tstamp_tc.nsec_mask = (1ULL << shift) - 1;
3896 
3897 	ptp->tx_tstamp_tc.cc_mask = BNXT_CYCLECOUNTER_MASK;
3898 	ptp->tx_tstamp_tc.cc_shift = shift;
3899 	ptp->tx_tstamp_tc.nsec_mask = (1ULL << shift) - 1;
3900 
3901 	/* TODO Revisit for Thor 2 */
3902 	if (!BNXT_CHIP_P5(bp))
3903 		bnxt_map_ptp_regs(bp);
3904 	else
3905 		rc = bnxt_ptp_start(bp);
3906 
3907 	return rc;
3908 }
3909 
3910 static int
3911 bnxt_timesync_disable(struct rte_eth_dev *dev)
3912 {
3913 	struct bnxt *bp = dev->data->dev_private;
3914 	struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
3915 
3916 	if (!ptp)
3917 		return -ENOTSUP;
3918 
3919 	ptp->rx_filter = 0;
3920 	ptp->tx_tstamp_en = 0;
3921 	ptp->rxctl = 0;
3922 	ptp->filter_all = 0;
3923 
3924 	bnxt_hwrm_ptp_cfg(bp);
3925 
3926 	/* TODO Revisit for Thor 2 */
3927 	bp->ptp_all_rx_tstamp = 0;
3928 	if (!BNXT_CHIP_P5(bp))
3929 		bnxt_unmap_ptp_regs(bp);
3930 	else
3931 		bnxt_ptp_stop(bp);
3932 
3933 	return 0;
3934 }
3935 
3936 static int
3937 bnxt_timesync_read_rx_timestamp(struct rte_eth_dev *dev,
3938 				 struct timespec *timestamp,
3939 				 uint32_t flags __rte_unused)
3940 {
3941 	struct bnxt *bp = dev->data->dev_private;
3942 	struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
3943 	uint64_t rx_tstamp_cycles = 0;
3944 	uint64_t ns;
3945 
3946 	if (!ptp)
3947 		return -ENOTSUP;
3948 
3949 	/* TODO Revisit for Thor 2 */
3950 	if (BNXT_CHIP_P5(bp))
3951 		rx_tstamp_cycles = ptp->rx_timestamp;
3952 	else
3953 		bnxt_get_rx_ts(bp, &rx_tstamp_cycles);
3954 
3955 	ns = rte_timecounter_update(&ptp->rx_tstamp_tc, rx_tstamp_cycles);
3956 	*timestamp = rte_ns_to_timespec(ns);
3957 	return  0;
3958 }
3959 
3960 static int
3961 bnxt_timesync_read_tx_timestamp(struct rte_eth_dev *dev,
3962 				 struct timespec *timestamp)
3963 {
3964 	struct bnxt *bp = dev->data->dev_private;
3965 	struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
3966 	uint64_t tx_tstamp_cycles = 0;
3967 	uint64_t ns;
3968 	int rc = 0;
3969 
3970 	if (!ptp)
3971 		return -ENOTSUP;
3972 
3973 	/* TODO Revisit for Thor 2 */
3974 	if (BNXT_CHIP_P5(bp))
3975 		rc = bnxt_hwrm_port_ts_query(bp, BNXT_PTP_FLAGS_PATH_TX,
3976 					     &tx_tstamp_cycles);
3977 	else
3978 		rc = bnxt_get_tx_ts(bp, &tx_tstamp_cycles);
3979 
3980 	ns = rte_timecounter_update(&ptp->tx_tstamp_tc, tx_tstamp_cycles);
3981 	*timestamp = rte_ns_to_timespec(ns);
3982 
3983 	return rc;
3984 }
3985 
3986 static int
3987 bnxt_timesync_adjust_time(struct rte_eth_dev *dev, int64_t delta)
3988 {
3989 	struct bnxt *bp = dev->data->dev_private;
3990 	struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
3991 
3992 	if (!ptp)
3993 		return -ENOTSUP;
3994 
3995 	ptp->tc.nsec += delta;
3996 	ptp->tx_tstamp_tc.nsec += delta;
3997 	ptp->rx_tstamp_tc.nsec += delta;
3998 
3999 	return 0;
4000 }
4001 
4002 static int
4003 bnxt_get_eeprom_length_op(struct rte_eth_dev *dev)
4004 {
4005 	struct bnxt *bp = dev->data->dev_private;
4006 	int rc;
4007 	uint32_t dir_entries;
4008 	uint32_t entry_length;
4009 
4010 	rc = is_bnxt_in_error(bp);
4011 	if (rc)
4012 		return rc;
4013 
4014 	PMD_DRV_LOG_LINE(INFO, PCI_PRI_FMT,
4015 		    bp->pdev->addr.domain, bp->pdev->addr.bus,
4016 		    bp->pdev->addr.devid, bp->pdev->addr.function);
4017 
4018 	rc = bnxt_hwrm_nvm_get_dir_info(bp, &dir_entries, &entry_length);
4019 	if (rc != 0)
4020 		return rc;
4021 
4022 	return dir_entries * entry_length;
4023 }
4024 
4025 static int
4026 bnxt_get_eeprom_op(struct rte_eth_dev *dev,
4027 		struct rte_dev_eeprom_info *in_eeprom)
4028 {
4029 	struct bnxt *bp = dev->data->dev_private;
4030 	uint32_t index;
4031 	uint32_t offset;
4032 	int rc;
4033 
4034 	rc = is_bnxt_in_error(bp);
4035 	if (rc)
4036 		return rc;
4037 
4038 	PMD_DRV_LOG_LINE(INFO, PCI_PRI_FMT " in_eeprom->offset = %d len = %d",
4039 		    bp->pdev->addr.domain, bp->pdev->addr.bus,
4040 		    bp->pdev->addr.devid, bp->pdev->addr.function,
4041 		    in_eeprom->offset, in_eeprom->length);
4042 
4043 	if (in_eeprom->offset == 0) /* special offset value to get directory */
4044 		return bnxt_get_nvram_directory(bp, in_eeprom->length,
4045 						in_eeprom->data);
4046 
4047 	index = in_eeprom->offset >> 24;
4048 	offset = in_eeprom->offset & 0xffffff;
4049 
4050 	if (index != 0)
4051 		return bnxt_hwrm_get_nvram_item(bp, index - 1, offset,
4052 					   in_eeprom->length, in_eeprom->data);
4053 
4054 	return 0;
4055 }
4056 
4057 static bool bnxt_dir_type_is_ape_bin_format(uint16_t dir_type)
4058 {
4059 	switch (dir_type) {
4060 	case BNX_DIR_TYPE_CHIMP_PATCH:
4061 	case BNX_DIR_TYPE_BOOTCODE:
4062 	case BNX_DIR_TYPE_BOOTCODE_2:
4063 	case BNX_DIR_TYPE_APE_FW:
4064 	case BNX_DIR_TYPE_APE_PATCH:
4065 	case BNX_DIR_TYPE_KONG_FW:
4066 	case BNX_DIR_TYPE_KONG_PATCH:
4067 	case BNX_DIR_TYPE_BONO_FW:
4068 	case BNX_DIR_TYPE_BONO_PATCH:
4069 		/* FALLTHROUGH */
4070 		return true;
4071 	}
4072 
4073 	return false;
4074 }
4075 
4076 static bool bnxt_dir_type_is_other_exec_format(uint16_t dir_type)
4077 {
4078 	switch (dir_type) {
4079 	case BNX_DIR_TYPE_AVS:
4080 	case BNX_DIR_TYPE_EXP_ROM_MBA:
4081 	case BNX_DIR_TYPE_PCIE:
4082 	case BNX_DIR_TYPE_TSCF_UCODE:
4083 	case BNX_DIR_TYPE_EXT_PHY:
4084 	case BNX_DIR_TYPE_CCM:
4085 	case BNX_DIR_TYPE_ISCSI_BOOT:
4086 	case BNX_DIR_TYPE_ISCSI_BOOT_IPV6:
4087 	case BNX_DIR_TYPE_ISCSI_BOOT_IPV4N6:
4088 		/* FALLTHROUGH */
4089 		return true;
4090 	}
4091 
4092 	return false;
4093 }
4094 
4095 static bool bnxt_dir_type_is_executable(uint16_t dir_type)
4096 {
4097 	return bnxt_dir_type_is_ape_bin_format(dir_type) ||
4098 		bnxt_dir_type_is_other_exec_format(dir_type);
4099 }
4100 
4101 static int
4102 bnxt_set_eeprom_op(struct rte_eth_dev *dev,
4103 		struct rte_dev_eeprom_info *in_eeprom)
4104 {
4105 	struct bnxt *bp = dev->data->dev_private;
4106 	uint8_t index, dir_op;
4107 	uint16_t type, ext, ordinal, attr;
4108 	int rc;
4109 
4110 	rc = is_bnxt_in_error(bp);
4111 	if (rc)
4112 		return rc;
4113 
4114 	PMD_DRV_LOG_LINE(INFO, PCI_PRI_FMT " in_eeprom->offset = %d len = %d",
4115 		    bp->pdev->addr.domain, bp->pdev->addr.bus,
4116 		    bp->pdev->addr.devid, bp->pdev->addr.function,
4117 		    in_eeprom->offset, in_eeprom->length);
4118 
4119 	if (!BNXT_PF(bp)) {
4120 		PMD_DRV_LOG_LINE(ERR, "NVM write not supported from a VF");
4121 		return -EINVAL;
4122 	}
4123 
4124 	type = in_eeprom->magic >> 16;
4125 
4126 	if (type == 0xffff) { /* special value for directory operations */
4127 		index = in_eeprom->magic & 0xff;
4128 		dir_op = in_eeprom->magic >> 8;
4129 		if (index == 0)
4130 			return -EINVAL;
4131 		switch (dir_op) {
4132 		case 0x0e: /* erase */
4133 			if (in_eeprom->offset != ~in_eeprom->magic)
4134 				return -EINVAL;
4135 			return bnxt_hwrm_erase_nvram_directory(bp, index - 1);
4136 		default:
4137 			return -EINVAL;
4138 		}
4139 	}
4140 
4141 	/* Create or re-write an NVM item: */
4142 	if (bnxt_dir_type_is_executable(type) == true)
4143 		return -EOPNOTSUPP;
4144 	ext = in_eeprom->magic & 0xffff;
4145 	ordinal = in_eeprom->offset >> 16;
4146 	attr = in_eeprom->offset & 0xffff;
4147 
4148 	return bnxt_hwrm_flash_nvram(bp, type, ordinal, ext, attr,
4149 				     in_eeprom->data, in_eeprom->length);
4150 }
4151 
4152 static int bnxt_get_module_info(struct rte_eth_dev *dev,
4153 				struct rte_eth_dev_module_info *modinfo)
4154 {
4155 	uint8_t module_info[SFF_DIAG_SUPPORT_OFFSET + 1];
4156 	struct bnxt *bp = dev->data->dev_private;
4157 	int rc;
4158 
4159 	/* No point in going further if phy status indicates
4160 	 * module is not inserted or if it is powered down or
4161 	 * if it is of type 10GBase-T
4162 	 */
4163 	if (bp->link_info->module_status >
4164 	    HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_WARNINGMSG) {
4165 		PMD_DRV_LOG_LINE(NOTICE, "Port %u : Module is not inserted or is powered down",
4166 			    dev->data->port_id);
4167 		return -ENOTSUP;
4168 	}
4169 
4170 	/* This feature is not supported in older firmware versions */
4171 	if (bp->hwrm_spec_code < 0x10202) {
4172 		PMD_DRV_LOG_LINE(NOTICE, "Port %u : Feature is not supported in older firmware",
4173 			    dev->data->port_id);
4174 		return -ENOTSUP;
4175 	}
4176 
4177 	rc = bnxt_hwrm_read_sfp_module_eeprom_info(bp, I2C_DEV_ADDR_A0, 0, 0,
4178 						   SFF_DIAG_SUPPORT_OFFSET + 1,
4179 						   module_info);
4180 
4181 	if (rc)
4182 		return rc;
4183 
4184 	switch (module_info[0]) {
4185 	case SFF_MODULE_ID_SFP:
4186 		modinfo->type = RTE_ETH_MODULE_SFF_8472;
4187 		modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8472_LEN;
4188 		if (module_info[SFF_DIAG_SUPPORT_OFFSET] == 0)
4189 			modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8436_LEN;
4190 		break;
4191 	case SFF_MODULE_ID_QSFP:
4192 	case SFF_MODULE_ID_QSFP_PLUS:
4193 		modinfo->type = RTE_ETH_MODULE_SFF_8436;
4194 		modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8436_LEN;
4195 		break;
4196 	case SFF_MODULE_ID_QSFP28:
4197 		modinfo->type = RTE_ETH_MODULE_SFF_8636;
4198 		modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8636_MAX_LEN;
4199 		if (module_info[SFF8636_FLATMEM_OFFSET] & SFF8636_FLATMEM_MASK)
4200 			modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8636_LEN;
4201 		break;
4202 	default:
4203 		PMD_DRV_LOG_LINE(NOTICE, "Port %u : Unsupported module", dev->data->port_id);
4204 		return -ENOTSUP;
4205 	}
4206 
4207 	PMD_DRV_LOG_LINE(INFO, "Port %u : modinfo->type = %d modinfo->eeprom_len = %d",
4208 		    dev->data->port_id, modinfo->type, modinfo->eeprom_len);
4209 
4210 	return 0;
4211 }
4212 
4213 static int bnxt_get_module_eeprom(struct rte_eth_dev *dev,
4214 				  struct rte_dev_eeprom_info *info)
4215 {
4216 	uint8_t pg_addr[5] = { I2C_DEV_ADDR_A0, I2C_DEV_ADDR_A0 };
4217 	uint32_t offset = info->offset, length = info->length;
4218 	uint8_t module_info[SFF_DIAG_SUPPORT_OFFSET + 1];
4219 	struct bnxt *bp = dev->data->dev_private;
4220 	uint8_t *data = info->data;
4221 	uint8_t page = offset >> 7;
4222 	uint8_t max_pages = 2;
4223 	uint8_t opt_pages;
4224 	int rc;
4225 
4226 	rc = bnxt_hwrm_read_sfp_module_eeprom_info(bp, I2C_DEV_ADDR_A0, 0, 0,
4227 						   SFF_DIAG_SUPPORT_OFFSET + 1,
4228 						   module_info);
4229 	if (rc)
4230 		return rc;
4231 
4232 	switch (module_info[0]) {
4233 	case SFF_MODULE_ID_SFP:
4234 		if (module_info[SFF_DIAG_SUPPORT_OFFSET]) {
4235 			pg_addr[2] = I2C_DEV_ADDR_A2;
4236 			pg_addr[3] = I2C_DEV_ADDR_A2;
4237 			max_pages = 4;
4238 		}
4239 		break;
4240 	case SFF_MODULE_ID_QSFP28:
4241 		rc = bnxt_hwrm_read_sfp_module_eeprom_info(bp, I2C_DEV_ADDR_A0, 0,
4242 							   SFF8636_OPT_PAGES_OFFSET,
4243 							   1, &opt_pages);
4244 		if (rc)
4245 			return rc;
4246 
4247 		if (opt_pages & SFF8636_PAGE1_MASK) {
4248 			pg_addr[2] = I2C_DEV_ADDR_A0;
4249 			max_pages = 3;
4250 		}
4251 		if (opt_pages & SFF8636_PAGE2_MASK) {
4252 			pg_addr[3] = I2C_DEV_ADDR_A0;
4253 			max_pages = 4;
4254 		}
4255 		if (~module_info[SFF8636_FLATMEM_OFFSET] & SFF8636_FLATMEM_MASK) {
4256 			pg_addr[4] = I2C_DEV_ADDR_A0;
4257 			max_pages = 5;
4258 		}
4259 		break;
4260 	default:
4261 		break;
4262 	}
4263 
4264 	memset(data, 0, length);
4265 
4266 	offset &= 0xff;
4267 	while (length && page < max_pages) {
4268 		uint8_t raw_page = page ? page - 1 : 0;
4269 		uint16_t chunk;
4270 
4271 		if (pg_addr[page] == I2C_DEV_ADDR_A2)
4272 			raw_page = 0;
4273 		else if (page)
4274 			offset |= 0x80;
4275 		chunk = RTE_MIN(length, 256 - offset);
4276 
4277 		if (pg_addr[page]) {
4278 			rc = bnxt_hwrm_read_sfp_module_eeprom_info(bp, pg_addr[page],
4279 								   raw_page, offset,
4280 								   chunk, data);
4281 			if (rc)
4282 				return rc;
4283 		}
4284 
4285 		data += chunk;
4286 		length -= chunk;
4287 		offset = 0;
4288 		page += 1 + (chunk > 128);
4289 	}
4290 
4291 	return length ? -EINVAL : 0;
4292 }
4293 
4294 #if (RTE_VERSION_NUM(22, 11, 0, 0) <= RTE_VERSION)
4295 static int bnxt_speed_lanes_set(struct rte_eth_dev *dev, uint32_t speed_lanes)
4296 {
4297 	struct bnxt *bp = dev->data->dev_private;
4298 
4299 	if (!BNXT_LINK_SPEEDS_V2(bp))
4300 		return -ENOTSUP;
4301 
4302 	bp->link_info->pmd_speed_lanes = speed_lanes;
4303 
4304 	return 0;
4305 }
4306 
4307 static uint32_t
4308 bnxt_get_speed_lanes_capa(struct rte_eth_speed_lanes_capa *speed_lanes_capa,
4309 			  uint32_t speed_capa)
4310 {
4311 	uint32_t speed_bit;
4312 	uint32_t num = 0;
4313 	uint32_t i;
4314 
4315 	for (i = 0; i < RTE_DIM(speed_lanes_capa_tbl); i++) {
4316 		speed_bit =
4317 			rte_eth_speed_bitflag(speed_lanes_capa_tbl[i].speed,
4318 					      RTE_ETH_LINK_FULL_DUPLEX);
4319 		if ((speed_capa & speed_bit) == 0)
4320 			continue;
4321 
4322 		speed_lanes_capa[num].speed = speed_lanes_capa_tbl[i].speed;
4323 		speed_lanes_capa[num].capa = speed_lanes_capa_tbl[i].capa;
4324 		num++;
4325 	}
4326 
4327 	return num;
4328 }
4329 
4330 static int bnxt_speed_lanes_get_capa(struct rte_eth_dev *dev,
4331 				     struct rte_eth_speed_lanes_capa *speed_lanes_capa,
4332 				     unsigned int num)
4333 {
4334 	struct rte_eth_link *link = &dev->data->dev_link;
4335 	struct bnxt *bp = dev->data->dev_private;
4336 	unsigned int speed_num;
4337 	uint32_t speed_capa;
4338 	int rc;
4339 
4340 	rc = is_bnxt_in_error(bp);
4341 	if (rc)
4342 		return rc;
4343 
4344 	if (!BNXT_LINK_SPEEDS_V2(bp))
4345 		return -ENOTSUP;
4346 
4347 	/* speed_num counts number of speed capabilities.
4348 	 * When link is down, show the user choice all combinations of speeds x lanes
4349 	 */
4350 	if (link->link_status) {
4351 		speed_capa = bnxt_get_speed_capabilities_v2(bp);
4352 		speed_num = rte_popcount32(speed_capa & BNXT_SPEEDS_SUPP_SPEED_LANES);
4353 	} else {
4354 		speed_capa = BNXT_SPEEDS_SUPP_SPEED_LANES;
4355 		speed_num = rte_popcount32(BNXT_SPEEDS_SUPP_SPEED_LANES);
4356 	}
4357 	if (speed_num == 0)
4358 		return -ENOTSUP;
4359 
4360 	if (speed_lanes_capa == NULL)
4361 		return speed_num;
4362 
4363 	if (num < speed_num)
4364 		return -EINVAL;
4365 
4366 	return bnxt_get_speed_lanes_capa(speed_lanes_capa, speed_capa);
4367 }
4368 
4369 static int bnxt_speed_lanes_get(struct rte_eth_dev *dev, uint32_t *lanes)
4370 {
4371 	struct rte_eth_link *link = &dev->data->dev_link;
4372 	struct bnxt *bp = dev->data->dev_private;
4373 	int rc;
4374 
4375 	rc = is_bnxt_in_error(bp);
4376 	if (rc)
4377 		return rc;
4378 
4379 	if (!BNXT_LINK_SPEEDS_V2(bp))
4380 		return -ENOTSUP;
4381 
4382 	if (!link->link_status)
4383 		return -EINVAL;
4384 
4385 	 /* user app expects lanes 1 for zero */
4386 	*lanes = (bp->link_info->active_lanes) ?
4387 		bp->link_info->active_lanes : 1;
4388 	return 0;
4389 }
4390 
4391 #endif
4392 
4393 /*
4394  * Initialization
4395  */
4396 
4397 static const struct eth_dev_ops bnxt_dev_ops = {
4398 	.dev_infos_get = bnxt_dev_info_get_op,
4399 	.dev_close = bnxt_dev_close_op,
4400 	.dev_configure = bnxt_dev_configure_op,
4401 	.dev_start = bnxt_dev_start_op,
4402 	.dev_stop = bnxt_dev_stop_op,
4403 	.dev_set_link_up = bnxt_dev_set_link_up_op,
4404 	.dev_set_link_down = bnxt_dev_set_link_down_op,
4405 	.stats_get = bnxt_stats_get_op,
4406 	.stats_reset = bnxt_stats_reset_op,
4407 	.rx_queue_setup = bnxt_rx_queue_setup_op,
4408 	.rx_queue_release = bnxt_rx_queue_release_op,
4409 	.tx_queue_setup = bnxt_tx_queue_setup_op,
4410 	.tx_queue_release = bnxt_tx_queue_release_op,
4411 	.rx_queue_intr_enable = bnxt_rx_queue_intr_enable_op,
4412 	.rx_queue_intr_disable = bnxt_rx_queue_intr_disable_op,
4413 	.reta_update = bnxt_reta_update_op,
4414 	.reta_query = bnxt_reta_query_op,
4415 	.rss_hash_update = bnxt_rss_hash_update_op,
4416 	.rss_hash_conf_get = bnxt_rss_hash_conf_get_op,
4417 	.link_update = bnxt_link_update_op,
4418 	.promiscuous_enable = bnxt_promiscuous_enable_op,
4419 	.promiscuous_disable = bnxt_promiscuous_disable_op,
4420 	.allmulticast_enable = bnxt_allmulticast_enable_op,
4421 	.allmulticast_disable = bnxt_allmulticast_disable_op,
4422 	.mac_addr_add = bnxt_mac_addr_add_op,
4423 	.mac_addr_remove = bnxt_mac_addr_remove_op,
4424 	.flow_ctrl_get = bnxt_flow_ctrl_get_op,
4425 	.flow_ctrl_set = bnxt_flow_ctrl_set_op,
4426 	.udp_tunnel_port_add  = bnxt_udp_tunnel_port_add_op,
4427 	.udp_tunnel_port_del  = bnxt_udp_tunnel_port_del_op,
4428 	.vlan_filter_set = bnxt_vlan_filter_set_op,
4429 	.vlan_offload_set = bnxt_vlan_offload_set_op,
4430 	.vlan_tpid_set = bnxt_vlan_tpid_set_op,
4431 	.vlan_pvid_set = bnxt_vlan_pvid_set_op,
4432 	.mtu_set = bnxt_mtu_set_op,
4433 	.mac_addr_set = bnxt_set_default_mac_addr_op,
4434 	.xstats_get = bnxt_dev_xstats_get_op,
4435 	.xstats_get_names = bnxt_dev_xstats_get_names_op,
4436 	.xstats_reset = bnxt_dev_xstats_reset_op,
4437 	.fw_version_get = bnxt_fw_version_get,
4438 	.set_mc_addr_list = bnxt_dev_set_mc_addr_list_op,
4439 	.rxq_info_get = bnxt_rxq_info_get_op,
4440 	.txq_info_get = bnxt_txq_info_get_op,
4441 	.rx_burst_mode_get = bnxt_rx_burst_mode_get,
4442 	.tx_burst_mode_get = bnxt_tx_burst_mode_get,
4443 	.dev_led_on = bnxt_dev_led_on_op,
4444 	.dev_led_off = bnxt_dev_led_off_op,
4445 	.rx_queue_start = bnxt_rx_queue_start,
4446 	.rx_queue_stop = bnxt_rx_queue_stop,
4447 	.tx_queue_start = bnxt_tx_queue_start,
4448 	.tx_queue_stop = bnxt_tx_queue_stop,
4449 	.flow_ops_get = bnxt_flow_ops_get_op,
4450 	.dev_supported_ptypes_get = bnxt_dev_supported_ptypes_get_op,
4451 	.get_eeprom_length    = bnxt_get_eeprom_length_op,
4452 	.get_eeprom           = bnxt_get_eeprom_op,
4453 	.set_eeprom           = bnxt_set_eeprom_op,
4454 	.get_module_info = bnxt_get_module_info,
4455 	.get_module_eeprom = bnxt_get_module_eeprom,
4456 	.timesync_enable      = bnxt_timesync_enable,
4457 	.timesync_disable     = bnxt_timesync_disable,
4458 	.timesync_read_time   = bnxt_timesync_read_time,
4459 	.timesync_write_time   = bnxt_timesync_write_time,
4460 	.timesync_adjust_time = bnxt_timesync_adjust_time,
4461 	.timesync_read_rx_timestamp = bnxt_timesync_read_rx_timestamp,
4462 	.timesync_read_tx_timestamp = bnxt_timesync_read_tx_timestamp,
4463 	.mtr_ops_get = bnxt_flow_meter_ops_get,
4464 #if (RTE_VERSION_NUM(22, 11, 0, 0) <= RTE_VERSION)
4465 	.speed_lanes_get = bnxt_speed_lanes_get,
4466 	.speed_lanes_set = bnxt_speed_lanes_set,
4467 	.speed_lanes_get_capa = bnxt_speed_lanes_get_capa,
4468 #endif
4469 };
4470 
4471 static uint32_t bnxt_map_reset_regs(struct bnxt *bp, uint32_t reg)
4472 {
4473 	uint32_t offset;
4474 
4475 	/* Only pre-map the reset GRC registers using window 3 */
4476 	rte_write32(reg & 0xfffff000, (uint8_t *)bp->bar0 +
4477 		    BNXT_GRCPF_REG_WINDOW_BASE_OUT + 8);
4478 
4479 	offset = BNXT_GRCP_WINDOW_3_BASE + (reg & 0xffc);
4480 
4481 	return offset;
4482 }
4483 
4484 int bnxt_map_fw_health_status_regs(struct bnxt *bp)
4485 {
4486 	struct bnxt_error_recovery_info *info = bp->recovery_info;
4487 	uint32_t reg_base = 0xffffffff;
4488 	int i;
4489 
4490 	/* Only pre-map the monitoring GRC registers using window 2 */
4491 	for (i = 0; i < BNXT_FW_STATUS_REG_CNT; i++) {
4492 		uint32_t reg = info->status_regs[i];
4493 
4494 		if (BNXT_FW_STATUS_REG_TYPE(reg) != BNXT_FW_STATUS_REG_TYPE_GRC)
4495 			continue;
4496 
4497 		if (reg_base == 0xffffffff)
4498 			reg_base = reg & 0xfffff000;
4499 		if ((reg & 0xfffff000) != reg_base)
4500 			return -ERANGE;
4501 
4502 		/* Use mask 0xffc as the Lower 2 bits indicates
4503 		 * address space location
4504 		 */
4505 		info->mapped_status_regs[i] = BNXT_GRCP_WINDOW_2_BASE +
4506 						(reg & 0xffc);
4507 	}
4508 
4509 	if (reg_base == 0xffffffff)
4510 		return 0;
4511 
4512 	rte_write32(reg_base, (uint8_t *)bp->bar0 +
4513 		    BNXT_GRCPF_REG_WINDOW_BASE_OUT + 4);
4514 
4515 	return 0;
4516 }
4517 
4518 static void bnxt_write_fw_reset_reg(struct bnxt *bp, uint32_t index)
4519 {
4520 	struct bnxt_error_recovery_info *info = bp->recovery_info;
4521 	uint32_t delay = info->delay_after_reset[index];
4522 	uint32_t val = info->reset_reg_val[index];
4523 	uint32_t reg = info->reset_reg[index];
4524 	uint32_t type, offset;
4525 	int ret;
4526 
4527 	type = BNXT_FW_STATUS_REG_TYPE(reg);
4528 	offset = BNXT_FW_STATUS_REG_OFF(reg);
4529 
4530 	switch (type) {
4531 	case BNXT_FW_STATUS_REG_TYPE_CFG:
4532 		ret = rte_pci_write_config(bp->pdev, &val, sizeof(val), offset);
4533 		if (ret < 0) {
4534 			PMD_DRV_LOG_LINE(ERR, "Failed to write %#x at PCI offset %#x",
4535 				    val, offset);
4536 			return;
4537 		}
4538 		break;
4539 	case BNXT_FW_STATUS_REG_TYPE_GRC:
4540 		offset = bnxt_map_reset_regs(bp, offset);
4541 		rte_write32(val, (uint8_t *)bp->bar0 + offset);
4542 		break;
4543 	case BNXT_FW_STATUS_REG_TYPE_BAR0:
4544 		rte_write32(val, (uint8_t *)bp->bar0 + offset);
4545 		break;
4546 	}
4547 	/* wait on a specific interval of time until core reset is complete */
4548 	if (delay)
4549 		rte_delay_ms(delay);
4550 }
4551 
4552 static void bnxt_dev_cleanup(struct bnxt *bp)
4553 {
4554 	bp->eth_dev->data->dev_link.link_status = 0;
4555 	bp->link_info->link_up = 0;
4556 	if (bp->eth_dev->data->dev_started)
4557 		bnxt_dev_stop(bp->eth_dev);
4558 
4559 	bnxt_uninit_resources(bp, true);
4560 }
4561 
4562 static int
4563 bnxt_check_fw_reset_done(struct bnxt *bp)
4564 {
4565 	int timeout = bp->fw_reset_max_msecs;
4566 	uint16_t val = 0;
4567 	int rc;
4568 
4569 	do {
4570 		rc = rte_pci_read_config(bp->pdev, &val, sizeof(val), PCI_SUBSYSTEM_ID_OFFSET);
4571 		if (rc < 0) {
4572 			PMD_DRV_LOG_LINE(ERR, "Failed to read PCI offset 0x%x",
4573 				PCI_SUBSYSTEM_ID_OFFSET);
4574 			return rc;
4575 		}
4576 		if (val != 0xffff)
4577 			break;
4578 		rte_delay_ms(1);
4579 	} while (timeout--);
4580 
4581 	if (val == 0xffff) {
4582 		PMD_DRV_LOG_LINE(ERR, "Firmware reset aborted, PCI config space invalid");
4583 		return -1;
4584 	}
4585 
4586 	return 0;
4587 }
4588 
4589 static int bnxt_restore_vlan_filters(struct bnxt *bp)
4590 {
4591 	struct rte_eth_dev *dev = bp->eth_dev;
4592 	struct rte_vlan_filter_conf *vfc;
4593 	int vidx, vbit, rc;
4594 	uint16_t vlan_id;
4595 
4596 	for (vlan_id = 1; vlan_id <= RTE_ETHER_MAX_VLAN_ID; vlan_id++) {
4597 		vfc = &dev->data->vlan_filter_conf;
4598 		vidx = vlan_id / 64;
4599 		vbit = vlan_id % 64;
4600 
4601 		/* Each bit corresponds to a VLAN id */
4602 		if (vfc->ids[vidx] & (UINT64_C(1) << vbit)) {
4603 			rc = bnxt_add_vlan_filter(bp, vlan_id);
4604 			if (rc)
4605 				return rc;
4606 		}
4607 	}
4608 
4609 	return 0;
4610 }
4611 
4612 static int bnxt_restore_mac_filters(struct bnxt *bp)
4613 {
4614 	struct rte_eth_dev *dev = bp->eth_dev;
4615 	struct rte_eth_dev_info dev_info;
4616 	struct rte_ether_addr *addr;
4617 	uint64_t pool_mask;
4618 	uint32_t pool = 0;
4619 	uint32_t i;
4620 	int rc;
4621 
4622 	if (BNXT_VF(bp) && !BNXT_VF_IS_TRUSTED(bp))
4623 		return 0;
4624 
4625 	rc = bnxt_dev_info_get_op(dev, &dev_info);
4626 	if (rc)
4627 		return rc;
4628 
4629 	/* replay MAC address configuration */
4630 	for (i = 1; i < dev_info.max_mac_addrs; i++) {
4631 		addr = &dev->data->mac_addrs[i];
4632 
4633 		/* skip zero address */
4634 		if (rte_is_zero_ether_addr(addr))
4635 			continue;
4636 
4637 		pool = 0;
4638 		pool_mask = dev->data->mac_pool_sel[i];
4639 
4640 		do {
4641 			if (pool_mask & 1ULL) {
4642 				rc = bnxt_mac_addr_add_op(dev, addr, i, pool);
4643 				if (rc)
4644 					return rc;
4645 			}
4646 			pool_mask >>= 1;
4647 			pool++;
4648 		} while (pool_mask);
4649 	}
4650 
4651 	return 0;
4652 }
4653 
4654 static int bnxt_restore_mcast_mac_filters(struct bnxt *bp)
4655 {
4656 	int ret = 0;
4657 
4658 	ret = bnxt_dev_set_mc_addr_list_op(bp->eth_dev, bp->mcast_addr_list,
4659 					   bp->nb_mc_addr);
4660 	if (ret)
4661 		PMD_DRV_LOG_LINE(ERR, "Failed to restore multicast MAC addreeses");
4662 
4663 	return ret;
4664 }
4665 
4666 static int bnxt_restore_filters(struct bnxt *bp)
4667 {
4668 	struct rte_eth_dev *dev = bp->eth_dev;
4669 	int ret = 0;
4670 
4671 	if (dev->data->all_multicast) {
4672 		ret = bnxt_allmulticast_enable_op(dev);
4673 		if (ret)
4674 			return ret;
4675 	}
4676 	if (dev->data->promiscuous) {
4677 		ret = bnxt_promiscuous_enable_op(dev);
4678 		if (ret)
4679 			return ret;
4680 	}
4681 
4682 	ret = bnxt_restore_mac_filters(bp);
4683 	if (ret)
4684 		return ret;
4685 
4686 	/* if vlans are already programmed, this can fail with -EEXIST */
4687 	ret = bnxt_restore_vlan_filters(bp);
4688 	if (ret && ret != -EEXIST)
4689 		return ret;
4690 
4691 	ret = bnxt_restore_mcast_mac_filters(bp);
4692 	if (ret)
4693 		return ret;
4694 
4695 	return ret;
4696 }
4697 
4698 static int bnxt_check_fw_ready(struct bnxt *bp)
4699 {
4700 	int timeout = bp->fw_reset_max_msecs ? : BNXT_MAX_FW_RESET_TIMEOUT;
4701 	int rc = 0;
4702 
4703 	do {
4704 		rc = bnxt_hwrm_poll_ver_get(bp);
4705 		if (rc == 0)
4706 			break;
4707 		rte_delay_ms(BNXT_FW_READY_WAIT_INTERVAL);
4708 		timeout -= BNXT_FW_READY_WAIT_INTERVAL;
4709 	} while (rc && timeout > 0);
4710 
4711 	if (rc)
4712 		PMD_DRV_LOG_LINE(ERR, "FW is not Ready after reset");
4713 
4714 	return rc;
4715 }
4716 
4717 static void bnxt_dev_recover(void *arg)
4718 {
4719 	struct bnxt *bp = arg;
4720 	int rc = 0;
4721 
4722 	pthread_mutex_lock(&bp->err_recovery_lock);
4723 
4724 	if (!bp->fw_reset_min_msecs) {
4725 		rc = bnxt_check_fw_reset_done(bp);
4726 		if (rc)
4727 			goto err;
4728 	}
4729 
4730 	/* Clear Error flag so that device re-init should happen */
4731 	bp->flags &= ~BNXT_FLAG_FATAL_ERROR;
4732 	PMD_DRV_LOG_LINE(INFO, "Port: %u Starting recovery...",
4733 		    bp->eth_dev->data->port_id);
4734 
4735 	rc = bnxt_check_fw_ready(bp);
4736 	if (rc)
4737 		goto err;
4738 
4739 	rc = bnxt_init_resources(bp, true);
4740 	if (rc) {
4741 		PMD_DRV_LOG_LINE(ERR,
4742 			    "Failed to initialize resources after reset");
4743 		goto err;
4744 	}
4745 	/* clear reset flag as the device is initialized now */
4746 	bp->flags &= ~BNXT_FLAG_FW_RESET;
4747 
4748 	rc = bnxt_dev_start_op(bp->eth_dev);
4749 	if (rc) {
4750 		PMD_DRV_LOG_LINE(ERR, "Failed to start port after reset");
4751 		goto err_start;
4752 	}
4753 
4754 	rc = bnxt_restore_filters(bp);
4755 	if (rc)
4756 		goto err_start;
4757 
4758 	rte_eth_fp_ops[bp->eth_dev->data->port_id].rx_pkt_burst =
4759 		bp->eth_dev->rx_pkt_burst;
4760 	rte_eth_fp_ops[bp->eth_dev->data->port_id].tx_pkt_burst =
4761 		bp->eth_dev->tx_pkt_burst;
4762 	rte_mb();
4763 
4764 	PMD_DRV_LOG_LINE(INFO, "Port: %u Recovered from FW reset",
4765 		    bp->eth_dev->data->port_id);
4766 	pthread_mutex_unlock(&bp->err_recovery_lock);
4767 	rte_eth_dev_callback_process(bp->eth_dev,
4768 				     RTE_ETH_EVENT_RECOVERY_SUCCESS,
4769 				     NULL);
4770 	return;
4771 err_start:
4772 	bnxt_dev_stop(bp->eth_dev);
4773 err:
4774 	bp->flags |= BNXT_FLAG_FATAL_ERROR;
4775 	bnxt_uninit_resources(bp, false);
4776 	rte_eth_dev_callback_process(bp->eth_dev,
4777 				     RTE_ETH_EVENT_RECOVERY_FAILED,
4778 				     NULL);
4779 	if (bp->eth_dev->data->dev_conf.intr_conf.rmv)
4780 		rte_eth_dev_callback_process(bp->eth_dev,
4781 					     RTE_ETH_EVENT_INTR_RMV,
4782 					     NULL);
4783 	pthread_mutex_unlock(&bp->err_recovery_lock);
4784 	PMD_DRV_LOG_LINE(ERR, "Port %u: Failed to recover from FW reset",
4785 		    bp->eth_dev->data->port_id);
4786 }
4787 
4788 void bnxt_dev_reset_and_resume(void *arg)
4789 {
4790 	struct bnxt *bp = arg;
4791 	uint32_t us = US_PER_MS * bp->fw_reset_min_msecs;
4792 	uint16_t val = 0;
4793 	int rc;
4794 
4795 	bnxt_dev_cleanup(bp);
4796 	PMD_DRV_LOG_LINE(INFO, "Port: %u Finished bnxt_dev_cleanup",
4797 		    bp->eth_dev->data->port_id);
4798 
4799 	bnxt_wait_for_device_shutdown(bp);
4800 
4801 	/* During some fatal firmware error conditions, the PCI config space
4802 	 * register 0x2e which normally contains the subsystem ID will become
4803 	 * 0xffff. This register will revert back to the normal value after
4804 	 * the chip has completed core reset. If we detect this condition,
4805 	 * we can poll this config register immediately for the value to revert.
4806 	 */
4807 	if (bp->flags & BNXT_FLAG_FATAL_ERROR) {
4808 		rc = rte_pci_read_config(bp->pdev, &val, sizeof(val), PCI_SUBSYSTEM_ID_OFFSET);
4809 		if (rc < 0) {
4810 			PMD_DRV_LOG_LINE(ERR, "Failed to read PCI offset 0x%x",
4811 				PCI_SUBSYSTEM_ID_OFFSET);
4812 			return;
4813 		}
4814 		if (val == 0xffff) {
4815 			bp->fw_reset_min_msecs = 0;
4816 			us = 1;
4817 		}
4818 	}
4819 
4820 	rc = rte_eal_alarm_set(us, bnxt_dev_recover, (void *)bp);
4821 	if (rc)
4822 		PMD_DRV_LOG_LINE(ERR, "Port %u: Error setting recovery alarm",
4823 			    bp->eth_dev->data->port_id);
4824 }
4825 
4826 uint32_t bnxt_read_fw_status_reg(struct bnxt *bp, uint32_t index)
4827 {
4828 	struct bnxt_error_recovery_info *info = bp->recovery_info;
4829 	uint32_t reg = info->status_regs[index];
4830 	uint32_t type, offset, val = 0;
4831 	int ret = 0;
4832 
4833 	type = BNXT_FW_STATUS_REG_TYPE(reg);
4834 	offset = BNXT_FW_STATUS_REG_OFF(reg);
4835 
4836 	switch (type) {
4837 	case BNXT_FW_STATUS_REG_TYPE_CFG:
4838 		ret = rte_pci_read_config(bp->pdev, &val, sizeof(val), offset);
4839 		if (ret < 0)
4840 			PMD_DRV_LOG_LINE(ERR, "Failed to read PCI offset %#x",
4841 				    offset);
4842 		break;
4843 	case BNXT_FW_STATUS_REG_TYPE_GRC:
4844 		offset = info->mapped_status_regs[index];
4845 		/* FALLTHROUGH */
4846 	case BNXT_FW_STATUS_REG_TYPE_BAR0:
4847 		val = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
4848 				       offset));
4849 		break;
4850 	}
4851 
4852 	return val;
4853 }
4854 
4855 static int bnxt_fw_reset_all(struct bnxt *bp)
4856 {
4857 	struct bnxt_error_recovery_info *info = bp->recovery_info;
4858 	uint32_t i;
4859 	int rc = 0;
4860 
4861 	if (info->flags & BNXT_FLAG_ERROR_RECOVERY_HOST) {
4862 		/* Reset through primary function driver */
4863 		for (i = 0; i < info->reg_array_cnt; i++)
4864 			bnxt_write_fw_reset_reg(bp, i);
4865 		/* Wait for time specified by FW after triggering reset */
4866 		rte_delay_ms(info->primary_func_wait_period_after_reset);
4867 	} else if (info->flags & BNXT_FLAG_ERROR_RECOVERY_CO_CPU) {
4868 		/* Reset with the help of Kong processor */
4869 		rc = bnxt_hwrm_fw_reset(bp);
4870 		if (rc)
4871 			PMD_DRV_LOG_LINE(ERR, "Failed to reset FW");
4872 	}
4873 
4874 	return rc;
4875 }
4876 
4877 static void bnxt_fw_reset_cb(void *arg)
4878 {
4879 	struct bnxt *bp = arg;
4880 	struct bnxt_error_recovery_info *info = bp->recovery_info;
4881 	int rc = 0;
4882 
4883 	/* Only Primary function can do FW reset */
4884 	if (bnxt_is_primary_func(bp) &&
4885 	    bnxt_is_recovery_enabled(bp)) {
4886 		rc = bnxt_fw_reset_all(bp);
4887 		if (rc) {
4888 			PMD_DRV_LOG_LINE(ERR, "Adapter recovery failed");
4889 			return;
4890 		}
4891 	}
4892 
4893 	/* if recovery method is ERROR_RECOVERY_CO_CPU, KONG will send
4894 	 * EXCEPTION_FATAL_ASYNC event to all the functions
4895 	 * (including MASTER FUNC). After receiving this Async, all the active
4896 	 * drivers should treat this case as FW initiated recovery
4897 	 */
4898 	if (info->flags & BNXT_FLAG_ERROR_RECOVERY_HOST) {
4899 		bp->fw_reset_min_msecs = BNXT_MIN_FW_READY_TIMEOUT;
4900 		bp->fw_reset_max_msecs = BNXT_MAX_FW_RESET_TIMEOUT;
4901 
4902 		/* To recover from error */
4903 		rte_eal_alarm_set(US_PER_MS, bnxt_dev_reset_and_resume,
4904 				  (void *)bp);
4905 	}
4906 }
4907 
4908 /* Driver should poll FW heartbeat, reset_counter with the frequency
4909  * advertised by FW in HWRM_ERROR_RECOVERY_QCFG.
4910  * When the driver detects heartbeat stop or change in reset_counter,
4911  * it has to trigger a reset to recover from the error condition.
4912  * A “primary function” is the function who will have the privilege to
4913  * initiate the chimp reset. The primary function will be elected by the
4914  * firmware and will be notified through async message.
4915  */
4916 static void bnxt_check_fw_health(void *arg)
4917 {
4918 	struct bnxt *bp = arg;
4919 	struct bnxt_error_recovery_info *info = bp->recovery_info;
4920 	uint32_t val = 0, wait_msec;
4921 
4922 	if (!info || !bnxt_is_recovery_enabled(bp) ||
4923 	    is_bnxt_in_error(bp))
4924 		return;
4925 
4926 	val = bnxt_read_fw_status_reg(bp, BNXT_FW_HEARTBEAT_CNT_REG);
4927 	if (val == info->last_heart_beat)
4928 		goto reset;
4929 
4930 	info->last_heart_beat = val;
4931 
4932 	val = bnxt_read_fw_status_reg(bp, BNXT_FW_RECOVERY_CNT_REG);
4933 	if (val != info->last_reset_counter)
4934 		goto reset;
4935 
4936 	info->last_reset_counter = val;
4937 
4938 	rte_eal_alarm_set(US_PER_MS * info->driver_polling_freq,
4939 			  bnxt_check_fw_health, (void *)bp);
4940 
4941 	return;
4942 reset:
4943 	/* Stop DMA to/from device */
4944 	bp->flags |= BNXT_FLAG_FATAL_ERROR;
4945 	bp->flags |= BNXT_FLAG_FW_RESET;
4946 
4947 	bnxt_stop_rxtx(bp->eth_dev);
4948 
4949 	PMD_DRV_LOG_LINE(ERR, "Detected FW dead condition");
4950 
4951 	rte_eth_dev_callback_process(bp->eth_dev,
4952 				     RTE_ETH_EVENT_ERR_RECOVERING,
4953 				     NULL);
4954 
4955 	if (bnxt_is_primary_func(bp))
4956 		wait_msec = info->primary_func_wait_period;
4957 	else
4958 		wait_msec = info->normal_func_wait_period;
4959 
4960 	rte_eal_alarm_set(US_PER_MS * wait_msec,
4961 			  bnxt_fw_reset_cb, (void *)bp);
4962 }
4963 
4964 void bnxt_schedule_fw_health_check(struct bnxt *bp)
4965 {
4966 	uint32_t polling_freq;
4967 
4968 	pthread_mutex_lock(&bp->health_check_lock);
4969 
4970 	if (!bnxt_is_recovery_enabled(bp))
4971 		goto done;
4972 
4973 	if (bp->flags & BNXT_FLAG_FW_HEALTH_CHECK_SCHEDULED)
4974 		goto done;
4975 
4976 	polling_freq = bp->recovery_info->driver_polling_freq;
4977 
4978 	rte_eal_alarm_set(US_PER_MS * polling_freq,
4979 			  bnxt_check_fw_health, (void *)bp);
4980 	bp->flags |= BNXT_FLAG_FW_HEALTH_CHECK_SCHEDULED;
4981 
4982 done:
4983 	pthread_mutex_unlock(&bp->health_check_lock);
4984 }
4985 
4986 static void bnxt_cancel_fw_health_check(struct bnxt *bp)
4987 {
4988 	rte_eal_alarm_cancel(bnxt_check_fw_health, (void *)bp);
4989 	bp->flags &= ~BNXT_FLAG_FW_HEALTH_CHECK_SCHEDULED;
4990 }
4991 
4992 static bool bnxt_vf_pciid(uint16_t device_id)
4993 {
4994 	switch (device_id) {
4995 	case BROADCOM_DEV_ID_57304_VF:
4996 	case BROADCOM_DEV_ID_57406_VF:
4997 	case BROADCOM_DEV_ID_5731X_VF:
4998 	case BROADCOM_DEV_ID_5741X_VF:
4999 	case BROADCOM_DEV_ID_57414_VF:
5000 	case BROADCOM_DEV_ID_STRATUS_NIC_VF1:
5001 	case BROADCOM_DEV_ID_STRATUS_NIC_VF2:
5002 	case BROADCOM_DEV_ID_58802_VF:
5003 	case BROADCOM_DEV_ID_57500_VF1:
5004 	case BROADCOM_DEV_ID_57500_VF2:
5005 	case BROADCOM_DEV_ID_58818_VF:
5006 	case BROADCOM_DEV_ID_5760X_VF:
5007 		/* FALLTHROUGH */
5008 		return true;
5009 	default:
5010 		return false;
5011 	}
5012 }
5013 
5014 /* Phase 5 device */
5015 static bool bnxt_p5_device(uint16_t device_id)
5016 {
5017 	switch (device_id) {
5018 	case BROADCOM_DEV_ID_57508:
5019 	case BROADCOM_DEV_ID_57504:
5020 	case BROADCOM_DEV_ID_57502:
5021 	case BROADCOM_DEV_ID_57508_MF1:
5022 	case BROADCOM_DEV_ID_57504_MF1:
5023 	case BROADCOM_DEV_ID_57502_MF1:
5024 	case BROADCOM_DEV_ID_57508_MF2:
5025 	case BROADCOM_DEV_ID_57504_MF2:
5026 	case BROADCOM_DEV_ID_57502_MF2:
5027 	case BROADCOM_DEV_ID_57500_VF1:
5028 	case BROADCOM_DEV_ID_57500_VF2:
5029 	case BROADCOM_DEV_ID_58812:
5030 	case BROADCOM_DEV_ID_58814:
5031 	case BROADCOM_DEV_ID_58818:
5032 		/* FALLTHROUGH */
5033 		return true;
5034 	default:
5035 		return false;
5036 	}
5037 }
5038 
5039 /* Phase 7 device */
5040 static bool bnxt_p7_device(uint16_t device_id)
5041 {
5042 	switch (device_id) {
5043 	case BROADCOM_DEV_ID_58818_VF:
5044 	case BROADCOM_DEV_ID_57608:
5045 	case BROADCOM_DEV_ID_57604:
5046 	case BROADCOM_DEV_ID_57602:
5047 	case BROADCOM_DEV_ID_57601:
5048 	case BROADCOM_DEV_ID_5760X_VF:
5049 		/* FALLTHROUGH */
5050 		return true;
5051 	default:
5052 		return false;
5053 	}
5054 }
5055 
5056 bool bnxt_stratus_device(struct bnxt *bp)
5057 {
5058 	uint16_t device_id = bp->pdev->id.device_id;
5059 
5060 	switch (device_id) {
5061 	case BROADCOM_DEV_ID_STRATUS_NIC:
5062 	case BROADCOM_DEV_ID_STRATUS_NIC_VF1:
5063 	case BROADCOM_DEV_ID_STRATUS_NIC_VF2:
5064 		/* FALLTHROUGH */
5065 		return true;
5066 	default:
5067 		return false;
5068 	}
5069 }
5070 
5071 static int bnxt_map_pci_bars(struct rte_eth_dev *eth_dev)
5072 {
5073 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
5074 	struct bnxt *bp = eth_dev->data->dev_private;
5075 
5076 	/* enable device (incl. PCI PM wakeup), and bus-mastering */
5077 	bp->bar0 = (void *)pci_dev->mem_resource[0].addr;
5078 	bp->doorbell_base = (void *)pci_dev->mem_resource[2].addr;
5079 	if (!bp->bar0 || !bp->doorbell_base) {
5080 		PMD_DRV_LOG_LINE(ERR, "Unable to access Hardware");
5081 		return -ENODEV;
5082 	}
5083 
5084 	bp->eth_dev = eth_dev;
5085 	bp->pdev = pci_dev;
5086 
5087 	return 0;
5088 }
5089 
5090 static void bnxt_init_ctxm_mem(struct bnxt_ctx_mem *ctxm, void *p, int len)
5091 {
5092 	uint8_t init_val = ctxm->init_value;
5093 	uint16_t offset = ctxm->init_offset;
5094 	uint8_t *p2 = p;
5095 	int i;
5096 
5097 	if (!init_val)
5098 		return;
5099 	if (offset == BNXT_CTX_INIT_INVALID_OFFSET) {
5100 		memset(p, init_val, len);
5101 		return;
5102 	}
5103 	for (i = 0; i < len; i += ctxm->entry_size)
5104 		*(p2 + i + offset) = init_val;
5105 }
5106 
5107 static int bnxt_alloc_ctx_mem_blk(struct bnxt *bp,
5108 				  struct bnxt_ctx_pg_info *ctx_pg,
5109 				  struct bnxt_ctx_mem *ctxm,
5110 				  uint32_t mem_size,
5111 				  const char *suffix,
5112 				  uint16_t idx)
5113 {
5114 	struct bnxt_ring_mem_info *rmem = &ctx_pg->ring_mem;
5115 	const struct rte_memzone *mz = NULL;
5116 	char name[RTE_MEMZONE_NAMESIZE];
5117 	rte_iova_t mz_phys_addr;
5118 	uint64_t valid_bits = 0;
5119 	uint32_t sz;
5120 	int i;
5121 
5122 	if (!mem_size)
5123 		return 0;
5124 
5125 	rmem->nr_pages =
5126 		RTE_ALIGN_MUL_CEIL(mem_size, BNXT_PAGE_SIZE) / BNXT_PAGE_SIZE;
5127 	rmem->page_size = BNXT_PAGE_SIZE;
5128 
5129 	snprintf(name, RTE_MEMZONE_NAMESIZE, "bnxt_ctx_pg_arr%s_%x_%d",
5130 		 suffix, idx, bp->eth_dev->data->port_id);
5131 	ctx_pg->ctx_pg_arr = rte_zmalloc(name, sizeof(void *) * rmem->nr_pages, 0);
5132 	if (ctx_pg->ctx_pg_arr == NULL)
5133 		return -ENOMEM;
5134 
5135 	snprintf(name, RTE_MEMZONE_NAMESIZE, "bnxt_ctx_dma_arr%s_%x_%d",
5136 		 suffix, idx, bp->eth_dev->data->port_id);
5137 	ctx_pg->ctx_dma_arr = rte_zmalloc(name, sizeof(rte_iova_t *) * rmem->nr_pages, 0);
5138 	if (ctx_pg->ctx_dma_arr == NULL)
5139 		return -ENOMEM;
5140 
5141 	rmem->pg_arr = ctx_pg->ctx_pg_arr;
5142 	rmem->dma_arr = ctx_pg->ctx_dma_arr;
5143 	rmem->flags = BNXT_RMEM_VALID_PTE_FLAG | BNXT_RMEM_USE_FULL_PAGE_FLAG;
5144 
5145 	valid_bits = PTU_PTE_VALID;
5146 
5147 	if (rmem->nr_pages > 1) {
5148 		snprintf(name, RTE_MEMZONE_NAMESIZE,
5149 			 "bnxt_ctxpgtbl%s_%x_%d",
5150 			 suffix, idx, bp->eth_dev->data->port_id);
5151 		name[RTE_MEMZONE_NAMESIZE - 1] = 0;
5152 		mz = rte_memzone_lookup(name);
5153 		if (!mz) {
5154 			mz = rte_memzone_reserve_aligned(name,
5155 						rmem->nr_pages * 8,
5156 						bp->eth_dev->device->numa_node,
5157 						RTE_MEMZONE_2MB |
5158 						RTE_MEMZONE_SIZE_HINT_ONLY,
5159 						BNXT_PAGE_SIZE);
5160 			if (mz == NULL)
5161 				return -ENOMEM;
5162 		}
5163 
5164 		memset(mz->addr, 0xff, mz->len);
5165 		mz_phys_addr = mz->iova;
5166 
5167 		if (ctxm != NULL)
5168 			bnxt_init_ctxm_mem(ctxm, mz->addr, mz->len);
5169 		rmem->pg_tbl = mz->addr;
5170 		rmem->pg_tbl_map = mz_phys_addr;
5171 		rmem->pg_tbl_mz = mz;
5172 	}
5173 
5174 	snprintf(name, RTE_MEMZONE_NAMESIZE, "bnxt_ctx_%s_%x_%d",
5175 		 suffix, idx, bp->eth_dev->data->port_id);
5176 	mz = rte_memzone_lookup(name);
5177 	if (!mz) {
5178 		mz = rte_memzone_reserve_aligned(name,
5179 						 mem_size,
5180 						 bp->eth_dev->device->numa_node,
5181 						 RTE_MEMZONE_1GB |
5182 						 RTE_MEMZONE_SIZE_HINT_ONLY,
5183 						 BNXT_PAGE_SIZE);
5184 		if (mz == NULL)
5185 			return -ENOMEM;
5186 	}
5187 
5188 	memset(mz->addr, 0xff, mz->len);
5189 	mz_phys_addr = mz->iova;
5190 
5191 	if (ctxm != NULL)
5192 		bnxt_init_ctxm_mem(ctxm, mz->addr, mz->len);
5193 	for (sz = 0, i = 0; sz < mem_size; sz += BNXT_PAGE_SIZE, i++) {
5194 		rmem->pg_arr[i] = ((char *)mz->addr) + sz;
5195 		rmem->dma_arr[i] = mz_phys_addr + sz;
5196 
5197 		if (rmem->nr_pages > 1) {
5198 			if (i == rmem->nr_pages - 2 &&
5199 			    (rmem->flags & BNXT_RMEM_RING_PTE_FLAG))
5200 				valid_bits |= PTU_PTE_NEXT_TO_LAST;
5201 			else if (i == rmem->nr_pages - 1 &&
5202 				 (rmem->flags & BNXT_RMEM_RING_PTE_FLAG))
5203 				valid_bits |= PTU_PTE_LAST;
5204 
5205 			rmem->pg_tbl[i] = rte_cpu_to_le_64(rmem->dma_arr[i] |
5206 							   valid_bits);
5207 		}
5208 	}
5209 
5210 	rmem->mz = mz;
5211 	if (rmem->vmem_size)
5212 		rmem->vmem = (void **)mz->addr;
5213 	rmem->dma_arr[0] = mz_phys_addr;
5214 	return 0;
5215 }
5216 
5217 static void bnxt_free_ctx_mem_v2(struct bnxt *bp)
5218 {
5219 	uint16_t type;
5220 
5221 	for (type = 0; type < bp->ctx->types; type++) {
5222 		struct bnxt_ctx_mem *ctxm = &bp->ctx->ctx_arr[type];
5223 		struct bnxt_ctx_pg_info *ctx_pg = ctxm->pg_info;
5224 		int i, n = 1;
5225 
5226 		if (!ctx_pg)
5227 			continue;
5228 		if (ctxm->instance_bmap)
5229 			n = hweight32(ctxm->instance_bmap);
5230 
5231 		for (i = 0; i < n; i++) {
5232 			rte_free(ctx_pg[i].ctx_pg_arr);
5233 			rte_free(ctx_pg[i].ctx_dma_arr);
5234 			rte_memzone_free(ctx_pg[i].ring_mem.mz);
5235 			rte_memzone_free(ctx_pg[i].ring_mem.pg_tbl_mz);
5236 		}
5237 
5238 		rte_free(ctx_pg);
5239 		ctxm->pg_info = NULL;
5240 	}
5241 	rte_free(bp->ctx->ctx_arr);
5242 	bp->ctx->ctx_arr = NULL;
5243 }
5244 
5245 static void bnxt_free_ctx_mem(struct bnxt *bp)
5246 {
5247 	int i;
5248 
5249 	if (!bp->ctx || !(bp->ctx->flags & BNXT_CTX_FLAG_INITED))
5250 		return;
5251 
5252 	bp->ctx->flags &= ~BNXT_CTX_FLAG_INITED;
5253 
5254 	if (BNXT_FW_BACKING_STORE_V2_EN(bp)) {
5255 		bnxt_free_ctx_mem_v2(bp);
5256 		goto free_ctx;
5257 	}
5258 
5259 	rte_free(bp->ctx->qp_mem.ctx_pg_arr);
5260 	rte_free(bp->ctx->srq_mem.ctx_pg_arr);
5261 	rte_free(bp->ctx->cq_mem.ctx_pg_arr);
5262 	rte_free(bp->ctx->vnic_mem.ctx_pg_arr);
5263 	rte_free(bp->ctx->stat_mem.ctx_pg_arr);
5264 	rte_free(bp->ctx->qp_mem.ctx_dma_arr);
5265 	rte_free(bp->ctx->srq_mem.ctx_dma_arr);
5266 	rte_free(bp->ctx->cq_mem.ctx_dma_arr);
5267 	rte_free(bp->ctx->vnic_mem.ctx_dma_arr);
5268 	rte_free(bp->ctx->stat_mem.ctx_dma_arr);
5269 
5270 	rte_memzone_free(bp->ctx->qp_mem.ring_mem.mz);
5271 	rte_memzone_free(bp->ctx->srq_mem.ring_mem.mz);
5272 	rte_memzone_free(bp->ctx->cq_mem.ring_mem.mz);
5273 	rte_memzone_free(bp->ctx->vnic_mem.ring_mem.mz);
5274 	rte_memzone_free(bp->ctx->stat_mem.ring_mem.mz);
5275 	rte_memzone_free(bp->ctx->qp_mem.ring_mem.pg_tbl_mz);
5276 	rte_memzone_free(bp->ctx->srq_mem.ring_mem.pg_tbl_mz);
5277 	rte_memzone_free(bp->ctx->cq_mem.ring_mem.pg_tbl_mz);
5278 	rte_memzone_free(bp->ctx->vnic_mem.ring_mem.pg_tbl_mz);
5279 	rte_memzone_free(bp->ctx->stat_mem.ring_mem.pg_tbl_mz);
5280 
5281 	for (i = 0; i < bp->ctx->tqm_fp_rings_count + 1; i++) {
5282 		rte_free(bp->ctx->tqm_mem[i]->ctx_pg_arr);
5283 		rte_free(bp->ctx->tqm_mem[i]->ctx_dma_arr);
5284 		if (bp->ctx->tqm_mem[i])
5285 			rte_memzone_free(bp->ctx->tqm_mem[i]->ring_mem.mz);
5286 	}
5287 
5288 free_ctx:
5289 	rte_free(bp->ctx);
5290 	bp->ctx = NULL;
5291 }
5292 
5293 #define bnxt_roundup(x, y)   ((((x) + ((y) - 1)) / (y)) * (y))
5294 
5295 #define clamp_t(type, _x, min, max) RTE_MIN_T(RTE_MAX_T(_x, min, type), max, type)
5296 
5297 int bnxt_alloc_ctx_pg_tbls(struct bnxt *bp)
5298 {
5299 	struct bnxt_ctx_mem_info *ctx = bp->ctx;
5300 	struct bnxt_ctx_mem *ctx2;
5301 	uint16_t type;
5302 	int rc = 0;
5303 
5304 	ctx2 = &ctx->ctx_arr[0];
5305 	for (type = 0; type < ctx->types && rc == 0; type++) {
5306 		struct bnxt_ctx_mem *ctxm = &ctx->ctx_arr[type];
5307 		struct bnxt_ctx_pg_info *ctx_pg;
5308 		uint32_t entries, mem_size;
5309 		int w = 1;
5310 		int i;
5311 
5312 		if (ctxm->entry_size == 0)
5313 			continue;
5314 
5315 		ctx_pg = ctxm->pg_info;
5316 
5317 		if (ctxm->instance_bmap)
5318 			w = hweight32(ctxm->instance_bmap);
5319 
5320 		for (i = 0; i < w && rc == 0; i++) {
5321 			char name[RTE_MEMZONE_NAMESIZE] = {0};
5322 
5323 			sprintf(name, "_%d_%d", i, type);
5324 
5325 			if (ctxm->entry_multiple)
5326 				entries = bnxt_roundup(ctxm->max_entries,
5327 						       ctxm->entry_multiple);
5328 			else
5329 				entries = ctxm->max_entries;
5330 
5331 			if (ctxm->type == HWRM_FUNC_BACKING_STORE_CFG_V2_INPUT_TYPE_CQ)
5332 				entries = ctxm->cq_l2_entries;
5333 			else if (ctxm->type == HWRM_FUNC_BACKING_STORE_CFG_V2_INPUT_TYPE_QP)
5334 				entries = ctxm->qp_l2_entries;
5335 			else if (ctxm->type == HWRM_FUNC_BACKING_STORE_CFG_V2_INPUT_TYPE_MRAV)
5336 				entries = ctxm->mrav_av_entries;
5337 			else if (ctxm->type == HWRM_FUNC_BACKING_STORE_CFG_V2_INPUT_TYPE_TIM)
5338 				entries = ctx2->qp_l2_entries;
5339 			entries = clamp_t(uint32_t, entries, ctxm->min_entries,
5340 					  ctxm->max_entries);
5341 			ctx_pg[i].entries = entries;
5342 			mem_size = ctxm->entry_size * entries;
5343 			PMD_DRV_LOG_LINE(DEBUG,
5344 				    "Type:0x%x instance:%d entries:%d size:%d",
5345 				    ctxm->type, i, ctx_pg[i].entries, mem_size);
5346 			rc = bnxt_alloc_ctx_mem_blk(bp, &ctx_pg[i],
5347 						    ctxm->init_value ? ctxm : NULL,
5348 						    mem_size, name, i);
5349 		}
5350 	}
5351 
5352 	return rc;
5353 }
5354 
5355 int bnxt_alloc_ctx_mem(struct bnxt *bp)
5356 {
5357 	struct bnxt_ctx_pg_info *ctx_pg;
5358 	struct bnxt_ctx_mem_info *ctx;
5359 	uint32_t mem_size, ena, entries;
5360 	int types = BNXT_CTX_MIN;
5361 	uint32_t entries_sp, min;
5362 	int i, rc = 0;
5363 
5364 	if (!BNXT_FW_BACKING_STORE_V1_EN(bp) &&
5365 	    !BNXT_FW_BACKING_STORE_V2_EN(bp))
5366 		return rc;
5367 
5368 	if (BNXT_FW_BACKING_STORE_V2_EN(bp)) {
5369 		types = bnxt_hwrm_func_backing_store_types_count(bp);
5370 		if (types <= 0)
5371 			return types;
5372 	}
5373 
5374 	rc = bnxt_hwrm_func_backing_store_ctx_alloc(bp, types);
5375 	if (rc != 0)
5376 		return rc;
5377 
5378 	if (bp->ctx->flags & BNXT_CTX_FLAG_INITED)
5379 		return 0;
5380 
5381 	ctx = bp->ctx;
5382 	if (BNXT_FW_BACKING_STORE_V2_EN(bp)) {
5383 		rc = bnxt_hwrm_func_backing_store_qcaps_v2(bp);
5384 
5385 		for (i = 0 ; i < bp->ctx->types && rc == 0; i++) {
5386 			struct bnxt_ctx_mem *ctxm = &ctx->ctx_arr[i];
5387 
5388 			rc = bnxt_hwrm_func_backing_store_cfg_v2(bp, ctxm);
5389 		}
5390 		goto done;
5391 	}
5392 
5393 	rc = bnxt_hwrm_func_backing_store_qcaps(bp);
5394 	if (rc) {
5395 		PMD_DRV_LOG_LINE(ERR, "Query context mem capability failed");
5396 		return rc;
5397 	}
5398 
5399 	ctx_pg = &ctx->qp_mem;
5400 	ctx_pg->entries = ctx->qp_min_qp1_entries + ctx->qp_max_l2_entries;
5401 	if (ctx->qp_entry_size) {
5402 		mem_size = ctx->qp_entry_size * ctx_pg->entries;
5403 		rc = bnxt_alloc_ctx_mem_blk(bp, ctx_pg, NULL, mem_size, "qp_mem", 0);
5404 		if (rc)
5405 			return rc;
5406 	}
5407 
5408 	ctx_pg = &ctx->srq_mem;
5409 	ctx_pg->entries = ctx->srq_max_l2_entries;
5410 	if (ctx->srq_entry_size) {
5411 		mem_size = ctx->srq_entry_size * ctx_pg->entries;
5412 		rc = bnxt_alloc_ctx_mem_blk(bp, ctx_pg, NULL, mem_size, "srq_mem", 0);
5413 		if (rc)
5414 			return rc;
5415 	}
5416 
5417 	ctx_pg = &ctx->cq_mem;
5418 	ctx_pg->entries = ctx->cq_max_l2_entries;
5419 	if (ctx->cq_entry_size) {
5420 		mem_size = ctx->cq_entry_size * ctx_pg->entries;
5421 		rc = bnxt_alloc_ctx_mem_blk(bp, ctx_pg, NULL, mem_size, "cq_mem", 0);
5422 		if (rc)
5423 			return rc;
5424 	}
5425 
5426 	ctx_pg = &ctx->vnic_mem;
5427 	ctx_pg->entries = ctx->vnic_max_vnic_entries +
5428 		ctx->vnic_max_ring_table_entries;
5429 	if (ctx->vnic_entry_size) {
5430 		mem_size = ctx->vnic_entry_size * ctx_pg->entries;
5431 		rc = bnxt_alloc_ctx_mem_blk(bp, ctx_pg, NULL, mem_size, "vnic_mem", 0);
5432 		if (rc)
5433 			return rc;
5434 	}
5435 
5436 	ctx_pg = &ctx->stat_mem;
5437 	ctx_pg->entries = ctx->stat_max_entries;
5438 	if (ctx->stat_entry_size) {
5439 		mem_size = ctx->stat_entry_size * ctx_pg->entries;
5440 		rc = bnxt_alloc_ctx_mem_blk(bp, ctx_pg, NULL, mem_size, "stat_mem", 0);
5441 		if (rc)
5442 			return rc;
5443 	}
5444 
5445 	min = ctx->tqm_min_entries_per_ring;
5446 
5447 	entries_sp = ctx->qp_max_l2_entries +
5448 		     ctx->vnic_max_vnic_entries +
5449 		     2 * ctx->qp_min_qp1_entries + min;
5450 	entries_sp = bnxt_roundup(entries_sp, ctx->tqm_entries_multiple);
5451 
5452 	entries = ctx->qp_max_l2_entries + ctx->qp_min_qp1_entries;
5453 	entries = bnxt_roundup(entries, ctx->tqm_entries_multiple);
5454 	entries = clamp_t(uint32_t, entries, min,
5455 			  ctx->tqm_max_entries_per_ring);
5456 	for (i = 0, ena = 0; i < ctx->tqm_fp_rings_count + 1; i++) {
5457 		/* i=0 is for TQM_SP. i=1 to i=8 applies to RING0 to RING7.
5458 		 * i > 8 is other ext rings.
5459 		 */
5460 		ctx_pg = ctx->tqm_mem[i];
5461 		ctx_pg->entries = i ? entries : entries_sp;
5462 		if (ctx->tqm_entry_size) {
5463 			mem_size = ctx->tqm_entry_size * ctx_pg->entries;
5464 			rc = bnxt_alloc_ctx_mem_blk(bp, ctx_pg, NULL,
5465 						    mem_size, "tqm_mem", i);
5466 			if (rc)
5467 				return rc;
5468 		}
5469 		if (i < BNXT_MAX_TQM_LEGACY_RINGS)
5470 			ena |= HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_TQM_SP << i;
5471 		else
5472 			ena |= HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_TQM_RING8;
5473 	}
5474 
5475 	ena |= FUNC_BACKING_STORE_CFG_INPUT_DFLT_ENABLES;
5476 	rc = bnxt_hwrm_func_backing_store_cfg(bp, ena);
5477 done:
5478 	if (rc)
5479 		PMD_DRV_LOG_LINE(ERR,
5480 			    "Failed to configure context mem: rc = %d", rc);
5481 	else
5482 		ctx->flags |= BNXT_CTX_FLAG_INITED;
5483 
5484 	return rc;
5485 }
5486 
5487 static int bnxt_alloc_stats_mem(struct bnxt *bp)
5488 {
5489 	struct rte_pci_device *pci_dev = bp->pdev;
5490 	char mz_name[RTE_MEMZONE_NAMESIZE];
5491 	const struct rte_memzone *mz = NULL;
5492 	uint32_t total_alloc_len;
5493 	rte_iova_t mz_phys_addr;
5494 
5495 	if (pci_dev->id.device_id == BROADCOM_DEV_ID_NS2)
5496 		return 0;
5497 
5498 	snprintf(mz_name, RTE_MEMZONE_NAMESIZE,
5499 		 "bnxt_" PCI_PRI_FMT "-%s", pci_dev->addr.domain,
5500 		 pci_dev->addr.bus, pci_dev->addr.devid,
5501 		 pci_dev->addr.function, "rx_port_stats");
5502 	mz_name[RTE_MEMZONE_NAMESIZE - 1] = 0;
5503 	mz = rte_memzone_lookup(mz_name);
5504 	total_alloc_len =
5505 		RTE_CACHE_LINE_ROUNDUP(sizeof(struct rx_port_stats) +
5506 				       sizeof(struct rx_port_stats_ext) + 512);
5507 	if (!mz) {
5508 		mz = rte_memzone_reserve(mz_name, total_alloc_len,
5509 					 SOCKET_ID_ANY,
5510 					 RTE_MEMZONE_2MB |
5511 					 RTE_MEMZONE_SIZE_HINT_ONLY |
5512 					 RTE_MEMZONE_IOVA_CONTIG);
5513 		if (mz == NULL)
5514 			return -ENOMEM;
5515 	}
5516 	memset(mz->addr, 0, mz->len);
5517 	mz_phys_addr = mz->iova;
5518 
5519 	bp->rx_mem_zone = (const void *)mz;
5520 	bp->hw_rx_port_stats = mz->addr;
5521 	bp->hw_rx_port_stats_map = mz_phys_addr;
5522 
5523 	snprintf(mz_name, RTE_MEMZONE_NAMESIZE,
5524 		 "bnxt_" PCI_PRI_FMT "-%s", pci_dev->addr.domain,
5525 		 pci_dev->addr.bus, pci_dev->addr.devid,
5526 		 pci_dev->addr.function, "tx_port_stats");
5527 	mz_name[RTE_MEMZONE_NAMESIZE - 1] = 0;
5528 	mz = rte_memzone_lookup(mz_name);
5529 	total_alloc_len =
5530 		RTE_CACHE_LINE_ROUNDUP(sizeof(struct tx_port_stats) +
5531 				       sizeof(struct tx_port_stats_ext) + 512);
5532 	if (!mz) {
5533 		mz = rte_memzone_reserve(mz_name,
5534 					 total_alloc_len,
5535 					 SOCKET_ID_ANY,
5536 					 RTE_MEMZONE_2MB |
5537 					 RTE_MEMZONE_SIZE_HINT_ONLY |
5538 					 RTE_MEMZONE_IOVA_CONTIG);
5539 		if (mz == NULL)
5540 			return -ENOMEM;
5541 	}
5542 	memset(mz->addr, 0, mz->len);
5543 	mz_phys_addr = mz->iova;
5544 
5545 	bp->tx_mem_zone = (const void *)mz;
5546 	bp->hw_tx_port_stats = mz->addr;
5547 	bp->hw_tx_port_stats_map = mz_phys_addr;
5548 	bp->flags |= BNXT_FLAG_PORT_STATS;
5549 
5550 	/* Display extended statistics if FW supports it */
5551 	if (bp->hwrm_spec_code < HWRM_SPEC_CODE_1_8_4 ||
5552 	    bp->hwrm_spec_code == HWRM_SPEC_CODE_1_9_0 ||
5553 	    !(bp->flags & BNXT_FLAG_EXT_STATS_SUPPORTED))
5554 		return 0;
5555 
5556 	bp->hw_rx_port_stats_ext = (void *)
5557 		((uint8_t *)bp->hw_rx_port_stats +
5558 		 sizeof(struct rx_port_stats));
5559 	bp->hw_rx_port_stats_ext_map = bp->hw_rx_port_stats_map +
5560 		sizeof(struct rx_port_stats);
5561 	bp->flags |= BNXT_FLAG_EXT_RX_PORT_STATS;
5562 
5563 	if (bp->hwrm_spec_code < HWRM_SPEC_CODE_1_9_2 ||
5564 	    bp->flags & BNXT_FLAG_EXT_STATS_SUPPORTED) {
5565 		bp->hw_tx_port_stats_ext = (void *)
5566 			((uint8_t *)bp->hw_tx_port_stats +
5567 			 sizeof(struct tx_port_stats));
5568 		bp->hw_tx_port_stats_ext_map =
5569 			bp->hw_tx_port_stats_map +
5570 			sizeof(struct tx_port_stats);
5571 		bp->flags |= BNXT_FLAG_EXT_TX_PORT_STATS;
5572 	}
5573 
5574 	return 0;
5575 }
5576 
5577 static int bnxt_setup_mac_addr(struct rte_eth_dev *eth_dev)
5578 {
5579 	struct bnxt *bp = eth_dev->data->dev_private;
5580 	size_t max_mac_addr = RTE_MIN(bp->max_l2_ctx, RTE_ETH_NUM_RECEIVE_MAC_ADDR);
5581 	int rc = 0;
5582 
5583 	if (bp->max_l2_ctx > RTE_ETH_NUM_RECEIVE_MAC_ADDR)
5584 		PMD_DRV_LOG_LINE(INFO, "Max number of MAC addrs supported is %d, but will be limited to %d",
5585 			    bp->max_l2_ctx, RTE_ETH_NUM_RECEIVE_MAC_ADDR);
5586 
5587 	eth_dev->data->mac_addrs = rte_zmalloc("bnxt_mac_addr_tbl",
5588 					       RTE_ETHER_ADDR_LEN * max_mac_addr,
5589 					       0);
5590 	if (eth_dev->data->mac_addrs == NULL) {
5591 		PMD_DRV_LOG_LINE(ERR, "Failed to alloc MAC addr tbl");
5592 		return -ENOMEM;
5593 	}
5594 
5595 	if (!BNXT_HAS_DFLT_MAC_SET(bp)) {
5596 		if (BNXT_PF(bp))
5597 			return -EINVAL;
5598 
5599 		/* Generate a random MAC address, if none was assigned by PF */
5600 		PMD_DRV_LOG_LINE(INFO, "VF MAC address not assigned by Host PF");
5601 		bnxt_eth_hw_addr_random(bp->mac_addr);
5602 		PMD_DRV_LOG_LINE(INFO,
5603 			    "Assign random MAC:" RTE_ETHER_ADDR_PRT_FMT,
5604 			    bp->mac_addr[0], bp->mac_addr[1], bp->mac_addr[2],
5605 			    bp->mac_addr[3], bp->mac_addr[4], bp->mac_addr[5]);
5606 
5607 		rc = bnxt_hwrm_set_mac(bp);
5608 		if (rc)
5609 			return rc;
5610 	}
5611 
5612 	/* Copy the permanent MAC from the FUNC_QCAPS response */
5613 	memcpy(&eth_dev->data->mac_addrs[0], bp->mac_addr, RTE_ETHER_ADDR_LEN);
5614 
5615 	/*
5616 	 *  Allocate memory to hold multicast mac addresses added.
5617 	 *  Used to restore them during reset recovery
5618 	 */
5619 	bp->mcast_addr_list = rte_zmalloc("bnxt_mcast_addr_tbl",
5620 					  sizeof(struct rte_ether_addr) *
5621 					  BNXT_MAX_MC_ADDRS, 0);
5622 	if (bp->mcast_addr_list == NULL) {
5623 		PMD_DRV_LOG_LINE(ERR, "Failed to allocate multicast addr table");
5624 		return -ENOMEM;
5625 	}
5626 	bp->mc_list_dma_addr = rte_malloc_virt2iova(bp->mcast_addr_list);
5627 	if (bp->mc_list_dma_addr == RTE_BAD_IOVA) {
5628 		PMD_DRV_LOG_LINE(ERR, "Fail to map mcast_addr_list to physical memory");
5629 		return -ENOMEM;
5630 	}
5631 
5632 	return rc;
5633 }
5634 
5635 static int bnxt_restore_dflt_mac(struct bnxt *bp)
5636 {
5637 	int rc = 0;
5638 
5639 	/* MAC is already configured in FW */
5640 	if (BNXT_HAS_DFLT_MAC_SET(bp))
5641 		return 0;
5642 
5643 	/* Restore the old MAC configured */
5644 	rc = bnxt_hwrm_set_mac(bp);
5645 	if (rc)
5646 		PMD_DRV_LOG_LINE(ERR, "Failed to restore MAC address");
5647 
5648 	return rc;
5649 }
5650 
5651 static void bnxt_config_vf_req_fwd(struct bnxt *bp)
5652 {
5653 	if (!BNXT_PF(bp))
5654 		return;
5655 
5656 	memset(bp->pf->vf_req_fwd, 0, sizeof(bp->pf->vf_req_fwd));
5657 
5658 	if (!(bp->fw_cap & BNXT_FW_CAP_LINK_ADMIN))
5659 		BNXT_HWRM_CMD_TO_FORWARD(HWRM_PORT_PHY_QCFG);
5660 	BNXT_HWRM_CMD_TO_FORWARD(HWRM_FUNC_CFG);
5661 	BNXT_HWRM_CMD_TO_FORWARD(HWRM_FUNC_VF_CFG);
5662 	BNXT_HWRM_CMD_TO_FORWARD(HWRM_CFA_L2_FILTER_ALLOC);
5663 	BNXT_HWRM_CMD_TO_FORWARD(HWRM_OEM_CMD);
5664 }
5665 
5666 static void bnxt_alloc_error_recovery_info(struct bnxt *bp)
5667 {
5668 	struct bnxt_error_recovery_info *info = bp->recovery_info;
5669 
5670 	if (info) {
5671 		if (!(bp->fw_cap & BNXT_FW_CAP_HCOMM_FW_STATUS))
5672 			memset(info, 0, sizeof(*info));
5673 		return;
5674 	}
5675 
5676 	if (!(bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY))
5677 		return;
5678 
5679 	info = rte_zmalloc("bnxt_hwrm_error_recovery_qcfg",
5680 			   sizeof(*info), 0);
5681 	if (!info)
5682 		bp->fw_cap &= ~BNXT_FW_CAP_ERROR_RECOVERY;
5683 
5684 	bp->recovery_info = info;
5685 }
5686 
5687 static void bnxt_check_fw_status(struct bnxt *bp)
5688 {
5689 	uint32_t fw_status;
5690 
5691 	if (!(bp->recovery_info &&
5692 	      (bp->fw_cap & BNXT_FW_CAP_HCOMM_FW_STATUS)))
5693 		return;
5694 
5695 	fw_status = bnxt_read_fw_status_reg(bp, BNXT_FW_STATUS_REG);
5696 	if (fw_status != BNXT_FW_STATUS_HEALTHY)
5697 		PMD_DRV_LOG_LINE(ERR, "Firmware not responding, status: %#x",
5698 			    fw_status);
5699 }
5700 
5701 static int bnxt_map_hcomm_fw_status_reg(struct bnxt *bp)
5702 {
5703 	struct bnxt_error_recovery_info *info = bp->recovery_info;
5704 	uint32_t status_loc;
5705 	uint32_t sig_ver;
5706 
5707 	rte_write32(HCOMM_STATUS_STRUCT_LOC, (uint8_t *)bp->bar0 +
5708 		    BNXT_GRCPF_REG_WINDOW_BASE_OUT + 4);
5709 	sig_ver = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
5710 				   BNXT_GRCP_WINDOW_2_BASE +
5711 				   offsetof(struct hcomm_status,
5712 					    sig_ver)));
5713 	/* If the signature is absent, then FW does not support this feature */
5714 	if ((sig_ver & HCOMM_STATUS_SIGNATURE_MASK) !=
5715 	    HCOMM_STATUS_SIGNATURE_VAL)
5716 		return 0;
5717 
5718 	if (!info) {
5719 		info = rte_zmalloc("bnxt_hwrm_error_recovery_qcfg",
5720 				   sizeof(*info), 0);
5721 		if (!info)
5722 			return -ENOMEM;
5723 		bp->recovery_info = info;
5724 	} else {
5725 		memset(info, 0, sizeof(*info));
5726 	}
5727 
5728 	status_loc = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
5729 				      BNXT_GRCP_WINDOW_2_BASE +
5730 				      offsetof(struct hcomm_status,
5731 					       fw_status_loc)));
5732 
5733 	/* Only pre-map the FW health status GRC register */
5734 	if (BNXT_FW_STATUS_REG_TYPE(status_loc) != BNXT_FW_STATUS_REG_TYPE_GRC)
5735 		return 0;
5736 
5737 	info->status_regs[BNXT_FW_STATUS_REG] = status_loc;
5738 	info->mapped_status_regs[BNXT_FW_STATUS_REG] =
5739 		BNXT_GRCP_WINDOW_2_BASE + (status_loc & BNXT_GRCP_OFFSET_MASK);
5740 
5741 	rte_write32((status_loc & BNXT_GRCP_BASE_MASK), (uint8_t *)bp->bar0 +
5742 		    BNXT_GRCPF_REG_WINDOW_BASE_OUT + 4);
5743 
5744 	bp->fw_cap |= BNXT_FW_CAP_HCOMM_FW_STATUS;
5745 
5746 	return 0;
5747 }
5748 
5749 /* This function gets the FW version along with the
5750  * capabilities(MAX and current) of the function, vnic,
5751  * error recovery, phy and other chip related info
5752  */
5753 static int bnxt_get_config(struct bnxt *bp)
5754 {
5755 	uint16_t mtu;
5756 	int timeout;
5757 	int rc = 0;
5758 
5759 	bp->fw_cap = 0;
5760 
5761 	rc = bnxt_map_hcomm_fw_status_reg(bp);
5762 	if (rc)
5763 		return rc;
5764 
5765 	timeout = BNXT_CHIP_P7(bp) ?
5766 		  PCI_FUNC_RESET_WAIT_TIMEOUT :
5767 		  DFLT_HWRM_CMD_TIMEOUT;
5768 try_again:
5769 	rc = bnxt_hwrm_ver_get(bp, timeout);
5770 	if (rc) {
5771 		if (rc == -ETIMEDOUT && timeout == PCI_FUNC_RESET_WAIT_TIMEOUT) {
5772 			bp->flags &= ~BNXT_FLAG_FW_TIMEDOUT;
5773 			timeout = DFLT_HWRM_CMD_TIMEOUT;
5774 			goto try_again;
5775 		}
5776 		bnxt_check_fw_status(bp);
5777 		return rc;
5778 	}
5779 
5780 	rc = bnxt_hwrm_func_reset(bp);
5781 	if (rc)
5782 		return -EIO;
5783 
5784 	rc = bnxt_hwrm_vnic_qcaps(bp);
5785 	if (rc)
5786 		return rc;
5787 
5788 	rc = bnxt_hwrm_queue_qportcfg(bp);
5789 	if (rc)
5790 		return rc;
5791 
5792 	/* Get the MAX capabilities for this function.
5793 	 * This function also allocates context memory for TQM rings and
5794 	 * informs the firmware about this allocated backing store memory.
5795 	 */
5796 	rc = bnxt_hwrm_func_qcaps(bp);
5797 	if (rc)
5798 		return rc;
5799 
5800 	rc = bnxt_hwrm_func_qcfg(bp, &mtu);
5801 	if (rc)
5802 		return rc;
5803 
5804 	bnxt_hwrm_port_mac_qcfg(bp);
5805 
5806 	bnxt_hwrm_parent_pf_qcfg(bp);
5807 
5808 	bnxt_hwrm_port_phy_qcaps(bp);
5809 
5810 	bnxt_alloc_error_recovery_info(bp);
5811 	/* Get the adapter error recovery support info */
5812 	rc = bnxt_hwrm_error_recovery_qcfg(bp);
5813 	if (rc)
5814 		bp->fw_cap &= ~BNXT_FW_CAP_ERROR_RECOVERY;
5815 
5816 	bnxt_hwrm_port_led_qcaps(bp);
5817 
5818 	return 0;
5819 }
5820 
5821 static int
5822 bnxt_init_locks(struct bnxt *bp)
5823 {
5824 	pthread_mutex_init(&bp->flow_lock, NULL);
5825 	pthread_mutex_init(&bp->def_cp_lock, NULL);
5826 	pthread_mutex_init(&bp->health_check_lock, NULL);
5827 	pthread_mutex_init(&bp->err_recovery_lock, NULL);
5828 
5829 	return 0;
5830 }
5831 
5832 /* This should be called after we have queried trusted VF cap */
5833 static int bnxt_alloc_switch_domain(struct bnxt *bp)
5834 {
5835 	int rc = 0;
5836 
5837 	if (BNXT_PF(bp) || BNXT_VF_IS_TRUSTED(bp)) {
5838 		rc = rte_eth_switch_domain_alloc(&bp->switch_domain_id);
5839 		if (rc)
5840 			PMD_DRV_LOG_LINE(ERR,
5841 				    "Failed to alloc switch domain: %d", rc);
5842 		else
5843 			PMD_DRV_LOG_LINE(INFO,
5844 				    "Switch domain allocated %d",
5845 				    bp->switch_domain_id);
5846 	}
5847 
5848 	return rc;
5849 }
5850 
5851 static int bnxt_init_resources(struct bnxt *bp, bool reconfig_dev)
5852 {
5853 	int rc = 0;
5854 
5855 	if (reconfig_dev) {
5856 		rc = bnxt_get_config(bp);
5857 		if (rc)
5858 			return rc;
5859 	}
5860 
5861 	rc = bnxt_alloc_switch_domain(bp);
5862 	if (rc)
5863 		return rc;
5864 
5865 	if (!reconfig_dev) {
5866 		rc = bnxt_setup_mac_addr(bp->eth_dev);
5867 		if (rc)
5868 			return rc;
5869 	} else {
5870 		rc = bnxt_restore_dflt_mac(bp);
5871 		if (rc)
5872 			return rc;
5873 	}
5874 
5875 	bnxt_config_vf_req_fwd(bp);
5876 
5877 	rc = bnxt_hwrm_func_driver_register(bp);
5878 	if (rc) {
5879 		PMD_DRV_LOG_LINE(ERR, "Failed to register driver");
5880 		return -EBUSY;
5881 	}
5882 
5883 	if (BNXT_PF(bp)) {
5884 		if (bp->pdev->max_vfs) {
5885 			rc = bnxt_hwrm_allocate_vfs(bp, bp->pdev->max_vfs);
5886 			if (rc) {
5887 				PMD_DRV_LOG_LINE(ERR, "Failed to allocate VFs");
5888 				return rc;
5889 			}
5890 		} else {
5891 			rc = bnxt_hwrm_allocate_pf_only(bp);
5892 			if (rc) {
5893 				PMD_DRV_LOG_LINE(ERR,
5894 					    "Failed to allocate PF resources");
5895 				return rc;
5896 			}
5897 		}
5898 	}
5899 
5900 	if (!reconfig_dev) {
5901 		bp->rss_conf.rss_key = rte_zmalloc("bnxt_rss_key",
5902 						   HW_HASH_KEY_SIZE, 0);
5903 		if (bp->rss_conf.rss_key == NULL) {
5904 			PMD_DRV_LOG_LINE(ERR, "port %u cannot allocate RSS hash key memory",
5905 				    bp->eth_dev->data->port_id);
5906 			return -ENOMEM;
5907 		}
5908 	}
5909 
5910 	rc = bnxt_alloc_mem(bp, reconfig_dev);
5911 	if (rc)
5912 		return rc;
5913 
5914 	rc = bnxt_setup_int(bp);
5915 	if (rc)
5916 		return rc;
5917 
5918 	rc = bnxt_request_int(bp);
5919 	if (rc)
5920 		return rc;
5921 
5922 	rc = bnxt_init_ctx_mem(bp);
5923 	if (rc) {
5924 		PMD_DRV_LOG_LINE(ERR, "Failed to init adv_flow_counters");
5925 		return rc;
5926 	}
5927 
5928 	return 0;
5929 }
5930 
5931 static int
5932 bnxt_parse_devarg_flow_xstat(__rte_unused const char *key,
5933 			     const char *value, void *opaque_arg)
5934 {
5935 	struct bnxt *bp = opaque_arg;
5936 	unsigned long flow_xstat;
5937 	char *end = NULL;
5938 
5939 	if (!value || !opaque_arg) {
5940 		PMD_DRV_LOG_LINE(ERR,
5941 			    "Invalid parameter passed to flow_xstat devarg.");
5942 		return -EINVAL;
5943 	}
5944 
5945 	flow_xstat = strtoul(value, &end, 10);
5946 	if (end == NULL || *end != '\0' ||
5947 	    (flow_xstat == ULONG_MAX && errno == ERANGE)) {
5948 		PMD_DRV_LOG_LINE(ERR,
5949 			    "Invalid parameter passed to flow_xstat devarg.");
5950 		return -EINVAL;
5951 	}
5952 
5953 	if (BNXT_DEVARG_FLOW_XSTAT_INVALID(flow_xstat)) {
5954 		PMD_DRV_LOG_LINE(ERR,
5955 			    "Invalid value passed to flow_xstat devarg.");
5956 		return -EINVAL;
5957 	}
5958 
5959 	bp->flags |= BNXT_FLAG_FLOW_XSTATS_EN;
5960 	if (BNXT_FLOW_XSTATS_EN(bp))
5961 		PMD_DRV_LOG_LINE(INFO, "flow_xstat feature enabled.");
5962 
5963 	return 0;
5964 }
5965 
5966 static int
5967 bnxt_parse_devarg_max_num_kflows(__rte_unused const char *key,
5968 					const char *value, void *opaque_arg)
5969 {
5970 	struct bnxt *bp = opaque_arg;
5971 	unsigned long max_num_kflows;
5972 	char *end = NULL;
5973 
5974 	if (!value || !opaque_arg) {
5975 		PMD_DRV_LOG_LINE(ERR,
5976 			"Invalid parameter passed to max_num_kflows devarg.");
5977 		return -EINVAL;
5978 	}
5979 
5980 	max_num_kflows = strtoul(value, &end, 10);
5981 	if (end == NULL || *end != '\0' ||
5982 		(max_num_kflows == ULONG_MAX && errno == ERANGE)) {
5983 		PMD_DRV_LOG_LINE(ERR,
5984 			"Invalid parameter passed to max_num_kflows devarg.");
5985 		return -EINVAL;
5986 	}
5987 
5988 	if (bnxt_devarg_max_num_kflow_invalid(max_num_kflows)) {
5989 		PMD_DRV_LOG_LINE(ERR,
5990 			"Invalid value passed to max_num_kflows devarg.");
5991 		return -EINVAL;
5992 	}
5993 
5994 	bp->max_num_kflows = max_num_kflows;
5995 	if (bp->max_num_kflows)
5996 		PMD_DRV_LOG_LINE(INFO, "max_num_kflows set as %ldK.",
5997 				max_num_kflows);
5998 
5999 	return 0;
6000 }
6001 
6002 static int
6003 bnxt_parse_devarg_cqe_mode(__rte_unused const char *key,
6004 			   const char *value, void *opaque_arg)
6005 {
6006 	struct bnxt *bp = opaque_arg;
6007 	unsigned long cqe_mode;
6008 	char *end = NULL;
6009 
6010 	if (!value || !opaque_arg) {
6011 		PMD_DRV_LOG_LINE(ERR,
6012 			    "Invalid parameter passed to cqe-mode "
6013 			    "devargs.");
6014 		return -EINVAL;
6015 	}
6016 
6017 	cqe_mode = strtoul(value, &end, 10);
6018 	if (end == NULL || *end != '\0' ||
6019 	    (cqe_mode == ULONG_MAX && errno == ERANGE)) {
6020 		PMD_DRV_LOG_LINE(ERR,
6021 			    "Invalid parameter passed to cqe-mode "
6022 			    "devargs.");
6023 		return -EINVAL;
6024 	}
6025 
6026 	if (BNXT_DEVARG_CQE_MODE_INVALID(cqe_mode)) {
6027 		PMD_DRV_LOG_LINE(ERR, "Invalid cqe-mode(%d) devargs.",
6028 			    (uint16_t)cqe_mode);
6029 		return -EINVAL;
6030 	}
6031 
6032 	if (cqe_mode == 1)
6033 		bp->flags2 |= BNXT_FLAGS2_COMPRESSED_RX_CQE;
6034 	PMD_DRV_LOG_LINE(INFO, "cqe-mode=%d feature enabled.", (uint8_t)cqe_mode);
6035 
6036 	return 0;
6037 }
6038 
6039 static int
6040 bnxt_parse_devarg_app_id(__rte_unused const char *key,
6041 				 const char *value, void *opaque_arg)
6042 {
6043 	struct bnxt *bp = opaque_arg;
6044 	unsigned long app_id;
6045 	char *end = NULL;
6046 
6047 	if (!value || !opaque_arg) {
6048 		PMD_DRV_LOG_LINE(ERR,
6049 			    "Invalid parameter passed to app-id "
6050 			    "devargs.");
6051 		return -EINVAL;
6052 	}
6053 
6054 	app_id = strtoul(value, &end, 10);
6055 	if (end == NULL || *end != '\0' ||
6056 	    (app_id == ULONG_MAX && errno == ERANGE)) {
6057 		PMD_DRV_LOG_LINE(ERR,
6058 			    "Invalid parameter passed to app_id "
6059 			    "devargs.");
6060 		return -EINVAL;
6061 	}
6062 
6063 	if (BNXT_DEVARG_APP_ID_INVALID(app_id)) {
6064 		PMD_DRV_LOG_LINE(ERR, "Invalid app-id(%d) devargs.",
6065 			    (uint16_t)app_id);
6066 		return -EINVAL;
6067 	}
6068 
6069 	bp->app_id = app_id;
6070 	PMD_DRV_LOG_LINE(INFO, "app-id=%d feature enabled.", (uint16_t)app_id);
6071 
6072 	return 0;
6073 }
6074 
6075 static int
6076 bnxt_parse_devarg_mpc(__rte_unused const char *key,
6077 		      const char *value, __rte_unused void *opaque_arg)
6078 {
6079 	char *end = NULL;
6080 
6081 	if (!value || !opaque_arg) {
6082 		PMD_DRV_LOG_LINE(ERR,
6083 				 "Invalid parameter passed to app-id "
6084 				 "devargs");
6085 		return -EINVAL;
6086 	}
6087 
6088 	mpc = strtoul(value, &end, 10);
6089 	if (end == NULL || *end != '\0' ||
6090 	    (mpc == ULONG_MAX && errno == ERANGE)) {
6091 		PMD_DRV_LOG_LINE(ERR, "Invalid parameter passed to mpc "
6092 				 "devargs");
6093 		return -EINVAL;
6094 	}
6095 
6096 	if (BNXT_DEVARG_MPC_INVALID(mpc)) {
6097 		PMD_DRV_LOG_LINE(ERR, "Invalid mpc(%d) devargs",
6098 				 (uint16_t)mpc);
6099 		return -EINVAL;
6100 	}
6101 
6102 	PMD_DRV_LOG_LINE(INFO, "MPC%d feature enabled", (uint16_t)mpc);
6103 	return 0;
6104 }
6105 
6106 static int
6107 bnxt_parse_devarg_ieee_1588(__rte_unused const char *key,
6108 			    const char *value, void *opaque_arg)
6109 {
6110 	struct bnxt *bp = opaque_arg;
6111 	unsigned long ieee_1588;
6112 	char *end = NULL;
6113 
6114 	if (!value || !opaque_arg) {
6115 		PMD_DRV_LOG_LINE(ERR,
6116 			    "Invalid parameter passed to ieee-1588 "
6117 			    "devargs.");
6118 		return -EINVAL;
6119 	}
6120 
6121 	ieee_1588 = strtoul(value, &end, 10);
6122 	if (end == NULL || *end != '\0' ||
6123 	    (ieee_1588 == ULONG_MAX && errno == ERANGE)) {
6124 		PMD_DRV_LOG_LINE(ERR,
6125 			    "Invalid parameter passed to ieee_1588 "
6126 			    "devargs.");
6127 		return -EINVAL;
6128 	}
6129 
6130 	if (BNXT_DEVARG_IEEE_1588_INVALID(ieee_1588)) {
6131 		PMD_DRV_LOG_LINE(ERR, "Invalid ieee-1588(%d) devargs.",
6132 			    (uint16_t)ieee_1588);
6133 		return -EINVAL;
6134 	}
6135 
6136 	bp->ieee_1588 = ieee_1588;
6137 	PMD_DRV_LOG_LINE(INFO, "ieee-1588=%d feature enabled.", (uint16_t)ieee_1588);
6138 
6139 	return 0;
6140 }
6141 
6142 static int
6143 bnxt_parse_devarg_rep_is_pf(__rte_unused const char *key,
6144 			    const char *value, void *opaque_arg)
6145 {
6146 	struct bnxt_representor *vfr_bp = opaque_arg;
6147 	unsigned long rep_is_pf;
6148 	char *end = NULL;
6149 
6150 	if (!value || !opaque_arg) {
6151 		PMD_DRV_LOG_LINE(ERR,
6152 			    "Invalid parameter passed to rep_is_pf devargs.");
6153 		return -EINVAL;
6154 	}
6155 
6156 	rep_is_pf = strtoul(value, &end, 10);
6157 	if (end == NULL || *end != '\0' ||
6158 	    (rep_is_pf == ULONG_MAX && errno == ERANGE)) {
6159 		PMD_DRV_LOG_LINE(ERR,
6160 			    "Invalid parameter passed to rep_is_pf devargs.");
6161 		return -EINVAL;
6162 	}
6163 
6164 	if (BNXT_DEVARG_REP_IS_PF_INVALID(rep_is_pf)) {
6165 		PMD_DRV_LOG_LINE(ERR,
6166 			    "Invalid value passed to rep_is_pf devargs.");
6167 		return -EINVAL;
6168 	}
6169 
6170 	vfr_bp->flags |= rep_is_pf;
6171 	if (BNXT_REP_PF(vfr_bp))
6172 		PMD_DRV_LOG_LINE(INFO, "PF representor");
6173 	else
6174 		PMD_DRV_LOG_LINE(INFO, "VF representor");
6175 
6176 	return 0;
6177 }
6178 
6179 static int
6180 bnxt_parse_devarg_rep_based_pf(__rte_unused const char *key,
6181 			       const char *value, void *opaque_arg)
6182 {
6183 	struct bnxt_representor *vfr_bp = opaque_arg;
6184 	unsigned long rep_based_pf;
6185 	char *end = NULL;
6186 
6187 	if (!value || !opaque_arg) {
6188 		PMD_DRV_LOG_LINE(ERR,
6189 			    "Invalid parameter passed to rep_based_pf "
6190 			    "devargs.");
6191 		return -EINVAL;
6192 	}
6193 
6194 	rep_based_pf = strtoul(value, &end, 10);
6195 	if (end == NULL || *end != '\0' ||
6196 	    (rep_based_pf == ULONG_MAX && errno == ERANGE)) {
6197 		PMD_DRV_LOG_LINE(ERR,
6198 			    "Invalid parameter passed to rep_based_pf "
6199 			    "devargs.");
6200 		return -EINVAL;
6201 	}
6202 
6203 	if (BNXT_DEVARG_REP_BASED_PF_INVALID(rep_based_pf)) {
6204 		PMD_DRV_LOG_LINE(ERR,
6205 			    "Invalid value passed to rep_based_pf devargs.");
6206 		return -EINVAL;
6207 	}
6208 
6209 	vfr_bp->rep_based_pf = rep_based_pf;
6210 	vfr_bp->flags |= BNXT_REP_BASED_PF_VALID;
6211 
6212 	PMD_DRV_LOG_LINE(INFO, "rep-based-pf = %d", vfr_bp->rep_based_pf);
6213 
6214 	return 0;
6215 }
6216 
6217 static int
6218 bnxt_parse_devarg_rep_q_r2f(__rte_unused const char *key,
6219 			    const char *value, void *opaque_arg)
6220 {
6221 	struct bnxt_representor *vfr_bp = opaque_arg;
6222 	unsigned long rep_q_r2f;
6223 	char *end = NULL;
6224 
6225 	if (!value || !opaque_arg) {
6226 		PMD_DRV_LOG_LINE(ERR,
6227 			    "Invalid parameter passed to rep_q_r2f "
6228 			    "devargs.");
6229 		return -EINVAL;
6230 	}
6231 
6232 	rep_q_r2f = strtoul(value, &end, 10);
6233 	if (end == NULL || *end != '\0' ||
6234 	    (rep_q_r2f == ULONG_MAX && errno == ERANGE)) {
6235 		PMD_DRV_LOG_LINE(ERR,
6236 			    "Invalid parameter passed to rep_q_r2f "
6237 			    "devargs.");
6238 		return -EINVAL;
6239 	}
6240 
6241 	if (BNXT_DEVARG_REP_Q_R2F_INVALID(rep_q_r2f)) {
6242 		PMD_DRV_LOG_LINE(ERR,
6243 			    "Invalid value passed to rep_q_r2f devargs.");
6244 		return -EINVAL;
6245 	}
6246 
6247 	vfr_bp->rep_q_r2f = rep_q_r2f;
6248 	vfr_bp->flags |= BNXT_REP_Q_R2F_VALID;
6249 	PMD_DRV_LOG_LINE(INFO, "rep-q-r2f = %d", vfr_bp->rep_q_r2f);
6250 
6251 	return 0;
6252 }
6253 
6254 static int
6255 bnxt_parse_devarg_rep_q_f2r(__rte_unused const char *key,
6256 			    const char *value, void *opaque_arg)
6257 {
6258 	struct bnxt_representor *vfr_bp = opaque_arg;
6259 	unsigned long rep_q_f2r;
6260 	char *end = NULL;
6261 
6262 	if (!value || !opaque_arg) {
6263 		PMD_DRV_LOG_LINE(ERR,
6264 			    "Invalid parameter passed to rep_q_f2r "
6265 			    "devargs.");
6266 		return -EINVAL;
6267 	}
6268 
6269 	rep_q_f2r = strtoul(value, &end, 10);
6270 	if (end == NULL || *end != '\0' ||
6271 	    (rep_q_f2r == ULONG_MAX && errno == ERANGE)) {
6272 		PMD_DRV_LOG_LINE(ERR,
6273 			    "Invalid parameter passed to rep_q_f2r "
6274 			    "devargs.");
6275 		return -EINVAL;
6276 	}
6277 
6278 	if (BNXT_DEVARG_REP_Q_F2R_INVALID(rep_q_f2r)) {
6279 		PMD_DRV_LOG_LINE(ERR,
6280 			    "Invalid value passed to rep_q_f2r devargs.");
6281 		return -EINVAL;
6282 	}
6283 
6284 	vfr_bp->rep_q_f2r = rep_q_f2r;
6285 	vfr_bp->flags |= BNXT_REP_Q_F2R_VALID;
6286 	PMD_DRV_LOG_LINE(INFO, "rep-q-f2r = %d", vfr_bp->rep_q_f2r);
6287 
6288 	return 0;
6289 }
6290 
6291 static int
6292 bnxt_parse_devarg_rep_fc_r2f(__rte_unused const char *key,
6293 			     const char *value, void *opaque_arg)
6294 {
6295 	struct bnxt_representor *vfr_bp = opaque_arg;
6296 	unsigned long rep_fc_r2f;
6297 	char *end = NULL;
6298 
6299 	if (!value || !opaque_arg) {
6300 		PMD_DRV_LOG_LINE(ERR,
6301 			    "Invalid parameter passed to rep_fc_r2f "
6302 			    "devargs.");
6303 		return -EINVAL;
6304 	}
6305 
6306 	rep_fc_r2f = strtoul(value, &end, 10);
6307 	if (end == NULL || *end != '\0' ||
6308 	    (rep_fc_r2f == ULONG_MAX && errno == ERANGE)) {
6309 		PMD_DRV_LOG_LINE(ERR,
6310 			    "Invalid parameter passed to rep_fc_r2f "
6311 			    "devargs.");
6312 		return -EINVAL;
6313 	}
6314 
6315 	if (BNXT_DEVARG_REP_FC_R2F_INVALID(rep_fc_r2f)) {
6316 		PMD_DRV_LOG_LINE(ERR,
6317 			    "Invalid value passed to rep_fc_r2f devargs.");
6318 		return -EINVAL;
6319 	}
6320 
6321 	vfr_bp->flags |= BNXT_REP_FC_R2F_VALID;
6322 	vfr_bp->rep_fc_r2f = rep_fc_r2f;
6323 	PMD_DRV_LOG_LINE(INFO, "rep-fc-r2f = %lu", rep_fc_r2f);
6324 
6325 	return 0;
6326 }
6327 
6328 static int
6329 bnxt_parse_devarg_rep_fc_f2r(__rte_unused const char *key,
6330 			     const char *value, void *opaque_arg)
6331 {
6332 	struct bnxt_representor *vfr_bp = opaque_arg;
6333 	unsigned long rep_fc_f2r;
6334 	char *end = NULL;
6335 
6336 	if (!value || !opaque_arg) {
6337 		PMD_DRV_LOG_LINE(ERR,
6338 			    "Invalid parameter passed to rep_fc_f2r "
6339 			    "devargs.");
6340 		return -EINVAL;
6341 	}
6342 
6343 	rep_fc_f2r = strtoul(value, &end, 10);
6344 	if (end == NULL || *end != '\0' ||
6345 	    (rep_fc_f2r == ULONG_MAX && errno == ERANGE)) {
6346 		PMD_DRV_LOG_LINE(ERR,
6347 			    "Invalid parameter passed to rep_fc_f2r "
6348 			    "devargs.");
6349 		return -EINVAL;
6350 	}
6351 
6352 	if (BNXT_DEVARG_REP_FC_F2R_INVALID(rep_fc_f2r)) {
6353 		PMD_DRV_LOG_LINE(ERR,
6354 			    "Invalid value passed to rep_fc_f2r devargs.");
6355 		return -EINVAL;
6356 	}
6357 
6358 	vfr_bp->flags |= BNXT_REP_FC_F2R_VALID;
6359 	vfr_bp->rep_fc_f2r = rep_fc_f2r;
6360 	PMD_DRV_LOG_LINE(INFO, "rep-fc-f2r = %lu", rep_fc_f2r);
6361 
6362 	return 0;
6363 }
6364 
6365 static int
6366 bnxt_parse_dev_args(struct bnxt *bp, struct rte_devargs *devargs)
6367 {
6368 	struct rte_kvargs *kvlist;
6369 	int ret = 0;
6370 
6371 	if (devargs == NULL)
6372 		return 0;
6373 
6374 	kvlist = rte_kvargs_parse(devargs->args, bnxt_dev_args);
6375 	if (kvlist == NULL)
6376 		return -EINVAL;
6377 
6378 	/*
6379 	 * Handler for "flow_xstat" devarg.
6380 	 * Invoked as for ex: "-a 0000:00:0d.0,flow_xstat=1"
6381 	 */
6382 	ret = rte_kvargs_process(kvlist, BNXT_DEVARG_FLOW_XSTAT,
6383 				 bnxt_parse_devarg_flow_xstat, bp);
6384 	if (ret)
6385 		goto err;
6386 
6387 	/*
6388 	 * Handler for "max_num_kflows" devarg.
6389 	 * Invoked as for ex: "-a 000:00:0d.0,max_num_kflows=32"
6390 	 */
6391 	ret = rte_kvargs_process(kvlist, BNXT_DEVARG_MAX_NUM_KFLOWS,
6392 				 bnxt_parse_devarg_max_num_kflows, bp);
6393 	if (ret)
6394 		goto err;
6395 
6396 err:
6397 	/*
6398 	 * Handler for "app-id" devarg.
6399 	 * Invoked as for ex: "-a 000:00:0d.0,app-id=1"
6400 	 */
6401 	rte_kvargs_process(kvlist, BNXT_DEVARG_APP_ID,
6402 			   bnxt_parse_devarg_app_id, bp);
6403 
6404 	/*
6405 	 * Handler for "ieee-1588" devarg.
6406 	 * Invoked as for ex: "-a 000:00:0d.0,ieee-1588=1"
6407 	 */
6408 	rte_kvargs_process(kvlist, BNXT_DEVARG_IEEE_1588,
6409 			   bnxt_parse_devarg_ieee_1588, bp);
6410 
6411 	/*
6412 	 * Handler for "mpc" devarg.
6413 	 * Invoked as for ex: "-a 000:00:0d.0,mpc=1"
6414 	 */
6415 	rte_kvargs_process(kvlist, BNXT_DEVARG_MPC,
6416 			   bnxt_parse_devarg_mpc, bp);
6417 
6418 	/*
6419 	 * Handler for "cqe-mode" devarg.
6420 	 * Invoked as for ex: "-a 000:00:0d.0,cqe-mode=1"
6421 	 */
6422 	rte_kvargs_process(kvlist, BNXT_DEVARG_CQE_MODE,
6423 			   bnxt_parse_devarg_cqe_mode, bp);
6424 
6425 	rte_kvargs_free(kvlist);
6426 	return ret;
6427 }
6428 
6429 /* Allocate and initialize various fields in bnxt struct that
6430  * need to be allocated/destroyed only once in the lifetime of the driver
6431  */
6432 static int bnxt_drv_init(struct rte_eth_dev *eth_dev)
6433 {
6434 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
6435 	struct bnxt *bp = eth_dev->data->dev_private;
6436 	int rc = 0;
6437 
6438 	bp->flags &= ~BNXT_FLAG_RX_VECTOR_PKT_MODE;
6439 
6440 	if (bnxt_vf_pciid(pci_dev->id.device_id))
6441 		bp->flags |= BNXT_FLAG_VF;
6442 
6443 	if (bnxt_p5_device(pci_dev->id.device_id))
6444 		bp->flags |= BNXT_FLAG_CHIP_P5;
6445 
6446 	if (bnxt_p7_device(pci_dev->id.device_id))
6447 		bp->flags |= BNXT_FLAG_CHIP_P7;
6448 
6449 	if (pci_dev->id.device_id == BROADCOM_DEV_ID_58802 ||
6450 	    pci_dev->id.device_id == BROADCOM_DEV_ID_58804 ||
6451 	    pci_dev->id.device_id == BROADCOM_DEV_ID_58808 ||
6452 	    pci_dev->id.device_id == BROADCOM_DEV_ID_58802_VF)
6453 		bp->flags |= BNXT_FLAG_STINGRAY;
6454 
6455 	rc = bnxt_map_pci_bars(eth_dev);
6456 	if (rc) {
6457 		PMD_DRV_LOG_LINE(ERR,
6458 			    "Failed to initialize board rc: %x", rc);
6459 		return rc;
6460 	}
6461 
6462 	rc = bnxt_alloc_pf_info(bp);
6463 	if (rc)
6464 		return rc;
6465 
6466 	rc = bnxt_alloc_link_info(bp);
6467 	if (rc)
6468 		return rc;
6469 
6470 	rc = bnxt_alloc_parent_info(bp);
6471 	if (rc)
6472 		return rc;
6473 
6474 	rc = bnxt_alloc_hwrm_resources(bp);
6475 	if (rc) {
6476 		PMD_DRV_LOG_LINE(ERR,
6477 			    "Failed to allocate response buffer rc: %x", rc);
6478 		return rc;
6479 	}
6480 	rc = bnxt_alloc_leds_info(bp);
6481 	if (rc)
6482 		return rc;
6483 
6484 	rc = bnxt_alloc_cos_queues(bp);
6485 	if (rc)
6486 		return rc;
6487 
6488 	rc = bnxt_init_locks(bp);
6489 	if (rc)
6490 		return rc;
6491 
6492 	rc = bnxt_get_config(bp);
6493 	if (rc)
6494 		return rc;
6495 
6496 	if (BNXT_TRUFLOW_EN(bp)) {
6497 		/* extra mbuf field is required to store CFA code from mark */
6498 		static const struct rte_mbuf_dynfield bnxt_cfa_code_dynfield_desc = {
6499 			.name = RTE_PMD_BNXT_CFA_CODE_DYNFIELD_NAME,
6500 			.size = sizeof(bnxt_cfa_code_dynfield_t),
6501 			.align = alignof(bnxt_cfa_code_dynfield_t),
6502 		};
6503 		bnxt_cfa_code_dynfield_offset =
6504 			rte_mbuf_dynfield_register(&bnxt_cfa_code_dynfield_desc);
6505 		if (bnxt_cfa_code_dynfield_offset < 0) {
6506 			PMD_DRV_LOG_LINE(ERR,
6507 			    "Failed to register mbuf field for TruFlow mark");
6508 			return -rte_errno;
6509 		}
6510 	}
6511 
6512 	return rc;
6513 }
6514 
6515 static int
6516 bnxt_dev_init(struct rte_eth_dev *eth_dev, void *params __rte_unused)
6517 {
6518 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
6519 	static int version_printed;
6520 	struct bnxt *bp;
6521 	int rc;
6522 
6523 	if (version_printed++ == 0)
6524 		PMD_DRV_LOG_LINE(INFO, "%s", bnxt_version);
6525 
6526 	eth_dev->dev_ops = &bnxt_dev_ops;
6527 	eth_dev->rx_queue_count = bnxt_rx_queue_count_op;
6528 	eth_dev->rx_descriptor_status = bnxt_rx_descriptor_status_op;
6529 	eth_dev->tx_descriptor_status = bnxt_tx_descriptor_status_op;
6530 	eth_dev->rx_pkt_burst = &bnxt_recv_pkts;
6531 	eth_dev->tx_pkt_burst = &bnxt_xmit_pkts;
6532 
6533 	/*
6534 	 * For secondary processes, we don't initialise any further
6535 	 * as primary has already done this work.
6536 	 */
6537 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
6538 		return 0;
6539 
6540 	rte_eth_copy_pci_info(eth_dev, pci_dev);
6541 	eth_dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
6542 	eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC;
6543 
6544 	bp = eth_dev->data->dev_private;
6545 
6546 	/* set the default app id */
6547 	bp->app_id = bnxt_ulp_default_app_id_get();
6548 
6549 	/* Parse dev arguments passed on when starting the DPDK application. */
6550 	rc = bnxt_parse_dev_args(bp, pci_dev->device.devargs);
6551 	if (rc)
6552 		goto error_free;
6553 
6554 	rc = bnxt_drv_init(eth_dev);
6555 	if (rc)
6556 		goto error_free;
6557 
6558 	rc = bnxt_init_resources(bp, false);
6559 	if (rc)
6560 		goto error_free;
6561 
6562 	rc = bnxt_alloc_stats_mem(bp);
6563 	if (rc)
6564 		goto error_free;
6565 
6566 	PMD_DRV_LOG_LINE(INFO,
6567 		    "Found %s device at mem %" PRIX64 ", node addr %pM",
6568 		    DRV_MODULE_NAME,
6569 		    pci_dev->mem_resource[0].phys_addr,
6570 		    pci_dev->mem_resource[0].addr);
6571 
6572 	return 0;
6573 
6574 error_free:
6575 	bnxt_dev_uninit(eth_dev);
6576 	return rc;
6577 }
6578 
6579 
6580 static void bnxt_free_ctx_mem_buf(struct bnxt_ctx_mem_buf_info *ctx)
6581 {
6582 	if (!ctx)
6583 		return;
6584 
6585 	rte_free(ctx->va);
6586 
6587 	ctx->va = NULL;
6588 	ctx->dma = RTE_BAD_IOVA;
6589 	ctx->ctx_id = BNXT_CTX_VAL_INVAL;
6590 }
6591 
6592 static void bnxt_unregister_fc_ctx_mem(struct bnxt *bp)
6593 {
6594 	bnxt_hwrm_cfa_counter_cfg(bp, BNXT_DIR_RX,
6595 				  CFA_COUNTER_CFG_IN_COUNTER_TYPE_FC,
6596 				  bp->flow_stat->rx_fc_out_tbl.ctx_id,
6597 				  bp->flow_stat->max_fc,
6598 				  false);
6599 
6600 	bnxt_hwrm_cfa_counter_cfg(bp, BNXT_DIR_TX,
6601 				  CFA_COUNTER_CFG_IN_COUNTER_TYPE_FC,
6602 				  bp->flow_stat->tx_fc_out_tbl.ctx_id,
6603 				  bp->flow_stat->max_fc,
6604 				  false);
6605 
6606 	if (bp->flow_stat->rx_fc_in_tbl.ctx_id != BNXT_CTX_VAL_INVAL)
6607 		bnxt_hwrm_ctx_unrgtr(bp, bp->flow_stat->rx_fc_in_tbl.ctx_id);
6608 	bp->flow_stat->rx_fc_in_tbl.ctx_id = BNXT_CTX_VAL_INVAL;
6609 
6610 	if (bp->flow_stat->rx_fc_out_tbl.ctx_id != BNXT_CTX_VAL_INVAL)
6611 		bnxt_hwrm_ctx_unrgtr(bp, bp->flow_stat->rx_fc_out_tbl.ctx_id);
6612 	bp->flow_stat->rx_fc_out_tbl.ctx_id = BNXT_CTX_VAL_INVAL;
6613 
6614 	if (bp->flow_stat->tx_fc_in_tbl.ctx_id != BNXT_CTX_VAL_INVAL)
6615 		bnxt_hwrm_ctx_unrgtr(bp, bp->flow_stat->tx_fc_in_tbl.ctx_id);
6616 	bp->flow_stat->tx_fc_in_tbl.ctx_id = BNXT_CTX_VAL_INVAL;
6617 
6618 	if (bp->flow_stat->tx_fc_out_tbl.ctx_id != BNXT_CTX_VAL_INVAL)
6619 		bnxt_hwrm_ctx_unrgtr(bp, bp->flow_stat->tx_fc_out_tbl.ctx_id);
6620 	bp->flow_stat->tx_fc_out_tbl.ctx_id = BNXT_CTX_VAL_INVAL;
6621 }
6622 
6623 static void bnxt_uninit_fc_ctx_mem(struct bnxt *bp)
6624 {
6625 	bnxt_unregister_fc_ctx_mem(bp);
6626 
6627 	bnxt_free_ctx_mem_buf(&bp->flow_stat->rx_fc_in_tbl);
6628 	bnxt_free_ctx_mem_buf(&bp->flow_stat->rx_fc_out_tbl);
6629 	bnxt_free_ctx_mem_buf(&bp->flow_stat->tx_fc_in_tbl);
6630 	bnxt_free_ctx_mem_buf(&bp->flow_stat->tx_fc_out_tbl);
6631 }
6632 
6633 static void bnxt_uninit_ctx_mem(struct bnxt *bp)
6634 {
6635 	if (BNXT_FLOW_XSTATS_EN(bp))
6636 		bnxt_uninit_fc_ctx_mem(bp);
6637 }
6638 
6639 static void
6640 bnxt_free_error_recovery_info(struct bnxt *bp)
6641 {
6642 	rte_free(bp->recovery_info);
6643 	bp->recovery_info = NULL;
6644 	bp->fw_cap &= ~BNXT_FW_CAP_ERROR_RECOVERY;
6645 }
6646 
6647 static int
6648 bnxt_uninit_resources(struct bnxt *bp, bool reconfig_dev)
6649 {
6650 	int rc;
6651 
6652 	bnxt_free_int(bp);
6653 	bnxt_free_mem(bp, reconfig_dev);
6654 
6655 	bnxt_hwrm_func_buf_unrgtr(bp);
6656 	if (bp->pf != NULL) {
6657 		rte_free(bp->pf->vf_req_buf);
6658 		bp->pf->vf_req_buf = NULL;
6659 	}
6660 
6661 	rc = bnxt_hwrm_func_driver_unregister(bp);
6662 	bp->flags &= ~BNXT_FLAG_REGISTERED;
6663 	bnxt_free_ctx_mem(bp);
6664 	if (!reconfig_dev) {
6665 		bnxt_free_hwrm_resources(bp);
6666 		bnxt_free_error_recovery_info(bp);
6667 		rte_free(bp->mcast_addr_list);
6668 		bp->mcast_addr_list = NULL;
6669 		rte_free(bp->rss_conf.rss_key);
6670 		bp->rss_conf.rss_key = NULL;
6671 	}
6672 
6673 	bnxt_uninit_ctx_mem(bp);
6674 
6675 	bnxt_free_flow_stats_info(bp);
6676 	bnxt_free_switch_domain(bp);
6677 	rte_free(bp->ptp_cfg);
6678 	bp->ptp_cfg = NULL;
6679 	return rc;
6680 }
6681 
6682 static int
6683 bnxt_dev_uninit(struct rte_eth_dev *eth_dev)
6684 {
6685 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
6686 		return -EPERM;
6687 
6688 	PMD_DRV_LOG_LINE(DEBUG, "Calling Device uninit");
6689 
6690 	if (eth_dev->state != RTE_ETH_DEV_UNUSED)
6691 		bnxt_dev_close_op(eth_dev);
6692 
6693 	return 0;
6694 }
6695 
6696 static int bnxt_pci_remove_dev_with_reps(struct rte_eth_dev *eth_dev)
6697 {
6698 	struct bnxt *bp = eth_dev->data->dev_private;
6699 	struct rte_eth_dev *vf_rep_eth_dev;
6700 	int ret = 0, i;
6701 
6702 	if (!bp)
6703 		return -EINVAL;
6704 
6705 	for (i = 0; i < bp->num_reps; i++) {
6706 		vf_rep_eth_dev = bp->rep_info[i].vfr_eth_dev;
6707 		if (!vf_rep_eth_dev)
6708 			continue;
6709 		PMD_DRV_LOG_LINE(DEBUG, "BNXT Port:%d VFR pci remove",
6710 			    vf_rep_eth_dev->data->port_id);
6711 		rte_eth_dev_destroy(vf_rep_eth_dev, bnxt_representor_uninit);
6712 	}
6713 	PMD_DRV_LOG_LINE(DEBUG, "BNXT Port:%d pci remove",
6714 		    eth_dev->data->port_id);
6715 	ret = rte_eth_dev_destroy(eth_dev, bnxt_dev_uninit);
6716 
6717 	return ret;
6718 }
6719 
6720 static void bnxt_free_rep_info(struct bnxt *bp)
6721 {
6722 	rte_free(bp->rep_info);
6723 	bp->rep_info = NULL;
6724 	rte_free(bp->cfa_code_map);
6725 	bp->cfa_code_map = NULL;
6726 }
6727 
6728 static int bnxt_init_rep_info(struct bnxt *bp)
6729 {
6730 	int i = 0;
6731 
6732 	if (bp->rep_info)
6733 		return 0;
6734 
6735 	bp->rep_info = rte_zmalloc("bnxt_rep_info",
6736 				   sizeof(bp->rep_info[0]) * BNXT_MAX_VF_REPS(bp),
6737 				   0);
6738 	if (!bp->rep_info) {
6739 		PMD_DRV_LOG_LINE(ERR, "Failed to alloc memory for rep info");
6740 		return -ENOMEM;
6741 	}
6742 	bp->cfa_code_map = rte_zmalloc("bnxt_cfa_code_map",
6743 				       sizeof(*bp->cfa_code_map) *
6744 				       BNXT_MAX_CFA_CODE, 0);
6745 	if (!bp->cfa_code_map) {
6746 		PMD_DRV_LOG_LINE(ERR, "Failed to alloc memory for cfa_code_map");
6747 		bnxt_free_rep_info(bp);
6748 		return -ENOMEM;
6749 	}
6750 
6751 	for (i = 0; i < BNXT_MAX_CFA_CODE; i++)
6752 		bp->cfa_code_map[i] = BNXT_VF_IDX_INVALID;
6753 
6754 	return pthread_mutex_init(&bp->rep_info->vfr_start_lock, NULL);
6755 }
6756 
6757 static int bnxt_rep_port_probe(struct rte_pci_device *pci_dev,
6758 			       struct rte_eth_devargs *eth_da,
6759 			       struct rte_eth_dev *backing_eth_dev,
6760 			       const char *dev_args)
6761 {
6762 	struct rte_eth_dev *vf_rep_eth_dev;
6763 	char name[RTE_ETH_NAME_MAX_LEN];
6764 	struct bnxt *backing_bp = backing_eth_dev->data->dev_private;
6765 	uint16_t max_vf_reps = BNXT_MAX_VF_REPS(backing_bp);
6766 
6767 	uint16_t num_rep;
6768 	int i, ret = 0;
6769 	struct rte_kvargs *kvlist = NULL;
6770 
6771 	if (eth_da->type == RTE_ETH_REPRESENTOR_NONE)
6772 		return 0;
6773 	if (eth_da->type != RTE_ETH_REPRESENTOR_VF) {
6774 		PMD_DRV_LOG_LINE(ERR, "unsupported representor type %d",
6775 			    eth_da->type);
6776 		return -ENOTSUP;
6777 	}
6778 	num_rep = eth_da->nb_representor_ports;
6779 	if (num_rep > max_vf_reps) {
6780 		PMD_DRV_LOG_LINE(ERR, "nb_representor_ports = %d > %d MAX VF REPS",
6781 			    num_rep, max_vf_reps);
6782 		return -EINVAL;
6783 	}
6784 
6785 	if (num_rep >= RTE_MAX_ETHPORTS) {
6786 		PMD_DRV_LOG_LINE(ERR,
6787 			    "nb_representor_ports = %d > %d MAX ETHPORTS",
6788 			    num_rep, RTE_MAX_ETHPORTS);
6789 		return -EINVAL;
6790 	}
6791 
6792 	if (!(BNXT_PF(backing_bp) || BNXT_VF_IS_TRUSTED(backing_bp))) {
6793 		PMD_DRV_LOG_LINE(ERR,
6794 			    "Not a PF or trusted VF. No Representor support");
6795 		/* Returning an error is not an option.
6796 		 * Applications are not handling this correctly
6797 		 */
6798 		return 0;
6799 	}
6800 
6801 	if (bnxt_init_rep_info(backing_bp))
6802 		return 0;
6803 
6804 	for (i = 0; i < num_rep; i++) {
6805 		struct bnxt_representor representor = {
6806 			.vf_id = eth_da->representor_ports[i],
6807 			.switch_domain_id = backing_bp->switch_domain_id,
6808 			.parent_dev = backing_eth_dev
6809 		};
6810 
6811 		if (representor.vf_id >= max_vf_reps) {
6812 			PMD_DRV_LOG_LINE(ERR, "VF-Rep id %d >= %d MAX VF ID",
6813 				    representor.vf_id, max_vf_reps);
6814 			continue;
6815 		}
6816 
6817 		/* representor port net_bdf_port */
6818 		snprintf(name, sizeof(name), "net_%s_representor_%d",
6819 			 pci_dev->device.name, eth_da->representor_ports[i]);
6820 
6821 		kvlist = rte_kvargs_parse(dev_args, bnxt_dev_args);
6822 		if (kvlist) {
6823 			/*
6824 			 * Handler for "rep_is_pf" devarg.
6825 			 * Invoked as for ex: "-a 000:00:0d.0,
6826 			 * rep-based-pf=<pf index> rep-is-pf=<VF=0 or PF=1>"
6827 			 */
6828 			ret = rte_kvargs_process(kvlist, BNXT_DEVARG_REP_IS_PF,
6829 						 bnxt_parse_devarg_rep_is_pf,
6830 						 (void *)&representor);
6831 			if (ret) {
6832 				ret = -EINVAL;
6833 				goto err;
6834 			}
6835 			/*
6836 			 * Handler for "rep_based_pf" devarg.
6837 			 * Invoked as for ex: "-a 000:00:0d.0,
6838 			 * rep-based-pf=<pf index> rep-is-pf=<VF=0 or PF=1>"
6839 			 */
6840 			ret = rte_kvargs_process(kvlist,
6841 						 BNXT_DEVARG_REP_BASED_PF,
6842 						 bnxt_parse_devarg_rep_based_pf,
6843 						 (void *)&representor);
6844 			if (ret) {
6845 				ret = -EINVAL;
6846 				goto err;
6847 			}
6848 			/*
6849 			 * Handler for "rep_based_pf" devarg.
6850 			 * Invoked as for ex: "-a 000:00:0d.0,
6851 			 * rep-based-pf=<pf index> rep-is-pf=<VF=0 or PF=1>"
6852 			 */
6853 			ret = rte_kvargs_process(kvlist, BNXT_DEVARG_REP_Q_R2F,
6854 						 bnxt_parse_devarg_rep_q_r2f,
6855 						 (void *)&representor);
6856 			if (ret) {
6857 				ret = -EINVAL;
6858 				goto err;
6859 			}
6860 			/*
6861 			 * Handler for "rep_based_pf" devarg.
6862 			 * Invoked as for ex: "-a 000:00:0d.0,
6863 			 * rep-based-pf=<pf index> rep-is-pf=<VF=0 or PF=1>"
6864 			 */
6865 			ret = rte_kvargs_process(kvlist, BNXT_DEVARG_REP_Q_F2R,
6866 						 bnxt_parse_devarg_rep_q_f2r,
6867 						 (void *)&representor);
6868 			if (ret) {
6869 				ret = -EINVAL;
6870 				goto err;
6871 			}
6872 			/*
6873 			 * Handler for "rep_based_pf" devarg.
6874 			 * Invoked as for ex: "-a 000:00:0d.0,
6875 			 * rep-based-pf=<pf index> rep-is-pf=<VF=0 or PF=1>"
6876 			 */
6877 			ret = rte_kvargs_process(kvlist, BNXT_DEVARG_REP_FC_R2F,
6878 						 bnxt_parse_devarg_rep_fc_r2f,
6879 						 (void *)&representor);
6880 			if (ret) {
6881 				ret = -EINVAL;
6882 				goto err;
6883 			}
6884 			/*
6885 			 * Handler for "rep_based_pf" devarg.
6886 			 * Invoked as for ex: "-a 000:00:0d.0,
6887 			 * rep-based-pf=<pf index> rep-is-pf=<VF=0 or PF=1>"
6888 			 */
6889 			ret = rte_kvargs_process(kvlist, BNXT_DEVARG_REP_FC_F2R,
6890 						 bnxt_parse_devarg_rep_fc_f2r,
6891 						 (void *)&representor);
6892 			if (ret) {
6893 				ret = -EINVAL;
6894 				goto err;
6895 			}
6896 		}
6897 
6898 		ret = rte_eth_dev_create(&pci_dev->device, name,
6899 					 sizeof(struct bnxt_representor),
6900 					 NULL, NULL,
6901 					 bnxt_representor_init,
6902 					 &representor);
6903 		if (ret) {
6904 			PMD_DRV_LOG_LINE(ERR, "failed to create bnxt vf "
6905 				    "representor %s.", name);
6906 			goto err;
6907 		}
6908 
6909 		vf_rep_eth_dev = rte_eth_dev_allocated(name);
6910 		if (!vf_rep_eth_dev) {
6911 			PMD_DRV_LOG_LINE(ERR, "Failed to find the eth_dev"
6912 				    " for VF-Rep: %s.", name);
6913 			ret = -ENODEV;
6914 			goto err;
6915 		}
6916 
6917 		PMD_DRV_LOG_LINE(DEBUG, "BNXT Port:%d VFR pci probe",
6918 			    backing_eth_dev->data->port_id);
6919 		backing_bp->rep_info[representor.vf_id].vfr_eth_dev =
6920 							 vf_rep_eth_dev;
6921 		backing_bp->num_reps++;
6922 
6923 	}
6924 
6925 	rte_kvargs_free(kvlist);
6926 	return 0;
6927 
6928 err:
6929 	/* If num_rep > 1, then rollback already created
6930 	 * ports, since we'll be failing the probe anyway
6931 	 */
6932 	if (num_rep > 1)
6933 		bnxt_pci_remove_dev_with_reps(backing_eth_dev);
6934 	rte_errno = -ret;
6935 	rte_kvargs_free(kvlist);
6936 
6937 	return ret;
6938 }
6939 
6940 static int bnxt_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
6941 			  struct rte_pci_device *pci_dev)
6942 {
6943 	struct rte_eth_devargs eth_da = { .nb_representor_ports = 0 };
6944 	struct rte_eth_dev *backing_eth_dev;
6945 	uint16_t num_rep;
6946 	int ret = 0;
6947 
6948 	if (pci_dev->device.devargs) {
6949 		ret = rte_eth_devargs_parse(pci_dev->device.devargs->args,
6950 					    &eth_da, 1);
6951 		if (ret < 0)
6952 			return ret;
6953 	}
6954 
6955 	num_rep = eth_da.nb_representor_ports;
6956 	PMD_DRV_LOG_LINE(DEBUG, "nb_representor_ports = %d",
6957 		    num_rep);
6958 
6959 	/* We could come here after first level of probe is already invoked
6960 	 * as part of an application bringup(OVS-DPDK vswitchd), so first check
6961 	 * for already allocated eth_dev for the backing device (PF/Trusted VF)
6962 	 */
6963 	backing_eth_dev = rte_eth_dev_allocated(pci_dev->device.name);
6964 	if (backing_eth_dev == NULL) {
6965 		ret = rte_eth_dev_create(&pci_dev->device, pci_dev->device.name,
6966 					 sizeof(struct bnxt),
6967 					 eth_dev_pci_specific_init, pci_dev,
6968 					 bnxt_dev_init, NULL);
6969 
6970 		if (ret || !num_rep)
6971 			return ret;
6972 
6973 		backing_eth_dev = rte_eth_dev_allocated(pci_dev->device.name);
6974 	}
6975 	PMD_DRV_LOG_LINE(DEBUG, "BNXT Port:%d pci probe",
6976 		    backing_eth_dev->data->port_id);
6977 
6978 	if (!num_rep)
6979 		return ret;
6980 
6981 	/* probe representor ports now */
6982 	ret = bnxt_rep_port_probe(pci_dev, &eth_da, backing_eth_dev,
6983 				  pci_dev->device.devargs->args);
6984 
6985 	return ret;
6986 }
6987 
6988 static int bnxt_pci_remove(struct rte_pci_device *pci_dev)
6989 {
6990 	struct rte_eth_dev *eth_dev;
6991 
6992 	eth_dev = rte_eth_dev_allocated(pci_dev->device.name);
6993 	if (!eth_dev)
6994 		return 0; /* Invoked typically only by OVS-DPDK, by the
6995 			   * time it comes here the eth_dev is already
6996 			   * deleted by rte_eth_dev_close(), so returning
6997 			   * +ve value will at least help in proper cleanup
6998 			   */
6999 
7000 	PMD_DRV_LOG_LINE(DEBUG, "BNXT Port:%d pci remove", eth_dev->data->port_id);
7001 	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
7002 		if (rte_eth_dev_is_repr(eth_dev))
7003 			return rte_eth_dev_destroy(eth_dev,
7004 						   bnxt_representor_uninit);
7005 		else
7006 			return rte_eth_dev_destroy(eth_dev,
7007 						   bnxt_dev_uninit);
7008 	} else {
7009 		return rte_eth_dev_pci_generic_remove(pci_dev, NULL);
7010 	}
7011 }
7012 
7013 static struct rte_pci_driver bnxt_rte_pmd = {
7014 	.id_table = bnxt_pci_id_map,
7015 	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
7016 			RTE_PCI_DRV_INTR_RMV |
7017 			RTE_PCI_DRV_PROBE_AGAIN, /* Needed in case of VF-REPs
7018 						  * and OVS-DPDK
7019 						  */
7020 	.probe = bnxt_pci_probe,
7021 	.remove = bnxt_pci_remove,
7022 };
7023 
7024 static bool
7025 is_device_supported(struct rte_eth_dev *dev, struct rte_pci_driver *drv)
7026 {
7027 	if (strcmp(dev->device->driver->name, drv->driver.name))
7028 		return false;
7029 
7030 	return true;
7031 }
7032 
7033 bool is_bnxt_supported(struct rte_eth_dev *dev)
7034 {
7035 	return is_device_supported(dev, &bnxt_rte_pmd);
7036 }
7037 
7038 struct bnxt *
7039 bnxt_pmd_get_bp(uint16_t port)
7040 {
7041 	struct bnxt *bp;
7042 	struct rte_eth_dev *dev;
7043 
7044 	if (!rte_eth_dev_is_valid_port(port)) {
7045 		PMD_DRV_LOG_LINE(ERR, "Invalid port %d", port);
7046 		return NULL;
7047 	}
7048 
7049 	dev = &rte_eth_devices[port];
7050 	if (!is_bnxt_supported(dev)) {
7051 		PMD_DRV_LOG_LINE(ERR, "Device %d not supported", port);
7052 		return NULL;
7053 	}
7054 
7055 	bp = (struct bnxt *)dev->data->dev_private;
7056 	if (!BNXT_TRUFLOW_EN(bp)) {
7057 		PMD_DRV_LOG_LINE(ERR, "TRUFLOW not enabled");
7058 		return NULL;
7059 	}
7060 
7061 	return bp;
7062 }
7063 
7064 /* check if ULP should be enabled or not */
7065 static bool bnxt_enable_ulp(struct bnxt *bp)
7066 {
7067 	/* truflow and MPC should be enabled */
7068 	/* not enabling ulp for cli and no truflow apps */
7069 	if (BNXT_TRUFLOW_EN(bp) && bp->app_id != 254 &&
7070 	    bp->app_id != 255) {
7071 		if (BNXT_CHIP_P7(bp) && !mpc)
7072 			return false;
7073 		return true;
7074 	}
7075 	return false;
7076 }
7077 
7078 RTE_LOG_REGISTER_SUFFIX(bnxt_logtype_driver, driver, NOTICE);
7079 RTE_PMD_REGISTER_PCI(net_bnxt, bnxt_rte_pmd);
7080 RTE_PMD_REGISTER_PCI_TABLE(net_bnxt, bnxt_pci_id_map);
7081 RTE_PMD_REGISTER_KMOD_DEP(net_bnxt, "* igb_uio | uio_pci_generic | vfio-pci");
7082