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