xref: /freebsd/sys/dev/bnxt/bnxt_en/if_bnxt.c (revision 62c80d76f7dc960f430cb34f88c2a549612e3e93)
1 /*-
2  * Broadcom NetXtreme-C/E network driver.
3  *
4  * Copyright (c) 2016 Broadcom, All Rights Reserved.
5  * The term Broadcom refers to Broadcom Limited and/or its subsidiaries
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26  * THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include <sys/param.h>
30 #include <sys/socket.h>
31 #include <sys/kernel.h>
32 #include <sys/bus.h>
33 #include <sys/module.h>
34 #include <sys/rman.h>
35 #include <sys/endian.h>
36 #include <sys/sockio.h>
37 #include <sys/priv.h>
38 
39 #include <machine/bus.h>
40 #include <machine/resource.h>
41 
42 #include <dev/pci/pcireg.h>
43 
44 #include <net/if.h>
45 #include <net/if_dl.h>
46 #include <net/if_media.h>
47 #include <net/if_var.h>
48 #include <net/ethernet.h>
49 #include <net/iflib.h>
50 #include <net/rss_config.h>
51 
52 #define	WANT_NATIVE_PCI_GET_SLOT
53 #include <linux/pci.h>
54 #include <linux/kmod.h>
55 #include <linux/module.h>
56 #include <linux/delay.h>
57 #include <linux/idr.h>
58 #include <linux/netdevice.h>
59 #include <linux/etherdevice.h>
60 #include <linux/rcupdate.h>
61 #include "opt_inet.h"
62 #include "opt_inet6.h"
63 #include "opt_rss.h"
64 
65 #include "ifdi_if.h"
66 
67 #include "bnxt.h"
68 #include "bnxt_hwrm.h"
69 #include "bnxt_ioctl.h"
70 #include "bnxt_sysctl.h"
71 #include "hsi_struct_def.h"
72 #include "bnxt_mgmt.h"
73 #include "bnxt_ulp.h"
74 #include "bnxt_auxbus_compat.h"
75 #include "bnxt_log.h"
76 #include "bnxt_log_data.h"
77 #include "bnxt_coredump.h"
78 
79 /*
80  * PCI Device ID Table
81  */
82 
83 static const pci_vendor_info_t bnxt_vendor_info_array[] =
84 {
85     PVID(BROADCOM_VENDOR_ID, BCM57301,
86 	"Broadcom BCM57301 NetXtreme-C 10Gb Ethernet Controller"),
87     PVID(BROADCOM_VENDOR_ID, BCM57302,
88 	"Broadcom BCM57302 NetXtreme-C 10Gb/25Gb Ethernet Controller"),
89     PVID(BROADCOM_VENDOR_ID, BCM57304,
90 	"Broadcom BCM57304 NetXtreme-C 10Gb/25Gb/40Gb/50Gb Ethernet Controller"),
91     PVID(BROADCOM_VENDOR_ID, BCM57311,
92 	"Broadcom BCM57311 NetXtreme-C 10Gb Ethernet"),
93     PVID(BROADCOM_VENDOR_ID, BCM57312,
94 	"Broadcom BCM57312 NetXtreme-C 10Gb/25Gb Ethernet"),
95     PVID(BROADCOM_VENDOR_ID, BCM57314,
96 	"Broadcom BCM57314 NetXtreme-C 10Gb/25Gb/40Gb/50Gb Ethernet"),
97     PVID(BROADCOM_VENDOR_ID, BCM57402,
98 	"Broadcom BCM57402 NetXtreme-E 10Gb Ethernet Controller"),
99     PVID(BROADCOM_VENDOR_ID, BCM57402_NPAR,
100 	"Broadcom BCM57402 NetXtreme-E Partition"),
101     PVID(BROADCOM_VENDOR_ID, BCM57404,
102 	"Broadcom BCM57404 NetXtreme-E 10Gb/25Gb Ethernet Controller"),
103     PVID(BROADCOM_VENDOR_ID, BCM57404_NPAR,
104 	"Broadcom BCM57404 NetXtreme-E Partition"),
105     PVID(BROADCOM_VENDOR_ID, BCM57406,
106 	"Broadcom BCM57406 NetXtreme-E 10GBase-T Ethernet Controller"),
107     PVID(BROADCOM_VENDOR_ID, BCM57406_NPAR,
108 	"Broadcom BCM57406 NetXtreme-E Partition"),
109     PVID(BROADCOM_VENDOR_ID, BCM57407,
110 	"Broadcom BCM57407 NetXtreme-E 10GBase-T Ethernet Controller"),
111     PVID(BROADCOM_VENDOR_ID, BCM57407_NPAR,
112 	"Broadcom BCM57407 NetXtreme-E Ethernet Partition"),
113     PVID(BROADCOM_VENDOR_ID, BCM57407_SFP,
114 	"Broadcom BCM57407 NetXtreme-E 25Gb Ethernet Controller"),
115     PVID(BROADCOM_VENDOR_ID, BCM57412,
116 	"Broadcom BCM57412 NetXtreme-E 10Gb Ethernet"),
117     PVID(BROADCOM_VENDOR_ID, BCM57412_NPAR1,
118 	"Broadcom BCM57412 NetXtreme-E Ethernet Partition"),
119     PVID(BROADCOM_VENDOR_ID, BCM57412_NPAR2,
120 	"Broadcom BCM57412 NetXtreme-E Ethernet Partition"),
121     PVID(BROADCOM_VENDOR_ID, BCM57414,
122 	"Broadcom BCM57414 NetXtreme-E 10Gb/25Gb Ethernet"),
123     PVID(BROADCOM_VENDOR_ID, BCM57414_NPAR1,
124 	"Broadcom BCM57414 NetXtreme-E Ethernet Partition"),
125     PVID(BROADCOM_VENDOR_ID, BCM57414_NPAR2,
126 	"Broadcom BCM57414 NetXtreme-E Ethernet Partition"),
127     PVID(BROADCOM_VENDOR_ID, BCM57416,
128 	"Broadcom BCM57416 NetXtreme-E 10GBase-T Ethernet"),
129     PVID(BROADCOM_VENDOR_ID, BCM57416_NPAR1,
130 	"Broadcom BCM57416 NetXtreme-E Ethernet Partition"),
131     PVID(BROADCOM_VENDOR_ID, BCM57416_NPAR2,
132 	"Broadcom BCM57416 NetXtreme-E Ethernet Partition"),
133     PVID(BROADCOM_VENDOR_ID, BCM57416_SFP,
134 	"Broadcom BCM57416 NetXtreme-E 10Gb Ethernet"),
135     PVID(BROADCOM_VENDOR_ID, BCM57417,
136 	"Broadcom BCM57417 NetXtreme-E 10GBase-T Ethernet"),
137     PVID(BROADCOM_VENDOR_ID, BCM57417_NPAR1,
138 	"Broadcom BCM57417 NetXtreme-E Ethernet Partition"),
139     PVID(BROADCOM_VENDOR_ID, BCM57417_NPAR2,
140 	"Broadcom BCM57417 NetXtreme-E Ethernet Partition"),
141     PVID(BROADCOM_VENDOR_ID, BCM57417_SFP,
142 	"Broadcom BCM57417 NetXtreme-E 10Gb/25Gb Ethernet"),
143     PVID(BROADCOM_VENDOR_ID, BCM57454,
144 	"Broadcom BCM57454 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb Ethernet"),
145     PVID(BROADCOM_VENDOR_ID, BCM58700,
146 	"Broadcom BCM58700 Nitro 1Gb/2.5Gb/10Gb Ethernet"),
147     PVID(BROADCOM_VENDOR_ID, BCM57508,
148 	"Broadcom BCM57508 NetXtreme-E 10Gb/25Gb/50Gb/100Gb/200Gb Ethernet"),
149     PVID(BROADCOM_VENDOR_ID, BCM57504,
150 	"Broadcom BCM57504 NetXtreme-E 10Gb/25Gb/50Gb/100Gb/200Gb Ethernet"),
151     PVID(BROADCOM_VENDOR_ID, BCM57504_NPAR,
152 	"Broadcom BCM57504 NetXtreme-E Ethernet Partition"),
153     PVID(BROADCOM_VENDOR_ID, BCM57502,
154 	"Broadcom BCM57502 NetXtreme-E 10Gb/25Gb/50Gb/100Gb/200Gb Ethernet"),
155     PVID(BROADCOM_VENDOR_ID, BCM57608,
156 	"Broadcom BCM57608 NetXtreme-E 25Gb/50Gb/100Gb/200Gb/400Gb Ethernet"),
157     PVID(BROADCOM_VENDOR_ID, BCM57604,
158 	"Broadcom BCM57604 NetXtreme-E 25Gb/50Gb/100Gb/200Gb Ethernet"),
159     PVID(BROADCOM_VENDOR_ID, BCM57602,
160 	"Broadcom BCM57602 NetXtreme-E 25Gb/50Gb Ethernet"),
161     PVID(BROADCOM_VENDOR_ID, BCM57601,
162 	"Broadcom BCM57601 NetXtreme-E 25Gb/50Gb Ethernet"),
163     PVID(BROADCOM_VENDOR_ID, NETXTREME_C_VF1,
164 	"Broadcom NetXtreme-C Ethernet Virtual Function"),
165     PVID(BROADCOM_VENDOR_ID, NETXTREME_C_VF2,
166 	"Broadcom NetXtreme-C Ethernet Virtual Function"),
167     PVID(BROADCOM_VENDOR_ID, NETXTREME_C_VF3,
168 	"Broadcom NetXtreme-C Ethernet Virtual Function"),
169     PVID(BROADCOM_VENDOR_ID, NETXTREME_E_VF1,
170 	"Broadcom NetXtreme-E Ethernet Virtual Function"),
171     PVID(BROADCOM_VENDOR_ID, NETXTREME_E_VF2,
172 	"Broadcom NetXtreme-E Ethernet Virtual Function"),
173     PVID(BROADCOM_VENDOR_ID, NETXTREME_E_VF3,
174 	"Broadcom NetXtreme-E Ethernet Virtual Function"),
175     PVID(BROADCOM_VENDOR_ID, NETXTREME_E_VF4,
176 	"Broadcom NetXtreme-E Ethernet Virtual Function"),
177     PVID(BROADCOM_VENDOR_ID, NETXTREME_E_VF5,
178 	"Broadcom NetXtreme-E Ethernet Virtual Function"),
179     PVID(BROADCOM_VENDOR_ID, NETXTREME_E_P5_VF1,
180 	"Broadcom BCM5750X NetXtreme-E Ethernet Virtual Function"),
181     PVID(BROADCOM_VENDOR_ID, NETXTREME_E_P5_VF2,
182 	"Broadcom BCM5750X NetXtreme-E Ethernet Virtual Function"),
183     PVID(BROADCOM_VENDOR_ID, NETXTREME_E_P5_VF_HV1,
184 	"Broadcom NetXtreme-C Virtual Function for Hyper-V"),
185     PVID(BROADCOM_VENDOR_ID, NETXTREME_E_P5_VF_HV2,
186 	"Broadcom NetXtreme-C Virtual Function for Hyper-V"),
187     PVID(BROADCOM_VENDOR_ID, E_P7_VF,
188 	"Broadcom BCM5760X Virtual Function"),
189     /* required last entry */
190 
191     PVID_END
192 };
193 
194 /*
195  * Function prototypes
196  */
197 
198 SLIST_HEAD(softc_list, bnxt_softc_list) pf_list;
199 int bnxt_num_pfs = 0;
200 
201 void
202 process_nq(struct bnxt_softc *softc, uint16_t nqid);
203 static void *bnxt_register(device_t dev);
204 
205 /* Soft queue setup and teardown */
206 static int bnxt_tx_queues_alloc(if_ctx_t ctx, caddr_t *vaddrs,
207     uint64_t *paddrs, int ntxqs, int ntxqsets);
208 static int bnxt_rx_queues_alloc(if_ctx_t ctx, caddr_t *vaddrs,
209     uint64_t *paddrs, int nrxqs, int nrxqsets);
210 static void bnxt_queues_free(if_ctx_t ctx);
211 
212 /* Device setup and teardown */
213 static int bnxt_attach_pre(if_ctx_t ctx);
214 static int bnxt_attach_post(if_ctx_t ctx);
215 static int bnxt_detach(if_ctx_t ctx);
216 
217 /* Device configuration */
218 static void bnxt_init(if_ctx_t ctx);
219 static int bnxt_init_hw(if_ctx_t ctx);
220 static void bnxt_stop(if_ctx_t ctx);
221 static void bnxt_if_led_func(if_ctx_t ctx, int onoff);
222 static bool bnxt_if_led_supported(if_ctx_t ctx);
223 static void bnxt_led_restore(struct bnxt_softc *softc);
224 static void bnxt_multi_set(if_ctx_t ctx);
225 static int bnxt_mtu_set(if_ctx_t ctx, uint32_t mtu);
226 static void bnxt_media_status(if_ctx_t ctx, struct ifmediareq * ifmr);
227 static int bnxt_media_change(if_ctx_t ctx);
228 static int bnxt_promisc_set(if_ctx_t ctx, int flags);
229 static uint64_t	bnxt_get_counter(if_ctx_t, ift_counter);
230 static void bnxt_update_admin_status(if_ctx_t ctx);
231 static void bnxt_if_timer(if_ctx_t ctx, uint16_t qid);
232 
233 /* Interrupt enable / disable */
234 static void bnxt_intr_enable(if_ctx_t ctx);
235 static int bnxt_rx_queue_intr_enable(if_ctx_t ctx, uint16_t qid);
236 static int bnxt_tx_queue_intr_enable(if_ctx_t ctx, uint16_t qid);
237 static void bnxt_disable_intr(if_ctx_t ctx);
238 static int bnxt_msix_intr_assign(if_ctx_t ctx, int msix);
239 
240 /* vlan support */
241 static void bnxt_vlan_register(if_ctx_t ctx, uint16_t vtag);
242 static void bnxt_vlan_unregister(if_ctx_t ctx, uint16_t vtag);
243 
244 /* ioctl */
245 static int bnxt_priv_ioctl(if_ctx_t ctx, u_long command, caddr_t data);
246 
247 static int bnxt_shutdown(if_ctx_t ctx);
248 static int bnxt_suspend(if_ctx_t ctx);
249 static int bnxt_resume(if_ctx_t ctx);
250 
251 /* Internal support functions */
252 static int bnxt_probe_phy(struct bnxt_softc *softc);
253 static void bnxt_add_media_types(struct bnxt_softc *softc);
254 static int bnxt_pci_mapping(struct bnxt_softc *softc);
255 static void bnxt_pci_mapping_free(struct bnxt_softc *softc);
256 static int bnxt_update_link(struct bnxt_softc *softc, bool chng_link_state);
257 static int bnxt_handle_def_cp(void *arg);
258 static int bnxt_handle_isr(void *arg);
259 static void bnxt_clear_ids(struct bnxt_softc *softc);
260 static void inline bnxt_do_enable_intr(struct bnxt_cp_ring *cpr);
261 static void inline bnxt_do_disable_intr(struct bnxt_cp_ring *cpr);
262 static void bnxt_mark_cpr_invalid(struct bnxt_cp_ring *cpr);
263 static void bnxt_def_cp_task(void *context, int pending);
264 static void bnxt_handle_async_event(struct bnxt_softc *softc,
265     struct cmpl_base *cmpl);
266 static uint64_t bnxt_get_baudrate(struct bnxt_link_info *link);
267 static void bnxt_get_wol_settings(struct bnxt_softc *softc);
268 static int bnxt_wol_config(if_ctx_t ctx);
269 static bool bnxt_if_needs_restart(if_ctx_t, enum iflib_restart_event);
270 static int bnxt_i2c_req(if_ctx_t ctx, struct ifi2creq *i2c);
271 static void bnxt_get_port_module_status(struct bnxt_softc *softc);
272 static void bnxt_rdma_aux_device_init(struct bnxt_softc *softc);
273 static void bnxt_rdma_aux_device_uninit(struct bnxt_softc *softc);
274 static void bnxt_queue_fw_reset_work(struct bnxt_softc *bp, unsigned long delay);
275 void bnxt_queue_sp_work(struct bnxt_softc *bp);
276 
277 void bnxt_fw_reset(struct bnxt_softc *bp);
278 static int bnxt_crash_dump_init(struct bnxt_softc *softc);
279 /*
280  * Device Interface Declaration
281  */
282 
283 static device_method_t bnxt_methods[] = {
284 	/* Device interface */
285 	DEVMETHOD(device_register, bnxt_register),
286 	DEVMETHOD(device_probe, iflib_device_probe),
287 	DEVMETHOD(device_attach, iflib_device_attach),
288 	DEVMETHOD(device_detach, iflib_device_detach),
289 	DEVMETHOD(device_shutdown, iflib_device_shutdown),
290 	DEVMETHOD(device_suspend, iflib_device_suspend),
291 	DEVMETHOD(device_resume, iflib_device_resume),
292 #ifdef PCI_IOV
293 	DEVMETHOD(pci_iov_init, iflib_device_iov_init),
294 	DEVMETHOD(pci_iov_uninit, iflib_device_iov_uninit),
295 	DEVMETHOD(pci_iov_add_vf, iflib_device_iov_add_vf),
296 #endif
297 	DEVMETHOD_END
298 };
299 
300 static driver_t bnxt_driver = {
301 	"bnxt", bnxt_methods, sizeof(struct bnxt_softc),
302 };
303 
304 DRIVER_MODULE(bnxt, pci, bnxt_driver, 0, 0);
305 
306 MODULE_LICENSE("Dual BSD/GPL");
307 MODULE_DEPEND(if_bnxt, pci, 1, 1, 1);
308 MODULE_DEPEND(if_bnxt, ether, 1, 1, 1);
309 MODULE_DEPEND(if_bnxt, iflib, 1, 1, 1);
310 MODULE_DEPEND(if_bnxt, linuxkpi, 1, 1, 1);
311 MODULE_VERSION(if_bnxt, 1);
312 
313 IFLIB_PNP_INFO(pci, bnxt, bnxt_vendor_info_array);
314 
315 void writel_fbsd(struct bnxt_softc *bp, u32, u8, u32);
316 u32 readl_fbsd(struct bnxt_softc *bp, u32, u8);
317 
318 u32 readl_fbsd(struct bnxt_softc *bp, u32 reg_off, u8 bar_idx)
319 {
320 
321 	if (!bar_idx)
322 		return bus_space_read_4(bp->doorbell_bar.tag, bp->doorbell_bar.handle, reg_off);
323 	else
324 		return bus_space_read_4(bp->hwrm_bar.tag, bp->hwrm_bar.handle, reg_off);
325 }
326 
327 void writel_fbsd(struct bnxt_softc *bp, u32 reg_off, u8 bar_idx, u32 val)
328 {
329 
330 	if (!bar_idx)
331 		bus_space_write_4(bp->doorbell_bar.tag, bp->doorbell_bar.handle, reg_off, htole32(val));
332 	else
333 		bus_space_write_4(bp->hwrm_bar.tag, bp->hwrm_bar.handle, reg_off, htole32(val));
334 }
335 
336 static DEFINE_IDA(bnxt_aux_dev_ids);
337 
338 static device_method_t bnxt_iflib_methods[] = {
339 	DEVMETHOD(ifdi_tx_queues_alloc, bnxt_tx_queues_alloc),
340 	DEVMETHOD(ifdi_rx_queues_alloc, bnxt_rx_queues_alloc),
341 	DEVMETHOD(ifdi_queues_free, bnxt_queues_free),
342 
343 	DEVMETHOD(ifdi_attach_pre, bnxt_attach_pre),
344 	DEVMETHOD(ifdi_attach_post, bnxt_attach_post),
345 	DEVMETHOD(ifdi_detach, bnxt_detach),
346 
347 	DEVMETHOD(ifdi_init, bnxt_init),
348 	DEVMETHOD(ifdi_stop, bnxt_stop),
349 	DEVMETHOD(ifdi_led_func, bnxt_if_led_func),
350 	DEVMETHOD(ifdi_led_supported, bnxt_if_led_supported),
351 	DEVMETHOD(ifdi_multi_set, bnxt_multi_set),
352 	DEVMETHOD(ifdi_mtu_set, bnxt_mtu_set),
353 	DEVMETHOD(ifdi_media_status, bnxt_media_status),
354 	DEVMETHOD(ifdi_media_change, bnxt_media_change),
355 	DEVMETHOD(ifdi_promisc_set, bnxt_promisc_set),
356 	DEVMETHOD(ifdi_get_counter, bnxt_get_counter),
357 	DEVMETHOD(ifdi_update_admin_status, bnxt_update_admin_status),
358 	DEVMETHOD(ifdi_timer, bnxt_if_timer),
359 
360 	DEVMETHOD(ifdi_intr_enable, bnxt_intr_enable),
361 	DEVMETHOD(ifdi_tx_queue_intr_enable, bnxt_tx_queue_intr_enable),
362 	DEVMETHOD(ifdi_rx_queue_intr_enable, bnxt_rx_queue_intr_enable),
363 	DEVMETHOD(ifdi_intr_disable, bnxt_disable_intr),
364 	DEVMETHOD(ifdi_msix_intr_assign, bnxt_msix_intr_assign),
365 
366 	DEVMETHOD(ifdi_vlan_register, bnxt_vlan_register),
367 	DEVMETHOD(ifdi_vlan_unregister, bnxt_vlan_unregister),
368 
369 	DEVMETHOD(ifdi_priv_ioctl, bnxt_priv_ioctl),
370 
371 	DEVMETHOD(ifdi_suspend, bnxt_suspend),
372 	DEVMETHOD(ifdi_shutdown, bnxt_shutdown),
373 	DEVMETHOD(ifdi_resume, bnxt_resume),
374 	DEVMETHOD(ifdi_i2c_req, bnxt_i2c_req),
375 
376 	DEVMETHOD(ifdi_needs_restart, bnxt_if_needs_restart),
377 #ifdef PCI_IOV
378 	DEVMETHOD(ifdi_iov_init, bnxt_iov_init),
379 	DEVMETHOD(ifdi_iov_uninit, bnxt_iov_uninit),
380 	DEVMETHOD(ifdi_iov_vf_add, bnxt_iov_vf_add),
381 #endif
382 	DEVMETHOD_END
383 };
384 
385 static driver_t bnxt_iflib_driver = {
386 	"bnxt", bnxt_iflib_methods, sizeof(struct bnxt_softc)
387 };
388 
389 /*
390  * iflib shared context
391  */
392 #define BNXT_DRIVER_VERSION	"230.0.133.0"
393 const char bnxt_driver_version[] = BNXT_DRIVER_VERSION;
394 
395 static char drv_version_msg[] =
396 		"Broadcom NetXtreme-C/E Ethernet Driver if_bnxt" \
397 		" v" BNXT_DRIVER_VERSION;
398 
399 extern struct if_txrx bnxt_txrx;
400 
401 static struct if_shared_ctx bnxt_sctx_template = {
402 	.isc_magic = IFLIB_MAGIC,
403 	.isc_driver = &bnxt_iflib_driver,
404 	.isc_nfl = 2,
405 	.isc_flags = IFLIB_HAS_RXCQ | IFLIB_HAS_TXCQ | IFLIB_NEED_ETHER_PAD,
406 	.isc_q_align = PAGE_SIZE,
407 	.isc_tx_maxsize = BNXT_TSO_SIZE + sizeof(struct ether_vlan_header),
408 	.isc_tx_maxsegsize = BNXT_TSO_SIZE + sizeof(struct ether_vlan_header),
409 	.isc_tso_maxsize = BNXT_TSO_SIZE + sizeof(struct ether_vlan_header),
410 	.isc_tso_maxsegsize = BNXT_TSO_SIZE + sizeof(struct ether_vlan_header),
411 	.isc_rx_maxsize = BNXT_TSO_SIZE + sizeof(struct ether_vlan_header),
412 	.isc_rx_maxsegsize = BNXT_TSO_SIZE + sizeof(struct ether_vlan_header),
413 	.isc_rx_nsegments = 1,
414 	.isc_ntxqs = 3,
415 	.isc_nrxqs = 3,
416 	.isc_nrxd_min = {16, 16, 16},
417 	.isc_nrxd_default = {PAGE_SIZE / sizeof(struct cmpl_base) * 8,
418 			     PAGE_SIZE / sizeof(struct rx_prod_pkt_bd),
419 			     PAGE_SIZE / sizeof(struct rx_prod_pkt_bd)},
420 	.isc_nrxd_max = {BNXT_MAX_RXD, BNXT_MAX_RXD, BNXT_MAX_RXD},
421 	.isc_ntxd_min = {16, 16, 16},
422 	.isc_ntxd_default = {PAGE_SIZE / sizeof(struct cmpl_base) * 2,
423 			     PAGE_SIZE / sizeof(struct tx_bd_short),
424 			     PAGE_SIZE / sizeof(struct cmpl_base) * 16},
425 	.isc_ntxd_max = {BNXT_MAX_TXD, BNXT_MAX_TXD, BNXT_MAX_TXD},
426 	.isc_vendor_info = bnxt_vendor_info_array,
427 	.isc_driver_version = bnxt_driver_version,
428 };
429 
430 static struct if_shared_ctx bnxt_sctx_template_p7 = {
431 	.isc_magic = IFLIB_MAGIC,
432 	.isc_driver = &bnxt_iflib_driver,
433 	.isc_nfl = 2,
434 	.isc_flags = IFLIB_HAS_RXCQ | IFLIB_HAS_TXCQ | IFLIB_NEED_ETHER_PAD,
435 	.isc_q_align = PAGE_SIZE,
436 	.isc_tx_maxsize = BNXT_TSO_SIZE + sizeof(struct ether_vlan_header),
437 	.isc_tx_maxsegsize = BNXT_TSO_SIZE + sizeof(struct ether_vlan_header),
438 	.isc_tso_maxsize = BNXT_TSO_SIZE + sizeof(struct ether_vlan_header),
439 	.isc_tso_maxsegsize = BNXT_TSO_SIZE + sizeof(struct ether_vlan_header),
440 	.isc_rx_maxsize = BNXT_TSO_SIZE + sizeof(struct ether_vlan_header),
441 	.isc_rx_maxsegsize = BNXT_TSO_SIZE + sizeof(struct ether_vlan_header),
442 	.isc_rx_nsegments = 1,
443 	.isc_ntxqs = 3,
444 	.isc_nrxqs = 3,
445 	.isc_nrxd_min = {16, 16, 16},
446 	.isc_nrxd_default = {PAGE_SIZE / sizeof(struct cmpl_base) * 8,
447 			     PAGE_SIZE / sizeof(struct rx_prod_pkt_bd),
448 			     PAGE_SIZE / sizeof(struct rx_prod_pkt_bd)},
449 	.isc_nrxd_max = {BNXT_MAX_RXD, BNXT_MAX_RXD, BNXT_MAX_RXD},
450 	.isc_ntxd_min = {128, 128, 128},
451 	.isc_ntxd_default = {PAGE_SIZE / sizeof(struct cmpl_base) * 2,
452 			     PAGE_SIZE / sizeof(struct tx_bd_short),
453 			     PAGE_SIZE / sizeof(struct cmpl_base) * 16},
454 	.isc_ntxd_max = {BNXT_MAX_TXD, BNXT_MAX_TXD, BNXT_MAX_TXD},
455 	.isc_vendor_info = bnxt_vendor_info_array,
456 	.isc_driver_version = bnxt_driver_version,
457 };
458 
459 static struct if_shared_ctx bnxt_sctx_pf_init;
460 static struct if_shared_ctx bnxt_sctx_vf_init;
461 static bool sctx_initialized = false;
462 
463 static inline void
464 bnxt_init_sctx_variants(uint16_t device_id)
465 {
466     if (device_id == BCM57608)
467 	bnxt_sctx_pf_init = bnxt_sctx_template_p7;
468     else
469 	bnxt_sctx_pf_init = bnxt_sctx_template;
470 
471     bnxt_sctx_pf_init.isc_admin_intrcnt = BNXT_ROCE_IRQ_COUNT;
472 
473     bnxt_sctx_vf_init = bnxt_sctx_template;
474     bnxt_sctx_vf_init.isc_flags |= IFLIB_IS_VF;
475 }
476 
477 static inline bool
478 bnxt_is_vf_device(uint16_t device_id)
479 {
480 	switch (device_id) {
481 	case NETXTREME_C_VF1:
482 	case NETXTREME_C_VF2:
483 	case NETXTREME_C_VF3:
484 	case NETXTREME_E_VF1:
485 	case NETXTREME_E_VF2:
486 	case NETXTREME_E_VF3:
487 	case NETXTREME_E_VF4:
488 	case NETXTREME_E_VF5:
489 	case NETXTREME_E_P5_VF1:
490 	case NETXTREME_E_P5_VF2:
491 	case NETXTREME_E_P5_VF_HV1:
492 	case NETXTREME_E_P5_VF_HV2:
493 	case E_P7_VF:
494 		return true;
495 	default:
496 		return false;
497 	}
498 }
499 
500 void
501 bnxt_set_flags_by_devid(struct bnxt_softc *softc)
502 {
503 	uint16_t device_id = pci_get_device(softc->dev);
504 
505 	if (bnxt_is_vf_device(device_id))
506 		softc->flags |= BNXT_FLAG_VF;
507 
508 	switch (device_id) {
509 	case BCM57402_NPAR:
510 	case BCM57404_NPAR:
511 	case BCM57406_NPAR:
512 	case BCM57407_NPAR:
513 	case BCM57412_NPAR1:
514 	case BCM57412_NPAR2:
515 	case BCM57414_NPAR1:
516 	case BCM57414_NPAR2:
517 	case BCM57416_NPAR1:
518 	case BCM57416_NPAR2:
519 		softc->flags |= BNXT_FLAG_NPAR;
520 		break;
521 	}
522 }
523 
524 #define PCI_SUBSYSTEM_ID	0x2e
525 static struct workqueue_struct *bnxt_pf_wq;
526 
527 extern void bnxt_destroy_irq(struct bnxt_softc *softc);
528 
529 /*
530  * Device Methods
531  */
532 
533 static void *
534 bnxt_register(device_t dev)
535 {
536 	uint16_t vendor_id = pci_get_vendor(dev);
537 	uint16_t device_id = pci_get_device(dev);
538 
539 	if (vendor_id != BROADCOM_VENDOR_ID)
540 		return NULL;
541 
542 	if (!sctx_initialized) {
543 		printf("if_bnxt: %s\n", drv_version_msg);
544 		sctx_initialized = true;
545 	}
546 
547 	bnxt_init_sctx_variants(device_id);
548 
549 	if (bnxt_is_vf_device(device_id))
550 		return &bnxt_sctx_vf_init;
551 
552 	return &bnxt_sctx_pf_init;
553 }
554 
555 static void
556 bnxt_nq_alloc(struct bnxt_softc *softc, int nqsets)
557 {
558 
559 	if (softc->nq_rings)
560 		return;
561 
562 	softc->nq_rings = malloc(sizeof(struct bnxt_cp_ring) * nqsets,
563 	    M_DEVBUF, M_NOWAIT | M_ZERO);
564 }
565 
566 static void
567 bnxt_nq_free(struct bnxt_softc *softc)
568 {
569 
570 	if (softc->nq_rings)
571 		free(softc->nq_rings, M_DEVBUF);
572 	softc->nq_rings = NULL;
573 }
574 
575 
576 static void
577 bnxt_set_db_mask(struct bnxt_softc *bp, struct bnxt_ring *db,
578 		 u32 ring_type)
579 {
580 	if (BNXT_CHIP_P7(bp)) {
581 		db->db_epoch_mask = db->db_ring_mask + 1;
582 		db->db_epoch_shift = DBR_EPOCH_SFT - ilog2(db->db_epoch_mask);
583 
584 	}
585 }
586 
587 /*
588  * Device Dependent Configuration Functions
589 */
590 
591 /* Soft queue setup and teardown */
592 static int
593 bnxt_tx_queues_alloc(if_ctx_t ctx, caddr_t *vaddrs,
594     uint64_t *paddrs, int ntxqs, int ntxqsets)
595 {
596 	struct bnxt_softc *softc;
597 	int i;
598 	int rc;
599 
600 	softc = iflib_get_softc(ctx);
601 
602 	if (BNXT_CHIP_P5_PLUS(softc)) {
603 		bnxt_nq_alloc(softc, ntxqsets);
604 		if (!softc->nq_rings) {
605 			device_printf(iflib_get_dev(ctx),
606 					"unable to allocate NQ rings\n");
607 			rc = ENOMEM;
608 			goto nq_alloc_fail;
609 		}
610 	}
611 
612 	softc->tx_cp_rings = malloc(sizeof(struct bnxt_cp_ring) * ntxqsets,
613 	    M_DEVBUF, M_NOWAIT | M_ZERO);
614 	if (!softc->tx_cp_rings) {
615 		device_printf(iflib_get_dev(ctx),
616 		    "unable to allocate TX completion rings\n");
617 		rc = ENOMEM;
618 		goto cp_alloc_fail;
619 	}
620 	softc->tx_rings = malloc(sizeof(struct bnxt_ring) * ntxqsets,
621 	    M_DEVBUF, M_NOWAIT | M_ZERO);
622 	if (!softc->tx_rings) {
623 		device_printf(iflib_get_dev(ctx),
624 		    "unable to allocate TX rings\n");
625 		rc = ENOMEM;
626 		goto ring_alloc_fail;
627 	}
628 
629 	for (i=0; i < ntxqsets; i++) {
630 		rc = iflib_dma_alloc(ctx, sizeof(struct ctx_hw_stats),
631 				&softc->tx_stats[i], 0);
632 		if (rc)
633 			goto dma_alloc_fail;
634 		bus_dmamap_sync(softc->tx_stats[i].idi_tag, softc->tx_stats[i].idi_map,
635 				BUS_DMASYNC_PREREAD);
636 	}
637 
638 	for (i = 0; i < ntxqsets; i++) {
639 		/* Set up the completion ring */
640 		softc->tx_cp_rings[i].stats_ctx_id = HWRM_NA_SIGNATURE;
641 		softc->tx_cp_rings[i].ring.phys_id =
642 		    (uint16_t)HWRM_NA_SIGNATURE;
643 		softc->tx_cp_rings[i].ring.softc = softc;
644 		softc->tx_cp_rings[i].ring.idx = i;
645 		softc->tx_cp_rings[i].ring.id =
646 		    (softc->scctx->isc_nrxqsets * 2) + 1 + i;
647 		softc->tx_cp_rings[i].ring.doorbell = (BNXT_CHIP_P5_PLUS(softc)) ?
648 			softc->legacy_db_size: softc->tx_cp_rings[i].ring.id * 0x80;
649 		softc->tx_cp_rings[i].ring.ring_size =
650 		    softc->scctx->isc_ntxd[0];
651 		softc->tx_cp_rings[i].ring.db_ring_mask =
652 		    softc->tx_cp_rings[i].ring.ring_size - 1;
653 		softc->tx_cp_rings[i].ring.vaddr = vaddrs[i * ntxqs];
654 		softc->tx_cp_rings[i].ring.paddr = paddrs[i * ntxqs];
655 
656 
657 		/* Set up the TX ring */
658 		softc->tx_rings[i].phys_id = (uint16_t)HWRM_NA_SIGNATURE;
659 		softc->tx_rings[i].softc = softc;
660 		softc->tx_rings[i].idx = i;
661 		softc->tx_rings[i].id =
662 		    (softc->scctx->isc_nrxqsets * 2) + 1 + i;
663 		softc->tx_rings[i].doorbell = (BNXT_CHIP_P5_PLUS(softc)) ?
664 			softc->legacy_db_size : softc->tx_rings[i].id * 0x80;
665 		softc->tx_rings[i].ring_size = softc->scctx->isc_ntxd[1];
666 		softc->tx_rings[i].db_ring_mask = softc->tx_rings[i].ring_size - 1;
667 		softc->tx_rings[i].vaddr = vaddrs[i * ntxqs + 1];
668 		softc->tx_rings[i].paddr = paddrs[i * ntxqs + 1];
669 
670 		bnxt_create_tx_sysctls(softc, i);
671 
672 		if (BNXT_CHIP_P5_PLUS(softc)) {
673 			/* Set up the Notification ring (NQ) */
674 			softc->nq_rings[i].stats_ctx_id = HWRM_NA_SIGNATURE;
675 			softc->nq_rings[i].ring.phys_id =
676 				(uint16_t)HWRM_NA_SIGNATURE;
677 			softc->nq_rings[i].ring.softc = softc;
678 			softc->nq_rings[i].ring.idx = i;
679 			softc->nq_rings[i].ring.id = i;
680 			softc->nq_rings[i].ring.doorbell = (BNXT_CHIP_P5_PLUS(softc)) ?
681 				softc->legacy_db_size : softc->nq_rings[i].ring.id * 0x80;
682 			softc->nq_rings[i].ring.ring_size = softc->scctx->isc_ntxd[2];
683 			softc->nq_rings[i].ring.db_ring_mask = softc->nq_rings[i].ring.ring_size - 1;
684 			softc->nq_rings[i].ring.vaddr = vaddrs[i * ntxqs + 2];
685 			softc->nq_rings[i].ring.paddr = paddrs[i * ntxqs + 2];
686 			softc->nq_rings[i].type = Q_TYPE_TX;
687 		}
688 	}
689 
690 	softc->ntxqsets = ntxqsets;
691 	return rc;
692 
693 dma_alloc_fail:
694 	for (i = i - 1; i >= 0; i--)
695 		iflib_dma_free(&softc->tx_stats[i]);
696 	free(softc->tx_rings, M_DEVBUF);
697 ring_alloc_fail:
698 	free(softc->tx_cp_rings, M_DEVBUF);
699 cp_alloc_fail:
700 	bnxt_nq_free(softc);
701 nq_alloc_fail:
702 	return rc;
703 }
704 
705 static void
706 bnxt_queues_free(if_ctx_t ctx)
707 {
708 	struct bnxt_softc *softc = iflib_get_softc(ctx);
709 	int i;
710 
711 	// Free TX queues
712 	for (i=0; i<softc->ntxqsets; i++)
713 		iflib_dma_free(&softc->tx_stats[i]);
714 	free(softc->tx_rings, M_DEVBUF);
715 	softc->tx_rings = NULL;
716 	free(softc->tx_cp_rings, M_DEVBUF);
717 	softc->tx_cp_rings = NULL;
718 	softc->ntxqsets = 0;
719 
720 	// Free RX queues
721 	for (i=0; i<softc->nrxqsets; i++)
722 		iflib_dma_free(&softc->rx_stats[i]);
723 	iflib_dma_free(&softc->hw_tx_port_stats);
724 	iflib_dma_free(&softc->hw_rx_port_stats);
725 	iflib_dma_free(&softc->hw_tx_port_stats_ext);
726 	iflib_dma_free(&softc->hw_rx_port_stats_ext);
727 	free(softc->grp_info, M_DEVBUF);
728 	free(softc->ag_rings, M_DEVBUF);
729 	free(softc->rx_rings, M_DEVBUF);
730 	free(softc->rx_cp_rings, M_DEVBUF);
731 	bnxt_nq_free(softc);
732 }
733 
734 static int
735 bnxt_rx_queues_alloc(if_ctx_t ctx, caddr_t *vaddrs,
736     uint64_t *paddrs, int nrxqs, int nrxqsets)
737 {
738 	struct bnxt_softc *softc;
739 	int i;
740 	int rc;
741 
742 	softc = iflib_get_softc(ctx);
743 
744 	softc->rx_cp_rings = malloc(sizeof(struct bnxt_cp_ring) * nrxqsets,
745 	    M_DEVBUF, M_NOWAIT | M_ZERO);
746 	if (!softc->rx_cp_rings) {
747 		device_printf(iflib_get_dev(ctx),
748 		    "unable to allocate RX completion rings\n");
749 		rc = ENOMEM;
750 		goto cp_alloc_fail;
751 	}
752 	softc->rx_rings = malloc(sizeof(struct bnxt_ring) * nrxqsets,
753 	    M_DEVBUF, M_NOWAIT | M_ZERO);
754 	if (!softc->rx_rings) {
755 		device_printf(iflib_get_dev(ctx),
756 		    "unable to allocate RX rings\n");
757 		rc = ENOMEM;
758 		goto ring_alloc_fail;
759 	}
760 	softc->ag_rings = malloc(sizeof(struct bnxt_ring) * nrxqsets,
761 	    M_DEVBUF, M_NOWAIT | M_ZERO);
762 	if (!softc->ag_rings) {
763 		device_printf(iflib_get_dev(ctx),
764 		    "unable to allocate aggregation rings\n");
765 		rc = ENOMEM;
766 		goto ag_alloc_fail;
767 	}
768 	softc->grp_info = malloc(sizeof(struct bnxt_grp_info) * nrxqsets,
769 	    M_DEVBUF, M_NOWAIT | M_ZERO);
770 	if (!softc->grp_info) {
771 		device_printf(iflib_get_dev(ctx),
772 		    "unable to allocate ring groups\n");
773 		rc = ENOMEM;
774 		goto grp_alloc_fail;
775 	}
776 
777 	for (i=0; i < nrxqsets; i++) {
778 		rc = iflib_dma_alloc(ctx, sizeof(struct ctx_hw_stats),
779 				&softc->rx_stats[i], 0);
780 		if (rc)
781 			goto hw_stats_alloc_fail;
782 		bus_dmamap_sync(softc->rx_stats[i].idi_tag, softc->rx_stats[i].idi_map,
783 				BUS_DMASYNC_PREREAD);
784 	}
785 
786 /*
787  * Additional 512 bytes for future expansion.
788  * To prevent corruption when loaded with newer firmwares with added counters.
789  * This can be deleted when there will be no further additions of counters.
790  */
791 #define BNXT_PORT_STAT_PADDING  512
792 
793 	rc = iflib_dma_alloc(ctx, sizeof(struct rx_port_stats) + BNXT_PORT_STAT_PADDING,
794 	    &softc->hw_rx_port_stats, 0);
795 	if (rc)
796 		goto hw_port_rx_stats_alloc_fail;
797 
798 	bus_dmamap_sync(softc->hw_rx_port_stats.idi_tag,
799             softc->hw_rx_port_stats.idi_map, BUS_DMASYNC_PREREAD);
800 
801 
802 	rc = iflib_dma_alloc(ctx, sizeof(struct tx_port_stats) + BNXT_PORT_STAT_PADDING,
803 	    &softc->hw_tx_port_stats, 0);
804 	if (rc)
805 		goto hw_port_tx_stats_alloc_fail;
806 
807 	bus_dmamap_sync(softc->hw_tx_port_stats.idi_tag,
808             softc->hw_tx_port_stats.idi_map, BUS_DMASYNC_PREREAD);
809 
810 	softc->rx_port_stats = (void *) softc->hw_rx_port_stats.idi_vaddr;
811 	softc->tx_port_stats = (void *) softc->hw_tx_port_stats.idi_vaddr;
812 
813 
814 	rc = iflib_dma_alloc(ctx, sizeof(struct rx_port_stats_ext),
815 		&softc->hw_rx_port_stats_ext, 0);
816 	if (rc)
817 		goto hw_port_rx_stats_ext_alloc_fail;
818 
819 	bus_dmamap_sync(softc->hw_rx_port_stats_ext.idi_tag,
820 	    softc->hw_rx_port_stats_ext.idi_map, BUS_DMASYNC_PREREAD);
821 
822 	rc = iflib_dma_alloc(ctx, sizeof(struct tx_port_stats_ext),
823 		&softc->hw_tx_port_stats_ext, 0);
824 	if (rc)
825 		goto hw_port_tx_stats_ext_alloc_fail;
826 
827 	bus_dmamap_sync(softc->hw_tx_port_stats_ext.idi_tag,
828 	    softc->hw_tx_port_stats_ext.idi_map, BUS_DMASYNC_PREREAD);
829 
830 	softc->rx_port_stats_ext = (void *) softc->hw_rx_port_stats_ext.idi_vaddr;
831 	softc->tx_port_stats_ext = (void *) softc->hw_tx_port_stats_ext.idi_vaddr;
832 
833 	for (i = 0; i < nrxqsets; i++) {
834 		/* Allocation the completion ring */
835 		softc->rx_cp_rings[i].stats_ctx_id = HWRM_NA_SIGNATURE;
836 		softc->rx_cp_rings[i].ring.phys_id =
837 		    (uint16_t)HWRM_NA_SIGNATURE;
838 		softc->rx_cp_rings[i].ring.softc = softc;
839 		softc->rx_cp_rings[i].ring.idx = i;
840 		softc->rx_cp_rings[i].ring.id = i + 1;
841 		softc->rx_cp_rings[i].ring.doorbell = (BNXT_CHIP_P5_PLUS(softc)) ?
842 			softc->legacy_db_size : softc->rx_cp_rings[i].ring.id * 0x80;
843 		/*
844 		 * If this ring overflows, RX stops working.
845 		 */
846 		softc->rx_cp_rings[i].ring.ring_size =
847 		    softc->scctx->isc_nrxd[0];
848 		softc->rx_cp_rings[i].ring.db_ring_mask =
849 		    softc->rx_cp_rings[i].ring.ring_size - 1;
850 
851 		softc->rx_cp_rings[i].ring.vaddr = vaddrs[i * nrxqs];
852 		softc->rx_cp_rings[i].ring.paddr = paddrs[i * nrxqs];
853 
854 		/* Allocate the RX ring */
855 		softc->rx_rings[i].phys_id = (uint16_t)HWRM_NA_SIGNATURE;
856 		softc->rx_rings[i].softc = softc;
857 		softc->rx_rings[i].idx = i;
858 		softc->rx_rings[i].id = i + 1;
859 		softc->rx_rings[i].doorbell = (BNXT_CHIP_P5_PLUS(softc)) ?
860 			softc->legacy_db_size : softc->rx_rings[i].id * 0x80;
861 		softc->rx_rings[i].ring_size = softc->scctx->isc_nrxd[1];
862 		softc->rx_rings[i].db_ring_mask =
863 			softc->rx_rings[i].ring_size -1;
864 		softc->rx_rings[i].vaddr = vaddrs[i * nrxqs + 1];
865 		softc->rx_rings[i].paddr = paddrs[i * nrxqs + 1];
866 
867 		/* Allocate the TPA start buffer */
868 		softc->rx_rings[i].tpa_start = malloc(sizeof(struct bnxt_full_tpa_start) *
869 	    		(RX_TPA_START_CMPL_AGG_ID_MASK >> RX_TPA_START_CMPL_AGG_ID_SFT),
870 	    		M_DEVBUF, M_NOWAIT | M_ZERO);
871 		if (softc->rx_rings[i].tpa_start == NULL) {
872 			rc = -ENOMEM;
873 			device_printf(softc->dev,
874 					"Unable to allocate space for TPA\n");
875 			goto tpa_alloc_fail;
876 		}
877 		/* Allocate the AG ring */
878 		softc->ag_rings[i].phys_id = (uint16_t)HWRM_NA_SIGNATURE;
879 		softc->ag_rings[i].softc = softc;
880 		softc->ag_rings[i].idx = i;
881 		softc->ag_rings[i].id = nrxqsets + i + 1;
882 		softc->ag_rings[i].doorbell = (BNXT_CHIP_P5_PLUS(softc)) ?
883 			softc->legacy_db_size : softc->ag_rings[i].id * 0x80;
884 		softc->ag_rings[i].ring_size = softc->scctx->isc_nrxd[2];
885 		softc->ag_rings[i].db_ring_mask = softc->ag_rings[i].ring_size - 1;
886 		softc->ag_rings[i].vaddr = vaddrs[i * nrxqs + 2];
887 		softc->ag_rings[i].paddr = paddrs[i * nrxqs + 2];
888 
889 		/* Allocate the ring group */
890 		softc->grp_info[i].grp_id = (uint16_t)HWRM_NA_SIGNATURE;
891 		softc->grp_info[i].stats_ctx =
892 		    softc->rx_cp_rings[i].stats_ctx_id;
893 		softc->grp_info[i].rx_ring_id = softc->rx_rings[i].phys_id;
894 		softc->grp_info[i].ag_ring_id = softc->ag_rings[i].phys_id;
895 		softc->grp_info[i].cp_ring_id =
896 		    softc->rx_cp_rings[i].ring.phys_id;
897 
898 		bnxt_create_rx_sysctls(softc, i);
899 	}
900 
901 	/*
902 	 * When SR-IOV is enabled, avoid each VF sending PORT_QSTATS
903          * HWRM every sec with which firmware timeouts can happen
904          */
905 	if (BNXT_PF(softc))
906 		bnxt_create_port_stats_sysctls(softc);
907 
908 	/* And finally, the VNIC */
909 	softc->vnic_info.id = (uint16_t)HWRM_NA_SIGNATURE;
910 	softc->vnic_info.filter_id = -1;
911 	softc->vnic_info.def_ring_grp = (uint16_t)HWRM_NA_SIGNATURE;
912 	softc->vnic_info.cos_rule = (uint16_t)HWRM_NA_SIGNATURE;
913 	softc->vnic_info.lb_rule = (uint16_t)HWRM_NA_SIGNATURE;
914 	softc->vnic_info.rx_mask = HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_BCAST |
915 		HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ANYVLAN_NONVLAN;
916 	softc->vnic_info.mc_list_count = 0;
917 	softc->vnic_info.flags = BNXT_VNIC_FLAG_DEFAULT;
918 	rc = iflib_dma_alloc(ctx, BNXT_MAX_MC_ADDRS * ETHER_ADDR_LEN,
919 	    &softc->vnic_info.mc_list, 0);
920 	if (rc)
921 		goto mc_list_alloc_fail;
922 
923 	/* The VNIC RSS Hash Key */
924 	rc = iflib_dma_alloc(ctx, HW_HASH_KEY_SIZE,
925 	    &softc->vnic_info.rss_hash_key_tbl, 0);
926 	if (rc)
927 		goto rss_hash_alloc_fail;
928 	bus_dmamap_sync(softc->vnic_info.rss_hash_key_tbl.idi_tag,
929 	    softc->vnic_info.rss_hash_key_tbl.idi_map,
930 	    BUS_DMASYNC_PREWRITE);
931 	memcpy(softc->vnic_info.rss_hash_key_tbl.idi_vaddr,
932 	    softc->vnic_info.rss_hash_key, HW_HASH_KEY_SIZE);
933 
934 	/* Allocate the RSS tables */
935 	rc = iflib_dma_alloc(ctx, HW_HASH_INDEX_SIZE * sizeof(uint16_t),
936 	    &softc->vnic_info.rss_grp_tbl, 0);
937 	if (rc)
938 		goto rss_grp_alloc_fail;
939 	bus_dmamap_sync(softc->vnic_info.rss_grp_tbl.idi_tag,
940 	    softc->vnic_info.rss_grp_tbl.idi_map,
941 	    BUS_DMASYNC_PREWRITE);
942 	memset(softc->vnic_info.rss_grp_tbl.idi_vaddr, 0xff,
943 	    softc->vnic_info.rss_grp_tbl.idi_size);
944 
945 	softc->nrxqsets = nrxqsets;
946 	return rc;
947 
948 rss_grp_alloc_fail:
949 	iflib_dma_free(&softc->vnic_info.rss_hash_key_tbl);
950 rss_hash_alloc_fail:
951 	iflib_dma_free(&softc->vnic_info.mc_list);
952 mc_list_alloc_fail:
953 	for (i = i - 1; i >= 0; i--) {
954 		if (softc->rx_rings[i].tpa_start)
955 			free(softc->rx_rings[i].tpa_start, M_DEVBUF);
956 	}
957 tpa_alloc_fail:
958 	iflib_dma_free(&softc->hw_tx_port_stats_ext);
959 hw_port_tx_stats_ext_alloc_fail:
960 	iflib_dma_free(&softc->hw_rx_port_stats_ext);
961 hw_port_rx_stats_ext_alloc_fail:
962 	iflib_dma_free(&softc->hw_tx_port_stats);
963 hw_port_tx_stats_alloc_fail:
964 	iflib_dma_free(&softc->hw_rx_port_stats);
965 hw_port_rx_stats_alloc_fail:
966 	for (i=0; i < nrxqsets; i++) {
967 		if (softc->rx_stats[i].idi_vaddr)
968 			iflib_dma_free(&softc->rx_stats[i]);
969 	}
970 hw_stats_alloc_fail:
971 	free(softc->grp_info, M_DEVBUF);
972 grp_alloc_fail:
973 	free(softc->ag_rings, M_DEVBUF);
974 ag_alloc_fail:
975 	free(softc->rx_rings, M_DEVBUF);
976 ring_alloc_fail:
977 	free(softc->rx_cp_rings, M_DEVBUF);
978 cp_alloc_fail:
979 	return rc;
980 }
981 
982 static void bnxt_free_hwrm_short_cmd_req(struct bnxt_softc *softc)
983 {
984 	if (softc->hwrm_short_cmd_req_addr.idi_vaddr)
985 		iflib_dma_free(&softc->hwrm_short_cmd_req_addr);
986 	softc->hwrm_short_cmd_req_addr.idi_vaddr = NULL;
987 }
988 
989 static int bnxt_alloc_hwrm_short_cmd_req(struct bnxt_softc *softc)
990 {
991 	int rc;
992 
993 	rc = iflib_dma_alloc(softc->ctx, softc->hwrm_max_req_len,
994 	    &softc->hwrm_short_cmd_req_addr, BUS_DMA_NOWAIT);
995 
996 	return rc;
997 }
998 
999 static void bnxt_free_ring(struct bnxt_softc *softc, struct bnxt_ring_mem_info *rmem)
1000 {
1001 	int i;
1002 
1003 	for (i = 0; i < rmem->nr_pages; i++) {
1004 		if (!rmem->pg_arr[i].idi_vaddr)
1005 			continue;
1006 
1007 		iflib_dma_free(&rmem->pg_arr[i]);
1008 		rmem->pg_arr[i].idi_vaddr = NULL;
1009 	}
1010 	if (rmem->pg_tbl.idi_vaddr) {
1011 		iflib_dma_free(&rmem->pg_tbl);
1012 		rmem->pg_tbl.idi_vaddr = NULL;
1013 
1014 	}
1015 	if (rmem->vmem_size && *rmem->vmem) {
1016 		free(*rmem->vmem, M_DEVBUF);
1017 		*rmem->vmem = NULL;
1018 	}
1019 }
1020 
1021 static void bnxt_init_ctx_mem(struct bnxt_ctx_mem_type *ctxm, void *p, int len)
1022 {
1023 	u8 init_val = ctxm->init_value;
1024 	u16 offset = ctxm->init_offset;
1025 	u8 *p2 = p;
1026 	int i;
1027 
1028 	if (!init_val)
1029 		return;
1030 	if (offset == BNXT_CTX_INIT_INVALID_OFFSET) {
1031 		memset(p, init_val, len);
1032 		return;
1033 	}
1034 	for (i = 0; i < len; i += ctxm->entry_size)
1035 		*(p2 + i + offset) = init_val;
1036 }
1037 
1038 static int bnxt_alloc_ring(struct bnxt_softc *softc, struct bnxt_ring_mem_info *rmem)
1039 {
1040 	uint64_t valid_bit = 0;
1041 	int i;
1042 	int rc;
1043 
1044 	if (rmem->flags & (BNXT_RMEM_VALID_PTE_FLAG | BNXT_RMEM_RING_PTE_FLAG))
1045 		valid_bit = PTU_PTE_VALID;
1046 
1047 	if ((rmem->nr_pages > 1 || rmem->depth > 0) && !rmem->pg_tbl.idi_vaddr) {
1048 		size_t pg_tbl_size = rmem->nr_pages * 8;
1049 
1050 		if (rmem->flags & BNXT_RMEM_USE_FULL_PAGE_FLAG)
1051 			pg_tbl_size = rmem->page_size;
1052 
1053 		rc = iflib_dma_alloc(softc->ctx, pg_tbl_size, &rmem->pg_tbl, 0);
1054 		if (rc)
1055 			return -ENOMEM;
1056 	}
1057 
1058 	for (i = 0; i < rmem->nr_pages; i++) {
1059 		uint64_t extra_bits = valid_bit;
1060 		uint64_t *ptr;
1061 
1062 		rc = iflib_dma_alloc(softc->ctx, rmem->page_size, &rmem->pg_arr[i], 0);
1063 		if (rc)
1064 			return -ENOMEM;
1065 
1066 		if (rmem->ctx_mem)
1067 			bnxt_init_ctx_mem(rmem->ctx_mem, rmem->pg_arr[i].idi_vaddr,
1068 					rmem->page_size);
1069 
1070 		if (rmem->nr_pages > 1 || rmem->depth > 0) {
1071 			if (i == rmem->nr_pages - 2 &&
1072 					(rmem->flags & BNXT_RMEM_RING_PTE_FLAG))
1073 				extra_bits |= PTU_PTE_NEXT_TO_LAST;
1074 			else if (i == rmem->nr_pages - 1 &&
1075 					(rmem->flags & BNXT_RMEM_RING_PTE_FLAG))
1076 				extra_bits |= PTU_PTE_LAST;
1077 
1078 			ptr = (void *) rmem->pg_tbl.idi_vaddr;
1079 			ptr[i]  = htole64(rmem->pg_arr[i].idi_paddr | extra_bits);
1080 		}
1081 	}
1082 
1083 	if (rmem->vmem_size) {
1084 		*rmem->vmem = malloc(rmem->vmem_size, M_DEVBUF, M_NOWAIT | M_ZERO);
1085 		if (!(*rmem->vmem))
1086 			return -ENOMEM;
1087 	}
1088 	return 0;
1089 }
1090 
1091 
1092 #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_DFLT_ENABLES		\
1093 	(HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_QP |		\
1094 	 HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_SRQ |	\
1095 	 HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_CQ |		\
1096 	 HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_VNIC |	\
1097 	 HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_STAT)
1098 
1099 static int bnxt_alloc_ctx_mem_blk(struct bnxt_softc *softc,
1100 				  struct bnxt_ctx_pg_info *ctx_pg)
1101 {
1102 	struct bnxt_ring_mem_info *rmem = &ctx_pg->ring_mem;
1103 
1104 	rmem->page_size = BNXT_PAGE_SIZE;
1105 	rmem->pg_arr = ctx_pg->ctx_arr;
1106 	rmem->flags = BNXT_RMEM_VALID_PTE_FLAG;
1107 	if (rmem->depth >= 1)
1108 		rmem->flags |= BNXT_RMEM_USE_FULL_PAGE_FLAG;
1109 
1110 	return bnxt_alloc_ring(softc, rmem);
1111 }
1112 
1113 int
1114 bnxt_alloc_ctx_pg_tbls(struct bnxt_softc *softc,
1115     struct bnxt_ctx_pg_info *ctx_pg, uint32_t mem_size, uint8_t depth,
1116     struct bnxt_ctx_mem_type *ctxm)
1117 {
1118 	struct bnxt_ring_mem_info *rmem = &ctx_pg->ring_mem;
1119 	int rc;
1120 
1121 	if (!mem_size)
1122 		return -EINVAL;
1123 
1124 	ctx_pg->nr_pages = DIV_ROUND_UP(mem_size, BNXT_PAGE_SIZE);
1125 	if (ctx_pg->nr_pages > MAX_CTX_TOTAL_PAGES) {
1126 		ctx_pg->nr_pages = 0;
1127 		return -EINVAL;
1128 	}
1129 	if (ctx_pg->nr_pages > MAX_CTX_PAGES || depth > 1) {
1130 		int nr_tbls, i;
1131 
1132 		rmem->depth = 2;
1133 		ctx_pg->ctx_pg_tbl = kzalloc(MAX_CTX_PAGES * sizeof(ctx_pg),
1134 					      GFP_KERNEL);
1135 		if (!ctx_pg->ctx_pg_tbl)
1136 			return -ENOMEM;
1137 		nr_tbls = DIV_ROUND_UP(ctx_pg->nr_pages, MAX_CTX_PAGES);
1138 		rmem->nr_pages = nr_tbls;
1139 		rc = bnxt_alloc_ctx_mem_blk(softc, ctx_pg);
1140 		if (rc)
1141 			return rc;
1142 		for (i = 0; i < nr_tbls; i++) {
1143 			struct bnxt_ctx_pg_info *pg_tbl;
1144 
1145 			pg_tbl = kzalloc(sizeof(*pg_tbl), GFP_KERNEL);
1146 			if (!pg_tbl)
1147 				return -ENOMEM;
1148 			ctx_pg->ctx_pg_tbl[i] = pg_tbl;
1149 			rmem = &pg_tbl->ring_mem;
1150 			memcpy(&rmem->pg_tbl, &ctx_pg->ctx_arr[i], sizeof(struct iflib_dma_info));
1151 			rmem->depth = 1;
1152 			rmem->nr_pages = MAX_CTX_PAGES;
1153 			rmem->ctx_mem = ctxm;
1154 			if (i == (nr_tbls - 1)) {
1155 				int rem = ctx_pg->nr_pages % MAX_CTX_PAGES;
1156 
1157 				if (rem)
1158 					rmem->nr_pages = rem;
1159 			}
1160 			rc = bnxt_alloc_ctx_mem_blk(softc, pg_tbl);
1161 			if (rc)
1162 				break;
1163 		}
1164 	} else {
1165 		rmem->nr_pages = DIV_ROUND_UP(mem_size, BNXT_PAGE_SIZE);
1166 		if (rmem->nr_pages > 1 || depth)
1167 			rmem->depth = 1;
1168 		rmem->ctx_mem = ctxm;
1169 		rc = bnxt_alloc_ctx_mem_blk(softc, ctx_pg);
1170 	}
1171 	return rc;
1172 }
1173 
1174 void bnxt_free_ctx_pg_tbls(struct bnxt_softc *softc,
1175 			   struct bnxt_ctx_pg_info *ctx_pg)
1176 {
1177 	struct bnxt_ring_mem_info *rmem = &ctx_pg->ring_mem;
1178 
1179 	if (rmem->depth > 1 || ctx_pg->nr_pages > MAX_CTX_PAGES ||
1180 	    ctx_pg->ctx_pg_tbl) {
1181 		int i, nr_tbls = rmem->nr_pages;
1182 
1183 		for (i = 0; i < nr_tbls; i++) {
1184 			struct bnxt_ctx_pg_info *pg_tbl;
1185 			struct bnxt_ring_mem_info *rmem2;
1186 
1187 			pg_tbl = ctx_pg->ctx_pg_tbl[i];
1188 			if (!pg_tbl)
1189 				continue;
1190 			rmem2 = &pg_tbl->ring_mem;
1191 			bnxt_free_ring(softc, rmem2);
1192 			ctx_pg->ctx_arr[i].idi_vaddr = NULL;
1193 			free(pg_tbl , M_DEVBUF);
1194 			ctx_pg->ctx_pg_tbl[i] = NULL;
1195 		}
1196 		kfree(ctx_pg->ctx_pg_tbl);
1197 		ctx_pg->ctx_pg_tbl = NULL;
1198 	}
1199 	bnxt_free_ring(softc, rmem);
1200 	ctx_pg->nr_pages = 0;
1201 }
1202 
1203 static int bnxt_setup_ctxm_pg_tbls(struct bnxt_softc *softc,
1204 				   struct bnxt_ctx_mem_type *ctxm, u32 entries,
1205 				   u8 pg_lvl)
1206 {
1207 	struct bnxt_ctx_pg_info *ctx_pg = ctxm->pg_info;
1208 	int i, rc = 0, n = 1;
1209 	u32 mem_size;
1210 
1211 	if (!ctxm->entry_size || !ctx_pg)
1212 		return -EINVAL;
1213 	if (ctxm->instance_bmap)
1214 		n = hweight32(ctxm->instance_bmap);
1215 	if (ctxm->entry_multiple)
1216 		entries = roundup(entries, ctxm->entry_multiple);
1217 	entries = clamp_t(u32, entries, ctxm->min_entries, ctxm->max_entries);
1218 	mem_size = entries * ctxm->entry_size;
1219 	for (i = 0; i < n && !rc; i++) {
1220 		ctx_pg[i].entries = entries;
1221 		rc = bnxt_alloc_ctx_pg_tbls(softc, &ctx_pg[i], mem_size, pg_lvl,
1222 					    ctxm->init_value ? ctxm : NULL);
1223 	}
1224 	if (!rc)
1225 		ctxm->mem_valid = 1;
1226 	return rc;
1227 }
1228 
1229 static void bnxt_free_ctx_mem(struct bnxt_softc *softc)
1230 {
1231 	struct bnxt_ctx_mem_info *ctx = softc->ctx_mem;
1232 	u16 type;
1233 
1234 	if (!ctx)
1235 		return;
1236 
1237 	for (type = 0; type < BNXT_CTX_MAX; type++) {
1238 		struct bnxt_ctx_mem_type *ctxm = &ctx->ctx_arr[type];
1239 		struct bnxt_ctx_pg_info *ctx_pg = ctxm->pg_info;
1240 		int i, n = 1;
1241 
1242 		if (!ctx_pg)
1243 			continue;
1244 		if (ctxm->instance_bmap)
1245 			n = hweight32(ctxm->instance_bmap);
1246 		for (i = 0; i < n; i++)
1247 			bnxt_free_ctx_pg_tbls(softc, &ctx_pg[i]);
1248 
1249 		kfree(ctx_pg);
1250 		ctxm->pg_info = NULL;
1251 	}
1252 
1253 	ctx->flags &= ~BNXT_CTX_FLAG_INITED;
1254 	kfree(ctx);
1255 	softc->ctx_mem = NULL;
1256 }
1257 
1258 const u16 bnxt_bstore_to_trace[] = {
1259 	[BNXT_CTX_SRT_TRACE] =
1260 	    HWRM_DBG_LOG_BUFFER_FLUSH_INPUT_TYPE_SRT_TRACE,
1261 	[BNXT_CTX_SRT2_TRACE] =
1262 	    HWRM_DBG_LOG_BUFFER_FLUSH_INPUT_TYPE_SRT2_TRACE,
1263 	[BNXT_CTX_CRT_TRACE] =
1264 	    HWRM_DBG_LOG_BUFFER_FLUSH_INPUT_TYPE_CRT_TRACE,
1265 	[BNXT_CTX_CRT2_TRACE] =
1266 	    HWRM_DBG_LOG_BUFFER_FLUSH_INPUT_TYPE_CRT2_TRACE,
1267 	[BNXT_CTX_RIGP0_TRACE] =
1268 	    HWRM_DBG_LOG_BUFFER_FLUSH_INPUT_TYPE_RIGP0_TRACE,
1269 	[BNXT_CTX_L2_HWRM_TRACE] =
1270 	    HWRM_DBG_LOG_BUFFER_FLUSH_INPUT_TYPE_L2_HWRM_TRACE,
1271 	[BNXT_CTX_ROCE_HWRM_TRACE] =
1272 	    HWRM_DBG_LOG_BUFFER_FLUSH_INPUT_TYPE_ROCE_HWRM_TRACE,
1273 };
1274 
1275 static void
1276 bnxt_bs_trace_init(struct bnxt_softc *bp, struct bnxt_ctx_mem_type *ctxm)
1277 {
1278 	uint32_t mem_size, pages, rem_bytes, magic_byte_offset;
1279 	struct bnxt_ctx_pg_info *ctx_pg = ctxm->pg_info;
1280 	struct bnxt_ring_mem_info *rmem, *rmem_pg_tbl;
1281 	uint32_t last_pg, n = 1, size = sizeof(uint8_t);
1282 	struct bnxt_bs_trace_info *bs_trace;
1283 	uint16_t trace_type;
1284 
1285 	mem_size = ctxm->max_entries * ctxm->entry_size;
1286 	rem_bytes = mem_size % BNXT_PAGE_SIZE;
1287 	pages = DIV_ROUND_UP(mem_size, BNXT_PAGE_SIZE);
1288 
1289 	last_pg = (pages - 1) & (MAX_CTX_PAGES - 1);
1290 	magic_byte_offset = ((rem_bytes ? rem_bytes : BNXT_PAGE_SIZE) - size);
1291 
1292 	if (ctxm->instance_bmap) {
1293 		if (ctxm->instance_bmap > 1)
1294 			return;
1295 		n = bitcount32(ctxm->instance_bmap);
1296 	}
1297 
1298 	rmem = &ctx_pg[n - 1].ring_mem;
1299 	trace_type = bnxt_bstore_to_trace[ctxm->type];
1300 	bs_trace = &bp->bs_trace[trace_type];
1301 	bs_trace->ctx_type = ctxm->type;
1302 	bs_trace->trace_type = trace_type;
1303 	if (pages > MAX_CTX_PAGES) {
1304 		int last_pg_directory = rmem->nr_pages - 1;
1305 
1306 		rmem_pg_tbl =
1307 		    &ctx_pg[n - 1].ctx_pg_tbl[last_pg_directory]->ring_mem;
1308 		bs_trace->magic_byte = rmem_pg_tbl->pg_arr[last_pg].idi_vaddr;
1309 	} else {
1310 		bs_trace->magic_byte = rmem->pg_arr[last_pg].idi_vaddr;
1311 	}
1312 	bs_trace->magic_byte += magic_byte_offset;
1313 	*bs_trace->magic_byte = BNXT_TRACE_BUF_MAGIC_BYTE;
1314 }
1315 
1316 static int
1317 bnxt_backing_store_cfg_v2(struct bnxt_softc *softc, u32 ena)
1318 {
1319 	struct bnxt_ctx_mem_info *ctx = softc->ctx_mem;
1320 	struct bnxt_ctx_mem_type *ctxm;
1321 	u16 last_type = BNXT_CTX_INV;
1322 	int rc = 0;
1323 	u16 type;
1324 
1325 	if (BNXT_PF(softc)) {
1326 		for (type = BNXT_CTX_SRT_TRACE; type <= BNXT_CTX_ROCE_HWRM_TRACE; type++) {
1327 			ctxm = &ctx->ctx_arr[type];
1328 			if (!(ctxm->flags & BNXT_CTX_MEM_TYPE_VALID))
1329 				continue;
1330 			rc = bnxt_setup_ctxm_pg_tbls(softc, ctxm, ctxm->max_entries, 1);
1331 			if (rc) {
1332 				device_printf(softc->dev, "Unable to setup ctx page for type:0x%x.\n", type);
1333 				rc = 0;
1334 				continue;
1335 			}
1336 			/* ckp TODO: this is trace buffer related stuff, so keeping it diabled now. needs revisit */
1337 			bnxt_bs_trace_init(softc, ctxm);
1338 			last_type = type;
1339 		}
1340 	}
1341 
1342 	if (last_type == BNXT_CTX_INV) {
1343 		if (!ena)
1344 			return 0;
1345 		else if (ena & HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_TIM)
1346 			last_type = BNXT_CTX_MAX - 1;
1347 		else
1348 			last_type = BNXT_CTX_L2_MAX - 1;
1349 	}
1350 	ctx->ctx_arr[last_type].last = 1;
1351 
1352 	for (type = 0 ; type < BNXT_CTX_V2_MAX; type++) {
1353 		ctxm = &ctx->ctx_arr[type];
1354 
1355 		if (!ctxm->mem_valid)
1356 			continue;
1357 		rc = bnxt_hwrm_func_backing_store_cfg_v2(softc, ctxm, ctxm->last);
1358 		if (rc)
1359 			return rc;
1360 	}
1361 	return 0;
1362 }
1363 
1364 static int bnxt_alloc_ctx_mem(struct bnxt_softc *softc)
1365 {
1366 	struct bnxt_ctx_pg_info *ctx_pg;
1367 	struct bnxt_ctx_mem_type *ctxm;
1368 	struct bnxt_ctx_mem_info *ctx;
1369 	u32 l2_qps, qp1_qps, max_qps;
1370 	u32 ena, entries_sp, entries;
1371 	u32 srqs, max_srqs, min;
1372 	u32 num_mr, num_ah;
1373 	u32 extra_srqs = 0;
1374 	u32 extra_qps = 0;
1375 	u8 pg_lvl = 1;
1376 	int i, rc;
1377 
1378 	if (!BNXT_CHIP_P5_PLUS(softc))
1379 		return 0;
1380 
1381 	rc = bnxt_hwrm_func_backing_store_qcaps(softc);
1382 	if (rc) {
1383 		device_printf(softc->dev, "Failed querying context mem capability, rc = %d.\n",
1384 			   rc);
1385 		return rc;
1386 	}
1387 	ctx = softc->ctx_mem;
1388 	if (!ctx || (ctx->flags & BNXT_CTX_FLAG_INITED))
1389 		return 0;
1390 
1391 	ena = 0;
1392 	if (BNXT_VF(softc))
1393 		goto skip_legacy;
1394 
1395 	ctxm = &ctx->ctx_arr[BNXT_CTX_QP];
1396 	l2_qps = ctxm->qp_l2_entries;
1397 	qp1_qps = ctxm->qp_qp1_entries;
1398 	max_qps = ctxm->max_entries;
1399 	ctxm = &ctx->ctx_arr[BNXT_CTX_SRQ];
1400 	srqs = ctxm->srq_l2_entries;
1401 	max_srqs = ctxm->max_entries;
1402 	if (softc->flags & BNXT_FLAG_ROCE_CAP) {
1403 		pg_lvl = 2;
1404 		if (BNXT_SW_RES_LMT(softc)) {
1405 			extra_qps = max_qps - l2_qps - qp1_qps;
1406 			extra_srqs = max_srqs - srqs;
1407 		} else {
1408 			extra_qps = min_t(uint32_t, 65536, max_qps - l2_qps - qp1_qps);
1409 			extra_srqs = min_t(uint32_t, 8192, max_srqs - srqs);
1410 		}
1411 	}
1412 
1413 	ctxm = &ctx->ctx_arr[BNXT_CTX_QP];
1414 	rc = bnxt_setup_ctxm_pg_tbls(softc, ctxm, l2_qps + qp1_qps + extra_qps,
1415 				     pg_lvl);
1416 	if (rc)
1417 		return rc;
1418 
1419 	ctxm = &ctx->ctx_arr[BNXT_CTX_SRQ];
1420 	rc = bnxt_setup_ctxm_pg_tbls(softc, ctxm, srqs + extra_srqs, pg_lvl);
1421 	if (rc)
1422 		return rc;
1423 
1424 	ctxm = &ctx->ctx_arr[BNXT_CTX_CQ];
1425 	rc = bnxt_setup_ctxm_pg_tbls(softc, ctxm, ctxm->cq_l2_entries +
1426 				     extra_qps * 2, pg_lvl);
1427 	if (rc)
1428 		return rc;
1429 
1430 	ctxm = &ctx->ctx_arr[BNXT_CTX_VNIC];
1431 	rc = bnxt_setup_ctxm_pg_tbls(softc, ctxm, ctxm->max_entries, 1);
1432 	if (rc)
1433 		return rc;
1434 
1435 	ctxm = &ctx->ctx_arr[BNXT_CTX_STAT];
1436 	rc = bnxt_setup_ctxm_pg_tbls(softc, ctxm, ctxm->max_entries, 1);
1437 	if (rc)
1438 		return rc;
1439 
1440 	if (!(softc->flags & BNXT_FLAG_ROCE_CAP))
1441 		goto skip_rdma;
1442 
1443 	ctxm = &ctx->ctx_arr[BNXT_CTX_MRAV];
1444 	ctx_pg = ctxm->pg_info;
1445 	/* 128K extra is needed to accomodate static AH context
1446 	 * allocation by f/w.
1447 	 */
1448 	num_mr = min_t(u32, ctxm->max_entries / 2, 1024 * 256);
1449 	num_ah = min_t(u32, num_mr, 1024 * 128);
1450 	rc = bnxt_setup_ctxm_pg_tbls(softc, ctxm, num_mr + num_ah, 2);
1451 	if (rc)
1452 		return rc;
1453 	ctx_pg->entries = num_mr + num_ah;
1454 	ena = HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_MRAV;
1455 	if (ctxm->mrav_num_entries_units)
1456 		ctx_pg->entries =
1457 			((num_mr / ctxm->mrav_num_entries_units) << 16) |
1458 			 (num_ah / ctxm->mrav_num_entries_units);
1459 
1460 	ctxm = &ctx->ctx_arr[BNXT_CTX_TIM];
1461 	rc = bnxt_setup_ctxm_pg_tbls(softc, ctxm, l2_qps + qp1_qps + extra_qps, 1);
1462 	if (rc)
1463 		return rc;
1464 	ena |= HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_TIM;
1465 
1466 skip_rdma:
1467 	ctxm = &ctx->ctx_arr[BNXT_CTX_STQM];
1468 	min = ctxm->min_entries;
1469 	entries_sp = ctx->ctx_arr[BNXT_CTX_VNIC].vnic_entries + l2_qps +
1470 		     2 * (extra_qps + qp1_qps) + min;
1471 	rc = bnxt_setup_ctxm_pg_tbls(softc, ctxm, entries_sp, 2);
1472 		if (rc)
1473 			return rc;
1474 
1475 	ctxm = &ctx->ctx_arr[BNXT_CTX_FTQM];
1476 	entries = l2_qps + 2 * (extra_qps + qp1_qps);
1477 	rc = bnxt_setup_ctxm_pg_tbls(softc, ctxm, entries, 2);
1478 	if (rc)
1479 		return rc;
1480 	for (i = 0; i < ctx->tqm_fp_rings_count + 1; i++) {
1481 		if (i < BNXT_MAX_TQM_LEGACY_RINGS)
1482 			ena |= HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_TQM_SP << i;
1483 		else
1484 			ena |= HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_TQM_RING8;
1485 	}
1486 	ena |= HWRM_FUNC_BACKING_STORE_CFG_INPUT_DFLT_ENABLES;
1487 
1488 skip_legacy:
1489 	if (BNXT_CHIP_P7(softc)) {
1490 		if (softc->fw_cap & BNXT_FW_CAP_BACKING_STORE_V2)
1491 			rc = bnxt_backing_store_cfg_v2(softc, ena);
1492 	} else {
1493 		rc = bnxt_hwrm_func_backing_store_cfg(softc, ena);
1494 	}
1495 	if (rc) {
1496 		device_printf(softc->dev, "Failed configuring context mem, rc = %d.\n",
1497 			      rc);
1498 		return rc;
1499 	}
1500 	ctx->flags |= BNXT_CTX_FLAG_INITED;
1501 
1502 	return 0;
1503 }
1504 
1505 /*
1506  * If we update the index, a write barrier is needed after the write to ensure
1507  * the completion ring has space before the RX/TX ring does.  Since we can't
1508  * make the RX and AG doorbells covered by the same barrier without remapping
1509  * MSI-X vectors, we create the barrier over the enture doorbell bar.
1510  * TODO: Remap the MSI-X vectors to allow a barrier to only cover the doorbells
1511  *       for a single ring group.
1512  *
1513  * A barrier of just the size of the write is used to ensure the ordering
1514  * remains correct and no writes are lost.
1515  */
1516 
1517 static void bnxt_cuw_db_rx(void *db_ptr, uint16_t idx)
1518 {
1519 	struct bnxt_ring *ring = (struct bnxt_ring *) db_ptr;
1520 	struct bnxt_bar_info *db_bar = &ring->softc->doorbell_bar;
1521 
1522 	bus_space_barrier(db_bar->tag, db_bar->handle, ring->doorbell, 4,
1523 			BUS_SPACE_BARRIER_WRITE);
1524 	bus_space_write_4(db_bar->tag, db_bar->handle, ring->doorbell,
1525 			htole32(RX_DOORBELL_KEY_RX | idx));
1526 }
1527 
1528 static void bnxt_cuw_db_tx(void *db_ptr, uint16_t idx)
1529 {
1530 	struct bnxt_ring *ring = (struct bnxt_ring *) db_ptr;
1531 	struct bnxt_bar_info *db_bar = &ring->softc->doorbell_bar;
1532 
1533 	bus_space_barrier(db_bar->tag, db_bar->handle, ring->doorbell, 4,
1534 			BUS_SPACE_BARRIER_WRITE);
1535 	bus_space_write_4(db_bar->tag, db_bar->handle, ring->doorbell,
1536 			htole32(TX_DOORBELL_KEY_TX | idx));
1537 }
1538 
1539 static void bnxt_cuw_db_cq(void *db_ptr, bool enable_irq)
1540 {
1541 	struct bnxt_cp_ring *cpr = (struct bnxt_cp_ring *) db_ptr;
1542 	struct bnxt_bar_info *db_bar = &cpr->ring.softc->doorbell_bar;
1543 
1544 	bus_space_barrier(db_bar->tag, db_bar->handle, cpr->ring.doorbell, 4,
1545 			BUS_SPACE_BARRIER_WRITE);
1546 	bus_space_write_4(db_bar->tag, db_bar->handle, cpr->ring.doorbell,
1547 			htole32(CMPL_DOORBELL_KEY_CMPL |
1548 				((cpr->cons == UINT32_MAX) ? 0 :
1549 				 (cpr->cons | CMPL_DOORBELL_IDX_VALID)) |
1550 				((enable_irq) ? 0 : CMPL_DOORBELL_MASK)));
1551 	bus_space_barrier(db_bar->tag, db_bar->handle, 0, db_bar->size,
1552 			BUS_SPACE_BARRIER_WRITE);
1553 }
1554 
1555 static void bnxt_thor_db_rx(void *db_ptr, uint16_t idx)
1556 {
1557 	struct bnxt_ring *ring = (struct bnxt_ring *) db_ptr;
1558 	struct bnxt_bar_info *db_bar = &ring->softc->doorbell_bar;
1559 
1560 	bus_space_barrier(db_bar->tag, db_bar->handle, ring->doorbell, 8,
1561 			BUS_SPACE_BARRIER_WRITE);
1562 	bus_space_write_8(db_bar->tag, db_bar->handle, ring->doorbell,
1563 			htole64((DBR_PATH_L2 | DBR_TYPE_SRQ | idx) |
1564 				((uint64_t)ring->phys_id << DBR_XID_SFT)));
1565 }
1566 
1567 static void bnxt_thor_db_tx(void *db_ptr, uint16_t idx)
1568 {
1569 	struct bnxt_ring *ring = (struct bnxt_ring *) db_ptr;
1570 	struct bnxt_bar_info *db_bar = &ring->softc->doorbell_bar;
1571 
1572 	bus_space_barrier(db_bar->tag, db_bar->handle, ring->doorbell, 8,
1573 			BUS_SPACE_BARRIER_WRITE);
1574 	bus_space_write_8(db_bar->tag, db_bar->handle, ring->doorbell,
1575 			htole64((DBR_PATH_L2 | DBR_TYPE_SQ | idx) |
1576 				((uint64_t)ring->phys_id << DBR_XID_SFT)));
1577 }
1578 
1579 static void bnxt_thor_db_rx_cq(void *db_ptr, bool enable_irq)
1580 {
1581 	struct bnxt_cp_ring *cpr = (struct bnxt_cp_ring *) db_ptr;
1582 	struct bnxt_bar_info *db_bar = &cpr->ring.softc->doorbell_bar;
1583 	dbc_dbc_t db_msg = { 0 };
1584 	uint32_t cons = cpr->cons;
1585 
1586 	if (cons == UINT32_MAX)
1587 		cons = 0;
1588 	else
1589 		cons = RING_NEXT(&cpr->ring, cons);
1590 
1591 	db_msg.index = ((cons << DBC_DBC_INDEX_SFT) & DBC_DBC_INDEX_MASK);
1592 
1593 	db_msg.type_path_xid = ((cpr->ring.phys_id << DBC_DBC_XID_SFT) &
1594 			DBC_DBC_XID_MASK) | DBC_DBC_PATH_L2 |
1595 		((enable_irq) ? DBC_DBC_TYPE_CQ_ARMALL: DBC_DBC_TYPE_CQ);
1596 
1597 	bus_space_barrier(db_bar->tag, db_bar->handle, cpr->ring.doorbell, 8,
1598 			BUS_SPACE_BARRIER_WRITE);
1599 	bus_space_write_8(db_bar->tag, db_bar->handle, cpr->ring.doorbell,
1600 			htole64(*(uint64_t *)&db_msg));
1601 	bus_space_barrier(db_bar->tag, db_bar->handle, 0, db_bar->size,
1602 			BUS_SPACE_BARRIER_WRITE);
1603 }
1604 
1605 static void bnxt_thor_db_tx_cq(void *db_ptr, bool enable_irq)
1606 {
1607 	struct bnxt_cp_ring *cpr = (struct bnxt_cp_ring *) db_ptr;
1608 	struct bnxt_bar_info *db_bar = &cpr->ring.softc->doorbell_bar;
1609 	dbc_dbc_t db_msg = { 0 };
1610 	uint32_t cons = cpr->cons;
1611 
1612 	db_msg.index = ((cons << DBC_DBC_INDEX_SFT) & DBC_DBC_INDEX_MASK);
1613 
1614 	db_msg.type_path_xid = ((cpr->ring.phys_id << DBC_DBC_XID_SFT) &
1615 			DBC_DBC_XID_MASK) | DBC_DBC_PATH_L2 |
1616 		((enable_irq) ? DBC_DBC_TYPE_CQ_ARMALL: DBC_DBC_TYPE_CQ);
1617 
1618 	bus_space_barrier(db_bar->tag, db_bar->handle, cpr->ring.doorbell, 8,
1619 			BUS_SPACE_BARRIER_WRITE);
1620 	bus_space_write_8(db_bar->tag, db_bar->handle, cpr->ring.doorbell,
1621 			htole64(*(uint64_t *)&db_msg));
1622 	bus_space_barrier(db_bar->tag, db_bar->handle, 0, db_bar->size,
1623 			BUS_SPACE_BARRIER_WRITE);
1624 }
1625 
1626 static void bnxt_thor_db_nq(void *db_ptr, bool enable_irq)
1627 {
1628 	struct bnxt_cp_ring *cpr = (struct bnxt_cp_ring *) db_ptr;
1629 	struct bnxt_bar_info *db_bar = &cpr->ring.softc->doorbell_bar;
1630 	dbc_dbc_t db_msg = { 0 };
1631 	uint32_t cons = cpr->cons;
1632 
1633 	db_msg.index = ((cons << DBC_DBC_INDEX_SFT) & DBC_DBC_INDEX_MASK);
1634 
1635 	db_msg.type_path_xid = ((cpr->ring.phys_id << DBC_DBC_XID_SFT) &
1636 			DBC_DBC_XID_MASK) | DBC_DBC_PATH_L2 |
1637 		((enable_irq) ? DBC_DBC_TYPE_NQ_ARM: DBC_DBC_TYPE_NQ);
1638 
1639 	bus_space_barrier(db_bar->tag, db_bar->handle, cpr->ring.doorbell, 8,
1640 			BUS_SPACE_BARRIER_WRITE);
1641 	bus_space_write_8(db_bar->tag, db_bar->handle, cpr->ring.doorbell,
1642 			htole64(*(uint64_t *)&db_msg));
1643 	bus_space_barrier(db_bar->tag, db_bar->handle, 0, db_bar->size,
1644 			BUS_SPACE_BARRIER_WRITE);
1645 }
1646 
1647 static void
1648 bnxt_thor2_db_rx(void *db_ptr, uint16_t idx)
1649 {
1650 	struct bnxt_ring *ring = (struct bnxt_ring *) db_ptr;
1651 	struct bnxt_bar_info *db_bar = &ring->softc->doorbell_bar;
1652 	uint64_t db_val;
1653 
1654 	if (idx >= ring->ring_size) {
1655 		device_printf(ring->softc->dev, "%s: BRCM DBG: idx: %d crossed boundary\n", __func__, idx);
1656 		return;
1657 	}
1658 
1659 	db_val = ((DBR_PATH_L2 | DBR_TYPE_SRQ | DBR_VALID | idx) |
1660 				((uint64_t)ring->phys_id << DBR_XID_SFT));
1661 
1662 	/* Add the PI index */
1663 	db_val |= DB_RING_IDX(ring, idx, ring->epoch_arr[idx]);
1664 
1665 	bus_space_barrier(db_bar->tag, db_bar->handle, ring->doorbell, 8,
1666 			BUS_SPACE_BARRIER_WRITE);
1667 	bus_space_write_8(db_bar->tag, db_bar->handle, ring->doorbell,
1668 			htole64(db_val));
1669 }
1670 
1671 static void
1672 bnxt_thor2_db_tx(void *db_ptr, uint16_t idx)
1673 {
1674 	struct bnxt_ring *ring = (struct bnxt_ring *) db_ptr;
1675 	struct bnxt_bar_info *db_bar = &ring->softc->doorbell_bar;
1676 	uint64_t db_val;
1677 
1678 	if (idx >= ring->ring_size) {
1679 		device_printf(ring->softc->dev, "%s: BRCM DBG: idx: %d crossed boundary\n", __func__, idx);
1680 		return;
1681 	}
1682 
1683 	db_val = ((DBR_PATH_L2 | DBR_TYPE_SQ | DBR_VALID | idx) |
1684 				((uint64_t)ring->phys_id << DBR_XID_SFT));
1685 
1686 	/* Add the PI index */
1687 	db_val |= DB_RING_IDX(ring, idx, ring->epoch_arr[idx]);
1688 
1689 	bus_space_barrier(db_bar->tag, db_bar->handle, ring->doorbell, 8,
1690 			BUS_SPACE_BARRIER_WRITE);
1691 	bus_space_write_8(db_bar->tag, db_bar->handle, ring->doorbell,
1692 			htole64(db_val));
1693 }
1694 
1695 static void
1696 bnxt_thor2_db_rx_cq(void *db_ptr, bool enable_irq)
1697 {
1698 	struct bnxt_cp_ring *cpr = (struct bnxt_cp_ring *) db_ptr;
1699 	struct bnxt_bar_info *db_bar = &cpr->ring.softc->doorbell_bar;
1700 	u64 db_msg = { 0 };
1701 	uint32_t cons = cpr->raw_cons;
1702 	uint32_t toggle = 0;
1703 
1704 	if (cons == UINT32_MAX)
1705 		cons = 0;
1706 
1707 	if (enable_irq == true)
1708 		toggle = cpr->toggle;
1709 
1710 	db_msg = DBR_PATH_L2 | ((u64)cpr->ring.phys_id << DBR_XID_SFT) | DBR_VALID |
1711 			DB_RING_IDX_CMP(&cpr->ring, cons) | DB_TOGGLE(toggle);
1712 
1713 	if (enable_irq)
1714 		db_msg |= DBR_TYPE_CQ_ARMALL;
1715 	else
1716 		db_msg |= DBR_TYPE_CQ;
1717 
1718 	bus_space_barrier(db_bar->tag, db_bar->handle, cpr->ring.doorbell, 8,
1719 			BUS_SPACE_BARRIER_WRITE);
1720 	bus_space_write_8(db_bar->tag, db_bar->handle, cpr->ring.doorbell,
1721 			htole64(*(uint64_t *)&db_msg));
1722 	bus_space_barrier(db_bar->tag, db_bar->handle, 0, db_bar->size,
1723 			BUS_SPACE_BARRIER_WRITE);
1724 }
1725 
1726 static void
1727 bnxt_thor2_db_tx_cq(void *db_ptr, bool enable_irq)
1728 {
1729 	struct bnxt_cp_ring *cpr = (struct bnxt_cp_ring *) db_ptr;
1730 	struct bnxt_bar_info *db_bar = &cpr->ring.softc->doorbell_bar;
1731 	u64 db_msg = { 0 };
1732 	uint32_t cons = cpr->raw_cons;
1733 	uint32_t toggle = 0;
1734 
1735 	if (enable_irq == true)
1736 		toggle = cpr->toggle;
1737 
1738 	db_msg = DBR_PATH_L2 | ((u64)cpr->ring.phys_id << DBR_XID_SFT) | DBR_VALID |
1739 			DB_RING_IDX_CMP(&cpr->ring, cons) | DB_TOGGLE(toggle);
1740 
1741 	if (enable_irq)
1742 		db_msg |= DBR_TYPE_CQ_ARMALL;
1743 	else
1744 		db_msg |= DBR_TYPE_CQ;
1745 
1746 	bus_space_barrier(db_bar->tag, db_bar->handle, cpr->ring.doorbell, 8,
1747 			BUS_SPACE_BARRIER_WRITE);
1748 	bus_space_write_8(db_bar->tag, db_bar->handle, cpr->ring.doorbell,
1749 			htole64(*(uint64_t *)&db_msg));
1750 	bus_space_barrier(db_bar->tag, db_bar->handle, 0, db_bar->size,
1751 			BUS_SPACE_BARRIER_WRITE);
1752 }
1753 
1754 static void
1755 bnxt_thor2_db_nq(void *db_ptr, bool enable_irq)
1756 {
1757 	struct bnxt_cp_ring *cpr = (struct bnxt_cp_ring *) db_ptr;
1758 	struct bnxt_bar_info *db_bar = &cpr->ring.softc->doorbell_bar;
1759 	u64 db_msg = { 0 };
1760 	uint32_t cons = cpr->raw_cons;
1761 	uint32_t toggle = 0;
1762 
1763 	if (enable_irq == true)
1764 		toggle = cpr->toggle;
1765 
1766 	db_msg = DBR_PATH_L2 | ((u64)cpr->ring.phys_id << DBR_XID_SFT) | DBR_VALID |
1767 			DB_RING_IDX_CMP(&cpr->ring, cons) | DB_TOGGLE(toggle);
1768 
1769 	if (enable_irq)
1770 		db_msg |= DBR_TYPE_NQ_ARM;
1771 	else
1772 		db_msg |= DBR_TYPE_NQ_MASK;
1773 
1774 	bus_space_barrier(db_bar->tag, db_bar->handle, cpr->ring.doorbell, 8,
1775 			BUS_SPACE_BARRIER_WRITE);
1776 	bus_space_write_8(db_bar->tag, db_bar->handle, cpr->ring.doorbell,
1777 			htole64(*(uint64_t *)&db_msg));
1778 	bus_space_barrier(db_bar->tag, db_bar->handle, 0, db_bar->size,
1779 			BUS_SPACE_BARRIER_WRITE);
1780 }
1781 
1782 struct bnxt_softc *bnxt_find_dev(uint32_t domain, uint32_t bus, uint32_t dev_fn, char *dev_name)
1783 {
1784 	struct bnxt_softc_list *sc = NULL;
1785 
1786 	SLIST_FOREACH(sc, &pf_list, next) {
1787 		/* get the softc reference based on device name */
1788 		if (dev_name && !strncmp(dev_name, if_name(iflib_get_ifp(sc->softc->ctx)), BNXT_MAX_STR)) {
1789 			return sc->softc;
1790 		}
1791 		/* get the softc reference based on domain,bus,device,function */
1792 		if (!dev_name &&
1793 		    (domain == sc->softc->domain) &&
1794 		    (bus == sc->softc->bus) &&
1795 		    (dev_fn == sc->softc->dev_fn)) {
1796 			return sc->softc;
1797 
1798 		}
1799 	}
1800 
1801 	return NULL;
1802 }
1803 
1804 
1805 static void bnxt_verify_asym_queues(struct bnxt_softc *softc)
1806 {
1807 	uint8_t i, lltc = 0;
1808 
1809 	if (!softc->max_lltc)
1810 		return;
1811 
1812 	/* Verify that lossless TX and RX queues are in the same index */
1813 	for (i = 0; i < softc->max_tc; i++) {
1814 		if (BNXT_LLQ(softc->tx_q_info[i].queue_profile) &&
1815 		    BNXT_LLQ(softc->rx_q_info[i].queue_profile))
1816 			lltc++;
1817 	}
1818 	softc->max_lltc = min(softc->max_lltc, lltc);
1819 }
1820 
1821 static int bnxt_hwrm_poll(struct bnxt_softc *bp)
1822 {
1823 	struct hwrm_ver_get_output	*resp =
1824 	    (void *)bp->hwrm_cmd_resp.idi_vaddr;
1825 	struct hwrm_ver_get_input req = {0};
1826 	int rc;
1827 
1828 	bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_VER_GET);
1829 
1830 	req.hwrm_intf_maj = HWRM_VERSION_MAJOR;
1831 	req.hwrm_intf_min = HWRM_VERSION_MINOR;
1832 	req.hwrm_intf_upd = HWRM_VERSION_UPDATE;
1833 
1834 	rc = _hwrm_send_message(bp, &req, sizeof(req));
1835 	if (rc)
1836 		return rc;
1837 
1838 	if (resp->flags & HWRM_VER_GET_OUTPUT_FLAGS_DEV_NOT_RDY)
1839 		rc = -EAGAIN;
1840 
1841 	return rc;
1842 }
1843 
1844 static void bnxt_rtnl_lock_sp(struct bnxt_softc *bp)
1845 {
1846 	/* We are called from bnxt_sp_task which has BNXT_STATE_IN_SP_TASK
1847 	 * set.  If the device is being closed, bnxt_close() may be holding
1848 	 * rtnl() and waiting for BNXT_STATE_IN_SP_TASK to clear.  So we
1849 	 * must clear BNXT_STATE_IN_SP_TASK before holding rtnl().
1850 	 */
1851 	clear_bit(BNXT_STATE_IN_SP_TASK, &bp->state);
1852 	rtnl_lock();
1853 }
1854 
1855 static void bnxt_rtnl_unlock_sp(struct bnxt_softc *bp)
1856 {
1857 	set_bit(BNXT_STATE_IN_SP_TASK, &bp->state);
1858 	rtnl_unlock();
1859 }
1860 
1861 static void bnxt_fw_fatal_close(struct bnxt_softc *softc)
1862 {
1863 	bnxt_disable_intr(softc->ctx);
1864 	if (pci_is_enabled(softc->pdev))
1865 		pci_disable_device(softc->pdev);
1866 }
1867 
1868 static u32 bnxt_fw_health_readl(struct bnxt_softc *bp, int reg_idx)
1869 {
1870 	struct bnxt_fw_health *fw_health = bp->fw_health;
1871 	u32 reg = fw_health->regs[reg_idx];
1872 	u32 reg_type, reg_off, val = 0;
1873 
1874 	reg_type = BNXT_FW_HEALTH_REG_TYPE(reg);
1875 	reg_off = BNXT_FW_HEALTH_REG_OFF(reg);
1876 	switch (reg_type) {
1877 	case BNXT_FW_HEALTH_REG_TYPE_CFG:
1878 		pci_read_config_dword(bp->pdev, reg_off, &val);
1879 		break;
1880 	case BNXT_FW_HEALTH_REG_TYPE_GRC:
1881 		reg_off = fw_health->mapped_regs[reg_idx];
1882 		fallthrough;
1883 	case BNXT_FW_HEALTH_REG_TYPE_BAR0:
1884 		val = readl_fbsd(bp, reg_off, 0);
1885 		break;
1886 	case BNXT_FW_HEALTH_REG_TYPE_BAR1:
1887 		val = readl_fbsd(bp, reg_off, 2);
1888 		break;
1889 	}
1890 	if (reg_idx == BNXT_FW_RESET_INPROG_REG)
1891 		val &= fw_health->fw_reset_inprog_reg_mask;
1892 	return val;
1893 }
1894 
1895 static void bnxt_fw_reset_close(struct bnxt_softc *bp)
1896 {
1897 	int i;
1898 	bnxt_ulp_stop(bp);
1899 	/* When firmware is in fatal state, quiesce device and disable
1900 	 * bus master to prevent any potential bad DMAs before freeing
1901 	 * kernel memory.
1902 	 */
1903 	if (test_bit(BNXT_STATE_FW_FATAL_COND, &bp->state)) {
1904 		u16 val = 0;
1905 
1906 		val = pci_read_config(bp->dev, PCI_SUBSYSTEM_ID, 2);
1907 		if (val == 0xffff) {
1908 			bp->fw_reset_min_dsecs = 0;
1909 		}
1910 		bnxt_fw_fatal_close(bp);
1911 	}
1912 
1913 	iflib_request_reset(bp->ctx);
1914 	bnxt_stop(bp->ctx);
1915 	bnxt_hwrm_func_drv_unrgtr(bp, false);
1916 
1917 	for (i = bp->nrxqsets-1; i>=0; i--) {
1918 		if (BNXT_CHIP_P5_PLUS(bp))
1919 			iflib_irq_free(bp->ctx, &bp->nq_rings[i].irq);
1920 		else
1921 			iflib_irq_free(bp->ctx, &bp->rx_cp_rings[i].irq);
1922 
1923 	}
1924 	if (pci_is_enabled(bp->pdev))
1925 		pci_disable_device(bp->pdev);
1926 	pci_disable_busmaster(bp->dev);
1927 	bnxt_free_ctx_mem(bp);
1928 }
1929 
1930 static bool is_bnxt_fw_ok(struct bnxt_softc *bp)
1931 {
1932 	struct bnxt_fw_health *fw_health = bp->fw_health;
1933 	bool no_heartbeat = false, has_reset = false;
1934 	u32 val;
1935 
1936 	val = bnxt_fw_health_readl(bp, BNXT_FW_HEARTBEAT_REG);
1937 	if (val == fw_health->last_fw_heartbeat)
1938 		no_heartbeat = true;
1939 
1940 	val = bnxt_fw_health_readl(bp, BNXT_FW_RESET_CNT_REG);
1941 	if (val != fw_health->last_fw_reset_cnt)
1942 		has_reset = true;
1943 
1944 	if (!no_heartbeat && has_reset)
1945 		return true;
1946 
1947 	return false;
1948 }
1949 
1950 void bnxt_fw_reset(struct bnxt_softc *bp)
1951 {
1952 	bnxt_rtnl_lock_sp(bp);
1953 	if (test_bit(BNXT_STATE_OPEN, &bp->state) &&
1954 	    !test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) {
1955 		int tmo;
1956 		set_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
1957 		bnxt_fw_reset_close(bp);
1958 
1959 		if ((bp->fw_cap & BNXT_FW_CAP_ERR_RECOVER_RELOAD)) {
1960 			bp->fw_reset_state = BNXT_FW_RESET_STATE_POLL_FW_DOWN;
1961 			tmo = HZ / 10;
1962 		} else {
1963 			bp->fw_reset_state = BNXT_FW_RESET_STATE_ENABLE_DEV;
1964 			tmo = bp->fw_reset_min_dsecs * HZ /10;
1965 		}
1966 		bnxt_queue_fw_reset_work(bp, tmo);
1967 	}
1968 	bnxt_rtnl_unlock_sp(bp);
1969 }
1970 
1971 static void bnxt_queue_fw_reset_work(struct bnxt_softc *bp, unsigned long delay)
1972 {
1973 	if (!(test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)))
1974 		return;
1975 
1976 	if (BNXT_PF(bp))
1977 		queue_delayed_work(bnxt_pf_wq, &bp->fw_reset_task, delay);
1978 	else
1979 		schedule_delayed_work(&bp->fw_reset_task, delay);
1980 }
1981 
1982 void bnxt_queue_sp_work(struct bnxt_softc *bp)
1983 {
1984 	if (BNXT_PF(bp))
1985 		queue_work(bnxt_pf_wq, &bp->sp_task);
1986 	else
1987 		schedule_work(&bp->sp_task);
1988 }
1989 
1990 static void bnxt_fw_reset_writel(struct bnxt_softc *bp, int reg_idx)
1991 {
1992 	struct bnxt_fw_health *fw_health = bp->fw_health;
1993 	u32 reg = fw_health->fw_reset_seq_regs[reg_idx];
1994 	u32 val = fw_health->fw_reset_seq_vals[reg_idx];
1995 	u32 reg_type, reg_off, delay_msecs;
1996 
1997 	delay_msecs = fw_health->fw_reset_seq_delay_msec[reg_idx];
1998 	reg_type = BNXT_FW_HEALTH_REG_TYPE(reg);
1999 	reg_off = BNXT_FW_HEALTH_REG_OFF(reg);
2000 	switch (reg_type) {
2001 	case BNXT_FW_HEALTH_REG_TYPE_CFG:
2002 		pci_write_config_dword(bp->pdev, reg_off, val);
2003 		break;
2004 	case BNXT_FW_HEALTH_REG_TYPE_GRC:
2005 		writel_fbsd(bp, BNXT_GRCPF_REG_WINDOW_BASE_OUT + 4, 0, reg_off & BNXT_GRC_BASE_MASK);
2006 		reg_off = (reg_off & BNXT_GRC_OFFSET_MASK) + 0x2000;
2007 		fallthrough;
2008 	case BNXT_FW_HEALTH_REG_TYPE_BAR0:
2009 		writel_fbsd(bp, reg_off, 0, val);
2010 		break;
2011 	case BNXT_FW_HEALTH_REG_TYPE_BAR1:
2012 		writel_fbsd(bp, reg_off, 2, val);
2013 		break;
2014 	}
2015 	if (delay_msecs) {
2016 		pci_read_config_dword(bp->pdev, 0, &val);
2017 		msleep(delay_msecs);
2018 	}
2019 }
2020 
2021 static void bnxt_reset_all(struct bnxt_softc *bp)
2022 {
2023 	struct bnxt_fw_health *fw_health = bp->fw_health;
2024 	int i, rc;
2025 
2026 	if (bp->fw_cap & BNXT_FW_CAP_ERR_RECOVER_RELOAD) {
2027 		bp->fw_reset_timestamp = jiffies;
2028 		return;
2029 	}
2030 
2031 	if (fw_health->flags & HWRM_ERROR_RECOVERY_QCFG_OUTPUT_FLAGS_HOST) {
2032 		for (i = 0; i < fw_health->fw_reset_seq_cnt; i++)
2033 			bnxt_fw_reset_writel(bp, i);
2034 	} else if (fw_health->flags & HWRM_ERROR_RECOVERY_QCFG_OUTPUT_FLAGS_CO_CPU) {
2035 		struct hwrm_fw_reset_input req = {0};
2036 
2037 		bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FW_RESET);
2038 		req.target_id = htole16(HWRM_TARGET_ID_KONG);
2039 		req.embedded_proc_type = HWRM_FW_RESET_INPUT_EMBEDDED_PROC_TYPE_CHIP;
2040 		req.selfrst_status = HWRM_FW_RESET_INPUT_SELFRST_STATUS_SELFRSTASAP;
2041 		req.flags = HWRM_FW_RESET_INPUT_FLAGS_RESET_GRACEFUL;
2042 		rc = hwrm_send_message(bp, &req, sizeof(req));
2043 
2044 		if (rc != -ENODEV)
2045 			device_printf(bp->dev, "Unable to reset FW rc=%d\n", rc);
2046 	}
2047 	bp->fw_reset_timestamp = jiffies;
2048 }
2049 
2050 static int __bnxt_alloc_fw_health(struct bnxt_softc *bp)
2051 {
2052 	if (bp->fw_health)
2053 		return 0;
2054 
2055 	bp->fw_health = kzalloc(sizeof(*bp->fw_health), GFP_KERNEL);
2056 	if (!bp->fw_health)
2057 		return -ENOMEM;
2058 
2059 	mutex_init(&bp->fw_health->lock);
2060 	return 0;
2061 }
2062 
2063 static int bnxt_alloc_fw_health(struct bnxt_softc *bp)
2064 {
2065 	int rc;
2066 
2067 	if (!(bp->fw_cap & BNXT_FW_CAP_HOT_RESET) &&
2068 	    !(bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY))
2069 		return 0;
2070 
2071 	rc = __bnxt_alloc_fw_health(bp);
2072 	if (rc) {
2073 		bp->fw_cap &= ~BNXT_FW_CAP_HOT_RESET;
2074 		bp->fw_cap &= ~BNXT_FW_CAP_ERROR_RECOVERY;
2075 		return rc;
2076 	}
2077 
2078 	return 0;
2079 }
2080 
2081 static inline void __bnxt_map_fw_health_reg(struct bnxt_softc *bp, u32 reg)
2082 {
2083 	writel_fbsd(bp, BNXT_GRCPF_REG_WINDOW_BASE_OUT + BNXT_FW_HEALTH_WIN_MAP_OFF, 0, reg & BNXT_GRC_BASE_MASK);
2084 }
2085 
2086 static int bnxt_map_fw_health_regs(struct bnxt_softc *bp)
2087 {
2088 	struct bnxt_fw_health *fw_health = bp->fw_health;
2089 	u32 reg_base = 0xffffffff;
2090 	int i;
2091 
2092 	bp->fw_health->status_reliable = false;
2093 	bp->fw_health->resets_reliable = false;
2094 	/* Only pre-map the monitoring GRC registers using window 3 */
2095 	for (i = 0; i < 4; i++) {
2096 		u32 reg = fw_health->regs[i];
2097 
2098 		if (BNXT_FW_HEALTH_REG_TYPE(reg) != BNXT_FW_HEALTH_REG_TYPE_GRC)
2099 			continue;
2100 		if (reg_base == 0xffffffff)
2101 			reg_base = reg & BNXT_GRC_BASE_MASK;
2102 		if ((reg & BNXT_GRC_BASE_MASK) != reg_base)
2103 			return -ERANGE;
2104 		fw_health->mapped_regs[i] = BNXT_FW_HEALTH_WIN_OFF(reg);
2105 	}
2106 	bp->fw_health->status_reliable = true;
2107 	bp->fw_health->resets_reliable = true;
2108 	if (reg_base == 0xffffffff)
2109 		return 0;
2110 
2111 	__bnxt_map_fw_health_reg(bp, reg_base);
2112 	return 0;
2113 }
2114 
2115 static void bnxt_inv_fw_health_reg(struct bnxt_softc *bp)
2116 {
2117 	struct bnxt_fw_health *fw_health = bp->fw_health;
2118 	u32 reg_type;
2119 
2120 	if (!fw_health)
2121 		return;
2122 
2123 	reg_type = BNXT_FW_HEALTH_REG_TYPE(fw_health->regs[BNXT_FW_HEALTH_REG]);
2124 	if (reg_type == BNXT_FW_HEALTH_REG_TYPE_GRC)
2125 		fw_health->status_reliable = false;
2126 
2127 	reg_type = BNXT_FW_HEALTH_REG_TYPE(fw_health->regs[BNXT_FW_RESET_CNT_REG]);
2128 	if (reg_type == BNXT_FW_HEALTH_REG_TYPE_GRC)
2129 		fw_health->resets_reliable = false;
2130 }
2131 
2132 static int bnxt_hwrm_error_recovery_qcfg(struct bnxt_softc *bp)
2133 {
2134 	struct bnxt_fw_health *fw_health = bp->fw_health;
2135 	struct hwrm_error_recovery_qcfg_output *resp =
2136 	    (void *)bp->hwrm_cmd_resp.idi_vaddr;
2137 	struct hwrm_error_recovery_qcfg_input req = {0};
2138 	int rc, i;
2139 
2140 	if (!(bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY))
2141 		return 0;
2142 
2143 	bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_ERROR_RECOVERY_QCFG);
2144 	rc = _hwrm_send_message(bp, &req, sizeof(req));
2145 
2146 	if (rc)
2147 		goto err_recovery_out;
2148 	fw_health->flags = le32toh(resp->flags);
2149 	if ((fw_health->flags & HWRM_ERROR_RECOVERY_QCFG_OUTPUT_FLAGS_CO_CPU) &&
2150 	    !(bp->fw_cap & BNXT_FW_CAP_KONG_MB_CHNL)) {
2151 		rc = -EINVAL;
2152 		goto err_recovery_out;
2153 	}
2154 	fw_health->polling_dsecs = le32toh(resp->driver_polling_freq);
2155 	fw_health->master_func_wait_dsecs =
2156 		le32toh(resp->master_func_wait_period);
2157 	fw_health->normal_func_wait_dsecs =
2158 		le32toh(resp->normal_func_wait_period);
2159 	fw_health->post_reset_wait_dsecs =
2160 		le32toh(resp->master_func_wait_period_after_reset);
2161 	fw_health->post_reset_max_wait_dsecs =
2162 		le32toh(resp->max_bailout_time_after_reset);
2163 	fw_health->regs[BNXT_FW_HEALTH_REG] =
2164 		le32toh(resp->fw_health_status_reg);
2165 	fw_health->regs[BNXT_FW_HEARTBEAT_REG] =
2166 		le32toh(resp->fw_heartbeat_reg);
2167 	fw_health->regs[BNXT_FW_RESET_CNT_REG] =
2168 		le32toh(resp->fw_reset_cnt_reg);
2169 	fw_health->regs[BNXT_FW_RESET_INPROG_REG] =
2170 		le32toh(resp->reset_inprogress_reg);
2171 	fw_health->fw_reset_inprog_reg_mask =
2172 		le32toh(resp->reset_inprogress_reg_mask);
2173 	fw_health->fw_reset_seq_cnt = resp->reg_array_cnt;
2174 	if (fw_health->fw_reset_seq_cnt >= 16) {
2175 		rc = -EINVAL;
2176 		goto err_recovery_out;
2177 	}
2178 	for (i = 0; i < fw_health->fw_reset_seq_cnt; i++) {
2179 		fw_health->fw_reset_seq_regs[i] =
2180 			le32toh(resp->reset_reg[i]);
2181 		fw_health->fw_reset_seq_vals[i] =
2182 			le32toh(resp->reset_reg_val[i]);
2183 		fw_health->fw_reset_seq_delay_msec[i] =
2184 			le32toh(resp->delay_after_reset[i]);
2185 	}
2186 err_recovery_out:
2187 	if (!rc)
2188 		rc = bnxt_map_fw_health_regs(bp);
2189 	if (rc)
2190 		bp->fw_cap &= ~BNXT_FW_CAP_ERROR_RECOVERY;
2191 	return rc;
2192 }
2193 
2194 static int bnxt_drv_rgtr(struct bnxt_softc *bp)
2195 {
2196 	int rc;
2197 
2198 	/* determine whether we can support error recovery before
2199 	 * registering with FW
2200 	 */
2201 	if (bnxt_alloc_fw_health(bp)) {
2202 		device_printf(bp->dev, "no memory for firmware error recovery\n");
2203 	} else {
2204 		rc = bnxt_hwrm_error_recovery_qcfg(bp);
2205 		if (rc)
2206 			device_printf(bp->dev, "hwrm query error recovery failure rc: %d\n",
2207 				    rc);
2208 	}
2209 	rc = bnxt_hwrm_func_drv_rgtr(bp, NULL, 0, false);  //sumit dbg: revisit the params
2210 	if (rc)
2211 		return -ENODEV;
2212 	return 0;
2213 }
2214 
2215 static bool bnxt_fw_reset_timeout(struct bnxt_softc *bp)
2216 {
2217 	return time_after(jiffies, bp->fw_reset_timestamp +
2218 			  (bp->fw_reset_max_dsecs * HZ / 10));
2219 }
2220 
2221 static int bnxt_open(struct bnxt_softc *bp)
2222 {
2223 	int rc = 0;
2224 	if (BNXT_PF(bp))
2225 		rc = bnxt_hwrm_nvm_get_dev_info(bp, &bp->nvm_info->mfg_id,
2226 			&bp->nvm_info->device_id, &bp->nvm_info->sector_size,
2227 			&bp->nvm_info->size, &bp->nvm_info->reserved_size,
2228 			&bp->nvm_info->available_size);
2229 
2230 	/* Get the queue config */
2231 	rc = bnxt_hwrm_queue_qportcfg(bp, HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_TX);
2232 	if (rc) {
2233 		device_printf(bp->dev, "reinit: hwrm qportcfg (tx) failed\n");
2234 		return rc;
2235 	}
2236 	if (bp->is_asym_q) {
2237 		rc = bnxt_hwrm_queue_qportcfg(bp,
2238 					      HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_RX);
2239 		if (rc) {
2240 			device_printf(bp->dev, "re-init: hwrm qportcfg (rx)  failed\n");
2241 			return rc;
2242 		}
2243 		bnxt_verify_asym_queues(bp);
2244 	} else {
2245 		bp->rx_max_q = bp->tx_max_q;
2246 		memcpy(bp->rx_q_info, bp->tx_q_info, sizeof(bp->rx_q_info));
2247 		memcpy(bp->rx_q_ids, bp->tx_q_ids, sizeof(bp->rx_q_ids));
2248 	}
2249 	/* Get the HW capabilities */
2250 	rc = bnxt_hwrm_func_qcaps(bp);
2251 	if (rc)
2252 		return rc;
2253 	(void)bnxt_hwrm_port_led_qcaps(bp);
2254 
2255 	bnxt_hwrm_dbg_qcaps(bp);
2256 
2257 	/* Register the driver with the FW */
2258 	rc = bnxt_drv_rgtr(bp);
2259 	if (rc)
2260 		return rc;
2261 	/* Retry a restore which could not complete before firmware reset. */
2262 	bnxt_led_restore(bp);
2263 	if (bp->hwrm_spec_code >= 0x10803) {
2264 		rc = bnxt_alloc_ctx_mem(bp);
2265 		if (rc) {
2266 			device_printf(bp->dev, "attach: alloc_ctx_mem failed\n");
2267 			return rc;
2268 		}
2269 		rc = bnxt_hwrm_func_resc_qcaps(bp, true);
2270 		if (!rc)
2271 			bp->flags |= BNXT_FLAG_FW_CAP_NEW_RM;
2272 	}
2273 
2274 	if (BNXT_CHIP_P5_PLUS(bp))
2275 		bnxt_hwrm_reserve_rings(bp);
2276 
2277 	/* Get the current configuration of this function */
2278 	rc = bnxt_hwrm_func_qcfg(bp);
2279 	if (rc) {
2280 		device_printf(bp->dev, "re-init: hwrm func qcfg failed\n");
2281 		return rc;
2282 	}
2283 
2284 	bnxt_msix_intr_assign(bp->ctx, 0);
2285 	rc = bnxt_init_hw(bp->ctx);
2286 	if (rc != 0)
2287 		return (rc);
2288 	bnxt_intr_enable(bp->ctx);
2289 
2290 	if (test_and_clear_bit(BNXT_STATE_FW_RESET_DET, &bp->state)) {
2291 		if (!test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) {
2292 			bnxt_ulp_start(bp, 0);
2293 		}
2294 	}
2295 
2296 	device_printf(bp->dev, "Network interface is UP and operational\n");
2297 
2298 	return rc;
2299 }
2300 static void bnxt_fw_reset_abort(struct bnxt_softc *bp, int rc)
2301 {
2302 	clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
2303 	if (bp->fw_reset_state != BNXT_FW_RESET_STATE_POLL_VF) {
2304 		bnxt_ulp_start(bp, rc);
2305 	}
2306 	bp->fw_reset_state = 0;
2307 }
2308 
2309 static void bnxt_fw_reset_task(struct work_struct *work)
2310 {
2311 	struct bnxt_softc *bp = container_of(work, struct bnxt_softc, fw_reset_task.work);
2312 	int rc = 0;
2313 
2314 	if (!test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) {
2315 		device_printf(bp->dev, "bnxt_fw_reset_task() called when not in fw reset mode!\n");
2316 		return;
2317 	}
2318 
2319 	switch (bp->fw_reset_state) {
2320 	case BNXT_FW_RESET_STATE_POLL_FW_DOWN: {
2321 		u32 val;
2322 
2323 		val = bnxt_fw_health_readl(bp, BNXT_FW_HEALTH_REG);
2324 		if (!(val & BNXT_FW_STATUS_SHUTDOWN) &&
2325 		    !bnxt_fw_reset_timeout(bp)) {
2326 			bnxt_queue_fw_reset_work(bp, HZ / 5);
2327 			return;
2328 		}
2329 
2330 		if (!bp->fw_health->primary) {
2331 			u32 wait_dsecs = bp->fw_health->normal_func_wait_dsecs;
2332 
2333 			bp->fw_reset_state = BNXT_FW_RESET_STATE_ENABLE_DEV;
2334 			bnxt_queue_fw_reset_work(bp, wait_dsecs * HZ / 10);
2335 			return;
2336 		}
2337 		bp->fw_reset_state = BNXT_FW_RESET_STATE_RESET_FW;
2338 	}
2339 		fallthrough;
2340 	case BNXT_FW_RESET_STATE_RESET_FW:
2341 		bnxt_reset_all(bp);
2342 		bp->fw_reset_state = BNXT_FW_RESET_STATE_ENABLE_DEV;
2343 		bnxt_queue_fw_reset_work(bp, bp->fw_reset_min_dsecs * HZ / 10);
2344 		return;
2345 	case BNXT_FW_RESET_STATE_ENABLE_DEV:
2346 		bnxt_inv_fw_health_reg(bp);
2347 		if (test_bit(BNXT_STATE_FW_FATAL_COND, &bp->state) &&
2348 		    !bp->fw_reset_min_dsecs) {
2349 			u16 val;
2350 
2351 			val = pci_read_config(bp->dev, PCI_SUBSYSTEM_ID, 2);
2352 			if (val == 0xffff) {
2353 				if (bnxt_fw_reset_timeout(bp)) {
2354 					device_printf(bp->dev, "Firmware reset aborted, PCI config space invalid\n");
2355 					rc = -ETIMEDOUT;
2356 					goto fw_reset_abort;
2357 				}
2358 				bnxt_queue_fw_reset_work(bp, HZ / 1000);
2359 				return;
2360 			}
2361 		}
2362 		clear_bit(BNXT_STATE_FW_FATAL_COND, &bp->state);
2363 		clear_bit(BNXT_STATE_FW_NON_FATAL_COND, &bp->state);
2364 		if (!pci_is_enabled(bp->pdev)) {
2365 			if (pci_enable_device(bp->pdev)) {
2366 				device_printf(bp->dev, "Cannot re-enable PCI device\n");
2367 				rc = -ENODEV;
2368 				goto fw_reset_abort;
2369 			}
2370 		}
2371 		pci_set_master(bp->pdev);
2372 		bp->fw_reset_state = BNXT_FW_RESET_STATE_POLL_FW;
2373 		fallthrough;
2374 	case BNXT_FW_RESET_STATE_POLL_FW:
2375 		bp->hwrm_cmd_timeo = SHORT_HWRM_CMD_TIMEOUT;
2376 		rc = bnxt_hwrm_poll(bp);
2377 		if (rc) {
2378 			if (bnxt_fw_reset_timeout(bp)) {
2379 				device_printf(bp->dev, "Firmware reset aborted\n");
2380 				goto fw_reset_abort_status;
2381 			}
2382 			bnxt_queue_fw_reset_work(bp, HZ / 5);
2383 			return;
2384 		}
2385 		bp->hwrm_cmd_timeo = DFLT_HWRM_CMD_TIMEOUT;
2386 		bp->fw_reset_state = BNXT_FW_RESET_STATE_OPENING;
2387 		fallthrough;
2388 	case BNXT_FW_RESET_STATE_OPENING:
2389 		rc = bnxt_open(bp);
2390 		if (rc) {
2391 			device_printf(bp->dev, "bnxt_open() failed during FW reset\n");
2392 			bnxt_fw_reset_abort(bp, rc);
2393 			rtnl_unlock();
2394 			return;
2395 		}
2396 
2397 		if ((bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY) &&
2398 		    bp->fw_health->enabled) {
2399 			bp->fw_health->last_fw_reset_cnt =
2400 				bnxt_fw_health_readl(bp, BNXT_FW_RESET_CNT_REG);
2401 		}
2402 		bp->fw_reset_state = 0;
2403 		smp_mb__before_atomic();
2404 		clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
2405 		bnxt_ulp_start(bp, 0);
2406 		clear_bit(BNXT_STATE_FW_ACTIVATE, &bp->state);
2407 		set_bit(BNXT_STATE_OPEN, &bp->state);
2408 		bnxt_crash_dump_init(bp);
2409 #ifdef PCI_IOV
2410 		bnxt_reenable_sriov(bp);
2411 #endif
2412 		rtnl_unlock();
2413 	}
2414 	return;
2415 
2416 fw_reset_abort_status:
2417 	if (bp->fw_health->status_reliable ||
2418 	    (bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY)) {
2419 		u32 sts = bnxt_fw_health_readl(bp, BNXT_FW_HEALTH_REG);
2420 
2421 		device_printf(bp->dev, "fw_health_status 0x%x\n", sts);
2422 	}
2423 fw_reset_abort:
2424 	rtnl_lock();
2425 	bnxt_fw_reset_abort(bp, rc);
2426 	rtnl_unlock();
2427 }
2428 
2429 static void bnxt_force_fw_reset(struct bnxt_softc *bp)
2430 {
2431 	struct bnxt_fw_health *fw_health = bp->fw_health;
2432 	u32 wait_dsecs;
2433 
2434 	if (!test_bit(BNXT_STATE_OPEN, &bp->state) ||
2435 	    test_bit(BNXT_STATE_IN_FW_RESET, &bp->state))
2436 		return;
2437 	bnxt_fw_reset_close(bp);
2438 	wait_dsecs = fw_health->master_func_wait_dsecs;
2439 	if (fw_health->primary) {
2440 		if (fw_health->flags & HWRM_ERROR_RECOVERY_QCFG_OUTPUT_FLAGS_CO_CPU)
2441 			wait_dsecs = 0;
2442 		bp->fw_reset_state = BNXT_FW_RESET_STATE_RESET_FW;
2443 	} else {
2444 		bp->fw_reset_timestamp = jiffies + wait_dsecs * HZ / 10;
2445 		wait_dsecs = fw_health->normal_func_wait_dsecs;
2446 		bp->fw_reset_state = BNXT_FW_RESET_STATE_ENABLE_DEV;
2447 	}
2448 
2449 	bp->fw_reset_min_dsecs = fw_health->post_reset_wait_dsecs;
2450 	bp->fw_reset_max_dsecs = fw_health->post_reset_max_wait_dsecs;
2451 	bnxt_queue_fw_reset_work(bp, wait_dsecs * HZ / 10);
2452 }
2453 
2454 static void bnxt_fw_exception(struct bnxt_softc *bp)
2455 {
2456 	device_printf(bp->dev, "Detected firmware fatal condition, initiating reset\n");
2457 	set_bit(BNXT_STATE_FW_FATAL_COND, &bp->state);
2458 	bnxt_rtnl_lock_sp(bp);
2459 	bnxt_force_fw_reset(bp);
2460 	bnxt_rtnl_unlock_sp(bp);
2461 }
2462 
2463 static void __bnxt_fw_recover(struct bnxt_softc *bp)
2464 {
2465 	if (test_bit(BNXT_STATE_FW_FATAL_COND, &bp->state) ||
2466 	    test_bit(BNXT_STATE_FW_NON_FATAL_COND, &bp->state))
2467 		bnxt_fw_reset(bp);
2468 	else
2469 		bnxt_fw_exception(bp);
2470 }
2471 
2472 static void bnxt_devlink_health_fw_report(struct bnxt_softc *bp)
2473 {
2474 	struct bnxt_fw_health *fw_health = bp->fw_health;
2475 
2476 	if (!fw_health)
2477 		return;
2478 
2479 	if (!fw_health->fw_reporter) {
2480 		__bnxt_fw_recover(bp);
2481 		return;
2482 	}
2483 }
2484 
2485 static void bnxt_sp_task(struct work_struct *work)
2486 {
2487 	struct bnxt_softc *bp = container_of(work, struct bnxt_softc, sp_task);
2488 
2489 	set_bit(BNXT_STATE_IN_SP_TASK, &bp->state);
2490 	smp_mb__after_atomic();
2491 	if (!test_bit(BNXT_STATE_OPEN, &bp->state)) {
2492 		clear_bit(BNXT_STATE_IN_SP_TASK, &bp->state);
2493 		return;
2494 	}
2495 
2496 #ifdef PCI_IOV
2497 	if (test_and_clear_bit(BNXT_HWRM_EXEC_FWD_REQ_SP_EVENT, &bp->sp_event))
2498 		bnxt_hwrm_exec_fwd_req(bp);
2499 #endif
2500 
2501 	if (test_and_clear_bit(BNXT_FW_RESET_NOTIFY_SP_EVENT, &bp->sp_event)) {
2502 		if (test_bit(BNXT_STATE_FW_FATAL_COND, &bp->state) ||
2503 		    test_bit(BNXT_STATE_FW_NON_FATAL_COND, &bp->state))
2504 			bnxt_devlink_health_fw_report(bp);
2505 		else
2506 			bnxt_fw_reset(bp);
2507 	}
2508 
2509 	if (test_and_clear_bit(BNXT_FW_EXCEPTION_SP_EVENT, &bp->sp_event)) {
2510 		if (!is_bnxt_fw_ok(bp))
2511 			bnxt_devlink_health_fw_report(bp);
2512 	}
2513 	smp_mb__before_atomic();
2514 	clear_bit(BNXT_STATE_IN_SP_TASK, &bp->state);
2515 }
2516 
2517 int
2518 bnxt_hwrm_reserve_rings(struct bnxt_softc *softc)
2519 {
2520 	if (BNXT_PF(softc))
2521 		return bnxt_hwrm_reserve_pf_rings(softc);
2522 
2523 	else
2524 		return bnxt_hwrm_reserve_vf_rings(softc);
2525 }
2526 
2527 static void
2528 bnxt_log_live_data(void *d)
2529 {
2530 	struct bnxt_softc *bp = d;
2531 
2532 	bnxt_log_ring_states(bp);
2533 }
2534 
2535 /* DDR Crash Dump Setup */
2536 static int
2537 bnxt_crash_dump_init(struct bnxt_softc *softc)
2538 {
2539 	int rc;
2540 
2541 	rc = bnxt_alloc_crash_dump_mem(softc);
2542 	if (rc) {
2543 		device_printf(softc->dev,
2544 		    "crash dump mem alloc failure rc: %d\n", rc);
2545 		return (rc);
2546 	}
2547 
2548 	rc = bnxt_hwrm_crash_dump_mem_cfg(softc);
2549 	if (rc) {
2550 		bnxt_free_crash_dump_mem(softc);
2551 		device_printf(softc->dev,
2552 		    "hwrm crash dump mem failure rc: %d\n", rc);
2553 	}
2554 
2555 	return (rc);
2556 }
2557 
2558 /* Device setup and teardown */
2559 static int
2560 bnxt_attach_pre(if_ctx_t ctx)
2561 {
2562 	struct bnxt_softc *softc = iflib_get_softc(ctx);
2563 	if_softc_ctx_t scctx;
2564 	int rc = 0;
2565 
2566 	softc->ctx = ctx;
2567 	softc->dev = iflib_get_dev(ctx);
2568 	softc->media = iflib_get_media(ctx);
2569 	softc->scctx = iflib_get_softc_ctx(ctx);
2570 	softc->sctx = iflib_get_sctx(ctx);
2571 	scctx = softc->scctx;
2572 	softc->domain = pci_get_domain(softc->dev);
2573 	softc->bus = pci_get_bus(softc->dev);
2574 	softc->slot = pci_get_slot(softc->dev);
2575 	softc->function = pci_get_function(softc->dev);
2576 	softc->dev_fn = PCI_DEVFN(softc->slot, softc->function);
2577 
2578 	bnxt_set_flags_by_devid(softc);
2579 
2580 	if (bnxt_num_pfs == 0)
2581 		  SLIST_INIT(&pf_list);
2582 	bnxt_num_pfs++;
2583 	softc->list.softc = softc;
2584 	SLIST_INSERT_HEAD(&pf_list, &softc->list, next);
2585 
2586 	pci_enable_busmaster(softc->dev);
2587 
2588 	if (bnxt_pci_mapping(softc)) {
2589 		device_printf(softc->dev, "PCI mapping failed\n");
2590 		rc = ENXIO;
2591 		goto pci_map_fail;
2592 	}
2593 
2594 	softc->pdev = kzalloc(sizeof(*softc->pdev), GFP_KERNEL);
2595 	if (!softc->pdev) {
2596 		device_printf(softc->dev, "pdev alloc failed\n");
2597 		rc = -ENOMEM;
2598 		goto free_pci_map;
2599 	}
2600 
2601 	rc = linux_pci_attach_device(softc->dev, NULL, NULL, softc->pdev);
2602 	if (rc) {
2603 		device_printf(softc->dev, "Failed to attach Linux PCI device 0x%x\n", rc);
2604 		goto pci_attach_fail;
2605 	}
2606 
2607 	mtx_init(&softc->log_lock, "BNXT LOG Lock", NULL, MTX_DEF);
2608 	TAILQ_INIT(&softc->loggers_list);
2609 	bnxt_register_logger(softc, BNXT_LOGGER_L2, BNXT_L2_MAX_LOG_BUFFERS,
2610 			     bnxt_log_live_data, BNXT_L2_MAX_LIVE_LOG_SIZE);
2611 
2612 	/* HWRM setup/init */
2613 	BNXT_HWRM_LOCK_INIT(softc, device_get_nameunit(softc->dev));
2614 	rc = bnxt_alloc_hwrm_dma_mem(softc);
2615 	if (rc)
2616 		goto dma_fail;
2617 
2618 	/* Get firmware version and compare with driver */
2619 	softc->ver_info = malloc(sizeof(struct bnxt_ver_info),
2620 	    M_DEVBUF, M_NOWAIT | M_ZERO);
2621 	if (softc->ver_info == NULL) {
2622 		rc = ENOMEM;
2623 		device_printf(softc->dev,
2624 		    "Unable to allocate space for version info\n");
2625 		goto ver_alloc_fail;
2626 	}
2627 	/* Default minimum required HWRM version */
2628 	softc->ver_info->hwrm_min_major = HWRM_VERSION_MAJOR;
2629 	softc->ver_info->hwrm_min_minor = HWRM_VERSION_MINOR;
2630 	softc->ver_info->hwrm_min_update = HWRM_VERSION_UPDATE;
2631 
2632 	rc = bnxt_hwrm_ver_get(softc);
2633 	if (rc) {
2634 		device_printf(softc->dev, "attach: hwrm ver get failed\n");
2635 		goto ver_fail;
2636 	}
2637 
2638 	if ((softc->flags & BNXT_FLAG_SHORT_CMD) ||
2639 	    softc->hwrm_max_ext_req_len > BNXT_HWRM_MAX_REQ_LEN) {
2640 		rc = bnxt_alloc_hwrm_short_cmd_req(softc);
2641 		if (rc)
2642 			goto hwrm_short_cmd_alloc_fail;
2643 	}
2644 
2645 	/* Now perform a function reset */
2646 	rc = bnxt_hwrm_func_reset(softc);
2647 
2648 	if ((softc->ver_info->chip_num == BCM57508) ||
2649 	    (softc->ver_info->chip_num == BCM57504) ||
2650 	    (softc->ver_info->chip_num == BCM57504_NPAR) ||
2651 	    (softc->ver_info->chip_num == BCM57502) ||
2652 	    (softc->ver_info->chip_num == BCM57601) ||
2653 	    (softc->ver_info->chip_num == BCM57602) ||
2654 	    (softc->ver_info->chip_num == BCM57604))
2655 		softc->flags |= BNXT_FLAG_CHIP_P5;
2656 
2657 	if (softc->ver_info->chip_num == BCM57608)
2658 		softc->flags |= BNXT_FLAG_CHIP_P7;
2659 
2660 	softc->flags |= BNXT_FLAG_TPA;
2661 
2662 	if (BNXT_CHIP_P5_PLUS(softc) && (!softc->ver_info->chip_rev) &&
2663 			(!softc->ver_info->chip_metal))
2664 		softc->flags &= ~BNXT_FLAG_TPA;
2665 
2666 	if (BNXT_CHIP_P5_PLUS(softc))
2667 		softc->flags &= ~BNXT_FLAG_TPA;
2668 
2669 	/* Get NVRAM info */
2670 	if (BNXT_PF(softc)) {
2671 		if (!bnxt_pf_wq) {
2672 			bnxt_pf_wq =
2673 				create_singlethread_workqueue("bnxt_pf_wq");
2674 			if (!bnxt_pf_wq) {
2675 				device_printf(softc->dev, "Unable to create workqueue.\n");
2676 				rc = -ENOMEM;
2677 				goto nvm_alloc_fail;
2678 			}
2679 		}
2680 
2681 		softc->nvm_info = malloc(sizeof(struct bnxt_nvram_info),
2682 		    M_DEVBUF, M_NOWAIT | M_ZERO);
2683 		if (softc->nvm_info == NULL) {
2684 			rc = ENOMEM;
2685 			device_printf(softc->dev,
2686 			    "Unable to allocate space for NVRAM info\n");
2687 			goto nvm_alloc_fail;
2688 		}
2689 
2690 		rc = bnxt_hwrm_nvm_get_dev_info(softc, &softc->nvm_info->mfg_id,
2691 		    &softc->nvm_info->device_id, &softc->nvm_info->sector_size,
2692 		    &softc->nvm_info->size, &softc->nvm_info->reserved_size,
2693 		    &softc->nvm_info->available_size);
2694 	}
2695 
2696 	if (BNXT_CHIP_P5(softc)) {
2697 		softc->db_ops.bnxt_db_tx = bnxt_thor_db_tx;
2698 		softc->db_ops.bnxt_db_rx = bnxt_thor_db_rx;
2699 		softc->db_ops.bnxt_db_rx_cq = bnxt_thor_db_rx_cq;
2700 		softc->db_ops.bnxt_db_tx_cq = bnxt_thor_db_tx_cq;
2701 		softc->db_ops.bnxt_db_nq = bnxt_thor_db_nq;
2702 	} else if (BNXT_CHIP_P7(softc)) {
2703 		softc->db_ops.bnxt_db_tx = bnxt_thor2_db_tx;
2704 		softc->db_ops.bnxt_db_rx = bnxt_thor2_db_rx;
2705 		softc->db_ops.bnxt_db_rx_cq = bnxt_thor2_db_rx_cq;
2706 		softc->db_ops.bnxt_db_tx_cq = bnxt_thor2_db_tx_cq;
2707 		softc->db_ops.bnxt_db_nq = bnxt_thor2_db_nq;
2708 	} else {
2709 		softc->db_ops.bnxt_db_tx = bnxt_cuw_db_tx;
2710 		softc->db_ops.bnxt_db_rx = bnxt_cuw_db_rx;
2711 		softc->db_ops.bnxt_db_rx_cq = bnxt_cuw_db_cq;
2712 		softc->db_ops.bnxt_db_tx_cq = bnxt_cuw_db_cq;
2713 	}
2714 
2715 
2716 	/* Get the queue config */
2717 	rc = bnxt_hwrm_queue_qportcfg(softc, HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_TX);
2718 	if (rc) {
2719 		device_printf(softc->dev, "attach: hwrm qportcfg (tx) failed\n");
2720 		goto failed;
2721 	}
2722 	if (softc->is_asym_q) {
2723 		rc = bnxt_hwrm_queue_qportcfg(softc,
2724 					      HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_RX);
2725 		if (rc) {
2726 			device_printf(softc->dev, "attach: hwrm qportcfg (rx)  failed\n");
2727 			return rc;
2728 		}
2729 		bnxt_verify_asym_queues(softc);
2730 	} else {
2731 		softc->rx_max_q = softc->tx_max_q;
2732 		memcpy(softc->rx_q_info, softc->tx_q_info, sizeof(softc->rx_q_info));
2733 		memcpy(softc->rx_q_ids, softc->tx_q_ids, sizeof(softc->rx_q_ids));
2734 	}
2735 
2736 	/* Get the HW capabilities */
2737 	rc = bnxt_hwrm_func_qcaps(softc);
2738 	if (rc)
2739 		goto failed;
2740 	(void)bnxt_hwrm_port_led_qcaps(softc);
2741 
2742 	/* Inform PF to approve MAC as default VF MAC. */
2743 	if (BNXT_VF(softc)) {
2744 		rc = bnxt_approve_mac(softc);
2745 		if (rc) {
2746 			device_printf(softc->dev, "attach: bnxt_approve_mac failed\n");
2747 			goto failed;
2748 		}
2749 	}
2750 
2751 	bnxt_hwrm_dbg_qcaps(softc);
2752 
2753 	/*
2754 	 * Register the driver with the FW
2755 	 * Register the async events with the FW
2756 	 */
2757 	rc = bnxt_drv_rgtr(softc);
2758 	if (rc)
2759 		goto failed;
2760 
2761 	if (softc->hwrm_spec_code >= 0x10803) {
2762 		rc = bnxt_alloc_ctx_mem(softc);
2763 		if (rc) {
2764 			device_printf(softc->dev, "attach: alloc_ctx_mem failed\n");
2765 			return rc;
2766 		}
2767 		rc = bnxt_hwrm_func_resc_qcaps(softc, true);
2768 		if (!rc)
2769 			softc->flags |= BNXT_FLAG_FW_CAP_NEW_RM;
2770 	}
2771 
2772 	/* Get the current configuration of this function */
2773 	rc = bnxt_hwrm_func_qcfg(softc);
2774 	if (rc) {
2775 		device_printf(softc->dev, "attach: hwrm func qcfg failed\n");
2776 		goto failed;
2777 	}
2778 
2779 	scctx->isc_txrx = &bnxt_txrx;
2780 	scctx->isc_tx_csum_flags = (CSUM_IP | CSUM_TCP | CSUM_UDP |
2781 	    CSUM_TCP_IPV6 | CSUM_UDP_IPV6 | CSUM_TSO);
2782 	scctx->isc_capabilities = scctx->isc_capenable =
2783 	    /* These are translated to hwassit bits */
2784 	    IFCAP_TXCSUM | IFCAP_TXCSUM_IPV6 | IFCAP_TSO4 | IFCAP_TSO6 |
2785 	    /* These are checked by iflib */
2786 	    IFCAP_LRO | IFCAP_VLAN_HWFILTER |
2787 	    /* These are part of the iflib mask */
2788 	    IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6 | IFCAP_VLAN_MTU |
2789 	    IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_HWTSO |
2790 	    /* These likely get lost... */
2791 	    IFCAP_VLAN_HWCSUM | IFCAP_JUMBO_MTU;
2792 
2793 	if (bnxt_wol_supported(softc))
2794 		scctx->isc_capabilities |= IFCAP_WOL_MAGIC;
2795 	bnxt_get_wol_settings(softc);
2796 	if (softc->wol)
2797 		scctx->isc_capenable |= IFCAP_WOL_MAGIC;
2798 
2799 	/* Get the queue config */
2800 	bnxt_get_wol_settings(softc);
2801 
2802 	if (BNXT_CHIP_P5_PLUS(softc))
2803 		bnxt_hwrm_reserve_rings(softc);
2804 
2805 	rc = bnxt_hwrm_func_qcfg(softc);
2806 	if (rc) {
2807 		device_printf(softc->dev, "attach: hwrm func qcfg failed\n");
2808 		goto failed;
2809 	}
2810 
2811 	bnxt_clear_ids(softc);
2812 	if (rc)
2813 		goto failed;
2814 
2815 	/* Now set up iflib sc */
2816 	scctx->isc_tx_nsegments = 31,
2817 	scctx->isc_tx_tso_segments_max = 31;
2818 	scctx->isc_tx_tso_size_max = BNXT_TSO_SIZE;
2819 	scctx->isc_tx_tso_segsize_max = BNXT_TSO_SIZE;
2820 	scctx->isc_vectors = softc->func.max_cp_rings;
2821 	scctx->isc_min_frame_size = BNXT_MIN_FRAME_SIZE;
2822 	scctx->isc_txrx = &bnxt_txrx;
2823 
2824 	if (scctx->isc_nrxd[0] <
2825 	    ((scctx->isc_nrxd[1] * 4) + scctx->isc_nrxd[2]))
2826 		device_printf(softc->dev,
2827 		    "WARNING: nrxd0 (%d) should be at least 4 * nrxd1 (%d) + nrxd2 (%d).  Driver may be unstable\n",
2828 		    scctx->isc_nrxd[0], scctx->isc_nrxd[1], scctx->isc_nrxd[2]);
2829 	if (scctx->isc_ntxd[0] < scctx->isc_ntxd[1] * 2)
2830 		device_printf(softc->dev,
2831 		    "WARNING: ntxd0 (%d) should be at least 2 * ntxd1 (%d).  Driver may be unstable\n",
2832 		    scctx->isc_ntxd[0], scctx->isc_ntxd[1]);
2833 	scctx->isc_txqsizes[0] = sizeof(struct cmpl_base) * scctx->isc_ntxd[0];
2834 	scctx->isc_txqsizes[1] = sizeof(struct tx_bd_short) *
2835 	    scctx->isc_ntxd[1];
2836 	scctx->isc_txqsizes[2] = sizeof(struct cmpl_base) * scctx->isc_ntxd[2];
2837 	scctx->isc_rxqsizes[0] = sizeof(struct cmpl_base) * scctx->isc_nrxd[0];
2838 	scctx->isc_rxqsizes[1] = sizeof(struct rx_prod_pkt_bd) *
2839 	    scctx->isc_nrxd[1];
2840 	scctx->isc_rxqsizes[2] = sizeof(struct rx_prod_pkt_bd) *
2841 	    scctx->isc_nrxd[2];
2842 
2843 	scctx->isc_nrxqsets_max = min(pci_msix_count(softc->dev)-1,
2844 	    softc->fn_qcfg.alloc_completion_rings - 1);
2845 	scctx->isc_nrxqsets_max = min(scctx->isc_nrxqsets_max,
2846 	    softc->fn_qcfg.alloc_rx_rings);
2847 	scctx->isc_nrxqsets_max = min(scctx->isc_nrxqsets_max,
2848 	    softc->fn_qcfg.alloc_vnics);
2849 	scctx->isc_ntxqsets_max = min(softc->fn_qcfg.alloc_tx_rings,
2850 	    softc->fn_qcfg.alloc_completion_rings - scctx->isc_nrxqsets_max - 1);
2851 
2852 	scctx->isc_rss_table_size = HW_HASH_INDEX_SIZE;
2853 	scctx->isc_rss_table_mask = scctx->isc_rss_table_size - 1;
2854 
2855 	/* iflib will map and release this bar */
2856 	scctx->isc_msix_bar = pci_msix_table_bar(softc->dev);
2857 
2858         /*
2859          * Default settings for HW LRO (TPA):
2860          *  Disable HW LRO by default
2861          *  Can be enabled after taking care of 'packet forwarding'
2862          */
2863 	if (softc->flags & BNXT_FLAG_TPA) {
2864 		softc->hw_lro.enable = 0;
2865 		softc->hw_lro.is_mode_gro = 0;
2866 		softc->hw_lro.max_agg_segs = 5; /* 2^5 = 32 segs */
2867 		softc->hw_lro.max_aggs = HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_MAX;
2868 		softc->hw_lro.min_agg_len = 512;
2869 	}
2870 
2871 	/* Allocate the default completion ring */
2872 	softc->def_cp_ring.stats_ctx_id = HWRM_NA_SIGNATURE;
2873 	softc->def_cp_ring.ring.phys_id = (uint16_t)HWRM_NA_SIGNATURE;
2874 	softc->def_cp_ring.ring.softc = softc;
2875 	softc->def_cp_ring.ring.id = 0;
2876 	softc->def_cp_ring.ring.doorbell = (BNXT_CHIP_P5_PLUS(softc)) ?
2877 		softc->legacy_db_size : softc->def_cp_ring.ring.id * 0x80;
2878 	softc->def_cp_ring.ring.ring_size = PAGE_SIZE /
2879 	    sizeof(struct cmpl_base);
2880 	softc->def_cp_ring.ring.db_ring_mask = softc->def_cp_ring.ring.ring_size -1 ;
2881 	rc = iflib_dma_alloc(ctx,
2882 	    sizeof(struct cmpl_base) * softc->def_cp_ring.ring.ring_size,
2883 	    &softc->def_cp_ring_mem, 0);
2884 	softc->def_cp_ring.ring.vaddr = softc->def_cp_ring_mem.idi_vaddr;
2885 	softc->def_cp_ring.ring.paddr = softc->def_cp_ring_mem.idi_paddr;
2886 	iflib_config_task_init(ctx, &softc->def_cp_task, bnxt_def_cp_task);
2887 
2888 	rc = bnxt_init_sysctl_ctx(softc);
2889 	if (rc)
2890 		goto init_sysctl_failed;
2891 	if (BNXT_PF(softc)) {
2892 		rc = bnxt_create_nvram_sysctls(softc->nvm_info);
2893 		if (rc)
2894 			goto failed;
2895 	}
2896 
2897 	_Static_assert(HW_HASH_KEY_SIZE == RSS_KEYSIZE,
2898 	    "RSS key size mismatch");
2899 	rss_getkey(softc->vnic_info.rss_hash_key);
2900 	softc->vnic_info.rss_hash_type =
2901 	    HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4 |
2902 	    HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4 |
2903 	    HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4 |
2904 	    HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6 |
2905 	    HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6 |
2906 	    HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6;
2907 	rc = bnxt_create_config_sysctls_pre(softc);
2908 	if (rc)
2909 		goto failed;
2910 
2911 	rc = bnxt_create_hw_lro_sysctls(softc);
2912 	if (rc)
2913 		goto failed;
2914 
2915 	rc = bnxt_create_pause_fc_sysctls(softc);
2916 	if (rc)
2917 		goto failed;
2918 
2919 	rc = bnxt_create_dcb_sysctls(softc);
2920 	if (rc)
2921 		goto failed;
2922 
2923 	set_bit(BNXT_STATE_OPEN, &softc->state);
2924 	INIT_WORK(&softc->sp_task, bnxt_sp_task);
2925 	INIT_DELAYED_WORK(&softc->fw_reset_task, bnxt_fw_reset_task);
2926 
2927 	/* Initialize the vlan list */
2928 	SLIST_INIT(&softc->vnic_info.vlan_tags);
2929 	softc->vnic_info.vlan_tag_list.idi_vaddr = NULL;
2930 	softc->state_bv = bit_alloc(BNXT_STATE_MAX, M_DEVBUF,
2931 			M_WAITOK|M_ZERO);
2932 
2933 	if (BNXT_PF(softc)) {
2934 		const char *part_num;
2935 
2936 		if (pci_get_vpd_readonly(softc->dev, "PN", &part_num) == 0)
2937 			snprintf(softc->board_partno, sizeof(softc->board_partno), "%s", part_num);
2938 	}
2939 
2940 	return (rc);
2941 
2942 
2943 failed:
2944 	bnxt_free_sysctl_ctx(softc);
2945 init_sysctl_failed:
2946 	bnxt_hwrm_func_drv_unrgtr(softc, false);
2947 	if (BNXT_PF(softc))
2948 		free(softc->nvm_info, M_DEVBUF);
2949 nvm_alloc_fail:
2950 	bnxt_free_hwrm_short_cmd_req(softc);
2951 hwrm_short_cmd_alloc_fail:
2952 ver_fail:
2953 	free(softc->ver_info, M_DEVBUF);
2954 ver_alloc_fail:
2955 	bnxt_free_hwrm_dma_mem(softc);
2956 dma_fail:
2957 	BNXT_HWRM_LOCK_DESTROY(softc);
2958 	if (softc->pdev)
2959 		linux_pci_detach_device(softc->pdev);
2960 pci_attach_fail:
2961 	kfree(softc->pdev);
2962 	softc->pdev = NULL;
2963 free_pci_map:
2964 	bnxt_pci_mapping_free(softc);
2965 pci_map_fail:
2966 	pci_disable_busmaster(softc->dev);
2967 	return (rc);
2968 }
2969 
2970 static int
2971 bnxt_attach_post(if_ctx_t ctx)
2972 {
2973 	struct bnxt_softc *softc = iflib_get_softc(ctx);
2974 	if_t ifp = iflib_get_ifp(ctx);
2975 	int rc;
2976 
2977 	softc->ifp = ifp;
2978 	bnxt_create_config_sysctls_post(softc);
2979 
2980 	/* Update link state etc... */
2981 	rc = bnxt_probe_phy(softc);
2982 	if (rc)
2983 		goto failed;
2984 
2985 	/* Needs to be done after probing the phy */
2986 	bnxt_create_ver_sysctls(softc);
2987 	ifmedia_removeall(softc->media);
2988 	bnxt_add_media_types(softc);
2989 	ifmedia_set(softc->media, IFM_ETHER | IFM_AUTO);
2990 
2991 	softc->scctx->isc_max_frame_size = if_getmtu(ifp) + ETHER_HDR_LEN +
2992 	    ETHER_CRC_LEN;
2993 
2994 	softc->rx_buf_size = min(softc->scctx->isc_max_frame_size, BNXT_PAGE_SIZE);
2995 	bnxt_dcb_init(softc);
2996 	bnxt_rdma_aux_device_init(softc);
2997 
2998 	/* SR-IOV attach */
2999 	if (BNXT_PF(softc) && BNXT_CHIP_P5_PLUS(softc))
3000 		bnxt_sriov_attach(softc);
3001 
3002 	rc = bnxt_crash_dump_init(softc);
3003 	if (rc)
3004 		device_printf(softc->dev,
3005 		    "crash dump init failure rc: %d\n", rc);
3006 
3007 failed:
3008 	return rc;
3009 }
3010 
3011 static int
3012 bnxt_detach(if_ctx_t ctx)
3013 {
3014 	struct bnxt_softc *softc = iflib_get_softc(ctx);
3015 	struct bnxt_vlan_tag *tag;
3016 	struct bnxt_vlan_tag *tmp;
3017 	int i;
3018 
3019 	bnxt_rdma_aux_device_uninit(softc);
3020 	cancel_delayed_work_sync(&softc->fw_reset_task);
3021 	cancel_work_sync(&softc->sp_task);
3022 	bnxt_dcb_free(softc);
3023 	SLIST_REMOVE(&pf_list, &softc->list, bnxt_softc_list, next);
3024 	bnxt_num_pfs--;
3025 	bnxt_wol_config(ctx);
3026 	bnxt_do_disable_intr(&softc->def_cp_ring);
3027 	bnxt_free_sysctl_ctx(softc);
3028 	bnxt_free_crash_dump_mem(softc);
3029 	bnxt_hwrm_func_reset(softc);
3030 	bnxt_free_ctx_mem(softc);
3031 	bnxt_clear_ids(softc);
3032 	iflib_irq_free(ctx, &softc->def_cp_ring.irq);
3033 	/* We need to free() these here... */
3034 	for (i = softc->nrxqsets-1; i>=0; i--) {
3035 		if (BNXT_CHIP_P5_PLUS(softc))
3036 			iflib_irq_free(ctx, &softc->nq_rings[i].irq);
3037 		else
3038 			iflib_irq_free(ctx, &softc->rx_cp_rings[i].irq);
3039 
3040 	}
3041 	iflib_dma_free(&softc->vnic_info.mc_list);
3042 	iflib_dma_free(&softc->vnic_info.rss_hash_key_tbl);
3043 	iflib_dma_free(&softc->vnic_info.rss_grp_tbl);
3044 	if (softc->vnic_info.vlan_tag_list.idi_vaddr)
3045 		iflib_dma_free(&softc->vnic_info.vlan_tag_list);
3046 	SLIST_FOREACH_SAFE(tag, &softc->vnic_info.vlan_tags, next, tmp)
3047 		free(tag, M_DEVBUF);
3048 	iflib_dma_free(&softc->def_cp_ring_mem);
3049 	for (i = 0; i < softc->nrxqsets; i++)
3050 		free(softc->rx_rings[i].tpa_start, M_DEVBUF);
3051 	free(softc->ver_info, M_DEVBUF);
3052 	if (BNXT_PF(softc))
3053 		free(softc->nvm_info, M_DEVBUF);
3054 
3055 	bnxt_hwrm_func_drv_unrgtr(softc, false);
3056 	bnxt_free_hwrm_dma_mem(softc);
3057 	bnxt_free_hwrm_short_cmd_req(softc);
3058 	BNXT_HWRM_LOCK_DESTROY(softc);
3059 
3060 	bnxt_unregister_logger(softc, BNXT_LOGGER_L2);
3061 	mtx_destroy(&softc->log_lock);
3062 
3063 	if (!bnxt_num_pfs && bnxt_pf_wq)
3064 		destroy_workqueue(bnxt_pf_wq);
3065 
3066 	if (softc->pdev)
3067 		linux_pci_detach_device(softc->pdev);
3068 	free(softc->state_bv, M_DEVBUF);
3069 	pci_disable_busmaster(softc->dev);
3070 	bnxt_pci_mapping_free(softc);
3071 
3072 	return 0;
3073 }
3074 
3075 static void
3076 bnxt_hwrm_resource_free(struct bnxt_softc *softc)
3077 {
3078 	int i, rc = 0;
3079 
3080 	rc = bnxt_hwrm_ring_free(softc,
3081 			HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
3082 			&softc->def_cp_ring.ring,
3083 			(uint16_t)HWRM_NA_SIGNATURE);
3084 	if (rc)
3085 		goto fail;
3086 
3087 	for (i = 0; i < softc->ntxqsets; i++) {
3088 		rc = bnxt_hwrm_ring_free(softc,
3089 				HWRM_RING_ALLOC_INPUT_RING_TYPE_TX,
3090 				&softc->tx_rings[i],
3091 				softc->tx_cp_rings[i].ring.phys_id);
3092 		if (rc)
3093 			goto fail;
3094 
3095 		rc = bnxt_hwrm_ring_free(softc,
3096 				HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
3097 				&softc->tx_cp_rings[i].ring,
3098 				(uint16_t)HWRM_NA_SIGNATURE);
3099 		if (rc)
3100 			goto fail;
3101 
3102 		rc = bnxt_hwrm_stat_ctx_free(softc, &softc->tx_cp_rings[i]);
3103 		if (rc)
3104 			goto fail;
3105 	}
3106 	rc = bnxt_hwrm_free_filter(softc);
3107 	if (rc)
3108 		goto fail;
3109 
3110 	rc = bnxt_hwrm_vnic_free(softc, &softc->vnic_info);
3111 	if (rc)
3112 		goto fail;
3113 
3114 	rc = bnxt_hwrm_vnic_ctx_free(softc, softc->vnic_info.rss_id);
3115 	if (rc)
3116 		goto fail;
3117 
3118 	for (i = 0; i < softc->nrxqsets; i++) {
3119 		rc = bnxt_hwrm_ring_grp_free(softc, &softc->grp_info[i]);
3120 		if (rc)
3121 			goto fail;
3122 
3123 		rc = bnxt_hwrm_ring_free(softc,
3124 				HWRM_RING_ALLOC_INPUT_RING_TYPE_RX_AGG,
3125 				&softc->ag_rings[i],
3126 				(uint16_t)HWRM_NA_SIGNATURE);
3127 		if (rc)
3128 			goto fail;
3129 
3130 		rc = bnxt_hwrm_ring_free(softc,
3131 				HWRM_RING_ALLOC_INPUT_RING_TYPE_RX,
3132 				&softc->rx_rings[i],
3133 				softc->rx_cp_rings[i].ring.phys_id);
3134 		if (rc)
3135 			goto fail;
3136 
3137 		rc = bnxt_hwrm_ring_free(softc,
3138 				HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
3139 				&softc->rx_cp_rings[i].ring,
3140 				(uint16_t)HWRM_NA_SIGNATURE);
3141 		if (rc)
3142 			goto fail;
3143 
3144 		if (BNXT_CHIP_P5_PLUS(softc)) {
3145 			rc = bnxt_hwrm_ring_free(softc,
3146 					HWRM_RING_ALLOC_INPUT_RING_TYPE_NQ,
3147 					&softc->nq_rings[i].ring,
3148 					(uint16_t)HWRM_NA_SIGNATURE);
3149 			if (rc)
3150 				goto fail;
3151 		}
3152 
3153 		rc = bnxt_hwrm_stat_ctx_free(softc, &softc->rx_cp_rings[i]);
3154 		if (rc)
3155 			goto fail;
3156 	}
3157 
3158 fail:
3159 	return;
3160 }
3161 
3162 
3163 static void
3164 bnxt_func_reset(struct bnxt_softc *softc)
3165 {
3166 	bnxt_led_restore(softc);
3167 
3168 	if (!BNXT_CHIP_P5_PLUS(softc)) {
3169 		bnxt_hwrm_func_reset(softc);
3170 		return;
3171 	}
3172 
3173 	bnxt_hwrm_resource_free(softc);
3174 	return;
3175 }
3176 
3177 static void
3178 bnxt_rss_grp_tbl_init(struct bnxt_softc *softc)
3179 {
3180 	uint16_t *rgt = (uint16_t *) softc->vnic_info.rss_grp_tbl.idi_vaddr;
3181 	int i, j;
3182 
3183 	for (i = 0, j = 0; i < HW_HASH_INDEX_SIZE; i++) {
3184 		if (BNXT_CHIP_P5_PLUS(softc)) {
3185 			rgt[i++] = htole16(softc->rx_rings[j].phys_id);
3186 			rgt[i] = htole16(softc->rx_cp_rings[j].ring.phys_id);
3187 		} else {
3188 			rgt[i] = htole16(softc->grp_info[j].grp_id);
3189 		}
3190 		if (++j == softc->nrxqsets)
3191 			j = 0;
3192 	}
3193 }
3194 
3195 static void bnxt_get_port_module_status(struct bnxt_softc *softc)
3196 {
3197 	struct bnxt_link_info *link_info = &softc->link_info;
3198 	struct hwrm_port_phy_qcfg_output *resp = &link_info->phy_qcfg_resp;
3199 	uint8_t module_status;
3200 
3201 	if (bnxt_update_link(softc, false))
3202 		return;
3203 
3204 	module_status = link_info->module_status;
3205 	switch (module_status) {
3206 	case HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_DISABLETX:
3207 	case HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_PWRDOWN:
3208 	case HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_WARNINGMSG:
3209 		device_printf(softc->dev, "Unqualified SFP+ module detected on port %d\n",
3210 			    softc->pf.port_id);
3211 		if (softc->hwrm_spec_code >= 0x10201) {
3212 			device_printf(softc->dev, "Module part number %s\n",
3213 				    resp->phy_vendor_partnumber);
3214 		}
3215 		if (module_status == HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_DISABLETX)
3216 			device_printf(softc->dev, "TX is disabled\n");
3217 		if (module_status == HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_PWRDOWN)
3218 			device_printf(softc->dev, "SFP+ module is shutdown\n");
3219 	}
3220 }
3221 
3222 static void bnxt_aux_dev_free(struct bnxt_softc *softc)
3223 {
3224 	kfree(softc->aux_dev);
3225 	softc->aux_dev = NULL;
3226 }
3227 
3228 static struct bnxt_aux_dev *bnxt_aux_dev_init(struct bnxt_softc *softc)
3229 {
3230 	struct bnxt_aux_dev *bnxt_adev;
3231 
3232 	msleep(1000 * 2);
3233 	bnxt_adev = kzalloc(sizeof(*bnxt_adev), GFP_KERNEL);
3234 	if (!bnxt_adev)
3235 		return ERR_PTR(-ENOMEM);
3236 
3237 	return bnxt_adev;
3238 }
3239 
3240 static void bnxt_rdma_aux_device_uninit(struct bnxt_softc *softc)
3241 {
3242 	struct bnxt_aux_dev *bnxt_adev = softc->aux_dev;
3243 
3244 	/* Skip if no auxiliary device init was done. */
3245 	if (!(softc->flags & BNXT_FLAG_ROCE_CAP))
3246 		return;
3247 
3248 	if (IS_ERR_OR_NULL(bnxt_adev))
3249 		return;
3250 
3251 	bnxt_rdma_aux_device_del(softc);
3252 
3253 	if (bnxt_adev->id >= 0)
3254 		ida_free(&bnxt_aux_dev_ids, bnxt_adev->id);
3255 
3256 	bnxt_aux_dev_free(softc);
3257 }
3258 
3259 static void bnxt_rdma_aux_device_init(struct bnxt_softc *softc)
3260 {
3261 	int rc;
3262 
3263 	if (!(softc->flags & BNXT_FLAG_ROCE_CAP))
3264 		return;
3265 
3266 	softc->aux_dev = bnxt_aux_dev_init(softc);
3267 	if (IS_ERR_OR_NULL(softc->aux_dev)) {
3268 		device_printf(softc->dev, "Failed to init auxiliary device for ROCE\n");
3269 		goto skip_aux_init;
3270 	}
3271 
3272 	softc->aux_dev->id = ida_alloc(&bnxt_aux_dev_ids, GFP_KERNEL);
3273 	if (softc->aux_dev->id < 0) {
3274 		device_printf(softc->dev, "ida alloc failed for ROCE auxiliary device\n");
3275 		bnxt_aux_dev_free(softc);
3276 		goto skip_aux_init;
3277 	}
3278 
3279 	msleep(1000 * 2);
3280 	/* If aux bus init fails, continue with netdev init. */
3281 	rc = bnxt_rdma_aux_device_add(softc);
3282 	if (rc) {
3283 		device_printf(softc->dev, "Failed to add auxiliary device for ROCE\n");
3284 		msleep(1000 * 2);
3285 		ida_free(&bnxt_aux_dev_ids, softc->aux_dev->id);
3286 	}
3287 	device_printf(softc->dev, "%s:%d Added auxiliary device (id %d) for ROCE \n",
3288 		      __func__, __LINE__, softc->aux_dev->id);
3289 skip_aux_init:
3290 	return;
3291 }
3292 
3293 /* Device configuration */
3294 static void
3295 bnxt_init(if_ctx_t ctx)
3296 {
3297 
3298 	if (bnxt_init_hw(ctx) != 0)
3299 		iflib_init_failed(ctx);
3300 }
3301 
3302 static int
3303 bnxt_init_hw(if_ctx_t ctx)
3304 {
3305 	struct bnxt_softc *softc = iflib_get_softc(ctx);
3306 	struct ifmediareq ifmr;
3307 	int i;
3308 	int rc;
3309 
3310 	if (!BNXT_CHIP_P5_PLUS(softc)) {
3311 		rc = bnxt_hwrm_func_reset(softc);
3312 		if (rc)
3313 			return (rc);
3314 	} else if (softc->is_dev_init) {
3315 		bnxt_stop(ctx);
3316 	}
3317 
3318 	softc->is_dev_init = true;
3319 	bnxt_clear_ids(softc);
3320 
3321 	if (BNXT_CHIP_P5_PLUS(softc))
3322 		goto skip_def_cp_ring;
3323 	/* Allocate the default completion ring */
3324 	softc->def_cp_ring.cons = UINT32_MAX;
3325 	softc->def_cp_ring.v_bit = 1;
3326 	bnxt_mark_cpr_invalid(&softc->def_cp_ring);
3327 	rc = bnxt_hwrm_ring_alloc(softc,
3328 			HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
3329 			&softc->def_cp_ring.ring);
3330 	bnxt_set_db_mask(softc, &softc->def_cp_ring.ring,
3331 			HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL);
3332 	if (rc)
3333 		goto fail;
3334 skip_def_cp_ring:
3335 	for (i = 0; i < softc->nrxqsets; i++) {
3336 		/* Allocate the statistics context */
3337 		rc = bnxt_hwrm_stat_ctx_alloc(softc, &softc->rx_cp_rings[i],
3338 		    softc->rx_stats[i].idi_paddr);
3339 		if (rc)
3340 			goto fail;
3341 
3342 		if (BNXT_CHIP_P5_PLUS(softc)) {
3343 			/* Allocate the NQ */
3344 			softc->nq_rings[i].cons = 0;
3345 			softc->nq_rings[i].raw_cons = 0;
3346 			softc->nq_rings[i].v_bit = 1;
3347 			softc->nq_rings[i].last_idx = UINT32_MAX;
3348 			bnxt_mark_cpr_invalid(&softc->nq_rings[i]);
3349 			rc = bnxt_hwrm_ring_alloc(softc,
3350 					HWRM_RING_ALLOC_INPUT_RING_TYPE_NQ,
3351 					&softc->nq_rings[i].ring);
3352 			bnxt_set_db_mask(softc, &softc->nq_rings[i].ring,
3353 					HWRM_RING_ALLOC_INPUT_RING_TYPE_NQ);
3354 			if (rc)
3355 				goto fail;
3356 
3357 			softc->db_ops.bnxt_db_nq(&softc->nq_rings[i], 1);
3358 		}
3359 		/* Allocate the completion ring */
3360 		softc->rx_cp_rings[i].cons = UINT32_MAX;
3361 		softc->rx_cp_rings[i].raw_cons = UINT32_MAX;
3362 		softc->rx_cp_rings[i].v_bit = 1;
3363 		softc->rx_cp_rings[i].last_idx = UINT32_MAX;
3364 		softc->rx_cp_rings[i].toggle = 0;
3365 		bnxt_mark_cpr_invalid(&softc->rx_cp_rings[i]);
3366 		rc = bnxt_hwrm_ring_alloc(softc,
3367 				HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
3368 				&softc->rx_cp_rings[i].ring);
3369 		bnxt_set_db_mask(softc, &softc->rx_cp_rings[i].ring,
3370 				HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL);
3371 		if (rc)
3372 			goto fail;
3373 
3374 		if (BNXT_CHIP_P5_PLUS(softc))
3375 			softc->db_ops.bnxt_db_rx_cq(&softc->rx_cp_rings[i], 1);
3376 
3377 		/* Allocate the RX ring */
3378 		rc = bnxt_hwrm_ring_alloc(softc,
3379 		    HWRM_RING_ALLOC_INPUT_RING_TYPE_RX, &softc->rx_rings[i]);
3380 		bnxt_set_db_mask(softc, &softc->rx_rings[i],
3381 				HWRM_RING_ALLOC_INPUT_RING_TYPE_RX);
3382 		if (rc)
3383 			goto fail;
3384 		softc->db_ops.bnxt_db_rx(&softc->rx_rings[i], 0);
3385 
3386 		/* Allocate the AG ring */
3387 		rc = bnxt_hwrm_ring_alloc(softc,
3388 				HWRM_RING_ALLOC_INPUT_RING_TYPE_RX_AGG,
3389 				&softc->ag_rings[i]);
3390 		bnxt_set_db_mask(softc, &softc->ag_rings[i],
3391 				HWRM_RING_ALLOC_INPUT_RING_TYPE_RX_AGG);
3392 		if (rc)
3393 			goto fail;
3394 		softc->db_ops.bnxt_db_rx(&softc->ag_rings[i], 0);
3395 
3396 		/* Allocate the ring group */
3397 		softc->grp_info[i].stats_ctx =
3398 		    softc->rx_cp_rings[i].stats_ctx_id;
3399 		softc->grp_info[i].rx_ring_id = softc->rx_rings[i].phys_id;
3400 		softc->grp_info[i].ag_ring_id = softc->ag_rings[i].phys_id;
3401 		softc->grp_info[i].cp_ring_id =
3402 		    softc->rx_cp_rings[i].ring.phys_id;
3403 		rc = bnxt_hwrm_ring_grp_alloc(softc, &softc->grp_info[i]);
3404 		if (rc)
3405 			goto fail;
3406 	}
3407 
3408 	/* Inform PF to approve MAC as default VF MAC. */
3409 	if (BNXT_VF(softc))
3410 		bnxt_update_vf_mac(softc);
3411 
3412 	/* And now set the default CP / NQ ring for the async */
3413 	rc = bnxt_cfg_async_cr(softc);
3414 	if (rc)
3415 		goto fail;
3416 
3417 	/* Allocate the VNIC RSS context */
3418 	rc = bnxt_hwrm_vnic_ctx_alloc(softc, &softc->vnic_info.rss_id);
3419 	if (rc)
3420 		goto fail;
3421 
3422 	/* Allocate the vnic */
3423 	softc->vnic_info.def_ring_grp = softc->grp_info[0].grp_id;
3424 	softc->vnic_info.mru = softc->scctx->isc_max_frame_size;
3425 	rc = bnxt_hwrm_vnic_alloc(softc, &softc->vnic_info);
3426 	if (rc)
3427 		goto fail;
3428 	rc = bnxt_hwrm_vnic_cfg(softc, &softc->vnic_info);
3429 	if (rc)
3430 		goto fail;
3431 	rc = bnxt_hwrm_vnic_set_hds(softc, &softc->vnic_info);
3432 	if (rc)
3433 		goto fail;
3434 	rc = bnxt_hwrm_set_filter(softc);
3435 	if (rc)
3436 		goto fail;
3437 
3438 	bnxt_rss_grp_tbl_init(softc);
3439 
3440 	rc = bnxt_hwrm_rss_cfg(softc, &softc->vnic_info,
3441 	    softc->vnic_info.rss_hash_type);
3442 	if (rc)
3443 		goto fail;
3444 
3445 	rc = bnxt_hwrm_vnic_tpa_cfg(softc);
3446 	if (rc)
3447 		goto fail;
3448 
3449 	for (i = 0; i < softc->ntxqsets; i++) {
3450 		/* Allocate the statistics context */
3451 		rc = bnxt_hwrm_stat_ctx_alloc(softc, &softc->tx_cp_rings[i],
3452 		    softc->tx_stats[i].idi_paddr);
3453 		if (rc)
3454 			goto fail;
3455 
3456 		/* Allocate the completion ring */
3457 		softc->tx_cp_rings[i].cons = UINT32_MAX;
3458 		softc->tx_cp_rings[i].raw_cons = UINT32_MAX;
3459 		softc->tx_cp_rings[i].v_bit = 1;
3460 		softc->tx_cp_rings[i].toggle = 0;
3461 		bnxt_mark_cpr_invalid(&softc->tx_cp_rings[i]);
3462 		rc = bnxt_hwrm_ring_alloc(softc,
3463 				HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
3464 				&softc->tx_cp_rings[i].ring);
3465 		bnxt_set_db_mask(softc, &softc->tx_cp_rings[i].ring,
3466 				HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL);
3467 		if (rc)
3468 			goto fail;
3469 
3470 		if (BNXT_CHIP_P5_PLUS(softc))
3471 			softc->db_ops.bnxt_db_tx_cq(&softc->tx_cp_rings[i], 1);
3472 
3473 		/* Allocate the TX ring */
3474 		rc = bnxt_hwrm_ring_alloc(softc,
3475 				HWRM_RING_ALLOC_INPUT_RING_TYPE_TX,
3476 				&softc->tx_rings[i]);
3477 		bnxt_set_db_mask(softc, &softc->tx_rings[i],
3478 				HWRM_RING_ALLOC_INPUT_RING_TYPE_TX);
3479 		if (rc)
3480 			goto fail;
3481 		softc->db_ops.bnxt_db_tx(&softc->tx_rings[i], 0);
3482 	}
3483 
3484 	bnxt_do_enable_intr(&softc->def_cp_ring);
3485 	bnxt_get_port_module_status(softc);
3486 	bnxt_media_status(softc->ctx, &ifmr);
3487 	bnxt_hwrm_cfa_l2_set_rx_mask(softc, &softc->vnic_info);
3488 	return (0);
3489 
3490 fail:
3491 	bnxt_func_reset(softc);
3492 	bnxt_clear_ids(softc);
3493 	softc->is_dev_init = false;
3494 	return (rc);
3495 }
3496 
3497 static void
3498 bnxt_stop(if_ctx_t ctx)
3499 {
3500 	struct bnxt_softc *softc = iflib_get_softc(ctx);
3501 
3502 	softc->is_dev_init = false;
3503 	bnxt_do_disable_intr(&softc->def_cp_ring);
3504 	bnxt_func_reset(softc);
3505 	bnxt_clear_ids(softc);
3506 	return;
3507 }
3508 
3509 static void
3510 bnxt_if_led_func(if_ctx_t ctx, int onoff)
3511 {
3512 	struct bnxt_softc *softc = iflib_get_softc(ctx);
3513 	bool active;
3514 
3515 	active = onoff != 0;
3516 	if (active == softc->led_active)
3517 		return;
3518 	if (bnxt_hwrm_port_led_cfg(softc, active) == 0)
3519 		softc->led_active = active;
3520 }
3521 
3522 static void
3523 bnxt_led_restore(struct bnxt_softc *softc)
3524 {
3525 
3526 	if (!softc->led_active)
3527 		return;
3528 	if (bnxt_hwrm_port_led_cfg(softc, false) == 0)
3529 		softc->led_active = false;
3530 }
3531 
3532 static bool
3533 bnxt_if_led_supported(if_ctx_t ctx)
3534 {
3535 	struct bnxt_softc *softc = iflib_get_softc(ctx);
3536 
3537 	return (softc->num_leds != 0);
3538 }
3539 
3540 static u_int
3541 bnxt_copy_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt)
3542 {
3543 	uint8_t *mta = arg;
3544 
3545 	if (cnt == BNXT_MAX_MC_ADDRS)
3546 		return (1);
3547 
3548 	bcopy(LLADDR(sdl), &mta[cnt * ETHER_ADDR_LEN], ETHER_ADDR_LEN);
3549 
3550 	return (1);
3551 }
3552 
3553 static void
3554 bnxt_multi_set(if_ctx_t ctx)
3555 {
3556 	struct bnxt_softc *softc = iflib_get_softc(ctx);
3557 	if_t ifp = iflib_get_ifp(ctx);
3558 	uint8_t *mta;
3559 	int mcnt;
3560 
3561 	mta = softc->vnic_info.mc_list.idi_vaddr;
3562 	bzero(mta, softc->vnic_info.mc_list.idi_size);
3563 	mcnt = if_foreach_llmaddr(ifp, bnxt_copy_maddr, mta);
3564 
3565 	if (mcnt > BNXT_MAX_MC_ADDRS) {
3566 		softc->vnic_info.rx_mask |=
3567 		    HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ALL_MCAST;
3568 		bnxt_hwrm_cfa_l2_set_rx_mask(softc, &softc->vnic_info);
3569 	} else {
3570 		softc->vnic_info.rx_mask &=
3571 		    ~HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ALL_MCAST;
3572 		bus_dmamap_sync(softc->vnic_info.mc_list.idi_tag,
3573 		    softc->vnic_info.mc_list.idi_map, BUS_DMASYNC_PREWRITE);
3574 		softc->vnic_info.mc_list_count = mcnt;
3575 		softc->vnic_info.rx_mask |=
3576 		    HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_MCAST;
3577 		if (bnxt_hwrm_cfa_l2_set_rx_mask(softc, &softc->vnic_info))
3578 			device_printf(softc->dev,
3579 			    "set_multi: rx_mask set failed\n");
3580 	}
3581 }
3582 
3583 static int
3584 bnxt_mtu_set(if_ctx_t ctx, uint32_t mtu)
3585 {
3586 	struct bnxt_softc *softc = iflib_get_softc(ctx);
3587 
3588 	if (mtu > BNXT_MAX_MTU)
3589 		return EINVAL;
3590 
3591 	softc->scctx->isc_max_frame_size = mtu + ETHER_HDR_LEN + ETHER_CRC_LEN;
3592 	softc->rx_buf_size = min(softc->scctx->isc_max_frame_size, BNXT_PAGE_SIZE);
3593 	return 0;
3594 }
3595 
3596 static void
3597 bnxt_media_status(if_ctx_t ctx, struct ifmediareq * ifmr)
3598 {
3599 	struct bnxt_softc *softc = iflib_get_softc(ctx);
3600 	struct bnxt_link_info *link_info = &softc->link_info;
3601 	struct ifmedia_entry *next;
3602 	uint64_t target_baudrate = bnxt_get_baudrate(link_info);
3603 	int active_media = IFM_UNKNOWN;
3604 
3605 	bnxt_update_link(softc, true);
3606 
3607 	ifmr->ifm_status = IFM_AVALID;
3608 	ifmr->ifm_active = IFM_ETHER;
3609 
3610 	if (!link_info->link_up)
3611 		return;
3612 
3613 	ifmr->ifm_status |= IFM_ACTIVE;
3614 	if (link_info->duplex == HWRM_PORT_PHY_QCFG_OUTPUT_DUPLEX_CFG_FULL)
3615 		ifmr->ifm_active |= IFM_FDX;
3616 	else
3617 		ifmr->ifm_active |= IFM_HDX;
3618 
3619         /*
3620          * Go through the list of supported media which got prepared
3621          * as part of bnxt_add_media_types() using api ifmedia_add().
3622          */
3623 	LIST_FOREACH(next, &(iflib_get_media(ctx)->ifm_list), ifm_list) {
3624 		if (ifmedia_baudrate(next->ifm_media) == target_baudrate) {
3625 			active_media = next->ifm_media;
3626 			break;
3627 		}
3628 	}
3629 	ifmr->ifm_active |= active_media;
3630 
3631 	if (link_info->flow_ctrl.rx)
3632 		ifmr->ifm_active |= IFM_ETH_RXPAUSE;
3633 	if (link_info->flow_ctrl.tx)
3634 		ifmr->ifm_active |= IFM_ETH_TXPAUSE;
3635 
3636 	bnxt_report_link(softc);
3637 	return;
3638 }
3639 
3640 static int
3641 bnxt_media_change(if_ctx_t ctx)
3642 {
3643 	struct bnxt_softc *softc = iflib_get_softc(ctx);
3644 	struct ifmedia *ifm = iflib_get_media(ctx);
3645 	struct ifmediareq ifmr;
3646 	int rc;
3647 	struct bnxt_link_info *link_info = &softc->link_info;
3648 
3649 	if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
3650 		return EINVAL;
3651 
3652 	switch (IFM_SUBTYPE(ifm->ifm_media)) {
3653 	case IFM_100_T:
3654 		link_info->autoneg &= ~BNXT_AUTONEG_SPEED;
3655 		link_info->req_link_speed =
3656 		    HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_100MB;
3657 		break;
3658 	case IFM_1000_KX:
3659 	case IFM_1000_SGMII:
3660 	case IFM_1000_CX:
3661 	case IFM_1000_SX:
3662 	case IFM_1000_LX:
3663 
3664 		link_info->autoneg &= ~BNXT_AUTONEG_SPEED;
3665 
3666 		if (link_info->support_speeds & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_1GB) {
3667 			link_info->req_link_speed = HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_1GB;
3668 
3669 		} else if (link_info->support_speeds2 & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_1GB) {
3670 			link_info->req_link_speed = HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_1GB;
3671 			link_info->force_speed2_nrz = true;
3672 		}
3673 
3674 		break;
3675 
3676 	case IFM_2500_KX:
3677 	case IFM_2500_T:
3678 		link_info->autoneg &= ~BNXT_AUTONEG_SPEED;
3679 		link_info->req_link_speed =
3680 		    HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_2_5GB;
3681 		break;
3682 	case IFM_10G_CR1:
3683 	case IFM_10G_KR:
3684 	case IFM_10G_LR:
3685 	case IFM_10G_SR:
3686 
3687 		link_info->autoneg &= ~BNXT_AUTONEG_SPEED;
3688 
3689 		if (link_info->support_speeds & HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_10GB) {
3690 			link_info->req_link_speed = HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_10GB;
3691 
3692 		} else if (link_info->support_speeds2 & HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_10GB) {
3693 			link_info->req_link_speed = HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_10GB;
3694 			link_info->force_speed2_nrz = true;
3695 		}
3696 
3697 		break;
3698 	case IFM_20G_KR2:
3699 		link_info->autoneg &= ~BNXT_AUTONEG_SPEED;
3700 		link_info->req_link_speed =
3701 		    HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_20GB;
3702 		break;
3703 	case IFM_25G_CR:
3704 	case IFM_25G_KR:
3705 	case IFM_25G_SR:
3706 	case IFM_25G_LR:
3707 
3708 		link_info->autoneg &= ~BNXT_AUTONEG_SPEED;
3709 
3710 		if (link_info->support_speeds & HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_25GB) {
3711 			link_info->req_link_speed = HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_25GB;
3712 
3713 		} else if (link_info->support_speeds2 & HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_25GB) {
3714 			link_info->req_link_speed = HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_25GB;
3715 			link_info->force_speed2_nrz = true;
3716 		}
3717 
3718 		break;
3719 
3720 	case IFM_40G_CR4:
3721 	case IFM_40G_KR4:
3722 	case IFM_40G_LR4:
3723 	case IFM_40G_SR4:
3724 	case IFM_40G_XLAUI:
3725 	case IFM_40G_XLAUI_AC:
3726 
3727 		link_info->autoneg &= ~BNXT_AUTONEG_SPEED;
3728 
3729 		if (link_info->support_speeds & HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_40GB) {
3730 			link_info->req_link_speed = HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_40GB;
3731 
3732 		} else if (link_info->support_speeds2 & HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_40GB) {
3733 			link_info->req_link_speed = HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_40GB;
3734 			link_info->force_speed2_nrz = true;
3735 		}
3736 
3737 		break;
3738 
3739 	case IFM_50G_CR2:
3740 	case IFM_50G_KR2:
3741 	case IFM_50G_KR4:
3742 	case IFM_50G_SR2:
3743 	case IFM_50G_LR2:
3744 
3745 		link_info->autoneg &= ~BNXT_AUTONEG_SPEED;
3746 
3747 		if (link_info->support_speeds & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_50GB) {
3748 			link_info->req_link_speed = HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_50GB;
3749 
3750 		} else if (link_info->support_speeds2 & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_50GB) {
3751 			link_info->req_link_speed = HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_50GB;
3752 			link_info->force_speed2_nrz = true;
3753 		}
3754 
3755 		break;
3756 
3757 	case IFM_50G_CP:
3758 	case IFM_50G_LR:
3759 	case IFM_50G_SR:
3760 	case IFM_50G_KR_PAM4:
3761 
3762 		link_info->autoneg &= ~BNXT_AUTONEG_SPEED;
3763 
3764 		if (link_info->support_pam4_speeds & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_PAM4_SPEEDS_50G) {
3765 			link_info->req_link_speed = HWRM_PORT_PHY_CFG_INPUT_FORCE_PAM4_LINK_SPEED_50GB;
3766 			link_info->force_pam4_speed = true;
3767 
3768 		} else if (link_info->support_speeds2 & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_50GB_PAM4_56) {
3769 			link_info->req_link_speed = HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_50GB_PAM4_56;
3770 			link_info->force_pam4_56_speed2 = true;
3771 		}
3772 
3773 		break;
3774 
3775 	case IFM_100G_CR4:
3776 	case IFM_100G_KR4:
3777 	case IFM_100G_LR4:
3778 	case IFM_100G_SR4:
3779 	case IFM_100G_AUI4:
3780 
3781 		link_info->autoneg &= ~BNXT_AUTONEG_SPEED;
3782 
3783 		if (link_info->support_speeds & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_100GB) {
3784 			link_info->req_link_speed = HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_100GB;
3785 
3786 		} else if (link_info->support_speeds2 & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_100GB) {
3787 			link_info->req_link_speed = HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_100GB;
3788 			link_info->force_speed2_nrz = true;
3789 		}
3790 
3791 		break;
3792 
3793 	case IFM_100G_CP2:
3794 	case IFM_100G_SR2:
3795 	case IFM_100G_KR2_PAM4:
3796 	case IFM_100G_AUI2:
3797 
3798 		link_info->autoneg &= ~BNXT_AUTONEG_SPEED;
3799 
3800 		if (link_info->support_pam4_speeds & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_PAM4_SPEEDS_100G) {
3801 			link_info->req_link_speed = HWRM_PORT_PHY_CFG_INPUT_FORCE_PAM4_LINK_SPEED_100GB;
3802 			link_info->force_pam4_speed = true;
3803 
3804 		} else if (link_info->support_speeds2 & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_100GB_PAM4_56) {
3805 			link_info->req_link_speed = HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_100GB_PAM4_56;
3806 			link_info->force_pam4_56_speed2 = true;
3807 		}
3808 
3809 		break;
3810 
3811 	case IFM_100G_KR_PAM4:
3812 	case IFM_100G_CR_PAM4:
3813 	case IFM_100G_DR:
3814 	case IFM_100G_AUI2_AC:
3815 
3816 		link_info->autoneg &= ~BNXT_AUTONEG_SPEED;
3817 
3818 		if (link_info->support_speeds2 & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_100GB_PAM4_112) {
3819 			link_info->req_link_speed = HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_100GB_PAM4_112;
3820 			link_info->force_pam4_112_speed2 = true;
3821 		}
3822 
3823 		break;
3824 
3825 	case IFM_200G_SR4:
3826 	case IFM_200G_FR4:
3827 	case IFM_200G_LR4:
3828 	case IFM_200G_DR4:
3829 	case IFM_200G_CR4_PAM4:
3830 	case IFM_200G_KR4_PAM4:
3831 
3832 		link_info->autoneg &= ~BNXT_AUTONEG_SPEED;
3833 
3834 		if (link_info->support_pam4_speeds & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_PAM4_SPEEDS_200G) {
3835 			link_info->req_link_speed = HWRM_PORT_PHY_CFG_INPUT_FORCE_PAM4_LINK_SPEED_200GB;
3836 			link_info->force_pam4_speed = true;
3837 
3838 		} else if (link_info->support_speeds2 & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_200GB_PAM4_56) {
3839 			link_info->req_link_speed = HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_200GB_PAM4_56;
3840 			link_info->force_pam4_56_speed2 = true;
3841 		}
3842 
3843 		break;
3844 
3845 	case IFM_200G_AUI4:
3846 
3847 		link_info->autoneg &= ~BNXT_AUTONEG_SPEED;
3848 
3849 		if (link_info->support_speeds2 & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_200GB_PAM4_112) {
3850 			link_info->req_link_speed = HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_200GB_PAM4_112;
3851 			link_info->force_pam4_112_speed2 = true;
3852 		}
3853 
3854 		break;
3855 
3856 	case IFM_400G_FR8:
3857 	case IFM_400G_LR8:
3858 	case IFM_400G_AUI8:
3859 		link_info->autoneg &= ~BNXT_AUTONEG_SPEED;
3860 
3861 		if (link_info->support_speeds2 & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_400GB_PAM4_56) {
3862 			link_info->req_link_speed = HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_400GB_PAM4_56;
3863 			link_info->force_pam4_56_speed2 = true;
3864 		}
3865 
3866 		break;
3867 
3868 	case IFM_400G_AUI8_AC:
3869 	case IFM_400G_DR4:
3870 		link_info->autoneg &= ~BNXT_AUTONEG_SPEED;
3871 
3872 		if (link_info->support_speeds2 & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_400GB_PAM4_112) {
3873 			link_info->req_link_speed = HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_400GB_PAM4_112;
3874 			link_info->force_pam4_112_speed2 = true;
3875 		}
3876 
3877 		break;
3878 
3879 	case IFM_1000_T:
3880 		link_info->advertising = HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_1GB;
3881 		link_info->autoneg |= BNXT_AUTONEG_SPEED;
3882 		break;
3883 	case IFM_10G_T:
3884 		link_info->advertising = HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_10GB;
3885 		link_info->autoneg |= BNXT_AUTONEG_SPEED;
3886 		break;
3887 	default:
3888 		device_printf(softc->dev,
3889 		    "Unsupported media type!  Using auto\n");
3890 		/* Fall-through */
3891 	case IFM_AUTO:
3892 		// Auto
3893 		link_info->autoneg |= BNXT_AUTONEG_SPEED;
3894 		break;
3895 	}
3896 
3897 	rc = bnxt_hwrm_set_link_setting(softc, true, true, true);
3898 	bnxt_media_status(softc->ctx, &ifmr);
3899 	return rc;
3900 }
3901 
3902 static int
3903 bnxt_promisc_set(if_ctx_t ctx, int flags)
3904 {
3905 	struct bnxt_softc *softc = iflib_get_softc(ctx);
3906 	if_t ifp = iflib_get_ifp(ctx);
3907 	int rc;
3908 
3909 	if (if_getflags(ifp) & IFF_ALLMULTI ||
3910 	    if_llmaddr_count(ifp) > BNXT_MAX_MC_ADDRS)
3911 		softc->vnic_info.rx_mask |=
3912 		    HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ALL_MCAST;
3913 	else
3914 		softc->vnic_info.rx_mask &=
3915 		    ~HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ALL_MCAST;
3916 
3917 	if ((if_getflags(ifp) & IFF_PROMISC) &&
3918 	     bnxt_promisc_ok(softc))
3919 		softc->vnic_info.rx_mask |=
3920 		    HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_PROMISCUOUS |
3921 		    HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ANYVLAN_NONVLAN;
3922 	else
3923 		softc->vnic_info.rx_mask &=
3924 		    ~(HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_PROMISCUOUS |
3925 		    HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ANYVLAN_NONVLAN);
3926 
3927 	rc = bnxt_hwrm_cfa_l2_set_rx_mask(softc, &softc->vnic_info);
3928 
3929 	return rc;
3930 }
3931 
3932 static uint64_t
3933 bnxt_get_counter(if_ctx_t ctx, ift_counter cnt)
3934 {
3935 	if_t ifp = iflib_get_ifp(ctx);
3936 
3937 	if (cnt < IFCOUNTERS)
3938 		return if_get_counter_default(ifp, cnt);
3939 
3940 	return 0;
3941 }
3942 
3943 static void
3944 bnxt_update_admin_status(if_ctx_t ctx)
3945 {
3946 	struct bnxt_softc *softc = iflib_get_softc(ctx);
3947 
3948 	/*
3949 	 * When SR-IOV is enabled, avoid each VF sending this HWRM
3950 	 * request every sec with which firmware timeouts can happen
3951 	 */
3952 	if (!BNXT_PF(softc))
3953 		return;
3954 
3955 	bnxt_hwrm_port_qstats(softc);
3956 
3957 	if (BNXT_CHIP_P5_PLUS(softc) &&
3958 	    (softc->flags & BNXT_FLAG_FW_CAP_EXT_STATS))
3959 		bnxt_hwrm_port_qstats_ext(softc);
3960 
3961 	if (BNXT_CHIP_P5_PLUS(softc)) {
3962 		struct ifmediareq ifmr;
3963 
3964 		if (bit_test(softc->state_bv, BNXT_STATE_LINK_CHANGE)) {
3965 			bit_clear(softc->state_bv, BNXT_STATE_LINK_CHANGE);
3966 			bnxt_media_status(softc->ctx, &ifmr);
3967 		}
3968 	}
3969 
3970 	return;
3971 }
3972 
3973 static void
3974 bnxt_if_timer(if_ctx_t ctx, uint16_t qid)
3975 {
3976 
3977 	struct bnxt_softc *softc = iflib_get_softc(ctx);
3978 	uint64_t ticks_now = ticks;
3979 
3980         /* Schedule bnxt_update_admin_status() once per sec */
3981 	if (ticks_now - softc->admin_ticks >= hz) {
3982 		softc->admin_ticks = ticks_now;
3983 		iflib_admin_intr_deferred(ctx);
3984 	}
3985 
3986 	return;
3987 }
3988 
3989 static void inline
3990 bnxt_do_enable_intr(struct bnxt_cp_ring *cpr)
3991 {
3992 	struct bnxt_softc *softc = cpr->ring.softc;
3993 
3994 
3995 	if (cpr->ring.phys_id == (uint16_t)HWRM_NA_SIGNATURE)
3996 		return;
3997 
3998 	if (BNXT_CHIP_P5_PLUS(softc))
3999 		softc->db_ops.bnxt_db_nq(cpr, 1);
4000 	else
4001 		softc->db_ops.bnxt_db_rx_cq(cpr, 1);
4002 }
4003 
4004 static void inline
4005 bnxt_do_disable_intr(struct bnxt_cp_ring *cpr)
4006 {
4007 	struct bnxt_softc *softc = cpr->ring.softc;
4008 
4009 	if (cpr->ring.phys_id == (uint16_t)HWRM_NA_SIGNATURE)
4010 		return;
4011 
4012 	if (BNXT_CHIP_P5_PLUS(softc))
4013 		softc->db_ops.bnxt_db_nq(cpr, 0);
4014 	else
4015 		softc->db_ops.bnxt_db_rx_cq(cpr, 0);
4016 }
4017 
4018 /* Enable all interrupts */
4019 static void
4020 bnxt_intr_enable(if_ctx_t ctx)
4021 {
4022 	struct bnxt_softc *softc = iflib_get_softc(ctx);
4023 	int i;
4024 
4025 	bnxt_do_enable_intr(&softc->def_cp_ring);
4026 	for (i = 0; i < softc->nrxqsets; i++)
4027 		if (BNXT_CHIP_P5_PLUS(softc))
4028 			softc->db_ops.bnxt_db_nq(&softc->nq_rings[i], 1);
4029 		else
4030 			softc->db_ops.bnxt_db_rx_cq(&softc->rx_cp_rings[i], 1);
4031 
4032 	return;
4033 }
4034 
4035 /* Enable interrupt for a single queue */
4036 static int
4037 bnxt_tx_queue_intr_enable(if_ctx_t ctx, uint16_t qid)
4038 {
4039 	struct bnxt_softc *softc = iflib_get_softc(ctx);
4040 
4041 	if (BNXT_CHIP_P5_PLUS(softc))
4042 		softc->db_ops.bnxt_db_nq(&softc->nq_rings[qid], 1);
4043 	else
4044 		softc->db_ops.bnxt_db_rx_cq(&softc->tx_cp_rings[qid], 1);
4045 
4046 	return 0;
4047 }
4048 
4049 static void
4050 bnxt_process_cmd_cmpl(struct bnxt_softc *softc, hwrm_cmpl_t *cmd_cmpl)
4051 {
4052 	device_printf(softc->dev, "cmd sequence number %d\n",
4053 			cmd_cmpl->sequence_id);
4054 	return;
4055 }
4056 
4057 static void
4058 bnxt_process_async_msg(struct bnxt_cp_ring *cpr, tx_cmpl_t *cmpl)
4059 {
4060 	struct bnxt_softc *softc = cpr->ring.softc;
4061 	uint16_t type = cmpl->flags_type & TX_CMPL_TYPE_MASK;
4062 #ifdef PCI_IOV
4063 	struct hwrm_fwd_req_cmpl *fwd_req_cmpl = (struct hwrm_fwd_req_cmpl *)cmpl;
4064 	uint16_t vf_id;
4065 #endif
4066 
4067 	switch (type) {
4068 	case HWRM_CMPL_TYPE_HWRM_DONE:
4069 		bnxt_process_cmd_cmpl(softc, (hwrm_cmpl_t *)cmpl);
4070 		break;
4071 	case HWRM_ASYNC_EVENT_CMPL_TYPE_HWRM_ASYNC_EVENT:
4072 		bnxt_handle_async_event(softc, (cmpl_base_t *) cmpl);
4073 		break;
4074 #ifdef PCI_IOV
4075 	case CMPL_BASE_TYPE_HWRM_FWD_REQ:
4076 		vf_id = le16_to_cpu(fwd_req_cmpl->source_id);
4077 
4078 		if ((vf_id < softc->pf.first_vf_id) ||
4079 		    (vf_id >= softc->pf.first_vf_id + softc->pf.active_vfs))
4080 			return;
4081 
4082 		set_bit(vf_id - softc->pf.first_vf_id, softc->pf.vf_event_bmap);
4083 		set_bit(BNXT_HWRM_EXEC_FWD_REQ_SP_EVENT, &softc->sp_event);
4084 		bnxt_queue_sp_work(softc);
4085 		break;
4086 #endif
4087 	default:
4088 		device_printf(softc->dev, "%s:%d Unhandled async message %x\n",
4089 				__FUNCTION__, __LINE__, type);
4090 		break;
4091 	}
4092 }
4093 
4094 void
4095 process_nq(struct bnxt_softc *softc, uint16_t nqid)
4096 {
4097 	struct bnxt_cp_ring *cpr = &softc->nq_rings[nqid];
4098 	nq_cn_t *cmp = (nq_cn_t *) cpr->ring.vaddr;
4099 	struct bnxt_cp_ring *tx_cpr = &softc->tx_cp_rings[nqid];
4100 	struct bnxt_cp_ring *rx_cpr = &softc->rx_cp_rings[nqid];
4101 	bool v_bit = cpr->v_bit;
4102 	uint32_t cons = cpr->cons;
4103 	uint32_t raw_cons = cpr->raw_cons;
4104 	uint16_t nq_type, nqe_cnt = 0;
4105 
4106 	while (1) {
4107 		if (!NQ_VALID(&cmp[cons], v_bit)) {
4108 			goto done;
4109 		}
4110 
4111 		nq_type = NQ_CN_TYPE_MASK & cmp[cons].type;
4112 
4113 		if (NQE_CN_TYPE(nq_type) != NQ_CN_TYPE_CQ_NOTIFICATION) {
4114 			 bnxt_process_async_msg(cpr, (tx_cmpl_t *)&cmp[cons]);
4115 		} else {
4116 			tx_cpr->toggle = NQE_CN_TOGGLE(cmp[cons].type);
4117 			rx_cpr->toggle = NQE_CN_TOGGLE(cmp[cons].type);
4118 		}
4119 
4120 		NEXT_CP_CONS_V(&cpr->ring, cons, v_bit);
4121 		raw_cons++;
4122 		nqe_cnt++;
4123 	}
4124 done:
4125 	if (nqe_cnt) {
4126 		cpr->cons = cons;
4127 		cpr->raw_cons = raw_cons;
4128 		cpr->v_bit = v_bit;
4129 	}
4130 }
4131 
4132 static int
4133 bnxt_rx_queue_intr_enable(if_ctx_t ctx, uint16_t qid)
4134 {
4135 	struct bnxt_softc *softc = iflib_get_softc(ctx);
4136 
4137 	if (BNXT_CHIP_P5_PLUS(softc)) {
4138 		process_nq(softc, qid);
4139 		softc->db_ops.bnxt_db_nq(&softc->nq_rings[qid], 1);
4140 	}
4141 	softc->db_ops.bnxt_db_rx_cq(&softc->rx_cp_rings[qid], 1);
4142         return 0;
4143 }
4144 
4145 /* Disable all interrupts */
4146 static void
4147 bnxt_disable_intr(if_ctx_t ctx)
4148 {
4149 	struct bnxt_softc *softc = iflib_get_softc(ctx);
4150 	int i;
4151 
4152 	/*
4153 	 * NOTE: These TX interrupts should never get enabled, so don't
4154 	 * update the index
4155 	 */
4156 	for (i = 0; i < softc->nrxqsets; i++)
4157 		if (BNXT_CHIP_P5_PLUS(softc))
4158 			softc->db_ops.bnxt_db_nq(&softc->nq_rings[i], 0);
4159 		else
4160 			softc->db_ops.bnxt_db_rx_cq(&softc->rx_cp_rings[i], 0);
4161 
4162 
4163 	return;
4164 }
4165 
4166 static int
4167 bnxt_msix_intr_assign(if_ctx_t ctx, int msix)
4168 {
4169 	struct bnxt_softc *softc = iflib_get_softc(ctx);
4170 	struct bnxt_cp_ring *ring;
4171 	struct if_irq *irq;
4172 	uint16_t id;
4173 	int rc;
4174 	int i;
4175 	char irq_name[16];
4176 
4177 	if (BNXT_CHIP_P5_PLUS(softc))
4178 		goto skip_default_cp;
4179 
4180 	rc = iflib_irq_alloc_generic(ctx, &softc->def_cp_ring.irq,
4181 	    softc->def_cp_ring.ring.id + 1, IFLIB_INTR_ADMIN,
4182 	    bnxt_handle_def_cp, softc, 0, "def_cp");
4183 	if (rc) {
4184 		device_printf(iflib_get_dev(ctx),
4185 		    "Failed to register default completion ring handler\n");
4186 		return rc;
4187 	}
4188 
4189 skip_default_cp:
4190 	for (i=0; i<softc->scctx->isc_nrxqsets; i++) {
4191 		if (BNXT_CHIP_P5_PLUS(softc)) {
4192 			irq = &softc->nq_rings[i].irq;
4193 			id = softc->nq_rings[i].ring.id;
4194 			ring = &softc->nq_rings[i];
4195 		} else {
4196 			irq = &softc->rx_cp_rings[i].irq;
4197 			id = softc->rx_cp_rings[i].ring.id ;
4198 			ring = &softc->rx_cp_rings[i];
4199 		}
4200 		snprintf(irq_name, sizeof(irq_name), "rxq%d", i);
4201 		rc = iflib_irq_alloc_generic(ctx, irq, id + 1, IFLIB_INTR_RX,
4202 				bnxt_handle_isr, ring, i, irq_name);
4203 		if (rc) {
4204 			device_printf(iflib_get_dev(ctx),
4205 			    "Failed to register RX completion ring handler\n");
4206 			i--;
4207 			goto fail;
4208 		}
4209 	}
4210 
4211 	for (i=0; i<softc->scctx->isc_ntxqsets; i++)
4212 		iflib_softirq_alloc_generic(ctx, NULL, IFLIB_INTR_TX, NULL, i, "tx_cp");
4213 
4214 	return rc;
4215 
4216 fail:
4217 	for (; i>=0; i--)
4218 		iflib_irq_free(ctx, &softc->rx_cp_rings[i].irq);
4219 	iflib_irq_free(ctx, &softc->def_cp_ring.irq);
4220 	return rc;
4221 }
4222 
4223 /*
4224  * We're explicitly allowing duplicates here.  They will need to be
4225  * removed as many times as they are added.
4226  */
4227 static void
4228 bnxt_vlan_register(if_ctx_t ctx, uint16_t vtag)
4229 {
4230 	struct bnxt_softc *softc = iflib_get_softc(ctx);
4231 	struct bnxt_vlan_tag *new_tag;
4232 
4233 	new_tag = malloc(sizeof(struct bnxt_vlan_tag), M_DEVBUF, M_NOWAIT);
4234 	if (new_tag == NULL)
4235 		return;
4236 	new_tag->tag = vtag;
4237 	new_tag->filter_id = -1;
4238 	SLIST_INSERT_HEAD(&softc->vnic_info.vlan_tags, new_tag, next);
4239 };
4240 
4241 static void
4242 bnxt_vlan_unregister(if_ctx_t ctx, uint16_t vtag)
4243 {
4244 	struct bnxt_softc *softc = iflib_get_softc(ctx);
4245 	struct bnxt_vlan_tag *vlan_tag;
4246 
4247 	SLIST_FOREACH(vlan_tag, &softc->vnic_info.vlan_tags, next) {
4248 		if (vlan_tag->tag == vtag) {
4249 			SLIST_REMOVE(&softc->vnic_info.vlan_tags, vlan_tag,
4250 			    bnxt_vlan_tag, next);
4251 			free(vlan_tag, M_DEVBUF);
4252 			break;
4253 		}
4254 	}
4255 }
4256 
4257 static int
4258 bnxt_wol_config(if_ctx_t ctx)
4259 {
4260 	struct bnxt_softc *softc = iflib_get_softc(ctx);
4261 	if_t ifp = iflib_get_ifp(ctx);
4262 
4263 	if (!softc)
4264 		return -EBUSY;
4265 
4266 	if (!bnxt_wol_supported(softc))
4267 		return -ENOTSUP;
4268 
4269 	if (if_getcapenable(ifp) & IFCAP_WOL_MAGIC) {
4270 		if (!softc->wol) {
4271 			if (bnxt_hwrm_alloc_wol_fltr(softc))
4272 				return -EBUSY;
4273 			softc->wol = 1;
4274 		}
4275 	} else {
4276 		if (softc->wol) {
4277 			if (bnxt_hwrm_free_wol_fltr(softc))
4278 				return -EBUSY;
4279 			softc->wol = 0;
4280 		}
4281 	}
4282 
4283 	return 0;
4284 }
4285 
4286 static bool
4287 bnxt_if_needs_restart(if_ctx_t ctx __unused, enum iflib_restart_event event)
4288 {
4289 	switch (event) {
4290 	case IFLIB_RESTART_VLAN_CONFIG:
4291 	default:
4292 		return (false);
4293 	}
4294 }
4295 
4296 static int
4297 bnxt_shutdown(if_ctx_t ctx)
4298 {
4299 	bnxt_wol_config(ctx);
4300 	return 0;
4301 }
4302 
4303 static int
4304 bnxt_suspend(if_ctx_t ctx)
4305 {
4306 	bnxt_wol_config(ctx);
4307 	return 0;
4308 }
4309 
4310 static int
4311 bnxt_resume(if_ctx_t ctx)
4312 {
4313 	struct bnxt_softc *softc = iflib_get_softc(ctx);
4314 
4315 	bnxt_get_wol_settings(softc);
4316 	return 0;
4317 }
4318 
4319 static int
4320 bnxt_priv_ioctl(if_ctx_t ctx, u_long command, caddr_t data)
4321 {
4322 	struct bnxt_softc *softc = iflib_get_softc(ctx);
4323 	struct ifreq *ifr = (struct ifreq *)data;
4324 	struct bnxt_ioctl_header *ioh;
4325 	size_t iol;
4326 	int rc = ENOTSUP;
4327 	struct bnxt_ioctl_data iod_storage, *iod = &iod_storage;
4328 
4329 	switch (command) {
4330 	case SIOCGPRIVATE_0:
4331 		if ((rc = priv_check(curthread, PRIV_DRIVER)) != 0)
4332 			goto exit;
4333 
4334 		ioh = ifr_buffer_get_buffer(ifr);
4335 		iol = ifr_buffer_get_length(ifr);
4336 		if (iol > sizeof(iod_storage))
4337 			return (EINVAL);
4338 
4339 		if ((rc = copyin(ioh, iod, iol)) != 0)
4340 			goto exit;
4341 
4342 		switch (iod->hdr.type) {
4343 		case BNXT_HWRM_NVM_FIND_DIR_ENTRY:
4344 		{
4345 			struct bnxt_ioctl_hwrm_nvm_find_dir_entry *find =
4346 			    &iod->find;
4347 
4348 			rc = bnxt_hwrm_nvm_find_dir_entry(softc, find->type,
4349 			    &find->ordinal, find->ext, &find->index,
4350 			    find->use_index, find->search_opt,
4351 			    &find->data_length, &find->item_length,
4352 			    &find->fw_ver);
4353 			if (rc) {
4354 				iod->hdr.rc = rc;
4355 				rc = copyout(&iod->hdr.rc, &ioh->rc,
4356 				    sizeof(ioh->rc));
4357 			} else {
4358 				iod->hdr.rc = 0;
4359 				rc = copyout(iod, ioh, iol);
4360 			}
4361 
4362 			goto exit;
4363 		}
4364 		case BNXT_HWRM_NVM_READ:
4365 		{
4366 			struct bnxt_ioctl_hwrm_nvm_read *rd = &iod->read;
4367 			struct iflib_dma_info dma_data;
4368 			size_t offset;
4369 			size_t remain;
4370 			size_t csize;
4371 
4372 			/*
4373 			 * Some HWRM versions can't read more than 0x8000 bytes
4374 			 */
4375 			rc = iflib_dma_alloc(softc->ctx,
4376 			    min(rd->length, 0x8000), &dma_data, BUS_DMA_NOWAIT);
4377 			if (rc)
4378 				break;
4379 			for (remain = rd->length, offset = 0;
4380 			    remain && offset < rd->length; offset += 0x8000) {
4381 				csize = min(remain, 0x8000);
4382 				rc = bnxt_hwrm_nvm_read(softc, rd->index,
4383 				    rd->offset + offset, csize, &dma_data);
4384 				if (rc) {
4385 					iod->hdr.rc = rc;
4386 					rc = copyout(&iod->hdr.rc, &ioh->rc,
4387 					    sizeof(ioh->rc));
4388 					break;
4389 				} else {
4390 					rc = copyout(dma_data.idi_vaddr,
4391 					    rd->data + offset, csize);
4392 					iod->hdr.rc = rc;
4393 				}
4394 				remain -= csize;
4395 			}
4396 			if (rc == 0)
4397 				rc = copyout(iod, ioh, iol);
4398 
4399 			iflib_dma_free(&dma_data);
4400 			goto exit;
4401 		}
4402 		case BNXT_HWRM_FW_RESET:
4403 		{
4404 			struct bnxt_ioctl_hwrm_fw_reset *rst =
4405 			    &iod->reset;
4406 
4407 			rc = bnxt_hwrm_fw_reset(softc, rst->processor,
4408 			    &rst->selfreset);
4409 			if (rc) {
4410 				iod->hdr.rc = rc;
4411 				rc = copyout(&iod->hdr.rc, &ioh->rc,
4412 				    sizeof(ioh->rc));
4413 			} else {
4414 				iod->hdr.rc = 0;
4415 				rc = copyout(iod, ioh, iol);
4416 			}
4417 
4418 			goto exit;
4419 		}
4420 		case BNXT_HWRM_FW_QSTATUS:
4421 		{
4422 			struct bnxt_ioctl_hwrm_fw_qstatus *qstat =
4423 			    &iod->status;
4424 
4425 			rc = bnxt_hwrm_fw_qstatus(softc, qstat->processor,
4426 			    &qstat->selfreset);
4427 			if (rc) {
4428 				iod->hdr.rc = rc;
4429 				rc = copyout(&iod->hdr.rc, &ioh->rc,
4430 				    sizeof(ioh->rc));
4431 			} else {
4432 				iod->hdr.rc = 0;
4433 				rc = copyout(iod, ioh, iol);
4434 			}
4435 
4436 			goto exit;
4437 		}
4438 		case BNXT_HWRM_NVM_WRITE:
4439 		{
4440 			struct bnxt_ioctl_hwrm_nvm_write *wr =
4441 			    &iod->write;
4442 
4443 			rc = bnxt_hwrm_nvm_write(softc, wr->data, true,
4444 			    wr->type, wr->ordinal, wr->ext, wr->attr,
4445 			    wr->option, wr->data_length, wr->keep,
4446 			    &wr->item_length, &wr->index);
4447 			if (rc) {
4448 				iod->hdr.rc = rc;
4449 				rc = copyout(&iod->hdr.rc, &ioh->rc,
4450 				    sizeof(ioh->rc));
4451 			}
4452 			else {
4453 				iod->hdr.rc = 0;
4454 				rc = copyout(iod, ioh, iol);
4455 			}
4456 
4457 			goto exit;
4458 		}
4459 		case BNXT_HWRM_NVM_ERASE_DIR_ENTRY:
4460 		{
4461 			struct bnxt_ioctl_hwrm_nvm_erase_dir_entry *erase =
4462 			    &iod->erase;
4463 
4464 			rc = bnxt_hwrm_nvm_erase_dir_entry(softc, erase->index);
4465 			if (rc) {
4466 				iod->hdr.rc = rc;
4467 				rc = copyout(&iod->hdr.rc, &ioh->rc,
4468 				    sizeof(ioh->rc));
4469 			} else {
4470 				iod->hdr.rc = 0;
4471 				rc = copyout(iod, ioh, iol);
4472 			}
4473 
4474 			goto exit;
4475 		}
4476 		case BNXT_HWRM_NVM_GET_DIR_INFO:
4477 		{
4478 			struct bnxt_ioctl_hwrm_nvm_get_dir_info *info =
4479 			    &iod->dir_info;
4480 
4481 			rc = bnxt_hwrm_nvm_get_dir_info(softc, &info->entries,
4482 			    &info->entry_length);
4483 			if (rc) {
4484 				iod->hdr.rc = rc;
4485 				rc = copyout(&iod->hdr.rc, &ioh->rc,
4486 				    sizeof(ioh->rc));
4487 			} else {
4488 				iod->hdr.rc = 0;
4489 				rc = copyout(iod, ioh, iol);
4490 			}
4491 
4492 			goto exit;
4493 		}
4494 		case BNXT_HWRM_NVM_GET_DIR_ENTRIES:
4495 		{
4496 			struct bnxt_ioctl_hwrm_nvm_get_dir_entries *get =
4497 			    &iod->dir_entries;
4498 			struct iflib_dma_info dma_data;
4499 
4500 			rc = iflib_dma_alloc(softc->ctx, get->max_size,
4501 			    &dma_data, BUS_DMA_NOWAIT);
4502 			if (rc)
4503 				break;
4504 			rc = bnxt_hwrm_nvm_get_dir_entries(softc, &get->entries,
4505 			    &get->entry_length, &dma_data);
4506 			if (rc) {
4507 				iod->hdr.rc = rc;
4508 				rc = copyout(&iod->hdr.rc, &ioh->rc,
4509 				    sizeof(ioh->rc));
4510 			} else {
4511 				rc = copyout(dma_data.idi_vaddr, get->data,
4512 				    get->entry_length * get->entries);
4513 				iod->hdr.rc = rc;
4514 				if (rc == 0)
4515 					rc = copyout(iod, ioh, iol);
4516 			}
4517 			iflib_dma_free(&dma_data);
4518 
4519 			goto exit;
4520 		}
4521 		case BNXT_HWRM_NVM_VERIFY_UPDATE:
4522 		{
4523 			struct bnxt_ioctl_hwrm_nvm_verify_update *vrfy =
4524 			    &iod->verify;
4525 
4526 			rc = bnxt_hwrm_nvm_verify_update(softc, vrfy->type,
4527 			    vrfy->ordinal, vrfy->ext);
4528 			if (rc) {
4529 				iod->hdr.rc = rc;
4530 				rc = copyout(&iod->hdr.rc, &ioh->rc,
4531 				    sizeof(ioh->rc));
4532 			} else {
4533 				iod->hdr.rc = 0;
4534 				rc = copyout(iod, ioh, iol);
4535 			}
4536 
4537 			goto exit;
4538 		}
4539 		case BNXT_HWRM_NVM_INSTALL_UPDATE:
4540 		{
4541 			struct bnxt_ioctl_hwrm_nvm_install_update *inst =
4542 			    &iod->install;
4543 
4544 			rc = bnxt_hwrm_nvm_install_update(softc,
4545 			    inst->install_type, &inst->installed_items,
4546 			    &inst->result, &inst->problem_item,
4547 			    &inst->reset_required);
4548 			if (rc) {
4549 				iod->hdr.rc = rc;
4550 				rc = copyout(&iod->hdr.rc, &ioh->rc,
4551 				    sizeof(ioh->rc));
4552 			} else {
4553 				iod->hdr.rc = 0;
4554 				rc = copyout(iod, ioh, iol);
4555 			}
4556 
4557 			goto exit;
4558 		}
4559 		case BNXT_HWRM_NVM_MODIFY:
4560 		{
4561 			struct bnxt_ioctl_hwrm_nvm_modify *mod = &iod->modify;
4562 
4563 			rc = bnxt_hwrm_nvm_modify(softc, mod->index,
4564 			    mod->offset, mod->data, true, mod->length);
4565 			if (rc) {
4566 				iod->hdr.rc = rc;
4567 				rc = copyout(&iod->hdr.rc, &ioh->rc,
4568 				    sizeof(ioh->rc));
4569 			} else {
4570 				iod->hdr.rc = 0;
4571 				rc = copyout(iod, ioh, iol);
4572 			}
4573 
4574 			goto exit;
4575 		}
4576 		case BNXT_HWRM_FW_GET_TIME:
4577 		{
4578 			struct bnxt_ioctl_hwrm_fw_get_time *gtm =
4579 			    &iod->get_time;
4580 
4581 			rc = bnxt_hwrm_fw_get_time(softc, &gtm->year,
4582 			    &gtm->month, &gtm->day, &gtm->hour, &gtm->minute,
4583 			    &gtm->second, &gtm->millisecond, &gtm->zone);
4584 			if (rc) {
4585 				iod->hdr.rc = rc;
4586 				rc = copyout(&iod->hdr.rc, &ioh->rc,
4587 				    sizeof(ioh->rc));
4588 			} else {
4589 				iod->hdr.rc = 0;
4590 				rc = copyout(iod, ioh, iol);
4591 			}
4592 
4593 			goto exit;
4594 		}
4595 		case BNXT_HWRM_FW_SET_TIME:
4596 		{
4597 			struct bnxt_ioctl_hwrm_fw_set_time *stm =
4598 			    &iod->set_time;
4599 
4600 			rc = bnxt_hwrm_fw_set_time(softc, stm->year,
4601 			    stm->month, stm->day, stm->hour, stm->minute,
4602 			    stm->second, stm->millisecond, stm->zone);
4603 			if (rc) {
4604 				iod->hdr.rc = rc;
4605 				rc = copyout(&iod->hdr.rc, &ioh->rc,
4606 				    sizeof(ioh->rc));
4607 			} else {
4608 				iod->hdr.rc = 0;
4609 				rc = copyout(iod, ioh, iol);
4610 			}
4611 
4612 			goto exit;
4613 		}
4614 		}
4615 		break;
4616 	}
4617 
4618 exit:
4619 	return rc;
4620 }
4621 
4622 static int
4623 bnxt_i2c_req(if_ctx_t ctx, struct ifi2creq *i2c)
4624 {
4625 	struct bnxt_softc *softc = iflib_get_softc(ctx);
4626 	uint8_t *data = i2c->data;
4627 	int rc;
4628 
4629 	/* No point in going further if phy status indicates
4630 	 * module is not inserted or if it is powered down or
4631 	 * if it is of type 10GBase-T
4632 	 */
4633 	if (softc->link_info.module_status >
4634 		HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_WARNINGMSG)
4635 		return -EOPNOTSUPP;
4636 
4637 	/* This feature is not supported in older firmware versions */
4638 	if (!BNXT_CHIP_P5_PLUS(softc) ||
4639 	    (softc->hwrm_spec_code < 0x10202))
4640 		return -EOPNOTSUPP;
4641 
4642 
4643 	rc = bnxt_read_sfp_module_eeprom_info(softc, i2c->dev_addr, 0, 0, 0,
4644 		i2c->offset, i2c->len, data);
4645 
4646 	return rc;
4647 }
4648 
4649 /*
4650  * Support functions
4651  */
4652 static int
4653 bnxt_probe_phy(struct bnxt_softc *softc)
4654 {
4655 	struct bnxt_link_info *link_info = &softc->link_info;
4656 	int rc = 0;
4657 
4658 	softc->phy_flags = 0;
4659 	rc = bnxt_hwrm_phy_qcaps(softc);
4660 	if (rc) {
4661 		device_printf(softc->dev,
4662 			      "Probe phy can't get phy capabilities (rc: %x)\n", rc);
4663 		return rc;
4664 	}
4665 
4666 	rc = bnxt_update_link(softc, false);
4667 	if (rc) {
4668 		device_printf(softc->dev,
4669 		    "Probe phy can't update link (rc: %x)\n", rc);
4670 		return (rc);
4671 	}
4672 
4673 	bnxt_get_port_module_status(softc);
4674 
4675 	/*initialize the ethool setting copy with NVM settings */
4676 	if (link_info->auto_mode != HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_NONE)
4677 		link_info->autoneg |= BNXT_AUTONEG_SPEED;
4678 
4679 	link_info->req_duplex = link_info->duplex_setting;
4680 
4681 	/* NRZ link speed */
4682 	if (link_info->autoneg & BNXT_AUTONEG_SPEED)
4683 		link_info->req_link_speed = link_info->auto_link_speeds;
4684 	else
4685 		link_info->req_link_speed = link_info->force_link_speed;
4686 
4687 	/* PAM4 link speed */
4688 	if (link_info->auto_pam4_link_speeds)
4689 		link_info->req_link_speed = link_info->auto_pam4_link_speeds;
4690 	if (link_info->force_pam4_link_speed)
4691 		link_info->req_link_speed = link_info->force_pam4_link_speed;
4692 
4693 	return (rc);
4694 }
4695 
4696 static void
4697 add_media(struct bnxt_softc *softc, u8 media_type, u16 supported_NRZ_speeds,
4698 	  u16 supported_pam4_speeds, u16 supported_speeds2)
4699 {
4700 
4701 	switch (media_type) {
4702 		case BNXT_MEDIA_CR:
4703 
4704 			BNXT_IFMEDIA_ADD(supported_pam4_speeds, PAM4_SPEEDS_50G, IFM_50G_CP);
4705 			BNXT_IFMEDIA_ADD(supported_pam4_speeds, PAM4_SPEEDS_100G, IFM_100G_CP2);
4706 			BNXT_IFMEDIA_ADD(supported_pam4_speeds, PAM4_SPEEDS_200G, IFM_200G_CR4_PAM4);
4707 
4708 			BNXT_IFMEDIA_ADD(supported_NRZ_speeds, SPEEDS_100GB, IFM_100G_CR4);
4709 			BNXT_IFMEDIA_ADD(supported_NRZ_speeds, SPEEDS_50GB, IFM_50G_CR2);
4710 			BNXT_IFMEDIA_ADD(supported_NRZ_speeds, SPEEDS_40GB, IFM_40G_CR4);
4711 			BNXT_IFMEDIA_ADD(supported_NRZ_speeds, SPEEDS_25GB, IFM_25G_CR);
4712 			BNXT_IFMEDIA_ADD(supported_NRZ_speeds, SPEEDS_10GB, IFM_10G_CR1);
4713 			BNXT_IFMEDIA_ADD(supported_NRZ_speeds, SPEEDS_1GB, IFM_1000_CX);
4714 			/* thor2 nrz*/
4715 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_100GB, IFM_100G_CR4);
4716 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_50GB, IFM_50G_CR2);
4717 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_40GB, IFM_40G_CR4);
4718 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_25GB, IFM_25G_CR);
4719 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_10GB, IFM_10G_CR1);
4720 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_1GB, IFM_1000_CX);
4721 			/* thor2 PAM56 */
4722 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_50GB_PAM4_56, IFM_50G_CP);
4723 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_100GB_PAM4_56, IFM_100G_CP2);
4724 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_200GB_PAM4_56, IFM_200G_CR4_PAM4);
4725 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_400GB_PAM4_56, IFM_400G_AUI8);
4726 			/* thor2 PAM112 */
4727 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_100GB_PAM4_112, IFM_100G_CR_PAM4);
4728 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_200GB_PAM4_112, IFM_200G_AUI4);
4729 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_400GB_PAM4_112, IFM_400G_AUI8_AC);
4730 
4731 			break;
4732 
4733 		case BNXT_MEDIA_LR:
4734 			BNXT_IFMEDIA_ADD(supported_pam4_speeds, PAM4_SPEEDS_50G, IFM_50G_LR);
4735 			BNXT_IFMEDIA_ADD(supported_pam4_speeds, PAM4_SPEEDS_200G, IFM_200G_LR4);
4736 			BNXT_IFMEDIA_ADD(supported_NRZ_speeds, SPEEDS_100GB, IFM_100G_LR4);
4737 			BNXT_IFMEDIA_ADD(supported_NRZ_speeds, SPEEDS_50GB, IFM_50G_LR2);
4738 			BNXT_IFMEDIA_ADD(supported_NRZ_speeds, SPEEDS_40GB, IFM_40G_LR4);
4739 			BNXT_IFMEDIA_ADD(supported_NRZ_speeds, SPEEDS_25GB, IFM_25G_LR);
4740 			BNXT_IFMEDIA_ADD(supported_NRZ_speeds, SPEEDS_10GB, IFM_10G_LR);
4741 			/* thor2 nrz*/
4742 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_100GB, IFM_100G_LR4);
4743 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_50GB, IFM_50G_LR2);
4744 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_40GB, IFM_40G_LR4);
4745 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_25GB, IFM_25G_LR);
4746 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_10GB, IFM_10G_LR);
4747 			/* thor2 PAM56 */
4748 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_50GB_PAM4_56, IFM_50G_LR);
4749 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_100GB_PAM4_56, IFM_100G_AUI2);
4750 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_200GB_PAM4_56, IFM_200G_LR4);
4751 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_400GB_PAM4_56, IFM_400G_LR8);
4752 			/* thor2 PAM112 */
4753 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_100GB_PAM4_112, IFM_100G_AUI2_AC);
4754 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_200GB_PAM4_112, IFM_200G_AUI4);
4755 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_400GB_PAM4_112, IFM_400G_AUI8_AC);
4756 
4757 			break;
4758 
4759 		case BNXT_MEDIA_SR:
4760 			BNXT_IFMEDIA_ADD(supported_pam4_speeds, PAM4_SPEEDS_50G, IFM_50G_SR);
4761 			BNXT_IFMEDIA_ADD(supported_pam4_speeds, PAM4_SPEEDS_100G, IFM_100G_SR2);
4762 			BNXT_IFMEDIA_ADD(supported_pam4_speeds, PAM4_SPEEDS_200G, IFM_200G_SR4);
4763 			BNXT_IFMEDIA_ADD(supported_NRZ_speeds, SPEEDS_100GB, IFM_100G_SR4);
4764 			BNXT_IFMEDIA_ADD(supported_NRZ_speeds, SPEEDS_50GB, IFM_50G_SR2);
4765 			BNXT_IFMEDIA_ADD(supported_NRZ_speeds, SPEEDS_40GB, IFM_40G_SR4);
4766 			BNXT_IFMEDIA_ADD(supported_NRZ_speeds, SPEEDS_25GB, IFM_25G_SR);
4767 			BNXT_IFMEDIA_ADD(supported_NRZ_speeds, SPEEDS_10GB, IFM_10G_SR);
4768 			BNXT_IFMEDIA_ADD(supported_NRZ_speeds, SPEEDS_1GB, IFM_1000_SX);
4769 			/* thor2 nrz*/
4770 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_100GB, IFM_100G_SR4);
4771 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_50GB, IFM_50G_SR2);
4772 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_40GB, IFM_40G_SR4);
4773 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_25GB, IFM_25G_SR);
4774 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_10GB, IFM_10G_SR);
4775 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_1GB, IFM_1000_SX);
4776 			/* thor2 PAM56 */
4777 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_50GB_PAM4_56, IFM_50G_SR);
4778 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_100GB_PAM4_56, IFM_100G_SR2);
4779 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_200GB_PAM4_56, IFM_200G_SR4);
4780 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_400GB_PAM4_56, IFM_400G_AUI8);
4781 			/* thor2 PAM112 */
4782 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_100GB_PAM4_112, IFM_100G_AUI2_AC);
4783 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_200GB_PAM4_112, IFM_200G_AUI4);
4784 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_400GB_PAM4_112, IFM_400G_DR4);
4785 			break;
4786 
4787 		case BNXT_MEDIA_ER:
4788 			BNXT_IFMEDIA_ADD(supported_NRZ_speeds, SPEEDS_40GB, IFM_40G_ER4);
4789 			BNXT_IFMEDIA_ADD(supported_NRZ_speeds, SPEEDS_100GB, IFM_100G_AUI4);
4790 			/* thor2 PAM56 */
4791 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_50GB_PAM4_56, IFM_50G_LR);
4792 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_100GB_PAM4_56, IFM_100G_AUI2);
4793 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_200GB_PAM4_56, IFM_200G_LR4);
4794 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_400GB_PAM4_56, IFM_400G_FR8);
4795 			/* thor2 PAM112 */
4796 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_100GB_PAM4_112, IFM_100G_AUI2_AC);
4797 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_200GB_PAM4_112, IFM_200G_AUI4_AC);
4798 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_400GB_PAM4_112, IFM_400G_AUI8_AC);
4799 			break;
4800 
4801 		case BNXT_MEDIA_KR:
4802 			BNXT_IFMEDIA_ADD(supported_pam4_speeds, PAM4_SPEEDS_50G, IFM_50G_KR_PAM4);
4803 			BNXT_IFMEDIA_ADD(supported_pam4_speeds, PAM4_SPEEDS_100G, IFM_100G_KR2_PAM4);
4804 			BNXT_IFMEDIA_ADD(supported_pam4_speeds, PAM4_SPEEDS_200G, IFM_200G_KR4_PAM4);
4805 			BNXT_IFMEDIA_ADD(supported_NRZ_speeds, SPEEDS_100GB, IFM_100G_KR4);
4806 			BNXT_IFMEDIA_ADD(supported_NRZ_speeds, SPEEDS_50GB, IFM_50G_KR2);
4807 			BNXT_IFMEDIA_ADD(supported_NRZ_speeds, SPEEDS_50GB, IFM_50G_KR4);
4808 			BNXT_IFMEDIA_ADD(supported_NRZ_speeds, SPEEDS_40GB, IFM_40G_KR4);
4809 			BNXT_IFMEDIA_ADD(supported_NRZ_speeds, SPEEDS_25GB, IFM_25G_KR);
4810 			BNXT_IFMEDIA_ADD(supported_NRZ_speeds, SPEEDS_20GB, IFM_20G_KR2);
4811 			BNXT_IFMEDIA_ADD(supported_NRZ_speeds, SPEEDS_10GB, IFM_10G_KR);
4812 			BNXT_IFMEDIA_ADD(supported_NRZ_speeds, SPEEDS_1GB, IFM_1000_KX);
4813 			break;
4814 
4815 		case BNXT_MEDIA_AC:
4816 			BNXT_IFMEDIA_ADD(supported_NRZ_speeds, SPEEDS_25GB, IFM_25G_ACC);
4817 			BNXT_IFMEDIA_ADD(supported_NRZ_speeds, SPEEDS_10GB, IFM_10G_AOC);
4818 			BNXT_IFMEDIA_ADD(supported_NRZ_speeds, SPEEDS_40GB, IFM_40G_XLAUI);
4819 			BNXT_IFMEDIA_ADD(supported_NRZ_speeds, SPEEDS_40GB, IFM_40G_XLAUI_AC);
4820 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_25GB, IFM_25G_ACC);
4821 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_10GB, IFM_10G_AOC);
4822 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_40GB, IFM_40G_XLAUI);
4823 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_40GB, IFM_40G_XLAUI_AC);
4824 			break;
4825 
4826 		case BNXT_MEDIA_BASECX:
4827 			BNXT_IFMEDIA_ADD(supported_NRZ_speeds, SPEEDS_1GB, IFM_1000_CX);
4828 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_1GB, IFM_1000_CX);
4829 			break;
4830 
4831 		case BNXT_MEDIA_BASET:
4832 			BNXT_IFMEDIA_ADD(supported_NRZ_speeds, SPEEDS_10GB, IFM_10G_T);
4833 			BNXT_IFMEDIA_ADD(supported_NRZ_speeds, SPEEDS_2_5GB, IFM_2500_T);
4834 			BNXT_IFMEDIA_ADD(supported_NRZ_speeds, SPEEDS_1GB, IFM_1000_T);
4835 			BNXT_IFMEDIA_ADD(supported_NRZ_speeds, SPEEDS_100MB, IFM_100_T);
4836 			BNXT_IFMEDIA_ADD(supported_NRZ_speeds, SPEEDS_10MB, IFM_10_T);
4837 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_10GB, IFM_10G_T);
4838 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_1GB, IFM_1000_T);
4839 			break;
4840 
4841 		case BNXT_MEDIA_BASEKX:
4842 			BNXT_IFMEDIA_ADD(supported_NRZ_speeds, SPEEDS_10GB, IFM_10G_KR);
4843 			BNXT_IFMEDIA_ADD(supported_NRZ_speeds, SPEEDS_2_5GB, IFM_2500_KX);
4844 			BNXT_IFMEDIA_ADD(supported_NRZ_speeds, SPEEDS_1GB, IFM_1000_KX);
4845 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_10GB, IFM_10G_KR);
4846 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_1GB, IFM_1000_KX);
4847 			break;
4848 
4849 		case BNXT_MEDIA_BASESGMII:
4850 			BNXT_IFMEDIA_ADD(supported_NRZ_speeds, SPEEDS_1GB, IFM_1000_SGMII);
4851 			BNXT_IFMEDIA_ADD(supported_speeds2, SPEEDS2_1GB, IFM_1000_SGMII);
4852 			break;
4853 
4854 		default:
4855 			break;
4856 
4857 	}
4858 	return;
4859 
4860 }
4861 
4862 static void
4863 bnxt_add_media_types(struct bnxt_softc *softc)
4864 {
4865 	struct bnxt_link_info *link_info = &softc->link_info;
4866 	uint16_t supported_NRZ_speeds = 0, supported_pam4_speeds = 0, supported_speeds2 = 0;
4867 	uint8_t phy_type = get_phy_type(softc), media_type;
4868 
4869 	supported_NRZ_speeds = link_info->support_speeds;
4870 	supported_speeds2 = link_info->support_speeds2;
4871 	supported_pam4_speeds = link_info->support_pam4_speeds;
4872 
4873 	/* Auto is always supported */
4874 	ifmedia_add(softc->media, IFM_ETHER | IFM_AUTO, 0, NULL);
4875 
4876 	if (softc->flags & BNXT_FLAG_NPAR)
4877 		return;
4878 
4879 	switch (phy_type) {
4880 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASECR4:
4881 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_BASECR4:
4882 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_25G_BASECR_CA_L:
4883 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_25G_BASECR_CA_S:
4884 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_25G_BASECR_CA_N:
4885 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASECR:
4886 
4887 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_50G_BASECR:
4888 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASECR2:
4889 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_200G_BASECR4:
4890 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_400G_BASECR8:
4891 
4892 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASECR:
4893 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_200G_BASECR2:
4894 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_400G_BASECR4:
4895 
4896 		media_type = BNXT_MEDIA_CR;
4897 		break;
4898 
4899 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASELR4:
4900 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_BASELR4:
4901 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASELR:
4902 
4903 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_50G_BASELR:
4904 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASELR2:
4905 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_200G_BASELR4:
4906 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_400G_BASELR8:
4907 
4908 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASELR:
4909 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_200G_BASELR2:
4910 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_400G_BASELR4:
4911 
4912 		media_type = BNXT_MEDIA_LR;
4913 		break;
4914 
4915 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASESR10:
4916 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASESR4:
4917 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_BASESR4:
4918 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASESR:
4919 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_25G_BASESR:
4920 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_1G_BASESX:
4921 
4922 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_50G_BASESR:
4923 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASESR2:
4924 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_200G_BASESR4:
4925 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_400G_BASESR8:
4926 
4927 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASESR:
4928 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_200G_BASESR2:
4929 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_400G_BASESR4:
4930 
4931 		media_type = BNXT_MEDIA_SR;
4932 		break;
4933 
4934 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_BASEER4:
4935 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASEER4:
4936 
4937 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_50G_BASEER:
4938 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASEER2:
4939 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_200G_BASEER4:
4940 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_400G_BASEER8:
4941 
4942 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASEER:
4943 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_200G_BASEER2:
4944 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_400G_BASEER4:
4945 
4946 		media_type = BNXT_MEDIA_ER;
4947 		break;
4948 
4949 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR4:
4950 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR2:
4951 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR:
4952 		media_type = BNXT_MEDIA_KR;
4953 		break;
4954 
4955 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_ACTIVE_CABLE:
4956 		media_type = BNXT_MEDIA_AC;
4957 		break;
4958 
4959 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_1G_BASECX:
4960 		media_type = BNXT_MEDIA_BASECX;
4961 		break;
4962 
4963 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_1G_BASET:
4964 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASET:
4965 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASETE:
4966 		media_type = BNXT_MEDIA_BASET;
4967 		break;
4968 
4969 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKX:
4970 		media_type = BNXT_MEDIA_BASEKX;
4971 		break;
4972 
4973 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_SGMIIEXTPHY:
4974 		media_type = BNXT_MEDIA_BASESGMII;
4975 		break;
4976 
4977 	case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_UNKNOWN:
4978 		/* Only Autoneg is supported for TYPE_UNKNOWN */
4979 		break;
4980 
4981         default:
4982 		/* Only Autoneg is supported for new phy type values */
4983 		device_printf(softc->dev, "phy type %d not supported by driver\n", phy_type);
4984 		break;
4985 	}
4986 
4987 	switch (link_info->sig_mode) {
4988 	case BNXT_SIG_MODE_NRZ:
4989 		if (supported_NRZ_speeds != 0)
4990 			add_media(softc, media_type, supported_NRZ_speeds, 0, 0);
4991 		else
4992 			add_media(softc, media_type, 0, 0, supported_speeds2);
4993 		break;
4994 	case BNXT_SIG_MODE_PAM4:
4995 		if (supported_pam4_speeds != 0)
4996 			add_media(softc, media_type, 0, supported_pam4_speeds, 0);
4997 		else
4998 			add_media(softc, media_type, 0, 0, supported_speeds2);
4999 		break;
5000 	case BNXT_SIG_MODE_PAM4_112:
5001 		add_media(softc, media_type, 0, 0, supported_speeds2);
5002 		break;
5003 	}
5004 
5005 	return;
5006 }
5007 
5008 static int
5009 bnxt_map_bar(struct bnxt_softc *softc, struct bnxt_bar_info *bar, int bar_num, bool shareable)
5010 {
5011 	uint32_t	flag;
5012 
5013 	if (bar->res != NULL) {
5014 		device_printf(softc->dev, "Bar %d already mapped\n", bar_num);
5015 		return EDOOFUS;
5016 	}
5017 
5018 	bar->rid = PCIR_BAR(bar_num);
5019 	flag = RF_ACTIVE;
5020 	if (shareable)
5021 		flag |= RF_SHAREABLE;
5022 
5023 	if ((bar->res =
5024 		bus_alloc_resource_any(softc->dev,
5025 			   SYS_RES_MEMORY,
5026 			   &bar->rid,
5027 			   flag)) == NULL) {
5028 		device_printf(softc->dev,
5029 		    "PCI BAR%d mapping failure\n", bar_num);
5030 		return (ENXIO);
5031 	}
5032 	bar->tag = rman_get_bustag(bar->res);
5033 	bar->handle = rman_get_bushandle(bar->res);
5034 	bar->size = rman_get_size(bar->res);
5035 
5036 	return 0;
5037 }
5038 
5039 static int
5040 bnxt_pci_mapping(struct bnxt_softc *softc)
5041 {
5042 	int rc;
5043 
5044 	rc = bnxt_map_bar(softc, &softc->hwrm_bar, 0, true);
5045 	if (rc)
5046 		return rc;
5047 
5048 	rc = bnxt_map_bar(softc, &softc->doorbell_bar, 2, false);
5049 
5050 	return rc;
5051 }
5052 
5053 static void
5054 bnxt_pci_mapping_free(struct bnxt_softc *softc)
5055 {
5056 	if (softc->hwrm_bar.res != NULL)
5057 		bus_release_resource(softc->dev, SYS_RES_MEMORY,
5058 		    softc->hwrm_bar.rid, softc->hwrm_bar.res);
5059 	softc->hwrm_bar.res = NULL;
5060 
5061 	if (softc->doorbell_bar.res != NULL)
5062 		bus_release_resource(softc->dev, SYS_RES_MEMORY,
5063 		    softc->doorbell_bar.rid, softc->doorbell_bar.res);
5064 	softc->doorbell_bar.res = NULL;
5065 }
5066 
5067 static int
5068 bnxt_update_link(struct bnxt_softc *softc, bool chng_link_state)
5069 {
5070 	struct bnxt_link_info *link_info = &softc->link_info;
5071 	uint8_t link_up = link_info->link_up;
5072 	int rc = 0;
5073 
5074 	rc = bnxt_hwrm_port_phy_qcfg(softc);
5075 	if (rc)
5076 		goto exit;
5077 
5078 	/* TODO: need to add more logic to report VF link */
5079 	if (chng_link_state) {
5080 		if (link_info->phy_link_status ==
5081 		    HWRM_PORT_PHY_QCFG_OUTPUT_LINK_LINK)
5082 			link_info->link_up = 1;
5083 		else
5084 			link_info->link_up = 0;
5085 		if (link_up != link_info->link_up)
5086 			bnxt_report_link(softc);
5087 	} else {
5088 		/* always link down if not require to update link state */
5089 		link_info->link_up = 0;
5090 	}
5091 
5092 exit:
5093 	return rc;
5094 }
5095 
5096 #define ETHTOOL_SPEED_1000		1000
5097 #define ETHTOOL_SPEED_10000		10000
5098 #define ETHTOOL_SPEED_20000		20000
5099 #define ETHTOOL_SPEED_25000		25000
5100 #define ETHTOOL_SPEED_40000		40000
5101 #define ETHTOOL_SPEED_50000		50000
5102 #define ETHTOOL_SPEED_100000		100000
5103 #define ETHTOOL_SPEED_200000		200000
5104 #define ETHTOOL_SPEED_UNKNOWN		-1
5105 
5106 static u32
5107 bnxt_fw_to_ethtool_speed(u16 fw_link_speed)
5108 {
5109 	switch (fw_link_speed) {
5110 	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_1GB:
5111 		return ETHTOOL_SPEED_1000;
5112 	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_10GB:
5113 		return ETHTOOL_SPEED_10000;
5114 	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_20GB:
5115 		return ETHTOOL_SPEED_20000;
5116 	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_25GB:
5117 		return ETHTOOL_SPEED_25000;
5118 	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_40GB:
5119 		return ETHTOOL_SPEED_40000;
5120 	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_50GB:
5121 		return ETHTOOL_SPEED_50000;
5122 	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_100GB:
5123 		return ETHTOOL_SPEED_100000;
5124 	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_200GB:
5125 		return ETHTOOL_SPEED_200000;
5126 	default:
5127 		return ETHTOOL_SPEED_UNKNOWN;
5128 	}
5129 }
5130 
5131 void
5132 bnxt_report_link(struct bnxt_softc *softc)
5133 {
5134 	struct bnxt_link_info *link_info = &softc->link_info;
5135 	const char *duplex = NULL, *flow_ctrl = NULL;
5136 	const char *signal_mode = "";
5137 
5138 	if(softc->edev) {
5139 		softc->edev->espeed =
5140 		    bnxt_fw_to_ethtool_speed(link_info->link_speed);
5141 		softc->edev->lanes = link_info->active_lanes;
5142 	}
5143 
5144 	if (link_info->link_up == link_info->last_link_up) {
5145 		if (!link_info->link_up)
5146 			return;
5147 		if ((link_info->duplex == link_info->last_duplex) &&
5148 		    (link_info->phy_type == link_info->last_phy_type) &&
5149                     (!(BNXT_IS_FLOW_CTRL_CHANGED(link_info))))
5150 			return;
5151 	}
5152 
5153 	if (link_info->link_up) {
5154 		if (link_info->duplex ==
5155 		    HWRM_PORT_PHY_QCFG_OUTPUT_DUPLEX_CFG_FULL)
5156 			duplex = "full duplex";
5157 		else
5158 			duplex = "half duplex";
5159 		if (link_info->flow_ctrl.tx & link_info->flow_ctrl.rx)
5160 			flow_ctrl = "FC - receive & transmit";
5161 		else if (link_info->flow_ctrl.tx)
5162 			flow_ctrl = "FC - transmit";
5163 		else if (link_info->flow_ctrl.rx)
5164 			flow_ctrl = "FC - receive";
5165 		else
5166 			flow_ctrl = "FC - none";
5167 
5168 		if (softc->link_info.phy_qcfg_resp.option_flags &
5169 		    HWRM_PORT_PHY_QCFG_OUTPUT_OPTION_FLAGS_SIGNAL_MODE_KNOWN) {
5170 			uint8_t sig_mode = softc->link_info.active_fec_sig_mode &
5171 				      HWRM_PORT_PHY_QCFG_OUTPUT_SIGNAL_MODE_MASK;
5172 			switch (sig_mode) {
5173 			case BNXT_SIG_MODE_NRZ:
5174 				signal_mode = "(NRZ) ";
5175 				break;
5176 			case BNXT_SIG_MODE_PAM4:
5177 				signal_mode = "(PAM4 56Gbps) ";
5178 				break;
5179 			case BNXT_SIG_MODE_PAM4_112:
5180 				signal_mode = "(PAM4 112Gbps) ";
5181 				break;
5182 			default:
5183 				break;
5184 			}
5185 		link_info->sig_mode = sig_mode;
5186 		}
5187 
5188 		iflib_link_state_change(softc->ctx, LINK_STATE_UP,
5189 		    bnxt_get_baudrate(&softc->link_info));
5190 		device_printf(softc->dev, "Link is UP %s %s, %s - %d Mbps \n", duplex, signal_mode,
5191 		    flow_ctrl, (link_info->link_speed * 100));
5192 	} else {
5193 		iflib_link_state_change(softc->ctx, LINK_STATE_DOWN,
5194 		    bnxt_get_baudrate(&softc->link_info));
5195 		device_printf(softc->dev, "Link is Down\n");
5196 	}
5197 
5198 	link_info->last_link_up = link_info->link_up;
5199 	link_info->last_duplex = link_info->duplex;
5200 	link_info->last_phy_type = link_info->phy_type;
5201 	link_info->last_flow_ctrl.tx = link_info->flow_ctrl.tx;
5202 	link_info->last_flow_ctrl.rx = link_info->flow_ctrl.rx;
5203 	link_info->last_flow_ctrl.autoneg = link_info->flow_ctrl.autoneg;
5204 	/* update media types */
5205 	ifmedia_removeall(softc->media);
5206 	bnxt_add_media_types(softc);
5207 	ifmedia_set(softc->media, IFM_ETHER | IFM_AUTO);
5208 }
5209 
5210 static int
5211 bnxt_handle_isr(void *arg)
5212 {
5213 	struct bnxt_cp_ring *cpr = arg;
5214 	struct bnxt_softc *softc = cpr->ring.softc;
5215 
5216 	cpr->int_count++;
5217 	/* Disable further interrupts for this queue */
5218 	if (!BNXT_CHIP_P5_PLUS(softc))
5219 		softc->db_ops.bnxt_db_rx_cq(cpr, 0);
5220 
5221 	return FILTER_SCHEDULE_THREAD;
5222 }
5223 
5224 static int
5225 bnxt_handle_def_cp(void *arg)
5226 {
5227 	struct bnxt_softc *softc = arg;
5228 
5229 	softc->db_ops.bnxt_db_rx_cq(&softc->def_cp_ring, 0);
5230 	iflib_config_task_enqueue(softc->ctx, &softc->def_cp_task);
5231 	return FILTER_HANDLED;
5232 }
5233 
5234 static void
5235 bnxt_clear_ids(struct bnxt_softc *softc)
5236 {
5237 	int i;
5238 
5239 	softc->def_cp_ring.stats_ctx_id = HWRM_NA_SIGNATURE;
5240 	softc->def_cp_ring.ring.phys_id = (uint16_t)HWRM_NA_SIGNATURE;
5241 	softc->def_nq_ring.stats_ctx_id = HWRM_NA_SIGNATURE;
5242 	softc->def_nq_ring.ring.phys_id = (uint16_t)HWRM_NA_SIGNATURE;
5243 	for (i = 0; i < softc->ntxqsets; i++) {
5244 		softc->tx_cp_rings[i].stats_ctx_id = HWRM_NA_SIGNATURE;
5245 		softc->tx_cp_rings[i].ring.phys_id =
5246 		    (uint16_t)HWRM_NA_SIGNATURE;
5247 		softc->tx_rings[i].phys_id = (uint16_t)HWRM_NA_SIGNATURE;
5248 
5249 		if (!softc->nq_rings)
5250 			continue;
5251 		softc->nq_rings[i].stats_ctx_id = HWRM_NA_SIGNATURE;
5252 		softc->nq_rings[i].ring.phys_id = (uint16_t)HWRM_NA_SIGNATURE;
5253 	}
5254 	for (i = 0; i < softc->nrxqsets; i++) {
5255 		softc->rx_cp_rings[i].stats_ctx_id = HWRM_NA_SIGNATURE;
5256 		softc->rx_cp_rings[i].ring.phys_id =
5257 		    (uint16_t)HWRM_NA_SIGNATURE;
5258 		softc->rx_rings[i].phys_id = (uint16_t)HWRM_NA_SIGNATURE;
5259 		softc->ag_rings[i].phys_id = (uint16_t)HWRM_NA_SIGNATURE;
5260 		softc->grp_info[i].grp_id = (uint16_t)HWRM_NA_SIGNATURE;
5261 	}
5262 	softc->vnic_info.filter_id = -1;
5263 	softc->vnic_info.id = (uint16_t)HWRM_NA_SIGNATURE;
5264 	softc->vnic_info.rss_id = (uint16_t)HWRM_NA_SIGNATURE;
5265 	memset(softc->vnic_info.rss_grp_tbl.idi_vaddr, 0xff,
5266 	    softc->vnic_info.rss_grp_tbl.idi_size);
5267 }
5268 
5269 static void
5270 bnxt_mark_cpr_invalid(struct bnxt_cp_ring *cpr)
5271 {
5272 	struct cmpl_base *cmp = (void *)cpr->ring.vaddr;
5273 	int i;
5274 
5275 	for (i = 0; i < cpr->ring.ring_size; i++)
5276 		cmp[i].info3_v = !cpr->v_bit;
5277 }
5278 
5279 static void bnxt_event_error_report(struct bnxt_softc *softc, u32 data1, u32 data2)
5280 {
5281 	u32 err_type = BNXT_EVENT_ERROR_REPORT_TYPE(data1);
5282 
5283 	switch (err_type) {
5284 	case HWRM_ASYNC_EVENT_CMPL_ERROR_REPORT_BASE_EVENT_DATA1_ERROR_TYPE_INVALID_SIGNAL:
5285 		device_printf(softc->dev,
5286 			      "1PPS: Received invalid signal on pin%u from the external source. Please fix the signal and reconfigure the pin\n",
5287 			      BNXT_EVENT_INVALID_SIGNAL_DATA(data2));
5288 		break;
5289 	case HWRM_ASYNC_EVENT_CMPL_ERROR_REPORT_BASE_EVENT_DATA1_ERROR_TYPE_PAUSE_STORM:
5290 		device_printf(softc->dev,
5291 			      "Pause Storm detected!\n");
5292 		break;
5293 	case HWRM_ASYNC_EVENT_CMPL_ERROR_REPORT_BASE_EVENT_DATA1_ERROR_TYPE_DOORBELL_DROP_THRESHOLD:
5294 		device_printf(softc->dev,
5295 			      "One or more MMIO doorbells dropped by the device! epoch: 0x%x\n",
5296 			      BNXT_EVENT_DBR_EPOCH(data1));
5297 		break;
5298 	case HWRM_ASYNC_EVENT_CMPL_ERROR_REPORT_BASE_EVENT_DATA1_ERROR_TYPE_NVM: {
5299 		const char *nvm_err_str;
5300 
5301 		if (EVENT_DATA1_NVM_ERR_TYPE_WRITE(data1))
5302 			nvm_err_str = "nvm write error";
5303 		else if (EVENT_DATA1_NVM_ERR_TYPE_ERASE(data1))
5304 			nvm_err_str = "nvm erase error";
5305 		else
5306 			nvm_err_str = "unrecognized nvm error";
5307 
5308 		device_printf(softc->dev,
5309 			      "%s reported at address 0x%x\n", nvm_err_str,
5310 			      (u32)EVENT_DATA2_NVM_ERR_ADDR(data2));
5311 		break;
5312 	}
5313 	case HWRM_ASYNC_EVENT_CMPL_ERROR_REPORT_BASE_EVENT_DATA1_ERROR_TYPE_THERMAL_THRESHOLD: {
5314 		char *threshold_type;
5315 		char *dir_str;
5316 
5317 		switch (EVENT_DATA1_THERMAL_THRESHOLD_TYPE(data1)) {
5318 		case HWRM_ASYNC_EVENT_CMPL_ERROR_REPORT_THERMAL_EVENT_DATA1_THRESHOLD_TYPE_WARN:
5319 			threshold_type = "warning";
5320 			break;
5321 		case HWRM_ASYNC_EVENT_CMPL_ERROR_REPORT_THERMAL_EVENT_DATA1_THRESHOLD_TYPE_CRITICAL:
5322 			threshold_type = "critical";
5323 			break;
5324 		case HWRM_ASYNC_EVENT_CMPL_ERROR_REPORT_THERMAL_EVENT_DATA1_THRESHOLD_TYPE_FATAL:
5325 			threshold_type = "fatal";
5326 			break;
5327 		case HWRM_ASYNC_EVENT_CMPL_ERROR_REPORT_THERMAL_EVENT_DATA1_THRESHOLD_TYPE_SHUTDOWN:
5328 			threshold_type = "shutdown";
5329 			break;
5330 		default:
5331 			device_printf(softc->dev,
5332 				      "Unknown Thermal threshold type event\n");
5333 			return;
5334 		}
5335 		if (EVENT_DATA1_THERMAL_THRESHOLD_DIR_INCREASING(data1))
5336 			dir_str = "above";
5337 		else
5338 			dir_str = "below";
5339 		device_printf(softc->dev,
5340 			      "Chip temperature has gone %s the %s thermal threshold!\n",
5341 			      dir_str, threshold_type);
5342 		device_printf(softc->dev,
5343 			      "Temperature (In Celsius), Current: %u, threshold: %u\n",
5344 			      BNXT_EVENT_THERMAL_CURRENT_TEMP(data2),
5345 			      BNXT_EVENT_THERMAL_THRESHOLD_TEMP(data2));
5346 		break;
5347 	}
5348 	case HWRM_ASYNC_EVENT_CMPL_ERROR_REPORT_BASE_EVENT_DATA1_ERROR_TYPE_DUAL_DATA_RATE_NOT_SUPPORTED:
5349 		device_printf(softc->dev,
5350 			      "Speed change is not supported with dual rate transceivers on this board\n");
5351 		break;
5352 
5353 	default:
5354 	device_printf(softc->dev,
5355 		      "FW reported unknown error type: %u, data1: 0x%x data2: 0x%x\n",
5356 		      err_type, data1, data2);
5357 		break;
5358 	}
5359 }
5360 
5361 static void
5362 bnxt_handle_async_event(struct bnxt_softc *softc, struct cmpl_base *cmpl)
5363 {
5364 	struct hwrm_async_event_cmpl *ae = (void *)cmpl;
5365 	uint16_t async_id = le16toh(ae->event_id);
5366 	struct ifmediareq ifmr;
5367 	char *type_str;
5368 	char *status_desc;
5369 	struct bnxt_fw_health *fw_health;
5370 	u32 data1 = le32toh(ae->event_data1);
5371 	u32 data2 = le32toh(ae->event_data2);
5372 
5373 	switch (async_id) {
5374 	case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_STATUS_CHANGE:
5375 	case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CHANGE:
5376 	case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE:
5377 		if (BNXT_CHIP_P5_PLUS(softc))
5378 			bit_set(softc->state_bv, BNXT_STATE_LINK_CHANGE);
5379 		else
5380 			bnxt_media_status(softc->ctx, &ifmr);
5381 		break;
5382 	case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_ERROR_REPORT: {
5383 		bnxt_event_error_report(softc, data1, data2);
5384 		goto async_event_process_exit;
5385 	}
5386 	case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_DOORBELL_PACING_THRESHOLD:
5387 	case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_DOORBELL_PACING_NQ_UPDATE:
5388 		break;
5389 	case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_RESET_NOTIFY: {
5390 		type_str = "Solicited";
5391 
5392 		if (!softc->fw_health)
5393 			goto async_event_process_exit;
5394 
5395 		softc->fw_reset_timestamp = jiffies;
5396 		softc->fw_reset_min_dsecs = ae->timestamp_lo;
5397 		if (!softc->fw_reset_min_dsecs)
5398 			softc->fw_reset_min_dsecs = BNXT_DFLT_FW_RST_MIN_DSECS;
5399 		softc->fw_reset_max_dsecs = le16toh(ae->timestamp_hi);
5400 		if (!softc->fw_reset_max_dsecs)
5401 			softc->fw_reset_max_dsecs = BNXT_DFLT_FW_RST_MAX_DSECS;
5402 		if (EVENT_DATA1_RESET_NOTIFY_FW_ACTIVATION(data1)) {
5403 			set_bit(BNXT_STATE_FW_ACTIVATE_RESET, &softc->state);
5404 		} else if (EVENT_DATA1_RESET_NOTIFY_FATAL(data1)) {
5405 			type_str = "Fatal";
5406 			softc->fw_health->fatalities++;
5407 			set_bit(BNXT_STATE_FW_FATAL_COND, &softc->state);
5408 		} else if (data2 && BNXT_FW_STATUS_HEALTHY !=
5409 			   EVENT_DATA2_RESET_NOTIFY_FW_STATUS_CODE(data2)) {
5410 			type_str = "Non-fatal";
5411 			softc->fw_health->survivals++;
5412 			set_bit(BNXT_STATE_FW_NON_FATAL_COND, &softc->state);
5413 		}
5414 		device_printf(softc->dev,
5415 			   "%s firmware reset event, data1: 0x%x, data2: 0x%x, min wait %u ms, max wait %u ms\n",
5416 			   type_str, data1, data2,
5417 			   softc->fw_reset_min_dsecs * 100,
5418 			   softc->fw_reset_max_dsecs * 100);
5419 		set_bit(BNXT_FW_RESET_NOTIFY_SP_EVENT, &softc->sp_event);
5420 		break;
5421 	}
5422 	case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_ERROR_RECOVERY: {
5423 		fw_health = softc->fw_health;
5424 		status_desc = "healthy";
5425 		u32 status;
5426 
5427 		if (!fw_health)
5428 			goto async_event_process_exit;
5429 
5430 		if (!EVENT_DATA1_RECOVERY_ENABLED(data1)) {
5431 			fw_health->enabled = false;
5432 			device_printf(softc->dev, "Driver recovery watchdog is disabled\n");
5433 			break;
5434 		}
5435 		fw_health->primary = EVENT_DATA1_RECOVERY_MASTER_FUNC(data1);
5436 		fw_health->tmr_multiplier =
5437 			DIV_ROUND_UP(fw_health->polling_dsecs * HZ,
5438 				     HZ * 10);
5439 		fw_health->tmr_counter = fw_health->tmr_multiplier;
5440 		if (!fw_health->enabled)
5441 			fw_health->last_fw_heartbeat =
5442 				bnxt_fw_health_readl(softc, BNXT_FW_HEARTBEAT_REG);
5443 		fw_health->last_fw_reset_cnt =
5444 			bnxt_fw_health_readl(softc, BNXT_FW_RESET_CNT_REG);
5445 		status = bnxt_fw_health_readl(softc, BNXT_FW_HEALTH_REG);
5446 		if (status != BNXT_FW_STATUS_HEALTHY)
5447 			status_desc = "unhealthy";
5448 		device_printf(softc->dev,
5449 			   "Driver recovery watchdog, role: %s, firmware status: 0x%x (%s), resets: %u\n",
5450 			   fw_health->primary ? "primary" : "backup", status,
5451 			   status_desc, fw_health->last_fw_reset_cnt);
5452 		if (!fw_health->enabled) {
5453 			/* Make sure tmr_counter is set and seen by
5454 			 * bnxt_health_check() before setting enabled
5455 			 */
5456 			smp_mb();
5457 			fw_health->enabled = true;
5458 		}
5459 		goto async_event_process_exit;
5460 	}
5461 
5462 	case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_MTU_CHANGE:
5463 	case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_DCB_CONFIG_CHANGE:
5464 	case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PORT_CONN_NOT_ALLOWED:
5465 	case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_NOT_ALLOWED:
5466 	case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_FUNC_DRVR_UNLOAD:
5467 	case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_FUNC_DRVR_LOAD:
5468 	case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_DRVR_UNLOAD:
5469 	case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_DRVR_LOAD:
5470 	case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_FLR:
5471 	case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_MAC_ADDR_CHANGE:
5472 	case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_VF_COMM_STATUS_CHANGE:
5473 	case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_CFG_CHANGE:
5474 	case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_HWRM_ERROR:
5475 		device_printf(softc->dev,
5476 		    "Unhandled async completion type %u\n", async_id);
5477 		break;
5478 	default:
5479 		dev_dbg(softc->dev, "Unknown Async event completion type %u\n",
5480 			async_id);
5481 		break;
5482 	}
5483 	bnxt_queue_sp_work(softc);
5484 
5485 async_event_process_exit:
5486 	bnxt_ulp_async_events(softc, ae);
5487 }
5488 
5489 static void
5490 bnxt_def_cp_task(void *context, int pending)
5491 {
5492 	if_ctx_t ctx = context;
5493 	struct bnxt_softc *softc = iflib_get_softc(ctx);
5494 	struct bnxt_cp_ring *cpr = &softc->def_cp_ring;
5495 
5496 	/* Handle completions on the default completion ring */
5497 	struct cmpl_base *cmpl;
5498 	uint32_t cons;
5499 	bool v_bit;
5500 	bool last_v_bit;
5501 	uint32_t last_cons;
5502 	uint16_t type;
5503 
5504 	if (iflib_in_detach(ctx))
5505 		return;
5506 	cons = cpr->cons;
5507 	v_bit = cpr->v_bit;
5508 
5509 	for (;;) {
5510 		last_cons = cons;
5511 		last_v_bit = v_bit;
5512 		NEXT_CP_CONS_V(&cpr->ring, cons, v_bit);
5513 		cmpl = &((struct cmpl_base *)cpr->ring.vaddr)[cons];
5514 
5515 		if (!CMP_VALID(cmpl, v_bit))
5516 			break;
5517 
5518 		type = le16toh(cmpl->type) & CMPL_BASE_TYPE_MASK;
5519 		switch (type) {
5520 		case CMPL_BASE_TYPE_HWRM_ASYNC_EVENT:
5521 			bnxt_handle_async_event(softc, cmpl);
5522 			break;
5523 		case CMPL_BASE_TYPE_TX_L2:
5524 		case CMPL_BASE_TYPE_RX_L2:
5525 		case CMPL_BASE_TYPE_RX_L2_V3:
5526 		case CMPL_BASE_TYPE_RX_AGG:
5527 		case CMPL_BASE_TYPE_RX_TPA_START:
5528 		case CMPL_BASE_TYPE_RX_TPA_START_V3:
5529 		case CMPL_BASE_TYPE_RX_TPA_END:
5530 		case CMPL_BASE_TYPE_STAT_EJECT:
5531 		case CMPL_BASE_TYPE_HWRM_DONE:
5532 		case CMPL_BASE_TYPE_HWRM_FWD_REQ:
5533 		case CMPL_BASE_TYPE_HWRM_FWD_RESP:
5534 		case CMPL_BASE_TYPE_CQ_NOTIFICATION:
5535 		case CMPL_BASE_TYPE_SRQ_EVENT:
5536 		case CMPL_BASE_TYPE_DBQ_EVENT:
5537 		case CMPL_BASE_TYPE_QP_EVENT:
5538 		case CMPL_BASE_TYPE_FUNC_EVENT:
5539 			dev_dbg(softc->dev, "Unhandled Async event completion type %u\n",
5540 				type);
5541 			break;
5542 		default:
5543 			dev_dbg(softc->dev, "Unknown Async event completion type %u\n",
5544 				type);
5545 			break;
5546 		}
5547 	}
5548 
5549 	cpr->cons = last_cons;
5550 	cpr->v_bit = last_v_bit;
5551 	softc->db_ops.bnxt_db_rx_cq(cpr, 1);
5552 }
5553 
5554 uint8_t
5555 get_phy_type(struct bnxt_softc *softc)
5556 {
5557 	struct bnxt_link_info *link_info = &softc->link_info;
5558 	uint8_t phy_type = link_info->phy_type;
5559 	uint16_t supported;
5560 
5561 	if (phy_type != HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_UNKNOWN)
5562 		return phy_type;
5563 
5564 	/* Deduce the phy type from the media type and supported speeds */
5565 	supported = link_info->support_speeds;
5566 
5567 	if (link_info->media_type ==
5568 	    HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_TP)
5569 		return HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASET;
5570 	if (link_info->media_type ==
5571 	    HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_DAC) {
5572 		if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_2_5GB)
5573 			return HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKX;
5574 		if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_20GB)
5575 			return HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR;
5576 		return HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASECR;
5577 	}
5578 	if (link_info->media_type ==
5579 	    HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_FIBRE)
5580 		return HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASESR;
5581 
5582 	return phy_type;
5583 }
5584 
5585 bool
5586 bnxt_check_hwrm_version(struct bnxt_softc *softc)
5587 {
5588 	char buf[16];
5589 
5590 	sprintf(buf, "%hhu.%hhu.%hhu", softc->ver_info->hwrm_min_major,
5591 	    softc->ver_info->hwrm_min_minor, softc->ver_info->hwrm_min_update);
5592 	if (softc->ver_info->hwrm_min_major > softc->ver_info->hwrm_if_major) {
5593 		device_printf(softc->dev,
5594 		    "WARNING: HWRM version %s is too old (older than %s)\n",
5595 		    softc->ver_info->hwrm_if_ver, buf);
5596 		return false;
5597 	}
5598 	else if(softc->ver_info->hwrm_min_major ==
5599 	    softc->ver_info->hwrm_if_major) {
5600 		if (softc->ver_info->hwrm_min_minor >
5601 		    softc->ver_info->hwrm_if_minor) {
5602 			device_printf(softc->dev,
5603 			    "WARNING: HWRM version %s is too old (older than %s)\n",
5604 			    softc->ver_info->hwrm_if_ver, buf);
5605 			return false;
5606 		}
5607 		else if (softc->ver_info->hwrm_min_minor ==
5608 		    softc->ver_info->hwrm_if_minor) {
5609 			if (softc->ver_info->hwrm_min_update >
5610 			    softc->ver_info->hwrm_if_update) {
5611 				device_printf(softc->dev,
5612 				    "WARNING: HWRM version %s is too old (older than %s)\n",
5613 				    softc->ver_info->hwrm_if_ver, buf);
5614 				return false;
5615 			}
5616 		}
5617 	}
5618 	return true;
5619 }
5620 
5621 static uint64_t
5622 bnxt_get_baudrate(struct bnxt_link_info *link)
5623 {
5624 	switch (link->link_speed) {
5625 	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_100MB:
5626 		return IF_Mbps(100);
5627 	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_1GB:
5628 		return IF_Gbps(1);
5629 	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2GB:
5630 		return IF_Gbps(2);
5631 	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2_5GB:
5632 		return IF_Mbps(2500);
5633 	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_10GB:
5634 		return IF_Gbps(10);
5635 	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_20GB:
5636 		return IF_Gbps(20);
5637 	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_25GB:
5638 		return IF_Gbps(25);
5639 	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_40GB:
5640 		return IF_Gbps(40);
5641 	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_50GB:
5642 		return IF_Gbps(50);
5643 	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_100GB:
5644 		return IF_Gbps(100);
5645 	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_10MB:
5646 		return IF_Mbps(10);
5647 	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_200GB:
5648 		return IF_Gbps(200);
5649 	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_400GB:
5650 		return IF_Gbps(400);
5651 	}
5652 	return IF_Gbps(100);
5653 }
5654 
5655 static void
5656 bnxt_get_wol_settings(struct bnxt_softc *softc)
5657 {
5658 	uint16_t wol_handle = 0;
5659 
5660 	if (!bnxt_wol_supported(softc))
5661 		return;
5662 
5663 	do {
5664 		wol_handle = bnxt_hwrm_get_wol_fltrs(softc, wol_handle);
5665 	} while (wol_handle && wol_handle != BNXT_NO_MORE_WOL_FILTERS);
5666 }
5667