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