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