1 /* $OpenBSD: malo.c,v 1.121 2020/07/10 13:26:37 patrick Exp $ */ 2 3 /* 4 * Copyright (c) 2006 Claudio Jeker <claudio@openbsd.org> 5 * Copyright (c) 2006 Marcus Glocker <mglocker@openbsd.org> 6 * 7 * Permission to use, copy, modify, and 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 "bpfilter.h" 21 22 #include <sys/param.h> 23 24 #include <sys/device.h> 25 #include <sys/kernel.h> 26 #include <sys/malloc.h> 27 #include <sys/mbuf.h> 28 #include <sys/socket.h> 29 #include <sys/sockio.h> 30 #include <sys/systm.h> 31 #include <sys/endian.h> 32 33 #include <machine/bus.h> 34 #include <machine/intr.h> 35 36 #include <net/if.h> 37 #include <net/if_media.h> 38 39 #if NBPFILTER > 0 40 #include <net/bpf.h> 41 #endif 42 43 #include <netinet/in.h> 44 #include <netinet/if_ether.h> 45 46 #include <net80211/ieee80211_var.h> 47 #include <net80211/ieee80211_radiotap.h> 48 49 #include <dev/ic/malo.h> 50 51 #ifdef MALO_DEBUG 52 int malo_d = 1; 53 #define DPRINTF(l, x...) do { if ((l) <= malo_d) printf(x); } while (0) 54 #else 55 #define DPRINTF(l, x...) 56 #endif 57 58 /* internal structures and defines */ 59 struct malo_node { 60 struct ieee80211_node ni; 61 }; 62 63 struct malo_rx_data { 64 bus_dmamap_t map; 65 struct mbuf *m; 66 }; 67 68 struct malo_tx_data { 69 bus_dmamap_t map; 70 struct mbuf *m; 71 uint32_t softstat; 72 struct ieee80211_node *ni; 73 }; 74 75 /* RX descriptor used by HW */ 76 struct malo_rx_desc { 77 uint8_t rxctrl; 78 uint8_t rssi; 79 uint8_t status; 80 uint8_t channel; 81 uint16_t len; 82 uint8_t reserved1; /* actually unused */ 83 uint8_t datarate; 84 uint32_t physdata; /* DMA address of data */ 85 uint32_t physnext; /* DMA address of next control block */ 86 uint16_t qosctrl; 87 uint16_t reserved2; 88 } __packed; 89 90 /* TX descriptor used by HW */ 91 struct malo_tx_desc { 92 uint32_t status; 93 uint8_t datarate; 94 uint8_t txpriority; 95 uint16_t qosctrl; 96 uint32_t physdata; /* DMA address of data */ 97 uint16_t len; 98 uint8_t destaddr[6]; 99 uint32_t physnext; /* DMA address of next control block */ 100 uint32_t reserved1; /* SAP packet info ??? */ 101 uint32_t reserved2; 102 } __packed; 103 104 #define MALO_RX_RING_COUNT 256 105 #define MALO_TX_RING_COUNT 256 106 #define MALO_MAX_SCATTER 8 /* XXX unknown, wild guess */ 107 #define MALO_CMD_TIMEOUT 50 /* MALO_CMD_TIMEOUT * 100us */ 108 109 /* 110 * Firmware commands 111 */ 112 #define MALO_CMD_GET_HW_SPEC 0x0003 113 #define MALO_CMD_SET_RADIO 0x001c 114 #define MALO_CMD_SET_AID 0x010d 115 #define MALO_CMD_SET_TXPOWER 0x001e 116 #define MALO_CMD_SET_ANTENNA 0x0020 117 #define MALO_CMD_SET_PRESCAN 0x0107 118 #define MALO_CMD_SET_POSTSCAN 0x0108 119 #define MALO_CMD_SET_RATE 0x0110 120 #define MALO_CMD_SET_CHANNEL 0x010a 121 #define MALO_CMD_SET_RTS 0x0113 122 #define MALO_CMD_SET_SLOT 0x0114 123 #define MALO_CMD_RESPONSE 0x8000 124 125 #define MALO_CMD_RESULT_OK 0x0000 /* everything is fine */ 126 #define MALO_CMD_RESULT_ERROR 0x0001 /* general error */ 127 #define MALO_CMD_RESULT_NOSUPPORT 0x0002 /* command not valid */ 128 #define MALO_CMD_RESULT_PENDING 0x0003 /* will be processed */ 129 #define MALO_CMD_RESULT_BUSY 0x0004 /* command ignored */ 130 #define MALO_CMD_RESULT_PARTIALDATA 0x0005 /* buffer too small */ 131 132 struct malo_cmdheader { 133 uint16_t cmd; 134 uint16_t size; /* size of the command, incl. header */ 135 uint16_t seqnum; /* seems not to matter that much */ 136 uint16_t result; /* set to 0 on request */ 137 /* following the data payload, up to 256 bytes */ 138 }; 139 140 struct malo_hw_spec { 141 uint16_t HwVersion; 142 uint16_t NumOfWCB; 143 uint16_t NumOfMCastAdr; 144 uint8_t PermanentAddress[6]; 145 uint16_t RegionCode; 146 uint16_t NumberOfAntenna; 147 uint32_t FWReleaseNumber; 148 uint32_t WcbBase0; 149 uint32_t RxPdWrPtr; 150 uint32_t RxPdRdPtr; 151 uint32_t CookiePtr; 152 uint32_t WcbBase1; 153 uint32_t WcbBase2; 154 uint32_t WcbBase3; 155 } __packed; 156 157 struct malo_cmd_radio { 158 uint16_t action; 159 uint16_t preamble_mode; 160 uint16_t enable; 161 } __packed; 162 163 struct malo_cmd_aid { 164 uint16_t associd; 165 uint8_t macaddr[6]; 166 uint32_t gprotection; 167 uint8_t aprates[14]; 168 } __packed; 169 170 struct malo_cmd_txpower { 171 uint16_t action; 172 uint16_t supportpowerlvl; 173 uint16_t currentpowerlvl; 174 uint16_t reserved; 175 uint16_t powerlvllist[8]; 176 } __packed; 177 178 struct malo_cmd_antenna { 179 uint16_t action; 180 uint16_t mode; 181 } __packed; 182 183 struct malo_cmd_postscan { 184 uint32_t isibss; 185 uint8_t bssid[6]; 186 } __packed; 187 188 struct malo_cmd_channel { 189 uint16_t action; 190 uint8_t channel; 191 } __packed; 192 193 struct malo_cmd_rate { 194 uint8_t dataratetype; 195 uint8_t rateindex; 196 uint8_t aprates[14]; 197 } __packed; 198 199 struct malo_cmd_rts { 200 uint16_t action; 201 uint32_t threshold; 202 } __packed; 203 204 struct malo_cmd_slot { 205 uint16_t action; 206 uint8_t slot; 207 } __packed; 208 209 #define malo_mem_write4(sc, off, x) \ 210 bus_space_write_4((sc)->sc_mem1_bt, (sc)->sc_mem1_bh, (off), (x)) 211 #define malo_mem_write2(sc, off, x) \ 212 bus_space_write_2((sc)->sc_mem1_bt, (sc)->sc_mem1_bh, (off), (x)) 213 #define malo_mem_write1(sc, off, x) \ 214 bus_space_write_1((sc)->sc_mem1_bt, (sc)->sc_mem1_bh, (off), (x)) 215 216 #define malo_mem_read4(sc, off) \ 217 bus_space_read_4((sc)->sc_mem1_bt, (sc)->sc_mem1_bh, (off)) 218 #define malo_mem_read1(sc, off) \ 219 bus_space_read_1((sc)->sc_mem1_bt, (sc)->sc_mem1_bh, (off)) 220 221 #define malo_ctl_write4(sc, off, x) \ 222 bus_space_write_4((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, (off), (x)) 223 #define malo_ctl_read4(sc, off) \ 224 bus_space_read_4((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, (off)) 225 #define malo_ctl_read1(sc, off) \ 226 bus_space_read_1((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, (off)) 227 228 #define malo_ctl_barrier(sc, t) \ 229 bus_space_barrier((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, 0x0c00, 0xff, (t)) 230 231 struct cfdriver malo_cd = { 232 NULL, "malo", DV_IFNET 233 }; 234 235 int malo_alloc_cmd(struct malo_softc *sc); 236 void malo_free_cmd(struct malo_softc *sc); 237 void malo_send_cmd(struct malo_softc *sc, bus_addr_t addr); 238 int malo_send_cmd_dma(struct malo_softc *sc, bus_addr_t addr); 239 int malo_alloc_rx_ring(struct malo_softc *sc, struct malo_rx_ring *ring, 240 int count); 241 void malo_reset_rx_ring(struct malo_softc *sc, struct malo_rx_ring *ring); 242 void malo_free_rx_ring(struct malo_softc *sc, struct malo_rx_ring *ring); 243 int malo_alloc_tx_ring(struct malo_softc *sc, struct malo_tx_ring *ring, 244 int count); 245 void malo_reset_tx_ring(struct malo_softc *sc, struct malo_tx_ring *ring); 246 void malo_free_tx_ring(struct malo_softc *sc, struct malo_tx_ring *ring); 247 int malo_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data); 248 void malo_start(struct ifnet *ifp); 249 void malo_watchdog(struct ifnet *ifp); 250 int malo_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, 251 int arg); 252 void malo_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni, 253 int isnew); 254 struct ieee80211_node * 255 malo_node_alloc(struct ieee80211com *ic); 256 int malo_media_change(struct ifnet *ifp); 257 void malo_media_status(struct ifnet *ifp, struct ifmediareq *imr); 258 int malo_chip2rate(int chip_rate); 259 int malo_fix2rate(int fix_rate); 260 void malo_next_scan(void *arg); 261 void malo_tx_intr(struct malo_softc *sc); 262 int malo_tx_mgt(struct malo_softc *sc, struct mbuf *m0, 263 struct ieee80211_node *ni); 264 int malo_tx_data(struct malo_softc *sc, struct mbuf *m0, 265 struct ieee80211_node *ni); 266 void malo_tx_setup_desc(struct malo_softc *sc, struct malo_tx_desc *desc, 267 int len, int rate, const bus_dma_segment_t *segs, int nsegs); 268 void malo_rx_intr(struct malo_softc *sc); 269 int malo_load_bootimg(struct malo_softc *sc); 270 int malo_load_firmware(struct malo_softc *sc); 271 272 int malo_set_slot(struct malo_softc *sc); 273 void malo_update_slot(struct ieee80211com *ic); 274 #ifdef MALO_DEBUG 275 void malo_hexdump(void *buf, int len); 276 #endif 277 static char * 278 malo_cmd_string(uint16_t cmd); 279 static char * 280 malo_cmd_string_result(uint16_t result); 281 int malo_cmd_get_spec(struct malo_softc *sc); 282 int malo_cmd_set_prescan(struct malo_softc *sc); 283 int malo_cmd_set_postscan(struct malo_softc *sc, uint8_t *macaddr, 284 uint8_t ibsson); 285 int malo_cmd_set_channel(struct malo_softc *sc, uint8_t channel); 286 int malo_cmd_set_antenna(struct malo_softc *sc, uint16_t antenna_type); 287 int malo_cmd_set_radio(struct malo_softc *sc, uint16_t mode, 288 uint16_t preamble); 289 int malo_cmd_set_aid(struct malo_softc *sc, uint8_t *bssid, 290 uint16_t associd); 291 int malo_cmd_set_txpower(struct malo_softc *sc, unsigned int powerlevel); 292 int malo_cmd_set_rts(struct malo_softc *sc, uint32_t threshold); 293 int malo_cmd_set_slot(struct malo_softc *sc, uint8_t slot); 294 int malo_cmd_set_rate(struct malo_softc *sc, uint8_t rate); 295 void malo_cmd_response(struct malo_softc *sc); 296 297 int 298 malo_intr(void *arg) 299 { 300 struct malo_softc *sc = arg; 301 uint32_t status; 302 303 status = malo_ctl_read4(sc, 0x0c30); 304 if (status == 0xffffffff || status == 0) 305 /* not for us */ 306 return (0); 307 308 if (status & 0x1) 309 malo_tx_intr(sc); 310 if (status & 0x2) 311 malo_rx_intr(sc); 312 if (status & 0x4) { 313 /* XXX cmd done interrupt handling doesn't work yet */ 314 DPRINTF(1, "%s: got cmd done interrupt\n", sc->sc_dev.dv_xname); 315 //malo_cmd_response(sc); 316 } 317 318 if (status & ~0x7) 319 DPRINTF(1, "%s: unknown interrupt %x\n", 320 sc->sc_dev.dv_xname, status); 321 322 /* just ack the interrupt */ 323 malo_ctl_write4(sc, 0x0c30, 0); 324 325 return (1); 326 } 327 328 int 329 malo_attach(struct malo_softc *sc) 330 { 331 struct ieee80211com *ic = &sc->sc_ic; 332 struct ifnet *ifp = &sc->sc_ic.ic_if; 333 int i; 334 335 /* initialize channel scanning timer */ 336 timeout_set(&sc->sc_scan_to, malo_next_scan, sc); 337 338 /* allocate DMA structures */ 339 malo_alloc_cmd(sc); 340 malo_alloc_rx_ring(sc, &sc->sc_rxring, MALO_RX_RING_COUNT); 341 malo_alloc_tx_ring(sc, &sc->sc_txring, MALO_TX_RING_COUNT); 342 343 /* setup interface */ 344 ifp->if_softc = sc; 345 ifp->if_ioctl = malo_ioctl; 346 ifp->if_start = malo_start; 347 ifp->if_watchdog = malo_watchdog; 348 ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST; 349 strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ); 350 ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN); 351 352 /* set supported rates */ 353 ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b; 354 ic->ic_sup_rates[IEEE80211_MODE_11G] = ieee80211_std_rateset_11g; 355 sc->sc_last_txrate = -1; 356 357 /* set channels */ 358 for (i = 1; i <= 14; i++) { 359 ic->ic_channels[i].ic_freq = 360 ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ); 361 ic->ic_channels[i].ic_flags = 362 IEEE80211_CHAN_PUREG | 363 IEEE80211_CHAN_B | 364 IEEE80211_CHAN_G; 365 } 366 367 /* set the rest */ 368 ic->ic_caps = 369 IEEE80211_C_IBSS | 370 IEEE80211_C_MONITOR | 371 IEEE80211_C_SHPREAMBLE | 372 IEEE80211_C_SHSLOT | 373 IEEE80211_C_WEP | 374 IEEE80211_C_RSN; 375 ic->ic_opmode = IEEE80211_M_STA; 376 ic->ic_state = IEEE80211_S_INIT; 377 ic->ic_max_rssi = 75; 378 for (i = 0; i < 6; i++) 379 ic->ic_myaddr[i] = malo_ctl_read1(sc, 0xa528 + i); 380 381 /* show our mac address */ 382 printf(", address %s\n", ether_sprintf(ic->ic_myaddr)); 383 384 /* attach interface */ 385 if_attach(ifp); 386 ieee80211_ifattach(ifp); 387 388 /* post attach vector functions */ 389 sc->sc_newstate = ic->ic_newstate; 390 ic->ic_newstate = malo_newstate; 391 ic->ic_newassoc = malo_newassoc; 392 ic->ic_node_alloc = malo_node_alloc; 393 ic->ic_updateslot = malo_update_slot; 394 395 ieee80211_media_init(ifp, malo_media_change, malo_media_status); 396 397 #if NBPFILTER > 0 398 bpfattach(&sc->sc_drvbpf, ifp, DLT_IEEE802_11_RADIO, 399 sizeof(struct ieee80211_frame) + 64); 400 401 sc->sc_rxtap_len = sizeof(sc->sc_rxtapu); 402 sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); 403 sc->sc_rxtap.wr_ihdr.it_present = htole32(MALO_RX_RADIOTAP_PRESENT); 404 405 sc->sc_txtap_len = sizeof(sc->sc_txtapu); 406 sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); 407 sc->sc_txtap.wt_ihdr.it_present = htole32(MALO_TX_RADIOTAP_PRESENT); 408 #endif 409 410 return (0); 411 } 412 413 int 414 malo_detach(void *arg) 415 { 416 struct malo_softc *sc = arg; 417 struct ieee80211com *ic = &sc->sc_ic; 418 struct ifnet *ifp = &ic->ic_if; 419 420 /* remove channel scanning timer */ 421 timeout_del(&sc->sc_scan_to); 422 423 malo_stop(sc); 424 ieee80211_ifdetach(ifp); 425 if_detach(ifp); 426 malo_free_cmd(sc); 427 malo_free_rx_ring(sc, &sc->sc_rxring); 428 malo_free_tx_ring(sc, &sc->sc_txring); 429 430 return (0); 431 } 432 433 int 434 malo_alloc_cmd(struct malo_softc *sc) 435 { 436 int error, nsegs; 437 438 error = bus_dmamap_create(sc->sc_dmat, PAGE_SIZE, 1, 439 PAGE_SIZE, 0, BUS_DMA_ALLOCNOW, &sc->sc_cmd_dmam); 440 if (error != 0) { 441 printf("%s: can not create DMA tag\n", sc->sc_dev.dv_xname); 442 return (-1); 443 } 444 445 error = bus_dmamem_alloc(sc->sc_dmat, PAGE_SIZE, PAGE_SIZE, 446 0, &sc->sc_cmd_dmas, 1, &nsegs, BUS_DMA_WAITOK); 447 if (error != 0) { 448 printf("%s: error alloc dma memory\n", sc->sc_dev.dv_xname); 449 return (-1); 450 } 451 452 error = bus_dmamem_map(sc->sc_dmat, &sc->sc_cmd_dmas, nsegs, 453 PAGE_SIZE, (caddr_t *)&sc->sc_cmd_mem, BUS_DMA_WAITOK); 454 if (error != 0) { 455 printf("%s: error map dma memory\n", sc->sc_dev.dv_xname); 456 return (-1); 457 } 458 459 error = bus_dmamap_load(sc->sc_dmat, sc->sc_cmd_dmam, 460 sc->sc_cmd_mem, PAGE_SIZE, NULL, BUS_DMA_NOWAIT); 461 if (error != 0) { 462 printf("%s: error load dma memory\n", sc->sc_dev.dv_xname); 463 bus_dmamem_free(sc->sc_dmat, &sc->sc_cmd_dmas, nsegs); 464 return (-1); 465 } 466 467 sc->sc_cookie = sc->sc_cmd_mem; 468 *sc->sc_cookie = htole32(0xaa55aa55); 469 sc->sc_cmd_mem = (caddr_t)sc->sc_cmd_mem + sizeof(uint32_t); 470 sc->sc_cookie_dmaaddr = sc->sc_cmd_dmam->dm_segs[0].ds_addr; 471 sc->sc_cmd_dmaaddr = sc->sc_cmd_dmam->dm_segs[0].ds_addr + 472 sizeof(uint32_t); 473 474 return (0); 475 } 476 477 void 478 malo_free_cmd(struct malo_softc *sc) 479 { 480 bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE, 481 BUS_DMASYNC_POSTWRITE); 482 bus_dmamap_unload(sc->sc_dmat, sc->sc_cmd_dmam); 483 bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_cookie, PAGE_SIZE); 484 bus_dmamem_free(sc->sc_dmat, &sc->sc_cmd_dmas, 1); 485 } 486 487 void 488 malo_send_cmd(struct malo_softc *sc, bus_addr_t addr) 489 { 490 malo_ctl_write4(sc, 0x0c10, (uint32_t)addr); 491 malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE); 492 malo_ctl_write4(sc, 0x0c18, 2); /* CPU_TRANSFER_CMD */ 493 malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE); 494 } 495 496 int 497 malo_send_cmd_dma(struct malo_softc *sc, bus_addr_t addr) 498 { 499 int i; 500 struct malo_cmdheader *hdr = sc->sc_cmd_mem; 501 502 malo_ctl_write4(sc, 0x0c10, (uint32_t)addr); 503 malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE); 504 malo_ctl_write4(sc, 0x0c18, 2); /* CPU_TRANSFER_CMD */ 505 malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE); 506 507 for (i = 0; i < MALO_CMD_TIMEOUT; i++) { 508 delay(100); 509 bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE, 510 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 511 if (hdr->cmd & htole16(0x8000)) 512 break; 513 } 514 if (i == MALO_CMD_TIMEOUT) { 515 printf("%s: timeout while waiting for cmd response!\n", 516 sc->sc_dev.dv_xname); 517 return (ETIMEDOUT); 518 } 519 520 malo_cmd_response(sc); 521 522 return (0); 523 } 524 525 int 526 malo_alloc_rx_ring(struct malo_softc *sc, struct malo_rx_ring *ring, int count) 527 { 528 struct malo_rx_desc *desc; 529 struct malo_rx_data *data; 530 int i, nsegs, error; 531 532 ring->count = count; 533 ring->cur = ring->next = 0; 534 535 error = bus_dmamap_create(sc->sc_dmat, 536 count * sizeof(struct malo_rx_desc), 1, 537 count * sizeof(struct malo_rx_desc), 0, 538 BUS_DMA_NOWAIT, &ring->map); 539 if (error != 0) { 540 printf("%s: could not create desc DMA map\n", 541 sc->sc_dev.dv_xname); 542 goto fail; 543 } 544 545 error = bus_dmamem_alloc(sc->sc_dmat, 546 count * sizeof(struct malo_rx_desc), 547 PAGE_SIZE, 0, &ring->seg, 1, &nsegs, 548 BUS_DMA_NOWAIT | BUS_DMA_ZERO); 549 if (error != 0) { 550 printf("%s: could not allocate DMA memory\n", 551 sc->sc_dev.dv_xname); 552 goto fail; 553 } 554 555 error = bus_dmamem_map(sc->sc_dmat, &ring->seg, nsegs, 556 count * sizeof(struct malo_rx_desc), (caddr_t *)&ring->desc, 557 BUS_DMA_NOWAIT); 558 if (error != 0) { 559 printf("%s: can't map desc DMA memory\n", 560 sc->sc_dev.dv_xname); 561 goto fail; 562 } 563 564 error = bus_dmamap_load(sc->sc_dmat, ring->map, ring->desc, 565 count * sizeof(struct malo_rx_desc), NULL, BUS_DMA_NOWAIT); 566 if (error != 0) { 567 printf("%s: could not load desc DMA map\n", 568 sc->sc_dev.dv_xname); 569 goto fail; 570 } 571 572 ring->physaddr = ring->map->dm_segs->ds_addr; 573 574 ring->data = mallocarray(count, sizeof (struct malo_rx_data), 575 M_DEVBUF, M_NOWAIT); 576 if (ring->data == NULL) { 577 printf("%s: could not allocate soft data\n", 578 sc->sc_dev.dv_xname); 579 error = ENOMEM; 580 goto fail; 581 } 582 583 /* 584 * Pre-allocate Rx buffers and populate Rx ring. 585 */ 586 bzero(ring->data, count * sizeof (struct malo_rx_data)); 587 for (i = 0; i < count; i++) { 588 desc = &ring->desc[i]; 589 data = &ring->data[i]; 590 591 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 592 0, BUS_DMA_NOWAIT, &data->map); 593 if (error != 0) { 594 printf("%s: could not create DMA map\n", 595 sc->sc_dev.dv_xname); 596 goto fail; 597 } 598 599 MGETHDR(data->m, M_DONTWAIT, MT_DATA); 600 if (data->m == NULL) { 601 printf("%s: could not allocate rx mbuf\n", 602 sc->sc_dev.dv_xname); 603 error = ENOMEM; 604 goto fail; 605 } 606 607 MCLGET(data->m, M_DONTWAIT); 608 if (!(data->m->m_flags & M_EXT)) { 609 printf("%s: could not allocate rx mbuf cluster\n", 610 sc->sc_dev.dv_xname); 611 error = ENOMEM; 612 goto fail; 613 } 614 615 error = bus_dmamap_load(sc->sc_dmat, data->map, 616 mtod(data->m, void *), MCLBYTES, NULL, BUS_DMA_NOWAIT); 617 if (error != 0) { 618 printf("%s: could not load rx buf DMA map", 619 sc->sc_dev.dv_xname); 620 goto fail; 621 } 622 623 desc->status = 1; 624 desc->physdata = htole32(data->map->dm_segs->ds_addr); 625 desc->physnext = htole32(ring->physaddr + 626 (i + 1) % count * sizeof(struct malo_rx_desc)); 627 } 628 629 bus_dmamap_sync(sc->sc_dmat, ring->map, 0, ring->map->dm_mapsize, 630 BUS_DMASYNC_PREWRITE); 631 632 return (0); 633 634 fail: malo_free_rx_ring(sc, ring); 635 return (error); 636 } 637 638 void 639 malo_reset_rx_ring(struct malo_softc *sc, struct malo_rx_ring *ring) 640 { 641 int i; 642 643 for (i = 0; i < ring->count; i++) 644 ring->desc[i].status = 0; 645 646 bus_dmamap_sync(sc->sc_dmat, ring->map, 0, ring->map->dm_mapsize, 647 BUS_DMASYNC_PREWRITE); 648 649 ring->cur = ring->next = 0; 650 } 651 652 void 653 malo_free_rx_ring(struct malo_softc *sc, struct malo_rx_ring *ring) 654 { 655 struct malo_rx_data *data; 656 int i; 657 658 if (ring->desc != NULL) { 659 bus_dmamap_sync(sc->sc_dmat, ring->map, 0, 660 ring->map->dm_mapsize, BUS_DMASYNC_POSTWRITE); 661 bus_dmamap_unload(sc->sc_dmat, ring->map); 662 bus_dmamem_unmap(sc->sc_dmat, (caddr_t)ring->desc, 663 ring->count * sizeof(struct malo_rx_desc)); 664 bus_dmamem_free(sc->sc_dmat, &ring->seg, 1); 665 } 666 667 if (ring->data != NULL) { 668 for (i = 0; i < ring->count; i++) { 669 data = &ring->data[i]; 670 671 if (data->m != NULL) { 672 bus_dmamap_sync(sc->sc_dmat, data->map, 0, 673 data->map->dm_mapsize, 674 BUS_DMASYNC_POSTREAD); 675 bus_dmamap_unload(sc->sc_dmat, data->map); 676 m_freem(data->m); 677 } 678 679 if (data->map != NULL) 680 bus_dmamap_destroy(sc->sc_dmat, data->map); 681 } 682 free(ring->data, M_DEVBUF, 0); 683 } 684 } 685 686 int 687 malo_alloc_tx_ring(struct malo_softc *sc, struct malo_tx_ring *ring, 688 int count) 689 { 690 int i, nsegs, error; 691 692 ring->count = count; 693 ring->queued = 0; 694 ring->cur = ring->next = ring->stat = 0; 695 696 error = bus_dmamap_create(sc->sc_dmat, 697 count * sizeof(struct malo_tx_desc), 1, 698 count * sizeof(struct malo_tx_desc), 0, BUS_DMA_NOWAIT, &ring->map); 699 if (error != 0) { 700 printf("%s: could not create desc DMA map\n", 701 sc->sc_dev.dv_xname); 702 goto fail; 703 } 704 705 error = bus_dmamem_alloc(sc->sc_dmat, 706 count * sizeof(struct malo_tx_desc), PAGE_SIZE, 0, 707 &ring->seg, 1, &nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO); 708 if (error != 0) { 709 printf("%s: could not allocate DMA memory\n", 710 sc->sc_dev.dv_xname); 711 goto fail; 712 } 713 714 error = bus_dmamem_map(sc->sc_dmat, &ring->seg, nsegs, 715 count * sizeof(struct malo_tx_desc), (caddr_t *)&ring->desc, 716 BUS_DMA_NOWAIT); 717 if (error != 0) { 718 printf("%s: can't map desc DMA memory\n", 719 sc->sc_dev.dv_xname); 720 goto fail; 721 } 722 723 error = bus_dmamap_load(sc->sc_dmat, ring->map, ring->desc, 724 count * sizeof(struct malo_tx_desc), NULL, BUS_DMA_NOWAIT); 725 if (error != 0) { 726 printf("%s: could not load desc DMA map\n", 727 sc->sc_dev.dv_xname); 728 goto fail; 729 } 730 731 ring->physaddr = ring->map->dm_segs->ds_addr; 732 733 ring->data = mallocarray(count, sizeof(struct malo_tx_data), 734 M_DEVBUF, M_NOWAIT); 735 if (ring->data == NULL) { 736 printf("%s: could not allocate soft data\n", 737 sc->sc_dev.dv_xname); 738 error = ENOMEM; 739 goto fail; 740 } 741 742 memset(ring->data, 0, count * sizeof(struct malo_tx_data)); 743 for (i = 0; i < count; i++) { 744 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 745 MALO_MAX_SCATTER, MCLBYTES, 0, BUS_DMA_NOWAIT, 746 &ring->data[i].map); 747 if (error != 0) { 748 printf("%s: could not create DMA map\n", 749 sc->sc_dev.dv_xname); 750 goto fail; 751 } 752 ring->desc[i].physnext = htole32(ring->physaddr + 753 (i + 1) % count * sizeof(struct malo_tx_desc)); 754 } 755 756 return (0); 757 758 fail: malo_free_tx_ring(sc, ring); 759 return (error); 760 } 761 762 void 763 malo_reset_tx_ring(struct malo_softc *sc, struct malo_tx_ring *ring) 764 { 765 struct malo_tx_desc *desc; 766 struct malo_tx_data *data; 767 int i; 768 769 for (i = 0; i < ring->count; i++) { 770 desc = &ring->desc[i]; 771 data = &ring->data[i]; 772 773 if (data->m != NULL) { 774 bus_dmamap_sync(sc->sc_dmat, data->map, 0, 775 data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE); 776 bus_dmamap_unload(sc->sc_dmat, data->map); 777 m_freem(data->m); 778 data->m = NULL; 779 } 780 781 /* 782 * The node has already been freed at that point so don't call 783 * ieee80211_release_node() here. 784 */ 785 data->ni = NULL; 786 787 desc->status = 0; 788 } 789 790 bus_dmamap_sync(sc->sc_dmat, ring->map, 0, ring->map->dm_mapsize, 791 BUS_DMASYNC_PREWRITE); 792 793 ring->queued = 0; 794 ring->cur = ring->next = ring->stat = 0; 795 } 796 797 void 798 malo_free_tx_ring(struct malo_softc *sc, struct malo_tx_ring *ring) 799 { 800 struct malo_tx_data *data; 801 int i; 802 803 if (ring->desc != NULL) { 804 bus_dmamap_sync(sc->sc_dmat, ring->map, 0, 805 ring->map->dm_mapsize, BUS_DMASYNC_POSTWRITE); 806 bus_dmamap_unload(sc->sc_dmat, ring->map); 807 bus_dmamem_unmap(sc->sc_dmat, (caddr_t)ring->desc, 808 ring->count * sizeof(struct malo_tx_desc)); 809 bus_dmamem_free(sc->sc_dmat, &ring->seg, 1); 810 } 811 812 if (ring->data != NULL) { 813 for (i = 0; i < ring->count; i++) { 814 data = &ring->data[i]; 815 816 if (data->m != NULL) { 817 bus_dmamap_sync(sc->sc_dmat, data->map, 0, 818 data->map->dm_mapsize, 819 BUS_DMASYNC_POSTWRITE); 820 bus_dmamap_unload(sc->sc_dmat, data->map); 821 m_freem(data->m); 822 } 823 824 /* 825 * The node has already been freed at that point so 826 * don't call ieee80211_release_node() here. 827 */ 828 data->ni = NULL; 829 830 if (data->map != NULL) 831 bus_dmamap_destroy(sc->sc_dmat, data->map); 832 } 833 free(ring->data, M_DEVBUF, 0); 834 } 835 } 836 837 int 838 malo_init(struct ifnet *ifp) 839 { 840 struct malo_softc *sc = ifp->if_softc; 841 struct ieee80211com *ic = &sc->sc_ic; 842 uint8_t chan; 843 int error; 844 845 DPRINTF(1, "%s: %s\n", ifp->if_xname, __func__); 846 847 /* if interface already runs stop it first */ 848 if (ifp->if_flags & IFF_RUNNING) 849 malo_stop(sc); 850 851 /* power on cardbus socket */ 852 if (sc->sc_enable) 853 sc->sc_enable(sc); 854 855 /* disable interrupts */ 856 malo_ctl_read4(sc, 0x0c30); 857 malo_ctl_write4(sc, 0x0c30, 0); 858 malo_ctl_write4(sc, 0x0c34, 0); 859 malo_ctl_write4(sc, 0x0c3c, 0); 860 861 /* load firmware */ 862 if ((error = malo_load_bootimg(sc))) 863 goto fail; 864 if ((error = malo_load_firmware(sc))) 865 goto fail; 866 867 /* enable interrupts */ 868 malo_ctl_write4(sc, 0x0c34, 0x1f); 869 malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE); 870 malo_ctl_write4(sc, 0x0c3c, 0x1f); 871 malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE); 872 873 if ((error = malo_cmd_get_spec(sc))) 874 goto fail; 875 876 /* select default channel */ 877 ic->ic_bss->ni_chan = ic->ic_ibss_chan; 878 chan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan); 879 880 /* initialize hardware */ 881 if ((error = malo_cmd_set_channel(sc, chan))) { 882 printf("%s: setting channel failed!\n", 883 sc->sc_dev.dv_xname); 884 goto fail; 885 } 886 if ((error = malo_cmd_set_antenna(sc, 1))) { 887 printf("%s: setting RX antenna failed!\n", 888 sc->sc_dev.dv_xname); 889 goto fail; 890 } 891 if ((error = malo_cmd_set_antenna(sc, 2))) { 892 printf("%s: setting TX antenna failed!\n", 893 sc->sc_dev.dv_xname); 894 goto fail; 895 } 896 if ((error = malo_cmd_set_radio(sc, 1, 5))) { 897 printf("%s: turn radio on failed!\n", 898 sc->sc_dev.dv_xname); 899 goto fail; 900 } 901 if ((error = malo_cmd_set_txpower(sc, 100))) { 902 printf("%s: setting TX power failed!\n", 903 sc->sc_dev.dv_xname); 904 goto fail; 905 } 906 if ((error = malo_cmd_set_rts(sc, IEEE80211_RTS_MAX))) { 907 printf("%s: setting RTS failed!\n", 908 sc->sc_dev.dv_xname); 909 goto fail; 910 } 911 912 ifp->if_flags |= IFF_RUNNING; 913 914 if (ic->ic_opmode != IEEE80211_M_MONITOR) 915 /* start background scanning */ 916 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 917 else 918 /* in monitor mode change directly into run state */ 919 ieee80211_new_state(ic, IEEE80211_S_RUN, -1); 920 921 return (0); 922 923 fail: 924 /* reset adapter */ 925 DPRINTF(1, "%s: malo_init failed, resetting card\n", 926 sc->sc_dev.dv_xname); 927 malo_stop(sc); 928 return (error); 929 } 930 931 int 932 malo_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 933 { 934 struct malo_softc *sc = ifp->if_softc; 935 struct ieee80211com *ic = &sc->sc_ic; 936 int s, error = 0; 937 uint8_t chan; 938 939 s = splnet(); 940 941 switch (cmd) { 942 case SIOCSIFADDR: 943 ifp->if_flags |= IFF_UP; 944 /* FALLTHROUGH */ 945 case SIOCSIFFLAGS: 946 if (ifp->if_flags & IFF_UP) { 947 if ((ifp->if_flags & IFF_RUNNING) == 0) 948 malo_init(ifp); 949 } else { 950 if (ifp->if_flags & IFF_RUNNING) 951 malo_stop(sc); 952 } 953 break; 954 case SIOCS80211CHANNEL: 955 /* allow fast channel switching in monitor mode */ 956 error = ieee80211_ioctl(ifp, cmd, data); 957 if (error == ENETRESET && 958 ic->ic_opmode == IEEE80211_M_MONITOR) { 959 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == 960 (IFF_UP | IFF_RUNNING)) { 961 ic->ic_bss->ni_chan = ic->ic_ibss_chan; 962 chan = ieee80211_chan2ieee(ic, 963 ic->ic_bss->ni_chan); 964 malo_cmd_set_channel(sc, chan); 965 } 966 error = 0; 967 } 968 break; 969 default: 970 error = ieee80211_ioctl(ifp, cmd, data); 971 break; 972 } 973 974 if (error == ENETRESET) { 975 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == 976 (IFF_UP | IFF_RUNNING)) 977 malo_init(ifp); 978 error = 0; 979 } 980 981 splx(s); 982 983 return (error); 984 } 985 986 void 987 malo_start(struct ifnet *ifp) 988 { 989 struct malo_softc *sc = ifp->if_softc; 990 struct ieee80211com *ic = &sc->sc_ic; 991 struct mbuf *m0; 992 struct ieee80211_node *ni; 993 994 DPRINTF(2, "%s: %s\n", sc->sc_dev.dv_xname, __func__); 995 996 if (!(ifp->if_flags & IFF_RUNNING) || ifq_is_oactive(&ifp->if_snd)) 997 return; 998 999 for (;;) { 1000 if (sc->sc_txring.queued >= MALO_TX_RING_COUNT - 1) { 1001 ifq_set_oactive(&ifp->if_snd); 1002 break; 1003 } 1004 1005 m0 = mq_dequeue(&ic->ic_mgtq); 1006 if (m0 != NULL) { 1007 ni = m0->m_pkthdr.ph_cookie; 1008 #if NBPFILTER > 0 1009 if (ic->ic_rawbpf != NULL) 1010 bpf_mtap(ic->ic_rawbpf, m0, BPF_DIRECTION_OUT); 1011 #endif 1012 if (malo_tx_mgt(sc, m0, ni) != 0) 1013 break; 1014 } else { 1015 if (ic->ic_state != IEEE80211_S_RUN) 1016 break; 1017 1018 m0 = ifq_dequeue(&ifp->if_snd); 1019 if (m0 == NULL) 1020 break; 1021 #if NBPFILTER > 0 1022 if (ifp->if_bpf != NULL) 1023 bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT); 1024 #endif 1025 m0 = ieee80211_encap(ifp, m0, &ni); 1026 if (m0 == NULL) 1027 continue; 1028 #if NBPFILTER > 0 1029 if (ic->ic_rawbpf != NULL) 1030 bpf_mtap(ic->ic_rawbpf, m0, BPF_DIRECTION_OUT); 1031 #endif 1032 if (malo_tx_data(sc, m0, ni) != 0) { 1033 if (ni != NULL) 1034 ieee80211_release_node(ic, ni); 1035 ifp->if_oerrors++; 1036 break; 1037 } 1038 } 1039 } 1040 } 1041 1042 void 1043 malo_stop(struct malo_softc *sc) 1044 { 1045 struct ieee80211com *ic = &sc->sc_ic; 1046 struct ifnet *ifp = &ic->ic_if; 1047 1048 DPRINTF(1, "%s: %s\n", ifp->if_xname, __func__); 1049 1050 /* reset adapter */ 1051 if (ifp->if_flags & IFF_RUNNING) 1052 malo_ctl_write4(sc, 0x0c18, (1 << 15)); 1053 1054 /* device is not running anymore */ 1055 ifp->if_flags &= ~IFF_RUNNING; 1056 ifq_clr_oactive(&ifp->if_snd); 1057 1058 /* change back to initial state */ 1059 ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 1060 1061 /* reset RX / TX rings */ 1062 malo_reset_tx_ring(sc, &sc->sc_txring); 1063 malo_reset_rx_ring(sc, &sc->sc_rxring); 1064 1065 /* set initial rate */ 1066 sc->sc_last_txrate = -1; 1067 1068 /* power off cardbus socket */ 1069 if (sc->sc_disable) 1070 sc->sc_disable(sc); 1071 } 1072 1073 void 1074 malo_watchdog(struct ifnet *ifp) 1075 { 1076 1077 } 1078 1079 int 1080 malo_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) 1081 { 1082 struct malo_softc *sc = ic->ic_if.if_softc; 1083 enum ieee80211_state ostate; 1084 uint8_t chan; 1085 int rate; 1086 1087 DPRINTF(2, "%s: %s\n", sc->sc_dev.dv_xname, __func__); 1088 1089 ostate = ic->ic_state; 1090 timeout_del(&sc->sc_scan_to); 1091 1092 switch (nstate) { 1093 case IEEE80211_S_INIT: 1094 break; 1095 case IEEE80211_S_SCAN: 1096 if (ostate == IEEE80211_S_INIT) { 1097 if (malo_cmd_set_prescan(sc) != 0) 1098 DPRINTF(1, "%s: can't set prescan\n", 1099 sc->sc_dev.dv_xname); 1100 } else { 1101 chan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan); 1102 1103 malo_cmd_set_channel(sc, chan); 1104 } 1105 timeout_add_msec(&sc->sc_scan_to, 500); 1106 break; 1107 case IEEE80211_S_AUTH: 1108 DPRINTF(1, "%s: newstate AUTH\n", sc->sc_dev.dv_xname); 1109 malo_cmd_set_postscan(sc, ic->ic_myaddr, 1); 1110 chan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan); 1111 malo_cmd_set_channel(sc, chan); 1112 break; 1113 case IEEE80211_S_ASSOC: 1114 DPRINTF(1, "%s: newstate ASSOC\n", sc->sc_dev.dv_xname); 1115 if (ic->ic_flags & IEEE80211_F_SHPREAMBLE) 1116 malo_cmd_set_radio(sc, 1, 3); /* short preamble */ 1117 else 1118 malo_cmd_set_radio(sc, 1, 1); /* long preamble */ 1119 1120 malo_cmd_set_aid(sc, ic->ic_bss->ni_bssid, 1121 ic->ic_bss->ni_associd); 1122 1123 if (ic->ic_fixed_rate == -1) 1124 /* automatic rate adaption */ 1125 malo_cmd_set_rate(sc, 0); 1126 else { 1127 /* fixed rate */ 1128 rate = malo_fix2rate(ic->ic_fixed_rate); 1129 malo_cmd_set_rate(sc, rate); 1130 } 1131 1132 malo_set_slot(sc); 1133 break; 1134 case IEEE80211_S_RUN: 1135 DPRINTF(1, "%s: newstate RUN\n", sc->sc_dev.dv_xname); 1136 break; 1137 default: 1138 break; 1139 } 1140 1141 return (sc->sc_newstate(ic, nstate, arg)); 1142 } 1143 1144 void 1145 malo_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni, int isnew) 1146 { 1147 1148 } 1149 1150 struct ieee80211_node * 1151 malo_node_alloc(struct ieee80211com *ic) 1152 { 1153 struct malo_node *wn; 1154 1155 wn = malloc(sizeof(*wn), M_DEVBUF, M_NOWAIT | M_ZERO); 1156 if (wn == NULL) 1157 return (NULL); 1158 1159 return ((struct ieee80211_node *)wn); 1160 } 1161 1162 int 1163 malo_media_change(struct ifnet *ifp) 1164 { 1165 int error; 1166 1167 DPRINTF(1, "%s: %s\n", ifp->if_xname, __func__); 1168 1169 error = ieee80211_media_change(ifp); 1170 if (error != ENETRESET) 1171 return (error); 1172 1173 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING)) 1174 malo_init(ifp); 1175 1176 return (0); 1177 } 1178 1179 void 1180 malo_media_status(struct ifnet *ifp, struct ifmediareq *imr) 1181 { 1182 struct malo_softc *sc = ifp->if_softc; 1183 struct ieee80211com *ic = &sc->sc_ic; 1184 1185 imr->ifm_status = IFM_AVALID; 1186 imr->ifm_active = IFM_IEEE80211; 1187 if (ic->ic_state == IEEE80211_S_RUN) 1188 imr->ifm_status |= IFM_ACTIVE; 1189 1190 /* report last TX rate used by chip */ 1191 imr->ifm_active |= ieee80211_rate2media(ic, sc->sc_last_txrate, 1192 ic->ic_curmode); 1193 1194 switch (ic->ic_opmode) { 1195 case IEEE80211_M_STA: 1196 break; 1197 #ifndef IEEE80211_STA_ONLY 1198 case IEEE80211_M_IBSS: 1199 imr->ifm_active |= IFM_IEEE80211_ADHOC; 1200 break; 1201 case IEEE80211_M_AHDEMO: 1202 break; 1203 case IEEE80211_M_HOSTAP: 1204 break; 1205 #endif 1206 case IEEE80211_M_MONITOR: 1207 imr->ifm_active |= IFM_IEEE80211_MONITOR; 1208 break; 1209 default: 1210 break; 1211 } 1212 1213 switch (ic->ic_curmode) { 1214 case IEEE80211_MODE_11B: 1215 imr->ifm_active |= IFM_IEEE80211_11B; 1216 break; 1217 case IEEE80211_MODE_11G: 1218 imr->ifm_active |= IFM_IEEE80211_11G; 1219 break; 1220 } 1221 } 1222 1223 int 1224 malo_chip2rate(int chip_rate) 1225 { 1226 switch (chip_rate) { 1227 /* CCK rates */ 1228 case 0: return (2); 1229 case 1: return (4); 1230 case 2: return (11); 1231 case 3: return (22); 1232 1233 /* OFDM rates */ 1234 case 4: return (0); /* reserved */ 1235 case 5: return (12); 1236 case 6: return (18); 1237 case 7: return (24); 1238 case 8: return (36); 1239 case 9: return (48); 1240 case 10: return (72); 1241 case 11: return (96); 1242 case 12: return (108); 1243 1244 /* no rate select yet or unknown rate */ 1245 default: return (-1); 1246 } 1247 } 1248 1249 int 1250 malo_fix2rate(int fix_rate) 1251 { 1252 switch (fix_rate) { 1253 /* CCK rates */ 1254 case 0: return (2); 1255 case 1: return (4); 1256 case 2: return (11); 1257 case 3: return (22); 1258 1259 /* OFDM rates */ 1260 case 4: return (12); 1261 case 5: return (18); 1262 case 6: return (24); 1263 case 7: return (36); 1264 case 8: return (48); 1265 case 9: return (72); 1266 case 10: return (96); 1267 case 11: return (108); 1268 1269 /* unknown rate: should not happen */ 1270 default: return (0); 1271 } 1272 } 1273 1274 void 1275 malo_next_scan(void *arg) 1276 { 1277 struct malo_softc *sc = arg; 1278 struct ieee80211com *ic = &sc->sc_ic; 1279 struct ifnet *ifp = &ic->ic_if; 1280 int s; 1281 1282 DPRINTF(1, "%s: %s\n", ifp->if_xname, __func__); 1283 1284 s = splnet(); 1285 1286 if (ic->ic_state == IEEE80211_S_SCAN) 1287 ieee80211_next_scan(ifp); 1288 1289 splx(s); 1290 } 1291 1292 void 1293 malo_tx_intr(struct malo_softc *sc) 1294 { 1295 struct ieee80211com *ic = &sc->sc_ic; 1296 struct ifnet *ifp = &ic->ic_if; 1297 struct malo_tx_desc *desc; 1298 struct malo_tx_data *data; 1299 struct malo_node *rn; 1300 int stat; 1301 1302 DPRINTF(2, "%s: %s\n", sc->sc_dev.dv_xname, __func__); 1303 1304 stat = sc->sc_txring.stat; 1305 for (;;) { 1306 desc = &sc->sc_txring.desc[sc->sc_txring.stat]; 1307 data = &sc->sc_txring.data[sc->sc_txring.stat]; 1308 rn = (struct malo_node *)data->ni; 1309 1310 /* check if TX descriptor is not owned by FW anymore */ 1311 if ((letoh32(desc->status) & 0x80000000) || 1312 !(letoh32(data->softstat) & 0x80)) 1313 break; 1314 1315 /* if no frame has been sent, ignore */ 1316 if (rn == NULL) 1317 goto next; 1318 1319 /* check TX state */ 1320 switch (letoh32(desc->status) & 0x1) { 1321 case 0x1: 1322 DPRINTF(2, "%s: data frame was sent successfully\n", 1323 sc->sc_dev.dv_xname); 1324 break; 1325 default: 1326 DPRINTF(1, "%s: data frame sending error\n", 1327 sc->sc_dev.dv_xname); 1328 ifp->if_oerrors++; 1329 break; 1330 } 1331 1332 /* save last used TX rate */ 1333 sc->sc_last_txrate = malo_chip2rate(desc->datarate); 1334 1335 /* cleanup TX data and TX descriptor */ 1336 bus_dmamap_sync(sc->sc_dmat, data->map, 0, 1337 data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE); 1338 bus_dmamap_unload(sc->sc_dmat, data->map); 1339 m_freem(data->m); 1340 ieee80211_release_node(ic, data->ni); 1341 data->m = NULL; 1342 data->ni = NULL; 1343 data->softstat &= htole32(~0x80); 1344 desc->status = 0; 1345 desc->len = 0; 1346 1347 DPRINTF(2, "%s: tx done idx=%d\n", 1348 sc->sc_dev.dv_xname, sc->sc_txring.stat); 1349 1350 sc->sc_txring.queued--; 1351 next: 1352 if (++sc->sc_txring.stat >= sc->sc_txring.count) 1353 sc->sc_txring.stat = 0; 1354 if (sc->sc_txring.stat == stat) 1355 break; 1356 } 1357 1358 sc->sc_tx_timer = 0; 1359 ifq_clr_oactive(&ifp->if_snd); 1360 malo_start(ifp); 1361 } 1362 1363 int 1364 malo_tx_mgt(struct malo_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) 1365 { 1366 struct ieee80211com *ic = &sc->sc_ic; 1367 struct ifnet *ifp = &ic->ic_if; 1368 struct malo_tx_desc *desc; 1369 struct malo_tx_data *data; 1370 struct ieee80211_frame *wh; 1371 int error; 1372 1373 DPRINTF(2, "%s: %s\n", sc->sc_dev.dv_xname, __func__); 1374 1375 desc = &sc->sc_txring.desc[sc->sc_txring.cur]; 1376 data = &sc->sc_txring.data[sc->sc_txring.cur]; 1377 1378 if (m0->m_len < sizeof(struct ieee80211_frame)) { 1379 m0 = m_pullup(m0, sizeof(struct ieee80211_frame)); 1380 if (m0 == NULL) { 1381 ifp->if_ierrors++; 1382 return (ENOBUFS); 1383 } 1384 } 1385 wh = mtod(m0, struct ieee80211_frame *); 1386 1387 #if NBPFILTER > 0 1388 if (sc->sc_drvbpf != NULL) { 1389 struct mbuf mb; 1390 struct malo_tx_radiotap_hdr *tap = &sc->sc_txtap; 1391 1392 tap->wt_flags = 0; 1393 tap->wt_rate = sc->sc_last_txrate; 1394 tap->wt_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq); 1395 tap->wt_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags); 1396 1397 mb.m_data = (caddr_t)tap; 1398 mb.m_len = sc->sc_txtap_len; 1399 mb.m_next = m0; 1400 mb.m_nextpkt = NULL; 1401 mb.m_type = 0; 1402 mb.m_flags = 0; 1403 bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_OUT); 1404 } 1405 #endif 1406 /* 1407 * inject FW specific fields into the 802.11 frame 1408 * 1409 * 2 bytes FW len (inject) 1410 * 24 bytes 802.11 frame header 1411 * 6 bytes addr4 (inject) 1412 * n bytes 802.11 frame body 1413 */ 1414 if (m_leadingspace(m0) < 8) { 1415 if (m_trailingspace(m0) < 8) 1416 panic("%s: not enough space for mbuf dance", 1417 sc->sc_dev.dv_xname); 1418 bcopy(m0->m_data, m0->m_data + 8, m0->m_len); 1419 m0->m_data += 8; 1420 } 1421 1422 /* move frame header */ 1423 bcopy(m0->m_data, m0->m_data - 6, sizeof(*wh)); 1424 m0->m_data -= 8; 1425 m0->m_len += 8; 1426 m0->m_pkthdr.len += 8; 1427 *mtod(m0, uint16_t *) = htole16(m0->m_len - 32); /* FW len */ 1428 1429 error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m0, 1430 BUS_DMA_NOWAIT); 1431 if (error != 0) { 1432 printf("%s: can't map mbuf (error %d)\n", 1433 sc->sc_dev.dv_xname, error); 1434 m_freem(m0); 1435 return (error); 1436 } 1437 1438 data->m = m0; 1439 data->ni = ni; 1440 data->softstat |= htole32(0x80); 1441 1442 malo_tx_setup_desc(sc, desc, m0->m_pkthdr.len, 0, 1443 data->map->dm_segs, data->map->dm_nsegs); 1444 1445 bus_dmamap_sync(sc->sc_dmat, data->map, 0, data->map->dm_mapsize, 1446 BUS_DMASYNC_PREWRITE); 1447 bus_dmamap_sync(sc->sc_dmat, sc->sc_txring.map, 1448 sc->sc_txring.cur * sizeof(struct malo_tx_desc), 1449 sizeof(struct malo_tx_desc), BUS_DMASYNC_PREWRITE); 1450 1451 DPRINTF(2, "%s: sending mgmt frame, pktlen=%u, idx=%u\n", 1452 sc->sc_dev.dv_xname, m0->m_pkthdr.len, sc->sc_txring.cur); 1453 1454 sc->sc_txring.queued++; 1455 sc->sc_txring.cur = (sc->sc_txring.cur + 1) % MALO_TX_RING_COUNT; 1456 1457 /* kick mgmt TX */ 1458 malo_ctl_write4(sc, 0x0c18, 1); 1459 malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE); 1460 1461 return (0); 1462 } 1463 1464 int 1465 malo_tx_data(struct malo_softc *sc, struct mbuf *m0, 1466 struct ieee80211_node *ni) 1467 { 1468 struct ieee80211com *ic = &sc->sc_ic; 1469 struct ifnet *ifp = &ic->ic_if; 1470 struct malo_tx_desc *desc; 1471 struct malo_tx_data *data; 1472 struct ieee80211_frame *wh; 1473 struct ieee80211_key *k; 1474 struct mbuf *mnew; 1475 int error; 1476 1477 DPRINTF(2, "%s: %s\n", sc->sc_dev.dv_xname, __func__); 1478 1479 desc = &sc->sc_txring.desc[sc->sc_txring.cur]; 1480 data = &sc->sc_txring.data[sc->sc_txring.cur]; 1481 1482 if (m0->m_len < sizeof(struct ieee80211_frame)) { 1483 m0 = m_pullup(m0, sizeof(struct ieee80211_frame)); 1484 if (m0 == NULL) { 1485 ifp->if_ierrors++; 1486 return (ENOBUFS); 1487 } 1488 } 1489 wh = mtod(m0, struct ieee80211_frame *); 1490 1491 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 1492 k = ieee80211_get_txkey(ic, wh, ni); 1493 if ((m0 = ieee80211_encrypt(ic, m0, k)) == NULL) 1494 return (ENOBUFS); 1495 1496 /* packet header may have moved, reset our local pointer */ 1497 wh = mtod(m0, struct ieee80211_frame *); 1498 } 1499 1500 #if NBPFILTER > 0 1501 if (sc->sc_drvbpf != NULL) { 1502 struct mbuf mb; 1503 struct malo_tx_radiotap_hdr *tap = &sc->sc_txtap; 1504 1505 tap->wt_flags = 0; 1506 tap->wt_rate = sc->sc_last_txrate; 1507 tap->wt_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq); 1508 tap->wt_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags); 1509 1510 mb.m_data = (caddr_t)tap; 1511 mb.m_len = sc->sc_txtap_len; 1512 mb.m_next = m0; 1513 mb.m_nextpkt = NULL; 1514 mb.m_type = 0; 1515 mb.m_flags = 0; 1516 bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_OUT); 1517 } 1518 #endif 1519 1520 /* 1521 * inject FW specific fields into the 802.11 frame 1522 * 1523 * 2 bytes FW len (inject) 1524 * 24 bytes 802.11 frame header 1525 * 6 bytes addr4 (inject) 1526 * n bytes 802.11 frame body 1527 * 1528 * For now copy all into a new mcluster. 1529 */ 1530 MGETHDR(mnew, M_DONTWAIT, MT_DATA); 1531 if (mnew == NULL) 1532 return (ENOBUFS); 1533 MCLGET(mnew, M_DONTWAIT); 1534 if (!(mnew->m_flags & M_EXT)) { 1535 m_free(mnew); 1536 return (ENOBUFS); 1537 } 1538 1539 *mtod(mnew, uint16_t *) = htole16(m0->m_pkthdr.len - 24); /* FW len */ 1540 bcopy(wh, mtod(mnew, caddr_t) + 2, sizeof(*wh)); 1541 bzero(mtod(mnew, caddr_t) + 26, 6); 1542 m_copydata(m0, sizeof(*wh), m0->m_pkthdr.len - sizeof(*wh), 1543 mtod(mnew, caddr_t) + 32); 1544 mnew->m_pkthdr.len = mnew->m_len = m0->m_pkthdr.len + 8; 1545 m_freem(m0); 1546 m0 = mnew; 1547 1548 error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m0, 1549 BUS_DMA_NOWAIT); 1550 if (error != 0) { 1551 printf("%s: can't map mbuf (error %d)\n", 1552 sc->sc_dev.dv_xname, error); 1553 m_freem(m0); 1554 return (error); 1555 } 1556 1557 data->m = m0; 1558 data->ni = ni; 1559 data->softstat |= htole32(0x80); 1560 1561 malo_tx_setup_desc(sc, desc, m0->m_pkthdr.len, 1, 1562 data->map->dm_segs, data->map->dm_nsegs); 1563 1564 bus_dmamap_sync(sc->sc_dmat, data->map, 0, data->map->dm_mapsize, 1565 BUS_DMASYNC_PREWRITE); 1566 bus_dmamap_sync(sc->sc_dmat, sc->sc_txring.map, 1567 sc->sc_txring.cur * sizeof(struct malo_tx_desc), 1568 sizeof(struct malo_tx_desc), BUS_DMASYNC_PREWRITE); 1569 1570 DPRINTF(2, "%s: sending data frame, pktlen=%u, idx=%u\n", 1571 sc->sc_dev.dv_xname, m0->m_pkthdr.len, sc->sc_txring.cur); 1572 1573 sc->sc_txring.queued++; 1574 sc->sc_txring.cur = (sc->sc_txring.cur + 1) % MALO_TX_RING_COUNT; 1575 1576 /* kick data TX */ 1577 malo_ctl_write4(sc, 0x0c18, 1); 1578 malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE); 1579 1580 return (0); 1581 } 1582 1583 void 1584 malo_tx_setup_desc(struct malo_softc *sc, struct malo_tx_desc *desc, 1585 int len, int rate, const bus_dma_segment_t *segs, int nsegs) 1586 { 1587 desc->len = htole16(segs[0].ds_len); 1588 desc->datarate = rate; /* 0 = mgmt frame, 1 = data frame */ 1589 desc->physdata = htole32(segs[0].ds_addr); 1590 desc->status = htole32(0x00000001 | 0x80000000); 1591 } 1592 1593 void 1594 malo_rx_intr(struct malo_softc *sc) 1595 { 1596 struct mbuf_list ml = MBUF_LIST_INITIALIZER(); 1597 struct ieee80211com *ic = &sc->sc_ic; 1598 struct ifnet *ifp = &ic->ic_if; 1599 struct malo_rx_desc *desc; 1600 struct malo_rx_data *data; 1601 struct ieee80211_frame *wh; 1602 struct ieee80211_rxinfo rxi; 1603 struct ieee80211_node *ni; 1604 struct mbuf *mnew, *m; 1605 uint32_t rxRdPtr, rxWrPtr; 1606 int error, i; 1607 1608 rxRdPtr = malo_mem_read4(sc, sc->sc_RxPdRdPtr); 1609 rxWrPtr = malo_mem_read4(sc, sc->sc_RxPdWrPtr); 1610 1611 for (i = 0; i < MALO_RX_RING_COUNT && rxRdPtr != rxWrPtr; i++) { 1612 desc = &sc->sc_rxring.desc[sc->sc_rxring.cur]; 1613 data = &sc->sc_rxring.data[sc->sc_rxring.cur]; 1614 1615 bus_dmamap_sync(sc->sc_dmat, sc->sc_rxring.map, 1616 sc->sc_rxring.cur * sizeof(struct malo_rx_desc), 1617 sizeof(struct malo_rx_desc), BUS_DMASYNC_POSTREAD); 1618 1619 DPRINTF(3, "%s: rx intr idx=%d, rxctrl=0x%02x, rssi=%d, " 1620 "status=0x%02x, channel=%d, len=%d, res1=%02x, rate=%d, " 1621 "physdata=0x%04x, physnext=0x%04x, qosctrl=%02x, res2=%d\n", 1622 sc->sc_dev.dv_xname, 1623 sc->sc_rxring.cur, desc->rxctrl, desc->rssi, desc->status, 1624 desc->channel, letoh16(desc->len), desc->reserved1, 1625 desc->datarate, letoh32(desc->physdata), 1626 letoh32(desc->physnext), desc->qosctrl, desc->reserved2); 1627 1628 if ((desc->rxctrl & 0x80) == 0) 1629 break; 1630 1631 MGETHDR(mnew, M_DONTWAIT, MT_DATA); 1632 if (mnew == NULL) { 1633 ifp->if_ierrors++; 1634 goto skip; 1635 } 1636 1637 MCLGET(mnew, M_DONTWAIT); 1638 if (!(mnew->m_flags & M_EXT)) { 1639 m_freem(mnew); 1640 ifp->if_ierrors++; 1641 goto skip; 1642 } 1643 1644 bus_dmamap_sync(sc->sc_dmat, data->map, 0, 1645 data->map->dm_mapsize, BUS_DMASYNC_POSTREAD); 1646 bus_dmamap_unload(sc->sc_dmat, data->map); 1647 1648 error = bus_dmamap_load(sc->sc_dmat, data->map, 1649 mtod(mnew, void *), MCLBYTES, NULL, BUS_DMA_NOWAIT); 1650 if (error != 0) { 1651 m_freem(mnew); 1652 1653 error = bus_dmamap_load(sc->sc_dmat, data->map, 1654 mtod(data->m, void *), MCLBYTES, NULL, 1655 BUS_DMA_NOWAIT); 1656 if (error != 0) { 1657 panic("%s: could not load old rx mbuf", 1658 sc->sc_dev.dv_xname); 1659 } 1660 ifp->if_ierrors++; 1661 goto skip; 1662 } 1663 1664 /* 1665 * New mbuf mbuf successfully loaded 1666 */ 1667 m = data->m; 1668 data->m = mnew; 1669 desc->physdata = htole32(data->map->dm_segs->ds_addr); 1670 1671 /* finalize mbuf */ 1672 m->m_pkthdr.len = m->m_len = letoh16(desc->len); 1673 1674 /* 1675 * cut out FW specific fields from the 802.11 frame 1676 * 1677 * 2 bytes FW len (cut out) 1678 * 24 bytes 802.11 frame header 1679 * 6 bytes addr4 (cut out) 1680 * n bytes 802.11 frame data 1681 */ 1682 bcopy(m->m_data, m->m_data + 6, 26); 1683 m_adj(m, 8); 1684 1685 #if NBPFILTER > 0 1686 if (sc->sc_drvbpf != NULL) { 1687 struct mbuf mb; 1688 struct malo_rx_radiotap_hdr *tap = &sc->sc_rxtap; 1689 1690 tap->wr_flags = 0; 1691 tap->wr_chan_freq = 1692 htole16(ic->ic_bss->ni_chan->ic_freq); 1693 tap->wr_chan_flags = 1694 htole16(ic->ic_bss->ni_chan->ic_flags); 1695 tap->wr_rssi = desc->rssi; 1696 tap->wr_max_rssi = ic->ic_max_rssi; 1697 1698 mb.m_data = (caddr_t)tap; 1699 mb.m_len = sc->sc_rxtap_len; 1700 mb.m_next = m; 1701 mb.m_nextpkt = NULL; 1702 mb.m_type = 0; 1703 mb.m_flags = 0; 1704 bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_IN); 1705 } 1706 #endif 1707 1708 wh = mtod(m, struct ieee80211_frame *); 1709 ni = ieee80211_find_rxnode(ic, wh); 1710 1711 /* send the frame to the 802.11 layer */ 1712 rxi.rxi_flags = 0; 1713 rxi.rxi_rssi = desc->rssi; 1714 rxi.rxi_tstamp = 0; /* unused */ 1715 ieee80211_inputm(ifp, m, ni, &rxi, &ml); 1716 1717 /* node is no longer needed */ 1718 ieee80211_release_node(ic, ni); 1719 1720 skip: 1721 desc->rxctrl = 0; 1722 rxRdPtr = letoh32(desc->physnext); 1723 1724 bus_dmamap_sync(sc->sc_dmat, sc->sc_rxring.map, 1725 sc->sc_rxring.cur * sizeof(struct malo_rx_desc), 1726 sizeof(struct malo_rx_desc), BUS_DMASYNC_PREWRITE); 1727 1728 sc->sc_rxring.cur = (sc->sc_rxring.cur + 1) % 1729 MALO_RX_RING_COUNT; 1730 } 1731 if_input(ifp, &ml); 1732 1733 malo_mem_write4(sc, sc->sc_RxPdRdPtr, rxRdPtr); 1734 } 1735 1736 int 1737 malo_load_bootimg(struct malo_softc *sc) 1738 { 1739 char *name = "malo8335-h"; 1740 uint8_t *ucode; 1741 size_t usize; 1742 int error, i; 1743 1744 /* load boot firmware */ 1745 if ((error = loadfirmware(name, &ucode, &usize)) != 0) { 1746 printf("%s: error %d, could not read firmware %s\n", 1747 sc->sc_dev.dv_xname, error, name); 1748 return (EIO); 1749 } 1750 1751 /* 1752 * It seems we are putting this code directly onto the stack of 1753 * the ARM cpu. I don't know why we need to instruct the DMA 1754 * engine to move the code. This is a big riddle without docu. 1755 */ 1756 DPRINTF(1, "%s: loading boot firmware\n", sc->sc_dev.dv_xname); 1757 malo_mem_write2(sc, 0xbef8, 0x001); 1758 malo_mem_write2(sc, 0xbefa, usize); 1759 malo_mem_write4(sc, 0xbefc, 0); 1760 1761 bus_space_write_region_1(sc->sc_mem1_bt, sc->sc_mem1_bh, 0xbf00, 1762 ucode, usize); 1763 1764 /* 1765 * we loaded the firmware into card memory now tell the CPU 1766 * to fetch the code and execute it. The memory mapped via the 1767 * first bar is internaly mapped to 0xc0000000. 1768 */ 1769 malo_send_cmd(sc, 0xc000bef8); 1770 1771 /* wait for the device to go into FW loading mode */ 1772 for (i = 0; i < 10; i++) { 1773 delay(50); 1774 malo_ctl_barrier(sc, BUS_SPACE_BARRIER_READ); 1775 if (malo_ctl_read4(sc, 0x0c14) == 0x5) 1776 break; 1777 } 1778 if (i == 10) { 1779 printf("%s: timeout at boot firmware load!\n", 1780 sc->sc_dev.dv_xname); 1781 free(ucode, M_DEVBUF, usize); 1782 return (ETIMEDOUT); 1783 } 1784 free(ucode, M_DEVBUF, usize); 1785 1786 /* tell the card we're done and... */ 1787 malo_mem_write2(sc, 0xbef8, 0x001); 1788 malo_mem_write2(sc, 0xbefa, 0); 1789 malo_mem_write4(sc, 0xbefc, 0); 1790 malo_send_cmd(sc, 0xc000bef8); 1791 1792 DPRINTF(1, "%s: boot firmware loaded\n", sc->sc_dev.dv_xname); 1793 1794 return (0); 1795 } 1796 1797 int 1798 malo_load_firmware(struct malo_softc *sc) 1799 { 1800 struct malo_cmdheader *hdr; 1801 char *name = "malo8335-m"; 1802 void *data; 1803 uint8_t *ucode; 1804 size_t size, count, bsize; 1805 int i, sn, error; 1806 1807 /* load real firmware now */ 1808 if ((error = loadfirmware(name, &ucode, &size)) != 0) { 1809 printf("%s: error %d, could not read firmware %s\n", 1810 sc->sc_dev.dv_xname, error, name); 1811 return (EIO); 1812 } 1813 1814 DPRINTF(1, "%s: uploading firmware\n", sc->sc_dev.dv_xname); 1815 1816 hdr = sc->sc_cmd_mem; 1817 data = hdr + 1; 1818 sn = 1; 1819 for (count = 0; count < size; count += bsize) { 1820 bsize = MIN(256, size - count); 1821 1822 hdr->cmd = htole16(0x0001); 1823 hdr->size = htole16(bsize); 1824 hdr->seqnum = htole16(sn++); 1825 hdr->result = 0; 1826 1827 bcopy(ucode + count, data, bsize); 1828 1829 bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE, 1830 BUS_DMASYNC_PREWRITE); 1831 malo_send_cmd(sc, sc->sc_cmd_dmaaddr); 1832 bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE, 1833 BUS_DMASYNC_POSTWRITE); 1834 delay(500); 1835 } 1836 free(ucode, M_DEVBUF, size); 1837 1838 DPRINTF(1, "%s: firmware upload finished\n", sc->sc_dev.dv_xname); 1839 1840 /* 1841 * send a command with size 0 to tell that the firmware has been 1842 * uploaded 1843 */ 1844 hdr->cmd = htole16(0x0001); 1845 hdr->size = 0; 1846 hdr->seqnum = htole16(sn++); 1847 hdr->result = 0; 1848 1849 bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE, 1850 BUS_DMASYNC_PREWRITE); 1851 malo_send_cmd(sc, sc->sc_cmd_dmaaddr); 1852 bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE, 1853 BUS_DMASYNC_POSTWRITE); 1854 delay(100); 1855 1856 DPRINTF(1, "%s: loading firmware\n", sc->sc_dev.dv_xname); 1857 1858 /* wait until firmware has been loaded */ 1859 for (i = 0; i < 200; i++) { 1860 malo_ctl_write4(sc, 0x0c10, 0x5a); 1861 delay(500); 1862 malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE | 1863 BUS_SPACE_BARRIER_READ); 1864 if (malo_ctl_read4(sc, 0x0c14) == 0xf0f1f2f4) 1865 break; 1866 } 1867 if (i == 200) { 1868 printf("%s: timeout at firmware load!\n", sc->sc_dev.dv_xname); 1869 return (ETIMEDOUT); 1870 } 1871 1872 DPRINTF(1, "%s: firmware loaded\n", sc->sc_dev.dv_xname); 1873 1874 return (0); 1875 } 1876 1877 int 1878 malo_set_slot(struct malo_softc *sc) 1879 { 1880 struct ieee80211com *ic = &sc->sc_ic; 1881 1882 if (ic->ic_flags & IEEE80211_F_SHSLOT) { 1883 /* set short slot */ 1884 if (malo_cmd_set_slot(sc, 1)) { 1885 printf("%s: setting short slot failed\n", 1886 sc->sc_dev.dv_xname); 1887 return (ENXIO); 1888 } 1889 } else { 1890 /* set long slot */ 1891 if (malo_cmd_set_slot(sc, 0)) { 1892 printf("%s: setting long slot failed\n", 1893 sc->sc_dev.dv_xname); 1894 return (ENXIO); 1895 } 1896 } 1897 1898 return (0); 1899 } 1900 1901 void 1902 malo_update_slot(struct ieee80211com *ic) 1903 { 1904 struct malo_softc *sc = ic->ic_if.if_softc; 1905 1906 malo_set_slot(sc); 1907 1908 #ifndef IEEE80211_STA_ONLY 1909 if (ic->ic_opmode == IEEE80211_M_HOSTAP) { 1910 /* TODO */ 1911 } 1912 #endif 1913 } 1914 1915 #ifdef MALO_DEBUG 1916 void 1917 malo_hexdump(void *buf, int len) 1918 { 1919 u_char b[16]; 1920 int i, j, l; 1921 1922 for (i = 0; i < len; i += l) { 1923 printf("%4i:", i); 1924 l = min(sizeof(b), len - i); 1925 bcopy(buf + i, b, l); 1926 1927 for (j = 0; j < sizeof(b); j++) { 1928 if (j % 2 == 0) 1929 printf(" "); 1930 if (j % 8 == 0) 1931 printf(" "); 1932 if (j < l) 1933 printf("%02x", (int)b[j]); 1934 else 1935 printf(" "); 1936 } 1937 printf(" |"); 1938 for (j = 0; j < l; j++) { 1939 if (b[j] >= 0x20 && b[j] <= 0x7e) 1940 printf("%c", b[j]); 1941 else 1942 printf("."); 1943 } 1944 printf("|\n"); 1945 } 1946 } 1947 #endif 1948 1949 static char * 1950 malo_cmd_string(uint16_t cmd) 1951 { 1952 int i; 1953 static char cmd_buf[16]; 1954 static const struct { 1955 uint16_t cmd_code; 1956 char *cmd_string; 1957 } cmds[] = { 1958 { MALO_CMD_GET_HW_SPEC, "GetHwSpecifications" }, 1959 { MALO_CMD_SET_RADIO, "SetRadio" }, 1960 { MALO_CMD_SET_AID, "SetAid" }, 1961 { MALO_CMD_SET_TXPOWER, "SetTxPower" }, 1962 { MALO_CMD_SET_ANTENNA, "SetAntenna" }, 1963 { MALO_CMD_SET_PRESCAN, "SetPrescan" }, 1964 { MALO_CMD_SET_POSTSCAN, "SetPostscan" }, 1965 { MALO_CMD_SET_RATE, "SetRate" }, 1966 { MALO_CMD_SET_CHANNEL, "SetChannel" }, 1967 { MALO_CMD_SET_RTS, "SetRTS" }, 1968 { MALO_CMD_SET_SLOT, "SetSlot" }, 1969 }; 1970 1971 for (i = 0; i < sizeof(cmds) / sizeof(cmds[0]); i++) 1972 if ((letoh16(cmd) & 0x7fff) == cmds[i].cmd_code) 1973 return (cmds[i].cmd_string); 1974 1975 snprintf(cmd_buf, sizeof(cmd_buf), "unknown %#x", cmd); 1976 return (cmd_buf); 1977 } 1978 1979 static char * 1980 malo_cmd_string_result(uint16_t result) 1981 { 1982 int i; 1983 static const struct { 1984 uint16_t result_code; 1985 char *result_string; 1986 } results[] = { 1987 { MALO_CMD_RESULT_OK, "OK" }, 1988 { MALO_CMD_RESULT_ERROR, "general error" }, 1989 { MALO_CMD_RESULT_NOSUPPORT, "not supported" }, 1990 { MALO_CMD_RESULT_PENDING, "pending" }, 1991 { MALO_CMD_RESULT_BUSY, "ignored" }, 1992 { MALO_CMD_RESULT_PARTIALDATA, "incomplete" }, 1993 }; 1994 1995 for (i = 0; i < sizeof(results) / sizeof(results[0]); i++) 1996 if (letoh16(result) == results[i].result_code) 1997 return (results[i].result_string); 1998 1999 return ("unknown"); 2000 } 2001 2002 int 2003 malo_cmd_get_spec(struct malo_softc *sc) 2004 { 2005 struct malo_cmdheader *hdr = sc->sc_cmd_mem; 2006 struct malo_hw_spec *spec; 2007 2008 hdr->cmd = htole16(MALO_CMD_GET_HW_SPEC); 2009 hdr->size = htole16(sizeof(*hdr) + sizeof(*spec)); 2010 hdr->seqnum = htole16(42); /* the one and only */ 2011 hdr->result = 0; 2012 spec = (struct malo_hw_spec *)(hdr + 1); 2013 2014 bzero(spec, sizeof(*spec)); 2015 memset(spec->PermanentAddress, 0xff, ETHER_ADDR_LEN); 2016 spec->CookiePtr = htole32(sc->sc_cookie_dmaaddr); 2017 2018 bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE, 2019 BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD); 2020 2021 if (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr) != 0) 2022 return (ETIMEDOUT); 2023 2024 /* get the data from the buffer */ 2025 DPRINTF(1, "%s: get_hw_spec: V%x R%x, #WCB %d, #Mcast %d, Regcode %d, " 2026 "#Ant %d\n", sc->sc_dev.dv_xname, htole16(spec->HwVersion), 2027 htole32(spec->FWReleaseNumber), htole16(spec->NumOfWCB), 2028 htole16(spec->NumOfMCastAdr), htole16(spec->RegionCode), 2029 htole16(spec->NumberOfAntenna)); 2030 2031 /* tell the DMA engine where our rings are */ 2032 malo_mem_write4(sc, letoh32(spec->RxPdRdPtr) & 0xffff, 2033 sc->sc_rxring.physaddr); 2034 malo_mem_write4(sc, letoh32(spec->RxPdWrPtr) & 0xffff, 2035 sc->sc_rxring.physaddr); 2036 malo_mem_write4(sc, letoh32(spec->WcbBase0) & 0xffff, 2037 sc->sc_txring.physaddr); 2038 2039 /* save DMA RX pointers for later use */ 2040 sc->sc_RxPdRdPtr = letoh32(spec->RxPdRdPtr) & 0xffff; 2041 sc->sc_RxPdWrPtr = letoh32(spec->RxPdWrPtr) & 0xffff; 2042 2043 return (0); 2044 } 2045 2046 int 2047 malo_cmd_set_prescan(struct malo_softc *sc) 2048 { 2049 struct malo_cmdheader *hdr = sc->sc_cmd_mem; 2050 2051 hdr->cmd = htole16(MALO_CMD_SET_PRESCAN); 2052 hdr->size = htole16(sizeof(*hdr)); 2053 hdr->seqnum = 1; 2054 hdr->result = 0; 2055 2056 bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE, 2057 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 2058 2059 return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr)); 2060 } 2061 2062 int 2063 malo_cmd_set_postscan(struct malo_softc *sc, uint8_t *macaddr, uint8_t ibsson) 2064 { 2065 struct malo_cmdheader *hdr = sc->sc_cmd_mem; 2066 struct malo_cmd_postscan *body; 2067 2068 hdr->cmd = htole16(MALO_CMD_SET_POSTSCAN); 2069 hdr->size = htole16(sizeof(*hdr) + sizeof(*body)); 2070 hdr->seqnum = 1; 2071 hdr->result = 0; 2072 body = (struct malo_cmd_postscan *)(hdr + 1); 2073 2074 bzero(body, sizeof(*body)); 2075 memcpy(&body->bssid, macaddr, ETHER_ADDR_LEN); 2076 body->isibss = htole32(ibsson); 2077 2078 bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE, 2079 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 2080 2081 return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr)); 2082 } 2083 2084 int 2085 malo_cmd_set_channel(struct malo_softc *sc, uint8_t channel) 2086 { 2087 struct malo_cmdheader *hdr = sc->sc_cmd_mem; 2088 struct malo_cmd_channel *body; 2089 2090 hdr->cmd = htole16(MALO_CMD_SET_CHANNEL); 2091 hdr->size = htole16(sizeof(*hdr) + sizeof(*body)); 2092 hdr->seqnum = 1; 2093 hdr->result = 0; 2094 body = (struct malo_cmd_channel *)(hdr + 1); 2095 2096 bzero(body, sizeof(*body)); 2097 body->action = htole16(1); 2098 body->channel = channel; 2099 2100 bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE, 2101 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 2102 2103 return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr)); 2104 } 2105 2106 int 2107 malo_cmd_set_antenna(struct malo_softc *sc, uint16_t antenna) 2108 { 2109 struct malo_cmdheader *hdr = sc->sc_cmd_mem; 2110 struct malo_cmd_antenna *body; 2111 2112 hdr->cmd = htole16(MALO_CMD_SET_ANTENNA); 2113 hdr->size = htole16(sizeof(*hdr) + sizeof(*body)); 2114 hdr->seqnum = 1; 2115 hdr->result = 0; 2116 body = (struct malo_cmd_antenna *)(hdr + 1); 2117 2118 bzero(body, sizeof(*body)); 2119 body->action = htole16(antenna); 2120 if (antenna == 1) 2121 body->mode = htole16(0xffff); 2122 else 2123 body->mode = htole16(2); 2124 2125 bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE, 2126 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 2127 2128 return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr)); 2129 } 2130 2131 int 2132 malo_cmd_set_radio(struct malo_softc *sc, uint16_t enable, 2133 uint16_t preamble_mode) 2134 { 2135 struct malo_cmdheader *hdr = sc->sc_cmd_mem; 2136 struct malo_cmd_radio *body; 2137 2138 hdr->cmd = htole16(MALO_CMD_SET_RADIO); 2139 hdr->size = htole16(sizeof(*hdr) + sizeof(*body)); 2140 hdr->seqnum = 1; 2141 hdr->result = 0; 2142 body = (struct malo_cmd_radio *)(hdr + 1); 2143 2144 bzero(body, sizeof(*body)); 2145 body->action = htole16(1); 2146 body->preamble_mode = htole16(preamble_mode); 2147 body->enable = htole16(enable); 2148 2149 bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE, 2150 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 2151 2152 return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr)); 2153 } 2154 2155 int 2156 malo_cmd_set_aid(struct malo_softc *sc, uint8_t *bssid, uint16_t associd) 2157 { 2158 struct malo_cmdheader *hdr = sc->sc_cmd_mem; 2159 struct malo_cmd_aid *body; 2160 2161 hdr->cmd = htole16(MALO_CMD_SET_AID); 2162 hdr->size = htole16(sizeof(*hdr) + sizeof(*body)); 2163 hdr->seqnum = 1; 2164 hdr->result = 0; 2165 body = (struct malo_cmd_aid *)(hdr + 1); 2166 2167 bzero(body, sizeof(*body)); 2168 body->associd = htole16(associd); 2169 memcpy(&body->macaddr[0], bssid, IEEE80211_ADDR_LEN); 2170 2171 bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE, 2172 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 2173 2174 return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr)); 2175 } 2176 2177 int 2178 malo_cmd_set_txpower(struct malo_softc *sc, unsigned int powerlevel) 2179 { 2180 struct malo_cmdheader *hdr = sc->sc_cmd_mem; 2181 struct malo_cmd_txpower *body; 2182 2183 hdr->cmd = htole16(MALO_CMD_SET_TXPOWER); 2184 hdr->size = htole16(sizeof(*hdr) + sizeof(*body)); 2185 hdr->seqnum = 1; 2186 hdr->result = 0; 2187 body = (struct malo_cmd_txpower *)(hdr + 1); 2188 2189 bzero(body, sizeof(*body)); 2190 body->action = htole16(1); 2191 if (powerlevel < 30) 2192 body->supportpowerlvl = htole16(5); /* LOW */ 2193 else if (powerlevel >= 30 && powerlevel < 60) 2194 body->supportpowerlvl = htole16(10); /* MEDIUM */ 2195 else 2196 body->supportpowerlvl = htole16(15); /* HIGH */ 2197 2198 bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE, 2199 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 2200 2201 return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr)); 2202 } 2203 2204 int 2205 malo_cmd_set_rts(struct malo_softc *sc, uint32_t threshold) 2206 { 2207 struct malo_cmdheader *hdr = sc->sc_cmd_mem; 2208 struct malo_cmd_rts *body; 2209 2210 hdr->cmd = htole16(MALO_CMD_SET_RTS); 2211 hdr->size = htole16(sizeof(*hdr) + sizeof(*body)); 2212 hdr->seqnum = 1; 2213 hdr->result = 0; 2214 body = (struct malo_cmd_rts *)(hdr + 1); 2215 2216 bzero(body, sizeof(*body)); 2217 body->action = htole16(1); 2218 body->threshold = htole32(threshold); 2219 2220 bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE, 2221 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 2222 2223 return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr)); 2224 } 2225 2226 int 2227 malo_cmd_set_slot(struct malo_softc *sc, uint8_t slot) 2228 { 2229 struct malo_cmdheader *hdr = sc->sc_cmd_mem; 2230 struct malo_cmd_slot *body; 2231 2232 hdr->cmd = htole16(MALO_CMD_SET_SLOT); 2233 hdr->size = htole16(sizeof(*hdr) + sizeof(*body)); 2234 hdr->seqnum = 1; 2235 hdr->result = 0; 2236 body = (struct malo_cmd_slot *)(hdr + 1); 2237 2238 bzero(body, sizeof(*body)); 2239 body->action = htole16(1); 2240 body->slot = slot; 2241 2242 bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE, 2243 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 2244 2245 return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr)); 2246 } 2247 2248 int 2249 malo_cmd_set_rate(struct malo_softc *sc, uint8_t rate) 2250 { 2251 struct ieee80211com *ic = &sc->sc_ic; 2252 struct malo_cmdheader *hdr = sc->sc_cmd_mem; 2253 struct malo_cmd_rate *body; 2254 int i; 2255 2256 hdr->cmd = htole16(MALO_CMD_SET_RATE); 2257 hdr->size = htole16(sizeof(*hdr) + sizeof(*body)); 2258 hdr->seqnum = 1; 2259 hdr->result = 0; 2260 body = (struct malo_cmd_rate *)(hdr + 1); 2261 2262 bzero(body, sizeof(*body)); 2263 2264 #ifndef IEEE80211_STA_ONLY 2265 if (ic->ic_opmode == IEEE80211_M_HOSTAP) { 2266 /* TODO */ 2267 } else 2268 #endif 2269 { 2270 body->aprates[0] = 2; 2271 body->aprates[1] = 4; 2272 body->aprates[2] = 11; 2273 body->aprates[3] = 22; 2274 if (ic->ic_curmode == IEEE80211_MODE_11G) { 2275 body->aprates[4] = 0; 2276 body->aprates[5] = 12; 2277 body->aprates[6] = 18; 2278 body->aprates[7] = 24; 2279 body->aprates[8] = 36; 2280 body->aprates[9] = 48; 2281 body->aprates[10] = 72; 2282 body->aprates[11] = 96; 2283 body->aprates[12] = 108; 2284 } 2285 } 2286 2287 if (rate != 0) { 2288 /* fixed rate */ 2289 for (i = 0; i < 13; i++) { 2290 if (body->aprates[i] == rate) { 2291 body->rateindex = i; 2292 body->dataratetype = 1; 2293 break; 2294 } 2295 } 2296 } 2297 2298 bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE, 2299 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 2300 2301 return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr)); 2302 } 2303 2304 void 2305 malo_cmd_response(struct malo_softc *sc) 2306 { 2307 struct malo_cmdheader *hdr = sc->sc_cmd_mem; 2308 2309 if (letoh16(hdr->result) != MALO_CMD_RESULT_OK) { 2310 printf("%s: firmware cmd %s failed with %s\n", 2311 sc->sc_dev.dv_xname, 2312 malo_cmd_string(hdr->cmd), 2313 malo_cmd_string_result(hdr->result)); 2314 } 2315 2316 #ifdef MALO_DEBUG 2317 printf("%s: cmd answer for %s=%s\n", 2318 sc->sc_dev.dv_xname, 2319 malo_cmd_string(hdr->cmd), 2320 malo_cmd_string_result(hdr->result)); 2321 2322 if (malo_d > 2) 2323 malo_hexdump(hdr, letoh16(hdr->size)); 2324 #endif 2325 } 2326