rtw.c revision 1.30
1/* $NetBSD: rtw.c,v 1.30 2004/12/27 20:04:45 dyoung Exp $ */ 2/*- 3 * Copyright (c) 2004, 2005 David Young. All rights reserved. 4 * 5 * Programmed for NetBSD by David Young. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of David Young may not be used to endorse or promote 16 * products derived from this software without specific prior 17 * written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY David Young ``AS IS'' AND ANY 20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 22 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David 23 * Young BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 25 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 30 * OF SUCH DAMAGE. 31 */ 32/* 33 * Device driver for the Realtek RTL8180 802.11 MAC/BBP. 34 */ 35 36#include <sys/cdefs.h> 37__KERNEL_RCSID(0, "$NetBSD: rtw.c,v 1.30 2004/12/27 20:04:45 dyoung Exp $"); 38 39#include "bpfilter.h" 40 41#include <sys/param.h> 42#include <sys/sysctl.h> 43#include <sys/systm.h> 44#include <sys/callout.h> 45#include <sys/mbuf.h> 46#include <sys/malloc.h> 47#include <sys/kernel.h> 48#if 0 49#include <sys/socket.h> 50#include <sys/ioctl.h> 51#include <sys/errno.h> 52#include <sys/device.h> 53#endif 54#include <sys/time.h> 55#include <sys/types.h> 56 57#include <machine/endian.h> 58#include <machine/bus.h> 59#include <machine/intr.h> /* splnet */ 60 61#include <uvm/uvm_extern.h> 62 63#include <net/if.h> 64#include <net/if_media.h> 65#include <net/if_ether.h> 66 67#include <net80211/ieee80211_var.h> 68#include <net80211/ieee80211_compat.h> 69#include <net80211/ieee80211_radiotap.h> 70 71#if NBPFILTER > 0 72#include <net/bpf.h> 73#endif 74 75#include <dev/ic/rtwreg.h> 76#include <dev/ic/rtwvar.h> 77#include <dev/ic/rtwphyio.h> 78#include <dev/ic/rtwphy.h> 79 80#include <dev/ic/smc93cx6var.h> 81 82#define KASSERT2(__cond, __msg) \ 83 do { \ 84 if (!(__cond)) \ 85 panic __msg ; \ 86 } while (0) 87 88int rtw_rfprog_fallback = 0; 89int rtw_host_rfio = 0; 90 91#ifdef RTW_DEBUG 92int rtw_debug = 0; 93#endif /* RTW_DEBUG */ 94 95#define NEXT_ATTACH_STATE(sc, state) do { \ 96 DPRINTF(sc, RTW_DEBUG_ATTACH, \ 97 ("%s: attach state %s\n", __func__, #state)); \ 98 sc->sc_attach_state = state; \ 99} while (0) 100 101int rtw_dwelltime = 200; /* milliseconds */ 102 103static void rtw_start(struct ifnet *); 104 105static int rtw_sysctl_verify_rfio(SYSCTLFN_PROTO); 106static int rtw_sysctl_verify_rfprog(SYSCTLFN_PROTO); 107#ifdef RTW_DEBUG 108static void rtw_print_txdesc(struct rtw_softc *, const char *, 109 struct rtw_txctl *, struct rtw_txdesc_blk *, int); 110static int rtw_sysctl_verify_debug(SYSCTLFN_PROTO); 111#endif /* RTW_DEBUG */ 112 113/* 114 * Setup sysctl(3) MIB, hw.rtw.* 115 * 116 * TBD condition CTLFLAG_PERMANENT on being an LKM or not 117 */ 118SYSCTL_SETUP(sysctl_rtw, "sysctl rtw(4) subtree setup") 119{ 120 int rc; 121 struct sysctlnode *cnode, *rnode; 122 123 if ((rc = sysctl_createv(clog, 0, NULL, &rnode, 124 CTLFLAG_PERMANENT, CTLTYPE_NODE, "hw", NULL, 125 NULL, 0, NULL, 0, CTL_HW, CTL_EOL)) != 0) 126 goto err; 127 128 if ((rc = sysctl_createv(clog, 0, &rnode, &rnode, 129 CTLFLAG_PERMANENT, CTLTYPE_NODE, "rtw", 130 "Realtek RTL818x 802.11 controls", 131 NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0) 132 goto err; 133 134#ifdef RTW_DEBUG 135 /* control debugging printfs */ 136 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode, 137 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, 138 "debug", SYSCTL_DESCR("Enable RTL818x debugging output"), 139 rtw_sysctl_verify_debug, 0, &rtw_debug, 0, 140 CTL_CREATE, CTL_EOL)) != 0) 141 goto err; 142#endif /* RTW_DEBUG */ 143 /* set fallback RF programming method */ 144 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode, 145 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, 146 "rfprog_fallback", 147 SYSCTL_DESCR("Set fallback RF programming method"), 148 rtw_sysctl_verify_rfprog, 0, &rtw_rfprog_fallback, 0, 149 CTL_CREATE, CTL_EOL)) != 0) 150 goto err; 151 152 /* force host to control RF I/O bus */ 153 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode, 154 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, 155 "host_rfio", SYSCTL_DESCR("Enable host control of RF I/O"), 156 rtw_sysctl_verify_rfio, 0, &rtw_host_rfio, 0, 157 CTL_CREATE, CTL_EOL)) != 0) 158 goto err; 159 160 return; 161err: 162 printf("%s: sysctl_createv failed (rc = %d)\n", __func__, rc); 163} 164 165static int 166rtw_sysctl_verify(SYSCTLFN_ARGS, int lower, int upper) 167{ 168 int error, t; 169 struct sysctlnode node; 170 171 node = *rnode; 172 t = *(int*)rnode->sysctl_data; 173 node.sysctl_data = &t; 174 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 175 if (error || newp == NULL) 176 return (error); 177 178 if (t < lower || t > upper) 179 return (EINVAL); 180 181 *(int*)rnode->sysctl_data = t; 182 183 return (0); 184} 185 186static int 187rtw_sysctl_verify_rfprog(SYSCTLFN_ARGS) 188{ 189 return rtw_sysctl_verify(SYSCTLFN_CALL(rnode), 0, 190 MASK_AND_RSHIFT(RTW_CONFIG4_RFTYPE_MASK, RTW_CONFIG4_RFTYPE_MASK)); 191} 192 193static int 194rtw_sysctl_verify_rfio(SYSCTLFN_ARGS) 195{ 196 return rtw_sysctl_verify(SYSCTLFN_CALL(rnode), 0, 1); 197} 198 199#ifdef RTW_DEBUG 200static int 201rtw_sysctl_verify_debug(SYSCTLFN_ARGS) 202{ 203 return rtw_sysctl_verify(SYSCTLFN_CALL(rnode), 0, RTW_DEBUG_MAX); 204} 205 206static void 207rtw_print_regs(struct rtw_regs *regs, const char *dvname, const char *where) 208{ 209#define PRINTREG32(sc, reg) \ 210 RTW_DPRINTF(RTW_DEBUG_REGDUMP, \ 211 ("%s: reg[ " #reg " / %03x ] = %08x\n", \ 212 dvname, reg, RTW_READ(regs, reg))) 213 214#define PRINTREG16(sc, reg) \ 215 RTW_DPRINTF(RTW_DEBUG_REGDUMP, \ 216 ("%s: reg[ " #reg " / %03x ] = %04x\n", \ 217 dvname, reg, RTW_READ16(regs, reg))) 218 219#define PRINTREG8(sc, reg) \ 220 RTW_DPRINTF(RTW_DEBUG_REGDUMP, \ 221 ("%s: reg[ " #reg " / %03x ] = %02x\n", \ 222 dvname, reg, RTW_READ8(regs, reg))) 223 224 RTW_DPRINTF(RTW_DEBUG_REGDUMP, ("%s: %s\n", dvname, where)); 225 226 PRINTREG32(regs, RTW_IDR0); 227 PRINTREG32(regs, RTW_IDR1); 228 PRINTREG32(regs, RTW_MAR0); 229 PRINTREG32(regs, RTW_MAR1); 230 PRINTREG32(regs, RTW_TSFTRL); 231 PRINTREG32(regs, RTW_TSFTRH); 232 PRINTREG32(regs, RTW_TLPDA); 233 PRINTREG32(regs, RTW_TNPDA); 234 PRINTREG32(regs, RTW_THPDA); 235 PRINTREG32(regs, RTW_TCR); 236 PRINTREG32(regs, RTW_RCR); 237 PRINTREG32(regs, RTW_TINT); 238 PRINTREG32(regs, RTW_TBDA); 239 PRINTREG32(regs, RTW_ANAPARM); 240 PRINTREG32(regs, RTW_BB); 241 PRINTREG32(regs, RTW_PHYCFG); 242 PRINTREG32(regs, RTW_WAKEUP0L); 243 PRINTREG32(regs, RTW_WAKEUP0H); 244 PRINTREG32(regs, RTW_WAKEUP1L); 245 PRINTREG32(regs, RTW_WAKEUP1H); 246 PRINTREG32(regs, RTW_WAKEUP2LL); 247 PRINTREG32(regs, RTW_WAKEUP2LH); 248 PRINTREG32(regs, RTW_WAKEUP2HL); 249 PRINTREG32(regs, RTW_WAKEUP2HH); 250 PRINTREG32(regs, RTW_WAKEUP3LL); 251 PRINTREG32(regs, RTW_WAKEUP3LH); 252 PRINTREG32(regs, RTW_WAKEUP3HL); 253 PRINTREG32(regs, RTW_WAKEUP3HH); 254 PRINTREG32(regs, RTW_WAKEUP4LL); 255 PRINTREG32(regs, RTW_WAKEUP4LH); 256 PRINTREG32(regs, RTW_WAKEUP4HL); 257 PRINTREG32(regs, RTW_WAKEUP4HH); 258 PRINTREG32(regs, RTW_DK0); 259 PRINTREG32(regs, RTW_DK1); 260 PRINTREG32(regs, RTW_DK2); 261 PRINTREG32(regs, RTW_DK3); 262 PRINTREG32(regs, RTW_RETRYCTR); 263 PRINTREG32(regs, RTW_RDSAR); 264 PRINTREG32(regs, RTW_FER); 265 PRINTREG32(regs, RTW_FEMR); 266 PRINTREG32(regs, RTW_FPSR); 267 PRINTREG32(regs, RTW_FFER); 268 269 /* 16-bit registers */ 270 PRINTREG16(regs, RTW_BRSR); 271 PRINTREG16(regs, RTW_IMR); 272 PRINTREG16(regs, RTW_ISR); 273 PRINTREG16(regs, RTW_BCNITV); 274 PRINTREG16(regs, RTW_ATIMWND); 275 PRINTREG16(regs, RTW_BINTRITV); 276 PRINTREG16(regs, RTW_ATIMTRITV); 277 PRINTREG16(regs, RTW_CRC16ERR); 278 PRINTREG16(regs, RTW_CRC0); 279 PRINTREG16(regs, RTW_CRC1); 280 PRINTREG16(regs, RTW_CRC2); 281 PRINTREG16(regs, RTW_CRC3); 282 PRINTREG16(regs, RTW_CRC4); 283 PRINTREG16(regs, RTW_CWR); 284 285 /* 8-bit registers */ 286 PRINTREG8(regs, RTW_CR); 287 PRINTREG8(regs, RTW_9346CR); 288 PRINTREG8(regs, RTW_CONFIG0); 289 PRINTREG8(regs, RTW_CONFIG1); 290 PRINTREG8(regs, RTW_CONFIG2); 291 PRINTREG8(regs, RTW_MSR); 292 PRINTREG8(regs, RTW_CONFIG3); 293 PRINTREG8(regs, RTW_CONFIG4); 294 PRINTREG8(regs, RTW_TESTR); 295 PRINTREG8(regs, RTW_PSR); 296 PRINTREG8(regs, RTW_SCR); 297 PRINTREG8(regs, RTW_PHYDELAY); 298 PRINTREG8(regs, RTW_CRCOUNT); 299 PRINTREG8(regs, RTW_PHYADDR); 300 PRINTREG8(regs, RTW_PHYDATAW); 301 PRINTREG8(regs, RTW_PHYDATAR); 302 PRINTREG8(regs, RTW_CONFIG5); 303 PRINTREG8(regs, RTW_TPPOLL); 304 305 PRINTREG16(regs, RTW_BSSID16); 306 PRINTREG32(regs, RTW_BSSID32); 307#undef PRINTREG32 308#undef PRINTREG16 309#undef PRINTREG8 310} 311#endif /* RTW_DEBUG */ 312 313void 314rtw_continuous_tx_enable(struct rtw_softc *sc, int enable) 315{ 316 struct rtw_regs *regs = &sc->sc_regs; 317 318 u_int32_t tcr; 319 tcr = RTW_READ(regs, RTW_TCR); 320 tcr &= ~RTW_TCR_LBK_MASK; 321 if (enable) 322 tcr |= RTW_TCR_LBK_CONT; 323 else 324 tcr |= RTW_TCR_LBK_NORMAL; 325 RTW_WRITE(regs, RTW_TCR, tcr); 326 RTW_SYNC(regs, RTW_TCR, RTW_TCR); 327 rtw_set_access(sc, RTW_ACCESS_ANAPARM); 328 rtw_txdac_enable(sc, !enable); 329 rtw_set_access(sc, RTW_ACCESS_ANAPARM); /* XXX Voodoo from Linux. */ 330 rtw_set_access(sc, RTW_ACCESS_NONE); 331} 332 333#ifdef RTW_DEBUG 334static const char * 335rtw_access_string(enum rtw_access access) 336{ 337 switch (access) { 338 case RTW_ACCESS_NONE: 339 return "none"; 340 case RTW_ACCESS_CONFIG: 341 return "config"; 342 case RTW_ACCESS_ANAPARM: 343 return "anaparm"; 344 default: 345 return "unknown"; 346 } 347} 348#endif /* RTW_DEBUG */ 349 350static void 351rtw_set_access1(struct rtw_regs *regs, 352 enum rtw_access oaccess, enum rtw_access naccess) 353{ 354 KASSERT(naccess >= RTW_ACCESS_NONE && naccess <= RTW_ACCESS_ANAPARM); 355 KASSERT(oaccess >= RTW_ACCESS_NONE && oaccess <= RTW_ACCESS_ANAPARM); 356 357 if (naccess == oaccess) 358 return; 359 360 switch (naccess) { 361 case RTW_ACCESS_NONE: 362 switch (oaccess) { 363 case RTW_ACCESS_ANAPARM: 364 rtw_anaparm_enable(regs, 0); 365 /*FALLTHROUGH*/ 366 case RTW_ACCESS_CONFIG: 367 rtw_config0123_enable(regs, 0); 368 /*FALLTHROUGH*/ 369 case RTW_ACCESS_NONE: 370 break; 371 } 372 break; 373 case RTW_ACCESS_CONFIG: 374 switch (oaccess) { 375 case RTW_ACCESS_NONE: 376 rtw_config0123_enable(regs, 1); 377 /*FALLTHROUGH*/ 378 case RTW_ACCESS_CONFIG: 379 break; 380 case RTW_ACCESS_ANAPARM: 381 rtw_anaparm_enable(regs, 0); 382 break; 383 } 384 break; 385 case RTW_ACCESS_ANAPARM: 386 switch (oaccess) { 387 case RTW_ACCESS_NONE: 388 rtw_config0123_enable(regs, 1); 389 /*FALLTHROUGH*/ 390 case RTW_ACCESS_CONFIG: 391 rtw_anaparm_enable(regs, 1); 392 /*FALLTHROUGH*/ 393 case RTW_ACCESS_ANAPARM: 394 break; 395 } 396 break; 397 } 398} 399 400void 401rtw_set_access(struct rtw_softc *sc, enum rtw_access access) 402{ 403 rtw_set_access1(&sc->sc_regs, sc->sc_access, access); 404 RTW_DPRINTF(RTW_DEBUG_ACCESS, 405 ("%s: access %s -> %s\n", sc->sc_dev.dv_xname, 406 rtw_access_string(sc->sc_access), 407 rtw_access_string(access))); 408 sc->sc_access = access; 409} 410 411/* 412 * Enable registers, switch register banks. 413 */ 414void 415rtw_config0123_enable(struct rtw_regs *regs, int enable) 416{ 417 u_int8_t ecr; 418 ecr = RTW_READ8(regs, RTW_9346CR); 419 ecr &= ~(RTW_9346CR_EEM_MASK | RTW_9346CR_EECS | RTW_9346CR_EESK); 420 if (enable) 421 ecr |= RTW_9346CR_EEM_CONFIG; 422 else { 423 RTW_WBW(regs, RTW_9346CR, MAX(RTW_CONFIG0, RTW_CONFIG3)); 424 ecr |= RTW_9346CR_EEM_NORMAL; 425 } 426 RTW_WRITE8(regs, RTW_9346CR, ecr); 427 RTW_SYNC(regs, RTW_9346CR, RTW_9346CR); 428} 429 430/* requires rtw_config0123_enable(, 1) */ 431void 432rtw_anaparm_enable(struct rtw_regs *regs, int enable) 433{ 434 u_int8_t cfg3; 435 436 cfg3 = RTW_READ8(regs, RTW_CONFIG3); 437 cfg3 |= RTW_CONFIG3_CLKRUNEN; 438 if (enable) 439 cfg3 |= RTW_CONFIG3_PARMEN; 440 else 441 cfg3 &= ~RTW_CONFIG3_PARMEN; 442 RTW_WRITE8(regs, RTW_CONFIG3, cfg3); 443 RTW_SYNC(regs, RTW_CONFIG3, RTW_CONFIG3); 444} 445 446/* requires rtw_anaparm_enable(, 1) */ 447void 448rtw_txdac_enable(struct rtw_softc *sc, int enable) 449{ 450 u_int32_t anaparm; 451 struct rtw_regs *regs = &sc->sc_regs; 452 453 anaparm = RTW_READ(regs, RTW_ANAPARM); 454 if (enable) 455 anaparm &= ~RTW_ANAPARM_TXDACOFF; 456 else 457 anaparm |= RTW_ANAPARM_TXDACOFF; 458 RTW_WRITE(regs, RTW_ANAPARM, anaparm); 459 RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM); 460} 461 462static __inline int 463rtw_chip_reset1(struct rtw_regs *regs, const char *dvname) 464{ 465 u_int8_t cr; 466 int i; 467 468 RTW_WRITE8(regs, RTW_CR, RTW_CR_RST); 469 470 RTW_WBR(regs, RTW_CR, RTW_CR); 471 472 for (i = 0; i < 1000; i++) { 473 if ((cr = RTW_READ8(regs, RTW_CR) & RTW_CR_RST) == 0) { 474 RTW_DPRINTF(RTW_DEBUG_RESET, 475 ("%s: reset in %dus\n", dvname, i)); 476 return 0; 477 } 478 RTW_RBR(regs, RTW_CR, RTW_CR); 479 DELAY(10); /* 10us */ 480 } 481 482 printf("%s: reset failed\n", dvname); 483 return ETIMEDOUT; 484} 485 486static __inline int 487rtw_chip_reset(struct rtw_regs *regs, const char *dvname) 488{ 489 uint32_t tcr; 490 491 /* from Linux driver */ 492 tcr = RTW_TCR_CWMIN | RTW_TCR_MXDMA_2048 | 493 LSHIFT(7, RTW_TCR_SRL_MASK) | LSHIFT(7, RTW_TCR_LRL_MASK); 494 495 RTW_WRITE(regs, RTW_TCR, tcr); 496 497 RTW_WBW(regs, RTW_CR, RTW_TCR); 498 499 return rtw_chip_reset1(regs, dvname); 500} 501 502static __inline int 503rtw_recall_eeprom(struct rtw_regs *regs, const char *dvname) 504{ 505 int i; 506 u_int8_t ecr; 507 508 ecr = RTW_READ8(regs, RTW_9346CR); 509 ecr = (ecr & ~RTW_9346CR_EEM_MASK) | RTW_9346CR_EEM_AUTOLOAD; 510 RTW_WRITE8(regs, RTW_9346CR, ecr); 511 512 RTW_WBR(regs, RTW_9346CR, RTW_9346CR); 513 514 /* wait 2.5ms for completion */ 515 for (i = 0; i < 25; i++) { 516 ecr = RTW_READ8(regs, RTW_9346CR); 517 if ((ecr & RTW_9346CR_EEM_MASK) == RTW_9346CR_EEM_NORMAL) { 518 RTW_DPRINTF(RTW_DEBUG_RESET, 519 ("%s: recall EEPROM in %dus\n", dvname, i * 100)); 520 return 0; 521 } 522 RTW_RBR(regs, RTW_9346CR, RTW_9346CR); 523 DELAY(100); 524 } 525 printf("%s: recall EEPROM failed\n", dvname); 526 return ETIMEDOUT; 527} 528 529static __inline int 530rtw_reset(struct rtw_softc *sc) 531{ 532 int rc; 533 uint8_t config1; 534 535 if ((rc = rtw_chip_reset(&sc->sc_regs, sc->sc_dev.dv_xname)) != 0) 536 return rc; 537 538 if ((rc = rtw_recall_eeprom(&sc->sc_regs, sc->sc_dev.dv_xname)) != 0) 539 ; 540 541 config1 = RTW_READ8(&sc->sc_regs, RTW_CONFIG1); 542 RTW_WRITE8(&sc->sc_regs, RTW_CONFIG1, config1 & ~RTW_CONFIG1_PMEN); 543 /* TBD turn off maximum power saving? */ 544 545 return 0; 546} 547 548static __inline int 549rtw_txdesc_dmamaps_create(bus_dma_tag_t dmat, struct rtw_txctl *descs, 550 u_int ndescs) 551{ 552 int i, rc = 0; 553 for (i = 0; i < ndescs; i++) { 554 rc = bus_dmamap_create(dmat, MCLBYTES, RTW_MAXPKTSEGS, MCLBYTES, 555 0, 0, &descs[i].stx_dmamap); 556 if (rc != 0) 557 break; 558 } 559 return rc; 560} 561 562static __inline int 563rtw_rxdesc_dmamaps_create(bus_dma_tag_t dmat, struct rtw_rxctl *descs, 564 u_int ndescs) 565{ 566 int i, rc = 0; 567 for (i = 0; i < ndescs; i++) { 568 rc = bus_dmamap_create(dmat, MCLBYTES, 1, MCLBYTES, 0, 0, 569 &descs[i].srx_dmamap); 570 if (rc != 0) 571 break; 572 } 573 return rc; 574} 575 576static __inline void 577rtw_rxctls_setup(struct rtw_rxctl *descs) 578{ 579 int i; 580 for (i = 0; i < RTW_RXQLEN; i++) 581 descs[i].srx_mbuf = NULL; 582} 583 584static __inline void 585rtw_rxdesc_dmamaps_destroy(bus_dma_tag_t dmat, struct rtw_rxctl *descs, 586 u_int ndescs) 587{ 588 int i; 589 for (i = 0; i < ndescs; i++) { 590 if (descs[i].srx_dmamap != NULL) 591 bus_dmamap_destroy(dmat, descs[i].srx_dmamap); 592 } 593} 594 595static __inline void 596rtw_txdesc_dmamaps_destroy(bus_dma_tag_t dmat, struct rtw_txctl *descs, 597 u_int ndescs) 598{ 599 int i; 600 for (i = 0; i < ndescs; i++) { 601 if (descs[i].stx_dmamap != NULL) 602 bus_dmamap_destroy(dmat, descs[i].stx_dmamap); 603 } 604} 605 606static __inline void 607rtw_srom_free(struct rtw_srom *sr) 608{ 609 sr->sr_size = 0; 610 if (sr->sr_content == NULL) 611 return; 612 free(sr->sr_content, M_DEVBUF); 613 sr->sr_content = NULL; 614} 615 616static void 617rtw_srom_defaults(struct rtw_srom *sr, u_int32_t *flags, u_int8_t *cs_threshold, 618 enum rtw_rfchipid *rfchipid, u_int32_t *rcr) 619{ 620 *flags |= (RTW_F_DIGPHY|RTW_F_ANTDIV); 621 *cs_threshold = RTW_SR_ENERGYDETTHR_DEFAULT; 622 *rcr |= RTW_RCR_ENCS1; 623 *rfchipid = RTW_RFCHIPID_PHILIPS; 624} 625 626static int 627rtw_srom_parse(struct rtw_srom *sr, u_int32_t *flags, u_int8_t *cs_threshold, 628 enum rtw_rfchipid *rfchipid, u_int32_t *rcr, enum rtw_locale *locale, 629 const char *dvname) 630{ 631 int i; 632 const char *rfname, *paname; 633 char scratch[sizeof("unknown 0xXX")]; 634 u_int16_t version; 635 u_int8_t mac[IEEE80211_ADDR_LEN]; 636 637 *flags &= ~(RTW_F_DIGPHY|RTW_F_DFLANTB|RTW_F_ANTDIV); 638 *rcr &= ~(RTW_RCR_ENCS1 | RTW_RCR_ENCS2); 639 640 version = RTW_SR_GET16(sr, RTW_SR_VERSION); 641 printf("%s: SROM version %d.%d", dvname, version >> 8, version & 0xff); 642 643 if (version <= 0x0101) { 644 printf(" is not understood, limping along with defaults\n"); 645 rtw_srom_defaults(sr, flags, cs_threshold, rfchipid, rcr); 646 return 0; 647 } 648 printf("\n"); 649 650 for (i = 0; i < IEEE80211_ADDR_LEN; i++) 651 mac[i] = RTW_SR_GET(sr, RTW_SR_MAC + i); 652 653 RTW_DPRINTF(RTW_DEBUG_ATTACH, 654 ("%s: EEPROM MAC %s\n", dvname, ether_sprintf(mac))); 655 656 *cs_threshold = RTW_SR_GET(sr, RTW_SR_ENERGYDETTHR); 657 658 if ((RTW_SR_GET(sr, RTW_SR_CONFIG2) & RTW_CONFIG2_ANT) != 0) 659 *flags |= RTW_F_ANTDIV; 660 661 /* Note well: the sense of the RTW_SR_RFPARM_DIGPHY bit seems 662 * to be reversed. 663 */ 664 if ((RTW_SR_GET(sr, RTW_SR_RFPARM) & RTW_SR_RFPARM_DIGPHY) == 0) 665 *flags |= RTW_F_DIGPHY; 666 if ((RTW_SR_GET(sr, RTW_SR_RFPARM) & RTW_SR_RFPARM_DFLANTB) != 0) 667 *flags |= RTW_F_DFLANTB; 668 669 *rcr |= LSHIFT(MASK_AND_RSHIFT(RTW_SR_GET(sr, RTW_SR_RFPARM), 670 RTW_SR_RFPARM_CS_MASK), RTW_RCR_ENCS1); 671 672 *rfchipid = RTW_SR_GET(sr, RTW_SR_RFCHIPID); 673 switch (*rfchipid) { 674 case RTW_RFCHIPID_GCT: /* this combo seen in the wild */ 675 rfname = "GCT GRF5101"; 676 paname = "Winspring WS9901"; 677 break; 678 case RTW_RFCHIPID_MAXIM: 679 rfname = "Maxim MAX2820"; /* guess */ 680 paname = "Maxim MAX2422"; /* guess */ 681 break; 682 case RTW_RFCHIPID_INTERSIL: 683 rfname = "Intersil HFA3873"; /* guess */ 684 paname = "Intersil <unknown>"; 685 break; 686 case RTW_RFCHIPID_PHILIPS: /* this combo seen in the wild */ 687 rfname = "Philips SA2400A"; 688 paname = "Philips SA2411"; 689 break; 690 case RTW_RFCHIPID_RFMD: 691 /* this is the same front-end as an atw(4)! */ 692 rfname = "RFMD RF2948B, " /* mentioned in Realtek docs */ 693 "LNA: RFMD RF2494, " /* mentioned in Realtek docs */ 694 "SYN: Silicon Labs Si4126"; /* inferred from 695 * reference driver 696 */ 697 paname = "RFMD RF2189"; /* mentioned in Realtek docs */ 698 break; 699 case RTW_RFCHIPID_RESERVED: 700 rfname = paname = "reserved"; 701 break; 702 default: 703 snprintf(scratch, sizeof(scratch), "unknown 0x%02x", *rfchipid); 704 rfname = paname = scratch; 705 } 706 printf("%s: RF: %s, PA: %s\n", dvname, rfname, paname); 707 708 switch (RTW_SR_GET(sr, RTW_SR_CONFIG0) & RTW_CONFIG0_GL_MASK) { 709 case RTW_CONFIG0_GL_USA: 710 *locale = RTW_LOCALE_USA; 711 break; 712 case RTW_CONFIG0_GL_EUROPE: 713 *locale = RTW_LOCALE_EUROPE; 714 break; 715 case RTW_CONFIG0_GL_JAPAN: 716 *locale = RTW_LOCALE_JAPAN; 717 break; 718 default: 719 *locale = RTW_LOCALE_UNKNOWN; 720 break; 721 } 722 return 0; 723} 724 725/* Returns -1 on failure. */ 726static int 727rtw_srom_read(struct rtw_regs *regs, u_int32_t flags, struct rtw_srom *sr, 728 const char *dvname) 729{ 730 int rc; 731 struct seeprom_descriptor sd; 732 u_int8_t ecr; 733 734 (void)memset(&sd, 0, sizeof(sd)); 735 736 ecr = RTW_READ8(regs, RTW_9346CR); 737 738 if ((flags & RTW_F_9356SROM) != 0) { 739 RTW_DPRINTF(RTW_DEBUG_ATTACH, ("%s: 93c56 SROM\n", dvname)); 740 sr->sr_size = 256; 741 sd.sd_chip = C56_66; 742 } else { 743 RTW_DPRINTF(RTW_DEBUG_ATTACH, ("%s: 93c46 SROM\n", dvname)); 744 sr->sr_size = 128; 745 sd.sd_chip = C46; 746 } 747 748 ecr &= ~(RTW_9346CR_EEDI | RTW_9346CR_EEDO | RTW_9346CR_EESK | 749 RTW_9346CR_EEM_MASK); 750 ecr |= RTW_9346CR_EEM_PROGRAM; 751 752 RTW_WRITE8(regs, RTW_9346CR, ecr); 753 754 sr->sr_content = malloc(sr->sr_size, M_DEVBUF, M_NOWAIT); 755 756 if (sr->sr_content == NULL) { 757 printf("%s: unable to allocate SROM buffer\n", dvname); 758 return ENOMEM; 759 } 760 761 (void)memset(sr->sr_content, 0, sr->sr_size); 762 763 /* RTL8180 has a single 8-bit register for controlling the 764 * 93cx6 SROM. There is no "ready" bit. The RTL8180 765 * input/output sense is the reverse of read_seeprom's. 766 */ 767 sd.sd_tag = regs->r_bt; 768 sd.sd_bsh = regs->r_bh; 769 sd.sd_regsize = 1; 770 sd.sd_control_offset = RTW_9346CR; 771 sd.sd_status_offset = RTW_9346CR; 772 sd.sd_dataout_offset = RTW_9346CR; 773 sd.sd_CK = RTW_9346CR_EESK; 774 sd.sd_CS = RTW_9346CR_EECS; 775 sd.sd_DI = RTW_9346CR_EEDO; 776 sd.sd_DO = RTW_9346CR_EEDI; 777 /* make read_seeprom enter EEPROM read/write mode */ 778 sd.sd_MS = ecr; 779 sd.sd_RDY = 0; 780#if 0 781 sd.sd_clkdelay = 50; 782#endif 783 784 /* TBD bus barriers */ 785 if (!read_seeprom(&sd, sr->sr_content, 0, sr->sr_size/2)) { 786 printf("%s: could not read SROM\n", dvname); 787 free(sr->sr_content, M_DEVBUF); 788 sr->sr_content = NULL; 789 return -1; /* XXX */ 790 } 791 792 /* end EEPROM read/write mode */ 793 RTW_WRITE8(regs, RTW_9346CR, 794 (ecr & ~RTW_9346CR_EEM_MASK) | RTW_9346CR_EEM_NORMAL); 795 RTW_WBRW(regs, RTW_9346CR, RTW_9346CR); 796 797 if ((rc = rtw_recall_eeprom(regs, dvname)) != 0) 798 return rc; 799 800#ifdef RTW_DEBUG 801 { 802 int i; 803 RTW_DPRINTF(RTW_DEBUG_ATTACH, 804 ("\n%s: serial ROM:\n\t", dvname)); 805 for (i = 0; i < sr->sr_size/2; i++) { 806 if (((i % 8) == 0) && (i != 0)) 807 RTW_DPRINTF(RTW_DEBUG_ATTACH, ("\n\t")); 808 RTW_DPRINTF(RTW_DEBUG_ATTACH, 809 (" %04x", sr->sr_content[i])); 810 } 811 RTW_DPRINTF(RTW_DEBUG_ATTACH, ("\n")); 812 } 813#endif /* RTW_DEBUG */ 814 return 0; 815} 816 817static void 818rtw_set_rfprog(struct rtw_regs *regs, enum rtw_rfchipid rfchipid, 819 const char *dvname) 820{ 821 u_int8_t cfg4; 822 const char *method; 823 824 cfg4 = RTW_READ8(regs, RTW_CONFIG4) & ~RTW_CONFIG4_RFTYPE_MASK; 825 826 switch (rfchipid) { 827 default: 828 cfg4 |= LSHIFT(rtw_rfprog_fallback, RTW_CONFIG4_RFTYPE_MASK); 829 method = "fallback"; 830 break; 831 case RTW_RFCHIPID_INTERSIL: 832 cfg4 |= RTW_CONFIG4_RFTYPE_INTERSIL; 833 method = "Intersil"; 834 break; 835 case RTW_RFCHIPID_PHILIPS: 836 cfg4 |= RTW_CONFIG4_RFTYPE_PHILIPS; 837 method = "Philips"; 838 break; 839 case RTW_RFCHIPID_RFMD: 840 cfg4 |= RTW_CONFIG4_RFTYPE_RFMD; 841 method = "RFMD"; 842 break; 843 } 844 845 RTW_WRITE8(regs, RTW_CONFIG4, cfg4); 846 847 RTW_WBR(regs, RTW_CONFIG4, RTW_CONFIG4); 848 849 RTW_DPRINTF(RTW_DEBUG_INIT, 850 ("%s: %s RF programming method, %#02x\n", dvname, method, 851 RTW_READ8(regs, RTW_CONFIG4))); 852} 853 854#if 0 855static __inline int 856rtw_identify_rf(struct rtw_regs *regs, enum rtw_rftype *rftype, 857 const char *dvname) 858{ 859 u_int8_t cfg4; 860 const char *name; 861 862 cfg4 = RTW_READ8(regs, RTW_CONFIG4); 863 864 switch (cfg4 & RTW_CONFIG4_RFTYPE_MASK) { 865 case RTW_CONFIG4_RFTYPE_PHILIPS: 866 *rftype = RTW_RFTYPE_PHILIPS; 867 name = "Philips"; 868 break; 869 case RTW_CONFIG4_RFTYPE_INTERSIL: 870 *rftype = RTW_RFTYPE_INTERSIL; 871 name = "Intersil"; 872 break; 873 case RTW_CONFIG4_RFTYPE_RFMD: 874 *rftype = RTW_RFTYPE_RFMD; 875 name = "RFMD"; 876 break; 877 default: 878 name = "<unknown>"; 879 return ENXIO; 880 } 881 882 printf("%s: RF prog type %s\n", dvname, name); 883 return 0; 884} 885#endif 886 887static __inline void 888rtw_init_channels(enum rtw_locale locale, 889 struct ieee80211_channel (*chans)[IEEE80211_CHAN_MAX+1], 890 const char *dvname) 891{ 892 int i; 893 const char *name = NULL; 894#define ADD_CHANNEL(_chans, _chan) do { \ 895 (*_chans)[_chan].ic_flags = IEEE80211_CHAN_B; \ 896 (*_chans)[_chan].ic_freq = \ 897 ieee80211_ieee2mhz(_chan, (*_chans)[_chan].ic_flags);\ 898} while (0) 899 900 switch (locale) { 901 case RTW_LOCALE_USA: /* 1-11 */ 902 name = "USA"; 903 for (i = 1; i <= 11; i++) 904 ADD_CHANNEL(chans, i); 905 break; 906 case RTW_LOCALE_JAPAN: /* 1-14 */ 907 name = "Japan"; 908 ADD_CHANNEL(chans, 14); 909 for (i = 1; i <= 14; i++) 910 ADD_CHANNEL(chans, i); 911 break; 912 case RTW_LOCALE_EUROPE: /* 1-13 */ 913 name = "Europe"; 914 for (i = 1; i <= 13; i++) 915 ADD_CHANNEL(chans, i); 916 break; 917 default: /* 10-11 allowed by most countries */ 918 name = "<unknown>"; 919 for (i = 10; i <= 11; i++) 920 ADD_CHANNEL(chans, i); 921 break; 922 } 923 printf("%s: Geographic Location %s\n", dvname, name); 924#undef ADD_CHANNEL 925} 926 927static __inline void 928rtw_identify_country(struct rtw_regs *regs, enum rtw_locale *locale, 929 const char *dvname) 930{ 931 u_int8_t cfg0 = RTW_READ8(regs, RTW_CONFIG0); 932 933 switch (cfg0 & RTW_CONFIG0_GL_MASK) { 934 case RTW_CONFIG0_GL_USA: 935 *locale = RTW_LOCALE_USA; 936 break; 937 case RTW_CONFIG0_GL_JAPAN: 938 *locale = RTW_LOCALE_JAPAN; 939 break; 940 case RTW_CONFIG0_GL_EUROPE: 941 *locale = RTW_LOCALE_EUROPE; 942 break; 943 default: 944 *locale = RTW_LOCALE_UNKNOWN; 945 break; 946 } 947} 948 949static __inline int 950rtw_identify_sta(struct rtw_regs *regs, u_int8_t (*addr)[IEEE80211_ADDR_LEN], 951 const char *dvname) 952{ 953 static const u_int8_t empty_macaddr[IEEE80211_ADDR_LEN] = { 954 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 955 }; 956 u_int32_t idr0 = RTW_READ(regs, RTW_IDR0), 957 idr1 = RTW_READ(regs, RTW_IDR1); 958 959 (*addr)[0] = MASK_AND_RSHIFT(idr0, BITS(0, 7)); 960 (*addr)[1] = MASK_AND_RSHIFT(idr0, BITS(8, 15)); 961 (*addr)[2] = MASK_AND_RSHIFT(idr0, BITS(16, 23)); 962 (*addr)[3] = MASK_AND_RSHIFT(idr0, BITS(24 ,31)); 963 964 (*addr)[4] = MASK_AND_RSHIFT(idr1, BITS(0, 7)); 965 (*addr)[5] = MASK_AND_RSHIFT(idr1, BITS(8, 15)); 966 967 if (IEEE80211_ADDR_EQ(addr, empty_macaddr)) { 968 printf("%s: could not get mac address, attach failed\n", 969 dvname); 970 return ENXIO; 971 } 972 973 printf("%s: 802.11 address %s\n", dvname, ether_sprintf(*addr)); 974 975 return 0; 976} 977 978static u_int8_t 979rtw_chan2txpower(struct rtw_srom *sr, struct ieee80211com *ic, 980 struct ieee80211_channel *chan) 981{ 982 u_int idx = RTW_SR_TXPOWER1 + ieee80211_chan2ieee(ic, chan) - 1; 983 KASSERT2(idx >= RTW_SR_TXPOWER1 && idx <= RTW_SR_TXPOWER14, 984 ("%s: channel %d out of range", __func__, 985 idx - RTW_SR_TXPOWER1 + 1)); 986 return RTW_SR_GET(sr, idx); 987} 988 989static void 990rtw_txdesc_blk_init_all(struct rtw_txdesc_blk *htcs) 991{ 992 int pri; 993 u_int ndesc[RTW_NTXPRI] = 994 {RTW_NTXDESCLO, RTW_NTXDESCMD, RTW_NTXDESCHI, RTW_NTXDESCBCN}; 995 996 for (pri = 0; pri < RTW_NTXPRI; pri++) { 997 htcs[pri].htc_nfree = ndesc[pri]; 998 htcs[pri].htc_next = 0; 999 } 1000} 1001 1002static int 1003rtw_txctl_blk_init(struct rtw_txctl_blk *stc) 1004{ 1005 int i; 1006 struct rtw_txctl *stx; 1007 1008 SIMPLEQ_INIT(&stc->stc_dirtyq); 1009 SIMPLEQ_INIT(&stc->stc_freeq); 1010 for (i = 0; i < stc->stc_ndesc; i++) { 1011 stx = &stc->stc_desc[i]; 1012 stx->stx_mbuf = NULL; 1013 SIMPLEQ_INSERT_TAIL(&stc->stc_freeq, stx, stx_q); 1014 } 1015 return 0; 1016} 1017 1018static void 1019rtw_txctl_blk_init_all(struct rtw_txctl_blk *stcs) 1020{ 1021 int pri; 1022 for (pri = 0; pri < RTW_NTXPRI; pri++) 1023 rtw_txctl_blk_init(&stcs[pri]); 1024} 1025 1026static __inline void 1027rtw_rxdescs_sync(bus_dma_tag_t dmat, bus_dmamap_t dmap, u_int desc0, u_int 1028 nsync, int ops) 1029{ 1030 KASSERT(nsync <= RTW_RXQLEN); 1031 /* sync to end of ring */ 1032 if (desc0 + nsync > RTW_RXQLEN) { 1033 bus_dmamap_sync(dmat, dmap, 1034 offsetof(struct rtw_descs, hd_rx[desc0]), 1035 sizeof(struct rtw_rxdesc) * (RTW_RXQLEN - desc0), ops); 1036 nsync -= (RTW_RXQLEN - desc0); 1037 desc0 = 0; 1038 } 1039 1040 KASSERT(desc0 < RTW_RXQLEN); 1041 KASSERT(nsync <= RTW_RXQLEN); 1042 KASSERT(desc0 + nsync <= RTW_RXQLEN); 1043 1044 /* sync what remains */ 1045 bus_dmamap_sync(dmat, dmap, 1046 offsetof(struct rtw_descs, hd_rx[desc0]), 1047 sizeof(struct rtw_rxdesc) * nsync, ops); 1048} 1049 1050static void 1051rtw_txdescs_sync(bus_dma_tag_t dmat, bus_dmamap_t dmap, 1052 struct rtw_txdesc_blk *htc, u_int desc0, u_int nsync, int ops) 1053{ 1054 /* sync to end of ring */ 1055 if (desc0 + nsync > htc->htc_ndesc) { 1056 bus_dmamap_sync(dmat, dmap, 1057 htc->htc_ofs + sizeof(struct rtw_txdesc) * desc0, 1058 sizeof(struct rtw_txdesc) * (htc->htc_ndesc - desc0), 1059 ops); 1060 nsync -= (htc->htc_ndesc - desc0); 1061 desc0 = 0; 1062 } 1063 1064 /* sync what remains */ 1065 bus_dmamap_sync(dmat, dmap, 1066 htc->htc_ofs + sizeof(struct rtw_txdesc) * desc0, 1067 sizeof(struct rtw_txdesc) * nsync, ops); 1068} 1069 1070static void 1071rtw_txdescs_sync_all(bus_dma_tag_t dmat, bus_dmamap_t dmap, 1072 struct rtw_txdesc_blk *htcs) 1073{ 1074 int pri; 1075 for (pri = 0; pri < RTW_NTXPRI; pri++) { 1076 rtw_txdescs_sync(dmat, dmap, 1077 &htcs[pri], 0, htcs[pri].htc_ndesc, 1078 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 1079 } 1080} 1081 1082static void 1083rtw_rxbufs_release(bus_dma_tag_t dmat, struct rtw_rxctl *desc) 1084{ 1085 int i; 1086 struct rtw_rxctl *srx; 1087 1088 for (i = 0; i < RTW_RXQLEN; i++) { 1089 srx = &desc[i]; 1090 bus_dmamap_sync(dmat, srx->srx_dmamap, 0, 1091 srx->srx_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD); 1092 bus_dmamap_unload(dmat, srx->srx_dmamap); 1093 m_freem(srx->srx_mbuf); 1094 srx->srx_mbuf = NULL; 1095 } 1096} 1097 1098static __inline int 1099rtw_rxbuf_alloc(bus_dma_tag_t dmat, struct rtw_rxctl *srx) 1100{ 1101 int rc; 1102 struct mbuf *m; 1103 1104 MGETHDR(m, M_DONTWAIT, MT_DATA); 1105 if (m == NULL) 1106 return ENOBUFS; 1107 1108 MCLGET(m, M_DONTWAIT); 1109 if (m == NULL) 1110 return ENOBUFS; 1111 1112 m->m_pkthdr.len = m->m_len = m->m_ext.ext_size; 1113 1114 if (srx->srx_mbuf != NULL) 1115 bus_dmamap_unload(dmat, srx->srx_dmamap); 1116 1117 srx->srx_mbuf = NULL; 1118 1119 rc = bus_dmamap_load_mbuf(dmat, srx->srx_dmamap, m, BUS_DMA_NOWAIT); 1120 if (rc != 0) { 1121 m_freem(m); 1122 return -1; 1123 } 1124 1125 srx->srx_mbuf = m; 1126 1127 return 0; 1128} 1129 1130static int 1131rtw_rxctl_init_all(bus_dma_tag_t dmat, struct rtw_rxctl *desc, 1132 u_int *next, const char *dvname) 1133{ 1134 int i, rc; 1135 struct rtw_rxctl *srx; 1136 1137 for (i = 0; i < RTW_RXQLEN; i++) { 1138 srx = &desc[i]; 1139 if ((rc = rtw_rxbuf_alloc(dmat, srx)) == 0) 1140 continue; 1141 printf("%s: failed rtw_rxbuf_alloc after %d buffers, rc = %d\n", 1142 dvname, i, rc); 1143 if (i == 0) { 1144 rtw_rxbufs_release(dmat, desc); 1145 return rc; 1146 } 1147 } 1148 *next = 0; 1149 return 0; 1150} 1151 1152static __inline void 1153rtw_rxdesc_init(bus_dma_tag_t dmat, bus_dmamap_t dmam, 1154 struct rtw_rxdesc *hrx, struct rtw_rxctl *srx, int idx, int kick) 1155{ 1156 int is_last = (idx == RTW_RXQLEN - 1); 1157 uint32_t ctl, octl, obuf; 1158 1159 obuf = hrx->hrx_buf; 1160 hrx->hrx_buf = htole32(srx->srx_dmamap->dm_segs[0].ds_addr); 1161 1162 ctl = LSHIFT(srx->srx_mbuf->m_len, RTW_RXCTL_LENGTH_MASK) | 1163 RTW_RXCTL_OWN | RTW_RXCTL_FS | RTW_RXCTL_LS; 1164 1165 if (is_last) 1166 ctl |= RTW_RXCTL_EOR; 1167 1168 octl = hrx->hrx_ctl; 1169 hrx->hrx_ctl = htole32(ctl); 1170 1171 RTW_DPRINTF( 1172 kick ? (RTW_DEBUG_RECV_DESC | RTW_DEBUG_IO_KICK) 1173 : RTW_DEBUG_RECV_DESC, 1174 ("%s: hrx %p buf %08x -> %08x ctl %08x -> %08x\n", __func__, hrx, 1175 le32toh(obuf), le32toh(hrx->hrx_buf), le32toh(octl), 1176 le32toh(hrx->hrx_ctl))); 1177 1178 /* sync the mbuf */ 1179 bus_dmamap_sync(dmat, srx->srx_dmamap, 0, srx->srx_dmamap->dm_mapsize, 1180 BUS_DMASYNC_PREREAD); 1181 1182 /* sync the descriptor */ 1183 bus_dmamap_sync(dmat, dmam, RTW_DESC_OFFSET(hd_rx, idx), 1184 sizeof(struct rtw_rxdesc), 1185 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 1186} 1187 1188static void 1189rtw_rxdesc_init_all(bus_dma_tag_t dmat, bus_dmamap_t dmam, 1190 struct rtw_rxdesc *desc, struct rtw_rxctl *ctl, int kick) 1191{ 1192 int i; 1193 struct rtw_rxdesc *hrx; 1194 struct rtw_rxctl *srx; 1195 1196 for (i = 0; i < RTW_RXQLEN; i++) { 1197 hrx = &desc[i]; 1198 srx = &ctl[i]; 1199 rtw_rxdesc_init(dmat, dmam, hrx, srx, i, kick); 1200 } 1201} 1202 1203static void 1204rtw_io_enable(struct rtw_regs *regs, u_int8_t flags, int enable) 1205{ 1206 u_int8_t cr; 1207 1208 RTW_DPRINTF(RTW_DEBUG_IOSTATE, ("%s: %s 0x%02x\n", __func__, 1209 enable ? "enable" : "disable", flags)); 1210 1211 cr = RTW_READ8(regs, RTW_CR); 1212 1213 /* XXX reference source does not enable MULRW */ 1214#if 0 1215 /* enable PCI Read/Write Multiple */ 1216 cr |= RTW_CR_MULRW; 1217#endif 1218 1219 RTW_RBW(regs, RTW_CR, RTW_CR); /* XXX paranoia? */ 1220 if (enable) 1221 cr |= flags; 1222 else 1223 cr &= ~flags; 1224 RTW_WRITE8(regs, RTW_CR, cr); 1225 RTW_SYNC(regs, RTW_CR, RTW_CR); 1226} 1227 1228static void 1229rtw_intr_rx(struct rtw_softc *sc, u_int16_t isr) 1230{ 1231 static const int ratetbl[4] = {2, 4, 11, 22}; /* convert rates: 1232 * hardware -> net80211 1233 */ 1234 u_int next, nproc = 0; 1235 int hwrate, len, rate, rssi; 1236 u_int32_t hrssi, hstat, htsfth, htsftl; 1237 struct rtw_rxdesc *hrx; 1238 struct rtw_rxctl *srx; 1239 struct mbuf *m; 1240 1241 struct ieee80211_node *ni; 1242 struct ieee80211_frame *wh; 1243 1244 KASSERT(sc->sc_rxnext < RTW_RXQLEN); 1245 1246 for (next = sc->sc_rxnext; ; next = (next + 1) % RTW_RXQLEN) { 1247 rtw_rxdescs_sync(sc->sc_dmat, sc->sc_desc_dmamap, 1248 next, 1, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 1249 hrx = &sc->sc_rxdesc[next]; 1250 srx = &sc->sc_rxctl[next]; 1251 1252 hstat = le32toh(hrx->hrx_stat); 1253 hrssi = le32toh(hrx->hrx_rssi); 1254 htsfth = le32toh(hrx->hrx_tsfth); 1255 htsftl = le32toh(hrx->hrx_tsftl); 1256 1257 RTW_DPRINTF(RTW_DEBUG_RECV_DESC, 1258 ("%s: rxdesc[%d] hstat %08x hrssi %08x htsft %08x%08x\n", 1259 __func__, next, hstat, hrssi, htsfth, htsftl)); 1260 1261 KASSERT((hstat & (RTW_RXSTAT_FS|RTW_RXSTAT_LS)) == 1262 (RTW_RXSTAT_FS|RTW_RXSTAT_LS)); 1263 1264 ++nproc; 1265 1266 /* still belongs to NIC */ 1267 if ((hstat & RTW_RXSTAT_OWN) != 0) { 1268 if (nproc > 1) 1269 break; 1270 1271 /* sometimes the NIC skips to the 0th descriptor */ 1272 rtw_rxdescs_sync(sc->sc_dmat, sc->sc_desc_dmamap, 1273 0, 1, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 1274 hrx = &sc->sc_rxdesc[0]; 1275 if ((hrx->hrx_stat & htole32(RTW_RXSTAT_OWN)) != 0) 1276 break; 1277 RTW_DPRINTF(RTW_DEBUG_BUGS, 1278 ("%s: NIC skipped to rxdesc[0]\n", 1279 sc->sc_dev.dv_xname)); 1280 next = 0; 1281 continue; 1282 } 1283 1284 if ((hstat & RTW_RXSTAT_IOERROR) != 0) { 1285 printf("%s: DMA error/FIFO overflow %08x, " 1286 "rx descriptor %d\n", sc->sc_dev.dv_xname, 1287 hstat & RTW_RXSTAT_IOERROR, next); 1288 sc->sc_if.if_ierrors++; 1289 goto next; 1290 } 1291 1292 len = MASK_AND_RSHIFT(hstat, RTW_RXSTAT_LENGTH_MASK); 1293 if (len < IEEE80211_MIN_LEN) { 1294 sc->sc_ic.ic_stats.is_rx_tooshort++; 1295 goto next; 1296 } 1297 1298 hwrate = MASK_AND_RSHIFT(hstat, RTW_RXSTAT_RATE_MASK); 1299 if (hwrate >= sizeof(ratetbl) / sizeof(ratetbl[0])) { 1300 printf("%s: unknown rate #%d\n", sc->sc_dev.dv_xname, 1301 MASK_AND_RSHIFT(hstat, RTW_RXSTAT_RATE_MASK)); 1302 sc->sc_if.if_ierrors++; 1303 goto next; 1304 } 1305 rate = ratetbl[hwrate]; 1306 1307#ifdef RTW_DEBUG 1308#define PRINTSTAT(flag) do { \ 1309 if ((hstat & flag) != 0) { \ 1310 printf("%s" #flag, delim); \ 1311 delim = ","; \ 1312 } \ 1313} while (0) 1314 if ((rtw_debug & RTW_DEBUG_RECV_DESC) != 0) { 1315 const char *delim = "<"; 1316 printf("%s: ", sc->sc_dev.dv_xname); 1317 if ((hstat & RTW_RXSTAT_DEBUG) != 0) { 1318 printf("status %08x", hstat); 1319 PRINTSTAT(RTW_RXSTAT_SPLCP); 1320 PRINTSTAT(RTW_RXSTAT_MAR); 1321 PRINTSTAT(RTW_RXSTAT_PAR); 1322 PRINTSTAT(RTW_RXSTAT_BAR); 1323 PRINTSTAT(RTW_RXSTAT_PWRMGT); 1324 PRINTSTAT(RTW_RXSTAT_CRC32); 1325 PRINTSTAT(RTW_RXSTAT_ICV); 1326 printf(">, "); 1327 } 1328 printf("rate %d.%d Mb/s, time %08x%08x\n", 1329 (rate * 5) / 10, (rate * 5) % 10, htsfth, htsftl); 1330 } 1331#endif /* RTW_DEBUG */ 1332 1333 if ((hstat & RTW_RXSTAT_RES) != 0 && 1334 sc->sc_ic.ic_opmode != IEEE80211_M_MONITOR) 1335 goto next; 1336 1337 /* if bad flags, skip descriptor */ 1338 if ((hstat & RTW_RXSTAT_ONESEG) != RTW_RXSTAT_ONESEG) { 1339 printf("%s: too many rx segments\n", 1340 sc->sc_dev.dv_xname); 1341 goto next; 1342 } 1343 1344 bus_dmamap_sync(sc->sc_dmat, srx->srx_dmamap, 0, 1345 srx->srx_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD); 1346 1347 m = srx->srx_mbuf; 1348 1349 /* if temporarily out of memory, re-use mbuf */ 1350 switch (rtw_rxbuf_alloc(sc->sc_dmat, srx)) { 1351 case 0: 1352 break; 1353 case ENOBUFS: 1354 printf("%s: rtw_rxbuf_alloc(, %d) failed, " 1355 "dropping this packet\n", sc->sc_dev.dv_xname, 1356 next); 1357 goto next; 1358 default: 1359 /* XXX shorten rx ring, instead? */ 1360 panic("%s: could not load DMA map\n", 1361 sc->sc_dev.dv_xname); 1362 } 1363 1364 if (sc->sc_rfchipid == RTW_RFCHIPID_PHILIPS) 1365 rssi = MASK_AND_RSHIFT(hrssi, RTW_RXRSSI_RSSI); 1366 else { 1367 rssi = MASK_AND_RSHIFT(hrssi, RTW_RXRSSI_IMR_RSSI); 1368 /* TBD find out each front-end's LNA gain in the 1369 * front-end's units 1370 */ 1371 if ((hrssi & RTW_RXRSSI_IMR_LNA) == 0) 1372 rssi |= 0x80; 1373 } 1374 1375 m->m_pkthdr.rcvif = &sc->sc_if; 1376 m->m_pkthdr.len = m->m_len = len; 1377 m->m_flags |= M_HASFCS; 1378 1379 wh = mtod(m, struct ieee80211_frame *); 1380 /* TBD use _MAR, _BAR, _PAR flags as hints to _find_rxnode? */ 1381 ni = ieee80211_find_rxnode(&sc->sc_ic, wh); 1382 1383 sc->sc_tsfth = htsfth; 1384 1385#ifdef RTW_DEBUG 1386 if ((sc->sc_if.if_flags & (IFF_DEBUG|IFF_LINK2)) == 1387 (IFF_DEBUG|IFF_LINK2)) { 1388 ieee80211_dump_pkt(mtod(m, uint8_t *), m->m_pkthdr.len, 1389 rate, rssi); 1390 } 1391#endif /* RTW_DEBUG */ 1392 ieee80211_input(&sc->sc_if, m, ni, rssi, htsftl); 1393 ieee80211_release_node(&sc->sc_ic, ni); 1394next: 1395 rtw_rxdesc_init(sc->sc_dmat, sc->sc_desc_dmamap, 1396 hrx, srx, next, 0); 1397 } 1398 KASSERT(sc->sc_rxnext < RTW_RXQLEN); 1399 1400 sc->sc_rxnext = next; 1401 1402 return; 1403} 1404 1405static void 1406rtw_txbuf_release(bus_dma_tag_t dmat, struct ieee80211com *ic, 1407 struct rtw_txctl *stx) 1408{ 1409 struct mbuf *m; 1410 struct ieee80211_node *ni; 1411 1412 m = stx->stx_mbuf; 1413 ni = stx->stx_ni; 1414 KASSERT(m != NULL); 1415 KASSERT(ni != NULL); 1416 stx->stx_mbuf = NULL; 1417 stx->stx_ni = NULL; 1418 1419 bus_dmamap_sync(dmat, stx->stx_dmamap, 0, stx->stx_dmamap->dm_mapsize, 1420 BUS_DMASYNC_POSTWRITE); 1421 bus_dmamap_unload(dmat, stx->stx_dmamap); 1422 m_freem(m); 1423 ieee80211_release_node(ic, ni); 1424} 1425 1426static void 1427rtw_txbufs_release(bus_dma_tag_t dmat, bus_dmamap_t desc_dmamap, 1428 struct ieee80211com *ic, struct rtw_txctl_blk *stc) 1429{ 1430 struct rtw_txctl *stx; 1431 1432 while ((stx = SIMPLEQ_FIRST(&stc->stc_dirtyq)) != NULL) { 1433 rtw_txbuf_release(dmat, ic, stx); 1434 SIMPLEQ_REMOVE_HEAD(&stc->stc_dirtyq, stx_q); 1435 SIMPLEQ_INSERT_TAIL(&stc->stc_freeq, stx, stx_q); 1436 } 1437} 1438 1439static __inline void 1440rtw_collect_txpkt(struct rtw_softc *sc, struct rtw_txdesc_blk *htc, 1441 struct rtw_txctl *stx, int ndesc) 1442{ 1443 uint32_t hstat; 1444 int data_retry, rts_retry; 1445 struct rtw_txdesc *htxn; 1446 const char *condstring; 1447 1448 rtw_txbuf_release(sc->sc_dmat, &sc->sc_ic, stx); 1449 1450 htc->htc_nfree += ndesc; 1451 1452 htxn = &htc->htc_desc[stx->stx_last]; 1453 1454 hstat = le32toh(htxn->htx_stat); 1455 rts_retry = MASK_AND_RSHIFT(hstat, RTW_TXSTAT_RTSRETRY_MASK); 1456 data_retry = MASK_AND_RSHIFT(hstat, RTW_TXSTAT_DRC_MASK); 1457 1458 sc->sc_if.if_collisions += rts_retry + data_retry; 1459 1460 if ((hstat & RTW_TXSTAT_TOK) != 0) 1461 condstring = "ok"; 1462 else { 1463 sc->sc_if.if_oerrors++; 1464 condstring = "error"; 1465 } 1466 1467 DPRINTF(sc, RTW_DEBUG_XMIT_DESC, 1468 ("%s: stx %p txdesc[%d, %d] %s tries rts %u data %u\n", 1469 sc->sc_dev.dv_xname, stx, stx->stx_first, stx->stx_last, 1470 condstring, rts_retry, data_retry)); 1471} 1472 1473/* Collect transmitted packets. */ 1474static __inline void 1475rtw_collect_txring(struct rtw_softc *sc, struct rtw_txctl_blk *stc, 1476 struct rtw_txdesc_blk *htc) 1477{ 1478 int ndesc; 1479 struct rtw_txctl *stx; 1480 1481 while ((stx = SIMPLEQ_FIRST(&stc->stc_dirtyq)) != NULL) { 1482 ndesc = 1 + stx->stx_last - stx->stx_first; 1483 if (stx->stx_last < stx->stx_first) 1484 ndesc += htc->htc_ndesc; 1485 1486 KASSERT(ndesc > 0); 1487 1488 rtw_txdescs_sync(sc->sc_dmat, sc->sc_desc_dmamap, htc, 1489 stx->stx_first, ndesc, 1490 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 1491 1492 if ((htc->htc_desc[stx->stx_last].htx_stat & 1493 htole32(RTW_TXSTAT_OWN)) != 0) 1494 break; 1495 1496 rtw_collect_txpkt(sc, htc, stx, ndesc); 1497 SIMPLEQ_REMOVE_HEAD(&stc->stc_dirtyq, stx_q); 1498 SIMPLEQ_INSERT_TAIL(&stc->stc_freeq, stx, stx_q); 1499 sc->sc_if.if_flags &= ~IFF_OACTIVE; 1500 } 1501 if (stx == NULL) 1502 stc->stc_tx_timer = 0; 1503} 1504 1505static void 1506rtw_intr_tx(struct rtw_softc *sc, u_int16_t isr) 1507{ 1508 int pri; 1509 struct rtw_txctl_blk *stc; 1510 struct rtw_txdesc_blk *htc; 1511 1512 for (pri = 0; pri < RTW_NTXPRI; pri++) { 1513 stc = &sc->sc_txctl_blk[pri]; 1514 htc = &sc->sc_txdesc_blk[pri]; 1515 1516 rtw_collect_txring(sc, stc, htc); 1517 1518 if ((isr & RTW_INTR_TX) != 0) 1519 rtw_start(&sc->sc_if); 1520 } 1521 1522 /* TBD */ 1523 return; 1524} 1525 1526static void 1527rtw_intr_beacon(struct rtw_softc *sc, u_int16_t isr) 1528{ 1529 /* TBD */ 1530 return; 1531} 1532 1533static void 1534rtw_intr_atim(struct rtw_softc *sc) 1535{ 1536 /* TBD */ 1537 return; 1538} 1539 1540#ifdef RTW_DEBUG 1541static void 1542rtw_dump_rings(struct rtw_softc *sc) 1543{ 1544 struct rtw_txdesc_blk *htc; 1545 struct rtw_rxdesc *hrx; 1546 int desc, pri; 1547 1548 if ((rtw_debug & RTW_DEBUG_IO_KICK) == 0) 1549 return; 1550 1551 for (pri = 0; pri < RTW_NTXPRI; pri++) { 1552 htc = &sc->sc_txdesc_blk[pri]; 1553 printf("%s: txpri %d ndesc %d nfree %d\n", __func__, pri, 1554 htc->htc_ndesc, htc->htc_nfree); 1555 for (desc = 0; desc < htc->htc_ndesc; desc++) 1556 rtw_print_txdesc(sc, ".", NULL, htc, desc); 1557 } 1558 1559 for (desc = 0; desc < RTW_RXQLEN; desc++) { 1560 hrx = &sc->sc_rxdesc[desc]; 1561 printf("%s: ctl %08x rsvd0/rssi %08x buf/tsftl %08x " 1562 "rsvd1/tsfth %08x\n", __func__, 1563 le32toh(hrx->hrx_ctl), le32toh(hrx->hrx_rssi), 1564 le32toh(hrx->hrx_buf), le32toh(hrx->hrx_tsfth)); 1565 } 1566} 1567#endif /* RTW_DEBUG */ 1568 1569static void 1570rtw_hwring_setup(struct rtw_softc *sc) 1571{ 1572 struct rtw_regs *regs = &sc->sc_regs; 1573 RTW_WRITE(regs, RTW_RDSAR, RTW_RING_BASE(sc, hd_rx)); 1574 RTW_WRITE(regs, RTW_TLPDA, RTW_RING_BASE(sc, hd_txlo)); 1575 RTW_WRITE(regs, RTW_TNPDA, RTW_RING_BASE(sc, hd_txmd)); 1576 RTW_WRITE(regs, RTW_THPDA, RTW_RING_BASE(sc, hd_txhi)); 1577 RTW_WRITE(regs, RTW_TBDA, RTW_RING_BASE(sc, hd_bcn)); 1578 RTW_SYNC(regs, RTW_TLPDA, RTW_RDSAR); 1579 RTW_DPRINTF(RTW_DEBUG_XMIT_DESC, 1580 ("%s: reg[TLPDA] <- %" PRIxPTR "\n", __func__, 1581 (uintptr_t)RTW_RING_BASE(sc, hd_txlo))); 1582 RTW_DPRINTF(RTW_DEBUG_XMIT_DESC, 1583 ("%s: reg[TNPDA] <- %" PRIxPTR "\n", __func__, 1584 (uintptr_t)RTW_RING_BASE(sc, hd_txmd))); 1585 RTW_DPRINTF(RTW_DEBUG_XMIT_DESC, 1586 ("%s: reg[THPDA] <- %" PRIxPTR "\n", __func__, 1587 (uintptr_t)RTW_RING_BASE(sc, hd_txhi))); 1588 RTW_DPRINTF(RTW_DEBUG_XMIT_DESC, 1589 ("%s: reg[TBDA] <- %" PRIxPTR "\n", __func__, 1590 (uintptr_t)RTW_RING_BASE(sc, hd_bcn))); 1591 RTW_DPRINTF(RTW_DEBUG_RECV_DESC, 1592 ("%s: reg[RDSAR] <- %" PRIxPTR "\n", __func__, 1593 (uintptr_t)RTW_RING_BASE(sc, hd_rx))); 1594} 1595 1596static void 1597rtw_swring_setup(struct rtw_softc *sc) 1598{ 1599 rtw_txdesc_blk_init_all(&sc->sc_txdesc_blk[0]); 1600 1601 rtw_txctl_blk_init_all(&sc->sc_txctl_blk[0]); 1602 1603 rtw_rxdescs_sync(sc->sc_dmat, sc->sc_desc_dmamap, 1604 0, RTW_RXQLEN, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 1605 rtw_rxctl_init_all(sc->sc_dmat, sc->sc_rxctl, &sc->sc_rxnext, 1606 sc->sc_dev.dv_xname); 1607 rtw_rxdesc_init_all(sc->sc_dmat, sc->sc_desc_dmamap, 1608 sc->sc_rxdesc, sc->sc_rxctl, 1); 1609 1610 rtw_txdescs_sync_all(sc->sc_dmat, sc->sc_desc_dmamap, 1611 &sc->sc_txdesc_blk[0]); 1612#if 0 /* redundant with rtw_rxdesc_init_all */ 1613 rtw_rxdescs_sync(sc->sc_dmat, sc->sc_desc_dmamap, 1614 0, RTW_RXQLEN, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 1615#endif 1616} 1617 1618static void 1619rtw_txdesc_blk_reset(struct rtw_txdesc_blk *htc) 1620{ 1621 int i; 1622 1623 (void)memset(htc->htc_desc, 0, 1624 sizeof(htc->htc_desc[0]) * htc->htc_ndesc); 1625 for (i = 0; i < htc->htc_ndesc; i++) 1626 htc->htc_desc[i].htx_next = htole32(RTW_NEXT_DESC(htc, i)); 1627 htc->htc_nfree = htc->htc_ndesc; 1628 htc->htc_next = 0; 1629} 1630 1631static void 1632rtw_txdescs_reset(struct rtw_softc *sc) 1633{ 1634 int pri; 1635 struct rtw_txdesc_blk *htc; 1636 1637 for (pri = 0; pri < RTW_NTXPRI; pri++) { 1638 htc = &sc->sc_txdesc_blk[pri]; 1639 rtw_txbufs_release(sc->sc_dmat, sc->sc_desc_dmamap, &sc->sc_ic, 1640 &sc->sc_txctl_blk[pri]); 1641 rtw_txdesc_blk_reset(htc); 1642 rtw_txdescs_sync(sc->sc_dmat, sc->sc_desc_dmamap, htc, 1643 0, htc->htc_ndesc, 1644 BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD); 1645 } 1646} 1647 1648static void 1649rtw_rxdescs_reset(struct rtw_softc *sc) 1650{ 1651 /* Re-initialize descriptors, just in case. */ 1652 rtw_rxdesc_init_all(sc->sc_dmat, sc->sc_desc_dmamap, sc->sc_rxdesc, 1653 &sc->sc_rxctl[0], 1); 1654 1655 /* Reset to start of ring. */ 1656 sc->sc_rxnext = 0; 1657} 1658 1659static void 1660rtw_intr_ioerror(struct rtw_softc *sc, uint16_t isr) 1661{ 1662 struct rtw_regs *regs = &sc->sc_regs; 1663 1664 if ((isr & RTW_INTR_TXFOVW) != 0) 1665 printf("%s: tx fifo overflow\n", sc->sc_dev.dv_xname); 1666 1667 if ((isr & (RTW_INTR_RDU|RTW_INTR_RXFOVW)) == 0) 1668 return; 1669 1670 RTW_DPRINTF(RTW_DEBUG_BUGS, ("%s: restarting xmit/recv\n", 1671 sc->sc_dev.dv_xname)); 1672 1673#ifdef RTW_DEBUG 1674 rtw_dump_rings(sc); 1675#endif /* RTW_DEBUG */ 1676 1677 rtw_io_enable(regs, RTW_CR_RE | RTW_CR_TE, 0); 1678 1679 /* Collect rx'd packets. Refresh rx buffers. */ 1680 rtw_intr_rx(sc, 0); 1681 /* Collect tx'd packets. */ 1682 rtw_intr_tx(sc, 0); 1683 1684 RTW_WRITE16(regs, RTW_IMR, 0); 1685 RTW_SYNC(regs, RTW_IMR, RTW_IMR); 1686 1687 rtw_chip_reset1(regs, sc->sc_dev.dv_xname); 1688 1689 rtw_rxdescs_reset(sc); 1690 rtw_txdescs_reset(sc); 1691 1692 rtw_hwring_setup(sc); 1693 1694#ifdef RTW_DEBUG 1695 rtw_dump_rings(sc); 1696#endif /* RTW_DEBUG */ 1697 1698 RTW_WRITE16(regs, RTW_IMR, sc->sc_inten); 1699 RTW_SYNC(regs, RTW_IMR, RTW_IMR); 1700 rtw_io_enable(regs, RTW_CR_RE | RTW_CR_TE, 1); 1701} 1702 1703static __inline void 1704rtw_suspend_ticks(struct rtw_softc *sc) 1705{ 1706 RTW_DPRINTF(RTW_DEBUG_TIMEOUT, 1707 ("%s: suspending ticks\n", sc->sc_dev.dv_xname)); 1708 sc->sc_do_tick = 0; 1709} 1710 1711static __inline void 1712rtw_resume_ticks(struct rtw_softc *sc) 1713{ 1714 u_int32_t tsftrl0, tsftrl1, next_tick; 1715 1716 tsftrl0 = RTW_READ(&sc->sc_regs, RTW_TSFTRL); 1717 1718 tsftrl1 = RTW_READ(&sc->sc_regs, RTW_TSFTRL); 1719 next_tick = tsftrl1 + 1000000; 1720 RTW_WRITE(&sc->sc_regs, RTW_TINT, next_tick); 1721 1722 sc->sc_do_tick = 1; 1723 1724 RTW_DPRINTF(RTW_DEBUG_TIMEOUT, 1725 ("%s: resume ticks delta %#08x now %#08x next %#08x\n", 1726 sc->sc_dev.dv_xname, tsftrl1 - tsftrl0, tsftrl1, next_tick)); 1727} 1728 1729static void 1730rtw_intr_timeout(struct rtw_softc *sc) 1731{ 1732 RTW_DPRINTF(RTW_DEBUG_TIMEOUT, ("%s: timeout\n", sc->sc_dev.dv_xname)); 1733 if (sc->sc_do_tick) 1734 rtw_resume_ticks(sc); 1735 return; 1736} 1737 1738int 1739rtw_intr(void *arg) 1740{ 1741 int i; 1742 struct rtw_softc *sc = arg; 1743 struct rtw_regs *regs = &sc->sc_regs; 1744 u_int16_t isr; 1745 1746 /* 1747 * If the interface isn't running, the interrupt couldn't 1748 * possibly have come from us. 1749 */ 1750 if ((sc->sc_flags & RTW_F_ENABLED) == 0 || 1751 (sc->sc_if.if_flags & IFF_RUNNING) == 0 || 1752 (sc->sc_dev.dv_flags & DVF_ACTIVE) == 0) { 1753 RTW_DPRINTF(RTW_DEBUG_INTR, ("%s: stray interrupt\n", sc->sc_dev.dv_xname)); 1754 return (0); 1755 } 1756 1757 for (i = 0; i < 10; i++) { 1758 isr = RTW_READ16(regs, RTW_ISR); 1759 1760 RTW_WRITE16(regs, RTW_ISR, isr); 1761 RTW_WBR(regs, RTW_ISR, RTW_ISR); 1762 1763 if (sc->sc_intr_ack != NULL) 1764 (*sc->sc_intr_ack)(regs); 1765 1766 if (isr == 0) 1767 break; 1768 1769#ifdef RTW_DEBUG 1770#define PRINTINTR(flag) do { \ 1771 if ((isr & flag) != 0) { \ 1772 printf("%s" #flag, delim); \ 1773 delim = ","; \ 1774 } \ 1775} while (0) 1776 1777 if ((rtw_debug & RTW_DEBUG_INTR) != 0 && isr != 0) { 1778 const char *delim = "<"; 1779 1780 printf("%s: reg[ISR] = %x", sc->sc_dev.dv_xname, isr); 1781 1782 PRINTINTR(RTW_INTR_TXFOVW); 1783 PRINTINTR(RTW_INTR_TIMEOUT); 1784 PRINTINTR(RTW_INTR_BCNINT); 1785 PRINTINTR(RTW_INTR_ATIMINT); 1786 PRINTINTR(RTW_INTR_TBDER); 1787 PRINTINTR(RTW_INTR_TBDOK); 1788 PRINTINTR(RTW_INTR_THPDER); 1789 PRINTINTR(RTW_INTR_THPDOK); 1790 PRINTINTR(RTW_INTR_TNPDER); 1791 PRINTINTR(RTW_INTR_TNPDOK); 1792 PRINTINTR(RTW_INTR_RXFOVW); 1793 PRINTINTR(RTW_INTR_RDU); 1794 PRINTINTR(RTW_INTR_TLPDER); 1795 PRINTINTR(RTW_INTR_TLPDOK); 1796 PRINTINTR(RTW_INTR_RER); 1797 PRINTINTR(RTW_INTR_ROK); 1798 1799 printf(">\n"); 1800 } 1801#undef PRINTINTR 1802#endif /* RTW_DEBUG */ 1803 1804 if ((isr & RTW_INTR_RX) != 0) 1805 rtw_intr_rx(sc, isr & RTW_INTR_RX); 1806 if ((isr & RTW_INTR_TX) != 0) 1807 rtw_intr_tx(sc, isr & RTW_INTR_TX); 1808 if ((isr & RTW_INTR_BEACON) != 0) 1809 rtw_intr_beacon(sc, isr & RTW_INTR_BEACON); 1810 if ((isr & RTW_INTR_ATIMINT) != 0) 1811 rtw_intr_atim(sc); 1812 if ((isr & RTW_INTR_IOERROR) != 0) 1813 rtw_intr_ioerror(sc, isr & RTW_INTR_IOERROR); 1814 if ((isr & RTW_INTR_TIMEOUT) != 0) 1815 rtw_intr_timeout(sc); 1816 } 1817 1818 return 1; 1819} 1820 1821/* Must be called at splnet. */ 1822static void 1823rtw_stop(struct ifnet *ifp, int disable) 1824{ 1825 int pri; 1826 struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc; 1827 struct ieee80211com *ic = &sc->sc_ic; 1828 struct rtw_regs *regs = &sc->sc_regs; 1829 1830 if ((sc->sc_flags & RTW_F_ENABLED) == 0) 1831 return; 1832 1833 rtw_suspend_ticks(sc); 1834 1835 ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 1836 1837 if ((sc->sc_flags & RTW_F_INVALID) == 0) { 1838 /* Disable interrupts. */ 1839 RTW_WRITE16(regs, RTW_IMR, 0); 1840 1841 RTW_WBW(regs, RTW_TPPOLL, RTW_IMR); 1842 1843 /* Stop the transmit and receive processes. First stop DMA, 1844 * then disable receiver and transmitter. 1845 */ 1846 RTW_WRITE8(regs, RTW_TPPOLL, 1847 RTW_TPPOLL_SBQ|RTW_TPPOLL_SHPQ|RTW_TPPOLL_SNPQ| 1848 RTW_TPPOLL_SLPQ); 1849 1850 RTW_SYNC(regs, RTW_TPPOLL, RTW_IMR); 1851 1852 rtw_io_enable(&sc->sc_regs, RTW_CR_RE|RTW_CR_TE, 0); 1853 } 1854 1855 for (pri = 0; pri < RTW_NTXPRI; pri++) { 1856 rtw_txbufs_release(sc->sc_dmat, sc->sc_desc_dmamap, &sc->sc_ic, 1857 &sc->sc_txctl_blk[pri]); 1858 } 1859 1860 if (disable) { 1861 rtw_disable(sc); 1862 rtw_rxbufs_release(sc->sc_dmat, &sc->sc_rxctl[0]); 1863 } 1864 1865 /* Mark the interface as not running. Cancel the watchdog timer. */ 1866 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 1867 ifp->if_timer = 0; 1868 1869 return; 1870} 1871 1872const char * 1873rtw_pwrstate_string(enum rtw_pwrstate power) 1874{ 1875 switch (power) { 1876 case RTW_ON: 1877 return "on"; 1878 case RTW_SLEEP: 1879 return "sleep"; 1880 case RTW_OFF: 1881 return "off"; 1882 default: 1883 return "unknown"; 1884 } 1885} 1886 1887/* XXX For Maxim, I am using the RFMD settings gleaned from the 1888 * reference driver, plus a magic Maxim "ON" value that comes from 1889 * the Realtek document "Windows PG for Rtl8180." 1890 */ 1891static void 1892rtw_maxim_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power, 1893 int before_rf, int digphy) 1894{ 1895 u_int32_t anaparm; 1896 1897 anaparm = RTW_READ(regs, RTW_ANAPARM); 1898 anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF); 1899 1900 switch (power) { 1901 case RTW_OFF: 1902 if (before_rf) 1903 return; 1904 anaparm |= RTW_ANAPARM_RFPOW_MAXIM_OFF; 1905 anaparm |= RTW_ANAPARM_TXDACOFF; 1906 break; 1907 case RTW_SLEEP: 1908 if (!before_rf) 1909 return; 1910 anaparm |= RTW_ANAPARM_RFPOW_MAXIM_SLEEP; 1911 anaparm |= RTW_ANAPARM_TXDACOFF; 1912 break; 1913 case RTW_ON: 1914 if (!before_rf) 1915 return; 1916 anaparm |= RTW_ANAPARM_RFPOW_MAXIM_ON; 1917 break; 1918 } 1919 RTW_DPRINTF(RTW_DEBUG_PWR, 1920 ("%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n", 1921 __func__, rtw_pwrstate_string(power), 1922 (before_rf) ? "before" : "after", anaparm)); 1923 1924 RTW_WRITE(regs, RTW_ANAPARM, anaparm); 1925 RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM); 1926} 1927 1928/* XXX I am using the RFMD settings gleaned from the reference 1929 * driver. They agree 1930 */ 1931static void 1932rtw_rfmd_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power, 1933 int before_rf, int digphy) 1934{ 1935 u_int32_t anaparm; 1936 1937 anaparm = RTW_READ(regs, RTW_ANAPARM); 1938 anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF); 1939 1940 switch (power) { 1941 case RTW_OFF: 1942 if (before_rf) 1943 return; 1944 anaparm |= RTW_ANAPARM_RFPOW_RFMD_OFF; 1945 anaparm |= RTW_ANAPARM_TXDACOFF; 1946 break; 1947 case RTW_SLEEP: 1948 if (!before_rf) 1949 return; 1950 anaparm |= RTW_ANAPARM_RFPOW_RFMD_SLEEP; 1951 anaparm |= RTW_ANAPARM_TXDACOFF; 1952 break; 1953 case RTW_ON: 1954 if (!before_rf) 1955 return; 1956 anaparm |= RTW_ANAPARM_RFPOW_RFMD_ON; 1957 break; 1958 } 1959 RTW_DPRINTF(RTW_DEBUG_PWR, 1960 ("%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n", 1961 __func__, rtw_pwrstate_string(power), 1962 (before_rf) ? "before" : "after", anaparm)); 1963 1964 RTW_WRITE(regs, RTW_ANAPARM, anaparm); 1965 RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM); 1966} 1967 1968static void 1969rtw_philips_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power, 1970 int before_rf, int digphy) 1971{ 1972 u_int32_t anaparm; 1973 1974 anaparm = RTW_READ(regs, RTW_ANAPARM); 1975 anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF); 1976 1977 switch (power) { 1978 case RTW_OFF: 1979 if (before_rf) 1980 return; 1981 anaparm |= RTW_ANAPARM_RFPOW_PHILIPS_OFF; 1982 anaparm |= RTW_ANAPARM_TXDACOFF; 1983 break; 1984 case RTW_SLEEP: 1985 if (!before_rf) 1986 return; 1987 anaparm |= RTW_ANAPARM_RFPOW_PHILIPS_SLEEP; 1988 anaparm |= RTW_ANAPARM_TXDACOFF; 1989 break; 1990 case RTW_ON: 1991 if (!before_rf) 1992 return; 1993 if (digphy) { 1994 anaparm |= RTW_ANAPARM_RFPOW_DIG_PHILIPS_ON; 1995 /* XXX guess */ 1996 anaparm |= RTW_ANAPARM_TXDACOFF; 1997 } else 1998 anaparm |= RTW_ANAPARM_RFPOW_ANA_PHILIPS_ON; 1999 break; 2000 } 2001 RTW_DPRINTF(RTW_DEBUG_PWR, 2002 ("%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n", 2003 __func__, rtw_pwrstate_string(power), 2004 (before_rf) ? "before" : "after", anaparm)); 2005 2006 RTW_WRITE(regs, RTW_ANAPARM, anaparm); 2007 RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM); 2008} 2009 2010static void 2011rtw_pwrstate0(struct rtw_softc *sc, enum rtw_pwrstate power, int before_rf, 2012 int digphy) 2013{ 2014 struct rtw_regs *regs = &sc->sc_regs; 2015 2016 rtw_set_access(sc, RTW_ACCESS_ANAPARM); 2017 2018 (*sc->sc_pwrstate_cb)(regs, power, before_rf, digphy); 2019 2020 rtw_set_access(sc, RTW_ACCESS_NONE); 2021 2022 return; 2023} 2024 2025static int 2026rtw_pwrstate(struct rtw_softc *sc, enum rtw_pwrstate power) 2027{ 2028 int rc; 2029 2030 RTW_DPRINTF(RTW_DEBUG_PWR, 2031 ("%s: %s->%s\n", __func__, 2032 rtw_pwrstate_string(sc->sc_pwrstate), rtw_pwrstate_string(power))); 2033 2034 if (sc->sc_pwrstate == power) 2035 return 0; 2036 2037 rtw_pwrstate0(sc, power, 1, sc->sc_flags & RTW_F_DIGPHY); 2038 rc = rtw_rf_pwrstate(sc->sc_rf, power); 2039 rtw_pwrstate0(sc, power, 0, sc->sc_flags & RTW_F_DIGPHY); 2040 2041 switch (power) { 2042 case RTW_ON: 2043 /* TBD set LEDs */ 2044 break; 2045 case RTW_SLEEP: 2046 /* TBD */ 2047 break; 2048 case RTW_OFF: 2049 /* TBD */ 2050 break; 2051 } 2052 if (rc == 0) 2053 sc->sc_pwrstate = power; 2054 else 2055 sc->sc_pwrstate = RTW_OFF; 2056 return rc; 2057} 2058 2059static int 2060rtw_tune(struct rtw_softc *sc) 2061{ 2062 struct ieee80211com *ic = &sc->sc_ic; 2063 u_int chan; 2064 int rc; 2065 int antdiv = sc->sc_flags & RTW_F_ANTDIV, 2066 dflantb = sc->sc_flags & RTW_F_DFLANTB; 2067 2068 KASSERT(ic->ic_bss->ni_chan != NULL); 2069 2070 chan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan); 2071 if (chan == IEEE80211_CHAN_ANY) 2072 panic("%s: chan == IEEE80211_CHAN_ANY\n", __func__); 2073 2074 if (chan == sc->sc_cur_chan) { 2075 RTW_DPRINTF(RTW_DEBUG_TUNE, 2076 ("%s: already tuned chan #%d\n", __func__, chan)); 2077 return 0; 2078 } 2079 2080 rtw_suspend_ticks(sc); 2081 2082 rtw_io_enable(&sc->sc_regs, RTW_CR_RE | RTW_CR_TE, 0); 2083 2084 /* TBD wait for Tx to complete */ 2085 2086 KASSERT((sc->sc_flags & RTW_F_ENABLED) != 0); 2087 2088 if ((rc = rtw_phy_init(&sc->sc_regs, sc->sc_rf, 2089 rtw_chan2txpower(&sc->sc_srom, ic, ic->ic_bss->ni_chan), 2090 sc->sc_csthr, ic->ic_bss->ni_chan->ic_freq, antdiv, 2091 dflantb, RTW_ON)) != 0) { 2092 /* XXX condition on powersaving */ 2093 printf("%s: phy init failed\n", sc->sc_dev.dv_xname); 2094 } 2095 2096 sc->sc_cur_chan = chan; 2097 2098 rtw_io_enable(&sc->sc_regs, RTW_CR_RE | RTW_CR_TE, 1); 2099 2100 rtw_resume_ticks(sc); 2101 2102 return rc; 2103} 2104 2105void 2106rtw_disable(struct rtw_softc *sc) 2107{ 2108 int rc; 2109 2110 if ((sc->sc_flags & RTW_F_ENABLED) == 0) 2111 return; 2112 2113 /* turn off PHY */ 2114 if ((rc = rtw_pwrstate(sc, RTW_OFF)) != 0) 2115 printf("%s: failed to turn off PHY (%d)\n", 2116 sc->sc_dev.dv_xname, rc); 2117 2118 if (sc->sc_disable != NULL) 2119 (*sc->sc_disable)(sc); 2120 2121 sc->sc_flags &= ~RTW_F_ENABLED; 2122} 2123 2124int 2125rtw_enable(struct rtw_softc *sc) 2126{ 2127 if ((sc->sc_flags & RTW_F_ENABLED) == 0) { 2128 if (sc->sc_enable != NULL && (*sc->sc_enable)(sc) != 0) { 2129 printf("%s: device enable failed\n", 2130 sc->sc_dev.dv_xname); 2131 return (EIO); 2132 } 2133 sc->sc_flags |= RTW_F_ENABLED; 2134 } 2135 return (0); 2136} 2137 2138static void 2139rtw_transmit_config(struct rtw_regs *regs) 2140{ 2141 u_int32_t tcr; 2142 2143 tcr = RTW_READ(regs, RTW_TCR); 2144 2145 tcr |= RTW_TCR_CWMIN; 2146 tcr &= ~RTW_TCR_MXDMA_MASK; 2147 tcr |= RTW_TCR_MXDMA_256; 2148 tcr |= RTW_TCR_SAT; /* send ACK as fast as possible */ 2149 tcr &= ~RTW_TCR_LBK_MASK; 2150 tcr |= RTW_TCR_LBK_NORMAL; /* normal operating mode */ 2151 2152 /* set short/long retry limits */ 2153 tcr &= ~(RTW_TCR_SRL_MASK|RTW_TCR_LRL_MASK); 2154 tcr |= LSHIFT(4, RTW_TCR_SRL_MASK) | LSHIFT(4, RTW_TCR_LRL_MASK); 2155 2156 tcr &= ~RTW_TCR_CRC; /* NIC appends CRC32 */ 2157 2158 RTW_WRITE(regs, RTW_TCR, tcr); 2159 RTW_SYNC(regs, RTW_TCR, RTW_TCR); 2160} 2161 2162static __inline void 2163rtw_enable_interrupts(struct rtw_softc *sc) 2164{ 2165 struct rtw_regs *regs = &sc->sc_regs; 2166 2167 sc->sc_inten = RTW_INTR_RX|RTW_INTR_TX|RTW_INTR_BEACON|RTW_INTR_ATIMINT; 2168 sc->sc_inten |= RTW_INTR_IOERROR|RTW_INTR_TIMEOUT; 2169 2170 RTW_WRITE16(regs, RTW_IMR, sc->sc_inten); 2171 RTW_WBW(regs, RTW_IMR, RTW_ISR); 2172 RTW_WRITE16(regs, RTW_ISR, 0xffff); 2173 RTW_SYNC(regs, RTW_IMR, RTW_ISR); 2174 2175 /* XXX necessary? */ 2176 if (sc->sc_intr_ack != NULL) 2177 (*sc->sc_intr_ack)(regs); 2178} 2179 2180static void 2181rtw_set_nettype(struct rtw_softc *sc, enum ieee80211_opmode opmode) 2182{ 2183 uint8_t msr; 2184 2185 /* I'm guessing that MSR is protected as CONFIG[0123] are. */ 2186 rtw_set_access(sc, RTW_ACCESS_CONFIG); 2187 2188 msr = RTW_READ8(&sc->sc_regs, RTW_MSR) & ~RTW_MSR_NETYPE_MASK; 2189 2190 switch (opmode) { 2191 case IEEE80211_M_AHDEMO: 2192 case IEEE80211_M_IBSS: 2193 msr |= RTW_MSR_NETYPE_ADHOC_OK; 2194 break; 2195 case IEEE80211_M_HOSTAP: 2196 msr |= RTW_MSR_NETYPE_AP_OK; 2197 break; 2198 case IEEE80211_M_MONITOR: 2199 /* XXX */ 2200 msr |= RTW_MSR_NETYPE_NOLINK; 2201 break; 2202 case IEEE80211_M_STA: 2203 msr |= RTW_MSR_NETYPE_INFRA_OK; 2204 break; 2205 } 2206 RTW_WRITE8(&sc->sc_regs, RTW_MSR, msr); 2207 2208 rtw_set_access(sc, RTW_ACCESS_NONE); 2209} 2210 2211/* XXX is the endianness correct? test. */ 2212#define rtw_calchash(addr) \ 2213 (ether_crc32_le((addr), IEEE80211_ADDR_LEN) & BITS(5, 0)) 2214 2215static void 2216rtw_pktfilt_load(struct rtw_softc *sc) 2217{ 2218 struct rtw_regs *regs = &sc->sc_regs; 2219 struct ieee80211com *ic = &sc->sc_ic; 2220 struct ethercom *ec = &ic->ic_ec; 2221 struct ifnet *ifp = &sc->sc_ic.ic_if; 2222 int hash; 2223 u_int32_t hashes[2] = { 0, 0 }; 2224 struct ether_multi *enm; 2225 struct ether_multistep step; 2226 2227 /* XXX might be necessary to stop Rx/Tx engines while setting filters */ 2228 2229#define RTW_RCR_MONITOR (RTW_RCR_ACRC32|RTW_RCR_APM|RTW_RCR_AAP|RTW_RCR_AB|RTW_RCR_ACF | RTW_RCR_AICV | RTW_RCR_ACRC32) 2230 2231 if (ic->ic_opmode == IEEE80211_M_MONITOR) 2232 sc->sc_rcr |= RTW_RCR_MONITOR; 2233 else 2234 sc->sc_rcr &= ~RTW_RCR_MONITOR; 2235 2236 /* XXX reference sources BEGIN */ 2237 sc->sc_rcr |= RTW_RCR_ENMARP; 2238 sc->sc_rcr |= RTW_RCR_AB | RTW_RCR_AM | RTW_RCR_APM; 2239#if 0 2240 /* receive broadcasts in our BSS */ 2241 sc->sc_rcr |= RTW_RCR_ADD3; 2242#endif 2243 /* XXX reference sources END */ 2244 2245 /* receive pwrmgmt frames. */ 2246 sc->sc_rcr |= RTW_RCR_APWRMGT; 2247 /* receive mgmt/ctrl/data frames. */ 2248 sc->sc_rcr |= RTW_RCR_ADF | RTW_RCR_AMF; 2249 /* initialize Rx DMA threshold, Tx DMA burst size */ 2250 sc->sc_rcr |= RTW_RCR_RXFTH_WHOLE | RTW_RCR_MXDMA_1024; 2251 2252 ifp->if_flags &= ~IFF_ALLMULTI; 2253 2254 if (ifp->if_flags & IFF_PROMISC) { 2255 sc->sc_rcr |= RTW_RCR_AB; /* accept all broadcast */ 2256allmulti: 2257 ifp->if_flags |= IFF_ALLMULTI; 2258 goto setit; 2259 } 2260 2261 /* 2262 * Program the 64-bit multicast hash filter. 2263 */ 2264 ETHER_FIRST_MULTI(step, ec, enm); 2265 while (enm != NULL) { 2266 /* XXX */ 2267 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, 2268 ETHER_ADDR_LEN) != 0) 2269 goto allmulti; 2270 2271 hash = rtw_calchash(enm->enm_addrlo); 2272 hashes[hash >> 5] |= 1 << (hash & 0x1f); 2273 ETHER_NEXT_MULTI(step, enm); 2274 } 2275 2276 if (ifp->if_flags & IFF_BROADCAST) { 2277 hash = rtw_calchash(etherbroadcastaddr); 2278 hashes[hash >> 5] |= 1 << (hash & 0x1f); 2279 } 2280 2281 /* all bits set => hash is useless */ 2282 if (~(hashes[0] & hashes[1]) == 0) 2283 goto allmulti; 2284 2285 setit: 2286 if (ifp->if_flags & IFF_ALLMULTI) 2287 sc->sc_rcr |= RTW_RCR_AM; /* accept all multicast */ 2288 2289 if (ic->ic_state == IEEE80211_S_SCAN) 2290 sc->sc_rcr |= RTW_RCR_AB; /* accept all broadcast */ 2291 2292 hashes[0] = hashes[1] = 0xffffffff; 2293 2294 RTW_WRITE(regs, RTW_MAR0, hashes[0]); 2295 RTW_WRITE(regs, RTW_MAR1, hashes[1]); 2296 RTW_WRITE(regs, RTW_RCR, sc->sc_rcr); 2297 RTW_SYNC(regs, RTW_MAR0, RTW_RCR); /* RTW_MAR0 < RTW_MAR1 < RTW_RCR */ 2298 2299 DPRINTF(sc, RTW_DEBUG_PKTFILT, 2300 ("%s: RTW_MAR0 %08x RTW_MAR1 %08x RTW_RCR %08x\n", 2301 sc->sc_dev.dv_xname, RTW_READ(regs, RTW_MAR0), 2302 RTW_READ(regs, RTW_MAR1), RTW_READ(regs, RTW_RCR))); 2303 2304 return; 2305} 2306 2307/* Must be called at splnet. */ 2308static int 2309rtw_init(struct ifnet *ifp) 2310{ 2311 struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc; 2312 struct ieee80211com *ic = &sc->sc_ic; 2313 struct rtw_regs *regs = &sc->sc_regs; 2314 int rc = 0; 2315 2316 if ((rc = rtw_enable(sc)) != 0) 2317 goto out; 2318 2319 /* Cancel pending I/O and reset. */ 2320 rtw_stop(ifp, 0); 2321 2322 ic->ic_bss->ni_chan = ic->ic_ibss_chan; 2323 DPRINTF(sc, RTW_DEBUG_TUNE, ("%s: channel %d freq %d flags 0x%04x\n", 2324 __func__, ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan), 2325 ic->ic_bss->ni_chan->ic_freq, ic->ic_bss->ni_chan->ic_flags)); 2326 2327 if ((rc = rtw_pwrstate(sc, RTW_OFF)) != 0) 2328 goto out; 2329 2330 rtw_swring_setup(sc); 2331 2332 rtw_transmit_config(regs); 2333 2334 rtw_set_access(sc, RTW_ACCESS_CONFIG); 2335 2336 RTW_WRITE8(regs, RTW_MSR, 0x0); /* no link */ 2337 RTW_WBW(regs, RTW_MSR, RTW_BRSR); 2338 2339 /* long PLCP header, 1Mb/2Mb basic rate */ 2340 RTW_WRITE16(regs, RTW_BRSR, RTW_BRSR_MBR8180_2MBPS); 2341 RTW_SYNC(regs, RTW_BRSR, RTW_BRSR); 2342 2343 rtw_set_access(sc, RTW_ACCESS_ANAPARM); 2344 rtw_set_access(sc, RTW_ACCESS_NONE); 2345 2346#if 0 2347 RTW_WRITE(regs, RTW_FEMR, RTW_FEMR_GWAKE|RTW_FEMR_WKUP|RTW_FEMR_INTR); 2348#endif 2349 /* XXX from reference sources */ 2350 RTW_WRITE(regs, RTW_FEMR, 0xffff); 2351 RTW_SYNC(regs, RTW_FEMR, RTW_FEMR); 2352 2353 rtw_set_rfprog(regs, sc->sc_rfchipid, sc->sc_dev.dv_xname); 2354 2355 RTW_WRITE8(regs, RTW_PHYDELAY, sc->sc_phydelay); 2356 /* from Linux driver */ 2357 RTW_WRITE8(regs, RTW_CRCOUNT, RTW_CRCOUNT_MAGIC); 2358 2359 RTW_SYNC(regs, RTW_PHYDELAY, RTW_CRCOUNT); 2360 2361 rtw_enable_interrupts(sc); 2362 2363 rtw_pktfilt_load(sc); 2364 2365 rtw_hwring_setup(sc); 2366 2367 rtw_io_enable(regs, RTW_CR_RE|RTW_CR_TE, 1); 2368 2369 ifp->if_flags |= IFF_RUNNING; 2370 ic->ic_state = IEEE80211_S_INIT; 2371 2372 RTW_WRITE16(regs, RTW_BSSID16, 0x0); 2373 RTW_WRITE(regs, RTW_BSSID32, 0x0); 2374 2375 rtw_resume_ticks(sc); 2376 2377 rtw_set_nettype(sc, IEEE80211_M_MONITOR); 2378 2379 if (ic->ic_opmode == IEEE80211_M_MONITOR) 2380 return ieee80211_new_state(ic, IEEE80211_S_RUN, -1); 2381 else 2382 return ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 2383 2384out: 2385 return rc; 2386} 2387 2388static int 2389rtw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 2390{ 2391 int rc = 0, s; 2392 struct rtw_softc *sc = ifp->if_softc; 2393 struct ifreq *ifr = (struct ifreq *)data; 2394 2395 s = splnet(); 2396 switch (cmd) { 2397 case SIOCSIFFLAGS: 2398 if ((ifp->if_flags & IFF_UP) != 0) { 2399 if (0 && (sc->sc_flags & RTW_F_ENABLED) != 0) { 2400 rtw_pktfilt_load(sc); 2401 } else 2402 rc = rtw_init(ifp); 2403#ifdef RTW_DEBUG 2404 rtw_print_regs(&sc->sc_regs, ifp->if_xname, __func__); 2405#endif /* RTW_DEBUG */ 2406 } else if ((sc->sc_flags & RTW_F_ENABLED) != 0) { 2407#ifdef RTW_DEBUG 2408 rtw_print_regs(&sc->sc_regs, ifp->if_xname, __func__); 2409#endif /* RTW_DEBUG */ 2410 rtw_stop(ifp, 1); 2411 } 2412 break; 2413 case SIOCADDMULTI: 2414 case SIOCDELMULTI: 2415 if (cmd == SIOCADDMULTI) 2416 rc = ether_addmulti(ifr, &sc->sc_ic.ic_ec); 2417 else 2418 rc = ether_delmulti(ifr, &sc->sc_ic.ic_ec); 2419 if (rc == ENETRESET) { 2420 if (ifp->if_flags & IFF_RUNNING) 2421 rtw_pktfilt_load(sc); 2422 rc = 0; 2423 } 2424 break; 2425 default: 2426 if ((rc = ieee80211_ioctl(ifp, cmd, data)) == ENETRESET) { 2427 if ((sc->sc_flags & RTW_F_ENABLED) != 0) 2428 rc = rtw_init(ifp); 2429 else 2430 rc = 0; 2431 } 2432 break; 2433 } 2434 splx(s); 2435 return rc; 2436} 2437 2438/* Point *mp at the next 802.11 frame to transmit. Point *stcp 2439 * at the driver's selection of transmit control block for the packet. 2440 */ 2441static __inline int 2442rtw_dequeue(struct ifnet *ifp, struct rtw_txctl_blk **stcp, 2443 struct rtw_txdesc_blk **htcp, struct mbuf **mp, 2444 struct ieee80211_node **nip) 2445{ 2446 struct rtw_txctl_blk *stc; 2447 struct rtw_txdesc_blk *htc; 2448 struct mbuf *m0; 2449 struct rtw_softc *sc; 2450 struct ieee80211com *ic; 2451 2452 sc = (struct rtw_softc *)ifp->if_softc; 2453 2454 DPRINTF(sc, RTW_DEBUG_XMIT, 2455 ("%s: enter %s\n", sc->sc_dev.dv_xname, __func__)); 2456 *mp = NULL; 2457 2458 stc = &sc->sc_txctl_blk[RTW_TXPRIMD]; 2459 htc = &sc->sc_txdesc_blk[RTW_TXPRIMD]; 2460 2461 if (SIMPLEQ_EMPTY(&stc->stc_freeq) || htc->htc_nfree == 0) { 2462 DPRINTF(sc, RTW_DEBUG_XMIT, 2463 ("%s: out of descriptors\n", __func__)); 2464 ifp->if_flags |= IFF_OACTIVE; 2465 return 0; 2466 } 2467 2468 ic = &sc->sc_ic; 2469 2470 if (!IF_IS_EMPTY(&ic->ic_mgtq)) { 2471 IF_DEQUEUE(&ic->ic_mgtq, m0); 2472 *nip = (struct ieee80211_node *)m0->m_pkthdr.rcvif; 2473 m0->m_pkthdr.rcvif = NULL; 2474 DPRINTF(sc, RTW_DEBUG_XMIT, 2475 ("%s: dequeue mgt frame\n", __func__)); 2476 } else if (ic->ic_state != IEEE80211_S_RUN) { 2477 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: not running\n", __func__)); 2478 return 0; 2479 } else if (!IF_IS_EMPTY(&ic->ic_pwrsaveq)) { 2480 IF_DEQUEUE(&ic->ic_pwrsaveq, m0); 2481 *nip = (struct ieee80211_node *)m0->m_pkthdr.rcvif; 2482 m0->m_pkthdr.rcvif = NULL; 2483 DPRINTF(sc, RTW_DEBUG_XMIT, 2484 ("%s: dequeue pwrsave frame\n", __func__)); 2485 } else { 2486 IFQ_DEQUEUE(&ifp->if_snd, m0); 2487 if (m0 == NULL) { 2488 DPRINTF(sc, RTW_DEBUG_XMIT, 2489 ("%s: no frame\n", __func__)); 2490 return 0; 2491 } 2492 DPRINTF(sc, RTW_DEBUG_XMIT, 2493 ("%s: dequeue data frame\n", __func__)); 2494 ifp->if_opackets++; 2495#if NBPFILTER > 0 2496 if (ifp->if_bpf) 2497 bpf_mtap(ifp->if_bpf, m0); 2498#endif 2499 if ((m0 = ieee80211_encap(ifp, m0, nip)) == NULL) { 2500 DPRINTF(sc, RTW_DEBUG_XMIT, 2501 ("%s: encap error\n", __func__)); 2502 ifp->if_oerrors++; 2503 return -1; 2504 } 2505 } 2506 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: leave\n", __func__)); 2507 *stcp = stc; 2508 *htcp = htc; 2509 *mp = m0; 2510 return 0; 2511} 2512 2513static int 2514rtw_seg_too_short(bus_dmamap_t dmamap) 2515{ 2516 int i; 2517 for (i = 0; i < dmamap->dm_nsegs; i++) { 2518 if (dmamap->dm_segs[i].ds_len < 4) { 2519 printf("%s: segment too short\n", __func__); 2520 return 1; 2521 } 2522 } 2523 return 0; 2524} 2525 2526/* TBD factor with atw_start */ 2527static struct mbuf * 2528rtw_dmamap_load_txbuf(bus_dma_tag_t dmat, bus_dmamap_t dmam, struct mbuf *chain, 2529 u_int ndescfree, short *ifflagsp, const char *dvname) 2530{ 2531 int first, rc; 2532 struct mbuf *m, *m0; 2533 2534 m0 = chain; 2535 2536 /* 2537 * Load the DMA map. Copy and try (once) again if the packet 2538 * didn't fit in the alloted number of segments. 2539 */ 2540 for (first = 1; 2541 ((rc = bus_dmamap_load_mbuf(dmat, dmam, m0, 2542 BUS_DMA_WRITE|BUS_DMA_NOWAIT)) != 0 || 2543 dmam->dm_nsegs > ndescfree || rtw_seg_too_short(dmam)) && first; 2544 first = 0) { 2545 if (rc == 0) 2546 bus_dmamap_unload(dmat, dmam); 2547 MGETHDR(m, M_DONTWAIT, MT_DATA); 2548 if (m == NULL) { 2549 printf("%s: unable to allocate Tx mbuf\n", 2550 dvname); 2551 break; 2552 } 2553 if (m0->m_pkthdr.len > MHLEN) { 2554 MCLGET(m, M_DONTWAIT); 2555 if ((m->m_flags & M_EXT) == 0) { 2556 printf("%s: cannot allocate Tx cluster\n", 2557 dvname); 2558 m_freem(m); 2559 break; 2560 } 2561 } 2562 m_copydata(m0, 0, m0->m_pkthdr.len, mtod(m, caddr_t)); 2563 m->m_pkthdr.len = m->m_len = m0->m_pkthdr.len; 2564 m_freem(m0); 2565 m0 = m; 2566 m = NULL; 2567 } 2568 if (rc != 0) { 2569 printf("%s: cannot load Tx buffer, rc = %d\n", dvname, rc); 2570 m_freem(m0); 2571 return NULL; 2572 } else if (rtw_seg_too_short(dmam)) { 2573 printf("%s: cannot load Tx buffer, segment too short\n", 2574 dvname); 2575 bus_dmamap_unload(dmat, dmam); 2576 m_freem(m0); 2577 return NULL; 2578 } else if (dmam->dm_nsegs > ndescfree) { 2579 *ifflagsp |= IFF_OACTIVE; 2580 bus_dmamap_unload(dmat, dmam); 2581 m_freem(m0); 2582 return NULL; 2583 } 2584 return m0; 2585} 2586 2587#ifdef RTW_DEBUG 2588static void 2589rtw_print_txdesc(struct rtw_softc *sc, const char *action, 2590 struct rtw_txctl *stx, struct rtw_txdesc_blk *htc, int desc) 2591{ 2592 struct rtw_txdesc *htx = &htc->htc_desc[desc]; 2593 DPRINTF(sc, RTW_DEBUG_XMIT_DESC, ("%s: %p %s txdesc[%d] ctl0 %#08x " 2594 "ctl1 %#08x buf %#08x len %#08x\n", 2595 sc->sc_dev.dv_xname, stx, action, desc, 2596 le32toh(htx->htx_ctl0), 2597 le32toh(htx->htx_ctl1), le32toh(htx->htx_buf), 2598 le32toh(htx->htx_len))); 2599} 2600#endif /* RTW_DEBUG */ 2601 2602static void 2603rtw_start(struct ifnet *ifp) 2604{ 2605 uint8_t tppoll; 2606 int desc, i, lastdesc, npkt, rate; 2607 uint32_t proto_ctl0, ctl0, ctl1; 2608 bus_dmamap_t dmamap; 2609 struct ieee80211com *ic; 2610 struct ieee80211_duration *d0; 2611 struct ieee80211_frame *wh; 2612 struct ieee80211_node *ni; 2613 struct mbuf *m0; 2614 struct rtw_softc *sc; 2615 struct rtw_txctl_blk *stc; 2616 struct rtw_txdesc_blk *htc; 2617 struct rtw_txctl *stx; 2618 struct rtw_txdesc *htx; 2619 2620 sc = (struct rtw_softc *)ifp->if_softc; 2621 ic = &sc->sc_ic; 2622 2623 DPRINTF(sc, RTW_DEBUG_XMIT, 2624 ("%s: enter %s\n", sc->sc_dev.dv_xname, __func__)); 2625 2626 /* XXX do real rate control */ 2627 proto_ctl0 = RTW_TXCTL0_RTSRATE_1MBPS; 2628 2629 switch (rate = MAX(2, ieee80211_get_rate(ic))) { 2630 case 2: 2631 proto_ctl0 |= RTW_TXCTL0_RATE_1MBPS; 2632 break; 2633 case 4: 2634 proto_ctl0 |= RTW_TXCTL0_RATE_2MBPS; 2635 break; 2636 case 11: 2637 proto_ctl0 |= RTW_TXCTL0_RATE_5MBPS; 2638 break; 2639 case 22: 2640 proto_ctl0 |= RTW_TXCTL0_RATE_11MBPS; 2641 break; 2642 } 2643 2644 if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0) 2645 proto_ctl0 |= RTW_TXCTL0_SPLCP; 2646 2647 for (;;) { 2648 if (rtw_dequeue(ifp, &stc, &htc, &m0, &ni) == -1) 2649 continue; 2650 if (m0 == NULL) 2651 break; 2652 stx = SIMPLEQ_FIRST(&stc->stc_freeq); 2653 2654 dmamap = stx->stx_dmamap; 2655 2656 m0 = rtw_dmamap_load_txbuf(sc->sc_dmat, dmamap, m0, 2657 htc->htc_nfree, &ifp->if_flags, sc->sc_dev.dv_xname); 2658 2659 if (m0 == NULL || dmamap->dm_nsegs == 0) { 2660 DPRINTF(sc, RTW_DEBUG_XMIT, 2661 ("%s: fail dmamap load\n", __func__)); 2662 goto post_dequeue_err; 2663 } 2664 2665#ifdef RTW_DEBUG 2666 if ((sc->sc_if.if_flags & (IFF_DEBUG|IFF_LINK2)) == 2667 (IFF_DEBUG|IFF_LINK2)) { 2668 ieee80211_dump_pkt(mtod(m0, uint8_t *), 2669 (dmamap->dm_nsegs == 1) ? m0->m_pkthdr.len 2670 : sizeof(wh), 2671 rate, 0); 2672 } 2673#endif /* RTW_DEBUG */ 2674 ctl0 = proto_ctl0 | 2675 LSHIFT(m0->m_pkthdr.len, RTW_TXCTL0_TPKTSIZE_MASK); 2676 2677 wh = mtod(m0, struct ieee80211_frame *); 2678 2679 if (ieee80211_compute_duration(wh, m0->m_pkthdr.len, 2680 ic->ic_flags, ic->ic_fragthreshold, 2681 rate, &stx->stx_d0, &stx->stx_dn, &npkt, 2682 (sc->sc_if.if_flags & (IFF_DEBUG|IFF_LINK2)) == 2683 (IFF_DEBUG|IFF_LINK2)) == -1) { 2684 DPRINTF(sc, RTW_DEBUG_XMIT, 2685 ("%s: fail compute duration\n", __func__)); 2686 goto post_load_err; 2687 } 2688 2689 /* XXX >= ? */ 2690 if (m0->m_pkthdr.len > ic->ic_rtsthreshold) 2691 ctl0 |= RTW_TXCTL0_RTSEN; 2692 2693 d0 = &stx->stx_d0; 2694 2695 *(uint16_t*)wh->i_dur = htole16(d0->d_data_dur); 2696 2697 ctl1 = LSHIFT(d0->d_plcp_len, RTW_TXCTL1_LENGTH_MASK) | 2698 LSHIFT(d0->d_rts_dur, RTW_TXCTL1_RTSDUR_MASK); 2699 2700 if (d0->d_residue) 2701 ctl1 |= RTW_TXCTL1_LENGEXT; 2702 2703 /* TBD fragmentation */ 2704 2705 stx->stx_first = htc->htc_next; 2706 2707 rtw_txdescs_sync(sc->sc_dmat, sc->sc_desc_dmamap, 2708 htc, stx->stx_first, dmamap->dm_nsegs, 2709 BUS_DMASYNC_PREWRITE); 2710 2711 KASSERT(stx->stx_first < htc->htc_ndesc); 2712 2713 for (i = 0, lastdesc = desc = stx->stx_first; 2714 i < dmamap->dm_nsegs; 2715 i++, desc = RTW_NEXT_IDX(htc, desc)) { 2716 if (dmamap->dm_segs[i].ds_len > RTW_TXLEN_LENGTH_MASK) { 2717 DPRINTF(sc, RTW_DEBUG_XMIT_DESC, 2718 ("%s: seg too long\n", __func__)); 2719 goto post_load_err; 2720 } 2721 htx = &htc->htc_desc[desc]; 2722 htx->htx_ctl0 = htole32(ctl0); 2723 if (i != 0) 2724 htx->htx_ctl0 |= htole32(RTW_TXCTL0_OWN); 2725 htx->htx_ctl1 = htole32(ctl1); 2726 htx->htx_buf = htole32(dmamap->dm_segs[i].ds_addr); 2727 htx->htx_len = htole32(dmamap->dm_segs[i].ds_len); 2728 lastdesc = desc; 2729#ifdef RTW_DEBUG 2730 rtw_print_txdesc(sc, "load", stx, htc, desc); 2731#endif /* RTW_DEBUG */ 2732 } 2733 2734 KASSERT(desc < htc->htc_ndesc); 2735 2736 stx->stx_ni = ni; 2737 stx->stx_mbuf = m0; 2738 stx->stx_last = lastdesc; 2739 htc->htc_desc[stx->stx_last].htx_ctl0 |= htole32(RTW_TXCTL0_LS); 2740 htc->htc_desc[stx->stx_first].htx_ctl0 |= 2741 htole32(RTW_TXCTL0_FS); 2742 2743#ifdef RTW_DEBUG 2744 rtw_print_txdesc(sc, "FS on", stx, htc, stx->stx_first); 2745 rtw_print_txdesc(sc, "LS on", stx, htc, stx->stx_last); 2746#endif /* RTW_DEBUG */ 2747 2748 htc->htc_nfree -= dmamap->dm_nsegs; 2749 htc->htc_next = desc; 2750 2751 rtw_txdescs_sync(sc->sc_dmat, sc->sc_desc_dmamap, 2752 htc, stx->stx_first, dmamap->dm_nsegs, 2753 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 2754 2755 htc->htc_desc[stx->stx_first].htx_ctl0 |= 2756 htole32(RTW_TXCTL0_OWN); 2757 2758#ifdef RTW_DEBUG 2759 rtw_print_txdesc(sc, "OWN on", stx, htc, stx->stx_first); 2760#endif /* RTW_DEBUG */ 2761 2762 rtw_txdescs_sync(sc->sc_dmat, sc->sc_desc_dmamap, 2763 htc, stx->stx_first, 1, 2764 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 2765 2766 SIMPLEQ_REMOVE_HEAD(&stc->stc_freeq, stx_q); 2767 SIMPLEQ_INSERT_TAIL(&stc->stc_dirtyq, stx, stx_q); 2768 2769 stc->stc_tx_timer = 5; 2770 ifp->if_timer = 1; 2771 2772 tppoll = RTW_READ8(&sc->sc_regs, RTW_TPPOLL); 2773 2774 /* TBD poke other queues. */ 2775 RTW_WRITE8(&sc->sc_regs, RTW_TPPOLL, tppoll | RTW_TPPOLL_NPQ); 2776 RTW_SYNC(&sc->sc_regs, RTW_TPPOLL, RTW_TPPOLL); 2777 } 2778 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: leave\n", __func__)); 2779 return; 2780post_load_err: 2781 bus_dmamap_unload(sc->sc_dmat, dmamap); 2782 m_freem(m0); 2783post_dequeue_err: 2784 ieee80211_release_node(&sc->sc_ic, ni); 2785 return; 2786} 2787 2788static void 2789rtw_watchdog(struct ifnet *ifp) 2790{ 2791 int pri; 2792 struct rtw_softc *sc; 2793 struct rtw_txctl_blk *stc; 2794 2795 sc = ifp->if_softc; 2796 2797 ifp->if_timer = 0; 2798 2799 if ((sc->sc_flags & RTW_F_ENABLED) == 0) 2800 return; 2801 2802 for (pri = 0; pri < RTW_NTXPRI; pri++) { 2803 stc = &sc->sc_txctl_blk[pri]; 2804 2805 if (stc->stc_tx_timer == 0) 2806 continue; 2807 2808 if (--stc->stc_tx_timer == 0) { 2809 if (SIMPLEQ_EMPTY(&stc->stc_dirtyq)) 2810 continue; 2811 printf("%s: transmit timeout, priority %d\n", 2812 ifp->if_xname, pri); 2813 ifp->if_oerrors++; 2814 /* Stop Tx DMA, disable transmitter, clear 2815 * Tx rings, and restart. 2816 */ 2817 RTW_WRITE8(&sc->sc_regs, RTW_TPPOLL, RTW_TPPOLL_SNPQ); 2818 RTW_SYNC(&sc->sc_regs, RTW_TPPOLL, RTW_TPPOLL); 2819 rtw_io_enable(&sc->sc_regs, RTW_CR_TE, 0); 2820 rtw_txdescs_reset(sc); 2821 rtw_io_enable(&sc->sc_regs, RTW_CR_TE, 1); 2822 rtw_start(ifp); 2823 } else 2824 ifp->if_timer = 1; 2825 } 2826 ieee80211_watchdog(ifp); 2827 return; 2828} 2829 2830static void 2831rtw_start_beacon(struct rtw_softc *sc, int enable) 2832{ 2833 /* TBD */ 2834 return; 2835} 2836 2837static void 2838rtw_next_scan(void *arg) 2839{ 2840 struct ieee80211com *ic = arg; 2841 int s; 2842 2843 /* don't call rtw_start w/o network interrupts blocked */ 2844 s = splnet(); 2845 if (ic->ic_state == IEEE80211_S_SCAN) 2846 ieee80211_next_scan(ic); 2847 splx(s); 2848} 2849 2850static void 2851rtw_join_bss(struct rtw_softc *sc, uint8_t *bssid, enum ieee80211_opmode opmode, 2852 uint16_t intval0) 2853{ 2854 uint16_t bcnitv, intval; 2855 int i; 2856 struct rtw_regs *regs = &sc->sc_regs; 2857 2858 for (i = 0; i < IEEE80211_ADDR_LEN; i++) 2859 RTW_WRITE8(regs, RTW_BSSID + i, bssid[i]); 2860 2861 RTW_SYNC(regs, RTW_BSSID16, RTW_BSSID32); 2862 2863 rtw_set_access(sc, RTW_ACCESS_CONFIG); 2864 2865 intval = MIN(intval0, PRESHIFT(RTW_BCNITV_BCNITV_MASK)); 2866 2867 bcnitv = RTW_READ16(regs, RTW_BCNITV) & ~RTW_BCNITV_BCNITV_MASK; 2868 bcnitv |= LSHIFT(intval, RTW_BCNITV_BCNITV_MASK); 2869 RTW_WRITE16(regs, RTW_BCNITV, bcnitv); 2870 /* magic from Linux */ 2871 RTW_WRITE16(regs, RTW_ATIMWND, LSHIFT(1, RTW_ATIMWND_ATIMWND)); 2872 RTW_WRITE16(regs, RTW_ATIMTRITV, LSHIFT(2, RTW_ATIMTRITV_ATIMTRITV)); 2873 2874 rtw_set_nettype(sc, opmode); 2875 2876 rtw_set_access(sc, RTW_ACCESS_NONE); 2877 2878 /* TBD WEP */ 2879 RTW_WRITE8(regs, RTW_SCR, 0); 2880 2881 rtw_io_enable(regs, RTW_CR_RE | RTW_CR_TE, 1); 2882} 2883 2884/* Synchronize the hardware state with the software state. */ 2885static int 2886rtw_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) 2887{ 2888 struct ifnet *ifp = &ic->ic_if; 2889 struct rtw_softc *sc = ifp->if_softc; 2890 enum ieee80211_state ostate; 2891 int error; 2892 2893 ostate = ic->ic_state; 2894 2895 if (nstate == IEEE80211_S_INIT) { 2896 callout_stop(&sc->sc_scan_ch); 2897 sc->sc_cur_chan = IEEE80211_CHAN_ANY; 2898 rtw_start_beacon(sc, 0); 2899 return (*sc->sc_mtbl.mt_newstate)(ic, nstate, arg); 2900 } 2901 2902 if (ostate == IEEE80211_S_INIT && nstate != IEEE80211_S_INIT) 2903 rtw_pwrstate(sc, RTW_ON); 2904 2905 if ((error = rtw_tune(sc)) != 0) 2906 return error; 2907 2908 switch (nstate) { 2909 case IEEE80211_S_ASSOC: 2910 rtw_join_bss(sc, ic->ic_bss->ni_bssid, ic->ic_opmode, 2911 ic->ic_bss->ni_intval); 2912 break; 2913 case IEEE80211_S_INIT: 2914 panic("%s: unexpected state IEEE80211_S_INIT\n", __func__); 2915 break; 2916 case IEEE80211_S_SCAN: 2917 if (ostate != IEEE80211_S_SCAN) { 2918 (void)memset(ic->ic_bss->ni_bssid, 0, 2919 IEEE80211_ADDR_LEN); 2920 rtw_join_bss(sc, ic->ic_bss->ni_bssid, ic->ic_opmode, 2921 ic->ic_bss->ni_intval); 2922 } 2923 2924 callout_reset(&sc->sc_scan_ch, rtw_dwelltime * hz / 1000, 2925 rtw_next_scan, ic); 2926 2927 break; 2928 case IEEE80211_S_RUN: 2929 if (ic->ic_opmode == IEEE80211_M_STA) 2930 break; 2931 /*FALLTHROUGH*/ 2932 case IEEE80211_S_AUTH: 2933#if 0 2934 rtw_write_bcn_thresh(sc); 2935 rtw_write_ssid(sc); 2936 rtw_write_sup_rates(sc); 2937#endif 2938 if (ic->ic_opmode == IEEE80211_M_AHDEMO || 2939 ic->ic_opmode == IEEE80211_M_MONITOR) 2940 break; 2941 2942 /* TBD set listen interval */ 2943 2944#if 0 2945 rtw_tsf(sc); 2946#endif 2947 break; 2948 } 2949 2950 if (nstate != IEEE80211_S_SCAN) 2951 callout_stop(&sc->sc_scan_ch); 2952 2953 if (nstate == IEEE80211_S_RUN && 2954 (ic->ic_opmode == IEEE80211_M_HOSTAP || 2955 ic->ic_opmode == IEEE80211_M_IBSS)) 2956 rtw_start_beacon(sc, 1); 2957 else 2958 rtw_start_beacon(sc, 0); 2959 2960 return (*sc->sc_mtbl.mt_newstate)(ic, nstate, arg); 2961} 2962 2963static void 2964rtw_recv_beacon(struct rtw_softc *sc, struct mbuf *m, 2965 struct ieee80211_node *ni, int subtype, int rssi, u_int32_t rstamp) 2966{ 2967 (*sc->sc_mtbl.mt_recv_mgmt)(&sc->sc_ic, m, ni, subtype, rssi, rstamp); 2968 return; 2969} 2970 2971static void 2972rtw_recv_mgmt(struct ieee80211com *ic, struct mbuf *m, 2973 struct ieee80211_node *ni, int subtype, int rssi, u_int32_t rstamp) 2974{ 2975 struct rtw_softc *sc = (struct rtw_softc*)ic->ic_softc; 2976 2977 switch (subtype) { 2978 case IEEE80211_FC0_SUBTYPE_PROBE_REQ: 2979 /* do nothing: hardware answers probe request XXX */ 2980 break; 2981 case IEEE80211_FC0_SUBTYPE_PROBE_RESP: 2982 case IEEE80211_FC0_SUBTYPE_BEACON: 2983 rtw_recv_beacon(sc, m, ni, subtype, rssi, rstamp); 2984 break; 2985 default: 2986 (*sc->sc_mtbl.mt_recv_mgmt)(ic, m, ni, subtype, rssi, rstamp); 2987 break; 2988 } 2989 return; 2990} 2991 2992static struct ieee80211_node * 2993rtw_node_alloc(struct ieee80211com *ic) 2994{ 2995 struct rtw_softc *sc = (struct rtw_softc *)ic->ic_if.if_softc; 2996 struct ieee80211_node *ni = (*sc->sc_mtbl.mt_node_alloc)(ic); 2997 2998 DPRINTF(sc, RTW_DEBUG_NODE, 2999 ("%s: alloc node %p\n", sc->sc_dev.dv_xname, ni)); 3000 return ni; 3001} 3002 3003static void 3004rtw_node_free(struct ieee80211com *ic, struct ieee80211_node *ni) 3005{ 3006 struct rtw_softc *sc = (struct rtw_softc *)ic->ic_if.if_softc; 3007 3008 DPRINTF(sc, RTW_DEBUG_NODE, 3009 ("%s: freeing node %p %s\n", sc->sc_dev.dv_xname, ni, 3010 ether_sprintf(ni->ni_bssid))); 3011 (*sc->sc_mtbl.mt_node_free)(ic, ni); 3012} 3013 3014static int 3015rtw_media_change(struct ifnet *ifp) 3016{ 3017 int error; 3018 3019 error = ieee80211_media_change(ifp); 3020 if (error == ENETRESET) { 3021 if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) == 3022 (IFF_RUNNING|IFF_UP)) 3023 rtw_init(ifp); /* XXX lose error */ 3024 error = 0; 3025 } 3026 return error; 3027} 3028 3029static void 3030rtw_media_status(struct ifnet *ifp, struct ifmediareq *imr) 3031{ 3032 struct rtw_softc *sc = ifp->if_softc; 3033 3034 if ((sc->sc_flags & RTW_F_ENABLED) == 0) { 3035 imr->ifm_active = IFM_IEEE80211 | IFM_NONE; 3036 imr->ifm_status = 0; 3037 return; 3038 } 3039 ieee80211_media_status(ifp, imr); 3040} 3041 3042void 3043rtw_power(int why, void *arg) 3044{ 3045 struct rtw_softc *sc = arg; 3046 struct ifnet *ifp = &sc->sc_ic.ic_if; 3047 int s; 3048 3049 DPRINTF(sc, RTW_DEBUG_PWR, 3050 ("%s: rtw_power(%d,)\n", sc->sc_dev.dv_xname, why)); 3051 3052 s = splnet(); 3053 switch (why) { 3054 case PWR_STANDBY: 3055 /* XXX do nothing. */ 3056 break; 3057 case PWR_SUSPEND: 3058 rtw_stop(ifp, 0); 3059 if (sc->sc_power != NULL) 3060 (*sc->sc_power)(sc, why); 3061 break; 3062 case PWR_RESUME: 3063 if (ifp->if_flags & IFF_UP) { 3064 if (sc->sc_power != NULL) 3065 (*sc->sc_power)(sc, why); 3066 rtw_init(ifp); 3067 } 3068 break; 3069 case PWR_SOFTSUSPEND: 3070 case PWR_SOFTSTANDBY: 3071 case PWR_SOFTRESUME: 3072 break; 3073 } 3074 splx(s); 3075} 3076 3077/* rtw_shutdown: make sure the interface is stopped at reboot time. */ 3078void 3079rtw_shutdown(void *arg) 3080{ 3081 struct rtw_softc *sc = arg; 3082 3083 rtw_stop(&sc->sc_ic.ic_if, 1); 3084} 3085 3086static __inline void 3087rtw_setifprops(struct ifnet *ifp, const char *dvname, void *softc) 3088{ 3089 (void)memcpy(ifp->if_xname, dvname, IFNAMSIZ); 3090 ifp->if_softc = softc; 3091 ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST | 3092 IFF_NOTRAILERS; 3093 ifp->if_ioctl = rtw_ioctl; 3094 ifp->if_start = rtw_start; 3095 ifp->if_watchdog = rtw_watchdog; 3096 ifp->if_init = rtw_init; 3097 ifp->if_stop = rtw_stop; 3098} 3099 3100static __inline void 3101rtw_set80211props(struct ieee80211com *ic) 3102{ 3103 int nrate; 3104 ic->ic_phytype = IEEE80211_T_DS; 3105 ic->ic_opmode = IEEE80211_M_STA; 3106 ic->ic_caps = IEEE80211_C_PMGT | IEEE80211_C_IBSS | 3107 IEEE80211_C_HOSTAP | IEEE80211_C_MONITOR | IEEE80211_C_WEP; 3108 3109 nrate = 0; 3110 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] = 3111 IEEE80211_RATE_BASIC | 2; 3112 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] = 3113 IEEE80211_RATE_BASIC | 4; 3114 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] = 11; 3115 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] = 22; 3116 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_nrates = nrate; 3117} 3118 3119static __inline void 3120rtw_set80211methods(struct rtw_mtbl *mtbl, struct ieee80211com *ic) 3121{ 3122 mtbl->mt_newstate = ic->ic_newstate; 3123 ic->ic_newstate = rtw_newstate; 3124 3125 mtbl->mt_recv_mgmt = ic->ic_recv_mgmt; 3126 ic->ic_recv_mgmt = rtw_recv_mgmt; 3127 3128 mtbl->mt_node_free = ic->ic_node_free; 3129 ic->ic_node_free = rtw_node_free; 3130 3131 mtbl->mt_node_alloc = ic->ic_node_alloc; 3132 ic->ic_node_alloc = rtw_node_alloc; 3133} 3134 3135static __inline void 3136rtw_establish_hooks(struct rtw_hooks *hooks, const char *dvname, 3137 void *arg) 3138{ 3139 /* 3140 * Make sure the interface is shutdown during reboot. 3141 */ 3142 hooks->rh_shutdown = shutdownhook_establish(rtw_shutdown, arg); 3143 if (hooks->rh_shutdown == NULL) 3144 printf("%s: WARNING: unable to establish shutdown hook\n", 3145 dvname); 3146 3147 /* 3148 * Add a suspend hook to make sure we come back up after a 3149 * resume. 3150 */ 3151 hooks->rh_power = powerhook_establish(rtw_power, arg); 3152 if (hooks->rh_power == NULL) 3153 printf("%s: WARNING: unable to establish power hook\n", 3154 dvname); 3155} 3156 3157static __inline void 3158rtw_disestablish_hooks(struct rtw_hooks *hooks, const char *dvname, 3159 void *arg) 3160{ 3161 if (hooks->rh_shutdown != NULL) 3162 shutdownhook_disestablish(hooks->rh_shutdown); 3163 3164 if (hooks->rh_power != NULL) 3165 powerhook_disestablish(hooks->rh_power); 3166} 3167 3168static __inline void 3169rtw_init_radiotap(struct rtw_softc *sc) 3170{ 3171 memset(&sc->sc_rxtapu, 0, sizeof(sc->sc_rxtapu)); 3172 sc->sc_rxtap.rr_ihdr.it_len = sizeof(sc->sc_rxtapu); 3173 sc->sc_rxtap.rr_ihdr.it_present = RTW_RX_RADIOTAP_PRESENT; 3174 3175 memset(&sc->sc_txtapu, 0, sizeof(sc->sc_txtapu)); 3176 sc->sc_txtap.rt_ihdr.it_len = sizeof(sc->sc_txtapu); 3177 sc->sc_txtap.rt_ihdr.it_present = RTW_TX_RADIOTAP_PRESENT; 3178} 3179 3180static int 3181rtw_txctl_blk_setup(struct rtw_txctl_blk *stc, u_int qlen) 3182{ 3183 SIMPLEQ_INIT(&stc->stc_dirtyq); 3184 SIMPLEQ_INIT(&stc->stc_freeq); 3185 stc->stc_ndesc = qlen; 3186 stc->stc_desc = malloc(qlen * sizeof(*stc->stc_desc), M_DEVBUF, 3187 M_NOWAIT); 3188 if (stc->stc_desc == NULL) 3189 return ENOMEM; 3190 return 0; 3191} 3192 3193static void 3194rtw_txctl_blk_cleanup_all(struct rtw_softc *sc) 3195{ 3196 int pri; 3197 struct rtw_txctl_blk *stc; 3198 3199 for (pri = 0; pri < RTW_NTXPRI; pri++) { 3200 stc = &sc->sc_txctl_blk[pri]; 3201 free(stc->stc_desc, M_DEVBUF); 3202 stc->stc_desc = NULL; 3203 } 3204} 3205 3206static int 3207rtw_txctl_blk_setup_all(struct rtw_softc *sc) 3208{ 3209 int pri, rc = 0; 3210 int qlen[RTW_NTXPRI] = 3211 {RTW_TXQLENLO, RTW_TXQLENMD, RTW_TXQLENHI, RTW_TXQLENBCN}; 3212 3213 for (pri = 0; pri < RTW_NTXPRI; pri++) { 3214 rc = rtw_txctl_blk_setup(&sc->sc_txctl_blk[pri], qlen[pri]); 3215 if (rc != 0) 3216 break; 3217 } 3218 return rc; 3219} 3220 3221static void 3222rtw_txdesc_blk_setup(struct rtw_txdesc_blk *htc, struct rtw_txdesc *desc, 3223 u_int ndesc, bus_addr_t ofs, bus_addr_t physbase) 3224{ 3225 htc->htc_ndesc = ndesc; 3226 htc->htc_desc = desc; 3227 htc->htc_physbase = physbase; 3228 htc->htc_ofs = ofs; 3229 3230 (void)memset(htc->htc_desc, 0, 3231 sizeof(htc->htc_desc[0]) * htc->htc_ndesc); 3232 3233 rtw_txdesc_blk_reset(htc); 3234} 3235 3236static void 3237rtw_txdesc_blk_setup_all(struct rtw_softc *sc) 3238{ 3239 rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRILO], 3240 &sc->sc_descs->hd_txlo[0], RTW_NTXDESCLO, 3241 RTW_RING_OFFSET(hd_txlo), RTW_RING_BASE(sc, hd_txlo)); 3242 3243 rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIMD], 3244 &sc->sc_descs->hd_txmd[0], RTW_NTXDESCMD, 3245 RTW_RING_OFFSET(hd_txmd), RTW_RING_BASE(sc, hd_txmd)); 3246 3247 rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIHI], 3248 &sc->sc_descs->hd_txhi[0], RTW_NTXDESCHI, 3249 RTW_RING_OFFSET(hd_txhi), RTW_RING_BASE(sc, hd_txhi)); 3250 3251 rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIBCN], 3252 &sc->sc_descs->hd_bcn[0], RTW_NTXDESCBCN, 3253 RTW_RING_OFFSET(hd_bcn), RTW_RING_BASE(sc, hd_bcn)); 3254} 3255 3256static struct rtw_rf * 3257rtw_rf_attach(struct rtw_softc *sc, enum rtw_rfchipid rfchipid, 3258 rtw_rf_write_t rf_write, int digphy) 3259{ 3260 struct rtw_rf *rf; 3261 3262 switch (rfchipid) { 3263 case RTW_RFCHIPID_MAXIM: 3264 rf = rtw_max2820_create(&sc->sc_regs, rf_write, 0); 3265 sc->sc_pwrstate_cb = rtw_maxim_pwrstate; 3266 break; 3267 case RTW_RFCHIPID_PHILIPS: 3268 rf = rtw_sa2400_create(&sc->sc_regs, rf_write, digphy); 3269 sc->sc_pwrstate_cb = rtw_philips_pwrstate; 3270 break; 3271 case RTW_RFCHIPID_RFMD: 3272 /* XXX RFMD has no RF constructor */ 3273 sc->sc_pwrstate_cb = rtw_rfmd_pwrstate; 3274 /*FALLTHROUGH*/ 3275 default: 3276 return NULL; 3277 } 3278 rf->rf_continuous_tx_cb = 3279 (rtw_continuous_tx_cb_t)rtw_continuous_tx_enable; 3280 rf->rf_continuous_tx_arg = (void *)sc; 3281 return rf; 3282} 3283 3284/* Revision C and later use a different PHY delay setting than 3285 * revisions A and B. 3286 */ 3287static u_int8_t 3288rtw_check_phydelay(struct rtw_regs *regs, u_int32_t rcr0) 3289{ 3290#define REVAB (RTW_RCR_MXDMA_UNLIMITED | RTW_RCR_AICV) 3291#define REVC (REVAB | RTW_RCR_RXFTH_WHOLE) 3292 3293 u_int8_t phydelay = LSHIFT(0x6, RTW_PHYDELAY_PHYDELAY); 3294 3295 RTW_WRITE(regs, RTW_RCR, REVAB); 3296 RTW_WBW(regs, RTW_RCR, RTW_RCR); 3297 RTW_WRITE(regs, RTW_RCR, REVC); 3298 3299 RTW_WBR(regs, RTW_RCR, RTW_RCR); 3300 if ((RTW_READ(regs, RTW_RCR) & REVC) == REVC) 3301 phydelay |= RTW_PHYDELAY_REVC_MAGIC; 3302 3303 RTW_WRITE(regs, RTW_RCR, rcr0); /* restore RCR */ 3304 RTW_SYNC(regs, RTW_RCR, RTW_RCR); 3305 3306 return phydelay; 3307#undef REVC 3308} 3309 3310void 3311rtw_attach(struct rtw_softc *sc) 3312{ 3313 rtw_rf_write_t rf_write; 3314 struct rtw_txctl_blk *stc; 3315 int pri, rc, vers; 3316 3317#if 0 3318 CASSERT(RTW_DESC_ALIGNMENT % sizeof(struct rtw_txdesc) == 0, 3319 "RTW_DESC_ALIGNMENT is not a multiple of " 3320 "sizeof(struct rtw_txdesc)"); 3321 3322 CASSERT(RTW_DESC_ALIGNMENT % sizeof(struct rtw_rxdesc) == 0, 3323 "RTW_DESC_ALIGNMENT is not a multiple of " 3324 "sizeof(struct rtw_rxdesc)"); 3325 3326 CASSERT(RTW_DESC_ALIGNMENT % RTW_MAXPKTSEGS == 0, 3327 "RTW_DESC_ALIGNMENT is not a multiple of RTW_MAXPKTSEGS"); 3328#endif 3329 3330 NEXT_ATTACH_STATE(sc, DETACHED); 3331 3332 switch (RTW_READ(&sc->sc_regs, RTW_TCR) & RTW_TCR_HWVERID_MASK) { 3333 case RTW_TCR_HWVERID_F: 3334 vers = 'F'; 3335 rf_write = rtw_rf_hostwrite; 3336 break; 3337 case RTW_TCR_HWVERID_D: 3338 vers = 'D'; 3339 if (rtw_host_rfio) 3340 rf_write = rtw_rf_hostwrite; 3341 else 3342 rf_write = rtw_rf_macwrite; 3343 break; 3344 default: 3345 vers = '?'; 3346 rf_write = rtw_rf_macwrite; 3347 break; 3348 } 3349 printf("%s: hardware version %c\n", sc->sc_dev.dv_xname, vers); 3350 3351 rc = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct rtw_descs), 3352 RTW_DESC_ALIGNMENT, 0, &sc->sc_desc_segs, 1, &sc->sc_desc_nsegs, 3353 0); 3354 3355 if (rc != 0) { 3356 printf("%s: could not allocate hw descriptors, error %d\n", 3357 sc->sc_dev.dv_xname, rc); 3358 goto err; 3359 } 3360 3361 NEXT_ATTACH_STATE(sc, FINISH_DESC_ALLOC); 3362 3363 rc = bus_dmamem_map(sc->sc_dmat, &sc->sc_desc_segs, 3364 sc->sc_desc_nsegs, sizeof(struct rtw_descs), 3365 (caddr_t*)&sc->sc_descs, BUS_DMA_COHERENT); 3366 3367 if (rc != 0) { 3368 printf("%s: could not map hw descriptors, error %d\n", 3369 sc->sc_dev.dv_xname, rc); 3370 goto err; 3371 } 3372 NEXT_ATTACH_STATE(sc, FINISH_DESC_MAP); 3373 3374 rc = bus_dmamap_create(sc->sc_dmat, sizeof(struct rtw_descs), 1, 3375 sizeof(struct rtw_descs), 0, 0, &sc->sc_desc_dmamap); 3376 3377 if (rc != 0) { 3378 printf("%s: could not create DMA map for hw descriptors, " 3379 "error %d\n", sc->sc_dev.dv_xname, rc); 3380 goto err; 3381 } 3382 NEXT_ATTACH_STATE(sc, FINISH_DESCMAP_CREATE); 3383 3384 rc = bus_dmamap_load(sc->sc_dmat, sc->sc_desc_dmamap, sc->sc_descs, 3385 sizeof(struct rtw_descs), NULL, 0); 3386 3387 if (rc != 0) { 3388 printf("%s: could not load DMA map for hw descriptors, " 3389 "error %d\n", sc->sc_dev.dv_xname, rc); 3390 goto err; 3391 } 3392 NEXT_ATTACH_STATE(sc, FINISH_DESCMAP_LOAD); 3393 3394 if (rtw_txctl_blk_setup_all(sc) != 0) 3395 goto err; 3396 NEXT_ATTACH_STATE(sc, FINISH_TXCTLBLK_SETUP); 3397 3398 rtw_txdesc_blk_setup_all(sc); 3399 3400 NEXT_ATTACH_STATE(sc, FINISH_TXDESCBLK_SETUP); 3401 3402 sc->sc_rxdesc = &sc->sc_descs->hd_rx[0]; 3403 3404 rtw_rxctls_setup(&sc->sc_rxctl[0]); 3405 3406 for (pri = 0; pri < RTW_NTXPRI; pri++) { 3407 stc = &sc->sc_txctl_blk[pri]; 3408 3409 if ((rc = rtw_txdesc_dmamaps_create(sc->sc_dmat, 3410 &stc->stc_desc[0], stc->stc_ndesc)) != 0) { 3411 printf("%s: could not load DMA map for " 3412 "hw tx descriptors, error %d\n", 3413 sc->sc_dev.dv_xname, rc); 3414 goto err; 3415 } 3416 } 3417 3418 NEXT_ATTACH_STATE(sc, FINISH_TXMAPS_CREATE); 3419 if ((rc = rtw_rxdesc_dmamaps_create(sc->sc_dmat, &sc->sc_rxctl[0], 3420 RTW_RXQLEN)) != 0) { 3421 printf("%s: could not load DMA map for hw rx descriptors, " 3422 "error %d\n", sc->sc_dev.dv_xname, rc); 3423 goto err; 3424 } 3425 NEXT_ATTACH_STATE(sc, FINISH_RXMAPS_CREATE); 3426 3427 /* Reset the chip to a known state. */ 3428 if (rtw_reset(sc) != 0) 3429 goto err; 3430 NEXT_ATTACH_STATE(sc, FINISH_RESET); 3431 3432 sc->sc_rcr = RTW_READ(&sc->sc_regs, RTW_RCR); 3433 3434 if ((sc->sc_rcr & RTW_RCR_9356SEL) != 0) 3435 sc->sc_flags |= RTW_F_9356SROM; 3436 3437 if (rtw_srom_read(&sc->sc_regs, sc->sc_flags, &sc->sc_srom, 3438 sc->sc_dev.dv_xname) != 0) 3439 goto err; 3440 3441 NEXT_ATTACH_STATE(sc, FINISH_READ_SROM); 3442 3443 if (rtw_srom_parse(&sc->sc_srom, &sc->sc_flags, &sc->sc_csthr, 3444 &sc->sc_rfchipid, &sc->sc_rcr, &sc->sc_locale, 3445 sc->sc_dev.dv_xname) != 0) { 3446 printf("%s: attach failed, malformed serial ROM\n", 3447 sc->sc_dev.dv_xname); 3448 goto err; 3449 } 3450 3451 printf("%s: %s PHY\n", sc->sc_dev.dv_xname, 3452 ((sc->sc_flags & RTW_F_DIGPHY) != 0) ? "digital" : "analog"); 3453 3454 printf("%s: CS threshold %u\n", sc->sc_dev.dv_xname, sc->sc_csthr); 3455 3456 NEXT_ATTACH_STATE(sc, FINISH_PARSE_SROM); 3457 3458 sc->sc_rf = rtw_rf_attach(sc, sc->sc_rfchipid, rf_write, 3459 sc->sc_flags & RTW_F_DIGPHY); 3460 3461 if (sc->sc_rf == NULL) { 3462 printf("%s: attach failed, could not attach RF\n", 3463 sc->sc_dev.dv_xname); 3464 goto err; 3465 } 3466 3467#if 0 3468 if (rtw_identify_rf(&sc->sc_regs, &sc->sc_rftype, 3469 sc->sc_dev.dv_xname) != 0) { 3470 printf("%s: attach failed, unknown RF unidentified\n", 3471 sc->sc_dev.dv_xname); 3472 goto err; 3473 } 3474#endif 3475 3476 NEXT_ATTACH_STATE(sc, FINISH_RF_ATTACH); 3477 3478 sc->sc_phydelay = rtw_check_phydelay(&sc->sc_regs, sc->sc_rcr); 3479 3480 RTW_DPRINTF(RTW_DEBUG_ATTACH, 3481 ("%s: PHY delay %d\n", sc->sc_dev.dv_xname, sc->sc_phydelay)); 3482 3483 if (sc->sc_locale == RTW_LOCALE_UNKNOWN) 3484 rtw_identify_country(&sc->sc_regs, &sc->sc_locale, 3485 sc->sc_dev.dv_xname); 3486 3487 rtw_init_channels(sc->sc_locale, &sc->sc_ic.ic_channels, 3488 sc->sc_dev.dv_xname); 3489 3490 if (rtw_identify_sta(&sc->sc_regs, &sc->sc_ic.ic_myaddr, 3491 sc->sc_dev.dv_xname) != 0) 3492 goto err; 3493 NEXT_ATTACH_STATE(sc, FINISH_ID_STA); 3494 3495 rtw_setifprops(&sc->sc_if, sc->sc_dev.dv_xname, (void*)sc); 3496 3497 IFQ_SET_READY(&sc->sc_if.if_snd); 3498 3499 rtw_set80211props(&sc->sc_ic); 3500 3501 /* 3502 * Call MI attach routines. 3503 */ 3504 if_attach(&sc->sc_if); 3505 ieee80211_ifattach(&sc->sc_if); 3506 3507 rtw_set80211methods(&sc->sc_mtbl, &sc->sc_ic); 3508 3509 /* possibly we should fill in our own sc_send_prresp, since 3510 * the RTL8180 is probably sending probe responses in ad hoc 3511 * mode. 3512 */ 3513 3514 /* complete initialization */ 3515 ieee80211_media_init(&sc->sc_if, rtw_media_change, rtw_media_status); 3516 callout_init(&sc->sc_scan_ch); 3517 3518#if NBPFILTER > 0 3519 bpfattach2(&sc->sc_if, DLT_IEEE802_11_RADIO, 3520 sizeof(struct ieee80211_frame) + 64, &sc->sc_radiobpf); 3521#endif 3522 3523 rtw_establish_hooks(&sc->sc_hooks, sc->sc_dev.dv_xname, (void*)sc); 3524 3525 rtw_init_radiotap(sc); 3526 3527 NEXT_ATTACH_STATE(sc, FINISHED); 3528 3529 return; 3530err: 3531 rtw_detach(sc); 3532 return; 3533} 3534 3535int 3536rtw_detach(struct rtw_softc *sc) 3537{ 3538 int pri; 3539 3540 switch (sc->sc_attach_state) { 3541 case FINISHED: 3542 rtw_stop(&sc->sc_if, 1); 3543 3544 rtw_disestablish_hooks(&sc->sc_hooks, sc->sc_dev.dv_xname, 3545 (void*)sc); 3546 callout_stop(&sc->sc_scan_ch); 3547 ieee80211_ifdetach(&sc->sc_if); 3548 if_detach(&sc->sc_if); 3549 break; 3550 case FINISH_ID_STA: 3551 case FINISH_RF_ATTACH: 3552 rtw_rf_destroy(sc->sc_rf); 3553 sc->sc_rf = NULL; 3554 /*FALLTHROUGH*/ 3555 case FINISH_PARSE_SROM: 3556 case FINISH_READ_SROM: 3557 rtw_srom_free(&sc->sc_srom); 3558 /*FALLTHROUGH*/ 3559 case FINISH_RESET: 3560 case FINISH_RXMAPS_CREATE: 3561 rtw_rxdesc_dmamaps_destroy(sc->sc_dmat, &sc->sc_rxctl[0], 3562 RTW_RXQLEN); 3563 /*FALLTHROUGH*/ 3564 case FINISH_TXMAPS_CREATE: 3565 for (pri = 0; pri < RTW_NTXPRI; pri++) { 3566 rtw_txdesc_dmamaps_destroy(sc->sc_dmat, 3567 sc->sc_txctl_blk[pri].stc_desc, 3568 sc->sc_txctl_blk[pri].stc_ndesc); 3569 } 3570 /*FALLTHROUGH*/ 3571 case FINISH_TXDESCBLK_SETUP: 3572 case FINISH_TXCTLBLK_SETUP: 3573 rtw_txctl_blk_cleanup_all(sc); 3574 /*FALLTHROUGH*/ 3575 case FINISH_DESCMAP_LOAD: 3576 bus_dmamap_unload(sc->sc_dmat, sc->sc_desc_dmamap); 3577 /*FALLTHROUGH*/ 3578 case FINISH_DESCMAP_CREATE: 3579 bus_dmamap_destroy(sc->sc_dmat, sc->sc_desc_dmamap); 3580 /*FALLTHROUGH*/ 3581 case FINISH_DESC_MAP: 3582 bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_descs, 3583 sizeof(struct rtw_descs)); 3584 /*FALLTHROUGH*/ 3585 case FINISH_DESC_ALLOC: 3586 bus_dmamem_free(sc->sc_dmat, &sc->sc_desc_segs, 3587 sc->sc_desc_nsegs); 3588 /*FALLTHROUGH*/ 3589 case DETACHED: 3590 NEXT_ATTACH_STATE(sc, DETACHED); 3591 break; 3592 } 3593 return 0; 3594} 3595 3596int 3597rtw_activate(struct device *self, enum devact act) 3598{ 3599 struct rtw_softc *sc = (struct rtw_softc *)self; 3600 int rc = 0, s; 3601 3602 s = splnet(); 3603 switch (act) { 3604 case DVACT_ACTIVATE: 3605 rc = EOPNOTSUPP; 3606 break; 3607 3608 case DVACT_DEACTIVATE: 3609 if_deactivate(&sc->sc_ic.ic_if); 3610 break; 3611 } 3612 splx(s); 3613 return rc; 3614} 3615