rtw.c revision 1.1
1/* $NetBSD: rtw.c,v 1.1 2004/09/26 02:29:15 dyoung Exp $ */ 2/*- 3 * Copyright (c) 2004, 2005 David Young. All rights reserved. 4 * 5 * Programmed for NetBSD by David Young. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of David Young may not be used to endorse or promote 16 * products derived from this software without specific prior 17 * written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY David Young ``AS IS'' AND ANY 20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 22 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David 23 * Young BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 25 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 30 * OF SUCH DAMAGE. 31 */ 32/* 33 * Device driver for the Realtek RTL8180 802.11 MAC/BBP. 34 */ 35 36#include <sys/cdefs.h> 37__KERNEL_RCSID(0, "$NetBSD: rtw.c,v 1.1 2004/09/26 02:29:15 dyoung Exp $"); 38 39#include "bpfilter.h" 40 41#include <sys/param.h> 42#include <sys/systm.h> 43#include <sys/callout.h> 44#include <sys/mbuf.h> 45#include <sys/malloc.h> 46#include <sys/kernel.h> 47#if 0 48#include <sys/socket.h> 49#include <sys/ioctl.h> 50#include <sys/errno.h> 51#include <sys/device.h> 52#endif 53#include <sys/time.h> 54#include <sys/types.h> 55 56#include <machine/endian.h> 57#include <machine/bus.h> 58#include <machine/intr.h> /* splnet */ 59 60#include <uvm/uvm_extern.h> 61 62#include <net/if.h> 63#include <net/if_media.h> 64#include <net/if_ether.h> 65 66#include <net80211/ieee80211_var.h> 67#include <net80211/ieee80211_compat.h> 68#include <net80211/ieee80211_radiotap.h> 69 70#if NBPFILTER > 0 71#include <net/bpf.h> 72#endif 73 74#include <dev/ic/rtwreg.h> 75#include <dev/ic/rtwvar.h> 76#include <dev/ic/rtwphyio.h> 77#include <dev/ic/rtwphy.h> 78 79#include <dev/ic/smc93cx6var.h> 80 81#define KASSERT2(__cond, __msg) \ 82 do { \ 83 if (!(__cond)) \ 84 panic __msg ; \ 85 } while (0) 86 87#ifdef RTW_DEBUG 88int rtw_debug = 2; 89#endif /* RTW_DEBUG */ 90 91#define NEXT_ATTACH_STATE(sc, state) do { \ 92 DPRINTF(sc, ("%s: attach state %s\n", __func__, #state)); \ 93 sc->sc_attach_state = state; \ 94} while (0) 95 96int rtw_dwelltime = 1000; /* milliseconds */ 97 98#ifdef RTW_DEBUG 99static void 100rtw_print_regs(struct rtw_regs *regs, const char *dvname, const char *where) 101{ 102#define PRINTREG32(sc, reg) \ 103 RTW_DPRINTF2(("%s: reg[ " #reg " / %03x ] = %08x\n", \ 104 dvname, reg, RTW_READ(regs, reg))) 105 106#define PRINTREG16(sc, reg) \ 107 RTW_DPRINTF2(("%s: reg[ " #reg " / %03x ] = %04x\n", \ 108 dvname, reg, RTW_READ16(regs, reg))) 109 110#define PRINTREG8(sc, reg) \ 111 RTW_DPRINTF2(("%s: reg[ " #reg " / %03x ] = %02x\n", \ 112 dvname, reg, RTW_READ8(regs, reg))) 113 114 RTW_DPRINTF2(("%s: %s\n", dvname, where)); 115 116 PRINTREG32(regs, RTW_IDR0); 117 PRINTREG32(regs, RTW_IDR1); 118 PRINTREG32(regs, RTW_MAR0); 119 PRINTREG32(regs, RTW_MAR1); 120 PRINTREG32(regs, RTW_TSFTRL); 121 PRINTREG32(regs, RTW_TSFTRH); 122 PRINTREG32(regs, RTW_TLPDA); 123 PRINTREG32(regs, RTW_TNPDA); 124 PRINTREG32(regs, RTW_THPDA); 125 PRINTREG32(regs, RTW_TCR); 126 PRINTREG32(regs, RTW_RCR); 127 PRINTREG32(regs, RTW_TINT); 128 PRINTREG32(regs, RTW_TBDA); 129 PRINTREG32(regs, RTW_ANAPARM); 130 PRINTREG32(regs, RTW_BB); 131 PRINTREG32(regs, RTW_PHYCFG); 132 PRINTREG32(regs, RTW_WAKEUP0L); 133 PRINTREG32(regs, RTW_WAKEUP0H); 134 PRINTREG32(regs, RTW_WAKEUP1L); 135 PRINTREG32(regs, RTW_WAKEUP1H); 136 PRINTREG32(regs, RTW_WAKEUP2LL); 137 PRINTREG32(regs, RTW_WAKEUP2LH); 138 PRINTREG32(regs, RTW_WAKEUP2HL); 139 PRINTREG32(regs, RTW_WAKEUP2HH); 140 PRINTREG32(regs, RTW_WAKEUP3LL); 141 PRINTREG32(regs, RTW_WAKEUP3LH); 142 PRINTREG32(regs, RTW_WAKEUP3HL); 143 PRINTREG32(regs, RTW_WAKEUP3HH); 144 PRINTREG32(regs, RTW_WAKEUP4LL); 145 PRINTREG32(regs, RTW_WAKEUP4LH); 146 PRINTREG32(regs, RTW_WAKEUP4HL); 147 PRINTREG32(regs, RTW_WAKEUP4HH); 148 PRINTREG32(regs, RTW_DK0); 149 PRINTREG32(regs, RTW_DK1); 150 PRINTREG32(regs, RTW_DK2); 151 PRINTREG32(regs, RTW_DK3); 152 PRINTREG32(regs, RTW_RETRYCTR); 153 PRINTREG32(regs, RTW_RDSAR); 154 PRINTREG32(regs, RTW_FER); 155 PRINTREG32(regs, RTW_FEMR); 156 PRINTREG32(regs, RTW_FPSR); 157 PRINTREG32(regs, RTW_FFER); 158 159 /* 16-bit registers */ 160 PRINTREG16(regs, RTW_BRSR); 161 PRINTREG16(regs, RTW_IMR); 162 PRINTREG16(regs, RTW_ISR); 163 PRINTREG16(regs, RTW_BCNITV); 164 PRINTREG16(regs, RTW_ATIMWND); 165 PRINTREG16(regs, RTW_BINTRITV); 166 PRINTREG16(regs, RTW_ATIMTRITV); 167 PRINTREG16(regs, RTW_CRC16ERR); 168 PRINTREG16(regs, RTW_CRC0); 169 PRINTREG16(regs, RTW_CRC1); 170 PRINTREG16(regs, RTW_CRC2); 171 PRINTREG16(regs, RTW_CRC3); 172 PRINTREG16(regs, RTW_CRC4); 173 PRINTREG16(regs, RTW_CWR); 174 175 /* 8-bit registers */ 176 PRINTREG8(regs, RTW_CR); 177 PRINTREG8(regs, RTW_9346CR); 178 PRINTREG8(regs, RTW_CONFIG0); 179 PRINTREG8(regs, RTW_CONFIG1); 180 PRINTREG8(regs, RTW_CONFIG2); 181 PRINTREG8(regs, RTW_MSR); 182 PRINTREG8(regs, RTW_CONFIG3); 183 PRINTREG8(regs, RTW_CONFIG4); 184 PRINTREG8(regs, RTW_TESTR); 185 PRINTREG8(regs, RTW_PSR); 186 PRINTREG8(regs, RTW_SCR); 187 PRINTREG8(regs, RTW_PHYDELAY); 188 PRINTREG8(regs, RTW_CRCOUNT); 189 PRINTREG8(regs, RTW_PHYADDR); 190 PRINTREG8(regs, RTW_PHYDATAW); 191 PRINTREG8(regs, RTW_PHYDATAR); 192 PRINTREG8(regs, RTW_CONFIG5); 193 PRINTREG8(regs, RTW_TPPOLL); 194 195 PRINTREG16(regs, RTW_BSSID16); 196 PRINTREG32(regs, RTW_BSSID32); 197#undef PRINTREG32 198#undef PRINTREG16 199#undef PRINTREG8 200} 201#endif /* RTW_DEBUG */ 202 203void 204rtw_continuous_tx_enable(struct rtw_regs *regs, int enable) 205{ 206 u_int32_t tcr; 207 tcr = RTW_READ(regs, RTW_TCR); 208 tcr &= ~RTW_TCR_LBK_MASK; 209 if (enable) 210 tcr |= RTW_TCR_LBK_CONT; 211 else 212 tcr |= RTW_TCR_LBK_NORMAL; 213 RTW_WRITE(regs, RTW_TCR, tcr); 214 RTW_SYNC(regs, RTW_TCR, RTW_TCR); 215 if (enable) { 216 rtw_config0123_enable(regs, 1); 217 rtw_anaparm_enable(regs, 1); 218 rtw_txdac_enable(regs, 0); 219 } else { 220 rtw_txdac_enable(regs, 1); 221 rtw_anaparm_enable(regs, 0); 222 rtw_config0123_enable(regs, 0); 223 } 224} 225 226/* 227 * Enable registers, switch register banks. 228 */ 229void 230rtw_config0123_enable(struct rtw_regs *regs, int enable) 231{ 232 u_int8_t ecr; 233 ecr = RTW_READ8(regs, RTW_9346CR); 234 ecr &= ~(RTW_9346CR_EEM_MASK | RTW_9346CR_EECS | RTW_9346CR_EESK); 235 if (enable) 236 ecr |= RTW_9346CR_EEM_CONFIG; 237 else 238 ecr |= RTW_9346CR_EEM_NORMAL; 239 RTW_WRITE8(regs, RTW_9346CR, ecr); 240 RTW_SYNC(regs, RTW_9346CR, RTW_9346CR); 241} 242 243/* requires rtw_config0123_enable(, 1) */ 244void 245rtw_anaparm_enable(struct rtw_regs *regs, int enable) 246{ 247 u_int8_t cfg3; 248 249 cfg3 = RTW_READ8(regs, RTW_CONFIG3); 250 cfg3 |= RTW_CONFIG3_PARMEN | RTW_CONFIG3_CLKRUNEN; 251 if (!enable) 252 cfg3 &= ~RTW_CONFIG3_PARMEN; 253 RTW_WRITE8(regs, RTW_CONFIG3, cfg3); 254 RTW_SYNC(regs, RTW_CONFIG3, RTW_CONFIG3); 255} 256 257/* requires rtw_anaparm_enable(, 1) */ 258void 259rtw_txdac_enable(struct rtw_regs *regs, int enable) 260{ 261 u_int32_t anaparm; 262 263 anaparm = RTW_READ(regs, RTW_ANAPARM); 264 if (enable) 265 anaparm &= ~RTW_ANAPARM_TXDACOFF; 266 else 267 anaparm |= RTW_ANAPARM_TXDACOFF; 268 RTW_WRITE(regs, RTW_ANAPARM, anaparm); 269 RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM); 270} 271 272static __inline int 273rtw_chip_reset(struct rtw_regs *regs, char (*dvname)[IFNAMSIZ]) 274{ 275 int i; 276 u_int8_t cr; 277 uint32_t tcr; 278 279 /* from Linux driver */ 280 tcr = RTW_TCR_CWMIN | RTW_TCR_MXDMA_2048 | 281 LSHIFT(7, RTW_TCR_SRL_MASK) | LSHIFT(7, RTW_TCR_LRL_MASK); 282 283 RTW_WRITE(regs, RTW_TCR, tcr); 284 285 RTW_WBW(regs, RTW_CR, RTW_TCR); 286 287 RTW_WRITE8(regs, RTW_CR, RTW_CR_RST); 288 289 RTW_WBR(regs, RTW_CR, RTW_CR); 290 291 for (i = 0; i < 10000; i++) { 292 if ((cr = RTW_READ8(regs, RTW_CR) & RTW_CR_RST) == 0) { 293 RTW_DPRINTF(("%s: reset in %dus\n", *dvname, i)); 294 return 0; 295 } 296 RTW_RBR(regs, RTW_CR, RTW_CR); 297 DELAY(1); /* 1us */ 298 } 299 300 printf("%s: reset failed\n", *dvname); 301 return ETIMEDOUT; 302} 303 304static __inline int 305rtw_recall_eeprom(struct rtw_regs *regs, char (*dvname)[IFNAMSIZ]) 306{ 307 int i; 308 u_int8_t ecr; 309 310 ecr = RTW_READ8(regs, RTW_9346CR); 311 ecr = (ecr & ~RTW_9346CR_EEM_MASK) | RTW_9346CR_EEM_AUTOLOAD; 312 RTW_WRITE8(regs, RTW_9346CR, ecr); 313 314 RTW_WBR(regs, RTW_9346CR, RTW_9346CR); 315 316 /* wait 2.5ms for completion */ 317 for (i = 0; i < 25; i++) { 318 ecr = RTW_READ8(regs, RTW_9346CR); 319 if ((ecr & RTW_9346CR_EEM_MASK) == RTW_9346CR_EEM_NORMAL) { 320 RTW_DPRINTF(("%s: recall EEPROM in %dus\n", *dvname, 321 i * 100)); 322 return 0; 323 } 324 RTW_RBR(regs, RTW_9346CR, RTW_9346CR); 325 DELAY(100); 326 } 327 printf("%s: recall EEPROM failed\n", *dvname); 328 return ETIMEDOUT; 329} 330 331static __inline int 332rtw_reset(struct rtw_softc *sc) 333{ 334 int rc; 335 uint32_t config1; 336 337 if ((rc = rtw_chip_reset(&sc->sc_regs, &sc->sc_dev.dv_xname)) != 0) 338 return rc; 339 340 if ((rc = rtw_recall_eeprom(&sc->sc_regs, &sc->sc_dev.dv_xname)) != 0) 341 ; 342 343 config1 = RTW_READ(&sc->sc_regs, RTW_CONFIG1); 344 RTW_WRITE(&sc->sc_regs, RTW_CONFIG1, config1 & ~RTW_CONFIG1_PMEN); 345 /* TBD turn off maximum power saving? */ 346 347 return 0; 348} 349 350static __inline int 351rtw_txdesc_dmamaps_create(bus_dma_tag_t dmat, struct rtw_txctl *descs, 352 u_int ndescs) 353{ 354 int i, rc = 0; 355 for (i = 0; i < ndescs; i++) { 356 rc = bus_dmamap_create(dmat, MCLBYTES, RTW_MAXPKTSEGS, MCLBYTES, 357 0, 0, &descs[i].stx_dmamap); 358 if (rc != 0) 359 break; 360 } 361 return rc; 362} 363 364static __inline int 365rtw_rxdesc_dmamaps_create(bus_dma_tag_t dmat, struct rtw_rxctl *descs, 366 u_int ndescs) 367{ 368 int i, rc = 0; 369 for (i = 0; i < ndescs; i++) { 370 rc = bus_dmamap_create(dmat, MCLBYTES, 1, MCLBYTES, 0, 0, 371 &descs[i].srx_dmamap); 372 if (rc != 0) 373 break; 374 } 375 return rc; 376} 377 378static __inline void 379rtw_rxctls_setup(struct rtw_rxctl (*descs)[RTW_RXQLEN]) 380{ 381 int i; 382 for (i = 0; i < RTW_RXQLEN; i++) 383 (*descs)[i].srx_mbuf = NULL; 384} 385 386static __inline void 387rtw_rxdesc_dmamaps_destroy(bus_dma_tag_t dmat, struct rtw_rxctl *descs, 388 u_int ndescs) 389{ 390 int i; 391 for (i = 0; i < ndescs; i++) { 392 if (descs[i].srx_dmamap != NULL) 393 bus_dmamap_destroy(dmat, descs[i].srx_dmamap); 394 } 395} 396 397static __inline void 398rtw_txdesc_dmamaps_destroy(bus_dma_tag_t dmat, struct rtw_txctl *descs, 399 u_int ndescs) 400{ 401 int i; 402 for (i = 0; i < ndescs; i++) { 403 if (descs[i].stx_dmamap != NULL) 404 bus_dmamap_destroy(dmat, descs[i].stx_dmamap); 405 } 406} 407 408static __inline void 409rtw_srom_free(struct rtw_srom *sr) 410{ 411 sr->sr_size = 0; 412 if (sr->sr_content == NULL) 413 return; 414 free(sr->sr_content, M_DEVBUF); 415 sr->sr_content = NULL; 416} 417 418static void 419rtw_srom_defaults(struct rtw_srom *sr, u_int32_t *flags, u_int8_t *cs_threshold, 420 enum rtw_rfchipid *rfchipid, u_int32_t *rcr, char (*dvname)[IFNAMSIZ]) 421{ 422 *flags |= (RTW_F_DIGPHY|RTW_F_ANTDIV); 423 *cs_threshold = RTW_SR_ENERGYDETTHR_DEFAULT; 424 *rcr |= RTW_RCR_ENCS1; 425 *rfchipid = RTW_RFCHIPID_PHILIPS; 426} 427 428static int 429rtw_srom_parse(struct rtw_srom *sr, u_int32_t *flags, u_int8_t *cs_threshold, 430 enum rtw_rfchipid *rfchipid, u_int32_t *rcr, enum rtw_locale *locale, 431 char (*dvname)[IFNAMSIZ]) 432{ 433 int i; 434 const char *rfname, *paname; 435 char scratch[sizeof("unknown 0xXX")]; 436 u_int16_t version; 437 u_int8_t mac[IEEE80211_ADDR_LEN]; 438 439 *flags &= ~(RTW_F_DIGPHY|RTW_F_DFLANTB|RTW_F_ANTDIV); 440 *rcr &= ~(RTW_RCR_ENCS1 | RTW_RCR_ENCS2); 441 442 version = RTW_SR_GET16(sr, RTW_SR_VERSION); 443 printf("%s: SROM version %d.%d", *dvname, version >> 8, version & 0xff); 444 445 if (version <= 0x0101) { 446 printf(" is not understood, limping along with defaults\n"); 447 rtw_srom_defaults(sr, flags, cs_threshold, rfchipid, rcr, 448 dvname); 449 return 0; 450 } 451 printf("\n"); 452 453 for (i = 0; i < IEEE80211_ADDR_LEN; i++) 454 mac[i] = RTW_SR_GET(sr, RTW_SR_MAC + i); 455 456 RTW_DPRINTF(("%s: EEPROM MAC %s\n", *dvname, ether_sprintf(mac))); 457 458 *cs_threshold = RTW_SR_GET(sr, RTW_SR_ENERGYDETTHR); 459 460 if ((RTW_SR_GET(sr, RTW_SR_CONFIG2) & RTW_CONFIG2_ANT) != 0) 461 *flags |= RTW_F_ANTDIV; 462 463 if ((RTW_SR_GET(sr, RTW_SR_RFPARM) & RTW_SR_RFPARM_DIGPHY) != 0) 464 *flags |= RTW_F_DIGPHY; 465 if ((RTW_SR_GET(sr, RTW_SR_RFPARM) & RTW_SR_RFPARM_DFLANTB) != 0) 466 *flags |= RTW_F_DFLANTB; 467 468 *rcr |= LSHIFT(MASK_AND_RSHIFT(RTW_SR_GET(sr, RTW_SR_RFPARM), 469 RTW_SR_RFPARM_CS_MASK), RTW_RCR_ENCS1); 470 471 *rfchipid = RTW_SR_GET(sr, RTW_SR_RFCHIPID); 472 switch (*rfchipid) { 473 case RTW_RFCHIPID_GCT: /* this combo seen in the wild */ 474 rfname = "GCT GRF5101"; 475 paname = "Winspring WS9901"; 476 break; 477 case RTW_RFCHIPID_MAXIM: 478 rfname = "Maxim MAX2820"; /* guess */ 479 paname = "Maxim MAX2422"; /* guess */ 480 break; 481 case RTW_RFCHIPID_INTERSIL: 482 rfname = "Intersil HFA3873"; /* guess */ 483 paname = "Intersil <unknown>"; 484 break; 485 case RTW_RFCHIPID_PHILIPS: /* this combo seen in the wild */ 486 rfname = "Philips SA2400A"; 487 paname = "Philips SA2411"; 488 break; 489 case RTW_RFCHIPID_RFMD: 490 /* this is the same front-end as an atw(4)! */ 491 rfname = "RFMD RF2948B, " /* mentioned in Realtek docs */ 492 "LNA: RFMD RF2494, " /* mentioned in Realtek docs */ 493 "SYN: Silicon Labs Si4126"; /* inferred from 494 * reference driver 495 */ 496 paname = "RFMD RF2189"; /* mentioned in Realtek docs */ 497 break; 498 case RTW_RFCHIPID_RESERVED: 499 rfname = paname = "reserved"; 500 break; 501 default: 502 snprintf(scratch, sizeof(scratch), "unknown 0x%02x", *rfchipid); 503 rfname = paname = scratch; 504 } 505 printf("%s: RF: %s, PA: %s\n", *dvname, rfname, paname); 506 507 switch (RTW_SR_GET(sr, RTW_SR_CONFIG0) & RTW_CONFIG0_GL_MASK) { 508 case RTW_CONFIG0_GL_USA: 509 *locale = RTW_LOCALE_USA; 510 break; 511 case RTW_CONFIG0_GL_EUROPE: 512 *locale = RTW_LOCALE_EUROPE; 513 break; 514 case RTW_CONFIG0_GL_JAPAN: 515 *locale = RTW_LOCALE_JAPAN; 516 break; 517 default: 518 *locale = RTW_LOCALE_UNKNOWN; 519 break; 520 } 521 return 0; 522} 523 524/* Returns -1 on failure. */ 525static int 526rtw_srom_read(struct rtw_regs *regs, u_int32_t flags, struct rtw_srom *sr, 527 char (*dvname)[IFNAMSIZ]) 528{ 529 int rc; 530 struct seeprom_descriptor sd; 531 u_int8_t ecr; 532 533 (void)memset(&sd, 0, sizeof(sd)); 534 535 ecr = RTW_READ8(regs, RTW_9346CR); 536 537 if ((flags & RTW_F_9356SROM) != 0) { 538 RTW_DPRINTF(("%s: 93c56 SROM\n", *dvname)); 539 sr->sr_size = 256; 540 sd.sd_chip = C56_66; 541 } else { 542 RTW_DPRINTF(("%s: 93c46 SROM\n", *dvname)); 543 sr->sr_size = 128; 544 sd.sd_chip = C46; 545 } 546 547 ecr &= ~(RTW_9346CR_EEDI | RTW_9346CR_EEDO | RTW_9346CR_EESK | 548 RTW_9346CR_EEM_MASK); 549 ecr |= RTW_9346CR_EEM_PROGRAM; 550 551 RTW_WRITE8(regs, RTW_9346CR, ecr); 552 553 sr->sr_content = malloc(sr->sr_size, M_DEVBUF, M_NOWAIT); 554 555 if (sr->sr_content == NULL) { 556 printf("%s: unable to allocate SROM buffer\n", *dvname); 557 return ENOMEM; 558 } 559 560 (void)memset(sr->sr_content, 0, sr->sr_size); 561 562 /* RTL8180 has a single 8-bit register for controlling the 563 * 93cx6 SROM. There is no "ready" bit. The RTL8180 564 * input/output sense is the reverse of read_seeprom's. 565 */ 566 sd.sd_tag = regs->r_bt; 567 sd.sd_bsh = regs->r_bh; 568 sd.sd_regsize = 1; 569 sd.sd_control_offset = RTW_9346CR; 570 sd.sd_status_offset = RTW_9346CR; 571 sd.sd_dataout_offset = RTW_9346CR; 572 sd.sd_CK = RTW_9346CR_EESK; 573 sd.sd_CS = RTW_9346CR_EECS; 574 sd.sd_DI = RTW_9346CR_EEDO; 575 sd.sd_DO = RTW_9346CR_EEDI; 576 /* make read_seeprom enter EEPROM read/write mode */ 577 sd.sd_MS = ecr; 578 sd.sd_RDY = 0; 579#if 0 580 sd.sd_clkdelay = 50; 581#endif 582 583 if (!read_seeprom(&sd, sr->sr_content, 0, sr->sr_size/2)) { 584 printf("%s: could not read SROM\n", *dvname); 585 free(sr->sr_content, M_DEVBUF); 586 sr->sr_content = NULL; 587 return -1; /* XXX */ 588 } 589 590 /* end EEPROM read/write mode */ 591 RTW_WRITE8(regs, RTW_9346CR, 592 (ecr & ~RTW_9346CR_EEM_MASK) | RTW_9346CR_EEM_NORMAL); 593 RTW_WBRW(regs, RTW_9346CR, RTW_9346CR); 594 595 if ((rc = rtw_recall_eeprom(regs, dvname)) != 0) 596 return rc; 597 598#ifdef RTW_DEBUG 599 { 600 int i; 601 RTW_DPRINTF(("\n%s: serial ROM:\n\t", *dvname)); 602 for (i = 0; i < sr->sr_size/2; i++) { 603 if (((i % 8) == 0) && (i != 0)) 604 RTW_DPRINTF(("\n\t")); 605 RTW_DPRINTF((" %04x", sr->sr_content[i])); 606 } 607 RTW_DPRINTF(("\n")); 608 } 609#endif /* RTW_DEBUG */ 610 return 0; 611} 612 613#if 0 614static __inline int 615rtw_identify_rf(struct rtw_regs *regs, enum rtw_rftype *rftype, 616 char (*dvname)[IFNAMSIZ]) 617{ 618 u_int8_t cfg4; 619 const char *name; 620 621 cfg4 = RTW_READ8(regs, RTW_CONFIG4); 622 623 switch (cfg4 & RTW_CONFIG4_RFTYPE_MASK) { 624 case RTW_CONFIG4_RFTYPE_PHILIPS: 625 *rftype = RTW_RFTYPE_PHILIPS; 626 name = "Philips"; 627 break; 628 case RTW_CONFIG4_RFTYPE_INTERSIL: 629 *rftype = RTW_RFTYPE_INTERSIL; 630 name = "Intersil"; 631 break; 632 case RTW_CONFIG4_RFTYPE_RFMD: 633 *rftype = RTW_RFTYPE_RFMD; 634 name = "RFMD"; 635 break; 636 default: 637 name = "<unknown>"; 638 return ENXIO; 639 } 640 641 printf("%s: RF prog type %s\n", *dvname, name); 642 return 0; 643} 644#endif 645 646static __inline void 647rtw_init_channels(enum rtw_locale locale, 648 struct ieee80211_channel (*chans)[IEEE80211_CHAN_MAX+1], 649 char (*dvname)[IFNAMSIZ]) 650{ 651 int i; 652 const char *name = NULL; 653#define ADD_CHANNEL(_chans, _chan) do { \ 654 (*_chans)[_chan].ic_flags = IEEE80211_CHAN_B; \ 655 (*_chans)[_chan].ic_freq = \ 656 ieee80211_ieee2mhz(_chan, (*_chans)[_chan].ic_flags);\ 657} while (0) 658 659 switch (locale) { 660 case RTW_LOCALE_USA: /* 1-11 */ 661 name = "USA"; 662 for (i = 1; i <= 11; i++) 663 ADD_CHANNEL(chans, i); 664 break; 665 case RTW_LOCALE_JAPAN: /* 1-14 */ 666 name = "Japan"; 667 ADD_CHANNEL(chans, 14); 668 for (i = 1; i <= 14; i++) 669 ADD_CHANNEL(chans, i); 670 break; 671 case RTW_LOCALE_EUROPE: /* 1-13 */ 672 name = "Europe"; 673 for (i = 1; i <= 13; i++) 674 ADD_CHANNEL(chans, i); 675 break; 676 default: /* 10-11 allowed by most countries */ 677 name = "<unknown>"; 678 for (i = 10; i <= 11; i++) 679 ADD_CHANNEL(chans, i); 680 break; 681 } 682 printf("%s: Geographic Location %s\n", *dvname, name); 683#undef ADD_CHANNEL 684} 685 686static __inline void 687rtw_identify_country(struct rtw_regs *regs, enum rtw_locale *locale, 688 char (*dvname)[IFNAMSIZ]) 689{ 690 u_int8_t cfg0 = RTW_READ8(regs, RTW_CONFIG0); 691 692 switch (cfg0 & RTW_CONFIG0_GL_MASK) { 693 case RTW_CONFIG0_GL_USA: 694 *locale = RTW_LOCALE_USA; 695 break; 696 case RTW_CONFIG0_GL_JAPAN: 697 *locale = RTW_LOCALE_JAPAN; 698 break; 699 case RTW_CONFIG0_GL_EUROPE: 700 *locale = RTW_LOCALE_EUROPE; 701 break; 702 default: 703 *locale = RTW_LOCALE_UNKNOWN; 704 break; 705 } 706} 707 708static __inline int 709rtw_identify_sta(struct rtw_regs *regs, u_int8_t (*addr)[IEEE80211_ADDR_LEN], 710 char (*dvname)[IFNAMSIZ]) 711{ 712 static const u_int8_t empty_macaddr[IEEE80211_ADDR_LEN] = { 713 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 714 }; 715 u_int32_t idr0 = RTW_READ(regs, RTW_IDR0), 716 idr1 = RTW_READ(regs, RTW_IDR1); 717 718 (*addr)[0] = MASK_AND_RSHIFT(idr0, BITS(0, 7)); 719 (*addr)[1] = MASK_AND_RSHIFT(idr0, BITS(8, 15)); 720 (*addr)[2] = MASK_AND_RSHIFT(idr0, BITS(16, 23)); 721 (*addr)[3] = MASK_AND_RSHIFT(idr0, BITS(24 ,31)); 722 723 (*addr)[4] = MASK_AND_RSHIFT(idr1, BITS(0, 7)); 724 (*addr)[5] = MASK_AND_RSHIFT(idr1, BITS(8, 15)); 725 726 if (IEEE80211_ADDR_EQ(addr, empty_macaddr)) { 727 printf("%s: could not get mac address, attach failed\n", 728 *dvname); 729 return ENXIO; 730 } 731 732 printf("%s: 802.11 address %s\n", *dvname, ether_sprintf(*addr)); 733 734 return 0; 735} 736 737static u_int8_t 738rtw_chan2txpower(struct rtw_srom *sr, struct ieee80211com *ic, 739 struct ieee80211_channel *chan) 740{ 741 u_int idx = RTW_SR_TXPOWER1 + ieee80211_chan2ieee(ic, chan) - 1; 742 KASSERT2(idx >= RTW_SR_TXPOWER1 && idx <= RTW_SR_TXPOWER14, 743 ("%s: channel %d out of range", __func__, 744 idx - RTW_SR_TXPOWER1 + 1)); 745 return RTW_SR_GET(sr, idx); 746} 747 748static void 749rtw_txdesc_blk_init_all(struct rtw_txdesc_blk (*htcs)[RTW_NTXPRI]) 750{ 751 int pri; 752 u_int ndesc[RTW_NTXPRI] = 753 {RTW_NTXDESCLO, RTW_NTXDESCMD, RTW_NTXDESCHI, RTW_NTXDESCBCN}; 754 755 for (pri = 0; pri < RTW_NTXPRI; pri++) { 756 (*htcs)[pri].htc_nfree = ndesc[pri]; 757 (*htcs)[pri].htc_next = 0; 758 } 759} 760 761static int 762rtw_txctl_blk_init(struct rtw_txctl_blk *stc) 763{ 764 int i; 765 struct rtw_txctl *stx; 766 767 SIMPLEQ_INIT(&stc->stc_dirtyq); 768 SIMPLEQ_INIT(&stc->stc_freeq); 769 for (i = 0; i < stc->stc_ndesc; i++) { 770 stx = &stc->stc_desc[i]; 771 stx->stx_mbuf = NULL; 772 SIMPLEQ_INSERT_TAIL(&stc->stc_freeq, stx, stx_q); 773 } 774 return 0; 775} 776 777static void 778rtw_txctl_blk_init_all(struct rtw_txctl_blk (*stcs)[RTW_NTXPRI]) 779{ 780 int pri; 781 for (pri = 0; pri < RTW_NTXPRI; pri++) { 782 rtw_txctl_blk_init(&(*stcs)[pri]); 783 } 784} 785 786static __inline void 787rtw_rxdescs_sync(bus_dma_tag_t dmat, bus_dmamap_t dmap, u_int desc0, u_int 788 nsync, int ops) 789{ 790 /* sync to end of ring */ 791 if (desc0 + nsync > RTW_NRXDESC) { 792 bus_dmamap_sync(dmat, dmap, 793 offsetof(struct rtw_descs, hd_rx[desc0]), 794 sizeof(struct rtw_rxdesc) * (RTW_NRXDESC - desc0), ops); 795 nsync -= (RTW_NRXDESC - desc0); 796 desc0 = 0; 797 } 798 799 /* sync what remains */ 800 bus_dmamap_sync(dmat, dmap, 801 offsetof(struct rtw_descs, hd_rx[desc0]), 802 sizeof(struct rtw_rxdesc) * nsync, ops); 803} 804 805static void 806rtw_txdescs_sync(bus_dma_tag_t dmat, bus_dmamap_t dmap, 807 struct rtw_txdesc_blk *htc, u_int desc0, u_int nsync, int ops) 808{ 809 /* sync to end of ring */ 810 if (desc0 + nsync > htc->htc_ndesc) { 811 bus_dmamap_sync(dmat, dmap, 812 htc->htc_ofs + sizeof(struct rtw_txdesc) * desc0, 813 sizeof(struct rtw_txdesc) * (htc->htc_ndesc - desc0), 814 ops); 815 nsync -= (htc->htc_ndesc - desc0); 816 desc0 = 0; 817 } 818 819 /* sync what remains */ 820 bus_dmamap_sync(dmat, dmap, 821 htc->htc_ofs + sizeof(struct rtw_txdesc) * desc0, 822 sizeof(struct rtw_txdesc) * nsync, ops); 823} 824 825static void 826rtw_txdescs_sync_all(bus_dma_tag_t dmat, bus_dmamap_t dmap, 827 struct rtw_txdesc_blk (*htcs)[RTW_NTXPRI]) 828{ 829 int pri; 830 for (pri = 0; pri < RTW_NTXPRI; pri++) { 831 rtw_txdescs_sync(dmat, dmap, 832 &(*htcs)[pri], 0, (*htcs)[pri].htc_ndesc, 833 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 834 } 835} 836 837static void 838rtw_rxbufs_release(bus_dma_tag_t dmat, struct rtw_rxctl *desc) 839{ 840 int i; 841 struct rtw_rxctl *srx; 842 843 for (i = 0; i < RTW_NRXDESC; i++) { 844 srx = &desc[i]; 845 bus_dmamap_unload(dmat, srx->srx_dmamap); 846 m_freem(srx->srx_mbuf); 847 srx->srx_mbuf = NULL; 848 } 849} 850 851static __inline int 852rtw_rxbuf_alloc(bus_dma_tag_t dmat, struct rtw_rxctl *srx) 853{ 854 int rc; 855 struct mbuf *m; 856 857 MGETHDR(m, M_DONTWAIT, MT_DATA); 858 if (m == NULL) 859 return ENOMEM; 860 861 MCLGET(m, M_DONTWAIT); 862 if (m == NULL) 863 return ENOMEM; 864 865 m->m_pkthdr.len = m->m_len = m->m_ext.ext_size; 866 867 rc = bus_dmamap_load_mbuf(dmat, srx->srx_dmamap, m, BUS_DMA_NOWAIT); 868 if (rc != 0) 869 return rc; 870 871 srx->srx_mbuf = m; 872 873 return 0; 874} 875 876static int 877rtw_rxctl_init_all(bus_dma_tag_t dmat, struct rtw_rxctl *desc, 878 u_int *next, char (*dvname)[IFNAMSIZ]) 879{ 880 int i, rc; 881 struct rtw_rxctl *srx; 882 883 for (i = 0; i < RTW_NRXDESC; i++) { 884 srx = &desc[i]; 885 if ((rc = rtw_rxbuf_alloc(dmat, srx)) == 0) 886 continue; 887 printf("%s: failed rtw_rxbuf_alloc after %d buffers, rc = %d\n", 888 *dvname, i, rc); 889 if (i == 0) { 890 rtw_rxbufs_release(dmat, desc); 891 return rc; 892 } 893 } 894 *next = 0; 895 return 0; 896} 897 898static __inline void 899rtw_rxdesc_init(bus_dma_tag_t dmat, bus_dmamap_t dmam, 900 struct rtw_rxdesc *hrx, struct rtw_rxctl *srx, int idx) 901{ 902 int is_last = (idx == RTW_NRXDESC - 1); 903 uint32_t ctl; 904 905 hrx->hrx_buf = htole32(srx->srx_dmamap->dm_segs[0].ds_addr); 906 907 ctl = LSHIFT(srx->srx_mbuf->m_len, RTW_RXCTL_LENGTH_MASK) | 908 RTW_RXCTL_OWN | RTW_RXCTL_FS | RTW_RXCTL_LS; 909 910 if (is_last) 911 ctl |= RTW_RXCTL_EOR; 912 913 hrx->hrx_ctl = htole32(ctl); 914 915 /* sync the mbuf */ 916 bus_dmamap_sync(dmat, srx->srx_dmamap, 0, srx->srx_dmamap->dm_mapsize, 917 BUS_DMASYNC_PREREAD); 918 919 /* sync the descriptor */ 920 bus_dmamap_sync(dmat, dmam, RTW_DESC_OFFSET(hd_rx, idx), 921 sizeof(struct rtw_rxdesc), 922 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 923} 924 925static void 926rtw_rxdesc_init_all(bus_dma_tag_t dmat, bus_dmamap_t dmam, 927 struct rtw_rxdesc *desc, struct rtw_rxctl *ctl) 928{ 929 int i; 930 struct rtw_rxdesc *hrx; 931 struct rtw_rxctl *srx; 932 933 for (i = 0; i < RTW_NRXDESC; i++) { 934 hrx = &desc[i]; 935 srx = &ctl[i]; 936 rtw_rxdesc_init(dmat, dmam, hrx, srx, i); 937 } 938} 939 940static void 941rtw_io_enable(struct rtw_regs *regs, u_int8_t flags, int enable) 942{ 943 u_int8_t cr; 944 945 RTW_DPRINTF(("%s: %s 0x%02x\n", __func__, 946 enable ? "enable" : "disable", flags)); 947 948 cr = RTW_READ8(regs, RTW_CR); 949 950 /* XXX reference source does not enable MULRW */ 951#if 0 952 /* enable PCI Read/Write Multiple */ 953 cr |= RTW_CR_MULRW; 954#endif 955 956 RTW_RBW(regs, RTW_CR, RTW_CR); /* XXX paranoia? */ 957 if (enable) 958 cr |= flags; 959 else 960 cr &= ~flags; 961 RTW_WRITE8(regs, RTW_CR, cr); 962 RTW_SYNC(regs, RTW_CR, RTW_CR); 963} 964 965static void 966rtw_intr_rx(struct rtw_softc *sc, u_int16_t isr) 967{ 968 u_int next; 969 int rate, rssi; 970 u_int32_t hrssi, hstat, htsfth, htsftl; 971 struct rtw_rxdesc *hrx; 972 struct rtw_rxctl *srx; 973 struct mbuf *m; 974 975 struct ieee80211_node *ni; 976 struct ieee80211_frame *wh; 977 978 for (next = sc->sc_rxnext; ; next = (next + 1) % RTW_RXQLEN) { 979 rtw_rxdescs_sync(sc->sc_dmat, sc->sc_desc_dmamap, 980 next, 1, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 981 hrx = &sc->sc_rxdesc[next]; 982 srx = &sc->sc_rxctl[next]; 983 984 hstat = le32toh(hrx->hrx_stat); 985 hrssi = le32toh(hrx->hrx_rssi); 986 htsfth = le32toh(hrx->hrx_tsfth); 987 htsftl = le32toh(hrx->hrx_tsftl); 988 989 RTW_DPRINTF2(("%s: rxdesc[%d] hstat %#08x hrssi %#08x " 990 "htsft %#08x%08x\n", __func__, next, 991 hstat, hrssi, htsfth, htsftl)); 992 993 if ((hstat & RTW_RXSTAT_OWN) != 0) /* belongs to NIC */ 994 break; 995 996 if ((hstat & RTW_RXSTAT_IOERROR) != 0) { 997 printf("%s: DMA error/FIFO overflow %08x, " 998 "rx descriptor %d\n", sc->sc_dev.dv_xname, 999 hstat & RTW_RXSTAT_IOERROR, next); 1000 goto next; 1001 } 1002 1003 switch (hstat & RTW_RXSTAT_RATE_MASK) { 1004 case RTW_RXSTAT_RATE_1MBPS: 1005 rate = 10; 1006 break; 1007 case RTW_RXSTAT_RATE_2MBPS: 1008 rate = 20; 1009 break; 1010 case RTW_RXSTAT_RATE_5MBPS: 1011 rate = 55; 1012 break; 1013 default: 1014#ifdef RTW_DEBUG 1015 if (rtw_debug > 1) 1016 printf("%s: interpreting rate #%d as 11 MB/s\n", 1017 sc->sc_dev.dv_xname, 1018 MASK_AND_RSHIFT(hstat, 1019 RTW_RXSTAT_RATE_MASK)); 1020#endif /* RTW_DEBUG */ 1021 /*FALLTHROUGH*/ 1022 case RTW_RXSTAT_RATE_11MBPS: 1023 rate = 110; 1024 break; 1025 } 1026 1027 RTW_DPRINTF2(("%s: rate %d\n", __func__, rate)); 1028 1029#ifdef RTW_DEBUG 1030#define PRINTSTAT(flag) do { \ 1031 if ((hstat & flag) != 0) { \ 1032 printf("%s" #flag, delim); \ 1033 delim = ","; \ 1034 } \ 1035} while (0) 1036 if (rtw_debug > 1) { 1037 const char *delim = "<"; 1038 printf("%s: ", sc->sc_dev.dv_xname); 1039 if ((hstat & RTW_RXSTAT_DEBUG) != 0) { 1040 printf("status %08x<", hstat); 1041 PRINTSTAT(RTW_RXSTAT_SPLCP); 1042 PRINTSTAT(RTW_RXSTAT_MAR); 1043 PRINTSTAT(RTW_RXSTAT_PAR); 1044 PRINTSTAT(RTW_RXSTAT_BAR); 1045 PRINTSTAT(RTW_RXSTAT_PWRMGT); 1046 PRINTSTAT(RTW_RXSTAT_CRC32); 1047 PRINTSTAT(RTW_RXSTAT_ICV); 1048 printf(">, "); 1049 } 1050 printf("rate %d.%d Mb/s, time %08x%08x\n", 1051 rate / 10, rate % 10, htsfth, htsftl); 1052 } 1053#endif /* RTW_DEBUG */ 1054 1055 if ((hstat & RTW_RXSTAT_RES) != 0 && 1056 sc->sc_ic.ic_opmode != IEEE80211_M_MONITOR) 1057 goto next; 1058 1059 /* if bad flags, skip descriptor */ 1060 if ((hstat & RTW_RXSTAT_ONESEG) != RTW_RXSTAT_ONESEG) { 1061 printf("%s: too many rx segments\n", 1062 sc->sc_dev.dv_xname); 1063 goto next; 1064 } 1065 1066 m = srx->srx_mbuf; 1067 1068 /* if temporarily out of memory, re-use mbuf */ 1069 if (rtw_rxbuf_alloc(sc->sc_dmat, srx) != 0) { 1070 printf("%s: rtw_rxbuf_alloc(, %d) failed, " 1071 "dropping this packet\n", sc->sc_dev.dv_xname, 1072 next); 1073 goto next; 1074 } 1075 1076 if (sc->sc_rfchipid == RTW_RFCHIPID_PHILIPS) 1077 rssi = MASK_AND_RSHIFT(hrssi, RTW_RXRSSI_RSSI); 1078 else { 1079 rssi = MASK_AND_RSHIFT(hrssi, RTW_RXRSSI_IMR_RSSI); 1080 /* TBD find out each front-end's LNA gain in the 1081 * front-end's units 1082 */ 1083 if ((hrssi & RTW_RXRSSI_IMR_LNA) == 0) 1084 rssi |= 0x80; 1085 } 1086 1087 m->m_pkthdr.len = m->m_len = 1088 MASK_AND_RSHIFT(hstat, RTW_RXSTAT_LENGTH_MASK); 1089 m->m_flags |= M_HASFCS; 1090 1091 wh = mtod(m, struct ieee80211_frame *); 1092 /* TBD use _MAR, _BAR, _PAR flags as hints to _find_rxnode? */ 1093 ni = ieee80211_find_rxnode(&sc->sc_ic, wh); 1094 1095 sc->sc_tsfth = htsfth; 1096 1097 ieee80211_input(&sc->sc_if, m, ni, rssi, htsftl); 1098 ieee80211_release_node(&sc->sc_ic, ni); 1099next: 1100 rtw_rxdesc_init(sc->sc_dmat, sc->sc_desc_dmamap, 1101 hrx, srx, next); 1102 } 1103 sc->sc_rxnext = next; 1104 return; 1105} 1106 1107static void 1108rtw_intr_tx(struct rtw_softc *sc, u_int16_t isr) 1109{ 1110 /* TBD */ 1111 return; 1112} 1113 1114static void 1115rtw_intr_beacon(struct rtw_softc *sc, u_int16_t isr) 1116{ 1117 /* TBD */ 1118 return; 1119} 1120 1121static void 1122rtw_intr_atim(struct rtw_softc *sc) 1123{ 1124 /* TBD */ 1125 return; 1126} 1127 1128static void 1129rtw_intr_ioerror(struct rtw_softc *sc, u_int16_t isr) 1130{ 1131 if ((isr & (RTW_INTR_RDU|RTW_INTR_RXFOVW)) != 0) { 1132#if 0 1133 rtw_rxctl_init_all(sc->sc_dmat, sc->sc_rxctl, &sc->sc_rxnext, 1134 &sc->sc_dev.dv_xname); 1135 rtw_rxdesc_init_all(sc->sc_dmat, sc->sc_desc_dmamap, 1136 sc->sc_rxdesc, sc->sc_rxctl); 1137#endif 1138 rtw_io_enable(&sc->sc_regs, RTW_CR_RE, 1); 1139 } 1140 if ((isr & RTW_INTR_TXFOVW) != 0) 1141 ; /* TBD restart transmit engine */ 1142 return; 1143} 1144 1145static __inline void 1146rtw_suspend_ticks(struct rtw_softc *sc) 1147{ 1148 printf("%s: suspending ticks\n", sc->sc_dev.dv_xname); 1149 sc->sc_do_tick = 0; 1150} 1151 1152static __inline void 1153rtw_resume_ticks(struct rtw_softc *sc) 1154{ 1155 int s; 1156 struct timeval tv; 1157 u_int32_t tsftrl0, tsftrl1, next_tick; 1158 1159 tsftrl0 = RTW_READ(&sc->sc_regs, RTW_TSFTRL); 1160 1161 s = splclock(); 1162 timersub(&mono_time, &sc->sc_tick0, &tv); 1163 splx(s); 1164 1165 tsftrl1 = RTW_READ(&sc->sc_regs, RTW_TSFTRL); 1166 next_tick = tsftrl1 + 1000000 - tv.tv_usec; 1167 RTW_WRITE(&sc->sc_regs, RTW_TINT, next_tick); 1168 1169 sc->sc_do_tick = 1; 1170 1171 printf("%s: resume ticks delta %#08x now %#08x next %#08x\n", 1172 sc->sc_dev.dv_xname, tsftrl1 - tsftrl0, tsftrl1, next_tick); 1173} 1174 1175static void 1176rtw_intr_timeout(struct rtw_softc *sc) 1177{ 1178 printf("%s: timeout\n", sc->sc_dev.dv_xname); 1179 if (sc->sc_do_tick) 1180 rtw_resume_ticks(sc); 1181 return; 1182} 1183 1184int 1185rtw_intr(void *arg) 1186{ 1187 struct rtw_softc *sc = arg; 1188 struct rtw_regs *regs = &sc->sc_regs; 1189 u_int16_t isr; 1190 1191#ifdef RTW_DEBUG 1192 if ((sc->sc_flags & RTW_F_ENABLED) == 0) 1193 panic("%s: rtw_intr: not enabled", sc->sc_dev.dv_xname); 1194#endif /* RTW_DEBUG */ 1195 1196 /* 1197 * If the interface isn't running, the interrupt couldn't 1198 * possibly have come from us. 1199 */ 1200 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0 || 1201 (sc->sc_dev.dv_flags & DVF_ACTIVE) == 0) { 1202 RTW_DPRINTF2(("%s: stray interrupt\n", sc->sc_dev.dv_xname)); 1203 return (0); 1204 } 1205 1206 for (;;) { 1207 isr = RTW_READ16(regs, RTW_ISR); 1208 1209 RTW_WRITE16(regs, RTW_ISR, isr); 1210 1211 if (sc->sc_intr_ack != NULL) 1212 (*sc->sc_intr_ack)(regs); 1213 1214 if (isr == 0) 1215 break; 1216 1217#ifdef RTW_DEBUG 1218#define PRINTINTR(flag) do { \ 1219 if ((isr & flag) != 0) { \ 1220 printf("%s" #flag, delim); \ 1221 delim = ","; \ 1222 } \ 1223} while (0) 1224 1225 if (rtw_debug > 1 && isr != 0) { 1226 const char *delim = "<"; 1227 1228 printf("%s: reg[ISR] = %x", sc->sc_dev.dv_xname, isr); 1229 1230 PRINTINTR(RTW_INTR_TXFOVW); 1231 PRINTINTR(RTW_INTR_TIMEOUT); 1232 PRINTINTR(RTW_INTR_BCNINT); 1233 PRINTINTR(RTW_INTR_ATIMINT); 1234 PRINTINTR(RTW_INTR_TBDER); 1235 PRINTINTR(RTW_INTR_TBDOK); 1236 PRINTINTR(RTW_INTR_THPDER); 1237 PRINTINTR(RTW_INTR_THPDOK); 1238 PRINTINTR(RTW_INTR_TNPDER); 1239 PRINTINTR(RTW_INTR_TNPDOK); 1240 PRINTINTR(RTW_INTR_RXFOVW); 1241 PRINTINTR(RTW_INTR_RDU); 1242 PRINTINTR(RTW_INTR_TLPDER); 1243 PRINTINTR(RTW_INTR_TLPDOK); 1244 PRINTINTR(RTW_INTR_RER); 1245 PRINTINTR(RTW_INTR_ROK); 1246 1247 printf(">\n"); 1248 } 1249#undef PRINTINTR 1250#endif /* RTW_DEBUG */ 1251 1252 if ((isr & RTW_INTR_RX) != 0) 1253 rtw_intr_rx(sc, isr & RTW_INTR_RX); 1254 if ((isr & RTW_INTR_TX) != 0) 1255 rtw_intr_tx(sc, isr & RTW_INTR_TX); 1256 if ((isr & RTW_INTR_BEACON) != 0) 1257 rtw_intr_beacon(sc, isr & RTW_INTR_BEACON); 1258 if ((isr & RTW_INTR_ATIMINT) != 0) 1259 rtw_intr_atim(sc); 1260 if ((isr & RTW_INTR_IOERROR) != 0) 1261 rtw_intr_ioerror(sc, isr & RTW_INTR_IOERROR); 1262 if ((isr & RTW_INTR_TIMEOUT) != 0) 1263 rtw_intr_timeout(sc); 1264 } 1265 1266 return 1; 1267} 1268 1269static void 1270rtw_stop(struct ifnet *ifp, int disable) 1271{ 1272 struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc; 1273 struct ieee80211com *ic = &sc->sc_ic; 1274 struct rtw_regs *regs = &sc->sc_regs; 1275 1276 rtw_suspend_ticks(sc); 1277 1278 ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 1279 1280 /* Disable interrupts. */ 1281 RTW_WRITE16(regs, RTW_IMR, 0); 1282 1283 /* Stop the transmit and receive processes. First stop DMA, 1284 * then disable receiver and transmitter. 1285 */ 1286 RTW_WRITE8(regs, RTW_TPPOLL, 1287 RTW_TPPOLL_SBQ|RTW_TPPOLL_SHPQ|RTW_TPPOLL_SNPQ|RTW_TPPOLL_SLPQ); 1288 1289 rtw_io_enable(&sc->sc_regs, RTW_CR_RE|RTW_CR_TE, 0); 1290 1291 /* TBD Release transmit buffers. */ 1292 1293 if (disable) { 1294 rtw_disable(sc); 1295 rtw_rxbufs_release(sc->sc_dmat, &sc->sc_rxctl[0]); 1296 } 1297 1298 /* Mark the interface as not running. Cancel the watchdog timer. */ 1299 ifp->if_flags &= ~IFF_RUNNING; 1300 ifp->if_timer = 0; 1301 return; 1302} 1303 1304const char * 1305rtw_pwrstate_string(enum rtw_pwrstate power) 1306{ 1307 switch (power) { 1308 case RTW_ON: 1309 return "on"; 1310 case RTW_SLEEP: 1311 return "sleep"; 1312 case RTW_OFF: 1313 return "off"; 1314 default: 1315 return "unknown"; 1316 } 1317} 1318 1319/* XXX I am using the RFMD settings gleaned from the reference 1320 * driver. 1321 */ 1322static void 1323rtw_maxim_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power, 1324 int before_rf) 1325{ 1326 u_int32_t anaparm; 1327 1328 RTW_DPRINTF(("%s: power state %s, %s RF\n", __func__, 1329 rtw_pwrstate_string(power), (before_rf) ? "before" : "after")); 1330 1331 anaparm = RTW_READ(regs, RTW_ANAPARM); 1332 anaparm &= ~(RTW_ANAPARM_RFPOW0_MASK|RTW_ANAPARM_RFPOW1_MASK); 1333 anaparm &= ~RTW_ANAPARM_TXDACOFF; 1334 1335 switch (power) { 1336 case RTW_OFF: 1337 if (before_rf) 1338 return; 1339 anaparm |= RTW_ANAPARM_RFPOW0_RFMD_OFF; 1340 anaparm |= RTW_ANAPARM_RFPOW1_RFMD_OFF; 1341 anaparm |= RTW_ANAPARM_TXDACOFF; 1342 break; 1343 case RTW_SLEEP: 1344 if (!before_rf) 1345 return; 1346 anaparm |= RTW_ANAPARM_RFPOW0_RFMD_SLEEP; 1347 anaparm |= RTW_ANAPARM_RFPOW1_RFMD_SLEEP; 1348 anaparm |= RTW_ANAPARM_TXDACOFF; 1349 break; 1350 case RTW_ON: 1351 if (!before_rf) 1352 return; 1353 anaparm |= RTW_ANAPARM_RFPOW0_RFMD_ON; 1354 anaparm |= RTW_ANAPARM_RFPOW1_RFMD_ON; 1355 break; 1356 } 1357 RTW_WRITE(regs, RTW_ANAPARM, anaparm); 1358 RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM); 1359} 1360 1361static void 1362rtw_philips_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power, 1363 int before_rf) 1364{ 1365 u_int32_t anaparm; 1366 1367 RTW_DPRINTF(("%s: power state %s, %s RF\n", __func__, 1368 rtw_pwrstate_string(power), (before_rf) ? "before" : "after")); 1369 1370 anaparm = RTW_READ(regs, RTW_ANAPARM); 1371 anaparm &= ~(RTW_ANAPARM_RFPOW0_MASK|RTW_ANAPARM_RFPOW1_MASK); 1372 anaparm &= ~RTW_ANAPARM_TXDACOFF; 1373 1374 switch (power) { 1375 case RTW_OFF: 1376 if (before_rf) 1377 return; 1378 anaparm |= RTW_ANAPARM_RFPOW0_PHILIPS_OFF; 1379 anaparm |= RTW_ANAPARM_RFPOW1_PHILIPS_OFF; 1380 anaparm |= RTW_ANAPARM_TXDACOFF; 1381 break; 1382 case RTW_SLEEP: 1383 if (!before_rf) 1384 return; 1385 anaparm |= RTW_ANAPARM_RFPOW0_PHILIPS_SLEEP; 1386 anaparm |= RTW_ANAPARM_RFPOW1_PHILIPS_SLEEP; 1387 anaparm |= RTW_ANAPARM_TXDACOFF; 1388 break; 1389 case RTW_ON: 1390 if (!before_rf) 1391 return; 1392 anaparm |= RTW_ANAPARM_RFPOW0_PHILIPS_ON; 1393 anaparm |= RTW_ANAPARM_RFPOW1_PHILIPS_ON; 1394 break; 1395 } 1396 RTW_WRITE(regs, RTW_ANAPARM, anaparm); 1397 RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM); 1398} 1399 1400static void 1401rtw_pwrstate0(struct rtw_softc *sc, enum rtw_pwrstate power, int before_rf) 1402{ 1403 struct rtw_regs *regs = &sc->sc_regs; 1404 1405 rtw_config0123_enable(regs, 1); 1406 rtw_anaparm_enable(regs, 1); 1407 1408 (*sc->sc_pwrstate_cb)(regs, power, before_rf); 1409 1410 rtw_anaparm_enable(regs, 0); 1411 rtw_config0123_enable(regs, 0); 1412 1413 return; 1414} 1415 1416static int 1417rtw_pwrstate(struct rtw_softc *sc, enum rtw_pwrstate power) 1418{ 1419 int rc; 1420 1421 RTW_DPRINTF2(("%s: %s->%s\n", __func__, 1422 rtw_pwrstate_string(sc->sc_pwrstate), rtw_pwrstate_string(power))); 1423 1424 if (sc->sc_pwrstate == power) 1425 return 0; 1426 1427 rtw_pwrstate0(sc, power, 1); 1428 rc = rtw_rf_pwrstate(sc->sc_rf, power); 1429 rtw_pwrstate0(sc, power, 0); 1430 1431 switch (power) { 1432 case RTW_ON: 1433 /* TBD */ 1434 break; 1435 case RTW_SLEEP: 1436 /* TBD */ 1437 break; 1438 case RTW_OFF: 1439 /* TBD */ 1440 break; 1441 } 1442 if (rc == 0) 1443 sc->sc_pwrstate = power; 1444 else 1445 sc->sc_pwrstate = RTW_OFF; 1446 return rc; 1447} 1448 1449static int 1450rtw_tune(struct rtw_softc *sc) 1451{ 1452 struct ieee80211com *ic = &sc->sc_ic; 1453 u_int chan; 1454 int rc; 1455 int antdiv = sc->sc_flags & RTW_F_ANTDIV, 1456 dflantb = sc->sc_flags & RTW_F_DFLANTB; 1457 1458 KASSERT(ic->ic_bss->ni_chan != NULL); 1459 1460 chan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan); 1461 if (chan == IEEE80211_CHAN_ANY) 1462 panic("%s: chan == IEEE80211_CHAN_ANY\n", __func__); 1463 1464 if (chan == sc->sc_cur_chan) { 1465 RTW_DPRINTF(("%s: already tuned chan #%d\n", __func__, chan)); 1466 return 0; 1467 } 1468 1469 rtw_suspend_ticks(sc); 1470 1471 rtw_io_enable(&sc->sc_regs, RTW_CR_RE | RTW_CR_TE, 0); 1472 1473 /* TBD wait for Tx to complete */ 1474 1475 KASSERT((sc->sc_flags & RTW_F_ENABLED) != 0); 1476 1477 if ((rc = rtw_phy_init(&sc->sc_regs, sc->sc_rf, 1478 rtw_chan2txpower(&sc->sc_srom, ic, ic->ic_bss->ni_chan), 1479 sc->sc_csthr, ic->ic_bss->ni_chan->ic_freq, antdiv, 1480 dflantb, RTW_ON)) != 0) { 1481 /* XXX condition on powersaving */ 1482 printf("%s: phy init failed\n", sc->sc_dev.dv_xname); 1483 } 1484 1485 sc->sc_cur_chan = chan; 1486 1487 rtw_io_enable(&sc->sc_regs, RTW_CR_RE | RTW_CR_TE, 1); 1488 1489 rtw_resume_ticks(sc); 1490 1491 return rc; 1492} 1493 1494void 1495rtw_disable(struct rtw_softc *sc) 1496{ 1497 int rc; 1498 1499 if ((sc->sc_flags & RTW_F_ENABLED) == 0) 1500 return; 1501 1502 /* turn off PHY */ 1503 if ((rc = rtw_pwrstate(sc, RTW_OFF)) != 0) 1504 printf("%s: failed to turn off PHY (%d)\n", 1505 sc->sc_dev.dv_xname, rc); 1506 1507 if (sc->sc_disable != NULL) 1508 (*sc->sc_disable)(sc); 1509 1510 sc->sc_flags &= ~RTW_F_ENABLED; 1511} 1512 1513int 1514rtw_enable(struct rtw_softc *sc) 1515{ 1516 if ((sc->sc_flags & RTW_F_ENABLED) == 0) { 1517 if (sc->sc_enable != NULL && (*sc->sc_enable)(sc) != 0) { 1518 printf("%s: device enable failed\n", 1519 sc->sc_dev.dv_xname); 1520 return (EIO); 1521 } 1522 sc->sc_flags |= RTW_F_ENABLED; 1523 } 1524 return (0); 1525} 1526 1527static void 1528rtw_transmit_config(struct rtw_regs *regs) 1529{ 1530 u_int32_t tcr; 1531 1532 tcr = RTW_READ(regs, RTW_TCR); 1533 1534 tcr |= RTW_TCR_SAT; /* send ACK as fast as possible */ 1535 tcr &= ~RTW_TCR_LBK_MASK; 1536 tcr |= RTW_TCR_LBK_NORMAL; /* normal operating mode */ 1537 1538 /* set short/long retry limits */ 1539 tcr &= ~(RTW_TCR_SRL_MASK|RTW_TCR_LRL_MASK); 1540 tcr |= LSHIFT(7, RTW_TCR_SRL_MASK) | LSHIFT(7, RTW_TCR_LRL_MASK); 1541 1542 tcr |= RTW_TCR_CRC; /* NIC appends CRC32 */ 1543 1544 RTW_WRITE(regs, RTW_TCR, tcr); 1545} 1546 1547static __inline void 1548rtw_enable_interrupts(struct rtw_softc *sc) 1549{ 1550 struct rtw_regs *regs = &sc->sc_regs; 1551 1552 sc->sc_inten = RTW_INTR_RX|RTW_INTR_TX|RTW_INTR_BEACON|RTW_INTR_ATIMINT; 1553 sc->sc_inten |= RTW_INTR_IOERROR|RTW_INTR_TIMEOUT; 1554 1555 RTW_WRITE16(regs, RTW_IMR, sc->sc_inten); 1556 RTW_WRITE16(regs, RTW_ISR, 0xffff); 1557 1558 /* XXX necessary? */ 1559 if (sc->sc_intr_ack != NULL) 1560 (*sc->sc_intr_ack)(regs); 1561} 1562 1563/* XXX is the endianness correct? test. */ 1564#define rtw_calchash(addr) \ 1565 (ether_crc32_le((addr), IEEE80211_ADDR_LEN) & BITS(5, 0)) 1566 1567static void 1568rtw_pktfilt_load(struct rtw_softc *sc) 1569{ 1570 struct rtw_regs *regs = &sc->sc_regs; 1571 struct ieee80211com *ic = &sc->sc_ic; 1572 struct ethercom *ec = &ic->ic_ec; 1573 struct ifnet *ifp = &sc->sc_ic.ic_if; 1574 int hash; 1575 u_int32_t hashes[2] = { 0, 0 }; 1576 struct ether_multi *enm; 1577 struct ether_multistep step; 1578 1579 /* XXX might be necessary to stop Rx/Tx engines while setting filters */ 1580 1581#define RTW_RCR_MONITOR (RTW_RCR_ACRC32|RTW_RCR_APM|RTW_RCR_AAP|RTW_RCR_AB) 1582 1583 if (ic->ic_opmode == IEEE80211_M_MONITOR) 1584 sc->sc_rcr |= RTW_RCR_MONITOR; 1585 else 1586 sc->sc_rcr &= ~RTW_RCR_MONITOR; 1587 1588 /* XXX reference sources BEGIN */ 1589 sc->sc_rcr |= RTW_RCR_ENMARP | RTW_RCR_AICV | RTW_RCR_ACRC32; 1590 sc->sc_rcr |= RTW_RCR_AB | RTW_RCR_AM | RTW_RCR_APM; 1591#if 0 1592 /* receive broadcasts in our BSS */ 1593 sc->sc_rcr |= RTW_RCR_ADD3; 1594#endif 1595 /* XXX reference sources END */ 1596 1597 /* receive pwrmgmt frames. */ 1598 sc->sc_rcr |= RTW_RCR_APWRMGT; 1599 /* receive mgmt/ctrl/data frames. */ 1600 sc->sc_rcr |= RTW_RCR_AMF | RTW_RCR_ACF | RTW_RCR_ADF; 1601 /* initialize Rx DMA threshold, Tx DMA burst size */ 1602 sc->sc_rcr |= RTW_RCR_RXFTH_WHOLE | RTW_RCR_MXDMA_1024; 1603 1604 ifp->if_flags &= ~IFF_ALLMULTI; 1605 1606 if (ifp->if_flags & IFF_PROMISC) { 1607 sc->sc_rcr |= RTW_RCR_AB; /* accept all broadcast */ 1608allmulti: 1609 ifp->if_flags |= IFF_ALLMULTI; 1610 goto setit; 1611 } 1612 1613 /* 1614 * Program the 64-bit multicast hash filter. 1615 */ 1616 ETHER_FIRST_MULTI(step, ec, enm); 1617 while (enm != NULL) { 1618 /* XXX */ 1619 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, 1620 ETHER_ADDR_LEN) != 0) 1621 goto allmulti; 1622 1623 hash = rtw_calchash(enm->enm_addrlo); 1624 hashes[hash >> 5] |= 1 << (hash & 0x1f); 1625 ETHER_NEXT_MULTI(step, enm); 1626 } 1627 1628 if (ifp->if_flags & IFF_BROADCAST) { 1629 hash = rtw_calchash(etherbroadcastaddr); 1630 hashes[hash >> 5] |= 1 << (hash & 0x1f); 1631 } 1632 1633 /* all bits set => hash is useless */ 1634 if (~(hashes[0] & hashes[1]) == 0) 1635 goto allmulti; 1636 1637 setit: 1638 if (ifp->if_flags & IFF_ALLMULTI) 1639 sc->sc_rcr |= RTW_RCR_AM; /* accept all multicast */ 1640 1641 if (ic->ic_state == IEEE80211_S_SCAN) 1642 sc->sc_rcr |= RTW_RCR_AB; /* accept all broadcast */ 1643 1644 hashes[0] = hashes[1] = 0xffffffff; 1645 1646 RTW_WRITE(regs, RTW_MAR0, hashes[0]); 1647 RTW_WRITE(regs, RTW_MAR1, hashes[1]); 1648 RTW_WRITE(regs, RTW_RCR, sc->sc_rcr); 1649 RTW_SYNC(regs, RTW_MAR0, RTW_RCR); /* RTW_MAR0 < RTW_MAR1 < RTW_RCR */ 1650 1651 DPRINTF(sc, ("%s: RTW_MAR0 %08x RTW_MAR1 %08x RTW_RCR %08x\n", 1652 sc->sc_dev.dv_xname, RTW_READ(regs, RTW_MAR0), 1653 RTW_READ(regs, RTW_MAR1), RTW_READ(regs, RTW_RCR))); 1654 1655 return; 1656} 1657 1658static int 1659rtw_init(struct ifnet *ifp) 1660{ 1661 struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc; 1662 struct ieee80211com *ic = &sc->sc_ic; 1663 struct rtw_regs *regs = &sc->sc_regs; 1664 int rc = 0, s; 1665 1666 if ((rc = rtw_enable(sc)) != 0) 1667 goto out; 1668 1669 /* Cancel pending I/O and reset. */ 1670 rtw_stop(ifp, 0); 1671 1672 ic->ic_bss->ni_chan = ic->ic_ibss_chan; 1673 DPRINTF(sc, ("%s: channel %d freq %d flags 0x%04x\n", 1674 __func__, ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan), 1675 ic->ic_bss->ni_chan->ic_freq, ic->ic_bss->ni_chan->ic_flags)); 1676 1677 if ((rc = rtw_pwrstate(sc, RTW_OFF)) != 0) 1678 goto out; 1679 1680 rtw_txdesc_blk_init_all(&sc->sc_txdesc_blk); 1681 1682 rtw_txctl_blk_init_all(&sc->sc_txctl_blk); 1683 1684 rtw_rxctl_init_all(sc->sc_dmat, sc->sc_rxctl, &sc->sc_rxnext, 1685 &sc->sc_dev.dv_xname); 1686 rtw_rxdesc_init_all(sc->sc_dmat, sc->sc_desc_dmamap, 1687 sc->sc_rxdesc, sc->sc_rxctl); 1688 1689 rtw_txdescs_sync_all(sc->sc_dmat, sc->sc_desc_dmamap, 1690 &sc->sc_txdesc_blk); 1691#if 0 /* redundant with rtw_rxdesc_init_all */ 1692 rtw_rxdescs_sync(sc->sc_dmat, sc->sc_desc_dmamap, 1693 0, RTW_NRXDESC, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 1694#endif 1695 1696 RTW_WRITE(regs, RTW_RDSAR, RTW_RING_BASE(sc, hd_rx)); 1697 1698 rtw_transmit_config(regs); 1699 1700 rtw_config0123_enable(regs, 1); 1701 1702 RTW_WRITE(regs, RTW_MSR, 0x0); /* no link */ 1703 1704 RTW_WRITE(regs, RTW_BRSR, 0x0); /* long PLCP header, 1Mbps basic rate */ 1705 1706 rtw_anaparm_enable(regs, 0); 1707 1708 rtw_config0123_enable(regs, 0); 1709 1710#if 0 1711 RTW_WRITE(regs, RTW_FEMR, RTW_FEMR_GWAKE|RTW_FEMR_WKUP|RTW_FEMR_INTR); 1712#endif 1713 /* XXX from reference sources */ 1714 RTW_WRITE(regs, RTW_FEMR, 0xffff); 1715 1716 RTW_WRITE(regs, RTW_PHYDELAY, sc->sc_phydelay); 1717 /* from Linux driver */ 1718 RTW_WRITE(regs, RTW_CRCOUNT, RTW_CRCOUNT_MAGIC); 1719 1720 rtw_enable_interrupts(sc); 1721 1722 rtw_pktfilt_load(sc); 1723 1724 RTW_WRITE(regs, RTW_TLPDA, RTW_RING_BASE(sc, hd_txlo)); 1725 RTW_WRITE(regs, RTW_TNPDA, RTW_RING_BASE(sc, hd_txmd)); 1726 RTW_WRITE(regs, RTW_THPDA, RTW_RING_BASE(sc, hd_txhi)); 1727 RTW_WRITE(regs, RTW_TBDA, RTW_RING_BASE(sc, hd_bcn)); 1728 1729 rtw_io_enable(regs, RTW_CR_RE|RTW_CR_TE, 1); 1730 1731 ifp->if_flags |= IFF_RUNNING; 1732 ic->ic_state = IEEE80211_S_INIT; 1733 1734 RTW_WRITE16(regs, RTW_BSSID16, 0x0); 1735 RTW_WRITE(regs, RTW_BSSID32, 0x0); 1736 1737 s = splclock(); 1738 sc->sc_tick0 = mono_time; 1739 splx(s); 1740 1741 rtw_resume_ticks(sc); 1742 1743 switch (ic->ic_opmode) { 1744 case IEEE80211_M_AHDEMO: 1745 case IEEE80211_M_IBSS: 1746 RTW_WRITE8(regs, RTW_MSR, RTW_MSR_NETYPE_ADHOC_OK); 1747 break; 1748 case IEEE80211_M_HOSTAP: 1749 RTW_WRITE8(regs, RTW_MSR, RTW_MSR_NETYPE_AP_OK); 1750 case IEEE80211_M_MONITOR: 1751 /* XXX */ 1752 RTW_WRITE8(regs, RTW_MSR, RTW_MSR_NETYPE_NOLINK); 1753 return ieee80211_new_state(ic, IEEE80211_S_RUN, -1); 1754 case IEEE80211_M_STA: 1755 RTW_WRITE8(regs, RTW_MSR, RTW_MSR_NETYPE_INFRA_OK); 1756 break; 1757 } 1758 return ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 1759out: 1760 return rc; 1761} 1762 1763static int 1764rtw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 1765{ 1766 int rc = 0; 1767 struct rtw_softc *sc = ifp->if_softc; 1768 struct ifreq *ifr = (struct ifreq *)data; 1769 1770 switch (cmd) { 1771 case SIOCSIFFLAGS: 1772 if ((ifp->if_flags & IFF_UP) != 0) { 1773 if ((sc->sc_flags & RTW_F_ENABLED) != 0) { 1774 rtw_pktfilt_load(sc); 1775 } else 1776 rc = rtw_init(ifp); 1777#ifdef RTW_DEBUG 1778 rtw_print_regs(&sc->sc_regs, ifp->if_xname, __func__); 1779#endif /* RTW_DEBUG */ 1780 } else if ((sc->sc_flags & RTW_F_ENABLED) != 0) { 1781#ifdef RTW_DEBUG 1782 rtw_print_regs(&sc->sc_regs, ifp->if_xname, __func__); 1783#endif /* RTW_DEBUG */ 1784 rtw_stop(ifp, 1); 1785 } 1786 break; 1787 case SIOCADDMULTI: 1788 case SIOCDELMULTI: 1789 if (cmd == SIOCADDMULTI) 1790 rc = ether_addmulti(ifr, &sc->sc_ic.ic_ec); 1791 else 1792 rc = ether_delmulti(ifr, &sc->sc_ic.ic_ec); 1793 if (rc == ENETRESET) { 1794 if ((sc->sc_flags & RTW_F_ENABLED) != 0) 1795 rtw_pktfilt_load(sc); 1796 rc = 0; 1797 } 1798 break; 1799 default: 1800 if ((rc = ieee80211_ioctl(ifp, cmd, data)) == ENETRESET) { 1801 if ((sc->sc_flags & RTW_F_ENABLED) != 0) 1802 rc = rtw_init(ifp); 1803 else 1804 rc = 0; 1805 } 1806 break; 1807 } 1808 return rc; 1809} 1810 1811/* Point *mp at the next 802.11 frame to transmit. Point *stcp 1812 * at the driver's selection of transmit control block for the packet. 1813 */ 1814static __inline int 1815rtw_dequeue(struct ifnet *ifp, struct rtw_txctl_blk **stcp, struct mbuf **mp, 1816 struct ieee80211_node **nip) 1817{ 1818 struct mbuf *m0; 1819 struct rtw_softc *sc; 1820 struct ieee80211com *ic; 1821 1822 sc = (struct rtw_softc *)ifp->if_softc; 1823 ic = &sc->sc_ic; 1824 1825 *mp = NULL; 1826 1827 if (!IF_IS_EMPTY(&ic->ic_mgtq)) { 1828 IF_DEQUEUE(&ic->ic_mgtq, m0); 1829 *nip = (struct ieee80211_node *)m0->m_pkthdr.rcvif; 1830 m0->m_pkthdr.rcvif = NULL; 1831 } else if (ic->ic_state != IEEE80211_S_RUN) 1832 return 0; 1833 else if (!IF_IS_EMPTY(&ic->ic_pwrsaveq)) { 1834 IF_DEQUEUE(&ic->ic_pwrsaveq, m0); 1835 *nip = (struct ieee80211_node *)m0->m_pkthdr.rcvif; 1836 m0->m_pkthdr.rcvif = NULL; 1837 } else { 1838 IFQ_POLL(&ifp->if_snd, m0); 1839 if (m0 == NULL) 1840 return 0; 1841 IFQ_DEQUEUE(&ifp->if_snd, m0); 1842 ifp->if_opackets++; 1843#if NBPFILTER > 0 1844 if (ifp->if_bpf) 1845 bpf_mtap(ifp->if_bpf, m0); 1846#endif 1847 if ((m0 = ieee80211_encap(ifp, m0, nip)) == NULL) { 1848 ifp->if_oerrors++; 1849 return -1; 1850 } 1851 } 1852 *stcp = &sc->sc_txctl_blk[RTW_TXPRIMD]; 1853 *mp = m0; 1854 return 0; 1855} 1856 1857static void 1858rtw_start(struct ifnet *ifp) 1859{ 1860 struct mbuf *m0; 1861 struct rtw_softc *sc; 1862 struct rtw_txctl_blk *stc; 1863 struct ieee80211_node *ni; 1864 1865 sc = (struct rtw_softc *)ifp->if_softc; 1866 1867#if 0 1868 struct ifqueue ic_mgtq; 1869 struct ifqueue ic_pwrsaveq; 1870struct rtw_txctl_blk { 1871 /* dirty/free s/w descriptors */ 1872 struct rtw_txq stc_dirtyq; 1873 struct rtw_txq stc_freeq; 1874 u_int stc_ndesc; 1875 struct rtw_txctl *stc_desc; 1876}; 1877#endif 1878 while (!SIMPLEQ_EMPTY(&stc->stc_freeq)) { 1879 if (rtw_dequeue(ifp, &stc, &m0, &ni) == -1) 1880 continue; 1881 if (m0 == NULL) 1882 break; 1883 ieee80211_release_node(&sc->sc_ic, ni); 1884 } 1885 return; 1886} 1887 1888static void 1889rtw_watchdog(struct ifnet *ifp) 1890{ 1891 /* TBD */ 1892 return; 1893} 1894 1895static void 1896rtw_start_beacon(struct rtw_softc *sc, int enable) 1897{ 1898 /* TBD */ 1899 return; 1900} 1901 1902static void 1903rtw_next_scan(void *arg) 1904{ 1905 struct ieee80211com *ic = arg; 1906 int s; 1907 1908 /* don't call rtw_start w/o network interrupts blocked */ 1909 s = splnet(); 1910 if (ic->ic_state == IEEE80211_S_SCAN) 1911 ieee80211_next_scan(ic); 1912 splx(s); 1913} 1914 1915/* Synchronize the hardware state with the software state. */ 1916static int 1917rtw_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) 1918{ 1919 struct ifnet *ifp = &ic->ic_if; 1920 struct rtw_softc *sc = ifp->if_softc; 1921 enum ieee80211_state ostate; 1922 int error; 1923 1924 ostate = ic->ic_state; 1925 1926 if (nstate == IEEE80211_S_INIT) { 1927 callout_stop(&sc->sc_scan_ch); 1928 sc->sc_cur_chan = IEEE80211_CHAN_ANY; 1929 rtw_start_beacon(sc, 0); 1930 return (*sc->sc_mtbl.mt_newstate)(ic, nstate, arg); 1931 } 1932 1933 if (ostate == IEEE80211_S_INIT && nstate != IEEE80211_S_INIT) 1934 rtw_pwrstate(sc, RTW_ON); 1935 1936 if ((error = rtw_tune(sc)) != 0) 1937 return error; 1938 1939 switch (nstate) { 1940 case IEEE80211_S_ASSOC: 1941 break; 1942 case IEEE80211_S_INIT: 1943 panic("%s: unexpected state IEEE80211_S_INIT\n", __func__); 1944 break; 1945 case IEEE80211_S_SCAN: 1946#if 0 1947 memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN); 1948 rtw_write_bssid(sc); 1949#endif 1950 1951 callout_reset(&sc->sc_scan_ch, rtw_dwelltime * hz / 1000, 1952 rtw_next_scan, ic); 1953 1954 break; 1955 case IEEE80211_S_RUN: 1956 if (ic->ic_opmode == IEEE80211_M_STA) 1957 break; 1958 /*FALLTHROUGH*/ 1959 case IEEE80211_S_AUTH: 1960#if 0 1961 rtw_write_bssid(sc); 1962 rtw_write_bcn_thresh(sc); 1963 rtw_write_ssid(sc); 1964 rtw_write_sup_rates(sc); 1965#endif 1966 if (ic->ic_opmode == IEEE80211_M_AHDEMO || 1967 ic->ic_opmode == IEEE80211_M_MONITOR) 1968 break; 1969 1970 /* TBD set listen interval, beacon interval */ 1971 1972#if 0 1973 rtw_tsf(sc); 1974#endif 1975 break; 1976 } 1977 1978 if (nstate != IEEE80211_S_SCAN) 1979 callout_stop(&sc->sc_scan_ch); 1980 1981 if (nstate == IEEE80211_S_RUN && 1982 (ic->ic_opmode == IEEE80211_M_HOSTAP || 1983 ic->ic_opmode == IEEE80211_M_IBSS)) 1984 rtw_start_beacon(sc, 1); 1985 else 1986 rtw_start_beacon(sc, 0); 1987 1988 return (*sc->sc_mtbl.mt_newstate)(ic, nstate, arg); 1989} 1990 1991static void 1992rtw_recv_beacon(struct ieee80211com *ic, struct mbuf *m0, 1993 struct ieee80211_node *ni, int subtype, int rssi, u_int32_t rstamp) 1994{ 1995 /* TBD */ 1996 return; 1997} 1998 1999static void 2000rtw_recv_mgmt(struct ieee80211com *ic, struct mbuf *m, 2001 struct ieee80211_node *ni, int subtype, int rssi, u_int32_t rstamp) 2002{ 2003 struct rtw_softc *sc = (struct rtw_softc*)ic->ic_softc; 2004 2005 switch (subtype) { 2006 case IEEE80211_FC0_SUBTYPE_PROBE_REQ: 2007 /* do nothing: hardware answers probe request XXX */ 2008 break; 2009 case IEEE80211_FC0_SUBTYPE_PROBE_RESP: 2010 case IEEE80211_FC0_SUBTYPE_BEACON: 2011 rtw_recv_beacon(ic, m, ni, subtype, rssi, rstamp); 2012 break; 2013 default: 2014 (*sc->sc_mtbl.mt_recv_mgmt)(ic, m, ni, subtype, rssi, rstamp); 2015 break; 2016 } 2017 return; 2018} 2019 2020static struct ieee80211_node * 2021rtw_node_alloc(struct ieee80211com *ic) 2022{ 2023 struct rtw_softc *sc = (struct rtw_softc *)ic->ic_if.if_softc; 2024 struct ieee80211_node *ni = (*sc->sc_mtbl.mt_node_alloc)(ic); 2025 2026 DPRINTF(sc, ("%s: alloc node %p\n", sc->sc_dev.dv_xname, ni)); 2027 return ni; 2028} 2029 2030static void 2031rtw_node_free(struct ieee80211com *ic, struct ieee80211_node *ni) 2032{ 2033 struct rtw_softc *sc = (struct rtw_softc *)ic->ic_if.if_softc; 2034 2035 DPRINTF(sc, ("%s: freeing node %p %s\n", sc->sc_dev.dv_xname, ni, 2036 ether_sprintf(ni->ni_bssid))); 2037 (*sc->sc_mtbl.mt_node_free)(ic, ni); 2038} 2039 2040static int 2041rtw_media_change(struct ifnet *ifp) 2042{ 2043 int error; 2044 2045 error = ieee80211_media_change(ifp); 2046 if (error == ENETRESET) { 2047 if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) == 2048 (IFF_RUNNING|IFF_UP)) 2049 rtw_init(ifp); /* XXX lose error */ 2050 error = 0; 2051 } 2052 return error; 2053} 2054 2055static void 2056rtw_media_status(struct ifnet *ifp, struct ifmediareq *imr) 2057{ 2058 struct rtw_softc *sc = ifp->if_softc; 2059 2060 if ((sc->sc_flags & RTW_F_ENABLED) == 0) { 2061 imr->ifm_active = IFM_IEEE80211 | IFM_NONE; 2062 imr->ifm_status = 0; 2063 return; 2064 } 2065 ieee80211_media_status(ifp, imr); 2066} 2067 2068void 2069rtw_power(int why, void *arg) 2070{ 2071 struct rtw_softc *sc = arg; 2072 struct ifnet *ifp = &sc->sc_ic.ic_if; 2073 int s; 2074 2075 DPRINTF(sc, ("%s: rtw_power(%d,)\n", sc->sc_dev.dv_xname, why)); 2076 2077 s = splnet(); 2078 switch (why) { 2079 case PWR_STANDBY: 2080 /* XXX do nothing. */ 2081 break; 2082 case PWR_SUSPEND: 2083 rtw_stop(ifp, 0); 2084 if (sc->sc_power != NULL) 2085 (*sc->sc_power)(sc, why); 2086 break; 2087 case PWR_RESUME: 2088 if (ifp->if_flags & IFF_UP) { 2089 if (sc->sc_power != NULL) 2090 (*sc->sc_power)(sc, why); 2091 rtw_init(ifp); 2092 } 2093 break; 2094 case PWR_SOFTSUSPEND: 2095 case PWR_SOFTSTANDBY: 2096 case PWR_SOFTRESUME: 2097 break; 2098 } 2099 splx(s); 2100} 2101 2102/* rtw_shutdown: make sure the interface is stopped at reboot time. */ 2103void 2104rtw_shutdown(void *arg) 2105{ 2106 struct rtw_softc *sc = arg; 2107 2108 rtw_stop(&sc->sc_ic.ic_if, 1); 2109} 2110 2111static __inline void 2112rtw_setifprops(struct ifnet *ifp, char (*dvname)[IFNAMSIZ], void *softc) 2113{ 2114 (void)memcpy(ifp->if_xname, *dvname, IFNAMSIZ); 2115 ifp->if_softc = softc; 2116 ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST | 2117 IFF_NOTRAILERS; 2118 ifp->if_ioctl = rtw_ioctl; 2119 ifp->if_start = rtw_start; 2120 ifp->if_watchdog = rtw_watchdog; 2121 ifp->if_init = rtw_init; 2122 ifp->if_stop = rtw_stop; 2123} 2124 2125static __inline void 2126rtw_set80211props(struct ieee80211com *ic) 2127{ 2128 int nrate; 2129 ic->ic_phytype = IEEE80211_T_DS; 2130 ic->ic_opmode = IEEE80211_M_STA; 2131 ic->ic_caps = IEEE80211_C_PMGT | IEEE80211_C_IBSS | 2132 IEEE80211_C_HOSTAP | IEEE80211_C_MONITOR | IEEE80211_C_WEP; 2133 2134 nrate = 0; 2135 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] = 2; 2136 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] = 4; 2137 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] = 11; 2138 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] = 22; 2139 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_nrates = nrate; 2140} 2141 2142static __inline void 2143rtw_set80211methods(struct rtw_mtbl *mtbl, struct ieee80211com *ic) 2144{ 2145 mtbl->mt_newstate = ic->ic_newstate; 2146 ic->ic_newstate = rtw_newstate; 2147 2148 mtbl->mt_recv_mgmt = ic->ic_recv_mgmt; 2149 ic->ic_recv_mgmt = rtw_recv_mgmt; 2150 2151 mtbl->mt_node_free = ic->ic_node_free; 2152 ic->ic_node_free = rtw_node_free; 2153 2154 mtbl->mt_node_alloc = ic->ic_node_alloc; 2155 ic->ic_node_alloc = rtw_node_alloc; 2156} 2157 2158static __inline void 2159rtw_establish_hooks(struct rtw_hooks *hooks, char (*dvname)[IFNAMSIZ], 2160 void *arg) 2161{ 2162 /* 2163 * Make sure the interface is shutdown during reboot. 2164 */ 2165 hooks->rh_shutdown = shutdownhook_establish(rtw_shutdown, arg); 2166 if (hooks->rh_shutdown == NULL) 2167 printf("%s: WARNING: unable to establish shutdown hook\n", 2168 *dvname); 2169 2170 /* 2171 * Add a suspend hook to make sure we come back up after a 2172 * resume. 2173 */ 2174 hooks->rh_power = powerhook_establish(rtw_power, arg); 2175 if (hooks->rh_power == NULL) 2176 printf("%s: WARNING: unable to establish power hook\n", 2177 *dvname); 2178} 2179 2180static __inline void 2181rtw_disestablish_hooks(struct rtw_hooks *hooks, char (*dvname)[IFNAMSIZ], 2182 void *arg) 2183{ 2184 if (hooks->rh_shutdown != NULL) 2185 shutdownhook_disestablish(hooks->rh_shutdown); 2186 2187 if (hooks->rh_power != NULL) 2188 powerhook_disestablish(hooks->rh_power); 2189} 2190 2191static __inline void 2192rtw_init_radiotap(struct rtw_softc *sc) 2193{ 2194 memset(&sc->sc_rxtapu, 0, sizeof(sc->sc_rxtapu)); 2195 sc->sc_rxtap.rr_ihdr.it_len = sizeof(sc->sc_rxtapu); 2196 sc->sc_rxtap.rr_ihdr.it_present = RTW_RX_RADIOTAP_PRESENT; 2197 2198 memset(&sc->sc_txtapu, 0, sizeof(sc->sc_txtapu)); 2199 sc->sc_txtap.rt_ihdr.it_len = sizeof(sc->sc_txtapu); 2200 sc->sc_txtap.rt_ihdr.it_present = RTW_TX_RADIOTAP_PRESENT; 2201} 2202 2203static int 2204rtw_txctl_blk_setup(struct rtw_txctl_blk *stc, u_int qlen) 2205{ 2206 SIMPLEQ_INIT(&stc->stc_dirtyq); 2207 SIMPLEQ_INIT(&stc->stc_freeq); 2208 stc->stc_ndesc = qlen; 2209 stc->stc_desc = malloc(qlen * sizeof(*stc->stc_desc), M_DEVBUF, 2210 M_NOWAIT); 2211 if (stc->stc_desc == NULL) 2212 return ENOMEM; 2213 return 0; 2214} 2215 2216static void 2217rtw_txctl_blk_cleanup_all(struct rtw_softc *sc) 2218{ 2219 struct rtw_txctl_blk *stc; 2220 int qlen[RTW_NTXPRI] = 2221 {RTW_TXQLENLO, RTW_TXQLENMD, RTW_TXQLENHI, RTW_TXQLENBCN}; 2222 int pri; 2223 2224 for (pri = 0; pri < sizeof(qlen)/sizeof(qlen[0]); pri++) { 2225 stc = &sc->sc_txctl_blk[pri]; 2226 free(stc->stc_desc, M_DEVBUF); 2227 stc->stc_desc = NULL; 2228 } 2229} 2230 2231static int 2232rtw_txctl_blk_setup_all(struct rtw_softc *sc) 2233{ 2234 int pri, rc = 0; 2235 int qlen[RTW_NTXPRI] = 2236 {RTW_TXQLENLO, RTW_TXQLENMD, RTW_TXQLENHI, RTW_TXQLENBCN}; 2237 2238 for (pri = 0; pri < sizeof(qlen)/sizeof(qlen[0]); pri++) { 2239 rc = rtw_txctl_blk_setup(&sc->sc_txctl_blk[pri], qlen[pri]); 2240 if (rc != 0) 2241 break; 2242 } 2243 return rc; 2244} 2245 2246static void 2247rtw_txdesc_blk_setup(struct rtw_txdesc_blk *htc, struct rtw_txdesc *desc, 2248 u_int ndesc, bus_addr_t ofs, bus_addr_t physbase) 2249{ 2250 int i; 2251 2252 htc->htc_ndesc = ndesc; 2253 htc->htc_desc = desc; 2254 htc->htc_physbase = physbase; 2255 htc->htc_ofs = ofs; 2256 2257 (void)memset(htc->htc_desc, 0, 2258 sizeof(htc->htc_desc[0]) * htc->htc_ndesc); 2259 2260 for (i = 0; i < htc->htc_ndesc; i++) { 2261 htc->htc_desc[i].htx_next = htole32(RTW_NEXT_DESC(htc, i)); 2262 } 2263} 2264 2265static void 2266rtw_txdesc_blk_setup_all(struct rtw_softc *sc) 2267{ 2268 rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRILO], 2269 &sc->sc_descs->hd_txlo[0], RTW_NTXDESCLO, 2270 RTW_RING_OFFSET(hd_txlo), RTW_RING_BASE(sc, hd_txlo)); 2271 2272 rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIMD], 2273 &sc->sc_descs->hd_txmd[0], RTW_NTXDESCMD, 2274 RTW_RING_OFFSET(hd_txmd), RTW_RING_BASE(sc, hd_txmd)); 2275 2276 rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIHI], 2277 &sc->sc_descs->hd_txhi[0], RTW_NTXDESCHI, 2278 RTW_RING_OFFSET(hd_txhi), RTW_RING_BASE(sc, hd_txhi)); 2279 2280 rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIBCN], 2281 &sc->sc_descs->hd_bcn[0], RTW_NTXDESCBCN, 2282 RTW_RING_OFFSET(hd_bcn), RTW_RING_BASE(sc, hd_bcn)); 2283} 2284 2285static struct rtw_rf * 2286rtw_rf_attach(struct rtw_softc *sc, enum rtw_rfchipid rfchipid, 2287 rtw_rf_write_t rf_write, int digphy) 2288{ 2289 struct rtw_rf *rf; 2290 2291 switch (rfchipid) { 2292 case RTW_RFCHIPID_MAXIM: 2293 rf = rtw_max2820_create(&sc->sc_regs, rf_write, 0); 2294 sc->sc_pwrstate_cb = rtw_maxim_pwrstate; 2295 break; 2296 case RTW_RFCHIPID_PHILIPS: 2297 rf = rtw_sa2400_create(&sc->sc_regs, rf_write, digphy); 2298 sc->sc_pwrstate_cb = rtw_philips_pwrstate; 2299 break; 2300 default: 2301 return NULL; 2302 } 2303 rf->rf_continuous_tx_cb = 2304 (rtw_continuous_tx_cb_t)rtw_continuous_tx_enable; 2305 rf->rf_continuous_tx_arg = (void *)sc; 2306 return rf; 2307} 2308 2309/* Revision C and later use a different PHY delay setting than 2310 * revisions A and B. 2311 */ 2312static u_int8_t 2313rtw_check_phydelay(struct rtw_regs *regs, u_int32_t rcr0) 2314{ 2315#define REVAB (RTW_RCR_MXDMA_UNLIMITED | RTW_RCR_AICV) 2316#define REVC (REVAB | RTW_RCR_RXFTH_WHOLE) 2317 2318 u_int8_t phydelay = LSHIFT(0x6, RTW_PHYDELAY_PHYDELAY); 2319 2320 RTW_WRITE(regs, RTW_RCR, REVAB); 2321 RTW_WRITE(regs, RTW_RCR, REVC); 2322 2323 RTW_WBR(regs, RTW_RCR, RTW_RCR); 2324 if ((RTW_READ(regs, RTW_RCR) & REVC) == REVC) 2325 phydelay |= RTW_PHYDELAY_REVC_MAGIC; 2326 2327 RTW_WRITE(regs, RTW_RCR, rcr0); /* restore RCR */ 2328 2329 return phydelay; 2330#undef REVC 2331} 2332 2333void 2334rtw_attach(struct rtw_softc *sc) 2335{ 2336 rtw_rf_write_t rf_write; 2337 struct rtw_txctl_blk *stc; 2338 int pri, rc, vers; 2339 2340#if 0 2341 CASSERT(RTW_DESC_ALIGNMENT % sizeof(struct rtw_txdesc) == 0, 2342 "RTW_DESC_ALIGNMENT is not a multiple of " 2343 "sizeof(struct rtw_txdesc)"); 2344 2345 CASSERT(RTW_DESC_ALIGNMENT % sizeof(struct rtw_rxdesc) == 0, 2346 "RTW_DESC_ALIGNMENT is not a multiple of " 2347 "sizeof(struct rtw_rxdesc)"); 2348 2349 CASSERT(RTW_DESC_ALIGNMENT % RTW_MAXPKTSEGS == 0, 2350 "RTW_DESC_ALIGNMENT is not a multiple of RTW_MAXPKTSEGS"); 2351#endif 2352 2353 NEXT_ATTACH_STATE(sc, DETACHED); 2354 2355 switch (RTW_READ(&sc->sc_regs, RTW_TCR) & RTW_TCR_HWVERID_MASK) { 2356 case RTW_TCR_HWVERID_F: 2357 vers = 'F'; 2358 rf_write = rtw_rf_hostwrite; 2359 break; 2360 case RTW_TCR_HWVERID_D: 2361 vers = 'D'; 2362 rf_write = rtw_rf_macwrite; 2363 break; 2364 default: 2365 vers = '?'; 2366 rf_write = rtw_rf_macwrite; 2367 break; 2368 } 2369 printf("%s: hardware version %c\n", sc->sc_dev.dv_xname, vers); 2370 2371 rc = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct rtw_descs), 2372 RTW_DESC_ALIGNMENT, 0, &sc->sc_desc_segs, 1, &sc->sc_desc_nsegs, 2373 0); 2374 2375 if (rc != 0) { 2376 printf("%s: could not allocate hw descriptors, error %d\n", 2377 sc->sc_dev.dv_xname, rc); 2378 goto err; 2379 } 2380 2381 NEXT_ATTACH_STATE(sc, FINISH_DESC_ALLOC); 2382 2383 rc = bus_dmamem_map(sc->sc_dmat, &sc->sc_desc_segs, 2384 sc->sc_desc_nsegs, sizeof(struct rtw_descs), 2385 (caddr_t*)&sc->sc_descs, BUS_DMA_COHERENT); 2386 2387 if (rc != 0) { 2388 printf("%s: could not map hw descriptors, error %d\n", 2389 sc->sc_dev.dv_xname, rc); 2390 goto err; 2391 } 2392 NEXT_ATTACH_STATE(sc, FINISH_DESC_MAP); 2393 2394 rc = bus_dmamap_create(sc->sc_dmat, sizeof(struct rtw_descs), 1, 2395 sizeof(struct rtw_descs), 0, 0, &sc->sc_desc_dmamap); 2396 2397 if (rc != 0) { 2398 printf("%s: could not create DMA map for hw descriptors, " 2399 "error %d\n", sc->sc_dev.dv_xname, rc); 2400 goto err; 2401 } 2402 NEXT_ATTACH_STATE(sc, FINISH_DESCMAP_CREATE); 2403 2404 rc = bus_dmamap_load(sc->sc_dmat, sc->sc_desc_dmamap, sc->sc_descs, 2405 sizeof(struct rtw_descs), NULL, 0); 2406 2407 if (rc != 0) { 2408 printf("%s: could not load DMA map for hw descriptors, " 2409 "error %d\n", sc->sc_dev.dv_xname, rc); 2410 goto err; 2411 } 2412 NEXT_ATTACH_STATE(sc, FINISH_DESCMAP_LOAD); 2413 2414 if (rtw_txctl_blk_setup_all(sc) != 0) 2415 goto err; 2416 NEXT_ATTACH_STATE(sc, FINISH_TXCTLBLK_SETUP); 2417 2418 rtw_txdesc_blk_setup_all(sc); 2419 2420 NEXT_ATTACH_STATE(sc, FINISH_TXDESCBLK_SETUP); 2421 2422 sc->sc_rxdesc = &sc->sc_descs->hd_rx[0]; 2423 2424 rtw_rxctls_setup(&sc->sc_rxctl); 2425 2426 for (pri = 0; pri < RTW_NTXPRI; pri++) { 2427 stc = &sc->sc_txctl_blk[pri]; 2428 2429 if ((rc = rtw_txdesc_dmamaps_create(sc->sc_dmat, 2430 &stc->stc_desc[0], stc->stc_ndesc)) != 0) { 2431 printf("%s: could not load DMA map for " 2432 "hw tx descriptors, error %d\n", 2433 sc->sc_dev.dv_xname, rc); 2434 goto err; 2435 } 2436 } 2437 2438 NEXT_ATTACH_STATE(sc, FINISH_TXMAPS_CREATE); 2439 if ((rc = rtw_rxdesc_dmamaps_create(sc->sc_dmat, &sc->sc_rxctl[0], 2440 RTW_RXQLEN)) != 0) { 2441 printf("%s: could not load DMA map for hw rx descriptors, " 2442 "error %d\n", sc->sc_dev.dv_xname, rc); 2443 goto err; 2444 } 2445 NEXT_ATTACH_STATE(sc, FINISH_RXMAPS_CREATE); 2446 2447 /* Reset the chip to a known state. */ 2448 if (rtw_reset(sc) != 0) 2449 goto err; 2450 NEXT_ATTACH_STATE(sc, FINISH_RESET); 2451 2452 sc->sc_rcr = RTW_READ(&sc->sc_regs, RTW_RCR); 2453 2454 if ((sc->sc_rcr & RTW_RCR_9356SEL) != 0) 2455 sc->sc_flags |= RTW_F_9356SROM; 2456 2457 if (rtw_srom_read(&sc->sc_regs, sc->sc_flags, &sc->sc_srom, 2458 &sc->sc_dev.dv_xname) != 0) 2459 goto err; 2460 2461 NEXT_ATTACH_STATE(sc, FINISH_READ_SROM); 2462 2463 if (rtw_srom_parse(&sc->sc_srom, &sc->sc_flags, &sc->sc_csthr, 2464 &sc->sc_rfchipid, &sc->sc_rcr, &sc->sc_locale, 2465 &sc->sc_dev.dv_xname) != 0) { 2466 printf("%s: attach failed, malformed serial ROM\n", 2467 sc->sc_dev.dv_xname); 2468 goto err; 2469 } 2470 2471 RTW_DPRINTF(("%s: CS threshold %u\n", sc->sc_dev.dv_xname, 2472 sc->sc_csthr)); 2473 2474 NEXT_ATTACH_STATE(sc, FINISH_PARSE_SROM); 2475 2476 sc->sc_rf = rtw_rf_attach(sc, sc->sc_rfchipid, rf_write, 2477 sc->sc_flags & RTW_F_DIGPHY); 2478 2479 if (sc->sc_rf == NULL) { 2480 printf("%s: attach failed, could not attach RF\n", 2481 sc->sc_dev.dv_xname); 2482 goto err; 2483 } 2484 2485#if 0 2486 if (rtw_identify_rf(&sc->sc_regs, &sc->sc_rftype, 2487 &sc->sc_dev.dv_xname) != 0) { 2488 printf("%s: attach failed, unknown RF unidentified\n", 2489 sc->sc_dev.dv_xname); 2490 goto err; 2491 } 2492#endif 2493 2494 NEXT_ATTACH_STATE(sc, FINISH_RF_ATTACH); 2495 2496 sc->sc_phydelay = rtw_check_phydelay(&sc->sc_regs, sc->sc_rcr); 2497 2498 RTW_DPRINTF(("%s: PHY delay %d\n", sc->sc_dev.dv_xname, 2499 sc->sc_phydelay)); 2500 2501 if (sc->sc_locale == RTW_LOCALE_UNKNOWN) 2502 rtw_identify_country(&sc->sc_regs, &sc->sc_locale, 2503 &sc->sc_dev.dv_xname); 2504 2505 rtw_init_channels(sc->sc_locale, &sc->sc_ic.ic_channels, 2506 &sc->sc_dev.dv_xname); 2507 2508 if (rtw_identify_sta(&sc->sc_regs, &sc->sc_ic.ic_myaddr, 2509 &sc->sc_dev.dv_xname) != 0) 2510 goto err; 2511 NEXT_ATTACH_STATE(sc, FINISH_ID_STA); 2512 2513 rtw_setifprops(&sc->sc_if, &sc->sc_dev.dv_xname, (void*)sc); 2514 2515 IFQ_SET_READY(&sc->sc_if.if_snd); 2516 2517 rtw_set80211props(&sc->sc_ic); 2518 2519 /* 2520 * Call MI attach routines. 2521 */ 2522 if_attach(&sc->sc_if); 2523 ieee80211_ifattach(&sc->sc_if); 2524 2525 rtw_set80211methods(&sc->sc_mtbl, &sc->sc_ic); 2526 2527 /* possibly we should fill in our own sc_send_prresp, since 2528 * the RTL8180 is probably sending probe responses in ad hoc 2529 * mode. 2530 */ 2531 2532 /* complete initialization */ 2533 ieee80211_media_init(&sc->sc_if, rtw_media_change, rtw_media_status); 2534 callout_init(&sc->sc_scan_ch); 2535 2536#if NBPFILTER > 0 2537 bpfattach2(&sc->sc_if, DLT_IEEE802_11_RADIO, 2538 sizeof(struct ieee80211_frame) + 64, &sc->sc_radiobpf); 2539#endif 2540 2541 rtw_establish_hooks(&sc->sc_hooks, &sc->sc_dev.dv_xname, (void*)sc); 2542 2543 rtw_init_radiotap(sc); 2544 2545 NEXT_ATTACH_STATE(sc, FINISHED); 2546 2547 return; 2548err: 2549 rtw_detach(sc); 2550 return; 2551} 2552 2553int 2554rtw_detach(struct rtw_softc *sc) 2555{ 2556 int pri; 2557 2558 switch (sc->sc_attach_state) { 2559 case FINISHED: 2560 rtw_disestablish_hooks(&sc->sc_hooks, &sc->sc_dev.dv_xname, 2561 (void*)sc); 2562 callout_stop(&sc->sc_scan_ch); 2563 ieee80211_ifdetach(&sc->sc_if); 2564 if_detach(&sc->sc_if); 2565 break; 2566 case FINISH_ID_STA: 2567 case FINISH_RF_ATTACH: 2568 rtw_rf_destroy(sc->sc_rf); 2569 sc->sc_rf = NULL; 2570 /*FALLTHROUGH*/ 2571 case FINISH_PARSE_SROM: 2572 case FINISH_READ_SROM: 2573 rtw_srom_free(&sc->sc_srom); 2574 /*FALLTHROUGH*/ 2575 case FINISH_RESET: 2576 case FINISH_RXMAPS_CREATE: 2577 rtw_rxdesc_dmamaps_destroy(sc->sc_dmat, &sc->sc_rxctl[0], 2578 RTW_RXQLEN); 2579 /*FALLTHROUGH*/ 2580 case FINISH_TXMAPS_CREATE: 2581 for (pri = 0; pri < RTW_NTXPRI; pri++) { 2582 rtw_txdesc_dmamaps_destroy(sc->sc_dmat, 2583 sc->sc_txctl_blk[pri].stc_desc, 2584 sc->sc_txctl_blk[pri].stc_ndesc); 2585 } 2586 /*FALLTHROUGH*/ 2587 case FINISH_TXDESCBLK_SETUP: 2588 case FINISH_TXCTLBLK_SETUP: 2589 rtw_txctl_blk_cleanup_all(sc); 2590 /*FALLTHROUGH*/ 2591 case FINISH_DESCMAP_LOAD: 2592 bus_dmamap_unload(sc->sc_dmat, sc->sc_desc_dmamap); 2593 /*FALLTHROUGH*/ 2594 case FINISH_DESCMAP_CREATE: 2595 bus_dmamap_destroy(sc->sc_dmat, sc->sc_desc_dmamap); 2596 /*FALLTHROUGH*/ 2597 case FINISH_DESC_MAP: 2598 bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_descs, 2599 sizeof(struct rtw_descs)); 2600 /*FALLTHROUGH*/ 2601 case FINISH_DESC_ALLOC: 2602 bus_dmamem_free(sc->sc_dmat, &sc->sc_desc_segs, 2603 sc->sc_desc_nsegs); 2604 /*FALLTHROUGH*/ 2605 case DETACHED: 2606 NEXT_ATTACH_STATE(sc, DETACHED); 2607 break; 2608 } 2609 return 0; 2610} 2611 2612int 2613rtw_activate(struct device *self, enum devact act) 2614{ 2615 struct rtw_softc *sc = (struct rtw_softc *)self; 2616 int rc = 0, s; 2617 2618 s = splnet(); 2619 switch (act) { 2620 case DVACT_ACTIVATE: 2621 rc = EOPNOTSUPP; 2622 break; 2623 2624 case DVACT_DEACTIVATE: 2625 if_deactivate(&sc->sc_ic.ic_if); 2626 break; 2627 } 2628 splx(s); 2629 return rc; 2630} 2631