xref: /netbsd-src/sys/dev/pci/if_bwfm_pci.c (revision 53b02e147d4ed531c0d2a5ca9b3e8026ba3e99b5)
1 /*	$NetBSD: if_bwfm_pci.c,v 1.11 2021/08/26 21:33:36 andvar Exp $	*/
2 /*	$OpenBSD: if_bwfm_pci.c,v 1.18 2018/02/08 05:00:38 patrick Exp $	*/
3 /*
4  * Copyright (c) 2010-2016 Broadcom Corporation
5  * Copyright (c) 2017 Patrick Wildt <patrick@blueri.se>
6  *
7  * Permission to use, copy, modify, and/or distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include <sys/cdefs.h>
21 __KERNEL_RCSID(0, "$NetBSD: if_bwfm_pci.c,v 1.11 2021/08/26 21:33:36 andvar Exp $");
22 
23 #include <sys/param.h>
24 #include <sys/systm.h>
25 #include <sys/buf.h>
26 #include <sys/kernel.h>
27 #include <sys/kmem.h>
28 #include <sys/device.h>
29 #include <sys/pool.h>
30 #include <sys/workqueue.h>
31 #include <sys/socket.h>
32 
33 #include <net/bpf.h>
34 #include <net/if.h>
35 #include <net/if_dl.h>
36 #include <net/if_ether.h>
37 #include <net/if_media.h>
38 
39 #include <netinet/in.h>
40 
41 #include <net80211/ieee80211_var.h>
42 
43 #include <dev/pci/pcireg.h>
44 #include <dev/pci/pcivar.h>
45 #include <dev/pci/pcidevs.h>
46 
47 #include <dev/ic/bwfmreg.h>
48 #include <dev/ic/bwfmvar.h>
49 #include <dev/pci/if_bwfm_pci.h>
50 
51 #define BWFM_DMA_D2H_SCRATCH_BUF_LEN		8
52 #define BWFM_DMA_D2H_RINGUPD_BUF_LEN		1024
53 #define BWFM_DMA_H2D_IOCTL_BUF_LEN		ETHER_MAX_LEN
54 
55 #define BWFM_NUM_TX_MSGRINGS			2
56 #define BWFM_NUM_RX_MSGRINGS			3
57 
58 #define BWFM_NUM_TX_PKTIDS			2048
59 #define BWFM_NUM_RX_PKTIDS			1024
60 
61 #define BWFM_NUM_TX_DESCS			1
62 #define BWFM_NUM_RX_DESCS			1
63 
64 #ifdef BWFM_DEBUG
65 #define DPRINTF(x)	do { if (bwfm_debug > 0) printf x; } while (0)
66 #define DPRINTFN(n, x)	do { if (bwfm_debug >= (n)) printf x; } while (0)
67 static int bwfm_debug = 2;
68 #else
69 #define DPRINTF(x)	do { ; } while (0)
70 #define DPRINTFN(n, x)	do { ; } while (0)
71 #endif
72 
73 #define DEVNAME(sc)	device_xname((sc)->sc_sc.sc_dev)
74 #define letoh16		htole16
75 #define letoh32		htole32
76 #define nitems(x)	__arraycount(x)
77 
78 enum ring_status {
79 	RING_CLOSED,
80 	RING_CLOSING,
81 	RING_OPEN,
82 	RING_OPENING,
83 };
84 
85 struct bwfm_pci_msgring {
86 	uint32_t		 w_idx_addr;
87 	uint32_t		 r_idx_addr;
88 	uint32_t		 w_ptr;
89 	uint32_t		 r_ptr;
90 	int			 nitem;
91 	int			 itemsz;
92 	enum ring_status	 status;
93 	struct bwfm_pci_dmamem	*ring;
94 	struct mbuf		*m;
95 
96 	int			 fifo;
97 	uint8_t			 mac[ETHER_ADDR_LEN];
98 };
99 
100 struct bwfm_pci_buf {
101 	bus_dmamap_t	 bb_map;
102 	struct mbuf	*bb_m;
103 };
104 
105 struct bwfm_pci_pkts {
106 	struct bwfm_pci_buf	*pkts;
107 	uint32_t		 npkt;
108 	int			 last;
109 };
110 
111 struct if_rxring {
112 	u_int	rxr_total;
113 	u_int	rxr_inuse;
114 };
115 
116 struct bwfm_cmd_flowring_create {
117 	struct work		 wq_cookie;
118 	struct bwfm_pci_softc	*sc;
119 	struct mbuf		*m;
120 	int			 flowid;
121 	int			 prio;
122 };
123 
124 struct bwfm_pci_softc {
125 	struct bwfm_softc	 sc_sc;
126 	pci_chipset_tag_t	 sc_pc;
127 	pcitag_t		 sc_tag;
128 	pcireg_t		 sc_id;
129 	void			*sc_ih;
130 	pci_intr_handle_t	*sc_pihp;
131 
132 	bus_space_tag_t		 sc_reg_iot;
133 	bus_space_handle_t	 sc_reg_ioh;
134 	bus_size_t		 sc_reg_ios;
135 
136 	bus_space_tag_t		 sc_tcm_iot;
137 	bus_space_handle_t	 sc_tcm_ioh;
138 	bus_size_t		 sc_tcm_ios;
139 
140 	bus_dma_tag_t		 sc_dmat;
141 
142 	uint32_t		 sc_shared_address;
143 	uint32_t		 sc_shared_flags;
144 	uint8_t			 sc_shared_version;
145 
146 	uint8_t			 sc_dma_idx_sz;
147 	struct bwfm_pci_dmamem	*sc_dma_idx_buf;
148 	size_t			 sc_dma_idx_bufsz;
149 
150 	uint16_t		 sc_max_rxbufpost;
151 	uint32_t		 sc_rx_dataoffset;
152 	uint32_t		 sc_htod_mb_data_addr;
153 	uint32_t		 sc_dtoh_mb_data_addr;
154 	uint32_t		 sc_ring_info_addr;
155 
156 	uint32_t		 sc_console_base_addr;
157 	uint32_t		 sc_console_buf_addr;
158 	uint32_t		 sc_console_buf_size;
159 	uint32_t		 sc_console_readidx;
160 
161 	struct pool		 sc_flowring_pool;
162 	struct workqueue	*flowring_wq;
163 
164 	uint16_t		 sc_max_flowrings;
165 	uint16_t		 sc_max_submissionrings;
166 	uint16_t		 sc_max_completionrings;
167 
168 	struct bwfm_pci_msgring	 sc_ctrl_submit;
169 	struct bwfm_pci_msgring	 sc_rxpost_submit;
170 	struct bwfm_pci_msgring	 sc_ctrl_complete;
171 	struct bwfm_pci_msgring	 sc_tx_complete;
172 	struct bwfm_pci_msgring	 sc_rx_complete;
173 	struct bwfm_pci_msgring	*sc_flowrings;
174 
175 	struct bwfm_pci_dmamem	*sc_scratch_buf;
176 	struct bwfm_pci_dmamem	*sc_ringupd_buf;
177 
178 	struct bwfm_pci_dmamem	*sc_ioctl_buf;
179 	int			 sc_ioctl_reqid;
180 	uint32_t		 sc_ioctl_resp_pktid;
181 	uint32_t		 sc_ioctl_resp_ret_len;
182 	uint32_t		 sc_ioctl_resp_status;
183 	int			 sc_ioctl_poll;
184 
185 	struct if_rxring	 sc_ioctl_ring;
186 	struct if_rxring	 sc_event_ring;
187 	struct if_rxring	 sc_rxbuf_ring;
188 
189 	struct bwfm_pci_pkts	 sc_rx_pkts;
190 	struct bwfm_pci_pkts	 sc_tx_pkts;
191 	int			 sc_tx_pkts_full;
192 };
193 
194 struct bwfm_pci_dmamem {
195 	bus_dmamap_t		bdm_map;
196 	bus_dma_segment_t	bdm_seg;
197 	size_t			bdm_size;
198 	char *			bdm_kva;
199 };
200 
201 #define BWFM_PCI_DMA_MAP(_bdm)	((_bdm)->bdm_map)
202 #define BWFM_PCI_DMA_LEN(_bdm)	((_bdm)->bdm_size)
203 #define BWFM_PCI_DMA_DVA(_bdm)	(uint64_t)((_bdm)->bdm_map->dm_segs[0].ds_addr)
204 #define BWFM_PCI_DMA_KVA(_bdm)	((_bdm)->bdm_kva)
205 
206 static u_int	 if_rxr_get(struct if_rxring *rxr, unsigned int max);
207 static void	 if_rxr_put(struct if_rxring *rxr, unsigned int n);
208 static void	 if_rxr_init(struct if_rxring *rxr, unsigned int lwm, unsigned int hwm);
209 
210 int		 bwfm_pci_match(device_t parent, cfdata_t match, void *aux);
211 void		 bwfm_pci_attachhook(device_t);
212 void		 bwfm_pci_attach(device_t, device_t, void *);
213 int		 bwfm_pci_detach(device_t, int);
214 
215 int		 bwfm_pci_intr(void *);
216 void		 bwfm_pci_intr_enable(struct bwfm_pci_softc *);
217 void		 bwfm_pci_intr_disable(struct bwfm_pci_softc *);
218 int		 bwfm_pci_load_microcode(struct bwfm_pci_softc *, const u_char *,
219 		    size_t);
220 void		 bwfm_pci_select_core(struct bwfm_pci_softc *, int );
221 
222 struct bwfm_pci_dmamem *
223 		 bwfm_pci_dmamem_alloc(struct bwfm_pci_softc *, bus_size_t,
224 		    bus_size_t);
225 void		 bwfm_pci_dmamem_free(struct bwfm_pci_softc *, struct bwfm_pci_dmamem *);
226 int		 bwfm_pci_pktid_avail(struct bwfm_pci_softc *,
227 		    struct bwfm_pci_pkts *);
228 int		 bwfm_pci_pktid_new(struct bwfm_pci_softc *,
229 		    struct bwfm_pci_pkts *, struct mbuf **,
230 		    uint32_t *, paddr_t *);
231 struct mbuf *	 bwfm_pci_pktid_free(struct bwfm_pci_softc *,
232 		    struct bwfm_pci_pkts *, uint32_t);
233 void		 bwfm_pci_fill_rx_ioctl_ring(struct bwfm_pci_softc *,
234 		    struct if_rxring *, uint32_t);
235 void		 bwfm_pci_fill_rx_buf_ring(struct bwfm_pci_softc *);
236 void		 bwfm_pci_fill_rx_rings(struct bwfm_pci_softc *);
237 int		 bwfm_pci_setup_ring(struct bwfm_pci_softc *, struct bwfm_pci_msgring *,
238 		    int, size_t, uint32_t, uint32_t, int, uint32_t, uint32_t *);
239 int		 bwfm_pci_setup_flowring(struct bwfm_pci_softc *, struct bwfm_pci_msgring *,
240 		    int, size_t);
241 
242 void		 bwfm_pci_ring_bell(struct bwfm_pci_softc *,
243 		    struct bwfm_pci_msgring *);
244 void		 bwfm_pci_ring_update_rptr(struct bwfm_pci_softc *,
245 		    struct bwfm_pci_msgring *);
246 void		 bwfm_pci_ring_update_wptr(struct bwfm_pci_softc *,
247 		    struct bwfm_pci_msgring *);
248 void		 bwfm_pci_ring_write_rptr(struct bwfm_pci_softc *,
249 		    struct bwfm_pci_msgring *);
250 void		 bwfm_pci_ring_write_wptr(struct bwfm_pci_softc *,
251 		    struct bwfm_pci_msgring *);
252 void *		 bwfm_pci_ring_write_reserve(struct bwfm_pci_softc *,
253 		    struct bwfm_pci_msgring *);
254 void *		 bwfm_pci_ring_write_reserve_multi(struct bwfm_pci_softc *,
255 		    struct bwfm_pci_msgring *, int, int *);
256 void *		 bwfm_pci_ring_read_avail(struct bwfm_pci_softc *,
257 		    struct bwfm_pci_msgring *, int *);
258 void		 bwfm_pci_ring_read_commit(struct bwfm_pci_softc *,
259 		    struct bwfm_pci_msgring *, int);
260 void		 bwfm_pci_ring_write_commit(struct bwfm_pci_softc *,
261 		    struct bwfm_pci_msgring *);
262 void		 bwfm_pci_ring_write_cancel(struct bwfm_pci_softc *,
263 		    struct bwfm_pci_msgring *, int);
264 
265 void		 bwfm_pci_ring_rx(struct bwfm_pci_softc *,
266 		    struct bwfm_pci_msgring *);
267 void		 bwfm_pci_msg_rx(struct bwfm_pci_softc *, void *);
268 
269 uint32_t	 bwfm_pci_buscore_read(struct bwfm_softc *, uint32_t);
270 void		 bwfm_pci_buscore_write(struct bwfm_softc *, uint32_t,
271 		    uint32_t);
272 int		 bwfm_pci_buscore_prepare(struct bwfm_softc *);
273 int		 bwfm_pci_buscore_reset(struct bwfm_softc *);
274 void		 bwfm_pci_buscore_activate(struct bwfm_softc *, const uint32_t);
275 
276 int		 bwfm_pci_flowring_lookup(struct bwfm_pci_softc *,
277 		     struct mbuf *);
278 void		 bwfm_pci_flowring_create(struct bwfm_pci_softc *,
279 		     struct mbuf *);
280 void		 bwfm_pci_flowring_create_cb(struct work *, void *);
281 void		 bwfm_pci_flowring_delete(struct bwfm_pci_softc *, int);
282 
283 void		 bwfm_pci_stop(struct bwfm_softc *);
284 int		 bwfm_pci_txcheck(struct bwfm_softc *);
285 int		 bwfm_pci_txdata(struct bwfm_softc *, struct mbuf **);
286 
287 #ifdef BWFM_DEBUG
288 void		 bwfm_pci_debug_console(struct bwfm_pci_softc *);
289 #endif
290 
291 int		 bwfm_pci_msgbuf_query_dcmd(struct bwfm_softc *, int,
292 		    int, char *, size_t *);
293 int		 bwfm_pci_msgbuf_set_dcmd(struct bwfm_softc *, int,
294 		    int, char *, size_t);
295 
296 static const struct bwfm_buscore_ops bwfm_pci_buscore_ops = {
297 	.bc_read = bwfm_pci_buscore_read,
298 	.bc_write = bwfm_pci_buscore_write,
299 	.bc_prepare = bwfm_pci_buscore_prepare,
300 	.bc_reset = bwfm_pci_buscore_reset,
301 	.bc_setup = NULL,
302 	.bc_activate = bwfm_pci_buscore_activate,
303 };
304 
305 static const struct bwfm_bus_ops bwfm_pci_bus_ops = {
306 	.bs_init = NULL,
307 	.bs_stop = bwfm_pci_stop,
308 	.bs_txcheck = bwfm_pci_txcheck,
309 	.bs_txdata = bwfm_pci_txdata,
310 	.bs_txctl = NULL,
311 	.bs_rxctl = NULL,
312 };
313 
314 static const struct bwfm_proto_ops bwfm_pci_msgbuf_ops = {
315 	.proto_query_dcmd = bwfm_pci_msgbuf_query_dcmd,
316 	.proto_set_dcmd = bwfm_pci_msgbuf_set_dcmd,
317 };
318 
319 
320 CFATTACH_DECL_NEW(bwfm_pci, sizeof(struct bwfm_pci_softc),
321     bwfm_pci_match, bwfm_pci_attach, bwfm_pci_detach, NULL);
322 
323 static const struct bwfm_firmware_selector bwfm_pci_fwtab[] = {
324 	BWFM_FW_ENTRY(BRCM_CC_43602_CHIP_ID,
325 		      BWFM_FWSEL_ALLREVS, "brcmfmac43602-pcie"),
326 
327 	BWFM_FW_ENTRY(BRCM_CC_43465_CHIP_ID,
328 		      BWFM_FWSEL_REV_GE(4), "brcmfmac4366c-pcie"),
329 
330 	BWFM_FW_ENTRY(BRCM_CC_4350_CHIP_ID,
331 		      BWFM_FWSEL_REV_LE(7), "brcmfmac4350c2-pcie"),
332 	BWFM_FW_ENTRY(BRCM_CC_4350_CHIP_ID,
333 		      BWFM_FWSEL_REV_GE(8), "brcmfmac4350-pcie"),
334 
335 	BWFM_FW_ENTRY(BRCM_CC_43525_CHIP_ID,
336 		      BWFM_FWSEL_REV_GE(4), "brcmfmac4365c-pcie"),
337 
338 	BWFM_FW_ENTRY(BRCM_CC_4356_CHIP_ID,
339 		      BWFM_FWSEL_ALLREVS, "brcmfmac4356-pcie"),
340 
341 	BWFM_FW_ENTRY(BRCM_CC_43567_CHIP_ID,
342 		      BWFM_FWSEL_ALLREVS, "brcmfmac43570-pcie"),
343 	BWFM_FW_ENTRY(BRCM_CC_43569_CHIP_ID,
344 		      BWFM_FWSEL_ALLREVS, "brcmfmac43570-pcie"),
345 	BWFM_FW_ENTRY(BRCM_CC_43570_CHIP_ID,
346 		      BWFM_FWSEL_ALLREVS, "brcmfmac43570-pcie"),
347 
348 	BWFM_FW_ENTRY(BRCM_CC_4358_CHIP_ID,
349 		      BWFM_FWSEL_ALLREVS, "brcmfmac4358-pcie"),
350 
351 	BWFM_FW_ENTRY(BRCM_CC_4359_CHIP_ID,
352 		      BWFM_FWSEL_ALLREVS, "brcmfmac4359-pcie"),
353 
354 	BWFM_FW_ENTRY(BRCM_CC_4365_CHIP_ID,
355 		      BWFM_FWSEL_REV_LE(3), "brcmfmac4365b-pcie"),
356 	BWFM_FW_ENTRY(BRCM_CC_4365_CHIP_ID,
357 		      BWFM_FWSEL_REV_GE(4), "brcmfmac4365c-pcie"),
358 
359 	BWFM_FW_ENTRY(BRCM_CC_4366_CHIP_ID,
360 		      BWFM_FWSEL_REV_LE(3), "brcmfmac4366b-pcie"),
361 	BWFM_FW_ENTRY(BRCM_CC_4366_CHIP_ID,
362 		      BWFM_FWSEL_REV_GE(4), "brcmfmac4366c-pcie"),
363 	BWFM_FW_ENTRY(BRCM_CC_43664_CHIP_ID,
364 		      BWFM_FWSEL_REV_GE(4), "brcmfmac4366c-pcie"),
365 
366 	BWFM_FW_ENTRY(BRCM_CC_4371_CHIP_ID,
367 		      BWFM_FWSEL_ALLREVS, "brcmfmac4371-pcie"),
368 
369 	BWFM_FW_ENTRY_END
370 };
371 
372 static const struct device_compatible_entry compat_data[] = {
373 	{ .id = PCI_ID_CODE(PCI_VENDOR_BROADCOM,
374 		PCI_PRODUCT_BROADCOM_BCM43602), },
375 
376 	{ .id = PCI_ID_CODE(PCI_VENDOR_BROADCOM,
377 		PCI_PRODUCT_BROADCOM_BCM4350), },
378 
379 	PCI_COMPAT_EOL
380 };
381 
382 static struct mbuf *
383 MCLGETI(struct bwfm_pci_softc *sc __unused, int how,
384     struct ifnet *ifp __unused, u_int size)
385 {
386 	struct mbuf *m;
387 
388 	MGETHDR(m, how, MT_DATA);
389 	if (m == NULL)
390 		return NULL;
391 
392 	MEXTMALLOC(m, size, how);
393 	if ((m->m_flags & M_EXT) == 0) {
394 		m_freem(m);
395 		return NULL;
396 	}
397 	return m;
398 }
399 
400 int
401 bwfm_pci_match(device_t parent, cfdata_t match, void *aux)
402 {
403 	struct pci_attach_args *pa = aux;
404 
405 	return pci_compatible_match(pa, compat_data);
406 }
407 
408 void
409 bwfm_pci_attach(device_t parent, device_t self, void *aux)
410 {
411 	struct bwfm_pci_softc *sc = device_private(self);
412 	struct pci_attach_args *pa = (struct pci_attach_args *)aux;
413 	const char *intrstr;
414 	char intrbuf[PCI_INTRSTR_LEN];
415 
416 	sc->sc_sc.sc_dev = self;
417 
418 	if (pci_mapreg_map(pa, PCI_MAPREG_START + 0x00,
419 	    PCI_MAPREG_MEM_TYPE_64BIT, 0, &sc->sc_reg_iot, &sc->sc_reg_ioh,
420 	    NULL, &sc->sc_reg_ios)) {
421 		printf(": can't map bar0\n");
422 		return;
423 	}
424 
425 	if (pci_mapreg_map(pa, PCI_MAPREG_START + 0x08,
426 	    PCI_MAPREG_MEM_TYPE_64BIT, 0, &sc->sc_tcm_iot, &sc->sc_tcm_ioh,
427 	    NULL, &sc->sc_tcm_ios)) {
428 		printf(": can't map bar1\n");
429 		goto bar0;
430 	}
431 
432 	sc->sc_pc = pa->pa_pc;
433 	sc->sc_tag = pa->pa_tag;
434 	sc->sc_id = pa->pa_id;
435 
436 	if (pci_dma64_available(pa))
437 		sc->sc_dmat = pa->pa_dmat64;
438 	else
439 		sc->sc_dmat = pa->pa_dmat;
440 
441 	/* Map and establish the interrupt. */
442 	if (pci_intr_alloc(pa, &sc->sc_pihp, NULL, 0) != 0) {
443 		printf(": couldn't map interrupt\n");
444 		goto bar1;
445 	}
446 	intrstr = pci_intr_string(pa->pa_pc, sc->sc_pihp[0], intrbuf, sizeof(intrbuf));
447 
448 	sc->sc_ih = pci_intr_establish_xname(pa->pa_pc, sc->sc_pihp[0], IPL_NET,
449 	    bwfm_pci_intr, sc, device_xname(self));
450 	if (sc->sc_ih == NULL) {
451 		printf(": couldn't establish interrupt");
452 		if (intrstr != NULL)
453 			printf(" at %s", intrstr);
454 		printf("\n");
455 		goto bar1;
456 	}
457 	printf(": %s\n", intrstr);
458 
459 	config_mountroot(self, bwfm_pci_attachhook);
460 	return;
461 
462 bar1:
463 	bus_space_unmap(sc->sc_tcm_iot, sc->sc_tcm_ioh, sc->sc_tcm_ios);
464 bar0:
465 	bus_space_unmap(sc->sc_reg_iot, sc->sc_reg_ioh, sc->sc_reg_ios);
466 }
467 
468 void
469 bwfm_pci_attachhook(device_t self)
470 {
471 	struct bwfm_pci_softc *sc = device_private(self);
472 	struct bwfm_softc *bwfm = (void *)sc;
473 	struct bwfm_pci_ringinfo ringinfo;
474 	struct bwfm_firmware_context fwctx;
475 	uint8_t *ucode;
476 	size_t ucsize;
477 	uint32_t d2h_w_idx_ptr, d2h_r_idx_ptr;
478 	uint32_t h2d_w_idx_ptr, h2d_r_idx_ptr;
479 	uint32_t idx_offset, reg;
480 	int i;
481 
482 	sc->sc_sc.sc_buscore_ops = &bwfm_pci_buscore_ops;
483 	if (bwfm_chip_attach(&sc->sc_sc) != 0) {
484 		aprint_error_dev(bwfm->sc_dev, "cannot attach chip\n");
485 		return;
486 	}
487 
488 	bwfm_pci_select_core(sc, BWFM_AGENT_CORE_PCIE2);
489 	bus_space_write_4(sc->sc_reg_iot, sc->sc_reg_ioh,
490 	    BWFM_PCI_PCIE2REG_CONFIGADDR, 0x4e0);
491 	reg = bus_space_read_4(sc->sc_reg_iot, sc->sc_reg_ioh,
492 	    BWFM_PCI_PCIE2REG_CONFIGDATA);
493 	bus_space_write_4(sc->sc_reg_iot, sc->sc_reg_ioh,
494 	    BWFM_PCI_PCIE2REG_CONFIGDATA, reg);
495 
496 	bwfm_firmware_context_init(&fwctx,
497 	    bwfm->sc_chip.ch_chip, bwfm->sc_chip.ch_chiprev, NULL,
498 	    BWFM_FWREQ(BWFM_FILETYPE_UCODE));
499 
500 	if (!bwfm_firmware_open(bwfm, bwfm_pci_fwtab, &fwctx)) {
501 		/* Error message already displayed. */
502 		goto err;
503 	}
504 
505 	ucode = bwfm_firmware_data(&fwctx, BWFM_FILETYPE_UCODE, &ucsize);
506 	KASSERT(ucode != NULL);
507 
508 	/* Retrieve RAM size from firmware. */
509 	if (ucsize >= BWFM_RAMSIZE + 8) {
510 		uint32_t *ramsize = (uint32_t *)&ucode[BWFM_RAMSIZE];
511 		if (letoh32(ramsize[0]) == BWFM_RAMSIZE_MAGIC)
512 			bwfm->sc_chip.ch_ramsize = letoh32(ramsize[1]);
513 	}
514 
515 	if (bwfm_pci_load_microcode(sc, ucode, ucsize) != 0) {
516 		aprint_error_dev(bwfm->sc_dev, "could not load microcode\n");
517 		goto err;
518 	}
519 
520 	bwfm_firmware_close(&fwctx);
521 
522 	sc->sc_shared_flags = bus_space_read_4(sc->sc_tcm_iot, sc->sc_tcm_ioh,
523 	    sc->sc_shared_address + BWFM_SHARED_INFO);
524 	sc->sc_shared_version = sc->sc_shared_flags;
525 	if (sc->sc_shared_version > BWFM_SHARED_INFO_MAX_VERSION ||
526 	    sc->sc_shared_version < BWFM_SHARED_INFO_MIN_VERSION) {
527 		aprint_error_dev(bwfm->sc_dev,
528 		    "PCIe version %d unsupported\n", sc->sc_shared_version);
529 		return;
530 	}
531 
532 	if (sc->sc_shared_flags & BWFM_SHARED_INFO_DMA_INDEX) {
533 		if (sc->sc_shared_flags & BWFM_SHARED_INFO_DMA_2B_IDX)
534 			sc->sc_dma_idx_sz = sizeof(uint16_t);
535 		else
536 			sc->sc_dma_idx_sz = sizeof(uint32_t);
537 	}
538 
539 	/* Maximum RX data buffers in the ring. */
540 	sc->sc_max_rxbufpost = bus_space_read_2(sc->sc_tcm_iot, sc->sc_tcm_ioh,
541 	    sc->sc_shared_address + BWFM_SHARED_MAX_RXBUFPOST);
542 	if (sc->sc_max_rxbufpost == 0)
543 		sc->sc_max_rxbufpost = BWFM_SHARED_MAX_RXBUFPOST_DEFAULT;
544 
545 	/* Alternative offset of data in a packet */
546 	sc->sc_rx_dataoffset = bus_space_read_4(sc->sc_tcm_iot, sc->sc_tcm_ioh,
547 	    sc->sc_shared_address + BWFM_SHARED_RX_DATAOFFSET);
548 
549 	/* For Power Management */
550 	sc->sc_htod_mb_data_addr = bus_space_read_4(sc->sc_tcm_iot, sc->sc_tcm_ioh,
551 	    sc->sc_shared_address + BWFM_SHARED_HTOD_MB_DATA_ADDR);
552 	sc->sc_dtoh_mb_data_addr = bus_space_read_4(sc->sc_tcm_iot, sc->sc_tcm_ioh,
553 	    sc->sc_shared_address + BWFM_SHARED_DTOH_MB_DATA_ADDR);
554 
555 	/* Ring information */
556 	sc->sc_ring_info_addr = bus_space_read_4(sc->sc_tcm_iot, sc->sc_tcm_ioh,
557 	    sc->sc_shared_address + BWFM_SHARED_RING_INFO_ADDR);
558 
559 	/* Firmware's "dmesg" */
560 	sc->sc_console_base_addr = bus_space_read_4(sc->sc_tcm_iot, sc->sc_tcm_ioh,
561 	    sc->sc_shared_address + BWFM_SHARED_CONSOLE_ADDR);
562 	sc->sc_console_buf_addr = bus_space_read_4(sc->sc_tcm_iot, sc->sc_tcm_ioh,
563 	    sc->sc_console_base_addr + BWFM_CONSOLE_BUFADDR);
564 	sc->sc_console_buf_size = bus_space_read_4(sc->sc_tcm_iot, sc->sc_tcm_ioh,
565 	    sc->sc_console_base_addr + BWFM_CONSOLE_BUFSIZE);
566 
567 	/* Read ring information. */
568 	bus_space_read_region_1(sc->sc_tcm_iot, sc->sc_tcm_ioh,
569 	    sc->sc_ring_info_addr, (void *)&ringinfo, sizeof(ringinfo));
570 
571 	if (sc->sc_shared_version >= 6) {
572 		sc->sc_max_submissionrings = le16toh(ringinfo.max_submissionrings);
573 		sc->sc_max_flowrings = le16toh(ringinfo.max_flowrings);
574 		sc->sc_max_completionrings = le16toh(ringinfo.max_completionrings);
575 	} else {
576 		sc->sc_max_submissionrings = le16toh(ringinfo.max_flowrings);
577 		sc->sc_max_flowrings = sc->sc_max_submissionrings -
578 		    BWFM_NUM_TX_MSGRINGS;
579 		sc->sc_max_completionrings = BWFM_NUM_RX_MSGRINGS;
580 	}
581 
582 	if (sc->sc_dma_idx_sz == 0) {
583 		d2h_w_idx_ptr = letoh32(ringinfo.d2h_w_idx_ptr);
584 		d2h_r_idx_ptr = letoh32(ringinfo.d2h_r_idx_ptr);
585 		h2d_w_idx_ptr = letoh32(ringinfo.h2d_w_idx_ptr);
586 		h2d_r_idx_ptr = letoh32(ringinfo.h2d_r_idx_ptr);
587 		idx_offset = sizeof(uint32_t);
588 	} else {
589 		uint64_t address;
590 
591 		/* Each TX/RX Ring has a Read and Write Ptr */
592 		sc->sc_dma_idx_bufsz = (sc->sc_max_submissionrings +
593 		    sc->sc_max_completionrings) * sc->sc_dma_idx_sz * 2;
594 		sc->sc_dma_idx_buf = bwfm_pci_dmamem_alloc(sc,
595 		    sc->sc_dma_idx_bufsz, 8);
596 		if (sc->sc_dma_idx_buf == NULL) {
597 			/* XXX: Fallback to TCM? */
598 			aprint_error_dev(bwfm->sc_dev,
599 			    "cannot allocate idx buf\n");
600 			return;
601 		}
602 
603 		idx_offset = sc->sc_dma_idx_sz;
604 		h2d_w_idx_ptr = 0;
605 		address = BWFM_PCI_DMA_DVA(sc->sc_dma_idx_buf);
606 		ringinfo.h2d_w_idx_hostaddr_low =
607 		    htole32(address & 0xffffffff);
608 		ringinfo.h2d_w_idx_hostaddr_high =
609 		    htole32(address >> 32);
610 
611 		h2d_r_idx_ptr = h2d_w_idx_ptr +
612 		    sc->sc_max_submissionrings * idx_offset;
613 		address += sc->sc_max_submissionrings * idx_offset;
614 		ringinfo.h2d_r_idx_hostaddr_low =
615 		    htole32(address & 0xffffffff);
616 		ringinfo.h2d_r_idx_hostaddr_high =
617 		    htole32(address >> 32);
618 
619 		d2h_w_idx_ptr = h2d_r_idx_ptr +
620 		    sc->sc_max_submissionrings * idx_offset;
621 		address += sc->sc_max_submissionrings * idx_offset;
622 		ringinfo.d2h_w_idx_hostaddr_low =
623 		    htole32(address & 0xffffffff);
624 		ringinfo.d2h_w_idx_hostaddr_high =
625 		    htole32(address >> 32);
626 
627 		d2h_r_idx_ptr = d2h_w_idx_ptr +
628 		    sc->sc_max_completionrings * idx_offset;
629 		address += sc->sc_max_completionrings * idx_offset;
630 		ringinfo.d2h_r_idx_hostaddr_low =
631 		    htole32(address & 0xffffffff);
632 		ringinfo.d2h_r_idx_hostaddr_high =
633 		    htole32(address >> 32);
634 
635 		bus_space_write_region_1(sc->sc_tcm_iot, sc->sc_tcm_ioh,
636 		    sc->sc_ring_info_addr, (void *)&ringinfo, sizeof(ringinfo));
637 	}
638 
639 	uint32_t ring_mem_ptr = letoh32(ringinfo.ringmem);
640 	/* TX ctrl ring: Send ctrl buffers, send IOCTLs */
641 	if (bwfm_pci_setup_ring(sc, &sc->sc_ctrl_submit, 64, 40,
642 	    h2d_w_idx_ptr, h2d_r_idx_ptr, 0, idx_offset,
643 	    &ring_mem_ptr))
644 		goto cleanup;
645 	/* TX rxpost ring: Send clean data mbufs for RX */
646 	if (bwfm_pci_setup_ring(sc, &sc->sc_rxpost_submit, 512, 32,
647 	    h2d_w_idx_ptr, h2d_r_idx_ptr, 1, idx_offset,
648 	    &ring_mem_ptr))
649 		goto cleanup;
650 	/* RX completion rings: recv our filled buffers back */
651 	if (bwfm_pci_setup_ring(sc, &sc->sc_ctrl_complete, 64, 24,
652 	    d2h_w_idx_ptr, d2h_r_idx_ptr, 0, idx_offset,
653 	    &ring_mem_ptr))
654 		goto cleanup;
655 	if (bwfm_pci_setup_ring(sc, &sc->sc_tx_complete, 1024, 16,
656 	    d2h_w_idx_ptr, d2h_r_idx_ptr, 1, idx_offset,
657 	    &ring_mem_ptr))
658 		goto cleanup;
659 	if (bwfm_pci_setup_ring(sc, &sc->sc_rx_complete, 512, 32,
660 	    d2h_w_idx_ptr, d2h_r_idx_ptr, 2, idx_offset,
661 	    &ring_mem_ptr))
662 		goto cleanup;
663 
664 	/* Dynamic TX rings for actual data */
665 	sc->sc_flowrings = kmem_zalloc(sc->sc_max_flowrings *
666 	    sizeof(struct bwfm_pci_msgring), KM_SLEEP);
667 	for (i = 0; i < sc->sc_max_flowrings; i++) {
668 		struct bwfm_pci_msgring *ring = &sc->sc_flowrings[i];
669 		ring->w_idx_addr = h2d_w_idx_ptr + (i + 2) * idx_offset;
670 		ring->r_idx_addr = h2d_r_idx_ptr + (i + 2) * idx_offset;
671 	}
672 
673 	pool_init(&sc->sc_flowring_pool, sizeof(struct bwfm_cmd_flowring_create),
674 	    0, 0, 0, "bwfmpl", NULL, IPL_NET);
675 
676 	/* Scratch and ring update buffers for firmware */
677 	if ((sc->sc_scratch_buf = bwfm_pci_dmamem_alloc(sc,
678 	    BWFM_DMA_D2H_SCRATCH_BUF_LEN, 8)) == NULL)
679 		goto cleanup;
680 	bus_space_write_4(sc->sc_tcm_iot, sc->sc_tcm_ioh,
681 	    sc->sc_shared_address + BWFM_SHARED_DMA_SCRATCH_ADDR_LOW,
682 	    BWFM_PCI_DMA_DVA(sc->sc_scratch_buf) & 0xffffffff);
683 	bus_space_write_4(sc->sc_tcm_iot, sc->sc_tcm_ioh,
684 	    sc->sc_shared_address + BWFM_SHARED_DMA_SCRATCH_ADDR_HIGH,
685 	    BWFM_PCI_DMA_DVA(sc->sc_scratch_buf) >> 32);
686 	bus_space_write_4(sc->sc_tcm_iot, sc->sc_tcm_ioh,
687 	    sc->sc_shared_address + BWFM_SHARED_DMA_SCRATCH_LEN,
688 	    BWFM_DMA_D2H_SCRATCH_BUF_LEN);
689 
690 	if ((sc->sc_ringupd_buf = bwfm_pci_dmamem_alloc(sc,
691 	    BWFM_DMA_D2H_RINGUPD_BUF_LEN, 8)) == NULL)
692 		goto cleanup;
693 	bus_space_write_4(sc->sc_tcm_iot, sc->sc_tcm_ioh,
694 	    sc->sc_shared_address + BWFM_SHARED_DMA_RINGUPD_ADDR_LOW,
695 	    BWFM_PCI_DMA_DVA(sc->sc_ringupd_buf) & 0xffffffff);
696 	bus_space_write_4(sc->sc_tcm_iot, sc->sc_tcm_ioh,
697 	    sc->sc_shared_address + BWFM_SHARED_DMA_RINGUPD_ADDR_HIGH,
698 	    BWFM_PCI_DMA_DVA(sc->sc_ringupd_buf) >> 32);
699 	bus_space_write_4(sc->sc_tcm_iot, sc->sc_tcm_ioh,
700 	    sc->sc_shared_address + BWFM_SHARED_DMA_RINGUPD_LEN,
701 	    BWFM_DMA_D2H_RINGUPD_BUF_LEN);
702 
703 	if ((sc->sc_ioctl_buf = bwfm_pci_dmamem_alloc(sc,
704 	    BWFM_DMA_H2D_IOCTL_BUF_LEN, 8)) == NULL)
705 		goto cleanup;
706 
707 	if (workqueue_create(&sc->flowring_wq, "bwfmflow",
708 	    bwfm_pci_flowring_create_cb, sc, PRI_SOFTNET, IPL_NET, 0))
709 		goto cleanup;
710 
711 	bwfm_pci_select_core(sc, BWFM_AGENT_CORE_PCIE2);
712 	bwfm_pci_intr_enable(sc);
713 
714 	/* Maps RX mbufs to a packet id and back. */
715 	sc->sc_rx_pkts.npkt = BWFM_NUM_RX_PKTIDS;
716 	sc->sc_rx_pkts.pkts = kmem_zalloc(BWFM_NUM_RX_PKTIDS *
717 	    sizeof(struct bwfm_pci_buf), KM_SLEEP);
718 	for (i = 0; i < BWFM_NUM_RX_PKTIDS; i++)
719 		bus_dmamap_create(sc->sc_dmat, MSGBUF_MAX_PKT_SIZE,
720 		    BWFM_NUM_RX_DESCS, MSGBUF_MAX_PKT_SIZE, 0, BUS_DMA_WAITOK,
721 		    &sc->sc_rx_pkts.pkts[i].bb_map);
722 
723 	/* Maps TX mbufs to a packet id and back. */
724 	sc->sc_tx_pkts.npkt = BWFM_NUM_TX_PKTIDS;
725 	sc->sc_tx_pkts.pkts = kmem_zalloc(BWFM_NUM_TX_PKTIDS
726 	    * sizeof(struct bwfm_pci_buf), KM_SLEEP);
727 	for (i = 0; i < BWFM_NUM_TX_PKTIDS; i++)
728 		bus_dmamap_create(sc->sc_dmat, MSGBUF_MAX_PKT_SIZE,
729 		    BWFM_NUM_TX_DESCS, MSGBUF_MAX_PKT_SIZE, 0, BUS_DMA_WAITOK,
730 		    &sc->sc_tx_pkts.pkts[i].bb_map);
731 
732 	/*
733 	 * For whatever reason, could also be a bug somewhere in this
734 	 * driver, the firmware needs a bunch of RX buffers otherwise
735 	 * it won't send any RX complete messages.  64 buffers don't
736 	 * suffice, but 128 buffers are enough.
737 	 */
738 	if_rxr_init(&sc->sc_rxbuf_ring, 128, sc->sc_max_rxbufpost);
739 	if_rxr_init(&sc->sc_ioctl_ring, 8, 8);
740 	if_rxr_init(&sc->sc_event_ring, 8, 8);
741 	bwfm_pci_fill_rx_rings(sc);
742 
743 
744 #ifdef BWFM_DEBUG
745 	sc->sc_console_readidx = 0;
746 	bwfm_pci_debug_console(sc);
747 #endif
748 
749 	sc->sc_ioctl_poll = 1;
750 	sc->sc_sc.sc_bus_ops = &bwfm_pci_bus_ops;
751 	sc->sc_sc.sc_proto_ops = &bwfm_pci_msgbuf_ops;
752 	bwfm_attach(&sc->sc_sc);
753 	sc->sc_ioctl_poll = 0;
754 	return;
755 
756 cleanup:
757 	if (sc->flowring_wq != NULL)
758 		workqueue_destroy(sc->flowring_wq);
759 	if (sc->sc_ih != NULL) {
760 		pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
761 		pci_intr_release(sc->sc_pc, sc->sc_pihp, 1);
762 	}
763 	if (sc->sc_ioctl_buf)
764 		bwfm_pci_dmamem_free(sc, sc->sc_ioctl_buf);
765 	if (sc->sc_ringupd_buf)
766 		bwfm_pci_dmamem_free(sc, sc->sc_ringupd_buf);
767 	if (sc->sc_scratch_buf)
768 		bwfm_pci_dmamem_free(sc, sc->sc_scratch_buf);
769 	if (sc->sc_rx_complete.ring)
770 		bwfm_pci_dmamem_free(sc, sc->sc_rx_complete.ring);
771 	if (sc->sc_tx_complete.ring)
772 		bwfm_pci_dmamem_free(sc, sc->sc_tx_complete.ring);
773 	if (sc->sc_ctrl_complete.ring)
774 		bwfm_pci_dmamem_free(sc, sc->sc_ctrl_complete.ring);
775 	if (sc->sc_rxpost_submit.ring)
776 		bwfm_pci_dmamem_free(sc, sc->sc_rxpost_submit.ring);
777 	if (sc->sc_ctrl_submit.ring)
778 		bwfm_pci_dmamem_free(sc, sc->sc_ctrl_submit.ring);
779 	if (sc->sc_dma_idx_buf)
780 		bwfm_pci_dmamem_free(sc, sc->sc_dma_idx_buf);
781 
782  err:
783 	bwfm_firmware_close(&fwctx);
784 }
785 
786 int
787 bwfm_pci_load_microcode(struct bwfm_pci_softc *sc, const u_char *ucode, size_t size)
788 {
789 	struct bwfm_softc *bwfm = (void *)sc;
790 	struct bwfm_core *core;
791 	uint32_t shared;
792 	int i;
793 
794 	if (bwfm->sc_chip.ch_chip == BRCM_CC_43602_CHIP_ID) {
795 		bwfm_pci_select_core(sc, BWFM_AGENT_CORE_ARM_CR4);
796 		bus_space_write_4(sc->sc_reg_iot, sc->sc_reg_ioh,
797 		    BWFM_PCI_ARMCR4REG_BANKIDX, 5);
798 		bus_space_write_4(sc->sc_reg_iot, sc->sc_reg_ioh,
799 		    BWFM_PCI_ARMCR4REG_BANKPDA, 0);
800 		bus_space_write_4(sc->sc_reg_iot, sc->sc_reg_ioh,
801 		    BWFM_PCI_ARMCR4REG_BANKIDX, 7);
802 		bus_space_write_4(sc->sc_reg_iot, sc->sc_reg_ioh,
803 		    BWFM_PCI_ARMCR4REG_BANKPDA, 0);
804 	}
805 
806 	for (i = 0; i < size; i++)
807 		bus_space_write_1(sc->sc_tcm_iot, sc->sc_tcm_ioh,
808 		    bwfm->sc_chip.ch_rambase + i, ucode[i]);
809 
810 	/* Firmware replaces this with a pointer once up. */
811 	bus_space_write_4(sc->sc_tcm_iot, sc->sc_tcm_ioh,
812 	    bwfm->sc_chip.ch_rambase + bwfm->sc_chip.ch_ramsize - 4, 0);
813 
814 	/* TODO: restore NVRAM */
815 
816 	/* Load reset vector from firmware and kickstart core. */
817 	if (bwfm->sc_chip.ch_chip == BRCM_CC_43602_CHIP_ID) {
818 		core = bwfm_chip_get_core(bwfm, BWFM_AGENT_INTERNAL_MEM);
819 		bwfm->sc_chip.ch_core_reset(bwfm, core, 0, 0, 0);
820 	}
821 	bwfm_chip_set_active(bwfm, *(const uint32_t *)ucode);
822 
823 	for (i = 0; i < 40; i++) {
824 		delay(50 * 1000);
825 		shared = bus_space_read_4(sc->sc_tcm_iot, sc->sc_tcm_ioh,
826 		    bwfm->sc_chip.ch_rambase + bwfm->sc_chip.ch_ramsize - 4);
827 		if (shared)
828 			break;
829 	}
830 	if (!shared) {
831 		printf("%s: firmware did not come up\n", DEVNAME(sc));
832 		return 1;
833 	}
834 
835 	sc->sc_shared_address = shared;
836 	return 0;
837 }
838 
839 int
840 bwfm_pci_detach(device_t self, int flags)
841 {
842 	struct bwfm_pci_softc *sc = device_private(self);
843 
844 	bwfm_detach(&sc->sc_sc, flags);
845 
846 	/* FIXME: free RX buffers */
847 	/* FIXME: free TX buffers */
848 	/* FIXME: free more memory */
849 
850 	kmem_free(sc->sc_flowrings, sc->sc_max_flowrings
851 	    * sizeof(struct bwfm_pci_msgring));
852 	pool_destroy(&sc->sc_flowring_pool);
853 
854 	workqueue_destroy(sc->flowring_wq);
855 	pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
856 	pci_intr_release(sc->sc_pc, sc->sc_pihp, 1);
857 	bwfm_pci_dmamem_free(sc, sc->sc_ioctl_buf);
858 	bwfm_pci_dmamem_free(sc, sc->sc_ringupd_buf);
859 	bwfm_pci_dmamem_free(sc, sc->sc_scratch_buf);
860 	bwfm_pci_dmamem_free(sc, sc->sc_rx_complete.ring);
861 	bwfm_pci_dmamem_free(sc, sc->sc_tx_complete.ring);
862 	bwfm_pci_dmamem_free(sc, sc->sc_ctrl_complete.ring);
863 	bwfm_pci_dmamem_free(sc, sc->sc_rxpost_submit.ring);
864 	bwfm_pci_dmamem_free(sc, sc->sc_ctrl_submit.ring);
865 	bwfm_pci_dmamem_free(sc, sc->sc_dma_idx_buf);
866 	return 0;
867 }
868 
869 /* DMA code */
870 struct bwfm_pci_dmamem *
871 bwfm_pci_dmamem_alloc(struct bwfm_pci_softc *sc, bus_size_t size, bus_size_t align)
872 {
873 	struct bwfm_pci_dmamem *bdm;
874 	int nsegs;
875 
876 	bdm = kmem_zalloc(sizeof(*bdm), KM_SLEEP);
877 	bdm->bdm_size = size;
878 
879 	if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
880 	    BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW, &bdm->bdm_map) != 0)
881 		goto bdmfree;
882 
883 	if (bus_dmamem_alloc(sc->sc_dmat, size, align, 0, &bdm->bdm_seg, 1,
884 	    &nsegs, BUS_DMA_WAITOK) != 0)
885 		goto destroy;
886 
887 	if (bus_dmamem_map(sc->sc_dmat, &bdm->bdm_seg, nsegs, size,
888 	    (void **) &bdm->bdm_kva, BUS_DMA_WAITOK | BUS_DMA_COHERENT) != 0)
889 		goto free;
890 
891 	if (bus_dmamap_load(sc->sc_dmat, bdm->bdm_map, bdm->bdm_kva, size,
892 	    NULL, BUS_DMA_WAITOK) != 0)
893 		goto unmap;
894 
895 	bzero(bdm->bdm_kva, size);
896 
897 	return (bdm);
898 
899 unmap:
900 	bus_dmamem_unmap(sc->sc_dmat, bdm->bdm_kva, size);
901 free:
902 	bus_dmamem_free(sc->sc_dmat, &bdm->bdm_seg, 1);
903 destroy:
904 	bus_dmamap_destroy(sc->sc_dmat, bdm->bdm_map);
905 bdmfree:
906 	kmem_free(bdm, sizeof(*bdm));
907 
908 	return (NULL);
909 }
910 
911 void
912 bwfm_pci_dmamem_free(struct bwfm_pci_softc *sc, struct bwfm_pci_dmamem *bdm)
913 {
914 	bus_dmamem_unmap(sc->sc_dmat, bdm->bdm_kva, bdm->bdm_size);
915 	bus_dmamem_free(sc->sc_dmat, &bdm->bdm_seg, 1);
916 	bus_dmamap_destroy(sc->sc_dmat, bdm->bdm_map);
917 	kmem_free(bdm, sizeof(*bdm));
918 }
919 
920 /*
921  * We need a simple mapping from a packet ID to mbufs, because when
922  * a transfer completed, we only know the ID so we have to look up
923  * the memory for the ID.  This simply looks for an empty slot.
924  */
925 int
926 bwfm_pci_pktid_avail(struct bwfm_pci_softc *sc, struct bwfm_pci_pkts *pkts)
927 {
928 	int i, idx;
929 
930 	idx = pkts->last + 1;
931 	for (i = 0; i < pkts->npkt; i++) {
932 		if (idx == pkts->npkt)
933 			idx = 0;
934 		if (pkts->pkts[idx].bb_m == NULL)
935 			return 0;
936 		idx++;
937 	}
938 	return ENOBUFS;
939 }
940 
941 int
942 bwfm_pci_pktid_new(struct bwfm_pci_softc *sc, struct bwfm_pci_pkts *pkts,
943     struct mbuf **mp, uint32_t *pktid, paddr_t *paddr)
944 {
945 	int i, idx;
946 
947 	idx = pkts->last + 1;
948 	for (i = 0; i < pkts->npkt; i++) {
949 		if (idx == pkts->npkt)
950 			idx = 0;
951 		if (pkts->pkts[idx].bb_m == NULL) {
952 			if (bus_dmamap_load_mbuf(sc->sc_dmat,
953 			    pkts->pkts[idx].bb_map, *mp, BUS_DMA_NOWAIT) != 0) {
954 				/*
955 				 * Didn't fit.  Maybe it has too many
956 				 * segments.  If it has only one
957 				 * segment, fail; otherwise try to
958 				 * compact it into a single mbuf
959 				 * segment.
960 				 */
961 				if ((*mp)->m_next == NULL)
962 					return ENOBUFS;
963 				struct mbuf *m0 = MCLGETI(NULL, M_DONTWAIT,
964 				    NULL, MSGBUF_MAX_PKT_SIZE);
965 				if (m0 == NULL)
966 					return ENOBUFS;
967 				m_copydata(*mp, 0, (*mp)->m_pkthdr.len,
968 				    mtod(m0, void *));
969 				m0->m_pkthdr.len = m0->m_len =
970 				    (*mp)->m_pkthdr.len;
971 				m_freem(*mp);
972 				*mp = m0;
973 				if (bus_dmamap_load_mbuf(sc->sc_dmat,
974 				    pkts->pkts[idx].bb_map, *mp, BUS_DMA_NOWAIT) != 0)
975 					return EFBIG;
976 			}
977 			bus_dmamap_sync(sc->sc_dmat, pkts->pkts[idx].bb_map,
978 			    0, pkts->pkts[idx].bb_map->dm_mapsize,
979 			    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
980 			pkts->last = idx;
981 			pkts->pkts[idx].bb_m = *mp;
982 			*pktid = idx;
983 			*paddr = pkts->pkts[idx].bb_map->dm_segs[0].ds_addr;
984 			return 0;
985 		}
986 		idx++;
987 	}
988 	return ENOBUFS;
989 }
990 
991 struct mbuf *
992 bwfm_pci_pktid_free(struct bwfm_pci_softc *sc, struct bwfm_pci_pkts *pkts,
993     uint32_t pktid)
994 {
995 	struct mbuf *m;
996 
997 	if (pktid >= pkts->npkt || pkts->pkts[pktid].bb_m == NULL)
998 		return NULL;
999 	bus_dmamap_sync(sc->sc_dmat, pkts->pkts[pktid].bb_map, 0,
1000 	    pkts->pkts[pktid].bb_map->dm_mapsize,
1001 	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
1002 	bus_dmamap_unload(sc->sc_dmat, pkts->pkts[pktid].bb_map);
1003 	m = pkts->pkts[pktid].bb_m;
1004 	pkts->pkts[pktid].bb_m = NULL;
1005 	return m;
1006 }
1007 
1008 void
1009 bwfm_pci_fill_rx_rings(struct bwfm_pci_softc *sc)
1010 {
1011 	bwfm_pci_fill_rx_buf_ring(sc);
1012 	bwfm_pci_fill_rx_ioctl_ring(sc, &sc->sc_ioctl_ring,
1013 	    MSGBUF_TYPE_IOCTLRESP_BUF_POST);
1014 	bwfm_pci_fill_rx_ioctl_ring(sc, &sc->sc_event_ring,
1015 	    MSGBUF_TYPE_EVENT_BUF_POST);
1016 }
1017 
1018 void
1019 bwfm_pci_fill_rx_ioctl_ring(struct bwfm_pci_softc *sc, struct if_rxring *rxring,
1020     uint32_t msgtype)
1021 {
1022 	struct msgbuf_rx_ioctl_resp_or_event *req;
1023 	struct mbuf *m;
1024 	uint32_t pktid;
1025 	paddr_t paddr;
1026 	int s, slots;
1027 	uint64_t devaddr;
1028 
1029 	s = splnet();
1030 	for (slots = if_rxr_get(rxring, 8); slots > 0; slots--) {
1031 		if (bwfm_pci_pktid_avail(sc, &sc->sc_rx_pkts))
1032 			break;
1033 		req = bwfm_pci_ring_write_reserve(sc, &sc->sc_ctrl_submit);
1034 		if (req == NULL)
1035 			break;
1036 		m = MCLGETI(NULL, M_DONTWAIT, NULL, MSGBUF_MAX_PKT_SIZE);
1037 		if (m == NULL) {
1038 			bwfm_pci_ring_write_cancel(sc, &sc->sc_ctrl_submit, 1);
1039 			break;
1040 		}
1041 		m->m_len = m->m_pkthdr.len = MSGBUF_MAX_PKT_SIZE;
1042 		if (bwfm_pci_pktid_new(sc, &sc->sc_rx_pkts, &m, &pktid, &paddr)) {
1043 			bwfm_pci_ring_write_cancel(sc, &sc->sc_ctrl_submit, 1);
1044 			m_freem(m);
1045 			break;
1046 		}
1047 		devaddr = paddr;
1048 		memset(req, 0, sizeof(*req));
1049 		req->msg.msgtype = msgtype;
1050 		req->msg.request_id = htole32(pktid);
1051 		req->host_buf_len = htole16(MSGBUF_MAX_PKT_SIZE);
1052 		req->host_buf_addr.high_addr = htole32(devaddr >> 32);
1053 		req->host_buf_addr.low_addr = htole32(devaddr & 0xffffffff);
1054 		bwfm_pci_ring_write_commit(sc, &sc->sc_ctrl_submit);
1055 	}
1056 	if_rxr_put(rxring, slots);
1057 	splx(s);
1058 }
1059 
1060 void
1061 bwfm_pci_fill_rx_buf_ring(struct bwfm_pci_softc *sc)
1062 {
1063 	struct msgbuf_rx_bufpost *req;
1064 	struct mbuf *m;
1065 	uint32_t pktid;
1066 	paddr_t paddr;
1067 	int s, slots;
1068 	uint64_t devaddr;
1069 
1070 	s = splnet();
1071 	for (slots = if_rxr_get(&sc->sc_rxbuf_ring, sc->sc_max_rxbufpost);
1072 	    slots > 0; slots--) {
1073 		if (bwfm_pci_pktid_avail(sc, &sc->sc_rx_pkts))
1074 			break;
1075 		req = bwfm_pci_ring_write_reserve(sc, &sc->sc_rxpost_submit);
1076 		if (req == NULL)
1077 			break;
1078 		m = MCLGETI(NULL, M_DONTWAIT, NULL, MSGBUF_MAX_PKT_SIZE);
1079 		if (m == NULL) {
1080 			bwfm_pci_ring_write_cancel(sc, &sc->sc_rxpost_submit, 1);
1081 			break;
1082 		}
1083 		m->m_len = m->m_pkthdr.len = MSGBUF_MAX_PKT_SIZE;
1084 		if (bwfm_pci_pktid_new(sc, &sc->sc_rx_pkts, &m, &pktid, &paddr)) {
1085 			bwfm_pci_ring_write_cancel(sc, &sc->sc_rxpost_submit, 1);
1086 			m_freem(m);
1087 			break;
1088 		}
1089 		devaddr = paddr;
1090 		memset(req, 0, sizeof(*req));
1091 		req->msg.msgtype = MSGBUF_TYPE_RXBUF_POST;
1092 		req->msg.request_id = htole32(pktid);
1093 		req->data_buf_len = htole16(MSGBUF_MAX_PKT_SIZE);
1094 		req->data_buf_addr.high_addr = htole32(devaddr >> 32);
1095 		req->data_buf_addr.low_addr = htole32(devaddr & 0xffffffff);
1096 		bwfm_pci_ring_write_commit(sc, &sc->sc_rxpost_submit);
1097 	}
1098 	if_rxr_put(&sc->sc_rxbuf_ring, slots);
1099 	splx(s);
1100 }
1101 
1102 int
1103 bwfm_pci_setup_ring(struct bwfm_pci_softc *sc, struct bwfm_pci_msgring *ring,
1104     int nitem, size_t itemsz, uint32_t w_idx, uint32_t r_idx,
1105     int idx, uint32_t idx_off, uint32_t *ring_mem)
1106 {
1107 	ring->w_idx_addr = w_idx + idx * idx_off;
1108 	ring->r_idx_addr = r_idx + idx * idx_off;
1109 	ring->nitem = nitem;
1110 	ring->itemsz = itemsz;
1111 	bwfm_pci_ring_write_rptr(sc, ring);
1112 	bwfm_pci_ring_write_wptr(sc, ring);
1113 
1114 	ring->ring = bwfm_pci_dmamem_alloc(sc, nitem * itemsz, 8);
1115 	if (ring->ring == NULL)
1116 		return ENOMEM;
1117 	bus_space_write_4(sc->sc_tcm_iot, sc->sc_tcm_ioh,
1118 	    *ring_mem + BWFM_RING_MEM_BASE_ADDR_LOW,
1119 	    BWFM_PCI_DMA_DVA(ring->ring) & 0xffffffff);
1120 	bus_space_write_4(sc->sc_tcm_iot, sc->sc_tcm_ioh,
1121 	    *ring_mem + BWFM_RING_MEM_BASE_ADDR_HIGH,
1122 	    BWFM_PCI_DMA_DVA(ring->ring) >> 32);
1123 	bus_space_write_2(sc->sc_tcm_iot, sc->sc_tcm_ioh,
1124 	    *ring_mem + BWFM_RING_MAX_ITEM, nitem);
1125 	bus_space_write_2(sc->sc_tcm_iot, sc->sc_tcm_ioh,
1126 	    *ring_mem + BWFM_RING_LEN_ITEMS, itemsz);
1127 	*ring_mem = *ring_mem + BWFM_RING_MEM_SZ;
1128 	return 0;
1129 }
1130 
1131 int
1132 bwfm_pci_setup_flowring(struct bwfm_pci_softc *sc, struct bwfm_pci_msgring *ring,
1133     int nitem, size_t itemsz)
1134 {
1135 	ring->w_ptr = 0;
1136 	ring->r_ptr = 0;
1137 	ring->nitem = nitem;
1138 	ring->itemsz = itemsz;
1139 	bwfm_pci_ring_write_rptr(sc, ring);
1140 	bwfm_pci_ring_write_wptr(sc, ring);
1141 
1142 	ring->ring = bwfm_pci_dmamem_alloc(sc, nitem * itemsz, 8);
1143 	if (ring->ring == NULL)
1144 		return ENOMEM;
1145 	return 0;
1146 }
1147 
1148 /* Ring helpers */
1149 void
1150 bwfm_pci_ring_bell(struct bwfm_pci_softc *sc,
1151     struct bwfm_pci_msgring *ring)
1152 {
1153 	bus_space_write_4(sc->sc_reg_iot, sc->sc_reg_ioh,
1154 	    BWFM_PCI_PCIE2REG_H2D_MAILBOX, 1);
1155 }
1156 
1157 void
1158 bwfm_pci_ring_update_rptr(struct bwfm_pci_softc *sc,
1159     struct bwfm_pci_msgring *ring)
1160 {
1161 	if (sc->sc_dma_idx_sz == 0) {
1162 		ring->r_ptr = bus_space_read_2(sc->sc_tcm_iot,
1163 		    sc->sc_tcm_ioh, ring->r_idx_addr);
1164 	} else {
1165 		bus_dmamap_sync(sc->sc_dmat,
1166 		    BWFM_PCI_DMA_MAP(sc->sc_dma_idx_buf), ring->r_idx_addr,
1167 		    sizeof(uint16_t), BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
1168 		ring->r_ptr = *(uint16_t *)(BWFM_PCI_DMA_KVA(sc->sc_dma_idx_buf)
1169 		    + ring->r_idx_addr);
1170 	}
1171 }
1172 
1173 static u_int
1174 if_rxr_get(struct if_rxring *rxr, unsigned int max)
1175 {
1176 	u_int taken = MIN(max, (rxr->rxr_total - rxr->rxr_inuse));
1177 
1178 	KASSERTMSG(rxr->rxr_inuse + taken <= rxr->rxr_total,
1179 			"rxr->rxr_inuse: %d\n"
1180 			"taken: %d\n"
1181 			"rxr->rxr_total: %d\n",
1182 			rxr->rxr_inuse, taken, rxr->rxr_total);
1183 	rxr->rxr_inuse += taken;
1184 
1185 	return taken;
1186 }
1187 
1188 static void
1189 if_rxr_put(struct if_rxring *rxr, unsigned int n)
1190 {
1191 	KASSERTMSG(rxr->rxr_inuse >= n,
1192 			"rxr->rxr_inuse: %d\n"
1193 			"n: %d\n"
1194 			"rxr->rxr_total: %d\n",
1195 			rxr->rxr_inuse, n, rxr->rxr_total);
1196 
1197 	rxr->rxr_inuse -= n;
1198 }
1199 
1200 static void
1201 if_rxr_init(struct if_rxring *rxr, unsigned int lwm __unused, unsigned int hwm)
1202 {
1203 	(void) lwm;
1204 
1205 	rxr->rxr_total = hwm;
1206 	rxr->rxr_inuse = 0;
1207 }
1208 
1209 void
1210 bwfm_pci_ring_update_wptr(struct bwfm_pci_softc *sc,
1211     struct bwfm_pci_msgring *ring)
1212 {
1213 	if (sc->sc_dma_idx_sz == 0) {
1214 		ring->w_ptr = bus_space_read_2(sc->sc_tcm_iot,
1215 		    sc->sc_tcm_ioh, ring->w_idx_addr);
1216 	} else {
1217 		ring->w_ptr = *(uint16_t *)(BWFM_PCI_DMA_KVA(sc->sc_dma_idx_buf)
1218 		    + ring->w_idx_addr);
1219 		bus_dmamap_sync(sc->sc_dmat,
1220 		    BWFM_PCI_DMA_MAP(sc->sc_dma_idx_buf), ring->w_idx_addr,
1221 		    sizeof(uint16_t), BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
1222 	}
1223 }
1224 
1225 void
1226 bwfm_pci_ring_write_rptr(struct bwfm_pci_softc *sc,
1227     struct bwfm_pci_msgring *ring)
1228 {
1229 	if (sc->sc_dma_idx_sz == 0) {
1230 		bus_space_write_2(sc->sc_tcm_iot, sc->sc_tcm_ioh,
1231 		    ring->r_idx_addr, ring->r_ptr);
1232 	} else {
1233 		*(uint16_t *)(BWFM_PCI_DMA_KVA(sc->sc_dma_idx_buf)
1234 		    + ring->r_idx_addr) = ring->r_ptr;
1235 		bus_dmamap_sync(sc->sc_dmat,
1236 		    BWFM_PCI_DMA_MAP(sc->sc_dma_idx_buf), ring->r_idx_addr,
1237 		    sizeof(uint16_t), BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
1238 	}
1239 }
1240 
1241 void
1242 bwfm_pci_ring_write_wptr(struct bwfm_pci_softc *sc,
1243     struct bwfm_pci_msgring *ring)
1244 {
1245 	if (sc->sc_dma_idx_sz == 0) {
1246 		bus_space_write_2(sc->sc_tcm_iot, sc->sc_tcm_ioh,
1247 		    ring->w_idx_addr, ring->w_ptr);
1248 	} else {
1249 		*(uint16_t *)(BWFM_PCI_DMA_KVA(sc->sc_dma_idx_buf)
1250 		    + ring->w_idx_addr) = ring->w_ptr;
1251 		bus_dmamap_sync(sc->sc_dmat,
1252 		    BWFM_PCI_DMA_MAP(sc->sc_dma_idx_buf), ring->w_idx_addr,
1253 		    sizeof(uint16_t), BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
1254 	}
1255 }
1256 
1257 /*
1258  * Retrieve a free descriptor to put new stuff in, but don't commit
1259  * to it yet so we can rollback later if any error occurs.
1260  */
1261 void *
1262 bwfm_pci_ring_write_reserve(struct bwfm_pci_softc *sc,
1263     struct bwfm_pci_msgring *ring)
1264 {
1265 	int available;
1266 	char *ret;
1267 
1268 	bwfm_pci_ring_update_rptr(sc, ring);
1269 
1270 	if (ring->r_ptr > ring->w_ptr)
1271 		available = ring->r_ptr - ring->w_ptr;
1272 	else
1273 		available = ring->r_ptr + (ring->nitem - ring->w_ptr);
1274 
1275 	if (available < 1)
1276 		return NULL;
1277 
1278 	ret = BWFM_PCI_DMA_KVA(ring->ring) + (ring->w_ptr * ring->itemsz);
1279 	ring->w_ptr += 1;
1280 	if (ring->w_ptr == ring->nitem)
1281 		ring->w_ptr = 0;
1282 	return ret;
1283 }
1284 
1285 void *
1286 bwfm_pci_ring_write_reserve_multi(struct bwfm_pci_softc *sc,
1287     struct bwfm_pci_msgring *ring, int count, int *avail)
1288 {
1289 	int available;
1290 	char *ret;
1291 
1292 	bwfm_pci_ring_update_rptr(sc, ring);
1293 
1294 	if (ring->r_ptr > ring->w_ptr)
1295 		available = ring->r_ptr - ring->w_ptr;
1296 	else
1297 		available = ring->r_ptr + (ring->nitem - ring->w_ptr);
1298 
1299 	if (available < 1)
1300 		return NULL;
1301 
1302 	ret = BWFM_PCI_DMA_KVA(ring->ring) + (ring->w_ptr * ring->itemsz);
1303 	*avail = uimin(count, available - 1);
1304 	if (*avail + ring->w_ptr > ring->nitem)
1305 		*avail = ring->nitem - ring->w_ptr;
1306 	ring->w_ptr += *avail;
1307 	if (ring->w_ptr == ring->nitem)
1308 		ring->w_ptr = 0;
1309 	return ret;
1310 }
1311 
1312 /*
1313  * Read number of descriptors available (submitted by the firmware)
1314  * and retrieve pointer to first descriptor.
1315  */
1316 void *
1317 bwfm_pci_ring_read_avail(struct bwfm_pci_softc *sc,
1318     struct bwfm_pci_msgring *ring, int *avail)
1319 {
1320 	bwfm_pci_ring_update_wptr(sc, ring);
1321 
1322 	if (ring->w_ptr >= ring->r_ptr)
1323 		*avail = ring->w_ptr - ring->r_ptr;
1324 	else
1325 		*avail = ring->nitem - ring->r_ptr;
1326 
1327 	if (*avail == 0)
1328 		return NULL;
1329 	bus_dmamap_sync(sc->sc_dmat, BWFM_PCI_DMA_MAP(ring->ring),
1330 	    ring->r_ptr * ring->itemsz, *avail * ring->itemsz,
1331 	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
1332 	return BWFM_PCI_DMA_KVA(ring->ring) + (ring->r_ptr * ring->itemsz);
1333 }
1334 
1335 /*
1336  * Let firmware know we read N descriptors.
1337  */
1338 void
1339 bwfm_pci_ring_read_commit(struct bwfm_pci_softc *sc,
1340     struct bwfm_pci_msgring *ring, int nitem)
1341 {
1342 	ring->r_ptr += nitem;
1343 	if (ring->r_ptr == ring->nitem)
1344 		ring->r_ptr = 0;
1345 	bwfm_pci_ring_write_rptr(sc, ring);
1346 }
1347 
1348 /*
1349  * Let firmware know that we submitted some descriptors.
1350  */
1351 void
1352 bwfm_pci_ring_write_commit(struct bwfm_pci_softc *sc,
1353     struct bwfm_pci_msgring *ring)
1354 {
1355 	bus_dmamap_sync(sc->sc_dmat, BWFM_PCI_DMA_MAP(ring->ring),
1356 	    0, BWFM_PCI_DMA_LEN(ring->ring), BUS_DMASYNC_PREREAD |
1357 	    BUS_DMASYNC_PREWRITE);
1358 	bwfm_pci_ring_write_wptr(sc, ring);
1359 	bwfm_pci_ring_bell(sc, ring);
1360 }
1361 
1362 /*
1363  * Rollback N descriptors in case we don't actually want
1364  * to commit to it.
1365  */
1366 void
1367 bwfm_pci_ring_write_cancel(struct bwfm_pci_softc *sc,
1368     struct bwfm_pci_msgring *ring, int nitem)
1369 {
1370 	if (ring->w_ptr == 0)
1371 		ring->w_ptr = ring->nitem - nitem;
1372 	else
1373 		ring->w_ptr -= nitem;
1374 }
1375 
1376 /*
1377  * Foreach written descriptor on the ring, pass the descriptor to
1378  * a message handler and let the firmware know we handled it.
1379  */
1380 void
1381 bwfm_pci_ring_rx(struct bwfm_pci_softc *sc, struct bwfm_pci_msgring *ring)
1382 {
1383 	char *buf;
1384 	int avail, processed;
1385 
1386 again:
1387 	buf = bwfm_pci_ring_read_avail(sc, ring, &avail);
1388 	if (buf == NULL)
1389 		return;
1390 
1391 	processed = 0;
1392 	while (avail) {
1393 		bwfm_pci_msg_rx(sc, buf + sc->sc_rx_dataoffset);
1394 		buf += ring->itemsz;
1395 		processed++;
1396 		if (processed == 48) {
1397 			bwfm_pci_ring_read_commit(sc, ring, processed);
1398 			processed = 0;
1399 		}
1400 		avail--;
1401 	}
1402 	if (processed)
1403 		bwfm_pci_ring_read_commit(sc, ring, processed);
1404 	if (ring->r_ptr == 0)
1405 		goto again;
1406 }
1407 
1408 void
1409 bwfm_pci_msg_rx(struct bwfm_pci_softc *sc, void *buf)
1410 {
1411 	struct ifnet *ifp = sc->sc_sc.sc_ic.ic_ifp;
1412 	struct msgbuf_ioctl_resp_hdr *resp;
1413 	struct msgbuf_tx_status *tx;
1414 	struct msgbuf_rx_complete *rx;
1415 	struct msgbuf_rx_event *event;
1416 	struct msgbuf_common_hdr *msg;
1417 	struct msgbuf_flowring_create_resp *fcr;
1418 	struct msgbuf_flowring_delete_resp *fdr;
1419 	struct bwfm_pci_msgring *ring;
1420 	struct mbuf *m;
1421 	int flowid;
1422 
1423 	msg = (struct msgbuf_common_hdr *)buf;
1424 	switch (msg->msgtype)
1425 	{
1426 	case MSGBUF_TYPE_FLOW_RING_CREATE_CMPLT:
1427 		fcr = (struct msgbuf_flowring_create_resp *)buf;
1428 		flowid = letoh16(fcr->compl_hdr.flow_ring_id);
1429 		if (flowid < 2)
1430 			break;
1431 		flowid -= 2;
1432 		if (flowid >= sc->sc_max_flowrings)
1433 			break;
1434 		ring = &sc->sc_flowrings[flowid];
1435 		if (ring->status != RING_OPENING)
1436 			break;
1437 		if (fcr->compl_hdr.status) {
1438 			printf("%s: failed to open flowring %d\n",
1439 			    DEVNAME(sc), flowid);
1440 			ring->status = RING_CLOSED;
1441 			if (ring->m) {
1442 				m_freem(ring->m);
1443 				ring->m = NULL;
1444 			}
1445 			ifp->if_flags &= ~IFF_OACTIVE;
1446 			ifp->if_start(ifp);
1447 			break;
1448 		}
1449 		ring->status = RING_OPEN;
1450 		if (ring->m != NULL) {
1451 			m = ring->m;
1452 			ring->m = NULL;
1453 			if (bwfm_pci_txdata(&sc->sc_sc, &m))
1454 				m_freem(ring->m);
1455 		}
1456 		ifp->if_flags &= ~IFF_OACTIVE;
1457 		ifp->if_start(ifp);
1458 		break;
1459 	case MSGBUF_TYPE_FLOW_RING_DELETE_CMPLT:
1460 		fdr = (struct msgbuf_flowring_delete_resp *)buf;
1461 		flowid = letoh16(fdr->compl_hdr.flow_ring_id);
1462 		if (flowid < 2)
1463 			break;
1464 		flowid -= 2;
1465 		if (flowid >= sc->sc_max_flowrings)
1466 			break;
1467 		ring = &sc->sc_flowrings[flowid];
1468 		if (ring->status != RING_CLOSING)
1469 			break;
1470 		if (fdr->compl_hdr.status) {
1471 			printf("%s: failed to delete flowring %d\n",
1472 			    DEVNAME(sc), flowid);
1473 			break;
1474 		}
1475 		bwfm_pci_dmamem_free(sc, ring->ring);
1476 		ring->status = RING_CLOSED;
1477 		break;
1478 	case MSGBUF_TYPE_IOCTLPTR_REQ_ACK:
1479 		break;
1480 	case MSGBUF_TYPE_IOCTL_CMPLT:
1481 		resp = (struct msgbuf_ioctl_resp_hdr *)buf;
1482 		sc->sc_ioctl_resp_pktid = letoh32(resp->msg.request_id);
1483 		sc->sc_ioctl_resp_ret_len = letoh16(resp->resp_len);
1484 		sc->sc_ioctl_resp_status = letoh16(resp->compl_hdr.status);
1485 		if_rxr_put(&sc->sc_ioctl_ring, 1);
1486 		bwfm_pci_fill_rx_rings(sc);
1487 		wakeup(&sc->sc_ioctl_buf);
1488 		break;
1489 	case MSGBUF_TYPE_WL_EVENT:
1490 		event = (struct msgbuf_rx_event *)buf;
1491 		m = bwfm_pci_pktid_free(sc, &sc->sc_rx_pkts,
1492 		    letoh32(event->msg.request_id));
1493 		if (m == NULL)
1494 			break;
1495 		m_adj(m, sc->sc_rx_dataoffset);
1496 		m->m_len = m->m_pkthdr.len = letoh16(event->event_data_len);
1497 		bwfm_rx(&sc->sc_sc, m);
1498 		if_rxr_put(&sc->sc_event_ring, 1);
1499 		bwfm_pci_fill_rx_rings(sc);
1500 		break;
1501 	case MSGBUF_TYPE_TX_STATUS:
1502 		tx = (struct msgbuf_tx_status *)buf;
1503 		m = bwfm_pci_pktid_free(sc, &sc->sc_tx_pkts,
1504 		    letoh32(tx->msg.request_id));
1505 		if (m == NULL)
1506 			break;
1507 		m_freem(m);
1508 		if (sc->sc_tx_pkts_full) {
1509 			sc->sc_tx_pkts_full = 0;
1510 			ifp->if_flags &= ~IFF_OACTIVE;
1511 			ifp->if_start(ifp);
1512 		}
1513 		break;
1514 	case MSGBUF_TYPE_RX_CMPLT:
1515 		rx = (struct msgbuf_rx_complete *)buf;
1516 		m = bwfm_pci_pktid_free(sc, &sc->sc_rx_pkts,
1517 		    letoh32(rx->msg.request_id));
1518 		if (m == NULL)
1519 			break;
1520 		if (letoh16(rx->data_offset))
1521 			m_adj(m, letoh16(rx->data_offset));
1522 		else if (sc->sc_rx_dataoffset)
1523 			m_adj(m, sc->sc_rx_dataoffset);
1524 		m->m_len = m->m_pkthdr.len = letoh16(rx->data_len);
1525 		bwfm_rx(&sc->sc_sc, m);
1526 		if_rxr_put(&sc->sc_rxbuf_ring, 1);
1527 		bwfm_pci_fill_rx_rings(sc);
1528 		break;
1529 	default:
1530 		printf("%s: msgtype 0x%08x\n", __func__, msg->msgtype);
1531 		break;
1532 	}
1533 }
1534 
1535 /* Bus core helpers */
1536 void
1537 bwfm_pci_select_core(struct bwfm_pci_softc *sc, int id)
1538 {
1539 	struct bwfm_softc *bwfm = (void *)sc;
1540 	struct bwfm_core *core;
1541 
1542 	core = bwfm_chip_get_core(bwfm, id);
1543 	if (core == NULL) {
1544 		printf("%s: could not find core to select", DEVNAME(sc));
1545 		return;
1546 	}
1547 
1548 	pci_conf_write(sc->sc_pc, sc->sc_tag,
1549 	    BWFM_PCI_BAR0_WINDOW, core->co_base);
1550 	if (pci_conf_read(sc->sc_pc, sc->sc_tag,
1551 	    BWFM_PCI_BAR0_WINDOW) != core->co_base)
1552 		pci_conf_write(sc->sc_pc, sc->sc_tag,
1553 		    BWFM_PCI_BAR0_WINDOW, core->co_base);
1554 }
1555 
1556 uint32_t
1557 bwfm_pci_buscore_read(struct bwfm_softc *bwfm, uint32_t reg)
1558 {
1559 	struct bwfm_pci_softc *sc = (void *)bwfm;
1560 	uint32_t page, offset;
1561 
1562 	page = reg & ~(BWFM_PCI_BAR0_REG_SIZE - 1);
1563 	offset = reg & (BWFM_PCI_BAR0_REG_SIZE - 1);
1564 	pci_conf_write(sc->sc_pc, sc->sc_tag, BWFM_PCI_BAR0_WINDOW, page);
1565 	return bus_space_read_4(sc->sc_reg_iot, sc->sc_reg_ioh, offset);
1566 }
1567 
1568 void
1569 bwfm_pci_buscore_write(struct bwfm_softc *bwfm, uint32_t reg, uint32_t val)
1570 {
1571 	struct bwfm_pci_softc *sc = (void *)bwfm;
1572 	uint32_t page, offset;
1573 
1574 	page = reg & ~(BWFM_PCI_BAR0_REG_SIZE - 1);
1575 	offset = reg & (BWFM_PCI_BAR0_REG_SIZE - 1);
1576 	pci_conf_write(sc->sc_pc, sc->sc_tag, BWFM_PCI_BAR0_WINDOW, page);
1577 	bus_space_write_4(sc->sc_reg_iot, sc->sc_reg_ioh, offset, val);
1578 }
1579 
1580 int
1581 bwfm_pci_buscore_prepare(struct bwfm_softc *bwfm)
1582 {
1583 	return 0;
1584 }
1585 
1586 int
1587 bwfm_pci_buscore_reset(struct bwfm_softc *bwfm)
1588 {
1589 	struct bwfm_pci_softc *sc = (void *)bwfm;
1590 	struct bwfm_core *core;
1591 	uint32_t reg;
1592 	int i;
1593 
1594 	bwfm_pci_select_core(sc, BWFM_AGENT_CORE_PCIE2);
1595 	reg = pci_conf_read(sc->sc_pc, sc->sc_tag,
1596 	    BWFM_PCI_CFGREG_LINK_STATUS_CTRL);
1597 	pci_conf_write(sc->sc_pc, sc->sc_tag, BWFM_PCI_CFGREG_LINK_STATUS_CTRL,
1598 	    reg & ~BWFM_PCI_CFGREG_LINK_STATUS_CTRL_ASPM_ENAB);
1599 
1600 	bwfm_pci_select_core(sc, BWFM_AGENT_CORE_CHIPCOMMON);
1601 	bus_space_write_4(sc->sc_reg_iot, sc->sc_reg_ioh,
1602 	    BWFM_CHIP_REG_WATCHDOG, 4);
1603 	delay(100 * 1000);
1604 
1605 	bwfm_pci_select_core(sc, BWFM_AGENT_CORE_PCIE2);
1606 	pci_conf_write(sc->sc_pc, sc->sc_tag,
1607 	    BWFM_PCI_CFGREG_LINK_STATUS_CTRL, reg);
1608 
1609 	core = bwfm_chip_get_core(bwfm, BWFM_AGENT_CORE_PCIE2);
1610 	if (core->co_rev <= 13) {
1611 		uint16_t cfg_offset[] = {
1612 		    BWFM_PCI_CFGREG_STATUS_CMD,
1613 		    BWFM_PCI_CFGREG_PM_CSR,
1614 		    BWFM_PCI_CFGREG_MSI_CAP,
1615 		    BWFM_PCI_CFGREG_MSI_ADDR_L,
1616 		    BWFM_PCI_CFGREG_MSI_ADDR_H,
1617 		    BWFM_PCI_CFGREG_MSI_DATA,
1618 		    BWFM_PCI_CFGREG_LINK_STATUS_CTRL2,
1619 		    BWFM_PCI_CFGREG_RBAR_CTRL,
1620 		    BWFM_PCI_CFGREG_PML1_SUB_CTRL1,
1621 		    BWFM_PCI_CFGREG_REG_BAR2_CONFIG,
1622 		    BWFM_PCI_CFGREG_REG_BAR3_CONFIG,
1623 		};
1624 
1625 		for (i = 0; i < nitems(cfg_offset); i++) {
1626 			bus_space_write_4(sc->sc_reg_iot, sc->sc_reg_ioh,
1627 			    BWFM_PCI_PCIE2REG_CONFIGADDR, cfg_offset[i]);
1628 			reg = bus_space_read_4(sc->sc_reg_iot, sc->sc_reg_ioh,
1629 			    BWFM_PCI_PCIE2REG_CONFIGDATA);
1630 			DPRINTFN(3, ("%s: config offset 0x%04x, value 0x%04x\n",
1631 			    DEVNAME(sc), cfg_offset[i], reg));
1632 			bus_space_write_4(sc->sc_reg_iot, sc->sc_reg_ioh,
1633 			    BWFM_PCI_PCIE2REG_CONFIGDATA, reg);
1634 		}
1635 	}
1636 
1637 	reg = bus_space_read_4(sc->sc_reg_iot, sc->sc_reg_ioh,
1638 	    BWFM_PCI_PCIE2REG_MAILBOXINT);
1639 	if (reg != 0xffffffff)
1640 		bus_space_write_4(sc->sc_reg_iot, sc->sc_reg_ioh,
1641 		    BWFM_PCI_PCIE2REG_MAILBOXINT, reg);
1642 
1643 	return 0;
1644 }
1645 
1646 void
1647 bwfm_pci_buscore_activate(struct bwfm_softc *bwfm, const uint32_t rstvec)
1648 {
1649 	struct bwfm_pci_softc *sc = (void *)bwfm;
1650 	bus_space_write_4(sc->sc_tcm_iot, sc->sc_tcm_ioh, 0, rstvec);
1651 }
1652 
1653 static int bwfm_pci_prio2fifo[8] = {
1654 	1, /* best effort */
1655 	0, /* IPTOS_PREC_IMMEDIATE */
1656 	0, /* IPTOS_PREC_PRIORITY */
1657 	1, /* IPTOS_PREC_FLASH */
1658 	2, /* IPTOS_PREC_FLASHOVERRIDE */
1659 	2, /* IPTOS_PREC_CRITIC_ECP */
1660 	3, /* IPTOS_PREC_INTERNETCONTROL */
1661 	3, /* IPTOS_PREC_NETCONTROL */
1662 };
1663 
1664 int
1665 bwfm_pci_flowring_lookup(struct bwfm_pci_softc *sc, struct mbuf *m)
1666 {
1667 	struct ieee80211com *ic = &sc->sc_sc.sc_ic;
1668 	uint8_t *da = mtod(m, uint8_t *);
1669 	struct ether_header *eh;
1670 	int flowid, prio, fifo;
1671 	int i, found, ac;
1672 
1673 	/* No QoS for EAPOL frames. */
1674 	eh = mtod(m, struct ether_header *);
1675 	ac = (eh->ether_type != htons(ETHERTYPE_PAE)) ?
1676 	    M_WME_GETAC(m) : WME_AC_BE;
1677 
1678 	prio = ac;
1679 	fifo = bwfm_pci_prio2fifo[prio];
1680 
1681 	switch (ic->ic_opmode)
1682 	{
1683 	case IEEE80211_M_STA:
1684 		flowid = fifo;
1685 		break;
1686 #ifndef IEEE80211_STA_ONLY
1687 	case IEEE80211_M_HOSTAP:
1688 		if (ETHER_IS_MULTICAST(da))
1689 			da = __UNCONST(etherbroadcastaddr);
1690 		flowid = da[5] * 2 + fifo;
1691 		break;
1692 #endif
1693 	default:
1694 		printf("%s: state not supported\n", DEVNAME(sc));
1695 		return ENOBUFS;
1696 	}
1697 
1698 	found = 0;
1699 	flowid = flowid % sc->sc_max_flowrings;
1700 	for (i = 0; i < sc->sc_max_flowrings; i++) {
1701 		if (ic->ic_opmode == IEEE80211_M_STA &&
1702 		    sc->sc_flowrings[flowid].status >= RING_OPEN &&
1703 		    sc->sc_flowrings[flowid].fifo == fifo) {
1704 			found = 1;
1705 			break;
1706 		}
1707 #ifndef IEEE80211_STA_ONLY
1708 		if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
1709 		    sc->sc_flowrings[flowid].status >= RING_OPEN &&
1710 		    sc->sc_flowrings[flowid].fifo == fifo &&
1711 		    !memcmp(sc->sc_flowrings[flowid].mac, da, ETHER_ADDR_LEN)) {
1712 			found = 1;
1713 			break;
1714 		}
1715 #endif
1716 		flowid = (flowid + 1) % sc->sc_max_flowrings;
1717 	}
1718 
1719 	if (found)
1720 		return flowid;
1721 
1722 	return -1;
1723 }
1724 
1725 void
1726 bwfm_pci_flowring_create(struct bwfm_pci_softc *sc, struct mbuf *m)
1727 {
1728 	struct ieee80211com *ic = &sc->sc_sc.sc_ic;
1729 	struct bwfm_cmd_flowring_create * cmd;
1730 	uint8_t *da = mtod(m, uint8_t *);
1731 	struct ether_header *eh;
1732 	struct bwfm_pci_msgring *ring;
1733 	int flowid, prio, fifo;
1734 	int i, found, ac;
1735 
1736 	cmd = pool_get(&sc->sc_flowring_pool, PR_NOWAIT);
1737 	if (__predict_false(cmd == NULL))
1738 		return;
1739 
1740 	/* No QoS for EAPOL frames. */
1741 	eh = mtod(m, struct ether_header *);
1742 	ac = (eh->ether_type != htons(ETHERTYPE_PAE)) ?
1743 	    M_WME_GETAC(m) : WME_AC_BE;
1744 
1745 	prio = ac;
1746 	fifo = bwfm_pci_prio2fifo[prio];
1747 
1748 	switch (ic->ic_opmode)
1749 	{
1750 	case IEEE80211_M_STA:
1751 		flowid = fifo;
1752 		break;
1753 #ifndef IEEE80211_STA_ONLY
1754 	case IEEE80211_M_HOSTAP:
1755 		if (ETHER_IS_MULTICAST(da))
1756 			da = __UNCONST(etherbroadcastaddr);
1757 		flowid = da[5] * 2 + fifo;
1758 		break;
1759 #endif
1760 	default:
1761 		printf("%s: state not supported\n", DEVNAME(sc));
1762 		return;
1763 	}
1764 
1765 	found = 0;
1766 	flowid = flowid % sc->sc_max_flowrings;
1767 	for (i = 0; i < sc->sc_max_flowrings; i++) {
1768 		ring = &sc->sc_flowrings[flowid];
1769 		if (ring->status == RING_CLOSED) {
1770 			ring->status = RING_OPENING;
1771 			found = 1;
1772 			break;
1773 		}
1774 		flowid = (flowid + 1) % sc->sc_max_flowrings;
1775 	}
1776 
1777 	/*
1778 	 * We cannot recover from that so far.  Only a stop/init
1779 	 * cycle can revive this if it ever happens at all.
1780 	 */
1781 	if (!found) {
1782 		printf("%s: no flowring available\n", DEVNAME(sc));
1783 		return;
1784 	}
1785 
1786 	cmd->sc = sc;
1787 	cmd->m = m;
1788 	cmd->prio = prio;
1789 	cmd->flowid = flowid;
1790 	workqueue_enqueue(sc->flowring_wq, &cmd->wq_cookie, NULL);
1791 }
1792 
1793 void
1794 bwfm_pci_flowring_create_cb(struct work *wk, void *arg) //(struct bwfm_softc *bwfm, void *arg)
1795 {
1796 	struct bwfm_cmd_flowring_create *cmd = container_of(wk, struct bwfm_cmd_flowring_create, wq_cookie);
1797 	struct bwfm_pci_softc *sc = cmd->sc; // (void *)bwfm;
1798 	struct ieee80211com *ic = &sc->sc_sc.sc_ic;
1799 	struct msgbuf_tx_flowring_create_req *req;
1800 	struct bwfm_pci_msgring *ring;
1801 	uint8_t *da, *sa;
1802 
1803 	da = mtod(cmd->m, char *) + 0 * ETHER_ADDR_LEN;
1804 	sa = mtod(cmd->m, char *) + 1 * ETHER_ADDR_LEN;
1805 
1806 	ring = &sc->sc_flowrings[cmd->flowid];
1807 	if (ring->status != RING_OPENING) {
1808 		printf("%s: flowring not opening\n", DEVNAME(sc));
1809 		return;
1810 	}
1811 
1812 	if (bwfm_pci_setup_flowring(sc, ring, 512, 48)) {
1813 		printf("%s: cannot setup flowring\n", DEVNAME(sc));
1814 		return;
1815 	}
1816 
1817 	req = bwfm_pci_ring_write_reserve(sc, &sc->sc_ctrl_submit);
1818 	if (req == NULL) {
1819 		printf("%s: cannot reserve for flowring\n", DEVNAME(sc));
1820 		return;
1821 	}
1822 
1823 	ring->status = RING_OPENING;
1824 	ring->fifo = bwfm_pci_prio2fifo[cmd->prio];
1825 	ring->m = cmd->m;
1826 	memcpy(ring->mac, da, ETHER_ADDR_LEN);
1827 #ifndef IEEE80211_STA_ONLY
1828 	if (ic->ic_opmode == IEEE80211_M_HOSTAP && ETHER_IS_MULTICAST(da))
1829 		memcpy(ring->mac, etherbroadcastaddr, ETHER_ADDR_LEN);
1830 #endif
1831 
1832 	req->msg.msgtype = MSGBUF_TYPE_FLOW_RING_CREATE;
1833 	req->msg.ifidx = 0;
1834 	req->msg.request_id = 0;
1835 	req->tid = bwfm_pci_prio2fifo[cmd->prio];
1836 	req->flow_ring_id = letoh16(cmd->flowid + 2);
1837 	memcpy(req->da, da, ETHER_ADDR_LEN);
1838 	memcpy(req->sa, sa, ETHER_ADDR_LEN);
1839 	req->flow_ring_addr.high_addr =
1840 	    letoh32(BWFM_PCI_DMA_DVA(ring->ring) >> 32);
1841 	req->flow_ring_addr.low_addr =
1842 	    letoh32(BWFM_PCI_DMA_DVA(ring->ring) & 0xffffffff);
1843 	req->max_items = letoh16(512);
1844 	req->len_item = letoh16(48);
1845 
1846 	bwfm_pci_ring_write_commit(sc, &sc->sc_ctrl_submit);
1847 	pool_put(&sc->sc_flowring_pool, cmd);
1848 }
1849 
1850 void
1851 bwfm_pci_flowring_delete(struct bwfm_pci_softc *sc, int flowid)
1852 {
1853 	struct msgbuf_tx_flowring_delete_req *req;
1854 	struct bwfm_pci_msgring *ring;
1855 
1856 	ring = &sc->sc_flowrings[flowid];
1857 	if (ring->status != RING_OPEN) {
1858 		printf("%s: flowring not open\n", DEVNAME(sc));
1859 		return;
1860 	}
1861 
1862 	req = bwfm_pci_ring_write_reserve(sc, &sc->sc_ctrl_submit);
1863 	if (req == NULL) {
1864 		printf("%s: cannot reserve for flowring\n", DEVNAME(sc));
1865 		return;
1866 	}
1867 
1868 	ring->status = RING_CLOSING;
1869 
1870 	req->msg.msgtype = MSGBUF_TYPE_FLOW_RING_DELETE;
1871 	req->msg.ifidx = 0;
1872 	req->msg.request_id = 0;
1873 	req->flow_ring_id = letoh16(flowid + 2);
1874 	req->reason = 0;
1875 
1876 	bwfm_pci_ring_write_commit(sc, &sc->sc_ctrl_submit);
1877 }
1878 
1879 void
1880 bwfm_pci_stop(struct bwfm_softc *bwfm)
1881 {
1882 	struct bwfm_pci_softc *sc = (void *)bwfm;
1883 	struct bwfm_pci_msgring *ring;
1884 	int i;
1885 
1886 	for (i = 0; i < sc->sc_max_flowrings; i++) {
1887 		ring = &sc->sc_flowrings[i];
1888 		if (ring->status == RING_OPEN)
1889 			bwfm_pci_flowring_delete(sc, i);
1890 	}
1891 }
1892 
1893 int
1894 bwfm_pci_txcheck(struct bwfm_softc *bwfm)
1895 {
1896 	struct bwfm_pci_softc *sc = (void *)bwfm;
1897 	struct bwfm_pci_msgring *ring;
1898 	int i;
1899 
1900 	/* If we are transitioning, we cannot send. */
1901 	for (i = 0; i < sc->sc_max_flowrings; i++) {
1902 		ring = &sc->sc_flowrings[i];
1903 		if (ring->status == RING_OPENING)
1904 			return ENOBUFS;
1905 	}
1906 
1907 	if (bwfm_pci_pktid_avail(sc, &sc->sc_tx_pkts)) {
1908 		sc->sc_tx_pkts_full = 1;
1909 		return ENOBUFS;
1910 	}
1911 
1912 	return 0;
1913 }
1914 
1915 int
1916 bwfm_pci_txdata(struct bwfm_softc *bwfm, struct mbuf **mp)
1917 {
1918 	struct bwfm_pci_softc *sc = (void *)bwfm;
1919 	struct bwfm_pci_msgring *ring;
1920 	struct msgbuf_tx_msghdr *tx;
1921 	uint32_t pktid;
1922 	paddr_t paddr;
1923 	uint64_t devaddr;
1924 	struct ether_header *eh;
1925 	int flowid, ret, ac;
1926 
1927 	flowid = bwfm_pci_flowring_lookup(sc, *mp);
1928 	if (flowid < 0) {
1929 		/*
1930 		 * We cannot send the packet right now as there is
1931 		 * no flowring yet.  The flowring will be created
1932 		 * asynchronously.  While the ring is transitioning
1933 		 * the TX check will tell the upper layers that we
1934 		 * cannot send packets right now.  When the flowring
1935 		 * is created the queue will be restarted and this
1936 		 * mbuf will be transmitted.
1937 		 */
1938 		bwfm_pci_flowring_create(sc, *mp);
1939 		return 0;
1940 	}
1941 
1942 	ring = &sc->sc_flowrings[flowid];
1943 	if (ring->status == RING_OPENING ||
1944 	    ring->status == RING_CLOSING) {
1945 		printf("%s: tried to use a flow that was "
1946 		    "transitioning in status %d\n",
1947 		    DEVNAME(sc), ring->status);
1948 		return ENOBUFS;
1949 	}
1950 
1951 	tx = bwfm_pci_ring_write_reserve(sc, ring);
1952 	if (tx == NULL)
1953 		return ENOBUFS;
1954 
1955 	/* No QoS for EAPOL frames. */
1956 	eh = mtod(*mp, struct ether_header *);
1957 	ac = (eh->ether_type != htons(ETHERTYPE_PAE)) ?
1958 	    M_WME_GETAC(*mp) : WME_AC_BE;
1959 
1960 	memset(tx, 0, sizeof(*tx));
1961 	tx->msg.msgtype = MSGBUF_TYPE_TX_POST;
1962 	tx->msg.ifidx = 0;
1963 	tx->flags = BWFM_MSGBUF_PKT_FLAGS_FRAME_802_3;
1964 	tx->flags |= ac << BWFM_MSGBUF_PKT_FLAGS_PRIO_SHIFT;
1965 	tx->seg_cnt = 1;
1966 	memcpy(tx->txhdr, mtod(*mp, char *), ETHER_HDR_LEN);
1967 
1968 	ret = bwfm_pci_pktid_new(sc, &sc->sc_tx_pkts, mp, &pktid, &paddr);
1969 	if (ret) {
1970 		if (ret == ENOBUFS) {
1971 			printf("%s: no pktid available for TX\n",
1972 			    DEVNAME(sc));
1973 			sc->sc_tx_pkts_full = 1;
1974 		}
1975 		bwfm_pci_ring_write_cancel(sc, ring, 1);
1976 		return ret;
1977 	}
1978 	devaddr = paddr + ETHER_HDR_LEN;
1979 
1980 	tx->msg.request_id = htole32(pktid);
1981 	tx->data_len = htole16((*mp)->m_len - ETHER_HDR_LEN);
1982 	tx->data_buf_addr.high_addr = htole32(devaddr >> 32);
1983 	tx->data_buf_addr.low_addr = htole32(devaddr & 0xffffffff);
1984 
1985 	bwfm_pci_ring_write_commit(sc, ring);
1986 	return 0;
1987 }
1988 
1989 #ifdef BWFM_DEBUG
1990 void
1991 bwfm_pci_debug_console(struct bwfm_pci_softc *sc)
1992 {
1993 	uint32_t newidx = bus_space_read_4(sc->sc_tcm_iot, sc->sc_tcm_ioh,
1994 	    sc->sc_console_base_addr + BWFM_CONSOLE_WRITEIDX);
1995 
1996 	if (newidx != sc->sc_console_readidx)
1997 		DPRINTFN(3, ("BWFM CONSOLE: "));
1998 	while (newidx != sc->sc_console_readidx) {
1999 		uint8_t ch = bus_space_read_1(sc->sc_tcm_iot, sc->sc_tcm_ioh,
2000 		    sc->sc_console_buf_addr + sc->sc_console_readidx);
2001 		sc->sc_console_readidx++;
2002 		if (sc->sc_console_readidx == sc->sc_console_buf_size)
2003 			sc->sc_console_readidx = 0;
2004 		if (ch == '\r')
2005 			continue;
2006 		DPRINTFN(3, ("%c", ch));
2007 	}
2008 }
2009 #endif
2010 
2011 int
2012 bwfm_pci_intr(void *v)
2013 {
2014 	struct bwfm_pci_softc *sc = (void *)v;
2015 	uint32_t status;
2016 
2017 	if ((status = bus_space_read_4(sc->sc_reg_iot, sc->sc_reg_ioh,
2018 	    BWFM_PCI_PCIE2REG_MAILBOXINT)) == 0)
2019 		return 0;
2020 
2021 	bwfm_pci_intr_disable(sc);
2022 	bus_space_write_4(sc->sc_reg_iot, sc->sc_reg_ioh,
2023 	    BWFM_PCI_PCIE2REG_MAILBOXINT, status);
2024 
2025 	if (status & (BWFM_PCI_PCIE2REG_MAILBOXMASK_INT_FN0_0 |
2026 	    BWFM_PCI_PCIE2REG_MAILBOXMASK_INT_FN0_1))
2027 		printf("%s: handle MB data\n", __func__);
2028 
2029 	if (status & BWFM_PCI_PCIE2REG_MAILBOXMASK_INT_D2H_DB) {
2030 		bwfm_pci_ring_rx(sc, &sc->sc_rx_complete);
2031 		bwfm_pci_ring_rx(sc, &sc->sc_tx_complete);
2032 		bwfm_pci_ring_rx(sc, &sc->sc_ctrl_complete);
2033 	}
2034 
2035 #ifdef BWFM_DEBUG
2036 	bwfm_pci_debug_console(sc);
2037 #endif
2038 
2039 	bwfm_pci_intr_enable(sc);
2040 	return 1;
2041 }
2042 
2043 void
2044 bwfm_pci_intr_enable(struct bwfm_pci_softc *sc)
2045 {
2046 	bus_space_write_4(sc->sc_reg_iot, sc->sc_reg_ioh,
2047 	    BWFM_PCI_PCIE2REG_MAILBOXMASK,
2048 	    BWFM_PCI_PCIE2REG_MAILBOXMASK_INT_FN0_0 |
2049 	    BWFM_PCI_PCIE2REG_MAILBOXMASK_INT_FN0_1 |
2050 	    BWFM_PCI_PCIE2REG_MAILBOXMASK_INT_D2H_DB);
2051 }
2052 
2053 void
2054 bwfm_pci_intr_disable(struct bwfm_pci_softc *sc)
2055 {
2056 	bus_space_write_4(sc->sc_reg_iot, sc->sc_reg_ioh,
2057 	    BWFM_PCI_PCIE2REG_MAILBOXMASK, 0);
2058 }
2059 
2060 /* Msgbuf protocol implementation */
2061 int
2062 bwfm_pci_msgbuf_query_dcmd(struct bwfm_softc *bwfm, int ifidx,
2063     int cmd, char *buf, size_t *len)
2064 {
2065 	struct bwfm_pci_softc *sc = (void *)bwfm;
2066 	struct msgbuf_ioctl_req_hdr *req;
2067 	struct mbuf *m;
2068 	size_t buflen;
2069 	int s;
2070 
2071 	s = splnet();
2072 	sc->sc_ioctl_resp_pktid = -1;
2073 	req = bwfm_pci_ring_write_reserve(sc, &sc->sc_ctrl_submit);
2074 	if (req == NULL) {
2075 		printf("%s: cannot reserve for write\n", DEVNAME(sc));
2076 		splx(s);
2077 		return 1;
2078 	}
2079 	req->msg.msgtype = MSGBUF_TYPE_IOCTLPTR_REQ;
2080 	req->msg.ifidx = 0;
2081 	req->msg.flags = 0;
2082 	req->msg.request_id = htole32(MSGBUF_IOCTL_REQ_PKTID);
2083 	req->cmd = htole32(cmd);
2084 	req->output_buf_len = htole16(*len);
2085 	req->trans_id = htole16(sc->sc_ioctl_reqid++);
2086 
2087 	buflen = uimin(*len, BWFM_DMA_H2D_IOCTL_BUF_LEN);
2088 	req->input_buf_len = htole16(buflen);
2089 	req->req_buf_addr.high_addr =
2090 	    htole32((uint64_t)BWFM_PCI_DMA_DVA(sc->sc_ioctl_buf) >> 32);
2091 	req->req_buf_addr.low_addr =
2092 	    htole32((uint64_t)BWFM_PCI_DMA_DVA(sc->sc_ioctl_buf) & 0xffffffff);
2093 	if (buf)
2094 		memcpy(BWFM_PCI_DMA_KVA(sc->sc_ioctl_buf), buf, buflen);
2095 	else
2096 		memset(BWFM_PCI_DMA_KVA(sc->sc_ioctl_buf), 0, buflen);
2097 
2098 	bwfm_pci_ring_write_commit(sc, &sc->sc_ctrl_submit);
2099 	splx(s);
2100 
2101 	if (tsleep(&sc->sc_ioctl_buf, PCATCH, "bwfm", hz)) {
2102 		printf("%s: timeout waiting for ioctl response\n",
2103 		    DEVNAME(sc));
2104 		return 1;
2105 	}
2106 
2107 	m = bwfm_pci_pktid_free(sc, &sc->sc_rx_pkts, sc->sc_ioctl_resp_pktid);
2108 	if (m == NULL)
2109 		return 1;
2110 
2111 	*len = uimin(buflen, sc->sc_ioctl_resp_ret_len);
2112 	if (buf)
2113 		memcpy(buf, mtod(m, char *), *len);
2114 	m_freem(m);
2115 	splx(s);
2116 
2117 	return 0;
2118 }
2119 
2120 int
2121 bwfm_pci_msgbuf_set_dcmd(struct bwfm_softc *bwfm, int ifidx,
2122     int cmd, char *buf, size_t len)
2123 {
2124 	return bwfm_pci_msgbuf_query_dcmd(bwfm, ifidx, cmd, buf, &len);
2125 }
2126