Bug Summary

File:dev/pci/if_bnxt.c
Warning:line 2302, column 2
Value stored to 'last' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name if_bnxt.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -ffreestanding -mcmodel=kernel -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -target-feature -sse2 -target-feature -sse -target-feature -3dnow -target-feature -mmx -target-feature +save-args -disable-red-zone -no-implicit-float -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -nostdsysteminc -nobuiltininc -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/sys -I /usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -I /usr/src/sys/arch -I /usr/src/sys/dev/pci/drm/include -I /usr/src/sys/dev/pci/drm/include/uapi -I /usr/src/sys/dev/pci/drm/amd/include/asic_reg -I /usr/src/sys/dev/pci/drm/amd/include -I /usr/src/sys/dev/pci/drm/amd/amdgpu -I /usr/src/sys/dev/pci/drm/amd/display -I /usr/src/sys/dev/pci/drm/amd/display/include -I /usr/src/sys/dev/pci/drm/amd/display/dc -I /usr/src/sys/dev/pci/drm/amd/display/amdgpu_dm -I /usr/src/sys/dev/pci/drm/amd/pm/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu11 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu12 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/hwmgr -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/smumgr -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc/hw -I /usr/src/sys/dev/pci/drm/amd/display/dc/clk_mgr -I /usr/src/sys/dev/pci/drm/amd/display/modules/inc -I /usr/src/sys/dev/pci/drm/amd/display/modules/hdcp -I /usr/src/sys/dev/pci/drm/amd/display/dmub/inc -I /usr/src/sys/dev/pci/drm/i915 -D DDB -D DIAGNOSTIC -D KTRACE -D ACCOUNTING -D KMEMSTATS -D PTRACE -D POOL_DEBUG -D CRYPTO -D SYSVMSG -D SYSVSEM -D SYSVSHM -D UVM_SWAP_ENCRYPT -D FFS -D FFS2 -D FFS_SOFTUPDATES -D UFS_DIRHASH -D QUOTA -D EXT2FS -D MFS -D NFSCLIENT -D NFSSERVER -D CD9660 -D UDF -D MSDOSFS -D FIFO -D FUSE -D SOCKET_SPLICE -D TCP_ECN -D TCP_SIGNATURE -D INET6 -D IPSEC -D PPP_BSDCOMP -D PPP_DEFLATE -D PIPEX -D MROUTING -D MPLS -D BOOT_CONFIG -D USER_PCICONF -D APERTURE -D MTRR -D NTFS -D HIBERNATE -D PCIVERBOSE -D USBVERBOSE -D WSDISPLAY_COMPAT_USL -D WSDISPLAY_COMPAT_RAWKBD -D WSDISPLAY_DEFAULTSCREENS=6 -D X86EMU -D ONEWIREVERBOSE -D MULTIPROCESSOR -D MAXUSERS=80 -D _KERNEL -D CONFIG_DRM_AMD_DC_DCN3_0 -O2 -Wno-pointer-sign -Wno-address-of-packed-member -Wno-constant-conversion -Wno-unused-but-set-variable -Wno-gnu-folding-constant -fdebug-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -o /usr/obj/sys/arch/amd64/compile/GENERIC.MP/scan-build/2022-01-12-131800-47421-1 -x c /usr/src/sys/dev/pci/if_bnxt.c
1/* $OpenBSD: if_bnxt.c,v 1.34 2021/07/24 05:49:59 jmatthew Exp $ */
2/*-
3 * Broadcom NetXtreme-C/E network driver.
4 *
5 * Copyright (c) 2016 Broadcom, All Rights Reserved.
6 * The term Broadcom refers to Broadcom Limited and/or its subsidiaries
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27 * THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/*
31 * Copyright (c) 2018 Jonathan Matthew <jmatthew@openbsd.org>
32 *
33 * Permission to use, copy, modify, and distribute this software for any
34 * purpose with or without fee is hereby granted, provided that the above
35 * copyright notice and this permission notice appear in all copies.
36 *
37 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
38 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
39 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
40 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
41 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
42 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
43 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
44 */
45
46
47#include "bpfilter.h"
48#include "vlan.h"
49
50#include <sys/param.h>
51#include <sys/systm.h>
52#include <sys/mbuf.h>
53#include <sys/kernel.h>
54#include <sys/malloc.h>
55#include <sys/device.h>
56#include <sys/stdint.h>
57#include <sys/sockio.h>
58#include <sys/atomic.h>
59#include <sys/intrmap.h>
60
61#include <machine/bus.h>
62
63#include <dev/pci/pcireg.h>
64#include <dev/pci/pcivar.h>
65#include <dev/pci/pcidevs.h>
66
67#include <dev/pci/if_bnxtreg.h>
68
69#include <net/if.h>
70#include <net/if_media.h>
71#include <net/toeplitz.h>
72
73#if NBPFILTER1 > 0
74#include <net/bpf.h>
75#endif
76
77#include <netinet/in.h>
78#include <netinet/if_ether.h>
79
80#define BNXT_HWRM_BAR0x10 0x10
81#define BNXT_DOORBELL_BAR0x18 0x18
82
83#define BNXT_MAX_QUEUES8 8
84
85#define BNXT_CP_RING_ID_BASE0 0
86#define BNXT_RX_RING_ID_BASE(8 + 1) (BNXT_MAX_QUEUES8 + 1)
87#define BNXT_AG_RING_ID_BASE((8 * 2) + 1) ((BNXT_MAX_QUEUES8 * 2) + 1)
88#define BNXT_TX_RING_ID_BASE((8 * 3) + 1) ((BNXT_MAX_QUEUES8 * 3) + 1)
89
90#define BNXT_MAX_MTU9500 9500
91#define BNXT_AG_BUFFER_SIZE8192 8192
92
93#define BNXT_CP_PAGES4 4
94
95#define BNXT_MAX_TX_SEGS32 32 /* a bit much? */
96#define BNXT_TX_SLOTS(bs)(bs->bs_map->dm_nsegs + 1) (bs->bs_map->dm_nsegs + 1)
97
98#define BNXT_HWRM_SHORT_REQ_LENsizeof(struct hwrm_short_input) sizeof(struct hwrm_short_input)
99
100#define BNXT_HWRM_LOCK_INIT(_sc, _name)do { (void)(_name); (void)(0); __mtx_init((&sc->sc_lock
), ((((0x7)) > 0x0 && ((0x7)) < 0x9) ? 0x9 : ((
0x7)))); } while (0)
\
101 mtx_init_flags(&sc->sc_lock, IPL_NET, _name, 0)do { (void)(_name); (void)(0); __mtx_init((&sc->sc_lock
), ((((0x7)) > 0x0 && ((0x7)) < 0x9) ? 0x9 : ((
0x7)))); } while (0)
102#define BNXT_HWRM_LOCK(_sc)mtx_enter(&_sc->sc_lock) mtx_enter(&_sc->sc_lock)
103#define BNXT_HWRM_UNLOCK(_sc)mtx_leave(&_sc->sc_lock) mtx_leave(&_sc->sc_lock)
104#define BNXT_HWRM_LOCK_DESTROY(_sc) /* nothing */
105#define BNXT_HWRM_LOCK_ASSERT(_sc)do { if (((&_sc->sc_lock)->mtx_owner != ({struct cpu_info
*__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof
(struct cpu_info, ci_self))); __ci;})) && !(panicstr ||
db_active)) panic("mutex %p not held in %s", (&_sc->sc_lock
), __func__); } while (0)
MUTEX_ASSERT_LOCKED(&_sc->sc_lock)do { if (((&_sc->sc_lock)->mtx_owner != ({struct cpu_info
*__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof
(struct cpu_info, ci_self))); __ci;})) && !(panicstr ||
db_active)) panic("mutex %p not held in %s", (&_sc->sc_lock
), __func__); } while (0)
106
107#define BNXT_FLAG_VF0x0001 0x0001
108#define BNXT_FLAG_NPAR0x0002 0x0002
109#define BNXT_FLAG_WOL_CAP0x0004 0x0004
110#define BNXT_FLAG_SHORT_CMD0x0008 0x0008
111#define BNXT_FLAG_MSIX0x0010 0x0010
112
113/* NVRam stuff has a five minute timeout */
114#define BNXT_NVM_TIMEO(5 * 60 * 1000) (5 * 60 * 1000)
115
116#define NEXT_CP_CONS_V(_ring, _cons, _v_bit)do { if (++(_cons) == (_ring)->ring_size) ((_cons) = 0, (_v_bit
) = !_v_bit); } while (0);
\
117do { \
118 if (++(_cons) == (_ring)->ring_size) \
119 ((_cons) = 0, (_v_bit) = !_v_bit); \
120} while (0);
121
122struct bnxt_ring {
123 uint64_t paddr;
124 uint64_t doorbell;
125 caddr_t vaddr;
126 uint32_t ring_size;
127 uint16_t id;
128 uint16_t phys_id;
129};
130
131struct bnxt_cp_ring {
132 struct bnxt_ring ring;
133 void *irq;
134 struct bnxt_softc *softc;
135 uint32_t cons;
136 int v_bit;
137 uint32_t commit_cons;
138 int commit_v_bit;
139 struct ctx_hw_stats *stats;
140 uint32_t stats_ctx_id;
141 struct bnxt_dmamem *ring_mem;
142};
143
144struct bnxt_grp_info {
145 uint32_t grp_id;
146 uint16_t stats_ctx;
147 uint16_t rx_ring_id;
148 uint16_t cp_ring_id;
149 uint16_t ag_ring_id;
150};
151
152struct bnxt_vnic_info {
153 uint16_t id;
154 uint16_t def_ring_grp;
155 uint16_t cos_rule;
156 uint16_t lb_rule;
157 uint16_t mru;
158
159 uint32_t flags;
160#define BNXT_VNIC_FLAG_DEFAULT0x01 0x01
161#define BNXT_VNIC_FLAG_BD_STALL0x02 0x02
162#define BNXT_VNIC_FLAG_VLAN_STRIP0x04 0x04
163
164 uint64_t filter_id;
165 uint32_t flow_id;
166
167 uint16_t rss_id;
168};
169
170struct bnxt_slot {
171 bus_dmamap_t bs_map;
172 struct mbuf *bs_m;
173};
174
175struct bnxt_dmamem {
176 bus_dmamap_t bdm_map;
177 bus_dma_segment_t bdm_seg;
178 size_t bdm_size;
179 caddr_t bdm_kva;
180};
181#define BNXT_DMA_MAP(_bdm)((_bdm)->bdm_map) ((_bdm)->bdm_map)
182#define BNXT_DMA_LEN(_bdm)((_bdm)->bdm_size) ((_bdm)->bdm_size)
183#define BNXT_DMA_DVA(_bdm)((u_int64_t)(_bdm)->bdm_map->dm_segs[0].ds_addr) ((u_int64_t)(_bdm)->bdm_map->dm_segs[0].ds_addr)
184#define BNXT_DMA_KVA(_bdm)((void *)(_bdm)->bdm_kva) ((void *)(_bdm)->bdm_kva)
185
186struct bnxt_rx_queue {
187 struct bnxt_softc *rx_softc;
188 struct ifiqueue *rx_ifiq;
189 struct bnxt_dmamem *rx_ring_mem; /* rx and ag */
190 struct bnxt_ring rx_ring;
191 struct bnxt_ring rx_ag_ring;
192 struct if_rxring rxr[2];
193 struct bnxt_slot *rx_slots;
194 struct bnxt_slot *rx_ag_slots;
195 int rx_prod;
196 int rx_cons;
197 int rx_ag_prod;
198 int rx_ag_cons;
199 struct timeout rx_refill;
200};
201
202struct bnxt_tx_queue {
203 struct bnxt_softc *tx_softc;
204 struct ifqueue *tx_ifq;
205 struct bnxt_dmamem *tx_ring_mem;
206 struct bnxt_ring tx_ring;
207 struct bnxt_slot *tx_slots;
208 int tx_prod;
209 int tx_cons;
210 int tx_ring_prod;
211 int tx_ring_cons;
212};
213
214struct bnxt_queue {
215 char q_name[8];
216 int q_index;
217 void *q_ihc;
218 struct bnxt_softc *q_sc;
219 struct bnxt_cp_ring q_cp;
220 struct bnxt_rx_queue q_rx;
221 struct bnxt_tx_queue q_tx;
222 struct bnxt_grp_info q_rg;
223};
224
225struct bnxt_softc {
226 struct device sc_dev;
227 struct arpcom sc_ac;
228 struct ifmedia sc_media;
229
230 struct mutex sc_lock;
231
232 pci_chipset_tag_t sc_pc;
233 pcitag_t sc_tag;
234 bus_dma_tag_t sc_dmat;
235
236 bus_space_tag_t sc_hwrm_t;
237 bus_space_handle_t sc_hwrm_h;
238 bus_size_t sc_hwrm_s;
239
240 struct bnxt_dmamem *sc_cmd_resp;
241 uint16_t sc_cmd_seq;
242 uint16_t sc_max_req_len;
243 uint32_t sc_cmd_timeo;
244 uint32_t sc_flags;
245
246 bus_space_tag_t sc_db_t;
247 bus_space_handle_t sc_db_h;
248 bus_size_t sc_db_s;
249
250 void *sc_ih;
251
252 int sc_hwrm_ver;
253 int sc_tx_queue_id;
254
255 struct bnxt_vnic_info sc_vnic;
256 struct bnxt_dmamem *sc_stats_ctx_mem;
257 struct bnxt_dmamem *sc_rx_cfg;
258
259 struct bnxt_cp_ring sc_cp_ring;
260
261 int sc_nqueues;
262 struct intrmap *sc_intrmap;
263 struct bnxt_queue sc_queues[BNXT_MAX_QUEUES8];
264};
265#define DEVNAME(_sc)((_sc)->sc_dev.dv_xname) ((_sc)->sc_dev.dv_xname)
266
267const struct pci_matchid bnxt_devices[] = {
268 { PCI_VENDOR_BROADCOM0x14e4, PCI_PRODUCT_BROADCOM_BCM573010x16c8 },
269 { PCI_VENDOR_BROADCOM0x14e4, PCI_PRODUCT_BROADCOM_BCM573020x16c9 },
270 { PCI_VENDOR_BROADCOM0x14e4, PCI_PRODUCT_BROADCOM_BCM573040x16ca },
271 { PCI_VENDOR_BROADCOM0x14e4, PCI_PRODUCT_BROADCOM_BCM573110x16ce },
272 { PCI_VENDOR_BROADCOM0x14e4, PCI_PRODUCT_BROADCOM_BCM573120x16cf },
273 { PCI_VENDOR_BROADCOM0x14e4, PCI_PRODUCT_BROADCOM_BCM573140x16df },
274 { PCI_VENDOR_BROADCOM0x14e4, PCI_PRODUCT_BROADCOM_BCM574020x16d0 },
275 { PCI_VENDOR_BROADCOM0x14e4, PCI_PRODUCT_BROADCOM_BCM574040x16d1 },
276 { PCI_VENDOR_BROADCOM0x14e4, PCI_PRODUCT_BROADCOM_BCM574060x16d2 },
277 { PCI_VENDOR_BROADCOM0x14e4, PCI_PRODUCT_BROADCOM_BCM574070x16d5 },
278 { PCI_VENDOR_BROADCOM0x14e4, PCI_PRODUCT_BROADCOM_BCM574120x16d6 },
279 { PCI_VENDOR_BROADCOM0x14e4, PCI_PRODUCT_BROADCOM_BCM574140x16d7 },
280 { PCI_VENDOR_BROADCOM0x14e4, PCI_PRODUCT_BROADCOM_BCM574160x16d8 },
281 { PCI_VENDOR_BROADCOM0x14e4, PCI_PRODUCT_BROADCOM_BCM57416_SFP0x16e3 },
282 { PCI_VENDOR_BROADCOM0x14e4, PCI_PRODUCT_BROADCOM_BCM574170x16d8 },
283 { PCI_VENDOR_BROADCOM0x14e4, PCI_PRODUCT_BROADCOM_BCM57417_SFP0x16e2 }
284};
285
286int bnxt_match(struct device *, void *, void *);
287void bnxt_attach(struct device *, struct device *, void *);
288
289void bnxt_up(struct bnxt_softc *);
290void bnxt_down(struct bnxt_softc *);
291void bnxt_iff(struct bnxt_softc *);
292int bnxt_ioctl(struct ifnet *, u_long, caddr_t);
293int bnxt_rxrinfo(struct bnxt_softc *, struct if_rxrinfo *);
294void bnxt_start(struct ifqueue *);
295int bnxt_admin_intr(void *);
296int bnxt_intr(void *);
297void bnxt_watchdog(struct ifnet *);
298void bnxt_media_status(struct ifnet *, struct ifmediareq *);
299int bnxt_media_change(struct ifnet *);
300int bnxt_media_autonegotiate(struct bnxt_softc *);
301
302struct cmpl_base *bnxt_cpr_next_cmpl(struct bnxt_softc *, struct bnxt_cp_ring *);
303void bnxt_cpr_commit(struct bnxt_softc *, struct bnxt_cp_ring *);
304void bnxt_cpr_rollback(struct bnxt_softc *, struct bnxt_cp_ring *);
305
306void bnxt_mark_cpr_invalid(struct bnxt_cp_ring *);
307void bnxt_write_cp_doorbell(struct bnxt_softc *, struct bnxt_ring *,
308 int);
309void bnxt_write_cp_doorbell_index(struct bnxt_softc *,
310 struct bnxt_ring *, uint32_t, int);
311void bnxt_write_rx_doorbell(struct bnxt_softc *, struct bnxt_ring *,
312 int);
313void bnxt_write_tx_doorbell(struct bnxt_softc *, struct bnxt_ring *,
314 int);
315
316int bnxt_rx_fill(struct bnxt_queue *);
317u_int bnxt_rx_fill_slots(struct bnxt_softc *, struct bnxt_ring *, void *,
318 struct bnxt_slot *, uint *, int, uint16_t, u_int);
319void bnxt_refill(void *);
320int bnxt_rx(struct bnxt_softc *, struct bnxt_rx_queue *,
321 struct bnxt_cp_ring *, struct mbuf_list *, int *, int *,
322 struct cmpl_base *);
323
324void bnxt_txeof(struct bnxt_softc *, struct bnxt_tx_queue *, int *,
325 struct cmpl_base *);
326
327int bnxt_set_cp_ring_aggint(struct bnxt_softc *, struct bnxt_cp_ring *);
328
329int _hwrm_send_message(struct bnxt_softc *, void *, uint32_t);
330int hwrm_send_message(struct bnxt_softc *, void *, uint32_t);
331void bnxt_hwrm_cmd_hdr_init(struct bnxt_softc *, void *, uint16_t);
332int bnxt_hwrm_err_map(uint16_t err);
333
334/* HWRM Function Prototypes */
335int bnxt_hwrm_ring_alloc(struct bnxt_softc *, uint8_t,
336 struct bnxt_ring *, uint16_t, uint32_t, int);
337int bnxt_hwrm_ring_free(struct bnxt_softc *, uint8_t,
338 struct bnxt_ring *);
339int bnxt_hwrm_ver_get(struct bnxt_softc *);
340int bnxt_hwrm_queue_qportcfg(struct bnxt_softc *);
341int bnxt_hwrm_func_drv_rgtr(struct bnxt_softc *);
342int bnxt_hwrm_func_qcaps(struct bnxt_softc *);
343int bnxt_hwrm_func_qcfg(struct bnxt_softc *);
344int bnxt_hwrm_func_reset(struct bnxt_softc *);
345int bnxt_hwrm_vnic_ctx_alloc(struct bnxt_softc *, uint16_t *);
346int bnxt_hwrm_vnic_ctx_free(struct bnxt_softc *, uint16_t *);
347int bnxt_hwrm_vnic_cfg(struct bnxt_softc *,
348 struct bnxt_vnic_info *);
349int bnxt_hwrm_vnic_cfg_placement(struct bnxt_softc *,
350 struct bnxt_vnic_info *vnic);
351int bnxt_hwrm_stat_ctx_alloc(struct bnxt_softc *,
352 struct bnxt_cp_ring *, uint64_t);
353int bnxt_hwrm_stat_ctx_free(struct bnxt_softc *,
354 struct bnxt_cp_ring *);
355int bnxt_hwrm_ring_grp_alloc(struct bnxt_softc *,
356 struct bnxt_grp_info *);
357int bnxt_hwrm_ring_grp_free(struct bnxt_softc *,
358 struct bnxt_grp_info *);
359int bnxt_hwrm_vnic_alloc(struct bnxt_softc *,
360 struct bnxt_vnic_info *);
361int bnxt_hwrm_vnic_free(struct bnxt_softc *,
362 struct bnxt_vnic_info *);
363int bnxt_hwrm_cfa_l2_set_rx_mask(struct bnxt_softc *,
364 uint32_t, uint32_t, uint64_t, uint32_t);
365int bnxt_hwrm_set_filter(struct bnxt_softc *,
366 struct bnxt_vnic_info *);
367int bnxt_hwrm_free_filter(struct bnxt_softc *,
368 struct bnxt_vnic_info *);
369int bnxt_hwrm_vnic_rss_cfg(struct bnxt_softc *,
370 struct bnxt_vnic_info *, uint32_t, daddr_t, daddr_t);
371int bnxt_cfg_async_cr(struct bnxt_softc *, struct bnxt_cp_ring *);
372int bnxt_hwrm_nvm_get_dev_info(struct bnxt_softc *, uint16_t *,
373 uint16_t *, uint32_t *, uint32_t *, uint32_t *, uint32_t *);
374int bnxt_hwrm_port_phy_qcfg(struct bnxt_softc *,
375 struct ifmediareq *);
376int bnxt_hwrm_func_rgtr_async_events(struct bnxt_softc *);
377int bnxt_get_sffpage(struct bnxt_softc *, struct if_sffpage *);
378
379/* not used yet: */
380#if 0
381int bnxt_hwrm_func_drv_unrgtr(struct bnxt_softc *softc, bool_Bool shutdown);
382
383int bnxt_hwrm_port_qstats(struct bnxt_softc *softc);
384
385
386int bnxt_hwrm_vnic_tpa_cfg(struct bnxt_softc *softc);
387void bnxt_validate_hw_lro_settings(struct bnxt_softc *softc);
388int bnxt_hwrm_fw_reset(struct bnxt_softc *softc, uint8_t processor,
389 uint8_t *selfreset);
390int bnxt_hwrm_fw_qstatus(struct bnxt_softc *softc, uint8_t type,
391 uint8_t *selfreset);
392int bnxt_hwrm_fw_get_time(struct bnxt_softc *softc, uint16_t *year,
393 uint8_t *month, uint8_t *day, uint8_t *hour, uint8_t *minute,
394 uint8_t *second, uint16_t *millisecond, uint16_t *zone);
395int bnxt_hwrm_fw_set_time(struct bnxt_softc *softc, uint16_t year,
396 uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second,
397 uint16_t millisecond, uint16_t zone);
398
399#endif
400
401
402struct cfattach bnxt_ca = {
403 sizeof(struct bnxt_softc), bnxt_match, bnxt_attach
404};
405
406struct cfdriver bnxt_cd = {
407 NULL((void *)0), "bnxt", DV_IFNET
408};
409
410struct bnxt_dmamem *
411bnxt_dmamem_alloc(struct bnxt_softc *sc, size_t size)
412{
413 struct bnxt_dmamem *m;
414 int nsegs;
415
416 m = malloc(sizeof(*m), M_DEVBUF2, M_NOWAIT0x0002 | M_ZERO0x0008);
417 if (m == NULL((void *)0))
418 return (NULL((void *)0));
419
420 m->bdm_size = size;
421
422 if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), (size
), (1), (size), (0), (0x0001 | 0x0002), (&m->bdm_map))
423 BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &m->bdm_map)(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), (size
), (1), (size), (0), (0x0001 | 0x0002), (&m->bdm_map))
!= 0)
424 goto bdmfree;
425
426 if (bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, &m->bdm_seg, 1,(*(sc->sc_dmat)->_dmamem_alloc)((sc->sc_dmat), (size
), ((1 << 12)), (0), (&m->bdm_seg), (1), (&nsegs
), (0x0001 | 0x1000))
427 &nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO)(*(sc->sc_dmat)->_dmamem_alloc)((sc->sc_dmat), (size
), ((1 << 12)), (0), (&m->bdm_seg), (1), (&nsegs
), (0x0001 | 0x1000))
!= 0)
428 goto destroy;
429
430 if (bus_dmamem_map(sc->sc_dmat, &m->bdm_seg, nsegs, size, &m->bdm_kva,(*(sc->sc_dmat)->_dmamem_map)((sc->sc_dmat), (&m
->bdm_seg), (nsegs), (size), (&m->bdm_kva), (0x0001
))
431 BUS_DMA_NOWAIT)(*(sc->sc_dmat)->_dmamem_map)((sc->sc_dmat), (&m
->bdm_seg), (nsegs), (size), (&m->bdm_kva), (0x0001
))
!= 0)
432 goto free;
433
434 if (bus_dmamap_load(sc->sc_dmat, m->bdm_map, m->bdm_kva, size, NULL,(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (m->
bdm_map), (m->bdm_kva), (size), (((void *)0)), (0x0001))
435 BUS_DMA_NOWAIT)(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (m->
bdm_map), (m->bdm_kva), (size), (((void *)0)), (0x0001))
!= 0)
436 goto unmap;
437
438 return (m);
439
440unmap:
441 bus_dmamem_unmap(sc->sc_dmat, m->bdm_kva, m->bdm_size)(*(sc->sc_dmat)->_dmamem_unmap)((sc->sc_dmat), (m->
bdm_kva), (m->bdm_size))
;
442free:
443 bus_dmamem_free(sc->sc_dmat, &m->bdm_seg, 1)(*(sc->sc_dmat)->_dmamem_free)((sc->sc_dmat), (&
m->bdm_seg), (1))
;
444destroy:
445 bus_dmamap_destroy(sc->sc_dmat, m->bdm_map)(*(sc->sc_dmat)->_dmamap_destroy)((sc->sc_dmat), (m->
bdm_map))
;
446bdmfree:
447 free(m, M_DEVBUF2, sizeof *m);
448
449 return (NULL((void *)0));
450}
451
452void
453bnxt_dmamem_free(struct bnxt_softc *sc, struct bnxt_dmamem *m)
454{
455 bus_dmamem_unmap(sc->sc_dmat, m->bdm_kva, m->bdm_size)(*(sc->sc_dmat)->_dmamem_unmap)((sc->sc_dmat), (m->
bdm_kva), (m->bdm_size))
;
456 bus_dmamem_free(sc->sc_dmat, &m->bdm_seg, 1)(*(sc->sc_dmat)->_dmamem_free)((sc->sc_dmat), (&
m->bdm_seg), (1))
;
457 bus_dmamap_destroy(sc->sc_dmat, m->bdm_map)(*(sc->sc_dmat)->_dmamap_destroy)((sc->sc_dmat), (m->
bdm_map))
;
458 free(m, M_DEVBUF2, sizeof *m);
459}
460
461int
462bnxt_match(struct device *parent, void *match, void *aux)
463{
464 return (pci_matchbyid(aux, bnxt_devices, nitems(bnxt_devices)(sizeof((bnxt_devices)) / sizeof((bnxt_devices)[0]))));
465}
466
467void
468bnxt_attach(struct device *parent, struct device *self, void *aux)
469{
470 struct bnxt_softc *sc = (struct bnxt_softc *)self;
471 struct ifnet *ifp = &sc->sc_ac.ac_if;
472 struct pci_attach_args *pa = aux;
473 struct bnxt_cp_ring *cpr;
474 pci_intr_handle_t ih;
475 const char *intrstr;
476 u_int memtype;
477 int i;
478
479 sc->sc_pc = pa->pa_pc;
480 sc->sc_tag = pa->pa_tag;
481 sc->sc_dmat = pa->pa_dmat;
482
483 memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, BNXT_HWRM_BAR0x10);
484 if (pci_mapreg_map(pa, BNXT_HWRM_BAR0x10, memtype, 0, &sc->sc_hwrm_t,
485 &sc->sc_hwrm_h, NULL((void *)0), &sc->sc_hwrm_s, 0)) {
486 printf(": failed to map hwrm\n");
487 return;
488 }
489
490 memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, BNXT_DOORBELL_BAR0x18);
491 if (pci_mapreg_map(pa, BNXT_DOORBELL_BAR0x18, memtype, 0, &sc->sc_db_t,
492 &sc->sc_db_h, NULL((void *)0), &sc->sc_db_s, 0)) {
493 printf(": failed to map doorbell\n");
494 goto unmap_1;
495 }
496
497 BNXT_HWRM_LOCK_INIT(sc, DEVNAME(sc))do { (void)(((sc)->sc_dev.dv_xname)); (void)(0); __mtx_init
((&sc->sc_lock), ((((0x7)) > 0x0 && ((0x7))
< 0x9) ? 0x9 : ((0x7)))); } while (0)
;
498 sc->sc_cmd_resp = bnxt_dmamem_alloc(sc, PAGE_SIZE(1 << 12));
499 if (sc->sc_cmd_resp == NULL((void *)0)) {
500 printf(": failed to allocate command response buffer\n");
501 goto unmap_2;
502 }
503
504 if (bnxt_hwrm_ver_get(sc) != 0) {
505 printf(": failed to query version info\n");
506 goto free_resp;
507 }
508
509 if (bnxt_hwrm_nvm_get_dev_info(sc, NULL((void *)0), NULL((void *)0), NULL((void *)0), NULL((void *)0), NULL((void *)0), NULL((void *)0))
510 != 0) {
511 printf(": failed to get nvram info\n");
512 goto free_resp;
513 }
514
515 if (bnxt_hwrm_func_drv_rgtr(sc) != 0) {
516 printf(": failed to register driver with firmware\n");
517 goto free_resp;
518 }
519
520 if (bnxt_hwrm_func_rgtr_async_events(sc) != 0) {
521 printf(": failed to register async events\n");
522 goto free_resp;
523 }
524
525 if (bnxt_hwrm_func_qcaps(sc) != 0) {
526 printf(": failed to get queue capabilities\n");
527 goto free_resp;
528 }
529
530 /*
531 * devices advertise msi support, but there's no way to tell a
532 * completion queue to use msi mode, only legacy or msi-x.
533 */
534 if (pci_intr_map_msix(pa, 0, &ih) == 0) {
535 int nmsix;
536
537 sc->sc_flags |= BNXT_FLAG_MSIX0x0010;
538 intrstr = pci_intr_string(sc->sc_pc, ih);
539
540 nmsix = pci_intr_msix_count(pa);
541 if (nmsix > 1) {
542 sc->sc_ih = pci_intr_establish(sc->sc_pc, ih,
543 IPL_NET0x7 | IPL_MPSAFE0x100, bnxt_admin_intr, sc, DEVNAME(sc)((sc)->sc_dev.dv_xname));
544 sc->sc_intrmap = intrmap_create(&sc->sc_dev,
545 nmsix - 1, BNXT_MAX_QUEUES8, INTRMAP_POWEROF2(1 << 0));
546 sc->sc_nqueues = intrmap_count(sc->sc_intrmap);
547 KASSERT(sc->sc_nqueues > 0)((sc->sc_nqueues > 0) ? (void)0 : __assert("diagnostic "
, "/usr/src/sys/dev/pci/if_bnxt.c", 547, "sc->sc_nqueues > 0"
))
;
548 KASSERT(powerof2(sc->sc_nqueues))((((((sc->sc_nqueues)-1)&(sc->sc_nqueues))==0)) ? (
void)0 : __assert("diagnostic ", "/usr/src/sys/dev/pci/if_bnxt.c"
, 548, "powerof2(sc->sc_nqueues)"))
;
549 } else {
550 sc->sc_ih = pci_intr_establish(sc->sc_pc, ih,
551 IPL_NET0x7 | IPL_MPSAFE0x100, bnxt_intr, &sc->sc_queues[0],
552 DEVNAME(sc)((sc)->sc_dev.dv_xname));
553 sc->sc_nqueues = 1;
554 }
555 } else if (pci_intr_map(pa, &ih) == 0) {
556 intrstr = pci_intr_string(sc->sc_pc, ih);
557 sc->sc_ih = pci_intr_establish(sc->sc_pc, ih, IPL_NET0x7 | IPL_MPSAFE0x100,
558 bnxt_intr, &sc->sc_queues[0], DEVNAME(sc)((sc)->sc_dev.dv_xname));
559 sc->sc_nqueues = 1;
560 } else {
561 printf(": unable to map interrupt\n");
562 goto free_resp;
563 }
564 if (sc->sc_ih == NULL((void *)0)) {
565 printf(": unable to establish interrupt");
566 if (intrstr != NULL((void *)0))
567 printf(" at %s", intrstr);
568 printf("\n");
569 goto deintr;
570 }
571 printf("%s, %d queues, address %s\n", intrstr, sc->sc_nqueues,
572 ether_sprintf(sc->sc_ac.ac_enaddr));
573
574 if (bnxt_hwrm_func_qcfg(sc) != 0) {
575 printf("%s: failed to query function config\n", DEVNAME(sc)((sc)->sc_dev.dv_xname));
576 goto deintr;
577 }
578
579 if (bnxt_hwrm_queue_qportcfg(sc) != 0) {
580 printf("%s: failed to query port config\n", DEVNAME(sc)((sc)->sc_dev.dv_xname));
581 goto deintr;
582 }
583
584 if (bnxt_hwrm_func_reset(sc) != 0) {
585 printf("%s: reset failed\n", DEVNAME(sc)((sc)->sc_dev.dv_xname));
586 goto deintr;
587 }
588
589 if (sc->sc_intrmap == NULL((void *)0))
590 cpr = &sc->sc_queues[0].q_cp;
591 else
592 cpr = &sc->sc_cp_ring;
593
594 cpr->stats_ctx_id = HWRM_NA_SIGNATURE((uint32_t)(-1));
595 cpr->ring.phys_id = (uint16_t)HWRM_NA_SIGNATURE((uint32_t)(-1));
596 cpr->softc = sc;
597 cpr->ring.id = 0;
598 cpr->ring.doorbell = cpr->ring.id * 0x80;
599 cpr->ring.ring_size = (PAGE_SIZE(1 << 12) * BNXT_CP_PAGES4) /
600 sizeof(struct cmpl_base);
601 cpr->ring_mem = bnxt_dmamem_alloc(sc, PAGE_SIZE(1 << 12) *
602 BNXT_CP_PAGES4);
603 if (cpr->ring_mem == NULL((void *)0)) {
604 printf("%s: failed to allocate completion queue memory\n",
605 DEVNAME(sc)((sc)->sc_dev.dv_xname));
606 goto deintr;
607 }
608 cpr->ring.vaddr = BNXT_DMA_KVA(cpr->ring_mem)((void *)(cpr->ring_mem)->bdm_kva);
609 cpr->ring.paddr = BNXT_DMA_DVA(cpr->ring_mem)((u_int64_t)(cpr->ring_mem)->bdm_map->dm_segs[0].ds_addr
)
;
610 cpr->cons = UINT32_MAX0xffffffffU;
611 cpr->v_bit = 1;
612 bnxt_mark_cpr_invalid(cpr);
613 if (bnxt_hwrm_ring_alloc(sc, HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL0x0U,
614 &cpr->ring, (uint16_t)HWRM_NA_SIGNATURE((uint32_t)(-1)),
615 HWRM_NA_SIGNATURE((uint32_t)(-1)), 1) != 0) {
616 printf("%s: failed to allocate completion queue\n",
617 DEVNAME(sc)((sc)->sc_dev.dv_xname));
618 goto free_cp_mem;
619 }
620 if (bnxt_cfg_async_cr(sc, cpr) != 0) {
621 printf("%s: failed to set async completion ring\n",
622 DEVNAME(sc)((sc)->sc_dev.dv_xname));
623 goto free_cp_mem;
624 }
625 bnxt_write_cp_doorbell(sc, &cpr->ring, 1);
626
627 if (bnxt_set_cp_ring_aggint(sc, cpr) != 0) {
628 printf("%s: failed to set interrupt aggregation\n",
629 DEVNAME(sc)((sc)->sc_dev.dv_xname));
630 goto free_cp_mem;
631 }
632
633 strlcpy(ifp->if_xname, DEVNAME(sc)((sc)->sc_dev.dv_xname), IFNAMSIZ16);
634 ifp->if_softc = sc;
635 ifp->if_flags = IFF_BROADCAST0x2 | IFF_MULTICAST0x8000 | IFF_SIMPLEX0x800;
636 ifp->if_xflags = IFXF_MPSAFE0x1;
637 ifp->if_ioctl = bnxt_ioctl;
638 ifp->if_qstart = bnxt_start;
639 ifp->if_watchdog = bnxt_watchdog;
640 ifp->if_hardmtu = BNXT_MAX_MTU9500;
641 ifp->if_capabilitiesif_data.ifi_capabilities = IFCAP_VLAN_MTU0x00000010 | IFCAP_CSUM_IPv40x00000001 |
642 IFCAP_CSUM_UDPv40x00000004 | IFCAP_CSUM_TCPv40x00000002 | IFCAP_CSUM_UDPv60x00000100 |
643 IFCAP_CSUM_TCPv60x00000080;
644#if NVLAN1 > 0
645 ifp->if_capabilitiesif_data.ifi_capabilities |= IFCAP_VLAN_HWTAGGING0x00000020;
646#endif
647 ifq_set_maxlen(&ifp->if_snd, 1024)((&ifp->if_snd)->ifq_maxlen = (1024)); /* ? */
648
649 ifmedia_init(&sc->sc_media, IFM_IMASK0xff00000000000000ULL, bnxt_media_change,
650 bnxt_media_status);
651
652 if_attach(ifp);
653 ether_ifattach(ifp);
654
655 if_attach_iqueues(ifp, sc->sc_nqueues);
656 if_attach_queues(ifp, sc->sc_nqueues);
657 for (i = 0; i < sc->sc_nqueues; i++) {
658 struct ifiqueue *ifiq = ifp->if_iqs[i];
659 struct ifqueue *ifq = ifp->if_ifqs[i];
660 struct bnxt_queue *bq = &sc->sc_queues[i];
661 struct bnxt_cp_ring *cp = &bq->q_cp;
662 struct bnxt_rx_queue *rx = &bq->q_rx;
663 struct bnxt_tx_queue *tx = &bq->q_tx;
664
665 bq->q_index = i;
666 bq->q_sc = sc;
667
668 rx->rx_softc = sc;
669 rx->rx_ifiq = ifiq;
670 timeout_set(&rx->rx_refill, bnxt_refill, bq);
671 ifiq->ifiq_softc_ifiq_ptr._ifiq_softc = rx;
672
673 tx->tx_softc = sc;
674 tx->tx_ifq = ifq;
675 ifq->ifq_softc_ifq_ptr._ifq_softc = tx;
676
677 if (sc->sc_intrmap != NULL((void *)0)) {
678 cp->stats_ctx_id = HWRM_NA_SIGNATURE((uint32_t)(-1));
679 cp->ring.phys_id = (uint16_t)HWRM_NA_SIGNATURE((uint32_t)(-1));
680 cp->ring.id = i + 1; /* first cp ring is async only */
681 cp->softc = sc;
682 cp->ring.doorbell = bq->q_cp.ring.id * 0x80;
683 cp->ring.ring_size = (PAGE_SIZE(1 << 12) * BNXT_CP_PAGES4) /
684 sizeof(struct cmpl_base);
685 if (pci_intr_map_msix(pa, i + 1, &ih) != 0) {
686 printf("%s: unable to map queue interrupt %d\n",
687 DEVNAME(sc)((sc)->sc_dev.dv_xname), i);
688 goto intrdisestablish;
689 }
690 snprintf(bq->q_name, sizeof(bq->q_name), "%s:%d",
691 DEVNAME(sc)((sc)->sc_dev.dv_xname), i);
692 bq->q_ihc = pci_intr_establish_cpu(sc->sc_pc, ih,
693 IPL_NET0x7 | IPL_MPSAFE0x100, intrmap_cpu(sc->sc_intrmap, i),
694 bnxt_intr, bq, bq->q_name);
695 if (bq->q_ihc == NULL((void *)0)) {
696 printf("%s: unable to establish interrupt %d\n",
697 DEVNAME(sc)((sc)->sc_dev.dv_xname), i);
698 goto intrdisestablish;
699 }
700 }
701 }
702
703 bnxt_media_autonegotiate(sc);
704 bnxt_hwrm_port_phy_qcfg(sc, NULL((void *)0));
705 return;
706
707intrdisestablish:
708 for (i = 0; i < sc->sc_nqueues; i++) {
709 struct bnxt_queue *bq = &sc->sc_queues[i];
710 if (bq->q_ihc == NULL((void *)0))
711 continue;
712 pci_intr_disestablish(sc->sc_pc, bq->q_ihc);
713 bq->q_ihc = NULL((void *)0);
714 }
715free_cp_mem:
716 bnxt_dmamem_free(sc, cpr->ring_mem);
717deintr:
718 if (sc->sc_intrmap != NULL((void *)0)) {
719 intrmap_destroy(sc->sc_intrmap);
720 sc->sc_intrmap = NULL((void *)0);
721 }
722 pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
723 sc->sc_ih = NULL((void *)0);
724free_resp:
725 bnxt_dmamem_free(sc, sc->sc_cmd_resp);
726unmap_2:
727 bus_space_unmap(sc->sc_hwrm_t, sc->sc_hwrm_h, sc->sc_hwrm_s);
728 sc->sc_hwrm_s = 0;
729unmap_1:
730 bus_space_unmap(sc->sc_db_t, sc->sc_db_h, sc->sc_db_s);
731 sc->sc_db_s = 0;
732}
733
734void
735bnxt_free_slots(struct bnxt_softc *sc, struct bnxt_slot *slots, int allocated,
736 int total)
737{
738 struct bnxt_slot *bs;
739
740 int i = allocated;
741 while (i-- > 0) {
742 bs = &slots[i];
743 bus_dmamap_destroy(sc->sc_dmat, bs->bs_map)(*(sc->sc_dmat)->_dmamap_destroy)((sc->sc_dmat), (bs
->bs_map))
;
744 }
745 free(slots, M_DEVBUF2, total * sizeof(*bs));
746}
747
748int
749bnxt_set_cp_ring_aggint(struct bnxt_softc *sc, struct bnxt_cp_ring *cpr)
750{
751 struct hwrm_ring_cmpl_ring_cfg_aggint_params_input aggint;
752
753 /*
754 * set interrupt aggregation parameters for around 10k interrupts
755 * per second. the timers are in units of 80usec, and the counters
756 * are based on the minimum rx ring size of 32.
757 */
758 memset(&aggint, 0, sizeof(aggint))__builtin_memset((&aggint), (0), (sizeof(aggint)));
759 bnxt_hwrm_cmd_hdr_init(sc, &aggint,
760 HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS(0x53U));
761 aggint.ring_id = htole16(cpr->ring.phys_id)((__uint16_t)(cpr->ring.phys_id));
762 aggint.num_cmpl_dma_aggr = htole16(32)((__uint16_t)(32));
763 aggint.num_cmpl_dma_aggr_during_int = aggint.num_cmpl_dma_aggr;
764 aggint.cmpl_aggr_dma_tmr = htole16((1000000000 / 20000) / 80)((__uint16_t)((1000000000 / 20000) / 80));
765 aggint.cmpl_aggr_dma_tmr_during_int = aggint.cmpl_aggr_dma_tmr;
766 aggint.int_lat_tmr_min = htole16((1000000000 / 20000) / 80)((__uint16_t)((1000000000 / 20000) / 80));
767 aggint.int_lat_tmr_max = htole16((1000000000 / 10000) / 80)((__uint16_t)((1000000000 / 10000) / 80));
768 aggint.num_cmpl_aggr_int = htole16(16)((__uint16_t)(16));
769 return (hwrm_send_message(sc, &aggint, sizeof(aggint)));
770}
771
772int
773bnxt_queue_up(struct bnxt_softc *sc, struct bnxt_queue *bq)
774{
775 struct ifnet *ifp = &sc->sc_ac.ac_if;
776 struct bnxt_cp_ring *cp = &bq->q_cp;
777 struct bnxt_rx_queue *rx = &bq->q_rx;
778 struct bnxt_tx_queue *tx = &bq->q_tx;
779 struct bnxt_grp_info *rg = &bq->q_rg;
780 struct bnxt_slot *bs;
781 int i;
782
783 tx->tx_ring_mem = bnxt_dmamem_alloc(sc, PAGE_SIZE(1 << 12));
784 if (tx->tx_ring_mem == NULL((void *)0)) {
785 printf("%s: failed to allocate tx ring %d\n", DEVNAME(sc)((sc)->sc_dev.dv_xname), bq->q_index);
786 return ENOMEM12;
787 }
788
789 rx->rx_ring_mem = bnxt_dmamem_alloc(sc, PAGE_SIZE(1 << 12) * 2);
790 if (rx->rx_ring_mem == NULL((void *)0)) {
791 printf("%s: failed to allocate rx ring %d\n", DEVNAME(sc)((sc)->sc_dev.dv_xname), bq->q_index);
792 goto free_tx;
793 }
794
795 /* completion ring is already allocated if we're not using an intrmap */
796 if (sc->sc_intrmap != NULL((void *)0)) {
797 cp->ring_mem = bnxt_dmamem_alloc(sc, PAGE_SIZE(1 << 12) * BNXT_CP_PAGES4);
798 if (cp->ring_mem == NULL((void *)0)) {
799 printf("%s: failed to allocate completion ring %d mem\n",
800 DEVNAME(sc)((sc)->sc_dev.dv_xname), bq->q_index);
801 goto free_rx;
802 }
803 cp->ring.vaddr = BNXT_DMA_KVA(cp->ring_mem)((void *)(cp->ring_mem)->bdm_kva);
804 cp->ring.paddr = BNXT_DMA_DVA(cp->ring_mem)((u_int64_t)(cp->ring_mem)->bdm_map->dm_segs[0].ds_addr
)
;
805 cp->cons = UINT32_MAX0xffffffffU;
806 cp->v_bit = 1;
807 bnxt_mark_cpr_invalid(cp);
808
809 if (bnxt_hwrm_ring_alloc(sc, HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL0x0U,
810 &cp->ring, (uint16_t)HWRM_NA_SIGNATURE((uint32_t)(-1)),
811 HWRM_NA_SIGNATURE((uint32_t)(-1)), 1) != 0) {
812 printf("%s: failed to allocate completion queue %d\n",
813 DEVNAME(sc)((sc)->sc_dev.dv_xname), bq->q_index);
814 goto free_rx;
815 }
816
817 if (bnxt_set_cp_ring_aggint(sc, cp) != 0) {
818 printf("%s: failed to set interrupt %d aggregation\n",
819 DEVNAME(sc)((sc)->sc_dev.dv_xname), bq->q_index);
820 goto free_rx;
821 }
822 bnxt_write_cp_doorbell(sc, &cp->ring, 1);
823 }
824
825 if (bnxt_hwrm_stat_ctx_alloc(sc, &bq->q_cp,
826 BNXT_DMA_DVA(sc->sc_stats_ctx_mem)((u_int64_t)(sc->sc_stats_ctx_mem)->bdm_map->dm_segs
[0].ds_addr)
+
827 (bq->q_index * sizeof(struct ctx_hw_stats))) != 0) {
828 printf("%s: failed to set up stats context\n", DEVNAME(sc)((sc)->sc_dev.dv_xname));
829 goto free_rx;
830 }
831
832 tx->tx_ring.phys_id = (uint16_t)HWRM_NA_SIGNATURE((uint32_t)(-1));
833 tx->tx_ring.id = BNXT_TX_RING_ID_BASE((8 * 3) + 1) + bq->q_index;
834 tx->tx_ring.doorbell = tx->tx_ring.id * 0x80;
835 tx->tx_ring.ring_size = PAGE_SIZE(1 << 12) / sizeof(struct tx_bd_short);
836 tx->tx_ring.vaddr = BNXT_DMA_KVA(tx->tx_ring_mem)((void *)(tx->tx_ring_mem)->bdm_kva);
837 tx->tx_ring.paddr = BNXT_DMA_DVA(tx->tx_ring_mem)((u_int64_t)(tx->tx_ring_mem)->bdm_map->dm_segs[0].ds_addr
)
;
838 if (bnxt_hwrm_ring_alloc(sc, HWRM_RING_ALLOC_INPUT_RING_TYPE_TX0x1U,
839 &tx->tx_ring, cp->ring.phys_id, HWRM_NA_SIGNATURE((uint32_t)(-1)), 1) != 0) {
840 printf("%s: failed to set up tx ring\n",
841 DEVNAME(sc)((sc)->sc_dev.dv_xname));
842 goto dealloc_stats;
843 }
844 bnxt_write_tx_doorbell(sc, &tx->tx_ring, 0);
845
846 rx->rx_ring.phys_id = (uint16_t)HWRM_NA_SIGNATURE((uint32_t)(-1));
847 rx->rx_ring.id = BNXT_RX_RING_ID_BASE(8 + 1) + bq->q_index;
848 rx->rx_ring.doorbell = rx->rx_ring.id * 0x80;
849 rx->rx_ring.ring_size = PAGE_SIZE(1 << 12) / sizeof(struct rx_prod_pkt_bd);
850 rx->rx_ring.vaddr = BNXT_DMA_KVA(rx->rx_ring_mem)((void *)(rx->rx_ring_mem)->bdm_kva);
851 rx->rx_ring.paddr = BNXT_DMA_DVA(rx->rx_ring_mem)((u_int64_t)(rx->rx_ring_mem)->bdm_map->dm_segs[0].ds_addr
)
;
852 if (bnxt_hwrm_ring_alloc(sc, HWRM_RING_ALLOC_INPUT_RING_TYPE_RX0x2U,
853 &rx->rx_ring, cp->ring.phys_id, HWRM_NA_SIGNATURE((uint32_t)(-1)), 1) != 0) {
854 printf("%s: failed to set up rx ring\n",
855 DEVNAME(sc)((sc)->sc_dev.dv_xname));
856 goto dealloc_tx;
857 }
858 bnxt_write_rx_doorbell(sc, &rx->rx_ring, 0);
859
860 rx->rx_ag_ring.phys_id = (uint16_t)HWRM_NA_SIGNATURE((uint32_t)(-1));
861 rx->rx_ag_ring.id = BNXT_AG_RING_ID_BASE((8 * 2) + 1) + bq->q_index;
862 rx->rx_ag_ring.doorbell = rx->rx_ag_ring.id * 0x80;
863 rx->rx_ag_ring.ring_size = PAGE_SIZE(1 << 12) / sizeof(struct rx_prod_pkt_bd);
864 rx->rx_ag_ring.vaddr = BNXT_DMA_KVA(rx->rx_ring_mem)((void *)(rx->rx_ring_mem)->bdm_kva) + PAGE_SIZE(1 << 12);
865 rx->rx_ag_ring.paddr = BNXT_DMA_DVA(rx->rx_ring_mem)((u_int64_t)(rx->rx_ring_mem)->bdm_map->dm_segs[0].ds_addr
)
+ PAGE_SIZE(1 << 12);
866 if (bnxt_hwrm_ring_alloc(sc, HWRM_RING_ALLOC_INPUT_RING_TYPE_RX0x2U,
867 &rx->rx_ag_ring, cp->ring.phys_id, HWRM_NA_SIGNATURE((uint32_t)(-1)), 1) != 0) {
868 printf("%s: failed to set up rx ag ring\n",
869 DEVNAME(sc)((sc)->sc_dev.dv_xname));
870 goto dealloc_rx;
871 }
872 bnxt_write_rx_doorbell(sc, &rx->rx_ag_ring, 0);
873
874 rg->grp_id = HWRM_NA_SIGNATURE((uint32_t)(-1));
875 rg->stats_ctx = cp->stats_ctx_id;
876 rg->rx_ring_id = rx->rx_ring.phys_id;
877 rg->ag_ring_id = rx->rx_ag_ring.phys_id;
878 rg->cp_ring_id = cp->ring.phys_id;
879 if (bnxt_hwrm_ring_grp_alloc(sc, rg) != 0) {
880 printf("%s: failed to allocate ring group\n",
881 DEVNAME(sc)((sc)->sc_dev.dv_xname));
882 goto dealloc_ag;
883 }
884
885 rx->rx_slots = mallocarray(sizeof(*bs), rx->rx_ring.ring_size,
886 M_DEVBUF2, M_WAITOK0x0001 | M_ZERO0x0008);
887 if (rx->rx_slots == NULL((void *)0)) {
888 printf("%s: failed to allocate rx slots\n", DEVNAME(sc)((sc)->sc_dev.dv_xname));
889 goto dealloc_ring_group;
890 }
891
892 for (i = 0; i < rx->rx_ring.ring_size; i++) {
893 bs = &rx->rx_slots[i];
894 if (bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 0,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), ((1 <<
11)), (1), ((1 << 11)), (0), (0x0000 | 0x0002), (&
bs->bs_map))
895 BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW, &bs->bs_map)(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), ((1 <<
11)), (1), ((1 << 11)), (0), (0x0000 | 0x0002), (&
bs->bs_map))
!= 0) {
896 printf("%s: failed to allocate rx dma maps\n",
897 DEVNAME(sc)((sc)->sc_dev.dv_xname));
898 goto destroy_rx_slots;
899 }
900 }
901
902 rx->rx_ag_slots = mallocarray(sizeof(*bs), rx->rx_ag_ring.ring_size,
903 M_DEVBUF2, M_WAITOK0x0001 | M_ZERO0x0008);
904 if (rx->rx_ag_slots == NULL((void *)0)) {
905 printf("%s: failed to allocate rx ag slots\n", DEVNAME(sc)((sc)->sc_dev.dv_xname));
906 goto destroy_rx_slots;
907 }
908
909 for (i = 0; i < rx->rx_ag_ring.ring_size; i++) {
910 bs = &rx->rx_ag_slots[i];
911 if (bus_dmamap_create(sc->sc_dmat, BNXT_AG_BUFFER_SIZE, 1,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), (8192
), (1), (8192), (0), (0x0000 | 0x0002), (&bs->bs_map))
912 BNXT_AG_BUFFER_SIZE, 0, BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), (8192
), (1), (8192), (0), (0x0000 | 0x0002), (&bs->bs_map))
913 &bs->bs_map)(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), (8192
), (1), (8192), (0), (0x0000 | 0x0002), (&bs->bs_map))
!= 0) {
914 printf("%s: failed to allocate rx ag dma maps\n",
915 DEVNAME(sc)((sc)->sc_dev.dv_xname));
916 goto destroy_rx_ag_slots;
917 }
918 }
919
920 tx->tx_slots = mallocarray(sizeof(*bs), tx->tx_ring.ring_size,
921 M_DEVBUF2, M_WAITOK0x0001 | M_ZERO0x0008);
922 if (tx->tx_slots == NULL((void *)0)) {
923 printf("%s: failed to allocate tx slots\n", DEVNAME(sc)((sc)->sc_dev.dv_xname));
924 goto destroy_rx_ag_slots;
925 }
926
927 for (i = 0; i < tx->tx_ring.ring_size; i++) {
928 bs = &tx->tx_slots[i];
929 if (bus_dmamap_create(sc->sc_dmat, BNXT_MAX_MTU, BNXT_MAX_TX_SEGS,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), (9500
), (32), (9500), (0), (0x0000 | 0x0002), (&bs->bs_map)
)
930 BNXT_MAX_MTU, 0, BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), (9500
), (32), (9500), (0), (0x0000 | 0x0002), (&bs->bs_map)
)
931 &bs->bs_map)(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), (9500
), (32), (9500), (0), (0x0000 | 0x0002), (&bs->bs_map)
)
!= 0) {
932 printf("%s: failed to allocate tx dma maps\n",
933 DEVNAME(sc)((sc)->sc_dev.dv_xname));
934 goto destroy_tx_slots;
935 }
936 }
937
938 /*
939 * initially, the rx ring must be filled at least some distance beyond
940 * the current consumer index, as it looks like the firmware assumes the
941 * ring is full on creation, but doesn't prefetch the whole thing.
942 * once the whole ring has been used once, we should be able to back off
943 * to 2 or so slots, but we currently don't have a way of doing that.
944 */
945 if_rxr_init(&rx->rxr[0], 32, rx->rx_ring.ring_size - 1);
946 if_rxr_init(&rx->rxr[1], 32, rx->rx_ag_ring.ring_size - 1);
947 rx->rx_prod = 0;
948 rx->rx_cons = 0;
949 rx->rx_ag_prod = 0;
950 rx->rx_ag_cons = 0;
951 bnxt_rx_fill(bq);
952
953 tx->tx_cons = 0;
954 tx->tx_prod = 0;
955 tx->tx_ring_cons = 0;
956 tx->tx_ring_prod = 0;
957 ifq_clr_oactive(ifp->if_ifqs[bq->q_index]);
958 ifq_restart(ifp->if_ifqs[bq->q_index]);
959 return 0;
960
961destroy_tx_slots:
962 bnxt_free_slots(sc, tx->tx_slots, i, tx->tx_ring.ring_size);
963 tx->tx_slots = NULL((void *)0);
964
965 i = rx->rx_ag_ring.ring_size;
966destroy_rx_ag_slots:
967 bnxt_free_slots(sc, rx->rx_ag_slots, i, rx->rx_ag_ring.ring_size);
968 rx->rx_ag_slots = NULL((void *)0);
969
970 i = rx->rx_ring.ring_size;
971destroy_rx_slots:
972 bnxt_free_slots(sc, rx->rx_slots, i, rx->rx_ring.ring_size);
973 rx->rx_slots = NULL((void *)0);
974dealloc_ring_group:
975 bnxt_hwrm_ring_grp_free(sc, &bq->q_rg);
976dealloc_ag:
977 bnxt_hwrm_ring_free(sc, HWRM_RING_ALLOC_INPUT_RING_TYPE_RX0x2U,
978 &rx->rx_ag_ring);
979dealloc_tx:
980 bnxt_hwrm_ring_free(sc, HWRM_RING_ALLOC_INPUT_RING_TYPE_TX0x1U,
981 &tx->tx_ring);
982dealloc_rx:
983 bnxt_hwrm_ring_free(sc, HWRM_RING_ALLOC_INPUT_RING_TYPE_RX0x2U,
984 &rx->rx_ring);
985dealloc_stats:
986 bnxt_hwrm_stat_ctx_free(sc, cp);
987free_rx:
988 bnxt_dmamem_free(sc, rx->rx_ring_mem);
989 rx->rx_ring_mem = NULL((void *)0);
990free_tx:
991 bnxt_dmamem_free(sc, tx->tx_ring_mem);
992 tx->tx_ring_mem = NULL((void *)0);
993 return ENOMEM12;
994}
995
996void
997bnxt_queue_down(struct bnxt_softc *sc, struct bnxt_queue *bq)
998{
999 struct bnxt_cp_ring *cp = &bq->q_cp;
1000 struct bnxt_rx_queue *rx = &bq->q_rx;
1001 struct bnxt_tx_queue *tx = &bq->q_tx;
1002
1003 /* empty rx ring first i guess */
1004
1005 bnxt_free_slots(sc, tx->tx_slots, tx->tx_ring.ring_size,
1006 tx->tx_ring.ring_size);
1007 tx->tx_slots = NULL((void *)0);
1008
1009 bnxt_free_slots(sc, rx->rx_ag_slots, rx->rx_ag_ring.ring_size,
1010 rx->rx_ag_ring.ring_size);
1011 rx->rx_ag_slots = NULL((void *)0);
1012
1013 bnxt_free_slots(sc, rx->rx_slots, rx->rx_ring.ring_size,
1014 rx->rx_ring.ring_size);
1015 rx->rx_slots = NULL((void *)0);
1016
1017 bnxt_hwrm_ring_grp_free(sc, &bq->q_rg);
1018 bnxt_hwrm_stat_ctx_free(sc, &bq->q_cp);
1019
1020 /* may need to wait for 500ms here before we can free the rings */
1021
1022 bnxt_hwrm_ring_free(sc, HWRM_RING_ALLOC_INPUT_RING_TYPE_TX0x1U,
1023 &tx->tx_ring);
1024 bnxt_hwrm_ring_free(sc, HWRM_RING_ALLOC_INPUT_RING_TYPE_RX0x2U,
1025 &rx->rx_ag_ring);
1026 bnxt_hwrm_ring_free(sc, HWRM_RING_ALLOC_INPUT_RING_TYPE_RX0x2U,
1027 &rx->rx_ring);
1028
1029 /* if no intrmap, leave cp ring in place for async events */
1030 if (sc->sc_intrmap != NULL((void *)0)) {
1031 bnxt_hwrm_ring_free(sc, HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL0x0U,
1032 &cp->ring);
1033
1034 bnxt_dmamem_free(sc, cp->ring_mem);
1035 cp->ring_mem = NULL((void *)0);
1036 }
1037
1038 bnxt_dmamem_free(sc, rx->rx_ring_mem);
1039 rx->rx_ring_mem = NULL((void *)0);
1040
1041 bnxt_dmamem_free(sc, tx->tx_ring_mem);
1042 tx->tx_ring_mem = NULL((void *)0);
1043}
1044
1045void
1046bnxt_up(struct bnxt_softc *sc)
1047{
1048 struct ifnet *ifp = &sc->sc_ac.ac_if;
1049 int i;
1050
1051 sc->sc_stats_ctx_mem = bnxt_dmamem_alloc(sc,
1052 sizeof(struct ctx_hw_stats) * sc->sc_nqueues);
1053 if (sc->sc_stats_ctx_mem == NULL((void *)0)) {
1054 printf("%s: failed to allocate stats contexts\n", DEVNAME(sc)((sc)->sc_dev.dv_xname));
1055 return;
1056 }
1057
1058 sc->sc_rx_cfg = bnxt_dmamem_alloc(sc, PAGE_SIZE(1 << 12) * 2);
1059 if (sc->sc_rx_cfg == NULL((void *)0)) {
1060 printf("%s: failed to allocate rx config buffer\n",
1061 DEVNAME(sc)((sc)->sc_dev.dv_xname));
1062 goto free_stats;
1063 }
1064
1065 for (i = 0; i < sc->sc_nqueues; i++) {
1066 if (bnxt_queue_up(sc, &sc->sc_queues[i]) != 0) {
1067 goto down_queues;
1068 }
1069 }
1070
1071 sc->sc_vnic.rss_id = (uint16_t)HWRM_NA_SIGNATURE((uint32_t)(-1));
1072 if (bnxt_hwrm_vnic_ctx_alloc(sc, &sc->sc_vnic.rss_id) != 0) {
1073 printf("%s: failed to allocate vnic rss context\n",
1074 DEVNAME(sc)((sc)->sc_dev.dv_xname));
1075 goto down_queues;
1076 }
1077
1078 sc->sc_vnic.id = (uint16_t)HWRM_NA_SIGNATURE((uint32_t)(-1));
1079 sc->sc_vnic.def_ring_grp = sc->sc_queues[0].q_rg.grp_id;
1080 sc->sc_vnic.mru = BNXT_MAX_MTU9500;
1081 sc->sc_vnic.cos_rule = (uint16_t)HWRM_NA_SIGNATURE((uint32_t)(-1));
1082 sc->sc_vnic.lb_rule = (uint16_t)HWRM_NA_SIGNATURE((uint32_t)(-1));
1083 sc->sc_vnic.flags = BNXT_VNIC_FLAG_DEFAULT0x01 |
1084 BNXT_VNIC_FLAG_VLAN_STRIP0x04;
1085 if (bnxt_hwrm_vnic_alloc(sc, &sc->sc_vnic) != 0) {
1086 printf("%s: failed to allocate vnic\n", DEVNAME(sc)((sc)->sc_dev.dv_xname));
1087 goto dealloc_vnic_ctx;
1088 }
1089
1090 if (bnxt_hwrm_vnic_cfg(sc, &sc->sc_vnic) != 0) {
1091 printf("%s: failed to configure vnic\n", DEVNAME(sc)((sc)->sc_dev.dv_xname));
1092 goto dealloc_vnic;
1093 }
1094
1095 if (bnxt_hwrm_vnic_cfg_placement(sc, &sc->sc_vnic) != 0) {
1096 printf("%s: failed to configure vnic placement mode\n",
1097 DEVNAME(sc)((sc)->sc_dev.dv_xname));
1098 goto dealloc_vnic;
1099 }
1100
1101 sc->sc_vnic.filter_id = -1;
1102 if (bnxt_hwrm_set_filter(sc, &sc->sc_vnic) != 0) {
1103 printf("%s: failed to set vnic filter\n", DEVNAME(sc)((sc)->sc_dev.dv_xname));
1104 goto dealloc_vnic;
1105 }
1106
1107 if (sc->sc_nqueues > 1) {
1108 uint16_t *rss_table = (BNXT_DMA_KVA(sc->sc_rx_cfg)((void *)(sc->sc_rx_cfg)->bdm_kva) + PAGE_SIZE(1 << 12));
1109 uint8_t *hash_key = (uint8_t *)(rss_table + HW_HASH_INDEX_SIZE0x80);
1110
1111 for (i = 0; i < HW_HASH_INDEX_SIZE0x80; i++) {
1112 struct bnxt_queue *bq;
1113
1114 bq = &sc->sc_queues[i % sc->sc_nqueues];
1115 rss_table[i] = htole16(bq->q_rg.grp_id)((__uint16_t)(bq->q_rg.grp_id));
1116 }
1117 stoeplitz_to_key(hash_key, HW_HASH_KEY_SIZE40);
1118
1119 if (bnxt_hwrm_vnic_rss_cfg(sc, &sc->sc_vnic,
1120 HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV40x1U |
1121 HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV40x2U |
1122 HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV60x8U |
1123 HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV60x10U,
1124 BNXT_DMA_DVA(sc->sc_rx_cfg)((u_int64_t)(sc->sc_rx_cfg)->bdm_map->dm_segs[0].ds_addr
)
+ PAGE_SIZE(1 << 12),
1125 BNXT_DMA_DVA(sc->sc_rx_cfg)((u_int64_t)(sc->sc_rx_cfg)->bdm_map->dm_segs[0].ds_addr
)
+ PAGE_SIZE(1 << 12) +
1126 (HW_HASH_INDEX_SIZE0x80 * sizeof(uint16_t))) != 0) {
1127 printf("%s: failed to set RSS config\n", DEVNAME(sc)((sc)->sc_dev.dv_xname));
1128 goto dealloc_vnic;
1129 }
1130 }
1131
1132 bnxt_iff(sc);
1133 SET(ifp->if_flags, IFF_RUNNING)((ifp->if_flags) |= (0x40));
1134
1135 return;
1136
1137dealloc_vnic:
1138 bnxt_hwrm_vnic_free(sc, &sc->sc_vnic);
1139dealloc_vnic_ctx:
1140 bnxt_hwrm_vnic_ctx_free(sc, &sc->sc_vnic.rss_id);
1141down_queues:
1142 for (i = 0; i < sc->sc_nqueues; i++)
1143 bnxt_queue_down(sc, &sc->sc_queues[i]);
1144
1145 bnxt_dmamem_free(sc, sc->sc_rx_cfg);
1146 sc->sc_rx_cfg = NULL((void *)0);
1147free_stats:
1148 bnxt_dmamem_free(sc, sc->sc_stats_ctx_mem);
1149 sc->sc_stats_ctx_mem = NULL((void *)0);
1150}
1151
1152void
1153bnxt_down(struct bnxt_softc *sc)
1154{
1155 struct ifnet *ifp = &sc->sc_ac.ac_if;
1156 int i;
1157
1158 CLR(ifp->if_flags, IFF_RUNNING)((ifp->if_flags) &= ~(0x40));
1159
1160 for (i = 0; i < sc->sc_nqueues; i++) {
1161 ifq_clr_oactive(ifp->if_ifqs[i]);
1162 ifq_barrier(ifp->if_ifqs[i]);
1163 /* intr barrier? */
1164
1165 timeout_del(&sc->sc_queues[i].q_rx.rx_refill);
1166 }
1167
1168 bnxt_hwrm_free_filter(sc, &sc->sc_vnic);
1169 bnxt_hwrm_vnic_free(sc, &sc->sc_vnic);
1170 bnxt_hwrm_vnic_ctx_free(sc, &sc->sc_vnic.rss_id);
1171
1172 for (i = 0; i < sc->sc_nqueues; i++)
1173 bnxt_queue_down(sc, &sc->sc_queues[i]);
1174
1175 bnxt_dmamem_free(sc, sc->sc_rx_cfg);
1176 sc->sc_rx_cfg = NULL((void *)0);
1177
1178 bnxt_dmamem_free(sc, sc->sc_stats_ctx_mem);
1179 sc->sc_stats_ctx_mem = NULL((void *)0);
1180}
1181
1182void
1183bnxt_iff(struct bnxt_softc *sc)
1184{
1185 struct ifnet *ifp = &sc->sc_ac.ac_if;
1186 struct ether_multi *enm;
1187 struct ether_multistep step;
1188 char *mc_list;
1189 uint32_t rx_mask, mc_count;
1190
1191 rx_mask = HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_BCAST0x8U
1192 | HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_MCAST0x2U
1193 | HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ANYVLAN_NONVLAN0x100U;
1194
1195 mc_list = BNXT_DMA_KVA(sc->sc_rx_cfg)((void *)(sc->sc_rx_cfg)->bdm_kva);
1196 mc_count = 0;
1197
1198 if (ifp->if_flags & IFF_PROMISC0x100) {
1199 SET(ifp->if_flags, IFF_ALLMULTI)((ifp->if_flags) |= (0x200));
1200 rx_mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_PROMISCUOUS0x10U;
1201 } else if ((sc->sc_ac.ac_multirangecnt > 0) ||
1202 (sc->sc_ac.ac_multicnt > (PAGE_SIZE(1 << 12) / ETHER_ADDR_LEN6))) {
1203 SET(ifp->if_flags, IFF_ALLMULTI)((ifp->if_flags) |= (0x200));
1204 rx_mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ALL_MCAST0x4U;
1205 } else {
1206 CLR(ifp->if_flags, IFF_ALLMULTI)((ifp->if_flags) &= ~(0x200));
1207 ETHER_FIRST_MULTI(step, &sc->sc_ac, enm)do { (step).e_enm = ((&(&sc->sc_ac)->ac_multiaddrs
)->lh_first); do { if ((((enm)) = ((step)).e_enm) != ((void
*)0)) ((step)).e_enm = ((((enm)))->enm_list.le_next); } while
( 0); } while ( 0)
;
1208 while (enm != NULL((void *)0)) {
1209 memcpy(mc_list, enm->enm_addrlo, ETHER_ADDR_LEN)__builtin_memcpy((mc_list), (enm->enm_addrlo), (6));
1210 mc_list += ETHER_ADDR_LEN6;
1211 mc_count++;
1212
1213 ETHER_NEXT_MULTI(step, enm)do { if (((enm) = (step).e_enm) != ((void *)0)) (step).e_enm =
(((enm))->enm_list.le_next); } while ( 0)
;
1214 }
1215 }
1216
1217 bnxt_hwrm_cfa_l2_set_rx_mask(sc, sc->sc_vnic.id, rx_mask,
1218 BNXT_DMA_DVA(sc->sc_rx_cfg)((u_int64_t)(sc->sc_rx_cfg)->bdm_map->dm_segs[0].ds_addr
)
, mc_count);
1219}
1220
1221int
1222bnxt_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1223{
1224 struct bnxt_softc *sc = (struct bnxt_softc *)ifp->if_softc;
1225 struct ifreq *ifr = (struct ifreq *)data;
1226 int s, error = 0;
1227
1228 s = splnet()splraise(0x7);
1229 switch (cmd) {
1230 case SIOCSIFADDR((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((12)))
:
1231 ifp->if_flags |= IFF_UP0x1;
1232 /* FALLTHROUGH */
1233
1234 case SIOCSIFFLAGS((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((16)))
:
1235 if (ISSET(ifp->if_flags, IFF_UP)((ifp->if_flags) & (0x1))) {
1236 if (ISSET(ifp->if_flags, IFF_RUNNING)((ifp->if_flags) & (0x40)))
1237 error = ENETRESET52;
1238 else
1239 bnxt_up(sc);
1240 } else {
1241 if (ISSET(ifp->if_flags, IFF_RUNNING)((ifp->if_flags) & (0x40)))
1242 bnxt_down(sc);
1243 }
1244 break;
1245
1246 case SIOCGIFMEDIA(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifmediareq) & 0x1fff) << 16) | ((('i')) <<
8) | ((56)))
:
1247 case SIOCSIFMEDIA(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((55)))
:
1248 error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
1249 break;
1250
1251 case SIOCGIFRXR((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((170)))
:
1252 error = bnxt_rxrinfo(sc, (struct if_rxrinfo *)ifr->ifr_dataifr_ifru.ifru_data);
1253 break;
1254
1255 case SIOCGIFSFFPAGE(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct if_sffpage) & 0x1fff) << 16) | ((('i')) <<
8) | ((57)))
:
1256 error = bnxt_get_sffpage(sc, (struct if_sffpage *)data);
1257 break;
1258
1259 default:
1260 error = ether_ioctl(ifp, &sc->sc_ac, cmd, data);
1261 }
1262
1263 if (error == ENETRESET52) {
1264 if ((ifp->if_flags & (IFF_UP0x1 | IFF_RUNNING0x40)) ==
1265 (IFF_UP0x1 | IFF_RUNNING0x40))
1266 bnxt_iff(sc);
1267 error = 0;
1268 }
1269
1270 splx(s)spllower(s);
1271
1272 return (error);
1273}
1274
1275int
1276bnxt_rxrinfo(struct bnxt_softc *sc, struct if_rxrinfo *ifri)
1277{
1278 struct if_rxring_info *ifr;
1279 int i;
1280 int error;
1281
1282 ifr = mallocarray(sc->sc_nqueues * 2, sizeof(*ifr), M_TEMP127,
1283 M_WAITOK0x0001 | M_ZERO0x0008 | M_CANFAIL0x0004);
1284 if (ifr == NULL((void *)0))
1285 return (ENOMEM12);
1286
1287 for (i = 0; i < sc->sc_nqueues; i++) {
1288 ifr[(i * 2)].ifr_size = MCLBYTES(1 << 11);
1289 ifr[(i * 2)].ifr_info = sc->sc_queues[i].q_rx.rxr[0];
1290
1291 ifr[(i * 2) + 1].ifr_size = BNXT_AG_BUFFER_SIZE8192;
1292 ifr[(i * 2) + 1].ifr_info = sc->sc_queues[i].q_rx.rxr[1];
1293 }
1294
1295 error = if_rxr_info_ioctl(ifri, sc->sc_nqueues * 2, ifr);
1296 free(ifr, M_TEMP127, sc->sc_nqueues * 2 * sizeof(*ifr));
1297
1298 return (error);
1299}
1300
1301int
1302bnxt_load_mbuf(struct bnxt_softc *sc, struct bnxt_slot *bs, struct mbuf *m)
1303{
1304 switch (bus_dmamap_load_mbuf(sc->sc_dmat, bs->bs_map, m,(*(sc->sc_dmat)->_dmamap_load_mbuf)((sc->sc_dmat), (
bs->bs_map), (m), (0x0100 | 0x0001))
1305 BUS_DMA_STREAMING | BUS_DMA_NOWAIT)(*(sc->sc_dmat)->_dmamap_load_mbuf)((sc->sc_dmat), (
bs->bs_map), (m), (0x0100 | 0x0001))
) {
1306 case 0:
1307 break;
1308
1309 case EFBIG27:
1310 if (m_defrag(m, M_DONTWAIT0x0002) == 0 &&
1311 bus_dmamap_load_mbuf(sc->sc_dmat, bs->bs_map, m,(*(sc->sc_dmat)->_dmamap_load_mbuf)((sc->sc_dmat), (
bs->bs_map), (m), (0x0100 | 0x0001))
1312 BUS_DMA_STREAMING | BUS_DMA_NOWAIT)(*(sc->sc_dmat)->_dmamap_load_mbuf)((sc->sc_dmat), (
bs->bs_map), (m), (0x0100 | 0x0001))
== 0)
1313 break;
1314
1315 default:
1316 return (1);
1317 }
1318
1319 bs->bs_m = m;
1320 return (0);
1321}
1322
1323void
1324bnxt_start(struct ifqueue *ifq)
1325{
1326 struct ifnet *ifp = ifq->ifq_if;
1327 struct tx_bd_short *txring;
1328 struct tx_bd_long_hi *txhi;
1329 struct bnxt_tx_queue *tx = ifq->ifq_softc_ifq_ptr._ifq_softc;
1330 struct bnxt_softc *sc = tx->tx_softc;
1331 struct bnxt_slot *bs;
1332 bus_dmamap_t map;
1333 struct mbuf *m;
1334 u_int idx, free, used, laststart;
1335 uint16_t txflags;
1336 int i;
1337
1338 txring = (struct tx_bd_short *)BNXT_DMA_KVA(tx->tx_ring_mem)((void *)(tx->tx_ring_mem)->bdm_kva);
1339
1340 idx = tx->tx_ring_prod;
1341 free = tx->tx_ring_cons;
1342 if (free <= idx)
1343 free += tx->tx_ring.ring_size;
1344 free -= idx;
1345
1346 used = 0;
1347
1348 for (;;) {
1349 /* +1 for tx_bd_long_hi */
1350 if (used + BNXT_MAX_TX_SEGS32 + 1 > free) {
1351 ifq_set_oactive(ifq);
1352 break;
1353 }
1354
1355 m = ifq_dequeue(ifq);
1356 if (m == NULL((void *)0))
1357 break;
1358
1359 bs = &tx->tx_slots[tx->tx_prod];
1360 if (bnxt_load_mbuf(sc, bs, m) != 0) {
1361 m_freem(m);
1362 ifp->if_oerrorsif_data.ifi_oerrors++;
1363 continue;
1364 }
1365
1366#if NBPFILTER1 > 0
1367 if (ifp->if_bpf)
1368 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT(1 << 1));
1369#endif
1370 map = bs->bs_map;
1371 bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (map),
(0), (map->dm_mapsize), (0x04))
1372 BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (map),
(0), (map->dm_mapsize), (0x04))
;
1373 used += BNXT_TX_SLOTS(bs)(bs->bs_map->dm_nsegs + 1);
1374
1375 /* first segment */
1376 laststart = idx;
1377 txring[idx].len = htole16(map->dm_segs[0].ds_len)((__uint16_t)(map->dm_segs[0].ds_len));
1378 txring[idx].opaque = tx->tx_prod;
1379 txring[idx].addr = htole64(map->dm_segs[0].ds_addr)((__uint64_t)(map->dm_segs[0].ds_addr));
1380
1381 if (map->dm_mapsize < 512)
1382 txflags = TX_BD_LONG_FLAGS_LHINT_LT512(0x0U << 13);
1383 else if (map->dm_mapsize < 1024)
1384 txflags = TX_BD_LONG_FLAGS_LHINT_LT1K(0x1U << 13);
1385 else if (map->dm_mapsize < 2048)
1386 txflags = TX_BD_LONG_FLAGS_LHINT_LT2K(0x2U << 13);
1387 else
1388 txflags = TX_BD_LONG_FLAGS_LHINT_GTE2K(0x3U << 13);
1389 txflags |= TX_BD_LONG_TYPE_TX_BD_LONG0x10U |
1390 TX_BD_LONG_FLAGS_NO_CMPL0x80U |
1391 (BNXT_TX_SLOTS(bs)(bs->bs_map->dm_nsegs + 1) << TX_BD_LONG_FLAGS_BD_CNT_SFT8);
1392 if (map->dm_nsegs == 1)
1393 txflags |= TX_BD_SHORT_FLAGS_PACKET_END0x40U;
1394 txring[idx].flags_type = htole16(txflags)((__uint16_t)(txflags));
1395
1396 idx++;
1397 if (idx == tx->tx_ring.ring_size)
1398 idx = 0;
1399
1400 /* long tx descriptor */
1401 txhi = (struct tx_bd_long_hi *)&txring[idx];
1402 memset(txhi, 0, sizeof(*txhi))__builtin_memset((txhi), (0), (sizeof(*txhi)));
1403 txflags = 0;
1404 if (m->m_pkthdrM_dat.MH.MH_pkthdr.csum_flags & (M_UDP_CSUM_OUT0x0004 | M_TCP_CSUM_OUT0x0002))
1405 txflags |= TX_BD_LONG_LFLAGS_TCP_UDP_CHKSUM0x1U;
1406 if (m->m_pkthdrM_dat.MH.MH_pkthdr.csum_flags & M_IPV4_CSUM_OUT0x0001)
1407 txflags |= TX_BD_LONG_LFLAGS_IP_CHKSUM0x2U;
1408 txhi->lflags = htole16(txflags)((__uint16_t)(txflags));
1409
1410#if NVLAN1 > 0
1411 if (m->m_flagsm_hdr.mh_flags & M_VLANTAG0x0020) {
1412 txhi->cfa_meta = htole32(m->m_pkthdr.ether_vtag |((__uint32_t)(m->M_dat.MH.MH_pkthdr.ether_vtag | (0x1U <<
16) | (0x1U << 28)))
1413 TX_BD_LONG_CFA_META_VLAN_TPID_TPID8100 |((__uint32_t)(m->M_dat.MH.MH_pkthdr.ether_vtag | (0x1U <<
16) | (0x1U << 28)))
1414 TX_BD_LONG_CFA_META_KEY_VLAN_TAG)((__uint32_t)(m->M_dat.MH.MH_pkthdr.ether_vtag | (0x1U <<
16) | (0x1U << 28)))
;
1415 }
1416#endif
1417
1418 idx++;
1419 if (idx == tx->tx_ring.ring_size)
1420 idx = 0;
1421
1422 /* remaining segments */
1423 txflags = TX_BD_SHORT_TYPE_TX_BD_SHORT0x0U;
1424 for (i = 1; i < map->dm_nsegs; i++) {
1425 if (i == map->dm_nsegs - 1)
1426 txflags |= TX_BD_SHORT_FLAGS_PACKET_END0x40U;
1427 txring[idx].flags_type = htole16(txflags)((__uint16_t)(txflags));
1428
1429 txring[idx].len =
1430 htole16(bs->bs_map->dm_segs[i].ds_len)((__uint16_t)(bs->bs_map->dm_segs[i].ds_len));
1431 txring[idx].opaque = tx->tx_prod;
1432 txring[idx].addr =
1433 htole64(bs->bs_map->dm_segs[i].ds_addr)((__uint64_t)(bs->bs_map->dm_segs[i].ds_addr));
1434
1435 idx++;
1436 if (idx == tx->tx_ring.ring_size)
1437 idx = 0;
1438 }
1439
1440 if (++tx->tx_prod >= tx->tx_ring.ring_size)
1441 tx->tx_prod = 0;
1442 }
1443
1444 /* unset NO_CMPL on the first bd of the last packet */
1445 if (used != 0) {
1446 txring[laststart].flags_type &=
1447 ~htole16(TX_BD_SHORT_FLAGS_NO_CMPL)((__uint16_t)(0x80U));
1448 }
1449
1450 bnxt_write_tx_doorbell(sc, &tx->tx_ring, idx);
1451 tx->tx_ring_prod = idx;
1452}
1453
1454void
1455bnxt_handle_async_event(struct bnxt_softc *sc, struct cmpl_base *cmpl)
1456{
1457 struct hwrm_async_event_cmpl *ae = (struct hwrm_async_event_cmpl *)cmpl;
1458 uint16_t type = le16toh(ae->event_id)((__uint16_t)(ae->event_id));
1459
1460 switch (type) {
1461 case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_STATUS_CHANGE0x0U:
1462 case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CHANGE0x2U:
1463 case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE0x6U:
1464 bnxt_hwrm_port_phy_qcfg(sc, NULL((void *)0));
1465 break;
1466
1467 default:
1468 printf("%s: unexpected async event %x\n", DEVNAME(sc)((sc)->sc_dev.dv_xname), type);
1469 break;
1470 }
1471}
1472
1473struct cmpl_base *
1474bnxt_cpr_next_cmpl(struct bnxt_softc *sc, struct bnxt_cp_ring *cpr)
1475{
1476 struct cmpl_base *cmpl;
1477 uint32_t cons;
1478 int v_bit;
1479
1480 cons = cpr->cons + 1;
1481 v_bit = cpr->v_bit;
1482 if (cons == cpr->ring.ring_size) {
1483 cons = 0;
1484 v_bit = !v_bit;
1485 }
1486 cmpl = &((struct cmpl_base *)cpr->ring.vaddr)[cons];
1487
1488 if ((!!(cmpl->info3_v & htole32(CMPL_BASE_V)((__uint32_t)(0x1U)))) != (!!v_bit))
1489 return (NULL((void *)0));
1490
1491 cpr->cons = cons;
1492 cpr->v_bit = v_bit;
1493 return (cmpl);
1494}
1495
1496void
1497bnxt_cpr_commit(struct bnxt_softc *sc, struct bnxt_cp_ring *cpr)
1498{
1499 cpr->commit_cons = cpr->cons;
1500 cpr->commit_v_bit = cpr->v_bit;
1501}
1502
1503void
1504bnxt_cpr_rollback(struct bnxt_softc *sc, struct bnxt_cp_ring *cpr)
1505{
1506 cpr->cons = cpr->commit_cons;
1507 cpr->v_bit = cpr->commit_v_bit;
1508}
1509
1510int
1511bnxt_admin_intr(void *xsc)
1512{
1513 struct bnxt_softc *sc = (struct bnxt_softc *)xsc;
1514 struct bnxt_cp_ring *cpr = &sc->sc_cp_ring;
1515 struct cmpl_base *cmpl;
1516 uint16_t type;
1517
1518 bnxt_write_cp_doorbell(sc, &cpr->ring, 0);
1519 cmpl = bnxt_cpr_next_cmpl(sc, cpr);
1520 while (cmpl != NULL((void *)0)) {
1521 type = le16toh(cmpl->type)((__uint16_t)(cmpl->type)) & CMPL_BASE_TYPE_MASK0x3fU;
1522 switch (type) {
1523 case CMPL_BASE_TYPE_HWRM_ASYNC_EVENT0x2eU:
1524 bnxt_handle_async_event(sc, cmpl);
1525 break;
1526 default:
1527 printf("%s: unexpected completion type %u\n",
1528 DEVNAME(sc)((sc)->sc_dev.dv_xname), type);
1529 }
1530
1531 bnxt_cpr_commit(sc, cpr);
1532 cmpl = bnxt_cpr_next_cmpl(sc, cpr);
1533 }
1534
1535 bnxt_write_cp_doorbell_index(sc, &cpr->ring,
1536 (cpr->commit_cons+1) % cpr->ring.ring_size, 1);
1537 return (1);
1538}
1539
1540int
1541bnxt_intr(void *xq)
1542{
1543 struct bnxt_queue *q = (struct bnxt_queue *)xq;
1544 struct bnxt_softc *sc = q->q_sc;
1545 struct bnxt_cp_ring *cpr = &q->q_cp;
1546 struct bnxt_rx_queue *rx = &q->q_rx;
1547 struct bnxt_tx_queue *tx = &q->q_tx;
1548 struct cmpl_base *cmpl;
1549 struct mbuf_list ml = MBUF_LIST_INITIALIZER(){ ((void *)0), ((void *)0), 0 };
1550 uint16_t type;
1551 int rxfree, txfree, agfree, rv, rollback;
1552
1553 bnxt_write_cp_doorbell(sc, &cpr->ring, 0);
1554 rxfree = 0;
1555 txfree = 0;
1556 agfree = 0;
1557 rv = -1;
1558 cmpl = bnxt_cpr_next_cmpl(sc, cpr);
1559 while (cmpl != NULL((void *)0)) {
1560 type = le16toh(cmpl->type)((__uint16_t)(cmpl->type)) & CMPL_BASE_TYPE_MASK0x3fU;
1561 rollback = 0;
1562 switch (type) {
1563 case CMPL_BASE_TYPE_HWRM_ASYNC_EVENT0x2eU:
1564 bnxt_handle_async_event(sc, cmpl);
1565 break;
1566 case CMPL_BASE_TYPE_RX_L20x11U:
1567 rollback = bnxt_rx(sc, rx, cpr, &ml, &rxfree, &agfree, cmpl);
1568 break;
1569 case CMPL_BASE_TYPE_TX_L20x0U:
1570 bnxt_txeof(sc, tx, &txfree, cmpl);
1571 break;
1572 default:
1573 printf("%s: unexpected completion type %u\n",
1574 DEVNAME(sc)((sc)->sc_dev.dv_xname), type);
1575 }
1576
1577 if (rollback) {
1578 bnxt_cpr_rollback(sc, cpr);
1579 break;
1580 }
1581 rv = 1;
1582 bnxt_cpr_commit(sc, cpr);
1583 cmpl = bnxt_cpr_next_cmpl(sc, cpr);
1584 }
1585
1586 /*
1587 * comments in bnxtreg.h suggest we should be writing cpr->cons here,
1588 * but writing cpr->cons + 1 makes it stop interrupting.
1589 */
1590 bnxt_write_cp_doorbell_index(sc, &cpr->ring,
1591 (cpr->commit_cons+1) % cpr->ring.ring_size, 1);
1592
1593 if (rxfree != 0) {
1594 rx->rx_cons += rxfree;
1595 if (rx->rx_cons >= rx->rx_ring.ring_size)
1596 rx->rx_cons -= rx->rx_ring.ring_size;
1597
1598 rx->rx_ag_cons += agfree;
1599 if (rx->rx_ag_cons >= rx->rx_ag_ring.ring_size)
1600 rx->rx_ag_cons -= rx->rx_ag_ring.ring_size;
1601
1602 if_rxr_put(&rx->rxr[0], rxfree)do { (&rx->rxr[0])->rxr_alive -= (rxfree); } while (
0)
;
1603 if_rxr_put(&rx->rxr[1], agfree)do { (&rx->rxr[1])->rxr_alive -= (agfree); } while (
0)
;
1604
1605 if (ifiq_input(rx->rx_ifiq, &ml)) {
1606 if_rxr_livelocked(&rx->rxr[0]);
1607 if_rxr_livelocked(&rx->rxr[1]);
1608 }
1609
1610 bnxt_rx_fill(q);
1611 if ((rx->rx_cons == rx->rx_prod) ||
1612 (rx->rx_ag_cons == rx->rx_ag_prod))
1613 timeout_add(&rx->rx_refill, 0);
1614 }
1615 if (txfree != 0) {
1616 if (ifq_is_oactive(tx->tx_ifq))
1617 ifq_restart(tx->tx_ifq);
1618 }
1619 return (rv);
1620}
1621
1622void
1623bnxt_watchdog(struct ifnet *ifp)
1624{
1625}
1626
1627void
1628bnxt_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
1629{
1630 struct bnxt_softc *sc = (struct bnxt_softc *)ifp->if_softc;
1631 bnxt_hwrm_port_phy_qcfg(sc, ifmr);
1632}
1633
1634uint64_t
1635bnxt_get_media_type(uint64_t speed, int phy_type)
1636{
1637 switch (phy_type) {
1638 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_UNKNOWN0x0U:
1639 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASECR0x1U:
1640 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_25G_BASECR_CA_L0xbU:
1641 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_25G_BASECR_CA_S0xcU:
1642 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_25G_BASECR_CA_N0xdU:
1643 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASECR40xfU:
1644 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_BASECR40x14U:
1645 switch (speed) {
1646 case IF_Gbps(1)((((((1) * 1000ULL) * 1000ULL) * 1000ULL))):
1647 return IFM_1000_T16;
1648 case IF_Gbps(10)((((((10) * 1000ULL) * 1000ULL) * 1000ULL))):
1649 return IFM_10G_SFP_CU23;
1650 case IF_Gbps(25)((((((25) * 1000ULL) * 1000ULL) * 1000ULL))):
1651 return IFM_25G_CR47;
1652 case IF_Gbps(40)((((((40) * 1000ULL) * 1000ULL) * 1000ULL))):
1653 return IFM_40G_CR425;
1654 case IF_Gbps(50)((((((50) * 1000ULL) * 1000ULL) * 1000ULL))):
1655 return IFM_50G_CR250;
1656 case IF_Gbps(100)((((((100) * 1000ULL) * 1000ULL) * 1000ULL))):
1657 return IFM_100G_CR442;
1658 }
1659 break;
1660
1661 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASELR0x3U:
1662 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASELR40x11U:
1663 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_BASELR40x16U:
1664 switch (speed) {
1665 case IF_Gbps(1)((((((1) * 1000ULL) * 1000ULL) * 1000ULL))):
1666 return IFM_1000_LX14;
1667 case IF_Gbps(10)((((((10) * 1000ULL) * 1000ULL) * 1000ULL))):
1668 return IFM_10G_LR18;
1669 case IF_Gbps(25)((((((25) * 1000ULL) * 1000ULL) * 1000ULL))):
1670 return IFM_25G_LR52;
1671 case IF_Gbps(40)((((((40) * 1000ULL) * 1000ULL) * 1000ULL))):
1672 return IFM_40G_LR427;
1673 case IF_Gbps(100)((((((100) * 1000ULL) * 1000ULL) * 1000ULL))):
1674 return IFM_100G_LR445;
1675 }
1676 break;
1677
1678 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASESR0x4U:
1679 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_25G_BASESR0xeU:
1680 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASESR40x10U:
1681 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASESR100x13U:
1682 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_1G_BASESX0x1aU:
1683 switch (speed) {
1684 case IF_Gbps(1)((((((1) * 1000ULL) * 1000ULL) * 1000ULL))):
1685 return IFM_1000_SX11;
1686 case IF_Gbps(10)((((((10) * 1000ULL) * 1000ULL) * 1000ULL))):
1687 return IFM_10G_SR19;
1688 case IF_Gbps(25)((((((25) * 1000ULL) * 1000ULL) * 1000ULL))):
1689 return IFM_25G_SR49;
1690 case IF_Gbps(40)((((((40) * 1000ULL) * 1000ULL) * 1000ULL))):
1691 return IFM_40G_SR426;
1692 case IF_Gbps(100)((((((100) * 1000ULL) * 1000ULL) * 1000ULL))):
1693 return IFM_100G_SR443;
1694 }
1695 break;
1696
1697 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASEER40x12U:
1698 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_BASEER40x17U:
1699 switch (speed) {
1700 case IF_Gbps(10)((((((10) * 1000ULL) * 1000ULL) * 1000ULL))):
1701 return IFM_10G_ER41;
1702 case IF_Gbps(25)((((((25) * 1000ULL) * 1000ULL) * 1000ULL))):
1703 return IFM_25G_ER53;
1704 }
1705 /* missing IFM_40G_ER4, IFM_100G_ER4 */
1706 break;
1707
1708 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR40x2U:
1709 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR20x5U:
1710 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR0x7U:
1711 switch (speed) {
1712 case IF_Gbps(10)((((((10) * 1000ULL) * 1000ULL) * 1000ULL))):
1713 return IFM_10G_KR30;
1714 case IF_Gbps(20)((((((20) * 1000ULL) * 1000ULL) * 1000ULL))):
1715 return IFM_20G_KR232;
1716 case IF_Gbps(25)((((((25) * 1000ULL) * 1000ULL) * 1000ULL))):
1717 return IFM_25G_KR48;
1718 case IF_Gbps(40)((((((40) * 1000ULL) * 1000ULL) * 1000ULL))):
1719 return IFM_40G_KR440;
1720 case IF_Gbps(50)((((((50) * 1000ULL) * 1000ULL) * 1000ULL))):
1721 return IFM_50G_KR251;
1722 case IF_Gbps(100)((((((100) * 1000ULL) * 1000ULL) * 1000ULL))):
1723 return IFM_100G_KR444;
1724 }
1725 break;
1726
1727 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKX0x6U:
1728 switch (speed) {
1729 case IF_Gbps(1)((((((1) * 1000ULL) * 1000ULL) * 1000ULL))):
1730 return IFM_1000_KX28;
1731 case IF_Mbps(2500)((((2500) * 1000ULL) * 1000ULL)):
1732 return IFM_2500_KX33;
1733 case IF_Gbps(10)((((((10) * 1000ULL) * 1000ULL) * 1000ULL))):
1734 return IFM_10G_KX429;
1735 }
1736 break;
1737
1738 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASET0x8U:
1739 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASETE0x9U:
1740 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_1G_BASET0x19U:
1741 switch (speed) {
1742 case IF_Mbps(10)((((10) * 1000ULL) * 1000ULL)):
1743 return IFM_10_T3;
1744 case IF_Mbps(100)((((100) * 1000ULL) * 1000ULL)):
1745 return IFM_100_TX6;
1746 case IF_Gbps(1)((((((1) * 1000ULL) * 1000ULL) * 1000ULL))):
1747 return IFM_1000_T16;
1748 case IF_Mbps(2500)((((2500) * 1000ULL) * 1000ULL)):
1749 return IFM_2500_T34;
1750 case IF_Gbps(10)((((((10) * 1000ULL) * 1000ULL) * 1000ULL))):
1751 return IFM_10G_T22;
1752 }
1753 break;
1754
1755 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_SGMIIEXTPHY0xaU:
1756 switch (speed) {
1757 case IF_Gbps(1)((((((1) * 1000ULL) * 1000ULL) * 1000ULL))):
1758 return IFM_1000_SGMII36;
1759 }
1760 break;
1761
1762 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_ACTIVE_CABLE0x18U:
1763 switch (speed) {
1764 case IF_Gbps(10)((((((10) * 1000ULL) * 1000ULL) * 1000ULL))):
1765 return IFM_10G_AOC54;
1766 case IF_Gbps(25)((((((25) * 1000ULL) * 1000ULL) * 1000ULL))):
1767 return IFM_25G_AOC55;
1768 case IF_Gbps(40)((((((40) * 1000ULL) * 1000ULL) * 1000ULL))):
1769 return IFM_40G_AOC56;
1770 case IF_Gbps(100)((((((100) * 1000ULL) * 1000ULL) * 1000ULL))):
1771 return IFM_100G_AOC57;
1772 }
1773 break;
1774 }
1775
1776 return 0;
1777}
1778
1779void
1780bnxt_add_media_type(struct bnxt_softc *sc, int supported_speeds, uint64_t speed, uint64_t ifmt)
1781{
1782 int speed_bit = 0;
1783 switch (speed) {
1784 case IF_Gbps(1)((((((1) * 1000ULL) * 1000ULL) * 1000ULL))):
1785 speed_bit = HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_1GB0x8U;
1786 break;
1787 case IF_Gbps(2)((((((2) * 1000ULL) * 1000ULL) * 1000ULL))):
1788 speed_bit = HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_2GB0x10U;
1789 break;
1790 case IF_Mbps(2500)((((2500) * 1000ULL) * 1000ULL)):
1791 speed_bit = HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_2_5GB0x20U;
1792 break;
1793 case IF_Gbps(10)((((((10) * 1000ULL) * 1000ULL) * 1000ULL))):
1794 speed_bit = HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_10GB0x40U;
1795 break;
1796 case IF_Gbps(20)((((((20) * 1000ULL) * 1000ULL) * 1000ULL))):
1797 speed_bit = HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_20GB0x80U;
1798 break;
1799 case IF_Gbps(25)((((((25) * 1000ULL) * 1000ULL) * 1000ULL))):
1800 speed_bit = HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_25GB0x100U;
1801 break;
1802 case IF_Gbps(40)((((((40) * 1000ULL) * 1000ULL) * 1000ULL))):
1803 speed_bit = HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_40GB0x200U;
1804 break;
1805 case IF_Gbps(50)((((((50) * 1000ULL) * 1000ULL) * 1000ULL))):
1806 speed_bit = HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_50GB0x400U;
1807 break;
1808 case IF_Gbps(100)((((((100) * 1000ULL) * 1000ULL) * 1000ULL))):
1809 speed_bit = HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_100GB0x800U;
1810 break;
1811 }
1812 if (supported_speeds & speed_bit)
1813 ifmedia_add(&sc->sc_media, IFM_ETHER0x0000000000000100ULL | ifmt, 0, NULL((void *)0));
1814}
1815
1816int
1817bnxt_hwrm_port_phy_qcfg(struct bnxt_softc *softc, struct ifmediareq *ifmr)
1818{
1819 struct ifnet *ifp = &softc->sc_ac.ac_if;
1820 struct hwrm_port_phy_qcfg_input req = {0};
1821 struct hwrm_port_phy_qcfg_output *resp =
1822 BNXT_DMA_KVA(softc->sc_cmd_resp)((void *)(softc->sc_cmd_resp)->bdm_kva);
1823 int link_state = LINK_STATE_DOWN2;
1824 uint64_t speeds[] = {
1825 IF_Gbps(1)((((((1) * 1000ULL) * 1000ULL) * 1000ULL))), IF_Gbps(2)((((((2) * 1000ULL) * 1000ULL) * 1000ULL))), IF_Mbps(2500)((((2500) * 1000ULL) * 1000ULL)), IF_Gbps(10)((((((10) * 1000ULL) * 1000ULL) * 1000ULL))), IF_Gbps(20)((((((20) * 1000ULL) * 1000ULL) * 1000ULL))),
1826 IF_Gbps(25)((((((25) * 1000ULL) * 1000ULL) * 1000ULL))), IF_Gbps(40)((((((40) * 1000ULL) * 1000ULL) * 1000ULL))), IF_Gbps(50)((((((50) * 1000ULL) * 1000ULL) * 1000ULL))), IF_Gbps(100)((((((100) * 1000ULL) * 1000ULL) * 1000ULL)))
1827 };
1828 uint64_t media_type;
1829 int duplex;
1830 int rc = 0;
1831 int i;
1832
1833 BNXT_HWRM_LOCK(softc)mtx_enter(&softc->sc_lock);
1834 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_PORT_PHY_QCFG(0x27U));
1835
1836 rc = _hwrm_send_message(softc, &req, sizeof(req));
1837 if (rc) {
1838 printf("%s: failed to query port phy config\n", DEVNAME(softc)((softc)->sc_dev.dv_xname));
1839 goto exit;
1840 }
1841
1842 if (softc->sc_hwrm_ver > 0x10800)
1843 duplex = resp->duplex_state;
1844 else
1845 duplex = resp->duplex_cfg;
1846
1847 if (resp->link == HWRM_PORT_PHY_QCFG_OUTPUT_LINK_LINK0x2U) {
1848 if (duplex == HWRM_PORT_PHY_QCFG_OUTPUT_DUPLEX_STATE_HALF0x0U)
1849 link_state = LINK_STATE_HALF_DUPLEX5;
1850 else
1851 link_state = LINK_STATE_FULL_DUPLEX6;
1852
1853 switch (resp->link_speed) {
1854 case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_10MB0xffffU:
1855 ifp->if_baudrateif_data.ifi_baudrate = IF_Mbps(10)((((10) * 1000ULL) * 1000ULL));
1856 break;
1857 case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_100MB0x1U:
1858 ifp->if_baudrateif_data.ifi_baudrate = IF_Mbps(100)((((100) * 1000ULL) * 1000ULL));
1859 break;
1860 case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_1GB0xaU:
1861 ifp->if_baudrateif_data.ifi_baudrate = IF_Gbps(1)((((((1) * 1000ULL) * 1000ULL) * 1000ULL)));
1862 break;
1863 case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2GB0x14U:
1864 ifp->if_baudrateif_data.ifi_baudrate = IF_Gbps(2)((((((2) * 1000ULL) * 1000ULL) * 1000ULL)));
1865 break;
1866 case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2_5GB0x19U:
1867 ifp->if_baudrateif_data.ifi_baudrate = IF_Mbps(2500)((((2500) * 1000ULL) * 1000ULL));
1868 break;
1869 case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_10GB0x64U:
1870 ifp->if_baudrateif_data.ifi_baudrate = IF_Gbps(10)((((((10) * 1000ULL) * 1000ULL) * 1000ULL)));
1871 break;
1872 case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_20GB0xc8U:
1873 ifp->if_baudrateif_data.ifi_baudrate = IF_Gbps(20)((((((20) * 1000ULL) * 1000ULL) * 1000ULL)));
1874 break;
1875 case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_25GB0xfaU:
1876 ifp->if_baudrateif_data.ifi_baudrate = IF_Gbps(25)((((((25) * 1000ULL) * 1000ULL) * 1000ULL)));
1877 break;
1878 case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_40GB0x190U:
1879 ifp->if_baudrateif_data.ifi_baudrate = IF_Gbps(40)((((((40) * 1000ULL) * 1000ULL) * 1000ULL)));
1880 break;
1881 case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_50GB0x1f4U:
1882 ifp->if_baudrateif_data.ifi_baudrate = IF_Gbps(50)((((((50) * 1000ULL) * 1000ULL) * 1000ULL)));
1883 break;
1884 case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_100GB0x3e8U:
1885 ifp->if_baudrateif_data.ifi_baudrate = IF_Gbps(100)((((((100) * 1000ULL) * 1000ULL) * 1000ULL)));
1886 break;
1887 }
1888 }
1889
1890 ifmedia_delete_instance(&softc->sc_media, IFM_INST_ANY((uint64_t) -1));
1891 for (i = 0; i < nitems(speeds)(sizeof((speeds)) / sizeof((speeds)[0])); i++) {
1892 media_type = bnxt_get_media_type(speeds[i], resp->phy_type);
1893 if (media_type != 0)
1894 bnxt_add_media_type(softc, resp->support_speeds,
1895 speeds[i], media_type);
1896 }
1897 ifmedia_add(&softc->sc_media, IFM_ETHER0x0000000000000100ULL|IFM_AUTO0ULL, 0, NULL((void *)0));
1898 ifmedia_set(&softc->sc_media, IFM_ETHER0x0000000000000100ULL|IFM_AUTO0ULL);
1899
1900 if (ifmr != NULL((void *)0)) {
1901 ifmr->ifm_status = IFM_AVALID0x0000000000000001ULL;
1902 if (LINK_STATE_IS_UP(ifp->if_link_state)((ifp->if_data.ifi_link_state) >= 4 || (ifp->if_data
.ifi_link_state) == 0)
) {
1903 ifmr->ifm_status |= IFM_ACTIVE0x0000000000000002ULL;
1904 ifmr->ifm_active = IFM_ETHER0x0000000000000100ULL | IFM_AUTO0ULL;
1905 if (resp->pause & HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX0x1U)
1906 ifmr->ifm_active |= IFM_ETH_TXPAUSE0x0000000000040000ULL;
1907 if (resp->pause & HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX0x2U)
1908 ifmr->ifm_active |= IFM_ETH_RXPAUSE0x0000000000020000ULL;
1909 if (duplex == HWRM_PORT_PHY_QCFG_OUTPUT_DUPLEX_STATE_HALF0x0U)
1910 ifmr->ifm_active |= IFM_HDX0x0000020000000000ULL;
1911 else
1912 ifmr->ifm_active |= IFM_FDX0x0000010000000000ULL;
1913
1914 media_type = bnxt_get_media_type(ifp->if_baudrateif_data.ifi_baudrate, resp->phy_type);
1915 if (media_type != 0)
1916 ifmr->ifm_active |= media_type;
1917 }
1918 }
1919
1920exit:
1921 BNXT_HWRM_UNLOCK(softc)mtx_leave(&softc->sc_lock);
1922
1923 if (rc == 0 && (link_state != ifp->if_link_stateif_data.ifi_link_state)) {
1924 ifp->if_link_stateif_data.ifi_link_state = link_state;
1925 if_link_state_change(ifp);
1926 }
1927
1928 return rc;
1929}
1930
1931int
1932bnxt_media_change(struct ifnet *ifp)
1933{
1934 struct bnxt_softc *sc = (struct bnxt_softc *)ifp->if_softc;
1935 struct hwrm_port_phy_cfg_input req = {0};
1936 uint64_t link_speed;
1937
1938 if (IFM_TYPE(sc->sc_media.ifm_media)((sc->sc_media.ifm_media) & 0x000000000000ff00ULL) != IFM_ETHER0x0000000000000100ULL)
1939 return EINVAL22;
1940
1941 if (sc->sc_flags & BNXT_FLAG_NPAR0x0002)
1942 return ENODEV19;
1943
1944 bnxt_hwrm_cmd_hdr_init(sc, &req, HWRM_PORT_PHY_CFG(0x20U));
1945
1946 switch (IFM_SUBTYPE(sc->sc_media.ifm_media)((sc->sc_media.ifm_media) & 0x00000000000000ffULL)) {
1947 case IFM_100G_CR442:
1948 case IFM_100G_SR443:
1949 case IFM_100G_KR444:
1950 case IFM_100G_LR445:
1951 case IFM_100G_AOC57:
1952 link_speed = HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_100GB0x3e8U;
1953 break;
1954
1955 case IFM_50G_CR250:
1956 case IFM_50G_KR251:
1957 link_speed = HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_50GB0x1f4U;
1958 break;
1959
1960 case IFM_40G_CR425:
1961 case IFM_40G_SR426:
1962 case IFM_40G_LR427:
1963 case IFM_40G_KR440:
1964 case IFM_40G_AOC56:
1965 link_speed = HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_40GB0x190U;
1966 break;
1967
1968 case IFM_25G_CR47:
1969 case IFM_25G_KR48:
1970 case IFM_25G_SR49:
1971 case IFM_25G_LR52:
1972 case IFM_25G_ER53:
1973 case IFM_25G_AOC55:
1974 link_speed = HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_25GB0xfaU;
1975 break;
1976
1977 case IFM_10G_LR18:
1978 case IFM_10G_SR19:
1979 case IFM_10G_CX420:
1980 case IFM_10G_T22:
1981 case IFM_10G_SFP_CU23:
1982 case IFM_10G_LRM24:
1983 case IFM_10G_KX429:
1984 case IFM_10G_KR30:
1985 case IFM_10G_CR131:
1986 case IFM_10G_ER41:
1987 case IFM_10G_AOC54:
1988 link_speed = HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_10GB0x64U;
1989 break;
1990
1991 case IFM_2500_SX21:
1992 case IFM_2500_KX33:
1993 case IFM_2500_T34:
1994 link_speed = HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_2_5GB0x19U;
1995 break;
1996
1997 case IFM_1000_T16:
1998 case IFM_1000_LX14:
1999 case IFM_1000_SX11:
2000 case IFM_1000_CX15:
2001 case IFM_1000_KX28:
2002 link_speed = HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_1GB0xaU;
2003 break;
2004
2005 case IFM_100_TX6:
2006 link_speed = HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_100MB0x1U;
2007 break;
2008
2009 default:
2010 link_speed = 0;
2011 }
2012
2013 req.enables |= htole32(HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_DUPLEX)((__uint32_t)(0x2U));
2014 req.auto_duplex = HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_BOTH0x2U;
2015 if (link_speed == 0) {
2016 req.auto_mode |=
2017 HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_ALL_SPEEDS0x1U;
2018 req.flags |=
2019 htole32(HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESTART_AUTONEG)((__uint32_t)(0x8U));
2020 req.enables |=
2021 htole32(HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_MODE)((__uint32_t)(0x1U));
2022 } else {
2023 req.force_link_speed = htole16(link_speed)((__uint16_t)(link_speed));
2024 req.flags |= htole32(HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE)((__uint32_t)(0x4U));
2025 }
2026 req.flags |= htole32(HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESET_PHY)((__uint32_t)(0x1U));
2027
2028 return hwrm_send_message(sc, &req, sizeof(req));
2029}
2030
2031int
2032bnxt_media_autonegotiate(struct bnxt_softc *sc)
2033{
2034 struct hwrm_port_phy_cfg_input req = {0};
2035
2036 if (sc->sc_flags & BNXT_FLAG_NPAR0x0002)
2037 return ENODEV19;
2038
2039 bnxt_hwrm_cmd_hdr_init(sc, &req, HWRM_PORT_PHY_CFG(0x20U));
2040 req.auto_mode |= HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_ALL_SPEEDS0x1U;
2041 req.auto_duplex = HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_BOTH0x2U;
2042 req.enables |= htole32(HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_MODE |((__uint32_t)(0x1U | 0x2U))
2043 HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_DUPLEX)((__uint32_t)(0x1U | 0x2U));
2044 req.flags |= htole32(HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESTART_AUTONEG)((__uint32_t)(0x8U));
2045 req.flags |= htole32(HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESET_PHY)((__uint32_t)(0x1U));
2046
2047 return hwrm_send_message(sc, &req, sizeof(req));
2048}
2049
2050
2051void
2052bnxt_mark_cpr_invalid(struct bnxt_cp_ring *cpr)
2053{
2054 struct cmpl_base *cmp = (void *)cpr->ring.vaddr;
2055 int i;
2056
2057 for (i = 0; i < cpr->ring.ring_size; i++)
2058 cmp[i].info3_v = !cpr->v_bit;
2059}
2060
2061void
2062bnxt_write_cp_doorbell(struct bnxt_softc *sc, struct bnxt_ring *ring,
2063 int enable)
2064{
2065 uint32_t val = CMPL_DOORBELL_KEY_CMPL(0x2U << 28);
2066 if (enable == 0)
2067 val |= CMPL_DOORBELL_MASK0x8000000U;
2068
2069 bus_space_barrier(sc->sc_db_t, sc->sc_db_h, ring->doorbell, 4,
2070 BUS_SPACE_BARRIER_WRITE0x02);
2071 bus_space_barrier(sc->sc_db_t, sc->sc_db_h, 0, sc->sc_db_s,
2072 BUS_SPACE_BARRIER_WRITE0x02);
2073 bus_space_write_4(sc->sc_db_t, sc->sc_db_h, ring->doorbell,((sc->sc_db_t)->write_4((sc->sc_db_h), (ring->doorbell
), (((__uint32_t)(val)))))
2074 htole32(val))((sc->sc_db_t)->write_4((sc->sc_db_h), (ring->doorbell
), (((__uint32_t)(val)))))
;
2075}
2076
2077void
2078bnxt_write_cp_doorbell_index(struct bnxt_softc *sc, struct bnxt_ring *ring,
2079 uint32_t index, int enable)
2080{
2081 uint32_t val = CMPL_DOORBELL_KEY_CMPL(0x2U << 28) | CMPL_DOORBELL_IDX_VALID0x4000000U |
2082 (index & CMPL_DOORBELL_IDX_MASK0xffffffU);
2083 if (enable == 0)
2084 val |= CMPL_DOORBELL_MASK0x8000000U;
2085 bus_space_barrier(sc->sc_db_t, sc->sc_db_h, ring->doorbell, 4,
2086 BUS_SPACE_BARRIER_WRITE0x02);
2087 bus_space_write_4(sc->sc_db_t, sc->sc_db_h, ring->doorbell,((sc->sc_db_t)->write_4((sc->sc_db_h), (ring->doorbell
), (((__uint32_t)(val)))))
2088 htole32(val))((sc->sc_db_t)->write_4((sc->sc_db_h), (ring->doorbell
), (((__uint32_t)(val)))))
;
2089 bus_space_barrier(sc->sc_db_t, sc->sc_db_h, 0, sc->sc_db_s,
2090 BUS_SPACE_BARRIER_WRITE0x02);
2091}
2092
2093void
2094bnxt_write_rx_doorbell(struct bnxt_softc *sc, struct bnxt_ring *ring, int index)
2095{
2096 uint32_t val = RX_DOORBELL_KEY_RX(0x1U << 28) | index;
2097 bus_space_barrier(sc->sc_db_t, sc->sc_db_h, ring->doorbell, 4,
2098 BUS_SPACE_BARRIER_WRITE0x02);
2099 bus_space_write_4(sc->sc_db_t, sc->sc_db_h, ring->doorbell,((sc->sc_db_t)->write_4((sc->sc_db_h), (ring->doorbell
), (((__uint32_t)(val)))))
2100 htole32(val))((sc->sc_db_t)->write_4((sc->sc_db_h), (ring->doorbell
), (((__uint32_t)(val)))))
;
2101
2102 /* second write isn't necessary on all hardware */
2103 bus_space_barrier(sc->sc_db_t, sc->sc_db_h, ring->doorbell, 4,
2104 BUS_SPACE_BARRIER_WRITE0x02);
2105 bus_space_write_4(sc->sc_db_t, sc->sc_db_h, ring->doorbell,((sc->sc_db_t)->write_4((sc->sc_db_h), (ring->doorbell
), (((__uint32_t)(val)))))
2106 htole32(val))((sc->sc_db_t)->write_4((sc->sc_db_h), (ring->doorbell
), (((__uint32_t)(val)))))
;
2107}
2108
2109void
2110bnxt_write_tx_doorbell(struct bnxt_softc *sc, struct bnxt_ring *ring, int index)
2111{
2112 uint32_t val = TX_DOORBELL_KEY_TX(0x0U << 28) | index;
2113 bus_space_barrier(sc->sc_db_t, sc->sc_db_h, ring->doorbell, 4,
2114 BUS_SPACE_BARRIER_WRITE0x02);
2115 bus_space_write_4(sc->sc_db_t, sc->sc_db_h, ring->doorbell,((sc->sc_db_t)->write_4((sc->sc_db_h), (ring->doorbell
), (((__uint32_t)(val)))))
2116 htole32(val))((sc->sc_db_t)->write_4((sc->sc_db_h), (ring->doorbell
), (((__uint32_t)(val)))))
;
2117
2118 /* second write isn't necessary on all hardware */
2119 bus_space_barrier(sc->sc_db_t, sc->sc_db_h, ring->doorbell, 4,
2120 BUS_SPACE_BARRIER_WRITE0x02);
2121 bus_space_write_4(sc->sc_db_t, sc->sc_db_h, ring->doorbell,((sc->sc_db_t)->write_4((sc->sc_db_h), (ring->doorbell
), (((__uint32_t)(val)))))
2122 htole32(val))((sc->sc_db_t)->write_4((sc->sc_db_h), (ring->doorbell
), (((__uint32_t)(val)))))
;
2123}
2124
2125u_int
2126bnxt_rx_fill_slots(struct bnxt_softc *sc, struct bnxt_ring *ring, void *ring_mem,
2127 struct bnxt_slot *slots, uint *prod, int bufsize, uint16_t bdtype,
2128 u_int nslots)
2129{
2130 struct rx_prod_pkt_bd *rxring;
2131 struct bnxt_slot *bs;
2132 struct mbuf *m;
2133 uint p, fills;
2134
2135 rxring = (struct rx_prod_pkt_bd *)ring_mem;
2136 p = *prod;
2137 for (fills = 0; fills < nslots; fills++) {
2138 bs = &slots[p];
2139 m = MCLGETL(NULL, M_DONTWAIT, bufsize)m_clget((((void *)0)), (0x0002), (bufsize));
2140 if (m == NULL((void *)0))
2141 break;
2142
2143 m->m_lenm_hdr.mh_len = m->m_pkthdrM_dat.MH.MH_pkthdr.len = bufsize;
2144 if (bus_dmamap_load_mbuf(sc->sc_dmat, bs->bs_map, m,(*(sc->sc_dmat)->_dmamap_load_mbuf)((sc->sc_dmat), (
bs->bs_map), (m), (0x0001))
2145 BUS_DMA_NOWAIT)(*(sc->sc_dmat)->_dmamap_load_mbuf)((sc->sc_dmat), (
bs->bs_map), (m), (0x0001))
!= 0) {
2146 m_freem(m);
2147 break;
2148 }
2149 bs->bs_m = m;
2150
2151 rxring[p].flags_type = htole16(bdtype)((__uint16_t)(bdtype));
2152 rxring[p].len = htole16(bufsize)((__uint16_t)(bufsize));
2153 rxring[p].opaque = p;
2154 rxring[p].addr = htole64(bs->bs_map->dm_segs[0].ds_addr)((__uint64_t)(bs->bs_map->dm_segs[0].ds_addr));
2155
2156 if (++p >= ring->ring_size)
2157 p = 0;
2158 }
2159
2160 if (fills != 0)
2161 bnxt_write_rx_doorbell(sc, ring, p);
2162 *prod = p;
2163
2164 return (nslots - fills);
2165}
2166
2167int
2168bnxt_rx_fill(struct bnxt_queue *q)
2169{
2170 struct bnxt_rx_queue *rx = &q->q_rx;
2171 struct bnxt_softc *sc = q->q_sc;
2172 u_int slots;
2173 int rv = 0;
2174
2175 slots = if_rxr_get(&rx->rxr[0], rx->rx_ring.ring_size);
2176 if (slots > 0) {
2177 slots = bnxt_rx_fill_slots(sc, &rx->rx_ring,
2178 BNXT_DMA_KVA(rx->rx_ring_mem)((void *)(rx->rx_ring_mem)->bdm_kva), rx->rx_slots,
2179 &rx->rx_prod, MCLBYTES(1 << 11),
2180 RX_PROD_PKT_BD_TYPE_RX_PROD_PKT0x4U, slots);
2181 if_rxr_put(&rx->rxr[0], slots)do { (&rx->rxr[0])->rxr_alive -= (slots); } while (
0)
;
2182 } else
2183 rv = 1;
2184
2185 slots = if_rxr_get(&rx->rxr[1], rx->rx_ag_ring.ring_size);
2186 if (slots > 0) {
2187 slots = bnxt_rx_fill_slots(sc, &rx->rx_ag_ring,
2188 BNXT_DMA_KVA(rx->rx_ring_mem)((void *)(rx->rx_ring_mem)->bdm_kva) + PAGE_SIZE(1 << 12),
2189 rx->rx_ag_slots, &rx->rx_ag_prod,
2190 BNXT_AG_BUFFER_SIZE8192,
2191 RX_PROD_AGG_BD_TYPE_RX_PROD_AGG0x6U, slots);
2192 if_rxr_put(&rx->rxr[1], slots)do { (&rx->rxr[1])->rxr_alive -= (slots); } while (
0)
;
2193 } else
2194 rv = 1;
2195
2196 return (rv);
2197}
2198
2199void
2200bnxt_refill(void *xq)
2201{
2202 struct bnxt_queue *q = xq;
2203 struct bnxt_rx_queue *rx = &q->q_rx;
2204
2205 bnxt_rx_fill(q);
2206
2207 if (rx->rx_cons == rx->rx_prod)
2208 timeout_add(&rx->rx_refill, 1);
2209}
2210
2211int
2212bnxt_rx(struct bnxt_softc *sc, struct bnxt_rx_queue *rx,
2213 struct bnxt_cp_ring *cpr, struct mbuf_list *ml, int *slots, int *agslots,
2214 struct cmpl_base *cmpl)
2215{
2216 struct mbuf *m, *am;
2217 struct bnxt_slot *bs;
2218 struct rx_pkt_cmpl *rxlo = (struct rx_pkt_cmpl *)cmpl;
2219 struct rx_pkt_cmpl_hi *rxhi;
2220 struct rx_abuf_cmpl *ag;
2221 uint32_t flags;
2222 uint16_t errors;
2223
2224 /* second part of the rx completion */
2225 rxhi = (struct rx_pkt_cmpl_hi *)bnxt_cpr_next_cmpl(sc, cpr);
2226 if (rxhi == NULL((void *)0)) {
2227 return (1);
2228 }
2229
2230 /* packets over 2k in size use an aggregation buffer completion too */
2231 ag = NULL((void *)0);
2232 if ((rxlo->agg_bufs_v1 >> RX_PKT_CMPL_AGG_BUFS_SFT1) != 0) {
2233 ag = (struct rx_abuf_cmpl *)bnxt_cpr_next_cmpl(sc, cpr);
2234 if (ag == NULL((void *)0)) {
2235 return (1);
2236 }
2237 }
2238
2239 bs = &rx->rx_slots[rxlo->opaque];
2240 bus_dmamap_sync(sc->sc_dmat, bs->bs_map, 0, bs->bs_map->dm_mapsize,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (bs->
bs_map), (0), (bs->bs_map->dm_mapsize), (0x02))
2241 BUS_DMASYNC_POSTREAD)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (bs->
bs_map), (0), (bs->bs_map->dm_mapsize), (0x02))
;
2242 bus_dmamap_unload(sc->sc_dmat, bs->bs_map)(*(sc->sc_dmat)->_dmamap_unload)((sc->sc_dmat), (bs->
bs_map))
;
2243
2244 m = bs->bs_m;
2245 bs->bs_m = NULL((void *)0);
2246 m->m_pkthdrM_dat.MH.MH_pkthdr.len = m->m_lenm_hdr.mh_len = letoh16(rxlo->len)((__uint16_t)(rxlo->len));
2247 (*slots)++;
2248
2249 /* checksum flags */
2250 flags = lemtoh32(&rxhi->flags2)((__uint32_t)(*(__uint32_t *)(&rxhi->flags2)));
2251 errors = lemtoh16(&rxhi->errors_v2)((__uint16_t)(*(__uint16_t *)(&rxhi->errors_v2)));
2252 if ((flags & RX_PKT_CMPL_FLAGS2_IP_CS_CALC0x1U) != 0 &&
2253 (errors & RX_PKT_CMPL_ERRORS_IP_CS_ERROR0x10U) == 0)
2254 m->m_pkthdrM_dat.MH.MH_pkthdr.csum_flags |= M_IPV4_CSUM_IN_OK0x0008;
2255
2256 if ((flags & RX_PKT_CMPL_FLAGS2_L4_CS_CALC0x2U) != 0 &&
2257 (errors & RX_PKT_CMPL_ERRORS_L4_CS_ERROR0x20U) == 0)
2258 m->m_pkthdrM_dat.MH.MH_pkthdr.csum_flags |= M_TCP_CSUM_IN_OK0x0020 |
2259 M_UDP_CSUM_IN_OK0x0080;
2260
2261#if NVLAN1 > 0
2262 if ((flags & RX_PKT_CMPL_FLAGS2_META_FORMAT_MASK0xf0U) ==
2263 RX_PKT_CMPL_FLAGS2_META_FORMAT_VLAN(0x1U << 4)) {
2264 m->m_pkthdrM_dat.MH.MH_pkthdr.ether_vtag = lemtoh16(&rxhi->metadata)((__uint16_t)(*(__uint16_t *)(&rxhi->metadata)));
2265 m->m_flagsm_hdr.mh_flags |= M_VLANTAG0x0020;
2266 }
2267#endif
2268
2269 if (lemtoh16(&rxlo->flags_type)((__uint16_t)(*(__uint16_t *)(&rxlo->flags_type))) & RX_PKT_CMPL_FLAGS_RSS_VALID0x400U) {
2270 m->m_pkthdrM_dat.MH.MH_pkthdr.ph_flowid = lemtoh32(&rxlo->rss_hash)((__uint32_t)(*(__uint32_t *)(&rxlo->rss_hash)));
2271 m->m_pkthdrM_dat.MH.MH_pkthdr.csum_flags |= M_FLOWID0x4000;
2272 }
2273
2274 if (ag != NULL((void *)0)) {
2275 bs = &rx->rx_ag_slots[ag->opaque];
2276 bus_dmamap_sync(sc->sc_dmat, bs->bs_map, 0,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (bs->
bs_map), (0), (bs->bs_map->dm_mapsize), (0x02))
2277 bs->bs_map->dm_mapsize, BUS_DMASYNC_POSTREAD)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (bs->
bs_map), (0), (bs->bs_map->dm_mapsize), (0x02))
;
2278 bus_dmamap_unload(sc->sc_dmat, bs->bs_map)(*(sc->sc_dmat)->_dmamap_unload)((sc->sc_dmat), (bs->
bs_map))
;
2279
2280 am = bs->bs_m;
2281 bs->bs_m = NULL((void *)0);
2282 am->m_lenm_hdr.mh_len = letoh16(ag->len)((__uint16_t)(ag->len));
2283 m->m_nextm_hdr.mh_next = am;
2284 m->m_pkthdrM_dat.MH.MH_pkthdr.len += am->m_lenm_hdr.mh_len;
2285 (*agslots)++;
2286 }
2287
2288 ml_enqueue(ml, m);
2289 return (0);
2290}
2291
2292void
2293bnxt_txeof(struct bnxt_softc *sc, struct bnxt_tx_queue *tx, int *txfree,
2294 struct cmpl_base *cmpl)
2295{
2296 struct tx_cmpl *txcmpl = (struct tx_cmpl *)cmpl;
2297 struct bnxt_slot *bs;
2298 bus_dmamap_t map;
2299 u_int idx, segs, last;
2300
2301 idx = tx->tx_ring_cons;
2302 last = tx->tx_cons;
Value stored to 'last' is never read
2303 do {
2304 bs = &tx->tx_slots[tx->tx_cons];
2305 map = bs->bs_map;
2306
2307 segs = BNXT_TX_SLOTS(bs)(bs->bs_map->dm_nsegs + 1);
2308 bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (map),
(0), (map->dm_mapsize), (0x08))
2309 BUS_DMASYNC_POSTWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (map),
(0), (map->dm_mapsize), (0x08))
;
2310 bus_dmamap_unload(sc->sc_dmat, map)(*(sc->sc_dmat)->_dmamap_unload)((sc->sc_dmat), (map
))
;
2311 m_freem(bs->bs_m);
2312 bs->bs_m = NULL((void *)0);
2313
2314 idx += segs;
2315 (*txfree) += segs;
2316 if (idx >= tx->tx_ring.ring_size)
2317 idx -= tx->tx_ring.ring_size;
2318
2319 last = tx->tx_cons;
2320 if (++tx->tx_cons >= tx->tx_ring.ring_size)
2321 tx->tx_cons = 0;
2322
2323 } while (last != txcmpl->opaque);
2324 tx->tx_ring_cons = idx;
2325}
2326
2327/* bnxt_hwrm.c */
2328
2329int
2330bnxt_hwrm_err_map(uint16_t err)
2331{
2332 int rc;
2333
2334 switch (err) {
2335 case HWRM_ERR_CODE_SUCCESS(0x0U):
2336 return 0;
2337 case HWRM_ERR_CODE_INVALID_PARAMS(0x2U):
2338 case HWRM_ERR_CODE_INVALID_FLAGS(0x5U):
2339 case HWRM_ERR_CODE_INVALID_ENABLES(0x6U):
2340 return EINVAL22;
2341 case HWRM_ERR_CODE_RESOURCE_ACCESS_DENIED(0x3U):
2342 return EACCES13;
2343 case HWRM_ERR_CODE_RESOURCE_ALLOC_ERROR(0x4U):
2344 return ENOMEM12;
2345 case HWRM_ERR_CODE_CMD_NOT_SUPPORTED(0xffffU):
2346 return ENOSYS78;
2347 case HWRM_ERR_CODE_FAIL(0x1U):
2348 return EIO5;
2349 case HWRM_ERR_CODE_HWRM_ERROR(0xfU):
2350 case HWRM_ERR_CODE_UNKNOWN_ERR(0xfffeU):
2351 default:
2352 return EIO5;
2353 }
2354
2355 return rc;
2356}
2357
2358void
2359bnxt_hwrm_cmd_hdr_init(struct bnxt_softc *softc, void *request,
2360 uint16_t req_type)
2361{
2362 struct input *req = request;
2363
2364 req->req_type = htole16(req_type)((__uint16_t)(req_type));
2365 req->cmpl_ring = 0xffff;
2366 req->target_id = 0xffff;
2367 req->resp_addr = htole64(BNXT_DMA_DVA(softc->sc_cmd_resp))((__uint64_t)(((u_int64_t)(softc->sc_cmd_resp)->bdm_map
->dm_segs[0].ds_addr)))
;
2368}
2369
2370int
2371_hwrm_send_message(struct bnxt_softc *softc, void *msg, uint32_t msg_len)
2372{
2373 struct input *req = msg;
2374 struct hwrm_err_output *resp = BNXT_DMA_KVA(softc->sc_cmd_resp)((void *)(softc->sc_cmd_resp)->bdm_kva);
2375 uint32_t *data = msg;
2376 int i;
2377 uint8_t *valid;
2378 uint16_t err;
2379 uint16_t max_req_len = HWRM_MAX_REQ_LEN(128);
2380 struct hwrm_short_input short_input = {0};
2381
2382 /* TODO: DMASYNC in here. */
2383 req->seq_id = htole16(softc->sc_cmd_seq++)((__uint16_t)(softc->sc_cmd_seq++));
2384 memset(resp, 0, PAGE_SIZE)__builtin_memset((resp), (0), ((1 << 12)));
2385
2386 if (softc->sc_flags & BNXT_FLAG_SHORT_CMD0x0008) {
2387 void *short_cmd_req = BNXT_DMA_KVA(softc->sc_cmd_resp)((void *)(softc->sc_cmd_resp)->bdm_kva);
2388
2389 memcpy(short_cmd_req, req, msg_len)__builtin_memcpy((short_cmd_req), (req), (msg_len));
2390 memset((uint8_t *) short_cmd_req + msg_len, 0,__builtin_memset(((uint8_t *) short_cmd_req + msg_len), (0), (
softc->sc_max_req_len - msg_len))
2391 softc->sc_max_req_len - msg_len)__builtin_memset(((uint8_t *) short_cmd_req + msg_len), (0), (
softc->sc_max_req_len - msg_len))
;
2392
2393 short_input.req_type = req->req_type;
2394 short_input.signature =
2395 htole16(HWRM_SHORT_INPUT_SIGNATURE_SHORT_CMD)((__uint16_t)(0x4321U));
2396 short_input.size = htole16(msg_len)((__uint16_t)(msg_len));
2397 short_input.req_addr =
2398 htole64(BNXT_DMA_DVA(softc->sc_cmd_resp))((__uint64_t)(((u_int64_t)(softc->sc_cmd_resp)->bdm_map
->dm_segs[0].ds_addr)))
;
2399
2400 data = (uint32_t *)&short_input;
2401 msg_len = sizeof(short_input);
2402
2403 /* Sync memory write before updating doorbell */
2404 membar_sync()do { __asm volatile("mfence" ::: "memory"); } while (0);
2405
2406 max_req_len = BNXT_HWRM_SHORT_REQ_LENsizeof(struct hwrm_short_input);
2407 }
2408
2409 /* Write request msg to hwrm channel */
2410 for (i = 0; i < msg_len; i += 4) {
2411 bus_space_write_4(softc->sc_hwrm_t,((softc->sc_hwrm_t)->write_4((softc->sc_hwrm_h), (i)
, (*data)))
2412 softc->sc_hwrm_h,((softc->sc_hwrm_t)->write_4((softc->sc_hwrm_h), (i)
, (*data)))
2413 i, *data)((softc->sc_hwrm_t)->write_4((softc->sc_hwrm_h), (i)
, (*data)))
;
2414 data++;
2415 }
2416
2417 /* Clear to the end of the request buffer */
2418 for (i = msg_len; i < max_req_len; i += 4)
2419 bus_space_write_4(softc->sc_hwrm_t, softc->sc_hwrm_h,((softc->sc_hwrm_t)->write_4((softc->sc_hwrm_h), (i)
, (0)))
2420 i, 0)((softc->sc_hwrm_t)->write_4((softc->sc_hwrm_h), (i)
, (0)))
;
2421
2422 /* Ring channel doorbell */
2423 bus_space_write_4(softc->sc_hwrm_t, softc->sc_hwrm_h, 0x100,((softc->sc_hwrm_t)->write_4((softc->sc_hwrm_h), (0x100
), (((__uint32_t)(1)))))
2424 htole32(1))((softc->sc_hwrm_t)->write_4((softc->sc_hwrm_h), (0x100
), (((__uint32_t)(1)))))
;
2425
2426 /* Check if response len is updated */
2427 for (i = 0; i < softc->sc_cmd_timeo; i++) {
2428 if (resp->resp_len && resp->resp_len <= 4096)
2429 break;
2430 DELAY(1000)(*delay_func)(1000);
2431 }
2432 if (i >= softc->sc_cmd_timeo) {
2433 printf("%s: timeout sending %s: (timeout: %u) seq: %d\n",
2434 DEVNAME(softc)((softc)->sc_dev.dv_xname), GET_HWRM_REQ_TYPE(req->req_type)((req->req_type) == 0x99 ? "HWRM_CFA_NTUPLE_FILTER_ALLOC":
((req->req_type) == 0x90 ? "HWRM_CFA_L2_FILTER_ALLOC": ((
req->req_type) == 0x91 ? "HWRM_CFA_L2_FILTER_FREE": ((req->
req_type) == 0x92 ? "HWRM_CFA_L2_FILTER_CFG": ((req->req_type
) == 0x93 ? "HWRM_CFA_L2_SET_RX_MASK": ((req->req_type) ==
0x94 ? "HWRM_CFA_VLAN_ANTISPOOF_CFG": ((req->req_type) ==
0x95 ? "HWRM_CFA_TUNNEL_FILTER_ALLOC": ((req->req_type) ==
0x96 ? "HWRM_CFA_TUNNEL_FILTER_FREE": ((req->req_type) ==
0x10 ? "RESERVED1": ((req->req_type) == 0x11 ? "HWRM_FUNC_RESET"
: ((req->req_type) == 0x12 ? "HWRM_FUNC_GETFID": ((req->
req_type) == 0x13 ? "HWRM_FUNC_VF_ALLOC": ((req->req_type)
== 0x14 ? "HWRM_FUNC_VF_FREE": ((req->req_type) == 0x15 ?
"HWRM_FUNC_QCAPS": ((req->req_type) == 0x16 ? "HWRM_FUNC_QCFG"
: ((req->req_type) == 0x17 ? "HWRM_FUNC_CFG": ((req->req_type
) == 0x18 ? "HWRM_FUNC_QSTATS": ((req->req_type) == 0x19 ?
"HWRM_FUNC_CLR_STATS": ((req->req_type) == 0xe0 ? "HWRM_TEMP_MONITOR_QUERY"
: ((req->req_type) == 0x1a ? "HWRM_FUNC_DRV_UNRGTR": ((req
->req_type) == 0x1b ? "HWRM_FUNC_VF_RESC_FREE": ((req->
req_type) == 0x1c ? "HWRM_FUNC_VF_VNIC_IDS_QUERY": ((req->
req_type) == 0x1d ? "HWRM_FUNC_DRV_RGTR": ((req->req_type)
== 0x1e ? "HWRM_FUNC_DRV_QVER": ((req->req_type) == 0x1f ?
"HWRM_FUNC_BUF_RGTR": ((req->req_type) == 0x9a ? "HWRM_CFA_NTUPLE_FILTER_FREE"
: ((req->req_type) == 0x9b ? "HWRM_CFA_NTUPLE_FILTER_CFG":
((req->req_type) == 0xd3 ? "HWRM_FWD_ASYNC_EVENT_CMPL": (
(req->req_type) == 0xd2 ? "HWRM_FWD_RESP": ((req->req_type
) == 0xd1 ? "HWRM_REJECT_FWD_RESP": ((req->req_type) == 0xd0
? "HWRM_EXEC_FWD_RESP": ((req->req_type) == 0xc0 ? "HWRM_FW_RESET"
: ((req->req_type) == 0xc1 ? "HWRM_FW_QSTATUS": ((req->
req_type) == 0x70 ? "HWRM_VNIC_RSS_COS_LB_CTX_ALLOC": ((req->
req_type) == 0x71 ? "HWRM_VNIC_RSS_COS_LB_CTX_FREE": ((req->
req_type) == 0xb1 ? "HWRM_STAT_CTX_FREE": ((req->req_type)
== 0xb0 ? "HWRM_STAT_CTX_ALLOC": ((req->req_type) == 0xb3
? "HWRM_STAT_CTX_CLR_STATS": ((req->req_type) == 0xb2 ? "HWRM_STAT_CTX_QUERY"
: ((req->req_type) == 0xfff6 ? "HWRM_NVM_GET_DEV_INFO": ((
req->req_type) == 0x61 ? "HWRM_RING_GRP_FREE": ((req->req_type
) == 0x60 ? "HWRM_RING_GRP_ALLOC": ((req->req_type) == 0x24
? "HWRM_PORT_LPBK_QSTATS": ((req->req_type) == 0xf3 ? "HWRM_WOL_REASON_QCFG"
: ((req->req_type) == 0xa0 ? "HWRM_TUNNEL_DST_PORT_QUERY":
((req->req_type) == 0xa1 ? "HWRM_TUNNEL_DST_PORT_ALLOC": (
(req->req_type) == 0xa2 ? "HWRM_TUNNEL_DST_PORT_FREE": ((req
->req_type) == 0xfffc ? "HWRM_NVM_RAW_DUMP": ((req->req_type
) == 0xfffb ? "HWRM_NVM_GET_DIR_INFO": ((req->req_type) ==
0xfffa ? "HWRM_NVM_GET_DIR_ENTRIES": ((req->req_type) == 0x10a
? "HWRM_CFA_VLAN_ANTISPOOF_QCFG": ((req->req_type) == 0xe
? "HWRM_FUNC_BUF_UNRGTR": ((req->req_type) == 0xf ? "HWRM_FUNC_VF_CFG"
: ((req->req_type) == 0xffff ? "HWRM_NVM_RAW_WRITE_BLK": (
(req->req_type) == 0xfffe ? "HWRM_NVM_WRITE": ((req->req_type
) == 0xfffd ? "HWRM_NVM_READ": ((req->req_type) == 0x50 ? "HWRM_RING_ALLOC"
: ((req->req_type) == 0x51 ? "HWRM_RING_FREE": ((req->req_type
) == 0x52 ? "HWRM_RING_CMPL_RING_QAGGINT_PARAMS": ((req->req_type
) == 0x53 ? "HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS": ((req->
req_type) == 0x4a ? "HWRM_VNIC_QCAPS": ((req->req_type) ==
0x49 ? "HWRM_VNIC_PLCMODES_QCFG": ((req->req_type) == 0x48
? "HWRM_VNIC_PLCMODES_CFG": ((req->req_type) == 0x47 ? "HWRM_VNIC_RSS_QCFG"
: ((req->req_type) == 0x46 ? "HWRM_VNIC_RSS_CFG": ((req->
req_type) == 0x44 ? "HWRM_VNIC_TPA_CFG": ((req->req_type) ==
0x43 ? "HWRM_VNIC_QCFG": ((req->req_type) == 0x42 ? "HWRM_VNIC_CFG"
: ((req->req_type) == 0x41 ? "HWRM_VNIC_FREE": ((req->req_type
) == 0x40 ? "HWRM_VNIC_ALLOC": ((req->req_type) == 0x0 ? "HWRM_VER_GET"
: ((req->req_type) == 0xfff9 ? "HWRM_NVM_FIND_DIR_ENTRY": (
(req->req_type) == 0xfff8 ? "HWRM_NVM_MOD_DIR_ENTRY": ((req
->req_type) == 0xfff7 ? "HWRM_NVM_ERASE_DIR_ENTRY": ((req->
req_type) == 0x5e ? "HWRM_RING_RESET": ((req->req_type) ==
0xfff5 ? "HWRM_NVM_VERIFY_UPDATE": ((req->req_type) == 0xfff4
? "HWRM_NVM_MODIFY": ((req->req_type) == 0xfff3 ? "HWRM_NVM_INSTALL_UPDATE"
: ((req->req_type) == 0xfff2 ? "HWRM_NVM_SET_VARIABLE": ((
req->req_type) == 0xfff1 ? "HWRM_NVM_GET_VARIABLE": ((req->
req_type) == 0xfff0 ? "HWRM_NVM_FLUSH": ((req->req_type) ==
0x2e ? "HWRM_PORT_LED_QCFG": ((req->req_type) == 0x2d ? "HWRM_PORT_LED_CFG"
: ((req->req_type) == 0x2f ? "HWRM_PORT_LED_QCAPS": ((req->
req_type) == 0x2a ? "HWRM_PORT_PHY_QCAPS": ((req->req_type
) == 0x38 ? "HWRM_QUEUE_PRI2COS_CFG": ((req->req_type) == 0x39
? "HWRM_QUEUE_COS2BW_QCFG": ((req->req_type) == 0x32 ? "HWRM_QUEUE_CFG"
: ((req->req_type) == 0x33 ? "HWRM_FUNC_VLAN_CFG": ((req->
req_type) == 0x30 ? "HWRM_QUEUE_QPORTCFG": ((req->req_type
) == 0x31 ? "HWRM_QUEUE_QCFG": ((req->req_type) == 0x36 ? "HWRM_QUEUE_PFCENABLE_CFG"
: ((req->req_type) == 0x37 ? "HWRM_QUEUE_PRI2COS_QCFG": ((
req->req_type) == 0x34 ? "HWRM_FUNC_VLAN_QCFG": ((req->
req_type) == 0x35 ? "HWRM_QUEUE_PFCENABLE_QCFG": ((req->req_type
) == 0xff14 ? "HWRM_DBG_DUMP": ((req->req_type) == 0xc8 ? "HWRM_FW_SET_TIME"
: ((req->req_type) == 0xc9 ? "HWRM_FW_GET_TIME": ((req->
req_type) == 0xf1 ? "HWRM_WOL_FILTER_FREE": ((req->req_type
) == 0xf0 ? "HWRM_WOL_FILTER_ALLOC": ((req->req_type) == 0x27
? "HWRM_PORT_PHY_QCFG": ((req->req_type) == 0xf2 ? "HWRM_WOL_FILTER_QCFG"
: ((req->req_type) == 0x21 ? "HWRM_PORT_MAC_CFG": ((req->
req_type) == 0x20 ? "HWRM_PORT_PHY_CFG": ((req->req_type) ==
0x23 ? "HWRM_PORT_QSTATS": ((req->req_type) == 0x28 ? "HWRM_PORT_MAC_QCFG"
: ((req->req_type) == 0xffef ? "HWRM_NVM_VALIDATE_OPTION":
((req->req_type) == 0x3a ? "HWRM_QUEUE_COS2BW_CFG": "Unknown req_type"
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))))))))))))))))))))))
,
2435 softc->sc_cmd_timeo,
2436 le16toh(req->seq_id)((__uint16_t)(req->seq_id)));
2437 return ETIMEDOUT60;
2438 }
2439 /* Last byte of resp contains the valid key */
2440 valid = (uint8_t *)resp + resp->resp_len - 1;
2441 for (i = 0; i < softc->sc_cmd_timeo; i++) {
2442 if (*valid == HWRM_RESP_VALID_KEY1)
2443 break;
2444 DELAY(1000)(*delay_func)(1000);
2445 }
2446 if (i >= softc->sc_cmd_timeo) {
2447 printf("%s: timeout sending %s: "
2448 "(timeout: %u) msg {0x%x 0x%x} len:%d v: %d\n",
2449 DEVNAME(softc)((softc)->sc_dev.dv_xname), GET_HWRM_REQ_TYPE(req->req_type)((req->req_type) == 0x99 ? "HWRM_CFA_NTUPLE_FILTER_ALLOC":
((req->req_type) == 0x90 ? "HWRM_CFA_L2_FILTER_ALLOC": ((
req->req_type) == 0x91 ? "HWRM_CFA_L2_FILTER_FREE": ((req->
req_type) == 0x92 ? "HWRM_CFA_L2_FILTER_CFG": ((req->req_type
) == 0x93 ? "HWRM_CFA_L2_SET_RX_MASK": ((req->req_type) ==
0x94 ? "HWRM_CFA_VLAN_ANTISPOOF_CFG": ((req->req_type) ==
0x95 ? "HWRM_CFA_TUNNEL_FILTER_ALLOC": ((req->req_type) ==
0x96 ? "HWRM_CFA_TUNNEL_FILTER_FREE": ((req->req_type) ==
0x10 ? "RESERVED1": ((req->req_type) == 0x11 ? "HWRM_FUNC_RESET"
: ((req->req_type) == 0x12 ? "HWRM_FUNC_GETFID": ((req->
req_type) == 0x13 ? "HWRM_FUNC_VF_ALLOC": ((req->req_type)
== 0x14 ? "HWRM_FUNC_VF_FREE": ((req->req_type) == 0x15 ?
"HWRM_FUNC_QCAPS": ((req->req_type) == 0x16 ? "HWRM_FUNC_QCFG"
: ((req->req_type) == 0x17 ? "HWRM_FUNC_CFG": ((req->req_type
) == 0x18 ? "HWRM_FUNC_QSTATS": ((req->req_type) == 0x19 ?
"HWRM_FUNC_CLR_STATS": ((req->req_type) == 0xe0 ? "HWRM_TEMP_MONITOR_QUERY"
: ((req->req_type) == 0x1a ? "HWRM_FUNC_DRV_UNRGTR": ((req
->req_type) == 0x1b ? "HWRM_FUNC_VF_RESC_FREE": ((req->
req_type) == 0x1c ? "HWRM_FUNC_VF_VNIC_IDS_QUERY": ((req->
req_type) == 0x1d ? "HWRM_FUNC_DRV_RGTR": ((req->req_type)
== 0x1e ? "HWRM_FUNC_DRV_QVER": ((req->req_type) == 0x1f ?
"HWRM_FUNC_BUF_RGTR": ((req->req_type) == 0x9a ? "HWRM_CFA_NTUPLE_FILTER_FREE"
: ((req->req_type) == 0x9b ? "HWRM_CFA_NTUPLE_FILTER_CFG":
((req->req_type) == 0xd3 ? "HWRM_FWD_ASYNC_EVENT_CMPL": (
(req->req_type) == 0xd2 ? "HWRM_FWD_RESP": ((req->req_type
) == 0xd1 ? "HWRM_REJECT_FWD_RESP": ((req->req_type) == 0xd0
? "HWRM_EXEC_FWD_RESP": ((req->req_type) == 0xc0 ? "HWRM_FW_RESET"
: ((req->req_type) == 0xc1 ? "HWRM_FW_QSTATUS": ((req->
req_type) == 0x70 ? "HWRM_VNIC_RSS_COS_LB_CTX_ALLOC": ((req->
req_type) == 0x71 ? "HWRM_VNIC_RSS_COS_LB_CTX_FREE": ((req->
req_type) == 0xb1 ? "HWRM_STAT_CTX_FREE": ((req->req_type)
== 0xb0 ? "HWRM_STAT_CTX_ALLOC": ((req->req_type) == 0xb3
? "HWRM_STAT_CTX_CLR_STATS": ((req->req_type) == 0xb2 ? "HWRM_STAT_CTX_QUERY"
: ((req->req_type) == 0xfff6 ? "HWRM_NVM_GET_DEV_INFO": ((
req->req_type) == 0x61 ? "HWRM_RING_GRP_FREE": ((req->req_type
) == 0x60 ? "HWRM_RING_GRP_ALLOC": ((req->req_type) == 0x24
? "HWRM_PORT_LPBK_QSTATS": ((req->req_type) == 0xf3 ? "HWRM_WOL_REASON_QCFG"
: ((req->req_type) == 0xa0 ? "HWRM_TUNNEL_DST_PORT_QUERY":
((req->req_type) == 0xa1 ? "HWRM_TUNNEL_DST_PORT_ALLOC": (
(req->req_type) == 0xa2 ? "HWRM_TUNNEL_DST_PORT_FREE": ((req
->req_type) == 0xfffc ? "HWRM_NVM_RAW_DUMP": ((req->req_type
) == 0xfffb ? "HWRM_NVM_GET_DIR_INFO": ((req->req_type) ==
0xfffa ? "HWRM_NVM_GET_DIR_ENTRIES": ((req->req_type) == 0x10a
? "HWRM_CFA_VLAN_ANTISPOOF_QCFG": ((req->req_type) == 0xe
? "HWRM_FUNC_BUF_UNRGTR": ((req->req_type) == 0xf ? "HWRM_FUNC_VF_CFG"
: ((req->req_type) == 0xffff ? "HWRM_NVM_RAW_WRITE_BLK": (
(req->req_type) == 0xfffe ? "HWRM_NVM_WRITE": ((req->req_type
) == 0xfffd ? "HWRM_NVM_READ": ((req->req_type) == 0x50 ? "HWRM_RING_ALLOC"
: ((req->req_type) == 0x51 ? "HWRM_RING_FREE": ((req->req_type
) == 0x52 ? "HWRM_RING_CMPL_RING_QAGGINT_PARAMS": ((req->req_type
) == 0x53 ? "HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS": ((req->
req_type) == 0x4a ? "HWRM_VNIC_QCAPS": ((req->req_type) ==
0x49 ? "HWRM_VNIC_PLCMODES_QCFG": ((req->req_type) == 0x48
? "HWRM_VNIC_PLCMODES_CFG": ((req->req_type) == 0x47 ? "HWRM_VNIC_RSS_QCFG"
: ((req->req_type) == 0x46 ? "HWRM_VNIC_RSS_CFG": ((req->
req_type) == 0x44 ? "HWRM_VNIC_TPA_CFG": ((req->req_type) ==
0x43 ? "HWRM_VNIC_QCFG": ((req->req_type) == 0x42 ? "HWRM_VNIC_CFG"
: ((req->req_type) == 0x41 ? "HWRM_VNIC_FREE": ((req->req_type
) == 0x40 ? "HWRM_VNIC_ALLOC": ((req->req_type) == 0x0 ? "HWRM_VER_GET"
: ((req->req_type) == 0xfff9 ? "HWRM_NVM_FIND_DIR_ENTRY": (
(req->req_type) == 0xfff8 ? "HWRM_NVM_MOD_DIR_ENTRY": ((req
->req_type) == 0xfff7 ? "HWRM_NVM_ERASE_DIR_ENTRY": ((req->
req_type) == 0x5e ? "HWRM_RING_RESET": ((req->req_type) ==
0xfff5 ? "HWRM_NVM_VERIFY_UPDATE": ((req->req_type) == 0xfff4
? "HWRM_NVM_MODIFY": ((req->req_type) == 0xfff3 ? "HWRM_NVM_INSTALL_UPDATE"
: ((req->req_type) == 0xfff2 ? "HWRM_NVM_SET_VARIABLE": ((
req->req_type) == 0xfff1 ? "HWRM_NVM_GET_VARIABLE": ((req->
req_type) == 0xfff0 ? "HWRM_NVM_FLUSH": ((req->req_type) ==
0x2e ? "HWRM_PORT_LED_QCFG": ((req->req_type) == 0x2d ? "HWRM_PORT_LED_CFG"
: ((req->req_type) == 0x2f ? "HWRM_PORT_LED_QCAPS": ((req->
req_type) == 0x2a ? "HWRM_PORT_PHY_QCAPS": ((req->req_type
) == 0x38 ? "HWRM_QUEUE_PRI2COS_CFG": ((req->req_type) == 0x39
? "HWRM_QUEUE_COS2BW_QCFG": ((req->req_type) == 0x32 ? "HWRM_QUEUE_CFG"
: ((req->req_type) == 0x33 ? "HWRM_FUNC_VLAN_CFG": ((req->
req_type) == 0x30 ? "HWRM_QUEUE_QPORTCFG": ((req->req_type
) == 0x31 ? "HWRM_QUEUE_QCFG": ((req->req_type) == 0x36 ? "HWRM_QUEUE_PFCENABLE_CFG"
: ((req->req_type) == 0x37 ? "HWRM_QUEUE_PRI2COS_QCFG": ((
req->req_type) == 0x34 ? "HWRM_FUNC_VLAN_QCFG": ((req->
req_type) == 0x35 ? "HWRM_QUEUE_PFCENABLE_QCFG": ((req->req_type
) == 0xff14 ? "HWRM_DBG_DUMP": ((req->req_type) == 0xc8 ? "HWRM_FW_SET_TIME"
: ((req->req_type) == 0xc9 ? "HWRM_FW_GET_TIME": ((req->
req_type) == 0xf1 ? "HWRM_WOL_FILTER_FREE": ((req->req_type
) == 0xf0 ? "HWRM_WOL_FILTER_ALLOC": ((req->req_type) == 0x27
? "HWRM_PORT_PHY_QCFG": ((req->req_type) == 0xf2 ? "HWRM_WOL_FILTER_QCFG"
: ((req->req_type) == 0x21 ? "HWRM_PORT_MAC_CFG": ((req->
req_type) == 0x20 ? "HWRM_PORT_PHY_CFG": ((req->req_type) ==
0x23 ? "HWRM_PORT_QSTATS": ((req->req_type) == 0x28 ? "HWRM_PORT_MAC_QCFG"
: ((req->req_type) == 0xffef ? "HWRM_NVM_VALIDATE_OPTION":
((req->req_type) == 0x3a ? "HWRM_QUEUE_COS2BW_CFG": "Unknown req_type"
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))))))))))))))))))))))
,
2450 softc->sc_cmd_timeo, le16toh(req->req_type)((__uint16_t)(req->req_type)),
2451 le16toh(req->seq_id)((__uint16_t)(req->seq_id)), msg_len,
2452 *valid);
2453 return ETIMEDOUT60;
2454 }
2455
2456 err = le16toh(resp->error_code)((__uint16_t)(resp->error_code));
2457 if (err) {
2458 /* HWRM_ERR_CODE_FAIL is a "normal" error, don't log */
2459 if (err != HWRM_ERR_CODE_FAIL(0x1U)) {
2460 printf("%s: %s command returned %s error.\n",
2461 DEVNAME(softc)((softc)->sc_dev.dv_xname),
2462 GET_HWRM_REQ_TYPE(req->req_type)((req->req_type) == 0x99 ? "HWRM_CFA_NTUPLE_FILTER_ALLOC":
((req->req_type) == 0x90 ? "HWRM_CFA_L2_FILTER_ALLOC": ((
req->req_type) == 0x91 ? "HWRM_CFA_L2_FILTER_FREE": ((req->
req_type) == 0x92 ? "HWRM_CFA_L2_FILTER_CFG": ((req->req_type
) == 0x93 ? "HWRM_CFA_L2_SET_RX_MASK": ((req->req_type) ==
0x94 ? "HWRM_CFA_VLAN_ANTISPOOF_CFG": ((req->req_type) ==
0x95 ? "HWRM_CFA_TUNNEL_FILTER_ALLOC": ((req->req_type) ==
0x96 ? "HWRM_CFA_TUNNEL_FILTER_FREE": ((req->req_type) ==
0x10 ? "RESERVED1": ((req->req_type) == 0x11 ? "HWRM_FUNC_RESET"
: ((req->req_type) == 0x12 ? "HWRM_FUNC_GETFID": ((req->
req_type) == 0x13 ? "HWRM_FUNC_VF_ALLOC": ((req->req_type)
== 0x14 ? "HWRM_FUNC_VF_FREE": ((req->req_type) == 0x15 ?
"HWRM_FUNC_QCAPS": ((req->req_type) == 0x16 ? "HWRM_FUNC_QCFG"
: ((req->req_type) == 0x17 ? "HWRM_FUNC_CFG": ((req->req_type
) == 0x18 ? "HWRM_FUNC_QSTATS": ((req->req_type) == 0x19 ?
"HWRM_FUNC_CLR_STATS": ((req->req_type) == 0xe0 ? "HWRM_TEMP_MONITOR_QUERY"
: ((req->req_type) == 0x1a ? "HWRM_FUNC_DRV_UNRGTR": ((req
->req_type) == 0x1b ? "HWRM_FUNC_VF_RESC_FREE": ((req->
req_type) == 0x1c ? "HWRM_FUNC_VF_VNIC_IDS_QUERY": ((req->
req_type) == 0x1d ? "HWRM_FUNC_DRV_RGTR": ((req->req_type)
== 0x1e ? "HWRM_FUNC_DRV_QVER": ((req->req_type) == 0x1f ?
"HWRM_FUNC_BUF_RGTR": ((req->req_type) == 0x9a ? "HWRM_CFA_NTUPLE_FILTER_FREE"
: ((req->req_type) == 0x9b ? "HWRM_CFA_NTUPLE_FILTER_CFG":
((req->req_type) == 0xd3 ? "HWRM_FWD_ASYNC_EVENT_CMPL": (
(req->req_type) == 0xd2 ? "HWRM_FWD_RESP": ((req->req_type
) == 0xd1 ? "HWRM_REJECT_FWD_RESP": ((req->req_type) == 0xd0
? "HWRM_EXEC_FWD_RESP": ((req->req_type) == 0xc0 ? "HWRM_FW_RESET"
: ((req->req_type) == 0xc1 ? "HWRM_FW_QSTATUS": ((req->
req_type) == 0x70 ? "HWRM_VNIC_RSS_COS_LB_CTX_ALLOC": ((req->
req_type) == 0x71 ? "HWRM_VNIC_RSS_COS_LB_CTX_FREE": ((req->
req_type) == 0xb1 ? "HWRM_STAT_CTX_FREE": ((req->req_type)
== 0xb0 ? "HWRM_STAT_CTX_ALLOC": ((req->req_type) == 0xb3
? "HWRM_STAT_CTX_CLR_STATS": ((req->req_type) == 0xb2 ? "HWRM_STAT_CTX_QUERY"
: ((req->req_type) == 0xfff6 ? "HWRM_NVM_GET_DEV_INFO": ((
req->req_type) == 0x61 ? "HWRM_RING_GRP_FREE": ((req->req_type
) == 0x60 ? "HWRM_RING_GRP_ALLOC": ((req->req_type) == 0x24
? "HWRM_PORT_LPBK_QSTATS": ((req->req_type) == 0xf3 ? "HWRM_WOL_REASON_QCFG"
: ((req->req_type) == 0xa0 ? "HWRM_TUNNEL_DST_PORT_QUERY":
((req->req_type) == 0xa1 ? "HWRM_TUNNEL_DST_PORT_ALLOC": (
(req->req_type) == 0xa2 ? "HWRM_TUNNEL_DST_PORT_FREE": ((req
->req_type) == 0xfffc ? "HWRM_NVM_RAW_DUMP": ((req->req_type
) == 0xfffb ? "HWRM_NVM_GET_DIR_INFO": ((req->req_type) ==
0xfffa ? "HWRM_NVM_GET_DIR_ENTRIES": ((req->req_type) == 0x10a
? "HWRM_CFA_VLAN_ANTISPOOF_QCFG": ((req->req_type) == 0xe
? "HWRM_FUNC_BUF_UNRGTR": ((req->req_type) == 0xf ? "HWRM_FUNC_VF_CFG"
: ((req->req_type) == 0xffff ? "HWRM_NVM_RAW_WRITE_BLK": (
(req->req_type) == 0xfffe ? "HWRM_NVM_WRITE": ((req->req_type
) == 0xfffd ? "HWRM_NVM_READ": ((req->req_type) == 0x50 ? "HWRM_RING_ALLOC"
: ((req->req_type) == 0x51 ? "HWRM_RING_FREE": ((req->req_type
) == 0x52 ? "HWRM_RING_CMPL_RING_QAGGINT_PARAMS": ((req->req_type
) == 0x53 ? "HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS": ((req->
req_type) == 0x4a ? "HWRM_VNIC_QCAPS": ((req->req_type) ==
0x49 ? "HWRM_VNIC_PLCMODES_QCFG": ((req->req_type) == 0x48
? "HWRM_VNIC_PLCMODES_CFG": ((req->req_type) == 0x47 ? "HWRM_VNIC_RSS_QCFG"
: ((req->req_type) == 0x46 ? "HWRM_VNIC_RSS_CFG": ((req->
req_type) == 0x44 ? "HWRM_VNIC_TPA_CFG": ((req->req_type) ==
0x43 ? "HWRM_VNIC_QCFG": ((req->req_type) == 0x42 ? "HWRM_VNIC_CFG"
: ((req->req_type) == 0x41 ? "HWRM_VNIC_FREE": ((req->req_type
) == 0x40 ? "HWRM_VNIC_ALLOC": ((req->req_type) == 0x0 ? "HWRM_VER_GET"
: ((req->req_type) == 0xfff9 ? "HWRM_NVM_FIND_DIR_ENTRY": (
(req->req_type) == 0xfff8 ? "HWRM_NVM_MOD_DIR_ENTRY": ((req
->req_type) == 0xfff7 ? "HWRM_NVM_ERASE_DIR_ENTRY": ((req->
req_type) == 0x5e ? "HWRM_RING_RESET": ((req->req_type) ==
0xfff5 ? "HWRM_NVM_VERIFY_UPDATE": ((req->req_type) == 0xfff4
? "HWRM_NVM_MODIFY": ((req->req_type) == 0xfff3 ? "HWRM_NVM_INSTALL_UPDATE"
: ((req->req_type) == 0xfff2 ? "HWRM_NVM_SET_VARIABLE": ((
req->req_type) == 0xfff1 ? "HWRM_NVM_GET_VARIABLE": ((req->
req_type) == 0xfff0 ? "HWRM_NVM_FLUSH": ((req->req_type) ==
0x2e ? "HWRM_PORT_LED_QCFG": ((req->req_type) == 0x2d ? "HWRM_PORT_LED_CFG"
: ((req->req_type) == 0x2f ? "HWRM_PORT_LED_QCAPS": ((req->
req_type) == 0x2a ? "HWRM_PORT_PHY_QCAPS": ((req->req_type
) == 0x38 ? "HWRM_QUEUE_PRI2COS_CFG": ((req->req_type) == 0x39
? "HWRM_QUEUE_COS2BW_QCFG": ((req->req_type) == 0x32 ? "HWRM_QUEUE_CFG"
: ((req->req_type) == 0x33 ? "HWRM_FUNC_VLAN_CFG": ((req->
req_type) == 0x30 ? "HWRM_QUEUE_QPORTCFG": ((req->req_type
) == 0x31 ? "HWRM_QUEUE_QCFG": ((req->req_type) == 0x36 ? "HWRM_QUEUE_PFCENABLE_CFG"
: ((req->req_type) == 0x37 ? "HWRM_QUEUE_PRI2COS_QCFG": ((
req->req_type) == 0x34 ? "HWRM_FUNC_VLAN_QCFG": ((req->
req_type) == 0x35 ? "HWRM_QUEUE_PFCENABLE_QCFG": ((req->req_type
) == 0xff14 ? "HWRM_DBG_DUMP": ((req->req_type) == 0xc8 ? "HWRM_FW_SET_TIME"
: ((req->req_type) == 0xc9 ? "HWRM_FW_GET_TIME": ((req->
req_type) == 0xf1 ? "HWRM_WOL_FILTER_FREE": ((req->req_type
) == 0xf0 ? "HWRM_WOL_FILTER_ALLOC": ((req->req_type) == 0x27
? "HWRM_PORT_PHY_QCFG": ((req->req_type) == 0xf2 ? "HWRM_WOL_FILTER_QCFG"
: ((req->req_type) == 0x21 ? "HWRM_PORT_MAC_CFG": ((req->
req_type) == 0x20 ? "HWRM_PORT_PHY_CFG": ((req->req_type) ==
0x23 ? "HWRM_PORT_QSTATS": ((req->req_type) == 0x28 ? "HWRM_PORT_MAC_QCFG"
: ((req->req_type) == 0xffef ? "HWRM_NVM_VALIDATE_OPTION":
((req->req_type) == 0x3a ? "HWRM_QUEUE_COS2BW_CFG": "Unknown req_type"
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))))))))))))))))))))))
,
2463 GET_HWRM_ERROR_CODE(err)((err) == 0xf ? "HWRM_ERROR": ((err) == 0xffff ? "CMD_NOT_SUPPORTED"
: ((err) == 0xfffe ? "UNKNOWN_ERR": ((err) == 0x4 ? "RESOURCE_ALLOC_ERROR"
: ((err) == 0x5 ? "INVALID_FLAGS": ((err) == 0x6 ? "INVALID_ENABLES"
: ((err) == 0x0 ? "SUCCESS": ((err) == 0x1 ? "FAIL": ((err) ==
0x2 ? "INVALID_PARAMS": ((err) == 0x3 ? "RESOURCE_ACCESS_DENIED"
: "Unknown error_code"))))))))))
);
2464 }
2465 return bnxt_hwrm_err_map(err);
2466 }
2467
2468 return 0;
2469}
2470
2471
2472int
2473hwrm_send_message(struct bnxt_softc *softc, void *msg, uint32_t msg_len)
2474{
2475 int rc;
2476
2477 BNXT_HWRM_LOCK(softc)mtx_enter(&softc->sc_lock);
2478 rc = _hwrm_send_message(softc, msg, msg_len);
2479 BNXT_HWRM_UNLOCK(softc)mtx_leave(&softc->sc_lock);
2480 return rc;
2481}
2482
2483
2484int
2485bnxt_hwrm_queue_qportcfg(struct bnxt_softc *softc)
2486{
2487 struct hwrm_queue_qportcfg_input req = {0};
2488 struct hwrm_queue_qportcfg_output *resp =
2489 BNXT_DMA_KVA(softc->sc_cmd_resp)((void *)(softc->sc_cmd_resp)->bdm_kva);
2490 int rc = 0;
2491
2492 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_QUEUE_QPORTCFG(0x30U));
2493
2494 BNXT_HWRM_LOCK(softc)mtx_enter(&softc->sc_lock);
2495 rc = _hwrm_send_message(softc, &req, sizeof(req));
2496 if (rc)
2497 goto qportcfg_exit;
2498
2499 if (!resp->max_configurable_queues) {
2500 rc = -EINVAL22;
2501 goto qportcfg_exit;
2502 }
2503
2504 softc->sc_tx_queue_id = resp->queue_id0;
2505
2506qportcfg_exit:
2507 BNXT_HWRM_UNLOCK(softc)mtx_leave(&softc->sc_lock);
2508 return rc;
2509}
2510
2511int
2512bnxt_hwrm_ver_get(struct bnxt_softc *softc)
2513{
2514 struct hwrm_ver_get_input req = {0};
2515 struct hwrm_ver_get_output *resp =
2516 BNXT_DMA_KVA(softc->sc_cmd_resp)((void *)(softc->sc_cmd_resp)->bdm_kva);
2517 int rc;
2518#if 0
2519 const char nastr[] = "<not installed>";
2520 const char naver[] = "<N/A>";
2521#endif
2522 uint32_t dev_caps_cfg;
2523
2524 softc->sc_max_req_len = HWRM_MAX_REQ_LEN(128);
2525 softc->sc_cmd_timeo = 1000;
2526 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_VER_GET(0x0U));
2527
2528 req.hwrm_intf_maj = HWRM_VERSION_MAJOR1;
2529 req.hwrm_intf_min = HWRM_VERSION_MINOR8;
2530 req.hwrm_intf_upd = HWRM_VERSION_UPDATE1;
2531
2532 BNXT_HWRM_LOCK(softc)mtx_enter(&softc->sc_lock);
2533 rc = _hwrm_send_message(softc, &req, sizeof(req));
2534 if (rc)
2535 goto fail;
2536
2537 printf(": fw ver %d.%d.%d, ", resp->hwrm_fw_maj, resp->hwrm_fw_min,
2538 resp->hwrm_fw_bld);
2539
2540 softc->sc_hwrm_ver = (resp->hwrm_intf_maj << 16) |
2541 (resp->hwrm_intf_min << 8) | resp->hwrm_intf_upd;
2542#if 0
2543 snprintf(softc->ver_info->hwrm_if_ver, BNXT_VERSTR_SIZE, "%d.%d.%d",
2544 resp->hwrm_intf_maj, resp->hwrm_intf_min, resp->hwrm_intf_upd);
2545 softc->ver_info->hwrm_if_major = resp->hwrm_intf_maj;
2546 softc->ver_info->hwrm_if_minor = resp->hwrm_intf_min;
2547 softc->ver_info->hwrm_if_update = resp->hwrm_intf_upd;
2548 snprintf(softc->ver_info->hwrm_fw_ver, BNXT_VERSTR_SIZE, "%d.%d.%d",
2549 resp->hwrm_fw_maj, resp->hwrm_fw_min, resp->hwrm_fw_bld);
2550 strlcpy(softc->ver_info->driver_hwrm_if_ver, HWRM_VERSION_STR"1.8.1.7",
2551 BNXT_VERSTR_SIZE);
2552 strlcpy(softc->ver_info->hwrm_fw_name, resp->hwrm_fw_name,
2553 BNXT_NAME_SIZE);
2554
2555 if (resp->mgmt_fw_maj == 0 && resp->mgmt_fw_min == 0 &&
2556 resp->mgmt_fw_bld == 0) {
2557 strlcpy(softc->ver_info->mgmt_fw_ver, naver, BNXT_VERSTR_SIZE);
2558 strlcpy(softc->ver_info->mgmt_fw_name, nastr, BNXT_NAME_SIZE);
2559 }
2560 else {
2561 snprintf(softc->ver_info->mgmt_fw_ver, BNXT_VERSTR_SIZE,
2562 "%d.%d.%d", resp->mgmt_fw_maj, resp->mgmt_fw_min,
2563 resp->mgmt_fw_bld);
2564 strlcpy(softc->ver_info->mgmt_fw_name, resp->mgmt_fw_name,
2565 BNXT_NAME_SIZE);
2566 }
2567 if (resp->netctrl_fw_maj == 0 && resp->netctrl_fw_min == 0 &&
2568 resp->netctrl_fw_bld == 0) {
2569 strlcpy(softc->ver_info->netctrl_fw_ver, naver,
2570 BNXT_VERSTR_SIZE);
2571 strlcpy(softc->ver_info->netctrl_fw_name, nastr,
2572 BNXT_NAME_SIZE);
2573 }
2574 else {
2575 snprintf(softc->ver_info->netctrl_fw_ver, BNXT_VERSTR_SIZE,
2576 "%d.%d.%d", resp->netctrl_fw_maj, resp->netctrl_fw_min,
2577 resp->netctrl_fw_bld);
2578 strlcpy(softc->ver_info->netctrl_fw_name, resp->netctrl_fw_name,
2579 BNXT_NAME_SIZE);
2580 }
2581 if (resp->roce_fw_maj == 0 && resp->roce_fw_min == 0 &&
2582 resp->roce_fw_bld == 0) {
2583 strlcpy(softc->ver_info->roce_fw_ver, naver, BNXT_VERSTR_SIZE);
2584 strlcpy(softc->ver_info->roce_fw_name, nastr, BNXT_NAME_SIZE);
2585 }
2586 else {
2587 snprintf(softc->ver_info->roce_fw_ver, BNXT_VERSTR_SIZE,
2588 "%d.%d.%d", resp->roce_fw_maj, resp->roce_fw_min,
2589 resp->roce_fw_bld);
2590 strlcpy(softc->ver_info->roce_fw_name, resp->roce_fw_name,
2591 BNXT_NAME_SIZE);
2592 }
2593 softc->ver_info->chip_num = le16toh(resp->chip_num)((__uint16_t)(resp->chip_num));
2594 softc->ver_info->chip_rev = resp->chip_rev;
2595 softc->ver_info->chip_metal = resp->chip_metal;
2596 softc->ver_info->chip_bond_id = resp->chip_bond_id;
2597 softc->ver_info->chip_type = resp->chip_platform_type;
2598#endif
2599
2600 if (resp->max_req_win_len)
2601 softc->sc_max_req_len = le16toh(resp->max_req_win_len)((__uint16_t)(resp->max_req_win_len));
2602 if (resp->def_req_timeout)
2603 softc->sc_cmd_timeo = le16toh(resp->def_req_timeout)((__uint16_t)(resp->def_req_timeout));
2604
2605 dev_caps_cfg = le32toh(resp->dev_caps_cfg)((__uint32_t)(resp->dev_caps_cfg));
2606 if ((dev_caps_cfg & HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_SHORT_CMD_SUPPORTED0x4U) &&
2607 (dev_caps_cfg & HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_SHORT_CMD_REQUIRED0x8U))
2608 softc->sc_flags |= BNXT_FLAG_SHORT_CMD0x0008;
2609
2610fail:
2611 BNXT_HWRM_UNLOCK(softc)mtx_leave(&softc->sc_lock);
2612 return rc;
2613}
2614
2615
2616int
2617bnxt_hwrm_func_drv_rgtr(struct bnxt_softc *softc)
2618{
2619 struct hwrm_func_drv_rgtr_input req = {0};
2620
2621 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_DRV_RGTR(0x1dU));
2622
2623 req.enables = htole32(HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_VER |((__uint32_t)(0x2U | 0x1U))
2624 HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_OS_TYPE)((__uint32_t)(0x2U | 0x1U));
2625 req.os_type = htole16(HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_FREEBSD)((__uint16_t)(0x2aU));
2626
2627 req.ver_maj = 6;
2628 req.ver_min = 4;
2629 req.ver_upd = 0;
2630
2631 return hwrm_send_message(softc, &req, sizeof(req));
2632}
2633
2634#if 0
2635
2636int
2637bnxt_hwrm_func_drv_unrgtr(struct bnxt_softc *softc, bool_Bool shutdown)
2638{
2639 struct hwrm_func_drv_unrgtr_input req = {0};
2640
2641 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_DRV_UNRGTR(0x1aU));
2642 if (shutdown == true1)
2643 req.flags |=
2644 HWRM_FUNC_DRV_UNRGTR_INPUT_FLAGS_PREPARE_FOR_SHUTDOWN0x1U;
2645 return hwrm_send_message(softc, &req, sizeof(req));
2646}
2647
2648#endif
2649
2650int
2651bnxt_hwrm_func_qcaps(struct bnxt_softc *softc)
2652{
2653 int rc = 0;
2654 struct hwrm_func_qcaps_input req = {0};
2655 struct hwrm_func_qcaps_output *resp =
2656 BNXT_DMA_KVA(softc->sc_cmd_resp)((void *)(softc->sc_cmd_resp)->bdm_kva);
2657 /* struct bnxt_func_info *func = &softc->func; */
2658
2659 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_QCAPS(0x15U));
2660 req.fid = htole16(0xffff)((__uint16_t)(0xffff));
2661
2662 BNXT_HWRM_LOCK(softc)mtx_enter(&softc->sc_lock);
2663 rc = _hwrm_send_message(softc, &req, sizeof(req));
2664 if (rc)
2665 goto fail;
2666
2667 if (resp->flags &
2668 htole32(HWRM_FUNC_QCAPS_OUTPUT_FLAGS_WOL_MAGICPKT_SUPPORTED)((__uint32_t)(0x20U)))
2669 softc->sc_flags |= BNXT_FLAG_WOL_CAP0x0004;
2670
2671 memcpy(softc->sc_ac.ac_enaddr, resp->mac_address, 6)__builtin_memcpy((softc->sc_ac.ac_enaddr), (resp->mac_address
), (6))
;
2672 /*
2673 func->fw_fid = le16toh(resp->fid);
2674 memcpy(func->mac_addr, resp->mac_address, ETHER_ADDR_LEN);
2675 func->max_rsscos_ctxs = le16toh(resp->max_rsscos_ctx);
2676 func->max_cp_rings = le16toh(resp->max_cmpl_rings);
2677 func->max_tx_rings = le16toh(resp->max_tx_rings);
2678 func->max_rx_rings = le16toh(resp->max_rx_rings);
2679 func->max_hw_ring_grps = le32toh(resp->max_hw_ring_grps);
2680 if (!func->max_hw_ring_grps)
2681 func->max_hw_ring_grps = func->max_tx_rings;
2682 func->max_l2_ctxs = le16toh(resp->max_l2_ctxs);
2683 func->max_vnics = le16toh(resp->max_vnics);
2684 func->max_stat_ctxs = le16toh(resp->max_stat_ctx);
2685 if (BNXT_PF(softc)) {
2686 struct bnxt_pf_info *pf = &softc->pf;
2687
2688 pf->port_id = le16toh(resp->port_id);
2689 pf->first_vf_id = le16toh(resp->first_vf_id);
2690 pf->max_vfs = le16toh(resp->max_vfs);
2691 pf->max_encap_records = le32toh(resp->max_encap_records);
2692 pf->max_decap_records = le32toh(resp->max_decap_records);
2693 pf->max_tx_em_flows = le32toh(resp->max_tx_em_flows);
2694 pf->max_tx_wm_flows = le32toh(resp->max_tx_wm_flows);
2695 pf->max_rx_em_flows = le32toh(resp->max_rx_em_flows);
2696 pf->max_rx_wm_flows = le32toh(resp->max_rx_wm_flows);
2697 }
2698 if (!_is_valid_ether_addr(func->mac_addr)) {
2699 device_printf(softc->dev, "Invalid ethernet address, generating random locally administered address\n");
2700 get_random_ether_addr(func->mac_addr);
2701 }
2702 */
2703
2704fail:
2705 BNXT_HWRM_UNLOCK(softc)mtx_leave(&softc->sc_lock);
2706 return rc;
2707}
2708
2709
2710int
2711bnxt_hwrm_func_qcfg(struct bnxt_softc *softc)
2712{
2713 struct hwrm_func_qcfg_input req = {0};
2714 /* struct hwrm_func_qcfg_output *resp =
2715 BNXT_DMA_KVA(softc->sc_cmd_resp);
2716 struct bnxt_func_qcfg *fn_qcfg = &softc->fn_qcfg; */
2717 int rc;
2718
2719 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_QCFG(0x16U));
2720 req.fid = htole16(0xffff)((__uint16_t)(0xffff));
2721 BNXT_HWRM_LOCK(softc)mtx_enter(&softc->sc_lock);
2722 rc = _hwrm_send_message(softc, &req, sizeof(req));
2723 if (rc)
2724 goto fail;
2725
2726 /*
2727 fn_qcfg->alloc_completion_rings = le16toh(resp->alloc_cmpl_rings);
2728 fn_qcfg->alloc_tx_rings = le16toh(resp->alloc_tx_rings);
2729 fn_qcfg->alloc_rx_rings = le16toh(resp->alloc_rx_rings);
2730 fn_qcfg->alloc_vnics = le16toh(resp->alloc_vnics);
2731 */
2732fail:
2733 BNXT_HWRM_UNLOCK(softc)mtx_leave(&softc->sc_lock);
2734 return rc;
2735}
2736
2737
2738int
2739bnxt_hwrm_func_reset(struct bnxt_softc *softc)
2740{
2741 struct hwrm_func_reset_input req = {0};
2742
2743 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_RESET(0x11U));
2744 req.enables = 0;
2745
2746 return hwrm_send_message(softc, &req, sizeof(req));
2747}
2748
2749int
2750bnxt_hwrm_vnic_cfg_placement(struct bnxt_softc *softc,
2751 struct bnxt_vnic_info *vnic)
2752{
2753 struct hwrm_vnic_plcmodes_cfg_input req = {0};
2754
2755 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_VNIC_PLCMODES_CFG(0x48U));
2756
2757 req.flags = htole32(((__uint32_t)(0x2U))
2758 HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_JUMBO_PLACEMENT)((__uint32_t)(0x2U));
2759 req.enables = htole32(((__uint32_t)(0x1U))
2760 HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_JUMBO_THRESH_VALID)((__uint32_t)(0x1U));
2761 req.vnic_id = htole16(vnic->id)((__uint16_t)(vnic->id));
2762 req.jumbo_thresh = htole16(MCLBYTES)((__uint16_t)((1 << 11)));
2763
2764 return hwrm_send_message(softc, &req, sizeof(req));
2765}
2766
2767int
2768bnxt_hwrm_vnic_cfg(struct bnxt_softc *softc, struct bnxt_vnic_info *vnic)
2769{
2770 struct hwrm_vnic_cfg_input req = {0};
2771
2772 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_VNIC_CFG(0x42U));
2773
2774 if (vnic->flags & BNXT_VNIC_FLAG_DEFAULT0x01)
2775 req.flags |= htole32(HWRM_VNIC_CFG_INPUT_FLAGS_DEFAULT)((__uint32_t)(0x1U));
2776 if (vnic->flags & BNXT_VNIC_FLAG_BD_STALL0x02)
2777 req.flags |= htole32(HWRM_VNIC_CFG_INPUT_FLAGS_BD_STALL_MODE)((__uint32_t)(0x4U));
2778 if (vnic->flags & BNXT_VNIC_FLAG_VLAN_STRIP0x04)
2779 req.flags |= htole32(HWRM_VNIC_CFG_INPUT_FLAGS_VLAN_STRIP_MODE)((__uint32_t)(0x2U));
2780 req.enables = htole32(HWRM_VNIC_CFG_INPUT_ENABLES_DFLT_RING_GRP |((__uint32_t)(0x1U | 0x2U | 0x10U))
2781 HWRM_VNIC_CFG_INPUT_ENABLES_RSS_RULE |((__uint32_t)(0x1U | 0x2U | 0x10U))
2782 HWRM_VNIC_CFG_INPUT_ENABLES_MRU)((__uint32_t)(0x1U | 0x2U | 0x10U));
2783 req.vnic_id = htole16(vnic->id)((__uint16_t)(vnic->id));
2784 req.dflt_ring_grp = htole16(vnic->def_ring_grp)((__uint16_t)(vnic->def_ring_grp));
2785 req.rss_rule = htole16(vnic->rss_id)((__uint16_t)(vnic->rss_id));
2786 req.cos_rule = htole16(vnic->cos_rule)((__uint16_t)(vnic->cos_rule));
2787 req.lb_rule = htole16(vnic->lb_rule)((__uint16_t)(vnic->lb_rule));
2788 req.mru = htole16(vnic->mru)((__uint16_t)(vnic->mru));
2789
2790 return hwrm_send_message(softc, &req, sizeof(req));
2791}
2792
2793int
2794bnxt_hwrm_vnic_alloc(struct bnxt_softc *softc, struct bnxt_vnic_info *vnic)
2795{
2796 struct hwrm_vnic_alloc_input req = {0};
2797 struct hwrm_vnic_alloc_output *resp =
2798 BNXT_DMA_KVA(softc->sc_cmd_resp)((void *)(softc->sc_cmd_resp)->bdm_kva);
2799 int rc;
2800
2801 if (vnic->id != (uint16_t)HWRM_NA_SIGNATURE((uint32_t)(-1))) {
2802 printf("%s: attempt to re-allocate vnic %04x\n",
2803 DEVNAME(softc)((softc)->sc_dev.dv_xname), vnic->id);
2804 return EINVAL22;
2805 }
2806
2807 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_VNIC_ALLOC(0x40U));
2808
2809 if (vnic->flags & BNXT_VNIC_FLAG_DEFAULT0x01)
2810 req.flags = htole32(HWRM_VNIC_ALLOC_INPUT_FLAGS_DEFAULT)((__uint32_t)(0x1U));
2811
2812 BNXT_HWRM_LOCK(softc)mtx_enter(&softc->sc_lock);
2813 rc = _hwrm_send_message(softc, &req, sizeof(req));
2814 if (rc)
2815 goto fail;
2816
2817 vnic->id = le32toh(resp->vnic_id)((__uint32_t)(resp->vnic_id));
2818
2819fail:
2820 BNXT_HWRM_UNLOCK(softc)mtx_leave(&softc->sc_lock);
2821 return rc;
2822}
2823
2824int
2825bnxt_hwrm_vnic_free(struct bnxt_softc *softc, struct bnxt_vnic_info *vnic)
2826{
2827 struct hwrm_vnic_free_input req = {0};
2828 int rc;
2829
2830 if (vnic->id == (uint16_t)HWRM_NA_SIGNATURE((uint32_t)(-1))) {
2831 printf("%s: attempt to deallocate vnic %04x\n",
2832 DEVNAME(softc)((softc)->sc_dev.dv_xname), vnic->id);
2833 return (EINVAL22);
2834 }
2835
2836 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_VNIC_FREE(0x41U));
2837 req.vnic_id = htole16(vnic->id)((__uint16_t)(vnic->id));
2838
2839 BNXT_HWRM_LOCK(softc)mtx_enter(&softc->sc_lock);
2840 rc = _hwrm_send_message(softc, &req, sizeof(req));
2841 if (rc == 0)
2842 vnic->id = (uint16_t)HWRM_NA_SIGNATURE((uint32_t)(-1));
2843 BNXT_HWRM_UNLOCK(softc)mtx_leave(&softc->sc_lock);
2844
2845 return (rc);
2846}
2847
2848int
2849bnxt_hwrm_vnic_ctx_alloc(struct bnxt_softc *softc, uint16_t *ctx_id)
2850{
2851 struct hwrm_vnic_rss_cos_lb_ctx_alloc_input req = {0};
2852 struct hwrm_vnic_rss_cos_lb_ctx_alloc_output *resp =
2853 BNXT_DMA_KVA(softc->sc_cmd_resp)((void *)(softc->sc_cmd_resp)->bdm_kva);
2854 int rc;
2855
2856 if (*ctx_id != (uint16_t)HWRM_NA_SIGNATURE((uint32_t)(-1))) {
2857 printf("%s: attempt to re-allocate vnic ctx %04x\n",
2858 DEVNAME(softc)((softc)->sc_dev.dv_xname), *ctx_id);
2859 return EINVAL22;
2860 }
2861
2862 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_VNIC_RSS_COS_LB_CTX_ALLOC(0x70U));
2863
2864 BNXT_HWRM_LOCK(softc)mtx_enter(&softc->sc_lock);
2865 rc = _hwrm_send_message(softc, &req, sizeof(req));
2866 if (rc)
2867 goto fail;
2868
2869 *ctx_id = letoh16(resp->rss_cos_lb_ctx_id)((__uint16_t)(resp->rss_cos_lb_ctx_id));
2870
2871fail:
2872 BNXT_HWRM_UNLOCK(softc)mtx_leave(&softc->sc_lock);
2873 return (rc);
2874}
2875
2876int
2877bnxt_hwrm_vnic_ctx_free(struct bnxt_softc *softc, uint16_t *ctx_id)
2878{
2879 struct hwrm_vnic_rss_cos_lb_ctx_free_input req = {0};
2880 int rc;
2881
2882 if (*ctx_id == (uint16_t)HWRM_NA_SIGNATURE((uint32_t)(-1))) {
2883 printf("%s: attempt to deallocate vnic ctx %04x\n",
2884 DEVNAME(softc)((softc)->sc_dev.dv_xname), *ctx_id);
2885 return (EINVAL22);
2886 }
2887
2888 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_VNIC_RSS_COS_LB_CTX_FREE(0x71U));
2889 req.rss_cos_lb_ctx_id = htole32(*ctx_id)((__uint32_t)(*ctx_id));
2890
2891 BNXT_HWRM_LOCK(softc)mtx_enter(&softc->sc_lock);
2892 rc = _hwrm_send_message(softc, &req, sizeof(req));
2893 if (rc == 0)
2894 *ctx_id = (uint16_t)HWRM_NA_SIGNATURE((uint32_t)(-1));
2895 BNXT_HWRM_UNLOCK(softc)mtx_leave(&softc->sc_lock);
2896 return (rc);
2897}
2898
2899int
2900bnxt_hwrm_ring_grp_alloc(struct bnxt_softc *softc, struct bnxt_grp_info *grp)
2901{
2902 struct hwrm_ring_grp_alloc_input req = {0};
2903 struct hwrm_ring_grp_alloc_output *resp;
2904 int rc = 0;
2905
2906 if (grp->grp_id != HWRM_NA_SIGNATURE((uint32_t)(-1))) {
2907 printf("%s: attempt to re-allocate ring group %04x\n",
2908 DEVNAME(softc)((softc)->sc_dev.dv_xname), grp->grp_id);
2909 return EINVAL22;
2910 }
2911
2912 resp = BNXT_DMA_KVA(softc->sc_cmd_resp)((void *)(softc->sc_cmd_resp)->bdm_kva);
2913 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_RING_GRP_ALLOC(0x60U));
2914 req.cr = htole16(grp->cp_ring_id)((__uint16_t)(grp->cp_ring_id));
2915 req.rr = htole16(grp->rx_ring_id)((__uint16_t)(grp->rx_ring_id));
2916 req.ar = htole16(grp->ag_ring_id)((__uint16_t)(grp->ag_ring_id));
2917 req.sc = htole16(grp->stats_ctx)((__uint16_t)(grp->stats_ctx));
2918
2919 BNXT_HWRM_LOCK(softc)mtx_enter(&softc->sc_lock);
2920 rc = _hwrm_send_message(softc, &req, sizeof(req));
2921 if (rc)
2922 goto fail;
2923
2924 grp->grp_id = letoh32(resp->ring_group_id)((__uint32_t)(resp->ring_group_id));
2925
2926fail:
2927 BNXT_HWRM_UNLOCK(softc)mtx_leave(&softc->sc_lock);
2928 return rc;
2929}
2930
2931int
2932bnxt_hwrm_ring_grp_free(struct bnxt_softc *softc, struct bnxt_grp_info *grp)
2933{
2934 struct hwrm_ring_grp_free_input req = {0};
2935 int rc = 0;
2936
2937 if (grp->grp_id == HWRM_NA_SIGNATURE((uint32_t)(-1))) {
2938 printf("%s: attempt to free ring group %04x\n",
2939 DEVNAME(softc)((softc)->sc_dev.dv_xname), grp->grp_id);
2940 return EINVAL22;
2941 }
2942
2943 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_RING_GRP_FREE(0x61U));
2944 req.ring_group_id = htole32(grp->grp_id)((__uint32_t)(grp->grp_id));
2945
2946 BNXT_HWRM_LOCK(softc)mtx_enter(&softc->sc_lock);
2947 rc = _hwrm_send_message(softc, &req, sizeof(req));
2948 if (rc == 0)
2949 grp->grp_id = HWRM_NA_SIGNATURE((uint32_t)(-1));
2950
2951 BNXT_HWRM_UNLOCK(softc)mtx_leave(&softc->sc_lock);
2952 return (rc);
2953}
2954
2955/*
2956 * Ring allocation message to the firmware
2957 */
2958int
2959bnxt_hwrm_ring_alloc(struct bnxt_softc *softc, uint8_t type,
2960 struct bnxt_ring *ring, uint16_t cmpl_ring_id, uint32_t stat_ctx_id,
2961 int irq)
2962{
2963 struct hwrm_ring_alloc_input req = {0};
2964 struct hwrm_ring_alloc_output *resp;
2965 int rc;
2966
2967 if (ring->phys_id != (uint16_t)HWRM_NA_SIGNATURE((uint32_t)(-1))) {
2968 printf("%s: attempt to re-allocate ring %04x\n",
2969 DEVNAME(softc)((softc)->sc_dev.dv_xname), ring->phys_id);
2970 return EINVAL22;
2971 }
2972
2973 resp = BNXT_DMA_KVA(softc->sc_cmd_resp)((void *)(softc->sc_cmd_resp)->bdm_kva);
2974 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_RING_ALLOC(0x50U));
2975 req.enables = htole32(0)((__uint32_t)(0));
2976 req.fbo = htole32(0)((__uint32_t)(0));
2977
2978 if (stat_ctx_id != HWRM_NA_SIGNATURE((uint32_t)(-1))) {
2979 req.enables |= htole32(((__uint32_t)(0x8U))
2980 HWRM_RING_ALLOC_INPUT_ENABLES_STAT_CTX_ID_VALID)((__uint32_t)(0x8U));
2981 req.stat_ctx_id = htole32(stat_ctx_id)((__uint32_t)(stat_ctx_id));
2982 }
2983 req.ring_type = type;
2984 req.page_tbl_addr = htole64(ring->paddr)((__uint64_t)(ring->paddr));
2985 req.length = htole32(ring->ring_size)((__uint32_t)(ring->ring_size));
2986 req.logical_id = htole16(ring->id)((__uint16_t)(ring->id));
2987 req.cmpl_ring_id = htole16(cmpl_ring_id)((__uint16_t)(cmpl_ring_id));
2988 req.queue_id = htole16(softc->sc_tx_queue_id)((__uint16_t)(softc->sc_tx_queue_id));
2989 req.int_mode = (softc->sc_flags & BNXT_FLAG_MSIX0x0010) ?
2990 HWRM_RING_ALLOC_INPUT_INT_MODE_MSIX0x2U :
2991 HWRM_RING_ALLOC_INPUT_INT_MODE_LEGACY0x0U;
2992 BNXT_HWRM_LOCK(softc)mtx_enter(&softc->sc_lock);
2993 rc = _hwrm_send_message(softc, &req, sizeof(req));
2994 if (rc)
2995 goto fail;
2996
2997 ring->phys_id = le16toh(resp->ring_id)((__uint16_t)(resp->ring_id));
2998
2999fail:
3000 BNXT_HWRM_UNLOCK(softc)mtx_leave(&softc->sc_lock);
3001 return rc;
3002}
3003
3004int
3005bnxt_hwrm_ring_free(struct bnxt_softc *softc, uint8_t type, struct bnxt_ring *ring)
3006{
3007 struct hwrm_ring_free_input req = {0};
3008 int rc;
3009
3010 if (ring->phys_id == (uint16_t)HWRM_NA_SIGNATURE((uint32_t)(-1))) {
3011 printf("%s: attempt to deallocate ring %04x\n",
3012 DEVNAME(softc)((softc)->sc_dev.dv_xname), ring->phys_id);
3013 return (EINVAL22);
3014 }
3015
3016 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_RING_FREE(0x51U));
3017 req.ring_type = type;
3018 req.ring_id = htole16(ring->phys_id)((__uint16_t)(ring->phys_id));
3019 BNXT_HWRM_LOCK(softc)mtx_enter(&softc->sc_lock);
3020 rc = _hwrm_send_message(softc, &req, sizeof(req));
3021 if (rc)
3022 goto fail;
3023
3024 ring->phys_id = (uint16_t)HWRM_NA_SIGNATURE((uint32_t)(-1));
3025fail:
3026 BNXT_HWRM_UNLOCK(softc)mtx_leave(&softc->sc_lock);
3027 return (rc);
3028}
3029
3030
3031int
3032bnxt_hwrm_stat_ctx_alloc(struct bnxt_softc *softc, struct bnxt_cp_ring *cpr,
3033 uint64_t paddr)
3034{
3035 struct hwrm_stat_ctx_alloc_input req = {0};
3036 struct hwrm_stat_ctx_alloc_output *resp;
3037 int rc = 0;
3038
3039 if (cpr->stats_ctx_id != HWRM_NA_SIGNATURE((uint32_t)(-1))) {
3040 printf("%s: attempt to re-allocate stats ctx %08x\n",
3041 DEVNAME(softc)((softc)->sc_dev.dv_xname), cpr->stats_ctx_id);
3042 return EINVAL22;
3043 }
3044
3045 resp = BNXT_DMA_KVA(softc->sc_cmd_resp)((void *)(softc->sc_cmd_resp)->bdm_kva);
3046 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_STAT_CTX_ALLOC(0xb0U));
3047
3048 req.update_period_ms = htole32(1000)((__uint32_t)(1000));
3049 req.stats_dma_addr = htole64(paddr)((__uint64_t)(paddr));
3050
3051 BNXT_HWRM_LOCK(softc)mtx_enter(&softc->sc_lock);
3052 rc = _hwrm_send_message(softc, &req, sizeof(req));
3053 if (rc)
3054 goto fail;
3055
3056 cpr->stats_ctx_id = le32toh(resp->stat_ctx_id)((__uint32_t)(resp->stat_ctx_id));
3057
3058fail:
3059 BNXT_HWRM_UNLOCK(softc)mtx_leave(&softc->sc_lock);
3060
3061 return rc;
3062}
3063
3064int
3065bnxt_hwrm_stat_ctx_free(struct bnxt_softc *softc, struct bnxt_cp_ring *cpr)
3066{
3067 struct hwrm_stat_ctx_free_input req = {0};
3068 int rc = 0;
3069
3070 if (cpr->stats_ctx_id == HWRM_NA_SIGNATURE((uint32_t)(-1))) {
3071 printf("%s: attempt to free stats ctx %08x\n",
3072 DEVNAME(softc)((softc)->sc_dev.dv_xname), cpr->stats_ctx_id);
3073 return EINVAL22;
3074 }
3075
3076 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_STAT_CTX_FREE(0xb1U));
3077 req.stat_ctx_id = htole32(cpr->stats_ctx_id)((__uint32_t)(cpr->stats_ctx_id));
3078
3079 BNXT_HWRM_LOCK(softc)mtx_enter(&softc->sc_lock);
3080 rc = _hwrm_send_message(softc, &req, sizeof(req));
3081 BNXT_HWRM_UNLOCK(softc)mtx_leave(&softc->sc_lock);
3082
3083 if (rc == 0)
3084 cpr->stats_ctx_id = HWRM_NA_SIGNATURE((uint32_t)(-1));
3085
3086 return (rc);
3087}
3088
3089#if 0
3090
3091int
3092bnxt_hwrm_port_qstats(struct bnxt_softc *softc)
3093{
3094 struct hwrm_port_qstats_input req = {0};
3095 int rc = 0;
3096
3097 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_PORT_QSTATS(0x23U));
3098
3099 req.port_id = htole16(softc->pf.port_id)((__uint16_t)(softc->pf.port_id));
3100 req.rx_stat_host_addr = htole64(softc->hw_rx_port_stats.idi_paddr)((__uint64_t)(softc->hw_rx_port_stats.idi_paddr));
3101 req.tx_stat_host_addr = htole64(softc->hw_tx_port_stats.idi_paddr)((__uint64_t)(softc->hw_tx_port_stats.idi_paddr));
3102
3103 BNXT_HWRM_LOCK(softc)mtx_enter(&softc->sc_lock);
3104 rc = _hwrm_send_message(softc, &req, sizeof(req));
3105 BNXT_HWRM_UNLOCK(softc)mtx_leave(&softc->sc_lock);
3106
3107 return rc;
3108}
3109
3110#endif
3111
3112int
3113bnxt_hwrm_cfa_l2_set_rx_mask(struct bnxt_softc *softc,
3114 uint32_t vnic_id, uint32_t rx_mask, uint64_t mc_addr, uint32_t mc_count)
3115{
3116 struct hwrm_cfa_l2_set_rx_mask_input req = {0};
3117
3118 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_CFA_L2_SET_RX_MASK(0x93U));
3119
3120 req.vnic_id = htole32(vnic_id)((__uint32_t)(vnic_id));
3121 req.mask = htole32(rx_mask)((__uint32_t)(rx_mask));
3122 req.mc_tbl_addr = htole64(mc_addr)((__uint64_t)(mc_addr));
3123 req.num_mc_entries = htole32(mc_count)((__uint32_t)(mc_count));
3124 return hwrm_send_message(softc, &req, sizeof(req));
3125}
3126
3127int
3128bnxt_hwrm_set_filter(struct bnxt_softc *softc, struct bnxt_vnic_info *vnic)
3129{
3130 struct hwrm_cfa_l2_filter_alloc_input req = {0};
3131 struct hwrm_cfa_l2_filter_alloc_output *resp;
3132 uint32_t enables = 0;
3133 int rc = 0;
3134
3135 if (vnic->filter_id != -1) {
3136 printf("%s: attempt to re-allocate l2 ctx filter\n",
3137 DEVNAME(softc)((softc)->sc_dev.dv_xname));
3138 return EINVAL22;
3139 }
3140
3141 resp = BNXT_DMA_KVA(softc->sc_cmd_resp)((void *)(softc->sc_cmd_resp)->bdm_kva);
3142 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_CFA_L2_FILTER_ALLOC(0x90U));
3143
3144 req.flags = htole32(HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX((__uint32_t)((0x1U << 0) | 0x8U))
3145 | HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_OUTERMOST)((__uint32_t)((0x1U << 0) | 0x8U));
3146 enables = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR0x1U
3147 | HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR_MASK0x2U
3148 | HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_DST_ID0x8000U;
3149 req.enables = htole32(enables)((__uint32_t)(enables));
3150 req.dst_id = htole16(vnic->id)((__uint16_t)(vnic->id));
3151 memcpy(req.l2_addr, softc->sc_ac.ac_enaddr, ETHER_ADDR_LEN)__builtin_memcpy((req.l2_addr), (softc->sc_ac.ac_enaddr), (
6))
;
3152 memset(&req.l2_addr_mask, 0xff, sizeof(req.l2_addr_mask))__builtin_memset((&req.l2_addr_mask), (0xff), (sizeof(req
.l2_addr_mask)))
;
3153
3154 BNXT_HWRM_LOCK(softc)mtx_enter(&softc->sc_lock);
3155 rc = _hwrm_send_message(softc, &req, sizeof(req));
3156 if (rc)
3157 goto fail;
3158
3159 vnic->filter_id = le64toh(resp->l2_filter_id)((__uint64_t)(resp->l2_filter_id));
3160 vnic->flow_id = le64toh(resp->flow_id)((__uint64_t)(resp->flow_id));
3161
3162fail:
3163 BNXT_HWRM_UNLOCK(softc)mtx_leave(&softc->sc_lock);
3164 return (rc);
3165}
3166
3167int
3168bnxt_hwrm_free_filter(struct bnxt_softc *softc, struct bnxt_vnic_info *vnic)
3169{
3170 struct hwrm_cfa_l2_filter_free_input req = {0};
3171 int rc = 0;
3172
3173 if (vnic->filter_id == -1) {
3174 printf("%s: attempt to deallocate filter %llx\n",
3175 DEVNAME(softc)((softc)->sc_dev.dv_xname), vnic->filter_id);
3176 return (EINVAL22);
3177 }
3178
3179 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_CFA_L2_FILTER_FREE(0x91U));
3180 req.l2_filter_id = htole64(vnic->filter_id)((__uint64_t)(vnic->filter_id));
3181
3182 BNXT_HWRM_LOCK(softc)mtx_enter(&softc->sc_lock);
3183 rc = _hwrm_send_message(softc, &req, sizeof(req));
3184 if (rc == 0)
3185 vnic->filter_id = -1;
3186 BNXT_HWRM_UNLOCK(softc)mtx_leave(&softc->sc_lock);
3187
3188 return (rc);
3189}
3190
3191
3192int
3193bnxt_hwrm_vnic_rss_cfg(struct bnxt_softc *softc, struct bnxt_vnic_info *vnic,
3194 uint32_t hash_type, daddr_t rss_table, daddr_t rss_key)
3195{
3196 struct hwrm_vnic_rss_cfg_input req = {0};
3197
3198 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_VNIC_RSS_CFG(0x46U));
3199
3200 req.hash_type = htole32(hash_type)((__uint32_t)(hash_type));
3201 req.ring_grp_tbl_addr = htole64(rss_table)((__uint64_t)(rss_table));
3202 req.hash_key_tbl_addr = htole64(rss_key)((__uint64_t)(rss_key));
3203 req.rss_ctx_idx = htole16(vnic->rss_id)((__uint16_t)(vnic->rss_id));
3204
3205 return hwrm_send_message(softc, &req, sizeof(req));
3206}
3207
3208int
3209bnxt_cfg_async_cr(struct bnxt_softc *softc, struct bnxt_cp_ring *cpr)
3210{
3211 int rc = 0;
3212
3213 if (1 /* BNXT_PF(softc) */) {
3214 struct hwrm_func_cfg_input req = {0};
3215
3216 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_CFG(0x17U));
3217
3218 req.fid = htole16(0xffff)((__uint16_t)(0xffff));
3219 req.enables = htole32(HWRM_FUNC_CFG_INPUT_ENABLES_ASYNC_EVENT_CR)((__uint32_t)(0x4000U));
3220 req.async_event_cr = htole16(cpr->ring.phys_id)((__uint16_t)(cpr->ring.phys_id));
3221
3222 rc = hwrm_send_message(softc, &req, sizeof(req));
3223 } else {
3224 struct hwrm_func_vf_cfg_input req = {0};
3225
3226 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_VF_CFG(0xfU));
3227
3228 req.enables = htole32(HWRM_FUNC_VF_CFG_INPUT_ENABLES_ASYNC_EVENT_CR)((__uint32_t)(0x4U));
3229 req.async_event_cr = htole16(cpr->ring.phys_id)((__uint16_t)(cpr->ring.phys_id));
3230
3231 rc = hwrm_send_message(softc, &req, sizeof(req));
3232 }
3233 return rc;
3234}
3235
3236#if 0
3237
3238void
3239bnxt_validate_hw_lro_settings(struct bnxt_softc *softc)
3240{
3241 softc->hw_lro.enable = min(softc->hw_lro.enable, 1);
3242
3243 softc->hw_lro.is_mode_gro = min(softc->hw_lro.is_mode_gro, 1);
3244
3245 softc->hw_lro.max_agg_segs = min(softc->hw_lro.max_agg_segs,
3246 HWRM_VNIC_TPA_CFG_INPUT_MAX_AGG_SEGS_MAX0x1fU);
3247
3248 softc->hw_lro.max_aggs = min(softc->hw_lro.max_aggs,
3249 HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_MAX0x7U);
3250
3251 softc->hw_lro.min_agg_len = min(softc->hw_lro.min_agg_len, BNXT_MAX_MTU9500);
3252}
3253
3254int
3255bnxt_hwrm_vnic_tpa_cfg(struct bnxt_softc *softc)
3256{
3257 struct hwrm_vnic_tpa_cfg_input req = {0};
3258 uint32_t flags;
3259
3260 if (softc->vnic_info.id == (uint16_t) HWRM_NA_SIGNATURE((uint32_t)(-1))) {
3261 return 0;
3262 }
3263
3264 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_VNIC_TPA_CFG(0x44U));
3265
3266 if (softc->hw_lro.enable) {
3267 flags = HWRM_VNIC_TPA_CFG_INPUT_FLAGS_TPA0x1U |
3268 HWRM_VNIC_TPA_CFG_INPUT_FLAGS_ENCAP_TPA0x2U |
3269 HWRM_VNIC_TPA_CFG_INPUT_FLAGS_AGG_WITH_ECN0x10U |
3270 HWRM_VNIC_TPA_CFG_INPUT_FLAGS_AGG_WITH_SAME_GRE_SEQ0x20U;
3271
3272 if (softc->hw_lro.is_mode_gro)
3273 flags |= HWRM_VNIC_TPA_CFG_INPUT_FLAGS_GRO0x8U;
3274 else
3275 flags |= HWRM_VNIC_TPA_CFG_INPUT_FLAGS_RSC_WND_UPDATE0x4U;
3276
3277 req.flags = htole32(flags)((__uint32_t)(flags));
3278
3279 req.enables = htole32(HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MAX_AGG_SEGS |((__uint32_t)(0x1U | 0x2U | 0x8U))
3280 HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MAX_AGGS |((__uint32_t)(0x1U | 0x2U | 0x8U))
3281 HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MIN_AGG_LEN)((__uint32_t)(0x1U | 0x2U | 0x8U));
3282
3283 req.max_agg_segs = htole16(softc->hw_lro.max_agg_segs)((__uint16_t)(softc->hw_lro.max_agg_segs));
3284 req.max_aggs = htole16(softc->hw_lro.max_aggs)((__uint16_t)(softc->hw_lro.max_aggs));
3285 req.min_agg_len = htole32(softc->hw_lro.min_agg_len)((__uint32_t)(softc->hw_lro.min_agg_len));
3286 }
3287
3288 req.vnic_id = htole16(softc->vnic_info.id)((__uint16_t)(softc->vnic_info.id));
3289
3290 return hwrm_send_message(softc, &req, sizeof(req));
3291}
3292
3293
3294int
3295bnxt_hwrm_fw_reset(struct bnxt_softc *softc, uint8_t processor,
3296 uint8_t *selfreset)
3297{
3298 struct hwrm_fw_reset_input req = {0};
3299 struct hwrm_fw_reset_output *resp =
3300 (void *)softc->hwrm_cmd_resp.idi_vaddr;
3301 int rc;
3302
3303 MPASS(selfreset);
3304
3305 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FW_RESET(0xc0U));
3306 req.embedded_proc_type = processor;
3307 req.selfrst_status = *selfreset;
3308
3309 BNXT_HWRM_LOCK(softc)mtx_enter(&softc->sc_lock);
3310 rc = _hwrm_send_message(softc, &req, sizeof(req));
3311 if (rc)
3312 goto exit;
3313 *selfreset = resp->selfrst_status;
3314
3315exit:
3316 BNXT_HWRM_UNLOCK(softc)mtx_leave(&softc->sc_lock);
3317 return rc;
3318}
3319
3320int
3321bnxt_hwrm_fw_qstatus(struct bnxt_softc *softc, uint8_t type, uint8_t *selfreset)
3322{
3323 struct hwrm_fw_qstatus_input req = {0};
3324 struct hwrm_fw_qstatus_output *resp =
3325 (void *)softc->hwrm_cmd_resp.idi_vaddr;
3326 int rc;
3327
3328 MPASS(selfreset);
3329
3330 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FW_QSTATUS(0xc1U));
3331 req.embedded_proc_type = type;
3332
3333 BNXT_HWRM_LOCK(softc)mtx_enter(&softc->sc_lock);
3334 rc = _hwrm_send_message(softc, &req, sizeof(req));
3335 if (rc)
3336 goto exit;
3337 *selfreset = resp->selfrst_status;
3338
3339exit:
3340 BNXT_HWRM_UNLOCK(softc)mtx_leave(&softc->sc_lock);
3341 return rc;
3342}
3343
3344#endif
3345
3346int
3347bnxt_hwrm_nvm_get_dev_info(struct bnxt_softc *softc, uint16_t *mfg_id,
3348 uint16_t *device_id, uint32_t *sector_size, uint32_t *nvram_size,
3349 uint32_t *reserved_size, uint32_t *available_size)
3350{
3351 struct hwrm_nvm_get_dev_info_input req = {0};
3352 struct hwrm_nvm_get_dev_info_output *resp =
3353 BNXT_DMA_KVA(softc->sc_cmd_resp)((void *)(softc->sc_cmd_resp)->bdm_kva);
3354 int rc;
3355 uint32_t old_timeo;
3356
3357 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_NVM_GET_DEV_INFO(0xfff6U));
3358
3359 BNXT_HWRM_LOCK(softc)mtx_enter(&softc->sc_lock);
3360 old_timeo = softc->sc_cmd_timeo;
3361 softc->sc_cmd_timeo = BNXT_NVM_TIMEO(5 * 60 * 1000);
3362 rc = _hwrm_send_message(softc, &req, sizeof(req));
3363 softc->sc_cmd_timeo = old_timeo;
3364 if (rc)
3365 goto exit;
3366
3367 if (mfg_id)
3368 *mfg_id = le16toh(resp->manufacturer_id)((__uint16_t)(resp->manufacturer_id));
3369 if (device_id)
3370 *device_id = le16toh(resp->device_id)((__uint16_t)(resp->device_id));
3371 if (sector_size)
3372 *sector_size = le32toh(resp->sector_size)((__uint32_t)(resp->sector_size));
3373 if (nvram_size)
3374 *nvram_size = le32toh(resp->nvram_size)((__uint32_t)(resp->nvram_size));
3375 if (reserved_size)
3376 *reserved_size = le32toh(resp->reserved_size)((__uint32_t)(resp->reserved_size));
3377 if (available_size)
3378 *available_size = le32toh(resp->available_size)((__uint32_t)(resp->available_size));
3379
3380exit:
3381 BNXT_HWRM_UNLOCK(softc)mtx_leave(&softc->sc_lock);
3382 return rc;
3383}
3384
3385#if 0
3386
3387int
3388bnxt_hwrm_fw_get_time(struct bnxt_softc *softc, uint16_t *year, uint8_t *month,
3389 uint8_t *day, uint8_t *hour, uint8_t *minute, uint8_t *second,
3390 uint16_t *millisecond, uint16_t *zone)
3391{
3392 struct hwrm_fw_get_time_input req = {0};
3393 struct hwrm_fw_get_time_output *resp =
3394 (void *)softc->hwrm_cmd_resp.idi_vaddr;
3395 int rc;
3396
3397 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FW_GET_TIME(0xc9U));
3398
3399 BNXT_HWRM_LOCK(softc)mtx_enter(&softc->sc_lock);
3400 rc = _hwrm_send_message(softc, &req, sizeof(req));
3401 if (rc)
3402 goto exit;
3403
3404 if (year)
3405 *year = le16toh(resp->year)((__uint16_t)(resp->year));
3406 if (month)
3407 *month = resp->month;
3408 if (day)
3409 *day = resp->day;
3410 if (hour)
3411 *hour = resp->hour;
3412 if (minute)
3413 *minute = resp->minute;
3414 if (second)
3415 *second = resp->second;
3416 if (millisecond)
3417 *millisecond = le16toh(resp->millisecond)((__uint16_t)(resp->millisecond));
3418 if (zone)
3419 *zone = le16toh(resp->zone)((__uint16_t)(resp->zone));
3420
3421exit:
3422 BNXT_HWRM_UNLOCK(softc)mtx_leave(&softc->sc_lock);
3423 return rc;
3424}
3425
3426int
3427bnxt_hwrm_fw_set_time(struct bnxt_softc *softc, uint16_t year, uint8_t month,
3428 uint8_t day, uint8_t hour, uint8_t minute, uint8_t second,
3429 uint16_t millisecond, uint16_t zone)
3430{
3431 struct hwrm_fw_set_time_input req = {0};
3432
3433 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FW_SET_TIME(0xc8U));
3434
3435 req.year = htole16(year)((__uint16_t)(year));
3436 req.month = month;
3437 req.day = day;
3438 req.hour = hour;
3439 req.minute = minute;
3440 req.second = second;
3441 req.millisecond = htole16(millisecond)((__uint16_t)(millisecond));
3442 req.zone = htole16(zone)((__uint16_t)(zone));
3443 return hwrm_send_message(softc, &req, sizeof(req));
3444}
3445
3446#endif
3447
3448void
3449_bnxt_hwrm_set_async_event_bit(struct hwrm_func_drv_rgtr_input *req, int bit)
3450{
3451 req->async_event_fwd[bit/32] |= (1 << (bit % 32));
3452}
3453
3454int bnxt_hwrm_func_rgtr_async_events(struct bnxt_softc *softc)
3455{
3456 struct hwrm_func_drv_rgtr_input req = {0};
3457 int events[] = {
3458 HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_STATUS_CHANGE0x0U,
3459 HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_DRVR_UNLOAD0x20U,
3460 HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PORT_CONN_NOT_ALLOWED0x4U,
3461 HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_CFG_CHANGE0x33U,
3462 HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE0x6U
3463 };
3464 int i;
3465
3466 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_DRV_RGTR(0x1dU));
3467
3468 req.enables =
3469 htole32(HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_ASYNC_EVENT_FWD)((__uint32_t)(0x10U));
3470
3471 for (i = 0; i < nitems(events)(sizeof((events)) / sizeof((events)[0])); i++)
3472 _bnxt_hwrm_set_async_event_bit(&req, events[i]);
3473
3474 return hwrm_send_message(softc, &req, sizeof(req));
3475}
3476
3477int
3478bnxt_get_sffpage(struct bnxt_softc *softc, struct if_sffpage *sff)
3479{
3480 struct hwrm_port_phy_i2c_read_input req;
3481 struct hwrm_port_phy_i2c_read_output *out;
3482 int offset;
3483
3484 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_PORT_PHY_I2C_READ(0x2cU));
3485 req.i2c_slave_addr = sff->sff_addr;
3486 req.page_number = htole16(sff->sff_page)((__uint16_t)(sff->sff_page));
3487
3488 for (offset = 0; offset < 256; offset += sizeof(out->data)) {
3489 req.page_offset = htole16(offset)((__uint16_t)(offset));
3490 req.data_length = sizeof(out->data);
3491 req.enables = htole32(HWRM_PORT_PHY_I2C_READ_REQ_ENABLES_PAGE_OFFSET)((__uint32_t)(0x1UL));
3492
3493 if (hwrm_send_message(softc, &req, sizeof(req))) {
3494 printf("%s: failed to read i2c data\n", DEVNAME(softc)((softc)->sc_dev.dv_xname));
3495 return 1;
3496 }
3497
3498 out = (struct hwrm_port_phy_i2c_read_output *)
3499 BNXT_DMA_KVA(softc->sc_cmd_resp)((void *)(softc->sc_cmd_resp)->bdm_kva);
3500 memcpy(sff->sff_data + offset, out->data, sizeof(out->data))__builtin_memcpy((sff->sff_data + offset), (out->data),
(sizeof(out->data)))
;
3501 }
3502
3503 return 0;
3504}