1 /* 2 * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 /* 7 * Copyright (c) 2006 8 * Damien Bergamini <damien.bergamini@free.fr> 9 * 10 * Permission to use, copy, modify, and distribute this software for any 11 * purpose with or without fee is hereby granted, provided that the above 12 * copyright notice and this permission notice appear in all copies. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 15 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 16 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 17 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 19 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 20 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 21 */ 22 23 /* 24 * Ralink Technology RT2561, RT2561S and RT2661 chipset driver 25 * http://www.ralinktech.com/ 26 */ 27 28 #include <sys/types.h> 29 #include <sys/byteorder.h> 30 #include <sys/conf.h> 31 #include <sys/cmn_err.h> 32 #include <sys/stat.h> 33 #include <sys/ddi.h> 34 #include <sys/sunddi.h> 35 #include <sys/strsubr.h> 36 #include <sys/ethernet.h> 37 #include <inet/common.h> 38 #include <inet/nd.h> 39 #include <inet/mi.h> 40 #include <sys/note.h> 41 #include <sys/stream.h> 42 #include <sys/strsun.h> 43 #include <sys/modctl.h> 44 #include <sys/devops.h> 45 #include <sys/dlpi.h> 46 #include <sys/mac_provider.h> 47 #include <sys/mac_wifi.h> 48 #include <sys/net80211.h> 49 #include <sys/net80211_proto.h> 50 #include <sys/varargs.h> 51 #include <sys/policy.h> 52 #include <sys/pci.h> 53 #include <sys/crypto/common.h> 54 #include <sys/crypto/api.h> 55 #include <inet/wifi_ioctl.h> 56 57 #include "rt2661_reg.h" 58 #include "rt2661_var.h" 59 #include "rt2661_ucode.h" 60 61 #define RT2661_DBG_80211 (1 << 0) 62 #define RT2661_DBG_DMA (1 << 1) 63 #define RT2661_DBG_EEPROM (1 << 2) 64 #define RT2661_DBG_FW (1 << 3) 65 #define RT2661_DBG_HW (1 << 4) 66 #define RT2661_DBG_INTR (1 << 5) 67 #define RT2661_DBG_RX (1 << 6) 68 #define RT2661_DBG_SCAN (1 << 7) 69 #define RT2661_DBG_TX (1 << 8) 70 #define RT2661_DBG_RADIO (1 << 9) 71 #define RT2661_DBG_RESUME (1 << 10) 72 #define RT2661_DBG_MSG (1 << 11) 73 74 uint32_t rt2661_dbg_flags = 0; 75 76 #ifdef DEBUG 77 #define RWD_DEBUG \ 78 rt2661_debug 79 #else 80 #define RWD_DEBUG 81 #endif 82 83 static void *rt2661_soft_state_p = NULL; 84 85 static const uint8_t *ucode = NULL; 86 int usize; 87 88 static const struct { 89 uint32_t reg; 90 uint32_t val; 91 } rt2661_def_mac[] = { 92 RT2661_DEF_MAC 93 }; 94 95 static const struct { 96 uint8_t reg; 97 uint8_t val; 98 } rt2661_def_bbp[] = { 99 RT2661_DEF_BBP 100 }; 101 102 static const struct rfprog { 103 uint8_t chan; 104 uint32_t r1, r2, r3, r4; 105 } rt2661_rf5225_1[] = { 106 RT2661_RF5225_1 107 }, rt2661_rf5225_2[] = { 108 RT2661_RF5225_2 109 }; 110 111 /* 112 * PIO access attributes for registers 113 */ 114 static ddi_device_acc_attr_t rt2661_csr_accattr = { 115 DDI_DEVICE_ATTR_V0, 116 DDI_STRUCTURE_LE_ACC, 117 DDI_STRICTORDER_ACC 118 }; 119 120 /* 121 * DMA access attributes for descriptors: NOT to be byte swapped. 122 */ 123 static ddi_device_acc_attr_t rt2661_desc_accattr = { 124 DDI_DEVICE_ATTR_V0, 125 DDI_STRUCTURE_LE_ACC, 126 DDI_STRICTORDER_ACC 127 }; 128 129 static ddi_device_acc_attr_t rt2661_buf_accattr = { 130 DDI_DEVICE_ATTR_V0, 131 DDI_NEVERSWAP_ACC, 132 DDI_STRICTORDER_ACC, 133 DDI_DEFAULT_ACC 134 }; 135 136 /* 137 * Describes the chip's DMA engine 138 */ 139 static ddi_dma_attr_t rt2661_dma_attr = { 140 DMA_ATTR_V0, /* dma_attr version */ 141 0x0, /* dma_attr_addr_lo */ 142 0xffffffffU, /* dma_attr_addr_hi */ 143 0xffffffffU, /* dma_attr_count_max */ 144 1, /* dma_attr_align */ 145 0x00000fff, /* dma_attr_burstsizes */ 146 1, /* dma_attr_minxfer */ 147 0xffffffffU, /* dma_attr_maxxfer */ 148 0xffffffffU, /* dma_attr_seg */ 149 1, /* dma_attr_sgllen */ 150 1, /* dma_attr_granular */ 151 0 /* dma_attr_flags */ 152 }; 153 154 static const struct ieee80211_rateset rt2661_rateset_11b = 155 { 4, { 2, 4, 11, 22 } }; 156 157 static const struct ieee80211_rateset rt2661_rateset_11g = 158 { 12, { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 } }; 159 160 161 static const char *rt2661_get_rf(int); 162 163 static void rt2661_read_eeprom(struct rt2661_softc *); 164 static uint16_t rt2661_eeprom_read(struct rt2661_softc *, uint8_t); 165 static int rt2661_load_microcode(struct rt2661_softc *, 166 const uint8_t *, int); 167 168 static int rt2661_alloc_dma_mem(dev_info_t *, ddi_dma_attr_t *, size_t, 169 ddi_device_acc_attr_t *, uint_t, uint_t, struct dma_area *); 170 static void rt2661_free_dma_mem(struct dma_area *); 171 static int rt2661_alloc_tx_ring(struct rt2661_softc *, 172 struct rt2661_tx_ring *, int); 173 static void rt2661_reset_tx_ring(struct rt2661_softc *, 174 struct rt2661_tx_ring *); 175 static void rt2661_free_tx_ring(struct rt2661_softc *, 176 struct rt2661_tx_ring *); 177 static int rt2661_alloc_rx_ring(struct rt2661_softc *, 178 struct rt2661_rx_ring *, int); 179 static void rt2661_reset_rx_ring(struct rt2661_softc *, 180 struct rt2661_rx_ring *); 181 static void rt2661_free_rx_ring(struct rt2661_softc *, 182 struct rt2661_rx_ring *); 183 static void rt2661_tx_dma_intr(struct rt2661_softc *, 184 struct rt2661_tx_ring *); 185 static void rt2661_tx_intr(struct rt2661_softc *); 186 static void rt2661_rx_intr(struct rt2661_softc *); 187 static uint_t rt2661_softintr(caddr_t, caddr_t); 188 static void rt2661_mcu_wakeup(struct rt2661_softc *); 189 static void rt2661_mcu_cmd_intr(struct rt2661_softc *); 190 static uint_t rt2661_intr(caddr_t, caddr_t); 191 192 static uint16_t rt2661_txtime(int, int, uint32_t); 193 static int rt2661_ack_rate(struct ieee80211com *, int); 194 static uint8_t rt2661_plcp_signal(int); 195 static void rt2661_setup_tx_desc(struct rt2661_softc *, 196 struct rt2661_tx_desc *, uint32_t, uint16_t, int, 197 int, int); 198 199 static int rt2661_get_rssi(struct rt2661_softc *, uint8_t); 200 201 static int rt2661_send(ieee80211com_t *, mblk_t *); 202 static int rt2661_mgmt_send(ieee80211com_t *, mblk_t *, uint8_t); 203 204 static void rt2661_amrr_node_init(const struct rt2661_amrr *, 205 struct rt2661_amrr_node *); 206 static void rt2661_amrr_choose(struct rt2661_amrr *, 207 struct ieee80211_node *, struct rt2661_amrr_node *); 208 209 static void rt2661_update_promisc(struct rt2661_softc *); 210 static void rt2661_updateslot(struct ieee80211com *, int); 211 static void rt2661_set_slottime(struct rt2661_softc *); 212 static void rt2661_enable_mrr(struct rt2661_softc *); 213 static void rt2661_set_txpreamble(struct rt2661_softc *); 214 static void rt2661_set_basicrates(struct rt2661_softc *); 215 static void rt2661_set_bssid(struct rt2661_softc *, const uint8_t *); 216 static void rt2661_newassoc(struct ieee80211com *, struct ieee80211_node *); 217 static void rt2661_updatestats(void *); 218 static void rt2661_rx_tune(struct rt2661_softc *); 219 static void rt2661_enable_tsf_sync(struct rt2661_softc *); 220 static int rt2661_newstate(struct ieee80211com *, 221 enum ieee80211_state, int); 222 223 static void rt2661_set_macaddr(struct rt2661_softc *, const uint8_t *); 224 static int rt2661_bbp_init(struct rt2661_softc *); 225 static uint8_t rt2661_bbp_read(struct rt2661_softc *, uint8_t); 226 static void rt2661_bbp_write(struct rt2661_softc *, uint8_t, uint8_t); 227 static void rt2661_select_band(struct rt2661_softc *, 228 struct ieee80211_channel *); 229 static void rt2661_select_antenna(struct rt2661_softc *); 230 static void rt2661_rf_write(struct rt2661_softc *, uint8_t, uint32_t); 231 static void rt2661_set_chan(struct rt2661_softc *, 232 struct ieee80211_channel *); 233 234 static void rt2661_stop_locked(struct rt2661_softc *); 235 static int rt2661_init(struct rt2661_softc *); 236 static void rt2661_stop(struct rt2661_softc *); 237 /* 238 * device operations 239 */ 240 static int rt2661_attach(dev_info_t *, ddi_attach_cmd_t); 241 static int rt2661_detach(dev_info_t *, ddi_detach_cmd_t); 242 static int rt2661_quiesce(dev_info_t *); 243 244 /* 245 * Module Loading Data & Entry Points 246 */ 247 DDI_DEFINE_STREAM_OPS(rwd_dev_ops, nulldev, nulldev, rt2661_attach, 248 rt2661_detach, nodev, NULL, D_MP, NULL, rt2661_quiesce); 249 250 static struct modldrv rwd_modldrv = { 251 &mod_driverops, /* Type of module. This one is a driver */ 252 "Ralink RT2661 driver v1.1", /* short description */ 253 &rwd_dev_ops /* driver specific ops */ 254 }; 255 256 static struct modlinkage modlinkage = { 257 MODREV_1, 258 { (void *)&rwd_modldrv, NULL } 259 }; 260 261 static int rt2661_m_stat(void *, uint_t, uint64_t *); 262 static int rt2661_m_start(void *); 263 static void rt2661_m_stop(void *); 264 static int rt2661_m_promisc(void *, boolean_t); 265 static int rt2661_m_multicst(void *, boolean_t, const uint8_t *); 266 static int rt2661_m_unicst(void *, const uint8_t *); 267 static mblk_t *rt2661_m_tx(void *, mblk_t *); 268 static void rt2661_m_ioctl(void *, queue_t *, mblk_t *); 269 static int rt2661_m_setprop(void *arg, const char *pr_name, 270 mac_prop_id_t wldp_pr_num, 271 uint_t wldp_length, const void *wldp_buf); 272 static int rt2661_m_getprop(void *arg, const char *pr_name, 273 mac_prop_id_t wldp_pr_num, uint_t wldp_length, 274 void *wldp_buf); 275 static void rt2661_m_propinfo(void *arg, const char *pr_name, 276 mac_prop_id_t wldp_pr_num, mac_prop_info_handle_t mph); 277 278 static mac_callbacks_t rt2661_m_callbacks = { 279 MC_IOCTL | MC_SETPROP | MC_GETPROP | MC_PROPINFO, 280 rt2661_m_stat, 281 rt2661_m_start, 282 rt2661_m_stop, 283 rt2661_m_promisc, 284 rt2661_m_multicst, 285 rt2661_m_unicst, 286 rt2661_m_tx, 287 NULL, 288 rt2661_m_ioctl, 289 NULL, 290 NULL, 291 NULL, 292 rt2661_m_setprop, 293 rt2661_m_getprop, 294 rt2661_m_propinfo 295 }; 296 297 #ifdef DEBUG 298 void 299 rt2661_debug(uint32_t dbg_flags, const int8_t *fmt, ...) 300 { 301 va_list args; 302 303 if (dbg_flags & rt2661_dbg_flags) { 304 va_start(args, fmt); 305 vcmn_err(CE_CONT, fmt, args); 306 va_end(args); 307 } 308 } 309 #endif 310 311 /* 312 * Read 16 bits at address 'addr' from the serial EEPROM (either 93C46 or 313 * 93C66). 314 */ 315 static uint16_t 316 rt2661_eeprom_read(struct rt2661_softc *sc, uint8_t addr) 317 { 318 uint32_t tmp; 319 uint16_t val; 320 int n; 321 322 /* clock C once before the first command */ 323 RT2661_EEPROM_CTL(sc, 0); 324 325 RT2661_EEPROM_CTL(sc, RT2661_S); 326 RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_C); 327 RT2661_EEPROM_CTL(sc, RT2661_S); 328 329 /* write start bit (1) */ 330 RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_D); 331 RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_D | RT2661_C); 332 333 /* write READ opcode (10) */ 334 RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_D); 335 RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_D | RT2661_C); 336 RT2661_EEPROM_CTL(sc, RT2661_S); 337 RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_C); 338 339 /* write address (A5-A0 or A7-A0) */ 340 n = (RT2661_READ(sc, RT2661_E2PROM_CSR) & RT2661_93C46) ? 5 : 7; 341 for (; n >= 0; n--) { 342 RT2661_EEPROM_CTL(sc, RT2661_S | 343 (((addr >> n) & 1) << RT2661_SHIFT_D)); 344 RT2661_EEPROM_CTL(sc, RT2661_S | 345 (((addr >> n) & 1) << RT2661_SHIFT_D) | RT2661_C); 346 } 347 348 RT2661_EEPROM_CTL(sc, RT2661_S); 349 350 /* read data Q15-Q0 */ 351 val = 0; 352 for (n = 15; n >= 0; n--) { 353 RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_C); 354 tmp = RT2661_READ(sc, RT2661_E2PROM_CSR); 355 val |= ((tmp & RT2661_Q) >> RT2661_SHIFT_Q) << n; 356 RT2661_EEPROM_CTL(sc, RT2661_S); 357 } 358 359 RT2661_EEPROM_CTL(sc, 0); 360 361 /* clear Chip Select and clock C */ 362 RT2661_EEPROM_CTL(sc, RT2661_S); 363 RT2661_EEPROM_CTL(sc, 0); 364 RT2661_EEPROM_CTL(sc, RT2661_C); 365 366 return (val); 367 } 368 369 370 static void 371 rt2661_read_eeprom(struct rt2661_softc *sc) 372 { 373 struct ieee80211com *ic = &sc->sc_ic; 374 uint16_t val; 375 int i; 376 377 /* read MAC address */ 378 val = rt2661_eeprom_read(sc, RT2661_EEPROM_MAC01); 379 ic->ic_macaddr[0] = val & 0xff; 380 ic->ic_macaddr[1] = val >> 8; 381 382 val = rt2661_eeprom_read(sc, RT2661_EEPROM_MAC23); 383 ic->ic_macaddr[2] = val & 0xff; 384 ic->ic_macaddr[3] = val >> 8; 385 386 val = rt2661_eeprom_read(sc, RT2661_EEPROM_MAC45); 387 ic->ic_macaddr[4] = val & 0xff; 388 ic->ic_macaddr[5] = val >> 8; 389 390 val = rt2661_eeprom_read(sc, RT2661_EEPROM_ANTENNA); 391 /* XXX: test if different from 0xffff? */ 392 sc->rf_rev = (val >> 11) & 0x1f; 393 sc->hw_radio = (val >> 10) & 0x1; 394 sc->rx_ant = (val >> 4) & 0x3; 395 sc->tx_ant = (val >> 2) & 0x3; 396 sc->nb_ant = val & 0x3; 397 398 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_read_eeprom(): " 399 "RF revision=%d\n", sc->rf_rev); 400 401 val = rt2661_eeprom_read(sc, RT2661_EEPROM_CONFIG2); 402 sc->ext_5ghz_lna = (val >> 6) & 0x1; 403 sc->ext_2ghz_lna = (val >> 4) & 0x1; 404 405 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_read_eeprom(): " 406 "External 2GHz LNA=%d\nExternal 5GHz LNA=%d\n", 407 sc->ext_2ghz_lna, sc->ext_5ghz_lna); 408 409 val = rt2661_eeprom_read(sc, RT2661_EEPROM_RSSI_2GHZ_OFFSET); 410 if ((val & 0xff) != 0xff) 411 sc->rssi_2ghz_corr = (int8_t)(val & 0xff); 412 413 val = rt2661_eeprom_read(sc, RT2661_EEPROM_RSSI_5GHZ_OFFSET); 414 if ((val & 0xff) != 0xff) 415 sc->rssi_5ghz_corr = (int8_t)(val & 0xff); 416 417 /* adjust RSSI correction for external low-noise amplifier */ 418 if (sc->ext_2ghz_lna) 419 sc->rssi_2ghz_corr -= 14; 420 if (sc->ext_5ghz_lna) 421 sc->rssi_5ghz_corr -= 14; 422 423 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_read_eeprom(): " 424 "RSSI 2GHz corr=%d\nRSSI 5GHz corr=%d\n", 425 sc->rssi_2ghz_corr, sc->rssi_5ghz_corr); 426 427 val = rt2661_eeprom_read(sc, RT2661_EEPROM_FREQ_OFFSET); 428 if ((val >> 8) != 0xff) 429 sc->rfprog = (val >> 8) & 0x3; 430 if ((val & 0xff) != 0xff) 431 sc->rffreq = val & 0xff; 432 433 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_read_eeprom(): " 434 "RF prog=%d\nRF freq=%d\n", sc->rfprog, sc->rffreq); 435 436 /* read Tx power for all a/b/g channels */ 437 for (i = 0; i < 19; i++) { 438 val = rt2661_eeprom_read(sc, RT2661_EEPROM_TXPOWER + i); 439 sc->txpow[i * 2] = (int8_t)(val >> 8); 440 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_read_eeprom(): " 441 "Channel=%d Tx power=%d\n", 442 rt2661_rf5225_1[i * 2].chan, sc->txpow[i * 2]); 443 sc->txpow[i * 2 + 1] = (int8_t)(val & 0xff); 444 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_read_eeprom(): " 445 "Channel=%d Tx power=%d\n", 446 rt2661_rf5225_1[i * 2 + 1].chan, sc->txpow[i * 2 + 1]); 447 } 448 449 /* read vendor-specific BBP values */ 450 for (i = 0; i < 16; i++) { 451 val = rt2661_eeprom_read(sc, RT2661_EEPROM_BBP_BASE + i); 452 if (val == 0 || val == 0xffff) 453 continue; 454 sc->bbp_prom[i].reg = val >> 8; 455 sc->bbp_prom[i].val = val & 0xff; 456 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_read_eeprom(): " 457 "BBP R%d=%02x\n", sc->bbp_prom[i].reg, 458 sc->bbp_prom[i].val); 459 } 460 } 461 462 static const char * 463 rt2661_get_rf(int rev) 464 { 465 switch (rev) { 466 case RT2661_RF_5225: return "RT5225"; 467 case RT2661_RF_5325: return "RT5325 (MIMO XR)"; 468 case RT2661_RF_2527: return "RT2527"; 469 case RT2661_RF_2529: return "RT2529 (MIMO XR)"; 470 default: return "unknown"; 471 } 472 } 473 474 static int 475 rt2661_load_microcode(struct rt2661_softc *sc, const uint8_t *ucode_p, int size) 476 { 477 int ntries; 478 uint32_t off, i; 479 const uint8_t *fptr; 480 481 fptr = ucode_p; 482 off = RT2661_MCU_CODE_BASE; 483 484 /* reset 8051 */ 485 RT2661_WRITE(sc, RT2661_MCU_CNTL_CSR, RT2661_MCU_RESET); 486 487 /* cancel any pending Host to MCU command */ 488 RT2661_WRITE(sc, RT2661_H2M_MAILBOX_CSR, 0); 489 RT2661_WRITE(sc, RT2661_M2H_CMD_DONE_CSR, 0xffffffff); 490 RT2661_WRITE(sc, RT2661_HOST_CMD_CSR, 0); 491 492 /* write 8051's microcode */ 493 RT2661_WRITE(sc, RT2661_MCU_CNTL_CSR, 494 RT2661_MCU_RESET | RT2661_MCU_SEL); 495 /* RT2661_WRITE_REGION_1(sc, RT2661_MCU_CODE_BASE, ucode, size); */ 496 497 for (i = 0; i < size; i++) { 498 RT2661_MEM_WRITE1(sc, off++, *fptr++); 499 } 500 501 RT2661_WRITE(sc, RT2661_MCU_CNTL_CSR, RT2661_MCU_RESET); 502 503 /* kick 8051's ass */ 504 RT2661_WRITE(sc, RT2661_MCU_CNTL_CSR, 0); 505 506 /* wait for 8051 to initialize */ 507 for (ntries = 0; ntries < 500; ntries++) { 508 if (RT2661_READ(sc, RT2661_MCU_CNTL_CSR) & RT2661_MCU_READY) 509 break; 510 DELAY(100); 511 } 512 if (ntries == 500) { 513 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_load_microcode(): " 514 "timeout waiting for MCU to initialize\n"); 515 return (RT2661_FAILURE); 516 } 517 518 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_load_microcode(): " 519 "MCU initialized successfully\n"); 520 return (RT2661_SUCCESS); 521 } 522 523 /* 524 * Allocate an DMA memory and a DMA handle for accessing it 525 */ 526 static int 527 rt2661_alloc_dma_mem(dev_info_t *devinfo, ddi_dma_attr_t *dma_attr, 528 size_t memsize, ddi_device_acc_attr_t *attr_p, uint_t alloc_flags, 529 uint_t bind_flags, struct dma_area *dma_p) 530 { 531 int err; 532 533 /* 534 * Allocate handle 535 */ 536 err = ddi_dma_alloc_handle(devinfo, dma_attr, 537 DDI_DMA_SLEEP, NULL, &dma_p->dma_hdl); 538 if (err != DDI_SUCCESS) { 539 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rwd_allo_dma_mem(): " 540 "failed to alloc handle\n"); 541 goto fail1; 542 } 543 544 /* 545 * Allocate memory 546 */ 547 err = ddi_dma_mem_alloc(dma_p->dma_hdl, memsize, attr_p, 548 alloc_flags, DDI_DMA_SLEEP, NULL, &dma_p->mem_va, 549 &dma_p->alength, &dma_p->acc_hdl); 550 if (err != DDI_SUCCESS) { 551 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rwd_alloc_dma_mem(): " 552 "failed to alloc mem\n"); 553 goto fail2; 554 } 555 556 /* 557 * Bind the two together 558 */ 559 err = ddi_dma_addr_bind_handle(dma_p->dma_hdl, NULL, 560 dma_p->mem_va, dma_p->alength, bind_flags, 561 DDI_DMA_SLEEP, NULL, &dma_p->cookie, &dma_p->ncookies); 562 if (err != DDI_DMA_MAPPED) { 563 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rwd_alloc_dma_mem(): " 564 "failed to bind handle\n"); 565 goto fail3; 566 } 567 568 if (dma_p->ncookies != 1) { 569 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rwd_alloc_dma_mem(): " 570 "failed to alloc cookies\n"); 571 goto fail4; 572 } 573 574 dma_p->nslots = ~0U; 575 dma_p->size = ~0U; 576 dma_p->token = ~0U; 577 dma_p->offset = 0; 578 return (DDI_SUCCESS); 579 580 fail4: 581 (void) ddi_dma_unbind_handle(dma_p->dma_hdl); 582 fail3: 583 ddi_dma_mem_free(&dma_p->acc_hdl); 584 fail2: 585 ddi_dma_free_handle(&dma_p->dma_hdl); 586 fail1: 587 return (err); 588 } 589 590 static void 591 rt2661_free_dma_mem(struct dma_area *dma_p) 592 { 593 if (dma_p->dma_hdl != NULL) { 594 (void) ddi_dma_unbind_handle(dma_p->dma_hdl); 595 if (dma_p->acc_hdl != NULL) { 596 ddi_dma_mem_free(&dma_p->acc_hdl); 597 dma_p->acc_hdl = NULL; 598 } 599 ddi_dma_free_handle(&dma_p->dma_hdl); 600 dma_p->ncookies = 0; 601 dma_p->dma_hdl = NULL; 602 } 603 } 604 605 /*ARGSUSED*/ 606 static int 607 rt2661_alloc_tx_ring(struct rt2661_softc *sc, 608 struct rt2661_tx_ring *ring, int count) 609 { 610 struct rt2661_tx_desc *desc; 611 struct rt2661_tx_data *data; 612 int i, err, size, len; 613 614 size = count * RT2661_TX_DESC_SIZE; 615 len = count * sizeof (struct rt2661_tx_data); 616 617 ring->count = count; 618 ring->queued = 0; 619 ring->cur = 0; 620 ring->next = 0; 621 ring->stat = 0; 622 623 err = rt2661_alloc_dma_mem(sc->sc_dev, &rt2661_dma_attr, size, 624 &rt2661_desc_accattr, DDI_DMA_CONSISTENT, 625 DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 626 &ring->txdesc_dma); 627 if (err != DDI_SUCCESS) { 628 RWD_DEBUG(RT2661_DBG_DMA, "rwd: rt2661_alloc_tx_ring(): " 629 "failed to alloc dma mem\n"); 630 goto fail1; 631 } 632 633 ring->desc = (struct rt2661_tx_desc *)ring->txdesc_dma.mem_va; 634 (void) bzero(ring->desc, size); 635 ring->paddr = ring->txdesc_dma.cookie.dmac_address; 636 637 ring->data = kmem_zalloc(len, KM_NOSLEEP); 638 if (ring->data == NULL) { 639 RWD_DEBUG(RT2661_DBG_DMA, "rwd: rt2661_alloc_tx_ring(): " 640 "failed to alloc tx buffer\n"); 641 goto fail2; 642 } 643 644 for (i = 0; i < count; i++) { 645 desc = &ring->desc[i]; 646 data = &ring->data[i]; 647 err = rt2661_alloc_dma_mem(sc->sc_dev, 648 &rt2661_dma_attr, sc->sc_dmabuf_size, 649 &rt2661_buf_accattr, DDI_DMA_CONSISTENT, 650 DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 651 &data->txdata_dma); 652 if (err != DDI_SUCCESS) { 653 RWD_DEBUG(RT2661_DBG_DMA, 654 "rwd: rt2661_alloc_tx_ring(): " 655 "failed to alloc tx buffer dma\n"); 656 while (i >= 0) { 657 rt2661_free_dma_mem(&ring->data[i].txdata_dma); 658 i--; 659 } 660 goto fail3; 661 } 662 desc->addr[0] = data->txdata_dma.cookie.dmac_address; 663 data->buf = data->txdata_dma.mem_va; 664 data->paddr = data->txdata_dma.cookie.dmac_address; 665 } 666 667 (void) ddi_dma_sync(ring->txdesc_dma.dma_hdl, 668 0, size, DDI_DMA_SYNC_FORDEV); 669 return (DDI_SUCCESS); 670 fail3: 671 if (ring->data) 672 kmem_free(ring->data, 673 count * sizeof (struct rt2661_tx_data)); 674 fail2: 675 rt2661_free_dma_mem(&ring->txdesc_dma); 676 fail1: 677 return (err); 678 } 679 680 static void 681 rt2661_reset_tx_ring(struct rt2661_softc *sc, struct rt2661_tx_ring *ring) 682 { 683 struct rt2661_tx_desc *desc; 684 struct rt2661_tx_data *data; 685 int i; 686 687 for (i = 0; i < ring->count; i++) { 688 desc = &ring->desc[i]; 689 data = &ring->data[i]; 690 691 if (data->ni != NULL) { 692 ieee80211_free_node(data->ni); 693 data->ni = NULL; 694 } 695 696 desc->flags = 0; 697 } 698 699 if (!RT2661_IS_FASTREBOOT(sc)) 700 (void) ddi_dma_sync(ring->txdesc_dma.dma_hdl, 0, 701 ring->count * sizeof (struct rt2661_tx_desc), 702 DDI_DMA_SYNC_FORDEV); 703 704 ring->queued = 0; 705 ring->cur = ring->next = ring->stat = 0; 706 } 707 708 709 /*ARGSUSED*/ 710 static void 711 rt2661_free_tx_ring(struct rt2661_softc *sc, struct rt2661_tx_ring *ring) 712 { 713 struct rt2661_tx_data *data; 714 int i; 715 716 if (ring->desc != NULL) { 717 rt2661_free_dma_mem(&ring->txdesc_dma); 718 } 719 720 if (ring->data != NULL) { 721 for (i = 0; i < ring->count; i++) { 722 data = &ring->data[i]; 723 rt2661_free_dma_mem(&data->txdata_dma); 724 if (data->ni != NULL) { 725 ieee80211_free_node(data->ni); 726 data->ni = NULL; 727 } 728 } 729 kmem_free(ring->data, 730 ring->count * sizeof (struct rt2661_tx_data)); 731 } 732 } 733 734 /*ARGSUSED*/ 735 static int 736 rt2661_alloc_rx_ring(struct rt2661_softc *sc, 737 struct rt2661_rx_ring *ring, int count) 738 { 739 struct rt2661_rx_desc *desc; 740 struct rt2661_rx_data *data; 741 int i, err, len, size; 742 743 size = count * RT2661_RX_DESC_SIZE; 744 len = count * sizeof (struct rt2661_rx_data); 745 746 ring->count = count; 747 ring->cur = 0; 748 ring->next = 0; 749 750 err = rt2661_alloc_dma_mem(sc->sc_dev, &rt2661_dma_attr, size, 751 &rt2661_desc_accattr, DDI_DMA_CONSISTENT, 752 DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 753 &ring->rxdesc_dma); 754 if (err != DDI_SUCCESS) { 755 RWD_DEBUG(RT2661_DBG_DMA, "rwd: rt2661_alloc_rx_ring(): " 756 "failed to alloc dma mem\n"); 757 goto fail1; 758 } 759 760 ring->desc = (struct rt2661_rx_desc *)ring->rxdesc_dma.mem_va; 761 (void) bzero(ring->desc, size); 762 ring->paddr = ring->rxdesc_dma.cookie.dmac_address; 763 764 ring->data = kmem_zalloc(len, KM_NOSLEEP); 765 if (ring->data == NULL) { 766 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_alloc_rx_ring(): " 767 "failed to alloc rx buffer\n"); 768 goto fail2; 769 } 770 771 for (i = 0; i < count; i++) { 772 desc = &ring->desc[i]; 773 data = &ring->data[i]; 774 err = rt2661_alloc_dma_mem(sc->sc_dev, 775 &rt2661_dma_attr, sc->sc_dmabuf_size, 776 &rt2661_buf_accattr, DDI_DMA_CONSISTENT, 777 DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 778 &data->rxdata_dma); 779 if (err != DDI_SUCCESS) { 780 RWD_DEBUG(RT2661_DBG_DMA, 781 "rwd: rt2661_alloc_rx_ring(): " 782 "failed to alloc rx buffer dma\n"); 783 while (i >= 0) { 784 rt2661_free_dma_mem(&ring->data[i].rxdata_dma); 785 i--; 786 } 787 goto fail3; 788 } 789 data->buf = data->rxdata_dma.mem_va; 790 data->paddr = data->rxdata_dma.cookie.dmac_address; 791 desc->flags = LE_32(RT2661_RX_BUSY); 792 desc->physaddr = LE_32(data->paddr); 793 } 794 795 (void) ddi_dma_sync(ring->rxdesc_dma.dma_hdl, 796 0, size, DDI_DMA_SYNC_FORDEV); 797 return (DDI_SUCCESS); 798 fail3: 799 if (ring->data) 800 kmem_free(ring->data, 801 count * sizeof (struct rt2661_rx_data)); 802 fail2: 803 rt2661_free_dma_mem(&ring->rxdesc_dma); 804 fail1: 805 return (err); 806 } 807 808 static void 809 rt2661_reset_rx_ring(struct rt2661_softc *sc, struct rt2661_rx_ring *ring) 810 { 811 int i; 812 813 for (i = 0; i < ring->count; i++) 814 ring->desc[i].flags = LE_32(RT2661_RX_BUSY); 815 816 if (!RT2661_IS_FASTREBOOT(sc)) 817 (void) ddi_dma_sync(ring->rxdesc_dma.dma_hdl, 0, 818 ring->count * sizeof (struct rt2661_rx_ring), 819 DDI_DMA_SYNC_FORKERNEL); 820 821 ring->cur = ring->next = 0; 822 } 823 824 /*ARGSUSED*/ 825 static void 826 rt2661_free_rx_ring(struct rt2661_softc *sc, struct rt2661_rx_ring *ring) 827 { 828 struct rt2661_rx_data *data; 829 int i; 830 831 if (ring->desc != NULL) { 832 rt2661_free_dma_mem(&ring->rxdesc_dma); 833 } 834 835 if (ring->data != NULL) { 836 for (i = 0; i < ring->count; i++) { 837 data = &ring->data[i]; 838 rt2661_free_dma_mem(&data->rxdata_dma); 839 } 840 kmem_free(ring->data, 841 ring->count * sizeof (struct rt2661_rx_data)); 842 } 843 } 844 845 static void 846 rt2661_tx_dma_intr(struct rt2661_softc *sc, struct rt2661_tx_ring *ring) 847 { 848 struct rt2661_tx_desc *desc; 849 struct rt2661_tx_data *data; 850 851 for (;;) { 852 desc = &ring->desc[ring->next]; 853 data = &ring->data[ring->next]; 854 855 (void) ddi_dma_sync(ring->txdesc_dma.dma_hdl, 856 ring->next * RT2661_TX_DESC_SIZE, 857 RT2661_TX_DESC_SIZE, 858 DDI_DMA_SYNC_FORKERNEL); 859 860 if ((LE_32(desc->flags) & RT2661_TX_BUSY) || 861 !(LE_32(desc->flags) & RT2661_TX_VALID)) 862 break; 863 864 (void) ddi_dma_sync(data->txdata_dma.dma_hdl, 865 0, sc->sc_dmabuf_size, 866 DDI_DMA_SYNC_FORDEV); 867 868 /* descriptor is no longer valid */ 869 desc->flags &= ~LE_32(RT2661_TX_VALID); 870 871 (void) ddi_dma_sync(ring->txdesc_dma.dma_hdl, 872 ring->next * RT2661_TX_DESC_SIZE, 873 RT2661_TX_DESC_SIZE, 874 DDI_DMA_SYNC_FORDEV); 875 876 RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_tx_dma_intr(): " 877 "tx dma done q=%p idx=%u\n", ring, ring->next); 878 879 if (++ring->next >= ring->count) /* faster than % count */ 880 ring->next = 0; 881 } 882 } 883 884 static void 885 rt2661_tx_intr(struct rt2661_softc *sc) 886 { 887 struct ieee80211com *ic = &sc->sc_ic; 888 struct rt2661_tx_ring *ring; 889 struct rt2661_tx_data *data; 890 struct rt2661_node *rn; 891 892 uint32_t val; 893 int qid, retrycnt; 894 895 for (;;) { 896 val = RT2661_READ(sc, RT2661_STA_CSR4); 897 if (!(val & RT2661_TX_STAT_VALID)) 898 break; 899 900 /* retrieve the queue in which this frame was send */ 901 qid = RT2661_TX_QID(val); 902 ring = (qid <= 3) ? &sc->txq[qid] : &sc->mgtq; 903 904 /* retrieve rate control algorithm context */ 905 data = &ring->data[ring->stat]; 906 rn = (struct rt2661_node *)data->ni; 907 908 /* if no frame has been sent, ignore */ 909 if (rn == NULL) { 910 RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_tx_intr(): " 911 "no frame has been send, ignore\n"); 912 continue; 913 } 914 915 switch (RT2661_TX_RESULT(val)) { 916 case RT2661_TX_SUCCESS: 917 retrycnt = RT2661_TX_RETRYCNT(val); 918 919 RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_tx_intr(): " 920 "data frame sent successfully after " 921 "%d retries\n", retrycnt); 922 rn->amn.amn_txcnt++; 923 if (retrycnt > 0) { 924 rn->amn.amn_retrycnt++; 925 sc->sc_tx_retries++; 926 } 927 break; 928 case RT2661_TX_RETRY_FAIL: 929 RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_tx_intr(): " 930 "sending data frame failed (too much retries)\n"); 931 rn->amn.amn_txcnt++; 932 rn->amn.amn_retrycnt++; 933 break; 934 default: 935 /* other failure */ 936 RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_tx_intr():" 937 "sending data frame failed 0x%08x\n", val); 938 } 939 940 RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_tx_intr(): " 941 "tx done q=%d idx=%u\n", qid, ring->stat); 942 943 ieee80211_free_node(data->ni); 944 data->ni = NULL; 945 946 ring->queued--; 947 948 /* faster than % count */ 949 if (++ring->stat >= ring->count) 950 ring->stat = 0; 951 952 if (sc->sc_need_sched) { 953 sc->sc_need_sched = 0; 954 mac_tx_update(ic->ic_mach); 955 } 956 } 957 sc->sc_tx_timer = 0; 958 } 959 960 static void 961 rt2661_rx_intr(struct rt2661_softc *sc) 962 { 963 struct ieee80211com *ic = &sc->sc_ic; 964 struct rt2661_rx_ring *ring; 965 struct rt2661_rx_desc *desc; 966 struct rt2661_rx_data *data; 967 struct ieee80211_frame *wh; 968 struct ieee80211_node *ni; 969 970 mblk_t *m; 971 uint8_t *rxbuf; 972 uint32_t pktlen; 973 974 mutex_enter(&sc->sc_rxlock); 975 ring = &sc->rxq; 976 977 for (;;) { 978 int rssi; 979 980 desc = &ring->desc[ring->cur]; 981 data = &ring->data[ring->cur]; 982 983 (void) ddi_dma_sync(ring->rxdesc_dma.dma_hdl, 984 ring->cur * RT2661_RX_DESC_SIZE, 985 RT2661_RX_DESC_SIZE, 986 DDI_DMA_SYNC_FORKERNEL); 987 988 989 if (LE_32(desc->flags) & RT2661_RX_BUSY) 990 break; 991 992 if ((LE_32(desc->flags) & RT2661_RX_PHY_ERROR) || 993 (LE_32(desc->flags) & RT2661_RX_CRC_ERROR)) { 994 /* 995 * This should not happen since we did not request 996 * to receive those frames when we filled TXRX_CSR0. 997 */ 998 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_rx_intr(): " 999 "PHY or CRC error flags 0x%08x\n", 1000 LE_32(desc->flags)); 1001 sc->sc_rx_err++; 1002 goto skip; 1003 } 1004 1005 if ((LE_32(desc->flags) & RT2661_RX_CIPHER_MASK) != 0) { 1006 sc->sc_rx_err++; 1007 goto skip; 1008 } 1009 1010 (void) ddi_dma_sync(data->rxdata_dma.dma_hdl, 1011 0, sc->sc_dmabuf_size, 1012 DDI_DMA_SYNC_FORCPU); 1013 1014 rxbuf = (uint8_t *)data->rxdata_dma.mem_va; 1015 desc->physaddr = LE_32(data->rxdata_dma.cookie.dmac_address); 1016 pktlen = (LE_32(desc->flags) >> 16) & 0xfff; 1017 if ((pktlen < sizeof (struct ieee80211_frame_min)) || 1018 (pktlen > sc->sc_dmabuf_size)) { 1019 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_rx_intr(): " 1020 "bad fram length=%u\n", pktlen); 1021 sc->sc_rx_err++; 1022 goto skip; 1023 } 1024 1025 if ((m = allocb(pktlen, BPRI_MED)) == NULL) { 1026 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_rx_intr(): " 1027 "allocate mblk failed.\n"); 1028 sc->sc_rx_nobuf++; 1029 goto skip; 1030 } 1031 1032 bcopy(rxbuf, m->b_rptr, pktlen); 1033 m->b_wptr += pktlen; 1034 1035 wh = (struct ieee80211_frame *)m->b_rptr; 1036 ni = ieee80211_find_rxnode(ic, wh); 1037 1038 rssi = rt2661_get_rssi(sc, desc->rssi); 1039 /* send the frame to the 802.11 layer */ 1040 (void) ieee80211_input(ic, m, ni, rssi + 95, 0); 1041 1042 sc->avg_rssi = (rssi + 7 * sc->avg_rssi) / 8; 1043 1044 /* node is no longer needed */ 1045 ieee80211_free_node(ni); 1046 skip: 1047 desc->flags |= LE_32(RT2661_RX_BUSY); 1048 1049 (void) ddi_dma_sync(ring->rxdesc_dma.dma_hdl, 1050 ring->cur * RT2661_RX_DESC_SIZE, 1051 RT2661_RX_DESC_SIZE, 1052 DDI_DMA_SYNC_FORDEV); 1053 1054 RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_rx_intr(): " 1055 "rx intr idx=%u\n", sc->rxq.cur); 1056 ring->cur = (ring->cur + 1) % RT2661_RX_RING_COUNT; 1057 } 1058 mutex_exit(&sc->sc_rxlock); 1059 } 1060 1061 /*ARGSUSED*/ 1062 static uint_t 1063 rt2661_softintr(caddr_t data, caddr_t unused) 1064 { 1065 struct rt2661_softc *sc = (struct rt2661_softc *)data; 1066 1067 if (sc->sc_rx_pend) { 1068 sc->sc_rx_pend = 0; 1069 rt2661_rx_intr(sc); 1070 return (DDI_INTR_CLAIMED); 1071 } 1072 return (DDI_INTR_UNCLAIMED); 1073 } 1074 1075 static int 1076 rt2661_tx_cmd(struct rt2661_softc *sc, uint8_t cmd, uint16_t arg) 1077 { 1078 if (RT2661_READ(sc, RT2661_H2M_MAILBOX_CSR) & RT2661_H2M_BUSY) 1079 return (EIO); /* there is already a command pending */ 1080 1081 RT2661_WRITE(sc, RT2661_H2M_MAILBOX_CSR, 1082 RT2661_H2M_BUSY | RT2661_TOKEN_NO_INTR << 16 | arg); 1083 1084 RT2661_WRITE(sc, RT2661_HOST_CMD_CSR, RT2661_KICK_CMD | cmd); 1085 1086 return (0); 1087 } 1088 1089 static void 1090 rt2661_mcu_wakeup(struct rt2661_softc *sc) 1091 { 1092 RT2661_WRITE(sc, RT2661_MAC_CSR11, 5 << 16); 1093 1094 RT2661_WRITE(sc, RT2661_SOFT_RESET_CSR, 0x7); 1095 RT2661_WRITE(sc, RT2661_IO_CNTL_CSR, 0x18); 1096 RT2661_WRITE(sc, RT2661_PCI_USEC_CSR, 0x20); 1097 1098 /* send wakeup command to MCU */ 1099 (void) rt2661_tx_cmd(sc, RT2661_MCU_CMD_WAKEUP, 0); 1100 } 1101 1102 static void 1103 rt2661_mcu_cmd_intr(struct rt2661_softc *sc) 1104 { 1105 (void) RT2661_READ(sc, RT2661_M2H_CMD_DONE_CSR); 1106 RT2661_WRITE(sc, RT2661_M2H_CMD_DONE_CSR, 0xffffffff); 1107 } 1108 1109 /*ARGSUSED*/ 1110 static uint_t 1111 rt2661_intr(caddr_t arg, caddr_t unused) 1112 { 1113 struct rt2661_softc *sc = (struct rt2661_softc *)arg; 1114 uint32_t r1, r2; 1115 1116 RT2661_GLOCK(sc); 1117 1118 if (!RT2661_IS_RUNNING(sc) || RT2661_IS_SUSPEND(sc)) { 1119 RT2661_GUNLOCK(sc); 1120 return (DDI_INTR_UNCLAIMED); 1121 } 1122 1123 r1 = RT2661_READ(sc, RT2661_INT_SOURCE_CSR); 1124 r2 = RT2661_READ(sc, RT2661_MCU_INT_SOURCE_CSR); 1125 if (r1 == 0 && r2 == 0) { 1126 RT2661_GUNLOCK(sc); 1127 return (DDI_INTR_UNCLAIMED); /* not for us */ 1128 } 1129 1130 /* disable MAC and MCU interrupts */ 1131 RT2661_WRITE(sc, RT2661_INT_MASK_CSR, 0xffffff7f); 1132 RT2661_WRITE(sc, RT2661_MCU_INT_MASK_CSR, 0xffffffff); 1133 1134 /* acknowledge interrupts */ 1135 RT2661_WRITE(sc, RT2661_INT_SOURCE_CSR, r1); 1136 RT2661_WRITE(sc, RT2661_MCU_INT_SOURCE_CSR, r2); 1137 1138 if (r1 & RT2661_MGT_DONE) { 1139 RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_intr(): " 1140 "RT2661_MGT_DONE\n"); 1141 rt2661_tx_dma_intr(sc, &sc->mgtq); 1142 } 1143 1144 if (r1 & RT2661_RX_DONE) { 1145 RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_intr(): " 1146 "RT2661_RX_DONE\n"); 1147 sc->sc_rx_pend = 1; 1148 (void) ddi_intr_trigger_softint(sc->sc_softintr_hdl, NULL); 1149 } 1150 1151 if (r1 & RT2661_TX0_DMA_DONE) { 1152 RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_intr(): " 1153 "RT2661_TX0_DMA_DONE\n"); 1154 rt2661_tx_dma_intr(sc, &sc->txq[0]); 1155 } 1156 1157 if (r1 & RT2661_TX1_DMA_DONE) { 1158 RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_intr(): " 1159 "RT2661_TX1_DMA_DONE\n"); 1160 rt2661_tx_dma_intr(sc, &sc->txq[1]); 1161 } 1162 1163 if (r1 & RT2661_TX2_DMA_DONE) { 1164 RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_intr(): " 1165 "RT2661_TX2_DMA_DONE\n"); 1166 rt2661_tx_dma_intr(sc, &sc->txq[2]); 1167 } 1168 1169 if (r1 & RT2661_TX3_DMA_DONE) { 1170 RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_intr(): " 1171 "RT2661_TX3_DMA_DONE\n"); 1172 rt2661_tx_dma_intr(sc, &sc->txq[3]); 1173 } 1174 1175 if (r1 & RT2661_TX_DONE) { 1176 RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_intr(): " 1177 "RT2661_TX_DONE\n"); 1178 rt2661_tx_intr(sc); 1179 } 1180 1181 if (r2 & RT2661_MCU_CMD_DONE) { 1182 RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_intr(): " 1183 "RT2661_MCU_CMD_DONE\n"); 1184 rt2661_mcu_cmd_intr(sc); 1185 } 1186 1187 if (r2 & RT2661_MCU_WAKEUP) { 1188 RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_intr(): " 1189 "RT2661_MCU_WAKEUP\n"); 1190 rt2661_mcu_wakeup(sc); 1191 } 1192 1193 /* re-enable MAC and MCU interrupts */ 1194 RT2661_WRITE(sc, RT2661_INT_MASK_CSR, 0x0000ff10); 1195 RT2661_WRITE(sc, RT2661_MCU_INT_MASK_CSR, 0); 1196 1197 RT2661_GUNLOCK(sc); 1198 return (RT2661_SUCCESS); 1199 } 1200 1201 /* 1202 * Retrieve the "Received Signal Strength Indicator" from the raw values 1203 * contained in Rx descriptors. The computation depends on which band the 1204 * frame was received. Correction values taken from the reference driver. 1205 */ 1206 static int 1207 rt2661_get_rssi(struct rt2661_softc *sc, uint8_t raw) 1208 { 1209 int lna, agc, rssi; 1210 1211 lna = (raw >> 5) & 0x3; 1212 agc = raw & 0x1f; 1213 1214 rssi = 2 * agc; 1215 1216 if (IEEE80211_IS_CHAN_2GHZ(sc->sc_curchan)) { 1217 rssi += sc->rssi_2ghz_corr; 1218 1219 if (lna == 1) 1220 rssi -= 64; 1221 else if (lna == 2) 1222 rssi -= 74; 1223 else if (lna == 3) 1224 rssi -= 90; 1225 } else { 1226 rssi += sc->rssi_5ghz_corr; 1227 1228 if (lna == 1) 1229 rssi -= 64; 1230 else if (lna == 2) 1231 rssi -= 86; 1232 else if (lna == 3) 1233 rssi -= 100; 1234 } 1235 return (rssi); 1236 } 1237 1238 /* quickly determine if a given rate is CCK or OFDM */ 1239 #define RT2661_RATE_IS_OFDM(rate) ((rate) >= 12 && (rate) != 22) 1240 1241 #define RT2661_ACK_SIZE 14 /* 10 + 4(FCS) */ 1242 #define RT2661_CTS_SIZE 14 /* 10 + 4(FCS) */ 1243 1244 #define RT2661_SIFS 10 /* us */ 1245 1246 /* 1247 * Return the expected ack rate for a frame transmitted at rate `rate'. 1248 * XXX: this should depend on the destination node basic rate set. 1249 */ 1250 static int 1251 rt2661_ack_rate(struct ieee80211com *ic, int rate) 1252 { 1253 switch (rate) { 1254 /* CCK rates */ 1255 case 2: 1256 return (2); 1257 case 4: 1258 case 11: 1259 case 22: 1260 return ((ic->ic_curmode == IEEE80211_MODE_11B) ? 4 : rate); 1261 1262 /* OFDM rates */ 1263 case 12: 1264 case 18: 1265 return (12); 1266 case 24: 1267 case 36: 1268 return (24); 1269 case 48: 1270 case 72: 1271 case 96: 1272 case 108: 1273 return (48); 1274 } 1275 1276 /* default to 1Mbps */ 1277 return (2); 1278 } 1279 1280 /* 1281 * Compute the duration (in us) needed to transmit `len' bytes at rate `rate'. 1282 * The function automatically determines the operating mode depending on the 1283 * given rate. `flags' indicates whether short preamble is in use or not. 1284 */ 1285 static uint16_t 1286 rt2661_txtime(int len, int rate, uint32_t flags) 1287 { 1288 uint16_t txtime; 1289 1290 if (RT2661_RATE_IS_OFDM(rate)) { 1291 /* IEEE Std 802.11a-1999, pp. 37 */ 1292 txtime = (8 + 4 * len + 3 + rate - 1) / rate; 1293 txtime = 16 + 4 + 4 * txtime + 6; 1294 } else { 1295 /* IEEE Std 802.11b-1999, pp. 28 */ 1296 txtime = (16 * len + rate - 1) / rate; 1297 if (rate != 2 && (flags & IEEE80211_F_SHPREAMBLE)) 1298 txtime += 72 + 24; 1299 else 1300 txtime += 144 + 48; 1301 } 1302 1303 return (txtime); 1304 } 1305 1306 static uint8_t 1307 rt2661_plcp_signal(int rate) 1308 { 1309 switch (rate) { 1310 /* CCK rates (returned values are device-dependent) */ 1311 case 2: 1312 return (0x0); 1313 case 4: 1314 return (0x1); 1315 case 11: 1316 return (0x2); 1317 case 22: 1318 return (0x3); 1319 1320 /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ 1321 case 12: 1322 return (0xb); 1323 case 18: 1324 return (0xf); 1325 case 24: 1326 return (0xa); 1327 case 36: 1328 return (0xe); 1329 case 48: 1330 return (0x9); 1331 case 72: 1332 return (0xd); 1333 case 96: 1334 return (0x8); 1335 case 108: 1336 return (0xc); 1337 1338 /* unsupported rates (should not get there) */ 1339 default: 1340 return (0xff); 1341 } 1342 } 1343 1344 static void 1345 rt2661_setup_tx_desc(struct rt2661_softc *sc, struct rt2661_tx_desc *desc, 1346 uint32_t flags, uint16_t xflags, int len, int rate, int ac) 1347 { 1348 struct ieee80211com *ic = &sc->sc_ic; 1349 uint16_t plcp_length; 1350 int remainder; 1351 1352 desc->flags = LE_32(flags); 1353 desc->flags |= LE_32(len << 16); 1354 desc->flags |= LE_32(RT2661_TX_BUSY | RT2661_TX_VALID); 1355 1356 desc->xflags = LE_16(xflags); 1357 desc->xflags |= LE_16(1 << 13); 1358 1359 desc->wme = LE_16( 1360 RT2661_QID(ac) | 1361 RT2661_AIFSN(2) | 1362 RT2661_LOGCWMIN(4) | 1363 RT2661_LOGCWMAX(10)); 1364 1365 /* 1366 * Remember in which queue this frame was sent. This field is driver 1367 * private data only. It will be made available by the NIC in STA_CSR4 1368 * on Tx interrupts. 1369 */ 1370 desc->qid = (uint8_t)ac; 1371 1372 /* setup PLCP fields */ 1373 desc->plcp_signal = rt2661_plcp_signal(rate); 1374 desc->plcp_service = 4; 1375 1376 len += IEEE80211_CRC_LEN; 1377 1378 if (RT2661_RATE_IS_OFDM(rate)) { 1379 desc->flags |= LE_32(RT2661_TX_OFDM); 1380 1381 plcp_length = len & 0xfff; 1382 desc->plcp_length_hi = plcp_length >> 6; 1383 desc->plcp_length_lo = plcp_length & 0x3f; 1384 } else { 1385 plcp_length = (16 * len + rate - 1) / rate; 1386 if (rate == 22) { 1387 remainder = (16 * len) % 22; 1388 if (remainder != 0 && remainder < 7) 1389 desc->plcp_service |= RT2661_PLCP_LENGEXT; 1390 } 1391 desc->plcp_length_hi = plcp_length >> 8; 1392 desc->plcp_length_lo = plcp_length & 0xff; 1393 1394 if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE)) 1395 desc->plcp_signal |= 0x08; 1396 } 1397 1398 /* RT2x61 supports scatter with up to 5 segments */ 1399 desc->len [0] = LE_16(len); 1400 } 1401 1402 static int 1403 rt2661_send(ieee80211com_t *ic, mblk_t *mp) 1404 { 1405 struct rt2661_softc *sc = (struct rt2661_softc *)ic; 1406 struct rt2661_tx_ring *ring; 1407 struct rt2661_tx_desc *desc; 1408 struct rt2661_tx_data *data; 1409 struct ieee80211_frame *wh; 1410 struct ieee80211_node *ni; 1411 1412 int err, off, rate; 1413 int mblen, pktlen; 1414 mblk_t *m, *m0; 1415 uint16_t dur; 1416 uint32_t flags = 0; 1417 1418 mutex_enter(&sc->sc_txlock); 1419 ring = &sc->txq[0]; 1420 err = DDI_SUCCESS; 1421 1422 if (ring->queued > RT2661_TX_RING_COUNT - 8) { 1423 sc->sc_need_sched = 1; 1424 sc->sc_tx_nobuf++; 1425 err = ENOMEM; 1426 goto fail1; 1427 } 1428 1429 m = allocb(msgdsize(mp) + 32, BPRI_MED); 1430 if (m == NULL) { 1431 RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_send():" 1432 "can't alloc mblk.\n"); 1433 err = DDI_FAILURE; 1434 goto fail1; 1435 } 1436 1437 for (off = 0, m0 = mp; m0 != NULL; m0 = m0->b_cont) { 1438 mblen = MBLKL(m0); 1439 (void) bcopy(m0->b_rptr, m->b_rptr + off, mblen); 1440 off += mblen; 1441 } 1442 m->b_wptr += off; 1443 1444 wh = (struct ieee80211_frame *)m->b_rptr; 1445 ni = ieee80211_find_txnode(ic, wh->i_addr1); 1446 if (ni == NULL) { 1447 err = DDI_FAILURE; 1448 sc->sc_tx_err++; 1449 goto fail2; 1450 } 1451 1452 (void) ieee80211_encap(ic, m, ni); 1453 1454 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 1455 struct ieee80211_key *k; 1456 k = ieee80211_crypto_encap(ic, m); 1457 if (k == NULL) { 1458 sc->sc_tx_err++; 1459 err = DDI_FAILURE; 1460 goto fail3; 1461 } 1462 /* packet header may have moved, reset our local pointer */ 1463 wh = (struct ieee80211_frame *)m->b_rptr; 1464 } 1465 1466 pktlen = msgdsize(m); 1467 1468 desc = &ring->desc[ring->cur]; 1469 data = &ring->data[ring->cur]; 1470 data->ni = ieee80211_ref_node(ni); 1471 1472 /* pickup a rate */ 1473 if (IEEE80211_IS_MULTICAST(wh->i_addr1)) { 1474 /* multicast frames are sent at the lowest avail. rate */ 1475 rate = ni->in_rates.ir_rates[0]; 1476 } else if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE) { 1477 rate = ic->ic_sup_rates[ic->ic_curmode]. 1478 ir_rates[ic->ic_fixed_rate]; 1479 } else 1480 rate = ni->in_rates.ir_rates[ni->in_txrate]; 1481 if (rate == 0) 1482 rate = 2; /* XXX should not happen */ 1483 rate &= IEEE80211_RATE_VAL; 1484 1485 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { 1486 flags |= RT2661_TX_NEED_ACK; 1487 1488 dur = rt2661_txtime(RT2661_ACK_SIZE, 1489 rt2661_ack_rate(ic, rate), ic->ic_flags) + sc->sifs; 1490 *(uint16_t *)wh->i_dur = LE_16(dur); 1491 } 1492 1493 bcopy(m->b_rptr, data->buf, pktlen); 1494 rt2661_setup_tx_desc(sc, desc, flags, 0, pktlen, rate, 0); 1495 1496 (void) ddi_dma_sync(data->txdata_dma.dma_hdl, 1497 0, pktlen, 1498 DDI_DMA_SYNC_FORDEV); 1499 1500 (void) ddi_dma_sync(ring->txdesc_dma.dma_hdl, 1501 ring->cur * RT2661_TX_DESC_SIZE, 1502 RT2661_TX_DESC_SIZE, 1503 DDI_DMA_SYNC_FORDEV); 1504 1505 RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_send(): " 1506 "sending data frame len=%u idx=%u rate=%u\n", 1507 pktlen, ring->cur, rate); 1508 1509 /* kick Tx */ 1510 ring->queued++; 1511 ring->cur = (ring->cur + 1) % RT2661_TX_RING_COUNT; 1512 RT2661_WRITE(sc, RT2661_TX_CNTL_CSR, 1 << 0); 1513 1514 ic->ic_stats.is_tx_frags++; 1515 ic->ic_stats.is_tx_bytes += pktlen; 1516 fail3: 1517 ieee80211_free_node(ni); 1518 fail2: 1519 freemsg(m); 1520 fail1: 1521 if (err == DDI_SUCCESS) 1522 freemsg(mp); 1523 mutex_exit(&sc->sc_txlock); 1524 return (err); 1525 } 1526 1527 /*ARGSUSED*/ 1528 static int 1529 rt2661_mgmt_send(ieee80211com_t *ic, mblk_t *mp, uint8_t type) 1530 { 1531 struct rt2661_softc *sc = (struct rt2661_softc *)ic; 1532 struct rt2661_tx_ring *ring; 1533 struct rt2661_tx_desc *desc; 1534 struct rt2661_tx_data *data; 1535 struct ieee80211_frame *wh; 1536 struct ieee80211_node *ni; 1537 1538 int err, off, rate; 1539 int mblen, pktlen; 1540 mblk_t *m, *m0; 1541 uint16_t dur; 1542 uint32_t flags = 0; 1543 1544 if ((!RT2661_IS_RUNNING(sc)) || RT2661_IS_SUSPEND(sc)) { 1545 err = ENXIO; 1546 goto fail1; 1547 } 1548 1549 ring = &sc->mgtq; 1550 err = DDI_SUCCESS; 1551 1552 if (ring->queued >= RT2661_MGT_RING_COUNT) { 1553 sc->sc_tx_nobuf++; 1554 err = ENOMEM; 1555 goto fail1; 1556 } 1557 1558 m = allocb(msgdsize(mp) + 32, BPRI_MED); 1559 if (m == NULL) { 1560 RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_mgmt_send():" 1561 "can't alloc mblk.\n"); 1562 err = DDI_FAILURE; 1563 goto fail1; 1564 } 1565 1566 for (off = 0, m0 = mp; m0 != NULL; m0 = m0->b_cont) { 1567 mblen = MBLKL(m0); 1568 (void) bcopy(m0->b_rptr, m->b_rptr + off, mblen); 1569 off += mblen; 1570 } 1571 m->b_wptr += off; 1572 1573 wh = (struct ieee80211_frame *)m->b_rptr; 1574 ni = ieee80211_find_txnode(ic, wh->i_addr1); 1575 if (ni == NULL) { 1576 err = DDI_FAILURE; 1577 sc->sc_tx_err++; 1578 goto fail2; 1579 } 1580 1581 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 1582 struct ieee80211_key *k; 1583 k = ieee80211_crypto_encap(ic, m); 1584 if (k == NULL) { 1585 sc->sc_tx_err++; 1586 err = DDI_FAILURE; 1587 goto fail3; 1588 } 1589 /* packet header may have moved, reset our local pointer */ 1590 wh = (struct ieee80211_frame *)m->b_rptr; 1591 } 1592 1593 pktlen = msgdsize(m); 1594 1595 desc = &ring->desc[ring->cur]; 1596 data = &ring->data[ring->cur]; 1597 data->ni = ieee80211_ref_node(ni); 1598 1599 /* send mgt frames at the lowest available rate */ 1600 rate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 2; 1601 1602 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { 1603 flags |= RT2661_TX_NEED_ACK; 1604 1605 dur = rt2661_txtime(RT2661_ACK_SIZE, 1606 rate, ic->ic_flags) + sc->sifs; 1607 *(uint16_t *)wh->i_dur = LE_16(dur); 1608 1609 /* tell hardware to add timestamp in probe responses */ 1610 if ((wh->i_fc[0] & 1611 (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == 1612 (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP)) 1613 flags |= RT2661_TX_TIMESTAMP; 1614 } 1615 1616 bcopy(m->b_rptr, data->buf, pktlen); 1617 rt2661_setup_tx_desc(sc, desc, flags, 0, pktlen, rate, RT2661_QID_MGT); 1618 1619 (void) ddi_dma_sync(data->txdata_dma.dma_hdl, 1620 0, pktlen, 1621 DDI_DMA_SYNC_FORDEV); 1622 1623 (void) ddi_dma_sync(ring->txdesc_dma.dma_hdl, 1624 ring->cur * RT2661_TX_DESC_SIZE, 1625 RT2661_TX_DESC_SIZE, 1626 DDI_DMA_SYNC_FORDEV); 1627 1628 RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_mgmt_send(): " 1629 "sending mgmt frame len=%u idx=%u rate=%u\n", 1630 pktlen, ring->cur, rate); 1631 1632 /* kick Tx */ 1633 ring->queued++; 1634 ring->cur = (ring->cur + 1) % RT2661_MGT_RING_COUNT; 1635 RT2661_WRITE(sc, RT2661_TX_CNTL_CSR, RT2661_KICK_MGT); 1636 1637 ic->ic_stats.is_tx_frags++; 1638 ic->ic_stats.is_tx_bytes += pktlen; 1639 1640 fail3: 1641 ieee80211_free_node(ni); 1642 fail2: 1643 freemsg(m); 1644 fail1: 1645 freemsg(mp); 1646 return (err); 1647 } 1648 1649 static void 1650 rt2661_amrr_node_init(const struct rt2661_amrr *amrr, 1651 struct rt2661_amrr_node *amn) 1652 { 1653 amn->amn_success = 0; 1654 amn->amn_recovery = 0; 1655 amn->amn_txcnt = amn->amn_retrycnt = 0; 1656 amn->amn_success_threshold = amrr->amrr_min_success_threshold; 1657 } 1658 1659 static void 1660 rt2661_amrr_choose(struct rt2661_amrr *amrr, struct ieee80211_node *ni, 1661 struct rt2661_amrr_node *amn) 1662 { 1663 #define RV(rate) ((rate) & IEEE80211_RATE_VAL) 1664 #define is_success(amn) \ 1665 ((amn)->amn_retrycnt < (amn)->amn_txcnt / 10) 1666 #define is_failure(amn) \ 1667 ((amn)->amn_retrycnt > (amn)->amn_txcnt / 3) 1668 #define is_enough(amn) \ 1669 ((amn)->amn_txcnt > 10) 1670 #define is_min_rate(ni) \ 1671 ((ni)->in_txrate == 0) 1672 #define is_max_rate(ni) \ 1673 ((ni)->in_txrate == (ni)->in_rates.ir_nrates - 1) 1674 #define increase_rate(ni) \ 1675 ((ni)->in_txrate++) 1676 #define decrease_rate(ni) \ 1677 ((ni)->in_txrate--) 1678 #define reset_cnt(amn) \ 1679 { (amn)->amn_txcnt = (amn)->amn_retrycnt = 0; } 1680 1681 int need_change = 0; 1682 1683 if (is_success(amn) && is_enough(amn)) { 1684 amn->amn_success++; 1685 if (amn->amn_success >= amn->amn_success_threshold && 1686 !is_max_rate(ni)) { 1687 amn->amn_recovery = 1; 1688 amn->amn_success = 0; 1689 increase_rate(ni); 1690 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_amrr_choose(): " 1691 "increase rate = %d, #tx = %d, #retries = %d\n", 1692 RV(ni->in_rates.ir_rates[ni->in_txrate]), 1693 amn->amn_txcnt, amn->amn_retrycnt); 1694 need_change = 1; 1695 } else 1696 amn->amn_recovery = 0; 1697 } else if (is_failure(amn)) { 1698 amn->amn_success = 0; 1699 if (!is_min_rate(ni)) { 1700 if (amn->amn_recovery) { 1701 amn->amn_success_threshold *= 2; 1702 if (amn->amn_success_threshold > 1703 amrr->amrr_max_success_threshold) 1704 amn->amn_success_threshold = 1705 amrr->amrr_max_success_threshold; 1706 } else { 1707 amn->amn_success_threshold = 1708 amrr->amrr_min_success_threshold; 1709 } 1710 decrease_rate(ni); 1711 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_amrr_choose(): " 1712 "decrease rate = %d, #tx = %d, #retries = %d\n", 1713 RV(ni->in_rates.ir_rates[ni->in_txrate]), 1714 amn->amn_txcnt, amn->amn_retrycnt); 1715 need_change = 1; 1716 } 1717 amn->amn_recovery = 0; 1718 } 1719 1720 if (is_enough(amn) || need_change) 1721 reset_cnt(amn); 1722 #undef RV 1723 1724 } 1725 1726 static void 1727 rt2661_update_promisc(struct rt2661_softc *sc) 1728 { 1729 uint32_t tmp; 1730 1731 tmp = RT2661_READ(sc, RT2661_TXRX_CSR0); 1732 1733 tmp &= ~RT2661_DROP_NOT_TO_ME; 1734 if (!(sc->sc_rcr & RT2661_RCR_PROMISC)) 1735 tmp |= RT2661_DROP_NOT_TO_ME; 1736 1737 RT2661_WRITE(sc, RT2661_TXRX_CSR0, tmp); 1738 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_update_promisc(): " 1739 "%s promiscuous mode\n", 1740 (sc->sc_rcr & RT2661_RCR_PROMISC) ? "entering" : "leaving"); 1741 } 1742 1743 static void 1744 rt2661_updateslot(struct ieee80211com *ic, int onoff) 1745 { 1746 struct rt2661_softc *sc = (struct rt2661_softc *)ic; 1747 uint8_t slottime; 1748 uint32_t tmp; 1749 1750 slottime = (onoff ? 9 : 20); 1751 1752 tmp = RT2661_READ(sc, RT2661_MAC_CSR9); 1753 tmp = (tmp & ~0xff) | slottime; 1754 RT2661_WRITE(sc, RT2661_MAC_CSR9, tmp); 1755 1756 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_updateslot(): " 1757 "setting slot time to %uus\n", slottime); 1758 } 1759 1760 static void 1761 rt2661_set_slottime(struct rt2661_softc *sc) 1762 { 1763 struct ieee80211com *ic = &sc->sc_ic; 1764 uint8_t slottime; 1765 uint32_t tmp; 1766 1767 slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20; 1768 1769 tmp = RT2661_READ(sc, RT2661_MAC_CSR9); 1770 tmp = (tmp & ~0xff) | slottime; 1771 RT2661_WRITE(sc, RT2661_MAC_CSR9, tmp); 1772 1773 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_set_slottime(): " 1774 "setting slot time to %uus\n", slottime); 1775 } 1776 1777 1778 /* 1779 * Enable multi-rate retries for frames sent at OFDM rates. 1780 * In 802.11b/g mode, allow fallback to CCK rates. 1781 */ 1782 static void 1783 rt2661_enable_mrr(struct rt2661_softc *sc) 1784 { 1785 struct ieee80211com *ic = &sc->sc_ic; 1786 uint32_t tmp; 1787 1788 tmp = RT2661_READ(sc, RT2661_TXRX_CSR4); 1789 1790 tmp &= ~RT2661_MRR_CCK_FALLBACK; 1791 if (!IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) 1792 tmp |= RT2661_MRR_CCK_FALLBACK; 1793 tmp |= RT2661_MRR_ENABLED; 1794 1795 RT2661_WRITE(sc, RT2661_TXRX_CSR4, tmp); 1796 } 1797 1798 static void 1799 rt2661_set_txpreamble(struct rt2661_softc *sc) 1800 { 1801 uint32_t tmp; 1802 1803 tmp = RT2661_READ(sc, RT2661_TXRX_CSR4); 1804 1805 tmp &= ~RT2661_SHORT_PREAMBLE; 1806 if (sc->sc_ic.ic_flags & IEEE80211_F_SHPREAMBLE) 1807 tmp |= RT2661_SHORT_PREAMBLE; 1808 1809 RT2661_WRITE(sc, RT2661_TXRX_CSR4, tmp); 1810 } 1811 1812 static void 1813 rt2661_set_basicrates(struct rt2661_softc *sc) 1814 { 1815 struct ieee80211com *ic = &sc->sc_ic; 1816 1817 /* update basic rate set */ 1818 if (ic->ic_curmode == IEEE80211_MODE_11B) { 1819 /* 11b basic rates: 1, 2Mbps */ 1820 RT2661_WRITE(sc, RT2661_TXRX_CSR5, 0x3); 1821 } else if (ic->ic_curmode == IEEE80211_MODE_11A) { 1822 /* 11a basic rates: 6, 12, 24Mbps */ 1823 RT2661_WRITE(sc, RT2661_TXRX_CSR5, 0x150); 1824 } else { 1825 /* 11b/g basic rates: 1, 2, 5.5, 11Mbps */ 1826 RT2661_WRITE(sc, RT2661_TXRX_CSR5, 0xf); 1827 } 1828 } 1829 1830 static void 1831 rt2661_set_bssid(struct rt2661_softc *sc, const uint8_t *bssid) 1832 { 1833 uint32_t tmp; 1834 1835 tmp = bssid[0] | bssid[1] << 8 | bssid[2] << 16 | bssid[3] << 24; 1836 RT2661_WRITE(sc, RT2661_MAC_CSR4, tmp); 1837 1838 tmp = bssid[4] | bssid[5] << 8 | RT2661_ONE_BSSID << 16; 1839 RT2661_WRITE(sc, RT2661_MAC_CSR5, tmp); 1840 } 1841 1842 /* 1843 * Enable TSF synchronization and tell h/w to start sending beacons for IBSS 1844 * and HostAP operating modes. 1845 */ 1846 static void 1847 rt2661_enable_tsf_sync(struct rt2661_softc *sc) 1848 { 1849 struct ieee80211com *ic = &sc->sc_ic; 1850 uint32_t tmp; 1851 1852 tmp = RT2661_READ(sc, RT2661_TXRX_CSR9) & 0xff000000; 1853 1854 /* set beacon interval (in 1/16ms unit) */ 1855 tmp |= ic->ic_bss->in_intval * 16; 1856 1857 tmp |= RT2661_TSF_TICKING | RT2661_ENABLE_TBTT; 1858 if (ic->ic_opmode == IEEE80211_M_STA) 1859 tmp |= RT2661_TSF_MODE(1); 1860 1861 RT2661_WRITE(sc, RT2661_TXRX_CSR9, tmp); 1862 } 1863 1864 1865 static void 1866 rt2661_next_scan(void *arg) 1867 { 1868 struct rt2661_softc *sc = arg; 1869 struct ieee80211com *ic = &sc->sc_ic; 1870 1871 if (ic->ic_state == IEEE80211_S_SCAN) 1872 (void) ieee80211_next_scan(ic); 1873 } 1874 1875 static void 1876 rt2661_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni) 1877 { 1878 struct rt2661_softc *sc = (struct rt2661_softc *)ic; 1879 int i; 1880 1881 rt2661_amrr_node_init(&sc->amrr, &((struct rt2661_node *)ni)->amn); 1882 1883 /* set rate to some reasonable initial value */ 1884 i = ni->in_rates.ir_nrates - 1; 1885 while (i > 0 && ((ni->in_rates.ir_rates[i] & IEEE80211_RATE_VAL) > 72)) 1886 i--; 1887 1888 ni->in_txrate = i; 1889 } 1890 1891 static void 1892 rt2661_iter_func(void *arg, struct ieee80211_node *ni) 1893 { 1894 struct rt2661_softc *sc = arg; 1895 struct rt2661_node *rn = (struct rt2661_node *)ni; 1896 1897 rt2661_amrr_choose(&sc->amrr, ni, &rn->amn); 1898 1899 } 1900 1901 /* 1902 * Dynamically tune Rx sensitivity (BBP register 17) based on average RSSI and 1903 * false CCA count. This function is called periodically (every seconds) when 1904 * in the RUN state. Values taken from the reference driver. 1905 */ 1906 static void 1907 rt2661_rx_tune(struct rt2661_softc *sc) 1908 { 1909 uint8_t bbp17; 1910 uint16_t cca; 1911 int lo, hi, dbm; 1912 1913 /* 1914 * Tuning range depends on operating band and on the presence of an 1915 * external low-noise amplifier. 1916 */ 1917 lo = 0x20; 1918 if (IEEE80211_IS_CHAN_5GHZ(sc->sc_curchan)) 1919 lo += 0x08; 1920 if ((IEEE80211_IS_CHAN_2GHZ(sc->sc_curchan) && sc->ext_2ghz_lna) || 1921 (IEEE80211_IS_CHAN_5GHZ(sc->sc_curchan) && sc->ext_5ghz_lna)) 1922 lo += 0x10; 1923 hi = lo + 0x20; 1924 1925 dbm = sc->avg_rssi; 1926 /* retrieve false CCA count since last call (clear on read) */ 1927 cca = RT2661_READ(sc, RT2661_STA_CSR1) & 0xffff; 1928 1929 RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_rx_tune(): " 1930 "RSSI=%ddBm false CCA=%d\n", dbm, cca); 1931 1932 if (dbm < -74) { 1933 /* very bad RSSI, tune using false CCA count */ 1934 bbp17 = sc->bbp17; /* current value */ 1935 1936 hi -= 2 * (-74 - dbm); 1937 if (hi < lo) 1938 hi = lo; 1939 1940 if (bbp17 > hi) 1941 bbp17 = (uint8_t)hi; 1942 else if (cca > 512) 1943 bbp17 = (uint8_t)min(bbp17 + 1, hi); 1944 else if (cca < 100) 1945 bbp17 = (uint8_t)max(bbp17 - 1, lo); 1946 1947 } else if (dbm < -66) { 1948 bbp17 = lo + 0x08; 1949 } else if (dbm < -58) { 1950 bbp17 = lo + 0x10; 1951 } else if (dbm < -35) { 1952 bbp17 = (uint8_t)hi; 1953 } else { /* very good RSSI >= -35dBm */ 1954 bbp17 = 0x60; /* very low sensitivity */ 1955 } 1956 1957 if (bbp17 != sc->bbp17) { 1958 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_rx_tune(): " 1959 "BBP17 %x->%x\n", sc->bbp17, bbp17); 1960 rt2661_bbp_write(sc, 17, bbp17); 1961 sc->bbp17 = bbp17; 1962 } 1963 } 1964 1965 /* 1966 * This function is called periodically (every 500ms) in RUN state to update 1967 * various settings like rate control statistics or Rx sensitivity. 1968 */ 1969 static void 1970 rt2661_updatestats(void *arg) 1971 { 1972 struct rt2661_softc *sc = arg; 1973 struct ieee80211com *ic = &sc->sc_ic; 1974 1975 if (ic->ic_opmode == IEEE80211_M_STA) 1976 rt2661_iter_func(sc, ic->ic_bss); 1977 else 1978 ieee80211_iterate_nodes(&ic->ic_sta, rt2661_iter_func, arg); 1979 1980 /* update rx sensitivity every 1 sec */ 1981 if (++sc->ncalls & 1) 1982 rt2661_rx_tune(sc); 1983 1984 sc->sc_rssadapt_id = timeout(rt2661_updatestats, (void *)sc, 1985 drv_usectohz(200 * 1000)); 1986 } 1987 1988 static int 1989 rt2661_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) 1990 { 1991 struct rt2661_softc *sc = (struct rt2661_softc *)ic; 1992 enum ieee80211_state ostate; 1993 struct ieee80211_node *ni; 1994 uint32_t tmp; 1995 int err; 1996 1997 RT2661_GLOCK(sc); 1998 1999 ostate = ic->ic_state; 2000 sc->sc_ostate = ostate; 2001 2002 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt26661_newstate(): " 2003 "%x -> %x\n", ostate, nstate); 2004 2005 if (sc->sc_scan_id != 0) { 2006 (void) untimeout(sc->sc_scan_id); 2007 sc->sc_scan_id = 0; 2008 } 2009 2010 if (sc->sc_rssadapt_id) { 2011 (void) untimeout(sc->sc_rssadapt_id); 2012 sc->sc_rssadapt_id = 0; 2013 } 2014 2015 switch (nstate) { 2016 case IEEE80211_S_INIT: 2017 if (ostate == IEEE80211_S_RUN) { 2018 /* abort TSF synchronization */ 2019 tmp = RT2661_READ(sc, RT2661_TXRX_CSR9); 2020 RT2661_WRITE(sc, RT2661_TXRX_CSR9, tmp & ~0x00ffffff); 2021 } 2022 break; 2023 case IEEE80211_S_SCAN: 2024 rt2661_set_chan(sc, ic->ic_curchan); 2025 sc->sc_scan_id = timeout(rt2661_next_scan, (void *)sc, 2026 drv_usectohz(200000)); 2027 break; 2028 case IEEE80211_S_AUTH: 2029 case IEEE80211_S_ASSOC: 2030 rt2661_set_chan(sc, ic->ic_curchan); 2031 break; 2032 case IEEE80211_S_RUN: 2033 rt2661_set_chan(sc, ic->ic_curchan); 2034 2035 ni = ic->ic_bss; 2036 if (ic->ic_opmode != IEEE80211_M_MONITOR) { 2037 rt2661_set_slottime(sc); 2038 rt2661_enable_mrr(sc); 2039 rt2661_set_txpreamble(sc); 2040 rt2661_set_basicrates(sc); 2041 rt2661_set_bssid(sc, ni->in_bssid); 2042 } 2043 2044 if (ic->ic_opmode == IEEE80211_M_STA) { 2045 /* fake a join to init the tx rate */ 2046 rt2661_newassoc(ic, ni); 2047 } 2048 2049 if (ic->ic_opmode != IEEE80211_M_MONITOR) { 2050 sc->ncalls = 0; 2051 sc->avg_rssi = -95; /* reset EMA */ 2052 sc->sc_rssadapt_id = timeout(rt2661_updatestats, 2053 (void *)sc, drv_usectohz(200 * 1000)); 2054 rt2661_enable_tsf_sync(sc); 2055 } 2056 break; 2057 default: 2058 break; 2059 } 2060 2061 RT2661_GUNLOCK(sc); 2062 2063 err = sc->sc_newstate(ic, nstate, arg); 2064 return (err); 2065 } 2066 2067 /*ARGSUSED*/ 2068 static struct ieee80211_node * 2069 rt2661_node_alloc(ieee80211com_t *ic) 2070 { 2071 struct rt2661_node *rn; 2072 2073 rn = kmem_zalloc(sizeof (struct rt2661_node), KM_SLEEP); 2074 return ((rn != NULL) ? &rn->ni : NULL); 2075 } 2076 2077 static void 2078 rt2661_node_free(struct ieee80211_node *in) 2079 { 2080 struct ieee80211com *ic = in->in_ic; 2081 2082 ic->ic_node_cleanup(in); 2083 if (in->in_wpa_ie != NULL) 2084 ieee80211_free(in->in_wpa_ie); 2085 kmem_free(in, sizeof (struct rt2661_node)); 2086 } 2087 2088 static void 2089 rt2661_stop_locked(struct rt2661_softc *sc) 2090 { 2091 uint32_t tmp; 2092 2093 if (RT2661_IS_RUNNING(sc)) { 2094 sc->sc_tx_timer = 0; 2095 2096 /* abort Tx (for all 5 Tx rings) */ 2097 RT2661_WRITE(sc, RT2661_TX_CNTL_CSR, 0x1f << 16); 2098 2099 /* disable Rx (value remains after reset!) */ 2100 tmp = RT2661_READ(sc, RT2661_TXRX_CSR0); 2101 RT2661_WRITE(sc, RT2661_TXRX_CSR0, tmp | RT2661_DISABLE_RX); 2102 2103 /* reset ASIC */ 2104 RT2661_WRITE(sc, RT2661_MAC_CSR1, 3); 2105 RT2661_WRITE(sc, RT2661_MAC_CSR1, 0); 2106 2107 /* disable interrupts */ 2108 RT2661_WRITE(sc, RT2661_INT_MASK_CSR, 0xffffff7f); 2109 RT2661_WRITE(sc, RT2661_MCU_INT_MASK_CSR, 0xffffffff); 2110 2111 /* clear any pending interrupt */ 2112 RT2661_WRITE(sc, RT2661_INT_SOURCE_CSR, 0xffffffff); 2113 RT2661_WRITE(sc, RT2661_MCU_INT_SOURCE_CSR, 0xffffffff); 2114 2115 /* reset Tx and Rx rings */ 2116 rt2661_reset_tx_ring(sc, &sc->txq[0]); 2117 rt2661_reset_tx_ring(sc, &sc->txq[1]); 2118 rt2661_reset_tx_ring(sc, &sc->txq[2]); 2119 rt2661_reset_tx_ring(sc, &sc->txq[3]); 2120 rt2661_reset_tx_ring(sc, &sc->mgtq); 2121 rt2661_reset_rx_ring(sc, &sc->rxq); 2122 } 2123 } 2124 2125 static void 2126 rt2661_set_macaddr(struct rt2661_softc *sc, const uint8_t *addr) 2127 { 2128 uint32_t tmp; 2129 2130 tmp = addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24; 2131 RT2661_WRITE(sc, RT2661_MAC_CSR2, tmp); 2132 2133 tmp = addr[4] | addr[5] << 8 | 0xff << 16; 2134 RT2661_WRITE(sc, RT2661_MAC_CSR3, tmp); 2135 } 2136 2137 static uint8_t 2138 rt2661_bbp_read(struct rt2661_softc *sc, uint8_t reg) 2139 { 2140 uint32_t val; 2141 int ntries; 2142 2143 for (ntries = 0; ntries < 100; ntries++) { 2144 if (!(RT2661_READ(sc, RT2661_PHY_CSR3) & RT2661_BBP_BUSY)) 2145 break; 2146 DELAY(1); 2147 } 2148 if (ntries == 100) { 2149 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_bbp_read(): " 2150 "could not read from BBP\n"); 2151 return (0); 2152 } 2153 2154 val = RT2661_BBP_BUSY | RT2661_BBP_READ | reg << 8; 2155 RT2661_WRITE(sc, RT2661_PHY_CSR3, val); 2156 2157 for (ntries = 0; ntries < 100; ntries++) { 2158 val = RT2661_READ(sc, RT2661_PHY_CSR3); 2159 if (!(val & RT2661_BBP_BUSY)) 2160 return (val & 0xff); 2161 DELAY(1); 2162 } 2163 2164 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_bbp_read(): " 2165 "could not read from BBP\n"); 2166 return (0); 2167 } 2168 2169 static int 2170 rt2661_bbp_init(struct rt2661_softc *sc) 2171 { 2172 #define N(a) (sizeof (a) / sizeof ((a)[0])) 2173 2174 int i, ntries; 2175 uint8_t val; 2176 2177 /* wait for BBP to be ready */ 2178 for (ntries = 0; ntries < 100; ntries++) { 2179 val = rt2661_bbp_read(sc, 0); 2180 if (val != 0 && val != 0xff) 2181 break; 2182 DELAY(100); 2183 } 2184 if (ntries == 100) { 2185 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_bbp_init(): " 2186 "timeout waiting for BBP\n"); 2187 return (RT2661_FAILURE); 2188 } 2189 2190 /* initialize BBP registers to default values */ 2191 for (i = 0; i < N(rt2661_def_bbp); i++) { 2192 rt2661_bbp_write(sc, rt2661_def_bbp[i].reg, 2193 rt2661_def_bbp[i].val); 2194 } 2195 2196 /* write vendor-specific BBP values (from EEPROM) */ 2197 for (i = 0; i < 16; i++) { 2198 if (sc->bbp_prom[i].reg == 0) 2199 continue; 2200 rt2661_bbp_write(sc, sc->bbp_prom[i].reg, sc->bbp_prom[i].val); 2201 } 2202 2203 return (RT2661_SUCCESS); 2204 #undef N 2205 } 2206 2207 static void 2208 rt2661_bbp_write(struct rt2661_softc *sc, uint8_t reg, uint8_t val) 2209 { 2210 uint32_t tmp; 2211 int ntries; 2212 2213 for (ntries = 0; ntries < 100; ntries++) { 2214 if (!(RT2661_READ(sc, RT2661_PHY_CSR3) & RT2661_BBP_BUSY)) 2215 break; 2216 DELAY(1); 2217 } 2218 if (ntries == 100) { 2219 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_bbp_write(): " 2220 "could not write to BBP\n"); 2221 return; 2222 } 2223 2224 tmp = RT2661_BBP_BUSY | (reg & 0x7f) << 8 | val; 2225 RT2661_WRITE(sc, RT2661_PHY_CSR3, tmp); 2226 2227 RWD_DEBUG(RT2661_DBG_HW, "rwd: rt2661_bbp_write(): " 2228 "BBP R%u <- 0x%02x\n", reg, val); 2229 } 2230 2231 /* 2232 * Reprogram MAC/BBP to switch to a new band. Values taken from the reference 2233 * driver. 2234 */ 2235 static void 2236 rt2661_select_band(struct rt2661_softc *sc, struct ieee80211_channel *c) 2237 { 2238 uint8_t bbp17, bbp35, bbp96, bbp97, bbp98, bbp104; 2239 uint32_t tmp; 2240 2241 /* update all BBP registers that depend on the band */ 2242 bbp17 = 0x20; bbp96 = 0x48; bbp104 = 0x2c; 2243 bbp35 = 0x50; bbp97 = 0x48; bbp98 = 0x48; 2244 if (IEEE80211_IS_CHAN_5GHZ(c)) { 2245 bbp17 += 0x08; bbp96 += 0x10; bbp104 += 0x0c; 2246 bbp35 += 0x10; bbp97 += 0x10; bbp98 += 0x10; 2247 } 2248 if ((IEEE80211_IS_CHAN_2GHZ(c) && sc->ext_2ghz_lna) || 2249 (IEEE80211_IS_CHAN_5GHZ(c) && sc->ext_5ghz_lna)) { 2250 bbp17 += 0x10; bbp96 += 0x10; bbp104 += 0x10; 2251 } 2252 2253 sc->bbp17 = bbp17; 2254 rt2661_bbp_write(sc, 17, bbp17); 2255 rt2661_bbp_write(sc, 96, bbp96); 2256 rt2661_bbp_write(sc, 104, bbp104); 2257 2258 if ((IEEE80211_IS_CHAN_2GHZ(c) && sc->ext_2ghz_lna) || 2259 (IEEE80211_IS_CHAN_5GHZ(c) && sc->ext_5ghz_lna)) { 2260 rt2661_bbp_write(sc, 75, 0x80); 2261 rt2661_bbp_write(sc, 86, 0x80); 2262 rt2661_bbp_write(sc, 88, 0x80); 2263 } 2264 2265 rt2661_bbp_write(sc, 35, bbp35); 2266 rt2661_bbp_write(sc, 97, bbp97); 2267 rt2661_bbp_write(sc, 98, bbp98); 2268 2269 tmp = RT2661_READ(sc, RT2661_PHY_CSR0); 2270 tmp &= ~(RT2661_PA_PE_2GHZ | RT2661_PA_PE_5GHZ); 2271 if (IEEE80211_IS_CHAN_2GHZ(c)) 2272 tmp |= RT2661_PA_PE_2GHZ; 2273 else 2274 tmp |= RT2661_PA_PE_5GHZ; 2275 RT2661_WRITE(sc, RT2661_PHY_CSR0, tmp); 2276 2277 /* 802.11a uses a 16 microseconds short interframe space */ 2278 sc->sifs = IEEE80211_IS_CHAN_5GHZ(c) ? 16 : 10; 2279 } 2280 2281 static void 2282 rt2661_select_antenna(struct rt2661_softc *sc) 2283 { 2284 uint8_t bbp4, bbp77; 2285 uint32_t tmp; 2286 2287 bbp4 = rt2661_bbp_read(sc, 4); 2288 bbp77 = rt2661_bbp_read(sc, 77); 2289 2290 /* TBD */ 2291 2292 /* make sure Rx is disabled before switching antenna */ 2293 tmp = RT2661_READ(sc, RT2661_TXRX_CSR0); 2294 RT2661_WRITE(sc, RT2661_TXRX_CSR0, tmp | RT2661_DISABLE_RX); 2295 2296 rt2661_bbp_write(sc, 4, bbp4); 2297 rt2661_bbp_write(sc, 77, bbp77); 2298 2299 /* restore Rx filter */ 2300 RT2661_WRITE(sc, RT2661_TXRX_CSR0, tmp); 2301 } 2302 2303 static void 2304 rt2661_rf_write(struct rt2661_softc *sc, uint8_t reg, uint32_t val) 2305 { 2306 uint32_t tmp; 2307 int ntries; 2308 2309 for (ntries = 0; ntries < 100; ntries++) { 2310 if (!(RT2661_READ(sc, RT2661_PHY_CSR4) & RT2661_RF_BUSY)) 2311 break; 2312 DELAY(1); 2313 } 2314 if (ntries == 100) { 2315 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_rf_write(): " 2316 "could not write to RF\n"); 2317 return; 2318 } 2319 2320 tmp = RT2661_RF_BUSY | RT2661_RF_21BIT | (val & 0x1fffff) << 2 | 2321 (reg & 3); 2322 RT2661_WRITE(sc, RT2661_PHY_CSR4, tmp); 2323 2324 /* remember last written value in sc */ 2325 sc->rf_regs[reg] = val; 2326 2327 RWD_DEBUG(RT2661_DBG_FW, "rwd: rt2661_rf_write(): " 2328 "RF R[%u] <- 0x%05x\n", reg & 3, val & 0x1fffff); 2329 } 2330 2331 static void 2332 rt2661_set_chan(struct rt2661_softc *sc, struct ieee80211_channel *c) 2333 { 2334 struct ieee80211com *ic = &sc->sc_ic; 2335 const struct rfprog *rfprog; 2336 uint8_t bbp3, bbp94 = RT2661_BBPR94_DEFAULT; 2337 int8_t power; 2338 uint_t i, chan; 2339 2340 chan = ieee80211_chan2ieee(ic, c); 2341 if (chan == 0 || chan == IEEE80211_CHAN_ANY) 2342 return; 2343 2344 /* select the appropriate RF settings based on what EEPROM says */ 2345 rfprog = (sc->rfprog == 0) ? rt2661_rf5225_1 : rt2661_rf5225_2; 2346 2347 /* find the settings for this channel (we know it exists) */ 2348 i = 0; 2349 while (rfprog[i].chan != chan) 2350 i++; 2351 2352 power = sc->txpow[i]; 2353 if (power < 0) { 2354 bbp94 += power; 2355 power = 0; 2356 } else if (power > 31) { 2357 bbp94 += power - 31; 2358 power = 31; 2359 } 2360 2361 /* 2362 * If we are switching from the 2GHz band to the 5GHz band or 2363 * vice-versa, BBP registers need to be reprogrammed. 2364 */ 2365 if (ic->ic_flags != sc->sc_curchan->ich_flags) { 2366 rt2661_select_band(sc, c); 2367 rt2661_select_antenna(sc); 2368 } 2369 sc->sc_curchan = c; 2370 2371 rt2661_rf_write(sc, RT2661_RF1, rfprog[i].r1); 2372 rt2661_rf_write(sc, RT2661_RF2, rfprog[i].r2); 2373 rt2661_rf_write(sc, RT2661_RF3, rfprog[i].r3 | power << 7); 2374 rt2661_rf_write(sc, RT2661_RF4, rfprog[i].r4 | sc->rffreq << 10); 2375 2376 DELAY(200); 2377 2378 rt2661_rf_write(sc, RT2661_RF1, rfprog[i].r1); 2379 rt2661_rf_write(sc, RT2661_RF2, rfprog[i].r2); 2380 rt2661_rf_write(sc, RT2661_RF3, rfprog[i].r3 | power << 7 | 1); 2381 rt2661_rf_write(sc, RT2661_RF4, rfprog[i].r4 | sc->rffreq << 10); 2382 2383 DELAY(200); 2384 2385 rt2661_rf_write(sc, RT2661_RF1, rfprog[i].r1); 2386 rt2661_rf_write(sc, RT2661_RF2, rfprog[i].r2); 2387 rt2661_rf_write(sc, RT2661_RF3, rfprog[i].r3 | power << 7); 2388 rt2661_rf_write(sc, RT2661_RF4, rfprog[i].r4 | sc->rffreq << 10); 2389 2390 /* enable smart mode for MIMO-capable RFs */ 2391 bbp3 = rt2661_bbp_read(sc, 3); 2392 2393 bbp3 &= ~RT2661_SMART_MODE; 2394 if (sc->rf_rev == RT2661_RF_5325 || sc->rf_rev == RT2661_RF_2529) 2395 bbp3 |= RT2661_SMART_MODE; 2396 2397 rt2661_bbp_write(sc, 3, bbp3); 2398 2399 if (bbp94 != RT2661_BBPR94_DEFAULT) 2400 rt2661_bbp_write(sc, 94, bbp94); 2401 2402 /* 5GHz radio needs a 1ms delay here */ 2403 if (IEEE80211_IS_CHAN_5GHZ(c)) 2404 DELAY(1000); 2405 } 2406 2407 static int 2408 rt2661_init(struct rt2661_softc *sc) 2409 { 2410 #define N(a) (sizeof (a) / sizeof ((a)[0])) 2411 2412 struct ieee80211com *ic = &sc->sc_ic; 2413 uint32_t tmp, sta[3], *fptr; 2414 int i, err, off, ntries; 2415 2416 RT2661_GLOCK(sc); 2417 2418 rt2661_stop_locked(sc); 2419 2420 if (!RT2661_IS_FWLOADED(sc)) { 2421 err = rt2661_load_microcode(sc, ucode, usize); 2422 if (err != RT2661_SUCCESS) { 2423 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): " 2424 "could not load 8051 microcode\n"); 2425 return (DDI_FAILURE); 2426 } 2427 sc->sc_flags |= RT2661_F_FWLOADED; 2428 } 2429 2430 /* initialize Tx rings */ 2431 RT2661_WRITE(sc, RT2661_AC1_BASE_CSR, sc->txq[1].paddr); 2432 RT2661_WRITE(sc, RT2661_AC0_BASE_CSR, sc->txq[0].paddr); 2433 RT2661_WRITE(sc, RT2661_AC2_BASE_CSR, sc->txq[2].paddr); 2434 RT2661_WRITE(sc, RT2661_AC3_BASE_CSR, sc->txq[3].paddr); 2435 2436 /* initialize Mgt ring */ 2437 RT2661_WRITE(sc, RT2661_MGT_BASE_CSR, sc->mgtq.paddr); 2438 2439 /* initialize Rx ring */ 2440 RT2661_WRITE(sc, RT2661_RX_BASE_CSR, sc->rxq.paddr); 2441 2442 /* initialize Tx rings sizes */ 2443 RT2661_WRITE(sc, RT2661_TX_RING_CSR0, 2444 RT2661_TX_RING_COUNT << 24 | 2445 RT2661_TX_RING_COUNT << 16 | 2446 RT2661_TX_RING_COUNT << 8 | 2447 RT2661_TX_RING_COUNT); 2448 2449 RT2661_WRITE(sc, RT2661_TX_RING_CSR1, 2450 RT2661_TX_DESC_WSIZE << 16 | 2451 RT2661_TX_RING_COUNT << 8 | 2452 RT2661_MGT_RING_COUNT); 2453 2454 /* initialize Rx rings */ 2455 RT2661_WRITE(sc, RT2661_RX_RING_CSR, 2456 RT2661_RX_DESC_BACK << 16 | 2457 RT2661_RX_DESC_WSIZE << 8 | 2458 RT2661_RX_RING_COUNT); 2459 2460 /* XXX: some magic here */ 2461 RT2661_WRITE(sc, RT2661_TX_DMA_DST_CSR, 0xaa); 2462 2463 /* load base addresses of all 5 Tx rings (4 data + 1 mgt) */ 2464 RT2661_WRITE(sc, RT2661_LOAD_TX_RING_CSR, 0x1f); 2465 2466 /* load base address of Rx ring */ 2467 RT2661_WRITE(sc, RT2661_RX_CNTL_CSR, 2); 2468 2469 /* initialize MAC registers to default values */ 2470 for (i = 0; i < N(rt2661_def_mac); i++) 2471 RT2661_WRITE(sc, rt2661_def_mac[i].reg, rt2661_def_mac[i].val); 2472 2473 rt2661_set_macaddr(sc, ic->ic_macaddr); 2474 2475 /* set host ready */ 2476 RT2661_WRITE(sc, RT2661_MAC_CSR1, 3); 2477 RT2661_WRITE(sc, RT2661_MAC_CSR1, 0); 2478 2479 /* wait for BBP/RF to wakeup */ 2480 for (ntries = 0; ntries < 1000; ntries++) { 2481 if (RT2661_READ(sc, RT2661_MAC_CSR12) & 8) 2482 break; 2483 DELAY(1000); 2484 } 2485 if (ntries == 1000) { 2486 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): " 2487 "timeout waiting for BBP/RF to wakeup\n"); 2488 rt2661_stop_locked(sc); 2489 RT2661_GUNLOCK(sc); 2490 return (DDI_FAILURE); 2491 } 2492 2493 if (rt2661_bbp_init(sc) != RT2661_SUCCESS) { 2494 rt2661_stop_locked(sc); 2495 RT2661_GUNLOCK(sc); 2496 return (DDI_FAILURE); 2497 } 2498 2499 /* select default channel */ 2500 sc->sc_curchan = ic->ic_bss->in_chan = ic->ic_curchan; 2501 rt2661_select_band(sc, sc->sc_curchan); 2502 rt2661_select_antenna(sc); 2503 rt2661_set_chan(sc, sc->sc_curchan); 2504 2505 /* update Rx filter */ 2506 tmp = RT2661_READ(sc, RT2661_TXRX_CSR0) & 0xffff; 2507 2508 tmp |= RT2661_DROP_PHY_ERROR | RT2661_DROP_CRC_ERROR; 2509 if (ic->ic_opmode != IEEE80211_M_MONITOR) { 2510 tmp |= RT2661_DROP_CTL | RT2661_DROP_VER_ERROR | 2511 RT2661_DROP_ACKCTS; 2512 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 2513 tmp |= RT2661_DROP_TODS; 2514 if (!(sc->sc_rcr & RT2661_RCR_PROMISC)) 2515 tmp |= RT2661_DROP_NOT_TO_ME; 2516 } 2517 2518 RT2661_WRITE(sc, RT2661_TXRX_CSR0, tmp); 2519 2520 /* clear STA registers */ 2521 off = RT2661_STA_CSR0; 2522 fptr = sta; 2523 for (i = 0; i < N(sta); i++) { 2524 *fptr = RT2661_MEM_READ1(sc, off++); 2525 } 2526 2527 /* initialize ASIC */ 2528 RT2661_WRITE(sc, RT2661_MAC_CSR1, 4); 2529 2530 /* clear any pending interrupt */ 2531 RT2661_WRITE(sc, RT2661_INT_SOURCE_CSR, 0xffffffff); 2532 2533 /* enable interrupts */ 2534 RT2661_WRITE(sc, RT2661_INT_MASK_CSR, 0x0000ff10); 2535 RT2661_WRITE(sc, RT2661_MCU_INT_MASK_CSR, 0); 2536 2537 /* kick Rx */ 2538 RT2661_WRITE(sc, RT2661_RX_CNTL_CSR, 1); 2539 RT2661_GUNLOCK(sc); 2540 2541 #undef N 2542 return (DDI_SUCCESS); 2543 } 2544 2545 static void 2546 rt2661_stop(struct rt2661_softc *sc) 2547 { 2548 if (!RT2661_IS_FASTREBOOT(sc)) 2549 RT2661_GLOCK(sc); 2550 rt2661_stop_locked(sc); 2551 if (!RT2661_IS_FASTREBOOT(sc)) 2552 RT2661_GUNLOCK(sc); 2553 } 2554 2555 static int 2556 rt2661_m_start(void *arg) 2557 { 2558 struct rt2661_softc *sc = (struct rt2661_softc *)arg; 2559 struct ieee80211com *ic = &sc->sc_ic; 2560 int err; 2561 2562 err = rt2661_init(sc); 2563 if (err != DDI_SUCCESS) { 2564 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_m_start():" 2565 "Hardware initialization failed\n"); 2566 goto fail1; 2567 } 2568 2569 ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 2570 2571 RT2661_GLOCK(sc); 2572 sc->sc_flags |= RT2661_F_RUNNING; 2573 RT2661_GUNLOCK(sc); 2574 2575 return (DDI_SUCCESS); 2576 fail1: 2577 rt2661_stop(sc); 2578 return (err); 2579 } 2580 2581 static void 2582 rt2661_m_stop(void *arg) 2583 { 2584 struct rt2661_softc *sc = (struct rt2661_softc *)arg; 2585 2586 (void) rt2661_stop(sc); 2587 2588 ieee80211_new_state(&sc->sc_ic, IEEE80211_S_INIT, -1); 2589 2590 RT2661_GLOCK(sc); 2591 sc->sc_flags &= ~RT2661_F_RUNNING; 2592 RT2661_GUNLOCK(sc); 2593 } 2594 2595 static void 2596 rt2661_m_ioctl(void* arg, queue_t *wq, mblk_t *mp) 2597 { 2598 struct rt2661_softc *sc = (struct rt2661_softc *)arg; 2599 struct ieee80211com *ic = &sc->sc_ic; 2600 int err; 2601 2602 err = ieee80211_ioctl(ic, wq, mp); 2603 RT2661_GLOCK(sc); 2604 if (err == ENETRESET) { 2605 if (ic->ic_des_esslen) { 2606 if (RT2661_IS_RUNNING(sc)) { 2607 RT2661_GUNLOCK(sc); 2608 (void) rt2661_init(sc); 2609 (void) ieee80211_new_state(ic, 2610 IEEE80211_S_SCAN, -1); 2611 RT2661_GLOCK(sc); 2612 } 2613 } 2614 } 2615 RT2661_GUNLOCK(sc); 2616 } 2617 2618 /* 2619 * Call back function for get/set proporty 2620 */ 2621 static int 2622 rt2661_m_getprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num, 2623 uint_t wldp_length, void *wldp_buf) 2624 { 2625 struct rt2661_softc *sc = (struct rt2661_softc *)arg; 2626 int err = 0; 2627 2628 err = ieee80211_getprop(&sc->sc_ic, pr_name, wldp_pr_num, 2629 wldp_length, wldp_buf); 2630 2631 return (err); 2632 } 2633 2634 static void 2635 rt2661_m_propinfo(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num, 2636 mac_prop_info_handle_t mph) 2637 { 2638 struct rt2661_softc *sc = (struct rt2661_softc *)arg; 2639 2640 ieee80211_propinfo(&sc->sc_ic, pr_name, wldp_pr_num, mph); 2641 } 2642 2643 static int 2644 rt2661_m_setprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num, 2645 uint_t wldp_length, const void *wldp_buf) 2646 { 2647 struct rt2661_softc *sc = (struct rt2661_softc *)arg; 2648 ieee80211com_t *ic = &sc->sc_ic; 2649 int err; 2650 2651 err = ieee80211_setprop(ic, pr_name, wldp_pr_num, wldp_length, 2652 wldp_buf); 2653 RT2661_GLOCK(sc); 2654 if (err == ENETRESET) { 2655 if (ic->ic_des_esslen) { 2656 if (RT2661_IS_RUNNING(sc)) { 2657 RT2661_GUNLOCK(sc); 2658 (void) rt2661_init(sc); 2659 (void) ieee80211_new_state(ic, 2660 IEEE80211_S_SCAN, -1); 2661 RT2661_GLOCK(sc); 2662 } 2663 } 2664 err = 0; 2665 } 2666 RT2661_GUNLOCK(sc); 2667 return (err); 2668 } 2669 2670 static mblk_t * 2671 rt2661_m_tx(void *arg, mblk_t *mp) 2672 { 2673 struct rt2661_softc *sc = (struct rt2661_softc *)arg; 2674 struct ieee80211com *ic = &sc->sc_ic; 2675 mblk_t *next; 2676 2677 if (RT2661_IS_SUSPEND(sc)) { 2678 freemsgchain(mp); 2679 return (NULL); 2680 } 2681 2682 /* 2683 * No data frames go out unless we're associated; this 2684 * should not happen as the 802.11 layer does not enable 2685 * the xmit queue until we enter the RUN state. 2686 */ 2687 if (ic->ic_state != IEEE80211_S_RUN) { 2688 RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_tx_data(): " 2689 "discard, state %u\n", ic->ic_state); 2690 freemsgchain(mp); 2691 return (NULL); 2692 } 2693 2694 while (mp != NULL) { 2695 next = mp->b_next; 2696 mp->b_next = NULL; 2697 if (rt2661_send(ic, mp) != 2698 DDI_SUCCESS) { 2699 mp->b_next = next; 2700 break; 2701 } 2702 mp = next; 2703 } 2704 return (mp); 2705 } 2706 2707 /*ARGSUSED*/ 2708 static int 2709 rt2661_m_unicst(void *arg, const uint8_t *macaddr) 2710 { 2711 return (ENOTSUP); 2712 } 2713 2714 /*ARGSUSED*/ 2715 static int 2716 rt2661_m_multicst(void *arg, boolean_t add, const uint8_t *mca) 2717 { 2718 return (ENOTSUP); 2719 } 2720 2721 /*ARGSUSED*/ 2722 static int 2723 rt2661_m_promisc(void *arg, boolean_t on) 2724 { 2725 struct rt2661_softc *sc = (struct rt2661_softc *)arg; 2726 2727 if (on) { 2728 sc->sc_rcr |= RT2661_RCR_PROMISC; 2729 sc->sc_rcr |= RT2661_RCR_MULTI; 2730 } else { 2731 sc->sc_rcr &= ~RT2661_RCR_PROMISC; 2732 sc->sc_rcr &= ~RT2661_RCR_MULTI; 2733 } 2734 2735 rt2661_update_promisc(sc); 2736 return (0); 2737 } 2738 2739 static int 2740 rt2661_m_stat(void *arg, uint_t stat, uint64_t *val) 2741 { 2742 struct rt2661_softc *sc = (struct rt2661_softc *)arg; 2743 struct ieee80211com *ic = &sc->sc_ic; 2744 struct ieee80211_node *ni = ic->ic_bss; 2745 struct ieee80211_rateset *rs = &ni->in_rates; 2746 2747 RT2661_GLOCK(sc); 2748 switch (stat) { 2749 case MAC_STAT_IFSPEED: 2750 *val = ((ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) ? 2751 (rs->ir_rates[ni->in_txrate] & IEEE80211_RATE_VAL) 2752 : ic->ic_fixed_rate) / 2 * 1000000; 2753 break; 2754 case MAC_STAT_NOXMTBUF: 2755 *val = sc->sc_tx_nobuf; 2756 break; 2757 case MAC_STAT_NORCVBUF: 2758 *val = sc->sc_rx_nobuf; 2759 break; 2760 case MAC_STAT_IERRORS: 2761 *val = sc->sc_rx_err; 2762 break; 2763 case MAC_STAT_RBYTES: 2764 *val = ic->ic_stats.is_rx_bytes; 2765 break; 2766 case MAC_STAT_IPACKETS: 2767 *val = ic->ic_stats.is_rx_frags; 2768 break; 2769 case MAC_STAT_OBYTES: 2770 *val = ic->ic_stats.is_tx_bytes; 2771 break; 2772 case MAC_STAT_OPACKETS: 2773 *val = ic->ic_stats.is_tx_frags; 2774 break; 2775 case MAC_STAT_OERRORS: 2776 case WIFI_STAT_TX_FAILED: 2777 *val = sc->sc_tx_err; 2778 break; 2779 case WIFI_STAT_TX_RETRANS: 2780 *val = sc->sc_tx_retries; 2781 break; 2782 case WIFI_STAT_FCS_ERRORS: 2783 case WIFI_STAT_WEP_ERRORS: 2784 case WIFI_STAT_TX_FRAGS: 2785 case WIFI_STAT_MCAST_TX: 2786 case WIFI_STAT_RTS_SUCCESS: 2787 case WIFI_STAT_RTS_FAILURE: 2788 case WIFI_STAT_ACK_FAILURE: 2789 case WIFI_STAT_RX_FRAGS: 2790 case WIFI_STAT_MCAST_RX: 2791 case WIFI_STAT_RX_DUPS: 2792 RT2661_GUNLOCK(sc); 2793 return (ieee80211_stat(ic, stat, val)); 2794 default: 2795 RT2661_GUNLOCK(sc); 2796 return (ENOTSUP); 2797 } 2798 RT2661_GUNLOCK(sc); 2799 2800 return (0); 2801 } 2802 2803 static int 2804 rt2661_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd) 2805 { 2806 struct rt2661_softc *sc; 2807 struct ieee80211com *ic; 2808 2809 int i, ac, err, ntries, instance; 2810 int intr_type, intr_count, intr_actual; 2811 char strbuf[32]; 2812 uint8_t cachelsz; 2813 uint16_t command, vendor_id, device_id; 2814 uint32_t val; 2815 2816 wifi_data_t wd = { 0 }; 2817 mac_register_t *macp; 2818 2819 switch (cmd) { 2820 case DDI_ATTACH: 2821 break; 2822 case DDI_RESUME: 2823 sc = ddi_get_soft_state(rt2661_soft_state_p, 2824 ddi_get_instance(devinfo)); 2825 ASSERT(sc != NULL); 2826 RT2661_GLOCK(sc); 2827 sc->sc_flags &= ~RT2661_F_SUSPEND; 2828 RT2661_GUNLOCK(sc); 2829 if (RT2661_IS_RUNNING(sc)) 2830 (void) rt2661_init(sc); 2831 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): " 2832 "resume now\n"); 2833 return (DDI_SUCCESS); 2834 default: 2835 return (DDI_FAILURE); 2836 } 2837 2838 instance = ddi_get_instance(devinfo); 2839 2840 err = ddi_soft_state_zalloc(rt2661_soft_state_p, instance); 2841 if (err != DDI_SUCCESS) { 2842 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): " 2843 "unable to alloc soft_state_p\n"); 2844 return (err); 2845 } 2846 2847 sc = ddi_get_soft_state(rt2661_soft_state_p, instance); 2848 ic = (struct ieee80211com *)&sc->sc_ic; 2849 sc->sc_dev = devinfo; 2850 2851 /* PCI configuration */ 2852 err = ddi_regs_map_setup(devinfo, 0, &sc->sc_cfg_base, 0, 0, 2853 &rt2661_csr_accattr, &sc->sc_cfg_handle); 2854 if (err != DDI_SUCCESS) { 2855 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): " 2856 "ddi_regs_map_setup() failed"); 2857 goto fail1; 2858 } 2859 2860 cachelsz = ddi_get8(sc->sc_cfg_handle, 2861 (uint8_t *)(sc->sc_cfg_base + PCI_CONF_CACHE_LINESZ)); 2862 if (cachelsz == 0) 2863 cachelsz = 0x10; 2864 sc->sc_cachelsz = cachelsz << 2; 2865 sc->sc_dmabuf_size = roundup(IEEE80211_MAX_LEN, sc->sc_cachelsz); 2866 2867 vendor_id = ddi_get16(sc->sc_cfg_handle, 2868 (uint16_t *)((uintptr_t)(sc->sc_cfg_base) + PCI_CONF_VENID)); 2869 device_id = ddi_get16(sc->sc_cfg_handle, 2870 (uint16_t *)((uintptr_t)(sc->sc_cfg_base) + PCI_CONF_DEVID)); 2871 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): " 2872 "vendor 0x%x, device id 0x%x, cache size %d\n", 2873 vendor_id, device_id, cachelsz); 2874 2875 /* 2876 * Enable response to memory space accesses, 2877 * and enabe bus master. 2878 */ 2879 command = PCI_COMM_MAE | PCI_COMM_ME; 2880 ddi_put16(sc->sc_cfg_handle, 2881 (uint16_t *)((uintptr_t)(sc->sc_cfg_base) + PCI_CONF_COMM), 2882 command); 2883 ddi_put8(sc->sc_cfg_handle, 2884 (uint8_t *)(sc->sc_cfg_base + PCI_CONF_LATENCY_TIMER), 0xa8); 2885 ddi_put8(sc->sc_cfg_handle, 2886 (uint8_t *)(sc->sc_cfg_base + PCI_CONF_ILINE), 0x10); 2887 2888 /* pci i/o space */ 2889 err = ddi_regs_map_setup(devinfo, 1, 2890 &sc->sc_io_base, 0, 0, &rt2661_csr_accattr, &sc->sc_io_handle); 2891 if (err != DDI_SUCCESS) { 2892 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): " 2893 "ddi_regs_map_setup() failed"); 2894 goto fail2; 2895 } 2896 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): " 2897 "PCI configuration is done successfully\n"); 2898 2899 err = ddi_intr_get_supported_types(devinfo, &intr_type); 2900 if ((err != DDI_SUCCESS) || (!(intr_type & DDI_INTR_TYPE_FIXED))) { 2901 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): " 2902 "fixed type interrupt is not supported\n"); 2903 goto fail3; 2904 } 2905 2906 err = ddi_intr_get_nintrs(devinfo, DDI_INTR_TYPE_FIXED, &intr_count); 2907 if ((err != DDI_SUCCESS) || (intr_count != 1)) { 2908 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): " 2909 "no fixed interrupts\n"); 2910 goto fail3; 2911 } 2912 2913 sc->sc_intr_htable = kmem_zalloc(sizeof (ddi_intr_handle_t), KM_SLEEP); 2914 2915 err = ddi_intr_alloc(devinfo, sc->sc_intr_htable, 2916 DDI_INTR_TYPE_FIXED, 0, intr_count, &intr_actual, 0); 2917 if ((err != DDI_SUCCESS) || (intr_actual != 1)) { 2918 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): " 2919 "ddi_intr_alloc() failed 0x%x\n", err); 2920 goto faili4; 2921 } 2922 2923 err = ddi_intr_get_pri(sc->sc_intr_htable[0], &sc->sc_intr_pri); 2924 if (err != DDI_SUCCESS) { 2925 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): " 2926 "ddi_intr_get_pri() failed 0x%x\n", err); 2927 goto faili5; 2928 } 2929 2930 sc->amrr.amrr_min_success_threshold = 1; 2931 sc->amrr.amrr_max_success_threshold = 15; 2932 2933 /* wait for NIC to initialize */ 2934 for (ntries = 0; ntries < 1000; ntries++) { 2935 if ((val = RT2661_READ(sc, RT2661_MAC_CSR0)) != 0) 2936 break; 2937 DELAY(1000); 2938 } 2939 if (ntries == 1000) { 2940 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): " 2941 "timeout waiting for NIC to initialize\n"); 2942 goto faili5; 2943 } 2944 2945 /* retrieve RF rev. no and various other things from EEPROM */ 2946 rt2661_read_eeprom(sc); 2947 2948 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): " 2949 "MAC/BBP RT%X, RF %s\n" 2950 "MAC address is: %x:%x:%x:%x:%x:%x\n", val, 2951 rt2661_get_rf(sc->rf_rev), 2952 ic->ic_macaddr[0], ic->ic_macaddr[1], ic->ic_macaddr[2], 2953 ic->ic_macaddr[3], ic->ic_macaddr[4], ic->ic_macaddr[5]); 2954 2955 /* 2956 * Load 8051 microcode into NIC. 2957 */ 2958 switch (device_id) { 2959 case 0x0301: 2960 ucode = rt2561s_ucode; 2961 usize = sizeof (rt2561s_ucode); 2962 break; 2963 case 0x0302: 2964 ucode = rt2561_ucode; 2965 usize = sizeof (rt2561_ucode); 2966 break; 2967 case 0x0401: 2968 ucode = rt2661_ucode; 2969 usize = sizeof (rt2661_ucode); 2970 break; 2971 } 2972 2973 err = rt2661_load_microcode(sc, ucode, usize); 2974 if (err != RT2661_SUCCESS) { 2975 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): " 2976 "could not load 8051 microcode\n"); 2977 goto faili5; 2978 } 2979 2980 sc->sc_flags = 0; 2981 sc->sc_flags |= RT2661_F_FWLOADED; 2982 2983 /* 2984 * Allocate Tx and Rx rings. 2985 */ 2986 for (ac = 0; ac < 4; ac++) { 2987 err = rt2661_alloc_tx_ring(sc, &sc->txq[ac], 2988 RT2661_TX_RING_COUNT); 2989 if (err != RT2661_SUCCESS) { 2990 RWD_DEBUG(RT2661_DBG_DMA, "rwd: rt2661_attach(): " 2991 "could not allocate Tx ring %d\n", ac); 2992 goto fail4; 2993 } 2994 } 2995 2996 err = rt2661_alloc_tx_ring(sc, &sc->mgtq, RT2661_MGT_RING_COUNT); 2997 if (err != RT2661_SUCCESS) { 2998 RWD_DEBUG(RT2661_DBG_DMA, "rwd: rt2661_attach(): " 2999 "could not allocate Mgt ring\n"); 3000 goto fail5; 3001 } 3002 3003 err = rt2661_alloc_rx_ring(sc, &sc->rxq, RT2661_RX_RING_COUNT); 3004 if (err != RT2661_SUCCESS) { 3005 RWD_DEBUG(RT2661_DBG_DMA, "rwd: rt2661_attach(): " 3006 "could not allocate Rx ring\n"); 3007 goto fail6; 3008 } 3009 3010 mutex_init(&sc->sc_genlock, NULL, MUTEX_DRIVER, NULL); 3011 mutex_init(&sc->sc_txlock, NULL, MUTEX_DRIVER, NULL); 3012 mutex_init(&sc->sc_rxlock, NULL, MUTEX_DRIVER, NULL); 3013 3014 ic->ic_phytype = IEEE80211_T_OFDM; 3015 ic->ic_opmode = IEEE80211_M_STA; 3016 ic->ic_state = IEEE80211_S_INIT; 3017 3018 /* set device capabilities */ 3019 ic->ic_caps = 3020 IEEE80211_C_TXPMGT | 3021 IEEE80211_C_SHPREAMBLE | 3022 IEEE80211_C_SHSLOT; 3023 3024 /* WPA/WPA2 support */ 3025 ic->ic_caps |= IEEE80211_C_WPA; 3026 3027 /* set supported .11b and .11g rates */ 3028 ic->ic_sup_rates[IEEE80211_MODE_11B] = rt2661_rateset_11b; 3029 ic->ic_sup_rates[IEEE80211_MODE_11G] = rt2661_rateset_11g; 3030 3031 /* set supported .11b and .11g channels (1 through 14) */ 3032 for (i = 1; i <= 14; i++) { 3033 ic->ic_sup_channels[i].ich_freq = 3034 ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ); 3035 ic->ic_sup_channels[i].ich_flags = 3036 IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM | 3037 IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ; 3038 } 3039 3040 ic->ic_maxrssi = 63; 3041 ic->ic_xmit = rt2661_mgmt_send; 3042 3043 ieee80211_attach(ic); 3044 3045 /* register WPA door */ 3046 ieee80211_register_door(ic, ddi_driver_name(devinfo), 3047 ddi_get_instance(devinfo)); 3048 3049 ic->ic_node_alloc = rt2661_node_alloc; 3050 ic->ic_node_free = rt2661_node_free; 3051 ic->ic_set_shortslot = rt2661_updateslot; 3052 3053 /* override state transition machine */ 3054 sc->sc_newstate = ic->ic_newstate; 3055 ic->ic_newstate = rt2661_newstate; 3056 ieee80211_media_init(ic); 3057 ic->ic_def_txkey = 0; 3058 3059 err = ddi_intr_add_softint(devinfo, &sc->sc_softintr_hdl, 3060 DDI_INTR_SOFTPRI_MAX, rt2661_softintr, (caddr_t)sc); 3061 if (err != DDI_SUCCESS) { 3062 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): " 3063 "ddi_add_softintr() failed"); 3064 goto fail7; 3065 } 3066 3067 err = ddi_intr_add_handler(sc->sc_intr_htable[0], rt2661_intr, 3068 (caddr_t)sc, NULL); 3069 if (err != DDI_SUCCESS) { 3070 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): " 3071 "ddi_intr_addr_handle() failed\n"); 3072 goto fail8; 3073 } 3074 3075 err = ddi_intr_enable(sc->sc_intr_htable[0]); 3076 if (err != DDI_SUCCESS) { 3077 RWD_DEBUG(RT2661_DBG_MSG, "rwd; rt2661_attach(): " 3078 "ddi_intr_enable() failed\n"); 3079 goto fail9; 3080 } 3081 3082 /* 3083 * Provide initial settings for the WiFi plugin; whenever this 3084 * information changes, we need to call mac_plugindata_update() 3085 */ 3086 wd.wd_opmode = ic->ic_opmode; 3087 wd.wd_secalloc = WIFI_SEC_NONE; 3088 IEEE80211_ADDR_COPY(wd.wd_bssid, ic->ic_bss->in_bssid); 3089 3090 if ((macp = mac_alloc(MAC_VERSION)) == NULL) { 3091 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): " 3092 "MAC version mismatch\n"); 3093 goto fail10; 3094 } 3095 3096 macp->m_type_ident = MAC_PLUGIN_IDENT_WIFI; 3097 macp->m_driver = sc; 3098 macp->m_dip = devinfo; 3099 macp->m_src_addr = ic->ic_macaddr; 3100 macp->m_callbacks = &rt2661_m_callbacks; 3101 macp->m_min_sdu = 0; 3102 macp->m_max_sdu = IEEE80211_MTU; 3103 macp->m_pdata = &wd; 3104 macp->m_pdata_size = sizeof (wd); 3105 3106 err = mac_register(macp, &ic->ic_mach); 3107 mac_free(macp); 3108 if (err != 0) { 3109 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): " 3110 "mac_register err %x\n", err); 3111 goto fail10; 3112 } 3113 3114 /* 3115 * Create minor node of type DDI_NT_NET_WIFI 3116 */ 3117 (void) snprintf(strbuf, sizeof (strbuf), "%s%d", 3118 "rwd", instance); 3119 err = ddi_create_minor_node(devinfo, strbuf, S_IFCHR, 3120 instance + 1, DDI_NT_NET_WIFI, 0); 3121 3122 /* 3123 * Notify link is down now 3124 */ 3125 mac_link_update(ic->ic_mach, LINK_STATE_DOWN); 3126 3127 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): " 3128 "attach successfully\n"); 3129 return (DDI_SUCCESS); 3130 3131 fail10: 3132 (void) ddi_intr_disable(sc->sc_intr_htable[0]); 3133 fail9: 3134 (void) ddi_intr_remove_handler(sc->sc_intr_htable[0]); 3135 fail8: 3136 (void) ddi_intr_remove_softint(sc->sc_softintr_hdl); 3137 sc->sc_softintr_hdl = NULL; 3138 fail7: 3139 mutex_destroy(&sc->sc_genlock); 3140 mutex_destroy(&sc->sc_txlock); 3141 mutex_destroy(&sc->sc_rxlock); 3142 fail6: 3143 rt2661_free_rx_ring(sc, &sc->rxq); 3144 fail5: 3145 rt2661_free_tx_ring(sc, &sc->mgtq); 3146 fail4: 3147 while (--ac >= 0) 3148 rt2661_free_tx_ring(sc, &sc->txq[ac]); 3149 faili5: 3150 (void) ddi_intr_free(sc->sc_intr_htable[0]); 3151 faili4: 3152 kmem_free(sc->sc_intr_htable, sizeof (ddi_intr_handle_t)); 3153 fail3: 3154 ddi_regs_map_free(&sc->sc_io_handle); 3155 fail2: 3156 ddi_regs_map_free(&sc->sc_cfg_handle); 3157 fail1: 3158 return (DDI_FAILURE); 3159 } 3160 3161 static int 3162 rt2661_detach(dev_info_t *devinfo, ddi_detach_cmd_t cmd) 3163 { 3164 3165 struct rt2661_softc *sc; 3166 3167 sc = ddi_get_soft_state(rt2661_soft_state_p, ddi_get_instance(devinfo)); 3168 3169 switch (cmd) { 3170 case DDI_DETACH: 3171 break; 3172 case DDI_SUSPEND: 3173 if (RT2661_IS_RUNNING(sc)) 3174 rt2661_stop(sc); 3175 RT2661_GLOCK(sc); 3176 sc->sc_flags |= RT2661_F_SUSPEND; 3177 sc->sc_flags &= ~RT2661_F_FWLOADED; 3178 RT2661_GUNLOCK(sc); 3179 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_detach(): " 3180 "suspend now\n"); 3181 return (DDI_SUCCESS); 3182 default: 3183 return (DDI_FAILURE); 3184 } 3185 3186 if (mac_disable(sc->sc_ic.ic_mach) != 0) 3187 return (DDI_FAILURE); 3188 3189 /* 3190 * Unregister from the MAC layer subsystem 3191 */ 3192 (void) mac_unregister(sc->sc_ic.ic_mach); 3193 3194 (void) ddi_intr_remove_softint(sc->sc_softintr_hdl); 3195 sc->sc_softintr_hdl = NULL; 3196 (void) ddi_intr_disable(sc->sc_intr_htable[0]); 3197 (void) ddi_intr_remove_handler(sc->sc_intr_htable[0]); 3198 (void) ddi_intr_free(sc->sc_intr_htable[0]); 3199 kmem_free(sc->sc_intr_htable, sizeof (ddi_intr_handle_t)); 3200 3201 /* 3202 * detach ieee80211 layer 3203 */ 3204 ieee80211_detach(&sc->sc_ic); 3205 3206 mutex_destroy(&sc->sc_genlock); 3207 mutex_destroy(&sc->sc_txlock); 3208 mutex_destroy(&sc->sc_rxlock); 3209 3210 rt2661_free_tx_ring(sc, &sc->txq[0]); 3211 rt2661_free_tx_ring(sc, &sc->txq[1]); 3212 rt2661_free_tx_ring(sc, &sc->txq[2]); 3213 rt2661_free_tx_ring(sc, &sc->txq[3]); 3214 rt2661_free_tx_ring(sc, &sc->mgtq); 3215 rt2661_free_rx_ring(sc, &sc->rxq); 3216 3217 ddi_regs_map_free(&sc->sc_io_handle); 3218 ddi_regs_map_free(&sc->sc_cfg_handle); 3219 3220 ddi_remove_minor_node(devinfo, NULL); 3221 ddi_soft_state_free(rt2661_soft_state_p, ddi_get_instance(devinfo)); 3222 3223 RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_detach(): " 3224 "detach successfully\n"); 3225 return (DDI_SUCCESS); 3226 } 3227 3228 static int 3229 rt2661_quiesce(dev_info_t *dip) 3230 { 3231 struct rt2661_softc *sc; 3232 3233 sc = ddi_get_soft_state(rt2661_soft_state_p, ddi_get_instance(dip)); 3234 if (sc == NULL) 3235 return (DDI_FAILURE); 3236 3237 #ifdef DEBUG 3238 rt2661_dbg_flags = 0; 3239 #endif 3240 3241 /* 3242 * No more blocking is allowed while we are in quiesce(9E) entry point 3243 */ 3244 sc->sc_flags |= RT2661_F_QUIESCE; 3245 3246 /* 3247 * Disable all interrupts 3248 */ 3249 rt2661_stop(sc); 3250 return (DDI_SUCCESS); 3251 } 3252 3253 int 3254 _info(struct modinfo *modinfop) 3255 { 3256 return (mod_info(&modlinkage, modinfop)); 3257 } 3258 3259 int 3260 _init(void) 3261 { 3262 int status; 3263 3264 status = ddi_soft_state_init(&rt2661_soft_state_p, 3265 sizeof (struct rt2661_softc), 1); 3266 if (status != 0) 3267 return (status); 3268 3269 mac_init_ops(&rwd_dev_ops, "rwd"); 3270 status = mod_install(&modlinkage); 3271 if (status != 0) { 3272 mac_fini_ops(&rwd_dev_ops); 3273 ddi_soft_state_fini(&rt2661_soft_state_p); 3274 } 3275 return (status); 3276 } 3277 3278 int 3279 _fini(void) 3280 { 3281 int status; 3282 3283 status = mod_remove(&modlinkage); 3284 if (status == 0) { 3285 mac_fini_ops(&rwd_dev_ops); 3286 ddi_soft_state_fini(&rt2661_soft_state_p); 3287 } 3288 return (status); 3289 }