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