rtw.c revision 1.84
1/* $NetBSD: rtw.c,v 1.84 2007/01/29 07:08:09 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.84 2007/01/29 07:08:09 dyoung Exp $"); 38 39#include "bpfilter.h" 40 41#include <sys/param.h> 42#include <sys/sysctl.h> 43#include <sys/systm.h> 44#include <sys/callout.h> 45#include <sys/mbuf.h> 46#include <sys/malloc.h> 47#include <sys/kernel.h> 48#include <sys/time.h> 49#include <sys/types.h> 50 51#include <machine/endian.h> 52#include <machine/bus.h> 53#include <machine/intr.h> /* splnet */ 54 55#include <uvm/uvm_extern.h> 56 57#include <net/if.h> 58#include <net/if_media.h> 59#include <net/if_ether.h> 60 61#include <net80211/ieee80211_netbsd.h> 62#include <net80211/ieee80211_var.h> 63#include <net80211/ieee80211_radiotap.h> 64 65#if NBPFILTER > 0 66#include <net/bpf.h> 67#endif 68 69#include <dev/ic/rtwreg.h> 70#include <dev/ic/rtwvar.h> 71#include <dev/ic/rtwphyio.h> 72#include <dev/ic/rtwphy.h> 73 74#include <dev/ic/smc93cx6var.h> 75 76#define KASSERT2(__cond, __msg) \ 77 do { \ 78 if (!(__cond)) \ 79 panic __msg ; \ 80 } while (0) 81 82static int rtw_rfprog_fallback = 0; 83static int rtw_host_rfio = 0; 84 85#ifdef RTW_DEBUG 86int rtw_debug = 0; 87static int rtw_rxbufs_limit = RTW_RXQLEN; 88#endif /* RTW_DEBUG */ 89 90#define NEXT_ATTACH_STATE(sc, state) do { \ 91 DPRINTF(sc, RTW_DEBUG_ATTACH, \ 92 ("%s: attach state %s\n", __func__, #state)); \ 93 sc->sc_attach_state = state; \ 94} while (0) 95 96int rtw_dwelltime = 200; /* milliseconds */ 97static struct ieee80211_cipher rtw_cipher_wep; 98 99static void rtw_start(struct ifnet *); 100static void rtw_reset_oactive(struct rtw_softc *); 101static struct mbuf *rtw_beacon_alloc(struct rtw_softc *, 102 struct ieee80211_node *); 103static u_int rtw_txring_next(struct rtw_regs *, struct rtw_txdesc_blk *); 104 105static void rtw_io_enable(struct rtw_softc *, uint8_t, int); 106static int rtw_key_delete(struct ieee80211com *, const struct ieee80211_key *); 107static int rtw_key_set(struct ieee80211com *, const struct ieee80211_key *, 108 const u_int8_t[IEEE80211_ADDR_LEN]); 109static void rtw_key_update_end(struct ieee80211com *); 110static void rtw_key_update_begin(struct ieee80211com *); 111static int rtw_wep_decap(struct ieee80211_key *, struct mbuf *, int); 112static void rtw_wep_setkeys(struct rtw_softc *, struct ieee80211_key *, int); 113 114static void rtw_led_attach(struct rtw_led_state *, void *); 115static void rtw_led_init(struct rtw_regs *); 116static void rtw_led_slowblink(void *); 117static void rtw_led_fastblink(void *); 118static void rtw_led_set(struct rtw_led_state *, struct rtw_regs *, int); 119 120static int rtw_sysctl_verify_rfio(SYSCTLFN_PROTO); 121static int rtw_sysctl_verify_rfprog(SYSCTLFN_PROTO); 122#ifdef RTW_DEBUG 123static void rtw_dump_rings(struct rtw_softc *sc); 124static void rtw_print_txdesc(struct rtw_softc *, const char *, 125 struct rtw_txsoft *, struct rtw_txdesc_blk *, int); 126static int rtw_sysctl_verify_debug(SYSCTLFN_PROTO); 127static int rtw_sysctl_verify_rxbufs_limit(SYSCTLFN_PROTO); 128#endif /* RTW_DEBUG */ 129#ifdef RTW_DIAG 130static void rtw_txring_fixup(struct rtw_softc *sc, const char *fn, int ln); 131#endif /* RTW_DIAG */ 132 133/* 134 * Setup sysctl(3) MIB, hw.rtw.* 135 * 136 * TBD condition CTLFLAG_PERMANENT on being an LKM or not 137 */ 138SYSCTL_SETUP(sysctl_rtw, "sysctl rtw(4) subtree setup") 139{ 140 int rc; 141 const struct sysctlnode *cnode, *rnode; 142 143 if ((rc = sysctl_createv(clog, 0, NULL, &rnode, 144 CTLFLAG_PERMANENT, CTLTYPE_NODE, "hw", NULL, 145 NULL, 0, NULL, 0, CTL_HW, CTL_EOL)) != 0) 146 goto err; 147 148 if ((rc = sysctl_createv(clog, 0, &rnode, &rnode, 149 CTLFLAG_PERMANENT, CTLTYPE_NODE, "rtw", 150 "Realtek RTL818x 802.11 controls", 151 NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0) 152 goto err; 153 154#ifdef RTW_DEBUG 155 /* control debugging printfs */ 156 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode, 157 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, 158 "debug", SYSCTL_DESCR("Enable RTL818x debugging output"), 159 rtw_sysctl_verify_debug, 0, &rtw_debug, 0, 160 CTL_CREATE, CTL_EOL)) != 0) 161 goto err; 162 163 /* Limit rx buffers, for simulating resource exhaustion. */ 164 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode, 165 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, 166 "rxbufs_limit", 167 SYSCTL_DESCR("Set rx buffers limit"), 168 rtw_sysctl_verify_rxbufs_limit, 0, &rtw_rxbufs_limit, 0, 169 CTL_CREATE, CTL_EOL)) != 0) 170 goto err; 171 172#endif /* RTW_DEBUG */ 173 /* set fallback RF programming method */ 174 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode, 175 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, 176 "rfprog_fallback", 177 SYSCTL_DESCR("Set fallback RF programming method"), 178 rtw_sysctl_verify_rfprog, 0, &rtw_rfprog_fallback, 0, 179 CTL_CREATE, CTL_EOL)) != 0) 180 goto err; 181 182 /* force host to control RF I/O bus */ 183 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode, 184 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, 185 "host_rfio", SYSCTL_DESCR("Enable host control of RF I/O"), 186 rtw_sysctl_verify_rfio, 0, &rtw_host_rfio, 0, 187 CTL_CREATE, CTL_EOL)) != 0) 188 goto err; 189 190 return; 191err: 192 printf("%s: sysctl_createv failed (rc = %d)\n", __func__, rc); 193} 194 195static int 196rtw_sysctl_verify(SYSCTLFN_ARGS, int lower, int upper) 197{ 198 int error, t; 199 struct sysctlnode node; 200 201 node = *rnode; 202 t = *(int*)rnode->sysctl_data; 203 node.sysctl_data = &t; 204 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 205 if (error || newp == NULL) 206 return (error); 207 208 if (t < lower || t > upper) 209 return (EINVAL); 210 211 *(int*)rnode->sysctl_data = t; 212 213 return (0); 214} 215 216static int 217rtw_sysctl_verify_rfprog(SYSCTLFN_ARGS) 218{ 219 return rtw_sysctl_verify(SYSCTLFN_CALL(__UNCONST(rnode)), 0, 220 __SHIFTOUT(RTW_CONFIG4_RFTYPE_MASK, RTW_CONFIG4_RFTYPE_MASK)); 221} 222 223static int 224rtw_sysctl_verify_rfio(SYSCTLFN_ARGS) 225{ 226 return rtw_sysctl_verify(SYSCTLFN_CALL(__UNCONST(rnode)), 0, 1); 227} 228 229#ifdef RTW_DEBUG 230static int 231rtw_sysctl_verify_debug(SYSCTLFN_ARGS) 232{ 233 return rtw_sysctl_verify(SYSCTLFN_CALL(__UNCONST(rnode)), 234 0, RTW_DEBUG_MAX); 235} 236 237static int 238rtw_sysctl_verify_rxbufs_limit(SYSCTLFN_ARGS) 239{ 240 return rtw_sysctl_verify(SYSCTLFN_CALL(__UNCONST(rnode)), 241 0, RTW_RXQLEN); 242} 243 244static void 245rtw_print_regs(struct rtw_regs *regs, const char *dvname, const char *where) 246{ 247#define PRINTREG32(sc, reg) \ 248 RTW_DPRINTF(RTW_DEBUG_REGDUMP, \ 249 ("%s: reg[ " #reg " / %03x ] = %08x\n", \ 250 dvname, reg, RTW_READ(regs, reg))) 251 252#define PRINTREG16(sc, reg) \ 253 RTW_DPRINTF(RTW_DEBUG_REGDUMP, \ 254 ("%s: reg[ " #reg " / %03x ] = %04x\n", \ 255 dvname, reg, RTW_READ16(regs, reg))) 256 257#define PRINTREG8(sc, reg) \ 258 RTW_DPRINTF(RTW_DEBUG_REGDUMP, \ 259 ("%s: reg[ " #reg " / %03x ] = %02x\n", \ 260 dvname, reg, RTW_READ8(regs, reg))) 261 262 RTW_DPRINTF(RTW_DEBUG_REGDUMP, ("%s: %s\n", dvname, where)); 263 264 PRINTREG32(regs, RTW_IDR0); 265 PRINTREG32(regs, RTW_IDR1); 266 PRINTREG32(regs, RTW_MAR0); 267 PRINTREG32(regs, RTW_MAR1); 268 PRINTREG32(regs, RTW_TSFTRL); 269 PRINTREG32(regs, RTW_TSFTRH); 270 PRINTREG32(regs, RTW_TLPDA); 271 PRINTREG32(regs, RTW_TNPDA); 272 PRINTREG32(regs, RTW_THPDA); 273 PRINTREG32(regs, RTW_TCR); 274 PRINTREG32(regs, RTW_RCR); 275 PRINTREG32(regs, RTW_TINT); 276 PRINTREG32(regs, RTW_TBDA); 277 PRINTREG32(regs, RTW_ANAPARM); 278 PRINTREG32(regs, RTW_BB); 279 PRINTREG32(regs, RTW_PHYCFG); 280 PRINTREG32(regs, RTW_WAKEUP0L); 281 PRINTREG32(regs, RTW_WAKEUP0H); 282 PRINTREG32(regs, RTW_WAKEUP1L); 283 PRINTREG32(regs, RTW_WAKEUP1H); 284 PRINTREG32(regs, RTW_WAKEUP2LL); 285 PRINTREG32(regs, RTW_WAKEUP2LH); 286 PRINTREG32(regs, RTW_WAKEUP2HL); 287 PRINTREG32(regs, RTW_WAKEUP2HH); 288 PRINTREG32(regs, RTW_WAKEUP3LL); 289 PRINTREG32(regs, RTW_WAKEUP3LH); 290 PRINTREG32(regs, RTW_WAKEUP3HL); 291 PRINTREG32(regs, RTW_WAKEUP3HH); 292 PRINTREG32(regs, RTW_WAKEUP4LL); 293 PRINTREG32(regs, RTW_WAKEUP4LH); 294 PRINTREG32(regs, RTW_WAKEUP4HL); 295 PRINTREG32(regs, RTW_WAKEUP4HH); 296 PRINTREG32(regs, RTW_DK0); 297 PRINTREG32(regs, RTW_DK1); 298 PRINTREG32(regs, RTW_DK2); 299 PRINTREG32(regs, RTW_DK3); 300 PRINTREG32(regs, RTW_RETRYCTR); 301 PRINTREG32(regs, RTW_RDSAR); 302 PRINTREG32(regs, RTW_FER); 303 PRINTREG32(regs, RTW_FEMR); 304 PRINTREG32(regs, RTW_FPSR); 305 PRINTREG32(regs, RTW_FFER); 306 307 /* 16-bit registers */ 308 PRINTREG16(regs, RTW_BRSR); 309 PRINTREG16(regs, RTW_IMR); 310 PRINTREG16(regs, RTW_ISR); 311 PRINTREG16(regs, RTW_BCNITV); 312 PRINTREG16(regs, RTW_ATIMWND); 313 PRINTREG16(regs, RTW_BINTRITV); 314 PRINTREG16(regs, RTW_ATIMTRITV); 315 PRINTREG16(regs, RTW_CRC16ERR); 316 PRINTREG16(regs, RTW_CRC0); 317 PRINTREG16(regs, RTW_CRC1); 318 PRINTREG16(regs, RTW_CRC2); 319 PRINTREG16(regs, RTW_CRC3); 320 PRINTREG16(regs, RTW_CRC4); 321 PRINTREG16(regs, RTW_CWR); 322 323 /* 8-bit registers */ 324 PRINTREG8(regs, RTW_CR); 325 PRINTREG8(regs, RTW_9346CR); 326 PRINTREG8(regs, RTW_CONFIG0); 327 PRINTREG8(regs, RTW_CONFIG1); 328 PRINTREG8(regs, RTW_CONFIG2); 329 PRINTREG8(regs, RTW_MSR); 330 PRINTREG8(regs, RTW_CONFIG3); 331 PRINTREG8(regs, RTW_CONFIG4); 332 PRINTREG8(regs, RTW_TESTR); 333 PRINTREG8(regs, RTW_PSR); 334 PRINTREG8(regs, RTW_SCR); 335 PRINTREG8(regs, RTW_PHYDELAY); 336 PRINTREG8(regs, RTW_CRCOUNT); 337 PRINTREG8(regs, RTW_PHYADDR); 338 PRINTREG8(regs, RTW_PHYDATAW); 339 PRINTREG8(regs, RTW_PHYDATAR); 340 PRINTREG8(regs, RTW_CONFIG5); 341 PRINTREG8(regs, RTW_TPPOLL); 342 343 PRINTREG16(regs, RTW_BSSID16); 344 PRINTREG32(regs, RTW_BSSID32); 345#undef PRINTREG32 346#undef PRINTREG16 347#undef PRINTREG8 348} 349#endif /* RTW_DEBUG */ 350 351void 352rtw_continuous_tx_enable(struct rtw_softc *sc, int enable) 353{ 354 struct rtw_regs *regs = &sc->sc_regs; 355 356 uint32_t tcr; 357 tcr = RTW_READ(regs, RTW_TCR); 358 tcr &= ~RTW_TCR_LBK_MASK; 359 if (enable) 360 tcr |= RTW_TCR_LBK_CONT; 361 else 362 tcr |= RTW_TCR_LBK_NORMAL; 363 RTW_WRITE(regs, RTW_TCR, tcr); 364 RTW_SYNC(regs, RTW_TCR, RTW_TCR); 365 rtw_set_access(regs, RTW_ACCESS_ANAPARM); 366 rtw_txdac_enable(sc, !enable); 367 rtw_set_access(regs, RTW_ACCESS_ANAPARM);/* XXX Voodoo from Linux. */ 368 rtw_set_access(regs, RTW_ACCESS_NONE); 369} 370 371#ifdef RTW_DEBUG 372static const char * 373rtw_access_string(enum rtw_access access) 374{ 375 switch (access) { 376 case RTW_ACCESS_NONE: 377 return "none"; 378 case RTW_ACCESS_CONFIG: 379 return "config"; 380 case RTW_ACCESS_ANAPARM: 381 return "anaparm"; 382 default: 383 return "unknown"; 384 } 385} 386#endif /* RTW_DEBUG */ 387 388static void 389rtw_set_access1(struct rtw_regs *regs, enum rtw_access naccess) 390{ 391 KASSERT(/* naccess >= RTW_ACCESS_NONE && */ 392 naccess <= RTW_ACCESS_ANAPARM); 393 KASSERT(/* regs->r_access >= RTW_ACCESS_NONE && */ 394 regs->r_access <= RTW_ACCESS_ANAPARM); 395 396 if (naccess == regs->r_access) 397 return; 398 399 switch (naccess) { 400 case RTW_ACCESS_NONE: 401 switch (regs->r_access) { 402 case RTW_ACCESS_ANAPARM: 403 rtw_anaparm_enable(regs, 0); 404 /*FALLTHROUGH*/ 405 case RTW_ACCESS_CONFIG: 406 rtw_config0123_enable(regs, 0); 407 /*FALLTHROUGH*/ 408 case RTW_ACCESS_NONE: 409 break; 410 } 411 break; 412 case RTW_ACCESS_CONFIG: 413 switch (regs->r_access) { 414 case RTW_ACCESS_NONE: 415 rtw_config0123_enable(regs, 1); 416 /*FALLTHROUGH*/ 417 case RTW_ACCESS_CONFIG: 418 break; 419 case RTW_ACCESS_ANAPARM: 420 rtw_anaparm_enable(regs, 0); 421 break; 422 } 423 break; 424 case RTW_ACCESS_ANAPARM: 425 switch (regs->r_access) { 426 case RTW_ACCESS_NONE: 427 rtw_config0123_enable(regs, 1); 428 /*FALLTHROUGH*/ 429 case RTW_ACCESS_CONFIG: 430 rtw_anaparm_enable(regs, 1); 431 /*FALLTHROUGH*/ 432 case RTW_ACCESS_ANAPARM: 433 break; 434 } 435 break; 436 } 437} 438 439void 440rtw_set_access(struct rtw_regs *regs, enum rtw_access access) 441{ 442 rtw_set_access1(regs, access); 443 RTW_DPRINTF(RTW_DEBUG_ACCESS, 444 ("%s: access %s -> %s\n", __func__, 445 rtw_access_string(regs->r_access), 446 rtw_access_string(access))); 447 regs->r_access = access; 448} 449 450/* 451 * Enable registers, switch register banks. 452 */ 453void 454rtw_config0123_enable(struct rtw_regs *regs, int enable) 455{ 456 uint8_t ecr; 457 ecr = RTW_READ8(regs, RTW_9346CR); 458 ecr &= ~(RTW_9346CR_EEM_MASK | RTW_9346CR_EECS | RTW_9346CR_EESK); 459 if (enable) 460 ecr |= RTW_9346CR_EEM_CONFIG; 461 else { 462 RTW_WBW(regs, RTW_9346CR, MAX(RTW_CONFIG0, RTW_CONFIG3)); 463 ecr |= RTW_9346CR_EEM_NORMAL; 464 } 465 RTW_WRITE8(regs, RTW_9346CR, ecr); 466 RTW_SYNC(regs, RTW_9346CR, RTW_9346CR); 467} 468 469/* requires rtw_config0123_enable(, 1) */ 470void 471rtw_anaparm_enable(struct rtw_regs *regs, int enable) 472{ 473 uint8_t cfg3; 474 475 cfg3 = RTW_READ8(regs, RTW_CONFIG3); 476 cfg3 |= RTW_CONFIG3_CLKRUNEN; 477 if (enable) 478 cfg3 |= RTW_CONFIG3_PARMEN; 479 else 480 cfg3 &= ~RTW_CONFIG3_PARMEN; 481 RTW_WRITE8(regs, RTW_CONFIG3, cfg3); 482 RTW_SYNC(regs, RTW_CONFIG3, RTW_CONFIG3); 483} 484 485/* requires rtw_anaparm_enable(, 1) */ 486void 487rtw_txdac_enable(struct rtw_softc *sc, int enable) 488{ 489 uint32_t anaparm; 490 struct rtw_regs *regs = &sc->sc_regs; 491 492 anaparm = RTW_READ(regs, RTW_ANAPARM); 493 if (enable) 494 anaparm &= ~RTW_ANAPARM_TXDACOFF; 495 else 496 anaparm |= RTW_ANAPARM_TXDACOFF; 497 RTW_WRITE(regs, RTW_ANAPARM, anaparm); 498 RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM); 499} 500 501static inline int 502rtw_chip_reset1(struct rtw_regs *regs, const char *dvname) 503{ 504 uint8_t cr; 505 int i; 506 507 RTW_WRITE8(regs, RTW_CR, RTW_CR_RST); 508 509 RTW_WBR(regs, RTW_CR, RTW_CR); 510 511 for (i = 0; i < 1000; i++) { 512 if ((cr = RTW_READ8(regs, RTW_CR) & RTW_CR_RST) == 0) { 513 RTW_DPRINTF(RTW_DEBUG_RESET, 514 ("%s: reset in %dus\n", dvname, i)); 515 return 0; 516 } 517 RTW_RBR(regs, RTW_CR, RTW_CR); 518 DELAY(10); /* 10us */ 519 } 520 521 printf("%s: reset failed\n", dvname); 522 return ETIMEDOUT; 523} 524 525static inline int 526rtw_chip_reset(struct rtw_regs *regs, const char *dvname) 527{ 528 uint32_t tcr; 529 530 /* from Linux driver */ 531 tcr = RTW_TCR_CWMIN | RTW_TCR_MXDMA_2048 | 532 __SHIFTIN(7, RTW_TCR_SRL_MASK) | __SHIFTIN(7, RTW_TCR_LRL_MASK); 533 534 RTW_WRITE(regs, RTW_TCR, tcr); 535 536 RTW_WBW(regs, RTW_CR, RTW_TCR); 537 538 return rtw_chip_reset1(regs, dvname); 539} 540 541static int 542rtw_wep_decap(struct ieee80211_key *k, struct mbuf *m, int hdrlen) 543{ 544 struct ieee80211_key keycopy; 545 546 RTW_DPRINTF(RTW_DEBUG_KEY, ("%s:\n", __func__)); 547 548 keycopy = *k; 549 keycopy.wk_flags &= ~IEEE80211_KEY_SWCRYPT; 550 551 return (*ieee80211_cipher_wep.ic_decap)(&keycopy, m, hdrlen); 552} 553 554static int 555rtw_key_delete(struct ieee80211com *ic, const struct ieee80211_key *k) 556{ 557 struct rtw_softc *sc = ic->ic_ifp->if_softc; 558 u_int keyix = k->wk_keyix; 559 560 DPRINTF(sc, RTW_DEBUG_KEY, ("%s: delete key %u\n", __func__, keyix)); 561 562 if (keyix >= IEEE80211_WEP_NKID) 563 return 0; 564 if (k->wk_keylen != 0) 565 sc->sc_flags &= ~RTW_F_DK_VALID; 566 567 return 1; 568} 569 570static int 571rtw_key_set(struct ieee80211com *ic, const struct ieee80211_key *k, 572 const u_int8_t mac[IEEE80211_ADDR_LEN]) 573{ 574 struct rtw_softc *sc = ic->ic_ifp->if_softc; 575 576 DPRINTF(sc, RTW_DEBUG_KEY, ("%s: set key %u\n", __func__, k->wk_keyix)); 577 578 if (k->wk_keyix >= IEEE80211_WEP_NKID) 579 return 0; 580 581 sc->sc_flags &= ~RTW_F_DK_VALID; 582 583 return 1; 584} 585 586static void 587rtw_key_update_begin(struct ieee80211com *ic) 588{ 589#ifdef RTW_DEBUG 590 struct ifnet *ifp = ic->ic_ifp; 591 struct rtw_softc *sc = ifp->if_softc; 592#endif 593 594 DPRINTF(sc, RTW_DEBUG_KEY, ("%s:\n", __func__)); 595} 596 597static void 598rtw_key_update_end(struct ieee80211com *ic) 599{ 600 struct ifnet *ifp = ic->ic_ifp; 601 struct rtw_softc *sc = ifp->if_softc; 602 603 DPRINTF(sc, RTW_DEBUG_KEY, ("%s:\n", __func__)); 604 605 if ((sc->sc_flags & RTW_F_DK_VALID) != 0 || 606 (sc->sc_flags & RTW_F_ENABLED) == 0 || 607 (sc->sc_flags & RTW_F_INVALID) != 0) 608 return; 609 610 rtw_io_enable(sc, RTW_CR_RE | RTW_CR_TE, 0); 611 rtw_wep_setkeys(sc, ic->ic_nw_keys, ic->ic_def_txkey); 612 rtw_io_enable(sc, RTW_CR_RE | RTW_CR_TE, 613 (ifp->if_flags & IFF_RUNNING) != 0); 614} 615 616static inline int 617rtw_key_hwsupp(uint32_t flags, const struct ieee80211_key *k) 618{ 619 if (k->wk_cipher->ic_cipher != IEEE80211_CIPHER_WEP) 620 return 0; 621 622 return ((flags & RTW_C_RXWEP_40) != 0 && k->wk_keylen == 5) || 623 ((flags & RTW_C_RXWEP_104) != 0 && k->wk_keylen == 13); 624} 625 626static void 627rtw_wep_setkeys(struct rtw_softc *sc, struct ieee80211_key *wk, int txkey) 628{ 629 uint8_t psr, scr; 630 int i, keylen; 631 struct rtw_regs *regs; 632 union rtw_keys *rk; 633 634 regs = &sc->sc_regs; 635 rk = &sc->sc_keys; 636 637 (void)memset(rk->rk_keys, 0, sizeof(rk->rk_keys)); 638 639 /* Temporarily use software crypto for all keys. */ 640 for (i = 0; i < IEEE80211_WEP_NKID; i++) { 641 if (wk[i].wk_cipher == &rtw_cipher_wep) 642 wk[i].wk_cipher = &ieee80211_cipher_wep; 643 } 644 645 rtw_set_access(regs, RTW_ACCESS_CONFIG); 646 647 psr = RTW_READ8(regs, RTW_PSR); 648 scr = RTW_READ8(regs, RTW_SCR); 649 scr &= ~(RTW_SCR_KM_MASK | RTW_SCR_TXSECON | RTW_SCR_RXSECON); 650 651 if ((sc->sc_ic.ic_flags & IEEE80211_F_PRIVACY) == 0) 652 goto out; 653 654 for (keylen = i = 0; i < IEEE80211_WEP_NKID; i++) { 655 if (!rtw_key_hwsupp(sc->sc_flags, &wk[i])) 656 continue; 657 if (i == txkey) { 658 keylen = wk[i].wk_keylen; 659 break; 660 } 661 keylen = MAX(keylen, wk[i].wk_keylen); 662 } 663 664 if (keylen == 5) 665 scr |= RTW_SCR_KM_WEP40 | RTW_SCR_RXSECON; 666 else if (keylen == 13) 667 scr |= RTW_SCR_KM_WEP104 | RTW_SCR_RXSECON; 668 669 for (i = 0; i < IEEE80211_WEP_NKID; i++) { 670 if (wk[i].wk_keylen != keylen || 671 wk[i].wk_cipher->ic_cipher != IEEE80211_CIPHER_WEP) 672 continue; 673 /* h/w will decrypt, s/w still strips headers */ 674 wk[i].wk_cipher = &rtw_cipher_wep; 675 (void)memcpy(rk->rk_keys[i], wk[i].wk_key, wk[i].wk_keylen); 676 } 677 678out: 679 RTW_WRITE8(regs, RTW_PSR, psr & ~RTW_PSR_PSEN); 680 681 bus_space_write_region_4(regs->r_bt, regs->r_bh, 682 RTW_DK0, rk->rk_words, 683 sizeof(rk->rk_words) / sizeof(rk->rk_words[0])); 684 685 bus_space_barrier(regs->r_bt, regs->r_bh, RTW_DK0, sizeof(rk->rk_words), 686 BUS_SPACE_BARRIER_SYNC); 687 688 RTW_WBW(regs, RTW_DK0, RTW_PSR); 689 RTW_WRITE8(regs, RTW_PSR, psr); 690 RTW_WBW(regs, RTW_PSR, RTW_SCR); 691 RTW_WRITE8(regs, RTW_SCR, scr); 692 RTW_SYNC(regs, RTW_SCR, RTW_SCR); 693 rtw_set_access(regs, RTW_ACCESS_NONE); 694 sc->sc_flags |= RTW_F_DK_VALID; 695} 696 697static inline int 698rtw_recall_eeprom(struct rtw_regs *regs, const char *dvname) 699{ 700 int i; 701 uint8_t ecr; 702 703 ecr = RTW_READ8(regs, RTW_9346CR); 704 ecr = (ecr & ~RTW_9346CR_EEM_MASK) | RTW_9346CR_EEM_AUTOLOAD; 705 RTW_WRITE8(regs, RTW_9346CR, ecr); 706 707 RTW_WBR(regs, RTW_9346CR, RTW_9346CR); 708 709 /* wait 25ms for completion */ 710 for (i = 0; i < 250; i++) { 711 ecr = RTW_READ8(regs, RTW_9346CR); 712 if ((ecr & RTW_9346CR_EEM_MASK) == RTW_9346CR_EEM_NORMAL) { 713 RTW_DPRINTF(RTW_DEBUG_RESET, 714 ("%s: recall EEPROM in %dus\n", dvname, i * 100)); 715 return 0; 716 } 717 RTW_RBR(regs, RTW_9346CR, RTW_9346CR); 718 DELAY(100); 719 } 720 printf("%s: recall EEPROM failed\n", dvname); 721 return ETIMEDOUT; 722} 723 724static inline int 725rtw_reset(struct rtw_softc *sc) 726{ 727 int rc; 728 uint8_t config1; 729 730 sc->sc_flags &= ~RTW_F_DK_VALID; 731 732 if ((rc = rtw_chip_reset(&sc->sc_regs, sc->sc_dev.dv_xname)) != 0) 733 return rc; 734 735 rc = rtw_recall_eeprom(&sc->sc_regs, sc->sc_dev.dv_xname); 736 737 config1 = RTW_READ8(&sc->sc_regs, RTW_CONFIG1); 738 RTW_WRITE8(&sc->sc_regs, RTW_CONFIG1, config1 & ~RTW_CONFIG1_PMEN); 739 /* TBD turn off maximum power saving? */ 740 741 return 0; 742} 743 744static inline int 745rtw_txdesc_dmamaps_create(bus_dma_tag_t dmat, struct rtw_txsoft *descs, 746 u_int ndescs) 747{ 748 int i, rc = 0; 749 for (i = 0; i < ndescs; i++) { 750 rc = bus_dmamap_create(dmat, MCLBYTES, RTW_MAXPKTSEGS, MCLBYTES, 751 0, 0, &descs[i].ts_dmamap); 752 if (rc != 0) 753 break; 754 } 755 return rc; 756} 757 758static inline int 759rtw_rxdesc_dmamaps_create(bus_dma_tag_t dmat, struct rtw_rxsoft *descs, 760 u_int ndescs) 761{ 762 int i, rc = 0; 763 for (i = 0; i < ndescs; i++) { 764 rc = bus_dmamap_create(dmat, MCLBYTES, 1, MCLBYTES, 0, 0, 765 &descs[i].rs_dmamap); 766 if (rc != 0) 767 break; 768 } 769 return rc; 770} 771 772static inline void 773rtw_rxdesc_dmamaps_destroy(bus_dma_tag_t dmat, struct rtw_rxsoft *descs, 774 u_int ndescs) 775{ 776 int i; 777 for (i = 0; i < ndescs; i++) { 778 if (descs[i].rs_dmamap != NULL) 779 bus_dmamap_destroy(dmat, descs[i].rs_dmamap); 780 } 781} 782 783static inline void 784rtw_txdesc_dmamaps_destroy(bus_dma_tag_t dmat, struct rtw_txsoft *descs, 785 u_int ndescs) 786{ 787 int i; 788 for (i = 0; i < ndescs; i++) { 789 if (descs[i].ts_dmamap != NULL) 790 bus_dmamap_destroy(dmat, descs[i].ts_dmamap); 791 } 792} 793 794static inline void 795rtw_srom_free(struct rtw_srom *sr) 796{ 797 sr->sr_size = 0; 798 if (sr->sr_content == NULL) 799 return; 800 free(sr->sr_content, M_DEVBUF); 801 sr->sr_content = NULL; 802} 803 804static void 805rtw_srom_defaults(struct rtw_srom *sr, uint32_t *flags, 806 uint8_t *cs_threshold, enum rtw_rfchipid *rfchipid, uint32_t *rcr) 807{ 808 *flags |= (RTW_F_DIGPHY|RTW_F_ANTDIV); 809 *cs_threshold = RTW_SR_ENERGYDETTHR_DEFAULT; 810 *rcr |= RTW_RCR_ENCS1; 811 *rfchipid = RTW_RFCHIPID_PHILIPS; 812} 813 814static int 815rtw_srom_parse(struct rtw_srom *sr, uint32_t *flags, uint8_t *cs_threshold, 816 enum rtw_rfchipid *rfchipid, uint32_t *rcr, enum rtw_locale *locale, 817 const char *dvname) 818{ 819 int i; 820 const char *rfname, *paname; 821 char scratch[sizeof("unknown 0xXX")]; 822 uint16_t srom_version; 823 uint8_t mac[IEEE80211_ADDR_LEN]; 824 825 *flags &= ~(RTW_F_DIGPHY|RTW_F_DFLANTB|RTW_F_ANTDIV); 826 *rcr &= ~(RTW_RCR_ENCS1 | RTW_RCR_ENCS2); 827 828 srom_version = RTW_SR_GET16(sr, RTW_SR_VERSION); 829 printf("%s: SROM version %d.%d", dvname, 830 srom_version >> 8, srom_version & 0xff); 831 832 if (srom_version <= 0x0101) { 833 printf(" is not understood, limping along with defaults\n"); 834 rtw_srom_defaults(sr, flags, cs_threshold, rfchipid, rcr); 835 return 0; 836 } 837 printf("\n"); 838 839 for (i = 0; i < IEEE80211_ADDR_LEN; i++) 840 mac[i] = RTW_SR_GET(sr, RTW_SR_MAC + i); 841 842 RTW_DPRINTF(RTW_DEBUG_ATTACH, 843 ("%s: EEPROM MAC %s\n", dvname, ether_sprintf(mac))); 844 845 *cs_threshold = RTW_SR_GET(sr, RTW_SR_ENERGYDETTHR); 846 847 if ((RTW_SR_GET(sr, RTW_SR_CONFIG2) & RTW_CONFIG2_ANT) != 0) 848 *flags |= RTW_F_ANTDIV; 849 850 /* Note well: the sense of the RTW_SR_RFPARM_DIGPHY bit seems 851 * to be reversed. 852 */ 853 if ((RTW_SR_GET(sr, RTW_SR_RFPARM) & RTW_SR_RFPARM_DIGPHY) == 0) 854 *flags |= RTW_F_DIGPHY; 855 if ((RTW_SR_GET(sr, RTW_SR_RFPARM) & RTW_SR_RFPARM_DFLANTB) != 0) 856 *flags |= RTW_F_DFLANTB; 857 858 *rcr |= __SHIFTIN(__SHIFTOUT(RTW_SR_GET(sr, RTW_SR_RFPARM), 859 RTW_SR_RFPARM_CS_MASK), RTW_RCR_ENCS1); 860 861 if ((RTW_SR_GET(sr, RTW_SR_CONFIG0) & RTW_CONFIG0_WEP104) != 0) 862 *flags |= RTW_C_RXWEP_104; 863 864 *flags |= RTW_C_RXWEP_40; /* XXX */ 865 866 *rfchipid = RTW_SR_GET(sr, RTW_SR_RFCHIPID); 867 switch (*rfchipid) { 868 case RTW_RFCHIPID_GCT: /* this combo seen in the wild */ 869 rfname = "GCT GRF5101"; 870 paname = "Winspring WS9901"; 871 break; 872 case RTW_RFCHIPID_MAXIM: 873 rfname = "Maxim MAX2820"; /* guess */ 874 paname = "Maxim MAX2422"; /* guess */ 875 break; 876 case RTW_RFCHIPID_INTERSIL: 877 rfname = "Intersil HFA3873"; /* guess */ 878 paname = "Intersil <unknown>"; 879 break; 880 case RTW_RFCHIPID_PHILIPS: /* this combo seen in the wild */ 881 rfname = "Philips SA2400A"; 882 paname = "Philips SA2411"; 883 break; 884 case RTW_RFCHIPID_RFMD: 885 /* this is the same front-end as an atw(4)! */ 886 rfname = "RFMD RF2948B, " /* mentioned in Realtek docs */ 887 "LNA: RFMD RF2494, " /* mentioned in Realtek docs */ 888 "SYN: Silicon Labs Si4126"; /* inferred from 889 * reference driver 890 */ 891 paname = "RFMD RF2189"; /* mentioned in Realtek docs */ 892 break; 893 case RTW_RFCHIPID_RESERVED: 894 rfname = paname = "reserved"; 895 break; 896 default: 897 snprintf(scratch, sizeof(scratch), "unknown 0x%02x", *rfchipid); 898 rfname = paname = scratch; 899 } 900 printf("%s: RF: %s, PA: %s\n", dvname, rfname, paname); 901 902 switch (RTW_SR_GET(sr, RTW_SR_CONFIG0) & RTW_CONFIG0_GL_MASK) { 903 case RTW_CONFIG0_GL_USA: 904 case _RTW_CONFIG0_GL_USA: 905 *locale = RTW_LOCALE_USA; 906 break; 907 case RTW_CONFIG0_GL_EUROPE: 908 *locale = RTW_LOCALE_EUROPE; 909 break; 910 case RTW_CONFIG0_GL_JAPAN: 911 *locale = RTW_LOCALE_JAPAN; 912 break; 913 default: 914 *locale = RTW_LOCALE_UNKNOWN; 915 break; 916 } 917 return 0; 918} 919 920/* Returns -1 on failure. */ 921static int 922rtw_srom_read(struct rtw_regs *regs, uint32_t flags, struct rtw_srom *sr, 923 const char *dvname) 924{ 925 int rc; 926 struct seeprom_descriptor sd; 927 uint8_t ecr; 928 929 (void)memset(&sd, 0, sizeof(sd)); 930 931 ecr = RTW_READ8(regs, RTW_9346CR); 932 933 if ((flags & RTW_F_9356SROM) != 0) { 934 RTW_DPRINTF(RTW_DEBUG_ATTACH, ("%s: 93c56 SROM\n", dvname)); 935 sr->sr_size = 256; 936 sd.sd_chip = C56_66; 937 } else { 938 RTW_DPRINTF(RTW_DEBUG_ATTACH, ("%s: 93c46 SROM\n", dvname)); 939 sr->sr_size = 128; 940 sd.sd_chip = C46; 941 } 942 943 ecr &= ~(RTW_9346CR_EEDI | RTW_9346CR_EEDO | RTW_9346CR_EESK | 944 RTW_9346CR_EEM_MASK | RTW_9346CR_EECS); 945 ecr |= RTW_9346CR_EEM_PROGRAM; 946 947 RTW_WRITE8(regs, RTW_9346CR, ecr); 948 949 sr->sr_content = malloc(sr->sr_size, M_DEVBUF, M_NOWAIT); 950 951 if (sr->sr_content == NULL) { 952 printf("%s: unable to allocate SROM buffer\n", dvname); 953 return ENOMEM; 954 } 955 956 (void)memset(sr->sr_content, 0, sr->sr_size); 957 958 /* RTL8180 has a single 8-bit register for controlling the 959 * 93cx6 SROM. There is no "ready" bit. The RTL8180 960 * input/output sense is the reverse of read_seeprom's. 961 */ 962 sd.sd_tag = regs->r_bt; 963 sd.sd_bsh = regs->r_bh; 964 sd.sd_regsize = 1; 965 sd.sd_control_offset = RTW_9346CR; 966 sd.sd_status_offset = RTW_9346CR; 967 sd.sd_dataout_offset = RTW_9346CR; 968 sd.sd_CK = RTW_9346CR_EESK; 969 sd.sd_CS = RTW_9346CR_EECS; 970 sd.sd_DI = RTW_9346CR_EEDO; 971 sd.sd_DO = RTW_9346CR_EEDI; 972 /* make read_seeprom enter EEPROM read/write mode */ 973 sd.sd_MS = ecr; 974 sd.sd_RDY = 0; 975 976 /* TBD bus barriers */ 977 if (!read_seeprom(&sd, sr->sr_content, 0, sr->sr_size/2)) { 978 printf("%s: could not read SROM\n", dvname); 979 free(sr->sr_content, M_DEVBUF); 980 sr->sr_content = NULL; 981 return -1; /* XXX */ 982 } 983 984 /* end EEPROM read/write mode */ 985 RTW_WRITE8(regs, RTW_9346CR, 986 (ecr & ~RTW_9346CR_EEM_MASK) | RTW_9346CR_EEM_NORMAL); 987 RTW_WBRW(regs, RTW_9346CR, RTW_9346CR); 988 989 if ((rc = rtw_recall_eeprom(regs, dvname)) != 0) 990 return rc; 991 992#ifdef RTW_DEBUG 993 { 994 int i; 995 RTW_DPRINTF(RTW_DEBUG_ATTACH, 996 ("\n%s: serial ROM:\n\t", dvname)); 997 for (i = 0; i < sr->sr_size/2; i++) { 998 if (((i % 8) == 0) && (i != 0)) 999 RTW_DPRINTF(RTW_DEBUG_ATTACH, ("\n\t")); 1000 RTW_DPRINTF(RTW_DEBUG_ATTACH, 1001 (" %04x", sr->sr_content[i])); 1002 } 1003 RTW_DPRINTF(RTW_DEBUG_ATTACH, ("\n")); 1004 } 1005#endif /* RTW_DEBUG */ 1006 return 0; 1007} 1008 1009static void 1010rtw_set_rfprog(struct rtw_regs *regs, enum rtw_rfchipid rfchipid, 1011 const char *dvname) 1012{ 1013 uint8_t cfg4; 1014 const char *method; 1015 1016 cfg4 = RTW_READ8(regs, RTW_CONFIG4) & ~RTW_CONFIG4_RFTYPE_MASK; 1017 1018 switch (rfchipid) { 1019 default: 1020 cfg4 |= __SHIFTIN(rtw_rfprog_fallback, RTW_CONFIG4_RFTYPE_MASK); 1021 method = "fallback"; 1022 break; 1023 case RTW_RFCHIPID_INTERSIL: 1024 cfg4 |= RTW_CONFIG4_RFTYPE_INTERSIL; 1025 method = "Intersil"; 1026 break; 1027 case RTW_RFCHIPID_PHILIPS: 1028 cfg4 |= RTW_CONFIG4_RFTYPE_PHILIPS; 1029 method = "Philips"; 1030 break; 1031 case RTW_RFCHIPID_GCT: /* XXX a guess */ 1032 case RTW_RFCHIPID_RFMD: 1033 cfg4 |= RTW_CONFIG4_RFTYPE_RFMD; 1034 method = "RFMD"; 1035 break; 1036 } 1037 1038 RTW_WRITE8(regs, RTW_CONFIG4, cfg4); 1039 1040 RTW_WBR(regs, RTW_CONFIG4, RTW_CONFIG4); 1041 1042 RTW_DPRINTF(RTW_DEBUG_INIT, 1043 ("%s: %s RF programming method, %#02x\n", dvname, method, 1044 RTW_READ8(regs, RTW_CONFIG4))); 1045} 1046 1047static inline void 1048rtw_init_channels(enum rtw_locale locale, 1049 struct ieee80211_channel (*chans)[IEEE80211_CHAN_MAX+1], 1050 const char *dvname) 1051{ 1052 int i; 1053 const char *name = NULL; 1054#define ADD_CHANNEL(_chans, _chan) do { \ 1055 (*_chans)[_chan].ic_flags = IEEE80211_CHAN_B; \ 1056 (*_chans)[_chan].ic_freq = \ 1057 ieee80211_ieee2mhz(_chan, (*_chans)[_chan].ic_flags);\ 1058} while (0) 1059 1060 switch (locale) { 1061 case RTW_LOCALE_USA: /* 1-11 */ 1062 name = "USA"; 1063 for (i = 1; i <= 11; i++) 1064 ADD_CHANNEL(chans, i); 1065 break; 1066 case RTW_LOCALE_JAPAN: /* 1-14 */ 1067 name = "Japan"; 1068 ADD_CHANNEL(chans, 14); 1069 for (i = 1; i <= 14; i++) 1070 ADD_CHANNEL(chans, i); 1071 break; 1072 case RTW_LOCALE_EUROPE: /* 1-13 */ 1073 name = "Europe"; 1074 for (i = 1; i <= 13; i++) 1075 ADD_CHANNEL(chans, i); 1076 break; 1077 default: /* 10-11 allowed by most countries */ 1078 name = "<unknown>"; 1079 for (i = 10; i <= 11; i++) 1080 ADD_CHANNEL(chans, i); 1081 break; 1082 } 1083 printf("%s: Geographic Location %s\n", dvname, name); 1084#undef ADD_CHANNEL 1085} 1086 1087 1088static inline void 1089rtw_identify_country(struct rtw_regs *regs, enum rtw_locale *locale) 1090{ 1091 uint8_t cfg0 = RTW_READ8(regs, RTW_CONFIG0); 1092 1093 switch (cfg0 & RTW_CONFIG0_GL_MASK) { 1094 case RTW_CONFIG0_GL_USA: 1095 case _RTW_CONFIG0_GL_USA: 1096 *locale = RTW_LOCALE_USA; 1097 break; 1098 case RTW_CONFIG0_GL_JAPAN: 1099 *locale = RTW_LOCALE_JAPAN; 1100 break; 1101 case RTW_CONFIG0_GL_EUROPE: 1102 *locale = RTW_LOCALE_EUROPE; 1103 break; 1104 default: 1105 *locale = RTW_LOCALE_UNKNOWN; 1106 break; 1107 } 1108} 1109 1110static inline int 1111rtw_identify_sta(struct rtw_regs *regs, uint8_t (*addr)[IEEE80211_ADDR_LEN], 1112 const char *dvname) 1113{ 1114 static const uint8_t empty_macaddr[IEEE80211_ADDR_LEN] = { 1115 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 1116 }; 1117 uint32_t idr0 = RTW_READ(regs, RTW_IDR0), 1118 idr1 = RTW_READ(regs, RTW_IDR1); 1119 1120 (*addr)[0] = __SHIFTOUT(idr0, __BITS(0, 7)); 1121 (*addr)[1] = __SHIFTOUT(idr0, __BITS(8, 15)); 1122 (*addr)[2] = __SHIFTOUT(idr0, __BITS(16, 23)); 1123 (*addr)[3] = __SHIFTOUT(idr0, __BITS(24 ,31)); 1124 1125 (*addr)[4] = __SHIFTOUT(idr1, __BITS(0, 7)); 1126 (*addr)[5] = __SHIFTOUT(idr1, __BITS(8, 15)); 1127 1128 if (IEEE80211_ADDR_EQ(addr, empty_macaddr)) { 1129 printf("%s: could not get mac address, attach failed\n", 1130 dvname); 1131 return ENXIO; 1132 } 1133 1134 printf("%s: 802.11 address %s\n", dvname, ether_sprintf(*addr)); 1135 1136 return 0; 1137} 1138 1139static uint8_t 1140rtw_chan2txpower(struct rtw_srom *sr, struct ieee80211com *ic, 1141 struct ieee80211_channel *chan) 1142{ 1143 u_int idx = RTW_SR_TXPOWER1 + ieee80211_chan2ieee(ic, chan) - 1; 1144 KASSERT2(idx >= RTW_SR_TXPOWER1 && idx <= RTW_SR_TXPOWER14, 1145 ("%s: channel %d out of range", __func__, 1146 idx - RTW_SR_TXPOWER1 + 1)); 1147 return RTW_SR_GET(sr, idx); 1148} 1149 1150static void 1151rtw_txdesc_blk_init_all(struct rtw_txdesc_blk *tdb) 1152{ 1153 int pri; 1154 /* nfree: the number of free descriptors in each ring. 1155 * The beacon ring is a special case: I do not let the 1156 * driver use all of the descriptors on the beacon ring. 1157 * The reasons are two-fold: 1158 * 1159 * (1) A BEACON descriptor's OWN bit is (apparently) not 1160 * updated, so the driver cannot easily know if the descriptor 1161 * belongs to it, or if it is racing the NIC. If the NIC 1162 * does not OWN every descriptor, then the driver can safely 1163 * update the descriptors when RTW_TBDA points at tdb_next. 1164 * 1165 * (2) I hope that the NIC will process more than one BEACON 1166 * descriptor in a single beacon interval, since that will 1167 * enable multiple-BSS support. Since the NIC does not 1168 * clear the OWN bit, there is no natural place for it to 1169 * stop processing BEACON desciptors. Maybe it will *not* 1170 * stop processing them! I do not want to chance the NIC 1171 * looping around and around a saturated beacon ring, so 1172 * I will leave one descriptor unOWNed at all times. 1173 */ 1174 u_int nfree[RTW_NTXPRI] = 1175 {RTW_NTXDESCLO, RTW_NTXDESCMD, RTW_NTXDESCHI, 1176 RTW_NTXDESCBCN - 1}; 1177 1178 for (pri = 0; pri < RTW_NTXPRI; pri++) { 1179 tdb[pri].tdb_nfree = nfree[pri]; 1180 tdb[pri].tdb_next = 0; 1181 } 1182} 1183 1184static int 1185rtw_txsoft_blk_init(struct rtw_txsoft_blk *tsb) 1186{ 1187 int i; 1188 struct rtw_txsoft *ts; 1189 1190 SIMPLEQ_INIT(&tsb->tsb_dirtyq); 1191 SIMPLEQ_INIT(&tsb->tsb_freeq); 1192 for (i = 0; i < tsb->tsb_ndesc; i++) { 1193 ts = &tsb->tsb_desc[i]; 1194 ts->ts_mbuf = NULL; 1195 SIMPLEQ_INSERT_TAIL(&tsb->tsb_freeq, ts, ts_q); 1196 } 1197 tsb->tsb_tx_timer = 0; 1198 return 0; 1199} 1200 1201static void 1202rtw_txsoft_blk_init_all(struct rtw_txsoft_blk *tsb) 1203{ 1204 int pri; 1205 for (pri = 0; pri < RTW_NTXPRI; pri++) 1206 rtw_txsoft_blk_init(&tsb[pri]); 1207} 1208 1209static inline void 1210rtw_rxdescs_sync(struct rtw_rxdesc_blk *rdb, int desc0, int nsync, int ops) 1211{ 1212 KASSERT(nsync <= rdb->rdb_ndesc); 1213 /* sync to end of ring */ 1214 if (desc0 + nsync > rdb->rdb_ndesc) { 1215 bus_dmamap_sync(rdb->rdb_dmat, rdb->rdb_dmamap, 1216 offsetof(struct rtw_descs, hd_rx[desc0]), 1217 sizeof(struct rtw_rxdesc) * (rdb->rdb_ndesc - desc0), ops); 1218 nsync -= (rdb->rdb_ndesc - desc0); 1219 desc0 = 0; 1220 } 1221 1222 KASSERT(desc0 < rdb->rdb_ndesc); 1223 KASSERT(nsync <= rdb->rdb_ndesc); 1224 KASSERT(desc0 + nsync <= rdb->rdb_ndesc); 1225 1226 /* sync what remains */ 1227 bus_dmamap_sync(rdb->rdb_dmat, rdb->rdb_dmamap, 1228 offsetof(struct rtw_descs, hd_rx[desc0]), 1229 sizeof(struct rtw_rxdesc) * nsync, ops); 1230} 1231 1232static void 1233rtw_txdescs_sync(struct rtw_txdesc_blk *tdb, u_int desc0, u_int nsync, int ops) 1234{ 1235 /* sync to end of ring */ 1236 if (desc0 + nsync > tdb->tdb_ndesc) { 1237 bus_dmamap_sync(tdb->tdb_dmat, tdb->tdb_dmamap, 1238 tdb->tdb_ofs + sizeof(struct rtw_txdesc) * desc0, 1239 sizeof(struct rtw_txdesc) * (tdb->tdb_ndesc - desc0), 1240 ops); 1241 nsync -= (tdb->tdb_ndesc - desc0); 1242 desc0 = 0; 1243 } 1244 1245 /* sync what remains */ 1246 bus_dmamap_sync(tdb->tdb_dmat, tdb->tdb_dmamap, 1247 tdb->tdb_ofs + sizeof(struct rtw_txdesc) * desc0, 1248 sizeof(struct rtw_txdesc) * nsync, ops); 1249} 1250 1251static void 1252rtw_txdescs_sync_all(struct rtw_txdesc_blk *tdb) 1253{ 1254 int pri; 1255 for (pri = 0; pri < RTW_NTXPRI; pri++) { 1256 rtw_txdescs_sync(&tdb[pri], 0, tdb[pri].tdb_ndesc, 1257 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 1258 } 1259} 1260 1261static void 1262rtw_rxbufs_release(bus_dma_tag_t dmat, struct rtw_rxsoft *desc) 1263{ 1264 int i; 1265 struct rtw_rxsoft *rs; 1266 1267 for (i = 0; i < RTW_RXQLEN; i++) { 1268 rs = &desc[i]; 1269 if (rs->rs_mbuf == NULL) 1270 continue; 1271 bus_dmamap_sync(dmat, rs->rs_dmamap, 0, 1272 rs->rs_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD); 1273 bus_dmamap_unload(dmat, rs->rs_dmamap); 1274 m_freem(rs->rs_mbuf); 1275 rs->rs_mbuf = NULL; 1276 } 1277} 1278 1279static inline int 1280rtw_rxsoft_alloc(bus_dma_tag_t dmat, struct rtw_rxsoft *rs) 1281{ 1282 int rc; 1283 struct mbuf *m; 1284 1285 MGETHDR(m, M_DONTWAIT, MT_DATA); 1286 if (m == NULL) 1287 return ENOBUFS; 1288 1289 MCLGET(m, M_DONTWAIT); 1290 if ((m->m_flags & M_EXT) == 0) { 1291 m_freem(m); 1292 return ENOBUFS; 1293 } 1294 1295 m->m_pkthdr.len = m->m_len = m->m_ext.ext_size; 1296 1297 if (rs->rs_mbuf != NULL) 1298 bus_dmamap_unload(dmat, rs->rs_dmamap); 1299 1300 rs->rs_mbuf = NULL; 1301 1302 rc = bus_dmamap_load_mbuf(dmat, rs->rs_dmamap, m, BUS_DMA_NOWAIT); 1303 if (rc != 0) { 1304 m_freem(m); 1305 return -1; 1306 } 1307 1308 rs->rs_mbuf = m; 1309 1310 return 0; 1311} 1312 1313static int 1314rtw_rxsoft_init_all(bus_dma_tag_t dmat, struct rtw_rxsoft *desc, 1315 int *ndesc, const char *dvname) 1316{ 1317 int i, rc = 0; 1318 struct rtw_rxsoft *rs; 1319 1320 for (i = 0; i < RTW_RXQLEN; i++) { 1321 rs = &desc[i]; 1322 /* we're in rtw_init, so there should be no mbufs allocated */ 1323 KASSERT(rs->rs_mbuf == NULL); 1324#ifdef RTW_DEBUG 1325 if (i == rtw_rxbufs_limit) { 1326 printf("%s: TEST hit %d-buffer limit\n", dvname, i); 1327 rc = ENOBUFS; 1328 break; 1329 } 1330#endif /* RTW_DEBUG */ 1331 if ((rc = rtw_rxsoft_alloc(dmat, rs)) != 0) { 1332 printf("%s: rtw_rxsoft_alloc failed, %d buffers, " 1333 "rc %d\n", dvname, i, rc); 1334 break; 1335 } 1336 } 1337 *ndesc = i; 1338 return rc; 1339} 1340 1341static inline void 1342rtw_rxdesc_init(struct rtw_rxdesc_blk *rdb, struct rtw_rxsoft *rs, 1343 int idx, int kick) 1344{ 1345 int is_last = (idx == rdb->rdb_ndesc - 1); 1346 uint32_t ctl, octl, obuf; 1347 struct rtw_rxdesc *rd = &rdb->rdb_desc[idx]; 1348 1349 obuf = rd->rd_buf; 1350 rd->rd_buf = htole32(rs->rs_dmamap->dm_segs[0].ds_addr); 1351 1352 ctl = __SHIFTIN(rs->rs_mbuf->m_len, RTW_RXCTL_LENGTH_MASK) | 1353 RTW_RXCTL_OWN | RTW_RXCTL_FS | RTW_RXCTL_LS; 1354 1355 if (is_last) 1356 ctl |= RTW_RXCTL_EOR; 1357 1358 octl = rd->rd_ctl; 1359 rd->rd_ctl = htole32(ctl); 1360 1361 RTW_DPRINTF( 1362 kick ? (RTW_DEBUG_RECV_DESC | RTW_DEBUG_IO_KICK) 1363 : RTW_DEBUG_RECV_DESC, 1364 ("%s: rd %p buf %08x -> %08x ctl %08x -> %08x\n", __func__, rd, 1365 le32toh(obuf), le32toh(rd->rd_buf), le32toh(octl), 1366 le32toh(rd->rd_ctl))); 1367 1368 /* sync the mbuf */ 1369 bus_dmamap_sync(rdb->rdb_dmat, rs->rs_dmamap, 0, 1370 rs->rs_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD); 1371 1372 /* sync the descriptor */ 1373 bus_dmamap_sync(rdb->rdb_dmat, rdb->rdb_dmamap, 1374 RTW_DESC_OFFSET(hd_rx, idx), sizeof(struct rtw_rxdesc), 1375 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 1376} 1377 1378static void 1379rtw_rxdesc_init_all(struct rtw_rxdesc_blk *rdb, struct rtw_rxsoft *ctl, int kick) 1380{ 1381 int i; 1382 struct rtw_rxdesc *rd; 1383 struct rtw_rxsoft *rs; 1384 1385 for (i = 0; i < rdb->rdb_ndesc; i++) { 1386 rd = &rdb->rdb_desc[i]; 1387 rs = &ctl[i]; 1388 rtw_rxdesc_init(rdb, rs, i, kick); 1389 } 1390} 1391 1392static void 1393rtw_io_enable(struct rtw_softc *sc, uint8_t flags, int enable) 1394{ 1395 struct rtw_regs *regs = &sc->sc_regs; 1396 uint8_t cr; 1397 1398 RTW_DPRINTF(RTW_DEBUG_IOSTATE, ("%s: %s 0x%02x\n", __func__, 1399 enable ? "enable" : "disable", flags)); 1400 1401 cr = RTW_READ8(regs, RTW_CR); 1402 1403 /* XXX reference source does not enable MULRW */ 1404 /* enable PCI Read/Write Multiple */ 1405 cr |= RTW_CR_MULRW; 1406 1407 /* The receive engine will always start at RDSAR. */ 1408 if (enable && (flags & ~cr & RTW_CR_RE)) { 1409 struct rtw_rxdesc_blk *rdb; 1410 rdb = &sc->sc_rxdesc_blk; 1411 rdb->rdb_next = 0; 1412 } 1413 1414 RTW_RBW(regs, RTW_CR, RTW_CR); /* XXX paranoia? */ 1415 if (enable) 1416 cr |= flags; 1417 else 1418 cr &= ~flags; 1419 RTW_WRITE8(regs, RTW_CR, cr); 1420 RTW_SYNC(regs, RTW_CR, RTW_CR); 1421 1422#ifdef RTW_DIAG 1423 if (cr & RTW_CR_TE) 1424 rtw_txring_fixup(sc, __func__, __LINE__); 1425#endif 1426} 1427 1428static void 1429rtw_intr_rx(struct rtw_softc *sc, uint16_t isr) 1430{ 1431#define IS_BEACON(__fc0) \ 1432 ((__fc0 & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==\ 1433 (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_BEACON)) 1434 1435 static const int ratetbl[4] = {2, 4, 11, 22}; /* convert rates: 1436 * hardware -> net80211 1437 */ 1438 u_int next, nproc = 0; 1439 int hwrate, len, rate, rssi, sq; 1440 uint32_t hrssi, hstat, htsfth, htsftl; 1441 struct rtw_rxdesc *rd; 1442 struct rtw_rxsoft *rs; 1443 struct rtw_rxdesc_blk *rdb; 1444 struct mbuf *m; 1445 struct ifnet *ifp = &sc->sc_if; 1446 1447 struct ieee80211_node *ni; 1448 struct ieee80211_frame_min *wh; 1449 1450 rdb = &sc->sc_rxdesc_blk; 1451 1452 for (next = rdb->rdb_next; ; next = rdb->rdb_next) { 1453 KASSERT(next < rdb->rdb_ndesc); 1454 1455 rtw_rxdescs_sync(rdb, next, 1, 1456 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 1457 rd = &rdb->rdb_desc[next]; 1458 rs = &sc->sc_rxsoft[next]; 1459 1460 hstat = le32toh(rd->rd_stat); 1461 hrssi = le32toh(rd->rd_rssi); 1462 htsfth = le32toh(rd->rd_tsfth); 1463 htsftl = le32toh(rd->rd_tsftl); 1464 1465 RTW_DPRINTF(RTW_DEBUG_RECV_DESC, 1466 ("%s: rxdesc[%d] hstat %08x hrssi %08x htsft %08x%08x\n", 1467 __func__, next, hstat, hrssi, htsfth, htsftl)); 1468 1469 ++nproc; 1470 1471 /* still belongs to NIC */ 1472 if ((hstat & RTW_RXSTAT_OWN) != 0) { 1473 rtw_rxdescs_sync(rdb, next, 1, BUS_DMASYNC_PREREAD); 1474 break; 1475 } 1476 1477 /* ieee80211_input() might reset the receive engine 1478 * (e.g. by indirectly calling rtw_tune()), so save 1479 * the next pointer here and retrieve it again on 1480 * the next round. 1481 */ 1482 rdb->rdb_next = (next + 1) % rdb->rdb_ndesc; 1483 1484#ifdef RTW_DEBUG 1485#define PRINTSTAT(flag) do { \ 1486 if ((hstat & flag) != 0) { \ 1487 printf("%s" #flag, delim); \ 1488 delim = ","; \ 1489 } \ 1490} while (0) 1491 if ((rtw_debug & RTW_DEBUG_RECV_DESC) != 0) { 1492 const char *delim = "<"; 1493 printf("%s: ", sc->sc_dev.dv_xname); 1494 if ((hstat & RTW_RXSTAT_DEBUG) != 0) { 1495 printf("status %08x", hstat); 1496 PRINTSTAT(RTW_RXSTAT_SPLCP); 1497 PRINTSTAT(RTW_RXSTAT_MAR); 1498 PRINTSTAT(RTW_RXSTAT_PAR); 1499 PRINTSTAT(RTW_RXSTAT_BAR); 1500 PRINTSTAT(RTW_RXSTAT_PWRMGT); 1501 PRINTSTAT(RTW_RXSTAT_CRC32); 1502 PRINTSTAT(RTW_RXSTAT_ICV); 1503 printf(">, "); 1504 } 1505 } 1506#endif /* RTW_DEBUG */ 1507 1508 if ((hstat & RTW_RXSTAT_IOERROR) != 0) { 1509 printf("%s: DMA error/FIFO overflow %08" PRIx32 ", " 1510 "rx descriptor %d\n", sc->sc_dev.dv_xname, 1511 hstat, next); 1512 ifp->if_ierrors++; 1513 goto next; 1514 } 1515 1516 len = __SHIFTOUT(hstat, RTW_RXSTAT_LENGTH_MASK); 1517 if (len < IEEE80211_MIN_LEN) { 1518 sc->sc_ic.ic_stats.is_rx_tooshort++; 1519 goto next; 1520 } 1521 1522 /* CRC is included with the packet; trim it off. */ 1523 len -= IEEE80211_CRC_LEN; 1524 1525 hwrate = __SHIFTOUT(hstat, RTW_RXSTAT_RATE_MASK); 1526 if (hwrate >= sizeof(ratetbl) / sizeof(ratetbl[0])) { 1527 printf("%s: unknown rate #%" __PRIuBITS "\n", 1528 sc->sc_dev.dv_xname, 1529 __SHIFTOUT(hstat, RTW_RXSTAT_RATE_MASK)); 1530 ifp->if_ierrors++; 1531 goto next; 1532 } 1533 rate = ratetbl[hwrate]; 1534 1535#ifdef RTW_DEBUG 1536 RTW_DPRINTF(RTW_DEBUG_RECV_DESC, 1537 ("rate %d.%d Mb/s, time %08x%08x\n", (rate * 5) / 10, 1538 (rate * 5) % 10, htsfth, htsftl)); 1539#endif /* RTW_DEBUG */ 1540 1541 if ((hstat & RTW_RXSTAT_RES) != 0 && 1542 sc->sc_ic.ic_opmode != IEEE80211_M_MONITOR) 1543 goto next; 1544 1545 /* if bad flags, skip descriptor */ 1546 if ((hstat & RTW_RXSTAT_ONESEG) != RTW_RXSTAT_ONESEG) { 1547 printf("%s: too many rx segments, " 1548 "next=%d, %08" PRIx32 "\n", 1549 sc->sc_dev.dv_xname, next, hstat); 1550 goto next; 1551 } 1552 1553 bus_dmamap_sync(sc->sc_dmat, rs->rs_dmamap, 0, 1554 rs->rs_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD); 1555 1556 m = rs->rs_mbuf; 1557 1558 /* if temporarily out of memory, re-use mbuf */ 1559 switch (rtw_rxsoft_alloc(sc->sc_dmat, rs)) { 1560 case 0: 1561 break; 1562 case ENOBUFS: 1563 printf("%s: rtw_rxsoft_alloc(, %d) failed, " 1564 "dropping packet\n", sc->sc_dev.dv_xname, next); 1565 goto next; 1566 default: 1567 /* XXX shorten rx ring, instead? */ 1568 panic("%s: could not load DMA map\n", 1569 sc->sc_dev.dv_xname); 1570 } 1571 1572 if (sc->sc_rfchipid == RTW_RFCHIPID_PHILIPS) 1573 rssi = __SHIFTOUT(hrssi, RTW_RXRSSI_RSSI); 1574 else { 1575 rssi = __SHIFTOUT(hrssi, RTW_RXRSSI_IMR_RSSI); 1576 /* TBD find out each front-end's LNA gain in the 1577 * front-end's units 1578 */ 1579 if ((hrssi & RTW_RXRSSI_IMR_LNA) == 0) 1580 rssi |= 0x80; 1581 } 1582 sq = __SHIFTOUT(hrssi, RTW_RXRSSI_SQ); 1583 1584 /* Note well: now we cannot recycle the rs_mbuf unless 1585 * we restore its original length. 1586 */ 1587 m->m_pkthdr.rcvif = ifp; 1588 m->m_pkthdr.len = m->m_len = len; 1589 1590 wh = mtod(m, struct ieee80211_frame_min *); 1591 1592 if (!IS_BEACON(wh->i_fc[0])) 1593 sc->sc_led_state.ls_event |= RTW_LED_S_RX; 1594 /* TBD use _MAR, _BAR, _PAR flags as hints to _find_rxnode? */ 1595 ni = ieee80211_find_rxnode(&sc->sc_ic, wh); 1596 1597 sc->sc_tsfth = htsfth; 1598 1599#ifdef RTW_DEBUG 1600 if ((ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) == 1601 (IFF_DEBUG|IFF_LINK2)) { 1602 ieee80211_dump_pkt(mtod(m, uint8_t *), m->m_pkthdr.len, 1603 rate, rssi); 1604 } 1605#endif /* RTW_DEBUG */ 1606 1607#if NBPFILTER > 0 1608 if (sc->sc_radiobpf != NULL) { 1609 struct rtw_rx_radiotap_header *rr = &sc->sc_rxtap; 1610 1611 rr->rr_tsft = 1612 htole64(((uint64_t)htsfth << 32) | htsftl); 1613 1614 if ((hstat & RTW_RXSTAT_SPLCP) != 0) 1615 rr->rr_flags = IEEE80211_RADIOTAP_F_SHORTPRE; 1616 1617 rr->rr_flags = 0; 1618 rr->rr_rate = rate; 1619 rr->rr_antsignal = rssi; 1620 rr->rr_barker_lock = htole16(sq); 1621 1622 bpf_mtap2(sc->sc_radiobpf, (caddr_t)rr, 1623 sizeof(sc->sc_rxtapu), m); 1624 } 1625#endif /* NPBFILTER > 0 */ 1626 1627 ieee80211_input(&sc->sc_ic, m, ni, rssi, htsftl); 1628 ieee80211_free_node(ni); 1629next: 1630 rtw_rxdesc_init(rdb, rs, next, 0); 1631 } 1632#undef IS_BEACON 1633} 1634 1635static void 1636rtw_txsoft_release(bus_dma_tag_t dmat, struct ieee80211com *ic, 1637 struct rtw_txsoft *ts) 1638{ 1639 struct mbuf *m; 1640 struct ieee80211_node *ni; 1641 1642 m = ts->ts_mbuf; 1643 ni = ts->ts_ni; 1644 KASSERT(m != NULL); 1645 KASSERT(ni != NULL); 1646 ts->ts_mbuf = NULL; 1647 ts->ts_ni = NULL; 1648 1649 bus_dmamap_sync(dmat, ts->ts_dmamap, 0, ts->ts_dmamap->dm_mapsize, 1650 BUS_DMASYNC_POSTWRITE); 1651 bus_dmamap_unload(dmat, ts->ts_dmamap); 1652 m_freem(m); 1653 ieee80211_free_node(ni); 1654} 1655 1656static void 1657rtw_txsofts_release(bus_dma_tag_t dmat, struct ieee80211com *ic, 1658 struct rtw_txsoft_blk *tsb) 1659{ 1660 struct rtw_txsoft *ts; 1661 1662 while ((ts = SIMPLEQ_FIRST(&tsb->tsb_dirtyq)) != NULL) { 1663 rtw_txsoft_release(dmat, ic, ts); 1664 SIMPLEQ_REMOVE_HEAD(&tsb->tsb_dirtyq, ts_q); 1665 SIMPLEQ_INSERT_TAIL(&tsb->tsb_freeq, ts, ts_q); 1666 } 1667 tsb->tsb_tx_timer = 0; 1668} 1669 1670static inline void 1671rtw_collect_txpkt(struct rtw_softc *sc, struct rtw_txdesc_blk *tdb, 1672 struct rtw_txsoft *ts, int ndesc) 1673{ 1674 uint32_t hstat; 1675 int data_retry, rts_retry; 1676 struct rtw_txdesc *tdn; 1677 const char *condstring; 1678 struct ifnet *ifp = &sc->sc_if; 1679 1680 rtw_txsoft_release(sc->sc_dmat, &sc->sc_ic, ts); 1681 1682 tdb->tdb_nfree += ndesc; 1683 1684 tdn = &tdb->tdb_desc[ts->ts_last]; 1685 1686 hstat = le32toh(tdn->td_stat); 1687 rts_retry = __SHIFTOUT(hstat, RTW_TXSTAT_RTSRETRY_MASK); 1688 data_retry = __SHIFTOUT(hstat, RTW_TXSTAT_DRC_MASK); 1689 1690 ifp->if_collisions += rts_retry + data_retry; 1691 1692 if ((hstat & RTW_TXSTAT_TOK) != 0) 1693 condstring = "ok"; 1694 else { 1695 ifp->if_oerrors++; 1696 condstring = "error"; 1697 } 1698 1699 DPRINTF(sc, RTW_DEBUG_XMIT_DESC, 1700 ("%s: ts %p txdesc[%d, %d] %s tries rts %u data %u\n", 1701 sc->sc_dev.dv_xname, ts, ts->ts_first, ts->ts_last, 1702 condstring, rts_retry, data_retry)); 1703} 1704 1705static void 1706rtw_reset_oactive(struct rtw_softc *sc) 1707{ 1708 short oflags; 1709 int pri; 1710 struct rtw_txsoft_blk *tsb; 1711 struct rtw_txdesc_blk *tdb; 1712 oflags = sc->sc_if.if_flags; 1713 for (pri = 0; pri < RTW_NTXPRI; pri++) { 1714 tsb = &sc->sc_txsoft_blk[pri]; 1715 tdb = &sc->sc_txdesc_blk[pri]; 1716 if (!SIMPLEQ_EMPTY(&tsb->tsb_freeq) && tdb->tdb_nfree > 0) 1717 sc->sc_if.if_flags &= ~IFF_OACTIVE; 1718 } 1719 if (oflags != sc->sc_if.if_flags) { 1720 DPRINTF(sc, RTW_DEBUG_OACTIVE, 1721 ("%s: reset OACTIVE\n", __func__)); 1722 } 1723} 1724 1725/* Collect transmitted packets. */ 1726static inline void 1727rtw_collect_txring(struct rtw_softc *sc, struct rtw_txsoft_blk *tsb, 1728 struct rtw_txdesc_blk *tdb, int force) 1729{ 1730 int ndesc; 1731 struct rtw_txsoft *ts; 1732 1733#ifdef RTW_DEBUG 1734 rtw_dump_rings(sc); 1735#endif 1736 1737 while ((ts = SIMPLEQ_FIRST(&tsb->tsb_dirtyq)) != NULL) { 1738 /* If we're clearing a failed transmission, only clear 1739 up to the last packet the hardware has processed. */ 1740 if (ts->ts_first == rtw_txring_next(&sc->sc_regs, tdb)) 1741 break; 1742 1743 ndesc = 1 + ts->ts_last - ts->ts_first; 1744 if (ts->ts_last < ts->ts_first) 1745 ndesc += tdb->tdb_ndesc; 1746 1747 KASSERT(ndesc > 0); 1748 1749 rtw_txdescs_sync(tdb, ts->ts_first, ndesc, 1750 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 1751 1752 if (force) { 1753 int next; 1754#ifdef RTW_DIAG 1755 printf("%s: clearing packet, stats", __func__); 1756#endif 1757 for (next = ts->ts_first; ; 1758 next = RTW_NEXT_IDX(tdb, next)) { 1759#ifdef RTW_DIAG 1760 printf(" %" PRIx32 "/%" PRIx32 "/%" PRIx32 "/%" PRIu32 "/%" PRIx32, le32toh(tdb->tdb_desc[next].td_stat), le32toh(tdb->tdb_desc[next].td_ctl1), le32toh(tdb->tdb_desc[next].td_buf), le32toh(tdb->tdb_desc[next].td_len), le32toh(tdb->tdb_desc[next].td_next)); 1761#endif 1762 tdb->tdb_desc[next].td_stat &= 1763 ~htole32(RTW_TXSTAT_OWN); 1764 if (next == ts->ts_last) 1765 break; 1766 } 1767 rtw_txdescs_sync(tdb, ts->ts_first, ndesc, 1768 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 1769#ifdef RTW_DIAG 1770 next = RTW_NEXT_IDX(tdb, next); 1771 printf(" -> end %u stat %" PRIx32 ", was %u\n", next, 1772 le32toh(tdb->tdb_desc[next].td_stat), 1773 rtw_txring_next(&sc->sc_regs, tdb)); 1774#endif 1775 } else if ((tdb->tdb_desc[ts->ts_last].td_stat & 1776 htole32(RTW_TXSTAT_OWN)) != 0) { 1777 rtw_txdescs_sync(tdb, ts->ts_last, 1, 1778 BUS_DMASYNC_PREREAD); 1779 break; 1780 } 1781 1782 rtw_collect_txpkt(sc, tdb, ts, ndesc); 1783 SIMPLEQ_REMOVE_HEAD(&tsb->tsb_dirtyq, ts_q); 1784 SIMPLEQ_INSERT_TAIL(&tsb->tsb_freeq, ts, ts_q); 1785 } 1786 1787 /* no more pending transmissions, cancel watchdog */ 1788 if (ts == NULL) 1789 tsb->tsb_tx_timer = 0; 1790 rtw_reset_oactive(sc); 1791} 1792 1793static void 1794rtw_intr_tx(struct rtw_softc *sc, uint16_t isr) 1795{ 1796 int pri; 1797 struct rtw_txsoft_blk *tsb; 1798 struct rtw_txdesc_blk *tdb; 1799 struct ifnet *ifp = &sc->sc_if; 1800 1801 for (pri = 0; pri < RTW_NTXPRI; pri++) { 1802 tsb = &sc->sc_txsoft_blk[pri]; 1803 tdb = &sc->sc_txdesc_blk[pri]; 1804 rtw_collect_txring(sc, tsb, tdb, 0); 1805 } 1806 1807 if ((isr & RTW_INTR_TX) != 0) 1808 rtw_start(ifp); 1809 1810 return; 1811} 1812 1813static void 1814rtw_intr_beacon(struct rtw_softc *sc, uint16_t isr) 1815{ 1816 u_int next; 1817 uint32_t tsfth, tsftl; 1818 struct ieee80211com *ic; 1819 struct rtw_txdesc_blk *tdb = &sc->sc_txdesc_blk[RTW_TXPRIBCN]; 1820 struct rtw_txsoft_blk *tsb = &sc->sc_txsoft_blk[RTW_TXPRIBCN]; 1821 struct mbuf *m; 1822 1823 tsfth = RTW_READ(&sc->sc_regs, RTW_TSFTRH); 1824 tsftl = RTW_READ(&sc->sc_regs, RTW_TSFTRL); 1825 1826 if ((isr & (RTW_INTR_TBDOK|RTW_INTR_TBDER)) != 0) { 1827 next = rtw_txring_next(&sc->sc_regs, tdb); 1828 RTW_DPRINTF(RTW_DEBUG_BEACON, 1829 ("%s: beacon ring %sprocessed, isr = %#04" PRIx16 1830 ", next %u expected %u, %" PRIu64 "\n", __func__, 1831 (next == tdb->tdb_next) ? "" : "un", isr, next, 1832 tdb->tdb_next, (uint64_t)tsfth << 32 | tsftl)); 1833 if ((RTW_READ8(&sc->sc_regs, RTW_TPPOLL) & RTW_TPPOLL_BQ) == 0) 1834 rtw_collect_txring(sc, tsb, tdb, 1); 1835 } 1836 /* Start beacon transmission. */ 1837 1838 if ((isr & RTW_INTR_BCNINT) != 0 && 1839 sc->sc_ic.ic_state == IEEE80211_S_RUN && 1840 SIMPLEQ_EMPTY(&tsb->tsb_dirtyq)) { 1841 RTW_DPRINTF(RTW_DEBUG_BEACON, 1842 ("%s: beacon prep. time, isr = %#04" PRIx16 1843 ", %16" PRIu64 "\n", __func__, isr, 1844 (uint64_t)tsfth << 32 | tsftl)); 1845 ic = &sc->sc_ic; 1846 m = rtw_beacon_alloc(sc, ic->ic_bss); 1847 1848 if (m == NULL) { 1849 printf("%s: could not allocate beacon\n", 1850 sc->sc_dev.dv_xname); 1851 return; 1852 } 1853 m->m_pkthdr.rcvif = (void *)ieee80211_ref_node(ic->ic_bss); 1854 IF_ENQUEUE(&sc->sc_beaconq, m); 1855 rtw_start(&sc->sc_if); 1856 } 1857} 1858 1859static void 1860rtw_intr_atim(struct rtw_softc *sc) 1861{ 1862 /* TBD */ 1863 return; 1864} 1865 1866#ifdef RTW_DEBUG 1867static void 1868rtw_dump_rings(struct rtw_softc *sc) 1869{ 1870 struct rtw_txdesc_blk *tdb; 1871 struct rtw_rxdesc *rd; 1872 struct rtw_rxdesc_blk *rdb; 1873 int desc, pri; 1874 1875 if ((rtw_debug & RTW_DEBUG_IO_KICK) == 0) 1876 return; 1877 1878 for (pri = 0; pri < RTW_NTXPRI; pri++) { 1879 tdb = &sc->sc_txdesc_blk[pri]; 1880 printf("%s: txpri %d ndesc %d nfree %d\n", __func__, pri, 1881 tdb->tdb_ndesc, tdb->tdb_nfree); 1882 for (desc = 0; desc < tdb->tdb_ndesc; desc++) 1883 rtw_print_txdesc(sc, ".", NULL, tdb, desc); 1884 } 1885 1886 rdb = &sc->sc_rxdesc_blk; 1887 1888 for (desc = 0; desc < RTW_RXQLEN; desc++) { 1889 rd = &rdb->rdb_desc[desc]; 1890 printf("%s: %sctl %08x rsvd0/rssi %08x buf/tsftl %08x " 1891 "rsvd1/tsfth %08x\n", __func__, 1892 (desc >= rdb->rdb_ndesc) ? "UNUSED " : "", 1893 le32toh(rd->rd_ctl), le32toh(rd->rd_rssi), 1894 le32toh(rd->rd_buf), le32toh(rd->rd_tsfth)); 1895 } 1896} 1897#endif /* RTW_DEBUG */ 1898 1899static void 1900rtw_hwring_setup(struct rtw_softc *sc) 1901{ 1902 int pri; 1903 struct rtw_regs *regs = &sc->sc_regs; 1904 struct rtw_txdesc_blk *tdb; 1905 1906 sc->sc_txdesc_blk[RTW_TXPRILO].tdb_basereg = RTW_TLPDA; 1907 sc->sc_txdesc_blk[RTW_TXPRILO].tdb_base = RTW_RING_BASE(sc, hd_txlo); 1908 sc->sc_txdesc_blk[RTW_TXPRIMD].tdb_basereg = RTW_TNPDA; 1909 sc->sc_txdesc_blk[RTW_TXPRIMD].tdb_base = RTW_RING_BASE(sc, hd_txmd); 1910 sc->sc_txdesc_blk[RTW_TXPRIHI].tdb_basereg = RTW_THPDA; 1911 sc->sc_txdesc_blk[RTW_TXPRIHI].tdb_base = RTW_RING_BASE(sc, hd_txhi); 1912 sc->sc_txdesc_blk[RTW_TXPRIBCN].tdb_basereg = RTW_TBDA; 1913 sc->sc_txdesc_blk[RTW_TXPRIBCN].tdb_base = RTW_RING_BASE(sc, hd_bcn); 1914 1915 for (pri = 0; pri < RTW_NTXPRI; pri++) { 1916 tdb = &sc->sc_txdesc_blk[pri]; 1917 RTW_WRITE(regs, tdb->tdb_basereg, tdb->tdb_base); 1918 RTW_DPRINTF(RTW_DEBUG_XMIT_DESC, 1919 ("%s: reg[tdb->tdb_basereg] <- %" PRIxPTR "\n", __func__, 1920 (uintptr_t)tdb->tdb_base)); 1921 } 1922 1923 RTW_WRITE(regs, RTW_RDSAR, RTW_RING_BASE(sc, hd_rx)); 1924 1925 RTW_DPRINTF(RTW_DEBUG_RECV_DESC, 1926 ("%s: reg[RDSAR] <- %" PRIxPTR "\n", __func__, 1927 (uintptr_t)RTW_RING_BASE(sc, hd_rx))); 1928 1929 RTW_SYNC(regs, RTW_TLPDA, RTW_RDSAR); 1930 1931} 1932 1933static int 1934rtw_swring_setup(struct rtw_softc *sc) 1935{ 1936 int rc; 1937 struct rtw_rxdesc_blk *rdb; 1938 1939 rtw_txdesc_blk_init_all(&sc->sc_txdesc_blk[0]); 1940 1941 rtw_txsoft_blk_init_all(&sc->sc_txsoft_blk[0]); 1942 1943 rdb = &sc->sc_rxdesc_blk; 1944 if ((rc = rtw_rxsoft_init_all(sc->sc_dmat, sc->sc_rxsoft, &rdb->rdb_ndesc, 1945 sc->sc_dev.dv_xname)) != 0 && rdb->rdb_ndesc == 0) { 1946 printf("%s: could not allocate rx buffers\n", 1947 sc->sc_dev.dv_xname); 1948 return rc; 1949 } 1950 1951 rdb = &sc->sc_rxdesc_blk; 1952 rtw_rxdescs_sync(rdb, 0, rdb->rdb_ndesc, 1953 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 1954 rtw_rxdesc_init_all(rdb, sc->sc_rxsoft, 1); 1955 rdb->rdb_next = 0; 1956 1957 rtw_txdescs_sync_all(&sc->sc_txdesc_blk[0]); 1958 return 0; 1959} 1960 1961static void 1962rtw_txdesc_blk_init(struct rtw_txdesc_blk *tdb) 1963{ 1964 int i; 1965 1966 (void)memset(tdb->tdb_desc, 0, 1967 sizeof(tdb->tdb_desc[0]) * tdb->tdb_ndesc); 1968 for (i = 0; i < tdb->tdb_ndesc; i++) 1969 tdb->tdb_desc[i].td_next = htole32(RTW_NEXT_DESC(tdb, i)); 1970} 1971 1972static u_int 1973rtw_txring_next(struct rtw_regs *regs, struct rtw_txdesc_blk *tdb) 1974{ 1975 return (le32toh(RTW_READ(regs, tdb->tdb_basereg)) - tdb->tdb_base) / 1976 sizeof(struct rtw_txdesc); 1977} 1978 1979#ifdef RTW_DIAG 1980static void 1981rtw_txring_fixup(struct rtw_softc *sc, const char *fn, int ln) 1982{ 1983 int pri; 1984 u_int next; 1985 struct rtw_txdesc_blk *tdb; 1986 struct rtw_regs *regs = &sc->sc_regs; 1987 1988 for (pri = 0; pri < RTW_NTXPRI; pri++) { 1989 int i; 1990 tdb = &sc->sc_txdesc_blk[pri]; 1991 next = rtw_txring_next(regs, tdb); 1992 if (tdb->tdb_next == next) 1993 continue; 1994 for (i = 0; next != tdb->tdb_next; 1995 next = RTW_NEXT_IDX(tdb, next), i++) { 1996 if ((tdb->tdb_desc[next].td_stat & htole32(RTW_TXSTAT_OWN)) == 0) 1997 break; 1998 } 1999 printf("%s:%d: tx-ring %d expected next %u, read %u+%d -> %s\n", fn, 2000 ln, pri, tdb->tdb_next, next, i, tdb->tdb_next == next ? "okay" : "BAD"); 2001 if (tdb->tdb_next == next) 2002 continue; 2003 tdb->tdb_next = MIN(next, tdb->tdb_ndesc - 1); 2004 } 2005} 2006#endif 2007 2008static void 2009rtw_txdescs_reset(struct rtw_softc *sc) 2010{ 2011 int pri; 2012 struct rtw_txsoft_blk *tsb; 2013 struct rtw_txdesc_blk *tdb; 2014 2015 for (pri = 0; pri < RTW_NTXPRI; pri++) { 2016 tsb = &sc->sc_txsoft_blk[pri]; 2017 tdb = &sc->sc_txdesc_blk[pri]; 2018 rtw_collect_txring(sc, tsb, tdb, 1); 2019#ifdef RTW_DIAG 2020 if (!SIMPLEQ_EMPTY(&tsb->tsb_dirtyq)) 2021 printf("%s: packets left in ring %d\n", __func__, pri); 2022#endif 2023 } 2024} 2025 2026static void 2027rtw_intr_ioerror(struct rtw_softc *sc, uint16_t isr) 2028{ 2029 printf("%s: tx fifo underflow\n", sc->sc_dev.dv_xname); 2030 2031 RTW_DPRINTF(RTW_DEBUG_BUGS, ("%s: cleaning up xmit, isr %" PRIx16 2032 "\n", sc->sc_dev.dv_xname, isr)); 2033 2034#ifdef RTW_DEBUG 2035 rtw_dump_rings(sc); 2036#endif /* RTW_DEBUG */ 2037 2038 /* Collect tx'd packets. XXX let's hope this stops the transmit 2039 * timeouts. 2040 */ 2041 rtw_txdescs_reset(sc); 2042 2043#ifdef RTW_DEBUG 2044 rtw_dump_rings(sc); 2045#endif /* RTW_DEBUG */ 2046} 2047 2048static inline void 2049rtw_suspend_ticks(struct rtw_softc *sc) 2050{ 2051 RTW_DPRINTF(RTW_DEBUG_TIMEOUT, 2052 ("%s: suspending ticks\n", sc->sc_dev.dv_xname)); 2053 sc->sc_do_tick = 0; 2054} 2055 2056static inline void 2057rtw_resume_ticks(struct rtw_softc *sc) 2058{ 2059 uint32_t tsftrl0, tsftrl1, next_tick; 2060 2061 tsftrl0 = RTW_READ(&sc->sc_regs, RTW_TSFTRL); 2062 2063 tsftrl1 = RTW_READ(&sc->sc_regs, RTW_TSFTRL); 2064 next_tick = tsftrl1 + 1000000; 2065 RTW_WRITE(&sc->sc_regs, RTW_TINT, next_tick); 2066 2067 sc->sc_do_tick = 1; 2068 2069 RTW_DPRINTF(RTW_DEBUG_TIMEOUT, 2070 ("%s: resume ticks delta %#08x now %#08x next %#08x\n", 2071 sc->sc_dev.dv_xname, tsftrl1 - tsftrl0, tsftrl1, next_tick)); 2072} 2073 2074static void 2075rtw_intr_timeout(struct rtw_softc *sc) 2076{ 2077 RTW_DPRINTF(RTW_DEBUG_TIMEOUT, ("%s: timeout\n", sc->sc_dev.dv_xname)); 2078 if (sc->sc_do_tick) 2079 rtw_resume_ticks(sc); 2080 return; 2081} 2082 2083int 2084rtw_intr(void *arg) 2085{ 2086 int i; 2087 struct rtw_softc *sc = arg; 2088 struct rtw_regs *regs = &sc->sc_regs; 2089 uint16_t isr; 2090 struct ifnet *ifp = &sc->sc_if; 2091 2092 /* 2093 * If the interface isn't running, the interrupt couldn't 2094 * possibly have come from us. 2095 */ 2096 if ((sc->sc_flags & RTW_F_ENABLED) == 0 || 2097 (ifp->if_flags & IFF_RUNNING) == 0 || 2098 !device_is_active(&sc->sc_dev)) { 2099 RTW_DPRINTF(RTW_DEBUG_INTR, ("%s: stray interrupt\n", sc->sc_dev.dv_xname)); 2100 return (0); 2101 } 2102 2103 for (i = 0; i < 10; i++) { 2104 isr = RTW_READ16(regs, RTW_ISR); 2105 2106 RTW_WRITE16(regs, RTW_ISR, isr); 2107 RTW_WBR(regs, RTW_ISR, RTW_ISR); 2108 2109 if (sc->sc_intr_ack != NULL) 2110 (*sc->sc_intr_ack)(regs); 2111 2112 if (isr == 0) 2113 break; 2114 2115#ifdef RTW_DEBUG 2116#define PRINTINTR(flag) do { \ 2117 if ((isr & flag) != 0) { \ 2118 printf("%s" #flag, delim); \ 2119 delim = ","; \ 2120 } \ 2121} while (0) 2122 2123 if ((rtw_debug & RTW_DEBUG_INTR) != 0 && isr != 0) { 2124 const char *delim = "<"; 2125 2126 printf("%s: reg[ISR] = %x", sc->sc_dev.dv_xname, isr); 2127 2128 PRINTINTR(RTW_INTR_TXFOVW); 2129 PRINTINTR(RTW_INTR_TIMEOUT); 2130 PRINTINTR(RTW_INTR_BCNINT); 2131 PRINTINTR(RTW_INTR_ATIMINT); 2132 PRINTINTR(RTW_INTR_TBDER); 2133 PRINTINTR(RTW_INTR_TBDOK); 2134 PRINTINTR(RTW_INTR_THPDER); 2135 PRINTINTR(RTW_INTR_THPDOK); 2136 PRINTINTR(RTW_INTR_TNPDER); 2137 PRINTINTR(RTW_INTR_TNPDOK); 2138 PRINTINTR(RTW_INTR_RXFOVW); 2139 PRINTINTR(RTW_INTR_RDU); 2140 PRINTINTR(RTW_INTR_TLPDER); 2141 PRINTINTR(RTW_INTR_TLPDOK); 2142 PRINTINTR(RTW_INTR_RER); 2143 PRINTINTR(RTW_INTR_ROK); 2144 2145 printf(">\n"); 2146 } 2147#undef PRINTINTR 2148#endif /* RTW_DEBUG */ 2149 2150 if ((isr & RTW_INTR_RX) != 0) 2151 rtw_intr_rx(sc, isr); 2152 if ((isr & RTW_INTR_TX) != 0) 2153 rtw_intr_tx(sc, isr); 2154 if ((isr & RTW_INTR_BEACON) != 0) 2155 rtw_intr_beacon(sc, isr); 2156 if ((isr & RTW_INTR_ATIMINT) != 0) 2157 rtw_intr_atim(sc); 2158 if ((isr & RTW_INTR_IOERROR) != 0) 2159 rtw_intr_ioerror(sc, isr); 2160 if ((isr & RTW_INTR_TIMEOUT) != 0) 2161 rtw_intr_timeout(sc); 2162 } 2163 2164 return 1; 2165} 2166 2167/* Must be called at splnet. */ 2168static void 2169rtw_stop(struct ifnet *ifp, int disable) 2170{ 2171 int pri; 2172 struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc; 2173 struct ieee80211com *ic = &sc->sc_ic; 2174 struct rtw_regs *regs = &sc->sc_regs; 2175 2176 if ((sc->sc_flags & RTW_F_ENABLED) == 0) 2177 return; 2178 2179 rtw_suspend_ticks(sc); 2180 2181 ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 2182 2183 if ((sc->sc_flags & RTW_F_INVALID) == 0) { 2184 /* Disable interrupts. */ 2185 RTW_WRITE16(regs, RTW_IMR, 0); 2186 2187 RTW_WBW(regs, RTW_TPPOLL, RTW_IMR); 2188 2189 /* Stop the transmit and receive processes. First stop DMA, 2190 * then disable receiver and transmitter. 2191 */ 2192 RTW_WRITE8(regs, RTW_TPPOLL, RTW_TPPOLL_SALL); 2193 2194 RTW_SYNC(regs, RTW_TPPOLL, RTW_IMR); 2195 2196 rtw_io_enable(sc, RTW_CR_RE | RTW_CR_TE, 0); 2197 } 2198 2199 for (pri = 0; pri < RTW_NTXPRI; pri++) { 2200 rtw_txsofts_release(sc->sc_dmat, &sc->sc_ic, 2201 &sc->sc_txsoft_blk[pri]); 2202 } 2203 2204 rtw_rxbufs_release(sc->sc_dmat, &sc->sc_rxsoft[0]); 2205 2206 if (disable) 2207 rtw_disable(sc); 2208 2209 /* Mark the interface as not running. Cancel the watchdog timer. */ 2210 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 2211 ifp->if_timer = 0; 2212 2213 return; 2214} 2215 2216const char * 2217rtw_pwrstate_string(enum rtw_pwrstate power) 2218{ 2219 switch (power) { 2220 case RTW_ON: 2221 return "on"; 2222 case RTW_SLEEP: 2223 return "sleep"; 2224 case RTW_OFF: 2225 return "off"; 2226 default: 2227 return "unknown"; 2228 } 2229} 2230 2231/* XXX For Maxim, I am using the RFMD settings gleaned from the 2232 * reference driver, plus a magic Maxim "ON" value that comes from 2233 * the Realtek document "Windows PG for Rtl8180." 2234 */ 2235static void 2236rtw_maxim_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power, 2237 int before_rf, int digphy) 2238{ 2239 uint32_t anaparm; 2240 2241 anaparm = RTW_READ(regs, RTW_ANAPARM); 2242 anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF); 2243 2244 switch (power) { 2245 case RTW_OFF: 2246 if (before_rf) 2247 return; 2248 anaparm |= RTW_ANAPARM_RFPOW_MAXIM_OFF; 2249 anaparm |= RTW_ANAPARM_TXDACOFF; 2250 break; 2251 case RTW_SLEEP: 2252 if (!before_rf) 2253 return; 2254 anaparm |= RTW_ANAPARM_RFPOW_MAXIM_SLEEP; 2255 anaparm |= RTW_ANAPARM_TXDACOFF; 2256 break; 2257 case RTW_ON: 2258 if (!before_rf) 2259 return; 2260 anaparm |= RTW_ANAPARM_RFPOW_MAXIM_ON; 2261 break; 2262 } 2263 RTW_DPRINTF(RTW_DEBUG_PWR, 2264 ("%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n", 2265 __func__, rtw_pwrstate_string(power), 2266 (before_rf) ? "before" : "after", anaparm)); 2267 2268 RTW_WRITE(regs, RTW_ANAPARM, anaparm); 2269 RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM); 2270} 2271 2272/* XXX I am using the RFMD settings gleaned from the reference 2273 * driver. They agree 2274 */ 2275static void 2276rtw_rfmd_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power, 2277 int before_rf, int digphy) 2278{ 2279 uint32_t anaparm; 2280 2281 anaparm = RTW_READ(regs, RTW_ANAPARM); 2282 anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF); 2283 2284 switch (power) { 2285 case RTW_OFF: 2286 if (before_rf) 2287 return; 2288 anaparm |= RTW_ANAPARM_RFPOW_RFMD_OFF; 2289 anaparm |= RTW_ANAPARM_TXDACOFF; 2290 break; 2291 case RTW_SLEEP: 2292 if (!before_rf) 2293 return; 2294 anaparm |= RTW_ANAPARM_RFPOW_RFMD_SLEEP; 2295 anaparm |= RTW_ANAPARM_TXDACOFF; 2296 break; 2297 case RTW_ON: 2298 if (!before_rf) 2299 return; 2300 anaparm |= RTW_ANAPARM_RFPOW_RFMD_ON; 2301 break; 2302 } 2303 RTW_DPRINTF(RTW_DEBUG_PWR, 2304 ("%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n", 2305 __func__, rtw_pwrstate_string(power), 2306 (before_rf) ? "before" : "after", anaparm)); 2307 2308 RTW_WRITE(regs, RTW_ANAPARM, anaparm); 2309 RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM); 2310} 2311 2312static void 2313rtw_philips_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power, 2314 int before_rf, int digphy) 2315{ 2316 uint32_t anaparm; 2317 2318 anaparm = RTW_READ(regs, RTW_ANAPARM); 2319 anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF); 2320 2321 switch (power) { 2322 case RTW_OFF: 2323 if (before_rf) 2324 return; 2325 anaparm |= RTW_ANAPARM_RFPOW_PHILIPS_OFF; 2326 anaparm |= RTW_ANAPARM_TXDACOFF; 2327 break; 2328 case RTW_SLEEP: 2329 if (!before_rf) 2330 return; 2331 anaparm |= RTW_ANAPARM_RFPOW_PHILIPS_SLEEP; 2332 anaparm |= RTW_ANAPARM_TXDACOFF; 2333 break; 2334 case RTW_ON: 2335 if (!before_rf) 2336 return; 2337 if (digphy) { 2338 anaparm |= RTW_ANAPARM_RFPOW_DIG_PHILIPS_ON; 2339 /* XXX guess */ 2340 anaparm |= RTW_ANAPARM_TXDACOFF; 2341 } else 2342 anaparm |= RTW_ANAPARM_RFPOW_ANA_PHILIPS_ON; 2343 break; 2344 } 2345 RTW_DPRINTF(RTW_DEBUG_PWR, 2346 ("%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n", 2347 __func__, rtw_pwrstate_string(power), 2348 (before_rf) ? "before" : "after", anaparm)); 2349 2350 RTW_WRITE(regs, RTW_ANAPARM, anaparm); 2351 RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM); 2352} 2353 2354static void 2355rtw_pwrstate0(struct rtw_softc *sc, enum rtw_pwrstate power, int before_rf, 2356 int digphy) 2357{ 2358 struct rtw_regs *regs = &sc->sc_regs; 2359 2360 rtw_set_access(regs, RTW_ACCESS_ANAPARM); 2361 2362 (*sc->sc_pwrstate_cb)(regs, power, before_rf, digphy); 2363 2364 rtw_set_access(regs, RTW_ACCESS_NONE); 2365 2366 return; 2367} 2368 2369static int 2370rtw_pwrstate(struct rtw_softc *sc, enum rtw_pwrstate power) 2371{ 2372 int rc; 2373 2374 RTW_DPRINTF(RTW_DEBUG_PWR, 2375 ("%s: %s->%s\n", __func__, 2376 rtw_pwrstate_string(sc->sc_pwrstate), rtw_pwrstate_string(power))); 2377 2378 if (sc->sc_pwrstate == power) 2379 return 0; 2380 2381 rtw_pwrstate0(sc, power, 1, sc->sc_flags & RTW_F_DIGPHY); 2382 rc = rtw_rf_pwrstate(sc->sc_rf, power); 2383 rtw_pwrstate0(sc, power, 0, sc->sc_flags & RTW_F_DIGPHY); 2384 2385 switch (power) { 2386 case RTW_ON: 2387 /* TBD set LEDs */ 2388 break; 2389 case RTW_SLEEP: 2390 /* TBD */ 2391 break; 2392 case RTW_OFF: 2393 /* TBD */ 2394 break; 2395 } 2396 if (rc == 0) 2397 sc->sc_pwrstate = power; 2398 else 2399 sc->sc_pwrstate = RTW_OFF; 2400 return rc; 2401} 2402 2403static int 2404rtw_tune(struct rtw_softc *sc) 2405{ 2406 struct ieee80211com *ic = &sc->sc_ic; 2407 struct rtw_tx_radiotap_header *rt = &sc->sc_txtap; 2408 struct rtw_rx_radiotap_header *rr = &sc->sc_rxtap; 2409 u_int chan; 2410 int rc; 2411 int antdiv = sc->sc_flags & RTW_F_ANTDIV, 2412 dflantb = sc->sc_flags & RTW_F_DFLANTB; 2413 2414 chan = ieee80211_chan2ieee(ic, ic->ic_curchan); 2415 if (chan == IEEE80211_CHAN_ANY) 2416 panic("%s: chan == IEEE80211_CHAN_ANY\n", __func__); 2417 2418 rt->rt_chan_freq = htole16(ic->ic_curchan->ic_freq); 2419 rt->rt_chan_flags = htole16(ic->ic_curchan->ic_flags); 2420 2421 rr->rr_chan_freq = htole16(ic->ic_curchan->ic_freq); 2422 rr->rr_chan_flags = htole16(ic->ic_curchan->ic_flags); 2423 2424 if (chan == sc->sc_cur_chan) { 2425 RTW_DPRINTF(RTW_DEBUG_TUNE, 2426 ("%s: already tuned chan #%d\n", __func__, chan)); 2427 return 0; 2428 } 2429 2430 rtw_suspend_ticks(sc); 2431 2432 rtw_io_enable(sc, RTW_CR_RE | RTW_CR_TE, 0); 2433 2434 /* TBD wait for Tx to complete */ 2435 2436 KASSERT((sc->sc_flags & RTW_F_ENABLED) != 0); 2437 2438 if ((rc = rtw_phy_init(&sc->sc_regs, sc->sc_rf, 2439 rtw_chan2txpower(&sc->sc_srom, ic, ic->ic_curchan), sc->sc_csthr, 2440 ic->ic_curchan->ic_freq, antdiv, dflantb, RTW_ON)) != 0) { 2441 /* XXX condition on powersaving */ 2442 printf("%s: phy init failed\n", sc->sc_dev.dv_xname); 2443 } 2444 2445 sc->sc_cur_chan = chan; 2446 2447 rtw_io_enable(sc, RTW_CR_RE | RTW_CR_TE, 1); 2448 2449 rtw_resume_ticks(sc); 2450 2451 return rc; 2452} 2453 2454void 2455rtw_disable(struct rtw_softc *sc) 2456{ 2457 int rc; 2458 2459 if ((sc->sc_flags & RTW_F_ENABLED) == 0) 2460 return; 2461 2462 /* turn off PHY */ 2463 if ((sc->sc_flags & RTW_F_INVALID) == 0 && 2464 (rc = rtw_pwrstate(sc, RTW_OFF)) != 0) { 2465 printf("%s: failed to turn off PHY (%d)\n", 2466 sc->sc_dev.dv_xname, rc); 2467 } 2468 2469 if (sc->sc_disable != NULL) 2470 (*sc->sc_disable)(sc); 2471 2472 sc->sc_flags &= ~RTW_F_ENABLED; 2473} 2474 2475int 2476rtw_enable(struct rtw_softc *sc) 2477{ 2478 if ((sc->sc_flags & RTW_F_ENABLED) == 0) { 2479 if (sc->sc_enable != NULL && (*sc->sc_enable)(sc) != 0) { 2480 printf("%s: device enable failed\n", 2481 sc->sc_dev.dv_xname); 2482 return (EIO); 2483 } 2484 sc->sc_flags |= RTW_F_ENABLED; 2485 /* Power may have been removed, and WEP keys thus 2486 * reset. 2487 */ 2488 sc->sc_flags &= ~RTW_F_DK_VALID; 2489 } 2490 return (0); 2491} 2492 2493static void 2494rtw_transmit_config(struct rtw_regs *regs) 2495{ 2496 uint32_t tcr; 2497 2498 tcr = RTW_READ(regs, RTW_TCR); 2499 2500 tcr |= RTW_TCR_CWMIN; 2501 tcr &= ~RTW_TCR_MXDMA_MASK; 2502 tcr |= RTW_TCR_MXDMA_256; 2503 tcr |= RTW_TCR_SAT; /* send ACK as fast as possible */ 2504 tcr &= ~RTW_TCR_LBK_MASK; 2505 tcr |= RTW_TCR_LBK_NORMAL; /* normal operating mode */ 2506 2507 /* set short/long retry limits */ 2508 tcr &= ~(RTW_TCR_SRL_MASK|RTW_TCR_LRL_MASK); 2509 tcr |= __SHIFTIN(4, RTW_TCR_SRL_MASK) | __SHIFTIN(4, RTW_TCR_LRL_MASK); 2510 2511 tcr &= ~RTW_TCR_CRC; /* NIC appends CRC32 */ 2512 2513 RTW_WRITE(regs, RTW_TCR, tcr); 2514 RTW_SYNC(regs, RTW_TCR, RTW_TCR); 2515} 2516 2517static inline void 2518rtw_enable_interrupts(struct rtw_softc *sc) 2519{ 2520 struct rtw_regs *regs = &sc->sc_regs; 2521 2522 sc->sc_inten = RTW_INTR_RX|RTW_INTR_TX|RTW_INTR_BEACON|RTW_INTR_ATIMINT; 2523 sc->sc_inten |= RTW_INTR_IOERROR|RTW_INTR_TIMEOUT; 2524 2525 RTW_WRITE16(regs, RTW_IMR, sc->sc_inten); 2526 RTW_WBW(regs, RTW_IMR, RTW_ISR); 2527 RTW_WRITE16(regs, RTW_ISR, 0xffff); 2528 RTW_SYNC(regs, RTW_IMR, RTW_ISR); 2529 2530 /* XXX necessary? */ 2531 if (sc->sc_intr_ack != NULL) 2532 (*sc->sc_intr_ack)(regs); 2533} 2534 2535static void 2536rtw_set_nettype(struct rtw_softc *sc, enum ieee80211_opmode opmode) 2537{ 2538 uint8_t msr; 2539 2540 /* I'm guessing that MSR is protected as CONFIG[0123] are. */ 2541 rtw_set_access(&sc->sc_regs, RTW_ACCESS_CONFIG); 2542 2543 msr = RTW_READ8(&sc->sc_regs, RTW_MSR) & ~RTW_MSR_NETYPE_MASK; 2544 2545 switch (opmode) { 2546 case IEEE80211_M_AHDEMO: 2547 case IEEE80211_M_IBSS: 2548 msr |= RTW_MSR_NETYPE_ADHOC_OK; 2549 break; 2550 case IEEE80211_M_HOSTAP: 2551 msr |= RTW_MSR_NETYPE_AP_OK; 2552 break; 2553 case IEEE80211_M_MONITOR: 2554 /* XXX */ 2555 msr |= RTW_MSR_NETYPE_NOLINK; 2556 break; 2557 case IEEE80211_M_STA: 2558 msr |= RTW_MSR_NETYPE_INFRA_OK; 2559 break; 2560 } 2561 RTW_WRITE8(&sc->sc_regs, RTW_MSR, msr); 2562 2563 rtw_set_access(&sc->sc_regs, RTW_ACCESS_NONE); 2564} 2565 2566#define rtw_calchash(addr) \ 2567 (ether_crc32_be((addr), IEEE80211_ADDR_LEN) >> 26) 2568 2569static void 2570rtw_pktfilt_load(struct rtw_softc *sc) 2571{ 2572 struct rtw_regs *regs = &sc->sc_regs; 2573 struct ieee80211com *ic = &sc->sc_ic; 2574 struct ethercom *ec = &sc->sc_ec; 2575 struct ifnet *ifp = &sc->sc_if; 2576 int hash; 2577 uint32_t hashes[2] = { 0, 0 }; 2578 struct ether_multi *enm; 2579 struct ether_multistep step; 2580 2581 /* XXX might be necessary to stop Rx/Tx engines while setting filters */ 2582 2583 sc->sc_rcr &= ~RTW_RCR_PKTFILTER_MASK; 2584 sc->sc_rcr &= ~(RTW_RCR_MXDMA_MASK | RTW_RCR_RXFTH_MASK); 2585 2586 sc->sc_rcr |= RTW_RCR_PKTFILTER_DEFAULT; 2587 /* MAC auto-reset PHY (huh?) */ 2588 sc->sc_rcr |= RTW_RCR_ENMARP; 2589 /* DMA whole Rx packets, only. Set Tx DMA burst size to 1024 bytes. */ 2590 sc->sc_rcr |= RTW_RCR_MXDMA_1024 | RTW_RCR_RXFTH_WHOLE; 2591 2592 switch (ic->ic_opmode) { 2593 case IEEE80211_M_MONITOR: 2594 sc->sc_rcr |= RTW_RCR_MONITOR; 2595 break; 2596 case IEEE80211_M_AHDEMO: 2597 case IEEE80211_M_IBSS: 2598 /* receive broadcasts in our BSS */ 2599 sc->sc_rcr |= RTW_RCR_ADD3; 2600 break; 2601 default: 2602 break; 2603 } 2604 2605 ifp->if_flags &= ~IFF_ALLMULTI; 2606 2607 /* XXX accept all broadcast if scanning */ 2608 if ((ifp->if_flags & IFF_BROADCAST) != 0) 2609 sc->sc_rcr |= RTW_RCR_AB; /* accept all broadcast */ 2610 2611 if (ifp->if_flags & IFF_PROMISC) { 2612 sc->sc_rcr |= RTW_RCR_AB; /* accept all broadcast */ 2613allmulti: 2614 ifp->if_flags |= IFF_ALLMULTI; 2615 goto setit; 2616 } 2617 2618 /* 2619 * Program the 64-bit multicast hash filter. 2620 */ 2621 ETHER_FIRST_MULTI(step, ec, enm); 2622 while (enm != NULL) { 2623 /* XXX */ 2624 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, 2625 ETHER_ADDR_LEN) != 0) 2626 goto allmulti; 2627 2628 hash = rtw_calchash(enm->enm_addrlo); 2629 hashes[hash >> 5] |= (1 << (hash & 0x1f)); 2630 sc->sc_rcr |= RTW_RCR_AM; 2631 ETHER_NEXT_MULTI(step, enm); 2632 } 2633 2634 /* all bits set => hash is useless */ 2635 if (~(hashes[0] & hashes[1]) == 0) 2636 goto allmulti; 2637 2638 setit: 2639 if (ifp->if_flags & IFF_ALLMULTI) { 2640 sc->sc_rcr |= RTW_RCR_AM; /* accept all multicast */ 2641 hashes[0] = hashes[1] = 0xffffffff; 2642 } 2643 2644 RTW_WRITE(regs, RTW_MAR0, hashes[0]); 2645 RTW_WRITE(regs, RTW_MAR1, hashes[1]); 2646 RTW_WRITE(regs, RTW_RCR, sc->sc_rcr); 2647 RTW_SYNC(regs, RTW_MAR0, RTW_RCR); /* RTW_MAR0 < RTW_MAR1 < RTW_RCR */ 2648 2649 DPRINTF(sc, RTW_DEBUG_PKTFILT, 2650 ("%s: RTW_MAR0 %08x RTW_MAR1 %08x RTW_RCR %08x\n", 2651 sc->sc_dev.dv_xname, RTW_READ(regs, RTW_MAR0), 2652 RTW_READ(regs, RTW_MAR1), RTW_READ(regs, RTW_RCR))); 2653 2654 return; 2655} 2656 2657static struct mbuf * 2658rtw_beacon_alloc(struct rtw_softc *sc, struct ieee80211_node *ni) 2659{ 2660 struct ieee80211com *ic = &sc->sc_ic; 2661 struct mbuf *m; 2662 struct ieee80211_beacon_offsets boff; 2663 2664 if ((m = ieee80211_beacon_alloc(ic, ni, &boff)) != NULL) { 2665 RTW_DPRINTF(RTW_DEBUG_BEACON, 2666 ("%s: m %p len %u\n", __func__, m, m->m_len)); 2667 } 2668 return m; 2669} 2670 2671/* Must be called at splnet. */ 2672static int 2673rtw_init(struct ifnet *ifp) 2674{ 2675 struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc; 2676 struct ieee80211com *ic = &sc->sc_ic; 2677 struct rtw_regs *regs = &sc->sc_regs; 2678 int rc = 0; 2679 2680 if ((rc = rtw_enable(sc)) != 0) 2681 goto out; 2682 2683 /* Cancel pending I/O and reset. */ 2684 rtw_stop(ifp, 0); 2685 2686 DPRINTF(sc, RTW_DEBUG_TUNE, ("%s: channel %d freq %d flags 0x%04x\n", 2687 __func__, ieee80211_chan2ieee(ic, ic->ic_curchan), 2688 ic->ic_curchan->ic_freq, ic->ic_curchan->ic_flags)); 2689 2690 if ((rc = rtw_pwrstate(sc, RTW_OFF)) != 0) 2691 goto out; 2692 2693 if ((rc = rtw_swring_setup(sc)) != 0) 2694 goto out; 2695 2696 rtw_transmit_config(regs); 2697 2698 rtw_set_access(regs, RTW_ACCESS_CONFIG); 2699 2700 RTW_WRITE8(regs, RTW_MSR, 0x0); /* no link */ 2701 RTW_WBW(regs, RTW_MSR, RTW_BRSR); 2702 2703 /* long PLCP header, 1Mb/2Mb basic rate */ 2704 RTW_WRITE16(regs, RTW_BRSR, RTW_BRSR_MBR8180_2MBPS); 2705 RTW_SYNC(regs, RTW_BRSR, RTW_BRSR); 2706 2707 rtw_set_access(regs, RTW_ACCESS_ANAPARM); 2708 rtw_set_access(regs, RTW_ACCESS_NONE); 2709 2710 /* XXX from reference sources */ 2711 RTW_WRITE(regs, RTW_FEMR, 0xffff); 2712 RTW_SYNC(regs, RTW_FEMR, RTW_FEMR); 2713 2714 rtw_set_rfprog(regs, sc->sc_rfchipid, sc->sc_dev.dv_xname); 2715 2716 RTW_WRITE8(regs, RTW_PHYDELAY, sc->sc_phydelay); 2717 /* from Linux driver */ 2718 RTW_WRITE8(regs, RTW_CRCOUNT, RTW_CRCOUNT_MAGIC); 2719 2720 RTW_SYNC(regs, RTW_PHYDELAY, RTW_CRCOUNT); 2721 2722 rtw_enable_interrupts(sc); 2723 2724 rtw_pktfilt_load(sc); 2725 2726 rtw_hwring_setup(sc); 2727 2728 rtw_wep_setkeys(sc, ic->ic_nw_keys, ic->ic_def_txkey); 2729 2730 rtw_io_enable(sc, RTW_CR_RE | RTW_CR_TE, 1); 2731 2732 ifp->if_flags |= IFF_RUNNING; 2733 ic->ic_state = IEEE80211_S_INIT; 2734 2735 RTW_WRITE16(regs, RTW_BSSID16, 0x0); 2736 RTW_WRITE(regs, RTW_BSSID32, 0x0); 2737 2738 rtw_resume_ticks(sc); 2739 2740 rtw_set_nettype(sc, IEEE80211_M_MONITOR); 2741 2742 if (ic->ic_opmode == IEEE80211_M_MONITOR) 2743 return ieee80211_new_state(ic, IEEE80211_S_RUN, -1); 2744 else 2745 return ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 2746 2747out: 2748 printf("%s: interface not running\n", sc->sc_dev.dv_xname); 2749 return rc; 2750} 2751 2752static inline void 2753rtw_led_init(struct rtw_regs *regs) 2754{ 2755 uint8_t cfg0, cfg1; 2756 2757 rtw_set_access(regs, RTW_ACCESS_CONFIG); 2758 2759 cfg0 = RTW_READ8(regs, RTW_CONFIG0); 2760 cfg0 |= RTW_CONFIG0_LEDGPOEN; 2761 RTW_WRITE8(regs, RTW_CONFIG0, cfg0); 2762 2763 cfg1 = RTW_READ8(regs, RTW_CONFIG1); 2764 RTW_DPRINTF(RTW_DEBUG_LED, 2765 ("%s: read %" PRIx8 " from reg[CONFIG1]\n", __func__, cfg1)); 2766 2767 cfg1 &= ~RTW_CONFIG1_LEDS_MASK; 2768 cfg1 |= RTW_CONFIG1_LEDS_TX_RX; 2769 RTW_WRITE8(regs, RTW_CONFIG1, cfg1); 2770 2771 rtw_set_access(regs, RTW_ACCESS_NONE); 2772} 2773 2774/* 2775 * IEEE80211_S_INIT: LED1 off 2776 * 2777 * IEEE80211_S_AUTH, 2778 * IEEE80211_S_ASSOC, 2779 * IEEE80211_S_SCAN: LED1 blinks @ 1 Hz, blinks at 5Hz for tx/rx 2780 * 2781 * IEEE80211_S_RUN: LED1 on, blinks @ 5Hz for tx/rx 2782 */ 2783static void 2784rtw_led_newstate(struct rtw_softc *sc, enum ieee80211_state nstate) 2785{ 2786 struct rtw_led_state *ls; 2787 2788 ls = &sc->sc_led_state; 2789 2790 switch (nstate) { 2791 case IEEE80211_S_INIT: 2792 rtw_led_init(&sc->sc_regs); 2793 callout_stop(&ls->ls_slow_ch); 2794 callout_stop(&ls->ls_fast_ch); 2795 ls->ls_slowblink = 0; 2796 ls->ls_actblink = 0; 2797 ls->ls_default = 0; 2798 break; 2799 case IEEE80211_S_SCAN: 2800 callout_schedule(&ls->ls_slow_ch, RTW_LED_SLOW_TICKS); 2801 callout_schedule(&ls->ls_fast_ch, RTW_LED_FAST_TICKS); 2802 /*FALLTHROUGH*/ 2803 case IEEE80211_S_AUTH: 2804 case IEEE80211_S_ASSOC: 2805 ls->ls_default = RTW_LED1; 2806 ls->ls_actblink = RTW_LED1; 2807 ls->ls_slowblink = RTW_LED1; 2808 break; 2809 case IEEE80211_S_RUN: 2810 ls->ls_slowblink = 0; 2811 break; 2812 } 2813 rtw_led_set(ls, &sc->sc_regs, sc->sc_hwverid); 2814} 2815 2816static void 2817rtw_led_set(struct rtw_led_state *ls, struct rtw_regs *regs, int hwverid) 2818{ 2819 uint8_t led_condition; 2820 bus_size_t ofs; 2821 uint8_t mask, newval, val; 2822 2823 led_condition = ls->ls_default; 2824 2825 if (ls->ls_state & RTW_LED_S_SLOW) 2826 led_condition ^= ls->ls_slowblink; 2827 if (ls->ls_state & (RTW_LED_S_RX|RTW_LED_S_TX)) 2828 led_condition ^= ls->ls_actblink; 2829 2830 RTW_DPRINTF(RTW_DEBUG_LED, 2831 ("%s: LED condition %" PRIx8 "\n", __func__, led_condition)); 2832 2833 switch (hwverid) { 2834 default: 2835 case 'F': 2836 ofs = RTW_PSR; 2837 newval = mask = RTW_PSR_LEDGPO0 | RTW_PSR_LEDGPO1; 2838 if (led_condition & RTW_LED0) 2839 newval &= ~RTW_PSR_LEDGPO0; 2840 if (led_condition & RTW_LED1) 2841 newval &= ~RTW_PSR_LEDGPO1; 2842 break; 2843 case 'D': 2844 ofs = RTW_9346CR; 2845 mask = RTW_9346CR_EEM_MASK | RTW_9346CR_EEDI | RTW_9346CR_EECS; 2846 newval = RTW_9346CR_EEM_PROGRAM; 2847 if (led_condition & RTW_LED0) 2848 newval |= RTW_9346CR_EEDI; 2849 if (led_condition & RTW_LED1) 2850 newval |= RTW_9346CR_EECS; 2851 break; 2852 } 2853 val = RTW_READ8(regs, ofs); 2854 RTW_DPRINTF(RTW_DEBUG_LED, 2855 ("%s: read %" PRIx8 " from reg[%#02" PRIxPTR "]\n", __func__, val, 2856 (uintptr_t)ofs)); 2857 val &= ~mask; 2858 val |= newval; 2859 RTW_WRITE8(regs, ofs, val); 2860 RTW_DPRINTF(RTW_DEBUG_LED, 2861 ("%s: wrote %" PRIx8 " to reg[%#02" PRIxPTR "]\n", __func__, val, 2862 (uintptr_t)ofs)); 2863 RTW_SYNC(regs, ofs, ofs); 2864} 2865 2866static void 2867rtw_led_fastblink(void *arg) 2868{ 2869 int ostate, s; 2870 struct rtw_softc *sc = (struct rtw_softc *)arg; 2871 struct rtw_led_state *ls = &sc->sc_led_state; 2872 2873 s = splnet(); 2874 ostate = ls->ls_state; 2875 ls->ls_state ^= ls->ls_event; 2876 2877 if ((ls->ls_event & RTW_LED_S_TX) == 0) 2878 ls->ls_state &= ~RTW_LED_S_TX; 2879 2880 if ((ls->ls_event & RTW_LED_S_RX) == 0) 2881 ls->ls_state &= ~RTW_LED_S_RX; 2882 2883 ls->ls_event = 0; 2884 2885 if (ostate != ls->ls_state) 2886 rtw_led_set(ls, &sc->sc_regs, sc->sc_hwverid); 2887 splx(s); 2888 2889 callout_schedule(&ls->ls_fast_ch, RTW_LED_FAST_TICKS); 2890} 2891 2892static void 2893rtw_led_slowblink(void *arg) 2894{ 2895 int s; 2896 struct rtw_softc *sc = (struct rtw_softc *)arg; 2897 struct rtw_led_state *ls = &sc->sc_led_state; 2898 2899 s = splnet(); 2900 ls->ls_state ^= RTW_LED_S_SLOW; 2901 rtw_led_set(ls, &sc->sc_regs, sc->sc_hwverid); 2902 splx(s); 2903 callout_schedule(&ls->ls_slow_ch, RTW_LED_SLOW_TICKS); 2904} 2905 2906static inline void 2907rtw_led_attach(struct rtw_led_state *ls, void *arg) 2908{ 2909 callout_init(&ls->ls_fast_ch); 2910 callout_init(&ls->ls_slow_ch); 2911 callout_setfunc(&ls->ls_fast_ch, rtw_led_fastblink, arg); 2912 callout_setfunc(&ls->ls_slow_ch, rtw_led_slowblink, arg); 2913} 2914 2915static int 2916rtw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 2917{ 2918 int rc = 0, s; 2919 struct rtw_softc *sc = ifp->if_softc; 2920 struct ifreq *ifr = (struct ifreq *)data; 2921 2922 s = splnet(); 2923 switch (cmd) { 2924 case SIOCSIFFLAGS: 2925 if ((ifp->if_flags & IFF_UP) != 0) { 2926 if ((sc->sc_flags & RTW_F_ENABLED) != 0) { 2927 rtw_pktfilt_load(sc); 2928 } else 2929 rc = rtw_init(ifp); 2930 RTW_PRINT_REGS(&sc->sc_regs, ifp->if_xname, __func__); 2931 } else if ((sc->sc_flags & RTW_F_ENABLED) != 0) { 2932 RTW_PRINT_REGS(&sc->sc_regs, ifp->if_xname, __func__); 2933 rtw_stop(ifp, 1); 2934 } 2935 break; 2936 case SIOCADDMULTI: 2937 case SIOCDELMULTI: 2938 if (cmd == SIOCADDMULTI) 2939 rc = ether_addmulti(ifr, &sc->sc_ec); 2940 else 2941 rc = ether_delmulti(ifr, &sc->sc_ec); 2942 if (rc != ENETRESET) 2943 break; 2944 if (ifp->if_flags & IFF_RUNNING) 2945 rtw_pktfilt_load(sc); 2946 rc = 0; 2947 break; 2948 default: 2949 if ((rc = ieee80211_ioctl(&sc->sc_ic, cmd, data)) != ENETRESET) 2950 break; 2951 if ((sc->sc_flags & RTW_F_ENABLED) != 0) 2952 rc = rtw_init(ifp); 2953 else 2954 rc = 0; 2955 break; 2956 } 2957 splx(s); 2958 return rc; 2959} 2960 2961/* Select a transmit ring with at least one h/w and s/w descriptor free. 2962 * Return 0 on success, -1 on failure. 2963 */ 2964static inline int 2965rtw_txring_choose(struct rtw_softc *sc, struct rtw_txsoft_blk **tsbp, 2966 struct rtw_txdesc_blk **tdbp, int pri) 2967{ 2968 struct rtw_txsoft_blk *tsb; 2969 struct rtw_txdesc_blk *tdb; 2970 2971 KASSERT(pri >= 0 && pri < RTW_NTXPRI); 2972 2973 tsb = &sc->sc_txsoft_blk[pri]; 2974 tdb = &sc->sc_txdesc_blk[pri]; 2975 2976 if (SIMPLEQ_EMPTY(&tsb->tsb_freeq) || tdb->tdb_nfree == 0) { 2977 if (tsb->tsb_tx_timer == 0) 2978 tsb->tsb_tx_timer = 5; 2979 *tsbp = NULL; 2980 *tdbp = NULL; 2981 return -1; 2982 } 2983 *tsbp = tsb; 2984 *tdbp = tdb; 2985 return 0; 2986} 2987 2988static inline struct mbuf * 2989rtw_80211_dequeue(struct rtw_softc *sc, struct ifqueue *ifq, int pri, 2990 struct rtw_txsoft_blk **tsbp, struct rtw_txdesc_blk **tdbp, 2991 struct ieee80211_node **nip, short *if_flagsp) 2992{ 2993 struct mbuf *m; 2994 2995 if (IF_IS_EMPTY(ifq)) 2996 return NULL; 2997 if (rtw_txring_choose(sc, tsbp, tdbp, pri) == -1) { 2998 DPRINTF(sc, RTW_DEBUG_XMIT_RSRC, ("%s: no ring %d descriptor\n", 2999 __func__, pri)); 3000 *if_flagsp |= IFF_OACTIVE; 3001 sc->sc_if.if_timer = 1; 3002 return NULL; 3003 } 3004 IF_DEQUEUE(ifq, m); 3005 *nip = (struct ieee80211_node *)m->m_pkthdr.rcvif; 3006 m->m_pkthdr.rcvif = NULL; 3007 KASSERT(*nip != NULL); 3008 return m; 3009} 3010 3011/* Point *mp at the next 802.11 frame to transmit. Point *tsbp 3012 * at the driver's selection of transmit control block for the packet. 3013 */ 3014static inline int 3015rtw_dequeue(struct ifnet *ifp, struct rtw_txsoft_blk **tsbp, 3016 struct rtw_txdesc_blk **tdbp, struct mbuf **mp, 3017 struct ieee80211_node **nip) 3018{ 3019 int pri; 3020 struct ether_header *eh; 3021 struct mbuf *m0; 3022 struct rtw_softc *sc; 3023 short *if_flagsp; 3024 3025 *mp = NULL; 3026 3027 sc = (struct rtw_softc *)ifp->if_softc; 3028 3029 DPRINTF(sc, RTW_DEBUG_XMIT, 3030 ("%s: enter %s\n", sc->sc_dev.dv_xname, __func__)); 3031 3032 if_flagsp = &ifp->if_flags; 3033 3034 if (sc->sc_ic.ic_state == IEEE80211_S_RUN && 3035 (*mp = rtw_80211_dequeue(sc, &sc->sc_beaconq, RTW_TXPRIBCN, tsbp, 3036 tdbp, nip, if_flagsp)) != NULL) { 3037 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: dequeue beacon frame\n", 3038 __func__)); 3039 return 0; 3040 } 3041 3042 if ((*mp = rtw_80211_dequeue(sc, &sc->sc_ic.ic_mgtq, RTW_TXPRIMD, tsbp, 3043 tdbp, nip, if_flagsp)) != NULL) { 3044 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: dequeue mgt frame\n", 3045 __func__)); 3046 return 0; 3047 } 3048 3049 if (sc->sc_ic.ic_state != IEEE80211_S_RUN) { 3050 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: not running\n", __func__)); 3051 return 0; 3052 } 3053 3054 IFQ_POLL(&ifp->if_snd, m0); 3055 if (m0 == NULL) { 3056 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: no frame ready\n", 3057 __func__)); 3058 return 0; 3059 } 3060 3061 pri = ((m0->m_flags & M_PWR_SAV) != 0) ? RTW_TXPRIHI : RTW_TXPRIMD; 3062 3063 if (rtw_txring_choose(sc, tsbp, tdbp, pri) == -1) { 3064 DPRINTF(sc, RTW_DEBUG_XMIT_RSRC, ("%s: no ring %d descriptor\n", 3065 __func__, pri)); 3066 *if_flagsp |= IFF_OACTIVE; 3067 sc->sc_if.if_timer = 1; 3068 return 0; 3069 } 3070 3071 IFQ_DEQUEUE(&ifp->if_snd, m0); 3072 if (m0 == NULL) { 3073 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: no frame ready\n", 3074 __func__)); 3075 return 0; 3076 } 3077 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: dequeue data frame\n", __func__)); 3078 ifp->if_opackets++; 3079#if NBPFILTER > 0 3080 if (ifp->if_bpf) 3081 bpf_mtap(ifp->if_bpf, m0); 3082#endif 3083 eh = mtod(m0, struct ether_header *); 3084 *nip = ieee80211_find_txnode(&sc->sc_ic, eh->ether_dhost); 3085 if (*nip == NULL) { 3086 /* NB: ieee80211_find_txnode does stat+msg */ 3087 m_freem(m0); 3088 return -1; 3089 } 3090 if ((m0 = ieee80211_encap(&sc->sc_ic, m0, *nip)) == NULL) { 3091 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: encap error\n", __func__)); 3092 ifp->if_oerrors++; 3093 return -1; 3094 } 3095 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: leave\n", __func__)); 3096 *mp = m0; 3097 return 0; 3098} 3099 3100static int 3101rtw_seg_too_short(bus_dmamap_t dmamap) 3102{ 3103 int i; 3104 for (i = 0; i < dmamap->dm_nsegs; i++) { 3105 if (dmamap->dm_segs[i].ds_len < 4) 3106 return 1; 3107 } 3108 return 0; 3109} 3110 3111/* TBD factor with atw_start */ 3112static struct mbuf * 3113rtw_dmamap_load_txbuf(bus_dma_tag_t dmat, bus_dmamap_t dmam, struct mbuf *chain, 3114 u_int ndescfree, const char *dvname) 3115{ 3116 int first, rc; 3117 struct mbuf *m, *m0; 3118 3119 m0 = chain; 3120 3121 /* 3122 * Load the DMA map. Copy and try (once) again if the packet 3123 * didn't fit in the alloted number of segments. 3124 */ 3125 for (first = 1; 3126 ((rc = bus_dmamap_load_mbuf(dmat, dmam, m0, 3127 BUS_DMA_WRITE|BUS_DMA_NOWAIT)) != 0 || 3128 dmam->dm_nsegs > ndescfree || rtw_seg_too_short(dmam)) && first; 3129 first = 0) { 3130 if (rc == 0) { 3131#ifdef RTW_DIAGxxx 3132 if (rtw_seg_too_short(dmam)) { 3133 printf("%s: short segment, mbuf lengths:", __func__); 3134 for (m = m0; m; m = m->m_next) 3135 printf(" %d", m->m_len); 3136 printf("\n"); 3137 } 3138#endif 3139 bus_dmamap_unload(dmat, dmam); 3140 } 3141 MGETHDR(m, M_DONTWAIT, MT_DATA); 3142 if (m == NULL) { 3143 printf("%s: unable to allocate Tx mbuf\n", 3144 dvname); 3145 break; 3146 } 3147 if (m0->m_pkthdr.len > MHLEN) { 3148 MCLGET(m, M_DONTWAIT); 3149 if ((m->m_flags & M_EXT) == 0) { 3150 printf("%s: cannot allocate Tx cluster\n", 3151 dvname); 3152 m_freem(m); 3153 break; 3154 } 3155 } 3156 m_copydata(m0, 0, m0->m_pkthdr.len, mtod(m, caddr_t)); 3157 m->m_pkthdr.len = m->m_len = m0->m_pkthdr.len; 3158 m_freem(m0); 3159 m0 = m; 3160 m = NULL; 3161 } 3162 if (rc != 0) { 3163 printf("%s: cannot load Tx buffer, rc = %d\n", dvname, rc); 3164 m_freem(m0); 3165 return NULL; 3166 } else if (rtw_seg_too_short(dmam)) { 3167 printf("%s: cannot load Tx buffer, segment too short\n", 3168 dvname); 3169 bus_dmamap_unload(dmat, dmam); 3170 m_freem(m0); 3171 return NULL; 3172 } else if (dmam->dm_nsegs > ndescfree) { 3173 printf("%s: too many tx segments\n", dvname); 3174 bus_dmamap_unload(dmat, dmam); 3175 m_freem(m0); 3176 return NULL; 3177 } 3178 return m0; 3179} 3180 3181#ifdef RTW_DEBUG 3182static void 3183rtw_print_txdesc(struct rtw_softc *sc, const char *action, 3184 struct rtw_txsoft *ts, struct rtw_txdesc_blk *tdb, int desc) 3185{ 3186 struct rtw_txdesc *td = &tdb->tdb_desc[desc]; 3187 DPRINTF(sc, RTW_DEBUG_XMIT_DESC, ("%s: %p %s txdesc[%d] next %#08x " 3188 "buf %#08x ctl0 %#08x ctl1 %#08x len %#08x\n", 3189 sc->sc_dev.dv_xname, ts, action, desc, 3190 le32toh(td->td_buf), le32toh(td->td_next), 3191 le32toh(td->td_ctl0), le32toh(td->td_ctl1), 3192 le32toh(td->td_len))); 3193} 3194#endif /* RTW_DEBUG */ 3195 3196static void 3197rtw_start(struct ifnet *ifp) 3198{ 3199 uint8_t tppoll; 3200 int desc, i, lastdesc, npkt, rate; 3201 uint32_t proto_ctl0, ctl0, ctl1; 3202 bus_dmamap_t dmamap; 3203 struct ieee80211com *ic; 3204 struct ieee80211_duration *d0; 3205 struct ieee80211_frame_min *wh; 3206 struct ieee80211_node *ni = NULL; /* XXX: GCC */ 3207 struct mbuf *m0; 3208 struct rtw_softc *sc; 3209 struct rtw_txsoft_blk *tsb = NULL; /* XXX: GCC */ 3210 struct rtw_txdesc_blk *tdb = NULL; /* XXX: GCC */ 3211 struct rtw_txsoft *ts; 3212 struct rtw_txdesc *td; 3213 struct ieee80211_key *k; 3214 3215 sc = (struct rtw_softc *)ifp->if_softc; 3216 ic = &sc->sc_ic; 3217 3218 DPRINTF(sc, RTW_DEBUG_XMIT, 3219 ("%s: enter %s\n", sc->sc_dev.dv_xname, __func__)); 3220 3221 if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING) 3222 goto out; 3223 3224 /* XXX do real rate control */ 3225 proto_ctl0 = RTW_TXCTL0_RTSRATE_1MBPS; 3226 3227 if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0) 3228 proto_ctl0 |= RTW_TXCTL0_SPLCP; 3229 3230 for (;;) { 3231 if (rtw_dequeue(ifp, &tsb, &tdb, &m0, &ni) == -1) 3232 continue; 3233 if (m0 == NULL) 3234 break; 3235 3236 wh = mtod(m0, struct ieee80211_frame_min *); 3237 3238 if ((wh->i_fc[1] & IEEE80211_FC1_WEP) != 0 && 3239 (k = ieee80211_crypto_encap(ic, ni, m0)) == NULL) { 3240 m_freem(m0); 3241 break; 3242 } else 3243 k = NULL; 3244 3245 ts = SIMPLEQ_FIRST(&tsb->tsb_freeq); 3246 3247 dmamap = ts->ts_dmamap; 3248 3249 m0 = rtw_dmamap_load_txbuf(sc->sc_dmat, dmamap, m0, 3250 tdb->tdb_nfree, sc->sc_dev.dv_xname); 3251 3252 if (m0 == NULL || dmamap->dm_nsegs == 0) { 3253 DPRINTF(sc, RTW_DEBUG_XMIT, 3254 ("%s: fail dmamap load\n", __func__)); 3255 goto post_dequeue_err; 3256 } 3257 3258 /* Note well: rtw_dmamap_load_txbuf may have created 3259 * a new chain, so we must find the header once 3260 * more. 3261 */ 3262 wh = mtod(m0, struct ieee80211_frame_min *); 3263 3264 /* XXX do real rate control */ 3265 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == 3266 IEEE80211_FC0_TYPE_MGT) 3267 rate = 2; 3268 else 3269 rate = MAX(2, ieee80211_get_rate(ni)); 3270 3271#ifdef RTW_DEBUG 3272 if ((ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) == 3273 (IFF_DEBUG|IFF_LINK2)) { 3274 ieee80211_dump_pkt(mtod(m0, uint8_t *), 3275 (dmamap->dm_nsegs == 1) ? m0->m_pkthdr.len 3276 : sizeof(wh), 3277 rate, 0); 3278 } 3279#endif /* RTW_DEBUG */ 3280 ctl0 = proto_ctl0 | 3281 __SHIFTIN(m0->m_pkthdr.len, RTW_TXCTL0_TPKTSIZE_MASK); 3282 3283 switch (rate) { 3284 default: 3285 case 2: 3286 ctl0 |= RTW_TXCTL0_RATE_1MBPS; 3287 break; 3288 case 4: 3289 ctl0 |= RTW_TXCTL0_RATE_2MBPS; 3290 break; 3291 case 11: 3292 ctl0 |= RTW_TXCTL0_RATE_5MBPS; 3293 break; 3294 case 22: 3295 ctl0 |= RTW_TXCTL0_RATE_11MBPS; 3296 break; 3297 } 3298 /* XXX >= ? Compare after fragmentation? */ 3299 if (m0->m_pkthdr.len > ic->ic_rtsthreshold) 3300 ctl0 |= RTW_TXCTL0_RTSEN; 3301 3302 /* XXX Sometimes writes a bogus keyid; h/w doesn't 3303 * seem to care, since we don't activate h/w Tx 3304 * encryption. 3305 */ 3306 if (k != NULL) { 3307 ctl0 |= __SHIFTIN(k->wk_keyix, RTW_TXCTL0_KEYID_MASK) & 3308 RTW_TXCTL0_KEYID_MASK; 3309 } 3310 3311 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == 3312 IEEE80211_FC0_TYPE_MGT) { 3313 ctl0 &= ~(RTW_TXCTL0_SPLCP | RTW_TXCTL0_RTSEN); 3314 if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == 3315 IEEE80211_FC0_SUBTYPE_BEACON) 3316 ctl0 |= RTW_TXCTL0_BEACON; 3317 } 3318 3319 if (ieee80211_compute_duration(wh, k, m0->m_pkthdr.len, 3320 ic->ic_flags, ic->ic_fragthreshold, 3321 rate, &ts->ts_d0, &ts->ts_dn, &npkt, 3322 (ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) == 3323 (IFF_DEBUG|IFF_LINK2)) == -1) { 3324 DPRINTF(sc, RTW_DEBUG_XMIT, 3325 ("%s: fail compute duration\n", __func__)); 3326 goto post_load_err; 3327 } 3328 3329 d0 = &ts->ts_d0; 3330 3331 *(uint16_t*)wh->i_dur = htole16(d0->d_data_dur); 3332 3333 ctl1 = __SHIFTIN(d0->d_plcp_len, RTW_TXCTL1_LENGTH_MASK) | 3334 __SHIFTIN(d0->d_rts_dur, RTW_TXCTL1_RTSDUR_MASK); 3335 3336 if (d0->d_residue) 3337 ctl1 |= RTW_TXCTL1_LENGEXT; 3338 3339 /* TBD fragmentation */ 3340 3341 ts->ts_first = tdb->tdb_next; 3342 3343 rtw_txdescs_sync(tdb, ts->ts_first, dmamap->dm_nsegs, 3344 BUS_DMASYNC_PREWRITE); 3345 3346 KASSERT(ts->ts_first < tdb->tdb_ndesc); 3347 3348#if NBPFILTER > 0 3349 if (ic->ic_rawbpf != NULL) 3350 bpf_mtap((caddr_t)ic->ic_rawbpf, m0); 3351 3352 if (sc->sc_radiobpf != NULL) { 3353 struct rtw_tx_radiotap_header *rt = &sc->sc_txtap; 3354 3355 rt->rt_flags = 0; 3356 rt->rt_rate = rate; 3357 3358 bpf_mtap2(sc->sc_radiobpf, (caddr_t)rt, 3359 sizeof(sc->sc_txtapu), m0); 3360 } 3361#endif /* NPBFILTER > 0 */ 3362 3363 for (i = 0, lastdesc = desc = ts->ts_first; 3364 i < dmamap->dm_nsegs; 3365 i++, desc = RTW_NEXT_IDX(tdb, desc)) { 3366 if (dmamap->dm_segs[i].ds_len > RTW_TXLEN_LENGTH_MASK) { 3367 DPRINTF(sc, RTW_DEBUG_XMIT_DESC, 3368 ("%s: seg too long\n", __func__)); 3369 goto post_load_err; 3370 } 3371 td = &tdb->tdb_desc[desc]; 3372 td->td_ctl0 = htole32(ctl0); 3373 if (i != 0) 3374 td->td_ctl0 |= htole32(RTW_TXCTL0_OWN); 3375 td->td_ctl1 = htole32(ctl1); 3376 td->td_buf = htole32(dmamap->dm_segs[i].ds_addr); 3377 td->td_len = htole32(dmamap->dm_segs[i].ds_len); 3378 lastdesc = desc; 3379#ifdef RTW_DEBUG 3380 rtw_print_txdesc(sc, "load", ts, tdb, desc); 3381#endif /* RTW_DEBUG */ 3382 } 3383 3384 KASSERT(desc < tdb->tdb_ndesc); 3385 3386 ts->ts_ni = ni; 3387 KASSERT(ni != NULL); 3388 ts->ts_mbuf = m0; 3389 ts->ts_last = lastdesc; 3390 tdb->tdb_desc[ts->ts_last].td_ctl0 |= htole32(RTW_TXCTL0_LS); 3391 tdb->tdb_desc[ts->ts_first].td_ctl0 |= 3392 htole32(RTW_TXCTL0_FS); 3393 3394#ifdef RTW_DEBUG 3395 rtw_print_txdesc(sc, "FS on", ts, tdb, ts->ts_first); 3396 rtw_print_txdesc(sc, "LS on", ts, tdb, ts->ts_last); 3397#endif /* RTW_DEBUG */ 3398 3399 tdb->tdb_nfree -= dmamap->dm_nsegs; 3400 tdb->tdb_next = desc; 3401 3402 rtw_txdescs_sync(tdb, ts->ts_first, dmamap->dm_nsegs, 3403 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 3404 3405 tdb->tdb_desc[ts->ts_first].td_ctl0 |= 3406 htole32(RTW_TXCTL0_OWN); 3407 3408#ifdef RTW_DEBUG 3409 rtw_print_txdesc(sc, "OWN on", ts, tdb, ts->ts_first); 3410#endif /* RTW_DEBUG */ 3411 3412 rtw_txdescs_sync(tdb, ts->ts_first, 1, 3413 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 3414 3415 SIMPLEQ_REMOVE_HEAD(&tsb->tsb_freeq, ts_q); 3416 SIMPLEQ_INSERT_TAIL(&tsb->tsb_dirtyq, ts, ts_q); 3417 3418 if (tsb != &sc->sc_txsoft_blk[RTW_TXPRIBCN]) 3419 sc->sc_led_state.ls_event |= RTW_LED_S_TX; 3420 tsb->tsb_tx_timer = 5; 3421 ifp->if_timer = 1; 3422 tppoll = RTW_READ8(&sc->sc_regs, RTW_TPPOLL); 3423 tppoll &= ~RTW_TPPOLL_SALL; 3424 tppoll |= tsb->tsb_poll & RTW_TPPOLL_ALL; 3425 RTW_WRITE8(&sc->sc_regs, RTW_TPPOLL, tppoll); 3426 RTW_SYNC(&sc->sc_regs, RTW_TPPOLL, RTW_TPPOLL); 3427 } 3428out: 3429 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: leave\n", __func__)); 3430 return; 3431post_load_err: 3432 bus_dmamap_unload(sc->sc_dmat, dmamap); 3433 m_freem(m0); 3434post_dequeue_err: 3435 ieee80211_free_node(ni); 3436 return; 3437} 3438 3439static void 3440rtw_idle(struct rtw_regs *regs) 3441{ 3442 int active; 3443 3444 /* request stop DMA; wait for packets to stop transmitting. */ 3445 3446 RTW_WRITE8(regs, RTW_TPPOLL, RTW_TPPOLL_SALL); 3447 RTW_WBR(regs, RTW_TPPOLL, RTW_TPPOLL); 3448 3449 for (active = 0; active < 300 && 3450 (RTW_READ8(regs, RTW_TPPOLL) & RTW_TPPOLL_ACTIVE) != 0; active++) 3451 DELAY(10); 3452 printf("%s: transmit DMA idle in %dus\n", __func__, active * 10); 3453} 3454 3455static void 3456rtw_watchdog(struct ifnet *ifp) 3457{ 3458 int pri, tx_timeouts = 0; 3459 struct rtw_softc *sc; 3460 struct rtw_txsoft_blk *tsb; 3461 3462 sc = ifp->if_softc; 3463 3464 ifp->if_timer = 0; 3465 3466 if ((sc->sc_flags & RTW_F_ENABLED) == 0) 3467 return; 3468 3469 for (pri = 0; pri < RTW_NTXPRI; pri++) { 3470 tsb = &sc->sc_txsoft_blk[pri]; 3471 3472 if (tsb->tsb_tx_timer == 0) 3473 continue; 3474 else if (--tsb->tsb_tx_timer == 0) { 3475 if (SIMPLEQ_EMPTY(&tsb->tsb_dirtyq)) 3476 continue; 3477 printf("%s: transmit timeout, priority %d\n", 3478 ifp->if_xname, pri); 3479 ifp->if_oerrors++; 3480 if (pri != RTW_TXPRIBCN) 3481 tx_timeouts++; 3482 } else 3483 ifp->if_timer = 1; 3484 } 3485 3486 if (tx_timeouts > 0) { 3487 /* Stop Tx DMA, disable xmtr, flush Tx rings, enable xmtr, 3488 * reset s/w tx-ring pointers, and start transmission. 3489 * 3490 * TBD Stop/restart just the broken rings? 3491 */ 3492 rtw_idle(&sc->sc_regs); 3493 rtw_io_enable(sc, RTW_CR_TE, 0); 3494 rtw_txdescs_reset(sc); 3495 rtw_io_enable(sc, RTW_CR_TE, 1); 3496 rtw_start(ifp); 3497 } 3498 ieee80211_watchdog(&sc->sc_ic); 3499 return; 3500} 3501 3502static void 3503rtw_next_scan(void *arg) 3504{ 3505 struct ieee80211com *ic = arg; 3506 int s; 3507 3508 /* don't call rtw_start w/o network interrupts blocked */ 3509 s = splnet(); 3510 if (ic->ic_state == IEEE80211_S_SCAN) 3511 ieee80211_next_scan(ic); 3512 splx(s); 3513} 3514 3515static void 3516rtw_join_bss(struct rtw_softc *sc, uint8_t *bssid, uint16_t intval0) 3517{ 3518 uint16_t bcnitv, bintritv, intval; 3519 int i; 3520 struct rtw_regs *regs = &sc->sc_regs; 3521 3522 for (i = 0; i < IEEE80211_ADDR_LEN; i++) 3523 RTW_WRITE8(regs, RTW_BSSID + i, bssid[i]); 3524 3525 RTW_SYNC(regs, RTW_BSSID16, RTW_BSSID32); 3526 3527 rtw_set_access(regs, RTW_ACCESS_CONFIG); 3528 3529 intval = MIN(intval0, __SHIFTOUT_MASK(RTW_BCNITV_BCNITV_MASK)); 3530 3531 bcnitv = RTW_READ16(regs, RTW_BCNITV) & ~RTW_BCNITV_BCNITV_MASK; 3532 bcnitv |= __SHIFTIN(intval, RTW_BCNITV_BCNITV_MASK); 3533 RTW_WRITE16(regs, RTW_BCNITV, bcnitv); 3534 /* interrupt host 1ms before the TBTT */ 3535 bintritv = RTW_READ16(regs, RTW_BINTRITV) & ~RTW_BINTRITV_BINTRITV; 3536 bintritv |= __SHIFTIN(1000, RTW_BINTRITV_BINTRITV); 3537 RTW_WRITE16(regs, RTW_BINTRITV, bintritv); 3538 /* magic from Linux */ 3539 RTW_WRITE16(regs, RTW_ATIMWND, __SHIFTIN(1, RTW_ATIMWND_ATIMWND)); 3540 RTW_WRITE16(regs, RTW_ATIMTRITV, __SHIFTIN(2, RTW_ATIMTRITV_ATIMTRITV)); 3541 rtw_set_access(regs, RTW_ACCESS_NONE); 3542 3543 rtw_io_enable(sc, RTW_CR_RE | RTW_CR_TE, 1); 3544} 3545 3546/* Synchronize the hardware state with the software state. */ 3547static int 3548rtw_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) 3549{ 3550 struct ifnet *ifp = ic->ic_ifp; 3551 struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc; 3552 enum ieee80211_state ostate; 3553 int error; 3554 3555 ostate = ic->ic_state; 3556 3557 rtw_led_newstate(sc, nstate); 3558 3559 if (nstate == IEEE80211_S_INIT) { 3560 callout_stop(&sc->sc_scan_ch); 3561 sc->sc_cur_chan = IEEE80211_CHAN_ANY; 3562 return (*sc->sc_mtbl.mt_newstate)(ic, nstate, arg); 3563 } 3564 3565 if (ostate == IEEE80211_S_INIT && nstate != IEEE80211_S_INIT) 3566 rtw_pwrstate(sc, RTW_ON); 3567 3568 if ((error = rtw_tune(sc)) != 0) 3569 return error; 3570 3571 switch (nstate) { 3572 case IEEE80211_S_INIT: 3573 panic("%s: unexpected state IEEE80211_S_INIT\n", __func__); 3574 break; 3575 case IEEE80211_S_SCAN: 3576 if (ostate != IEEE80211_S_SCAN) { 3577 (void)memset(ic->ic_bss->ni_bssid, 0, 3578 IEEE80211_ADDR_LEN); 3579 rtw_set_nettype(sc, IEEE80211_M_MONITOR); 3580 } 3581 3582 callout_reset(&sc->sc_scan_ch, rtw_dwelltime * hz / 1000, 3583 rtw_next_scan, ic); 3584 3585 break; 3586 case IEEE80211_S_RUN: 3587 switch (ic->ic_opmode) { 3588 case IEEE80211_M_HOSTAP: 3589 case IEEE80211_M_IBSS: 3590 rtw_set_nettype(sc, IEEE80211_M_MONITOR); 3591 /*FALLTHROUGH*/ 3592 case IEEE80211_M_AHDEMO: 3593 case IEEE80211_M_STA: 3594 rtw_join_bss(sc, ic->ic_bss->ni_bssid, 3595 ic->ic_bss->ni_intval); 3596 break; 3597 case IEEE80211_M_MONITOR: 3598 break; 3599 } 3600 rtw_set_nettype(sc, ic->ic_opmode); 3601 break; 3602 case IEEE80211_S_ASSOC: 3603 case IEEE80211_S_AUTH: 3604 break; 3605 } 3606 3607 if (nstate != IEEE80211_S_SCAN) 3608 callout_stop(&sc->sc_scan_ch); 3609 3610 return (*sc->sc_mtbl.mt_newstate)(ic, nstate, arg); 3611} 3612 3613/* Extend a 32-bit TSF timestamp to a 64-bit timestamp. */ 3614static uint64_t 3615rtw_tsf_extend(struct rtw_regs *regs, uint32_t rstamp) 3616{ 3617 uint32_t tsftl, tsfth; 3618 3619 tsfth = RTW_READ(regs, RTW_TSFTRH); 3620 tsftl = RTW_READ(regs, RTW_TSFTRL); 3621 if (tsftl < rstamp) /* Compensate for rollover. */ 3622 tsfth--; 3623 return ((uint64_t)tsfth << 32) | rstamp; 3624} 3625 3626static void 3627rtw_recv_mgmt(struct ieee80211com *ic, struct mbuf *m, 3628 struct ieee80211_node *ni, int subtype, int rssi, uint32_t rstamp) 3629{ 3630 struct ifnet *ifp = ic->ic_ifp; 3631 struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc; 3632 3633 (*sc->sc_mtbl.mt_recv_mgmt)(ic, m, ni, subtype, rssi, rstamp); 3634 3635 switch (subtype) { 3636 case IEEE80211_FC0_SUBTYPE_PROBE_RESP: 3637 case IEEE80211_FC0_SUBTYPE_BEACON: 3638 if (ic->ic_opmode == IEEE80211_M_IBSS && 3639 ic->ic_state == IEEE80211_S_RUN) { 3640 uint64_t tsf = rtw_tsf_extend(&sc->sc_regs, rstamp); 3641 if (le64toh(ni->ni_tstamp.tsf) >= tsf) 3642 (void)ieee80211_ibss_merge(ni); 3643 } 3644 break; 3645 default: 3646 break; 3647 } 3648 return; 3649} 3650 3651static struct ieee80211_node * 3652rtw_node_alloc(struct ieee80211_node_table *nt) 3653{ 3654 struct ifnet *ifp = nt->nt_ic->ic_ifp; 3655 struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc; 3656 struct ieee80211_node *ni = (*sc->sc_mtbl.mt_node_alloc)(nt); 3657 3658 DPRINTF(sc, RTW_DEBUG_NODE, 3659 ("%s: alloc node %p\n", sc->sc_dev.dv_xname, ni)); 3660 return ni; 3661} 3662 3663static void 3664rtw_node_free(struct ieee80211_node *ni) 3665{ 3666 struct ieee80211com *ic = ni->ni_ic; 3667 struct ifnet *ifp = ic->ic_ifp; 3668 struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc; 3669 3670 DPRINTF(sc, RTW_DEBUG_NODE, 3671 ("%s: freeing node %p %s\n", sc->sc_dev.dv_xname, ni, 3672 ether_sprintf(ni->ni_bssid))); 3673 (*sc->sc_mtbl.mt_node_free)(ni); 3674} 3675 3676static int 3677rtw_media_change(struct ifnet *ifp) 3678{ 3679 int error; 3680 3681 error = ieee80211_media_change(ifp); 3682 if (error == ENETRESET) { 3683 if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) == 3684 (IFF_RUNNING|IFF_UP)) 3685 rtw_init(ifp); /* XXX lose error */ 3686 error = 0; 3687 } 3688 return error; 3689} 3690 3691static void 3692rtw_media_status(struct ifnet *ifp, struct ifmediareq *imr) 3693{ 3694 struct rtw_softc *sc = ifp->if_softc; 3695 3696 if ((sc->sc_flags & RTW_F_ENABLED) == 0) { 3697 imr->ifm_active = IFM_IEEE80211 | IFM_NONE; 3698 imr->ifm_status = 0; 3699 return; 3700 } 3701 ieee80211_media_status(ifp, imr); 3702} 3703 3704void 3705rtw_power(int why, void *arg) 3706{ 3707 struct rtw_softc *sc = arg; 3708 struct ifnet *ifp = &sc->sc_if; 3709 int s; 3710 3711 DPRINTF(sc, RTW_DEBUG_PWR, 3712 ("%s: rtw_power(%d,)\n", sc->sc_dev.dv_xname, why)); 3713 3714 s = splnet(); 3715 switch (why) { 3716 case PWR_STANDBY: 3717 /* XXX do nothing. */ 3718 break; 3719 case PWR_SUSPEND: 3720 rtw_stop(ifp, 0); 3721 if (sc->sc_power != NULL) 3722 (*sc->sc_power)(sc, why); 3723 break; 3724 case PWR_RESUME: 3725 if (ifp->if_flags & IFF_UP) { 3726 if (sc->sc_power != NULL) 3727 (*sc->sc_power)(sc, why); 3728 rtw_init(ifp); 3729 } 3730 break; 3731 case PWR_SOFTSUSPEND: 3732 case PWR_SOFTSTANDBY: 3733 case PWR_SOFTRESUME: 3734 break; 3735 } 3736 splx(s); 3737} 3738 3739/* rtw_shutdown: make sure the interface is stopped at reboot time. */ 3740void 3741rtw_shutdown(void *arg) 3742{ 3743 struct rtw_softc *sc = arg; 3744 3745 rtw_stop(&sc->sc_if, 1); 3746} 3747 3748static inline void 3749rtw_setifprops(struct ifnet *ifp, const char *dvname, void *softc) 3750{ 3751 (void)memcpy(ifp->if_xname, dvname, IFNAMSIZ); 3752 ifp->if_softc = softc; 3753 ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST | 3754 IFF_NOTRAILERS; 3755 ifp->if_ioctl = rtw_ioctl; 3756 ifp->if_start = rtw_start; 3757 ifp->if_watchdog = rtw_watchdog; 3758 ifp->if_init = rtw_init; 3759 ifp->if_stop = rtw_stop; 3760} 3761 3762static inline void 3763rtw_set80211props(struct ieee80211com *ic) 3764{ 3765 int nrate; 3766 ic->ic_phytype = IEEE80211_T_DS; 3767 ic->ic_opmode = IEEE80211_M_STA; 3768 ic->ic_caps = IEEE80211_C_PMGT | IEEE80211_C_IBSS | 3769 IEEE80211_C_HOSTAP | IEEE80211_C_MONITOR; 3770 3771 nrate = 0; 3772 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] = 3773 IEEE80211_RATE_BASIC | 2; 3774 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] = 3775 IEEE80211_RATE_BASIC | 4; 3776 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] = 11; 3777 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] = 22; 3778 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_nrates = nrate; 3779} 3780 3781static inline void 3782rtw_set80211methods(struct rtw_mtbl *mtbl, struct ieee80211com *ic) 3783{ 3784 mtbl->mt_newstate = ic->ic_newstate; 3785 ic->ic_newstate = rtw_newstate; 3786 3787 mtbl->mt_recv_mgmt = ic->ic_recv_mgmt; 3788 ic->ic_recv_mgmt = rtw_recv_mgmt; 3789 3790 mtbl->mt_node_free = ic->ic_node_free; 3791 ic->ic_node_free = rtw_node_free; 3792 3793 mtbl->mt_node_alloc = ic->ic_node_alloc; 3794 ic->ic_node_alloc = rtw_node_alloc; 3795 3796 ic->ic_crypto.cs_key_delete = rtw_key_delete; 3797 ic->ic_crypto.cs_key_set = rtw_key_set; 3798 ic->ic_crypto.cs_key_update_begin = rtw_key_update_begin; 3799 ic->ic_crypto.cs_key_update_end = rtw_key_update_end; 3800} 3801 3802static inline void 3803rtw_establish_hooks(struct rtw_hooks *hooks, const char *dvname, 3804 void *arg) 3805{ 3806 /* 3807 * Make sure the interface is shutdown during reboot. 3808 */ 3809 hooks->rh_shutdown = shutdownhook_establish(rtw_shutdown, arg); 3810 if (hooks->rh_shutdown == NULL) 3811 printf("%s: WARNING: unable to establish shutdown hook\n", 3812 dvname); 3813 3814 /* 3815 * Add a suspend hook to make sure we come back up after a 3816 * resume. 3817 */ 3818 hooks->rh_power = powerhook_establish(dvname, rtw_power, arg); 3819 if (hooks->rh_power == NULL) 3820 printf("%s: WARNING: unable to establish power hook\n", 3821 dvname); 3822} 3823 3824static inline void 3825rtw_disestablish_hooks(struct rtw_hooks *hooks, const char *dvname, 3826 void *arg) 3827{ 3828 if (hooks->rh_shutdown != NULL) 3829 shutdownhook_disestablish(hooks->rh_shutdown); 3830 3831 if (hooks->rh_power != NULL) 3832 powerhook_disestablish(hooks->rh_power); 3833} 3834 3835static inline void 3836rtw_init_radiotap(struct rtw_softc *sc) 3837{ 3838 memset(&sc->sc_rxtapu, 0, sizeof(sc->sc_rxtapu)); 3839 sc->sc_rxtap.rr_ihdr.it_len = htole16(sizeof(sc->sc_rxtapu)); 3840 sc->sc_rxtap.rr_ihdr.it_present = htole32(RTW_RX_RADIOTAP_PRESENT); 3841 3842 memset(&sc->sc_txtapu, 0, sizeof(sc->sc_txtapu)); 3843 sc->sc_txtap.rt_ihdr.it_len = htole16(sizeof(sc->sc_txtapu)); 3844 sc->sc_txtap.rt_ihdr.it_present = htole32(RTW_TX_RADIOTAP_PRESENT); 3845} 3846 3847static int 3848rtw_txsoft_blk_setup(struct rtw_txsoft_blk *tsb, u_int qlen) 3849{ 3850 SIMPLEQ_INIT(&tsb->tsb_dirtyq); 3851 SIMPLEQ_INIT(&tsb->tsb_freeq); 3852 tsb->tsb_ndesc = qlen; 3853 tsb->tsb_desc = malloc(qlen * sizeof(*tsb->tsb_desc), M_DEVBUF, 3854 M_NOWAIT); 3855 if (tsb->tsb_desc == NULL) 3856 return ENOMEM; 3857 return 0; 3858} 3859 3860static void 3861rtw_txsoft_blk_cleanup_all(struct rtw_softc *sc) 3862{ 3863 int pri; 3864 struct rtw_txsoft_blk *tsb; 3865 3866 for (pri = 0; pri < RTW_NTXPRI; pri++) { 3867 tsb = &sc->sc_txsoft_blk[pri]; 3868 free(tsb->tsb_desc, M_DEVBUF); 3869 tsb->tsb_desc = NULL; 3870 } 3871} 3872 3873static int 3874rtw_txsoft_blk_setup_all(struct rtw_softc *sc) 3875{ 3876 int pri, rc = 0; 3877 int qlen[RTW_NTXPRI] = 3878 {RTW_TXQLENLO, RTW_TXQLENMD, RTW_TXQLENHI, RTW_TXQLENBCN}; 3879 struct rtw_txsoft_blk *tsbs; 3880 3881 tsbs = sc->sc_txsoft_blk; 3882 3883 for (pri = 0; pri < RTW_NTXPRI; pri++) { 3884 rc = rtw_txsoft_blk_setup(&tsbs[pri], qlen[pri]); 3885 if (rc != 0) 3886 break; 3887 } 3888 tsbs[RTW_TXPRILO].tsb_poll = RTW_TPPOLL_LPQ | RTW_TPPOLL_SLPQ; 3889 tsbs[RTW_TXPRIMD].tsb_poll = RTW_TPPOLL_NPQ | RTW_TPPOLL_SNPQ; 3890 tsbs[RTW_TXPRIHI].tsb_poll = RTW_TPPOLL_HPQ | RTW_TPPOLL_SHPQ; 3891 tsbs[RTW_TXPRIBCN].tsb_poll = RTW_TPPOLL_BQ | RTW_TPPOLL_SBQ; 3892 return rc; 3893} 3894 3895static void 3896rtw_txdesc_blk_setup(struct rtw_txdesc_blk *tdb, struct rtw_txdesc *desc, 3897 u_int ndesc, bus_addr_t ofs, bus_addr_t physbase) 3898{ 3899 tdb->tdb_ndesc = ndesc; 3900 tdb->tdb_desc = desc; 3901 tdb->tdb_physbase = physbase; 3902 tdb->tdb_ofs = ofs; 3903 3904 (void)memset(tdb->tdb_desc, 0, 3905 sizeof(tdb->tdb_desc[0]) * tdb->tdb_ndesc); 3906 3907 rtw_txdesc_blk_init(tdb); 3908 tdb->tdb_next = 0; 3909} 3910 3911static void 3912rtw_txdesc_blk_setup_all(struct rtw_softc *sc) 3913{ 3914 rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRILO], 3915 &sc->sc_descs->hd_txlo[0], RTW_NTXDESCLO, 3916 RTW_RING_OFFSET(hd_txlo), RTW_RING_BASE(sc, hd_txlo)); 3917 3918 rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIMD], 3919 &sc->sc_descs->hd_txmd[0], RTW_NTXDESCMD, 3920 RTW_RING_OFFSET(hd_txmd), RTW_RING_BASE(sc, hd_txmd)); 3921 3922 rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIHI], 3923 &sc->sc_descs->hd_txhi[0], RTW_NTXDESCHI, 3924 RTW_RING_OFFSET(hd_txhi), RTW_RING_BASE(sc, hd_txhi)); 3925 3926 rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIBCN], 3927 &sc->sc_descs->hd_bcn[0], RTW_NTXDESCBCN, 3928 RTW_RING_OFFSET(hd_bcn), RTW_RING_BASE(sc, hd_bcn)); 3929} 3930 3931static struct rtw_rf * 3932rtw_rf_attach(struct rtw_softc *sc, enum rtw_rfchipid rfchipid, int digphy) 3933{ 3934 rtw_rf_write_t rf_write; 3935 struct rtw_rf *rf; 3936 3937 switch (rfchipid) { 3938 default: 3939 rf_write = rtw_rf_hostwrite; 3940 break; 3941 case RTW_RFCHIPID_INTERSIL: 3942 case RTW_RFCHIPID_PHILIPS: 3943 case RTW_RFCHIPID_GCT: /* XXX a guess */ 3944 case RTW_RFCHIPID_RFMD: 3945 rf_write = (rtw_host_rfio) ? rtw_rf_hostwrite : rtw_rf_macwrite; 3946 break; 3947 } 3948 3949 switch (rfchipid) { 3950 case RTW_RFCHIPID_GCT: 3951 rf = rtw_grf5101_create(&sc->sc_regs, rf_write, 0); 3952 sc->sc_pwrstate_cb = rtw_maxim_pwrstate; 3953 break; 3954 case RTW_RFCHIPID_MAXIM: 3955 rf = rtw_max2820_create(&sc->sc_regs, rf_write, 0); 3956 sc->sc_pwrstate_cb = rtw_maxim_pwrstate; 3957 break; 3958 case RTW_RFCHIPID_PHILIPS: 3959 rf = rtw_sa2400_create(&sc->sc_regs, rf_write, digphy); 3960 sc->sc_pwrstate_cb = rtw_philips_pwrstate; 3961 break; 3962 case RTW_RFCHIPID_RFMD: 3963 /* XXX RFMD has no RF constructor */ 3964 sc->sc_pwrstate_cb = rtw_rfmd_pwrstate; 3965 /*FALLTHROUGH*/ 3966 default: 3967 return NULL; 3968 } 3969 rf->rf_continuous_tx_cb = 3970 (rtw_continuous_tx_cb_t)rtw_continuous_tx_enable; 3971 rf->rf_continuous_tx_arg = (void *)sc; 3972 return rf; 3973} 3974 3975/* Revision C and later use a different PHY delay setting than 3976 * revisions A and B. 3977 */ 3978static uint8_t 3979rtw_check_phydelay(struct rtw_regs *regs, uint32_t old_rcr) 3980{ 3981#define REVAB (RTW_RCR_MXDMA_UNLIMITED | RTW_RCR_AICV) 3982#define REVC (REVAB | RTW_RCR_RXFTH_WHOLE) 3983 3984 uint8_t phydelay = __SHIFTIN(0x6, RTW_PHYDELAY_PHYDELAY); 3985 3986 RTW_WRITE(regs, RTW_RCR, REVAB); 3987 RTW_WBW(regs, RTW_RCR, RTW_RCR); 3988 RTW_WRITE(regs, RTW_RCR, REVC); 3989 3990 RTW_WBR(regs, RTW_RCR, RTW_RCR); 3991 if ((RTW_READ(regs, RTW_RCR) & REVC) == REVC) 3992 phydelay |= RTW_PHYDELAY_REVC_MAGIC; 3993 3994 RTW_WRITE(regs, RTW_RCR, old_rcr); /* restore RCR */ 3995 RTW_SYNC(regs, RTW_RCR, RTW_RCR); 3996 3997 return phydelay; 3998#undef REVC 3999} 4000 4001void 4002rtw_attach(struct rtw_softc *sc) 4003{ 4004 struct ifnet *ifp = &sc->sc_if; 4005 struct ieee80211com *ic = &sc->sc_ic; 4006 struct rtw_txsoft_blk *tsb; 4007 int pri, rc; 4008 4009 rtw_cipher_wep = ieee80211_cipher_wep; 4010 rtw_cipher_wep.ic_decap = rtw_wep_decap; 4011 4012 NEXT_ATTACH_STATE(sc, DETACHED); 4013 4014 switch (RTW_READ(&sc->sc_regs, RTW_TCR) & RTW_TCR_HWVERID_MASK) { 4015 case RTW_TCR_HWVERID_F: 4016 sc->sc_hwverid = 'F'; 4017 break; 4018 case RTW_TCR_HWVERID_D: 4019 sc->sc_hwverid = 'D'; 4020 break; 4021 default: 4022 sc->sc_hwverid = '?'; 4023 break; 4024 } 4025 printf("%s: hardware version %c\n", sc->sc_dev.dv_xname, 4026 sc->sc_hwverid); 4027 4028 rc = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct rtw_descs), 4029 RTW_DESC_ALIGNMENT, 0, &sc->sc_desc_segs, 1, &sc->sc_desc_nsegs, 4030 0); 4031 4032 if (rc != 0) { 4033 printf("%s: could not allocate hw descriptors, error %d\n", 4034 sc->sc_dev.dv_xname, rc); 4035 goto err; 4036 } 4037 4038 NEXT_ATTACH_STATE(sc, FINISH_DESC_ALLOC); 4039 4040 rc = bus_dmamem_map(sc->sc_dmat, &sc->sc_desc_segs, 4041 sc->sc_desc_nsegs, sizeof(struct rtw_descs), 4042 (caddr_t*)&sc->sc_descs, BUS_DMA_COHERENT); 4043 4044 if (rc != 0) { 4045 printf("%s: could not map hw descriptors, error %d\n", 4046 sc->sc_dev.dv_xname, rc); 4047 goto err; 4048 } 4049 NEXT_ATTACH_STATE(sc, FINISH_DESC_MAP); 4050 4051 rc = bus_dmamap_create(sc->sc_dmat, sizeof(struct rtw_descs), 1, 4052 sizeof(struct rtw_descs), 0, 0, &sc->sc_desc_dmamap); 4053 4054 if (rc != 0) { 4055 printf("%s: could not create DMA map for hw descriptors, " 4056 "error %d\n", sc->sc_dev.dv_xname, rc); 4057 goto err; 4058 } 4059 NEXT_ATTACH_STATE(sc, FINISH_DESCMAP_CREATE); 4060 4061 sc->sc_rxdesc_blk.rdb_dmat = sc->sc_dmat; 4062 sc->sc_rxdesc_blk.rdb_dmamap = sc->sc_desc_dmamap; 4063 4064 for (pri = 0; pri < RTW_NTXPRI; pri++) { 4065 sc->sc_txdesc_blk[pri].tdb_dmat = sc->sc_dmat; 4066 sc->sc_txdesc_blk[pri].tdb_dmamap = sc->sc_desc_dmamap; 4067 } 4068 4069 rc = bus_dmamap_load(sc->sc_dmat, sc->sc_desc_dmamap, sc->sc_descs, 4070 sizeof(struct rtw_descs), NULL, 0); 4071 4072 if (rc != 0) { 4073 printf("%s: could not load DMA map for hw descriptors, " 4074 "error %d\n", sc->sc_dev.dv_xname, rc); 4075 goto err; 4076 } 4077 NEXT_ATTACH_STATE(sc, FINISH_DESCMAP_LOAD); 4078 4079 if (rtw_txsoft_blk_setup_all(sc) != 0) 4080 goto err; 4081 NEXT_ATTACH_STATE(sc, FINISH_TXCTLBLK_SETUP); 4082 4083 rtw_txdesc_blk_setup_all(sc); 4084 4085 NEXT_ATTACH_STATE(sc, FINISH_TXDESCBLK_SETUP); 4086 4087 sc->sc_rxdesc_blk.rdb_desc = &sc->sc_descs->hd_rx[0]; 4088 4089 for (pri = 0; pri < RTW_NTXPRI; pri++) { 4090 tsb = &sc->sc_txsoft_blk[pri]; 4091 4092 if ((rc = rtw_txdesc_dmamaps_create(sc->sc_dmat, 4093 &tsb->tsb_desc[0], tsb->tsb_ndesc)) != 0) { 4094 printf("%s: could not load DMA map for " 4095 "hw tx descriptors, error %d\n", 4096 sc->sc_dev.dv_xname, rc); 4097 goto err; 4098 } 4099 } 4100 4101 NEXT_ATTACH_STATE(sc, FINISH_TXMAPS_CREATE); 4102 if ((rc = rtw_rxdesc_dmamaps_create(sc->sc_dmat, &sc->sc_rxsoft[0], 4103 RTW_RXQLEN)) != 0) { 4104 printf("%s: could not load DMA map for hw rx descriptors, " 4105 "error %d\n", sc->sc_dev.dv_xname, rc); 4106 goto err; 4107 } 4108 NEXT_ATTACH_STATE(sc, FINISH_RXMAPS_CREATE); 4109 4110 /* Reset the chip to a known state. */ 4111 if (rtw_reset(sc) != 0) 4112 goto err; 4113 NEXT_ATTACH_STATE(sc, FINISH_RESET); 4114 4115 sc->sc_rcr = RTW_READ(&sc->sc_regs, RTW_RCR); 4116 4117 if ((sc->sc_rcr & RTW_RCR_9356SEL) != 0) 4118 sc->sc_flags |= RTW_F_9356SROM; 4119 4120 if (rtw_srom_read(&sc->sc_regs, sc->sc_flags, &sc->sc_srom, 4121 sc->sc_dev.dv_xname) != 0) 4122 goto err; 4123 4124 NEXT_ATTACH_STATE(sc, FINISH_READ_SROM); 4125 4126 if (rtw_srom_parse(&sc->sc_srom, &sc->sc_flags, &sc->sc_csthr, 4127 &sc->sc_rfchipid, &sc->sc_rcr, &sc->sc_locale, 4128 sc->sc_dev.dv_xname) != 0) { 4129 printf("%s: attach failed, malformed serial ROM\n", 4130 sc->sc_dev.dv_xname); 4131 goto err; 4132 } 4133 4134 printf("%s: %s PHY\n", sc->sc_dev.dv_xname, 4135 ((sc->sc_flags & RTW_F_DIGPHY) != 0) ? "digital" : "analog"); 4136 4137 printf("%s: CS threshold %u\n", sc->sc_dev.dv_xname, sc->sc_csthr); 4138 4139 NEXT_ATTACH_STATE(sc, FINISH_PARSE_SROM); 4140 4141 sc->sc_rf = rtw_rf_attach(sc, sc->sc_rfchipid, 4142 sc->sc_flags & RTW_F_DIGPHY); 4143 4144 if (sc->sc_rf == NULL) { 4145 printf("%s: attach failed, could not attach RF\n", 4146 sc->sc_dev.dv_xname); 4147 goto err; 4148 } 4149 4150 NEXT_ATTACH_STATE(sc, FINISH_RF_ATTACH); 4151 4152 sc->sc_phydelay = rtw_check_phydelay(&sc->sc_regs, sc->sc_rcr); 4153 4154 RTW_DPRINTF(RTW_DEBUG_ATTACH, 4155 ("%s: PHY delay %d\n", sc->sc_dev.dv_xname, sc->sc_phydelay)); 4156 4157 if (sc->sc_locale == RTW_LOCALE_UNKNOWN) 4158 rtw_identify_country(&sc->sc_regs, &sc->sc_locale); 4159 4160 rtw_init_channels(sc->sc_locale, &sc->sc_ic.ic_channels, 4161 sc->sc_dev.dv_xname); 4162 4163 if (rtw_identify_sta(&sc->sc_regs, &sc->sc_ic.ic_myaddr, 4164 sc->sc_dev.dv_xname) != 0) 4165 goto err; 4166 NEXT_ATTACH_STATE(sc, FINISH_ID_STA); 4167 4168 rtw_setifprops(ifp, sc->sc_dev.dv_xname, (void*)sc); 4169 4170 IFQ_SET_READY(&ifp->if_snd); 4171 4172 sc->sc_ic.ic_ifp = ifp; 4173 rtw_set80211props(&sc->sc_ic); 4174 4175 rtw_led_attach(&sc->sc_led_state, (void *)sc); 4176 4177 /* 4178 * Call MI attach routines. 4179 */ 4180 if_attach(ifp); 4181 ieee80211_ifattach(&sc->sc_ic); 4182 4183 rtw_set80211methods(&sc->sc_mtbl, &sc->sc_ic); 4184 4185 /* possibly we should fill in our own sc_send_prresp, since 4186 * the RTL8180 is probably sending probe responses in ad hoc 4187 * mode. 4188 */ 4189 4190 /* complete initialization */ 4191 ieee80211_media_init(&sc->sc_ic, rtw_media_change, rtw_media_status); 4192 callout_init(&sc->sc_scan_ch); 4193 4194 rtw_init_radiotap(sc); 4195 4196#if NBPFILTER > 0 4197 bpfattach2(ifp, DLT_IEEE802_11_RADIO, 4198 sizeof(struct ieee80211_frame) + 64, &sc->sc_radiobpf); 4199#endif 4200 4201 rtw_establish_hooks(&sc->sc_hooks, sc->sc_dev.dv_xname, (void*)sc); 4202 4203 NEXT_ATTACH_STATE(sc, FINISHED); 4204 4205 ieee80211_announce(ic); 4206 return; 4207err: 4208 rtw_detach(sc); 4209 return; 4210} 4211 4212int 4213rtw_detach(struct rtw_softc *sc) 4214{ 4215 struct ifnet *ifp = &sc->sc_if; 4216 int pri; 4217 4218 sc->sc_flags |= RTW_F_INVALID; 4219 4220 switch (sc->sc_attach_state) { 4221 case FINISHED: 4222 rtw_stop(ifp, 1); 4223 4224 rtw_disestablish_hooks(&sc->sc_hooks, sc->sc_dev.dv_xname, 4225 (void*)sc); 4226 callout_stop(&sc->sc_scan_ch); 4227 ieee80211_ifdetach(&sc->sc_ic); 4228 if_detach(ifp); 4229 break; 4230 case FINISH_ID_STA: 4231 case FINISH_RF_ATTACH: 4232 rtw_rf_destroy(sc->sc_rf); 4233 sc->sc_rf = NULL; 4234 /*FALLTHROUGH*/ 4235 case FINISH_PARSE_SROM: 4236 case FINISH_READ_SROM: 4237 rtw_srom_free(&sc->sc_srom); 4238 /*FALLTHROUGH*/ 4239 case FINISH_RESET: 4240 case FINISH_RXMAPS_CREATE: 4241 rtw_rxdesc_dmamaps_destroy(sc->sc_dmat, &sc->sc_rxsoft[0], 4242 RTW_RXQLEN); 4243 /*FALLTHROUGH*/ 4244 case FINISH_TXMAPS_CREATE: 4245 for (pri = 0; pri < RTW_NTXPRI; pri++) { 4246 rtw_txdesc_dmamaps_destroy(sc->sc_dmat, 4247 sc->sc_txsoft_blk[pri].tsb_desc, 4248 sc->sc_txsoft_blk[pri].tsb_ndesc); 4249 } 4250 /*FALLTHROUGH*/ 4251 case FINISH_TXDESCBLK_SETUP: 4252 case FINISH_TXCTLBLK_SETUP: 4253 rtw_txsoft_blk_cleanup_all(sc); 4254 /*FALLTHROUGH*/ 4255 case FINISH_DESCMAP_LOAD: 4256 bus_dmamap_unload(sc->sc_dmat, sc->sc_desc_dmamap); 4257 /*FALLTHROUGH*/ 4258 case FINISH_DESCMAP_CREATE: 4259 bus_dmamap_destroy(sc->sc_dmat, sc->sc_desc_dmamap); 4260 /*FALLTHROUGH*/ 4261 case FINISH_DESC_MAP: 4262 bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_descs, 4263 sizeof(struct rtw_descs)); 4264 /*FALLTHROUGH*/ 4265 case FINISH_DESC_ALLOC: 4266 bus_dmamem_free(sc->sc_dmat, &sc->sc_desc_segs, 4267 sc->sc_desc_nsegs); 4268 /*FALLTHROUGH*/ 4269 case DETACHED: 4270 NEXT_ATTACH_STATE(sc, DETACHED); 4271 break; 4272 } 4273 return 0; 4274} 4275 4276int 4277rtw_activate(struct device *self, enum devact act) 4278{ 4279 struct rtw_softc *sc = (struct rtw_softc *)self; 4280 int rc = 0, s; 4281 4282 s = splnet(); 4283 switch (act) { 4284 case DVACT_ACTIVATE: 4285 rc = EOPNOTSUPP; 4286 break; 4287 4288 case DVACT_DEACTIVATE: 4289 if_deactivate(&sc->sc_if); 4290 break; 4291 } 4292 splx(s); 4293 return rc; 4294} 4295