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