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