xref: /dpdk/drivers/net/bnxt/bnxt_ethdev.c (revision f5019a53d7fc82474710c98bb48b4a09ee07c9f7)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2014-2018 Broadcom
3  * All rights reserved.
4  */
5 
6 #include <inttypes.h>
7 #include <stdbool.h>
8 
9 #include <rte_dev.h>
10 #include <rte_ethdev_driver.h>
11 #include <rte_ethdev_pci.h>
12 #include <rte_malloc.h>
13 #include <rte_cycles.h>
14 #include <rte_alarm.h>
15 
16 #include "bnxt.h"
17 #include "bnxt_filter.h"
18 #include "bnxt_hwrm.h"
19 #include "bnxt_irq.h"
20 #include "bnxt_ring.h"
21 #include "bnxt_rxq.h"
22 #include "bnxt_rxr.h"
23 #include "bnxt_stats.h"
24 #include "bnxt_txq.h"
25 #include "bnxt_txr.h"
26 #include "bnxt_vnic.h"
27 #include "hsi_struct_def_dpdk.h"
28 #include "bnxt_nvm_defs.h"
29 
30 #define DRV_MODULE_NAME		"bnxt"
31 static const char bnxt_version[] =
32 	"Broadcom NetXtreme driver " DRV_MODULE_NAME;
33 int bnxt_logtype_driver;
34 
35 /*
36  * The set of PCI devices this driver supports
37  */
38 static const struct rte_pci_id bnxt_pci_id_map[] = {
39 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM,
40 			 BROADCOM_DEV_ID_STRATUS_NIC_VF1) },
41 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM,
42 			 BROADCOM_DEV_ID_STRATUS_NIC_VF2) },
43 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_STRATUS_NIC) },
44 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57414_VF) },
45 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57301) },
46 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57302) },
47 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57304_PF) },
48 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57304_VF) },
49 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_NS2) },
50 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57402) },
51 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57404) },
52 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57406_PF) },
53 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57406_VF) },
54 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57402_MF) },
55 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57407_RJ45) },
56 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57404_MF) },
57 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57406_MF) },
58 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57407_SFP) },
59 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57407_MF) },
60 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_5741X_VF) },
61 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_5731X_VF) },
62 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57314) },
63 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57417_MF) },
64 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57311) },
65 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57312) },
66 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57412) },
67 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57414) },
68 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57416_RJ45) },
69 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57417_RJ45) },
70 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57412_MF) },
71 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57317_RJ45) },
72 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57417_SFP) },
73 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57416_SFP) },
74 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57317_SFP) },
75 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57414_MF) },
76 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57416_MF) },
77 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_58802) },
78 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_58804) },
79 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_58808) },
80 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_58802_VF) },
81 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57508) },
82 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57504) },
83 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57502) },
84 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57500_VF1) },
85 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57500_VF2) },
86 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57508_MF1) },
87 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57504_MF1) },
88 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57502_MF1) },
89 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57508_MF2) },
90 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57504_MF2) },
91 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57502_MF2) },
92 	{ .vendor_id = 0, /* sentinel */ },
93 };
94 
95 #define BNXT_ETH_RSS_SUPPORT (	\
96 	ETH_RSS_IPV4 |		\
97 	ETH_RSS_NONFRAG_IPV4_TCP |	\
98 	ETH_RSS_NONFRAG_IPV4_UDP |	\
99 	ETH_RSS_IPV6 |		\
100 	ETH_RSS_NONFRAG_IPV6_TCP |	\
101 	ETH_RSS_NONFRAG_IPV6_UDP)
102 
103 #define BNXT_DEV_TX_OFFLOAD_SUPPORT (DEV_TX_OFFLOAD_VLAN_INSERT | \
104 				     DEV_TX_OFFLOAD_IPV4_CKSUM | \
105 				     DEV_TX_OFFLOAD_TCP_CKSUM | \
106 				     DEV_TX_OFFLOAD_UDP_CKSUM | \
107 				     DEV_TX_OFFLOAD_TCP_TSO | \
108 				     DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM | \
109 				     DEV_TX_OFFLOAD_VXLAN_TNL_TSO | \
110 				     DEV_TX_OFFLOAD_GRE_TNL_TSO | \
111 				     DEV_TX_OFFLOAD_IPIP_TNL_TSO | \
112 				     DEV_TX_OFFLOAD_GENEVE_TNL_TSO | \
113 				     DEV_TX_OFFLOAD_QINQ_INSERT | \
114 				     DEV_TX_OFFLOAD_MULTI_SEGS)
115 
116 #define BNXT_DEV_RX_OFFLOAD_SUPPORT (DEV_RX_OFFLOAD_VLAN_FILTER | \
117 				     DEV_RX_OFFLOAD_VLAN_STRIP | \
118 				     DEV_RX_OFFLOAD_IPV4_CKSUM | \
119 				     DEV_RX_OFFLOAD_UDP_CKSUM | \
120 				     DEV_RX_OFFLOAD_TCP_CKSUM | \
121 				     DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM | \
122 				     DEV_RX_OFFLOAD_JUMBO_FRAME | \
123 				     DEV_RX_OFFLOAD_KEEP_CRC | \
124 				     DEV_RX_OFFLOAD_VLAN_EXTEND | \
125 				     DEV_RX_OFFLOAD_TCP_LRO | \
126 				     DEV_RX_OFFLOAD_SCATTER)
127 
128 static int bnxt_vlan_offload_set_op(struct rte_eth_dev *dev, int mask);
129 static void bnxt_print_link_info(struct rte_eth_dev *eth_dev);
130 static int bnxt_dev_uninit(struct rte_eth_dev *eth_dev);
131 static int bnxt_init_resources(struct bnxt *bp, bool reconfig_dev);
132 static int bnxt_uninit_resources(struct bnxt *bp, bool reconfig_dev);
133 static void bnxt_cancel_fw_health_check(struct bnxt *bp);
134 
135 int is_bnxt_in_error(struct bnxt *bp)
136 {
137 	if (bp->flags & BNXT_FLAG_FATAL_ERROR)
138 		return -EIO;
139 	if (bp->flags & BNXT_FLAG_FW_RESET)
140 		return -EBUSY;
141 
142 	return 0;
143 }
144 
145 /***********************/
146 
147 /*
148  * High level utility functions
149  */
150 
151 uint16_t bnxt_rss_ctxts(const struct bnxt *bp)
152 {
153 	if (!BNXT_CHIP_THOR(bp))
154 		return 1;
155 
156 	return RTE_ALIGN_MUL_CEIL(bp->rx_nr_rings,
157 				  BNXT_RSS_ENTRIES_PER_CTX_THOR) /
158 				    BNXT_RSS_ENTRIES_PER_CTX_THOR;
159 }
160 
161 static uint16_t  bnxt_rss_hash_tbl_size(const struct bnxt *bp)
162 {
163 	if (!BNXT_CHIP_THOR(bp))
164 		return HW_HASH_INDEX_SIZE;
165 
166 	return bnxt_rss_ctxts(bp) * BNXT_RSS_ENTRIES_PER_CTX_THOR;
167 }
168 
169 static void bnxt_free_mem(struct bnxt *bp, bool reconfig)
170 {
171 	bnxt_free_filter_mem(bp);
172 	bnxt_free_vnic_attributes(bp);
173 	bnxt_free_vnic_mem(bp);
174 
175 	/* tx/rx rings are configured as part of *_queue_setup callbacks.
176 	 * If the number of rings change across fw update,
177 	 * we don't have much choice except to warn the user.
178 	 */
179 	if (!reconfig) {
180 		bnxt_free_stats(bp);
181 		bnxt_free_tx_rings(bp);
182 		bnxt_free_rx_rings(bp);
183 	}
184 	bnxt_free_async_cp_ring(bp);
185 	bnxt_free_rxtx_nq_ring(bp);
186 
187 	rte_free(bp->grp_info);
188 	bp->grp_info = NULL;
189 }
190 
191 static int bnxt_alloc_mem(struct bnxt *bp, bool reconfig)
192 {
193 	int rc;
194 
195 	rc = bnxt_alloc_ring_grps(bp);
196 	if (rc)
197 		goto alloc_mem_err;
198 
199 	rc = bnxt_alloc_async_ring_struct(bp);
200 	if (rc)
201 		goto alloc_mem_err;
202 
203 	rc = bnxt_alloc_vnic_mem(bp);
204 	if (rc)
205 		goto alloc_mem_err;
206 
207 	rc = bnxt_alloc_vnic_attributes(bp);
208 	if (rc)
209 		goto alloc_mem_err;
210 
211 	rc = bnxt_alloc_filter_mem(bp);
212 	if (rc)
213 		goto alloc_mem_err;
214 
215 	rc = bnxt_alloc_async_cp_ring(bp);
216 	if (rc)
217 		goto alloc_mem_err;
218 
219 	rc = bnxt_alloc_rxtx_nq_ring(bp);
220 	if (rc)
221 		goto alloc_mem_err;
222 
223 	return 0;
224 
225 alloc_mem_err:
226 	bnxt_free_mem(bp, reconfig);
227 	return rc;
228 }
229 
230 static int bnxt_init_chip(struct bnxt *bp)
231 {
232 	struct bnxt_rx_queue *rxq;
233 	struct rte_eth_link new;
234 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(bp->eth_dev);
235 	struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
236 	struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
237 	uint64_t rx_offloads = dev_conf->rxmode.offloads;
238 	uint32_t intr_vector = 0;
239 	uint32_t queue_id, base = BNXT_MISC_VEC_ID;
240 	uint32_t vec = BNXT_MISC_VEC_ID;
241 	unsigned int i, j;
242 	int rc;
243 
244 	if (bp->eth_dev->data->mtu > RTE_ETHER_MTU) {
245 		bp->eth_dev->data->dev_conf.rxmode.offloads |=
246 			DEV_RX_OFFLOAD_JUMBO_FRAME;
247 		bp->flags |= BNXT_FLAG_JUMBO;
248 	} else {
249 		bp->eth_dev->data->dev_conf.rxmode.offloads &=
250 			~DEV_RX_OFFLOAD_JUMBO_FRAME;
251 		bp->flags &= ~BNXT_FLAG_JUMBO;
252 	}
253 
254 	/* THOR does not support ring groups.
255 	 * But we will use the array to save RSS context IDs.
256 	 */
257 	if (BNXT_CHIP_THOR(bp))
258 		bp->max_ring_grps = BNXT_MAX_RSS_CTXTS_THOR;
259 
260 	rc = bnxt_alloc_all_hwrm_stat_ctxs(bp);
261 	if (rc) {
262 		PMD_DRV_LOG(ERR, "HWRM stat ctx alloc failure rc: %x\n", rc);
263 		goto err_out;
264 	}
265 
266 	rc = bnxt_alloc_hwrm_rings(bp);
267 	if (rc) {
268 		PMD_DRV_LOG(ERR, "HWRM ring alloc failure rc: %x\n", rc);
269 		goto err_out;
270 	}
271 
272 	rc = bnxt_alloc_all_hwrm_ring_grps(bp);
273 	if (rc) {
274 		PMD_DRV_LOG(ERR, "HWRM ring grp alloc failure: %x\n", rc);
275 		goto err_out;
276 	}
277 
278 	if (!(bp->vnic_cap_flags & BNXT_VNIC_CAP_COS_CLASSIFY))
279 		goto skip_cosq_cfg;
280 
281 	for (j = 0, i = 0; i < BNXT_COS_QUEUE_COUNT; i++) {
282 		if (bp->rx_cos_queue[i].id != 0xff) {
283 			struct bnxt_vnic_info *vnic = &bp->vnic_info[j++];
284 
285 			if (!vnic) {
286 				PMD_DRV_LOG(ERR,
287 					    "Num pools more than FW profile\n");
288 				rc = -EINVAL;
289 				goto err_out;
290 			}
291 			vnic->cos_queue_id = bp->rx_cos_queue[i].id;
292 			bp->rx_cosq_cnt++;
293 		}
294 	}
295 
296 skip_cosq_cfg:
297 	rc = bnxt_mq_rx_configure(bp);
298 	if (rc) {
299 		PMD_DRV_LOG(ERR, "MQ mode configure failure rc: %x\n", rc);
300 		goto err_out;
301 	}
302 
303 	/* VNIC configuration */
304 	for (i = 0; i < bp->nr_vnics; i++) {
305 		struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
306 		struct bnxt_vnic_info *vnic = &bp->vnic_info[i];
307 
308 		rc = bnxt_vnic_grp_alloc(bp, vnic);
309 		if (rc)
310 			goto err_out;
311 
312 		PMD_DRV_LOG(DEBUG, "vnic[%d] = %p vnic->fw_grp_ids = %p\n",
313 			    i, vnic, vnic->fw_grp_ids);
314 
315 		rc = bnxt_hwrm_vnic_alloc(bp, vnic);
316 		if (rc) {
317 			PMD_DRV_LOG(ERR, "HWRM vnic %d alloc failure rc: %x\n",
318 				i, rc);
319 			goto err_out;
320 		}
321 
322 		/* Alloc RSS context only if RSS mode is enabled */
323 		if (dev_conf->rxmode.mq_mode & ETH_MQ_RX_RSS) {
324 			int j, nr_ctxs = bnxt_rss_ctxts(bp);
325 
326 			rc = 0;
327 			for (j = 0; j < nr_ctxs; j++) {
328 				rc = bnxt_hwrm_vnic_ctx_alloc(bp, vnic, j);
329 				if (rc)
330 					break;
331 			}
332 			if (rc) {
333 				PMD_DRV_LOG(ERR,
334 				  "HWRM vnic %d ctx %d alloc failure rc: %x\n",
335 				  i, j, rc);
336 				goto err_out;
337 			}
338 			vnic->num_lb_ctxts = nr_ctxs;
339 		}
340 
341 		/*
342 		 * Firmware sets pf pair in default vnic cfg. If the VLAN strip
343 		 * setting is not available at this time, it will not be
344 		 * configured correctly in the CFA.
345 		 */
346 		if (rx_offloads & DEV_RX_OFFLOAD_VLAN_STRIP)
347 			vnic->vlan_strip = true;
348 		else
349 			vnic->vlan_strip = false;
350 
351 		rc = bnxt_hwrm_vnic_cfg(bp, vnic);
352 		if (rc) {
353 			PMD_DRV_LOG(ERR, "HWRM vnic %d cfg failure rc: %x\n",
354 				i, rc);
355 			goto err_out;
356 		}
357 
358 		rc = bnxt_set_hwrm_vnic_filters(bp, vnic);
359 		if (rc) {
360 			PMD_DRV_LOG(ERR,
361 				"HWRM vnic %d filter failure rc: %x\n",
362 				i, rc);
363 			goto err_out;
364 		}
365 
366 		for (j = 0; j < bp->rx_num_qs_per_vnic; j++) {
367 			rxq = bp->eth_dev->data->rx_queues[j];
368 
369 			PMD_DRV_LOG(DEBUG,
370 				    "rxq[%d]->vnic=%p vnic->fw_grp_ids=%p\n",
371 				    j, rxq->vnic, rxq->vnic->fw_grp_ids);
372 
373 			if (BNXT_HAS_RING_GRPS(bp) && rxq->rx_deferred_start)
374 				rxq->vnic->fw_grp_ids[j] = INVALID_HW_RING_ID;
375 		}
376 
377 		rc = bnxt_vnic_rss_configure(bp, vnic);
378 		if (rc) {
379 			PMD_DRV_LOG(ERR,
380 				    "HWRM vnic set RSS failure rc: %x\n", rc);
381 			goto err_out;
382 		}
383 
384 		bnxt_hwrm_vnic_plcmode_cfg(bp, vnic);
385 
386 		if (bp->eth_dev->data->dev_conf.rxmode.offloads &
387 		    DEV_RX_OFFLOAD_TCP_LRO)
388 			bnxt_hwrm_vnic_tpa_cfg(bp, vnic, 1);
389 		else
390 			bnxt_hwrm_vnic_tpa_cfg(bp, vnic, 0);
391 	}
392 	rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, &bp->vnic_info[0], 0, NULL);
393 	if (rc) {
394 		PMD_DRV_LOG(ERR,
395 			"HWRM cfa l2 rx mask failure rc: %x\n", rc);
396 		goto err_out;
397 	}
398 
399 	/* check and configure queue intr-vector mapping */
400 	if ((rte_intr_cap_multiple(intr_handle) ||
401 	     !RTE_ETH_DEV_SRIOV(bp->eth_dev).active) &&
402 	    bp->eth_dev->data->dev_conf.intr_conf.rxq != 0) {
403 		intr_vector = bp->eth_dev->data->nb_rx_queues;
404 		PMD_DRV_LOG(DEBUG, "intr_vector = %d\n", intr_vector);
405 		if (intr_vector > bp->rx_cp_nr_rings) {
406 			PMD_DRV_LOG(ERR, "At most %d intr queues supported",
407 					bp->rx_cp_nr_rings);
408 			return -ENOTSUP;
409 		}
410 		rc = rte_intr_efd_enable(intr_handle, intr_vector);
411 		if (rc)
412 			return rc;
413 	}
414 
415 	if (rte_intr_dp_is_en(intr_handle) && !intr_handle->intr_vec) {
416 		intr_handle->intr_vec =
417 			rte_zmalloc("intr_vec",
418 				    bp->eth_dev->data->nb_rx_queues *
419 				    sizeof(int), 0);
420 		if (intr_handle->intr_vec == NULL) {
421 			PMD_DRV_LOG(ERR, "Failed to allocate %d rx_queues"
422 				" intr_vec", bp->eth_dev->data->nb_rx_queues);
423 			rc = -ENOMEM;
424 			goto err_disable;
425 		}
426 		PMD_DRV_LOG(DEBUG, "intr_handle->intr_vec = %p "
427 			"intr_handle->nb_efd = %d intr_handle->max_intr = %d\n",
428 			 intr_handle->intr_vec, intr_handle->nb_efd,
429 			intr_handle->max_intr);
430 		for (queue_id = 0; queue_id < bp->eth_dev->data->nb_rx_queues;
431 		     queue_id++) {
432 			intr_handle->intr_vec[queue_id] =
433 							vec + BNXT_RX_VEC_START;
434 			if (vec < base + intr_handle->nb_efd - 1)
435 				vec++;
436 		}
437 	}
438 
439 	/* enable uio/vfio intr/eventfd mapping */
440 	rc = rte_intr_enable(intr_handle);
441 	if (rc)
442 		goto err_free;
443 
444 	rc = bnxt_get_hwrm_link_config(bp, &new);
445 	if (rc) {
446 		PMD_DRV_LOG(ERR, "HWRM Get link config failure rc: %x\n", rc);
447 		goto err_free;
448 	}
449 
450 	if (!bp->link_info.link_up) {
451 		rc = bnxt_set_hwrm_link_config(bp, true);
452 		if (rc) {
453 			PMD_DRV_LOG(ERR,
454 				"HWRM link config failure rc: %x\n", rc);
455 			goto err_free;
456 		}
457 	}
458 	bnxt_print_link_info(bp->eth_dev);
459 
460 	return 0;
461 
462 err_free:
463 	rte_free(intr_handle->intr_vec);
464 err_disable:
465 	rte_intr_efd_disable(intr_handle);
466 err_out:
467 	/* Some of the error status returned by FW may not be from errno.h */
468 	if (rc > 0)
469 		rc = -EIO;
470 
471 	return rc;
472 }
473 
474 static int bnxt_shutdown_nic(struct bnxt *bp)
475 {
476 	bnxt_free_all_hwrm_resources(bp);
477 	bnxt_free_all_filters(bp);
478 	bnxt_free_all_vnics(bp);
479 	return 0;
480 }
481 
482 static int bnxt_init_nic(struct bnxt *bp)
483 {
484 	int rc;
485 
486 	if (BNXT_HAS_RING_GRPS(bp)) {
487 		rc = bnxt_init_ring_grps(bp);
488 		if (rc)
489 			return rc;
490 	}
491 
492 	bnxt_init_vnics(bp);
493 	bnxt_init_filters(bp);
494 
495 	return 0;
496 }
497 
498 /*
499  * Device configuration and status function
500  */
501 
502 static int bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev,
503 				struct rte_eth_dev_info *dev_info)
504 {
505 	struct rte_pci_device *pdev = RTE_DEV_TO_PCI(eth_dev->device);
506 	struct bnxt *bp = eth_dev->data->dev_private;
507 	uint16_t max_vnics, i, j, vpool, vrxq;
508 	unsigned int max_rx_rings;
509 	int rc;
510 
511 	rc = is_bnxt_in_error(bp);
512 	if (rc)
513 		return rc;
514 
515 	/* MAC Specifics */
516 	dev_info->max_mac_addrs = bp->max_l2_ctx;
517 	dev_info->max_hash_mac_addrs = 0;
518 
519 	/* PF/VF specifics */
520 	if (BNXT_PF(bp))
521 		dev_info->max_vfs = pdev->max_vfs;
522 
523 	max_rx_rings = RTE_MIN(bp->max_rx_rings, bp->max_stat_ctx);
524 	/* For the sake of symmetry, max_rx_queues = max_tx_queues */
525 	dev_info->max_rx_queues = max_rx_rings;
526 	dev_info->max_tx_queues = max_rx_rings;
527 	dev_info->reta_size = bnxt_rss_hash_tbl_size(bp);
528 	dev_info->hash_key_size = 40;
529 	max_vnics = bp->max_vnics;
530 
531 	/* MTU specifics */
532 	dev_info->min_mtu = RTE_ETHER_MIN_MTU;
533 	dev_info->max_mtu = BNXT_MAX_MTU;
534 
535 	/* Fast path specifics */
536 	dev_info->min_rx_bufsize = 1;
537 	dev_info->max_rx_pktlen = BNXT_MAX_PKT_LEN;
538 
539 	dev_info->rx_offload_capa = BNXT_DEV_RX_OFFLOAD_SUPPORT;
540 	if (bp->flags & BNXT_FLAG_PTP_SUPPORTED)
541 		dev_info->rx_offload_capa |= DEV_RX_OFFLOAD_TIMESTAMP;
542 	dev_info->tx_offload_capa = BNXT_DEV_TX_OFFLOAD_SUPPORT;
543 	dev_info->flow_type_rss_offloads = BNXT_ETH_RSS_SUPPORT;
544 
545 	/* *INDENT-OFF* */
546 	dev_info->default_rxconf = (struct rte_eth_rxconf) {
547 		.rx_thresh = {
548 			.pthresh = 8,
549 			.hthresh = 8,
550 			.wthresh = 0,
551 		},
552 		.rx_free_thresh = 32,
553 		/* If no descriptors available, pkts are dropped by default */
554 		.rx_drop_en = 1,
555 	};
556 
557 	dev_info->default_txconf = (struct rte_eth_txconf) {
558 		.tx_thresh = {
559 			.pthresh = 32,
560 			.hthresh = 0,
561 			.wthresh = 0,
562 		},
563 		.tx_free_thresh = 32,
564 		.tx_rs_thresh = 32,
565 	};
566 	eth_dev->data->dev_conf.intr_conf.lsc = 1;
567 
568 	eth_dev->data->dev_conf.intr_conf.rxq = 1;
569 	dev_info->rx_desc_lim.nb_min = BNXT_MIN_RING_DESC;
570 	dev_info->rx_desc_lim.nb_max = BNXT_MAX_RX_RING_DESC;
571 	dev_info->tx_desc_lim.nb_min = BNXT_MIN_RING_DESC;
572 	dev_info->tx_desc_lim.nb_max = BNXT_MAX_TX_RING_DESC;
573 
574 	/* *INDENT-ON* */
575 
576 	/*
577 	 * TODO: default_rxconf, default_txconf, rx_desc_lim, and tx_desc_lim
578 	 *       need further investigation.
579 	 */
580 
581 	/* VMDq resources */
582 	vpool = 64; /* ETH_64_POOLS */
583 	vrxq = 128; /* ETH_VMDQ_DCB_NUM_QUEUES */
584 	for (i = 0; i < 4; vpool >>= 1, i++) {
585 		if (max_vnics > vpool) {
586 			for (j = 0; j < 5; vrxq >>= 1, j++) {
587 				if (dev_info->max_rx_queues > vrxq) {
588 					if (vpool > vrxq)
589 						vpool = vrxq;
590 					goto found;
591 				}
592 			}
593 			/* Not enough resources to support VMDq */
594 			break;
595 		}
596 	}
597 	/* Not enough resources to support VMDq */
598 	vpool = 0;
599 	vrxq = 0;
600 found:
601 	dev_info->max_vmdq_pools = vpool;
602 	dev_info->vmdq_queue_num = vrxq;
603 
604 	dev_info->vmdq_pool_base = 0;
605 	dev_info->vmdq_queue_base = 0;
606 
607 	return 0;
608 }
609 
610 /* Configure the device based on the configuration provided */
611 static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev)
612 {
613 	struct bnxt *bp = eth_dev->data->dev_private;
614 	uint64_t rx_offloads = eth_dev->data->dev_conf.rxmode.offloads;
615 	int rc;
616 
617 	bp->rx_queues = (void *)eth_dev->data->rx_queues;
618 	bp->tx_queues = (void *)eth_dev->data->tx_queues;
619 	bp->tx_nr_rings = eth_dev->data->nb_tx_queues;
620 	bp->rx_nr_rings = eth_dev->data->nb_rx_queues;
621 
622 	rc = is_bnxt_in_error(bp);
623 	if (rc)
624 		return rc;
625 
626 	if (BNXT_VF(bp) && (bp->flags & BNXT_FLAG_NEW_RM)) {
627 		rc = bnxt_hwrm_check_vf_rings(bp);
628 		if (rc) {
629 			PMD_DRV_LOG(ERR, "HWRM insufficient resources\n");
630 			return -ENOSPC;
631 		}
632 
633 		/* If a resource has already been allocated - in this case
634 		 * it is the async completion ring, free it. Reallocate it after
635 		 * resource reservation. This will ensure the resource counts
636 		 * are calculated correctly.
637 		 */
638 
639 		pthread_mutex_lock(&bp->def_cp_lock);
640 
641 		if (!BNXT_HAS_NQ(bp) && bp->async_cp_ring) {
642 			bnxt_disable_int(bp);
643 			bnxt_free_cp_ring(bp, bp->async_cp_ring);
644 		}
645 
646 		rc = bnxt_hwrm_func_reserve_vf_resc(bp, false);
647 		if (rc) {
648 			PMD_DRV_LOG(ERR, "HWRM resource alloc fail:%x\n", rc);
649 			pthread_mutex_unlock(&bp->def_cp_lock);
650 			return -ENOSPC;
651 		}
652 
653 		if (!BNXT_HAS_NQ(bp) && bp->async_cp_ring) {
654 			rc = bnxt_alloc_async_cp_ring(bp);
655 			if (rc) {
656 				pthread_mutex_unlock(&bp->def_cp_lock);
657 				return rc;
658 			}
659 			bnxt_enable_int(bp);
660 		}
661 
662 		pthread_mutex_unlock(&bp->def_cp_lock);
663 	} else {
664 		/* legacy driver needs to get updated values */
665 		rc = bnxt_hwrm_func_qcaps(bp);
666 		if (rc) {
667 			PMD_DRV_LOG(ERR, "hwrm func qcaps fail:%d\n", rc);
668 			return rc;
669 		}
670 	}
671 
672 	/* Inherit new configurations */
673 	if (eth_dev->data->nb_rx_queues > bp->max_rx_rings ||
674 	    eth_dev->data->nb_tx_queues > bp->max_tx_rings ||
675 	    eth_dev->data->nb_rx_queues + eth_dev->data->nb_tx_queues
676 		+ BNXT_NUM_ASYNC_CPR(bp) > bp->max_cp_rings ||
677 	    eth_dev->data->nb_rx_queues + eth_dev->data->nb_tx_queues >
678 	    bp->max_stat_ctx)
679 		goto resource_error;
680 
681 	if (BNXT_HAS_RING_GRPS(bp) &&
682 	    (uint32_t)(eth_dev->data->nb_rx_queues) > bp->max_ring_grps)
683 		goto resource_error;
684 
685 	if (!(eth_dev->data->dev_conf.rxmode.mq_mode & ETH_MQ_RX_RSS) &&
686 	    bp->max_vnics < eth_dev->data->nb_rx_queues)
687 		goto resource_error;
688 
689 	bp->rx_cp_nr_rings = bp->rx_nr_rings;
690 	bp->tx_cp_nr_rings = bp->tx_nr_rings;
691 
692 	if (rx_offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) {
693 		eth_dev->data->mtu =
694 			eth_dev->data->dev_conf.rxmode.max_rx_pkt_len -
695 			RTE_ETHER_HDR_LEN - RTE_ETHER_CRC_LEN - VLAN_TAG_SIZE *
696 			BNXT_NUM_VLANS;
697 		bnxt_mtu_set_op(eth_dev, eth_dev->data->mtu);
698 	}
699 	return 0;
700 
701 resource_error:
702 	PMD_DRV_LOG(ERR,
703 		    "Insufficient resources to support requested config\n");
704 	PMD_DRV_LOG(ERR,
705 		    "Num Queues Requested: Tx %d, Rx %d\n",
706 		    eth_dev->data->nb_tx_queues,
707 		    eth_dev->data->nb_rx_queues);
708 	PMD_DRV_LOG(ERR,
709 		    "MAX: TxQ %d, RxQ %d, CQ %d Stat %d, Grp %d, Vnic %d\n",
710 		    bp->max_tx_rings, bp->max_rx_rings, bp->max_cp_rings,
711 		    bp->max_stat_ctx, bp->max_ring_grps, bp->max_vnics);
712 	return -ENOSPC;
713 }
714 
715 static void bnxt_print_link_info(struct rte_eth_dev *eth_dev)
716 {
717 	struct rte_eth_link *link = &eth_dev->data->dev_link;
718 
719 	if (link->link_status)
720 		PMD_DRV_LOG(INFO, "Port %d Link Up - speed %u Mbps - %s\n",
721 			eth_dev->data->port_id,
722 			(uint32_t)link->link_speed,
723 			(link->link_duplex == ETH_LINK_FULL_DUPLEX) ?
724 			("full-duplex") : ("half-duplex\n"));
725 	else
726 		PMD_DRV_LOG(INFO, "Port %d Link Down\n",
727 			eth_dev->data->port_id);
728 }
729 
730 /*
731  * Determine whether the current configuration requires support for scattered
732  * receive; return 1 if scattered receive is required and 0 if not.
733  */
734 static int bnxt_scattered_rx(struct rte_eth_dev *eth_dev)
735 {
736 	uint16_t buf_size;
737 	int i;
738 
739 	if (eth_dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_SCATTER)
740 		return 1;
741 
742 	for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
743 		struct bnxt_rx_queue *rxq = eth_dev->data->rx_queues[i];
744 
745 		buf_size = (uint16_t)(rte_pktmbuf_data_room_size(rxq->mb_pool) -
746 				      RTE_PKTMBUF_HEADROOM);
747 		if (eth_dev->data->dev_conf.rxmode.max_rx_pkt_len > buf_size)
748 			return 1;
749 	}
750 	return 0;
751 }
752 
753 static eth_rx_burst_t
754 bnxt_receive_function(__rte_unused struct rte_eth_dev *eth_dev)
755 {
756 #ifdef RTE_ARCH_X86
757 #ifndef RTE_LIBRTE_IEEE1588
758 	/*
759 	 * Vector mode receive can be enabled only if scatter rx is not
760 	 * in use and rx offloads are limited to VLAN stripping and
761 	 * CRC stripping.
762 	 */
763 	if (!eth_dev->data->scattered_rx &&
764 	    !(eth_dev->data->dev_conf.rxmode.offloads &
765 	      ~(DEV_RX_OFFLOAD_VLAN_STRIP |
766 		DEV_RX_OFFLOAD_KEEP_CRC |
767 		DEV_RX_OFFLOAD_JUMBO_FRAME |
768 		DEV_RX_OFFLOAD_IPV4_CKSUM |
769 		DEV_RX_OFFLOAD_UDP_CKSUM |
770 		DEV_RX_OFFLOAD_TCP_CKSUM |
771 		DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM |
772 		DEV_RX_OFFLOAD_VLAN_FILTER))) {
773 		PMD_DRV_LOG(INFO, "Using vector mode receive for port %d\n",
774 			    eth_dev->data->port_id);
775 		return bnxt_recv_pkts_vec;
776 	}
777 	PMD_DRV_LOG(INFO, "Vector mode receive disabled for port %d\n",
778 		    eth_dev->data->port_id);
779 	PMD_DRV_LOG(INFO,
780 		    "Port %d scatter: %d rx offload: %" PRIX64 "\n",
781 		    eth_dev->data->port_id,
782 		    eth_dev->data->scattered_rx,
783 		    eth_dev->data->dev_conf.rxmode.offloads);
784 #endif
785 #endif
786 	return bnxt_recv_pkts;
787 }
788 
789 static eth_tx_burst_t
790 bnxt_transmit_function(__rte_unused struct rte_eth_dev *eth_dev)
791 {
792 #ifdef RTE_ARCH_X86
793 #ifndef RTE_LIBRTE_IEEE1588
794 	/*
795 	 * Vector mode transmit can be enabled only if not using scatter rx
796 	 * or tx offloads.
797 	 */
798 	if (!eth_dev->data->scattered_rx &&
799 	    !eth_dev->data->dev_conf.txmode.offloads) {
800 		PMD_DRV_LOG(INFO, "Using vector mode transmit for port %d\n",
801 			    eth_dev->data->port_id);
802 		return bnxt_xmit_pkts_vec;
803 	}
804 	PMD_DRV_LOG(INFO, "Vector mode transmit disabled for port %d\n",
805 		    eth_dev->data->port_id);
806 	PMD_DRV_LOG(INFO,
807 		    "Port %d scatter: %d tx offload: %" PRIX64 "\n",
808 		    eth_dev->data->port_id,
809 		    eth_dev->data->scattered_rx,
810 		    eth_dev->data->dev_conf.txmode.offloads);
811 #endif
812 #endif
813 	return bnxt_xmit_pkts;
814 }
815 
816 static int bnxt_handle_if_change_status(struct bnxt *bp)
817 {
818 	int rc;
819 
820 	/* Since fw has undergone a reset and lost all contexts,
821 	 * set fatal flag to not issue hwrm during cleanup
822 	 */
823 	bp->flags |= BNXT_FLAG_FATAL_ERROR;
824 	bnxt_uninit_resources(bp, true);
825 
826 	/* clear fatal flag so that re-init happens */
827 	bp->flags &= ~BNXT_FLAG_FATAL_ERROR;
828 	rc = bnxt_init_resources(bp, true);
829 
830 	bp->flags &= ~BNXT_FLAG_IF_CHANGE_HOT_FW_RESET_DONE;
831 
832 	return rc;
833 }
834 
835 static int bnxt_dev_start_op(struct rte_eth_dev *eth_dev)
836 {
837 	struct bnxt *bp = eth_dev->data->dev_private;
838 	uint64_t rx_offloads = eth_dev->data->dev_conf.rxmode.offloads;
839 	int vlan_mask = 0;
840 	int rc;
841 
842 	if (!eth_dev->data->nb_tx_queues || !eth_dev->data->nb_rx_queues) {
843 		PMD_DRV_LOG(ERR, "Queues are not configured yet!\n");
844 		return -EINVAL;
845 	}
846 
847 	if (bp->rx_cp_nr_rings > RTE_ETHDEV_QUEUE_STAT_CNTRS) {
848 		PMD_DRV_LOG(ERR,
849 			"RxQ cnt %d > CONFIG_RTE_ETHDEV_QUEUE_STAT_CNTRS %d\n",
850 			bp->rx_cp_nr_rings, RTE_ETHDEV_QUEUE_STAT_CNTRS);
851 	}
852 
853 	rc = bnxt_hwrm_if_change(bp, 1);
854 	if (!rc) {
855 		if (bp->flags & BNXT_FLAG_IF_CHANGE_HOT_FW_RESET_DONE) {
856 			rc = bnxt_handle_if_change_status(bp);
857 			if (rc)
858 				return rc;
859 		}
860 	}
861 	bnxt_enable_int(bp);
862 
863 	rc = bnxt_init_chip(bp);
864 	if (rc)
865 		goto error;
866 
867 	eth_dev->data->scattered_rx = bnxt_scattered_rx(eth_dev);
868 
869 	bnxt_link_update_op(eth_dev, 1);
870 
871 	if (rx_offloads & DEV_RX_OFFLOAD_VLAN_FILTER)
872 		vlan_mask |= ETH_VLAN_FILTER_MASK;
873 	if (rx_offloads & DEV_RX_OFFLOAD_VLAN_STRIP)
874 		vlan_mask |= ETH_VLAN_STRIP_MASK;
875 	rc = bnxt_vlan_offload_set_op(eth_dev, vlan_mask);
876 	if (rc)
877 		goto error;
878 
879 	eth_dev->rx_pkt_burst = bnxt_receive_function(eth_dev);
880 	eth_dev->tx_pkt_burst = bnxt_transmit_function(eth_dev);
881 
882 	bp->flags |= BNXT_FLAG_INIT_DONE;
883 	eth_dev->data->dev_started = 1;
884 	bp->dev_stopped = 0;
885 	pthread_mutex_lock(&bp->def_cp_lock);
886 	bnxt_schedule_fw_health_check(bp);
887 	pthread_mutex_unlock(&bp->def_cp_lock);
888 	return 0;
889 
890 error:
891 	bnxt_hwrm_if_change(bp, 0);
892 	bnxt_shutdown_nic(bp);
893 	bnxt_free_tx_mbufs(bp);
894 	bnxt_free_rx_mbufs(bp);
895 	return rc;
896 }
897 
898 static int bnxt_dev_set_link_up_op(struct rte_eth_dev *eth_dev)
899 {
900 	struct bnxt *bp = eth_dev->data->dev_private;
901 	int rc = 0;
902 
903 	if (!bp->link_info.link_up)
904 		rc = bnxt_set_hwrm_link_config(bp, true);
905 	if (!rc)
906 		eth_dev->data->dev_link.link_status = 1;
907 
908 	bnxt_print_link_info(eth_dev);
909 	return rc;
910 }
911 
912 static int bnxt_dev_set_link_down_op(struct rte_eth_dev *eth_dev)
913 {
914 	struct bnxt *bp = eth_dev->data->dev_private;
915 
916 	eth_dev->data->dev_link.link_status = 0;
917 	bnxt_set_hwrm_link_config(bp, false);
918 	bp->link_info.link_up = 0;
919 
920 	return 0;
921 }
922 
923 /* Unload the driver, release resources */
924 static void bnxt_dev_stop_op(struct rte_eth_dev *eth_dev)
925 {
926 	struct bnxt *bp = eth_dev->data->dev_private;
927 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
928 	struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
929 
930 	eth_dev->data->dev_started = 0;
931 	/* Prevent crashes when queues are still in use */
932 	eth_dev->rx_pkt_burst = &bnxt_dummy_recv_pkts;
933 	eth_dev->tx_pkt_burst = &bnxt_dummy_xmit_pkts;
934 
935 	bnxt_disable_int(bp);
936 
937 	/* disable uio/vfio intr/eventfd mapping */
938 	rte_intr_disable(intr_handle);
939 
940 	bnxt_cancel_fw_health_check(bp);
941 
942 	bp->flags &= ~BNXT_FLAG_INIT_DONE;
943 	if (bp->eth_dev->data->dev_started) {
944 		/* TBD: STOP HW queues DMA */
945 		eth_dev->data->dev_link.link_status = 0;
946 	}
947 	bnxt_dev_set_link_down_op(eth_dev);
948 
949 	/* Wait for link to be reset and the async notification to process.
950 	 * During reset recovery, there is no need to wait
951 	 */
952 	if (!is_bnxt_in_error(bp))
953 		rte_delay_ms(BNXT_LINK_WAIT_INTERVAL * 2);
954 
955 	/* Clean queue intr-vector mapping */
956 	rte_intr_efd_disable(intr_handle);
957 	if (intr_handle->intr_vec != NULL) {
958 		rte_free(intr_handle->intr_vec);
959 		intr_handle->intr_vec = NULL;
960 	}
961 
962 	bnxt_hwrm_port_clr_stats(bp);
963 	bnxt_free_tx_mbufs(bp);
964 	bnxt_free_rx_mbufs(bp);
965 	/* Process any remaining notifications in default completion queue */
966 	bnxt_int_handler(eth_dev);
967 	bnxt_shutdown_nic(bp);
968 	bnxt_hwrm_if_change(bp, 0);
969 	bp->dev_stopped = 1;
970 }
971 
972 static void bnxt_dev_close_op(struct rte_eth_dev *eth_dev)
973 {
974 	struct bnxt *bp = eth_dev->data->dev_private;
975 
976 	if (bp->dev_stopped == 0)
977 		bnxt_dev_stop_op(eth_dev);
978 
979 	if (eth_dev->data->mac_addrs != NULL) {
980 		rte_free(eth_dev->data->mac_addrs);
981 		eth_dev->data->mac_addrs = NULL;
982 	}
983 	if (bp->grp_info != NULL) {
984 		rte_free(bp->grp_info);
985 		bp->grp_info = NULL;
986 	}
987 
988 	bnxt_dev_uninit(eth_dev);
989 }
990 
991 static void bnxt_mac_addr_remove_op(struct rte_eth_dev *eth_dev,
992 				    uint32_t index)
993 {
994 	struct bnxt *bp = eth_dev->data->dev_private;
995 	uint64_t pool_mask = eth_dev->data->mac_pool_sel[index];
996 	struct bnxt_vnic_info *vnic;
997 	struct bnxt_filter_info *filter, *temp_filter;
998 	uint32_t i;
999 
1000 	if (is_bnxt_in_error(bp))
1001 		return;
1002 
1003 	/*
1004 	 * Loop through all VNICs from the specified filter flow pools to
1005 	 * remove the corresponding MAC addr filter
1006 	 */
1007 	for (i = 0; i < bp->nr_vnics; i++) {
1008 		if (!(pool_mask & (1ULL << i)))
1009 			continue;
1010 
1011 		vnic = &bp->vnic_info[i];
1012 		filter = STAILQ_FIRST(&vnic->filter);
1013 		while (filter) {
1014 			temp_filter = STAILQ_NEXT(filter, next);
1015 			if (filter->mac_index == index) {
1016 				STAILQ_REMOVE(&vnic->filter, filter,
1017 						bnxt_filter_info, next);
1018 				bnxt_hwrm_clear_l2_filter(bp, filter);
1019 				filter->mac_index = INVALID_MAC_INDEX;
1020 				memset(&filter->l2_addr, 0, RTE_ETHER_ADDR_LEN);
1021 				STAILQ_INSERT_TAIL(&bp->free_filter_list,
1022 						   filter, next);
1023 			}
1024 			filter = temp_filter;
1025 		}
1026 	}
1027 }
1028 
1029 static int bnxt_add_mac_filter(struct bnxt *bp, struct bnxt_vnic_info *vnic,
1030 			       struct rte_ether_addr *mac_addr, uint32_t index)
1031 {
1032 	struct bnxt_filter_info *filter;
1033 	int rc = 0;
1034 
1035 	filter = STAILQ_FIRST(&vnic->filter);
1036 	/* During bnxt_mac_addr_add_op, default MAC is
1037 	 * already programmed, so skip it. But, when
1038 	 * hw-vlan-filter is turned OFF from ON, default
1039 	 * MAC filter should be restored
1040 	 */
1041 	if (index == 0 && filter->dflt)
1042 		return 0;
1043 
1044 	filter = bnxt_alloc_filter(bp);
1045 	if (!filter) {
1046 		PMD_DRV_LOG(ERR, "L2 filter alloc failed\n");
1047 		return -ENODEV;
1048 	}
1049 
1050 	filter->mac_index = index;
1051 	/* bnxt_alloc_filter copies default MAC to filter->l2_addr. So,
1052 	 * if the MAC that's been programmed now is a different one, then,
1053 	 * copy that addr to filter->l2_addr
1054 	 */
1055 	if (mac_addr)
1056 		memcpy(filter->l2_addr, mac_addr, RTE_ETHER_ADDR_LEN);
1057 	filter->flags |= HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_OUTERMOST;
1058 
1059 	rc = bnxt_hwrm_set_l2_filter(bp, vnic->fw_vnic_id, filter);
1060 	if (!rc) {
1061 		if (filter->mac_index == 0) {
1062 			filter->dflt = true;
1063 			STAILQ_INSERT_HEAD(&vnic->filter, filter, next);
1064 		} else {
1065 			STAILQ_INSERT_TAIL(&vnic->filter, filter, next);
1066 		}
1067 	} else {
1068 		filter->mac_index = INVALID_MAC_INDEX;
1069 		memset(&filter->l2_addr, 0, RTE_ETHER_ADDR_LEN);
1070 		bnxt_free_filter(bp, filter);
1071 	}
1072 
1073 	return rc;
1074 }
1075 
1076 static int bnxt_mac_addr_add_op(struct rte_eth_dev *eth_dev,
1077 				struct rte_ether_addr *mac_addr,
1078 				uint32_t index, uint32_t pool)
1079 {
1080 	struct bnxt *bp = eth_dev->data->dev_private;
1081 	struct bnxt_vnic_info *vnic = &bp->vnic_info[pool];
1082 	struct bnxt_filter_info *filter;
1083 	int rc = 0;
1084 
1085 	rc = is_bnxt_in_error(bp);
1086 	if (rc)
1087 		return rc;
1088 
1089 	if (BNXT_VF(bp) & !BNXT_VF_IS_TRUSTED(bp)) {
1090 		PMD_DRV_LOG(ERR, "Cannot add MAC address to a VF interface\n");
1091 		return -ENOTSUP;
1092 	}
1093 
1094 	if (!vnic) {
1095 		PMD_DRV_LOG(ERR, "VNIC not found for pool %d!\n", pool);
1096 		return -EINVAL;
1097 	}
1098 	/* Attach requested MAC address to the new l2_filter */
1099 	STAILQ_FOREACH(filter, &vnic->filter, next) {
1100 		if (filter->mac_index == index) {
1101 			PMD_DRV_LOG(ERR,
1102 				"MAC addr already existed for pool %d\n", pool);
1103 			return 0;
1104 		}
1105 	}
1106 
1107 	rc = bnxt_add_mac_filter(bp, vnic, mac_addr, index);
1108 
1109 	return rc;
1110 }
1111 
1112 int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete)
1113 {
1114 	int rc = 0;
1115 	struct bnxt *bp = eth_dev->data->dev_private;
1116 	struct rte_eth_link new;
1117 	unsigned int cnt = BNXT_LINK_WAIT_CNT;
1118 
1119 	rc = is_bnxt_in_error(bp);
1120 	if (rc)
1121 		return rc;
1122 
1123 	memset(&new, 0, sizeof(new));
1124 	do {
1125 		/* Retrieve link info from hardware */
1126 		rc = bnxt_get_hwrm_link_config(bp, &new);
1127 		if (rc) {
1128 			new.link_speed = ETH_LINK_SPEED_100M;
1129 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
1130 			PMD_DRV_LOG(ERR,
1131 				"Failed to retrieve link rc = 0x%x!\n", rc);
1132 			goto out;
1133 		}
1134 
1135 		if (!wait_to_complete || new.link_status)
1136 			break;
1137 
1138 		rte_delay_ms(BNXT_LINK_WAIT_INTERVAL);
1139 	} while (cnt--);
1140 
1141 out:
1142 	/* Timed out or success */
1143 	if (new.link_status != eth_dev->data->dev_link.link_status ||
1144 	new.link_speed != eth_dev->data->dev_link.link_speed) {
1145 		rte_eth_linkstatus_set(eth_dev, &new);
1146 
1147 		_rte_eth_dev_callback_process(eth_dev,
1148 					      RTE_ETH_EVENT_INTR_LSC,
1149 					      NULL);
1150 
1151 		bnxt_print_link_info(eth_dev);
1152 	}
1153 
1154 	return rc;
1155 }
1156 
1157 static int bnxt_promiscuous_enable_op(struct rte_eth_dev *eth_dev)
1158 {
1159 	struct bnxt *bp = eth_dev->data->dev_private;
1160 	struct bnxt_vnic_info *vnic;
1161 	uint32_t old_flags;
1162 	int rc;
1163 
1164 	rc = is_bnxt_in_error(bp);
1165 	if (rc)
1166 		return rc;
1167 
1168 	if (bp->vnic_info == NULL)
1169 		return 0;
1170 
1171 	vnic = BNXT_GET_DEFAULT_VNIC(bp);
1172 
1173 	old_flags = vnic->flags;
1174 	vnic->flags |= BNXT_VNIC_INFO_PROMISC;
1175 	rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
1176 	if (rc != 0)
1177 		vnic->flags = old_flags;
1178 
1179 	return rc;
1180 }
1181 
1182 static int bnxt_promiscuous_disable_op(struct rte_eth_dev *eth_dev)
1183 {
1184 	struct bnxt *bp = eth_dev->data->dev_private;
1185 	struct bnxt_vnic_info *vnic;
1186 	uint32_t old_flags;
1187 	int rc;
1188 
1189 	rc = is_bnxt_in_error(bp);
1190 	if (rc)
1191 		return rc;
1192 
1193 	if (bp->vnic_info == NULL)
1194 		return 0;
1195 
1196 	vnic = BNXT_GET_DEFAULT_VNIC(bp);
1197 
1198 	old_flags = vnic->flags;
1199 	vnic->flags &= ~BNXT_VNIC_INFO_PROMISC;
1200 	rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
1201 	if (rc != 0)
1202 		vnic->flags = old_flags;
1203 
1204 	return rc;
1205 }
1206 
1207 static int bnxt_allmulticast_enable_op(struct rte_eth_dev *eth_dev)
1208 {
1209 	struct bnxt *bp = eth_dev->data->dev_private;
1210 	struct bnxt_vnic_info *vnic;
1211 	uint32_t old_flags;
1212 	int rc;
1213 
1214 	rc = is_bnxt_in_error(bp);
1215 	if (rc)
1216 		return rc;
1217 
1218 	if (bp->vnic_info == NULL)
1219 		return 0;
1220 
1221 	vnic = BNXT_GET_DEFAULT_VNIC(bp);
1222 
1223 	old_flags = vnic->flags;
1224 	vnic->flags |= BNXT_VNIC_INFO_ALLMULTI;
1225 	rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
1226 	if (rc != 0)
1227 		vnic->flags = old_flags;
1228 
1229 	return rc;
1230 }
1231 
1232 static int bnxt_allmulticast_disable_op(struct rte_eth_dev *eth_dev)
1233 {
1234 	struct bnxt *bp = eth_dev->data->dev_private;
1235 	struct bnxt_vnic_info *vnic;
1236 	uint32_t old_flags;
1237 	int rc;
1238 
1239 	rc = is_bnxt_in_error(bp);
1240 	if (rc)
1241 		return rc;
1242 
1243 	if (bp->vnic_info == NULL)
1244 		return 0;
1245 
1246 	vnic = BNXT_GET_DEFAULT_VNIC(bp);
1247 
1248 	old_flags = vnic->flags;
1249 	vnic->flags &= ~BNXT_VNIC_INFO_ALLMULTI;
1250 	rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
1251 	if (rc != 0)
1252 		vnic->flags = old_flags;
1253 
1254 	return rc;
1255 }
1256 
1257 /* Return bnxt_rx_queue pointer corresponding to a given rxq. */
1258 static struct bnxt_rx_queue *bnxt_qid_to_rxq(struct bnxt *bp, uint16_t qid)
1259 {
1260 	if (qid >= bp->rx_nr_rings)
1261 		return NULL;
1262 
1263 	return bp->eth_dev->data->rx_queues[qid];
1264 }
1265 
1266 /* Return rxq corresponding to a given rss table ring/group ID. */
1267 static uint16_t bnxt_rss_to_qid(struct bnxt *bp, uint16_t fwr)
1268 {
1269 	struct bnxt_rx_queue *rxq;
1270 	unsigned int i;
1271 
1272 	if (!BNXT_HAS_RING_GRPS(bp)) {
1273 		for (i = 0; i < bp->rx_nr_rings; i++) {
1274 			rxq = bp->eth_dev->data->rx_queues[i];
1275 			if (rxq->rx_ring->rx_ring_struct->fw_ring_id == fwr)
1276 				return rxq->index;
1277 		}
1278 	} else {
1279 		for (i = 0; i < bp->rx_nr_rings; i++) {
1280 			if (bp->grp_info[i].fw_grp_id == fwr)
1281 				return i;
1282 		}
1283 	}
1284 
1285 	return INVALID_HW_RING_ID;
1286 }
1287 
1288 static int bnxt_reta_update_op(struct rte_eth_dev *eth_dev,
1289 			    struct rte_eth_rss_reta_entry64 *reta_conf,
1290 			    uint16_t reta_size)
1291 {
1292 	struct bnxt *bp = eth_dev->data->dev_private;
1293 	struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
1294 	struct bnxt_vnic_info *vnic = &bp->vnic_info[0];
1295 	uint16_t tbl_size = bnxt_rss_hash_tbl_size(bp);
1296 	uint16_t idx, sft;
1297 	int i, rc;
1298 
1299 	rc = is_bnxt_in_error(bp);
1300 	if (rc)
1301 		return rc;
1302 
1303 	if (!vnic->rss_table)
1304 		return -EINVAL;
1305 
1306 	if (!(dev_conf->rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG))
1307 		return -EINVAL;
1308 
1309 	if (reta_size != tbl_size) {
1310 		PMD_DRV_LOG(ERR, "The configured hash table lookup size "
1311 			"(%d) must equal the size supported by the hardware "
1312 			"(%d)\n", reta_size, tbl_size);
1313 		return -EINVAL;
1314 	}
1315 
1316 	for (i = 0; i < reta_size; i++) {
1317 		struct bnxt_rx_queue *rxq;
1318 
1319 		idx = i / RTE_RETA_GROUP_SIZE;
1320 		sft = i % RTE_RETA_GROUP_SIZE;
1321 
1322 		if (!(reta_conf[idx].mask & (1ULL << sft)))
1323 			continue;
1324 
1325 		rxq = bnxt_qid_to_rxq(bp, reta_conf[idx].reta[sft]);
1326 		if (!rxq) {
1327 			PMD_DRV_LOG(ERR, "Invalid ring in reta_conf.\n");
1328 			return -EINVAL;
1329 		}
1330 
1331 		if (BNXT_CHIP_THOR(bp)) {
1332 			vnic->rss_table[i * 2] =
1333 				rxq->rx_ring->rx_ring_struct->fw_ring_id;
1334 			vnic->rss_table[i * 2 + 1] =
1335 				rxq->cp_ring->cp_ring_struct->fw_ring_id;
1336 		} else {
1337 			vnic->rss_table[i] =
1338 			    vnic->fw_grp_ids[reta_conf[idx].reta[sft]];
1339 		}
1340 	}
1341 
1342 	bnxt_hwrm_vnic_rss_cfg(bp, vnic);
1343 	return 0;
1344 }
1345 
1346 static int bnxt_reta_query_op(struct rte_eth_dev *eth_dev,
1347 			      struct rte_eth_rss_reta_entry64 *reta_conf,
1348 			      uint16_t reta_size)
1349 {
1350 	struct bnxt *bp = eth_dev->data->dev_private;
1351 	struct bnxt_vnic_info *vnic = &bp->vnic_info[0];
1352 	uint16_t tbl_size = bnxt_rss_hash_tbl_size(bp);
1353 	uint16_t idx, sft, i;
1354 	int rc;
1355 
1356 	rc = is_bnxt_in_error(bp);
1357 	if (rc)
1358 		return rc;
1359 
1360 	/* Retrieve from the default VNIC */
1361 	if (!vnic)
1362 		return -EINVAL;
1363 	if (!vnic->rss_table)
1364 		return -EINVAL;
1365 
1366 	if (reta_size != tbl_size) {
1367 		PMD_DRV_LOG(ERR, "The configured hash table lookup size "
1368 			"(%d) must equal the size supported by the hardware "
1369 			"(%d)\n", reta_size, tbl_size);
1370 		return -EINVAL;
1371 	}
1372 
1373 	for (idx = 0, i = 0; i < reta_size; i++) {
1374 		idx = i / RTE_RETA_GROUP_SIZE;
1375 		sft = i % RTE_RETA_GROUP_SIZE;
1376 
1377 		if (reta_conf[idx].mask & (1ULL << sft)) {
1378 			uint16_t qid;
1379 
1380 			if (BNXT_CHIP_THOR(bp))
1381 				qid = bnxt_rss_to_qid(bp,
1382 						      vnic->rss_table[i * 2]);
1383 			else
1384 				qid = bnxt_rss_to_qid(bp, vnic->rss_table[i]);
1385 
1386 			if (qid == INVALID_HW_RING_ID) {
1387 				PMD_DRV_LOG(ERR, "Inv. entry in rss table.\n");
1388 				return -EINVAL;
1389 			}
1390 			reta_conf[idx].reta[sft] = qid;
1391 		}
1392 	}
1393 
1394 	return 0;
1395 }
1396 
1397 static int bnxt_rss_hash_update_op(struct rte_eth_dev *eth_dev,
1398 				   struct rte_eth_rss_conf *rss_conf)
1399 {
1400 	struct bnxt *bp = eth_dev->data->dev_private;
1401 	struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
1402 	struct bnxt_vnic_info *vnic;
1403 	int rc;
1404 
1405 	rc = is_bnxt_in_error(bp);
1406 	if (rc)
1407 		return rc;
1408 
1409 	/*
1410 	 * If RSS enablement were different than dev_configure,
1411 	 * then return -EINVAL
1412 	 */
1413 	if (dev_conf->rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG) {
1414 		if (!rss_conf->rss_hf)
1415 			PMD_DRV_LOG(ERR, "Hash type NONE\n");
1416 	} else {
1417 		if (rss_conf->rss_hf & BNXT_ETH_RSS_SUPPORT)
1418 			return -EINVAL;
1419 	}
1420 
1421 	bp->flags |= BNXT_FLAG_UPDATE_HASH;
1422 	memcpy(&bp->rss_conf, rss_conf, sizeof(*rss_conf));
1423 
1424 	/* Update the default RSS VNIC(s) */
1425 	vnic = &bp->vnic_info[0];
1426 	vnic->hash_type = bnxt_rte_to_hwrm_hash_types(rss_conf->rss_hf);
1427 
1428 	/*
1429 	 * If hashkey is not specified, use the previously configured
1430 	 * hashkey
1431 	 */
1432 	if (!rss_conf->rss_key)
1433 		goto rss_config;
1434 
1435 	if (rss_conf->rss_key_len != HW_HASH_KEY_SIZE) {
1436 		PMD_DRV_LOG(ERR,
1437 			    "Invalid hashkey length, should be 16 bytes\n");
1438 		return -EINVAL;
1439 	}
1440 	memcpy(vnic->rss_hash_key, rss_conf->rss_key, rss_conf->rss_key_len);
1441 
1442 rss_config:
1443 	bnxt_hwrm_vnic_rss_cfg(bp, vnic);
1444 	return 0;
1445 }
1446 
1447 static int bnxt_rss_hash_conf_get_op(struct rte_eth_dev *eth_dev,
1448 				     struct rte_eth_rss_conf *rss_conf)
1449 {
1450 	struct bnxt *bp = eth_dev->data->dev_private;
1451 	struct bnxt_vnic_info *vnic = &bp->vnic_info[0];
1452 	int len, rc;
1453 	uint32_t hash_types;
1454 
1455 	rc = is_bnxt_in_error(bp);
1456 	if (rc)
1457 		return rc;
1458 
1459 	/* RSS configuration is the same for all VNICs */
1460 	if (vnic && vnic->rss_hash_key) {
1461 		if (rss_conf->rss_key) {
1462 			len = rss_conf->rss_key_len <= HW_HASH_KEY_SIZE ?
1463 			      rss_conf->rss_key_len : HW_HASH_KEY_SIZE;
1464 			memcpy(rss_conf->rss_key, vnic->rss_hash_key, len);
1465 		}
1466 
1467 		hash_types = vnic->hash_type;
1468 		rss_conf->rss_hf = 0;
1469 		if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4) {
1470 			rss_conf->rss_hf |= ETH_RSS_IPV4;
1471 			hash_types &= ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4;
1472 		}
1473 		if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4) {
1474 			rss_conf->rss_hf |= ETH_RSS_NONFRAG_IPV4_TCP;
1475 			hash_types &=
1476 				~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4;
1477 		}
1478 		if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4) {
1479 			rss_conf->rss_hf |= ETH_RSS_NONFRAG_IPV4_UDP;
1480 			hash_types &=
1481 				~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4;
1482 		}
1483 		if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6) {
1484 			rss_conf->rss_hf |= ETH_RSS_IPV6;
1485 			hash_types &= ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6;
1486 		}
1487 		if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6) {
1488 			rss_conf->rss_hf |= ETH_RSS_NONFRAG_IPV6_TCP;
1489 			hash_types &=
1490 				~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6;
1491 		}
1492 		if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6) {
1493 			rss_conf->rss_hf |= ETH_RSS_NONFRAG_IPV6_UDP;
1494 			hash_types &=
1495 				~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6;
1496 		}
1497 		if (hash_types) {
1498 			PMD_DRV_LOG(ERR,
1499 				"Unknwon RSS config from firmware (%08x), RSS disabled",
1500 				vnic->hash_type);
1501 			return -ENOTSUP;
1502 		}
1503 	} else {
1504 		rss_conf->rss_hf = 0;
1505 	}
1506 	return 0;
1507 }
1508 
1509 static int bnxt_flow_ctrl_get_op(struct rte_eth_dev *dev,
1510 			       struct rte_eth_fc_conf *fc_conf)
1511 {
1512 	struct bnxt *bp = dev->data->dev_private;
1513 	struct rte_eth_link link_info;
1514 	int rc;
1515 
1516 	rc = is_bnxt_in_error(bp);
1517 	if (rc)
1518 		return rc;
1519 
1520 	rc = bnxt_get_hwrm_link_config(bp, &link_info);
1521 	if (rc)
1522 		return rc;
1523 
1524 	memset(fc_conf, 0, sizeof(*fc_conf));
1525 	if (bp->link_info.auto_pause)
1526 		fc_conf->autoneg = 1;
1527 	switch (bp->link_info.pause) {
1528 	case 0:
1529 		fc_conf->mode = RTE_FC_NONE;
1530 		break;
1531 	case HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX:
1532 		fc_conf->mode = RTE_FC_TX_PAUSE;
1533 		break;
1534 	case HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX:
1535 		fc_conf->mode = RTE_FC_RX_PAUSE;
1536 		break;
1537 	case (HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX |
1538 			HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX):
1539 		fc_conf->mode = RTE_FC_FULL;
1540 		break;
1541 	}
1542 	return 0;
1543 }
1544 
1545 static int bnxt_flow_ctrl_set_op(struct rte_eth_dev *dev,
1546 			       struct rte_eth_fc_conf *fc_conf)
1547 {
1548 	struct bnxt *bp = dev->data->dev_private;
1549 	int rc;
1550 
1551 	rc = is_bnxt_in_error(bp);
1552 	if (rc)
1553 		return rc;
1554 
1555 	if (!BNXT_SINGLE_PF(bp) || BNXT_VF(bp)) {
1556 		PMD_DRV_LOG(ERR, "Flow Control Settings cannot be modified\n");
1557 		return -ENOTSUP;
1558 	}
1559 
1560 	switch (fc_conf->mode) {
1561 	case RTE_FC_NONE:
1562 		bp->link_info.auto_pause = 0;
1563 		bp->link_info.force_pause = 0;
1564 		break;
1565 	case RTE_FC_RX_PAUSE:
1566 		if (fc_conf->autoneg) {
1567 			bp->link_info.auto_pause =
1568 					HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_RX;
1569 			bp->link_info.force_pause = 0;
1570 		} else {
1571 			bp->link_info.auto_pause = 0;
1572 			bp->link_info.force_pause =
1573 					HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_RX;
1574 		}
1575 		break;
1576 	case RTE_FC_TX_PAUSE:
1577 		if (fc_conf->autoneg) {
1578 			bp->link_info.auto_pause =
1579 					HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_TX;
1580 			bp->link_info.force_pause = 0;
1581 		} else {
1582 			bp->link_info.auto_pause = 0;
1583 			bp->link_info.force_pause =
1584 					HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_TX;
1585 		}
1586 		break;
1587 	case RTE_FC_FULL:
1588 		if (fc_conf->autoneg) {
1589 			bp->link_info.auto_pause =
1590 					HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_TX |
1591 					HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_RX;
1592 			bp->link_info.force_pause = 0;
1593 		} else {
1594 			bp->link_info.auto_pause = 0;
1595 			bp->link_info.force_pause =
1596 					HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_TX |
1597 					HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_RX;
1598 		}
1599 		break;
1600 	}
1601 	return bnxt_set_hwrm_link_config(bp, true);
1602 }
1603 
1604 /* Add UDP tunneling port */
1605 static int
1606 bnxt_udp_tunnel_port_add_op(struct rte_eth_dev *eth_dev,
1607 			 struct rte_eth_udp_tunnel *udp_tunnel)
1608 {
1609 	struct bnxt *bp = eth_dev->data->dev_private;
1610 	uint16_t tunnel_type = 0;
1611 	int rc = 0;
1612 
1613 	rc = is_bnxt_in_error(bp);
1614 	if (rc)
1615 		return rc;
1616 
1617 	switch (udp_tunnel->prot_type) {
1618 	case RTE_TUNNEL_TYPE_VXLAN:
1619 		if (bp->vxlan_port_cnt) {
1620 			PMD_DRV_LOG(ERR, "Tunnel Port %d already programmed\n",
1621 				udp_tunnel->udp_port);
1622 			if (bp->vxlan_port != udp_tunnel->udp_port) {
1623 				PMD_DRV_LOG(ERR, "Only one port allowed\n");
1624 				return -ENOSPC;
1625 			}
1626 			bp->vxlan_port_cnt++;
1627 			return 0;
1628 		}
1629 		tunnel_type =
1630 			HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN;
1631 		bp->vxlan_port_cnt++;
1632 		break;
1633 	case RTE_TUNNEL_TYPE_GENEVE:
1634 		if (bp->geneve_port_cnt) {
1635 			PMD_DRV_LOG(ERR, "Tunnel Port %d already programmed\n",
1636 				udp_tunnel->udp_port);
1637 			if (bp->geneve_port != udp_tunnel->udp_port) {
1638 				PMD_DRV_LOG(ERR, "Only one port allowed\n");
1639 				return -ENOSPC;
1640 			}
1641 			bp->geneve_port_cnt++;
1642 			return 0;
1643 		}
1644 		tunnel_type =
1645 			HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_GENEVE;
1646 		bp->geneve_port_cnt++;
1647 		break;
1648 	default:
1649 		PMD_DRV_LOG(ERR, "Tunnel type is not supported\n");
1650 		return -ENOTSUP;
1651 	}
1652 	rc = bnxt_hwrm_tunnel_dst_port_alloc(bp, udp_tunnel->udp_port,
1653 					     tunnel_type);
1654 	return rc;
1655 }
1656 
1657 static int
1658 bnxt_udp_tunnel_port_del_op(struct rte_eth_dev *eth_dev,
1659 			 struct rte_eth_udp_tunnel *udp_tunnel)
1660 {
1661 	struct bnxt *bp = eth_dev->data->dev_private;
1662 	uint16_t tunnel_type = 0;
1663 	uint16_t port = 0;
1664 	int rc = 0;
1665 
1666 	rc = is_bnxt_in_error(bp);
1667 	if (rc)
1668 		return rc;
1669 
1670 	switch (udp_tunnel->prot_type) {
1671 	case RTE_TUNNEL_TYPE_VXLAN:
1672 		if (!bp->vxlan_port_cnt) {
1673 			PMD_DRV_LOG(ERR, "No Tunnel port configured yet\n");
1674 			return -EINVAL;
1675 		}
1676 		if (bp->vxlan_port != udp_tunnel->udp_port) {
1677 			PMD_DRV_LOG(ERR, "Req Port: %d. Configured port: %d\n",
1678 				udp_tunnel->udp_port, bp->vxlan_port);
1679 			return -EINVAL;
1680 		}
1681 		if (--bp->vxlan_port_cnt)
1682 			return 0;
1683 
1684 		tunnel_type =
1685 			HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_VXLAN;
1686 		port = bp->vxlan_fw_dst_port_id;
1687 		break;
1688 	case RTE_TUNNEL_TYPE_GENEVE:
1689 		if (!bp->geneve_port_cnt) {
1690 			PMD_DRV_LOG(ERR, "No Tunnel port configured yet\n");
1691 			return -EINVAL;
1692 		}
1693 		if (bp->geneve_port != udp_tunnel->udp_port) {
1694 			PMD_DRV_LOG(ERR, "Req Port: %d. Configured port: %d\n",
1695 				udp_tunnel->udp_port, bp->geneve_port);
1696 			return -EINVAL;
1697 		}
1698 		if (--bp->geneve_port_cnt)
1699 			return 0;
1700 
1701 		tunnel_type =
1702 			HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_GENEVE;
1703 		port = bp->geneve_fw_dst_port_id;
1704 		break;
1705 	default:
1706 		PMD_DRV_LOG(ERR, "Tunnel type is not supported\n");
1707 		return -ENOTSUP;
1708 	}
1709 
1710 	rc = bnxt_hwrm_tunnel_dst_port_free(bp, port, tunnel_type);
1711 	if (!rc) {
1712 		if (tunnel_type ==
1713 		    HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_VXLAN)
1714 			bp->vxlan_port = 0;
1715 		if (tunnel_type ==
1716 		    HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_GENEVE)
1717 			bp->geneve_port = 0;
1718 	}
1719 	return rc;
1720 }
1721 
1722 static int bnxt_del_vlan_filter(struct bnxt *bp, uint16_t vlan_id)
1723 {
1724 	struct bnxt_filter_info *filter;
1725 	struct bnxt_vnic_info *vnic;
1726 	int rc = 0;
1727 	uint32_t chk = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN;
1728 
1729 	/* if VLAN exists && VLAN matches vlan_id
1730 	 *      remove the MAC+VLAN filter
1731 	 *      add a new MAC only filter
1732 	 * else
1733 	 *      VLAN filter doesn't exist, just skip and continue
1734 	 */
1735 	vnic = BNXT_GET_DEFAULT_VNIC(bp);
1736 	filter = STAILQ_FIRST(&vnic->filter);
1737 	while (filter) {
1738 		/* Search for this matching MAC+VLAN filter */
1739 		if ((filter->enables & chk) &&
1740 		    (filter->l2_ivlan == vlan_id &&
1741 		     filter->l2_ivlan_mask != 0) &&
1742 		    !memcmp(filter->l2_addr, bp->mac_addr,
1743 			    RTE_ETHER_ADDR_LEN)) {
1744 			/* Delete the filter */
1745 			rc = bnxt_hwrm_clear_l2_filter(bp, filter);
1746 			if (rc)
1747 				return rc;
1748 			STAILQ_REMOVE(&vnic->filter, filter,
1749 				      bnxt_filter_info, next);
1750 			STAILQ_INSERT_TAIL(&bp->free_filter_list, filter, next);
1751 
1752 			PMD_DRV_LOG(INFO,
1753 				    "Del Vlan filter for %d\n",
1754 				    vlan_id);
1755 			return rc;
1756 		}
1757 		filter = STAILQ_NEXT(filter, next);
1758 	}
1759 	return -ENOENT;
1760 }
1761 
1762 static int bnxt_add_vlan_filter(struct bnxt *bp, uint16_t vlan_id)
1763 {
1764 	struct bnxt_filter_info *filter;
1765 	struct bnxt_vnic_info *vnic;
1766 	int rc = 0;
1767 	uint32_t en = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN |
1768 		HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN_MASK;
1769 	uint32_t chk = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN;
1770 
1771 	/* Implementation notes on the use of VNIC in this command:
1772 	 *
1773 	 * By default, these filters belong to default vnic for the function.
1774 	 * Once these filters are set up, only destination VNIC can be modified.
1775 	 * If the destination VNIC is not specified in this command,
1776 	 * then the HWRM shall only create an l2 context id.
1777 	 */
1778 
1779 	vnic = BNXT_GET_DEFAULT_VNIC(bp);
1780 	filter = STAILQ_FIRST(&vnic->filter);
1781 	/* Check if the VLAN has already been added */
1782 	while (filter) {
1783 		if ((filter->enables & chk) &&
1784 		    (filter->l2_ivlan == vlan_id &&
1785 		     filter->l2_ivlan_mask == 0x0FFF) &&
1786 		     !memcmp(filter->l2_addr, bp->mac_addr,
1787 			     RTE_ETHER_ADDR_LEN))
1788 			return -EEXIST;
1789 
1790 		filter = STAILQ_NEXT(filter, next);
1791 	}
1792 
1793 	/* No match found. Alloc a fresh filter and issue the L2_FILTER_ALLOC
1794 	 * command to create MAC+VLAN filter with the right flags, enables set.
1795 	 */
1796 	filter = bnxt_alloc_filter(bp);
1797 	if (!filter) {
1798 		PMD_DRV_LOG(ERR,
1799 			    "MAC/VLAN filter alloc failed\n");
1800 		return -ENOMEM;
1801 	}
1802 	/* MAC + VLAN ID filter */
1803 	/* If l2_ivlan == 0 and l2_ivlan_mask != 0, only
1804 	 * untagged packets are received
1805 	 *
1806 	 * If l2_ivlan != 0 and l2_ivlan_mask != 0, untagged
1807 	 * packets and only the programmed vlan's packets are received
1808 	 */
1809 	filter->l2_ivlan = vlan_id;
1810 	filter->l2_ivlan_mask = 0x0FFF;
1811 	filter->enables |= en;
1812 	filter->flags |= HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_OUTERMOST;
1813 
1814 	rc = bnxt_hwrm_set_l2_filter(bp, vnic->fw_vnic_id, filter);
1815 	if (rc) {
1816 		/* Free the newly allocated filter as we were
1817 		 * not able to create the filter in hardware.
1818 		 */
1819 		filter->fw_l2_filter_id = UINT64_MAX;
1820 		STAILQ_INSERT_TAIL(&bp->free_filter_list, filter, next);
1821 		return rc;
1822 	} else {
1823 		/* Add this new filter to the list */
1824 		if (vlan_id == 0) {
1825 			filter->dflt = true;
1826 			STAILQ_INSERT_HEAD(&vnic->filter, filter, next);
1827 		} else {
1828 			STAILQ_INSERT_TAIL(&vnic->filter, filter, next);
1829 		}
1830 	}
1831 
1832 	PMD_DRV_LOG(INFO,
1833 		    "Added Vlan filter for %d\n", vlan_id);
1834 	return rc;
1835 }
1836 
1837 static int bnxt_vlan_filter_set_op(struct rte_eth_dev *eth_dev,
1838 		uint16_t vlan_id, int on)
1839 {
1840 	struct bnxt *bp = eth_dev->data->dev_private;
1841 	int rc;
1842 
1843 	rc = is_bnxt_in_error(bp);
1844 	if (rc)
1845 		return rc;
1846 
1847 	/* These operations apply to ALL existing MAC/VLAN filters */
1848 	if (on)
1849 		return bnxt_add_vlan_filter(bp, vlan_id);
1850 	else
1851 		return bnxt_del_vlan_filter(bp, vlan_id);
1852 }
1853 
1854 static int bnxt_del_dflt_mac_filter(struct bnxt *bp,
1855 				    struct bnxt_vnic_info *vnic)
1856 {
1857 	struct bnxt_filter_info *filter;
1858 	int rc;
1859 
1860 	filter = STAILQ_FIRST(&vnic->filter);
1861 	while (filter) {
1862 		if (filter->dflt &&
1863 		    !memcmp(filter->l2_addr, bp->mac_addr,
1864 			    RTE_ETHER_ADDR_LEN)) {
1865 			rc = bnxt_hwrm_clear_l2_filter(bp, filter);
1866 			if (rc)
1867 				return rc;
1868 			filter->dflt = false;
1869 			STAILQ_REMOVE(&vnic->filter, filter,
1870 				      bnxt_filter_info, next);
1871 			STAILQ_INSERT_TAIL(&bp->free_filter_list,
1872 					   filter, next);
1873 			filter->fw_l2_filter_id = -1;
1874 			break;
1875 		}
1876 		filter = STAILQ_NEXT(filter, next);
1877 	}
1878 	return 0;
1879 }
1880 
1881 static int
1882 bnxt_vlan_offload_set_op(struct rte_eth_dev *dev, int mask)
1883 {
1884 	struct bnxt *bp = dev->data->dev_private;
1885 	uint64_t rx_offloads = dev->data->dev_conf.rxmode.offloads;
1886 	struct bnxt_vnic_info *vnic;
1887 	unsigned int i;
1888 	int rc;
1889 
1890 	rc = is_bnxt_in_error(bp);
1891 	if (rc)
1892 		return rc;
1893 
1894 	vnic = BNXT_GET_DEFAULT_VNIC(bp);
1895 	if (!(rx_offloads & DEV_RX_OFFLOAD_VLAN_FILTER)) {
1896 		/* Remove any VLAN filters programmed */
1897 		for (i = 0; i < 4095; i++)
1898 			bnxt_del_vlan_filter(bp, i);
1899 
1900 		rc = bnxt_add_mac_filter(bp, vnic, NULL, 0);
1901 		if (rc)
1902 			return rc;
1903 	} else {
1904 		/* Default filter will allow packets that match the
1905 		 * dest mac. So, it has to be deleted, otherwise, we
1906 		 * will endup receiving vlan packets for which the
1907 		 * filter is not programmed, when hw-vlan-filter
1908 		 * configuration is ON
1909 		 */
1910 		bnxt_del_dflt_mac_filter(bp, vnic);
1911 		/* This filter will allow only untagged packets */
1912 		bnxt_add_vlan_filter(bp, 0);
1913 	}
1914 	PMD_DRV_LOG(DEBUG, "VLAN Filtering: %d\n",
1915 		    !!(rx_offloads & DEV_RX_OFFLOAD_VLAN_FILTER));
1916 
1917 	if (mask & ETH_VLAN_STRIP_MASK) {
1918 		/* Enable or disable VLAN stripping */
1919 		for (i = 0; i < bp->nr_vnics; i++) {
1920 			struct bnxt_vnic_info *vnic = &bp->vnic_info[i];
1921 			if (rx_offloads & DEV_RX_OFFLOAD_VLAN_STRIP)
1922 				vnic->vlan_strip = true;
1923 			else
1924 				vnic->vlan_strip = false;
1925 			bnxt_hwrm_vnic_cfg(bp, vnic);
1926 		}
1927 		PMD_DRV_LOG(DEBUG, "VLAN Strip Offload: %d\n",
1928 			!!(rx_offloads & DEV_RX_OFFLOAD_VLAN_STRIP));
1929 	}
1930 
1931 	if (mask & ETH_VLAN_EXTEND_MASK) {
1932 		if (rx_offloads & DEV_RX_OFFLOAD_VLAN_EXTEND)
1933 			PMD_DRV_LOG(DEBUG, "Extend VLAN supported\n");
1934 		else
1935 			PMD_DRV_LOG(INFO, "Extend VLAN unsupported\n");
1936 	}
1937 
1938 	return 0;
1939 }
1940 
1941 static int
1942 bnxt_vlan_tpid_set_op(struct rte_eth_dev *dev, enum rte_vlan_type vlan_type,
1943 		      uint16_t tpid)
1944 {
1945 	struct bnxt *bp = dev->data->dev_private;
1946 	int qinq = dev->data->dev_conf.rxmode.offloads &
1947 		   DEV_RX_OFFLOAD_VLAN_EXTEND;
1948 
1949 	if (vlan_type != ETH_VLAN_TYPE_INNER &&
1950 	    vlan_type != ETH_VLAN_TYPE_OUTER) {
1951 		PMD_DRV_LOG(ERR,
1952 			    "Unsupported vlan type.");
1953 		return -EINVAL;
1954 	}
1955 	if (!qinq) {
1956 		PMD_DRV_LOG(ERR,
1957 			    "QinQ not enabled. Needs to be ON as we can "
1958 			    "accelerate only outer vlan\n");
1959 		return -EINVAL;
1960 	}
1961 
1962 	if (vlan_type == ETH_VLAN_TYPE_OUTER) {
1963 		switch (tpid) {
1964 		case RTE_ETHER_TYPE_QINQ:
1965 			bp->outer_tpid_bd =
1966 				TX_BD_LONG_CFA_META_VLAN_TPID_TPID88A8;
1967 				break;
1968 		case RTE_ETHER_TYPE_VLAN:
1969 			bp->outer_tpid_bd =
1970 				TX_BD_LONG_CFA_META_VLAN_TPID_TPID8100;
1971 				break;
1972 		case 0x9100:
1973 			bp->outer_tpid_bd =
1974 				TX_BD_LONG_CFA_META_VLAN_TPID_TPID9100;
1975 				break;
1976 		case 0x9200:
1977 			bp->outer_tpid_bd =
1978 				TX_BD_LONG_CFA_META_VLAN_TPID_TPID9200;
1979 				break;
1980 		case 0x9300:
1981 			bp->outer_tpid_bd =
1982 				 TX_BD_LONG_CFA_META_VLAN_TPID_TPID9300;
1983 				break;
1984 		default:
1985 			PMD_DRV_LOG(ERR, "Invalid TPID: %x\n", tpid);
1986 			return -EINVAL;
1987 		}
1988 		bp->outer_tpid_bd |= tpid;
1989 		PMD_DRV_LOG(INFO, "outer_tpid_bd = %x\n", bp->outer_tpid_bd);
1990 	} else if (vlan_type == ETH_VLAN_TYPE_INNER) {
1991 		PMD_DRV_LOG(ERR,
1992 			    "Can accelerate only outer vlan in QinQ\n");
1993 		return -EINVAL;
1994 	}
1995 
1996 	return 0;
1997 }
1998 
1999 static int
2000 bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev,
2001 			     struct rte_ether_addr *addr)
2002 {
2003 	struct bnxt *bp = dev->data->dev_private;
2004 	/* Default Filter is tied to VNIC 0 */
2005 	struct bnxt_vnic_info *vnic = &bp->vnic_info[0];
2006 	struct bnxt_filter_info *filter;
2007 	int rc;
2008 
2009 	rc = is_bnxt_in_error(bp);
2010 	if (rc)
2011 		return rc;
2012 
2013 	if (BNXT_VF(bp) && !BNXT_VF_IS_TRUSTED(bp))
2014 		return -EPERM;
2015 
2016 	if (rte_is_zero_ether_addr(addr))
2017 		return -EINVAL;
2018 
2019 	STAILQ_FOREACH(filter, &vnic->filter, next) {
2020 		/* Default Filter is at Index 0 */
2021 		if (filter->mac_index != 0)
2022 			continue;
2023 
2024 		memcpy(filter->l2_addr, addr, RTE_ETHER_ADDR_LEN);
2025 		memset(filter->l2_addr_mask, 0xff, RTE_ETHER_ADDR_LEN);
2026 		filter->flags |= HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX |
2027 			HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_OUTERMOST;
2028 		filter->enables |=
2029 			HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR |
2030 			HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR_MASK;
2031 
2032 		rc = bnxt_hwrm_set_l2_filter(bp, vnic->fw_vnic_id, filter);
2033 		if (rc) {
2034 			memcpy(filter->l2_addr, bp->mac_addr,
2035 			       RTE_ETHER_ADDR_LEN);
2036 			return rc;
2037 		}
2038 
2039 		memcpy(bp->mac_addr, addr, RTE_ETHER_ADDR_LEN);
2040 		PMD_DRV_LOG(DEBUG, "Set MAC addr\n");
2041 		return 0;
2042 	}
2043 
2044 	return 0;
2045 }
2046 
2047 static int
2048 bnxt_dev_set_mc_addr_list_op(struct rte_eth_dev *eth_dev,
2049 			  struct rte_ether_addr *mc_addr_set,
2050 			  uint32_t nb_mc_addr)
2051 {
2052 	struct bnxt *bp = eth_dev->data->dev_private;
2053 	char *mc_addr_list = (char *)mc_addr_set;
2054 	struct bnxt_vnic_info *vnic;
2055 	uint32_t off = 0, i = 0;
2056 	int rc;
2057 
2058 	rc = is_bnxt_in_error(bp);
2059 	if (rc)
2060 		return rc;
2061 
2062 	vnic = BNXT_GET_DEFAULT_VNIC(bp);
2063 
2064 	if (nb_mc_addr > BNXT_MAX_MC_ADDRS) {
2065 		vnic->flags |= BNXT_VNIC_INFO_ALLMULTI;
2066 		goto allmulti;
2067 	}
2068 
2069 	/* TODO Check for Duplicate mcast addresses */
2070 	vnic->flags &= ~BNXT_VNIC_INFO_ALLMULTI;
2071 	for (i = 0; i < nb_mc_addr; i++) {
2072 		memcpy(vnic->mc_list + off, &mc_addr_list[i],
2073 			RTE_ETHER_ADDR_LEN);
2074 		off += RTE_ETHER_ADDR_LEN;
2075 	}
2076 
2077 	vnic->mc_addr_cnt = i;
2078 	if (vnic->mc_addr_cnt)
2079 		vnic->flags |= BNXT_VNIC_INFO_MCAST;
2080 	else
2081 		vnic->flags &= ~BNXT_VNIC_INFO_MCAST;
2082 
2083 allmulti:
2084 	return bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
2085 }
2086 
2087 static int
2088 bnxt_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size)
2089 {
2090 	struct bnxt *bp = dev->data->dev_private;
2091 	uint8_t fw_major = (bp->fw_ver >> 24) & 0xff;
2092 	uint8_t fw_minor = (bp->fw_ver >> 16) & 0xff;
2093 	uint8_t fw_updt = (bp->fw_ver >> 8) & 0xff;
2094 	int ret;
2095 
2096 	ret = snprintf(fw_version, fw_size, "%d.%d.%d",
2097 			fw_major, fw_minor, fw_updt);
2098 
2099 	ret += 1; /* add the size of '\0' */
2100 	if (fw_size < (uint32_t)ret)
2101 		return ret;
2102 	else
2103 		return 0;
2104 }
2105 
2106 static void
2107 bnxt_rxq_info_get_op(struct rte_eth_dev *dev, uint16_t queue_id,
2108 	struct rte_eth_rxq_info *qinfo)
2109 {
2110 	struct bnxt_rx_queue *rxq;
2111 
2112 	rxq = dev->data->rx_queues[queue_id];
2113 
2114 	qinfo->mp = rxq->mb_pool;
2115 	qinfo->scattered_rx = dev->data->scattered_rx;
2116 	qinfo->nb_desc = rxq->nb_rx_desc;
2117 
2118 	qinfo->conf.rx_free_thresh = rxq->rx_free_thresh;
2119 	qinfo->conf.rx_drop_en = 0;
2120 	qinfo->conf.rx_deferred_start = rxq->rx_deferred_start;
2121 }
2122 
2123 static void
2124 bnxt_txq_info_get_op(struct rte_eth_dev *dev, uint16_t queue_id,
2125 	struct rte_eth_txq_info *qinfo)
2126 {
2127 	struct bnxt_tx_queue *txq;
2128 
2129 	txq = dev->data->tx_queues[queue_id];
2130 
2131 	qinfo->nb_desc = txq->nb_tx_desc;
2132 
2133 	qinfo->conf.tx_thresh.pthresh = txq->pthresh;
2134 	qinfo->conf.tx_thresh.hthresh = txq->hthresh;
2135 	qinfo->conf.tx_thresh.wthresh = txq->wthresh;
2136 
2137 	qinfo->conf.tx_free_thresh = txq->tx_free_thresh;
2138 	qinfo->conf.tx_rs_thresh = 0;
2139 	qinfo->conf.tx_deferred_start = txq->tx_deferred_start;
2140 }
2141 
2142 int bnxt_mtu_set_op(struct rte_eth_dev *eth_dev, uint16_t new_mtu)
2143 {
2144 	struct bnxt *bp = eth_dev->data->dev_private;
2145 	uint32_t new_pkt_size;
2146 	uint32_t rc = 0;
2147 	uint32_t i;
2148 
2149 	rc = is_bnxt_in_error(bp);
2150 	if (rc)
2151 		return rc;
2152 
2153 	/* Exit if receive queues are not configured yet */
2154 	if (!eth_dev->data->nb_rx_queues)
2155 		return rc;
2156 
2157 	new_pkt_size = new_mtu + RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN +
2158 		       VLAN_TAG_SIZE * BNXT_NUM_VLANS;
2159 
2160 #ifdef RTE_ARCH_X86
2161 	/*
2162 	 * If vector-mode tx/rx is active, disallow any MTU change that would
2163 	 * require scattered receive support.
2164 	 */
2165 	if (eth_dev->data->dev_started &&
2166 	    (eth_dev->rx_pkt_burst == bnxt_recv_pkts_vec ||
2167 	     eth_dev->tx_pkt_burst == bnxt_xmit_pkts_vec) &&
2168 	    (new_pkt_size >
2169 	     eth_dev->data->min_rx_buf_size - RTE_PKTMBUF_HEADROOM)) {
2170 		PMD_DRV_LOG(ERR,
2171 			    "MTU change would require scattered rx support. ");
2172 		PMD_DRV_LOG(ERR, "Stop port before changing MTU.\n");
2173 		return -EINVAL;
2174 	}
2175 #endif
2176 
2177 	if (new_mtu > RTE_ETHER_MTU) {
2178 		bp->flags |= BNXT_FLAG_JUMBO;
2179 		bp->eth_dev->data->dev_conf.rxmode.offloads |=
2180 			DEV_RX_OFFLOAD_JUMBO_FRAME;
2181 	} else {
2182 		bp->eth_dev->data->dev_conf.rxmode.offloads &=
2183 			~DEV_RX_OFFLOAD_JUMBO_FRAME;
2184 		bp->flags &= ~BNXT_FLAG_JUMBO;
2185 	}
2186 
2187 	/* Is there a change in mtu setting? */
2188 	if (eth_dev->data->dev_conf.rxmode.max_rx_pkt_len == new_pkt_size)
2189 		return rc;
2190 
2191 	for (i = 0; i < bp->nr_vnics; i++) {
2192 		struct bnxt_vnic_info *vnic = &bp->vnic_info[i];
2193 		uint16_t size = 0;
2194 
2195 		vnic->mru = BNXT_VNIC_MRU(new_mtu);
2196 		rc = bnxt_hwrm_vnic_cfg(bp, vnic);
2197 		if (rc)
2198 			break;
2199 
2200 		size = rte_pktmbuf_data_room_size(bp->rx_queues[0]->mb_pool);
2201 		size -= RTE_PKTMBUF_HEADROOM;
2202 
2203 		if (size < new_mtu) {
2204 			rc = bnxt_hwrm_vnic_plcmode_cfg(bp, vnic);
2205 			if (rc)
2206 				return rc;
2207 		}
2208 	}
2209 
2210 	if (!rc)
2211 		eth_dev->data->dev_conf.rxmode.max_rx_pkt_len = new_pkt_size;
2212 
2213 	PMD_DRV_LOG(INFO, "New MTU is %d\n", new_mtu);
2214 
2215 	return rc;
2216 }
2217 
2218 static int
2219 bnxt_vlan_pvid_set_op(struct rte_eth_dev *dev, uint16_t pvid, int on)
2220 {
2221 	struct bnxt *bp = dev->data->dev_private;
2222 	uint16_t vlan = bp->vlan;
2223 	int rc;
2224 
2225 	rc = is_bnxt_in_error(bp);
2226 	if (rc)
2227 		return rc;
2228 
2229 	if (!BNXT_SINGLE_PF(bp) || BNXT_VF(bp)) {
2230 		PMD_DRV_LOG(ERR,
2231 			"PVID cannot be modified for this function\n");
2232 		return -ENOTSUP;
2233 	}
2234 	bp->vlan = on ? pvid : 0;
2235 
2236 	rc = bnxt_hwrm_set_default_vlan(bp, 0, 0);
2237 	if (rc)
2238 		bp->vlan = vlan;
2239 	return rc;
2240 }
2241 
2242 static int
2243 bnxt_dev_led_on_op(struct rte_eth_dev *dev)
2244 {
2245 	struct bnxt *bp = dev->data->dev_private;
2246 	int rc;
2247 
2248 	rc = is_bnxt_in_error(bp);
2249 	if (rc)
2250 		return rc;
2251 
2252 	return bnxt_hwrm_port_led_cfg(bp, true);
2253 }
2254 
2255 static int
2256 bnxt_dev_led_off_op(struct rte_eth_dev *dev)
2257 {
2258 	struct bnxt *bp = dev->data->dev_private;
2259 	int rc;
2260 
2261 	rc = is_bnxt_in_error(bp);
2262 	if (rc)
2263 		return rc;
2264 
2265 	return bnxt_hwrm_port_led_cfg(bp, false);
2266 }
2267 
2268 static uint32_t
2269 bnxt_rx_queue_count_op(struct rte_eth_dev *dev, uint16_t rx_queue_id)
2270 {
2271 	struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
2272 	uint32_t desc = 0, raw_cons = 0, cons;
2273 	struct bnxt_cp_ring_info *cpr;
2274 	struct bnxt_rx_queue *rxq;
2275 	struct rx_pkt_cmpl *rxcmp;
2276 	int rc;
2277 
2278 	rc = is_bnxt_in_error(bp);
2279 	if (rc)
2280 		return rc;
2281 
2282 	rxq = dev->data->rx_queues[rx_queue_id];
2283 	cpr = rxq->cp_ring;
2284 	raw_cons = cpr->cp_raw_cons;
2285 
2286 	while (1) {
2287 		cons = RING_CMP(cpr->cp_ring_struct, raw_cons);
2288 		rte_prefetch0(&cpr->cp_desc_ring[cons]);
2289 		rxcmp = (struct rx_pkt_cmpl *)&cpr->cp_desc_ring[cons];
2290 
2291 		if (!CMP_VALID(rxcmp, raw_cons, cpr->cp_ring_struct)) {
2292 			break;
2293 		} else {
2294 			raw_cons++;
2295 			desc++;
2296 		}
2297 	}
2298 
2299 	return desc;
2300 }
2301 
2302 static int
2303 bnxt_rx_descriptor_status_op(void *rx_queue, uint16_t offset)
2304 {
2305 	struct bnxt_rx_queue *rxq = (struct bnxt_rx_queue *)rx_queue;
2306 	struct bnxt_rx_ring_info *rxr;
2307 	struct bnxt_cp_ring_info *cpr;
2308 	struct bnxt_sw_rx_bd *rx_buf;
2309 	struct rx_pkt_cmpl *rxcmp;
2310 	uint32_t cons, cp_cons;
2311 	int rc;
2312 
2313 	if (!rxq)
2314 		return -EINVAL;
2315 
2316 	rc = is_bnxt_in_error(rxq->bp);
2317 	if (rc)
2318 		return rc;
2319 
2320 	cpr = rxq->cp_ring;
2321 	rxr = rxq->rx_ring;
2322 
2323 	if (offset >= rxq->nb_rx_desc)
2324 		return -EINVAL;
2325 
2326 	cons = RING_CMP(cpr->cp_ring_struct, offset);
2327 	cp_cons = cpr->cp_raw_cons;
2328 	rxcmp = (struct rx_pkt_cmpl *)&cpr->cp_desc_ring[cons];
2329 
2330 	if (cons > cp_cons) {
2331 		if (CMPL_VALID(rxcmp, cpr->valid))
2332 			return RTE_ETH_RX_DESC_DONE;
2333 	} else {
2334 		if (CMPL_VALID(rxcmp, !cpr->valid))
2335 			return RTE_ETH_RX_DESC_DONE;
2336 	}
2337 	rx_buf = &rxr->rx_buf_ring[cons];
2338 	if (rx_buf->mbuf == NULL)
2339 		return RTE_ETH_RX_DESC_UNAVAIL;
2340 
2341 
2342 	return RTE_ETH_RX_DESC_AVAIL;
2343 }
2344 
2345 static int
2346 bnxt_tx_descriptor_status_op(void *tx_queue, uint16_t offset)
2347 {
2348 	struct bnxt_tx_queue *txq = (struct bnxt_tx_queue *)tx_queue;
2349 	struct bnxt_tx_ring_info *txr;
2350 	struct bnxt_cp_ring_info *cpr;
2351 	struct bnxt_sw_tx_bd *tx_buf;
2352 	struct tx_pkt_cmpl *txcmp;
2353 	uint32_t cons, cp_cons;
2354 	int rc;
2355 
2356 	if (!txq)
2357 		return -EINVAL;
2358 
2359 	rc = is_bnxt_in_error(txq->bp);
2360 	if (rc)
2361 		return rc;
2362 
2363 	cpr = txq->cp_ring;
2364 	txr = txq->tx_ring;
2365 
2366 	if (offset >= txq->nb_tx_desc)
2367 		return -EINVAL;
2368 
2369 	cons = RING_CMP(cpr->cp_ring_struct, offset);
2370 	txcmp = (struct tx_pkt_cmpl *)&cpr->cp_desc_ring[cons];
2371 	cp_cons = cpr->cp_raw_cons;
2372 
2373 	if (cons > cp_cons) {
2374 		if (CMPL_VALID(txcmp, cpr->valid))
2375 			return RTE_ETH_TX_DESC_UNAVAIL;
2376 	} else {
2377 		if (CMPL_VALID(txcmp, !cpr->valid))
2378 			return RTE_ETH_TX_DESC_UNAVAIL;
2379 	}
2380 	tx_buf = &txr->tx_buf_ring[cons];
2381 	if (tx_buf->mbuf == NULL)
2382 		return RTE_ETH_TX_DESC_DONE;
2383 
2384 	return RTE_ETH_TX_DESC_FULL;
2385 }
2386 
2387 static struct bnxt_filter_info *
2388 bnxt_match_and_validate_ether_filter(struct bnxt *bp,
2389 				struct rte_eth_ethertype_filter *efilter,
2390 				struct bnxt_vnic_info *vnic0,
2391 				struct bnxt_vnic_info *vnic,
2392 				int *ret)
2393 {
2394 	struct bnxt_filter_info *mfilter = NULL;
2395 	int match = 0;
2396 	*ret = 0;
2397 
2398 	if (efilter->ether_type == RTE_ETHER_TYPE_IPV4 ||
2399 		efilter->ether_type == RTE_ETHER_TYPE_IPV6) {
2400 		PMD_DRV_LOG(ERR, "invalid ether_type(0x%04x) in"
2401 			" ethertype filter.", efilter->ether_type);
2402 		*ret = -EINVAL;
2403 		goto exit;
2404 	}
2405 	if (efilter->queue >= bp->rx_nr_rings) {
2406 		PMD_DRV_LOG(ERR, "Invalid queue %d\n", efilter->queue);
2407 		*ret = -EINVAL;
2408 		goto exit;
2409 	}
2410 
2411 	vnic0 = &bp->vnic_info[0];
2412 	vnic = &bp->vnic_info[efilter->queue];
2413 	if (vnic == NULL) {
2414 		PMD_DRV_LOG(ERR, "Invalid queue %d\n", efilter->queue);
2415 		*ret = -EINVAL;
2416 		goto exit;
2417 	}
2418 
2419 	if (efilter->flags & RTE_ETHTYPE_FLAGS_DROP) {
2420 		STAILQ_FOREACH(mfilter, &vnic0->filter, next) {
2421 			if ((!memcmp(efilter->mac_addr.addr_bytes,
2422 				     mfilter->l2_addr, RTE_ETHER_ADDR_LEN) &&
2423 			     mfilter->flags ==
2424 			     HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_FLAGS_DROP &&
2425 			     mfilter->ethertype == efilter->ether_type)) {
2426 				match = 1;
2427 				break;
2428 			}
2429 		}
2430 	} else {
2431 		STAILQ_FOREACH(mfilter, &vnic->filter, next)
2432 			if ((!memcmp(efilter->mac_addr.addr_bytes,
2433 				     mfilter->l2_addr, RTE_ETHER_ADDR_LEN) &&
2434 			     mfilter->ethertype == efilter->ether_type &&
2435 			     mfilter->flags ==
2436 			     HWRM_CFA_L2_FILTER_CFG_INPUT_FLAGS_PATH_RX)) {
2437 				match = 1;
2438 				break;
2439 			}
2440 	}
2441 
2442 	if (match)
2443 		*ret = -EEXIST;
2444 
2445 exit:
2446 	return mfilter;
2447 }
2448 
2449 static int
2450 bnxt_ethertype_filter(struct rte_eth_dev *dev,
2451 			enum rte_filter_op filter_op,
2452 			void *arg)
2453 {
2454 	struct bnxt *bp = dev->data->dev_private;
2455 	struct rte_eth_ethertype_filter *efilter =
2456 			(struct rte_eth_ethertype_filter *)arg;
2457 	struct bnxt_filter_info *bfilter, *filter1;
2458 	struct bnxt_vnic_info *vnic, *vnic0;
2459 	int ret;
2460 
2461 	if (filter_op == RTE_ETH_FILTER_NOP)
2462 		return 0;
2463 
2464 	if (arg == NULL) {
2465 		PMD_DRV_LOG(ERR, "arg shouldn't be NULL for operation %u.",
2466 			    filter_op);
2467 		return -EINVAL;
2468 	}
2469 
2470 	vnic0 = &bp->vnic_info[0];
2471 	vnic = &bp->vnic_info[efilter->queue];
2472 
2473 	switch (filter_op) {
2474 	case RTE_ETH_FILTER_ADD:
2475 		bnxt_match_and_validate_ether_filter(bp, efilter,
2476 							vnic0, vnic, &ret);
2477 		if (ret < 0)
2478 			return ret;
2479 
2480 		bfilter = bnxt_get_unused_filter(bp);
2481 		if (bfilter == NULL) {
2482 			PMD_DRV_LOG(ERR,
2483 				"Not enough resources for a new filter.\n");
2484 			return -ENOMEM;
2485 		}
2486 		bfilter->filter_type = HWRM_CFA_NTUPLE_FILTER;
2487 		memcpy(bfilter->l2_addr, efilter->mac_addr.addr_bytes,
2488 		       RTE_ETHER_ADDR_LEN);
2489 		memcpy(bfilter->dst_macaddr, efilter->mac_addr.addr_bytes,
2490 		       RTE_ETHER_ADDR_LEN);
2491 		bfilter->enables |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_MACADDR;
2492 		bfilter->ethertype = efilter->ether_type;
2493 		bfilter->enables |= NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE;
2494 
2495 		filter1 = bnxt_get_l2_filter(bp, bfilter, vnic0);
2496 		if (filter1 == NULL) {
2497 			ret = -EINVAL;
2498 			goto cleanup;
2499 		}
2500 		bfilter->enables |=
2501 			HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_L2_FILTER_ID;
2502 		bfilter->fw_l2_filter_id = filter1->fw_l2_filter_id;
2503 
2504 		bfilter->dst_id = vnic->fw_vnic_id;
2505 
2506 		if (efilter->flags & RTE_ETHTYPE_FLAGS_DROP) {
2507 			bfilter->flags =
2508 				HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_FLAGS_DROP;
2509 		}
2510 
2511 		ret = bnxt_hwrm_set_ntuple_filter(bp, bfilter->dst_id, bfilter);
2512 		if (ret)
2513 			goto cleanup;
2514 		STAILQ_INSERT_TAIL(&vnic->filter, bfilter, next);
2515 		break;
2516 	case RTE_ETH_FILTER_DELETE:
2517 		filter1 = bnxt_match_and_validate_ether_filter(bp, efilter,
2518 							vnic0, vnic, &ret);
2519 		if (ret == -EEXIST) {
2520 			ret = bnxt_hwrm_clear_ntuple_filter(bp, filter1);
2521 
2522 			STAILQ_REMOVE(&vnic->filter, filter1, bnxt_filter_info,
2523 				      next);
2524 			bnxt_free_filter(bp, filter1);
2525 		} else if (ret == 0) {
2526 			PMD_DRV_LOG(ERR, "No matching filter found\n");
2527 		}
2528 		break;
2529 	default:
2530 		PMD_DRV_LOG(ERR, "unsupported operation %u.", filter_op);
2531 		ret = -EINVAL;
2532 		goto error;
2533 	}
2534 	return ret;
2535 cleanup:
2536 	bnxt_free_filter(bp, bfilter);
2537 error:
2538 	return ret;
2539 }
2540 
2541 static inline int
2542 parse_ntuple_filter(struct bnxt *bp,
2543 		    struct rte_eth_ntuple_filter *nfilter,
2544 		    struct bnxt_filter_info *bfilter)
2545 {
2546 	uint32_t en = 0;
2547 
2548 	if (nfilter->queue >= bp->rx_nr_rings) {
2549 		PMD_DRV_LOG(ERR, "Invalid queue %d\n", nfilter->queue);
2550 		return -EINVAL;
2551 	}
2552 
2553 	switch (nfilter->dst_port_mask) {
2554 	case UINT16_MAX:
2555 		bfilter->dst_port_mask = -1;
2556 		bfilter->dst_port = nfilter->dst_port;
2557 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT |
2558 			NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT_MASK;
2559 		break;
2560 	default:
2561 		PMD_DRV_LOG(ERR, "invalid dst_port mask.");
2562 		return -EINVAL;
2563 	}
2564 
2565 	bfilter->ip_addr_type = NTUPLE_FLTR_ALLOC_INPUT_IP_ADDR_TYPE_IPV4;
2566 	en |= NTUPLE_FLTR_ALLOC_IN_EN_IP_PROTO;
2567 
2568 	switch (nfilter->proto_mask) {
2569 	case UINT8_MAX:
2570 		if (nfilter->proto == 17) /* IPPROTO_UDP */
2571 			bfilter->ip_protocol = 17;
2572 		else if (nfilter->proto == 6) /* IPPROTO_TCP */
2573 			bfilter->ip_protocol = 6;
2574 		else
2575 			return -EINVAL;
2576 		en |= NTUPLE_FLTR_ALLOC_IN_EN_IP_PROTO;
2577 		break;
2578 	default:
2579 		PMD_DRV_LOG(ERR, "invalid protocol mask.");
2580 		return -EINVAL;
2581 	}
2582 
2583 	switch (nfilter->dst_ip_mask) {
2584 	case UINT32_MAX:
2585 		bfilter->dst_ipaddr_mask[0] = -1;
2586 		bfilter->dst_ipaddr[0] = nfilter->dst_ip;
2587 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR |
2588 			NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR_MASK;
2589 		break;
2590 	default:
2591 		PMD_DRV_LOG(ERR, "invalid dst_ip mask.");
2592 		return -EINVAL;
2593 	}
2594 
2595 	switch (nfilter->src_ip_mask) {
2596 	case UINT32_MAX:
2597 		bfilter->src_ipaddr_mask[0] = -1;
2598 		bfilter->src_ipaddr[0] = nfilter->src_ip;
2599 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR |
2600 			NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR_MASK;
2601 		break;
2602 	default:
2603 		PMD_DRV_LOG(ERR, "invalid src_ip mask.");
2604 		return -EINVAL;
2605 	}
2606 
2607 	switch (nfilter->src_port_mask) {
2608 	case UINT16_MAX:
2609 		bfilter->src_port_mask = -1;
2610 		bfilter->src_port = nfilter->src_port;
2611 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT |
2612 			NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT_MASK;
2613 		break;
2614 	default:
2615 		PMD_DRV_LOG(ERR, "invalid src_port mask.");
2616 		return -EINVAL;
2617 	}
2618 
2619 	//TODO Priority
2620 	//nfilter->priority = (uint8_t)filter->priority;
2621 
2622 	bfilter->enables = en;
2623 	return 0;
2624 }
2625 
2626 static struct bnxt_filter_info*
2627 bnxt_match_ntuple_filter(struct bnxt *bp,
2628 			 struct bnxt_filter_info *bfilter,
2629 			 struct bnxt_vnic_info **mvnic)
2630 {
2631 	struct bnxt_filter_info *mfilter = NULL;
2632 	int i;
2633 
2634 	for (i = bp->nr_vnics - 1; i >= 0; i--) {
2635 		struct bnxt_vnic_info *vnic = &bp->vnic_info[i];
2636 		STAILQ_FOREACH(mfilter, &vnic->filter, next) {
2637 			if (bfilter->src_ipaddr[0] == mfilter->src_ipaddr[0] &&
2638 			    bfilter->src_ipaddr_mask[0] ==
2639 			    mfilter->src_ipaddr_mask[0] &&
2640 			    bfilter->src_port == mfilter->src_port &&
2641 			    bfilter->src_port_mask == mfilter->src_port_mask &&
2642 			    bfilter->dst_ipaddr[0] == mfilter->dst_ipaddr[0] &&
2643 			    bfilter->dst_ipaddr_mask[0] ==
2644 			    mfilter->dst_ipaddr_mask[0] &&
2645 			    bfilter->dst_port == mfilter->dst_port &&
2646 			    bfilter->dst_port_mask == mfilter->dst_port_mask &&
2647 			    bfilter->flags == mfilter->flags &&
2648 			    bfilter->enables == mfilter->enables) {
2649 				if (mvnic)
2650 					*mvnic = vnic;
2651 				return mfilter;
2652 			}
2653 		}
2654 	}
2655 	return NULL;
2656 }
2657 
2658 static int
2659 bnxt_cfg_ntuple_filter(struct bnxt *bp,
2660 		       struct rte_eth_ntuple_filter *nfilter,
2661 		       enum rte_filter_op filter_op)
2662 {
2663 	struct bnxt_filter_info *bfilter, *mfilter, *filter1;
2664 	struct bnxt_vnic_info *vnic, *vnic0, *mvnic;
2665 	int ret;
2666 
2667 	if (nfilter->flags != RTE_5TUPLE_FLAGS) {
2668 		PMD_DRV_LOG(ERR, "only 5tuple is supported.");
2669 		return -EINVAL;
2670 	}
2671 
2672 	if (nfilter->flags & RTE_NTUPLE_FLAGS_TCP_FLAG) {
2673 		PMD_DRV_LOG(ERR, "Ntuple filter: TCP flags not supported\n");
2674 		return -EINVAL;
2675 	}
2676 
2677 	bfilter = bnxt_get_unused_filter(bp);
2678 	if (bfilter == NULL) {
2679 		PMD_DRV_LOG(ERR,
2680 			"Not enough resources for a new filter.\n");
2681 		return -ENOMEM;
2682 	}
2683 	ret = parse_ntuple_filter(bp, nfilter, bfilter);
2684 	if (ret < 0)
2685 		goto free_filter;
2686 
2687 	vnic = &bp->vnic_info[nfilter->queue];
2688 	vnic0 = &bp->vnic_info[0];
2689 	filter1 = STAILQ_FIRST(&vnic0->filter);
2690 	if (filter1 == NULL) {
2691 		ret = -EINVAL;
2692 		goto free_filter;
2693 	}
2694 
2695 	bfilter->dst_id = vnic->fw_vnic_id;
2696 	bfilter->fw_l2_filter_id = filter1->fw_l2_filter_id;
2697 	bfilter->enables |=
2698 		HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_L2_FILTER_ID;
2699 	bfilter->ethertype = 0x800;
2700 	bfilter->enables |= NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE;
2701 
2702 	mfilter = bnxt_match_ntuple_filter(bp, bfilter, &mvnic);
2703 
2704 	if (mfilter != NULL && filter_op == RTE_ETH_FILTER_ADD &&
2705 	    bfilter->dst_id == mfilter->dst_id) {
2706 		PMD_DRV_LOG(ERR, "filter exists.\n");
2707 		ret = -EEXIST;
2708 		goto free_filter;
2709 	} else if (mfilter != NULL && filter_op == RTE_ETH_FILTER_ADD &&
2710 		   bfilter->dst_id != mfilter->dst_id) {
2711 		mfilter->dst_id = vnic->fw_vnic_id;
2712 		ret = bnxt_hwrm_set_ntuple_filter(bp, mfilter->dst_id, mfilter);
2713 		STAILQ_REMOVE(&mvnic->filter, mfilter, bnxt_filter_info, next);
2714 		STAILQ_INSERT_TAIL(&vnic->filter, mfilter, next);
2715 		PMD_DRV_LOG(ERR, "filter with matching pattern exists.\n");
2716 		PMD_DRV_LOG(ERR, " Updated it to the new destination queue\n");
2717 		goto free_filter;
2718 	}
2719 	if (mfilter == NULL && filter_op == RTE_ETH_FILTER_DELETE) {
2720 		PMD_DRV_LOG(ERR, "filter doesn't exist.");
2721 		ret = -ENOENT;
2722 		goto free_filter;
2723 	}
2724 
2725 	if (filter_op == RTE_ETH_FILTER_ADD) {
2726 		bfilter->filter_type = HWRM_CFA_NTUPLE_FILTER;
2727 		ret = bnxt_hwrm_set_ntuple_filter(bp, bfilter->dst_id, bfilter);
2728 		if (ret)
2729 			goto free_filter;
2730 		STAILQ_INSERT_TAIL(&vnic->filter, bfilter, next);
2731 	} else {
2732 		if (mfilter == NULL) {
2733 			/* This should not happen. But for Coverity! */
2734 			ret = -ENOENT;
2735 			goto free_filter;
2736 		}
2737 		ret = bnxt_hwrm_clear_ntuple_filter(bp, mfilter);
2738 
2739 		STAILQ_REMOVE(&vnic->filter, mfilter, bnxt_filter_info, next);
2740 		bnxt_free_filter(bp, mfilter);
2741 		mfilter->fw_l2_filter_id = -1;
2742 		bnxt_free_filter(bp, bfilter);
2743 		bfilter->fw_l2_filter_id = -1;
2744 	}
2745 
2746 	return 0;
2747 free_filter:
2748 	bfilter->fw_l2_filter_id = -1;
2749 	bnxt_free_filter(bp, bfilter);
2750 	return ret;
2751 }
2752 
2753 static int
2754 bnxt_ntuple_filter(struct rte_eth_dev *dev,
2755 			enum rte_filter_op filter_op,
2756 			void *arg)
2757 {
2758 	struct bnxt *bp = dev->data->dev_private;
2759 	int ret;
2760 
2761 	if (filter_op == RTE_ETH_FILTER_NOP)
2762 		return 0;
2763 
2764 	if (arg == NULL) {
2765 		PMD_DRV_LOG(ERR, "arg shouldn't be NULL for operation %u.",
2766 			    filter_op);
2767 		return -EINVAL;
2768 	}
2769 
2770 	switch (filter_op) {
2771 	case RTE_ETH_FILTER_ADD:
2772 		ret = bnxt_cfg_ntuple_filter(bp,
2773 			(struct rte_eth_ntuple_filter *)arg,
2774 			filter_op);
2775 		break;
2776 	case RTE_ETH_FILTER_DELETE:
2777 		ret = bnxt_cfg_ntuple_filter(bp,
2778 			(struct rte_eth_ntuple_filter *)arg,
2779 			filter_op);
2780 		break;
2781 	default:
2782 		PMD_DRV_LOG(ERR, "unsupported operation %u.", filter_op);
2783 		ret = -EINVAL;
2784 		break;
2785 	}
2786 	return ret;
2787 }
2788 
2789 static int
2790 bnxt_parse_fdir_filter(struct bnxt *bp,
2791 		       struct rte_eth_fdir_filter *fdir,
2792 		       struct bnxt_filter_info *filter)
2793 {
2794 	enum rte_fdir_mode fdir_mode =
2795 		bp->eth_dev->data->dev_conf.fdir_conf.mode;
2796 	struct bnxt_vnic_info *vnic0, *vnic;
2797 	struct bnxt_filter_info *filter1;
2798 	uint32_t en = 0;
2799 	int i;
2800 
2801 	if (fdir_mode == RTE_FDIR_MODE_PERFECT_TUNNEL)
2802 		return -EINVAL;
2803 
2804 	filter->l2_ovlan = fdir->input.flow_ext.vlan_tci;
2805 	en |= EM_FLOW_ALLOC_INPUT_EN_OVLAN_VID;
2806 
2807 	switch (fdir->input.flow_type) {
2808 	case RTE_ETH_FLOW_IPV4:
2809 	case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER:
2810 		/* FALLTHROUGH */
2811 		filter->src_ipaddr[0] = fdir->input.flow.ip4_flow.src_ip;
2812 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR;
2813 		filter->dst_ipaddr[0] = fdir->input.flow.ip4_flow.dst_ip;
2814 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR;
2815 		filter->ip_protocol = fdir->input.flow.ip4_flow.proto;
2816 		en |= NTUPLE_FLTR_ALLOC_IN_EN_IP_PROTO;
2817 		filter->ip_addr_type =
2818 			NTUPLE_FLTR_ALLOC_INPUT_IP_ADDR_TYPE_IPV4;
2819 		filter->src_ipaddr_mask[0] = 0xffffffff;
2820 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR_MASK;
2821 		filter->dst_ipaddr_mask[0] = 0xffffffff;
2822 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR_MASK;
2823 		filter->ethertype = 0x800;
2824 		filter->enables |= NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE;
2825 		break;
2826 	case RTE_ETH_FLOW_NONFRAG_IPV4_TCP:
2827 		filter->src_port = fdir->input.flow.tcp4_flow.src_port;
2828 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT;
2829 		filter->dst_port = fdir->input.flow.tcp4_flow.dst_port;
2830 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT;
2831 		filter->dst_port_mask = 0xffff;
2832 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT_MASK;
2833 		filter->src_port_mask = 0xffff;
2834 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT_MASK;
2835 		filter->src_ipaddr[0] = fdir->input.flow.tcp4_flow.ip.src_ip;
2836 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR;
2837 		filter->dst_ipaddr[0] = fdir->input.flow.tcp4_flow.ip.dst_ip;
2838 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR;
2839 		filter->ip_protocol = 6;
2840 		en |= NTUPLE_FLTR_ALLOC_IN_EN_IP_PROTO;
2841 		filter->ip_addr_type =
2842 			NTUPLE_FLTR_ALLOC_INPUT_IP_ADDR_TYPE_IPV4;
2843 		filter->src_ipaddr_mask[0] = 0xffffffff;
2844 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR_MASK;
2845 		filter->dst_ipaddr_mask[0] = 0xffffffff;
2846 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR_MASK;
2847 		filter->ethertype = 0x800;
2848 		filter->enables |= NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE;
2849 		break;
2850 	case RTE_ETH_FLOW_NONFRAG_IPV4_UDP:
2851 		filter->src_port = fdir->input.flow.udp4_flow.src_port;
2852 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT;
2853 		filter->dst_port = fdir->input.flow.udp4_flow.dst_port;
2854 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT;
2855 		filter->dst_port_mask = 0xffff;
2856 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT_MASK;
2857 		filter->src_port_mask = 0xffff;
2858 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT_MASK;
2859 		filter->src_ipaddr[0] = fdir->input.flow.udp4_flow.ip.src_ip;
2860 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR;
2861 		filter->dst_ipaddr[0] = fdir->input.flow.udp4_flow.ip.dst_ip;
2862 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR;
2863 		filter->ip_protocol = 17;
2864 		en |= NTUPLE_FLTR_ALLOC_IN_EN_IP_PROTO;
2865 		filter->ip_addr_type =
2866 			NTUPLE_FLTR_ALLOC_INPUT_IP_ADDR_TYPE_IPV4;
2867 		filter->src_ipaddr_mask[0] = 0xffffffff;
2868 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR_MASK;
2869 		filter->dst_ipaddr_mask[0] = 0xffffffff;
2870 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR_MASK;
2871 		filter->ethertype = 0x800;
2872 		filter->enables |= NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE;
2873 		break;
2874 	case RTE_ETH_FLOW_IPV6:
2875 	case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER:
2876 		/* FALLTHROUGH */
2877 		filter->ip_addr_type =
2878 			NTUPLE_FLTR_ALLOC_INPUT_IP_ADDR_TYPE_IPV6;
2879 		filter->ip_protocol = fdir->input.flow.ipv6_flow.proto;
2880 		en |= NTUPLE_FLTR_ALLOC_IN_EN_IP_PROTO;
2881 		rte_memcpy(filter->src_ipaddr,
2882 			   fdir->input.flow.ipv6_flow.src_ip, 16);
2883 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR;
2884 		rte_memcpy(filter->dst_ipaddr,
2885 			   fdir->input.flow.ipv6_flow.dst_ip, 16);
2886 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR;
2887 		memset(filter->dst_ipaddr_mask, 0xff, 16);
2888 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR_MASK;
2889 		memset(filter->src_ipaddr_mask, 0xff, 16);
2890 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR_MASK;
2891 		filter->ethertype = 0x86dd;
2892 		filter->enables |= NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE;
2893 		break;
2894 	case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
2895 		filter->src_port = fdir->input.flow.tcp6_flow.src_port;
2896 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT;
2897 		filter->dst_port = fdir->input.flow.tcp6_flow.dst_port;
2898 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT;
2899 		filter->dst_port_mask = 0xffff;
2900 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT_MASK;
2901 		filter->src_port_mask = 0xffff;
2902 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT_MASK;
2903 		filter->ip_addr_type =
2904 			NTUPLE_FLTR_ALLOC_INPUT_IP_ADDR_TYPE_IPV6;
2905 		filter->ip_protocol = fdir->input.flow.tcp6_flow.ip.proto;
2906 		en |= NTUPLE_FLTR_ALLOC_IN_EN_IP_PROTO;
2907 		rte_memcpy(filter->src_ipaddr,
2908 			   fdir->input.flow.tcp6_flow.ip.src_ip, 16);
2909 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR;
2910 		rte_memcpy(filter->dst_ipaddr,
2911 			   fdir->input.flow.tcp6_flow.ip.dst_ip, 16);
2912 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR;
2913 		memset(filter->dst_ipaddr_mask, 0xff, 16);
2914 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR_MASK;
2915 		memset(filter->src_ipaddr_mask, 0xff, 16);
2916 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR_MASK;
2917 		filter->ethertype = 0x86dd;
2918 		filter->enables |= NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE;
2919 		break;
2920 	case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
2921 		filter->src_port = fdir->input.flow.udp6_flow.src_port;
2922 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT;
2923 		filter->dst_port = fdir->input.flow.udp6_flow.dst_port;
2924 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT;
2925 		filter->dst_port_mask = 0xffff;
2926 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT_MASK;
2927 		filter->src_port_mask = 0xffff;
2928 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT_MASK;
2929 		filter->ip_addr_type =
2930 			NTUPLE_FLTR_ALLOC_INPUT_IP_ADDR_TYPE_IPV6;
2931 		filter->ip_protocol = fdir->input.flow.udp6_flow.ip.proto;
2932 		en |= NTUPLE_FLTR_ALLOC_IN_EN_IP_PROTO;
2933 		rte_memcpy(filter->src_ipaddr,
2934 			   fdir->input.flow.udp6_flow.ip.src_ip, 16);
2935 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR;
2936 		rte_memcpy(filter->dst_ipaddr,
2937 			   fdir->input.flow.udp6_flow.ip.dst_ip, 16);
2938 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR;
2939 		memset(filter->dst_ipaddr_mask, 0xff, 16);
2940 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR_MASK;
2941 		memset(filter->src_ipaddr_mask, 0xff, 16);
2942 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR_MASK;
2943 		filter->ethertype = 0x86dd;
2944 		filter->enables |= NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE;
2945 		break;
2946 	case RTE_ETH_FLOW_L2_PAYLOAD:
2947 		filter->ethertype = fdir->input.flow.l2_flow.ether_type;
2948 		en |= NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE;
2949 		break;
2950 	case RTE_ETH_FLOW_VXLAN:
2951 		if (fdir->action.behavior == RTE_ETH_FDIR_REJECT)
2952 			return -EINVAL;
2953 		filter->vni = fdir->input.flow.tunnel_flow.tunnel_id;
2954 		filter->tunnel_type =
2955 			CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_VXLAN;
2956 		en |= HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_TUNNEL_TYPE;
2957 		break;
2958 	case RTE_ETH_FLOW_NVGRE:
2959 		if (fdir->action.behavior == RTE_ETH_FDIR_REJECT)
2960 			return -EINVAL;
2961 		filter->vni = fdir->input.flow.tunnel_flow.tunnel_id;
2962 		filter->tunnel_type =
2963 			CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_NVGRE;
2964 		en |= HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_TUNNEL_TYPE;
2965 		break;
2966 	case RTE_ETH_FLOW_UNKNOWN:
2967 	case RTE_ETH_FLOW_RAW:
2968 	case RTE_ETH_FLOW_FRAG_IPV4:
2969 	case RTE_ETH_FLOW_NONFRAG_IPV4_SCTP:
2970 	case RTE_ETH_FLOW_FRAG_IPV6:
2971 	case RTE_ETH_FLOW_NONFRAG_IPV6_SCTP:
2972 	case RTE_ETH_FLOW_IPV6_EX:
2973 	case RTE_ETH_FLOW_IPV6_TCP_EX:
2974 	case RTE_ETH_FLOW_IPV6_UDP_EX:
2975 	case RTE_ETH_FLOW_GENEVE:
2976 		/* FALLTHROUGH */
2977 	default:
2978 		return -EINVAL;
2979 	}
2980 
2981 	vnic0 = &bp->vnic_info[0];
2982 	vnic = &bp->vnic_info[fdir->action.rx_queue];
2983 	if (vnic == NULL) {
2984 		PMD_DRV_LOG(ERR, "Invalid queue %d\n", fdir->action.rx_queue);
2985 		return -EINVAL;
2986 	}
2987 
2988 	if (fdir_mode == RTE_FDIR_MODE_PERFECT_MAC_VLAN) {
2989 		rte_memcpy(filter->dst_macaddr,
2990 			fdir->input.flow.mac_vlan_flow.mac_addr.addr_bytes, 6);
2991 			en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_MACADDR;
2992 	}
2993 
2994 	if (fdir->action.behavior == RTE_ETH_FDIR_REJECT) {
2995 		filter->flags = HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_FLAGS_DROP;
2996 		filter1 = STAILQ_FIRST(&vnic0->filter);
2997 		//filter1 = bnxt_get_l2_filter(bp, filter, vnic0);
2998 	} else {
2999 		filter->dst_id = vnic->fw_vnic_id;
3000 		for (i = 0; i < RTE_ETHER_ADDR_LEN; i++)
3001 			if (filter->dst_macaddr[i] == 0x00)
3002 				filter1 = STAILQ_FIRST(&vnic0->filter);
3003 			else
3004 				filter1 = bnxt_get_l2_filter(bp, filter, vnic);
3005 	}
3006 
3007 	if (filter1 == NULL)
3008 		return -EINVAL;
3009 
3010 	en |= HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_L2_FILTER_ID;
3011 	filter->fw_l2_filter_id = filter1->fw_l2_filter_id;
3012 
3013 	filter->enables = en;
3014 
3015 	return 0;
3016 }
3017 
3018 static struct bnxt_filter_info *
3019 bnxt_match_fdir(struct bnxt *bp, struct bnxt_filter_info *nf,
3020 		struct bnxt_vnic_info **mvnic)
3021 {
3022 	struct bnxt_filter_info *mf = NULL;
3023 	int i;
3024 
3025 	for (i = bp->nr_vnics - 1; i >= 0; i--) {
3026 		struct bnxt_vnic_info *vnic = &bp->vnic_info[i];
3027 
3028 		STAILQ_FOREACH(mf, &vnic->filter, next) {
3029 			if (mf->filter_type == nf->filter_type &&
3030 			    mf->flags == nf->flags &&
3031 			    mf->src_port == nf->src_port &&
3032 			    mf->src_port_mask == nf->src_port_mask &&
3033 			    mf->dst_port == nf->dst_port &&
3034 			    mf->dst_port_mask == nf->dst_port_mask &&
3035 			    mf->ip_protocol == nf->ip_protocol &&
3036 			    mf->ip_addr_type == nf->ip_addr_type &&
3037 			    mf->ethertype == nf->ethertype &&
3038 			    mf->vni == nf->vni &&
3039 			    mf->tunnel_type == nf->tunnel_type &&
3040 			    mf->l2_ovlan == nf->l2_ovlan &&
3041 			    mf->l2_ovlan_mask == nf->l2_ovlan_mask &&
3042 			    mf->l2_ivlan == nf->l2_ivlan &&
3043 			    mf->l2_ivlan_mask == nf->l2_ivlan_mask &&
3044 			    !memcmp(mf->l2_addr, nf->l2_addr,
3045 				    RTE_ETHER_ADDR_LEN) &&
3046 			    !memcmp(mf->l2_addr_mask, nf->l2_addr_mask,
3047 				    RTE_ETHER_ADDR_LEN) &&
3048 			    !memcmp(mf->src_macaddr, nf->src_macaddr,
3049 				    RTE_ETHER_ADDR_LEN) &&
3050 			    !memcmp(mf->dst_macaddr, nf->dst_macaddr,
3051 				    RTE_ETHER_ADDR_LEN) &&
3052 			    !memcmp(mf->src_ipaddr, nf->src_ipaddr,
3053 				    sizeof(nf->src_ipaddr)) &&
3054 			    !memcmp(mf->src_ipaddr_mask, nf->src_ipaddr_mask,
3055 				    sizeof(nf->src_ipaddr_mask)) &&
3056 			    !memcmp(mf->dst_ipaddr, nf->dst_ipaddr,
3057 				    sizeof(nf->dst_ipaddr)) &&
3058 			    !memcmp(mf->dst_ipaddr_mask, nf->dst_ipaddr_mask,
3059 				    sizeof(nf->dst_ipaddr_mask))) {
3060 				if (mvnic)
3061 					*mvnic = vnic;
3062 				return mf;
3063 			}
3064 		}
3065 	}
3066 	return NULL;
3067 }
3068 
3069 static int
3070 bnxt_fdir_filter(struct rte_eth_dev *dev,
3071 		 enum rte_filter_op filter_op,
3072 		 void *arg)
3073 {
3074 	struct bnxt *bp = dev->data->dev_private;
3075 	struct rte_eth_fdir_filter *fdir  = (struct rte_eth_fdir_filter *)arg;
3076 	struct bnxt_filter_info *filter, *match;
3077 	struct bnxt_vnic_info *vnic, *mvnic;
3078 	int ret = 0, i;
3079 
3080 	if (filter_op == RTE_ETH_FILTER_NOP)
3081 		return 0;
3082 
3083 	if (arg == NULL && filter_op != RTE_ETH_FILTER_FLUSH)
3084 		return -EINVAL;
3085 
3086 	switch (filter_op) {
3087 	case RTE_ETH_FILTER_ADD:
3088 	case RTE_ETH_FILTER_DELETE:
3089 		/* FALLTHROUGH */
3090 		filter = bnxt_get_unused_filter(bp);
3091 		if (filter == NULL) {
3092 			PMD_DRV_LOG(ERR,
3093 				"Not enough resources for a new flow.\n");
3094 			return -ENOMEM;
3095 		}
3096 
3097 		ret = bnxt_parse_fdir_filter(bp, fdir, filter);
3098 		if (ret != 0)
3099 			goto free_filter;
3100 		filter->filter_type = HWRM_CFA_NTUPLE_FILTER;
3101 
3102 		if (fdir->action.behavior == RTE_ETH_FDIR_REJECT)
3103 			vnic = &bp->vnic_info[0];
3104 		else
3105 			vnic = &bp->vnic_info[fdir->action.rx_queue];
3106 
3107 		match = bnxt_match_fdir(bp, filter, &mvnic);
3108 		if (match != NULL && filter_op == RTE_ETH_FILTER_ADD) {
3109 			if (match->dst_id == vnic->fw_vnic_id) {
3110 				PMD_DRV_LOG(ERR, "Flow already exists.\n");
3111 				ret = -EEXIST;
3112 				goto free_filter;
3113 			} else {
3114 				match->dst_id = vnic->fw_vnic_id;
3115 				ret = bnxt_hwrm_set_ntuple_filter(bp,
3116 								  match->dst_id,
3117 								  match);
3118 				STAILQ_REMOVE(&mvnic->filter, match,
3119 					      bnxt_filter_info, next);
3120 				STAILQ_INSERT_TAIL(&vnic->filter, match, next);
3121 				PMD_DRV_LOG(ERR,
3122 					"Filter with matching pattern exist\n");
3123 				PMD_DRV_LOG(ERR,
3124 					"Updated it to new destination q\n");
3125 				goto free_filter;
3126 			}
3127 		}
3128 		if (match == NULL && filter_op == RTE_ETH_FILTER_DELETE) {
3129 			PMD_DRV_LOG(ERR, "Flow does not exist.\n");
3130 			ret = -ENOENT;
3131 			goto free_filter;
3132 		}
3133 
3134 		if (filter_op == RTE_ETH_FILTER_ADD) {
3135 			ret = bnxt_hwrm_set_ntuple_filter(bp,
3136 							  filter->dst_id,
3137 							  filter);
3138 			if (ret)
3139 				goto free_filter;
3140 			STAILQ_INSERT_TAIL(&vnic->filter, filter, next);
3141 		} else {
3142 			ret = bnxt_hwrm_clear_ntuple_filter(bp, match);
3143 			STAILQ_REMOVE(&vnic->filter, match,
3144 				      bnxt_filter_info, next);
3145 			bnxt_free_filter(bp, match);
3146 			filter->fw_l2_filter_id = -1;
3147 			bnxt_free_filter(bp, filter);
3148 		}
3149 		break;
3150 	case RTE_ETH_FILTER_FLUSH:
3151 		for (i = bp->nr_vnics - 1; i >= 0; i--) {
3152 			struct bnxt_vnic_info *vnic = &bp->vnic_info[i];
3153 
3154 			STAILQ_FOREACH(filter, &vnic->filter, next) {
3155 				if (filter->filter_type ==
3156 				    HWRM_CFA_NTUPLE_FILTER) {
3157 					ret =
3158 					bnxt_hwrm_clear_ntuple_filter(bp,
3159 								      filter);
3160 					STAILQ_REMOVE(&vnic->filter, filter,
3161 						      bnxt_filter_info, next);
3162 				}
3163 			}
3164 		}
3165 		return ret;
3166 	case RTE_ETH_FILTER_UPDATE:
3167 	case RTE_ETH_FILTER_STATS:
3168 	case RTE_ETH_FILTER_INFO:
3169 		PMD_DRV_LOG(ERR, "operation %u not implemented", filter_op);
3170 		break;
3171 	default:
3172 		PMD_DRV_LOG(ERR, "unknown operation %u", filter_op);
3173 		ret = -EINVAL;
3174 		break;
3175 	}
3176 	return ret;
3177 
3178 free_filter:
3179 	filter->fw_l2_filter_id = -1;
3180 	bnxt_free_filter(bp, filter);
3181 	return ret;
3182 }
3183 
3184 static int
3185 bnxt_filter_ctrl_op(struct rte_eth_dev *dev __rte_unused,
3186 		    enum rte_filter_type filter_type,
3187 		    enum rte_filter_op filter_op, void *arg)
3188 {
3189 	int ret = 0;
3190 
3191 	ret = is_bnxt_in_error(dev->data->dev_private);
3192 	if (ret)
3193 		return ret;
3194 
3195 	switch (filter_type) {
3196 	case RTE_ETH_FILTER_TUNNEL:
3197 		PMD_DRV_LOG(ERR,
3198 			"filter type: %d: To be implemented\n", filter_type);
3199 		break;
3200 	case RTE_ETH_FILTER_FDIR:
3201 		ret = bnxt_fdir_filter(dev, filter_op, arg);
3202 		break;
3203 	case RTE_ETH_FILTER_NTUPLE:
3204 		ret = bnxt_ntuple_filter(dev, filter_op, arg);
3205 		break;
3206 	case RTE_ETH_FILTER_ETHERTYPE:
3207 		ret = bnxt_ethertype_filter(dev, filter_op, arg);
3208 		break;
3209 	case RTE_ETH_FILTER_GENERIC:
3210 		if (filter_op != RTE_ETH_FILTER_GET)
3211 			return -EINVAL;
3212 		*(const void **)arg = &bnxt_flow_ops;
3213 		break;
3214 	default:
3215 		PMD_DRV_LOG(ERR,
3216 			"Filter type (%d) not supported", filter_type);
3217 		ret = -EINVAL;
3218 		break;
3219 	}
3220 	return ret;
3221 }
3222 
3223 static const uint32_t *
3224 bnxt_dev_supported_ptypes_get_op(struct rte_eth_dev *dev)
3225 {
3226 	static const uint32_t ptypes[] = {
3227 		RTE_PTYPE_L2_ETHER_VLAN,
3228 		RTE_PTYPE_L3_IPV4_EXT_UNKNOWN,
3229 		RTE_PTYPE_L3_IPV6_EXT_UNKNOWN,
3230 		RTE_PTYPE_L4_ICMP,
3231 		RTE_PTYPE_L4_TCP,
3232 		RTE_PTYPE_L4_UDP,
3233 		RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN,
3234 		RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN,
3235 		RTE_PTYPE_INNER_L4_ICMP,
3236 		RTE_PTYPE_INNER_L4_TCP,
3237 		RTE_PTYPE_INNER_L4_UDP,
3238 		RTE_PTYPE_UNKNOWN
3239 	};
3240 
3241 	if (!dev->rx_pkt_burst)
3242 		return NULL;
3243 
3244 	return ptypes;
3245 }
3246 
3247 static int bnxt_map_regs(struct bnxt *bp, uint32_t *reg_arr, int count,
3248 			 int reg_win)
3249 {
3250 	uint32_t reg_base = *reg_arr & 0xfffff000;
3251 	uint32_t win_off;
3252 	int i;
3253 
3254 	for (i = 0; i < count; i++) {
3255 		if ((reg_arr[i] & 0xfffff000) != reg_base)
3256 			return -ERANGE;
3257 	}
3258 	win_off = BNXT_GRCPF_REG_WINDOW_BASE_OUT + (reg_win - 1) * 4;
3259 	rte_write32(reg_base, (uint8_t *)bp->bar0 + win_off);
3260 	return 0;
3261 }
3262 
3263 static int bnxt_map_ptp_regs(struct bnxt *bp)
3264 {
3265 	struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
3266 	uint32_t *reg_arr;
3267 	int rc, i;
3268 
3269 	reg_arr = ptp->rx_regs;
3270 	rc = bnxt_map_regs(bp, reg_arr, BNXT_PTP_RX_REGS, 5);
3271 	if (rc)
3272 		return rc;
3273 
3274 	reg_arr = ptp->tx_regs;
3275 	rc = bnxt_map_regs(bp, reg_arr, BNXT_PTP_TX_REGS, 6);
3276 	if (rc)
3277 		return rc;
3278 
3279 	for (i = 0; i < BNXT_PTP_RX_REGS; i++)
3280 		ptp->rx_mapped_regs[i] = 0x5000 + (ptp->rx_regs[i] & 0xfff);
3281 
3282 	for (i = 0; i < BNXT_PTP_TX_REGS; i++)
3283 		ptp->tx_mapped_regs[i] = 0x6000 + (ptp->tx_regs[i] & 0xfff);
3284 
3285 	return 0;
3286 }
3287 
3288 static void bnxt_unmap_ptp_regs(struct bnxt *bp)
3289 {
3290 	rte_write32(0, (uint8_t *)bp->bar0 +
3291 			 BNXT_GRCPF_REG_WINDOW_BASE_OUT + 16);
3292 	rte_write32(0, (uint8_t *)bp->bar0 +
3293 			 BNXT_GRCPF_REG_WINDOW_BASE_OUT + 20);
3294 }
3295 
3296 static uint64_t bnxt_cc_read(struct bnxt *bp)
3297 {
3298 	uint64_t ns;
3299 
3300 	ns = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
3301 			      BNXT_GRCPF_REG_SYNC_TIME));
3302 	ns |= (uint64_t)(rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
3303 					  BNXT_GRCPF_REG_SYNC_TIME + 4))) << 32;
3304 	return ns;
3305 }
3306 
3307 static int bnxt_get_tx_ts(struct bnxt *bp, uint64_t *ts)
3308 {
3309 	struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
3310 	uint32_t fifo;
3311 
3312 	fifo = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
3313 				ptp->tx_mapped_regs[BNXT_PTP_TX_FIFO]));
3314 	if (fifo & BNXT_PTP_TX_FIFO_EMPTY)
3315 		return -EAGAIN;
3316 
3317 	fifo = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
3318 				ptp->tx_mapped_regs[BNXT_PTP_TX_FIFO]));
3319 	*ts = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
3320 				ptp->tx_mapped_regs[BNXT_PTP_TX_TS_L]));
3321 	*ts |= (uint64_t)rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
3322 				ptp->tx_mapped_regs[BNXT_PTP_TX_TS_H])) << 32;
3323 
3324 	return 0;
3325 }
3326 
3327 static int bnxt_get_rx_ts(struct bnxt *bp, uint64_t *ts)
3328 {
3329 	struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
3330 	struct bnxt_pf_info *pf = &bp->pf;
3331 	uint16_t port_id;
3332 	uint32_t fifo;
3333 
3334 	if (!ptp)
3335 		return -ENODEV;
3336 
3337 	fifo = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
3338 				ptp->rx_mapped_regs[BNXT_PTP_RX_FIFO]));
3339 	if (!(fifo & BNXT_PTP_RX_FIFO_PENDING))
3340 		return -EAGAIN;
3341 
3342 	port_id = pf->port_id;
3343 	rte_write32(1 << port_id, (uint8_t *)bp->bar0 +
3344 	       ptp->rx_mapped_regs[BNXT_PTP_RX_FIFO_ADV]);
3345 
3346 	fifo = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
3347 				   ptp->rx_mapped_regs[BNXT_PTP_RX_FIFO]));
3348 	if (fifo & BNXT_PTP_RX_FIFO_PENDING) {
3349 /*		bnxt_clr_rx_ts(bp);	  TBD  */
3350 		return -EBUSY;
3351 	}
3352 
3353 	*ts = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
3354 				ptp->rx_mapped_regs[BNXT_PTP_RX_TS_L]));
3355 	*ts |= (uint64_t)rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
3356 				ptp->rx_mapped_regs[BNXT_PTP_RX_TS_H])) << 32;
3357 
3358 	return 0;
3359 }
3360 
3361 static int
3362 bnxt_timesync_write_time(struct rte_eth_dev *dev, const struct timespec *ts)
3363 {
3364 	uint64_t ns;
3365 	struct bnxt *bp = dev->data->dev_private;
3366 	struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
3367 
3368 	if (!ptp)
3369 		return 0;
3370 
3371 	ns = rte_timespec_to_ns(ts);
3372 	/* Set the timecounters to a new value. */
3373 	ptp->tc.nsec = ns;
3374 
3375 	return 0;
3376 }
3377 
3378 static int
3379 bnxt_timesync_read_time(struct rte_eth_dev *dev, struct timespec *ts)
3380 {
3381 	struct bnxt *bp = dev->data->dev_private;
3382 	struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
3383 	uint64_t ns, systime_cycles = 0;
3384 	int rc = 0;
3385 
3386 	if (!ptp)
3387 		return 0;
3388 
3389 	if (BNXT_CHIP_THOR(bp))
3390 		rc = bnxt_hwrm_port_ts_query(bp, BNXT_PTP_FLAGS_CURRENT_TIME,
3391 					     &systime_cycles);
3392 	else
3393 		systime_cycles = bnxt_cc_read(bp);
3394 
3395 	ns = rte_timecounter_update(&ptp->tc, systime_cycles);
3396 	*ts = rte_ns_to_timespec(ns);
3397 
3398 	return rc;
3399 }
3400 static int
3401 bnxt_timesync_enable(struct rte_eth_dev *dev)
3402 {
3403 	struct bnxt *bp = dev->data->dev_private;
3404 	struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
3405 	uint32_t shift = 0;
3406 	int rc;
3407 
3408 	if (!ptp)
3409 		return 0;
3410 
3411 	ptp->rx_filter = 1;
3412 	ptp->tx_tstamp_en = 1;
3413 	ptp->rxctl = BNXT_PTP_MSG_EVENTS;
3414 
3415 	rc = bnxt_hwrm_ptp_cfg(bp);
3416 	if (rc)
3417 		return rc;
3418 
3419 	memset(&ptp->tc, 0, sizeof(struct rte_timecounter));
3420 	memset(&ptp->rx_tstamp_tc, 0, sizeof(struct rte_timecounter));
3421 	memset(&ptp->tx_tstamp_tc, 0, sizeof(struct rte_timecounter));
3422 
3423 	ptp->tc.cc_mask = BNXT_CYCLECOUNTER_MASK;
3424 	ptp->tc.cc_shift = shift;
3425 	ptp->tc.nsec_mask = (1ULL << shift) - 1;
3426 
3427 	ptp->rx_tstamp_tc.cc_mask = BNXT_CYCLECOUNTER_MASK;
3428 	ptp->rx_tstamp_tc.cc_shift = shift;
3429 	ptp->rx_tstamp_tc.nsec_mask = (1ULL << shift) - 1;
3430 
3431 	ptp->tx_tstamp_tc.cc_mask = BNXT_CYCLECOUNTER_MASK;
3432 	ptp->tx_tstamp_tc.cc_shift = shift;
3433 	ptp->tx_tstamp_tc.nsec_mask = (1ULL << shift) - 1;
3434 
3435 	if (!BNXT_CHIP_THOR(bp))
3436 		bnxt_map_ptp_regs(bp);
3437 
3438 	return 0;
3439 }
3440 
3441 static int
3442 bnxt_timesync_disable(struct rte_eth_dev *dev)
3443 {
3444 	struct bnxt *bp = dev->data->dev_private;
3445 	struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
3446 
3447 	if (!ptp)
3448 		return 0;
3449 
3450 	ptp->rx_filter = 0;
3451 	ptp->tx_tstamp_en = 0;
3452 	ptp->rxctl = 0;
3453 
3454 	bnxt_hwrm_ptp_cfg(bp);
3455 
3456 	if (!BNXT_CHIP_THOR(bp))
3457 		bnxt_unmap_ptp_regs(bp);
3458 
3459 	return 0;
3460 }
3461 
3462 static int
3463 bnxt_timesync_read_rx_timestamp(struct rte_eth_dev *dev,
3464 				 struct timespec *timestamp,
3465 				 uint32_t flags __rte_unused)
3466 {
3467 	struct bnxt *bp = dev->data->dev_private;
3468 	struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
3469 	uint64_t rx_tstamp_cycles = 0;
3470 	uint64_t ns;
3471 
3472 	if (!ptp)
3473 		return 0;
3474 
3475 	if (BNXT_CHIP_THOR(bp))
3476 		rx_tstamp_cycles = ptp->rx_timestamp;
3477 	else
3478 		bnxt_get_rx_ts(bp, &rx_tstamp_cycles);
3479 
3480 	ns = rte_timecounter_update(&ptp->rx_tstamp_tc, rx_tstamp_cycles);
3481 	*timestamp = rte_ns_to_timespec(ns);
3482 	return  0;
3483 }
3484 
3485 static int
3486 bnxt_timesync_read_tx_timestamp(struct rte_eth_dev *dev,
3487 				 struct timespec *timestamp)
3488 {
3489 	struct bnxt *bp = dev->data->dev_private;
3490 	struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
3491 	uint64_t tx_tstamp_cycles = 0;
3492 	uint64_t ns;
3493 	int rc = 0;
3494 
3495 	if (!ptp)
3496 		return 0;
3497 
3498 	if (BNXT_CHIP_THOR(bp))
3499 		rc = bnxt_hwrm_port_ts_query(bp, BNXT_PTP_FLAGS_PATH_TX,
3500 					     &tx_tstamp_cycles);
3501 	else
3502 		rc = bnxt_get_tx_ts(bp, &tx_tstamp_cycles);
3503 
3504 	ns = rte_timecounter_update(&ptp->tx_tstamp_tc, tx_tstamp_cycles);
3505 	*timestamp = rte_ns_to_timespec(ns);
3506 
3507 	return rc;
3508 }
3509 
3510 static int
3511 bnxt_timesync_adjust_time(struct rte_eth_dev *dev, int64_t delta)
3512 {
3513 	struct bnxt *bp = dev->data->dev_private;
3514 	struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
3515 
3516 	if (!ptp)
3517 		return 0;
3518 
3519 	ptp->tc.nsec += delta;
3520 
3521 	return 0;
3522 }
3523 
3524 static int
3525 bnxt_get_eeprom_length_op(struct rte_eth_dev *dev)
3526 {
3527 	struct bnxt *bp = dev->data->dev_private;
3528 	int rc;
3529 	uint32_t dir_entries;
3530 	uint32_t entry_length;
3531 
3532 	rc = is_bnxt_in_error(bp);
3533 	if (rc)
3534 		return rc;
3535 
3536 	PMD_DRV_LOG(INFO, "%04x:%02x:%02x:%02x\n",
3537 		bp->pdev->addr.domain, bp->pdev->addr.bus,
3538 		bp->pdev->addr.devid, bp->pdev->addr.function);
3539 
3540 	rc = bnxt_hwrm_nvm_get_dir_info(bp, &dir_entries, &entry_length);
3541 	if (rc != 0)
3542 		return rc;
3543 
3544 	return dir_entries * entry_length;
3545 }
3546 
3547 static int
3548 bnxt_get_eeprom_op(struct rte_eth_dev *dev,
3549 		struct rte_dev_eeprom_info *in_eeprom)
3550 {
3551 	struct bnxt *bp = dev->data->dev_private;
3552 	uint32_t index;
3553 	uint32_t offset;
3554 	int rc;
3555 
3556 	rc = is_bnxt_in_error(bp);
3557 	if (rc)
3558 		return rc;
3559 
3560 	PMD_DRV_LOG(INFO, "%04x:%02x:%02x:%02x in_eeprom->offset = %d "
3561 		"len = %d\n", bp->pdev->addr.domain,
3562 		bp->pdev->addr.bus, bp->pdev->addr.devid,
3563 		bp->pdev->addr.function, in_eeprom->offset, in_eeprom->length);
3564 
3565 	if (in_eeprom->offset == 0) /* special offset value to get directory */
3566 		return bnxt_get_nvram_directory(bp, in_eeprom->length,
3567 						in_eeprom->data);
3568 
3569 	index = in_eeprom->offset >> 24;
3570 	offset = in_eeprom->offset & 0xffffff;
3571 
3572 	if (index != 0)
3573 		return bnxt_hwrm_get_nvram_item(bp, index - 1, offset,
3574 					   in_eeprom->length, in_eeprom->data);
3575 
3576 	return 0;
3577 }
3578 
3579 static bool bnxt_dir_type_is_ape_bin_format(uint16_t dir_type)
3580 {
3581 	switch (dir_type) {
3582 	case BNX_DIR_TYPE_CHIMP_PATCH:
3583 	case BNX_DIR_TYPE_BOOTCODE:
3584 	case BNX_DIR_TYPE_BOOTCODE_2:
3585 	case BNX_DIR_TYPE_APE_FW:
3586 	case BNX_DIR_TYPE_APE_PATCH:
3587 	case BNX_DIR_TYPE_KONG_FW:
3588 	case BNX_DIR_TYPE_KONG_PATCH:
3589 	case BNX_DIR_TYPE_BONO_FW:
3590 	case BNX_DIR_TYPE_BONO_PATCH:
3591 		/* FALLTHROUGH */
3592 		return true;
3593 	}
3594 
3595 	return false;
3596 }
3597 
3598 static bool bnxt_dir_type_is_other_exec_format(uint16_t dir_type)
3599 {
3600 	switch (dir_type) {
3601 	case BNX_DIR_TYPE_AVS:
3602 	case BNX_DIR_TYPE_EXP_ROM_MBA:
3603 	case BNX_DIR_TYPE_PCIE:
3604 	case BNX_DIR_TYPE_TSCF_UCODE:
3605 	case BNX_DIR_TYPE_EXT_PHY:
3606 	case BNX_DIR_TYPE_CCM:
3607 	case BNX_DIR_TYPE_ISCSI_BOOT:
3608 	case BNX_DIR_TYPE_ISCSI_BOOT_IPV6:
3609 	case BNX_DIR_TYPE_ISCSI_BOOT_IPV4N6:
3610 		/* FALLTHROUGH */
3611 		return true;
3612 	}
3613 
3614 	return false;
3615 }
3616 
3617 static bool bnxt_dir_type_is_executable(uint16_t dir_type)
3618 {
3619 	return bnxt_dir_type_is_ape_bin_format(dir_type) ||
3620 		bnxt_dir_type_is_other_exec_format(dir_type);
3621 }
3622 
3623 static int
3624 bnxt_set_eeprom_op(struct rte_eth_dev *dev,
3625 		struct rte_dev_eeprom_info *in_eeprom)
3626 {
3627 	struct bnxt *bp = dev->data->dev_private;
3628 	uint8_t index, dir_op;
3629 	uint16_t type, ext, ordinal, attr;
3630 	int rc;
3631 
3632 	rc = is_bnxt_in_error(bp);
3633 	if (rc)
3634 		return rc;
3635 
3636 	PMD_DRV_LOG(INFO, "%04x:%02x:%02x:%02x in_eeprom->offset = %d "
3637 		"len = %d\n", bp->pdev->addr.domain,
3638 		bp->pdev->addr.bus, bp->pdev->addr.devid,
3639 		bp->pdev->addr.function, in_eeprom->offset, in_eeprom->length);
3640 
3641 	if (!BNXT_PF(bp)) {
3642 		PMD_DRV_LOG(ERR, "NVM write not supported from a VF\n");
3643 		return -EINVAL;
3644 	}
3645 
3646 	type = in_eeprom->magic >> 16;
3647 
3648 	if (type == 0xffff) { /* special value for directory operations */
3649 		index = in_eeprom->magic & 0xff;
3650 		dir_op = in_eeprom->magic >> 8;
3651 		if (index == 0)
3652 			return -EINVAL;
3653 		switch (dir_op) {
3654 		case 0x0e: /* erase */
3655 			if (in_eeprom->offset != ~in_eeprom->magic)
3656 				return -EINVAL;
3657 			return bnxt_hwrm_erase_nvram_directory(bp, index - 1);
3658 		default:
3659 			return -EINVAL;
3660 		}
3661 	}
3662 
3663 	/* Create or re-write an NVM item: */
3664 	if (bnxt_dir_type_is_executable(type) == true)
3665 		return -EOPNOTSUPP;
3666 	ext = in_eeprom->magic & 0xffff;
3667 	ordinal = in_eeprom->offset >> 16;
3668 	attr = in_eeprom->offset & 0xffff;
3669 
3670 	return bnxt_hwrm_flash_nvram(bp, type, ordinal, ext, attr,
3671 				     in_eeprom->data, in_eeprom->length);
3672 }
3673 
3674 /*
3675  * Initialization
3676  */
3677 
3678 static const struct eth_dev_ops bnxt_dev_ops = {
3679 	.dev_infos_get = bnxt_dev_info_get_op,
3680 	.dev_close = bnxt_dev_close_op,
3681 	.dev_configure = bnxt_dev_configure_op,
3682 	.dev_start = bnxt_dev_start_op,
3683 	.dev_stop = bnxt_dev_stop_op,
3684 	.dev_set_link_up = bnxt_dev_set_link_up_op,
3685 	.dev_set_link_down = bnxt_dev_set_link_down_op,
3686 	.stats_get = bnxt_stats_get_op,
3687 	.stats_reset = bnxt_stats_reset_op,
3688 	.rx_queue_setup = bnxt_rx_queue_setup_op,
3689 	.rx_queue_release = bnxt_rx_queue_release_op,
3690 	.tx_queue_setup = bnxt_tx_queue_setup_op,
3691 	.tx_queue_release = bnxt_tx_queue_release_op,
3692 	.rx_queue_intr_enable = bnxt_rx_queue_intr_enable_op,
3693 	.rx_queue_intr_disable = bnxt_rx_queue_intr_disable_op,
3694 	.reta_update = bnxt_reta_update_op,
3695 	.reta_query = bnxt_reta_query_op,
3696 	.rss_hash_update = bnxt_rss_hash_update_op,
3697 	.rss_hash_conf_get = bnxt_rss_hash_conf_get_op,
3698 	.link_update = bnxt_link_update_op,
3699 	.promiscuous_enable = bnxt_promiscuous_enable_op,
3700 	.promiscuous_disable = bnxt_promiscuous_disable_op,
3701 	.allmulticast_enable = bnxt_allmulticast_enable_op,
3702 	.allmulticast_disable = bnxt_allmulticast_disable_op,
3703 	.mac_addr_add = bnxt_mac_addr_add_op,
3704 	.mac_addr_remove = bnxt_mac_addr_remove_op,
3705 	.flow_ctrl_get = bnxt_flow_ctrl_get_op,
3706 	.flow_ctrl_set = bnxt_flow_ctrl_set_op,
3707 	.udp_tunnel_port_add  = bnxt_udp_tunnel_port_add_op,
3708 	.udp_tunnel_port_del  = bnxt_udp_tunnel_port_del_op,
3709 	.vlan_filter_set = bnxt_vlan_filter_set_op,
3710 	.vlan_offload_set = bnxt_vlan_offload_set_op,
3711 	.vlan_tpid_set = bnxt_vlan_tpid_set_op,
3712 	.vlan_pvid_set = bnxt_vlan_pvid_set_op,
3713 	.mtu_set = bnxt_mtu_set_op,
3714 	.mac_addr_set = bnxt_set_default_mac_addr_op,
3715 	.xstats_get = bnxt_dev_xstats_get_op,
3716 	.xstats_get_names = bnxt_dev_xstats_get_names_op,
3717 	.xstats_reset = bnxt_dev_xstats_reset_op,
3718 	.fw_version_get = bnxt_fw_version_get,
3719 	.set_mc_addr_list = bnxt_dev_set_mc_addr_list_op,
3720 	.rxq_info_get = bnxt_rxq_info_get_op,
3721 	.txq_info_get = bnxt_txq_info_get_op,
3722 	.dev_led_on = bnxt_dev_led_on_op,
3723 	.dev_led_off = bnxt_dev_led_off_op,
3724 	.xstats_get_by_id = bnxt_dev_xstats_get_by_id_op,
3725 	.xstats_get_names_by_id = bnxt_dev_xstats_get_names_by_id_op,
3726 	.rx_queue_count = bnxt_rx_queue_count_op,
3727 	.rx_descriptor_status = bnxt_rx_descriptor_status_op,
3728 	.tx_descriptor_status = bnxt_tx_descriptor_status_op,
3729 	.rx_queue_start = bnxt_rx_queue_start,
3730 	.rx_queue_stop = bnxt_rx_queue_stop,
3731 	.tx_queue_start = bnxt_tx_queue_start,
3732 	.tx_queue_stop = bnxt_tx_queue_stop,
3733 	.filter_ctrl = bnxt_filter_ctrl_op,
3734 	.dev_supported_ptypes_get = bnxt_dev_supported_ptypes_get_op,
3735 	.get_eeprom_length    = bnxt_get_eeprom_length_op,
3736 	.get_eeprom           = bnxt_get_eeprom_op,
3737 	.set_eeprom           = bnxt_set_eeprom_op,
3738 	.timesync_enable      = bnxt_timesync_enable,
3739 	.timesync_disable     = bnxt_timesync_disable,
3740 	.timesync_read_time   = bnxt_timesync_read_time,
3741 	.timesync_write_time   = bnxt_timesync_write_time,
3742 	.timesync_adjust_time = bnxt_timesync_adjust_time,
3743 	.timesync_read_rx_timestamp = bnxt_timesync_read_rx_timestamp,
3744 	.timesync_read_tx_timestamp = bnxt_timesync_read_tx_timestamp,
3745 };
3746 
3747 static uint32_t bnxt_map_reset_regs(struct bnxt *bp, uint32_t reg)
3748 {
3749 	uint32_t offset;
3750 
3751 	/* Only pre-map the reset GRC registers using window 3 */
3752 	rte_write32(reg & 0xfffff000, (uint8_t *)bp->bar0 +
3753 		    BNXT_GRCPF_REG_WINDOW_BASE_OUT + 8);
3754 
3755 	offset = BNXT_GRCP_WINDOW_3_BASE + (reg & 0xffc);
3756 
3757 	return offset;
3758 }
3759 
3760 int bnxt_map_fw_health_status_regs(struct bnxt *bp)
3761 {
3762 	struct bnxt_error_recovery_info *info = bp->recovery_info;
3763 	uint32_t reg_base = 0xffffffff;
3764 	int i;
3765 
3766 	/* Only pre-map the monitoring GRC registers using window 2 */
3767 	for (i = 0; i < BNXT_FW_STATUS_REG_CNT; i++) {
3768 		uint32_t reg = info->status_regs[i];
3769 
3770 		if (BNXT_FW_STATUS_REG_TYPE(reg) != BNXT_FW_STATUS_REG_TYPE_GRC)
3771 			continue;
3772 
3773 		if (reg_base == 0xffffffff)
3774 			reg_base = reg & 0xfffff000;
3775 		if ((reg & 0xfffff000) != reg_base)
3776 			return -ERANGE;
3777 
3778 		/* Use mask 0xffc as the Lower 2 bits indicates
3779 		 * address space location
3780 		 */
3781 		info->mapped_status_regs[i] = BNXT_GRCP_WINDOW_2_BASE +
3782 						(reg & 0xffc);
3783 	}
3784 
3785 	if (reg_base == 0xffffffff)
3786 		return 0;
3787 
3788 	rte_write32(reg_base, (uint8_t *)bp->bar0 +
3789 		    BNXT_GRCPF_REG_WINDOW_BASE_OUT + 4);
3790 
3791 	return 0;
3792 }
3793 
3794 static void bnxt_write_fw_reset_reg(struct bnxt *bp, uint32_t index)
3795 {
3796 	struct bnxt_error_recovery_info *info = bp->recovery_info;
3797 	uint32_t delay = info->delay_after_reset[index];
3798 	uint32_t val = info->reset_reg_val[index];
3799 	uint32_t reg = info->reset_reg[index];
3800 	uint32_t type, offset;
3801 
3802 	type = BNXT_FW_STATUS_REG_TYPE(reg);
3803 	offset = BNXT_FW_STATUS_REG_OFF(reg);
3804 
3805 	switch (type) {
3806 	case BNXT_FW_STATUS_REG_TYPE_CFG:
3807 		rte_pci_write_config(bp->pdev, &val, sizeof(val), offset);
3808 		break;
3809 	case BNXT_FW_STATUS_REG_TYPE_GRC:
3810 		offset = bnxt_map_reset_regs(bp, offset);
3811 		rte_write32(val, (uint8_t *)bp->bar0 + offset);
3812 		break;
3813 	case BNXT_FW_STATUS_REG_TYPE_BAR0:
3814 		rte_write32(val, (uint8_t *)bp->bar0 + offset);
3815 		break;
3816 	}
3817 	/* wait on a specific interval of time until core reset is complete */
3818 	if (delay)
3819 		rte_delay_ms(delay);
3820 }
3821 
3822 static void bnxt_dev_cleanup(struct bnxt *bp)
3823 {
3824 	bnxt_set_hwrm_link_config(bp, false);
3825 	bp->link_info.link_up = 0;
3826 	if (bp->dev_stopped == 0)
3827 		bnxt_dev_stop_op(bp->eth_dev);
3828 
3829 	bnxt_uninit_resources(bp, true);
3830 }
3831 
3832 static int bnxt_restore_filters(struct bnxt *bp)
3833 {
3834 	struct rte_eth_dev *dev = bp->eth_dev;
3835 	int ret = 0;
3836 
3837 	if (dev->data->all_multicast)
3838 		ret = bnxt_allmulticast_enable_op(dev);
3839 	if (dev->data->promiscuous)
3840 		ret = bnxt_promiscuous_enable_op(dev);
3841 
3842 	/* TODO restore other filters as well */
3843 	return ret;
3844 }
3845 
3846 static void bnxt_dev_recover(void *arg)
3847 {
3848 	struct bnxt *bp = arg;
3849 	int timeout = bp->fw_reset_max_msecs;
3850 	int rc = 0;
3851 
3852 	/* Clear Error flag so that device re-init should happen */
3853 	bp->flags &= ~BNXT_FLAG_FATAL_ERROR;
3854 
3855 	do {
3856 		rc = bnxt_hwrm_ver_get(bp);
3857 		if (rc == 0)
3858 			break;
3859 		rte_delay_ms(BNXT_FW_READY_WAIT_INTERVAL);
3860 		timeout -= BNXT_FW_READY_WAIT_INTERVAL;
3861 	} while (rc && timeout);
3862 
3863 	if (rc) {
3864 		PMD_DRV_LOG(ERR, "FW is not Ready after reset\n");
3865 		goto err;
3866 	}
3867 
3868 	rc = bnxt_init_resources(bp, true);
3869 	if (rc) {
3870 		PMD_DRV_LOG(ERR,
3871 			    "Failed to initialize resources after reset\n");
3872 		goto err;
3873 	}
3874 	/* clear reset flag as the device is initialized now */
3875 	bp->flags &= ~BNXT_FLAG_FW_RESET;
3876 
3877 	rc = bnxt_dev_start_op(bp->eth_dev);
3878 	if (rc) {
3879 		PMD_DRV_LOG(ERR, "Failed to start port after reset\n");
3880 		goto err;
3881 	}
3882 
3883 	rc = bnxt_restore_filters(bp);
3884 	if (rc)
3885 		goto err;
3886 
3887 	PMD_DRV_LOG(INFO, "Recovered from FW reset\n");
3888 	return;
3889 err:
3890 	bp->flags |= BNXT_FLAG_FATAL_ERROR;
3891 	bnxt_uninit_resources(bp, false);
3892 	PMD_DRV_LOG(ERR, "Failed to recover from FW reset\n");
3893 }
3894 
3895 void bnxt_dev_reset_and_resume(void *arg)
3896 {
3897 	struct bnxt *bp = arg;
3898 	int rc;
3899 
3900 	bnxt_dev_cleanup(bp);
3901 
3902 	bnxt_wait_for_device_shutdown(bp);
3903 
3904 	rc = rte_eal_alarm_set(US_PER_MS * bp->fw_reset_min_msecs,
3905 			       bnxt_dev_recover, (void *)bp);
3906 	if (rc)
3907 		PMD_DRV_LOG(ERR, "Error setting recovery alarm");
3908 }
3909 
3910 uint32_t bnxt_read_fw_status_reg(struct bnxt *bp, uint32_t index)
3911 {
3912 	struct bnxt_error_recovery_info *info = bp->recovery_info;
3913 	uint32_t reg = info->status_regs[index];
3914 	uint32_t type, offset, val = 0;
3915 
3916 	type = BNXT_FW_STATUS_REG_TYPE(reg);
3917 	offset = BNXT_FW_STATUS_REG_OFF(reg);
3918 
3919 	switch (type) {
3920 	case BNXT_FW_STATUS_REG_TYPE_CFG:
3921 		rte_pci_read_config(bp->pdev, &val, sizeof(val), offset);
3922 		break;
3923 	case BNXT_FW_STATUS_REG_TYPE_GRC:
3924 		offset = info->mapped_status_regs[index];
3925 		/* FALLTHROUGH */
3926 	case BNXT_FW_STATUS_REG_TYPE_BAR0:
3927 		val = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 +
3928 				       offset));
3929 		break;
3930 	}
3931 
3932 	return val;
3933 }
3934 
3935 static int bnxt_fw_reset_all(struct bnxt *bp)
3936 {
3937 	struct bnxt_error_recovery_info *info = bp->recovery_info;
3938 	uint32_t i;
3939 	int rc = 0;
3940 
3941 	if (info->flags & BNXT_FLAG_ERROR_RECOVERY_HOST) {
3942 		/* Reset through master function driver */
3943 		for (i = 0; i < info->reg_array_cnt; i++)
3944 			bnxt_write_fw_reset_reg(bp, i);
3945 		/* Wait for time specified by FW after triggering reset */
3946 		rte_delay_ms(info->master_func_wait_period_after_reset);
3947 	} else if (info->flags & BNXT_FLAG_ERROR_RECOVERY_CO_CPU) {
3948 		/* Reset with the help of Kong processor */
3949 		rc = bnxt_hwrm_fw_reset(bp);
3950 		if (rc)
3951 			PMD_DRV_LOG(ERR, "Failed to reset FW\n");
3952 	}
3953 
3954 	return rc;
3955 }
3956 
3957 static void bnxt_fw_reset_cb(void *arg)
3958 {
3959 	struct bnxt *bp = arg;
3960 	struct bnxt_error_recovery_info *info = bp->recovery_info;
3961 	int rc = 0;
3962 
3963 	/* Only Master function can do FW reset */
3964 	if (bnxt_is_master_func(bp) &&
3965 	    bnxt_is_recovery_enabled(bp)) {
3966 		rc = bnxt_fw_reset_all(bp);
3967 		if (rc) {
3968 			PMD_DRV_LOG(ERR, "Adapter recovery failed\n");
3969 			return;
3970 		}
3971 	}
3972 
3973 	/* if recovery method is ERROR_RECOVERY_CO_CPU, KONG will send
3974 	 * EXCEPTION_FATAL_ASYNC event to all the functions
3975 	 * (including MASTER FUNC). After receiving this Async, all the active
3976 	 * drivers should treat this case as FW initiated recovery
3977 	 */
3978 	if (info->flags & BNXT_FLAG_ERROR_RECOVERY_HOST) {
3979 		bp->fw_reset_min_msecs = BNXT_MIN_FW_READY_TIMEOUT;
3980 		bp->fw_reset_max_msecs = BNXT_MAX_FW_RESET_TIMEOUT;
3981 
3982 		/* To recover from error */
3983 		rte_eal_alarm_set(US_PER_MS, bnxt_dev_reset_and_resume,
3984 				  (void *)bp);
3985 	}
3986 }
3987 
3988 /* Driver should poll FW heartbeat, reset_counter with the frequency
3989  * advertised by FW in HWRM_ERROR_RECOVERY_QCFG.
3990  * When the driver detects heartbeat stop or change in reset_counter,
3991  * it has to trigger a reset to recover from the error condition.
3992  * A “master PF” is the function who will have the privilege to
3993  * initiate the chimp reset. The master PF will be elected by the
3994  * firmware and will be notified through async message.
3995  */
3996 static void bnxt_check_fw_health(void *arg)
3997 {
3998 	struct bnxt *bp = arg;
3999 	struct bnxt_error_recovery_info *info = bp->recovery_info;
4000 	uint32_t val = 0, wait_msec;
4001 
4002 	if (!info || !bnxt_is_recovery_enabled(bp) ||
4003 	    is_bnxt_in_error(bp))
4004 		return;
4005 
4006 	val = bnxt_read_fw_status_reg(bp, BNXT_FW_HEARTBEAT_CNT_REG);
4007 	if (val == info->last_heart_beat)
4008 		goto reset;
4009 
4010 	info->last_heart_beat = val;
4011 
4012 	val = bnxt_read_fw_status_reg(bp, BNXT_FW_RECOVERY_CNT_REG);
4013 	if (val != info->last_reset_counter)
4014 		goto reset;
4015 
4016 	info->last_reset_counter = val;
4017 
4018 	rte_eal_alarm_set(US_PER_MS * info->driver_polling_freq,
4019 			  bnxt_check_fw_health, (void *)bp);
4020 
4021 	return;
4022 reset:
4023 	/* Stop DMA to/from device */
4024 	bp->flags |= BNXT_FLAG_FATAL_ERROR;
4025 	bp->flags |= BNXT_FLAG_FW_RESET;
4026 
4027 	PMD_DRV_LOG(ERR, "Detected FW dead condition\n");
4028 
4029 	if (bnxt_is_master_func(bp))
4030 		wait_msec = info->master_func_wait_period;
4031 	else
4032 		wait_msec = info->normal_func_wait_period;
4033 
4034 	rte_eal_alarm_set(US_PER_MS * wait_msec,
4035 			  bnxt_fw_reset_cb, (void *)bp);
4036 }
4037 
4038 void bnxt_schedule_fw_health_check(struct bnxt *bp)
4039 {
4040 	uint32_t polling_freq;
4041 
4042 	if (!bnxt_is_recovery_enabled(bp))
4043 		return;
4044 
4045 	if (bp->flags & BNXT_FLAG_FW_HEALTH_CHECK_SCHEDULED)
4046 		return;
4047 
4048 	polling_freq = bp->recovery_info->driver_polling_freq;
4049 
4050 	rte_eal_alarm_set(US_PER_MS * polling_freq,
4051 			  bnxt_check_fw_health, (void *)bp);
4052 	bp->flags |= BNXT_FLAG_FW_HEALTH_CHECK_SCHEDULED;
4053 }
4054 
4055 static void bnxt_cancel_fw_health_check(struct bnxt *bp)
4056 {
4057 	if (!bnxt_is_recovery_enabled(bp))
4058 		return;
4059 
4060 	rte_eal_alarm_cancel(bnxt_check_fw_health, (void *)bp);
4061 	bp->flags &= ~BNXT_FLAG_FW_HEALTH_CHECK_SCHEDULED;
4062 }
4063 
4064 static bool bnxt_vf_pciid(uint16_t id)
4065 {
4066 	if (id == BROADCOM_DEV_ID_57304_VF ||
4067 	    id == BROADCOM_DEV_ID_57406_VF ||
4068 	    id == BROADCOM_DEV_ID_5731X_VF ||
4069 	    id == BROADCOM_DEV_ID_5741X_VF ||
4070 	    id == BROADCOM_DEV_ID_57414_VF ||
4071 	    id == BROADCOM_DEV_ID_STRATUS_NIC_VF1 ||
4072 	    id == BROADCOM_DEV_ID_STRATUS_NIC_VF2 ||
4073 	    id == BROADCOM_DEV_ID_58802_VF ||
4074 	    id == BROADCOM_DEV_ID_57500_VF1 ||
4075 	    id == BROADCOM_DEV_ID_57500_VF2)
4076 		return true;
4077 	return false;
4078 }
4079 
4080 static bool bnxt_thor_device(uint16_t id)
4081 {
4082 	if (id == BROADCOM_DEV_ID_57508 ||
4083 	    id == BROADCOM_DEV_ID_57504 ||
4084 	    id == BROADCOM_DEV_ID_57502 ||
4085 	    id == BROADCOM_DEV_ID_57508_MF1 ||
4086 	    id == BROADCOM_DEV_ID_57504_MF1 ||
4087 	    id == BROADCOM_DEV_ID_57502_MF1 ||
4088 	    id == BROADCOM_DEV_ID_57508_MF2 ||
4089 	    id == BROADCOM_DEV_ID_57504_MF2 ||
4090 	    id == BROADCOM_DEV_ID_57502_MF2 ||
4091 	    id == BROADCOM_DEV_ID_57500_VF1 ||
4092 	    id == BROADCOM_DEV_ID_57500_VF2)
4093 		return true;
4094 
4095 	return false;
4096 }
4097 
4098 bool bnxt_stratus_device(struct bnxt *bp)
4099 {
4100 	uint16_t id = bp->pdev->id.device_id;
4101 
4102 	if (id == BROADCOM_DEV_ID_STRATUS_NIC ||
4103 	    id == BROADCOM_DEV_ID_STRATUS_NIC_VF1 ||
4104 	    id == BROADCOM_DEV_ID_STRATUS_NIC_VF2)
4105 		return true;
4106 	return false;
4107 }
4108 
4109 static int bnxt_init_board(struct rte_eth_dev *eth_dev)
4110 {
4111 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
4112 	struct bnxt *bp = eth_dev->data->dev_private;
4113 
4114 	/* enable device (incl. PCI PM wakeup), and bus-mastering */
4115 	bp->bar0 = (void *)pci_dev->mem_resource[0].addr;
4116 	bp->doorbell_base = (void *)pci_dev->mem_resource[2].addr;
4117 	if (!bp->bar0 || !bp->doorbell_base) {
4118 		PMD_DRV_LOG(ERR, "Unable to access Hardware\n");
4119 		return -ENODEV;
4120 	}
4121 
4122 	bp->eth_dev = eth_dev;
4123 	bp->pdev = pci_dev;
4124 
4125 	return 0;
4126 }
4127 
4128 static int bnxt_alloc_ctx_mem_blk(__rte_unused struct bnxt *bp,
4129 				  struct bnxt_ctx_pg_info *ctx_pg,
4130 				  uint32_t mem_size,
4131 				  const char *suffix,
4132 				  uint16_t idx)
4133 {
4134 	struct bnxt_ring_mem_info *rmem = &ctx_pg->ring_mem;
4135 	const struct rte_memzone *mz = NULL;
4136 	char mz_name[RTE_MEMZONE_NAMESIZE];
4137 	rte_iova_t mz_phys_addr;
4138 	uint64_t valid_bits = 0;
4139 	uint32_t sz;
4140 	int i;
4141 
4142 	if (!mem_size)
4143 		return 0;
4144 
4145 	rmem->nr_pages = RTE_ALIGN_MUL_CEIL(mem_size, BNXT_PAGE_SIZE) /
4146 			 BNXT_PAGE_SIZE;
4147 	rmem->page_size = BNXT_PAGE_SIZE;
4148 	rmem->pg_arr = ctx_pg->ctx_pg_arr;
4149 	rmem->dma_arr = ctx_pg->ctx_dma_arr;
4150 	rmem->flags = BNXT_RMEM_VALID_PTE_FLAG;
4151 
4152 	valid_bits = PTU_PTE_VALID;
4153 
4154 	if (rmem->nr_pages > 1) {
4155 		snprintf(mz_name, RTE_MEMZONE_NAMESIZE,
4156 			 "bnxt_ctx_pg_tbl%s_%x_%d",
4157 			 suffix, idx, bp->eth_dev->data->port_id);
4158 		mz_name[RTE_MEMZONE_NAMESIZE - 1] = 0;
4159 		mz = rte_memzone_lookup(mz_name);
4160 		if (!mz) {
4161 			mz = rte_memzone_reserve_aligned(mz_name,
4162 						rmem->nr_pages * 8,
4163 						SOCKET_ID_ANY,
4164 						RTE_MEMZONE_2MB |
4165 						RTE_MEMZONE_SIZE_HINT_ONLY |
4166 						RTE_MEMZONE_IOVA_CONTIG,
4167 						BNXT_PAGE_SIZE);
4168 			if (mz == NULL)
4169 				return -ENOMEM;
4170 		}
4171 
4172 		memset(mz->addr, 0, mz->len);
4173 		mz_phys_addr = mz->iova;
4174 		if ((unsigned long)mz->addr == mz_phys_addr) {
4175 			PMD_DRV_LOG(DEBUG,
4176 				    "physical address same as virtual\n");
4177 			PMD_DRV_LOG(DEBUG, "Using rte_mem_virt2iova()\n");
4178 			mz_phys_addr = rte_mem_virt2iova(mz->addr);
4179 			if (mz_phys_addr == RTE_BAD_IOVA) {
4180 				PMD_DRV_LOG(ERR,
4181 					"unable to map addr to phys memory\n");
4182 				return -ENOMEM;
4183 			}
4184 		}
4185 		rte_mem_lock_page(((char *)mz->addr));
4186 
4187 		rmem->pg_tbl = mz->addr;
4188 		rmem->pg_tbl_map = mz_phys_addr;
4189 		rmem->pg_tbl_mz = mz;
4190 	}
4191 
4192 	snprintf(mz_name, RTE_MEMZONE_NAMESIZE, "bnxt_ctx_%s_%x_%d",
4193 		 suffix, idx, bp->eth_dev->data->port_id);
4194 	mz = rte_memzone_lookup(mz_name);
4195 	if (!mz) {
4196 		mz = rte_memzone_reserve_aligned(mz_name,
4197 						 mem_size,
4198 						 SOCKET_ID_ANY,
4199 						 RTE_MEMZONE_1GB |
4200 						 RTE_MEMZONE_SIZE_HINT_ONLY |
4201 						 RTE_MEMZONE_IOVA_CONTIG,
4202 						 BNXT_PAGE_SIZE);
4203 		if (mz == NULL)
4204 			return -ENOMEM;
4205 	}
4206 
4207 	memset(mz->addr, 0, mz->len);
4208 	mz_phys_addr = mz->iova;
4209 	if ((unsigned long)mz->addr == mz_phys_addr) {
4210 		PMD_DRV_LOG(DEBUG,
4211 			    "Memzone physical address same as virtual.\n");
4212 		PMD_DRV_LOG(DEBUG, "Using rte_mem_virt2iova()\n");
4213 		for (sz = 0; sz < mem_size; sz += BNXT_PAGE_SIZE)
4214 			rte_mem_lock_page(((char *)mz->addr) + sz);
4215 		mz_phys_addr = rte_mem_virt2iova(mz->addr);
4216 		if (mz_phys_addr == RTE_BAD_IOVA) {
4217 			PMD_DRV_LOG(ERR,
4218 				    "unable to map addr to phys memory\n");
4219 			return -ENOMEM;
4220 		}
4221 	}
4222 
4223 	for (sz = 0, i = 0; sz < mem_size; sz += BNXT_PAGE_SIZE, i++) {
4224 		rte_mem_lock_page(((char *)mz->addr) + sz);
4225 		rmem->pg_arr[i] = ((char *)mz->addr) + sz;
4226 		rmem->dma_arr[i] = mz_phys_addr + sz;
4227 
4228 		if (rmem->nr_pages > 1) {
4229 			if (i == rmem->nr_pages - 2 &&
4230 			    (rmem->flags & BNXT_RMEM_RING_PTE_FLAG))
4231 				valid_bits |= PTU_PTE_NEXT_TO_LAST;
4232 			else if (i == rmem->nr_pages - 1 &&
4233 				 (rmem->flags & BNXT_RMEM_RING_PTE_FLAG))
4234 				valid_bits |= PTU_PTE_LAST;
4235 
4236 			rmem->pg_tbl[i] = rte_cpu_to_le_64(rmem->dma_arr[i] |
4237 							   valid_bits);
4238 		}
4239 	}
4240 
4241 	rmem->mz = mz;
4242 	if (rmem->vmem_size)
4243 		rmem->vmem = (void **)mz->addr;
4244 	rmem->dma_arr[0] = mz_phys_addr;
4245 	return 0;
4246 }
4247 
4248 static void bnxt_free_ctx_mem(struct bnxt *bp)
4249 {
4250 	int i;
4251 
4252 	if (!bp->ctx || !(bp->ctx->flags & BNXT_CTX_FLAG_INITED))
4253 		return;
4254 
4255 	bp->ctx->flags &= ~BNXT_CTX_FLAG_INITED;
4256 	rte_memzone_free(bp->ctx->qp_mem.ring_mem.mz);
4257 	rte_memzone_free(bp->ctx->srq_mem.ring_mem.mz);
4258 	rte_memzone_free(bp->ctx->cq_mem.ring_mem.mz);
4259 	rte_memzone_free(bp->ctx->vnic_mem.ring_mem.mz);
4260 	rte_memzone_free(bp->ctx->stat_mem.ring_mem.mz);
4261 	rte_memzone_free(bp->ctx->qp_mem.ring_mem.pg_tbl_mz);
4262 	rte_memzone_free(bp->ctx->srq_mem.ring_mem.pg_tbl_mz);
4263 	rte_memzone_free(bp->ctx->cq_mem.ring_mem.pg_tbl_mz);
4264 	rte_memzone_free(bp->ctx->vnic_mem.ring_mem.pg_tbl_mz);
4265 	rte_memzone_free(bp->ctx->stat_mem.ring_mem.pg_tbl_mz);
4266 
4267 	for (i = 0; i < BNXT_MAX_Q; i++) {
4268 		if (bp->ctx->tqm_mem[i])
4269 			rte_memzone_free(bp->ctx->tqm_mem[i]->ring_mem.mz);
4270 	}
4271 
4272 	rte_free(bp->ctx);
4273 	bp->ctx = NULL;
4274 }
4275 
4276 #define bnxt_roundup(x, y)   ((((x) + ((y) - 1)) / (y)) * (y))
4277 
4278 #define min_t(type, x, y) ({                    \
4279 	type __min1 = (x);                      \
4280 	type __min2 = (y);                      \
4281 	__min1 < __min2 ? __min1 : __min2; })
4282 
4283 #define max_t(type, x, y) ({                    \
4284 	type __max1 = (x);                      \
4285 	type __max2 = (y);                      \
4286 	__max1 > __max2 ? __max1 : __max2; })
4287 
4288 #define clamp_t(type, _x, min, max)     min_t(type, max_t(type, _x, min), max)
4289 
4290 int bnxt_alloc_ctx_mem(struct bnxt *bp)
4291 {
4292 	struct bnxt_ctx_pg_info *ctx_pg;
4293 	struct bnxt_ctx_mem_info *ctx;
4294 	uint32_t mem_size, ena, entries;
4295 	int i, rc;
4296 
4297 	rc = bnxt_hwrm_func_backing_store_qcaps(bp);
4298 	if (rc) {
4299 		PMD_DRV_LOG(ERR, "Query context mem capability failed\n");
4300 		return rc;
4301 	}
4302 	ctx = bp->ctx;
4303 	if (!ctx || (ctx->flags & BNXT_CTX_FLAG_INITED))
4304 		return 0;
4305 
4306 	ctx_pg = &ctx->qp_mem;
4307 	ctx_pg->entries = ctx->qp_min_qp1_entries + ctx->qp_max_l2_entries;
4308 	mem_size = ctx->qp_entry_size * ctx_pg->entries;
4309 	rc = bnxt_alloc_ctx_mem_blk(bp, ctx_pg, mem_size, "qp_mem", 0);
4310 	if (rc)
4311 		return rc;
4312 
4313 	ctx_pg = &ctx->srq_mem;
4314 	ctx_pg->entries = ctx->srq_max_l2_entries;
4315 	mem_size = ctx->srq_entry_size * ctx_pg->entries;
4316 	rc = bnxt_alloc_ctx_mem_blk(bp, ctx_pg, mem_size, "srq_mem", 0);
4317 	if (rc)
4318 		return rc;
4319 
4320 	ctx_pg = &ctx->cq_mem;
4321 	ctx_pg->entries = ctx->cq_max_l2_entries;
4322 	mem_size = ctx->cq_entry_size * ctx_pg->entries;
4323 	rc = bnxt_alloc_ctx_mem_blk(bp, ctx_pg, mem_size, "cq_mem", 0);
4324 	if (rc)
4325 		return rc;
4326 
4327 	ctx_pg = &ctx->vnic_mem;
4328 	ctx_pg->entries = ctx->vnic_max_vnic_entries +
4329 		ctx->vnic_max_ring_table_entries;
4330 	mem_size = ctx->vnic_entry_size * ctx_pg->entries;
4331 	rc = bnxt_alloc_ctx_mem_blk(bp, ctx_pg, mem_size, "vnic_mem", 0);
4332 	if (rc)
4333 		return rc;
4334 
4335 	ctx_pg = &ctx->stat_mem;
4336 	ctx_pg->entries = ctx->stat_max_entries;
4337 	mem_size = ctx->stat_entry_size * ctx_pg->entries;
4338 	rc = bnxt_alloc_ctx_mem_blk(bp, ctx_pg, mem_size, "stat_mem", 0);
4339 	if (rc)
4340 		return rc;
4341 
4342 	entries = ctx->qp_max_l2_entries +
4343 		  ctx->vnic_max_vnic_entries +
4344 		  ctx->tqm_min_entries_per_ring;
4345 	entries = bnxt_roundup(entries, ctx->tqm_entries_multiple);
4346 	entries = clamp_t(uint32_t, entries, ctx->tqm_min_entries_per_ring,
4347 			  ctx->tqm_max_entries_per_ring);
4348 	for (i = 0, ena = 0; i < BNXT_MAX_Q; i++) {
4349 		ctx_pg = ctx->tqm_mem[i];
4350 		/* use min tqm entries for now. */
4351 		ctx_pg->entries = entries;
4352 		mem_size = ctx->tqm_entry_size * ctx_pg->entries;
4353 		rc = bnxt_alloc_ctx_mem_blk(bp, ctx_pg, mem_size, "tqm_mem", i);
4354 		if (rc)
4355 			return rc;
4356 		ena |= HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_TQM_SP << i;
4357 	}
4358 
4359 	ena |= FUNC_BACKING_STORE_CFG_INPUT_DFLT_ENABLES;
4360 	rc = bnxt_hwrm_func_backing_store_cfg(bp, ena);
4361 	if (rc)
4362 		PMD_DRV_LOG(ERR,
4363 			    "Failed to configure context mem: rc = %d\n", rc);
4364 	else
4365 		ctx->flags |= BNXT_CTX_FLAG_INITED;
4366 
4367 	return rc;
4368 }
4369 
4370 static int bnxt_alloc_stats_mem(struct bnxt *bp)
4371 {
4372 	struct rte_pci_device *pci_dev = bp->pdev;
4373 	char mz_name[RTE_MEMZONE_NAMESIZE];
4374 	const struct rte_memzone *mz = NULL;
4375 	uint32_t total_alloc_len;
4376 	rte_iova_t mz_phys_addr;
4377 
4378 	if (pci_dev->id.device_id == BROADCOM_DEV_ID_NS2)
4379 		return 0;
4380 
4381 	snprintf(mz_name, RTE_MEMZONE_NAMESIZE,
4382 		 "bnxt_" PCI_PRI_FMT "-%s", pci_dev->addr.domain,
4383 		 pci_dev->addr.bus, pci_dev->addr.devid,
4384 		 pci_dev->addr.function, "rx_port_stats");
4385 	mz_name[RTE_MEMZONE_NAMESIZE - 1] = 0;
4386 	mz = rte_memzone_lookup(mz_name);
4387 	total_alloc_len =
4388 		RTE_CACHE_LINE_ROUNDUP(sizeof(struct rx_port_stats) +
4389 				       sizeof(struct rx_port_stats_ext) + 512);
4390 	if (!mz) {
4391 		mz = rte_memzone_reserve(mz_name, total_alloc_len,
4392 					 SOCKET_ID_ANY,
4393 					 RTE_MEMZONE_2MB |
4394 					 RTE_MEMZONE_SIZE_HINT_ONLY |
4395 					 RTE_MEMZONE_IOVA_CONTIG);
4396 		if (mz == NULL)
4397 			return -ENOMEM;
4398 	}
4399 	memset(mz->addr, 0, mz->len);
4400 	mz_phys_addr = mz->iova;
4401 	if ((unsigned long)mz->addr == mz_phys_addr) {
4402 		PMD_DRV_LOG(DEBUG,
4403 			    "Memzone physical address same as virtual.\n");
4404 		PMD_DRV_LOG(DEBUG,
4405 			    "Using rte_mem_virt2iova()\n");
4406 		mz_phys_addr = rte_mem_virt2iova(mz->addr);
4407 		if (mz_phys_addr == RTE_BAD_IOVA) {
4408 			PMD_DRV_LOG(ERR,
4409 				    "Can't map address to physical memory\n");
4410 			return -ENOMEM;
4411 		}
4412 	}
4413 
4414 	bp->rx_mem_zone = (const void *)mz;
4415 	bp->hw_rx_port_stats = mz->addr;
4416 	bp->hw_rx_port_stats_map = mz_phys_addr;
4417 
4418 	snprintf(mz_name, RTE_MEMZONE_NAMESIZE,
4419 		 "bnxt_" PCI_PRI_FMT "-%s", pci_dev->addr.domain,
4420 		 pci_dev->addr.bus, pci_dev->addr.devid,
4421 		 pci_dev->addr.function, "tx_port_stats");
4422 	mz_name[RTE_MEMZONE_NAMESIZE - 1] = 0;
4423 	mz = rte_memzone_lookup(mz_name);
4424 	total_alloc_len =
4425 		RTE_CACHE_LINE_ROUNDUP(sizeof(struct tx_port_stats) +
4426 				       sizeof(struct tx_port_stats_ext) + 512);
4427 	if (!mz) {
4428 		mz = rte_memzone_reserve(mz_name,
4429 					 total_alloc_len,
4430 					 SOCKET_ID_ANY,
4431 					 RTE_MEMZONE_2MB |
4432 					 RTE_MEMZONE_SIZE_HINT_ONLY |
4433 					 RTE_MEMZONE_IOVA_CONTIG);
4434 		if (mz == NULL)
4435 			return -ENOMEM;
4436 	}
4437 	memset(mz->addr, 0, mz->len);
4438 	mz_phys_addr = mz->iova;
4439 	if ((unsigned long)mz->addr == mz_phys_addr) {
4440 		PMD_DRV_LOG(DEBUG,
4441 			    "Memzone physical address same as virtual\n");
4442 		PMD_DRV_LOG(DEBUG, "Using rte_mem_virt2iova()\n");
4443 		mz_phys_addr = rte_mem_virt2iova(mz->addr);
4444 		if (mz_phys_addr == RTE_BAD_IOVA) {
4445 			PMD_DRV_LOG(ERR,
4446 				    "Can't map address to physical memory\n");
4447 			return -ENOMEM;
4448 		}
4449 	}
4450 
4451 	bp->tx_mem_zone = (const void *)mz;
4452 	bp->hw_tx_port_stats = mz->addr;
4453 	bp->hw_tx_port_stats_map = mz_phys_addr;
4454 	bp->flags |= BNXT_FLAG_PORT_STATS;
4455 
4456 	/* Display extended statistics if FW supports it */
4457 	if (bp->hwrm_spec_code < HWRM_SPEC_CODE_1_8_4 ||
4458 	    bp->hwrm_spec_code == HWRM_SPEC_CODE_1_9_0 ||
4459 	    !(bp->flags & BNXT_FLAG_EXT_STATS_SUPPORTED))
4460 		return 0;
4461 
4462 	bp->hw_rx_port_stats_ext = (void *)
4463 		((uint8_t *)bp->hw_rx_port_stats +
4464 		 sizeof(struct rx_port_stats));
4465 	bp->hw_rx_port_stats_ext_map = bp->hw_rx_port_stats_map +
4466 		sizeof(struct rx_port_stats);
4467 	bp->flags |= BNXT_FLAG_EXT_RX_PORT_STATS;
4468 
4469 	if (bp->hwrm_spec_code < HWRM_SPEC_CODE_1_9_2 ||
4470 	    bp->flags & BNXT_FLAG_EXT_STATS_SUPPORTED) {
4471 		bp->hw_tx_port_stats_ext = (void *)
4472 			((uint8_t *)bp->hw_tx_port_stats +
4473 			 sizeof(struct tx_port_stats));
4474 		bp->hw_tx_port_stats_ext_map =
4475 			bp->hw_tx_port_stats_map +
4476 			sizeof(struct tx_port_stats);
4477 		bp->flags |= BNXT_FLAG_EXT_TX_PORT_STATS;
4478 	}
4479 
4480 	return 0;
4481 }
4482 
4483 static int bnxt_setup_mac_addr(struct rte_eth_dev *eth_dev)
4484 {
4485 	struct bnxt *bp = eth_dev->data->dev_private;
4486 	int rc = 0;
4487 
4488 	eth_dev->data->mac_addrs = rte_zmalloc("bnxt_mac_addr_tbl",
4489 					       RTE_ETHER_ADDR_LEN *
4490 					       bp->max_l2_ctx,
4491 					       0);
4492 	if (eth_dev->data->mac_addrs == NULL) {
4493 		PMD_DRV_LOG(ERR, "Failed to alloc MAC addr tbl\n");
4494 		return -ENOMEM;
4495 	}
4496 
4497 	if (bnxt_check_zero_bytes(bp->dflt_mac_addr, RTE_ETHER_ADDR_LEN)) {
4498 		if (BNXT_PF(bp))
4499 			return -EINVAL;
4500 
4501 		/* Generate a random MAC address, if none was assigned by PF */
4502 		PMD_DRV_LOG(INFO, "VF MAC address not assigned by Host PF\n");
4503 		bnxt_eth_hw_addr_random(bp->mac_addr);
4504 		PMD_DRV_LOG(INFO,
4505 			    "Assign random MAC:%02X:%02X:%02X:%02X:%02X:%02X\n",
4506 			    bp->mac_addr[0], bp->mac_addr[1], bp->mac_addr[2],
4507 			    bp->mac_addr[3], bp->mac_addr[4], bp->mac_addr[5]);
4508 
4509 		rc = bnxt_hwrm_set_mac(bp);
4510 		if (!rc)
4511 			memcpy(&bp->eth_dev->data->mac_addrs[0], bp->mac_addr,
4512 			       RTE_ETHER_ADDR_LEN);
4513 		return rc;
4514 	}
4515 
4516 	/* Copy the permanent MAC from the FUNC_QCAPS response */
4517 	memcpy(bp->mac_addr, bp->dflt_mac_addr, RTE_ETHER_ADDR_LEN);
4518 	memcpy(&eth_dev->data->mac_addrs[0], bp->mac_addr, RTE_ETHER_ADDR_LEN);
4519 
4520 	return rc;
4521 }
4522 
4523 static int bnxt_restore_dflt_mac(struct bnxt *bp)
4524 {
4525 	int rc = 0;
4526 
4527 	/* MAC is already configured in FW */
4528 	if (!bnxt_check_zero_bytes(bp->dflt_mac_addr, RTE_ETHER_ADDR_LEN))
4529 		return 0;
4530 
4531 	/* Restore the old MAC configured */
4532 	rc = bnxt_hwrm_set_mac(bp);
4533 	if (rc)
4534 		PMD_DRV_LOG(ERR, "Failed to restore MAC address\n");
4535 
4536 	return rc;
4537 }
4538 
4539 static void bnxt_config_vf_req_fwd(struct bnxt *bp)
4540 {
4541 	if (!BNXT_PF(bp))
4542 		return;
4543 
4544 #define ALLOW_FUNC(x)	\
4545 	{ \
4546 		uint32_t arg = (x); \
4547 		bp->pf.vf_req_fwd[((arg) >> 5)] &= \
4548 		~rte_cpu_to_le_32(1 << ((arg) & 0x1f)); \
4549 	}
4550 
4551 	/* Forward all requests if firmware is new enough */
4552 	if (((bp->fw_ver >= ((20 << 24) | (6 << 16) | (100 << 8))) &&
4553 	     (bp->fw_ver < ((20 << 24) | (7 << 16)))) ||
4554 	    ((bp->fw_ver >= ((20 << 24) | (8 << 16))))) {
4555 		memset(bp->pf.vf_req_fwd, 0xff, sizeof(bp->pf.vf_req_fwd));
4556 	} else {
4557 		PMD_DRV_LOG(WARNING,
4558 			    "Firmware too old for VF mailbox functionality\n");
4559 		memset(bp->pf.vf_req_fwd, 0, sizeof(bp->pf.vf_req_fwd));
4560 	}
4561 
4562 	/*
4563 	 * The following are used for driver cleanup. If we disallow these,
4564 	 * VF drivers can't clean up cleanly.
4565 	 */
4566 	ALLOW_FUNC(HWRM_FUNC_DRV_UNRGTR);
4567 	ALLOW_FUNC(HWRM_VNIC_FREE);
4568 	ALLOW_FUNC(HWRM_RING_FREE);
4569 	ALLOW_FUNC(HWRM_RING_GRP_FREE);
4570 	ALLOW_FUNC(HWRM_VNIC_RSS_COS_LB_CTX_FREE);
4571 	ALLOW_FUNC(HWRM_CFA_L2_FILTER_FREE);
4572 	ALLOW_FUNC(HWRM_STAT_CTX_FREE);
4573 	ALLOW_FUNC(HWRM_PORT_PHY_QCFG);
4574 	ALLOW_FUNC(HWRM_VNIC_TPA_CFG);
4575 }
4576 
4577 static int bnxt_init_fw(struct bnxt *bp)
4578 {
4579 	uint16_t mtu;
4580 	int rc = 0;
4581 
4582 	rc = bnxt_hwrm_ver_get(bp);
4583 	if (rc)
4584 		return rc;
4585 
4586 	rc = bnxt_hwrm_func_reset(bp);
4587 	if (rc)
4588 		return -EIO;
4589 
4590 	rc = bnxt_hwrm_vnic_qcaps(bp);
4591 	if (rc)
4592 		return rc;
4593 
4594 	rc = bnxt_hwrm_queue_qportcfg(bp);
4595 	if (rc)
4596 		return rc;
4597 
4598 	/* Get the MAX capabilities for this function.
4599 	 * This function also allocates context memory for TQM rings and
4600 	 * informs the firmware about this allocated backing store memory.
4601 	 */
4602 	rc = bnxt_hwrm_func_qcaps(bp);
4603 	if (rc)
4604 		return rc;
4605 
4606 	rc = bnxt_hwrm_func_qcfg(bp, &mtu);
4607 	if (rc)
4608 		return rc;
4609 
4610 	rc = bnxt_hwrm_cfa_adv_flow_mgmt_qcaps(bp);
4611 	if (rc)
4612 		return rc;
4613 
4614 	/* Get the adapter error recovery support info */
4615 	rc = bnxt_hwrm_error_recovery_qcfg(bp);
4616 	if (rc)
4617 		bp->flags &= ~BNXT_FLAG_FW_CAP_ERROR_RECOVERY;
4618 
4619 	if (mtu >= RTE_ETHER_MIN_MTU && mtu <= BNXT_MAX_MTU &&
4620 	    mtu != bp->eth_dev->data->mtu)
4621 		bp->eth_dev->data->mtu = mtu;
4622 
4623 	bnxt_hwrm_port_led_qcaps(bp);
4624 
4625 	return 0;
4626 }
4627 
4628 static int
4629 bnxt_init_locks(struct bnxt *bp)
4630 {
4631 	int err;
4632 
4633 	err = pthread_mutex_init(&bp->flow_lock, NULL);
4634 	if (err) {
4635 		PMD_DRV_LOG(ERR, "Unable to initialize flow_lock\n");
4636 		return err;
4637 	}
4638 
4639 	err = pthread_mutex_init(&bp->def_cp_lock, NULL);
4640 	if (err)
4641 		PMD_DRV_LOG(ERR, "Unable to initialize def_cp_lock\n");
4642 	return err;
4643 }
4644 
4645 static int bnxt_init_resources(struct bnxt *bp, bool reconfig_dev)
4646 {
4647 	int rc;
4648 
4649 	rc = bnxt_init_fw(bp);
4650 	if (rc)
4651 		return rc;
4652 
4653 	if (!reconfig_dev) {
4654 		rc = bnxt_setup_mac_addr(bp->eth_dev);
4655 		if (rc)
4656 			return rc;
4657 	} else {
4658 		rc = bnxt_restore_dflt_mac(bp);
4659 		if (rc)
4660 			return rc;
4661 	}
4662 
4663 	bnxt_config_vf_req_fwd(bp);
4664 
4665 	rc = bnxt_hwrm_func_driver_register(bp);
4666 	if (rc) {
4667 		PMD_DRV_LOG(ERR, "Failed to register driver");
4668 		return -EBUSY;
4669 	}
4670 
4671 	if (BNXT_PF(bp)) {
4672 		if (bp->pdev->max_vfs) {
4673 			rc = bnxt_hwrm_allocate_vfs(bp, bp->pdev->max_vfs);
4674 			if (rc) {
4675 				PMD_DRV_LOG(ERR, "Failed to allocate VFs\n");
4676 				return rc;
4677 			}
4678 		} else {
4679 			rc = bnxt_hwrm_allocate_pf_only(bp);
4680 			if (rc) {
4681 				PMD_DRV_LOG(ERR,
4682 					    "Failed to allocate PF resources");
4683 				return rc;
4684 			}
4685 		}
4686 	}
4687 
4688 	rc = bnxt_alloc_mem(bp, reconfig_dev);
4689 	if (rc)
4690 		return rc;
4691 
4692 	rc = bnxt_setup_int(bp);
4693 	if (rc)
4694 		return rc;
4695 
4696 	bnxt_init_nic(bp);
4697 
4698 	rc = bnxt_request_int(bp);
4699 	if (rc)
4700 		return rc;
4701 
4702 	rc = bnxt_init_locks(bp);
4703 	if (rc)
4704 		return rc;
4705 
4706 	return 0;
4707 }
4708 
4709 static int
4710 bnxt_dev_init(struct rte_eth_dev *eth_dev)
4711 {
4712 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
4713 	static int version_printed;
4714 	struct bnxt *bp;
4715 	int rc;
4716 
4717 	if (version_printed++ == 0)
4718 		PMD_DRV_LOG(INFO, "%s\n", bnxt_version);
4719 
4720 	eth_dev->dev_ops = &bnxt_dev_ops;
4721 	eth_dev->rx_pkt_burst = &bnxt_recv_pkts;
4722 	eth_dev->tx_pkt_burst = &bnxt_xmit_pkts;
4723 
4724 	/*
4725 	 * For secondary processes, we don't initialise any further
4726 	 * as primary has already done this work.
4727 	 */
4728 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
4729 		return 0;
4730 
4731 	rte_eth_copy_pci_info(eth_dev, pci_dev);
4732 
4733 	bp = eth_dev->data->dev_private;
4734 
4735 	bp->dev_stopped = 1;
4736 
4737 	if (bnxt_vf_pciid(pci_dev->id.device_id))
4738 		bp->flags |= BNXT_FLAG_VF;
4739 
4740 	if (bnxt_thor_device(pci_dev->id.device_id))
4741 		bp->flags |= BNXT_FLAG_THOR_CHIP;
4742 
4743 	if (pci_dev->id.device_id == BROADCOM_DEV_ID_58802 ||
4744 	    pci_dev->id.device_id == BROADCOM_DEV_ID_58804 ||
4745 	    pci_dev->id.device_id == BROADCOM_DEV_ID_58808 ||
4746 	    pci_dev->id.device_id == BROADCOM_DEV_ID_58802_VF)
4747 		bp->flags |= BNXT_FLAG_STINGRAY;
4748 
4749 	rc = bnxt_init_board(eth_dev);
4750 	if (rc) {
4751 		PMD_DRV_LOG(ERR,
4752 			    "Failed to initialize board rc: %x\n", rc);
4753 		return rc;
4754 	}
4755 
4756 	rc = bnxt_alloc_hwrm_resources(bp);
4757 	if (rc) {
4758 		PMD_DRV_LOG(ERR,
4759 			    "Failed to allocate hwrm resource rc: %x\n", rc);
4760 		goto error_free;
4761 	}
4762 	rc = bnxt_init_resources(bp, false);
4763 	if (rc)
4764 		goto error_free;
4765 
4766 	rc = bnxt_alloc_stats_mem(bp);
4767 	if (rc)
4768 		goto error_free;
4769 
4770 	PMD_DRV_LOG(INFO,
4771 		    DRV_MODULE_NAME "found at mem %" PRIX64 ", node addr %pM\n",
4772 		    pci_dev->mem_resource[0].phys_addr,
4773 		    pci_dev->mem_resource[0].addr);
4774 
4775 	return 0;
4776 
4777 error_free:
4778 	bnxt_dev_uninit(eth_dev);
4779 	return rc;
4780 }
4781 
4782 static void
4783 bnxt_uninit_locks(struct bnxt *bp)
4784 {
4785 	pthread_mutex_destroy(&bp->flow_lock);
4786 	pthread_mutex_destroy(&bp->def_cp_lock);
4787 }
4788 
4789 static int
4790 bnxt_uninit_resources(struct bnxt *bp, bool reconfig_dev)
4791 {
4792 	int rc;
4793 
4794 	bnxt_free_int(bp);
4795 	bnxt_free_mem(bp, reconfig_dev);
4796 	bnxt_hwrm_func_buf_unrgtr(bp);
4797 	rc = bnxt_hwrm_func_driver_unregister(bp, 0);
4798 	bp->flags &= ~BNXT_FLAG_REGISTERED;
4799 	bnxt_free_ctx_mem(bp);
4800 	if (!reconfig_dev) {
4801 		bnxt_free_hwrm_resources(bp);
4802 
4803 		if (bp->recovery_info != NULL) {
4804 			rte_free(bp->recovery_info);
4805 			bp->recovery_info = NULL;
4806 		}
4807 	}
4808 
4809 	rte_free(bp->ptp_cfg);
4810 	bp->ptp_cfg = NULL;
4811 	return rc;
4812 }
4813 
4814 static int
4815 bnxt_dev_uninit(struct rte_eth_dev *eth_dev)
4816 {
4817 	struct bnxt *bp = eth_dev->data->dev_private;
4818 	int rc;
4819 
4820 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
4821 		return -EPERM;
4822 
4823 	PMD_DRV_LOG(DEBUG, "Calling Device uninit\n");
4824 
4825 	rc = bnxt_uninit_resources(bp, false);
4826 
4827 	if (bp->tx_mem_zone) {
4828 		rte_memzone_free((const struct rte_memzone *)bp->tx_mem_zone);
4829 		bp->tx_mem_zone = NULL;
4830 	}
4831 
4832 	if (bp->rx_mem_zone) {
4833 		rte_memzone_free((const struct rte_memzone *)bp->rx_mem_zone);
4834 		bp->rx_mem_zone = NULL;
4835 	}
4836 
4837 	if (bp->dev_stopped == 0)
4838 		bnxt_dev_close_op(eth_dev);
4839 	if (bp->pf.vf_info)
4840 		rte_free(bp->pf.vf_info);
4841 	eth_dev->dev_ops = NULL;
4842 	eth_dev->rx_pkt_burst = NULL;
4843 	eth_dev->tx_pkt_burst = NULL;
4844 
4845 	bnxt_uninit_locks(bp);
4846 
4847 	return rc;
4848 }
4849 
4850 static int bnxt_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
4851 	struct rte_pci_device *pci_dev)
4852 {
4853 	return rte_eth_dev_pci_generic_probe(pci_dev, sizeof(struct bnxt),
4854 		bnxt_dev_init);
4855 }
4856 
4857 static int bnxt_pci_remove(struct rte_pci_device *pci_dev)
4858 {
4859 	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
4860 		return rte_eth_dev_pci_generic_remove(pci_dev,
4861 				bnxt_dev_uninit);
4862 	else
4863 		return rte_eth_dev_pci_generic_remove(pci_dev, NULL);
4864 }
4865 
4866 static struct rte_pci_driver bnxt_rte_pmd = {
4867 	.id_table = bnxt_pci_id_map,
4868 	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
4869 	.probe = bnxt_pci_probe,
4870 	.remove = bnxt_pci_remove,
4871 };
4872 
4873 static bool
4874 is_device_supported(struct rte_eth_dev *dev, struct rte_pci_driver *drv)
4875 {
4876 	if (strcmp(dev->device->driver->name, drv->driver.name))
4877 		return false;
4878 
4879 	return true;
4880 }
4881 
4882 bool is_bnxt_supported(struct rte_eth_dev *dev)
4883 {
4884 	return is_device_supported(dev, &bnxt_rte_pmd);
4885 }
4886 
4887 RTE_INIT(bnxt_init_log)
4888 {
4889 	bnxt_logtype_driver = rte_log_register("pmd.net.bnxt.driver");
4890 	if (bnxt_logtype_driver >= 0)
4891 		rte_log_set_level(bnxt_logtype_driver, RTE_LOG_NOTICE);
4892 }
4893 
4894 RTE_PMD_REGISTER_PCI(net_bnxt, bnxt_rte_pmd);
4895 RTE_PMD_REGISTER_PCI_TABLE(net_bnxt, bnxt_pci_id_map);
4896 RTE_PMD_REGISTER_KMOD_DEP(net_bnxt, "* igb_uio | uio_pci_generic | vfio-pci");
4897