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