1 /* $OpenBSD: rtw.c,v 1.73 2009/03/29 21:53:52 sthen Exp $ */ 2 /* $NetBSD: rtw.c,v 1.29 2004/12/27 19:49:16 dyoung Exp $ */ 3 4 /*- 5 * Copyright (c) 2004, 2005 David Young. All rights reserved. 6 * 7 * Programmed for NetBSD by David Young. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. The name of David Young may not be used to endorse or promote 18 * products derived from this software without specific prior 19 * written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY David Young ``AS IS'' AND ANY 22 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 23 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 24 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David 25 * Young BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 26 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 27 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 29 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 32 * OF SUCH DAMAGE. 33 */ 34 /* 35 * Device driver for the Realtek RTL8180 802.11 MAC/BBP. 36 */ 37 38 #include <sys/cdefs.h> 39 #include "bpfilter.h" 40 41 #include <sys/param.h> 42 #include <sys/systm.h> 43 #include <sys/mbuf.h> 44 #include <sys/malloc.h> 45 #include <sys/kernel.h> 46 #include <sys/ioctl.h> 47 #include <sys/socket.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 60 #if NBPFILTER > 0 61 #include <net/bpf.h> 62 #endif 63 64 #ifdef INET 65 #include <netinet/in.h> 66 #include <netinet/if_ether.h> 67 #endif 68 69 #include <net80211/ieee80211_var.h> 70 #include <net80211/ieee80211_radiotap.h> 71 72 #include <dev/ic/rtwreg.h> 73 #include <dev/ic/rtwvar.h> 74 #include <dev/ic/max2820reg.h> 75 #include <dev/ic/sa2400reg.h> 76 #include <dev/ic/si4136reg.h> 77 #include <dev/ic/rtl8225reg.h> 78 #include <dev/ic/smc93cx6var.h> 79 80 int rtw_rfprog_fallback = 0; 81 int rtw_do_chip_reset = 0; 82 int rtw_dwelltime = 200; /* milliseconds per channel */ 83 int rtw_macbangbits_timeout = 100; 84 85 #ifdef RTW_DEBUG 86 int rtw_debug = 0; 87 int rtw_rxbufs_limit = RTW_RXQLEN; 88 #endif /* RTW_DEBUG */ 89 90 void rtw_start(struct ifnet *); 91 void rtw_txdesc_blk_init_all(struct rtw_txdesc_blk *); 92 void rtw_txsoft_blk_init_all(struct rtw_txsoft_blk *); 93 void rtw_txdesc_blk_init(struct rtw_txdesc_blk *); 94 void rtw_txdescs_sync(struct rtw_txdesc_blk *, u_int, u_int, int); 95 void rtw_txring_fixup(struct rtw_softc *); 96 void rtw_rxbufs_release(bus_dma_tag_t, struct rtw_rxsoft *); 97 void rtw_rxdesc_init(struct rtw_rxdesc_blk *, struct rtw_rxsoft *, int, int); 98 void rtw_rxring_fixup(struct rtw_softc *); 99 void rtw_io_enable(struct rtw_regs *, u_int8_t, int); 100 void rtw_intr_rx(struct rtw_softc *, u_int16_t); 101 #ifndef IEEE80211_STA_ONLY 102 void rtw_intr_beacon(struct rtw_softc *, u_int16_t); 103 void rtw_intr_atim(struct rtw_softc *); 104 #endif 105 void rtw_transmit_config(struct rtw_softc *); 106 void rtw_pktfilt_load(struct rtw_softc *); 107 void rtw_start(struct ifnet *); 108 void rtw_watchdog(struct ifnet *); 109 void rtw_next_scan(void *); 110 #ifndef IEEE80211_STA_ONLY 111 void rtw_recv_mgmt(struct ieee80211com *, struct mbuf *, 112 struct ieee80211_node *, struct ieee80211_rxinfo *, int); 113 #endif 114 struct ieee80211_node *rtw_node_alloc(struct ieee80211com *); 115 void rtw_node_free(struct ieee80211com *, struct ieee80211_node *); 116 void rtw_media_status(struct ifnet *, struct ifmediareq *); 117 void rtw_txsoft_blk_cleanup_all(struct rtw_softc *); 118 void rtw_txdesc_blk_setup(struct rtw_txdesc_blk *, struct rtw_txdesc *, 119 u_int, bus_addr_t, bus_addr_t); 120 void rtw_txdesc_blk_setup_all(struct rtw_softc *); 121 void rtw_intr_tx(struct rtw_softc *, u_int16_t); 122 void rtw_intr_ioerror(struct rtw_softc *, u_int16_t); 123 void rtw_intr_timeout(struct rtw_softc *); 124 void rtw_stop(struct ifnet *, int); 125 void rtw_maxim_pwrstate(struct rtw_regs *, enum rtw_pwrstate, int, int); 126 void rtw_philips_pwrstate(struct rtw_regs *, enum rtw_pwrstate, int, int); 127 void rtw_rtl_pwrstate(struct rtw_regs *, enum rtw_pwrstate, int, int); 128 void rtw_pwrstate0(struct rtw_softc *, enum rtw_pwrstate, int, int); 129 void rtw_join_bss(struct rtw_softc *, u_int8_t *, u_int16_t); 130 void rtw_set_access1(struct rtw_regs *, enum rtw_access); 131 int rtw_srom_parse(struct rtw_softc *); 132 int rtw_srom_read(struct rtw_regs *, u_int32_t, struct rtw_srom *, 133 const char *); 134 void rtw_set_rfprog(struct rtw_regs *, int, const char *); 135 u_int8_t rtw_chan2txpower(struct rtw_srom *, struct ieee80211com *, 136 struct ieee80211_channel *); 137 int rtw_txsoft_blk_init(struct rtw_txsoft_blk *); 138 int rtw_rxsoft_init_all(bus_dma_tag_t, struct rtw_rxsoft *, 139 int *, const char *); 140 void rtw_txsoft_release(bus_dma_tag_t, struct ieee80211com *, 141 struct rtw_txsoft *); 142 void rtw_txsofts_release(bus_dma_tag_t, struct ieee80211com *, 143 struct rtw_txsoft_blk *); 144 void rtw_hwring_setup(struct rtw_softc *); 145 int rtw_swring_setup(struct rtw_softc *); 146 void rtw_txdescs_reset(struct rtw_softc *); 147 void rtw_rfmd_pwrstate(struct rtw_regs *, enum rtw_pwrstate, int, int); 148 int rtw_pwrstate(struct rtw_softc *, enum rtw_pwrstate); 149 int rtw_tune(struct rtw_softc *); 150 void rtw_set_nettype(struct rtw_softc *, enum ieee80211_opmode); 151 int rtw_compute_duration1(int, int, uint32_t, int, struct rtw_duration *); 152 int rtw_compute_duration(struct ieee80211_frame *, int, uint32_t, int, 153 int, struct rtw_duration *, struct rtw_duration *, int *, int); 154 int rtw_init(struct ifnet *); 155 int rtw_ioctl(struct ifnet *, u_long, caddr_t); 156 int rtw_seg_too_short(bus_dmamap_t); 157 struct mbuf *rtw_dmamap_load_txbuf(bus_dma_tag_t, bus_dmamap_t, struct mbuf *, 158 u_int, short *, const char *); 159 int rtw_newstate(struct ieee80211com *, enum ieee80211_state, int); 160 int rtw_media_change(struct ifnet *); 161 int rtw_txsoft_blk_setup_all(struct rtw_softc *); 162 int rtw_rf_attach(struct rtw_softc *, int); 163 u_int8_t rtw_check_phydelay(struct rtw_regs *, u_int32_t); 164 int rtw_chip_reset1(struct rtw_regs *, const char *); 165 int rtw_chip_reset(struct rtw_regs *, const char *); 166 int rtw_recall_eeprom(struct rtw_regs *, const char *); 167 int rtw_reset(struct rtw_softc *); 168 void rtw_reset_oactive(struct rtw_softc *); 169 int rtw_txdesc_dmamaps_create(bus_dma_tag_t, struct rtw_txsoft *, u_int); 170 int rtw_rxdesc_dmamaps_create(bus_dma_tag_t, struct rtw_rxsoft *, u_int); 171 void rtw_rxdesc_dmamaps_destroy(bus_dma_tag_t, struct rtw_rxsoft *, u_int); 172 void rtw_txdesc_dmamaps_destroy(bus_dma_tag_t, struct rtw_txsoft *, u_int); 173 void rtw_identify_country(struct rtw_regs *, enum rtw_locale *); 174 int rtw_identify_sta(struct rtw_regs *, u_int8_t (*)[], const char *); 175 void rtw_rxdescs_sync(struct rtw_rxdesc_blk *, int, int, int); 176 int rtw_rxsoft_alloc(bus_dma_tag_t, struct rtw_rxsoft *); 177 void rtw_collect_txpkt(struct rtw_softc *, struct rtw_txdesc_blk *, 178 struct rtw_txsoft *, int); 179 void rtw_collect_txring(struct rtw_softc *, struct rtw_txsoft_blk *, 180 struct rtw_txdesc_blk *, int); 181 void rtw_suspend_ticks(struct rtw_softc *); 182 void rtw_resume_ticks(struct rtw_softc *); 183 void rtw_enable_interrupts(struct rtw_softc *); 184 int rtw_dequeue(struct ifnet *, struct rtw_txsoft_blk **, 185 struct rtw_txdesc_blk **, struct mbuf **, 186 struct ieee80211_node **); 187 void rtw_establish_hooks(struct rtw_hooks *, const char *, void *); 188 void rtw_disestablish_hooks(struct rtw_hooks *, const char *, void *); 189 int rtw_txsoft_blk_setup(struct rtw_txsoft_blk *, u_int); 190 void rtw_rxdesc_init_all(struct rtw_rxdesc_blk *, struct rtw_rxsoft *, 191 int); 192 int rtw_txring_choose(struct rtw_softc *, struct rtw_txsoft_blk **, 193 struct rtw_txdesc_blk **, int); 194 u_int rtw_txring_next(struct rtw_regs *, struct rtw_txdesc_blk *); 195 struct mbuf *rtw_80211_dequeue(struct rtw_softc *, struct ifqueue *, int, 196 struct rtw_txsoft_blk **, struct rtw_txdesc_blk **, 197 struct ieee80211_node **, short *); 198 uint64_t rtw_tsf_extend(struct rtw_regs *, u_int32_t); 199 #ifndef IEEE80211_STA_ONLY 200 void rtw_ibss_merge(struct rtw_softc *, struct ieee80211_node *, 201 u_int32_t); 202 #endif 203 void rtw_idle(struct rtw_regs *); 204 void rtw_led_attach(struct rtw_led_state *, void *); 205 void rtw_led_init(struct rtw_regs *); 206 void rtw_led_slowblink(void *); 207 void rtw_led_fastblink(void *); 208 void rtw_led_set(struct rtw_led_state *, struct rtw_regs *, u_int); 209 void rtw_led_newstate(struct rtw_softc *, enum ieee80211_state); 210 211 int rtw_phy_init(struct rtw_softc *); 212 int rtw_bbp_preinit(struct rtw_regs *, u_int, int, u_int); 213 int rtw_bbp_init(struct rtw_regs *, struct rtw_bbpset *, int, 214 int, u_int8_t, u_int); 215 void rtw_verify_syna(u_int, u_int32_t); 216 int rtw_sa2400_pwrstate(struct rtw_softc *, enum rtw_pwrstate); 217 int rtw_sa2400_txpower(struct rtw_softc *, u_int8_t); 218 int rtw_sa2400_tune(struct rtw_softc *, u_int); 219 int rtw_sa2400_vcocal_start(struct rtw_softc *, int); 220 int rtw_sa2400_vco_calibration(struct rtw_softc *); 221 int rtw_sa2400_filter_calibration(struct rtw_softc *); 222 int rtw_sa2400_dc_calibration(struct rtw_softc *); 223 int rtw_sa2400_calibrate(struct rtw_softc *, u_int); 224 int rtw_sa2400_init(struct rtw_softc *, u_int, u_int8_t, 225 enum rtw_pwrstate); 226 int rtw_max2820_pwrstate(struct rtw_softc *, enum rtw_pwrstate); 227 int rtw_max2820_init(struct rtw_softc *, u_int, u_int8_t, 228 enum rtw_pwrstate); 229 int rtw_max2820_txpower(struct rtw_softc *, u_int8_t); 230 int rtw_max2820_tune(struct rtw_softc *, u_int); 231 int rtw_rtl8225_pwrstate(struct rtw_softc *, enum rtw_pwrstate); 232 int rtw_rtl8225_init(struct rtw_softc *, u_int, u_int8_t, 233 enum rtw_pwrstate); 234 int rtw_rtl8225_txpower(struct rtw_softc *, u_int8_t); 235 int rtw_rtl8225_tune(struct rtw_softc *, u_int); 236 int rtw_rtl8255_pwrstate(struct rtw_softc *, enum rtw_pwrstate); 237 int rtw_rtl8255_init(struct rtw_softc *, u_int, u_int8_t, 238 enum rtw_pwrstate); 239 int rtw_rtl8255_txpower(struct rtw_softc *, u_int8_t); 240 int rtw_rtl8255_tune(struct rtw_softc *, u_int); 241 int rtw_grf5101_pwrstate(struct rtw_softc *, enum rtw_pwrstate); 242 int rtw_grf5101_init(struct rtw_softc *, u_int, u_int8_t, 243 enum rtw_pwrstate); 244 int rtw_grf5101_txpower(struct rtw_softc *, u_int8_t); 245 int rtw_grf5101_tune(struct rtw_softc *, u_int); 246 int rtw_rf_hostwrite(struct rtw_softc *, u_int, u_int32_t); 247 int rtw_rf_macwrite(struct rtw_softc *, u_int, u_int32_t); 248 int rtw_bbp_write(struct rtw_regs *, u_int, u_int); 249 u_int32_t rtw_grf5101_host_crypt(u_int, u_int32_t); 250 u_int32_t rtw_maxim_swizzle(u_int, uint32_t); 251 u_int32_t rtw_grf5101_mac_crypt(u_int, u_int32_t); 252 void rtw_rf_hostbangbits(struct rtw_regs *, u_int32_t, int, u_int); 253 void rtw_rf_rtl8225_hostbangbits(struct rtw_regs *, u_int32_t, int, u_int); 254 int rtw_rf_macbangbits(struct rtw_regs *, u_int32_t); 255 256 u_int8_t rtw_read8(void *, u_int32_t); 257 u_int16_t rtw_read16(void *, u_int32_t); 258 u_int32_t rtw_read32(void *, u_int32_t); 259 void rtw_write8(void *, u_int32_t, u_int8_t); 260 void rtw_write16(void *, u_int32_t, u_int16_t); 261 void rtw_write32(void *, u_int32_t, u_int32_t); 262 void rtw_barrier(void *, u_int32_t, u_int32_t, int); 263 264 #ifdef RTW_DEBUG 265 void rtw_print_txdesc(struct rtw_softc *, const char *, 266 struct rtw_txsoft *, struct rtw_txdesc_blk *, int); 267 const char *rtw_access_string(enum rtw_access); 268 void rtw_dump_rings(struct rtw_softc *); 269 void rtw_print_txdesc(struct rtw_softc *, const char *, 270 struct rtw_txsoft *, struct rtw_txdesc_blk *, int); 271 #endif 272 273 struct cfdriver rtw_cd = { 274 NULL, "rtw", DV_IFNET 275 }; 276 277 void 278 rtw_continuous_tx_enable(struct rtw_softc *sc, int enable) 279 { 280 struct rtw_regs *regs = &sc->sc_regs; 281 282 u_int32_t tcr; 283 tcr = RTW_READ(regs, RTW_TCR); 284 tcr &= ~RTW_TCR_LBK_MASK; 285 if (enable) 286 tcr |= RTW_TCR_LBK_CONT; 287 else 288 tcr |= RTW_TCR_LBK_NORMAL; 289 RTW_WRITE(regs, RTW_TCR, tcr); 290 RTW_SYNC(regs, RTW_TCR, RTW_TCR); 291 rtw_set_access(regs, RTW_ACCESS_ANAPARM); 292 rtw_txdac_enable(sc, !enable); 293 rtw_set_access(regs, RTW_ACCESS_ANAPARM);/* XXX Voodoo from Linux. */ 294 rtw_set_access(regs, RTW_ACCESS_NONE); 295 } 296 297 #ifdef RTW_DEBUG 298 const char * 299 rtw_access_string(enum rtw_access access) 300 { 301 switch (access) { 302 case RTW_ACCESS_NONE: 303 return "none"; 304 case RTW_ACCESS_CONFIG: 305 return "config"; 306 case RTW_ACCESS_ANAPARM: 307 return "anaparm"; 308 default: 309 return "unknown"; 310 } 311 } 312 #endif 313 314 void 315 rtw_set_access1(struct rtw_regs *regs, enum rtw_access naccess) 316 { 317 KASSERT(naccess >= RTW_ACCESS_NONE && naccess <= RTW_ACCESS_ANAPARM); 318 KASSERT(regs->r_access >= RTW_ACCESS_NONE && 319 regs->r_access <= RTW_ACCESS_ANAPARM); 320 321 if (naccess == regs->r_access) 322 return; 323 324 switch (naccess) { 325 case RTW_ACCESS_NONE: 326 switch (regs->r_access) { 327 case RTW_ACCESS_ANAPARM: 328 rtw_anaparm_enable(regs, 0); 329 /*FALLTHROUGH*/ 330 case RTW_ACCESS_CONFIG: 331 rtw_config0123_enable(regs, 0); 332 /*FALLTHROUGH*/ 333 case RTW_ACCESS_NONE: 334 break; 335 } 336 break; 337 case RTW_ACCESS_CONFIG: 338 switch (regs->r_access) { 339 case RTW_ACCESS_NONE: 340 rtw_config0123_enable(regs, 1); 341 /*FALLTHROUGH*/ 342 case RTW_ACCESS_CONFIG: 343 break; 344 case RTW_ACCESS_ANAPARM: 345 rtw_anaparm_enable(regs, 0); 346 break; 347 } 348 break; 349 case RTW_ACCESS_ANAPARM: 350 switch (regs->r_access) { 351 case RTW_ACCESS_NONE: 352 rtw_config0123_enable(regs, 1); 353 /*FALLTHROUGH*/ 354 case RTW_ACCESS_CONFIG: 355 rtw_anaparm_enable(regs, 1); 356 /*FALLTHROUGH*/ 357 case RTW_ACCESS_ANAPARM: 358 break; 359 } 360 break; 361 } 362 } 363 364 void 365 rtw_set_access(struct rtw_regs *regs, enum rtw_access access) 366 { 367 rtw_set_access1(regs, access); 368 RTW_DPRINTF(RTW_DEBUG_ACCESS, 369 ("%s: access %s -> %s\n",__func__, 370 rtw_access_string(regs->r_access), 371 rtw_access_string(access))); 372 regs->r_access = access; 373 } 374 375 /* 376 * Enable registers, switch register banks. 377 */ 378 void 379 rtw_config0123_enable(struct rtw_regs *regs, int enable) 380 { 381 u_int8_t ecr; 382 ecr = RTW_READ8(regs, RTW_9346CR); 383 ecr &= ~(RTW_9346CR_EEM_MASK | RTW_9346CR_EECS | RTW_9346CR_EESK); 384 if (enable) 385 ecr |= RTW_9346CR_EEM_CONFIG; 386 else { 387 RTW_WBW(regs, RTW_9346CR, MAX(RTW_CONFIG0, RTW_CONFIG3)); 388 ecr |= RTW_9346CR_EEM_NORMAL; 389 } 390 RTW_WRITE8(regs, RTW_9346CR, ecr); 391 RTW_SYNC(regs, RTW_9346CR, RTW_9346CR); 392 } 393 394 /* requires rtw_config0123_enable(, 1) */ 395 void 396 rtw_anaparm_enable(struct rtw_regs *regs, int enable) 397 { 398 u_int8_t cfg3; 399 400 cfg3 = RTW_READ8(regs, RTW_CONFIG3); 401 cfg3 |= RTW_CONFIG3_CLKRUNEN; 402 if (enable) 403 cfg3 |= RTW_CONFIG3_PARMEN; 404 else 405 cfg3 &= ~RTW_CONFIG3_PARMEN; 406 RTW_WRITE8(regs, RTW_CONFIG3, cfg3); 407 RTW_SYNC(regs, RTW_CONFIG3, RTW_CONFIG3); 408 } 409 410 /* requires rtw_anaparm_enable(, 1) */ 411 void 412 rtw_txdac_enable(struct rtw_softc *sc, int enable) 413 { 414 u_int32_t anaparm; 415 struct rtw_regs *regs = &sc->sc_regs; 416 417 anaparm = RTW_READ(regs, RTW_ANAPARM_0); 418 if (enable) 419 anaparm &= ~RTW_ANAPARM_TXDACOFF; 420 else 421 anaparm |= RTW_ANAPARM_TXDACOFF; 422 RTW_WRITE(regs, RTW_ANAPARM_0, anaparm); 423 RTW_SYNC(regs, RTW_ANAPARM_0, RTW_ANAPARM_0); 424 } 425 426 int 427 rtw_chip_reset1(struct rtw_regs *regs, const char *dvname) 428 { 429 u_int8_t cr; 430 int i; 431 432 RTW_WRITE8(regs, RTW_CR, RTW_CR_RST); 433 434 RTW_WBR(regs, RTW_CR, RTW_CR); 435 436 for (i = 0; i < 1000; i++) { 437 if ((cr = RTW_READ8(regs, RTW_CR) & RTW_CR_RST) == 0) { 438 RTW_DPRINTF(RTW_DEBUG_RESET, 439 ("%s: reset in %dus\n", dvname, i)); 440 return 0; 441 } 442 RTW_RBR(regs, RTW_CR, RTW_CR); 443 DELAY(10); /* 10us */ 444 } 445 446 printf("\n%s: reset failed\n", dvname); 447 return ETIMEDOUT; 448 } 449 450 int 451 rtw_chip_reset(struct rtw_regs *regs, const char *dvname) 452 { 453 uint32_t tcr; 454 455 /* from Linux driver */ 456 tcr = RTW_TCR_CWMIN | RTW_TCR_MXDMA_2048 | 457 LSHIFT(7, RTW_TCR_SRL_MASK) | LSHIFT(7, RTW_TCR_LRL_MASK); 458 459 RTW_WRITE(regs, RTW_TCR, tcr); 460 461 RTW_WBW(regs, RTW_CR, RTW_TCR); 462 463 return rtw_chip_reset1(regs, dvname); 464 } 465 466 int 467 rtw_recall_eeprom(struct rtw_regs *regs, const char *dvname) 468 { 469 int i; 470 u_int8_t ecr; 471 472 ecr = RTW_READ8(regs, RTW_9346CR); 473 ecr = (ecr & ~RTW_9346CR_EEM_MASK) | RTW_9346CR_EEM_AUTOLOAD; 474 RTW_WRITE8(regs, RTW_9346CR, ecr); 475 476 RTW_WBR(regs, RTW_9346CR, RTW_9346CR); 477 478 /* wait 10ms for completion */ 479 for (i = 0; i < 50; i++) { 480 ecr = RTW_READ8(regs, RTW_9346CR); 481 if ((ecr & RTW_9346CR_EEM_MASK) == RTW_9346CR_EEM_NORMAL) { 482 RTW_DPRINTF(RTW_DEBUG_RESET, 483 ("%s: recall EEPROM in %dus\n", dvname, i * 200)); 484 return (0); 485 } 486 RTW_RBR(regs, RTW_9346CR, RTW_9346CR); 487 DELAY(200); 488 } 489 490 printf("\n%s: could not recall EEPROM in %dus\n", dvname, i * 200); 491 492 return (ETIMEDOUT); 493 } 494 495 int 496 rtw_reset(struct rtw_softc *sc) 497 { 498 int rc; 499 uint8_t config1; 500 501 if ((rc = rtw_chip_reset(&sc->sc_regs, sc->sc_dev.dv_xname)) != 0) 502 return rc; 503 504 if ((rc = rtw_recall_eeprom(&sc->sc_regs, sc->sc_dev.dv_xname)) != 0) 505 ; 506 507 config1 = RTW_READ8(&sc->sc_regs, RTW_CONFIG1); 508 RTW_WRITE8(&sc->sc_regs, RTW_CONFIG1, config1 & ~RTW_CONFIG1_PMEN); 509 /* TBD turn off maximum power saving? */ 510 511 return 0; 512 } 513 514 int 515 rtw_txdesc_dmamaps_create(bus_dma_tag_t dmat, struct rtw_txsoft *descs, 516 u_int ndescs) 517 { 518 int i, rc = 0; 519 for (i = 0; i < ndescs; i++) { 520 rc = bus_dmamap_create(dmat, MCLBYTES, RTW_MAXPKTSEGS, MCLBYTES, 521 0, 0, &descs[i].ts_dmamap); 522 if (rc != 0) 523 break; 524 } 525 return rc; 526 } 527 528 int 529 rtw_rxdesc_dmamaps_create(bus_dma_tag_t dmat, struct rtw_rxsoft *descs, 530 u_int ndescs) 531 { 532 int i, rc = 0; 533 for (i = 0; i < ndescs; i++) { 534 rc = bus_dmamap_create(dmat, MCLBYTES, 1, MCLBYTES, 0, 0, 535 &descs[i].rs_dmamap); 536 if (rc != 0) 537 break; 538 } 539 return rc; 540 } 541 542 void 543 rtw_rxdesc_dmamaps_destroy(bus_dma_tag_t dmat, struct rtw_rxsoft *descs, 544 u_int ndescs) 545 { 546 int i; 547 for (i = 0; i < ndescs; i++) { 548 if (descs[i].rs_dmamap != NULL) 549 bus_dmamap_destroy(dmat, descs[i].rs_dmamap); 550 } 551 } 552 553 void 554 rtw_txdesc_dmamaps_destroy(bus_dma_tag_t dmat, struct rtw_txsoft *descs, 555 u_int ndescs) 556 { 557 int i; 558 for (i = 0; i < ndescs; i++) { 559 if (descs[i].ts_dmamap != NULL) 560 bus_dmamap_destroy(dmat, descs[i].ts_dmamap); 561 } 562 } 563 564 int 565 rtw_srom_parse(struct rtw_softc *sc) 566 { 567 int i; 568 struct rtw_srom *sr = &sc->sc_srom; 569 u_int32_t *flags = &sc->sc_flags; 570 u_int8_t *cs_threshold = &sc->sc_csthr; 571 int *rfchipid = &sc->sc_rfchipid; 572 u_int32_t *rcr = &sc->sc_rcr; 573 enum rtw_locale *locale = &sc->sc_locale; 574 u_int16_t version; 575 u_int8_t mac[IEEE80211_ADDR_LEN]; 576 577 *flags &= ~(RTW_F_DIGPHY|RTW_F_DFLANTB|RTW_F_ANTDIV); 578 *rcr &= ~(RTW_RCR_ENCS1 | RTW_RCR_ENCS2); 579 580 version = RTW_SR_GET16(sr, RTW_SR_VERSION); 581 RTW_DPRINTF(RTW_DEBUG_ATTACH, 582 ("%s: SROM %d.%d\n", sc->sc_dev.dv_xname, version >> 8, 583 version & 0xff)); 584 585 if (version <= 0x0101) { 586 printf(" is not understood, limping along with defaults "); 587 *flags |= (RTW_F_DIGPHY|RTW_F_ANTDIV); 588 *cs_threshold = RTW_SR_ENERGYDETTHR_DEFAULT; 589 *rcr |= RTW_RCR_ENCS1; 590 *rfchipid = RTW_RFCHIPID_PHILIPS; 591 return 0; 592 } 593 594 for (i = 0; i < IEEE80211_ADDR_LEN; i++) 595 mac[i] = RTW_SR_GET(sr, RTW_SR_MAC + i); 596 597 RTW_DPRINTF(RTW_DEBUG_ATTACH, 598 ("%s: EEPROM MAC %s\n", sc->sc_dev.dv_xname, ether_sprintf(mac))); 599 600 *cs_threshold = RTW_SR_GET(sr, RTW_SR_ENERGYDETTHR); 601 602 if ((RTW_SR_GET(sr, RTW_SR_CONFIG2) & RTW8180_CONFIG2_ANT) != 0) 603 *flags |= RTW_F_ANTDIV; 604 605 /* Note well: the sense of the RTW_SR_RFPARM_DIGPHY bit seems 606 * to be reversed. 607 */ 608 if ((RTW_SR_GET(sr, RTW_SR_RFPARM) & RTW_SR_RFPARM_DIGPHY) == 0) 609 *flags |= RTW_F_DIGPHY; 610 if ((RTW_SR_GET(sr, RTW_SR_RFPARM) & RTW_SR_RFPARM_DFLANTB) != 0) 611 *flags |= RTW_F_DFLANTB; 612 613 *rcr |= LSHIFT(MASK_AND_RSHIFT(RTW_SR_GET(sr, RTW_SR_RFPARM), 614 RTW_SR_RFPARM_CS_MASK), RTW_RCR_ENCS1); 615 616 *rfchipid = RTW_SR_GET(sr, RTW_SR_RFCHIPID); 617 618 if (sc->sc_flags & RTW_F_RTL8185) { 619 *locale = RTW_LOCALE_UNKNOWN; 620 return (0); 621 } 622 623 switch (RTW_SR_GET(sr, RTW_SR_CONFIG0) & RTW8180_CONFIG0_GL_MASK) { 624 case RTW8180_CONFIG0_GL_USA: 625 *locale = RTW_LOCALE_USA; 626 break; 627 case RTW8180_CONFIG0_GL_EUROPE: 628 *locale = RTW_LOCALE_EUROPE; 629 break; 630 case RTW8180_CONFIG0_GL_JAPAN: 631 case RTW8180_CONFIG0_GL_JAPAN2: 632 *locale = RTW_LOCALE_JAPAN; 633 break; 634 default: 635 *locale = RTW_LOCALE_UNKNOWN; 636 break; 637 } 638 return 0; 639 } 640 641 /* Returns -1 on failure. */ 642 int 643 rtw_srom_read(struct rtw_regs *regs, u_int32_t flags, struct rtw_srom *sr, 644 const char *dvname) 645 { 646 int rc; 647 struct seeprom_descriptor sd; 648 u_int8_t ecr; 649 650 bzero(&sd, sizeof(sd)); 651 652 ecr = RTW_READ8(regs, RTW_9346CR); 653 654 if ((flags & RTW_F_9356SROM) != 0) { 655 RTW_DPRINTF(RTW_DEBUG_ATTACH, ("%s: 93c56 SROM\n", dvname)); 656 sr->sr_size = 256; 657 sd.sd_chip = C56_66; 658 } else { 659 RTW_DPRINTF(RTW_DEBUG_ATTACH, ("%s: 93c46 SROM\n", dvname)); 660 sr->sr_size = 128; 661 sd.sd_chip = C46; 662 } 663 664 ecr &= ~(RTW_9346CR_EEDI | RTW_9346CR_EEDO | RTW_9346CR_EESK | 665 RTW_9346CR_EEM_MASK | RTW_9346CR_EECS); 666 ecr |= RTW_9346CR_EEM_PROGRAM; 667 668 RTW_WRITE8(regs, RTW_9346CR, ecr); 669 670 sr->sr_content = malloc(sr->sr_size, M_DEVBUF, M_NOWAIT | M_ZERO); 671 672 if (sr->sr_content == NULL) { 673 printf("%s: unable to allocate SROM buffer\n", dvname); 674 return ENOMEM; 675 } 676 677 /* RTL8180 has a single 8-bit register for controlling the 678 * 93cx6 SROM. There is no "ready" bit. The RTL8180 679 * input/output sense is the reverse of read_seeprom's. 680 */ 681 sd.sd_tag = regs->r_bt; 682 sd.sd_bsh = regs->r_bh; 683 sd.sd_regsize = 1; 684 sd.sd_control_offset = RTW_9346CR; 685 sd.sd_status_offset = RTW_9346CR; 686 sd.sd_dataout_offset = RTW_9346CR; 687 sd.sd_CK = RTW_9346CR_EESK; 688 sd.sd_CS = RTW_9346CR_EECS; 689 sd.sd_DI = RTW_9346CR_EEDO; 690 sd.sd_DO = RTW_9346CR_EEDI; 691 /* make read_seeprom enter EEPROM read/write mode */ 692 sd.sd_MS = ecr; 693 sd.sd_RDY = 0; 694 695 /* TBD bus barriers */ 696 if (!read_seeprom(&sd, sr->sr_content, 0, sr->sr_size/2)) { 697 printf("\n%s: could not read SROM\n", dvname); 698 free(sr->sr_content, M_DEVBUF); 699 sr->sr_content = NULL; 700 return -1; /* XXX */ 701 } 702 703 /* end EEPROM read/write mode */ 704 RTW_WRITE8(regs, RTW_9346CR, 705 (ecr & ~RTW_9346CR_EEM_MASK) | RTW_9346CR_EEM_NORMAL); 706 RTW_WBRW(regs, RTW_9346CR, RTW_9346CR); 707 708 if ((rc = rtw_recall_eeprom(regs, dvname)) != 0) 709 return rc; 710 711 #ifdef RTW_DEBUG 712 { 713 int i; 714 RTW_DPRINTF(RTW_DEBUG_ATTACH, 715 ("\n%s: serial ROM:\n\t", dvname)); 716 for (i = 0; i < sr->sr_size/2; i++) { 717 if (((i % 8) == 0) && (i != 0)) 718 RTW_DPRINTF(RTW_DEBUG_ATTACH, ("\n\t")); 719 RTW_DPRINTF(RTW_DEBUG_ATTACH, 720 (" %04x", sr->sr_content[i])); 721 } 722 RTW_DPRINTF(RTW_DEBUG_ATTACH, ("\n")); 723 } 724 #endif /* RTW_DEBUG */ 725 return 0; 726 } 727 728 void 729 rtw_set_rfprog(struct rtw_regs *regs, int rfchipid, 730 const char *dvname) 731 { 732 u_int8_t cfg4; 733 const char *method; 734 735 cfg4 = RTW_READ8(regs, RTW_CONFIG4) & ~RTW_CONFIG4_RFTYPE_MASK; 736 737 switch (rfchipid) { 738 default: 739 cfg4 |= LSHIFT(rtw_rfprog_fallback, RTW_CONFIG4_RFTYPE_MASK); 740 method = "fallback"; 741 break; 742 case RTW_RFCHIPID_INTERSIL: 743 cfg4 |= RTW_CONFIG4_RFTYPE_INTERSIL; 744 method = "Intersil"; 745 break; 746 case RTW_RFCHIPID_PHILIPS: 747 cfg4 |= RTW_CONFIG4_RFTYPE_PHILIPS; 748 method = "Philips"; 749 break; 750 case RTW_RFCHIPID_RFMD2948: 751 cfg4 |= RTW_CONFIG4_RFTYPE_RFMD; 752 method = "RFMD"; 753 break; 754 } 755 756 RTW_WRITE8(regs, RTW_CONFIG4, cfg4); 757 758 RTW_WBR(regs, RTW_CONFIG4, RTW_CONFIG4); 759 760 RTW_DPRINTF(RTW_DEBUG_INIT, 761 ("%s: %s RF programming method, %#02x\n", dvname, method, 762 RTW_READ8(regs, RTW_CONFIG4))); 763 } 764 765 void 766 rtw_identify_country(struct rtw_regs *regs, enum rtw_locale *locale) 767 { 768 u_int8_t cfg0 = RTW_READ8(regs, RTW_CONFIG0); 769 770 switch (cfg0 & RTW8180_CONFIG0_GL_MASK) { 771 case RTW8180_CONFIG0_GL_USA: 772 *locale = RTW_LOCALE_USA; 773 break; 774 case RTW8180_CONFIG0_GL_JAPAN: 775 case RTW8180_CONFIG0_GL_JAPAN2: 776 *locale = RTW_LOCALE_JAPAN; 777 break; 778 case RTW8180_CONFIG0_GL_EUROPE: 779 *locale = RTW_LOCALE_EUROPE; 780 break; 781 default: 782 *locale = RTW_LOCALE_UNKNOWN; 783 break; 784 } 785 } 786 787 int 788 rtw_identify_sta(struct rtw_regs *regs, u_int8_t (*addr)[IEEE80211_ADDR_LEN], 789 const char *dvname) 790 { 791 static const u_int8_t empty_macaddr[IEEE80211_ADDR_LEN] = { 792 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 793 }; 794 u_int32_t idr0 = RTW_READ(regs, RTW_IDR0), 795 idr1 = RTW_READ(regs, RTW_IDR1); 796 797 (*addr)[0] = MASK_AND_RSHIFT(idr0, BITS(0, 7)); 798 (*addr)[1] = MASK_AND_RSHIFT(idr0, BITS(8, 15)); 799 (*addr)[2] = MASK_AND_RSHIFT(idr0, BITS(16, 23)); 800 (*addr)[3] = MASK_AND_RSHIFT(idr0, BITS(24 ,31)); 801 802 (*addr)[4] = MASK_AND_RSHIFT(idr1, BITS(0, 7)); 803 (*addr)[5] = MASK_AND_RSHIFT(idr1, BITS(8, 15)); 804 805 if (IEEE80211_ADDR_EQ(addr, empty_macaddr)) { 806 printf("\n%s: could not get mac address, attach failed\n", 807 dvname); 808 return ENXIO; 809 } 810 811 printf("address %s\n", ether_sprintf(*addr)); 812 813 return 0; 814 } 815 816 u_int8_t 817 rtw_chan2txpower(struct rtw_srom *sr, struct ieee80211com *ic, 818 struct ieee80211_channel *chan) 819 { 820 u_int idx = RTW_SR_TXPOWER1 + ieee80211_chan2ieee(ic, chan) - 1; 821 KASSERT2(idx >= RTW_SR_TXPOWER1 && idx <= RTW_SR_TXPOWER14, 822 ("%s: channel %d out of range", __func__, 823 idx - RTW_SR_TXPOWER1 + 1)); 824 return RTW_SR_GET(sr, idx); 825 } 826 827 void 828 rtw_txdesc_blk_init_all(struct rtw_txdesc_blk *tdb) 829 { 830 int pri; 831 /* nfree: the number of free descriptors in each ring. 832 * The beacon ring is a special case: I do not let the 833 * driver use all of the descriptors on the beacon ring. 834 * The reasons are two-fold: 835 * 836 * (1) A BEACON descriptor's OWN bit is (apparently) not 837 * updated, so the driver cannot easily know if the descriptor 838 * belongs to it, or if it is racing the NIC. If the NIC 839 * does not OWN every descriptor, then the driver can safely 840 * update the descriptors when RTW_TBDA points at tdb_next. 841 * 842 * (2) I hope that the NIC will process more than one BEACON 843 * descriptor in a single beacon interval, since that will 844 * enable multiple-BSS support. Since the NIC does not 845 * clear the OWN bit, there is no natural place for it to 846 * stop processing BEACON desciptors. Maybe it will *not* 847 * stop processing them! I do not want to chance the NIC 848 * looping around and around a saturated beacon ring, so 849 * I will leave one descriptor unOWNed at all times. 850 */ 851 u_int nfree[RTW_NTXPRI] = 852 {RTW_NTXDESCLO, RTW_NTXDESCMD, RTW_NTXDESCHI, 853 RTW_NTXDESCBCN - 1}; 854 855 for (pri = 0; pri < RTW_NTXPRI; pri++) { 856 tdb[pri].tdb_nfree = nfree[pri]; 857 tdb[pri].tdb_next = 0; 858 } 859 } 860 861 int 862 rtw_txsoft_blk_init(struct rtw_txsoft_blk *tsb) 863 { 864 int i; 865 struct rtw_txsoft *ts; 866 867 SIMPLEQ_INIT(&tsb->tsb_dirtyq); 868 SIMPLEQ_INIT(&tsb->tsb_freeq); 869 for (i = 0; i < tsb->tsb_ndesc; i++) { 870 ts = &tsb->tsb_desc[i]; 871 ts->ts_mbuf = NULL; 872 SIMPLEQ_INSERT_TAIL(&tsb->tsb_freeq, ts, ts_q); 873 } 874 tsb->tsb_tx_timer = 0; 875 return 0; 876 } 877 878 void 879 rtw_txsoft_blk_init_all(struct rtw_txsoft_blk *tsb) 880 { 881 int pri; 882 for (pri = 0; pri < RTW_NTXPRI; pri++) 883 rtw_txsoft_blk_init(&tsb[pri]); 884 } 885 886 void 887 rtw_rxdescs_sync(struct rtw_rxdesc_blk *rdb, int desc0, int nsync, int ops) 888 { 889 KASSERT(nsync <= rdb->rdb_ndesc); 890 /* sync to end of ring */ 891 if (desc0 + nsync > rdb->rdb_ndesc) { 892 bus_dmamap_sync(rdb->rdb_dmat, rdb->rdb_dmamap, 893 offsetof(struct rtw_descs, hd_rx[desc0]), 894 sizeof(struct rtw_rxdesc) * (rdb->rdb_ndesc - desc0), ops); 895 nsync -= (rdb->rdb_ndesc - desc0); 896 desc0 = 0; 897 } 898 899 KASSERT(desc0 < rdb->rdb_ndesc); 900 KASSERT(nsync <= rdb->rdb_ndesc); 901 KASSERT(desc0 + nsync <= rdb->rdb_ndesc); 902 903 /* sync what remains */ 904 bus_dmamap_sync(rdb->rdb_dmat, rdb->rdb_dmamap, 905 offsetof(struct rtw_descs, hd_rx[desc0]), 906 sizeof(struct rtw_rxdesc) * nsync, ops); 907 } 908 909 void 910 rtw_txdescs_sync(struct rtw_txdesc_blk *tdb, u_int desc0, u_int nsync, int ops) 911 { 912 /* sync to end of ring */ 913 if (desc0 + nsync > tdb->tdb_ndesc) { 914 bus_dmamap_sync(tdb->tdb_dmat, tdb->tdb_dmamap, 915 tdb->tdb_ofs + sizeof(struct rtw_txdesc) * desc0, 916 sizeof(struct rtw_txdesc) * (tdb->tdb_ndesc - desc0), 917 ops); 918 nsync -= (tdb->tdb_ndesc - desc0); 919 desc0 = 0; 920 } 921 922 /* sync what remains */ 923 bus_dmamap_sync(tdb->tdb_dmat, tdb->tdb_dmamap, 924 tdb->tdb_ofs + sizeof(struct rtw_txdesc) * desc0, 925 sizeof(struct rtw_txdesc) * nsync, ops); 926 } 927 928 void 929 rtw_rxbufs_release(bus_dma_tag_t dmat, struct rtw_rxsoft *desc) 930 { 931 int i; 932 struct rtw_rxsoft *rs; 933 934 for (i = 0; i < RTW_RXQLEN; i++) { 935 rs = &desc[i]; 936 if (rs->rs_mbuf == NULL) 937 continue; 938 bus_dmamap_sync(dmat, rs->rs_dmamap, 0, 939 rs->rs_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD); 940 bus_dmamap_unload(dmat, rs->rs_dmamap); 941 m_freem(rs->rs_mbuf); 942 rs->rs_mbuf = NULL; 943 } 944 } 945 946 int 947 rtw_rxsoft_alloc(bus_dma_tag_t dmat, struct rtw_rxsoft *rs) 948 { 949 int rc; 950 struct mbuf *m; 951 952 MGETHDR(m, M_DONTWAIT, MT_DATA); 953 if (m == NULL) 954 return ENOBUFS; 955 956 MCLGET(m, M_DONTWAIT); 957 if ((m->m_flags & M_EXT) == 0) { 958 m_freem(m); 959 return ENOBUFS; 960 } 961 962 m->m_pkthdr.len = m->m_len = m->m_ext.ext_size; 963 964 if (rs->rs_mbuf != NULL) 965 bus_dmamap_unload(dmat, rs->rs_dmamap); 966 967 rs->rs_mbuf = NULL; 968 969 rc = bus_dmamap_load_mbuf(dmat, rs->rs_dmamap, m, BUS_DMA_NOWAIT); 970 if (rc != 0) { 971 m_freem(m); 972 return -1; 973 } 974 975 rs->rs_mbuf = m; 976 977 return 0; 978 } 979 980 int 981 rtw_rxsoft_init_all(bus_dma_tag_t dmat, struct rtw_rxsoft *desc, 982 int *ndesc, const char *dvname) 983 { 984 int i, rc = 0; 985 struct rtw_rxsoft *rs; 986 987 for (i = 0; i < RTW_RXQLEN; i++) { 988 rs = &desc[i]; 989 /* we're in rtw_init, so there should be no mbufs allocated */ 990 KASSERT(rs->rs_mbuf == NULL); 991 #ifdef RTW_DEBUG 992 if (i == rtw_rxbufs_limit) { 993 printf("%s: TEST hit %d-buffer limit\n", dvname, i); 994 rc = ENOBUFS; 995 break; 996 } 997 #endif /* RTW_DEBUG */ 998 if ((rc = rtw_rxsoft_alloc(dmat, rs)) != 0) { 999 printf("%s: rtw_rxsoft_alloc failed, %d buffers, " 1000 "rc %d\n", dvname, i, rc); 1001 break; 1002 } 1003 } 1004 *ndesc = i; 1005 return rc; 1006 } 1007 1008 void 1009 rtw_rxdesc_init(struct rtw_rxdesc_blk *rdb, struct rtw_rxsoft *rs, 1010 int idx, int kick) 1011 { 1012 int is_last = (idx == rdb->rdb_ndesc - 1); 1013 uint32_t ctl, octl, obuf; 1014 struct rtw_rxdesc *rd = &rdb->rdb_desc[idx]; 1015 1016 obuf = rd->rd_buf; 1017 rd->rd_buf = htole32(rs->rs_dmamap->dm_segs[0].ds_addr); 1018 1019 ctl = LSHIFT(rs->rs_mbuf->m_len, RTW_RXCTL_LENGTH_MASK) | 1020 RTW_RXCTL_OWN | RTW_RXCTL_FS | RTW_RXCTL_LS; 1021 1022 if (is_last) 1023 ctl |= RTW_RXCTL_EOR; 1024 1025 octl = rd->rd_ctl; 1026 rd->rd_ctl = htole32(ctl); 1027 1028 RTW_DPRINTF(kick ? (RTW_DEBUG_RECV_DESC | RTW_DEBUG_IO_KICK) 1029 : RTW_DEBUG_RECV_DESC, 1030 ("%s: rd %p buf %08x -> %08x ctl %08x -> %08x\n", __func__, rd, 1031 letoh32(obuf), letoh32(rd->rd_buf), letoh32(octl), 1032 letoh32(rd->rd_ctl))); 1033 1034 /* sync the mbuf */ 1035 bus_dmamap_sync(rdb->rdb_dmat, rs->rs_dmamap, 0, 1036 rs->rs_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD); 1037 1038 /* sync the descriptor */ 1039 bus_dmamap_sync(rdb->rdb_dmat, rdb->rdb_dmamap, 1040 RTW_DESC_OFFSET(hd_rx, idx), sizeof(struct rtw_rxdesc), 1041 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 1042 } 1043 1044 void 1045 rtw_rxdesc_init_all(struct rtw_rxdesc_blk *rdb, struct rtw_rxsoft *ctl, 1046 int kick) 1047 { 1048 int i; 1049 struct rtw_rxsoft *rs; 1050 1051 for (i = 0; i < rdb->rdb_ndesc; i++) { 1052 rs = &ctl[i]; 1053 rtw_rxdesc_init(rdb, rs, i, kick); 1054 } 1055 } 1056 1057 void 1058 rtw_io_enable(struct rtw_regs *regs, u_int8_t flags, int enable) 1059 { 1060 u_int8_t cr; 1061 1062 RTW_DPRINTF(RTW_DEBUG_IOSTATE, ("%s: %s 0x%02x\n", __func__, 1063 enable ? "enable" : "disable", flags)); 1064 1065 cr = RTW_READ8(regs, RTW_CR); 1066 1067 /* XXX reference source does not enable MULRW */ 1068 #if 0 1069 /* enable PCI Read/Write Multiple */ 1070 cr |= RTW_CR_MULRW; 1071 #endif 1072 1073 RTW_RBW(regs, RTW_CR, RTW_CR); /* XXX paranoia? */ 1074 if (enable) 1075 cr |= flags; 1076 else 1077 cr &= ~flags; 1078 RTW_WRITE8(regs, RTW_CR, cr); 1079 RTW_SYNC(regs, RTW_CR, RTW_CR); 1080 } 1081 1082 void 1083 rtw_intr_rx(struct rtw_softc *sc, u_int16_t isr) 1084 { 1085 #define IS_BEACON(__fc0) \ 1086 ((__fc0 & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==\ 1087 (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_BEACON)) 1088 1089 static const int ratetbl[4] = {2, 4, 11, 22}; /* convert rates: 1090 * hardware -> net80211 1091 */ 1092 u_int next, nproc = 0; 1093 int hwrate, len, rate, rssi, sq; 1094 u_int32_t hrssi, hstat, htsfth, htsftl; 1095 struct rtw_rxdesc *rd; 1096 struct rtw_rxsoft *rs; 1097 struct rtw_rxdesc_blk *rdb; 1098 struct mbuf *m; 1099 struct ieee80211_rxinfo rxi; 1100 struct ieee80211_node *ni; 1101 struct ieee80211_frame *wh; 1102 1103 rdb = &sc->sc_rxdesc_blk; 1104 1105 KASSERT(rdb->rdb_next < rdb->rdb_ndesc); 1106 1107 for (next = rdb->rdb_next; ; next = (next + 1) % rdb->rdb_ndesc) { 1108 rtw_rxdescs_sync(rdb, next, 1, 1109 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 1110 rd = &rdb->rdb_desc[next]; 1111 rs = &sc->sc_rxsoft[next]; 1112 1113 hstat = letoh32(rd->rd_stat); 1114 hrssi = letoh32(rd->rd_rssi); 1115 htsfth = letoh32(rd->rd_tsfth); 1116 htsftl = letoh32(rd->rd_tsftl); 1117 1118 RTW_DPRINTF(RTW_DEBUG_RECV_DESC, 1119 ("%s: rxdesc[%d] hstat %08x hrssi %08x htsft %08x%08x\n", 1120 __func__, next, hstat, hrssi, htsfth, htsftl)); 1121 1122 ++nproc; 1123 1124 /* still belongs to NIC */ 1125 if ((hstat & RTW_RXSTAT_OWN) != 0) { 1126 if (nproc > 1) 1127 break; 1128 1129 /* sometimes the NIC skips to the 0th descriptor */ 1130 rtw_rxdescs_sync(rdb, 0, 1, 1131 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 1132 rd = &rdb->rdb_desc[0]; 1133 if ((rd->rd_stat & htole32(RTW_RXSTAT_OWN)) != 0) 1134 break; 1135 RTW_DPRINTF(RTW_DEBUG_BUGS, 1136 ("%s: NIC skipped from rxdesc[%u] to rxdesc[0]\n", 1137 sc->sc_dev.dv_xname, next)); 1138 next = rdb->rdb_ndesc - 1; 1139 continue; 1140 } 1141 1142 #ifdef RTW_DEBUG 1143 #define PRINTSTAT(flag) do { \ 1144 if ((hstat & flag) != 0) { \ 1145 printf("%s" #flag, delim); \ 1146 delim = ","; \ 1147 } \ 1148 } while (0) 1149 if ((rtw_debug & RTW_DEBUG_RECV_DESC) != 0) { 1150 const char *delim = "<"; 1151 printf("%s: ", sc->sc_dev.dv_xname); 1152 if ((hstat & RTW_RXSTAT_DEBUG) != 0) { 1153 printf("status %08x", hstat); 1154 PRINTSTAT(RTW_RXSTAT_SPLCP); 1155 PRINTSTAT(RTW_RXSTAT_MAR); 1156 PRINTSTAT(RTW_RXSTAT_PAR); 1157 PRINTSTAT(RTW_RXSTAT_BAR); 1158 PRINTSTAT(RTW_RXSTAT_PWRMGT); 1159 PRINTSTAT(RTW_RXSTAT_CRC32); 1160 PRINTSTAT(RTW_RXSTAT_ICV); 1161 printf(">, "); 1162 } 1163 } 1164 #undef PRINTSTAT 1165 #endif /* RTW_DEBUG */ 1166 1167 if ((hstat & RTW_RXSTAT_IOERROR) != 0) { 1168 printf("%s: DMA error/FIFO overflow %08x, " 1169 "rx descriptor %d\n", sc->sc_dev.dv_xname, 1170 hstat & RTW_RXSTAT_IOERROR, next); 1171 sc->sc_if.if_ierrors++; 1172 goto next; 1173 } 1174 1175 len = MASK_AND_RSHIFT(hstat, RTW_RXSTAT_LENGTH_MASK); 1176 if (len < IEEE80211_MIN_LEN) { 1177 sc->sc_ic.ic_stats.is_rx_tooshort++; 1178 goto next; 1179 } 1180 1181 /* CRC is included with the packet; trim it off. */ 1182 len -= IEEE80211_CRC_LEN; 1183 1184 hwrate = MASK_AND_RSHIFT(hstat, RTW_RXSTAT_RATE_MASK); 1185 if (hwrate >= sizeof(ratetbl) / sizeof(ratetbl[0])) { 1186 printf("%s: unknown rate #%d\n", sc->sc_dev.dv_xname, 1187 MASK_AND_RSHIFT(hstat, RTW_RXSTAT_RATE_MASK)); 1188 sc->sc_if.if_ierrors++; 1189 goto next; 1190 } 1191 rate = ratetbl[hwrate]; 1192 1193 #ifdef RTW_DEBUG 1194 RTW_DPRINTF(RTW_DEBUG_RECV_DESC, 1195 ("rate %d.%d Mb/s, time %08x%08x\n", (rate * 5) / 10, 1196 (rate * 5) % 10, htsfth, htsftl)); 1197 #endif /* RTW_DEBUG */ 1198 1199 if ((hstat & RTW_RXSTAT_RES) != 0 && 1200 sc->sc_ic.ic_opmode != IEEE80211_M_MONITOR) 1201 goto next; 1202 1203 /* if bad flags, skip descriptor */ 1204 if ((hstat & RTW_RXSTAT_ONESEG) != RTW_RXSTAT_ONESEG) { 1205 printf("%s: too many rx segments\n", 1206 sc->sc_dev.dv_xname); 1207 goto next; 1208 } 1209 1210 bus_dmamap_sync(sc->sc_dmat, rs->rs_dmamap, 0, 1211 rs->rs_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD); 1212 1213 m = rs->rs_mbuf; 1214 1215 /* if temporarily out of memory, re-use mbuf */ 1216 switch (rtw_rxsoft_alloc(sc->sc_dmat, rs)) { 1217 case 0: 1218 break; 1219 case ENOBUFS: 1220 printf("%s: rtw_rxsoft_alloc(, %d) failed, " 1221 "dropping this packet\n", sc->sc_dev.dv_xname, 1222 next); 1223 goto next; 1224 default: 1225 /* XXX shorten rx ring, instead? */ 1226 panic("%s: could not load DMA map", 1227 sc->sc_dev.dv_xname); 1228 } 1229 1230 if (sc->sc_rfchipid == RTW_RFCHIPID_PHILIPS) 1231 rssi = MASK_AND_RSHIFT(hrssi, RTW_RXRSSI_RSSI); 1232 else { 1233 rssi = MASK_AND_RSHIFT(hrssi, RTW_RXRSSI_IMR_RSSI); 1234 /* TBD find out each front-end's LNA gain in the 1235 * front-end's units 1236 */ 1237 if ((hrssi & RTW_RXRSSI_IMR_LNA) == 0) 1238 rssi |= 0x80; 1239 } 1240 1241 sq = MASK_AND_RSHIFT(hrssi, RTW_RXRSSI_SQ); 1242 1243 /* 1244 * Note well: now we cannot recycle the rs_mbuf unless 1245 * we restore its original length. 1246 */ 1247 m->m_pkthdr.rcvif = &sc->sc_if; 1248 m->m_pkthdr.len = m->m_len = len; 1249 1250 wh = mtod(m, struct ieee80211_frame *); 1251 1252 if (!IS_BEACON(wh->i_fc[0])) 1253 sc->sc_led_state.ls_event |= RTW_LED_S_RX; 1254 /* TBD use _MAR, _BAR, _PAR flags as hints to _find_rxnode? */ 1255 ni = ieee80211_find_rxnode(&sc->sc_ic, wh); 1256 1257 sc->sc_tsfth = htsfth; 1258 1259 #ifdef RTW_DEBUG 1260 if ((sc->sc_if.if_flags & (IFF_DEBUG|IFF_LINK2)) == 1261 (IFF_DEBUG|IFF_LINK2)) { 1262 ieee80211_dump_pkt(mtod(m, uint8_t *), m->m_pkthdr.len, 1263 rate, rssi); 1264 } 1265 #endif /* RTW_DEBUG */ 1266 1267 #if NBPFILTER > 0 1268 if (sc->sc_radiobpf != NULL) { 1269 struct mbuf mb; 1270 struct ieee80211com *ic = &sc->sc_ic; 1271 struct rtw_rx_radiotap_header *rr = &sc->sc_rxtap; 1272 1273 rr->rr_tsft = 1274 htole64(((uint64_t)htsfth << 32) | htsftl); 1275 1276 rr->rr_flags = 0; 1277 if ((hstat & RTW_RXSTAT_SPLCP) != 0) 1278 rr->rr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 1279 1280 rr->rr_rate = rate; 1281 rr->rr_chan_freq = 1282 htole16(ic->ic_bss->ni_chan->ic_freq); 1283 rr->rr_chan_flags = 1284 htole16(ic->ic_bss->ni_chan->ic_flags); 1285 rr->rr_antsignal = rssi; 1286 rr->rr_barker_lock = htole16(sq); 1287 1288 mb.m_data = (caddr_t)rr; 1289 mb.m_len = sizeof(sc->sc_rxtapu); 1290 mb.m_next = m; 1291 mb.m_nextpkt = NULL; 1292 mb.m_type = 0; 1293 mb.m_flags = 0; 1294 bpf_mtap(sc->sc_radiobpf, &mb, BPF_DIRECTION_IN); 1295 } 1296 #endif /* NBPFILTER > 0 */ 1297 1298 rxi.rxi_flags = 0; 1299 rxi.rxi_rssi = rssi; 1300 rxi.rxi_tstamp = htsftl; 1301 ieee80211_input(&sc->sc_if, m, ni, &rxi); 1302 ieee80211_release_node(&sc->sc_ic, ni); 1303 next: 1304 rtw_rxdesc_init(rdb, rs, next, 0); 1305 } 1306 rdb->rdb_next = next; 1307 1308 KASSERT(rdb->rdb_next < rdb->rdb_ndesc); 1309 1310 return; 1311 #undef IS_BEACON 1312 } 1313 1314 void 1315 rtw_txsoft_release(bus_dma_tag_t dmat, struct ieee80211com *ic, 1316 struct rtw_txsoft *ts) 1317 { 1318 struct mbuf *m; 1319 struct ieee80211_node *ni; 1320 1321 m = ts->ts_mbuf; 1322 ni = ts->ts_ni; 1323 KASSERT(m != NULL); 1324 KASSERT(ni != NULL); 1325 ts->ts_mbuf = NULL; 1326 ts->ts_ni = NULL; 1327 1328 bus_dmamap_sync(dmat, ts->ts_dmamap, 0, ts->ts_dmamap->dm_mapsize, 1329 BUS_DMASYNC_POSTWRITE); 1330 bus_dmamap_unload(dmat, ts->ts_dmamap); 1331 m_freem(m); 1332 ieee80211_release_node(ic, ni); 1333 } 1334 1335 void 1336 rtw_txsofts_release(bus_dma_tag_t dmat, struct ieee80211com *ic, 1337 struct rtw_txsoft_blk *tsb) 1338 { 1339 struct rtw_txsoft *ts; 1340 1341 while ((ts = SIMPLEQ_FIRST(&tsb->tsb_dirtyq)) != NULL) { 1342 rtw_txsoft_release(dmat, ic, ts); 1343 SIMPLEQ_REMOVE_HEAD(&tsb->tsb_dirtyq, ts_q); 1344 SIMPLEQ_INSERT_TAIL(&tsb->tsb_freeq, ts, ts_q); 1345 } 1346 tsb->tsb_tx_timer = 0; 1347 } 1348 1349 void 1350 rtw_collect_txpkt(struct rtw_softc *sc, struct rtw_txdesc_blk *tdb, 1351 struct rtw_txsoft *ts, int ndesc) 1352 { 1353 uint32_t hstat; 1354 int data_retry, rts_retry; 1355 struct rtw_txdesc *tdn; 1356 const char *condstring; 1357 1358 rtw_txsoft_release(sc->sc_dmat, &sc->sc_ic, ts); 1359 1360 tdb->tdb_nfree += ndesc; 1361 1362 tdn = &tdb->tdb_desc[ts->ts_last]; 1363 1364 hstat = letoh32(tdn->td_stat); 1365 rts_retry = MASK_AND_RSHIFT(hstat, RTW_TXSTAT_RTSRETRY_MASK); 1366 data_retry = MASK_AND_RSHIFT(hstat, RTW_TXSTAT_DRC_MASK); 1367 1368 sc->sc_if.if_collisions += rts_retry + data_retry; 1369 1370 if ((hstat & RTW_TXSTAT_TOK) != 0) 1371 condstring = "ok"; 1372 else { 1373 sc->sc_if.if_oerrors++; 1374 condstring = "error"; 1375 } 1376 1377 DPRINTF(sc, RTW_DEBUG_XMIT_DESC, 1378 ("%s: ts %p txdesc[%d, %d] %s tries rts %u data %u\n", 1379 sc->sc_dev.dv_xname, ts, ts->ts_first, ts->ts_last, 1380 condstring, rts_retry, data_retry)); 1381 } 1382 1383 void 1384 rtw_reset_oactive(struct rtw_softc *sc) 1385 { 1386 short oflags; 1387 int pri; 1388 struct rtw_txsoft_blk *tsb; 1389 struct rtw_txdesc_blk *tdb; 1390 oflags = sc->sc_if.if_flags; 1391 for (pri = 0; pri < RTW_NTXPRI; pri++) { 1392 tsb = &sc->sc_txsoft_blk[pri]; 1393 tdb = &sc->sc_txdesc_blk[pri]; 1394 if (!SIMPLEQ_EMPTY(&tsb->tsb_freeq) && tdb->tdb_nfree > 0) 1395 sc->sc_if.if_flags &= ~IFF_OACTIVE; 1396 } 1397 if (oflags != sc->sc_if.if_flags) { 1398 DPRINTF(sc, RTW_DEBUG_OACTIVE, 1399 ("%s: reset OACTIVE\n", __func__)); 1400 } 1401 } 1402 1403 /* Collect transmitted packets. */ 1404 void 1405 rtw_collect_txring(struct rtw_softc *sc, struct rtw_txsoft_blk *tsb, 1406 struct rtw_txdesc_blk *tdb, int force) 1407 { 1408 int ndesc; 1409 struct rtw_txsoft *ts; 1410 1411 while ((ts = SIMPLEQ_FIRST(&tsb->tsb_dirtyq)) != NULL) { 1412 ndesc = 1 + ts->ts_last - ts->ts_first; 1413 if (ts->ts_last < ts->ts_first) 1414 ndesc += tdb->tdb_ndesc; 1415 1416 KASSERT(ndesc > 0); 1417 1418 rtw_txdescs_sync(tdb, ts->ts_first, ndesc, 1419 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 1420 1421 if (force) { 1422 int i; 1423 for (i = ts->ts_first; ; i = RTW_NEXT_IDX(tdb, i)) { 1424 tdb->tdb_desc[i].td_stat &= 1425 ~htole32(RTW_TXSTAT_OWN); 1426 if (i == ts->ts_last) 1427 break; 1428 } 1429 rtw_txdescs_sync(tdb, ts->ts_first, ndesc, 1430 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 1431 } else if ((tdb->tdb_desc[ts->ts_last].td_stat & 1432 htole32(RTW_TXSTAT_OWN)) != 0) 1433 break; 1434 1435 rtw_collect_txpkt(sc, tdb, ts, ndesc); 1436 SIMPLEQ_REMOVE_HEAD(&tsb->tsb_dirtyq, ts_q); 1437 SIMPLEQ_INSERT_TAIL(&tsb->tsb_freeq, ts, ts_q); 1438 } 1439 /* no more pending transmissions, cancel watchdog */ 1440 if (ts == NULL) 1441 tsb->tsb_tx_timer = 0; 1442 rtw_reset_oactive(sc); 1443 } 1444 1445 void 1446 rtw_intr_tx(struct rtw_softc *sc, u_int16_t isr) 1447 { 1448 int pri; 1449 struct rtw_txsoft_blk *tsb; 1450 struct rtw_txdesc_blk *tdb; 1451 1452 for (pri = 0; pri < RTW_NTXPRI; pri++) { 1453 tsb = &sc->sc_txsoft_blk[pri]; 1454 tdb = &sc->sc_txdesc_blk[pri]; 1455 1456 rtw_collect_txring(sc, tsb, tdb, 0); 1457 1458 } 1459 1460 if ((isr & RTW_INTR_TX) != 0) 1461 rtw_start(&sc->sc_if); 1462 } 1463 1464 #ifndef IEEE80211_STA_ONLY 1465 void 1466 rtw_intr_beacon(struct rtw_softc *sc, u_int16_t isr) 1467 { 1468 u_int next; 1469 uint32_t tsfth, tsftl; 1470 struct ieee80211com *ic; 1471 struct rtw_txdesc_blk *tdb = &sc->sc_txdesc_blk[RTW_TXPRIBCN]; 1472 struct rtw_txsoft_blk *tsb = &sc->sc_txsoft_blk[RTW_TXPRIBCN]; 1473 struct mbuf *m; 1474 1475 tsfth = RTW_READ(&sc->sc_regs, RTW_TSFTRH); 1476 tsftl = RTW_READ(&sc->sc_regs, RTW_TSFTRL); 1477 1478 if ((isr & (RTW_INTR_TBDOK|RTW_INTR_TBDER)) != 0) { 1479 next = rtw_txring_next(&sc->sc_regs, tdb); 1480 RTW_DPRINTF(RTW_DEBUG_BEACON, 1481 ("%s: beacon ring %sprocessed, isr = %#04hx" 1482 ", next %u expected %u, %llu\n", __func__, 1483 (next == tdb->tdb_next) ? "" : "un", isr, next, 1484 tdb->tdb_next, (uint64_t)tsfth << 32 | tsftl)); 1485 if ((RTW_READ8(&sc->sc_regs, RTW_TPPOLL) & RTW_TPPOLL_BQ) == 0){ 1486 rtw_collect_txring(sc, tsb, tdb, 1); 1487 tdb->tdb_next = 0; 1488 } 1489 } 1490 /* Start beacon transmission. */ 1491 1492 if ((isr & RTW_INTR_BCNINT) != 0 && 1493 sc->sc_ic.ic_state == IEEE80211_S_RUN && 1494 SIMPLEQ_EMPTY(&tsb->tsb_dirtyq)) { 1495 RTW_DPRINTF(RTW_DEBUG_BEACON, 1496 ("%s: beacon prep. time, isr = %#04hx" 1497 ", %16llu\n", __func__, isr, 1498 (uint64_t)tsfth << 32 | tsftl)); 1499 ic = &sc->sc_ic; 1500 if ((m = ieee80211_beacon_alloc(ic, ic->ic_bss)) != NULL) { 1501 RTW_DPRINTF(RTW_DEBUG_BEACON, 1502 ("%s: m %p len %u\n", __func__, m, m->m_len)); 1503 } 1504 1505 if (m == NULL) { 1506 printf("%s: could not allocate beacon\n", 1507 sc->sc_dev.dv_xname); 1508 return; 1509 } 1510 m->m_pkthdr.rcvif = (void *)ieee80211_ref_node(ic->ic_bss); 1511 IF_ENQUEUE(&sc->sc_beaconq, m); 1512 rtw_start(&sc->sc_if); 1513 } 1514 } 1515 1516 void 1517 rtw_intr_atim(struct rtw_softc *sc) 1518 { 1519 /* TBD */ 1520 return; 1521 } 1522 #endif /* IEEE80211_STA_ONLY */ 1523 1524 #ifdef RTW_DEBUG 1525 void 1526 rtw_dump_rings(struct rtw_softc *sc) 1527 { 1528 struct rtw_txdesc_blk *tdb; 1529 struct rtw_rxdesc *rd; 1530 struct rtw_rxdesc_blk *rdb; 1531 int desc, pri; 1532 1533 if ((rtw_debug & RTW_DEBUG_IO_KICK) == 0) 1534 return; 1535 1536 for (pri = 0; pri < RTW_NTXPRI; pri++) { 1537 tdb = &sc->sc_txdesc_blk[pri]; 1538 printf("%s: txpri %d ndesc %d nfree %d\n", __func__, pri, 1539 tdb->tdb_ndesc, tdb->tdb_nfree); 1540 for (desc = 0; desc < tdb->tdb_ndesc; desc++) 1541 rtw_print_txdesc(sc, ".", NULL, tdb, desc); 1542 } 1543 1544 rdb = &sc->sc_rxdesc_blk; 1545 1546 for (desc = 0; desc < RTW_RXQLEN; desc++) { 1547 rd = &rdb->rdb_desc[desc]; 1548 printf("%s: %sctl %08x rsvd0/rssi %08x buf/tsftl %08x " 1549 "rsvd1/tsfth %08x\n", __func__, 1550 (desc >= rdb->rdb_ndesc) ? "UNUSED " : "", 1551 letoh32(rd->rd_ctl), letoh32(rd->rd_rssi), 1552 letoh32(rd->rd_buf), letoh32(rd->rd_tsfth)); 1553 } 1554 } 1555 #endif /* RTW_DEBUG */ 1556 1557 void 1558 rtw_hwring_setup(struct rtw_softc *sc) 1559 { 1560 int pri; 1561 struct rtw_regs *regs = &sc->sc_regs; 1562 struct rtw_txdesc_blk *tdb; 1563 1564 sc->sc_txdesc_blk[RTW_TXPRILO].tdb_basereg = RTW_TLPDA; 1565 sc->sc_txdesc_blk[RTW_TXPRILO].tdb_base = RTW_RING_BASE(sc, hd_txlo); 1566 sc->sc_txdesc_blk[RTW_TXPRIMD].tdb_basereg = RTW_TNPDA; 1567 sc->sc_txdesc_blk[RTW_TXPRIMD].tdb_base = RTW_RING_BASE(sc, hd_txmd); 1568 sc->sc_txdesc_blk[RTW_TXPRIHI].tdb_basereg = RTW_THPDA; 1569 sc->sc_txdesc_blk[RTW_TXPRIHI].tdb_base = RTW_RING_BASE(sc, hd_txhi); 1570 sc->sc_txdesc_blk[RTW_TXPRIBCN].tdb_basereg = RTW_TBDA; 1571 sc->sc_txdesc_blk[RTW_TXPRIBCN].tdb_base = RTW_RING_BASE(sc, hd_bcn); 1572 1573 for (pri = 0; pri < RTW_NTXPRI; pri++) { 1574 tdb = &sc->sc_txdesc_blk[pri]; 1575 RTW_WRITE(regs, tdb->tdb_basereg, tdb->tdb_base); 1576 RTW_DPRINTF(RTW_DEBUG_XMIT_DESC, 1577 ("%s: reg[tdb->tdb_basereg] <- %lx\n", __func__, 1578 (u_int *)tdb->tdb_base)); 1579 } 1580 1581 RTW_WRITE(regs, RTW_RDSAR, RTW_RING_BASE(sc, hd_rx)); 1582 1583 RTW_DPRINTF(RTW_DEBUG_RECV_DESC, 1584 ("%s: reg[RDSAR] <- %lx\n", __func__, 1585 (u_int *)RTW_RING_BASE(sc, hd_rx))); 1586 1587 RTW_SYNC(regs, RTW_TLPDA, RTW_RDSAR); 1588 } 1589 1590 int 1591 rtw_swring_setup(struct rtw_softc *sc) 1592 { 1593 int rc, pri; 1594 struct rtw_rxdesc_blk *rdb; 1595 struct rtw_txdesc_blk *tdb; 1596 1597 rtw_txdesc_blk_init_all(&sc->sc_txdesc_blk[0]); 1598 1599 rtw_txsoft_blk_init_all(&sc->sc_txsoft_blk[0]); 1600 1601 rdb = &sc->sc_rxdesc_blk; 1602 if ((rc = rtw_rxsoft_init_all(sc->sc_dmat, sc->sc_rxsoft, 1603 &rdb->rdb_ndesc, sc->sc_dev.dv_xname)) != 0 && 1604 rdb->rdb_ndesc == 0) { 1605 printf("%s: could not allocate rx buffers\n", 1606 sc->sc_dev.dv_xname); 1607 return rc; 1608 } 1609 1610 rdb = &sc->sc_rxdesc_blk; 1611 rtw_rxdescs_sync(rdb, 0, rdb->rdb_ndesc, 1612 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 1613 rtw_rxdesc_init_all(rdb, sc->sc_rxsoft, 1); 1614 rdb->rdb_next = 0; 1615 1616 tdb = &sc->sc_txdesc_blk[0]; 1617 for (pri = 0; pri < RTW_NTXPRI; pri++) { 1618 rtw_txdescs_sync(&tdb[pri], 0, tdb[pri].tdb_ndesc, 1619 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 1620 } 1621 return 0; 1622 } 1623 1624 void 1625 rtw_txdesc_blk_init(struct rtw_txdesc_blk *tdb) 1626 { 1627 int i; 1628 1629 bzero(tdb->tdb_desc, sizeof(tdb->tdb_desc[0]) * tdb->tdb_ndesc); 1630 for (i = 0; i < tdb->tdb_ndesc; i++) 1631 tdb->tdb_desc[i].td_next = htole32(RTW_NEXT_DESC(tdb, i)); 1632 } 1633 1634 u_int 1635 rtw_txring_next(struct rtw_regs *regs, struct rtw_txdesc_blk *tdb) 1636 { 1637 return (letoh32(RTW_READ(regs, tdb->tdb_basereg)) - tdb->tdb_base) / 1638 sizeof(struct rtw_txdesc); 1639 } 1640 1641 void 1642 rtw_txring_fixup(struct rtw_softc *sc) 1643 { 1644 int pri; 1645 u_int next; 1646 struct rtw_txdesc_blk *tdb; 1647 struct rtw_regs *regs = &sc->sc_regs; 1648 1649 for (pri = 0; pri < RTW_NTXPRI; pri++) { 1650 tdb = &sc->sc_txdesc_blk[pri]; 1651 next = rtw_txring_next(regs, tdb); 1652 if (tdb->tdb_next == next) 1653 continue; 1654 RTW_DPRINTF(RTW_DEBUG_BUGS, 1655 ("%s: tx-ring %d expected next %u, read %u\n", __func__, 1656 pri, tdb->tdb_next, next)); 1657 tdb->tdb_next = MIN(next, tdb->tdb_ndesc - 1); 1658 } 1659 } 1660 1661 void 1662 rtw_rxring_fixup(struct rtw_softc *sc) 1663 { 1664 u_int next; 1665 uint32_t rdsar; 1666 struct rtw_rxdesc_blk *rdb; 1667 1668 rdsar = letoh32(RTW_READ(&sc->sc_regs, RTW_RDSAR)); 1669 next = (rdsar - RTW_RING_BASE(sc, hd_rx)) / sizeof(struct rtw_rxdesc); 1670 1671 rdb = &sc->sc_rxdesc_blk; 1672 if (rdb->rdb_next != next) { 1673 RTW_DPRINTF(RTW_DEBUG_BUGS, 1674 ("%s: rx-ring expected next %u, read %u\n", __func__, 1675 rdb->rdb_next, next)); 1676 rdb->rdb_next = MIN(next, rdb->rdb_ndesc - 1); 1677 } 1678 } 1679 1680 void 1681 rtw_txdescs_reset(struct rtw_softc *sc) 1682 { 1683 int pri; 1684 1685 for (pri = 0; pri < RTW_NTXPRI; pri++) { 1686 rtw_collect_txring(sc, &sc->sc_txsoft_blk[pri], 1687 &sc->sc_txdesc_blk[pri], 1); 1688 } 1689 } 1690 1691 void 1692 rtw_intr_ioerror(struct rtw_softc *sc, u_int16_t isr) 1693 { 1694 uint8_t cr = 0; 1695 int xmtr = 0, rcvr = 0; 1696 struct rtw_regs *regs = &sc->sc_regs; 1697 1698 if ((isr & RTW_INTR_TXFOVW) != 0) { 1699 RTW_DPRINTF(RTW_DEBUG_BUGS, 1700 ("%s: tx fifo underflow\n", sc->sc_dev.dv_xname)); 1701 rcvr = xmtr = 1; 1702 cr |= RTW_CR_TE | RTW_CR_RE; 1703 } 1704 1705 if ((isr & (RTW_INTR_RDU|RTW_INTR_RXFOVW)) != 0) { 1706 cr |= RTW_CR_RE; 1707 rcvr = 1; 1708 } 1709 1710 RTW_DPRINTF(RTW_DEBUG_BUGS, ("%s: restarting xmit/recv, isr %hx" 1711 "\n", sc->sc_dev.dv_xname, isr)); 1712 1713 #ifdef RTW_DEBUG 1714 rtw_dump_rings(sc); 1715 #endif /* RTW_DEBUG */ 1716 1717 rtw_io_enable(regs, cr, 0); 1718 1719 /* Collect rx'd packets. Refresh rx buffers. */ 1720 if (rcvr) 1721 rtw_intr_rx(sc, 0); 1722 /* Collect tx'd packets. XXX let's hope this stops the transmit 1723 * timeouts. 1724 */ 1725 if (xmtr) 1726 rtw_txdescs_reset(sc); 1727 1728 RTW_WRITE16(regs, RTW_IMR, 0); 1729 RTW_SYNC(regs, RTW_IMR, RTW_IMR); 1730 1731 if (rtw_do_chip_reset) { 1732 rtw_chip_reset1(regs, sc->sc_dev.dv_xname); 1733 } 1734 1735 rtw_rxdesc_init_all(&sc->sc_rxdesc_blk, &sc->sc_rxsoft[0], 1); 1736 1737 #ifdef RTW_DEBUG 1738 rtw_dump_rings(sc); 1739 #endif /* RTW_DEBUG */ 1740 1741 RTW_WRITE16(regs, RTW_IMR, sc->sc_inten); 1742 RTW_SYNC(regs, RTW_IMR, RTW_IMR); 1743 if (rcvr) 1744 rtw_rxring_fixup(sc); 1745 rtw_io_enable(regs, cr, 1); 1746 if (xmtr) 1747 rtw_txring_fixup(sc); 1748 } 1749 1750 void 1751 rtw_suspend_ticks(struct rtw_softc *sc) 1752 { 1753 RTW_DPRINTF(RTW_DEBUG_TIMEOUT, 1754 ("%s: suspending ticks\n", sc->sc_dev.dv_xname)); 1755 sc->sc_do_tick = 0; 1756 } 1757 1758 void 1759 rtw_resume_ticks(struct rtw_softc *sc) 1760 { 1761 u_int32_t tsftrl0, tsftrl1, next_tick; 1762 1763 tsftrl0 = RTW_READ(&sc->sc_regs, RTW_TSFTRL); 1764 1765 tsftrl1 = RTW_READ(&sc->sc_regs, RTW_TSFTRL); 1766 next_tick = tsftrl1 + 1000000; 1767 RTW_WRITE(&sc->sc_regs, RTW_TINT, next_tick); 1768 1769 sc->sc_do_tick = 1; 1770 1771 RTW_DPRINTF(RTW_DEBUG_TIMEOUT, 1772 ("%s: resume ticks delta %#08x now %#08x next %#08x\n", 1773 sc->sc_dev.dv_xname, tsftrl1 - tsftrl0, tsftrl1, next_tick)); 1774 } 1775 1776 void 1777 rtw_intr_timeout(struct rtw_softc *sc) 1778 { 1779 RTW_DPRINTF(RTW_DEBUG_TIMEOUT, ("%s: timeout\n", sc->sc_dev.dv_xname)); 1780 if (sc->sc_do_tick) 1781 rtw_resume_ticks(sc); 1782 return; 1783 } 1784 1785 int 1786 rtw_intr(void *arg) 1787 { 1788 int i; 1789 struct rtw_softc *sc = arg; 1790 struct rtw_regs *regs = &sc->sc_regs; 1791 u_int16_t isr; 1792 1793 /* 1794 * If the interface isn't running, the interrupt couldn't 1795 * possibly have come from us. 1796 */ 1797 if ((sc->sc_flags & RTW_F_ENABLED) == 0 || 1798 (sc->sc_if.if_flags & IFF_RUNNING) == 0 || 1799 (sc->sc_dev.dv_flags & DVF_ACTIVE) == 0) { 1800 RTW_DPRINTF(RTW_DEBUG_INTR, ("%s: stray interrupt\n", 1801 sc->sc_dev.dv_xname)); 1802 return (0); 1803 } 1804 1805 for (i = 0; i < 10; i++) { 1806 isr = RTW_READ16(regs, RTW_ISR); 1807 1808 RTW_WRITE16(regs, RTW_ISR, isr); 1809 RTW_WBR(regs, RTW_ISR, RTW_ISR); 1810 1811 if (sc->sc_intr_ack != NULL) 1812 (*sc->sc_intr_ack)(regs); 1813 1814 if (isr == 0) 1815 break; 1816 1817 #ifdef RTW_DEBUG 1818 #define PRINTINTR(flag) do { \ 1819 if ((isr & flag) != 0) { \ 1820 printf("%s" #flag, delim); \ 1821 delim = ","; \ 1822 } \ 1823 } while (0) 1824 1825 if ((rtw_debug & RTW_DEBUG_INTR) != 0 && isr != 0) { 1826 const char *delim = "<"; 1827 1828 printf("%s: reg[ISR] = %x", sc->sc_dev.dv_xname, isr); 1829 1830 PRINTINTR(RTW_INTR_TXFOVW); 1831 PRINTINTR(RTW_INTR_TIMEOUT); 1832 PRINTINTR(RTW_INTR_BCNINT); 1833 PRINTINTR(RTW_INTR_ATIMINT); 1834 PRINTINTR(RTW_INTR_TBDER); 1835 PRINTINTR(RTW_INTR_TBDOK); 1836 PRINTINTR(RTW_INTR_THPDER); 1837 PRINTINTR(RTW_INTR_THPDOK); 1838 PRINTINTR(RTW_INTR_TNPDER); 1839 PRINTINTR(RTW_INTR_TNPDOK); 1840 PRINTINTR(RTW_INTR_RXFOVW); 1841 PRINTINTR(RTW_INTR_RDU); 1842 PRINTINTR(RTW_INTR_TLPDER); 1843 PRINTINTR(RTW_INTR_TLPDOK); 1844 PRINTINTR(RTW_INTR_RER); 1845 PRINTINTR(RTW_INTR_ROK); 1846 1847 printf(">\n"); 1848 } 1849 #undef PRINTINTR 1850 #endif /* RTW_DEBUG */ 1851 1852 if ((isr & RTW_INTR_RX) != 0) 1853 rtw_intr_rx(sc, isr & RTW_INTR_RX); 1854 if ((isr & RTW_INTR_TX) != 0) 1855 rtw_intr_tx(sc, isr & RTW_INTR_TX); 1856 #ifndef IEEE80211_STA_ONLY 1857 if ((isr & RTW_INTR_BEACON) != 0) 1858 rtw_intr_beacon(sc, isr & RTW_INTR_BEACON); 1859 if ((isr & RTW_INTR_ATIMINT) != 0) 1860 rtw_intr_atim(sc); 1861 #endif 1862 if ((isr & RTW_INTR_IOERROR) != 0) 1863 rtw_intr_ioerror(sc, isr & RTW_INTR_IOERROR); 1864 if ((isr & RTW_INTR_TIMEOUT) != 0) 1865 rtw_intr_timeout(sc); 1866 } 1867 1868 return 1; 1869 } 1870 1871 /* Must be called at splnet. */ 1872 void 1873 rtw_stop(struct ifnet *ifp, int disable) 1874 { 1875 int pri; 1876 struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc; 1877 struct ieee80211com *ic = &sc->sc_ic; 1878 struct rtw_regs *regs = &sc->sc_regs; 1879 1880 if ((sc->sc_flags & RTW_F_ENABLED) == 0) 1881 return; 1882 1883 rtw_suspend_ticks(sc); 1884 1885 ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 1886 1887 if ((sc->sc_flags & RTW_F_INVALID) == 0) { 1888 /* Disable interrupts. */ 1889 RTW_WRITE16(regs, RTW_IMR, 0); 1890 1891 RTW_WBW(regs, RTW_TPPOLL, RTW_IMR); 1892 1893 /* Stop the transmit and receive processes. First stop DMA, 1894 * then disable receiver and transmitter. 1895 */ 1896 RTW_WRITE8(regs, RTW_TPPOLL, RTW_TPPOLL_SALL); 1897 1898 RTW_SYNC(regs, RTW_TPPOLL, RTW_IMR); 1899 1900 rtw_io_enable(&sc->sc_regs, RTW_CR_RE|RTW_CR_TE, 0); 1901 } 1902 1903 for (pri = 0; pri < RTW_NTXPRI; pri++) { 1904 rtw_txsofts_release(sc->sc_dmat, &sc->sc_ic, 1905 &sc->sc_txsoft_blk[pri]); 1906 } 1907 1908 rtw_rxbufs_release(sc->sc_dmat, &sc->sc_rxsoft[0]); 1909 1910 if (disable) 1911 rtw_disable(sc); 1912 1913 /* Mark the interface as not running. Cancel the watchdog timer. */ 1914 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 1915 ifp->if_timer = 0; 1916 1917 return; 1918 } 1919 1920 #ifdef RTW_DEBUG 1921 const char * 1922 rtw_pwrstate_string(enum rtw_pwrstate power) 1923 { 1924 switch (power) { 1925 case RTW_ON: 1926 return "on"; 1927 case RTW_SLEEP: 1928 return "sleep"; 1929 case RTW_OFF: 1930 return "off"; 1931 default: 1932 return "unknown"; 1933 } 1934 } 1935 #endif 1936 1937 /* XXX For Maxim, I am using the RFMD settings gleaned from the 1938 * reference driver, plus a magic Maxim "ON" value that comes from 1939 * the Realtek document "Windows PG for Rtl8180." 1940 */ 1941 void 1942 rtw_maxim_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power, 1943 int before_rf, int digphy) 1944 { 1945 u_int32_t anaparm; 1946 1947 anaparm = RTW_READ(regs, RTW_ANAPARM_0); 1948 anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF); 1949 1950 switch (power) { 1951 case RTW_OFF: 1952 if (before_rf) 1953 return; 1954 anaparm |= RTW_ANAPARM_RFPOW_MAXIM_OFF; 1955 anaparm |= RTW_ANAPARM_TXDACOFF; 1956 break; 1957 case RTW_SLEEP: 1958 if (!before_rf) 1959 return; 1960 anaparm |= RTW_ANAPARM_RFPOW_MAXIM_SLEEP; 1961 anaparm |= RTW_ANAPARM_TXDACOFF; 1962 break; 1963 case RTW_ON: 1964 if (!before_rf) 1965 return; 1966 anaparm |= RTW_ANAPARM_RFPOW_MAXIM_ON; 1967 break; 1968 } 1969 RTW_DPRINTF(RTW_DEBUG_PWR, 1970 ("%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n", 1971 __func__, rtw_pwrstate_string(power), 1972 (before_rf) ? "before" : "after", anaparm)); 1973 1974 RTW_WRITE(regs, RTW_ANAPARM_0, anaparm); 1975 RTW_SYNC(regs, RTW_ANAPARM_0, RTW_ANAPARM_0); 1976 } 1977 1978 /* XXX I am using the RFMD settings gleaned from the reference 1979 * driver. They agree 1980 */ 1981 void 1982 rtw_rfmd_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power, 1983 int before_rf, int digphy) 1984 { 1985 u_int32_t anaparm; 1986 1987 anaparm = RTW_READ(regs, RTW_ANAPARM_0); 1988 anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF); 1989 1990 switch (power) { 1991 case RTW_OFF: 1992 if (before_rf) 1993 return; 1994 anaparm |= RTW_ANAPARM_RFPOW_RFMD_OFF; 1995 anaparm |= RTW_ANAPARM_TXDACOFF; 1996 break; 1997 case RTW_SLEEP: 1998 if (!before_rf) 1999 return; 2000 anaparm |= RTW_ANAPARM_RFPOW_RFMD_SLEEP; 2001 anaparm |= RTW_ANAPARM_TXDACOFF; 2002 break; 2003 case RTW_ON: 2004 if (!before_rf) 2005 return; 2006 anaparm |= RTW_ANAPARM_RFPOW_RFMD_ON; 2007 break; 2008 } 2009 RTW_DPRINTF(RTW_DEBUG_PWR, 2010 ("%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n", 2011 __func__, rtw_pwrstate_string(power), 2012 (before_rf) ? "before" : "after", anaparm)); 2013 2014 RTW_WRITE(regs, RTW_ANAPARM_0, anaparm); 2015 RTW_SYNC(regs, RTW_ANAPARM_0, RTW_ANAPARM_0); 2016 } 2017 2018 void 2019 rtw_philips_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power, 2020 int before_rf, int digphy) 2021 { 2022 u_int32_t anaparm; 2023 2024 anaparm = RTW_READ(regs, RTW_ANAPARM_0); 2025 anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF); 2026 2027 switch (power) { 2028 case RTW_OFF: 2029 if (before_rf) 2030 return; 2031 anaparm |= RTW_ANAPARM_RFPOW_PHILIPS_OFF; 2032 anaparm |= RTW_ANAPARM_TXDACOFF; 2033 break; 2034 case RTW_SLEEP: 2035 if (!before_rf) 2036 return; 2037 anaparm |= RTW_ANAPARM_RFPOW_PHILIPS_SLEEP; 2038 anaparm |= RTW_ANAPARM_TXDACOFF; 2039 break; 2040 case RTW_ON: 2041 if (!before_rf) 2042 return; 2043 if (digphy) { 2044 anaparm |= RTW_ANAPARM_RFPOW_DIG_PHILIPS_ON; 2045 /* XXX guess */ 2046 anaparm |= RTW_ANAPARM_TXDACOFF; 2047 } else 2048 anaparm |= RTW_ANAPARM_RFPOW_ANA_PHILIPS_ON; 2049 break; 2050 } 2051 RTW_DPRINTF(RTW_DEBUG_PWR, 2052 ("%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n", 2053 __func__, rtw_pwrstate_string(power), 2054 (before_rf) ? "before" : "after", anaparm)); 2055 2056 RTW_WRITE(regs, RTW_ANAPARM_0, anaparm); 2057 RTW_SYNC(regs, RTW_ANAPARM_0, RTW_ANAPARM_0); 2058 } 2059 2060 void 2061 rtw_rtl_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power, 2062 int before_rf, int digphy) 2063 { 2064 /* empty */ 2065 } 2066 2067 void 2068 rtw_pwrstate0(struct rtw_softc *sc, enum rtw_pwrstate power, int before_rf, 2069 int digphy) 2070 { 2071 struct rtw_regs *regs = &sc->sc_regs; 2072 2073 rtw_set_access(regs, RTW_ACCESS_ANAPARM); 2074 2075 (*sc->sc_pwrstate_cb)(regs, power, before_rf, digphy); 2076 2077 rtw_set_access(regs, RTW_ACCESS_NONE); 2078 2079 return; 2080 } 2081 2082 int 2083 rtw_pwrstate(struct rtw_softc *sc, enum rtw_pwrstate power) 2084 { 2085 int rc; 2086 2087 RTW_DPRINTF(RTW_DEBUG_PWR, 2088 ("%s: %s->%s\n", __func__, 2089 rtw_pwrstate_string(sc->sc_pwrstate), rtw_pwrstate_string(power))); 2090 2091 if (sc->sc_pwrstate == power) 2092 return 0; 2093 2094 rtw_pwrstate0(sc, power, 1, sc->sc_flags & RTW_F_DIGPHY); 2095 rc = (*sc->sc_rf_pwrstate)(sc, power); 2096 rtw_pwrstate0(sc, power, 0, sc->sc_flags & RTW_F_DIGPHY); 2097 2098 switch (power) { 2099 case RTW_ON: 2100 /* TBD set LEDs */ 2101 break; 2102 case RTW_SLEEP: 2103 /* TBD */ 2104 break; 2105 case RTW_OFF: 2106 /* TBD */ 2107 break; 2108 } 2109 if (rc == 0) 2110 sc->sc_pwrstate = power; 2111 else 2112 sc->sc_pwrstate = RTW_OFF; 2113 return rc; 2114 } 2115 2116 int 2117 rtw_tune(struct rtw_softc *sc) 2118 { 2119 struct ieee80211com *ic = &sc->sc_ic; 2120 u_int chan, idx; 2121 u_int8_t txpower; 2122 int rc; 2123 2124 KASSERT(ic->ic_bss->ni_chan != NULL); 2125 2126 chan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan); 2127 if (chan == 0 || chan == IEEE80211_CHAN_ANY) 2128 return 0; 2129 2130 if (chan == sc->sc_cur_chan) { 2131 RTW_DPRINTF(RTW_DEBUG_TUNE, 2132 ("%s: already tuned chan #%d\n", __func__, chan)); 2133 return 0; 2134 } 2135 2136 rtw_suspend_ticks(sc); 2137 2138 rtw_io_enable(&sc->sc_regs, RTW_CR_RE | RTW_CR_TE, 0); 2139 2140 /* TBD wait for Tx to complete */ 2141 2142 KASSERT((sc->sc_flags & RTW_F_ENABLED) != 0); 2143 2144 idx = RTW_SR_TXPOWER1 + 2145 ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan) - 1; 2146 KASSERT2(idx >= RTW_SR_TXPOWER1 && idx <= RTW_SR_TXPOWER14, 2147 ("%s: channel %d out of range", __func__, 2148 idx - RTW_SR_TXPOWER1 + 1)); 2149 txpower = RTW_SR_GET(&sc->sc_srom, idx); 2150 2151 if ((rc = rtw_phy_init(sc)) != 0) { 2152 /* XXX condition on powersaving */ 2153 printf("%s: phy init failed\n", sc->sc_dev.dv_xname); 2154 } 2155 2156 sc->sc_cur_chan = chan; 2157 2158 rtw_io_enable(&sc->sc_regs, RTW_CR_RE | RTW_CR_TE, 1); 2159 2160 rtw_resume_ticks(sc); 2161 2162 return rc; 2163 } 2164 2165 void 2166 rtw_disable(struct rtw_softc *sc) 2167 { 2168 int rc; 2169 2170 if ((sc->sc_flags & RTW_F_ENABLED) == 0) 2171 return; 2172 2173 /* turn off PHY */ 2174 if ((sc->sc_flags & RTW_F_INVALID) == 0 && 2175 (rc = rtw_pwrstate(sc, RTW_OFF)) != 0) { 2176 printf("%s: failed to turn off PHY (%d)\n", 2177 sc->sc_dev.dv_xname, rc); 2178 } 2179 2180 if (sc->sc_disable != NULL) 2181 (*sc->sc_disable)(sc); 2182 2183 sc->sc_flags &= ~RTW_F_ENABLED; 2184 } 2185 2186 int 2187 rtw_enable(struct rtw_softc *sc) 2188 { 2189 if ((sc->sc_flags & RTW_F_ENABLED) == 0) { 2190 if (sc->sc_enable != NULL && (*sc->sc_enable)(sc) != 0) { 2191 printf("%s: device enable failed\n", 2192 sc->sc_dev.dv_xname); 2193 return (EIO); 2194 } 2195 sc->sc_flags |= RTW_F_ENABLED; 2196 } 2197 return (0); 2198 } 2199 2200 void 2201 rtw_transmit_config(struct rtw_softc *sc) 2202 { 2203 struct rtw_regs *regs = &sc->sc_regs; 2204 u_int32_t tcr; 2205 2206 tcr = RTW_READ(regs, RTW_TCR); 2207 2208 tcr |= RTW_TCR_CWMIN; 2209 tcr &= ~RTW_TCR_MXDMA_MASK; 2210 tcr |= RTW_TCR_MXDMA_256; 2211 if ((sc->sc_flags & RTW_F_RTL8185) == 0) 2212 tcr |= RTW8180_TCR_SAT; /* send ACK as fast as possible */ 2213 tcr &= ~RTW_TCR_LBK_MASK; 2214 tcr |= RTW_TCR_LBK_NORMAL; /* normal operating mode */ 2215 2216 /* set short/long retry limits */ 2217 tcr &= ~(RTW_TCR_SRL_MASK|RTW_TCR_LRL_MASK); 2218 tcr |= LSHIFT(4, RTW_TCR_SRL_MASK) | LSHIFT(4, RTW_TCR_LRL_MASK); 2219 2220 tcr &= ~RTW_TCR_CRC; /* NIC appends CRC32 */ 2221 2222 RTW_WRITE(regs, RTW_TCR, tcr); 2223 RTW_SYNC(regs, RTW_TCR, RTW_TCR); 2224 } 2225 2226 void 2227 rtw_enable_interrupts(struct rtw_softc *sc) 2228 { 2229 struct rtw_regs *regs = &sc->sc_regs; 2230 2231 sc->sc_inten = RTW_INTR_RX|RTW_INTR_TX|RTW_INTR_BEACON|RTW_INTR_ATIMINT; 2232 sc->sc_inten |= RTW_INTR_IOERROR|RTW_INTR_TIMEOUT; 2233 2234 RTW_WRITE16(regs, RTW_IMR, sc->sc_inten); 2235 RTW_WBW(regs, RTW_IMR, RTW_ISR); 2236 RTW_WRITE16(regs, RTW_ISR, 0xffff); 2237 RTW_SYNC(regs, RTW_IMR, RTW_ISR); 2238 2239 /* XXX necessary? */ 2240 if (sc->sc_intr_ack != NULL) 2241 (*sc->sc_intr_ack)(regs); 2242 } 2243 2244 void 2245 rtw_set_nettype(struct rtw_softc *sc, enum ieee80211_opmode opmode) 2246 { 2247 uint8_t msr; 2248 2249 /* I'm guessing that MSR is protected as CONFIG[0123] are. */ 2250 rtw_set_access(&sc->sc_regs, RTW_ACCESS_CONFIG); 2251 2252 msr = RTW_READ8(&sc->sc_regs, RTW_MSR) & ~RTW_MSR_NETYPE_MASK; 2253 2254 switch (opmode) { 2255 #ifndef IEEE80211_STA_ONLY 2256 case IEEE80211_M_AHDEMO: 2257 case IEEE80211_M_IBSS: 2258 msr |= RTW_MSR_NETYPE_ADHOC_OK; 2259 break; 2260 case IEEE80211_M_HOSTAP: 2261 msr |= RTW_MSR_NETYPE_AP_OK; 2262 break; 2263 #endif 2264 case IEEE80211_M_MONITOR: 2265 /* XXX */ 2266 msr |= RTW_MSR_NETYPE_NOLINK; 2267 break; 2268 case IEEE80211_M_STA: 2269 msr |= RTW_MSR_NETYPE_INFRA_OK; 2270 break; 2271 default: 2272 break; 2273 } 2274 RTW_WRITE8(&sc->sc_regs, RTW_MSR, msr); 2275 2276 rtw_set_access(&sc->sc_regs, RTW_ACCESS_NONE); 2277 } 2278 2279 void 2280 rtw_pktfilt_load(struct rtw_softc *sc) 2281 { 2282 struct rtw_regs *regs = &sc->sc_regs; 2283 struct ieee80211com *ic = &sc->sc_ic; 2284 struct arpcom *ec = &ic->ic_ac; 2285 struct ifnet *ifp = &sc->sc_ic.ic_if; 2286 int hash; 2287 u_int32_t hashes[2] = { 0, 0 }; 2288 struct ether_multi *enm; 2289 struct ether_multistep step; 2290 2291 /* XXX might be necessary to stop Rx/Tx engines while setting filters */ 2292 2293 sc->sc_rcr &= ~RTW_RCR_PKTFILTER_MASK; 2294 sc->sc_rcr &= ~(RTW_RCR_MXDMA_MASK | RTW8180_RCR_RXFTH_MASK); 2295 2296 sc->sc_rcr |= RTW_RCR_PKTFILTER_DEFAULT; 2297 /* MAC auto-reset PHY (huh?) */ 2298 sc->sc_rcr |= RTW_RCR_ENMARP; 2299 /* DMA whole Rx packets, only. Set Tx DMA burst size to 1024 bytes. */ 2300 sc->sc_rcr |= RTW_RCR_MXDMA_1024 | RTW8180_RCR_RXFTH_WHOLE; 2301 2302 switch (ic->ic_opmode) { 2303 case IEEE80211_M_MONITOR: 2304 sc->sc_rcr |= RTW_RCR_MONITOR; 2305 break; 2306 #ifndef IEEE80211_STA_ONLY 2307 case IEEE80211_M_AHDEMO: 2308 case IEEE80211_M_IBSS: 2309 /* receive broadcasts in our BSS */ 2310 sc->sc_rcr |= RTW_RCR_ADD3; 2311 break; 2312 #endif 2313 default: 2314 break; 2315 } 2316 2317 ifp->if_flags &= ~IFF_ALLMULTI; 2318 2319 /* XXX accept all broadcast if scanning */ 2320 if ((ifp->if_flags & IFF_BROADCAST) != 0) 2321 sc->sc_rcr |= RTW_RCR_AB; /* accept all broadcast */ 2322 2323 if (ifp->if_flags & IFF_PROMISC) { 2324 sc->sc_rcr |= RTW_RCR_AB; /* accept all broadcast */ 2325 allmulti: 2326 ifp->if_flags |= IFF_ALLMULTI; 2327 goto setit; 2328 } 2329 2330 /* 2331 * Program the 64-bit multicast hash filter. 2332 */ 2333 ETHER_FIRST_MULTI(step, ec, enm); 2334 while (enm != NULL) { 2335 /* XXX */ 2336 if (bcmp(enm->enm_addrlo, enm->enm_addrhi, 2337 ETHER_ADDR_LEN) != 0) 2338 goto allmulti; 2339 2340 hash = ether_crc32_be((enm->enm_addrlo), 2341 IEEE80211_ADDR_LEN) >> 26; 2342 hashes[hash >> 5] |= (1 << (hash & 0x1f)); 2343 sc->sc_rcr |= RTW_RCR_AM; 2344 ETHER_NEXT_MULTI(step, enm); 2345 } 2346 2347 /* all bits set => hash is useless */ 2348 if (~(hashes[0] & hashes[1]) == 0) 2349 goto allmulti; 2350 2351 setit: 2352 if (ifp->if_flags & IFF_ALLMULTI) { 2353 sc->sc_rcr |= RTW_RCR_AM; /* accept all multicast */ 2354 hashes[0] = hashes[1] = 0xffffffff; 2355 } 2356 2357 RTW_WRITE(regs, RTW_MAR0, hashes[0]); 2358 RTW_WRITE(regs, RTW_MAR1, hashes[1]); 2359 RTW_WRITE(regs, RTW_RCR, sc->sc_rcr); 2360 RTW_SYNC(regs, RTW_MAR0, RTW_RCR); /* RTW_MAR0 < RTW_MAR1 < RTW_RCR */ 2361 2362 DPRINTF(sc, RTW_DEBUG_PKTFILT, 2363 ("%s: RTW_MAR0 %08x RTW_MAR1 %08x RTW_RCR %08x\n", 2364 sc->sc_dev.dv_xname, RTW_READ(regs, RTW_MAR0), 2365 RTW_READ(regs, RTW_MAR1), RTW_READ(regs, RTW_RCR))); 2366 2367 return; 2368 } 2369 2370 /* Must be called at splnet. */ 2371 int 2372 rtw_init(struct ifnet *ifp) 2373 { 2374 struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc; 2375 struct ieee80211com *ic = &sc->sc_ic; 2376 struct rtw_regs *regs = &sc->sc_regs; 2377 int rc = 0; 2378 2379 if ((rc = rtw_enable(sc)) != 0) 2380 goto out; 2381 2382 /* Cancel pending I/O and reset. */ 2383 rtw_stop(ifp, 0); 2384 2385 ic->ic_bss->ni_chan = ic->ic_ibss_chan; 2386 DPRINTF(sc, RTW_DEBUG_TUNE, ("%s: channel %d freq %d flags 0x%04x\n", 2387 __func__, ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan), 2388 ic->ic_bss->ni_chan->ic_freq, ic->ic_bss->ni_chan->ic_flags)); 2389 2390 if ((rc = rtw_pwrstate(sc, RTW_OFF)) != 0) 2391 goto out; 2392 2393 if ((rc = rtw_swring_setup(sc)) != 0) 2394 goto out; 2395 2396 rtw_transmit_config(sc); 2397 2398 rtw_set_access(regs, RTW_ACCESS_CONFIG); 2399 2400 RTW_WRITE8(regs, RTW_MSR, 0x0); /* no link */ 2401 RTW_WBW(regs, RTW_MSR, RTW_BRSR); 2402 2403 /* long PLCP header, 1Mb/2Mb basic rate */ 2404 if (sc->sc_flags & RTW_F_RTL8185) 2405 RTW_WRITE16(regs, RTW_BRSR, RTW8185_BRSR_MBR_2MBPS); 2406 else 2407 RTW_WRITE16(regs, RTW_BRSR, RTW8180_BRSR_MBR_2MBPS); 2408 RTW_SYNC(regs, RTW_BRSR, RTW_BRSR); 2409 2410 rtw_set_access(regs, RTW_ACCESS_ANAPARM); 2411 rtw_set_access(regs, RTW_ACCESS_NONE); 2412 2413 /* XXX from reference sources */ 2414 RTW_WRITE(regs, RTW_FEMR, 0xffff); 2415 RTW_SYNC(regs, RTW_FEMR, RTW_FEMR); 2416 2417 rtw_set_rfprog(regs, sc->sc_rfchipid, sc->sc_dev.dv_xname); 2418 2419 RTW_WRITE8(regs, RTW_PHYDELAY, sc->sc_phydelay); 2420 /* from Linux driver */ 2421 RTW_WRITE8(regs, RTW_CRCOUNT, RTW_CRCOUNT_MAGIC); 2422 2423 RTW_SYNC(regs, RTW_PHYDELAY, RTW_CRCOUNT); 2424 2425 rtw_enable_interrupts(sc); 2426 2427 rtw_pktfilt_load(sc); 2428 2429 rtw_hwring_setup(sc); 2430 2431 rtw_io_enable(regs, RTW_CR_RE|RTW_CR_TE, 1); 2432 2433 ifp->if_flags |= IFF_RUNNING; 2434 ic->ic_state = IEEE80211_S_INIT; 2435 2436 RTW_WRITE16(regs, RTW_BSSID16, 0x0); 2437 RTW_WRITE(regs, RTW_BSSID32, 0x0); 2438 2439 rtw_resume_ticks(sc); 2440 2441 rtw_set_nettype(sc, IEEE80211_M_MONITOR); 2442 2443 if (ic->ic_opmode == IEEE80211_M_MONITOR) 2444 return ieee80211_new_state(ic, IEEE80211_S_RUN, -1); 2445 else 2446 return ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 2447 2448 out: 2449 printf("%s: interface not running\n", sc->sc_dev.dv_xname); 2450 return rc; 2451 } 2452 2453 void 2454 rtw_led_init(struct rtw_regs *regs) 2455 { 2456 u_int8_t cfg0, cfg1; 2457 2458 rtw_set_access(regs, RTW_ACCESS_CONFIG); 2459 2460 cfg0 = RTW_READ8(regs, RTW_CONFIG0); 2461 cfg0 |= RTW8180_CONFIG0_LEDGPOEN; 2462 RTW_WRITE8(regs, RTW_CONFIG0, cfg0); 2463 2464 cfg1 = RTW_READ8(regs, RTW_CONFIG1); 2465 RTW_DPRINTF(RTW_DEBUG_LED, 2466 ("%s: read % from reg[CONFIG1]\n", __func__, cfg1)); 2467 2468 cfg1 &= ~RTW_CONFIG1_LEDS_MASK; 2469 cfg1 |= RTW_CONFIG1_LEDS_TX_RX; 2470 RTW_WRITE8(regs, RTW_CONFIG1, cfg1); 2471 2472 rtw_set_access(regs, RTW_ACCESS_NONE); 2473 } 2474 2475 /* 2476 * IEEE80211_S_INIT: LED1 off 2477 * 2478 * IEEE80211_S_AUTH, 2479 * IEEE80211_S_ASSOC, 2480 * IEEE80211_S_SCAN: LED1 blinks @ 1 Hz, blinks at 5Hz for tx/rx 2481 * 2482 * IEEE80211_S_RUN: LED1 on, blinks @ 5Hz for tx/rx 2483 */ 2484 void 2485 rtw_led_newstate(struct rtw_softc *sc, enum ieee80211_state nstate) 2486 { 2487 struct rtw_led_state *ls; 2488 2489 ls = &sc->sc_led_state; 2490 2491 switch (nstate) { 2492 case IEEE80211_S_INIT: 2493 rtw_led_init(&sc->sc_regs); 2494 timeout_del(&ls->ls_slow_ch); 2495 timeout_del(&ls->ls_fast_ch); 2496 ls->ls_slowblink = 0; 2497 ls->ls_actblink = 0; 2498 ls->ls_default = 0; 2499 break; 2500 case IEEE80211_S_SCAN: 2501 timeout_add(&ls->ls_slow_ch, RTW_LED_SLOW_TICKS); 2502 timeout_add(&ls->ls_fast_ch, RTW_LED_FAST_TICKS); 2503 /*FALLTHROUGH*/ 2504 case IEEE80211_S_AUTH: 2505 case IEEE80211_S_ASSOC: 2506 ls->ls_default = RTW_LED1; 2507 ls->ls_actblink = RTW_LED1; 2508 ls->ls_slowblink = RTW_LED1; 2509 break; 2510 case IEEE80211_S_RUN: 2511 ls->ls_slowblink = 0; 2512 break; 2513 } 2514 rtw_led_set(ls, &sc->sc_regs, sc->sc_hwverid); 2515 } 2516 2517 void 2518 rtw_led_set(struct rtw_led_state *ls, struct rtw_regs *regs, u_int hwverid) 2519 { 2520 u_int8_t led_condition; 2521 bus_size_t ofs; 2522 u_int8_t mask, newval, val; 2523 2524 led_condition = ls->ls_default; 2525 2526 if (ls->ls_state & RTW_LED_S_SLOW) 2527 led_condition ^= ls->ls_slowblink; 2528 if (ls->ls_state & (RTW_LED_S_RX|RTW_LED_S_TX)) 2529 led_condition ^= ls->ls_actblink; 2530 2531 RTW_DPRINTF(RTW_DEBUG_LED, 2532 ("%s: LED condition %\n", __func__, led_condition)); 2533 2534 switch (hwverid) { 2535 default: 2536 case RTW_TCR_HWVERID_RTL8180F: 2537 ofs = RTW_PSR; 2538 newval = mask = RTW_PSR_LEDGPO0 | RTW_PSR_LEDGPO1; 2539 if (led_condition & RTW_LED0) 2540 newval &= ~RTW_PSR_LEDGPO0; 2541 if (led_condition & RTW_LED1) 2542 newval &= ~RTW_PSR_LEDGPO1; 2543 break; 2544 case RTW_TCR_HWVERID_RTL8180D: 2545 ofs = RTW_9346CR; 2546 mask = RTW_9346CR_EEM_MASK | RTW_9346CR_EEDI | RTW_9346CR_EECS; 2547 newval = RTW_9346CR_EEM_PROGRAM; 2548 if (led_condition & RTW_LED0) 2549 newval |= RTW_9346CR_EEDI; 2550 if (led_condition & RTW_LED1) 2551 newval |= RTW_9346CR_EECS; 2552 break; 2553 } 2554 val = RTW_READ8(regs, ofs); 2555 RTW_DPRINTF(RTW_DEBUG_LED, 2556 ("%s: read % from reg[%#02]\n", __func__, val, 2557 (u_int *)ofs)); 2558 val &= ~mask; 2559 val |= newval; 2560 RTW_WRITE8(regs, ofs, val); 2561 RTW_DPRINTF(RTW_DEBUG_LED, 2562 ("%s: wrote % to reg[%#02]\n", __func__, val, 2563 (u_int *)ofs)); 2564 RTW_SYNC(regs, ofs, ofs); 2565 } 2566 2567 void 2568 rtw_led_fastblink(void *arg) 2569 { 2570 int ostate, s; 2571 struct rtw_softc *sc = (struct rtw_softc *)arg; 2572 struct rtw_led_state *ls = &sc->sc_led_state; 2573 2574 s = splnet(); 2575 ostate = ls->ls_state; 2576 ls->ls_state ^= ls->ls_event; 2577 2578 if ((ls->ls_event & RTW_LED_S_TX) == 0) 2579 ls->ls_state &= ~RTW_LED_S_TX; 2580 2581 if ((ls->ls_event & RTW_LED_S_RX) == 0) 2582 ls->ls_state &= ~RTW_LED_S_RX; 2583 2584 ls->ls_event = 0; 2585 2586 if (ostate != ls->ls_state) 2587 rtw_led_set(ls, &sc->sc_regs, sc->sc_hwverid); 2588 splx(s); 2589 2590 timeout_add(&ls->ls_fast_ch, RTW_LED_FAST_TICKS); 2591 } 2592 2593 void 2594 rtw_led_slowblink(void *arg) 2595 { 2596 int s; 2597 struct rtw_softc *sc = (struct rtw_softc *)arg; 2598 struct rtw_led_state *ls = &sc->sc_led_state; 2599 2600 s = splnet(); 2601 ls->ls_state ^= RTW_LED_S_SLOW; 2602 rtw_led_set(ls, &sc->sc_regs, sc->sc_hwverid); 2603 splx(s); 2604 timeout_add(&ls->ls_slow_ch, RTW_LED_SLOW_TICKS); 2605 } 2606 2607 void 2608 rtw_led_attach(struct rtw_led_state *ls, void *arg) 2609 { 2610 timeout_set(&ls->ls_fast_ch, rtw_led_fastblink, arg); 2611 timeout_set(&ls->ls_slow_ch, rtw_led_slowblink, arg); 2612 } 2613 2614 int 2615 rtw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 2616 { 2617 struct rtw_softc *sc = ifp->if_softc; 2618 struct ieee80211com *ic = &sc->sc_ic; 2619 struct ifaddr *ifa = (struct ifaddr *)data; 2620 struct ifreq *ifr = (struct ifreq *)data; 2621 int rc = 0, s; 2622 2623 s = splnet(); 2624 2625 switch (cmd) { 2626 case SIOCSIFADDR: 2627 ifp->if_flags |= IFF_UP; 2628 #ifdef INET 2629 if (ifa->ifa_addr->sa_family == AF_INET) { 2630 arp_ifinit(&ic->ic_ac, ifa); 2631 } 2632 #endif /* INET */ 2633 /* FALLTHROUGH */ 2634 2635 case SIOCSIFFLAGS: 2636 if ((ifp->if_flags & IFF_UP) != 0) { 2637 if ((sc->sc_flags & RTW_F_ENABLED) != 0) { 2638 rtw_pktfilt_load(sc); 2639 } else 2640 rc = rtw_init(ifp); 2641 } else if ((sc->sc_flags & RTW_F_ENABLED) != 0) 2642 rtw_stop(ifp, 1); 2643 break; 2644 2645 case SIOCADDMULTI: 2646 case SIOCDELMULTI: 2647 if (cmd == SIOCADDMULTI) 2648 rc = ether_addmulti(ifr, &sc->sc_ic.ic_ac); 2649 else 2650 rc = ether_delmulti(ifr, &sc->sc_ic.ic_ac); 2651 if (rc != ENETRESET) 2652 break; 2653 if (ifp->if_flags & IFF_RUNNING) 2654 rtw_pktfilt_load(sc); 2655 rc = 0; 2656 break; 2657 2658 default: 2659 if ((rc = ieee80211_ioctl(ifp, cmd, data)) == ENETRESET) { 2660 if ((sc->sc_flags & RTW_F_ENABLED) != 0) 2661 rc = rtw_init(ifp); 2662 else 2663 rc = 0; 2664 } 2665 break; 2666 } 2667 2668 splx(s); 2669 return rc; 2670 } 2671 2672 /* Select a transmit ring with at least one h/w and s/w descriptor free. 2673 * Return 0 on success, -1 on failure. 2674 */ 2675 int 2676 rtw_txring_choose(struct rtw_softc *sc, struct rtw_txsoft_blk **tsbp, 2677 struct rtw_txdesc_blk **tdbp, int pri) 2678 { 2679 struct rtw_txsoft_blk *tsb; 2680 struct rtw_txdesc_blk *tdb; 2681 2682 KASSERT(pri >= 0 && pri < RTW_NTXPRI); 2683 2684 tsb = &sc->sc_txsoft_blk[pri]; 2685 tdb = &sc->sc_txdesc_blk[pri]; 2686 2687 if (SIMPLEQ_EMPTY(&tsb->tsb_freeq) || tdb->tdb_nfree == 0) { 2688 if (tsb->tsb_tx_timer == 0) 2689 tsb->tsb_tx_timer = 5; 2690 *tsbp = NULL; 2691 *tdbp = NULL; 2692 return -1; 2693 } 2694 *tsbp = tsb; 2695 *tdbp = tdb; 2696 return 0; 2697 } 2698 2699 struct mbuf * 2700 rtw_80211_dequeue(struct rtw_softc *sc, struct ifqueue *ifq, int pri, 2701 struct rtw_txsoft_blk **tsbp, struct rtw_txdesc_blk **tdbp, 2702 struct ieee80211_node **nip, short *if_flagsp) 2703 { 2704 struct mbuf *m; 2705 2706 if (IF_IS_EMPTY(ifq)) 2707 return NULL; 2708 if (rtw_txring_choose(sc, tsbp, tdbp, pri) == -1) { 2709 DPRINTF(sc, RTW_DEBUG_XMIT_RSRC, ("%s: no ring %d descriptor\n", 2710 __func__, pri)); 2711 *if_flagsp |= IFF_OACTIVE; 2712 sc->sc_if.if_timer = 1; 2713 return NULL; 2714 } 2715 IF_DEQUEUE(ifq, m); 2716 *nip = (struct ieee80211_node *)m->m_pkthdr.rcvif; 2717 m->m_pkthdr.rcvif = NULL; 2718 return m; 2719 } 2720 2721 /* Point *mp at the next 802.11 frame to transmit. Point *tsbp 2722 * at the driver's selection of transmit control block for the packet. 2723 */ 2724 int 2725 rtw_dequeue(struct ifnet *ifp, struct rtw_txsoft_blk **tsbp, 2726 struct rtw_txdesc_blk **tdbp, struct mbuf **mp, 2727 struct ieee80211_node **nip) 2728 { 2729 struct ieee80211com *ic; 2730 struct ieee80211_frame *wh; 2731 struct ieee80211_key *k; 2732 struct mbuf *m0; 2733 struct rtw_softc *sc; 2734 short *if_flagsp; 2735 2736 sc = (struct rtw_softc *)ifp->if_softc; 2737 ic = &sc->sc_ic; 2738 2739 DPRINTF(sc, RTW_DEBUG_XMIT, 2740 ("%s: enter %s\n", sc->sc_dev.dv_xname, __func__)); 2741 2742 if_flagsp = &ifp->if_flags; 2743 2744 if (ic->ic_state == IEEE80211_S_RUN && 2745 (*mp = rtw_80211_dequeue(sc, &sc->sc_beaconq, RTW_TXPRIBCN, tsbp, 2746 tdbp, nip, if_flagsp)) != NULL) { 2747 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: dequeue beacon frame\n", 2748 __func__)); 2749 return 0; 2750 } 2751 2752 if ((*mp = rtw_80211_dequeue(sc, &ic->ic_mgtq, RTW_TXPRIMD, tsbp, 2753 tdbp, nip, if_flagsp)) != NULL) { 2754 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: dequeue mgt frame\n", 2755 __func__)); 2756 return 0; 2757 } 2758 2759 if (sc->sc_ic.ic_state != IEEE80211_S_RUN) { 2760 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: not running\n", __func__)); 2761 return 0; 2762 } 2763 2764 if ((*mp = rtw_80211_dequeue(sc, &ic->ic_pwrsaveq, RTW_TXPRIHI, 2765 tsbp, tdbp, nip, if_flagsp)) != NULL) { 2766 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: dequeue pwrsave frame\n", 2767 __func__)); 2768 return 0; 2769 } 2770 2771 if (ic->ic_state != IEEE80211_S_RUN) { 2772 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: not running\n", __func__)); 2773 return 0; 2774 } 2775 2776 *mp = NULL; 2777 2778 IFQ_POLL(&ifp->if_snd, m0); 2779 if (m0 == NULL) { 2780 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: no frame ready\n", 2781 __func__)); 2782 return 0; 2783 } 2784 2785 if (rtw_txring_choose(sc, tsbp, tdbp, RTW_TXPRIMD) == -1) { 2786 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: no descriptor\n", __func__)); 2787 *if_flagsp |= IFF_OACTIVE; 2788 sc->sc_if.if_timer = 1; 2789 return 0; 2790 } 2791 2792 IFQ_DEQUEUE(&ifp->if_snd, m0); 2793 if (m0 == NULL) { 2794 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: no frame/ring ready\n", 2795 __func__)); 2796 return 0; 2797 } 2798 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: dequeue data frame\n", __func__)); 2799 ifp->if_opackets++; 2800 #if NBPFILTER > 0 2801 if (ifp->if_bpf) 2802 bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT); 2803 #endif 2804 if ((m0 = ieee80211_encap(ifp, m0, nip)) == NULL) { 2805 DPRINTF(sc, RTW_DEBUG_XMIT, 2806 ("%s: encap error\n", __func__)); 2807 ifp->if_oerrors++; 2808 return -1; 2809 } 2810 2811 /* XXX should do WEP in hardware */ 2812 if (ic->ic_flags & IEEE80211_F_WEPON) { 2813 wh = mtod(m0, struct ieee80211_frame *); 2814 k = ieee80211_get_txkey(ic, wh, *nip); 2815 if ((m0 = ieee80211_encrypt(ic, m0, k)) == NULL) 2816 return -1; 2817 } 2818 2819 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: leave\n", __func__)); 2820 *mp = m0; 2821 return 0; 2822 } 2823 2824 int 2825 rtw_seg_too_short(bus_dmamap_t dmamap) 2826 { 2827 int i; 2828 for (i = 0; i < dmamap->dm_nsegs; i++) { 2829 if (dmamap->dm_segs[i].ds_len < 4) { 2830 printf("%s: segment too short\n", __func__); 2831 return 1; 2832 } 2833 } 2834 return 0; 2835 } 2836 2837 /* TBD factor with atw_start */ 2838 struct mbuf * 2839 rtw_dmamap_load_txbuf(bus_dma_tag_t dmat, bus_dmamap_t dmam, struct mbuf *chain, 2840 u_int ndescfree, short *ifflagsp, const char *dvname) 2841 { 2842 int first, rc; 2843 struct mbuf *m, *m0; 2844 2845 m0 = chain; 2846 2847 /* 2848 * Load the DMA map. Copy and try (once) again if the packet 2849 * didn't fit in the alloted number of segments. 2850 */ 2851 for (first = 1; 2852 ((rc = bus_dmamap_load_mbuf(dmat, dmam, m0, 2853 BUS_DMA_WRITE|BUS_DMA_NOWAIT)) != 0 || 2854 dmam->dm_nsegs > ndescfree || rtw_seg_too_short(dmam)) && first; 2855 first = 0) { 2856 if (rc == 0) 2857 bus_dmamap_unload(dmat, dmam); 2858 MGETHDR(m, M_DONTWAIT, MT_DATA); 2859 if (m == NULL) { 2860 printf("%s: unable to allocate Tx mbuf\n", 2861 dvname); 2862 break; 2863 } 2864 if (m0->m_pkthdr.len > MHLEN) { 2865 MCLGET(m, M_DONTWAIT); 2866 if ((m->m_flags & M_EXT) == 0) { 2867 printf("%s: cannot allocate Tx cluster\n", 2868 dvname); 2869 m_freem(m); 2870 break; 2871 } 2872 } 2873 m_copydata(m0, 0, m0->m_pkthdr.len, mtod(m, caddr_t)); 2874 m->m_pkthdr.len = m->m_len = m0->m_pkthdr.len; 2875 m_freem(m0); 2876 m0 = m; 2877 m = NULL; 2878 } 2879 if (rc != 0) { 2880 printf("%s: cannot load Tx buffer, rc = %d\n", dvname, rc); 2881 m_freem(m0); 2882 return NULL; 2883 } else if (rtw_seg_too_short(dmam)) { 2884 printf("%s: cannot load Tx buffer, segment too short\n", 2885 dvname); 2886 bus_dmamap_unload(dmat, dmam); 2887 m_freem(m0); 2888 return NULL; 2889 } else if (dmam->dm_nsegs > ndescfree) { 2890 printf("%s: too many tx segments\n", dvname); 2891 bus_dmamap_unload(dmat, dmam); 2892 m_freem(m0); 2893 return NULL; 2894 } 2895 return m0; 2896 } 2897 2898 2899 /* 2900 * Arguments in: 2901 * 2902 * paylen: payload length (no FCS, no WEP header) 2903 * 2904 * hdrlen: header length 2905 * 2906 * rate: MSDU speed, units 500kb/s 2907 * 2908 * flags: IEEE80211_F_SHPREAMBLE (use short preamble), 2909 * IEEE80211_F_SHSLOT (use short slot length) 2910 * 2911 * Arguments out: 2912 * 2913 * d: 802.11 Duration field for RTS, 2914 * 802.11 Duration field for data frame, 2915 * PLCP Length for data frame, 2916 * residual octets at end of data slot 2917 */ 2918 int 2919 rtw_compute_duration1(int len, int use_ack, uint32_t flags, int rate, 2920 struct rtw_duration *d) 2921 { 2922 int pre, ctsrate; 2923 int ack, bitlen, data_dur, remainder; 2924 2925 /* RTS reserves medium for SIFS | CTS | SIFS | (DATA) | SIFS | ACK 2926 * DATA reserves medium for SIFS | ACK 2927 * 2928 * XXXMYC: no ACK on multicast/broadcast or control packets 2929 */ 2930 2931 bitlen = len * 8; 2932 2933 pre = IEEE80211_DUR_DS_SIFS; 2934 if ((flags & IEEE80211_F_SHPREAMBLE) != 0) 2935 pre += IEEE80211_DUR_DS_SHORT_PREAMBLE + 2936 IEEE80211_DUR_DS_FAST_PLCPHDR; 2937 else 2938 pre += IEEE80211_DUR_DS_LONG_PREAMBLE + 2939 IEEE80211_DUR_DS_SLOW_PLCPHDR; 2940 2941 d->d_residue = 0; 2942 data_dur = (bitlen * 2) / rate; 2943 remainder = (bitlen * 2) % rate; 2944 if (remainder != 0) { 2945 d->d_residue = (rate - remainder) / 16; 2946 data_dur++; 2947 } 2948 2949 switch (rate) { 2950 case 2: /* 1 Mb/s */ 2951 case 4: /* 2 Mb/s */ 2952 /* 1 - 2 Mb/s WLAN: send ACK/CTS at 1 Mb/s */ 2953 ctsrate = 2; 2954 break; 2955 case 11: /* 5.5 Mb/s */ 2956 case 22: /* 11 Mb/s */ 2957 case 44: /* 22 Mb/s */ 2958 /* 5.5 - 11 Mb/s WLAN: send ACK/CTS at 2 Mb/s */ 2959 ctsrate = 4; 2960 break; 2961 default: 2962 /* TBD */ 2963 return -1; 2964 } 2965 2966 d->d_plcp_len = data_dur; 2967 2968 ack = (use_ack) ? pre + (IEEE80211_DUR_DS_SLOW_ACK * 2) / ctsrate : 0; 2969 2970 d->d_rts_dur = 2971 pre + (IEEE80211_DUR_DS_SLOW_CTS * 2) / ctsrate + 2972 pre + data_dur + 2973 ack; 2974 2975 d->d_data_dur = ack; 2976 2977 return 0; 2978 } 2979 2980 /* 2981 * Arguments in: 2982 * 2983 * wh: 802.11 header 2984 * 2985 * len: packet length 2986 * 2987 * rate: MSDU speed, units 500kb/s 2988 * 2989 * fraglen: fragment length, set to maximum (or higher) for no 2990 * fragmentation 2991 * 2992 * flags: IEEE80211_F_WEPON (hardware adds WEP), 2993 * IEEE80211_F_SHPREAMBLE (use short preamble), 2994 * IEEE80211_F_SHSLOT (use short slot length) 2995 * 2996 * Arguments out: 2997 * 2998 * d0: 802.11 Duration fields (RTS/Data), PLCP Length, Service fields 2999 * of first/only fragment 3000 * 3001 * dn: 802.11 Duration fields (RTS/Data), PLCP Length, Service fields 3002 * of first/only fragment 3003 */ 3004 int 3005 rtw_compute_duration(struct ieee80211_frame *wh, int len, uint32_t flags, 3006 int fraglen, int rate, struct rtw_duration *d0, struct rtw_duration *dn, 3007 int *npktp, int debug) 3008 { 3009 int ack, rc; 3010 int firstlen, hdrlen, lastlen, lastlen0, npkt, overlen, paylen; 3011 3012 if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS) 3013 hdrlen = sizeof(struct ieee80211_frame_addr4); 3014 else 3015 hdrlen = sizeof(struct ieee80211_frame); 3016 3017 paylen = len - hdrlen; 3018 3019 if ((flags & IEEE80211_F_WEPON) != 0) 3020 overlen = IEEE80211_WEP_TOTLEN + IEEE80211_CRC_LEN; 3021 else 3022 overlen = IEEE80211_CRC_LEN; 3023 3024 npkt = paylen / fraglen; 3025 lastlen0 = paylen % fraglen; 3026 3027 if (npkt == 0) /* no fragments */ 3028 lastlen = paylen + overlen; 3029 else if (lastlen0 != 0) { /* a short "tail" fragment */ 3030 lastlen = lastlen0 + overlen; 3031 npkt++; 3032 } else /* full-length "tail" fragment */ 3033 lastlen = fraglen + overlen; 3034 3035 if (npktp != NULL) 3036 *npktp = npkt; 3037 3038 if (npkt > 1) 3039 firstlen = fraglen + overlen; 3040 else 3041 firstlen = paylen + overlen; 3042 3043 if (debug) { 3044 printf("%s: npkt %d firstlen %d lastlen0 %d lastlen %d " 3045 "fraglen %d overlen %d len %d rate %d flags %08x\n", 3046 __func__, npkt, firstlen, lastlen0, lastlen, fraglen, 3047 overlen, len, rate, flags); 3048 } 3049 3050 ack = !IEEE80211_IS_MULTICAST(wh->i_addr1) && 3051 (wh->i_fc[1] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_CTL; 3052 3053 rc = rtw_compute_duration1(firstlen + hdrlen, ack, flags, rate, d0); 3054 if (rc == -1) 3055 return rc; 3056 3057 if (npkt <= 1) { 3058 *dn = *d0; 3059 return 0; 3060 } 3061 return rtw_compute_duration1(lastlen + hdrlen, ack, flags, rate, dn); 3062 } 3063 3064 #ifdef RTW_DEBUG 3065 void 3066 rtw_print_txdesc(struct rtw_softc *sc, const char *action, 3067 struct rtw_txsoft *ts, struct rtw_txdesc_blk *tdb, int desc) 3068 { 3069 struct rtw_txdesc *td = &tdb->tdb_desc[desc]; 3070 DPRINTF(sc, RTW_DEBUG_XMIT_DESC, ("%s: %p %s txdesc[%d] next %#08x " 3071 "buf %#08x ctl0 %#08x ctl1 %#08x len %#08x\n", 3072 sc->sc_dev.dv_xname, ts, action, desc, 3073 letoh32(td->td_buf), letoh32(td->td_next), 3074 letoh32(td->td_ctl0), letoh32(td->td_ctl1), 3075 letoh32(td->td_len))); 3076 } 3077 #endif /* RTW_DEBUG */ 3078 3079 void 3080 rtw_start(struct ifnet *ifp) 3081 { 3082 uint8_t tppoll; 3083 int desc, i, lastdesc, npkt, rate; 3084 uint32_t proto_ctl0, ctl0, ctl1; 3085 bus_dmamap_t dmamap; 3086 struct ieee80211com *ic; 3087 struct ieee80211_frame *wh; 3088 struct ieee80211_node *ni; 3089 struct mbuf *m0; 3090 struct rtw_softc *sc; 3091 struct rtw_duration *d0; 3092 struct rtw_txsoft_blk *tsb; 3093 struct rtw_txdesc_blk *tdb; 3094 struct rtw_txsoft *ts; 3095 struct rtw_txdesc *td; 3096 3097 sc = (struct rtw_softc *)ifp->if_softc; 3098 ic = &sc->sc_ic; 3099 3100 DPRINTF(sc, RTW_DEBUG_XMIT, 3101 ("%s: enter %s\n", sc->sc_dev.dv_xname, __func__)); 3102 3103 if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING) 3104 goto out; 3105 3106 /* XXX do real rate control */ 3107 proto_ctl0 = RTW_TXCTL0_RTSRATE_1MBPS; 3108 3109 if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0) 3110 proto_ctl0 |= RTW_TXCTL0_SPLCP; 3111 3112 for (;;) { 3113 if (rtw_dequeue(ifp, &tsb, &tdb, &m0, &ni) == -1) 3114 continue; 3115 if (m0 == NULL) 3116 break; 3117 ts = SIMPLEQ_FIRST(&tsb->tsb_freeq); 3118 3119 dmamap = ts->ts_dmamap; 3120 3121 m0 = rtw_dmamap_load_txbuf(sc->sc_dmat, dmamap, m0, 3122 tdb->tdb_nfree, &ifp->if_flags, sc->sc_dev.dv_xname); 3123 3124 if (m0 == NULL || dmamap->dm_nsegs == 0) { 3125 DPRINTF(sc, RTW_DEBUG_XMIT, 3126 ("%s: fail dmamap load\n", __func__)); 3127 goto post_dequeue_err; 3128 } 3129 3130 wh = mtod(m0, struct ieee80211_frame *); 3131 3132 /* XXX do real rate control */ 3133 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == 3134 IEEE80211_FC0_TYPE_MGT) 3135 rate = 2; 3136 else 3137 rate = MAX(2, ieee80211_get_rate(ic)); 3138 3139 #ifdef RTW_DEBUG 3140 if ((sc->sc_if.if_flags & (IFF_DEBUG|IFF_LINK2)) == 3141 (IFF_DEBUG|IFF_LINK2)) { 3142 ieee80211_dump_pkt(mtod(m0, uint8_t *), 3143 (dmamap->dm_nsegs == 1) ? m0->m_pkthdr.len 3144 : sizeof(wh), 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 3166 /* XXX >= ? Compare after fragmentation? */ 3167 if (m0->m_pkthdr.len > ic->ic_rtsthreshold) 3168 ctl0 |= RTW_TXCTL0_RTSEN; 3169 3170 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == 3171 IEEE80211_FC0_TYPE_MGT) { 3172 ctl0 &= ~(RTW_TXCTL0_SPLCP | RTW_TXCTL0_RTSEN); 3173 if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == 3174 IEEE80211_FC0_SUBTYPE_BEACON) 3175 ctl0 |= RTW_TXCTL0_BEACON; 3176 } 3177 3178 if (rtw_compute_duration(wh, m0->m_pkthdr.len, 3179 ic->ic_flags & ~IEEE80211_F_WEPON, ic->ic_fragthreshold, 3180 rate, &ts->ts_d0, &ts->ts_dn, &npkt, 3181 (sc->sc_if.if_flags & (IFF_DEBUG|IFF_LINK2)) == 3182 (IFF_DEBUG|IFF_LINK2)) == -1) { 3183 DPRINTF(sc, RTW_DEBUG_XMIT, 3184 ("%s: fail compute duration\n", __func__)); 3185 goto post_load_err; 3186 } 3187 3188 d0 = &ts->ts_d0; 3189 3190 *(uint16_t*)wh->i_dur = htole16(d0->d_data_dur); 3191 3192 ctl1 = LSHIFT(d0->d_plcp_len, RTW_TXCTL1_LENGTH_MASK) | 3193 LSHIFT(d0->d_rts_dur, RTW_TXCTL1_RTSDUR_MASK); 3194 3195 if (d0->d_residue) 3196 ctl1 |= RTW_TXCTL1_LENGEXT; 3197 3198 /* TBD fragmentation */ 3199 3200 ts->ts_first = tdb->tdb_next; 3201 3202 rtw_txdescs_sync(tdb, ts->ts_first, dmamap->dm_nsegs, 3203 BUS_DMASYNC_PREWRITE); 3204 3205 KASSERT(ts->ts_first < tdb->tdb_ndesc); 3206 3207 #if NBPFILTER > 0 3208 if (ic->ic_rawbpf != NULL) 3209 bpf_mtap((caddr_t)ic->ic_rawbpf, m0, 3210 BPF_DIRECTION_OUT); 3211 3212 if (sc->sc_radiobpf != NULL) { 3213 struct mbuf mb; 3214 struct rtw_tx_radiotap_header *rt = &sc->sc_txtap; 3215 3216 rt->rt_flags = 0; 3217 rt->rt_rate = rate; 3218 rt->rt_chan_freq = 3219 htole16(ic->ic_bss->ni_chan->ic_freq); 3220 rt->rt_chan_flags = 3221 htole16(ic->ic_bss->ni_chan->ic_flags); 3222 3223 mb.m_data = (caddr_t)rt; 3224 mb.m_len = sizeof(sc->sc_txtapu); 3225 mb.m_next = m0; 3226 mb.m_nextpkt = NULL; 3227 mb.m_type = 0; 3228 mb.m_flags = 0; 3229 bpf_mtap(sc->sc_radiobpf, &mb, BPF_DIRECTION_OUT); 3230 3231 } 3232 #endif /* NBPFILTER > 0 */ 3233 3234 for (i = 0, lastdesc = desc = ts->ts_first; 3235 i < dmamap->dm_nsegs; 3236 i++, desc = RTW_NEXT_IDX(tdb, desc)) { 3237 if (dmamap->dm_segs[i].ds_len > RTW_TXLEN_LENGTH_MASK) { 3238 DPRINTF(sc, RTW_DEBUG_XMIT_DESC, 3239 ("%s: seg too long\n", __func__)); 3240 goto post_load_err; 3241 } 3242 td = &tdb->tdb_desc[desc]; 3243 td->td_ctl0 = htole32(ctl0); 3244 if (i != 0) 3245 td->td_ctl0 |= htole32(RTW_TXCTL0_OWN); 3246 td->td_ctl1 = htole32(ctl1); 3247 td->td_buf = htole32(dmamap->dm_segs[i].ds_addr); 3248 td->td_len = htole32(dmamap->dm_segs[i].ds_len); 3249 lastdesc = desc; 3250 #ifdef RTW_DEBUG 3251 rtw_print_txdesc(sc, "load", ts, tdb, desc); 3252 #endif /* RTW_DEBUG */ 3253 } 3254 3255 KASSERT(desc < tdb->tdb_ndesc); 3256 3257 ts->ts_ni = ni; 3258 ts->ts_mbuf = m0; 3259 ts->ts_last = lastdesc; 3260 tdb->tdb_desc[ts->ts_last].td_ctl0 |= htole32(RTW_TXCTL0_LS); 3261 tdb->tdb_desc[ts->ts_first].td_ctl0 |= 3262 htole32(RTW_TXCTL0_FS); 3263 3264 #ifdef RTW_DEBUG 3265 rtw_print_txdesc(sc, "FS on", ts, tdb, ts->ts_first); 3266 rtw_print_txdesc(sc, "LS on", ts, tdb, ts->ts_last); 3267 #endif /* RTW_DEBUG */ 3268 3269 tdb->tdb_nfree -= dmamap->dm_nsegs; 3270 tdb->tdb_next = desc; 3271 3272 rtw_txdescs_sync(tdb, ts->ts_first, dmamap->dm_nsegs, 3273 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 3274 3275 tdb->tdb_desc[ts->ts_first].td_ctl0 |= 3276 htole32(RTW_TXCTL0_OWN); 3277 3278 #ifdef RTW_DEBUG 3279 rtw_print_txdesc(sc, "OWN on", ts, tdb, ts->ts_first); 3280 #endif /* RTW_DEBUG */ 3281 3282 rtw_txdescs_sync(tdb, ts->ts_first, 1, 3283 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 3284 3285 SIMPLEQ_REMOVE_HEAD(&tsb->tsb_freeq, ts_q); 3286 SIMPLEQ_INSERT_TAIL(&tsb->tsb_dirtyq, ts, ts_q); 3287 3288 if (tsb != &sc->sc_txsoft_blk[RTW_TXPRIBCN]) 3289 sc->sc_led_state.ls_event |= RTW_LED_S_TX; 3290 tsb->tsb_tx_timer = 5; 3291 ifp->if_timer = 1; 3292 tppoll = RTW_READ8(&sc->sc_regs, RTW_TPPOLL); 3293 tppoll &= ~RTW_TPPOLL_SALL; 3294 tppoll |= tsb->tsb_poll & RTW_TPPOLL_ALL; 3295 RTW_WRITE8(&sc->sc_regs, RTW_TPPOLL, tppoll); 3296 RTW_SYNC(&sc->sc_regs, RTW_TPPOLL, RTW_TPPOLL); 3297 } 3298 out: 3299 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: leave\n", __func__)); 3300 return; 3301 post_load_err: 3302 bus_dmamap_unload(sc->sc_dmat, dmamap); 3303 m_freem(m0); 3304 post_dequeue_err: 3305 ieee80211_release_node(&sc->sc_ic, ni); 3306 return; 3307 } 3308 3309 void 3310 rtw_idle(struct rtw_regs *regs) 3311 { 3312 int active; 3313 3314 /* request stop DMA; wait for packets to stop transmitting. */ 3315 3316 RTW_WRITE8(regs, RTW_TPPOLL, RTW_TPPOLL_SALL); 3317 RTW_WBR(regs, RTW_TPPOLL, RTW_TPPOLL); 3318 3319 for (active = 0; active < 300 && 3320 (RTW_READ8(regs, RTW_TPPOLL) & RTW_TPPOLL_ACTIVE) != 0; active++) 3321 DELAY(10); 3322 RTW_DPRINTF(RTW_DEBUG_BUGS, 3323 ("%s: transmit DMA idle in %dus\n", __func__, active * 10)); 3324 } 3325 3326 void 3327 rtw_watchdog(struct ifnet *ifp) 3328 { 3329 int pri, tx_timeouts = 0; 3330 struct rtw_softc *sc; 3331 struct rtw_txsoft_blk *tsb; 3332 3333 sc = ifp->if_softc; 3334 3335 ifp->if_timer = 0; 3336 3337 if ((sc->sc_flags & RTW_F_ENABLED) == 0) 3338 return; 3339 3340 for (pri = 0; pri < RTW_NTXPRI; pri++) { 3341 tsb = &sc->sc_txsoft_blk[pri]; 3342 3343 if (tsb->tsb_tx_timer == 0) 3344 continue; 3345 else if (--tsb->tsb_tx_timer == 0) { 3346 if (SIMPLEQ_EMPTY(&tsb->tsb_dirtyq)) 3347 continue; 3348 RTW_DPRINTF(RTW_DEBUG_BUGS, 3349 ("%s: transmit timeout, priority %d\n", 3350 ifp->if_xname, pri)); 3351 ifp->if_oerrors++; 3352 tx_timeouts++; 3353 } else 3354 ifp->if_timer = 1; 3355 } 3356 3357 if (tx_timeouts > 0) { 3358 /* Stop Tx DMA, disable xmtr, flush Tx rings, enable xmtr, 3359 * reset s/w tx-ring pointers, and start transmission. 3360 * 3361 * TBD Stop/restart just the broken rings? 3362 */ 3363 rtw_idle(&sc->sc_regs); 3364 rtw_io_enable(&sc->sc_regs, RTW_CR_TE, 0); 3365 rtw_txdescs_reset(sc); 3366 rtw_io_enable(&sc->sc_regs, RTW_CR_TE, 1); 3367 rtw_txring_fixup(sc); 3368 rtw_start(ifp); 3369 } 3370 ieee80211_watchdog(ifp); 3371 } 3372 3373 void 3374 rtw_next_scan(void *arg) 3375 { 3376 struct rtw_softc *sc = arg; 3377 struct ieee80211com *ic = &sc->sc_ic; 3378 struct ifnet *ifp = &ic->ic_if; 3379 int s; 3380 3381 /* don't call rtw_start w/o network interrupts blocked */ 3382 s = splnet(); 3383 if (ic->ic_state == IEEE80211_S_SCAN) 3384 ieee80211_next_scan(ifp); 3385 splx(s); 3386 } 3387 3388 void 3389 rtw_join_bss(struct rtw_softc *sc, u_int8_t *bssid, u_int16_t intval0) 3390 { 3391 uint16_t bcnitv, bintritv, intval; 3392 int i; 3393 struct rtw_regs *regs = &sc->sc_regs; 3394 3395 for (i = 0; i < IEEE80211_ADDR_LEN; i++) 3396 RTW_WRITE8(regs, RTW_BSSID + i, bssid[i]); 3397 3398 RTW_SYNC(regs, RTW_BSSID16, RTW_BSSID32); 3399 3400 rtw_set_access(regs, RTW_ACCESS_CONFIG); 3401 3402 intval = MIN(intval0, PRESHIFT(RTW_BCNITV_BCNITV_MASK)); 3403 3404 bcnitv = RTW_READ16(regs, RTW_BCNITV) & ~RTW_BCNITV_BCNITV_MASK; 3405 bcnitv |= LSHIFT(intval, RTW_BCNITV_BCNITV_MASK); 3406 RTW_WRITE16(regs, RTW_BCNITV, bcnitv); 3407 /* interrupt host 1ms before the TBTT */ 3408 bintritv = RTW_READ16(regs, RTW_BINTRITV) & ~RTW_BINTRITV_BINTRITV; 3409 bintritv |= LSHIFT(1000, RTW_BINTRITV_BINTRITV); 3410 RTW_WRITE16(regs, RTW_BINTRITV, bintritv); 3411 /* magic from Linux */ 3412 RTW_WRITE16(regs, RTW_ATIMWND, LSHIFT(1, RTW_ATIMWND_ATIMWND)); 3413 RTW_WRITE16(regs, RTW_ATIMTRITV, LSHIFT(2, RTW_ATIMTRITV_ATIMTRITV)); 3414 rtw_set_access(regs, RTW_ACCESS_NONE); 3415 3416 /* TBD WEP */ 3417 RTW_WRITE8(regs, RTW8180_SCR, 0); 3418 3419 rtw_io_enable(regs, RTW_CR_RE | RTW_CR_TE, 1); 3420 } 3421 3422 /* Synchronize the hardware state with the software state. */ 3423 int 3424 rtw_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) 3425 { 3426 struct ifnet *ifp = &ic->ic_if; 3427 struct rtw_softc *sc = ifp->if_softc; 3428 enum ieee80211_state ostate; 3429 int error; 3430 3431 ostate = ic->ic_state; 3432 3433 rtw_led_newstate(sc, nstate); 3434 3435 if (nstate == IEEE80211_S_INIT) { 3436 timeout_del(&sc->sc_scan_to); 3437 sc->sc_cur_chan = IEEE80211_CHAN_ANY; 3438 return (*sc->sc_mtbl.mt_newstate)(ic, nstate, arg); 3439 } 3440 3441 if (ostate == IEEE80211_S_INIT && nstate != IEEE80211_S_INIT) 3442 rtw_pwrstate(sc, RTW_ON); 3443 3444 if ((error = rtw_tune(sc)) != 0) 3445 return error; 3446 3447 switch (nstate) { 3448 case IEEE80211_S_INIT: 3449 panic("%s: unexpected state IEEE80211_S_INIT", __func__); 3450 break; 3451 case IEEE80211_S_SCAN: 3452 if (ostate != IEEE80211_S_SCAN) { 3453 bzero(ic->ic_bss->ni_bssid, IEEE80211_ADDR_LEN); 3454 rtw_set_nettype(sc, IEEE80211_M_MONITOR); 3455 } 3456 3457 timeout_add_msec(&sc->sc_scan_to, rtw_dwelltime); 3458 3459 break; 3460 case IEEE80211_S_RUN: 3461 switch (ic->ic_opmode) { 3462 #ifndef IEEE80211_STA_ONLY 3463 case IEEE80211_M_HOSTAP: 3464 case IEEE80211_M_IBSS: 3465 rtw_set_nettype(sc, IEEE80211_M_MONITOR); 3466 /*FALLTHROUGH*/ 3467 case IEEE80211_M_AHDEMO: 3468 #endif 3469 case IEEE80211_M_STA: 3470 rtw_join_bss(sc, ic->ic_bss->ni_bssid, 3471 ic->ic_bss->ni_intval); 3472 break; 3473 default: 3474 break; 3475 } 3476 rtw_set_nettype(sc, ic->ic_opmode); 3477 break; 3478 case IEEE80211_S_ASSOC: 3479 case IEEE80211_S_AUTH: 3480 break; 3481 } 3482 3483 if (nstate != IEEE80211_S_SCAN) 3484 timeout_del(&sc->sc_scan_to); 3485 3486 return (*sc->sc_mtbl.mt_newstate)(ic, nstate, arg); 3487 } 3488 3489 /* Extend a 32-bit TSF timestamp to a 64-bit timestamp. */ 3490 uint64_t 3491 rtw_tsf_extend(struct rtw_regs *regs, u_int32_t rstamp) 3492 { 3493 u_int32_t tsftl, tsfth; 3494 3495 tsfth = RTW_READ(regs, RTW_TSFTRH); 3496 tsftl = RTW_READ(regs, RTW_TSFTRL); 3497 if (tsftl < rstamp) /* Compensate for rollover. */ 3498 tsfth--; 3499 return ((u_int64_t)tsfth << 32) | rstamp; 3500 } 3501 3502 #ifndef IEEE80211_STA_ONLY 3503 void 3504 rtw_ibss_merge(struct rtw_softc *sc, struct ieee80211_node *ni, 3505 u_int32_t rstamp) 3506 { 3507 u_int8_t tppoll; 3508 struct ieee80211com *ic = &sc->sc_ic; 3509 3510 if (ieee80211_ibss_merge(ic, ni, 3511 rtw_tsf_extend(&sc->sc_regs, rstamp)) == ENETRESET) { 3512 /* Stop beacon queue. Kick state machine to synchronize 3513 * with the new IBSS. 3514 */ 3515 tppoll = RTW_READ8(&sc->sc_regs, RTW_TPPOLL); 3516 tppoll |= RTW_TPPOLL_SBQ; 3517 RTW_WRITE8(&sc->sc_regs, RTW_TPPOLL, tppoll); 3518 (void)ieee80211_new_state(&sc->sc_ic, IEEE80211_S_RUN, -1); 3519 } 3520 return; 3521 } 3522 3523 void 3524 rtw_recv_mgmt(struct ieee80211com *ic, struct mbuf *m, 3525 struct ieee80211_node *ni, struct ieee80211_rxinfo *rxi, int subtype) 3526 { 3527 struct rtw_softc *sc = (struct rtw_softc*)ic->ic_softc; 3528 3529 (*sc->sc_mtbl.mt_recv_mgmt)(ic, m, ni, rxi, subtype); 3530 3531 switch (subtype) { 3532 case IEEE80211_FC0_SUBTYPE_PROBE_RESP: 3533 case IEEE80211_FC0_SUBTYPE_BEACON: 3534 if (ic->ic_opmode != IEEE80211_M_IBSS || 3535 ic->ic_state != IEEE80211_S_RUN) 3536 return; 3537 rtw_ibss_merge(sc, ni, rxi->rxi_tstamp); 3538 break; 3539 default: 3540 break; 3541 } 3542 return; 3543 } 3544 #endif /* IEEE80211_STA_ONLY */ 3545 3546 struct ieee80211_node * 3547 rtw_node_alloc(struct ieee80211com *ic) 3548 { 3549 struct rtw_softc *sc = (struct rtw_softc *)ic->ic_if.if_softc; 3550 struct ieee80211_node *ni = (*sc->sc_mtbl.mt_node_alloc)(ic); 3551 3552 DPRINTF(sc, RTW_DEBUG_NODE, 3553 ("%s: alloc node %p\n", sc->sc_dev.dv_xname, ni)); 3554 return ni; 3555 } 3556 3557 void 3558 rtw_node_free(struct ieee80211com *ic, struct ieee80211_node *ni) 3559 { 3560 struct rtw_softc *sc = (struct rtw_softc *)ic->ic_if.if_softc; 3561 3562 DPRINTF(sc, RTW_DEBUG_NODE, 3563 ("%s: freeing node %p %s\n", sc->sc_dev.dv_xname, ni, 3564 ether_sprintf(ni->ni_bssid))); 3565 (*sc->sc_mtbl.mt_node_free)(ic, ni); 3566 } 3567 3568 int 3569 rtw_media_change(struct ifnet *ifp) 3570 { 3571 int error; 3572 3573 error = ieee80211_media_change(ifp); 3574 if (error == ENETRESET) { 3575 if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) == 3576 (IFF_RUNNING|IFF_UP)) 3577 rtw_init(ifp); /* XXX lose error */ 3578 error = 0; 3579 } 3580 return error; 3581 } 3582 3583 void 3584 rtw_media_status(struct ifnet *ifp, struct ifmediareq *imr) 3585 { 3586 struct rtw_softc *sc = ifp->if_softc; 3587 3588 if ((sc->sc_flags & RTW_F_ENABLED) == 0) { 3589 imr->ifm_active = IFM_IEEE80211 | IFM_NONE; 3590 imr->ifm_status = 0; 3591 return; 3592 } 3593 ieee80211_media_status(ifp, imr); 3594 } 3595 3596 void 3597 rtw_power(int why, void *arg) 3598 { 3599 struct rtw_softc *sc = arg; 3600 struct ifnet *ifp = &sc->sc_ic.ic_if; 3601 int s; 3602 3603 DPRINTF(sc, RTW_DEBUG_PWR, 3604 ("%s: rtw_power(%d,)\n", sc->sc_dev.dv_xname, why)); 3605 3606 s = splnet(); 3607 switch (why) { 3608 case PWR_STANDBY: 3609 /* XXX do nothing. */ 3610 break; 3611 case PWR_SUSPEND: 3612 rtw_stop(ifp, 1); 3613 if (sc->sc_power != NULL) 3614 (*sc->sc_power)(sc, why); 3615 break; 3616 case PWR_RESUME: 3617 if (ifp->if_flags & IFF_UP) { 3618 if (sc->sc_power != NULL) 3619 (*sc->sc_power)(sc, why); 3620 rtw_init(ifp); 3621 } 3622 break; 3623 } 3624 splx(s); 3625 } 3626 3627 /* rtw_shutdown: make sure the interface is stopped at reboot time. */ 3628 void 3629 rtw_shutdown(void *arg) 3630 { 3631 struct rtw_softc *sc = arg; 3632 3633 rtw_stop(&sc->sc_ic.ic_if, 1); 3634 } 3635 3636 void 3637 rtw_establish_hooks(struct rtw_hooks *hooks, const char *dvname, 3638 void *arg) 3639 { 3640 /* 3641 * Make sure the interface is shutdown during reboot. 3642 */ 3643 hooks->rh_shutdown = shutdownhook_establish(rtw_shutdown, arg); 3644 if (hooks->rh_shutdown == NULL) 3645 printf("%s: WARNING: unable to establish shutdown hook\n", 3646 dvname); 3647 3648 /* 3649 * Add a suspend hook to make sure we come back up after a 3650 * resume. 3651 */ 3652 hooks->rh_power = powerhook_establish(rtw_power, arg); 3653 if (hooks->rh_power == NULL) 3654 printf("%s: WARNING: unable to establish power hook\n", 3655 dvname); 3656 } 3657 3658 void 3659 rtw_disestablish_hooks(struct rtw_hooks *hooks, const char *dvname, 3660 void *arg) 3661 { 3662 if (hooks->rh_shutdown != NULL) 3663 shutdownhook_disestablish(hooks->rh_shutdown); 3664 3665 if (hooks->rh_power != NULL) 3666 powerhook_disestablish(hooks->rh_power); 3667 } 3668 3669 int 3670 rtw_txsoft_blk_setup(struct rtw_txsoft_blk *tsb, u_int qlen) 3671 { 3672 SIMPLEQ_INIT(&tsb->tsb_dirtyq); 3673 SIMPLEQ_INIT(&tsb->tsb_freeq); 3674 tsb->tsb_ndesc = qlen; 3675 tsb->tsb_desc = malloc(qlen * sizeof(*tsb->tsb_desc), M_DEVBUF, 3676 M_NOWAIT); 3677 if (tsb->tsb_desc == NULL) 3678 return ENOMEM; 3679 return 0; 3680 } 3681 3682 void 3683 rtw_txsoft_blk_cleanup_all(struct rtw_softc *sc) 3684 { 3685 int pri; 3686 struct rtw_txsoft_blk *tsb; 3687 3688 for (pri = 0; pri < RTW_NTXPRI; pri++) { 3689 tsb = &sc->sc_txsoft_blk[pri]; 3690 free(tsb->tsb_desc, M_DEVBUF); 3691 tsb->tsb_desc = NULL; 3692 } 3693 } 3694 3695 int 3696 rtw_txsoft_blk_setup_all(struct rtw_softc *sc) 3697 { 3698 int pri, rc = 0; 3699 int qlen[RTW_NTXPRI] = 3700 {RTW_TXQLENLO, RTW_TXQLENMD, RTW_TXQLENHI, RTW_TXQLENBCN}; 3701 struct rtw_txsoft_blk *tsbs; 3702 3703 tsbs = sc->sc_txsoft_blk; 3704 3705 for (pri = 0; pri < RTW_NTXPRI; pri++) { 3706 rc = rtw_txsoft_blk_setup(&tsbs[pri], qlen[pri]); 3707 if (rc != 0) 3708 break; 3709 } 3710 tsbs[RTW_TXPRILO].tsb_poll = RTW_TPPOLL_LPQ | RTW_TPPOLL_SLPQ; 3711 tsbs[RTW_TXPRIMD].tsb_poll = RTW_TPPOLL_NPQ | RTW_TPPOLL_SNPQ; 3712 tsbs[RTW_TXPRIHI].tsb_poll = RTW_TPPOLL_HPQ | RTW_TPPOLL_SHPQ; 3713 tsbs[RTW_TXPRIBCN].tsb_poll = RTW_TPPOLL_BQ | RTW_TPPOLL_SBQ; 3714 return rc; 3715 } 3716 3717 void 3718 rtw_txdesc_blk_setup(struct rtw_txdesc_blk *tdb, struct rtw_txdesc *desc, 3719 u_int ndesc, bus_addr_t ofs, bus_addr_t physbase) 3720 { 3721 tdb->tdb_ndesc = ndesc; 3722 tdb->tdb_desc = desc; 3723 tdb->tdb_physbase = physbase; 3724 tdb->tdb_ofs = ofs; 3725 3726 bzero(tdb->tdb_desc, sizeof(tdb->tdb_desc[0]) * tdb->tdb_ndesc); 3727 3728 rtw_txdesc_blk_init(tdb); 3729 tdb->tdb_next = 0; 3730 } 3731 3732 void 3733 rtw_txdesc_blk_setup_all(struct rtw_softc *sc) 3734 { 3735 rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRILO], 3736 &sc->sc_descs->hd_txlo[0], RTW_NTXDESCLO, 3737 RTW_RING_OFFSET(hd_txlo), RTW_RING_BASE(sc, hd_txlo)); 3738 3739 rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIMD], 3740 &sc->sc_descs->hd_txmd[0], RTW_NTXDESCMD, 3741 RTW_RING_OFFSET(hd_txmd), RTW_RING_BASE(sc, hd_txmd)); 3742 3743 rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIHI], 3744 &sc->sc_descs->hd_txhi[0], RTW_NTXDESCHI, 3745 RTW_RING_OFFSET(hd_txhi), RTW_RING_BASE(sc, hd_txhi)); 3746 3747 rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIBCN], 3748 &sc->sc_descs->hd_bcn[0], RTW_NTXDESCBCN, 3749 RTW_RING_OFFSET(hd_bcn), RTW_RING_BASE(sc, hd_bcn)); 3750 } 3751 3752 int 3753 rtw_rf_attach(struct rtw_softc *sc, int rfchipid) 3754 { 3755 struct rtw_bbpset *bb = &sc->sc_bbpset; 3756 int notsup = 0; 3757 const char *rfname, *paname = NULL; 3758 char scratch[sizeof("unknown 0xXX")]; 3759 3760 switch (rfchipid) { 3761 case RTW_RFCHIPID_RTL8225: 3762 rfname = "RTL8225"; 3763 sc->sc_pwrstate_cb = rtw_rtl_pwrstate; 3764 sc->sc_rf_init = rtw_rtl8255_init; 3765 sc->sc_rf_pwrstate = rtw_rtl8225_pwrstate; 3766 sc->sc_rf_tune = rtw_rtl8225_tune; 3767 sc->sc_rf_txpower = rtw_rtl8225_txpower; 3768 break; 3769 case RTW_RFCHIPID_RTL8255: 3770 rfname = "RTL8255"; 3771 sc->sc_pwrstate_cb = rtw_rtl_pwrstate; 3772 sc->sc_rf_init = rtw_rtl8255_init; 3773 sc->sc_rf_pwrstate = rtw_rtl8255_pwrstate; 3774 sc->sc_rf_tune = rtw_rtl8255_tune; 3775 sc->sc_rf_txpower = rtw_rtl8255_txpower; 3776 break; 3777 case RTW_RFCHIPID_MAXIM2820: 3778 rfname = "MAX2820"; /* guess */ 3779 paname = "MAX2422"; /* guess */ 3780 /* XXX magic */ 3781 bb->bb_antatten = RTW_BBP_ANTATTEN_MAXIM_MAGIC; 3782 bb->bb_chestlim = 0x00; 3783 bb->bb_chsqlim = 0x9f; 3784 bb->bb_ifagcdet = 0x64; 3785 bb->bb_ifagcini = 0x90; 3786 bb->bb_ifagclimit = 0x1a; 3787 bb->bb_lnadet = 0xf8; 3788 bb->bb_sys1 = 0x88; 3789 bb->bb_sys2 = 0x47; 3790 bb->bb_sys3 = 0x9b; 3791 bb->bb_trl = 0x88; 3792 bb->bb_txagc = 0x08; 3793 sc->sc_pwrstate_cb = rtw_maxim_pwrstate; 3794 sc->sc_rf_init = rtw_max2820_init; 3795 sc->sc_rf_pwrstate = rtw_max2820_pwrstate; 3796 sc->sc_rf_tune = rtw_max2820_tune; 3797 sc->sc_rf_txpower = rtw_max2820_txpower; 3798 break; 3799 case RTW_RFCHIPID_PHILIPS: 3800 rfname = "SA2400A"; 3801 paname = "SA2411"; 3802 /* XXX magic */ 3803 bb->bb_antatten = RTW_BBP_ANTATTEN_PHILIPS_MAGIC; 3804 bb->bb_chestlim = 0x00; 3805 bb->bb_chsqlim = 0xa0; 3806 bb->bb_ifagcdet = 0x64; 3807 bb->bb_ifagcini = 0x90; 3808 bb->bb_ifagclimit = 0x1a; 3809 bb->bb_lnadet = 0xe0; 3810 bb->bb_sys1 = 0x98; 3811 bb->bb_sys2 = 0x47; 3812 bb->bb_sys3 = 0x90; 3813 bb->bb_trl = 0x88; 3814 bb->bb_txagc = 0x38; 3815 sc->sc_pwrstate_cb = rtw_philips_pwrstate; 3816 sc->sc_rf_init = rtw_sa2400_init; 3817 sc->sc_rf_pwrstate = rtw_sa2400_pwrstate; 3818 sc->sc_rf_tune = rtw_sa2400_tune; 3819 sc->sc_rf_txpower = rtw_sa2400_txpower; 3820 break; 3821 case RTW_RFCHIPID_RFMD2948: 3822 /* this is the same front-end as an atw(4)! */ 3823 rfname = "RFMD RF2948B, " /* mentioned in Realtek docs */ 3824 "LNA: RFMD RF2494, " /* mentioned in Realtek docs */ 3825 "SYN: Silicon Labs Si4126"; /* inferred from 3826 * reference driver 3827 */ 3828 paname = "RF2189"; /* mentioned in Realtek docs */ 3829 /* XXX RFMD has no RF constructor */ 3830 sc->sc_pwrstate_cb = rtw_rfmd_pwrstate; 3831 notsup = 1; 3832 break; 3833 case RTW_RFCHIPID_GCT: /* this combo seen in the wild */ 3834 rfname = "GRF5101"; 3835 paname = "WS9901"; 3836 /* XXX magic */ 3837 bb->bb_antatten = RTW_BBP_ANTATTEN_GCT_MAGIC; 3838 bb->bb_chestlim = 0x00; 3839 bb->bb_chsqlim = 0xa0; 3840 bb->bb_ifagcdet = 0x64; 3841 bb->bb_ifagcini = 0x90; 3842 bb->bb_ifagclimit = 0x1e; 3843 bb->bb_lnadet = 0xc0; 3844 bb->bb_sys1 = 0xa8; 3845 bb->bb_sys2 = 0x47; 3846 bb->bb_sys3 = 0x9b; 3847 bb->bb_trl = 0x88; 3848 bb->bb_txagc = 0x08; 3849 sc->sc_pwrstate_cb = rtw_maxim_pwrstate; 3850 sc->sc_rf_init = rtw_grf5101_init; 3851 sc->sc_rf_pwrstate = rtw_grf5101_pwrstate; 3852 sc->sc_rf_tune = rtw_grf5101_tune; 3853 sc->sc_rf_txpower = rtw_grf5101_txpower; 3854 break; 3855 case RTW_RFCHIPID_INTERSIL: 3856 rfname = "HFA3873"; /* guess */ 3857 paname = "Intersil <unknown>"; 3858 notsup = 1; 3859 break; 3860 default: 3861 snprintf(scratch, sizeof(scratch), "unknown 0x%02x", rfchipid); 3862 rfname = scratch; 3863 notsup = 1; 3864 } 3865 3866 printf("radio %s, ", rfname); 3867 if (paname != NULL) 3868 printf("amp %s, ", paname); 3869 3870 return (notsup); 3871 } 3872 3873 /* Revision C and later use a different PHY delay setting than 3874 * revisions A and B. 3875 */ 3876 u_int8_t 3877 rtw_check_phydelay(struct rtw_regs *regs, u_int32_t rcr0) 3878 { 3879 #define REVAB (RTW_RCR_MXDMA_UNLIMITED | RTW_RCR_AICV) 3880 #define REVC (REVAB | RTW8180_RCR_RXFTH_WHOLE) 3881 3882 u_int8_t phydelay = LSHIFT(0x6, RTW_PHYDELAY_PHYDELAY); 3883 3884 RTW_WRITE(regs, RTW_RCR, REVAB); 3885 RTW_WBW(regs, RTW_RCR, RTW_RCR); 3886 RTW_WRITE(regs, RTW_RCR, REVC); 3887 3888 RTW_WBR(regs, RTW_RCR, RTW_RCR); 3889 if ((RTW_READ(regs, RTW_RCR) & REVC) == REVC) 3890 phydelay |= RTW_PHYDELAY_REVC_MAGIC; 3891 3892 RTW_WRITE(regs, RTW_RCR, rcr0); /* restore RCR */ 3893 RTW_SYNC(regs, RTW_RCR, RTW_RCR); 3894 3895 return phydelay; 3896 #undef REVC 3897 } 3898 3899 void 3900 rtw_attach(struct rtw_softc *sc) 3901 { 3902 struct ieee80211com *ic = &sc->sc_ic; 3903 struct rtw_txsoft_blk *tsb; 3904 struct rtw_mtbl *mtbl; 3905 struct rtw_srom *sr; 3906 const char *vername; 3907 struct ifnet *ifp; 3908 char scratch[sizeof("unknown 0xXXXXXXXX")]; 3909 int pri, rc, i; 3910 3911 3912 /* Use default DMA memory access */ 3913 if (sc->sc_regs.r_read8 == NULL) { 3914 sc->sc_regs.r_read8 = rtw_read8; 3915 sc->sc_regs.r_read16 = rtw_read16; 3916 sc->sc_regs.r_read32 = rtw_read32; 3917 sc->sc_regs.r_write8 = rtw_write8; 3918 sc->sc_regs.r_write16 = rtw_write16; 3919 sc->sc_regs.r_write32 = rtw_write32; 3920 sc->sc_regs.r_barrier = rtw_barrier; 3921 } 3922 3923 sc->sc_hwverid = RTW_READ(&sc->sc_regs, RTW_TCR) & RTW_TCR_HWVERID_MASK; 3924 switch (sc->sc_hwverid) { 3925 case RTW_TCR_HWVERID_RTL8185: 3926 vername = "RTL8185"; 3927 sc->sc_flags |= RTW_F_RTL8185; 3928 break; 3929 case RTW_TCR_HWVERID_RTL8180F: 3930 vername = "RTL8180F"; 3931 break; 3932 case RTW_TCR_HWVERID_RTL8180D: 3933 vername = "RTL8180D"; 3934 break; 3935 default: 3936 snprintf(scratch, sizeof(scratch), "unknown 0x%08x", 3937 sc->sc_hwverid); 3938 vername = scratch; 3939 break; 3940 } 3941 3942 printf("%s: ver %s, ", sc->sc_dev.dv_xname, vername); 3943 3944 rc = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct rtw_descs), 3945 RTW_DESC_ALIGNMENT, 0, &sc->sc_desc_segs, 1, &sc->sc_desc_nsegs, 3946 0); 3947 3948 if (rc != 0) { 3949 printf("\n%s: could not allocate hw descriptors, error %d\n", 3950 sc->sc_dev.dv_xname, rc); 3951 goto fail0; 3952 } 3953 3954 rc = bus_dmamem_map(sc->sc_dmat, &sc->sc_desc_segs, 3955 sc->sc_desc_nsegs, sizeof(struct rtw_descs), 3956 (caddr_t*)&sc->sc_descs, BUS_DMA_COHERENT); 3957 3958 if (rc != 0) { 3959 printf("\n%s: can't map hw descriptors, error %d\n", 3960 sc->sc_dev.dv_xname, rc); 3961 goto fail1; 3962 } 3963 3964 rc = bus_dmamap_create(sc->sc_dmat, sizeof(struct rtw_descs), 1, 3965 sizeof(struct rtw_descs), 0, 0, &sc->sc_desc_dmamap); 3966 3967 if (rc != 0) { 3968 printf("\n%s: could not create DMA map for hw descriptors, " 3969 "error %d\n", sc->sc_dev.dv_xname, rc); 3970 goto fail2; 3971 } 3972 3973 sc->sc_rxdesc_blk.rdb_dmat = sc->sc_dmat; 3974 sc->sc_rxdesc_blk.rdb_dmamap = sc->sc_desc_dmamap; 3975 3976 for (pri = 0; pri < RTW_NTXPRI; pri++) { 3977 sc->sc_txdesc_blk[pri].tdb_dmat = sc->sc_dmat; 3978 sc->sc_txdesc_blk[pri].tdb_dmamap = sc->sc_desc_dmamap; 3979 } 3980 3981 rc = bus_dmamap_load(sc->sc_dmat, sc->sc_desc_dmamap, sc->sc_descs, 3982 sizeof(struct rtw_descs), NULL, 0); 3983 3984 if (rc != 0) { 3985 printf("\n%s: could not load DMA map for hw descriptors, " 3986 "error %d\n", sc->sc_dev.dv_xname, rc); 3987 goto fail3; 3988 } 3989 3990 if (rtw_txsoft_blk_setup_all(sc) != 0) 3991 goto fail4; 3992 3993 rtw_txdesc_blk_setup_all(sc); 3994 3995 sc->sc_rxdesc_blk.rdb_desc = &sc->sc_descs->hd_rx[0]; 3996 3997 for (pri = 0; pri < RTW_NTXPRI; pri++) { 3998 tsb = &sc->sc_txsoft_blk[pri]; 3999 4000 if ((rc = rtw_txdesc_dmamaps_create(sc->sc_dmat, 4001 &tsb->tsb_desc[0], tsb->tsb_ndesc)) != 0) { 4002 printf("\n%s: could not load DMA map for " 4003 "hw tx descriptors, error %d\n", 4004 sc->sc_dev.dv_xname, rc); 4005 goto fail5; 4006 } 4007 } 4008 4009 if ((rc = rtw_rxdesc_dmamaps_create(sc->sc_dmat, &sc->sc_rxsoft[0], 4010 RTW_RXQLEN)) != 0) { 4011 printf("\n%s: could not load DMA map for hw rx descriptors, " 4012 "error %d\n", sc->sc_dev.dv_xname, rc); 4013 goto fail6; 4014 } 4015 4016 /* Reset the chip to a known state. */ 4017 if (rtw_reset(sc) != 0) 4018 goto fail7; 4019 4020 sc->sc_rcr = RTW_READ(&sc->sc_regs, RTW_RCR); 4021 4022 if ((sc->sc_rcr & RTW_RCR_9356SEL) != 0) 4023 sc->sc_flags |= RTW_F_9356SROM; 4024 4025 if (rtw_srom_read(&sc->sc_regs, sc->sc_flags, &sc->sc_srom, 4026 sc->sc_dev.dv_xname) != 0) 4027 goto fail7; 4028 4029 if (rtw_srom_parse(sc) != 0) { 4030 printf("\n%s: attach failed, malformed serial ROM\n", 4031 sc->sc_dev.dv_xname); 4032 goto fail8; 4033 } 4034 4035 RTW_DPRINTF(RTW_DEBUG_ATTACH, ("%s: %s PHY\n", sc->sc_dev.dv_xname, 4036 ((sc->sc_flags & RTW_F_DIGPHY) != 0) ? "digital" : "analog")); 4037 4038 RTW_DPRINTF(RTW_DEBUG_ATTACH, ("%s: CS threshold %u\n", 4039 sc->sc_dev.dv_xname, sc->sc_csthr)); 4040 4041 if ((rtw_rf_attach(sc, sc->sc_rfchipid)) != 0) { 4042 printf("\n%s: attach failed, could not attach RF\n", 4043 sc->sc_dev.dv_xname); 4044 goto fail8; 4045 } 4046 4047 sc->sc_phydelay = rtw_check_phydelay(&sc->sc_regs, sc->sc_rcr); 4048 4049 RTW_DPRINTF(RTW_DEBUG_ATTACH, 4050 ("%s: PHY delay %d\n", sc->sc_dev.dv_xname, sc->sc_phydelay)); 4051 4052 if (sc->sc_locale == RTW_LOCALE_UNKNOWN) 4053 rtw_identify_country(&sc->sc_regs, &sc->sc_locale); 4054 4055 for (i = 1; i <= 14; i++) { 4056 sc->sc_ic.ic_channels[i].ic_flags = IEEE80211_CHAN_B; 4057 sc->sc_ic.ic_channels[i].ic_freq = 4058 ieee80211_ieee2mhz(i, sc->sc_ic.ic_channels[i].ic_flags); 4059 } 4060 4061 if (rtw_identify_sta(&sc->sc_regs, &sc->sc_ic.ic_myaddr, 4062 sc->sc_dev.dv_xname) != 0) 4063 goto fail8; 4064 4065 ifp = &sc->sc_if; 4066 (void)memcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ); 4067 ifp->if_softc = sc; 4068 ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST | 4069 IFF_NOTRAILERS; 4070 ifp->if_ioctl = rtw_ioctl; 4071 ifp->if_start = rtw_start; 4072 ifp->if_watchdog = rtw_watchdog; 4073 4074 IFQ_SET_READY(&sc->sc_if.if_snd); 4075 4076 ic->ic_phytype = IEEE80211_T_DS; 4077 ic->ic_opmode = IEEE80211_M_STA; 4078 ic->ic_caps = IEEE80211_C_PMGT | IEEE80211_C_MONITOR | IEEE80211_C_WEP; 4079 #ifndef IEEE80211_STA_ONLY 4080 ic->ic_caps |= IEEE80211_C_HOSTAP | IEEE80211_C_IBSS; 4081 #endif 4082 ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b; 4083 4084 rtw_led_attach(&sc->sc_led_state, (void *)sc); 4085 4086 /* 4087 * Call MI attach routines. 4088 */ 4089 if_attach(&sc->sc_if); 4090 ieee80211_ifattach(&sc->sc_if); 4091 4092 mtbl = &sc->sc_mtbl; 4093 mtbl->mt_newstate = ic->ic_newstate; 4094 ic->ic_newstate = rtw_newstate; 4095 4096 #ifndef IEEE80211_STA_ONLY 4097 mtbl->mt_recv_mgmt = ic->ic_recv_mgmt; 4098 ic->ic_recv_mgmt = rtw_recv_mgmt; 4099 #endif 4100 4101 mtbl->mt_node_free = ic->ic_node_free; 4102 ic->ic_node_free = rtw_node_free; 4103 4104 mtbl->mt_node_alloc = ic->ic_node_alloc; 4105 ic->ic_node_alloc = rtw_node_alloc; 4106 4107 /* possibly we should fill in our own sc_send_prresp, since 4108 * the RTL8180 is probably sending probe responses in ad hoc 4109 * mode. 4110 */ 4111 4112 /* complete initialization */ 4113 ieee80211_media_init(&sc->sc_if, rtw_media_change, rtw_media_status); 4114 timeout_set(&sc->sc_scan_to, rtw_next_scan, sc); 4115 4116 #if NBPFILTER > 0 4117 bzero(&sc->sc_rxtapu, sizeof(sc->sc_rxtapu)); 4118 sc->sc_rxtap.rr_ihdr.it_len = sizeof(sc->sc_rxtapu); 4119 sc->sc_rxtap.rr_ihdr.it_present = RTW_RX_RADIOTAP_PRESENT; 4120 4121 bzero(&sc->sc_txtapu, sizeof(sc->sc_txtapu)); 4122 sc->sc_txtap.rt_ihdr.it_len = sizeof(sc->sc_txtapu); 4123 sc->sc_txtap.rt_ihdr.it_present = RTW_TX_RADIOTAP_PRESENT; 4124 4125 bpfattach(&sc->sc_radiobpf, &sc->sc_ic.ic_if, DLT_IEEE802_11_RADIO, 4126 sizeof(struct ieee80211_frame) + 64); 4127 #endif 4128 4129 rtw_establish_hooks(&sc->sc_hooks, sc->sc_dev.dv_xname, (void*)sc); 4130 4131 return; 4132 4133 fail8: 4134 sr = &sc->sc_srom; 4135 sr->sr_size = 0; 4136 if (sr->sr_content != NULL) { 4137 free(sr->sr_content, M_DEVBUF); 4138 sr->sr_content = NULL; 4139 } 4140 4141 fail7: 4142 rtw_rxdesc_dmamaps_destroy(sc->sc_dmat, &sc->sc_rxsoft[0], 4143 RTW_RXQLEN); 4144 4145 fail6: 4146 for (pri = 0; pri < RTW_NTXPRI; pri++) { 4147 rtw_txdesc_dmamaps_destroy(sc->sc_dmat, 4148 sc->sc_txsoft_blk[pri].tsb_desc, 4149 sc->sc_txsoft_blk[pri].tsb_ndesc); 4150 } 4151 4152 fail5: 4153 rtw_txsoft_blk_cleanup_all(sc); 4154 4155 fail4: 4156 bus_dmamap_unload(sc->sc_dmat, sc->sc_desc_dmamap); 4157 fail3: 4158 bus_dmamap_destroy(sc->sc_dmat, sc->sc_desc_dmamap); 4159 fail2: 4160 bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_descs, 4161 sizeof(struct rtw_descs)); 4162 fail1: 4163 bus_dmamem_free(sc->sc_dmat, &sc->sc_desc_segs, 4164 sc->sc_desc_nsegs); 4165 fail0: 4166 return; 4167 } 4168 4169 int 4170 rtw_detach(struct rtw_softc *sc) 4171 { 4172 sc->sc_flags |= RTW_F_INVALID; 4173 4174 rtw_stop(&sc->sc_if, 1); 4175 4176 rtw_disestablish_hooks(&sc->sc_hooks, sc->sc_dev.dv_xname, 4177 (void*)sc); 4178 timeout_del(&sc->sc_scan_to); 4179 ieee80211_ifdetach(&sc->sc_if); 4180 if_detach(&sc->sc_if); 4181 4182 return 0; 4183 } 4184 4185 /* 4186 * PHY specific functions 4187 */ 4188 4189 int 4190 rtw_bbp_preinit(struct rtw_regs *regs, u_int antatten0, int dflantb, 4191 u_int freq) 4192 { 4193 u_int antatten = antatten0; 4194 if (dflantb) 4195 antatten |= RTW_BBP_ANTATTEN_DFLANTB; 4196 if (freq == 2484) /* channel 14 */ 4197 antatten |= RTW_BBP_ANTATTEN_CHAN14; 4198 return rtw_bbp_write(regs, RTW_BBP_ANTATTEN, antatten); 4199 } 4200 4201 int 4202 rtw_bbp_init(struct rtw_regs *regs, struct rtw_bbpset *bb, int antdiv, 4203 int dflantb, u_int8_t cs_threshold, u_int freq) 4204 { 4205 int rc; 4206 u_int32_t sys2, sys3; 4207 4208 sys2 = bb->bb_sys2; 4209 if (antdiv) 4210 sys2 |= RTW_BBP_SYS2_ANTDIV; 4211 sys3 = bb->bb_sys3 | 4212 LSHIFT(cs_threshold, RTW_BBP_SYS3_CSTHRESH_MASK); 4213 4214 #define RTW_BBP_WRITE_OR_RETURN(reg, val) \ 4215 if ((rc = rtw_bbp_write(regs, reg, val)) != 0) \ 4216 return rc; 4217 4218 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_SYS1, bb->bb_sys1); 4219 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_TXAGC, bb->bb_txagc); 4220 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_LNADET, bb->bb_lnadet); 4221 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_IFAGCINI, bb->bb_ifagcini); 4222 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_IFAGCLIMIT, bb->bb_ifagclimit); 4223 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_IFAGCDET, bb->bb_ifagcdet); 4224 4225 if ((rc = rtw_bbp_preinit(regs, bb->bb_antatten, dflantb, freq)) != 0) 4226 return rc; 4227 4228 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_TRL, bb->bb_trl); 4229 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_SYS2, sys2); 4230 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_SYS3, sys3); 4231 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_CHESTLIM, bb->bb_chestlim); 4232 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_CHSQLIM, bb->bb_chsqlim); 4233 return 0; 4234 } 4235 4236 int 4237 rtw_sa2400_txpower(struct rtw_softc *sc, u_int8_t opaque_txpower) 4238 { 4239 return rtw_rf_macwrite(sc, SA2400_TX, opaque_txpower); 4240 } 4241 4242 /* make sure we're using the same settings as the reference driver */ 4243 void 4244 rtw_verify_syna(u_int freq, u_int32_t val) 4245 { 4246 u_int32_t expected_val = ~val; 4247 4248 switch (freq) { 4249 case 2412: 4250 expected_val = 0x0000096c; /* ch 1 */ 4251 break; 4252 case 2417: 4253 expected_val = 0x00080970; /* ch 2 */ 4254 break; 4255 case 2422: 4256 expected_val = 0x00100974; /* ch 3 */ 4257 break; 4258 case 2427: 4259 expected_val = 0x00180978; /* ch 4 */ 4260 break; 4261 case 2432: 4262 expected_val = 0x00000980; /* ch 5 */ 4263 break; 4264 case 2437: 4265 expected_val = 0x00080984; /* ch 6 */ 4266 break; 4267 case 2442: 4268 expected_val = 0x00100988; /* ch 7 */ 4269 break; 4270 case 2447: 4271 expected_val = 0x0018098c; /* ch 8 */ 4272 break; 4273 case 2452: 4274 expected_val = 0x00000994; /* ch 9 */ 4275 break; 4276 case 2457: 4277 expected_val = 0x00080998; /* ch 10 */ 4278 break; 4279 case 2462: 4280 expected_val = 0x0010099c; /* ch 11 */ 4281 break; 4282 case 2467: 4283 expected_val = 0x001809a0; /* ch 12 */ 4284 break; 4285 case 2472: 4286 expected_val = 0x000009a8; /* ch 13 */ 4287 break; 4288 case 2484: 4289 expected_val = 0x000009b4; /* ch 14 */ 4290 break; 4291 } 4292 KASSERT(val == expected_val); 4293 } 4294 4295 /* freq is in MHz */ 4296 int 4297 rtw_sa2400_tune(struct rtw_softc *sc, u_int freq) 4298 { 4299 int rc; 4300 u_int32_t syna, synb, sync; 4301 4302 /* XO = 44MHz, R = 11, hence N is in units of XO / R = 4MHz. 4303 * 4304 * The channel spacing (5MHz) is not divisible by 4MHz, so 4305 * we set the fractional part of N to compensate. 4306 */ 4307 int n = freq / 4, nf = (freq % 4) * 2; 4308 4309 syna = LSHIFT(nf, SA2400_SYNA_NF_MASK) | LSHIFT(n, SA2400_SYNA_N_MASK); 4310 rtw_verify_syna(freq, syna); 4311 4312 /* Divide the 44MHz crystal down to 4MHz. Set the fractional 4313 * compensation charge pump value to agree with the fractional 4314 * modulus. 4315 */ 4316 synb = LSHIFT(11, SA2400_SYNB_R_MASK) | SA2400_SYNB_L_NORMAL | 4317 SA2400_SYNB_ON | SA2400_SYNB_ONE | 4318 LSHIFT(80, SA2400_SYNB_FC_MASK); /* agrees w/ SA2400_SYNA_FM = 0 */ 4319 4320 sync = SA2400_SYNC_CP_NORMAL; 4321 4322 if ((rc = rtw_rf_macwrite(sc, SA2400_SYNA, syna)) != 0) 4323 return rc; 4324 if ((rc = rtw_rf_macwrite(sc, SA2400_SYNB, synb)) != 0) 4325 return rc; 4326 if ((rc = rtw_rf_macwrite(sc, SA2400_SYNC, sync)) != 0) 4327 return rc; 4328 return rtw_rf_macwrite(sc, SA2400_SYND, 0x0); 4329 } 4330 4331 int 4332 rtw_sa2400_pwrstate(struct rtw_softc *sc, enum rtw_pwrstate power) 4333 { 4334 u_int32_t opmode; 4335 opmode = SA2400_OPMODE_DEFAULTS; 4336 switch (power) { 4337 case RTW_ON: 4338 opmode |= SA2400_OPMODE_MODE_TXRX; 4339 break; 4340 case RTW_SLEEP: 4341 opmode |= SA2400_OPMODE_MODE_WAIT; 4342 break; 4343 case RTW_OFF: 4344 opmode |= SA2400_OPMODE_MODE_SLEEP; 4345 break; 4346 } 4347 4348 if (sc->sc_flags & RTW_F_DIGPHY) 4349 opmode |= SA2400_OPMODE_DIGIN; 4350 4351 return rtw_rf_macwrite(sc, SA2400_OPMODE, opmode); 4352 } 4353 4354 int 4355 rtw_sa2400_vcocal_start(struct rtw_softc *sc, int start) 4356 { 4357 u_int32_t opmode; 4358 4359 opmode = SA2400_OPMODE_DEFAULTS; 4360 if (start) 4361 opmode |= SA2400_OPMODE_MODE_VCOCALIB; 4362 else 4363 opmode |= SA2400_OPMODE_MODE_SLEEP; 4364 4365 if (sc->sc_flags & RTW_F_DIGPHY) 4366 opmode |= SA2400_OPMODE_DIGIN; 4367 4368 return rtw_rf_macwrite(sc, SA2400_OPMODE, opmode); 4369 } 4370 4371 int 4372 rtw_sa2400_vco_calibration(struct rtw_softc *sc) 4373 { 4374 int rc; 4375 /* calibrate VCO */ 4376 if ((rc = rtw_sa2400_vcocal_start(sc, 1)) != 0) 4377 return rc; 4378 DELAY(2200); /* 2.2 milliseconds */ 4379 /* XXX superfluous: SA2400 automatically entered SLEEP mode. */ 4380 return rtw_sa2400_vcocal_start(sc, 0); 4381 } 4382 4383 int 4384 rtw_sa2400_filter_calibration(struct rtw_softc *sc) 4385 { 4386 u_int32_t opmode; 4387 4388 opmode = SA2400_OPMODE_DEFAULTS | SA2400_OPMODE_MODE_FCALIB; 4389 if (sc->sc_flags & RTW_F_DIGPHY) 4390 opmode |= SA2400_OPMODE_DIGIN; 4391 4392 return rtw_rf_macwrite(sc, SA2400_OPMODE, opmode); 4393 } 4394 4395 int 4396 rtw_sa2400_dc_calibration(struct rtw_softc *sc) 4397 { 4398 int rc; 4399 u_int32_t dccal; 4400 4401 rtw_continuous_tx_enable(sc, 1); 4402 4403 dccal = SA2400_OPMODE_DEFAULTS | SA2400_OPMODE_MODE_TXRX; 4404 4405 rc = rtw_rf_macwrite(sc, SA2400_OPMODE, dccal); 4406 4407 if (rc != 0) 4408 return rc; 4409 4410 DELAY(5); /* DCALIB after being in Tx mode for 5 4411 * microseconds 4412 */ 4413 4414 dccal &= ~SA2400_OPMODE_MODE_MASK; 4415 dccal |= SA2400_OPMODE_MODE_DCALIB; 4416 4417 rc = rtw_rf_macwrite(sc, SA2400_OPMODE, dccal); 4418 if (rc != 0) 4419 return rc; 4420 4421 DELAY(20); /* calibration takes at most 20 microseconds */ 4422 4423 rtw_continuous_tx_enable(sc, 0); 4424 4425 return 0; 4426 } 4427 4428 int 4429 rtw_sa2400_calibrate(struct rtw_softc *sc, u_int freq) 4430 { 4431 int i, rc; 4432 4433 /* XXX reference driver calibrates VCO twice. Is it a bug? */ 4434 for (i = 0; i < 2; i++) { 4435 if ((rc = rtw_sa2400_vco_calibration(sc)) != 0) 4436 return rc; 4437 } 4438 /* VCO calibration erases synthesizer registers, so re-tune */ 4439 if ((rc = rtw_sa2400_tune(sc, freq)) != 0) 4440 return rc; 4441 if ((rc = rtw_sa2400_filter_calibration(sc)) != 0) 4442 return rc; 4443 /* analog PHY needs DC calibration */ 4444 if (!(sc->sc_flags & RTW_F_DIGPHY)) 4445 return rtw_sa2400_dc_calibration(sc); 4446 return 0; 4447 } 4448 4449 int 4450 rtw_sa2400_init(struct rtw_softc *sc, u_int freq, u_int8_t opaque_txpower, 4451 enum rtw_pwrstate power) 4452 { 4453 int rc; 4454 u_int32_t agc, manrx; 4455 4456 if ((rc = rtw_sa2400_txpower(sc, opaque_txpower)) != 0) 4457 return rc; 4458 4459 /* skip configuration if it's time to sleep or to power-down. */ 4460 if (power == RTW_SLEEP || power == RTW_OFF) 4461 return rtw_sa2400_pwrstate(sc, power); 4462 4463 /* go to sleep for configuration */ 4464 if ((rc = rtw_sa2400_pwrstate(sc, RTW_SLEEP)) != 0) 4465 return rc; 4466 4467 if ((rc = rtw_sa2400_tune(sc, freq)) != 0) 4468 return rc; 4469 4470 agc = LSHIFT(25, SA2400_AGC_MAXGAIN_MASK); 4471 agc |= LSHIFT(7, SA2400_AGC_BBPDELAY_MASK); 4472 agc |= LSHIFT(15, SA2400_AGC_LNADELAY_MASK); 4473 agc |= LSHIFT(27, SA2400_AGC_RXONDELAY_MASK); 4474 4475 if ((rc = rtw_rf_macwrite(sc, SA2400_AGC, agc)) != 0) 4476 return rc; 4477 4478 /* XXX we are not supposed to be in RXMGC mode when we do this? */ 4479 manrx = SA2400_MANRX_AHSN; 4480 manrx |= SA2400_MANRX_TEN; 4481 manrx |= LSHIFT(1023, SA2400_MANRX_RXGAIN_MASK); 4482 4483 if ((rc = rtw_rf_macwrite(sc, SA2400_MANRX, manrx)) != 0) 4484 return rc; 4485 4486 if ((rc = rtw_sa2400_calibrate(sc, freq)) != 0) 4487 return rc; 4488 4489 /* enter Tx/Rx mode */ 4490 return rtw_sa2400_pwrstate(sc, power); 4491 } 4492 4493 /* freq is in MHz */ 4494 int 4495 rtw_max2820_tune(struct rtw_softc *sc, u_int freq) 4496 { 4497 if (freq < 2400 || freq > 2499) 4498 return -1; 4499 4500 return rtw_rf_hostwrite(sc, MAX2820_CHANNEL, 4501 LSHIFT(freq - 2400, MAX2820_CHANNEL_CF_MASK)); 4502 } 4503 4504 int 4505 rtw_max2820_init(struct rtw_softc *sc, u_int freq, u_int8_t opaque_txpower, 4506 enum rtw_pwrstate power) 4507 { 4508 int rc; 4509 4510 if ((rc = rtw_rf_hostwrite(sc, MAX2820_TEST, 4511 MAX2820_TEST_DEFAULT)) != 0) 4512 return rc; 4513 4514 if ((rc = rtw_rf_hostwrite(sc, MAX2820_ENABLE, 4515 MAX2820_ENABLE_DEFAULT)) != 0) 4516 return rc; 4517 4518 /* skip configuration if it's time to sleep or to power-down. */ 4519 if ((rc = rtw_max2820_pwrstate(sc, power)) != 0) 4520 return rc; 4521 else if (power == RTW_OFF || power == RTW_SLEEP) 4522 return 0; 4523 4524 if ((rc = rtw_rf_hostwrite(sc, MAX2820_SYNTH, 4525 MAX2820_SYNTH_R_44MHZ)) != 0) 4526 return rc; 4527 4528 if ((rc = rtw_max2820_tune(sc, freq)) != 0) 4529 return rc; 4530 4531 /* XXX The MAX2820 datasheet indicates that 1C and 2C should not 4532 * be changed from 7, however, the reference driver sets them 4533 * to 4 and 1, respectively. 4534 */ 4535 if ((rc = rtw_rf_hostwrite(sc, MAX2820_RECEIVE, 4536 MAX2820_RECEIVE_DL_DEFAULT | 4537 LSHIFT(4, MAX2820A_RECEIVE_1C_MASK) | 4538 LSHIFT(1, MAX2820A_RECEIVE_2C_MASK))) != 0) 4539 return rc; 4540 4541 return rtw_rf_hostwrite(sc, MAX2820_TRANSMIT, 4542 MAX2820_TRANSMIT_PA_DEFAULT); 4543 } 4544 4545 int 4546 rtw_max2820_txpower(struct rtw_softc *sc, u_int8_t opaque_txpower) 4547 { 4548 /* TBD */ 4549 return 0; 4550 } 4551 4552 int 4553 rtw_max2820_pwrstate(struct rtw_softc *sc, enum rtw_pwrstate power) 4554 { 4555 uint32_t enable; 4556 4557 switch (power) { 4558 case RTW_OFF: 4559 case RTW_SLEEP: 4560 default: 4561 enable = 0x0; 4562 break; 4563 case RTW_ON: 4564 enable = MAX2820_ENABLE_DEFAULT; 4565 break; 4566 } 4567 return rtw_rf_hostwrite(sc, MAX2820_ENABLE, enable); 4568 } 4569 4570 int 4571 rtw_grf5101_init(struct rtw_softc *sc, u_int freq, u_int8_t opaque_txpower, 4572 enum rtw_pwrstate power) 4573 { 4574 int rc; 4575 4576 /* 4577 * These values have been derived from the rtl8180-sa2400 Linux driver. 4578 * It is unknown what they all do, GCT refuse to release any documentation 4579 * so these are more than likely sub optimal settings 4580 */ 4581 4582 rtw_rf_macwrite(sc, 0x01, 0x1a23); 4583 rtw_rf_macwrite(sc, 0x02, 0x4971); 4584 rtw_rf_macwrite(sc, 0x03, 0x41de); 4585 rtw_rf_macwrite(sc, 0x04, 0x2d80); 4586 4587 rtw_rf_macwrite(sc, 0x05, 0x61ff); 4588 4589 rtw_rf_macwrite(sc, 0x06, 0x0); 4590 4591 rtw_rf_macwrite(sc, 0x08, 0x7533); 4592 rtw_rf_macwrite(sc, 0x09, 0xc401); 4593 rtw_rf_macwrite(sc, 0x0a, 0x0); 4594 rtw_rf_macwrite(sc, 0x0c, 0x1c7); 4595 rtw_rf_macwrite(sc, 0x0d, 0x29d3); 4596 rtw_rf_macwrite(sc, 0x0e, 0x2e8); 4597 rtw_rf_macwrite(sc, 0x10, 0x192); 4598 rtw_rf_macwrite(sc, 0x11, 0x248); 4599 rtw_rf_macwrite(sc, 0x12, 0x0); 4600 rtw_rf_macwrite(sc, 0x13, 0x20c4); 4601 rtw_rf_macwrite(sc, 0x14, 0xf4fc); 4602 rtw_rf_macwrite(sc, 0x15, 0x0); 4603 rtw_rf_macwrite(sc, 0x16, 0x1500); 4604 4605 if ((rc = rtw_grf5101_txpower(sc, opaque_txpower)) != 0) 4606 return rc; 4607 4608 if ((rc = rtw_grf5101_tune(sc, freq)) != 0) 4609 return rc; 4610 4611 return (0); 4612 } 4613 4614 int 4615 rtw_grf5101_tune(struct rtw_softc *sc, u_int freq) 4616 { 4617 struct ieee80211com *ic = &sc->sc_ic; 4618 u_int channel = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan); 4619 4620 /* set channel */ 4621 rtw_rf_macwrite(sc, 0x07, 0); 4622 rtw_rf_macwrite(sc, 0x0b, channel - 1); 4623 rtw_rf_macwrite(sc, 0x07, 0x1000); 4624 4625 return (0); 4626 } 4627 4628 int 4629 rtw_grf5101_txpower(struct rtw_softc *sc, u_int8_t opaque_txpower) 4630 { 4631 rtw_rf_macwrite(sc, 0x15, 0); 4632 rtw_rf_macwrite(sc, 0x06, opaque_txpower); 4633 rtw_rf_macwrite(sc, 0x15, 0x10); 4634 rtw_rf_macwrite(sc, 0x15, 0x00); 4635 4636 return (0); 4637 } 4638 4639 int 4640 rtw_grf5101_pwrstate(struct rtw_softc *sc, enum rtw_pwrstate power) 4641 { 4642 switch (power) { 4643 case RTW_OFF: 4644 case RTW_SLEEP: 4645 rtw_rf_macwrite(sc, 0x07, 0x0000); 4646 rtw_rf_macwrite(sc, 0x1f, 0x0045); 4647 rtw_rf_macwrite(sc, 0x1f, 0x0005); 4648 rtw_rf_macwrite(sc, 0x00, 0x08e4); 4649 default: 4650 break; 4651 case RTW_ON: 4652 rtw_rf_macwrite(sc, 0x1f, 0x0001); 4653 DELAY(10); 4654 rtw_rf_macwrite(sc, 0x1f, 0x0001); 4655 DELAY(10); 4656 rtw_rf_macwrite(sc, 0x1f, 0x0041); 4657 DELAY(10); 4658 rtw_rf_macwrite(sc, 0x1f, 0x0061); 4659 DELAY(10); 4660 rtw_rf_macwrite(sc, 0x00, 0x0ae4); 4661 DELAY(10); 4662 rtw_rf_macwrite(sc, 0x07, 0x1000); 4663 DELAY(100); 4664 break; 4665 } 4666 4667 return 0; 4668 } 4669 4670 int 4671 rtw_rtl8225_pwrstate(struct rtw_softc *sc, enum rtw_pwrstate power) 4672 { 4673 return (0); 4674 } 4675 4676 int 4677 rtw_rtl8225_init(struct rtw_softc *sc, u_int freq, u_int8_t opaque_txpower, 4678 enum rtw_pwrstate power) 4679 { 4680 return (0); 4681 } 4682 4683 int 4684 rtw_rtl8225_txpower(struct rtw_softc *sc, u_int8_t opaque_txpower) 4685 { 4686 return (0); 4687 } 4688 4689 int 4690 rtw_rtl8225_tune(struct rtw_softc *sc, u_int freq) 4691 { 4692 return (0); 4693 } 4694 4695 int 4696 rtw_rtl8255_pwrstate(struct rtw_softc *sc, enum rtw_pwrstate power) 4697 { 4698 return (0); 4699 } 4700 4701 int 4702 rtw_rtl8255_init(struct rtw_softc *sc, u_int freq, u_int8_t opaque_txpower, 4703 enum rtw_pwrstate power) 4704 { 4705 return (0); 4706 } 4707 4708 int 4709 rtw_rtl8255_txpower(struct rtw_softc *sc, u_int8_t opaque_txpower) 4710 { 4711 return (0); 4712 } 4713 4714 int 4715 rtw_rtl8255_tune(struct rtw_softc *sc, u_int freq) 4716 { 4717 return (0); 4718 } 4719 4720 int 4721 rtw_phy_init(struct rtw_softc *sc) 4722 { 4723 int rc; 4724 struct ieee80211com *ic = &sc->sc_ic; 4725 struct rtw_regs *regs = &sc->sc_regs; 4726 int antdiv = sc->sc_flags & RTW_F_ANTDIV; 4727 int dflantb = sc->sc_flags & RTW_F_DFLANTB; 4728 u_int freq = ic->ic_bss->ni_chan->ic_freq; /* freq is in MHz */ 4729 u_int8_t opaque_txpower = rtw_chan2txpower(&sc->sc_srom, ic, 4730 ic->ic_bss->ni_chan); 4731 u_int8_t cs_threshold = sc->sc_csthr; 4732 enum rtw_pwrstate power = RTW_ON; 4733 4734 RTW_DPRINTF(RTW_DEBUG_PHY, 4735 ("%s: txpower %u csthresh %u freq %u antdiv %u dflantb %u " 4736 "pwrstate %s\n", __func__, opaque_txpower, cs_threshold, freq, 4737 antdiv, dflantb, rtw_pwrstate_string(power))); 4738 4739 /* XXX is this really necessary? */ 4740 if ((rc = (*sc->sc_rf_txpower)(sc, opaque_txpower)) != 0) 4741 return rc; 4742 if ((rc = rtw_bbp_preinit(regs, sc->sc_bbpset.bb_antatten, dflantb, 4743 freq)) != 0) 4744 return rc; 4745 if ((rc = (*sc->sc_rf_tune)(sc, freq)) != 0) 4746 return rc; 4747 /* initialize RF */ 4748 if ((rc = (*sc->sc_rf_init)(sc, freq, opaque_txpower, power)) != 0) 4749 return rc; 4750 #if 0 /* what is this redundant tx power setting here for? */ 4751 if ((rc = (*sc->sc_rf_txpower)(sc, opaque_txpower)) != 0) 4752 return rc; 4753 #endif 4754 return rtw_bbp_init(regs, &sc->sc_bbpset, antdiv, dflantb, 4755 cs_threshold, freq); 4756 } 4757 4758 /* 4759 * Generic PHY I/O functions 4760 */ 4761 4762 int 4763 rtw_bbp_write(struct rtw_regs *regs, u_int addr, u_int val) 4764 { 4765 #define BBP_WRITE_ITERS 50 4766 #define BBP_WRITE_DELAY 1 4767 int i; 4768 u_int32_t wrbbp, rdbbp; 4769 4770 RTW_DPRINTF(RTW_DEBUG_PHYIO, 4771 ("%s: bbp[%u] <- %u\n", __func__, addr, val)); 4772 4773 KASSERT((addr & ~PRESHIFT(RTW_BB_ADDR_MASK)) == 0); 4774 KASSERT((val & ~PRESHIFT(RTW_BB_WR_MASK)) == 0); 4775 4776 wrbbp = LSHIFT(addr, RTW_BB_ADDR_MASK) | RTW_BB_WREN | 4777 LSHIFT(val, RTW_BB_WR_MASK) | RTW_BB_RD_MASK, 4778 4779 rdbbp = LSHIFT(addr, RTW_BB_ADDR_MASK) | 4780 RTW_BB_WR_MASK | RTW_BB_RD_MASK; 4781 4782 RTW_DPRINTF(RTW_DEBUG_PHYIO, 4783 ("%s: rdbbp = %#08x, wrbbp = %#08x\n", __func__, rdbbp, wrbbp)); 4784 4785 for (i = BBP_WRITE_ITERS; --i >= 0; ) { 4786 RTW_RBW(regs, RTW_BB, RTW_BB); 4787 RTW_WRITE(regs, RTW_BB, wrbbp); 4788 RTW_SYNC(regs, RTW_BB, RTW_BB); 4789 RTW_WRITE(regs, RTW_BB, rdbbp); 4790 RTW_SYNC(regs, RTW_BB, RTW_BB); 4791 delay(BBP_WRITE_DELAY); /* 1 microsecond */ 4792 if (MASK_AND_RSHIFT(RTW_READ(regs, RTW_BB), 4793 RTW_BB_RD_MASK) == val) { 4794 RTW_DPRINTF(RTW_DEBUG_PHYIO, 4795 ("%s: finished in %dus\n", __func__, 4796 BBP_WRITE_DELAY * (BBP_WRITE_ITERS - i))); 4797 return 0; 4798 } 4799 delay(BBP_WRITE_DELAY); /* again */ 4800 } 4801 printf("%s: timeout\n", __func__); 4802 return -1; 4803 } 4804 4805 /* Help rtw_rf_hostwrite bang bits to RF over 3-wire interface. */ 4806 void 4807 rtw_rf_hostbangbits(struct rtw_regs *regs, u_int32_t bits, int lo_to_hi, 4808 u_int nbits) 4809 { 4810 int i; 4811 u_int32_t mask, reg; 4812 4813 KASSERT(nbits <= 32); 4814 4815 RTW_DPRINTF(RTW_DEBUG_PHYIO, 4816 ("%s: %u bits, %#08x, %s\n", __func__, nbits, bits, 4817 (lo_to_hi) ? "lo to hi" : "hi to lo")); 4818 4819 reg = RTW8180_PHYCFG_HST; 4820 RTW_WRITE(regs, RTW8180_PHYCFG, reg); 4821 RTW_SYNC(regs, RTW8180_PHYCFG, RTW8180_PHYCFG); 4822 4823 if (lo_to_hi) 4824 mask = 0x1; 4825 else 4826 mask = 1 << (nbits - 1); 4827 4828 for (i = 0; i < nbits; i++) { 4829 RTW_DPRINTF(RTW_DEBUG_PHYBITIO, 4830 ("%s: bits %#08x mask %#08x -> bit %#08x\n", 4831 __func__, bits, mask, bits & mask)); 4832 4833 if ((bits & mask) != 0) 4834 reg |= RTW8180_PHYCFG_HST_DATA; 4835 else 4836 reg &= ~RTW8180_PHYCFG_HST_DATA; 4837 4838 reg |= RTW8180_PHYCFG_HST_CLK; 4839 RTW_WRITE(regs, RTW8180_PHYCFG, reg); 4840 RTW_SYNC(regs, RTW8180_PHYCFG, RTW8180_PHYCFG); 4841 4842 DELAY(2); /* arbitrary delay */ 4843 4844 reg &= ~RTW8180_PHYCFG_HST_CLK; 4845 RTW_WRITE(regs, RTW8180_PHYCFG, reg); 4846 RTW_SYNC(regs, RTW8180_PHYCFG, RTW8180_PHYCFG); 4847 4848 if (lo_to_hi) 4849 mask <<= 1; 4850 else 4851 mask >>= 1; 4852 } 4853 4854 reg |= RTW8180_PHYCFG_HST_EN; 4855 KASSERT((reg & RTW8180_PHYCFG_HST_CLK) == 0); 4856 RTW_WRITE(regs, RTW8180_PHYCFG, reg); 4857 RTW_SYNC(regs, RTW8180_PHYCFG, RTW8180_PHYCFG); 4858 } 4859 4860 #if 0 4861 void 4862 rtw_rf_rtl8225_hostbangbits(struct rtw_regs *regs, u_int32_t bits, int lo_to_hi, 4863 u_int nbits) 4864 { 4865 int i; 4866 u_int8_t page; 4867 u_int16_t reg0, reg1, reg2; 4868 u_int32_t mask; 4869 4870 /* enable page 0 */ 4871 page = RTW_READ8(regs, RTW_PSR); 4872 RTW_WRITE8(regs, RTW_PSR, page & ~RTW_PSR_PSEN); 4873 4874 /* enable RF access */ 4875 reg0 = RTW_READ16(regs, RTW8185_RFPINSOUTPUT) & 4876 RTW8185_RFPINSOUTPUT_MASK; 4877 reg1 = RTW_READ16(regs, RTW8185_RFPINSENABLE); 4878 RTW_WRITE16(regs, RTW8185_RFPINSENABLE, 4879 RTW8185_RFPINSENABLE_ENABLE | reg0); 4880 reg2 = RTW_READ16(regs, RTW8185_RFPINSSELECT); 4881 RTW_WRITE16(regs, RTW8185_RFPINSSELECT, 4882 RTW8185_RFPINSSELECT_ENABLE | reg1 /* XXX | SW_GPIO_CTL */); 4883 DELAY(10); 4884 4885 RTW_WRITE16(regs, RTW8185_RFPINSOUTPUT, reg0); 4886 DELAY(10); 4887 4888 if (lo_to_hi) 4889 mask = 0x1; 4890 else 4891 mask = 1 << (nbits - 1); 4892 4893 for (i = 0; i < nbits; i++) { 4894 RTW_DPRINTF(RTW_DEBUG_PHYBITIO, 4895 ("%s: bits %#08x mask %#08x -> bit %#08x\n", 4896 __func__, bits, mask, bits & mask)); 4897 4898 if ((bits & mask) != 0) 4899 reg |= RTW8180_PHYCFG_HST_DATA; 4900 else 4901 reg &= ~RTW8180_PHYCFG_HST_DATA; 4902 4903 reg |= RTW8180_PHYCFG_HST_CLK; 4904 RTW_WRITE(regs, RTW8180_PHYCFG, reg); 4905 RTW_SYNC(regs, RTW8180_PHYCFG, RTW8180_PHYCFG); 4906 4907 DELAY(2); /* arbitrary delay */ 4908 4909 reg &= ~RTW8180_PHYCFG_HST_CLK; 4910 RTW_WRITE(regs, RTW8180_PHYCFG, reg); 4911 RTW_SYNC(regs, RTW8180_PHYCFG, RTW8180_PHYCFG); 4912 4913 if (lo_to_hi) 4914 mask <<= 1; 4915 else 4916 mask >>= 1; 4917 } 4918 4919 /* reset the page */ 4920 RTW_WRITE8(regs, RTW_PSR, page); 4921 } 4922 #endif 4923 4924 /* Help rtw_rf_macwrite: tell MAC to bang bits to RF over the 3-wire 4925 * interface. 4926 */ 4927 int 4928 rtw_rf_macbangbits(struct rtw_regs *regs, u_int32_t reg) 4929 { 4930 int i; 4931 4932 RTW_DPRINTF(RTW_DEBUG_PHY, ("%s: %#08x\n", __func__, reg)); 4933 4934 RTW_WRITE(regs, RTW8180_PHYCFG, RTW8180_PHYCFG_MAC_POLL | reg); 4935 4936 RTW_WBR(regs, RTW8180_PHYCFG, RTW8180_PHYCFG); 4937 4938 for (i = rtw_macbangbits_timeout; --i >= 0; delay(1)) { 4939 if ((RTW_READ(regs, RTW8180_PHYCFG) & 4940 RTW8180_PHYCFG_MAC_POLL) == 0) { 4941 RTW_DPRINTF(RTW_DEBUG_PHY, 4942 ("%s: finished in %dus\n", __func__, 4943 rtw_macbangbits_timeout - i)); 4944 return 0; 4945 } 4946 RTW_RBR(regs, RTW8180_PHYCFG, RTW8180_PHYCFG); 4947 } 4948 4949 printf("%s: RTW8180_PHYCFG_MAC_POLL still set.\n", __func__); 4950 return -1; 4951 } 4952 4953 u_int32_t 4954 rtw_grf5101_host_crypt(u_int addr, u_int32_t val) 4955 { 4956 /* TBD */ 4957 return 0; 4958 } 4959 4960 u_int32_t 4961 rtw_grf5101_mac_crypt(u_int addr, u_int32_t val) 4962 { 4963 u_int32_t data_and_addr; 4964 #define EXTRACT_NIBBLE(d, which) (((d) >> (4 * (which))) & 0xf) 4965 static u_int8_t caesar[16] = { 4966 0x0, 0x8, 0x4, 0xc, 4967 0x2, 0xa, 0x6, 0xe, 4968 0x1, 0x9, 0x5, 0xd, 4969 0x3, 0xb, 0x7, 0xf 4970 }; 4971 data_and_addr = 4972 caesar[EXTRACT_NIBBLE(val, 2)] | 4973 (caesar[EXTRACT_NIBBLE(val, 1)] << 4) | 4974 (caesar[EXTRACT_NIBBLE(val, 0)] << 8) | 4975 (caesar[(addr >> 1) & 0xf] << 12) | 4976 ((addr & 0x1) << 16) | 4977 (caesar[EXTRACT_NIBBLE(val, 3)] << 24); 4978 return LSHIFT(data_and_addr, RTW8180_PHYCFG_MAC_PHILIPS_ADDR_MASK | 4979 RTW8180_PHYCFG_MAC_PHILIPS_DATA_MASK); 4980 #undef EXTRACT_NIBBLE 4981 } 4982 4983 /* Bang bits over the 3-wire interface. */ 4984 int 4985 rtw_rf_hostwrite(struct rtw_softc *sc, u_int addr, u_int32_t val) 4986 { 4987 u_int nbits; 4988 int lo_to_hi; 4989 u_int32_t bits; 4990 void(*rf_bangbits)(struct rtw_regs *, u_int32_t, int, u_int) = 4991 rtw_rf_hostbangbits; 4992 4993 RTW_DPRINTF(RTW_DEBUG_PHYIO, ("%s: [%u] <- %#08x\n", __func__, 4994 addr, val)); 4995 4996 switch (sc->sc_rfchipid) { 4997 case RTW_RFCHIPID_MAXIM2820: 4998 nbits = 16; 4999 lo_to_hi = 0; 5000 bits = LSHIFT(val, MAX2820_TWI_DATA_MASK) | 5001 LSHIFT(addr, MAX2820_TWI_ADDR_MASK); 5002 break; 5003 case RTW_RFCHIPID_PHILIPS: 5004 KASSERT((addr & ~PRESHIFT(SA2400_TWI_ADDR_MASK)) == 0); 5005 KASSERT((val & ~PRESHIFT(SA2400_TWI_DATA_MASK)) == 0); 5006 bits = LSHIFT(val, SA2400_TWI_DATA_MASK) | 5007 LSHIFT(addr, SA2400_TWI_ADDR_MASK) | SA2400_TWI_WREN; 5008 nbits = 32; 5009 lo_to_hi = 1; 5010 break; 5011 case RTW_RFCHIPID_GCT: 5012 KASSERT((addr & ~PRESHIFT(SI4126_TWI_ADDR_MASK)) == 0); 5013 KASSERT((val & ~PRESHIFT(SI4126_TWI_DATA_MASK)) == 0); 5014 bits = rtw_grf5101_host_crypt(addr, val); 5015 nbits = 21; 5016 lo_to_hi = 1; 5017 break; 5018 case RTW_RFCHIPID_RFMD2948: 5019 KASSERT((addr & ~PRESHIFT(SI4126_TWI_ADDR_MASK)) == 0); 5020 KASSERT((val & ~PRESHIFT(SI4126_TWI_DATA_MASK)) == 0); 5021 bits = LSHIFT(val, SI4126_TWI_DATA_MASK) | 5022 LSHIFT(addr, SI4126_TWI_ADDR_MASK); 5023 nbits = 22; 5024 lo_to_hi = 0; 5025 break; 5026 case RTW_RFCHIPID_RTL8225: 5027 case RTW_RFCHIPID_RTL8255: 5028 nbits = 16; 5029 lo_to_hi = 0; 5030 bits = LSHIFT(val, RTL8225_TWI_DATA_MASK) | 5031 LSHIFT(addr, RTL8225_TWI_ADDR_MASK); 5032 5033 /* the RTL8225 uses a slightly modified RF interface */ 5034 rf_bangbits = rtw_rf_hostbangbits; 5035 break; 5036 case RTW_RFCHIPID_INTERSIL: 5037 default: 5038 printf("%s: unknown rfchipid %d\n", __func__, sc->sc_rfchipid); 5039 return -1; 5040 } 5041 5042 (*rf_bangbits)(&sc->sc_regs, bits, lo_to_hi, nbits); 5043 5044 return 0; 5045 } 5046 5047 u_int32_t 5048 rtw_maxim_swizzle(u_int addr, u_int32_t val) 5049 { 5050 u_int32_t hidata, lodata; 5051 5052 KASSERT((val & ~(RTW_MAXIM_LODATA_MASK|RTW_MAXIM_HIDATA_MASK)) == 0); 5053 lodata = MASK_AND_RSHIFT(val, RTW_MAXIM_LODATA_MASK); 5054 hidata = MASK_AND_RSHIFT(val, RTW_MAXIM_HIDATA_MASK); 5055 return LSHIFT(lodata, RTW8180_PHYCFG_MAC_MAXIM_LODATA_MASK) | 5056 LSHIFT(hidata, RTW8180_PHYCFG_MAC_MAXIM_HIDATA_MASK) | 5057 LSHIFT(addr, RTW8180_PHYCFG_MAC_MAXIM_ADDR_MASK); 5058 } 5059 5060 /* Tell the MAC what to bang over the 3-wire interface. */ 5061 int 5062 rtw_rf_macwrite(struct rtw_softc *sc, u_int addr, u_int32_t val) 5063 { 5064 u_int32_t reg; 5065 5066 RTW_DPRINTF(RTW_DEBUG_PHYIO, ("%s: %s[%u] <- %#08x\n", __func__, 5067 addr, val)); 5068 5069 switch (sc->sc_rfchipid) { 5070 case RTW_RFCHIPID_GCT: 5071 reg = rtw_grf5101_mac_crypt(addr, val); 5072 break; 5073 case RTW_RFCHIPID_MAXIM2820: 5074 reg = rtw_maxim_swizzle(addr, val); 5075 break; 5076 default: /* XXX */ 5077 case RTW_RFCHIPID_PHILIPS: 5078 KASSERT((addr & 5079 ~PRESHIFT(RTW8180_PHYCFG_MAC_PHILIPS_ADDR_MASK)) == 0); 5080 KASSERT((val & 5081 ~PRESHIFT(RTW8180_PHYCFG_MAC_PHILIPS_DATA_MASK)) == 0); 5082 5083 reg = LSHIFT(addr, RTW8180_PHYCFG_MAC_PHILIPS_ADDR_MASK) | 5084 LSHIFT(val, RTW8180_PHYCFG_MAC_PHILIPS_DATA_MASK); 5085 } 5086 5087 switch (sc->sc_rfchipid) { 5088 case RTW_RFCHIPID_GCT: 5089 case RTW_RFCHIPID_MAXIM2820: 5090 case RTW_RFCHIPID_RFMD2948: 5091 reg |= RTW8180_PHYCFG_MAC_RFTYPE_RFMD; 5092 break; 5093 case RTW_RFCHIPID_INTERSIL: 5094 reg |= RTW8180_PHYCFG_MAC_RFTYPE_INTERSIL; 5095 break; 5096 case RTW_RFCHIPID_PHILIPS: 5097 reg |= RTW8180_PHYCFG_MAC_RFTYPE_PHILIPS; 5098 break; 5099 default: 5100 printf("%s: unknown rfchipid %d\n", __func__, sc->sc_rfchipid); 5101 return -1; 5102 } 5103 5104 return rtw_rf_macbangbits(&sc->sc_regs, reg); 5105 } 5106 5107 5108 u_int8_t 5109 rtw_read8(void *arg, u_int32_t off) 5110 { 5111 struct rtw_regs *regs = (struct rtw_regs *)arg; 5112 return (bus_space_read_1(regs->r_bt, regs->r_bh, off)); 5113 } 5114 5115 u_int16_t 5116 rtw_read16(void *arg, u_int32_t off) 5117 { 5118 struct rtw_regs *regs = (struct rtw_regs *)arg; 5119 return (bus_space_read_2(regs->r_bt, regs->r_bh, off)); 5120 } 5121 5122 u_int32_t 5123 rtw_read32(void *arg, u_int32_t off) 5124 { 5125 struct rtw_regs *regs = (struct rtw_regs *)arg; 5126 return (bus_space_read_4(regs->r_bt, regs->r_bh, off)); 5127 } 5128 5129 void 5130 rtw_write8(void *arg, u_int32_t off, u_int8_t val) 5131 { 5132 struct rtw_regs *regs = (struct rtw_regs *)arg; 5133 bus_space_write_1(regs->r_bt, regs->r_bh, off, val); 5134 } 5135 5136 void 5137 rtw_write16(void *arg, u_int32_t off, u_int16_t val) 5138 { 5139 struct rtw_regs *regs = (struct rtw_regs *)arg; 5140 bus_space_write_2(regs->r_bt, regs->r_bh, off, val); 5141 } 5142 5143 void 5144 rtw_write32(void *arg, u_int32_t off, u_int32_t val) 5145 { 5146 struct rtw_regs *regs = (struct rtw_regs *)arg; 5147 bus_space_write_4(regs->r_bt, regs->r_bh, off, val); 5148 } 5149 5150 void 5151 rtw_barrier(void *arg, u_int32_t reg0, u_int32_t reg1, int flags) 5152 { 5153 struct rtw_regs *regs = (struct rtw_regs *)arg; 5154 bus_space_barrier(regs->r_bt, regs->r_bh, MIN(reg0, reg1), 5155 MAX(reg0, reg1) - MIN(reg0, reg1) + 4, flags); 5156 } 5157