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