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