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