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