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