1 /*
   2  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
   3  * Use is subject to license terms.
   4  */
   5 
   6 /*
   7  * Copyright (c) 2004 David Young.  All rights reserved.
   8  *
   9  * This code was written by David Young.
  10  *
  11  * Redistribution and use in source and binary forms, with or without
  12  * modification, are permitted provided that the following conditions
  13  * are met:
  14  * 1. Redistributions of source code must retain the above copyright
  15  *    notice, this list of conditions and the following disclaimer.
  16  * 2. Redistributions in binary form must reproduce the above copyright
  17  *    notice, this list of conditions and the following disclaimer in the
  18  *    documentation and/or other materials provided with the distribution.
  19  * 3. Neither the name of the author nor the names of any co-contributors
  20  *    may be used to endorse or promote products derived from this software
  21  *    without specific prior written permission.
  22  *
  23  * THIS SOFTWARE IS PROVIDED BY David Young ``AS IS'' AND ANY
  24  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  25  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  26  * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL David
  27  * Young BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  28  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
  29  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  30  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  31  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  32  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
  34  * OF SUCH DAMAGE.
  35  */
  36 #include <sys/sysmacros.h>
  37 #include <sys/pci.h>
  38 #include <sys/stat.h>
  39 #include <sys/strsubr.h>
  40 #include <sys/strsun.h>
  41 #include <sys/mac_provider.h>
  42 #include <sys/mac_wifi.h>
  43 #include <sys/net80211.h>
  44 #include <sys/byteorder.h>
  45 #include "rtwreg.h"
  46 #include "rtwvar.h"
  47 #include "smc93cx6var.h"
  48 #include "rtwphy.h"
  49 #include "rtwphyio.h"
  50 
  51 /*
  52  * PIO access attributes for registers
  53  */
  54 static ddi_device_acc_attr_t rtw_reg_accattr = {
  55         DDI_DEVICE_ATTR_V0,
  56         DDI_STRUCTURE_LE_ACC,
  57         DDI_STRICTORDER_ACC,
  58         DDI_DEFAULT_ACC
  59 };
  60 
  61 /*
  62  * DMA access attributes for descriptors and bufs: NOT to be byte swapped.
  63  */
  64 static ddi_device_acc_attr_t rtw_desc_accattr = {
  65         DDI_DEVICE_ATTR_V0,
  66         DDI_NEVERSWAP_ACC,
  67         DDI_STRICTORDER_ACC,
  68         DDI_DEFAULT_ACC
  69 };
  70 static ddi_device_acc_attr_t rtw_buf_accattr = {
  71         DDI_DEVICE_ATTR_V0,
  72         DDI_NEVERSWAP_ACC,
  73         DDI_STRICTORDER_ACC,
  74         DDI_DEFAULT_ACC
  75 };
  76 
  77 /*
  78  * Describes the chip's DMA engine
  79  */
  80 static ddi_dma_attr_t dma_attr_desc = {
  81         DMA_ATTR_V0,                    /* dma_attr version */
  82         0x0000000000000000ull,          /* dma_attr_addr_lo */
  83         0xFFFFFFFF,                     /* dma_attr_addr_hi */
  84         0x00000000FFFFFFFFull,          /* dma_attr_count_max */
  85         0x100,                          /* dma_attr_align */
  86         0xFFFFFFFF,                     /* dma_attr_burstsizes */
  87         0x00000001,                     /* dma_attr_minxfer */
  88         0x00000000FFFFull,              /* dma_attr_maxxfer */
  89         0xFFFFFFFFFFFFFFFFull,          /* dma_attr_seg */
  90         1,                              /* dma_attr_sgllen */
  91         1,                              /* dma_attr_granular */
  92         0                               /* dma_attr_flags */
  93 };
  94 
  95 static ddi_dma_attr_t dma_attr_rxbuf = {
  96         DMA_ATTR_V0,                    /* dma_attr version */
  97         0x0000000000000000ull,          /* dma_attr_addr_lo */
  98         0xFFFFFFFF,                     /* dma_attr_addr_hi */
  99         0x00000000FFFFFFFFull,          /* dma_attr_count_max */
 100         (uint32_t)16,                   /* dma_attr_align */
 101         0xFFFFFFFF,                     /* dma_attr_burstsizes */
 102         0x00000001,                     /* dma_attr_minxfer */
 103         0x00000000FFFFull,              /* dma_attr_maxxfer */
 104         0xFFFFFFFFFFFFFFFFull,          /* dma_attr_seg */
 105         1,                              /* dma_attr_sgllen */
 106         1,                              /* dma_attr_granular */
 107         0                               /* dma_attr_flags */
 108 };
 109 
 110 static ddi_dma_attr_t dma_attr_txbuf = {
 111         DMA_ATTR_V0,                    /* dma_attr version */
 112         0x0000000000000000ull,          /* dma_attr_addr_lo */
 113         0xFFFFFFFF,                     /* dma_attr_addr_hi */
 114         0x00000000FFFFFFFFull,          /* dma_attr_count_max */
 115         (uint32_t)16,                   /* dma_attr_align */
 116         0xFFFFFFFF,                     /* dma_attr_burstsizes */
 117         0x00000001,                     /* dma_attr_minxfer */
 118         0x00000000FFFFull,              /* dma_attr_maxxfer */
 119         0xFFFFFFFFFFFFFFFFull,          /* dma_attr_seg */
 120         1,                              /* dma_attr_sgllen */
 121         1,                              /* dma_attr_granular */
 122         0                               /* dma_attr_flags */
 123 };
 124 
 125 
 126 static void *rtw_soft_state_p = NULL;
 127 
 128 static void     rtw_stop(void *);
 129 static int      rtw_attach(dev_info_t *, ddi_attach_cmd_t);
 130 static int      rtw_detach(dev_info_t *, ddi_detach_cmd_t);
 131 static int      rtw_quiesce(dev_info_t *);
 132 static int      rtw_m_stat(void *,  uint_t, uint64_t *);
 133 static int      rtw_m_start(void *);
 134 static void     rtw_m_stop(void *);
 135 static int      rtw_m_promisc(void *, boolean_t);
 136 static int      rtw_m_multicst(void *, boolean_t, const uint8_t *);
 137 static int      rtw_m_unicst(void *, const uint8_t *);
 138 static mblk_t   *rtw_m_tx(void *, mblk_t *);
 139 static void     rtw_m_ioctl(void *, queue_t *, mblk_t *);
 140 static int      rtw_m_setprop(void *, const char *, mac_prop_id_t,
 141     uint_t, const void *);
 142 static int      rtw_m_getprop(void *, const char *, mac_prop_id_t,
 143     uint_t, void *);
 144 static void     rtw_m_propinfo(void *, const char *, mac_prop_id_t,
 145     mac_prop_info_handle_t);
 146 
 147 static mac_callbacks_t rtw_m_callbacks = {
 148         MC_IOCTL | MC_SETPROP | MC_GETPROP | MC_PROPINFO,
 149         rtw_m_stat,
 150         rtw_m_start,
 151         rtw_m_stop,
 152         rtw_m_promisc,
 153         rtw_m_multicst,
 154         rtw_m_unicst,
 155         rtw_m_tx,
 156         NULL,
 157         rtw_m_ioctl,
 158         NULL,           /* mc_getcapab */
 159         NULL,
 160         NULL,
 161         rtw_m_setprop,
 162         rtw_m_getprop,
 163         rtw_m_propinfo
 164 };
 165 
 166 DDI_DEFINE_STREAM_OPS(rtw_dev_ops, nulldev, nulldev, rtw_attach, rtw_detach,
 167     nodev, NULL, D_MP, NULL, rtw_quiesce);
 168 
 169 static struct modldrv rtw_modldrv = {
 170         &mod_driverops,             /* Type of module.  This one is a driver */
 171         "realtek 8180L driver 1.7",     /* short description */
 172         &rtw_dev_ops                /* driver specific ops */
 173 };
 174 
 175 static struct modlinkage modlinkage = {
 176         MODREV_1, (void *)&rtw_modldrv, NULL
 177 };
 178 
 179 static uint32_t rtw_qlen[RTW_NTXPRI] = {
 180         RTW_TXQLENLO,
 181         RTW_TXQLENMD,
 182         RTW_TXQLENHI,
 183         RTW_TXQLENBCN
 184 };
 185 
 186 uint32_t rtw_dbg_flags = 0;
 187         /*
 188          * RTW_DEBUG_ATTACH | RTW_DEBUG_TUNE |
 189          * RTW_DEBUG_ACCESS | RTW_DEBUG_INIT | RTW_DEBUG_PKTFILT |
 190          * RTW_DEBUG_RECV | RTW_DEBUG_XMIT | RTW_DEBUG_80211 | RTW_DEBUG_INTR |
 191          * RTW_DEBUG_PKTDUMP;
 192          */
 193 
 194 /*
 195  * Supported rates for 802.11b modes (in 500Kbps unit).
 196  */
 197 static const struct ieee80211_rateset rtw_rateset_11b =
 198         { 4, { 2, 4, 11, 22 } };
 199 
 200 int
 201 _info(struct modinfo *modinfop)
 202 {
 203         return (mod_info(&modlinkage, modinfop));
 204 }
 205 
 206 int
 207 _init(void)
 208 {
 209         int status;
 210 
 211         status = ddi_soft_state_init(&rtw_soft_state_p,
 212             sizeof (rtw_softc_t), 1);
 213         if (status != 0)
 214                 return (status);
 215 
 216         mac_init_ops(&rtw_dev_ops, "rtw");
 217         status = mod_install(&modlinkage);
 218         if (status != 0) {
 219                 mac_fini_ops(&rtw_dev_ops);
 220                 ddi_soft_state_fini(&rtw_soft_state_p);
 221         }
 222         return (status);
 223 }
 224 
 225 int
 226 _fini(void)
 227 {
 228         int status;
 229 
 230         status = mod_remove(&modlinkage);
 231         if (status == 0) {
 232                 mac_fini_ops(&rtw_dev_ops);
 233                 ddi_soft_state_fini(&rtw_soft_state_p);
 234         }
 235         return (status);
 236 }
 237 
 238 void
 239 rtw_dbg(uint32_t dbg_flags, const int8_t *fmt, ...)
 240 {
 241         va_list args;
 242 
 243         if (dbg_flags & rtw_dbg_flags) {
 244                 va_start(args, fmt);
 245                 vcmn_err(CE_CONT, fmt, args);
 246                 va_end(args);
 247         }
 248 }
 249 
 250 #ifdef DEBUG
 251 static void
 252 rtw_print_regs(struct rtw_regs *regs, const char *dvname, const char *where)
 253 {
 254 #define PRINTREG32(sc, reg)                             \
 255         RTW_DPRINTF(RTW_DEBUG_REGDUMP,                  \
 256             "%s: reg[ " #reg " / %03x ] = %08x\n",      \
 257             dvname, reg, RTW_READ(regs, reg))
 258 
 259 #define PRINTREG16(sc, reg)                             \
 260         RTW_DPRINTF(RTW_DEBUG_REGDUMP,                  \
 261             "%s: reg[ " #reg " / %03x ] = %04x\n",      \
 262             dvname, reg, RTW_READ16(regs, reg))
 263 
 264 #define PRINTREG8(sc, reg)                              \
 265         RTW_DPRINTF(RTW_DEBUG_REGDUMP,                  \
 266             "%s: reg[ " #reg " / %03x ] = %02x\n",      \
 267             dvname, reg, RTW_READ8(regs, reg))
 268 
 269         RTW_DPRINTF(RTW_DEBUG_REGDUMP, "%s: %s\n", dvname, where);
 270 
 271         PRINTREG32(regs, RTW_IDR0);
 272         PRINTREG32(regs, RTW_IDR1);
 273         PRINTREG32(regs, RTW_MAR0);
 274         PRINTREG32(regs, RTW_MAR1);
 275         PRINTREG32(regs, RTW_TSFTRL);
 276         PRINTREG32(regs, RTW_TSFTRH);
 277         PRINTREG32(regs, RTW_TLPDA);
 278         PRINTREG32(regs, RTW_TNPDA);
 279         PRINTREG32(regs, RTW_THPDA);
 280         PRINTREG32(regs, RTW_TCR);
 281         PRINTREG32(regs, RTW_RCR);
 282         PRINTREG32(regs, RTW_TINT);
 283         PRINTREG32(regs, RTW_TBDA);
 284         PRINTREG32(regs, RTW_ANAPARM);
 285         PRINTREG32(regs, RTW_BB);
 286         PRINTREG32(regs, RTW_PHYCFG);
 287         PRINTREG32(regs, RTW_WAKEUP0L);
 288         PRINTREG32(regs, RTW_WAKEUP0H);
 289         PRINTREG32(regs, RTW_WAKEUP1L);
 290         PRINTREG32(regs, RTW_WAKEUP1H);
 291         PRINTREG32(regs, RTW_WAKEUP2LL);
 292         PRINTREG32(regs, RTW_WAKEUP2LH);
 293         PRINTREG32(regs, RTW_WAKEUP2HL);
 294         PRINTREG32(regs, RTW_WAKEUP2HH);
 295         PRINTREG32(regs, RTW_WAKEUP3LL);
 296         PRINTREG32(regs, RTW_WAKEUP3LH);
 297         PRINTREG32(regs, RTW_WAKEUP3HL);
 298         PRINTREG32(regs, RTW_WAKEUP3HH);
 299         PRINTREG32(regs, RTW_WAKEUP4LL);
 300         PRINTREG32(regs, RTW_WAKEUP4LH);
 301         PRINTREG32(regs, RTW_WAKEUP4HL);
 302         PRINTREG32(regs, RTW_WAKEUP4HH);
 303         PRINTREG32(regs, RTW_DK0);
 304         PRINTREG32(regs, RTW_DK1);
 305         PRINTREG32(regs, RTW_DK2);
 306         PRINTREG32(regs, RTW_DK3);
 307         PRINTREG32(regs, RTW_RETRYCTR);
 308         PRINTREG32(regs, RTW_RDSAR);
 309         PRINTREG32(regs, RTW_FER);
 310         PRINTREG32(regs, RTW_FEMR);
 311         PRINTREG32(regs, RTW_FPSR);
 312         PRINTREG32(regs, RTW_FFER);
 313 
 314         /* 16-bit registers */
 315         PRINTREG16(regs, RTW_BRSR);
 316         PRINTREG16(regs, RTW_IMR);
 317         PRINTREG16(regs, RTW_ISR);
 318         PRINTREG16(regs, RTW_BCNITV);
 319         PRINTREG16(regs, RTW_ATIMWND);
 320         PRINTREG16(regs, RTW_BINTRITV);
 321         PRINTREG16(regs, RTW_ATIMTRITV);
 322         PRINTREG16(regs, RTW_CRC16ERR);
 323         PRINTREG16(regs, RTW_CRC0);
 324         PRINTREG16(regs, RTW_CRC1);
 325         PRINTREG16(regs, RTW_CRC2);
 326         PRINTREG16(regs, RTW_CRC3);
 327         PRINTREG16(regs, RTW_CRC4);
 328         PRINTREG16(regs, RTW_CWR);
 329 
 330         /* 8-bit registers */
 331         PRINTREG8(regs, RTW_CR);
 332         PRINTREG8(regs, RTW_9346CR);
 333         PRINTREG8(regs, RTW_CONFIG0);
 334         PRINTREG8(regs, RTW_CONFIG1);
 335         PRINTREG8(regs, RTW_CONFIG2);
 336         PRINTREG8(regs, RTW_MSR);
 337         PRINTREG8(regs, RTW_CONFIG3);
 338         PRINTREG8(regs, RTW_CONFIG4);
 339         PRINTREG8(regs, RTW_TESTR);
 340         PRINTREG8(regs, RTW_PSR);
 341         PRINTREG8(regs, RTW_SCR);
 342         PRINTREG8(regs, RTW_PHYDELAY);
 343         PRINTREG8(regs, RTW_CRCOUNT);
 344         PRINTREG8(regs, RTW_PHYADDR);
 345         PRINTREG8(regs, RTW_PHYDATAW);
 346         PRINTREG8(regs, RTW_PHYDATAR);
 347         PRINTREG8(regs, RTW_CONFIG5);
 348         PRINTREG8(regs, RTW_TPPOLL);
 349 
 350         PRINTREG16(regs, RTW_BSSID16);
 351         PRINTREG32(regs, RTW_BSSID32);
 352 #undef PRINTREG32
 353 #undef PRINTREG16
 354 #undef PRINTREG8
 355 }
 356 
 357 #endif /* DEBUG */
 358 static const char *
 359 rtw_access_string(enum rtw_access access)
 360 {
 361         switch (access) {
 362         case RTW_ACCESS_NONE:
 363                 return ("none");
 364         case RTW_ACCESS_CONFIG:
 365                 return ("config");
 366         case RTW_ACCESS_ANAPARM:
 367                 return ("anaparm");
 368         default:
 369                 return ("unknown");
 370         }
 371 }
 372 
 373 /*
 374  * Enable registers, switch register banks.
 375  */
 376 void
 377 rtw_config0123_enable(struct rtw_regs *regs, int enable)
 378 {
 379         uint8_t ecr;
 380         ecr = RTW_READ8(regs, RTW_9346CR);
 381         ecr &= ~(RTW_9346CR_EEM_MASK | RTW_9346CR_EECS | RTW_9346CR_EESK);
 382         if (enable)
 383                 ecr |= RTW_9346CR_EEM_CONFIG;
 384         else {
 385                 RTW_WBW(regs, RTW_9346CR, MAX(RTW_CONFIG0, RTW_CONFIG3));
 386                 ecr |= RTW_9346CR_EEM_NORMAL;
 387         }
 388         RTW_WRITE8(regs, RTW_9346CR, ecr);
 389         RTW_SYNC(regs, RTW_9346CR, RTW_9346CR);
 390 }
 391 
 392 /*
 393  * requires rtw_config0123_enable(, 1)
 394  */
 395 void
 396 rtw_anaparm_enable(struct rtw_regs *regs, int enable)
 397 {
 398         uint8_t cfg3;
 399 
 400         cfg3 = RTW_READ8(regs, RTW_CONFIG3);
 401         cfg3 |= RTW_CONFIG3_CLKRUNEN;
 402         if (enable)
 403                 cfg3 |= RTW_CONFIG3_PARMEN;
 404         else
 405                 cfg3 &= ~RTW_CONFIG3_PARMEN;
 406         RTW_WRITE8(regs, RTW_CONFIG3, cfg3);
 407         RTW_SYNC(regs, RTW_CONFIG3, RTW_CONFIG3);
 408 }
 409 
 410 /*
 411  * requires rtw_anaparm_enable(, 1)
 412  */
 413 void
 414 rtw_txdac_enable(rtw_softc_t *rsc, int enable)
 415 {
 416         uint32_t anaparm;
 417         struct rtw_regs *regs = &rsc->sc_regs;
 418 
 419         anaparm = RTW_READ(regs, RTW_ANAPARM);
 420         if (enable)
 421                 anaparm &= ~RTW_ANAPARM_TXDACOFF;
 422         else
 423                 anaparm |= RTW_ANAPARM_TXDACOFF;
 424         RTW_WRITE(regs, RTW_ANAPARM, anaparm);
 425         RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM);
 426 }
 427 
 428 static void
 429 rtw_set_access1(struct rtw_regs *regs, enum rtw_access naccess)
 430 {
 431         ASSERT(naccess >= RTW_ACCESS_NONE && naccess <= RTW_ACCESS_ANAPARM);
 432         ASSERT(regs->r_access >= RTW_ACCESS_NONE &&
 433             regs->r_access <= RTW_ACCESS_ANAPARM);
 434 
 435         if (naccess == regs->r_access)
 436                 return;
 437 
 438         switch (naccess) {
 439         case RTW_ACCESS_NONE:
 440                 switch (regs->r_access) {
 441                 case RTW_ACCESS_ANAPARM:
 442                         rtw_anaparm_enable(regs, 0);
 443                         /*FALLTHROUGH*/
 444                 case RTW_ACCESS_CONFIG:
 445                         rtw_config0123_enable(regs, 0);
 446                         /*FALLTHROUGH*/
 447                 case RTW_ACCESS_NONE:
 448                         break;
 449                 }
 450                 break;
 451         case RTW_ACCESS_CONFIG:
 452                 switch (regs->r_access) {
 453                 case RTW_ACCESS_NONE:
 454                         rtw_config0123_enable(regs, 1);
 455                         /*FALLTHROUGH*/
 456                 case RTW_ACCESS_CONFIG:
 457                         break;
 458                 case RTW_ACCESS_ANAPARM:
 459                         rtw_anaparm_enable(regs, 0);
 460                         break;
 461                 }
 462                 break;
 463         case RTW_ACCESS_ANAPARM:
 464                 switch (regs->r_access) {
 465                 case RTW_ACCESS_NONE:
 466                         rtw_config0123_enable(regs, 1);
 467                         /*FALLTHROUGH*/
 468                 case RTW_ACCESS_CONFIG:
 469                         rtw_anaparm_enable(regs, 1);
 470                         /*FALLTHROUGH*/
 471                 case RTW_ACCESS_ANAPARM:
 472                         break;
 473                 }
 474                 break;
 475         }
 476 }
 477 
 478 void
 479 rtw_set_access(struct rtw_regs *regs, enum rtw_access access)
 480 {
 481         rtw_set_access1(regs, access);
 482         RTW_DPRINTF(RTW_DEBUG_ACCESS,
 483             "%s: access %s -> %s\n", __func__,
 484             rtw_access_string(regs->r_access),
 485             rtw_access_string(access));
 486         regs->r_access = access;
 487 }
 488 
 489 
 490 void
 491 rtw_continuous_tx_enable(rtw_softc_t *rsc, int enable)
 492 {
 493         struct rtw_regs *regs = &rsc->sc_regs;
 494 
 495         uint32_t tcr;
 496         tcr = RTW_READ(regs, RTW_TCR);
 497         tcr &= ~RTW_TCR_LBK_MASK;
 498         if (enable)
 499                 tcr |= RTW_TCR_LBK_CONT;
 500         else
 501                 tcr |= RTW_TCR_LBK_NORMAL;
 502         RTW_WRITE(regs, RTW_TCR, tcr);
 503         RTW_SYNC(regs, RTW_TCR, RTW_TCR);
 504         rtw_set_access(regs, RTW_ACCESS_ANAPARM);
 505         rtw_txdac_enable(rsc, !enable);
 506         rtw_set_access(regs, RTW_ACCESS_ANAPARM);
 507         rtw_set_access(regs, RTW_ACCESS_NONE);
 508 }
 509 
 510 static int
 511 rtw_chip_reset1(struct rtw_regs *regs, const char *dvname)
 512 {
 513         uint8_t cr;
 514         int i;
 515 
 516         RTW_WRITE8(regs, RTW_CR, RTW_CR_RST);
 517 
 518         RTW_WBR(regs, RTW_CR, RTW_CR);
 519 
 520         for (i = 0; i < 1000; i++) {
 521                 cr = RTW_READ8(regs, RTW_CR);
 522                 if ((cr & RTW_CR_RST) == 0) {
 523                         RTW_DPRINTF(RTW_DEBUG_RESET,
 524                             "%s: reset in %dus\n", dvname, i);
 525                         return (0);
 526                 }
 527                 RTW_RBR(regs, RTW_CR, RTW_CR);
 528                 DELAY(10); /* 10us */
 529         }
 530 
 531         cmn_err(CE_WARN, "%s: reset failed\n", dvname);
 532         return (ETIMEDOUT);
 533 }
 534 
 535 static int
 536 rtw_chip_reset(struct rtw_regs *regs, const char *dvname)
 537 {
 538         RTW_WBW(regs, RTW_CR, RTW_TCR);
 539         return (rtw_chip_reset1(regs, dvname));
 540 }
 541 
 542 static void
 543 rtw_disable_interrupts(struct rtw_regs *regs)
 544 {
 545         RTW_WRITE16(regs, RTW_IMR, 0);
 546         RTW_WRITE16(regs, RTW_ISR, 0xffff);
 547         (void) RTW_READ16(regs, RTW_IMR);
 548 }
 549 
 550 static void
 551 rtw_enable_interrupts(rtw_softc_t *rsc)
 552 {
 553         struct rtw_regs *regs = &rsc->sc_regs;
 554 
 555         rsc->sc_inten = RTW_INTR_RX | RTW_INTR_TX | RTW_INTR_IOERROR;
 556 
 557         RTW_WRITE16(regs, RTW_IMR, rsc->sc_inten);
 558         RTW_WRITE16(regs, RTW_ISR, 0xffff);
 559 
 560         /* XXX necessary? */
 561         if (rsc->sc_intr_ack != NULL)
 562                 (*rsc->sc_intr_ack)(regs);
 563 }
 564 
 565 static int
 566 rtw_recall_eeprom(struct rtw_regs *regs, const char *dvname)
 567 {
 568         int i;
 569         uint8_t ecr;
 570 
 571         ecr = RTW_READ8(regs, RTW_9346CR);
 572         ecr = (ecr & ~RTW_9346CR_EEM_MASK) | RTW_9346CR_EEM_AUTOLOAD;
 573         RTW_WRITE8(regs, RTW_9346CR, ecr);
 574 
 575         RTW_WBR(regs, RTW_9346CR, RTW_9346CR);
 576 
 577         /* wait 25ms for completion */
 578         for (i = 0; i < 250; i++) {
 579                 ecr = RTW_READ8(regs, RTW_9346CR);
 580                 if ((ecr & RTW_9346CR_EEM_MASK) == RTW_9346CR_EEM_NORMAL) {
 581                         RTW_DPRINTF(RTW_DEBUG_RESET,
 582                             "%s: recall EEPROM in %dus\n", dvname, i * 100);
 583                         return (0);
 584                 }
 585                 RTW_RBR(regs, RTW_9346CR, RTW_9346CR);
 586                 DELAY(100);
 587         }
 588         cmn_err(CE_WARN, "%s: recall EEPROM failed\n", dvname);
 589         return (ETIMEDOUT);
 590 }
 591 
 592 static int
 593 rtw_reset(rtw_softc_t *rsc)
 594 {
 595         int rc;
 596 
 597         rc = rtw_chip_reset(&rsc->sc_regs, "rtw");
 598         if (rc != 0)
 599                 return (rc);
 600 
 601         (void) rtw_recall_eeprom(&rsc->sc_regs, "rtw");
 602         return (0);
 603 }
 604 
 605 void
 606 rtw_set_mode(struct rtw_regs *regs, int mode)
 607 {
 608         uint8_t command;
 609         command = RTW_READ8(regs, RTW_9346CR);
 610         command = command &~ RTW_EPROM_CMD_OPERATING_MODE_MASK;
 611         command = command | (mode<<RTW_EPROM_CMD_OPERATING_MODE_SHIFT);
 612         command = command &~ (1<<RTW_EPROM_CS_SHIFT);
 613         command = command &~ (1<<RTW_EPROM_CK_SHIFT);
 614         RTW_WRITE8(regs, RTW_9346CR, command);
 615 }
 616 
 617 void
 618 rtw_dma_start(struct rtw_regs *regs, int priority)
 619 {
 620         uint8_t check = 0;
 621 
 622         check = RTW_READ8(regs, RTW_TPPOLL);
 623         switch (priority) {
 624         case (0):
 625                 RTW_WRITE8(regs, RTW_TPPOLL,
 626                     (1<< RTW_TX_DMA_POLLING_LOWPRIORITY_SHIFT) | check);
 627                 break;
 628         case (1):
 629                 RTW_WRITE8(regs, RTW_TPPOLL,
 630                     (1<< RTW_TX_DMA_POLLING_NORMPRIORITY_SHIFT) | check);
 631                 break;
 632         case (2):
 633                 RTW_WRITE8(regs, RTW_TPPOLL,
 634                     (1<< RTW_TX_DMA_POLLING_HIPRIORITY_SHIFT) | check);
 635                 break;
 636         }
 637         (void) RTW_READ8(regs, RTW_TPPOLL);
 638 }
 639 
 640 void
 641 rtw_beacon_tx_disable(struct rtw_regs *regs)
 642 {
 643         uint8_t mask = 0;
 644         mask |= (1 << RTW_TX_DMA_STOP_BEACON_SHIFT);
 645         rtw_set_mode(regs, RTW_EPROM_CMD_CONFIG);
 646         RTW_WRITE8(regs, RTW_TPPOLL, mask);
 647         rtw_set_mode(regs, RTW_EPROM_CMD_NORMAL);
 648 }
 649 
 650 static void
 651 rtw_io_enable(rtw_softc_t *rsc, uint8_t flags, int enable);
 652 
 653 void
 654 rtw_rtx_disable(rtw_softc_t *rsc)
 655 {
 656         struct rtw_regs *regs = &rsc->sc_regs;
 657 
 658         rtw_io_enable(rsc, RTW_CR_RE|RTW_CR_TE, 0);
 659         (void) RTW_READ8(regs, RTW_CR);
 660 }
 661 
 662 static void
 663 rtw_srom_free(struct rtw_srom *sr)
 664 {
 665         if (sr->sr_content == NULL)
 666                 return;
 667         kmem_free(sr->sr_content, sr->sr_size);
 668         sr->sr_size = 0;
 669         sr->sr_content = NULL;
 670 }
 671 
 672 /*ARGSUSED*/
 673 static void
 674 rtw_srom_defaults(struct rtw_srom *sr, uint32_t *flags, uint8_t *cs_threshold,
 675     enum rtw_rfchipid *rfchipid, uint32_t *rcr)
 676 {
 677         *flags |= (RTW_F_DIGPHY|RTW_F_ANTDIV);
 678         *cs_threshold = RTW_SR_ENERGYDETTHR_DEFAULT;
 679         *rcr |= RTW_RCR_ENCS1;
 680         *rfchipid = RTW_RFCHIPID_PHILIPS;
 681 }
 682 
 683 static int
 684 rtw_srom_parse(struct rtw_srom *sr, uint32_t *flags, uint8_t *cs_threshold,
 685     enum rtw_rfchipid *rfchipid, uint32_t *rcr, enum rtw_locale *locale,
 686     const char *dvname)
 687 {
 688         int i;
 689         const char *rfname, *paname;
 690         char scratch[sizeof ("unknown 0xXX")];
 691         uint16_t version;
 692         uint8_t mac[IEEE80211_ADDR_LEN];
 693 
 694         *flags &= ~(RTW_F_DIGPHY|RTW_F_DFLANTB|RTW_F_ANTDIV);
 695         *rcr &= ~(RTW_RCR_ENCS1 | RTW_RCR_ENCS2);
 696 
 697         version = RTW_SR_GET16(sr, RTW_SR_VERSION);
 698         RTW_DPRINTF(RTW_DEBUG_IOSTATE, "%s: SROM version %d.%d", dvname,
 699             version >> 8, version & 0xff);
 700 
 701         if (version <= 0x0101) {
 702                 cmn_err(CE_NOTE, " is not understood, limping along "
 703                     "with defaults\n");
 704                 rtw_srom_defaults(sr, flags, cs_threshold, rfchipid, rcr);
 705                 return (0);
 706         }
 707 
 708         for (i = 0; i < IEEE80211_ADDR_LEN; i++)
 709                 mac[i] = RTW_SR_GET(sr, RTW_SR_MAC + i);
 710 
 711         RTW_DPRINTF(RTW_DEBUG_ATTACH,
 712             "%s: EEPROM MAC %s\n", dvname, mac);
 713 
 714         *cs_threshold = RTW_SR_GET(sr, RTW_SR_ENERGYDETTHR);
 715 
 716         if ((RTW_SR_GET(sr, RTW_SR_CONFIG2) & RTW_CONFIG2_ANT) != 0)
 717                 *flags |= RTW_F_ANTDIV;
 718 
 719         /*
 720          * Note well: the sense of the RTW_SR_RFPARM_DIGPHY bit seems
 721          * to be reversed.
 722          */
 723         if ((RTW_SR_GET(sr, RTW_SR_RFPARM) & RTW_SR_RFPARM_DIGPHY) == 0)
 724                 *flags |= RTW_F_DIGPHY;
 725         if ((RTW_SR_GET(sr, RTW_SR_RFPARM) & RTW_SR_RFPARM_DFLANTB) != 0)
 726                 *flags |= RTW_F_DFLANTB;
 727 
 728         *rcr |= LSHIFT(MASK_AND_RSHIFT(RTW_SR_GET(sr, RTW_SR_RFPARM),
 729             RTW_SR_RFPARM_CS_MASK), RTW_RCR_ENCS1);
 730 
 731         *rfchipid = RTW_SR_GET(sr, RTW_SR_RFCHIPID);
 732         switch (*rfchipid) {
 733         case RTW_RFCHIPID_GCT:          /* this combo seen in the wild */
 734                 rfname = "GCT GRF5101";
 735                 paname = "Winspring WS9901";
 736                 break;
 737         case RTW_RFCHIPID_MAXIM:
 738                 rfname = "Maxim MAX2820";       /* guess */
 739                 paname = "Maxim MAX2422";       /* guess */
 740                 break;
 741         case RTW_RFCHIPID_INTERSIL:
 742                 rfname = "Intersil HFA3873";    /* guess */
 743                 paname = "Intersil <unknown>";
 744                 break;
 745         case RTW_RFCHIPID_PHILIPS:      /* this combo seen in the wild */
 746                 rfname = "Philips SA2400A";
 747                 paname = "Philips SA2411";
 748                 break;
 749         case RTW_RFCHIPID_RFMD:
 750                 /*
 751                  * this is the same front-end as an atw(4)!
 752                  */
 753                 rfname = "RFMD RF2948B, "       /* mentioned in Realtek docs */
 754                     "LNA: RFMD RF2494, "        /* mentioned in Realtek docs */
 755                     "SYN: Silicon Labs Si4126";
 756                 paname = "RFMD RF2189";         /* mentioned in Realtek docs */
 757                 break;
 758         case RTW_RFCHIPID_RESERVED:
 759                 rfname = paname = "reserved";
 760                 break;
 761         default:
 762                 (void) snprintf(scratch, sizeof (scratch),
 763                     "unknown 0x%02x", *rfchipid);
 764                 rfname = paname = scratch;
 765         }
 766         RTW_DPRINTF(RTW_DEBUG_PHY, "%s: RF: %s, PA: %s\n",
 767             dvname, rfname, paname);
 768 
 769         switch (RTW_SR_GET(sr, RTW_SR_CONFIG0) & RTW_CONFIG0_GL_MASK) {
 770         case RTW_CONFIG0_GL_USA:
 771                 *locale = RTW_LOCALE_USA;
 772                 break;
 773         case RTW_CONFIG0_GL_EUROPE:
 774                 *locale = RTW_LOCALE_EUROPE;
 775                 break;
 776         case RTW_CONFIG0_GL_JAPAN:
 777                 *locale = RTW_LOCALE_JAPAN;
 778                 break;
 779         default:
 780                 *locale = RTW_LOCALE_UNKNOWN;
 781                 break;
 782         }
 783         return (0);
 784 }
 785 
 786 /*
 787  * Returns -1 on failure.
 788  */
 789 static int
 790 rtw_srom_read(struct rtw_regs *regs, uint32_t flags, struct rtw_srom *sr,
 791     const char *dvname)
 792 {
 793         int rc;
 794         struct seeprom_descriptor sd;
 795         uint8_t ecr;
 796 
 797         (void) memset(&sd, 0, sizeof (sd));
 798 
 799         ecr = RTW_READ8(regs, RTW_9346CR);
 800 
 801         if ((flags & RTW_F_9356SROM) != 0) {
 802                 RTW_DPRINTF(RTW_DEBUG_ATTACH, "%s: 93c56 SROM\n", dvname);
 803                 sr->sr_size = 256;
 804                 sd.sd_chip = C56_66;
 805         } else {
 806                 RTW_DPRINTF(RTW_DEBUG_ATTACH, "%s: 93c46 SROM\n", dvname);
 807                 sr->sr_size = 128;
 808                 sd.sd_chip = C46;
 809         }
 810 
 811         ecr &= ~(RTW_9346CR_EEDI | RTW_9346CR_EEDO | RTW_9346CR_EESK |
 812             RTW_9346CR_EEM_MASK | RTW_9346CR_EECS);
 813         ecr |= RTW_9346CR_EEM_PROGRAM;
 814 
 815         RTW_WRITE8(regs, RTW_9346CR, ecr);
 816 
 817         sr->sr_content = kmem_zalloc(sr->sr_size, KM_SLEEP);
 818 
 819         (void) memset(sr->sr_content, 0, sr->sr_size);
 820 
 821         /*
 822          * RTL8180 has a single 8-bit register for controlling the
 823          * 93cx6 SROM.  There is no "ready" bit. The RTL8180
 824          * input/output sense is the reverse of read_seeprom's.
 825          */
 826         sd.sd_handle = regs->r_handle;
 827         sd.sd_base = regs->r_base;
 828         sd.sd_regsize = 1;
 829         sd.sd_control_offset = RTW_9346CR;
 830         sd.sd_status_offset = RTW_9346CR;
 831         sd.sd_dataout_offset = RTW_9346CR;
 832         sd.sd_CK = RTW_9346CR_EESK;
 833         sd.sd_CS = RTW_9346CR_EECS;
 834         sd.sd_DI = RTW_9346CR_EEDO;
 835         sd.sd_DO = RTW_9346CR_EEDI;
 836         /*
 837          * make read_seeprom enter EEPROM read/write mode
 838          */
 839         sd.sd_MS = ecr;
 840         sd.sd_RDY = 0;
 841 
 842         /*
 843          * TBD bus barriers
 844          */
 845         if (!read_seeprom(&sd, sr->sr_content, 0, sr->sr_size/2)) {
 846                 cmn_err(CE_WARN, "%s: could not read SROM\n", dvname);
 847                 kmem_free(sr->sr_content, sr->sr_size);
 848                 sr->sr_content = NULL;
 849                 return (-1);    /* XXX */
 850         }
 851 
 852         /*
 853          * end EEPROM read/write mode
 854          */
 855         RTW_WRITE8(regs, RTW_9346CR,
 856             (ecr & ~RTW_9346CR_EEM_MASK) | RTW_9346CR_EEM_NORMAL);
 857         RTW_WBRW(regs, RTW_9346CR, RTW_9346CR);
 858 
 859         if ((rc = rtw_recall_eeprom(regs, dvname)) != 0)
 860                 return (rc);
 861 
 862 #ifdef SROM_DEBUG
 863         {
 864                 int i;
 865                 RTW_DPRINTF(RTW_DEBUG_ATTACH,
 866                     "\n%s: serial ROM:\n\t", dvname);
 867                 for (i = 0; i < sr->sr_size/2; i++) {
 868                         RTW_DPRINTF(RTW_DEBUG_ATTACH,
 869                             "offset-0x%x: %04x", 2*i, sr->sr_content[i]);
 870                 }
 871         }
 872 #endif /* DEBUG */
 873         return (0);
 874 }
 875 
 876 static void
 877 rtw_set_rfprog(struct rtw_regs *regs, enum rtw_rfchipid rfchipid,
 878     const char *dvname)
 879 {
 880         uint8_t cfg4;
 881         const char *method;
 882 
 883         cfg4 = RTW_READ8(regs, RTW_CONFIG4) & ~RTW_CONFIG4_RFTYPE_MASK;
 884 
 885         switch (rfchipid) {
 886         default:
 887                 cfg4 |= LSHIFT(0, RTW_CONFIG4_RFTYPE_MASK);
 888                 method = "fallback";
 889                 break;
 890         case RTW_RFCHIPID_INTERSIL:
 891                 cfg4 |= RTW_CONFIG4_RFTYPE_INTERSIL;
 892                 method = "Intersil";
 893                 break;
 894         case RTW_RFCHIPID_PHILIPS:
 895                 cfg4 |= RTW_CONFIG4_RFTYPE_PHILIPS;
 896                 method = "Philips";
 897                 break;
 898         case RTW_RFCHIPID_GCT:  /* XXX a guess */
 899         case RTW_RFCHIPID_RFMD:
 900                 cfg4 |= RTW_CONFIG4_RFTYPE_RFMD;
 901                 method = "RFMD";
 902                 break;
 903         }
 904 
 905         RTW_WRITE8(regs, RTW_CONFIG4, cfg4);
 906 
 907         RTW_WBR(regs, RTW_CONFIG4, RTW_CONFIG4);
 908 
 909         RTW_DPRINTF(RTW_DEBUG_INIT,
 910             "%s: %s RF programming method, %02x\n", dvname, method,
 911             RTW_READ8(regs, RTW_CONFIG4));
 912 }
 913 
 914 static void
 915 rtw_init_channels(enum rtw_locale locale,
 916     struct ieee80211_channel (*chans)[IEEE80211_CHAN_MAX+1],
 917     const char *dvname)
 918 {
 919         int i;
 920         const char *name = NULL;
 921 #define ADD_CHANNEL(_chans, _chan) {                    \
 922         (*_chans)[_chan].ich_flags = IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK;\
 923         (*_chans)[_chan].ich_freq =                             \
 924             ieee80211_ieee2mhz(_chan, (*_chans)[_chan].ich_flags);\
 925 }
 926 
 927         switch (locale) {
 928         case RTW_LOCALE_USA:    /* 1-11 */
 929                 name = "USA";
 930                 for (i = 1; i <= 11; i++)
 931                         ADD_CHANNEL(chans, i);
 932                 break;
 933         case RTW_LOCALE_JAPAN:  /* 1-14 */
 934                 name = "Japan";
 935                 ADD_CHANNEL(chans, 14);
 936                 for (i = 1; i <= 14; i++)
 937                         ADD_CHANNEL(chans, i);
 938                 break;
 939         case RTW_LOCALE_EUROPE: /* 1-13 */
 940                 name = "Europe";
 941                 for (i = 1; i <= 13; i++)
 942                         ADD_CHANNEL(chans, i);
 943                 break;
 944         default:                        /* 10-11 allowed by most countries */
 945                 name = "<unknown>";
 946                 for (i = 10; i <= 11; i++)
 947                         ADD_CHANNEL(chans, i);
 948                 break;
 949         }
 950         RTW_DPRINTF(RTW_DEBUG_ATTACH, "%s: Geographic Location %s\n",
 951             dvname, name);
 952 #undef ADD_CHANNEL
 953 }
 954 
 955 static void
 956 rtw_set80211props(struct ieee80211com *ic)
 957 {
 958         ic->ic_phytype = IEEE80211_T_DS;
 959         ic->ic_opmode = IEEE80211_M_STA;
 960         ic->ic_caps = IEEE80211_C_PMGT | IEEE80211_C_IBSS |
 961             IEEE80211_C_SHPREAMBLE;
 962         /* IEEE80211_C_HOSTAP | IEEE80211_C_MONITOR | IEEE80211_C_WEP */
 963 
 964         ic->ic_sup_rates[IEEE80211_MODE_11B] = rtw_rateset_11b;
 965 }
 966 
 967 /*ARGSUSED*/
 968 static void
 969 rtw_identify_country(struct rtw_regs *regs, enum rtw_locale *locale,
 970     const char *dvname)
 971 {
 972         uint8_t cfg0 = RTW_READ8(regs, RTW_CONFIG0);
 973 
 974         switch (cfg0 & RTW_CONFIG0_GL_MASK) {
 975         case RTW_CONFIG0_GL_USA:
 976                 *locale = RTW_LOCALE_USA;
 977                 break;
 978         case RTW_CONFIG0_GL_JAPAN:
 979                 *locale = RTW_LOCALE_JAPAN;
 980                 break;
 981         case RTW_CONFIG0_GL_EUROPE:
 982                 *locale = RTW_LOCALE_EUROPE;
 983                 break;
 984         default:
 985                 *locale = RTW_LOCALE_UNKNOWN;
 986                 break;
 987         }
 988 }
 989 
 990 static int
 991 rtw_identify_sta(struct rtw_regs *regs, uint8_t *addr,
 992     const char *dvname)
 993 {
 994         uint32_t idr0 = RTW_READ(regs, RTW_IDR0),
 995             idr1 = RTW_READ(regs, RTW_IDR1);
 996 
 997         *addr = MASK_AND_RSHIFT(idr0, BITS(0,  7));
 998         *(addr + 1) = MASK_AND_RSHIFT(idr0, BITS(8,  15));
 999         *(addr + 2) = MASK_AND_RSHIFT(idr0, BITS(16, 23));
1000         *(addr + 3) = MASK_AND_RSHIFT(idr0, BITS(24, 31));
1001 
1002         *(addr + 4) = MASK_AND_RSHIFT(idr1, BITS(0,  7));
1003         *(addr + 5) = MASK_AND_RSHIFT(idr1, BITS(8, 15));
1004 
1005         RTW_DPRINTF(RTW_DEBUG_ATTACH,
1006             "%s: 802.11mac address %x:%x:%x:%x:%x:%x\n", dvname,
1007             *addr, *(addr+1), *(addr+2), *(addr+3), *(addr+4), *(addr+5));
1008 
1009         return (0);
1010 }
1011 
1012 static uint8_t
1013 rtw_chan2txpower(struct rtw_srom *sr, struct ieee80211com *ic,
1014     struct ieee80211_channel *chan)
1015 {
1016         uint32_t idx = RTW_SR_TXPOWER1 + ieee80211_chan2ieee(ic, chan) - 1;
1017         return (RTW_SR_GET(sr, idx));
1018 }
1019 
1020 static void
1021 rtw_rxdesc_init(rtw_softc_t *rsc, struct rtw_rxbuf *rbf, int idx, int is_last)
1022 {
1023         uint32_t ctl = 0;
1024         uint8_t *buf = (uint8_t *)rbf->bf_dma.mem_va;
1025 
1026         ASSERT(rbf != NULL);
1027         rbf->rxdesc->rd_buf = (rbf->bf_dma.cookie.dmac_address);
1028         bzero(buf, rbf->bf_dma.alength);
1029         RTW_DMA_SYNC(rbf->bf_dma, DDI_DMA_SYNC_FORDEV);
1030 
1031         ctl = (rbf->bf_dma.alength & 0xfff) | RTW_RXCTL_OWN;
1032 
1033         if (is_last)
1034                 ctl |= RTW_RXCTL_EOR;
1035 
1036         rbf->rxdesc->rd_ctl = (ctl);
1037         /* sync the mbuf */
1038 
1039         /* sync the descriptor */
1040         RTW_DMA_SYNC_DESC(rsc->sc_desc_dma,
1041             RTW_DESC_OFFSET(hd_rx, idx),
1042             sizeof (struct rtw_rxdesc),
1043             DDI_DMA_SYNC_FORDEV);
1044 }
1045 
1046 static void
1047 rtw_idle(struct rtw_regs *regs)
1048 {
1049         int active;
1050 
1051         /* request stop DMA; wait for packets to stop transmitting. */
1052 
1053         RTW_WRITE8(regs, RTW_TPPOLL, RTW_TPPOLL_SALL);
1054 
1055         for (active = 0; active < 300 &&
1056             (RTW_READ8(regs, RTW_TPPOLL) & RTW_TPPOLL_ALL) != 0; active++)
1057                 drv_usecwait(10);
1058 }
1059 
1060 static void
1061 rtw_io_enable(rtw_softc_t *rsc, uint8_t flags, int enable)
1062 {
1063         uint8_t cr;
1064         struct rtw_regs *regs = &rsc->sc_regs;
1065 
1066         RTW_DPRINTF(RTW_DEBUG_IOSTATE, "%s: %s 0x%02x\n", __func__,
1067             enable ? "enable" : "disable", flags);
1068 
1069         cr = RTW_READ8(regs, RTW_CR);
1070 
1071         /* The receive engine will always start at RDSAR.  */
1072         if (enable && (flags & ~cr & RTW_CR_RE)) {
1073                 RTW_DMA_SYNC_DESC(rsc->sc_desc_dma,
1074                     RTW_DESC_OFFSET(hd_rx, 0),
1075                     sizeof (struct rtw_rxdesc),
1076                     DDI_DMA_SYNC_FORCPU);
1077                 rsc->rx_next = 0;
1078                 rtw_rxdesc_init(rsc, rsc->rxbuf_h, 0, 0);
1079         }
1080 
1081         if (enable)
1082                 cr |= flags;
1083         else
1084                 cr &= ~flags;
1085         RTW_WRITE8(regs, RTW_CR, cr);
1086         (void) RTW_READ8(regs, RTW_CR);
1087 }
1088 
1089 /*
1090  * Allocate an area of memory and a DMA handle for accessing it
1091  */
1092 static int
1093 rtw_alloc_dma_mem(dev_info_t *devinfo, ddi_dma_attr_t *dma_attr,
1094         size_t memsize, ddi_device_acc_attr_t *attr_p, uint_t alloc_flags,
1095         uint_t bind_flags, dma_area_t *dma_p)
1096 {
1097         int err;
1098 
1099         /*
1100          * Allocate handle
1101          */
1102         err = ddi_dma_alloc_handle(devinfo, dma_attr,
1103             DDI_DMA_SLEEP, NULL, &dma_p->dma_hdl);
1104         if (err != DDI_SUCCESS)
1105                 return (DDI_FAILURE);
1106 
1107         /*
1108          * Allocate memory
1109          */
1110         err = ddi_dma_mem_alloc(dma_p->dma_hdl, memsize, attr_p,
1111             alloc_flags, DDI_DMA_SLEEP, NULL, &dma_p->mem_va,
1112             &dma_p->alength, &dma_p->acc_hdl);
1113         if (err != DDI_SUCCESS)
1114                 return (DDI_FAILURE);
1115 
1116         /*
1117          * Bind the two together
1118          */
1119         err = ddi_dma_addr_bind_handle(dma_p->dma_hdl, NULL,
1120             dma_p->mem_va, dma_p->alength, bind_flags,
1121             DDI_DMA_SLEEP, NULL, &dma_p->cookie, &dma_p->ncookies);
1122         if ((dma_p->ncookies != 1) || (err != DDI_DMA_MAPPED))
1123                 return (DDI_FAILURE);
1124 
1125         dma_p->nslots = ~0U;
1126         dma_p->size = ~0U;
1127         dma_p->token = ~0U;
1128         dma_p->offset = 0;
1129         return (DDI_SUCCESS);
1130 }
1131 
1132 /*
1133  * Free one allocated area of DMAable memory
1134  */
1135 static void
1136 rtw_free_dma_mem(dma_area_t *dma_p)
1137 {
1138         if (dma_p->dma_hdl != NULL) {
1139                 (void) ddi_dma_unbind_handle(dma_p->dma_hdl);
1140                 if (dma_p->acc_hdl != NULL) {
1141                         ddi_dma_mem_free(&dma_p->acc_hdl);
1142                         dma_p->acc_hdl = NULL;
1143                 }
1144                 ddi_dma_free_handle(&dma_p->dma_hdl);
1145                 dma_p->ncookies = 0;
1146                 dma_p->dma_hdl = NULL;
1147         }
1148 }
1149 
1150 static void
1151 rtw_dma_free(rtw_softc_t *rsc)
1152 {
1153         struct rtw_txbuf *txbf;
1154         struct rtw_rxbuf *rxbf;
1155         int i, j;
1156 
1157         /* Free TX DMA buffer */
1158         for (i = 0; i < RTW_NTXPRI; i++) {
1159                 txbf = list_head(&rsc->sc_txq[i].tx_free_list);
1160                 while (txbf != NULL) {
1161                         rtw_free_dma_mem(&txbf->bf_dma);
1162                         list_remove(&rsc->sc_txq[i].tx_free_list, txbf);
1163                         txbf = list_head(&rsc->sc_txq[i].tx_free_list);
1164                 }
1165                 list_destroy(&rsc->sc_txq[i].tx_free_list);
1166                 txbf = list_head(&rsc->sc_txq[i].tx_dirty_list);
1167                 while (txbf != NULL) {
1168                         rtw_free_dma_mem(&txbf->bf_dma);
1169                         list_remove(&rsc->sc_txq[i].tx_dirty_list, txbf);
1170                         txbf = list_head(&rsc->sc_txq[i].tx_dirty_list);
1171                 }
1172                 list_destroy(&rsc->sc_txq[i].tx_dirty_list);
1173 
1174                 if (rsc->sc_txq[i].txbuf_h != NULL) {
1175                         kmem_free(rsc->sc_txq[i].txbuf_h,
1176                             sizeof (struct rtw_txbuf) * rtw_qlen[i]);
1177                         rsc->sc_txq[i].txbuf_h = NULL;
1178                 }
1179         }
1180 
1181         /* Free RX DMA buffer */
1182         rxbf = rsc->rxbuf_h;
1183         for (j = 0; j < RTW_RXQLEN; j++) {
1184                 rtw_free_dma_mem(&rxbf->bf_dma);
1185                 rxbf++;
1186         }
1187 
1188         if (rsc->rxbuf_h != NULL) {
1189                 kmem_free(rsc->rxbuf_h,
1190                     sizeof (struct rtw_rxbuf) * RTW_RXQLEN);
1191                 rsc->rxbuf_h = NULL;
1192         }
1193 
1194         rtw_free_dma_mem(&rsc->sc_desc_dma);
1195 }
1196 
1197 static int
1198 rtw_dma_init(dev_info_t *devinfo, rtw_softc_t *rsc)
1199 {
1200         int i, j, err;
1201         size_t size;
1202         uint32_t buflen;
1203         struct rtw_txdesc *txds;
1204         struct rtw_rxdesc *rxds;
1205         struct rtw_txbuf *txbf;
1206         struct rtw_rxbuf *rxbf;
1207         uint32_t phybaseaddr, ptx[RTW_NTXPRI], prx;
1208         caddr_t virbaseaddr, vtx[RTW_NTXPRI], vrx;
1209 
1210         /* DMA buffer size for each TX/RX packet */
1211         rsc->sc_dmabuf_size = roundup(sizeof (struct ieee80211_frame) + 0x100 +
1212             IEEE80211_MTU + IEEE80211_CRC_LEN + sizeof (struct ieee80211_llc) +
1213             (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN +
1214             IEEE80211_WEP_CRCLEN), rsc->sc_cachelsz);
1215         size = sizeof (struct rtw_descs);
1216         err = rtw_alloc_dma_mem(devinfo, &dma_attr_desc, size,
1217             &rtw_desc_accattr,
1218             DDI_DMA_CONSISTENT, DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
1219             &rsc->sc_desc_dma);
1220         if (err != DDI_SUCCESS)
1221                 goto error;
1222         phybaseaddr = rsc->sc_desc_dma.cookie.dmac_address;
1223         virbaseaddr = rsc->sc_desc_dma.mem_va;
1224         ptx[0] = RTW_RING_BASE(phybaseaddr, hd_txlo);
1225         ptx[1] = RTW_RING_BASE(phybaseaddr, hd_txmd);
1226         ptx[2] = RTW_RING_BASE(phybaseaddr, hd_txhi);
1227         ptx[3] = RTW_RING_BASE(phybaseaddr, hd_bcn);
1228         vtx[0] = (caddr_t)(RTW_RING_BASE(virbaseaddr, hd_txlo));
1229         vtx[1] = (caddr_t)(RTW_RING_BASE(virbaseaddr, hd_txmd));
1230         vtx[2] = (caddr_t)(RTW_RING_BASE(virbaseaddr, hd_txhi));
1231         vtx[3] = (caddr_t)(RTW_RING_BASE(virbaseaddr, hd_bcn));
1232         for (i = 0; i < RTW_NTXPRI; i++) {
1233                 RTW_DPRINTF(RTW_DEBUG_DMA, "p[%d]=%x, v[%d]=%x", i, ptx[i],
1234                     i, vtx[i]);
1235                 RTW_DPRINTF(RTW_DEBUG_DMA, "ring%d:", i);
1236                 list_create(&rsc->sc_txq[i].tx_free_list,
1237                     sizeof (struct rtw_txbuf),
1238                     offsetof(struct rtw_txbuf, bf_node));
1239                 list_create(&rsc->sc_txq[i].tx_dirty_list,
1240                     sizeof (struct rtw_txbuf),
1241                     offsetof(struct rtw_txbuf, bf_node));
1242                 /* virtual address of the first descriptor */
1243                 rsc->sc_txq[i].txdesc_h =
1244                     (struct rtw_txdesc *)(uintptr_t)vtx[i];
1245 
1246                 txds = rsc->sc_txq[i].txdesc_h;
1247                 /* allocate data structures to describe TX DMA buffers */
1248                 buflen = sizeof (struct rtw_txbuf) * rtw_qlen[i];
1249                 txbf = (struct rtw_txbuf *)kmem_zalloc(buflen, KM_SLEEP);
1250                 rsc->sc_txq[i].txbuf_h = txbf;
1251                 for (j = 0; j < rtw_qlen[i]; j++, txbf++, txds++) {
1252                         txbf->txdesc = txds;
1253                         txbf->bf_daddr = ptx[i] + ((uintptr_t)txds -
1254                             (uintptr_t)rsc->sc_txq[i].txdesc_h);
1255                         list_insert_tail(&rsc->sc_txq[i].tx_free_list, txbf);
1256 
1257                         /* alloc DMA memory */
1258                         err = rtw_alloc_dma_mem(devinfo, &dma_attr_txbuf,
1259                             rsc->sc_dmabuf_size,
1260                             &rtw_buf_accattr,
1261                             DDI_DMA_STREAMING,
1262                             DDI_DMA_WRITE | DDI_DMA_STREAMING,
1263                             &txbf->bf_dma);
1264                         if (err != DDI_SUCCESS)
1265                                 goto error;
1266                         RTW_DPRINTF(RTW_DEBUG_DMA, "pbufaddr[%d]=%x",
1267                             j, txbf->bf_dma.cookie.dmac_address);
1268                 }
1269         }
1270         prx = RTW_RING_BASE(phybaseaddr, hd_rx);
1271         vrx = (caddr_t)(RTW_RING_BASE(virbaseaddr, hd_rx));
1272         /* virtual address of the first descriptor */
1273         rsc->rxdesc_h = (struct rtw_rxdesc *)(uintptr_t)vrx;
1274         rxds = rsc->rxdesc_h;
1275 
1276         /* allocate data structures to describe RX DMA buffers */
1277         buflen = sizeof (struct rtw_rxbuf) * RTW_RXQLEN;
1278         rxbf = (struct rtw_rxbuf *)kmem_zalloc(buflen, KM_SLEEP);
1279         rsc->rxbuf_h = rxbf;
1280 
1281         for (j = 0; j < RTW_RXQLEN; j++, rxbf++, rxds++) {
1282                 rxbf->rxdesc = rxds;
1283                 rxbf->bf_daddr =
1284                     prx + ((uintptr_t)rxds - (uintptr_t)rsc->rxdesc_h);
1285 
1286                 /* alloc DMA memory */
1287                 err = rtw_alloc_dma_mem(devinfo, &dma_attr_rxbuf,
1288                     rsc->sc_dmabuf_size,
1289                     &rtw_buf_accattr,
1290                     DDI_DMA_STREAMING, DDI_DMA_READ | DDI_DMA_STREAMING,
1291                     &rxbf->bf_dma);
1292                 if (err != DDI_SUCCESS)
1293                         goto error;
1294         }
1295 
1296         return (DDI_SUCCESS);
1297 error:
1298         return (DDI_FAILURE);
1299 }
1300 
1301 static void
1302 rtw_hwring_setup(rtw_softc_t *rsc)
1303 {
1304         struct rtw_regs *regs = &rsc->sc_regs;
1305         uint32_t phybaseaddr;
1306 
1307         phybaseaddr = rsc->sc_desc_dma.cookie.dmac_address;
1308 
1309         RTW_WRITE(regs, RTW_RDSAR, RTW_RING_BASE(phybaseaddr, hd_rx));
1310         RTW_WRITE(regs, RTW_TLPDA, RTW_RING_BASE(phybaseaddr, hd_txlo));
1311         RTW_WRITE(regs, RTW_TNPDA, RTW_RING_BASE(phybaseaddr, hd_txmd));
1312         RTW_WRITE(regs, RTW_THPDA, RTW_RING_BASE(phybaseaddr, hd_txhi));
1313         RTW_WRITE(regs, RTW_TBDA, RTW_RING_BASE(phybaseaddr, hd_bcn));
1314         rsc->hw_start = RTW_READ(regs, RTW_TNPDA);
1315         rsc->hw_go = RTW_READ(regs, RTW_TNPDA);
1316 }
1317 
1318 static void
1319 rtw_swring_setup(rtw_softc_t *rsc, int flag)
1320 {
1321         int i, j;
1322         int is_last;
1323         struct rtw_txbuf *txbf;
1324         struct rtw_rxbuf *rxbf;
1325         uint32_t phybaseaddr, ptx[RTW_NTXPRI], baddr_desc, taddr_desc;
1326 
1327         phybaseaddr = rsc->sc_desc_dma.cookie.dmac_address;
1328         ptx[0] = RTW_RING_BASE(phybaseaddr, hd_txlo);
1329         ptx[1] = RTW_RING_BASE(phybaseaddr, hd_txmd);
1330         ptx[2] = RTW_RING_BASE(phybaseaddr, hd_txhi);
1331         ptx[3] = RTW_RING_BASE(phybaseaddr, hd_bcn);
1332         RTW_DMA_SYNC(rsc->sc_desc_dma, DDI_DMA_SYNC_FORDEV);
1333         /* sync tx desc and tx buf */
1334         for (i = 0; i < RTW_NTXPRI; i++) {
1335                 rsc->sc_txq[i].tx_prod = rsc->sc_txq[i].tx_cons = 0;
1336                 rsc->sc_txq[i].tx_nfree = rtw_qlen[i];
1337                 txbf = list_head(&rsc->sc_txq[i].tx_free_list);
1338                 while (txbf != NULL) {
1339                         list_remove(&rsc->sc_txq[i].tx_free_list, txbf);
1340                         txbf = list_head(&rsc->sc_txq[i].tx_free_list);
1341                 }
1342                 txbf = list_head(&rsc->sc_txq[i].tx_dirty_list);
1343                 while (txbf != NULL) {
1344                         list_remove(&rsc->sc_txq[i].tx_dirty_list, txbf);
1345                         txbf = list_head(&rsc->sc_txq[i].tx_dirty_list);
1346                 }
1347                 txbf = rsc->sc_txq[i].txbuf_h;
1348                 baddr_desc = ptx[i];
1349                 taddr_desc = baddr_desc + sizeof (struct rtw_txdesc);
1350                 for (j = 0; j < rtw_qlen[i]; j++) {
1351                         list_insert_tail(&rsc->sc_txq[i].tx_free_list, txbf);
1352                         if (j == (rtw_qlen[i] - 1)) {
1353                                 is_last = 1;
1354                         } else {
1355                                 is_last = 0;
1356                         }
1357 
1358                         if (is_last) {
1359                                 txbf->txdesc->td_next = baddr_desc;
1360                         } else {
1361                                 txbf->txdesc->td_next = taddr_desc;
1362                         }
1363                         txbf->next_bf_daddr = txbf->txdesc->td_next;
1364                         RTW_DMA_SYNC(txbf->bf_dma, DDI_DMA_SYNC_FORDEV);
1365                         txbf->order = j;
1366                         txbf++;
1367                         taddr_desc += sizeof (struct rtw_txdesc);
1368                 }
1369         }
1370         if (!flag)
1371                 return;
1372 
1373         /* sync rx desc and rx buf */
1374         rsc->rx_next = 0;
1375         rxbf = rsc->rxbuf_h;
1376         for (j = 0; j < RTW_RXQLEN; j++) {
1377                 RTW_DMA_SYNC(rxbf->bf_dma, DDI_DMA_SYNC_FORCPU);
1378                 if (j == (RTW_RXQLEN - 1))
1379                         is_last = 1;
1380                 else
1381                         is_last = 0;
1382                 rtw_rxdesc_init(rsc, rxbf, j, is_last);
1383                 rxbf++;
1384         }
1385 }
1386 
1387 static void
1388 rtw_resume_ticks(rtw_softc_t *rsc)
1389 {
1390         RTW_WRITE(&rsc->sc_regs, RTW_TINT, 0xffffffff);
1391 }
1392 
1393 const char *
1394 rtw_pwrstate_string(enum rtw_pwrstate power)
1395 {
1396         switch (power) {
1397         case RTW_ON:
1398                 return ("on");
1399         case RTW_SLEEP:
1400                 return ("sleep");
1401         case RTW_OFF:
1402                 return ("off");
1403         default:
1404                 return ("unknown");
1405         }
1406 }
1407 
1408 /*
1409  * XXX For Maxim, I am using the RFMD settings gleaned from the
1410  * reference driver, plus a magic Maxim "ON" value that comes from
1411  * the Realtek document "Windows PG for Rtl8180."
1412  */
1413 /*ARGSUSED*/
1414 static void
1415 rtw_maxim_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power,
1416     int before_rf, int digphy)
1417 {
1418         uint32_t anaparm;
1419 
1420         anaparm = RTW_READ(regs, RTW_ANAPARM);
1421         anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF);
1422 
1423         switch (power) {
1424         case RTW_OFF:
1425                 if (before_rf)
1426                         return;
1427                 anaparm |= RTW_ANAPARM_RFPOW_MAXIM_OFF;
1428                 anaparm |= RTW_ANAPARM_TXDACOFF;
1429                 break;
1430         case RTW_SLEEP:
1431                 if (!before_rf)
1432                         return;
1433                 anaparm |= RTW_ANAPARM_RFPOW_MAXIM_SLEEP;
1434                 anaparm |= RTW_ANAPARM_TXDACOFF;
1435                 break;
1436         case RTW_ON:
1437                 if (!before_rf)
1438                         return;
1439                 anaparm |= RTW_ANAPARM_RFPOW_MAXIM_ON;
1440                 break;
1441         }
1442         RTW_DPRINTF(RTW_DEBUG_PWR,
1443             "%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n",
1444             __func__, rtw_pwrstate_string(power),
1445             (before_rf) ? "before" : "after", anaparm);
1446 
1447         RTW_WRITE(regs, RTW_ANAPARM, anaparm);
1448         RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM);
1449 }
1450 
1451 /*
1452  * XXX I am using the RFMD settings gleaned from the reference
1453  * driver.  They agree
1454  */
1455 /*ARGSUSED*/
1456 static void
1457 rtw_rfmd_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power,
1458     int before_rf, int digphy)
1459 {
1460         uint32_t anaparm;
1461 
1462         anaparm = RTW_READ(regs, RTW_ANAPARM);
1463         anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF);
1464 
1465         switch (power) {
1466         case RTW_OFF:
1467                 if (before_rf)
1468                         return;
1469                 anaparm |= RTW_ANAPARM_RFPOW_RFMD_OFF;
1470                 anaparm |= RTW_ANAPARM_TXDACOFF;
1471                 break;
1472         case RTW_SLEEP:
1473                 if (!before_rf)
1474                         return;
1475                 anaparm |= RTW_ANAPARM_RFPOW_RFMD_SLEEP;
1476                 anaparm |= RTW_ANAPARM_TXDACOFF;
1477                 break;
1478         case RTW_ON:
1479                 if (!before_rf)
1480                         return;
1481                 anaparm |= RTW_ANAPARM_RFPOW_RFMD_ON;
1482                 break;
1483         }
1484         RTW_DPRINTF(RTW_DEBUG_PWR,
1485             "%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n",
1486             __func__, rtw_pwrstate_string(power),
1487             (before_rf) ? "before" : "after", anaparm);
1488 
1489         RTW_WRITE(regs, RTW_ANAPARM, anaparm);
1490         RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM);
1491 }
1492 
1493 static void
1494 rtw_philips_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power,
1495     int before_rf, int digphy)
1496 {
1497         uint32_t anaparm;
1498 
1499         anaparm = RTW_READ(regs, RTW_ANAPARM);
1500         anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF);
1501 
1502         switch (power) {
1503         case RTW_OFF:
1504                 if (before_rf)
1505                         return;
1506                 anaparm |= RTW_ANAPARM_RFPOW_PHILIPS_OFF;
1507                 anaparm |= RTW_ANAPARM_TXDACOFF;
1508                 break;
1509         case RTW_SLEEP:
1510                 if (!before_rf)
1511                         return;
1512                 anaparm |= RTW_ANAPARM_RFPOW_PHILIPS_SLEEP;
1513                 anaparm |= RTW_ANAPARM_TXDACOFF;
1514                 break;
1515         case RTW_ON:
1516                 if (!before_rf)
1517                         return;
1518                 if (digphy) {
1519                         anaparm |= RTW_ANAPARM_RFPOW_DIG_PHILIPS_ON;
1520                         /* XXX guess */
1521                         anaparm |= RTW_ANAPARM_TXDACOFF;
1522                 } else
1523                         anaparm |= RTW_ANAPARM_RFPOW_ANA_PHILIPS_ON;
1524                 break;
1525         }
1526         RTW_DPRINTF(RTW_DEBUG_PWR,
1527             "%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n",
1528             __func__, rtw_pwrstate_string(power),
1529             (before_rf) ? "before" : "after", anaparm);
1530 
1531         RTW_WRITE(regs, RTW_ANAPARM, anaparm);
1532         RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM);
1533 }
1534 
1535 static void
1536 rtw_pwrstate0(rtw_softc_t *rsc, enum rtw_pwrstate power, int before_rf,
1537     int digphy)
1538 {
1539         struct rtw_regs *regs = &rsc->sc_regs;
1540 
1541         rtw_set_access(regs, RTW_ACCESS_ANAPARM);
1542 
1543         (*rsc->sc_pwrstate_cb)(regs, power, before_rf, digphy);
1544 
1545         rtw_set_access(regs, RTW_ACCESS_NONE);
1546 }
1547 
1548 static void
1549 rtw_rf_destroy(struct rtw_rf *rf)
1550 {
1551         (*rf->rf_destroy)(rf);
1552 }
1553 
1554 static int
1555 rtw_rf_pwrstate(struct rtw_rf *rf, enum rtw_pwrstate power)
1556 {
1557         return (*rf->rf_pwrstate)(rf, power);
1558 }
1559 
1560 static int
1561 rtw_pwrstate(rtw_softc_t *rsc, enum rtw_pwrstate power)
1562 {
1563         int rc;
1564 
1565         RTW_DPRINTF(RTW_DEBUG_PWR,
1566             "%s: %s->%s\n", __func__,
1567             rtw_pwrstate_string(rsc->sc_pwrstate), rtw_pwrstate_string(power));
1568 
1569         if (rsc->sc_pwrstate == power)
1570                 return (0);
1571 
1572         rtw_pwrstate0(rsc, power, 1, rsc->sc_flags & RTW_F_DIGPHY);
1573         rc = rtw_rf_pwrstate(rsc->sc_rf, power);
1574         rtw_pwrstate0(rsc, power, 0, rsc->sc_flags & RTW_F_DIGPHY);
1575 
1576         switch (power) {
1577         case RTW_ON:
1578                 /* TBD set LEDs */
1579                 break;
1580         case RTW_SLEEP:
1581                 /* TBD */
1582                 break;
1583         case RTW_OFF:
1584                 /* TBD */
1585                 break;
1586         }
1587         if (rc == 0)
1588                 rsc->sc_pwrstate = power;
1589         else
1590                 rsc->sc_pwrstate = RTW_OFF;
1591         return (rc);
1592 }
1593 
1594 void
1595 rtw_disable(rtw_softc_t *rsc)
1596 {
1597         int rc;
1598 
1599         if ((rsc->sc_flags & RTW_F_ENABLED) == 0)
1600                 return;
1601 
1602         /* turn off PHY */
1603         if ((rsc->sc_flags & RTW_F_INVALID) == 0 &&
1604             (rc = rtw_pwrstate(rsc, RTW_OFF)) != 0) {
1605                 cmn_err(CE_WARN, "failed to turn off PHY (%d)\n", rc);
1606         }
1607 
1608         if (rsc->sc_disable != NULL)
1609                 (*rsc->sc_disable)(rsc);
1610 
1611         rsc->sc_flags &= ~RTW_F_ENABLED;
1612 }
1613 
1614 int
1615 rtw_enable(rtw_softc_t *rsc)
1616 {
1617         if ((rsc->sc_flags & RTW_F_ENABLED) == 0) {
1618                 if (rsc->sc_enable != NULL && (*rsc->sc_enable)(rsc) != 0) {
1619                         cmn_err(CE_WARN, "device enable failed\n");
1620                         return (EIO);
1621                 }
1622                 rsc->sc_flags |= RTW_F_ENABLED;
1623                 if (rtw_pwrstate(rsc, RTW_ON) != 0)
1624                         cmn_err(CE_WARN, "PHY turn on failed\n");
1625         }
1626         return (0);
1627 }
1628 
1629 static void
1630 rtw_set_nettype(rtw_softc_t *rsc, enum ieee80211_opmode opmode)
1631 {
1632         uint8_t msr;
1633 
1634         /* I'm guessing that MSR is protected as CONFIG[0123] are. */
1635         rtw_set_access(&rsc->sc_regs, RTW_ACCESS_CONFIG);
1636 
1637         msr = RTW_READ8(&rsc->sc_regs, RTW_MSR) & ~RTW_MSR_NETYPE_MASK;
1638 
1639         switch (opmode) {
1640         case IEEE80211_M_AHDEMO:
1641         case IEEE80211_M_IBSS:
1642                 msr |= RTW_MSR_NETYPE_ADHOC_OK;
1643                 break;
1644         case IEEE80211_M_HOSTAP:
1645                 msr |= RTW_MSR_NETYPE_AP_OK;
1646                 break;
1647         case IEEE80211_M_STA:
1648                 msr |= RTW_MSR_NETYPE_INFRA_OK;
1649                 break;
1650         }
1651         RTW_WRITE8(&rsc->sc_regs, RTW_MSR, msr);
1652 
1653         rtw_set_access(&rsc->sc_regs, RTW_ACCESS_NONE);
1654 }
1655 
1656 static void
1657 rtw_pktfilt_load(rtw_softc_t *rsc)
1658 {
1659         struct rtw_regs *regs = &rsc->sc_regs;
1660         struct ieee80211com *ic = &rsc->sc_ic;
1661 
1662         /* XXX might be necessary to stop Rx/Tx engines while setting filters */
1663         rsc->sc_rcr &= ~RTW_RCR_PKTFILTER_MASK;
1664         rsc->sc_rcr &= ~(RTW_RCR_MXDMA_MASK | RTW_RCR_RXFTH_MASK);
1665 
1666         rsc->sc_rcr |= RTW_RCR_PKTFILTER_DEFAULT;
1667         /* MAC auto-reset PHY (huh?) */
1668         rsc->sc_rcr |= RTW_RCR_ENMARP;
1669         /* DMA whole Rx packets, only.  Set Tx DMA burst size to 1024 bytes. */
1670         rsc->sc_rcr |= RTW_RCR_RXFTH_WHOLE |RTW_RCR_MXDMA_1024;
1671 
1672         switch (ic->ic_opmode) {
1673         case IEEE80211_M_AHDEMO:
1674         case IEEE80211_M_IBSS:
1675                 /* receive broadcasts in our BSS */
1676                 rsc->sc_rcr |= RTW_RCR_ADD3;
1677                 break;
1678         default:
1679                 break;
1680         }
1681 #if 0
1682         /* XXX accept all broadcast if scanning */
1683         rsc->sc_rcr |= RTW_RCR_AB;   /* accept all broadcast */
1684 #endif
1685         RTW_WRITE(regs, RTW_MAR0, 0xffffffff);
1686         RTW_WRITE(regs, RTW_MAR1, 0xffffffff);
1687         rsc->sc_rcr |= RTW_RCR_AM;
1688         RTW_WRITE(regs, RTW_RCR, rsc->sc_rcr);
1689         RTW_SYNC(regs, RTW_MAR0, RTW_RCR); /* RTW_MAR0 < RTW_MAR1 < RTW_RCR */
1690 
1691         RTW_DPRINTF(RTW_DEBUG_PKTFILT,
1692             "RTW_MAR0 %08x RTW_MAR1 %08x RTW_RCR %08x\n",
1693             RTW_READ(regs, RTW_MAR0),
1694             RTW_READ(regs, RTW_MAR1), RTW_READ(regs, RTW_RCR));
1695         RTW_WRITE(regs, RTW_RCR, rsc->sc_rcr);
1696 }
1697 
1698 static void
1699 rtw_transmit_config(struct rtw_regs *regs)
1700 {
1701         uint32_t tcr;
1702 
1703         tcr = RTW_READ(regs, RTW_TCR);
1704 
1705         tcr |= RTW_TCR_CWMIN;
1706         tcr &= ~RTW_TCR_MXDMA_MASK;
1707         tcr |= RTW_TCR_MXDMA_1024;
1708         tcr |= RTW_TCR_SAT;             /* send ACK as fast as possible */
1709         tcr &= ~RTW_TCR_LBK_MASK;
1710         tcr |= RTW_TCR_LBK_NORMAL;      /* normal operating mode */
1711 
1712         /* set short/long retry limits */
1713         tcr &= ~(RTW_TCR_SRL_MASK|RTW_TCR_LRL_MASK);
1714         tcr |= LSHIFT(0x4, RTW_TCR_SRL_MASK) | LSHIFT(0x4, RTW_TCR_LRL_MASK);
1715 
1716         tcr &= ~RTW_TCR_CRC;        /* NIC appends CRC32 */
1717         RTW_WRITE(regs, RTW_TCR, tcr);
1718         RTW_SYNC(regs, RTW_TCR, RTW_TCR);
1719 }
1720 
1721 int
1722 rtw_refine_setting(rtw_softc_t *rsc)
1723 {
1724         struct rtw_regs *regs;
1725         int rc = 0;
1726 
1727         regs = &rsc->sc_regs;
1728         rc = rtw_reset(rsc);
1729         if (rc != 0)
1730                 return (-1);
1731 
1732         rtw_beacon_tx_disable(regs);
1733         rtw_io_enable(rsc, RTW_CR_RE|RTW_CR_TE, 1);
1734         rtw_set_mode(regs, RTW_EPROM_CMD_CONFIG);
1735 
1736         rtw_transmit_config(regs);
1737         rtw_pktfilt_load(rsc);
1738         rtw_set_access(regs, RTW_ACCESS_CONFIG);
1739         RTW_WRITE(regs, RTW_TINT, 0xffffffff);
1740         RTW_WRITE8(regs, RTW_MSR, 0x0); /* no link */
1741         RTW_WRITE16(regs, RTW_BRSR, 0);
1742 
1743         rtw_set_access(regs, RTW_ACCESS_ANAPARM);
1744         rtw_set_access(regs, RTW_ACCESS_NONE);
1745         RTW_WRITE(regs, RTW_FEMR, 0xffff);
1746         RTW_SYNC(regs, RTW_FEMR, RTW_FEMR);
1747         rtw_set_rfprog(regs, rsc->sc_rfchipid, "rtw");
1748 
1749         RTW_WRITE8(regs, RTW_PHYDELAY, rsc->sc_phydelay);
1750         RTW_WRITE8(regs, RTW_CRCOUNT, RTW_CRCOUNT_MAGIC);
1751         rtw_set_mode(regs, RTW_EPROM_CMD_NORMAL);
1752         return (0);
1753 }
1754 
1755 static int
1756 rtw_tune(rtw_softc_t *rsc)
1757 {
1758         struct ieee80211com *ic = &rsc->sc_ic;
1759         uint32_t chan;
1760         int rc;
1761         int antdiv = rsc->sc_flags & RTW_F_ANTDIV,
1762             dflantb = rsc->sc_flags & RTW_F_DFLANTB;
1763 
1764         ASSERT(ic->ic_curchan != NULL);
1765 
1766         chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
1767         RTW_DPRINTF(RTW_DEBUG_TUNE, "rtw: chan no = %x", chan);
1768 
1769         if (chan == IEEE80211_CHAN_ANY) {
1770                 cmn_err(CE_WARN, "%s: chan == IEEE80211_CHAN_ANY\n", __func__);
1771                 return (-1);
1772         }
1773 
1774         if (chan == rsc->sc_cur_chan) {
1775                 RTW_DPRINTF(RTW_DEBUG_TUNE,
1776                     "%s: already tuned chan %d\n", __func__, chan);
1777                 return (0);
1778         }
1779         rtw_idle(&rsc->sc_regs);
1780         rtw_io_enable(rsc, RTW_CR_RE | RTW_CR_TE, 0);
1781         ASSERT((rsc->sc_flags & RTW_F_ENABLED) != 0);
1782 
1783         if ((rc = rtw_phy_init(&rsc->sc_regs, rsc->sc_rf,
1784             rtw_chan2txpower(&rsc->sc_srom, ic, ic->ic_curchan),
1785             rsc->sc_csthr, ic->ic_curchan->ich_freq, antdiv,
1786             dflantb, RTW_ON)) != 0) {
1787                 /* XXX condition on powersaving */
1788                 cmn_err(CE_NOTE, "phy init failed\n");
1789         }
1790         rtw_io_enable(rsc, RTW_CR_RE | RTW_CR_TE, 1);
1791         rtw_resume_ticks(rsc);
1792         rsc->sc_cur_chan = chan;
1793         return (rc);
1794 }
1795 
1796 static int
1797 rtw_init(rtw_softc_t *rsc)
1798 {
1799         struct ieee80211com *ic = &rsc->sc_ic;
1800         int rc = 0;
1801 
1802         rtw_stop(rsc);
1803         mutex_enter(&rsc->sc_genlock);
1804         if ((rc = rtw_enable(rsc)) != 0)
1805                 goto out;
1806         rc = rtw_refine_setting(rsc);
1807         if (rc != 0) {
1808                 mutex_exit(&rsc->sc_genlock);
1809                 return (rc);
1810         }
1811         rtw_swring_setup(rsc, 1);
1812         rtw_hwring_setup(rsc);
1813         RTW_WRITE16(&rsc->sc_regs, RTW_BSSID16, 0x0);
1814         RTW_WRITE(&rsc->sc_regs, RTW_BSSID32, 0x0);
1815         rtw_enable_interrupts(rsc);
1816 
1817         ic->ic_ibss_chan = &ic->ic_sup_channels[1];
1818         ic->ic_curchan = ic->ic_ibss_chan;
1819         RTW_DPRINTF(RTW_DEBUG_TUNE, "%s: channel %d freq %d flags 0x%04x\n",
1820             __func__, ieee80211_chan2ieee(ic, ic->ic_curchan),
1821             ic->ic_curchan->ich_freq, ic->ic_curchan->ich_flags);
1822         rsc->sc_invalid = 0;
1823 out:
1824         mutex_exit(&rsc->sc_genlock);
1825         return (rc);
1826 }
1827 
1828 static struct rtw_rf *
1829 rtw_rf_attach(rtw_softc_t *rsc, enum rtw_rfchipid rfchipid, int digphy)
1830 {
1831         rtw_rf_write_t rf_write;
1832         struct rtw_rf *rf;
1833         int rtw_host_rfio;
1834 
1835         switch (rfchipid) {
1836         default:
1837                 rf_write = rtw_rf_hostwrite;
1838                 break;
1839         case RTW_RFCHIPID_INTERSIL:
1840         case RTW_RFCHIPID_PHILIPS:
1841         case RTW_RFCHIPID_GCT:  /* XXX a guess */
1842         case RTW_RFCHIPID_RFMD:
1843                 rtw_host_rfio = 1;
1844                 rf_write = (rtw_host_rfio) ? rtw_rf_hostwrite : rtw_rf_macwrite;
1845                 break;
1846         }
1847 
1848         switch (rfchipid) {
1849         case RTW_RFCHIPID_MAXIM:
1850                 rf = rtw_max2820_create(&rsc->sc_regs, rf_write, 0);
1851                 rsc->sc_pwrstate_cb = rtw_maxim_pwrstate;
1852                 break;
1853         case RTW_RFCHIPID_PHILIPS:
1854                 rf = rtw_sa2400_create(&rsc->sc_regs, rf_write, digphy);
1855                 rsc->sc_pwrstate_cb = rtw_philips_pwrstate;
1856                 break;
1857         case RTW_RFCHIPID_RFMD:
1858                 /* XXX RFMD has no RF constructor */
1859                 rsc->sc_pwrstate_cb = rtw_rfmd_pwrstate;
1860                 /*FALLTHROUGH*/
1861         default:
1862                 return (NULL);
1863         }
1864         if (rf != NULL) {
1865                 rf->rf_continuous_tx_cb =
1866                     (rtw_continuous_tx_cb_t)rtw_continuous_tx_enable;
1867                 rf->rf_continuous_tx_arg = (void *)rsc;
1868         }
1869         return (rf);
1870 }
1871 
1872 /*
1873  * Revision C and later use a different PHY delay setting than
1874  * revisions A and B.
1875  */
1876 static uint8_t
1877 rtw_check_phydelay(struct rtw_regs *regs, uint32_t rcr0)
1878 {
1879 #define REVAB (RTW_RCR_MXDMA_UNLIMITED | RTW_RCR_AICV)
1880 #define REVC (REVAB | RTW_RCR_RXFTH_WHOLE)
1881 
1882         uint8_t phydelay = LSHIFT(0x6, RTW_PHYDELAY_PHYDELAY);
1883 
1884         RTW_WRITE(regs, RTW_RCR, REVAB);
1885         RTW_WBW(regs, RTW_RCR, RTW_RCR);
1886         RTW_WRITE(regs, RTW_RCR, REVC);
1887 
1888         RTW_WBR(regs, RTW_RCR, RTW_RCR);
1889         if ((RTW_READ(regs, RTW_RCR) & REVC) == REVC)
1890                 phydelay |= RTW_PHYDELAY_REVC_MAGIC;
1891 
1892         RTW_WRITE(regs, RTW_RCR, rcr0); /* restore RCR */
1893         RTW_SYNC(regs, RTW_RCR, RTW_RCR);
1894 
1895         return (phydelay);
1896 #undef REVC
1897 }
1898 
1899 static void rtw_intr_rx(rtw_softc_t *rsc);
1900 static void rtw_ring_recycling(rtw_softc_t *rsc, uint16_t isr, uint32_t pri);
1901 
1902 static int
1903 rtw_get_rate(struct ieee80211com *ic)
1904 {
1905         uint8_t (*rates)[IEEE80211_RATE_MAXSIZE];
1906         int rate;
1907 
1908         rates = &ic->ic_bss->in_rates.ir_rates;
1909 
1910         if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE)
1911                 rate = ic->ic_fixed_rate;
1912         else if (ic->ic_state == IEEE80211_S_RUN)
1913                 rate = (*rates)[ic->ic_bss->in_txrate];
1914         else
1915                 rate = 0;
1916         return (rate & IEEE80211_RATE_VAL);
1917 }
1918 
1919 /*
1920  * Arguments in:
1921  *
1922  * paylen:  payload length (no FCS, no WEP header)
1923  *
1924  * hdrlen:  header length
1925  *
1926  * rate:    MSDU speed, units 500kb/s
1927  *
1928  * flags:   IEEE80211_F_SHPREAMBLE (use short preamble),
1929  *          IEEE80211_F_SHSLOT (use short slot length)
1930  *
1931  * Arguments out:
1932  *
1933  * d:       802.11 Duration field for RTS,
1934  *          802.11 Duration field for data frame,
1935  *          PLCP Length for data frame,
1936  *          residual octets at end of data slot
1937  */
1938 static int
1939 rtw_compute_duration1(int len, int use_ack, uint32_t flags, int rate,
1940     struct rtw_ieee80211_duration *d)
1941 {
1942         int pre, ctsrate;
1943         uint16_t ack, bitlen, data_dur, remainder;
1944 
1945         /*
1946          * RTS reserves medium for SIFS | CTS | SIFS | (DATA) | SIFS | ACK
1947          * DATA reserves medium for SIFS | ACK
1948          *
1949          * XXXMYC: no ACK on multicast/broadcast or control packets
1950          */
1951 
1952         bitlen = len * 8;
1953 
1954         pre = IEEE80211_DUR_DS_SIFS;
1955         if ((flags & IEEE80211_F_SHPREAMBLE) != 0)
1956                 pre += IEEE80211_DUR_DS_SHORT_PREAMBLE +
1957                     IEEE80211_DUR_DS_FAST_PLCPHDR;
1958         else
1959                 pre += IEEE80211_DUR_DS_LONG_PREAMBLE +
1960                     IEEE80211_DUR_DS_SLOW_PLCPHDR;
1961 
1962         d->d_residue = 0;
1963         data_dur = (bitlen * 2) / rate;
1964         remainder = (bitlen * 2) % rate;
1965         if (remainder != 0) {
1966                 if (rate == 22)
1967                         d->d_residue = (rate - remainder) / 16;
1968                 data_dur++;
1969         }
1970 
1971         switch (rate) {
1972         case 2:         /* 1 Mb/s */
1973         case 4:         /* 2 Mb/s */
1974                 /* 1 - 2 Mb/s WLAN: send ACK/CTS at 1 Mb/s */
1975                 ctsrate = 2;
1976                 break;
1977         case 11:        /* 5.5 Mb/s */
1978         case 22:        /* 11  Mb/s */
1979         case 44:        /* 22  Mb/s */
1980                 /* 5.5 - 11 Mb/s WLAN: send ACK/CTS at 2 Mb/s */
1981                 ctsrate = 4;
1982                 break;
1983         default:
1984                 /* TBD */
1985                 return (-1);
1986         }
1987 
1988         d->d_plcp_len = data_dur;
1989 
1990         ack = (use_ack) ? pre + (IEEE80211_DUR_DS_SLOW_ACK * 2) / ctsrate : 0;
1991 
1992         d->d_rts_dur =
1993             pre + (IEEE80211_DUR_DS_SLOW_CTS * 2) / ctsrate +
1994             pre + data_dur +
1995             ack;
1996 
1997         d->d_data_dur = ack;
1998 
1999         return (0);
2000 }
2001 
2002 /*
2003  * Arguments in:
2004  *
2005  * wh:      802.11 header
2006  *
2007  * paylen:  payload length (no FCS, no WEP header)
2008  *
2009  * rate:    MSDU speed, units 500kb/s
2010  *
2011  * fraglen: fragment length, set to maximum (or higher) for no
2012  *          fragmentation
2013  *
2014  * flags:   IEEE80211_F_PRIVACY (hardware adds WEP),
2015  *          IEEE80211_F_SHPREAMBLE (use short preamble),
2016  *          IEEE80211_F_SHSLOT (use short slot length)
2017  *
2018  * Arguments out:
2019  *
2020  * d0: 802.11 Duration fields (RTS/Data), PLCP Length, Service fields
2021  *     of first/only fragment
2022  *
2023  * dn: 802.11 Duration fields (RTS/Data), PLCP Length, Service fields
2024  *     of first/only fragment
2025  */
2026 static int
2027 rtw_compute_duration(struct ieee80211_frame *wh, int len,
2028     uint32_t flags, int fraglen, int rate, struct rtw_ieee80211_duration *d0,
2029     struct rtw_ieee80211_duration *dn, int *npktp)
2030 {
2031         int ack, rc;
2032         int firstlen, hdrlen, lastlen, lastlen0, npkt, overlen, paylen;
2033 
2034         /* don't think about addr4 here */
2035         hdrlen = sizeof (struct ieee80211_frame);
2036 
2037         paylen = len - hdrlen;
2038 
2039         if ((wh->i_fc[1] & IEEE80211_FC1_WEP) != 0) {
2040                 overlen = 8 + IEEE80211_CRC_LEN;
2041                 paylen -= 8;
2042         } else
2043                 overlen = IEEE80211_CRC_LEN;
2044 
2045         npkt = paylen / fraglen;
2046         lastlen0 = paylen % fraglen;
2047 
2048         if (npkt == 0)                  /* no fragments */
2049                 lastlen = paylen + overlen;
2050         else if (lastlen0 != 0) {       /* a short "tail" fragment */
2051                 lastlen = lastlen0 + overlen;
2052                 npkt++;
2053         } else                  /* full-length "tail" fragment */
2054                 lastlen = fraglen + overlen;
2055 
2056         if (npktp != NULL)
2057                 *npktp = npkt;
2058 
2059         if (npkt > 1)
2060                 firstlen = fraglen + overlen;
2061         else
2062                 firstlen = paylen + overlen;
2063 
2064         ack = !IEEE80211_IS_MULTICAST(wh->i_addr1) &&
2065             (wh->i_fc[1] & IEEE80211_FC0_TYPE_MASK) !=
2066             IEEE80211_FC0_TYPE_CTL;
2067 
2068         rc = rtw_compute_duration1(firstlen + hdrlen,
2069             ack, flags, rate, d0);
2070         if (rc == -1)
2071                 return (rc);
2072 
2073         if (npkt <= 1) {
2074                 *dn = *d0;
2075                 return (0);
2076         }
2077         return (rtw_compute_duration1(lastlen + hdrlen, ack, flags,
2078             rate, dn));
2079 }
2080 
2081 static int
2082 rtw_assembly_80211(rtw_softc_t *rsc, struct rtw_txbuf *bf,
2083     mblk_t *mp)
2084 {
2085         ieee80211com_t *ic;
2086         struct rtw_txdesc *ds;
2087         struct ieee80211_frame *wh;
2088         uint8_t *buf;
2089         uint32_t ctl0 = 0, ctl1 = 0;
2090         int npkt, rate;
2091         struct rtw_ieee80211_duration d0, dn;
2092         int32_t iswep, pktlen, mblen;
2093         mblk_t *mp0;
2094 
2095         ic = &rsc->sc_ic;
2096         ds = bf->txdesc;
2097         buf = (uint8_t *)bf->bf_dma.mem_va;
2098         bzero(buf, bf->bf_dma.alength);
2099         bzero((uint8_t *)ds, sizeof (struct rtw_txdesc));
2100         wh = (struct ieee80211_frame *)mp->b_rptr;
2101         iswep = wh->i_fc[1] & IEEE80211_FC1_WEP;
2102 
2103         /* ieee80211_crypto_encap() needs a single mblk */
2104         mp0 = allocb(bf->bf_dma.alength, BPRI_MED);
2105         if (mp0 == NULL) {
2106                 cmn_err(CE_WARN, "%s: allocb(mp) error", __func__);
2107                 return (-1);
2108         }
2109         for (; mp != NULL; mp = mp->b_cont) {
2110                         mblen = (uintptr_t)mp->b_wptr - (uintptr_t)mp->b_rptr;
2111                         bcopy(mp->b_rptr, mp0->b_wptr, mblen);
2112                         mp0->b_wptr += mblen;
2113         }
2114 
2115         if (iswep) {
2116                 struct ieee80211_key *k;
2117 
2118                 k = ieee80211_crypto_encap(ic, mp0);
2119                 if (k == NULL) {
2120                         cmn_err(CE_WARN, "%s: ieee80211_crypto_encap() error",
2121                             __func__);
2122                         freemsg(mp0);
2123                         return (-1);
2124                 }
2125         }
2126         pktlen = msgdsize(mp0);
2127 
2128 #if 0
2129         RTW_DPRINTF(RTW_DEBUG_XMIT, "-----------send------begin--------");
2130         ieee80211_dump_pkt((uint8_t *)(mp0->b_rptr), pktlen, 0, 0);
2131         RTW_DPRINTF(RTW_DEBUG_XMIT, "-----------send------end--------");
2132 #endif
2133         /* RTW_DMA_SYNC(bf->bf_dma, DDI_DMA_SYNC_FORDEV); */
2134         if (pktlen > bf->bf_dma.alength) {
2135                 cmn_err(CE_WARN, "%s: overlength packet pktlen = %d\n",
2136                     __func__, pktlen);
2137                 freemsg(mp0);
2138                 return (-1);
2139         }
2140         bcopy(mp0->b_rptr, buf, pktlen);
2141         RTW_DMA_SYNC(bf->bf_dma, DDI_DMA_SYNC_FORDEV);
2142 
2143         /* setup descriptor */
2144         ctl0 = RTW_TXCTL0_RTSRATE_1MBPS;
2145 
2146         if (((ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0) &&
2147             (ic->ic_bss->in_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE)) {
2148                 ctl0 |= RTW_TXCTL0_SPLCP;
2149         }
2150         /* XXX do real rate control */
2151         if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
2152             IEEE80211_FC0_TYPE_MGT)
2153                 rate = 2;
2154         else {
2155                 rate = MAX(2, rtw_get_rate(ic));
2156         }
2157         ctl0 = ctl0 |
2158             LSHIFT(pktlen, RTW_TXCTL0_TPKTSIZE_MASK);
2159 
2160         RTW_DPRINTF(RTW_DEBUG_XMIT, "%s: rate = %d", __func__, rate);
2161 
2162         switch (rate) {
2163         default:
2164         case 2:
2165                 ctl0 |= RTW_TXCTL0_RATE_1MBPS;
2166                 break;
2167         case 4:
2168                 ctl0 |= RTW_TXCTL0_RATE_2MBPS;
2169                 break;
2170         case 11:
2171                 ctl0 |= RTW_TXCTL0_RATE_5MBPS;
2172                 break;
2173         case 22:
2174                 ctl0 |= RTW_TXCTL0_RATE_11MBPS;
2175                 break;
2176         }
2177 
2178         /* XXX >= ? Compare after fragmentation? */
2179         if (pktlen > ic->ic_rtsthreshold) {
2180                 ctl0 |= RTW_TXCTL0_RTSEN;
2181                 cmn_err(CE_NOTE, "%s: fragmentation: pktlen = %d",
2182                     __func__, pktlen);
2183         }
2184 
2185         if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
2186             IEEE80211_FC0_TYPE_MGT) {
2187                 ctl0 &= ~(RTW_TXCTL0_SPLCP | RTW_TXCTL0_RTSEN);
2188                 if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) ==
2189                     IEEE80211_FC0_SUBTYPE_BEACON)
2190                         ctl0 |= RTW_TXCTL0_BEACON;
2191         }
2192 
2193         if (rtw_compute_duration(wh, pktlen,
2194             ic->ic_flags, ic->ic_fragthreshold,
2195             rate, &d0, &dn, &npkt) == -1) {
2196                 RTW_DPRINTF(RTW_DEBUG_XMIT,
2197                     "%s: fail compute duration\n", __func__);
2198                 freemsg(mp0);
2199                 return (-1);
2200         }
2201         *(uint16_t *)(uintptr_t)wh->i_dur = (d0.d_data_dur);
2202 
2203         ctl1 = LSHIFT(d0.d_plcp_len, RTW_TXCTL1_LENGTH_MASK) |
2204             LSHIFT(d0.d_rts_dur, RTW_TXCTL1_RTSDUR_MASK);
2205 
2206         if (d0.d_residue)
2207                 ctl1 |= RTW_TXCTL1_LENGEXT;
2208 
2209         RTW_DPRINTF(RTW_DEBUG_XMIT, "%s: duration=%x, ctl1=%x", __func__,
2210             *(uint16_t *)(uintptr_t)wh->i_dur, ctl1);
2211 
2212         if (bf->bf_dma.alength > RTW_TXLEN_LENGTH_MASK) {
2213                 RTW_DPRINTF(RTW_DEBUG_XMIT,
2214                     "%s: seg too long\n", __func__);
2215                 freemsg(mp0);
2216                 return (-1);
2217         }
2218         ds->td_ctl0 = ctl0;
2219         ds->td_ctl0 |= RTW_TXCTL0_OWN | RTW_TXCTL0_LS | RTW_TXCTL0_FS;
2220         ds->td_ctl1 = ctl1;
2221         ds->td_buf = bf->bf_dma.cookie.dmac_address;
2222         ds->td_len = pktlen & 0xfff;
2223         ds->td_next = bf->next_bf_daddr;
2224 
2225         RTW_DMA_SYNC_DESC(rsc->sc_desc_dma,
2226             RTW_DESC_OFFSET(hd_txmd, bf->order),
2227             sizeof (struct rtw_txdesc),
2228             DDI_DMA_SYNC_FORDEV);
2229 
2230         RTW_DPRINTF(RTW_DEBUG_XMIT,
2231             "descriptor: order = %d, phy_addr=%x, ctl0=%x,"
2232             " ctl1=%x, buf=%x, len=%x, next=%x", bf->order,
2233             bf->bf_daddr, ds->td_ctl0, ds->td_ctl1,
2234             ds->td_buf, ds->td_len, ds->td_next);
2235         rsc->sc_pktxmt64++;
2236         rsc->sc_bytexmt64 += pktlen;
2237 
2238         freemsg(mp0);
2239         return (0);
2240 }
2241 
2242 static int
2243 rtw_send(ieee80211com_t *ic, mblk_t *mp, uint8_t type)
2244 {
2245         rtw_softc_t *rsc = (rtw_softc_t *)ic;
2246         struct ieee80211_node *in = ic->ic_bss;
2247         struct rtw_txbuf *bf = NULL;
2248         int ret, i = RTW_TXPRIMD;
2249 
2250         mutex_enter(&rsc->sc_txlock);
2251         mutex_enter(&rsc->sc_txq[i].txbuf_lock);
2252         bf = list_head(&rsc->sc_txq[i].tx_free_list);
2253 
2254         if ((bf == NULL) || (rsc->sc_txq[i].tx_nfree <= 4)) {
2255                 RTW_DPRINTF(RTW_DEBUG_XMIT, "%s: no tx buf\n", __func__);
2256                 rsc->sc_noxmtbuf++;
2257                 if ((type & IEEE80211_FC0_TYPE_MASK) ==
2258                     IEEE80211_FC0_TYPE_DATA) {
2259                         RTW_DPRINTF(RTW_DEBUG_XMIT, "%s: need reschedule\n",
2260                             __func__);
2261                         rsc->sc_need_reschedule = 1;
2262                 } else {
2263                         freemsg(mp);
2264                 }
2265                 mutex_exit(&rsc->sc_txq[i].txbuf_lock);
2266                 mutex_exit(&rsc->sc_txlock);
2267                 return (1);
2268         }
2269         list_remove(&rsc->sc_txq[i].tx_free_list, bf);
2270         rsc->sc_txq[i].tx_nfree--;
2271 
2272         /* assemble 802.11 frame here */
2273         ret = rtw_assembly_80211(rsc, bf, mp);
2274         if (ret != 0) {
2275                 cmn_err(CE_WARN, "%s assembly frame error\n", __func__);
2276                 mutex_exit(&rsc->sc_txq[i].txbuf_lock);
2277                 mutex_exit(&rsc->sc_txlock);
2278                 if ((type & IEEE80211_FC0_TYPE_MASK) !=
2279                     IEEE80211_FC0_TYPE_DATA) {
2280                         freemsg(mp);
2281                 }
2282                 return (1);
2283         }
2284         list_insert_tail(&rsc->sc_txq[i].tx_dirty_list, bf);
2285         bf->bf_in = in;
2286         rtw_dma_start(&rsc->sc_regs, i);
2287 
2288         mutex_exit(&rsc->sc_txq[i].txbuf_lock);
2289         mutex_exit(&rsc->sc_txlock);
2290 
2291         freemsg(mp);
2292         return (0);
2293 }
2294 
2295 static mblk_t *
2296 rtw_m_tx(void *arg, mblk_t *mp)
2297 {
2298         rtw_softc_t *rsc = arg;
2299         ieee80211com_t *ic = (ieee80211com_t *)rsc;
2300         mblk_t *next;
2301 
2302         if (ic->ic_state != IEEE80211_S_RUN) {
2303                 freemsgchain(mp);
2304                 return (NULL);
2305         }
2306 
2307         while (mp != NULL) {
2308                 next = mp->b_next;
2309                 mp->b_next = NULL;
2310 
2311                 if (rtw_send(ic, mp, IEEE80211_FC0_TYPE_DATA)) {
2312                         mp->b_next = next;
2313                         break;
2314                 }
2315                 mp = next;
2316         }
2317 
2318         return (mp);
2319 
2320 }
2321 
2322 static void
2323 rtw_next_scan(void *arg)
2324 {
2325         ieee80211com_t *ic = arg;
2326         rtw_softc_t *rsc = (rtw_softc_t *)arg;
2327 
2328         rsc->sc_scan_id = 0;
2329         if (ic->ic_state == IEEE80211_S_SCAN) {
2330                 RTW_DPRINTF(RTW_DEBUG_TUNE, "rtw_next_scan\n");
2331                 (void) ieee80211_next_scan(ic);
2332         }
2333 
2334 }
2335 
2336 static void
2337 rtw_join_bss(rtw_softc_t *rsc, uint8_t *bssid, uint16_t intval0)
2338 {
2339         uint16_t bcnitv, intval;
2340         int i;
2341         struct rtw_regs *regs = &rsc->sc_regs;
2342 
2343         for (i = 0; i < IEEE80211_ADDR_LEN; i++)
2344                 RTW_WRITE8(regs, RTW_BSSID + i, bssid[i]);
2345 
2346         RTW_SYNC(regs, RTW_BSSID16, RTW_BSSID32);
2347         rtw_set_access(regs, RTW_ACCESS_CONFIG);
2348 
2349         RTW_WRITE8(regs, RTW_MSR, 0x8); /* sta mode link ok */
2350         intval = MIN(intval0, PRESHIFT(RTW_BCNITV_BCNITV_MASK));
2351 
2352         bcnitv = RTW_READ16(regs, RTW_BCNITV) & ~RTW_BCNITV_BCNITV_MASK;
2353         bcnitv |= LSHIFT(intval, RTW_BCNITV_BCNITV_MASK);
2354         RTW_WRITE16(regs, RTW_BCNITV, bcnitv);
2355         RTW_WRITE16(regs, RTW_ATIMWND, LSHIFT(1, RTW_ATIMWND_ATIMWND));
2356         RTW_WRITE16(regs, RTW_ATIMTRITV, LSHIFT(2, RTW_ATIMTRITV_ATIMTRITV));
2357 
2358         rtw_set_access(regs, RTW_ACCESS_NONE);
2359 
2360         /* TBD WEP */
2361         /* RTW_WRITE8(regs, RTW_SCR, 0); */
2362 
2363         rtw_io_enable(rsc, RTW_CR_RE | RTW_CR_TE, 1);
2364 }
2365 
2366 /*
2367  * Set the starting transmit rate for a node.
2368  */
2369 static void
2370 rtw_rate_ctl_start(rtw_softc_t *rsc, struct ieee80211_node *in)
2371 {
2372         ieee80211com_t *ic = (ieee80211com_t *)rsc;
2373         int32_t srate;
2374 
2375         if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) {
2376                 /*
2377                  * No fixed rate is requested. For 11b start with
2378                  * the highest negotiated rate; otherwise, for 11g
2379                  * and 11a, we start "in the middle" at 24Mb or 36Mb.
2380                  */
2381                 srate = in->in_rates.ir_nrates - 1;
2382                 if (ic->ic_curmode != IEEE80211_MODE_11B) {
2383                         /*
2384                          * Scan the negotiated rate set to find the
2385                          * closest rate.
2386                          */
2387                         /* NB: the rate set is assumed sorted */
2388                         for (; srate >= 0 && IEEE80211_RATE(srate) > 72;
2389                             srate--)
2390                                 ;
2391                 }
2392         } else {
2393                 /*
2394                  * A fixed rate is to be used;  We know the rate is
2395                  * there because the rate set is checked when the
2396                  * station associates.
2397                  */
2398                 /* NB: the rate set is assumed sorted */
2399                 srate = in->in_rates.ir_nrates - 1;
2400                 for (; srate >= 0 && IEEE80211_RATE(srate) != ic->ic_fixed_rate;
2401                     srate--)
2402                         ;
2403         }
2404         in->in_txrate = srate;
2405 }
2406 
2407 
2408 /*
2409  * Reset the rate control state for each 802.11 state transition.
2410  */
2411 static void
2412 rtw_rate_ctl_reset(rtw_softc_t *rsc, enum ieee80211_state state)
2413 {
2414         ieee80211com_t *ic = &rsc->sc_ic;
2415         ieee80211_node_t *in;
2416 
2417         if (ic->ic_opmode == IEEE80211_M_STA) {
2418                 /*
2419                  * Reset local xmit state; this is really only
2420                  * meaningful when operating in station mode.
2421                  */
2422                 in = (struct ieee80211_node *)ic->ic_bss;
2423 
2424                 if (state == IEEE80211_S_RUN) {
2425                         rtw_rate_ctl_start(rsc, in);
2426                 } else {
2427                         in->in_txrate = 0;
2428                 }
2429         }
2430 }
2431 
2432 /*
2433  * Examine and potentially adjust the transmit rate.
2434  */
2435 static void
2436 rtw_rate_ctl(void *arg)
2437 {
2438         ieee80211com_t  *ic = (ieee80211com_t *)arg;
2439         rtw_softc_t *rsc = (rtw_softc_t *)ic;
2440         struct ieee80211_node *in = ic->ic_bss;
2441         struct ieee80211_rateset *rs = &in->in_rates;
2442         int32_t mod = 1, nrate, enough;
2443 
2444         mutex_enter(&rsc->sc_genlock);
2445         enough = (rsc->sc_tx_ok + rsc->sc_tx_err) >= 600? 1 : 0;
2446 
2447         /* err ratio is high -> down */
2448         if (enough && rsc->sc_tx_ok < rsc->sc_tx_err)
2449                 mod = -1;
2450 
2451         nrate = in->in_txrate;
2452         switch (mod) {
2453         case -1:
2454                 if (nrate > 0) {
2455                         nrate--;
2456                 }
2457                 break;
2458         case 1:
2459                 if (nrate + 1 < rs->ir_nrates) {
2460                         nrate++;
2461                 }
2462                 break;
2463         }
2464 
2465         if (nrate != in->in_txrate)
2466                 in->in_txrate = nrate;
2467         rsc->sc_tx_ok = rsc->sc_tx_err = rsc->sc_tx_retr = 0;
2468         mutex_exit(&rsc->sc_genlock);
2469         if (ic->ic_state == IEEE80211_S_RUN)
2470                 rsc->sc_ratectl_id = timeout(rtw_rate_ctl, ic,
2471                     drv_usectohz(1000000));
2472 }
2473 
2474 static int32_t
2475 rtw_new_state(ieee80211com_t *ic, enum ieee80211_state nstate, int arg)
2476 {
2477         rtw_softc_t *rsc = (rtw_softc_t *)ic;
2478         int error;
2479         enum ieee80211_state ostate;
2480 
2481         ostate = ic->ic_state;
2482 
2483         RTW_DPRINTF(RTW_DEBUG_ATTACH,
2484             "rtw_new_state: ostate:0x%x, nstate:0x%x, opmode:0x%x\n",
2485             ostate, nstate, ic->ic_opmode);
2486 
2487 
2488         mutex_enter(&rsc->sc_genlock);
2489         if (rsc->sc_scan_id != 0) {
2490                 (void) untimeout(rsc->sc_scan_id);
2491                 rsc->sc_scan_id = 0;
2492         }
2493         if (rsc->sc_ratectl_id != 0) {
2494                 (void) untimeout(rsc->sc_ratectl_id);
2495                 rsc->sc_ratectl_id = 0;
2496         }
2497         rtw_rate_ctl_reset(rsc, nstate);
2498         if (ostate == IEEE80211_S_INIT && nstate != IEEE80211_S_INIT)
2499                 (void) rtw_pwrstate(rsc, RTW_ON);
2500         if (nstate != IEEE80211_S_INIT) {
2501                 if ((error = rtw_tune(rsc)) != 0) {
2502                         mutex_exit(&rsc->sc_genlock);
2503                         return (error);
2504                 }
2505         }
2506         switch (nstate) {
2507         case IEEE80211_S_INIT:
2508                 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw_new_state: S_INIT\n");
2509                 break;
2510         case IEEE80211_S_SCAN:
2511                 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw_new_state: S_SCAN\n");
2512                 rsc->sc_scan_id = timeout(rtw_next_scan, ic,
2513                     drv_usectohz(200000));
2514                 rtw_set_nettype(rsc, IEEE80211_M_MONITOR);
2515                 break;
2516         case IEEE80211_S_RUN:
2517                 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw_new_state: S_RUN\n");
2518                 switch (ic->ic_opmode) {
2519                 case IEEE80211_M_HOSTAP:
2520                 case IEEE80211_M_IBSS:
2521                         rtw_set_nettype(rsc, IEEE80211_M_MONITOR);
2522                         /* TBD */
2523                         /*FALLTHROUGH*/
2524                 case IEEE80211_M_AHDEMO:
2525                 case IEEE80211_M_STA:
2526                         RTW_DPRINTF(RTW_DEBUG_ATTACH,
2527                             "rtw_new_state: sta\n");
2528                         rtw_join_bss(rsc, ic->ic_bss->in_bssid, 0);
2529                         rsc->sc_ratectl_id = timeout(rtw_rate_ctl, ic,
2530                             drv_usectohz(1000000));
2531                         break;
2532                 case IEEE80211_M_MONITOR:
2533                         break;
2534                 }
2535                 rtw_set_nettype(rsc, ic->ic_opmode);
2536                 break;
2537         case IEEE80211_S_ASSOC:
2538         case IEEE80211_S_AUTH:
2539                 break;
2540         }
2541 
2542         mutex_exit(&rsc->sc_genlock);
2543         /*
2544          * Invoke the parent method to complete the work.
2545          */
2546         error = rsc->sc_newstate(ic, nstate, arg);
2547 
2548         return (error);
2549 }
2550 
2551 static void
2552 rtw_intr_rx(rtw_softc_t *rsc)
2553 {
2554 #define IS_BEACON(__fc0)                                                \
2555         ((__fc0 & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==\
2556         (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_BEACON))
2557         /*
2558          * ratetbl[4] = {2, 4, 11, 22};
2559          */
2560         struct rtw_rxbuf *bf;
2561         struct rtw_rxdesc *ds;
2562         int hwrate, len, rssi;
2563         uint32_t hstat, hrssi, htsftl;
2564         int is_last, next, n = 0, i;
2565         struct ieee80211_frame *wh;
2566         ieee80211com_t *ic = (ieee80211com_t *)rsc;
2567         mblk_t *mp;
2568 
2569         RTW_DPRINTF(RTW_DEBUG_RECV, "%s rtw_intr_rx: enter ic_state=%x\n",
2570             __func__, rsc->sc_ic.ic_state);
2571         mutex_enter(&rsc->rxbuf_lock);
2572         next = rsc->rx_next;
2573         mutex_exit(&rsc->rxbuf_lock);
2574         for (i = 0; i < RTW_RXQLEN; i++) {
2575                 RTW_DMA_SYNC_DESC(rsc->sc_desc_dma,
2576                     RTW_DESC_OFFSET(hd_rx, next),
2577                     sizeof (struct rtw_rxdesc),
2578                     DDI_DMA_SYNC_FORKERNEL);
2579                 n++;
2580                 bf = rsc->rxbuf_h + next;
2581                 ds = bf->rxdesc;
2582                 hstat = (ds->rd_stat);
2583                 hrssi = ds->rd_rssi;
2584                 htsftl = ds->rd_tsftl;
2585                 /* htsfth = ds->rd_tsfth; */
2586                 RTW_DPRINTF(RTW_DEBUG_RECV, "%s: stat=%x\n", __func__, hstat);
2587                 /* still belongs to NIC */
2588                 if ((hstat & RTW_RXSTAT_OWN) != 0) {
2589                         if (n > 1) {
2590                                 RTW_DPRINTF(RTW_DEBUG_RECV,
2591                                     "%s: n > 1\n", __func__);
2592                                 break;
2593                         }
2594                         RTW_DMA_SYNC_DESC(rsc->sc_desc_dma,
2595                             RTW_DESC_OFFSET(hd_rx, 0),
2596                             sizeof (struct rtw_rxdesc),
2597                             DDI_DMA_SYNC_FORCPU);
2598                         bf = rsc->rxbuf_h;
2599                         ds = bf->rxdesc;
2600                         hstat = (ds->rd_stat);
2601                         if ((hstat & RTW_RXSTAT_OWN) != 0)
2602                                 break;
2603                         next = 0 /* RTW_RXQLEN - 1 */;
2604                         continue;
2605                 }
2606 
2607                 rsc->sc_pktrcv64++;
2608                 if ((hstat & RTW_RXSTAT_IOERROR) != 0) {
2609                         RTW_DPRINTF(RTW_DEBUG_RECV,
2610                             "rtw: DMA error/FIFO overflow %08x, "
2611                             "rx descriptor %d\n",
2612                             hstat & RTW_RXSTAT_IOERROR, next);
2613                         goto next;
2614                 }
2615 
2616                 len = MASK_AND_RSHIFT(hstat, RTW_RXSTAT_LENGTH_MASK);
2617                 rsc->sc_bytercv64 += len;
2618 
2619                 /* CRC is included with the packet; trim it off. */
2620                 /* len -= IEEE80211_CRC_LEN; */
2621 
2622                 hwrate = MASK_AND_RSHIFT(hstat, RTW_RXSTAT_RATE_MASK);
2623                 if (hwrate >= 4) {
2624                         goto next;
2625                 }
2626 
2627                 if ((hstat & RTW_RXSTAT_RES) != 0 &&
2628                     rsc->sc_ic.ic_opmode != IEEE80211_M_MONITOR) {
2629                         goto next;
2630                 }
2631 
2632                 /* if bad flags, skip descriptor */
2633                 if ((hstat & RTW_RXSTAT_ONESEG) != RTW_RXSTAT_ONESEG) {
2634                         RTW_DPRINTF(RTW_DEBUG_RECV,
2635                             "rtw too many rx segments\n");
2636                         goto next;
2637                 }
2638 
2639                 if (rsc->sc_rfchipid == RTW_RFCHIPID_PHILIPS)
2640                         rssi = MASK_AND_RSHIFT(hrssi, RTW_RXRSSI_RSSI);
2641                 else {
2642                         rssi = MASK_AND_RSHIFT(hrssi, RTW_RXRSSI_IMR_RSSI);
2643                         /*
2644                          * TBD find out each front-end's LNA gain in the
2645                          * front-end's units
2646                          */
2647                         if ((hrssi & RTW_RXRSSI_IMR_LNA) == 0)
2648                                 rssi |= 0x80;
2649                 }
2650                 /* sq = MASK_AND_RSHIFT(hrssi, RTW_RXRSSI_SQ); */
2651 
2652 
2653                 /* deal with the frame itself here */
2654                 mp = allocb(rsc->sc_dmabuf_size, BPRI_MED);
2655                 if (mp == NULL) {
2656                         cmn_err(CE_WARN, "rtw: alloc mblk error");
2657                         rsc->sc_norcvbuf++;
2658                         return;
2659                 }
2660                 len -= IEEE80211_CRC_LEN;
2661                 RTW_DMA_SYNC(bf->bf_dma, DDI_DMA_SYNC_FORKERNEL);
2662                 bcopy(bf->bf_dma.mem_va, mp->b_rptr, len);
2663                 mp->b_wptr += len;
2664                 wh = (struct ieee80211_frame *)mp->b_rptr;
2665                 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
2666                     IEEE80211_FC0_TYPE_CTL) {
2667                         cmn_err(CE_WARN, "TYPE CTL !!\n");
2668                         freemsg(mp);
2669                         goto next;
2670                 }
2671                 (void) ieee80211_input(ic, mp, ic->ic_bss, rssi, htsftl);
2672 next:
2673                 if (next == 63)
2674                         is_last = 1;
2675                 else
2676                         is_last = 0;
2677                 rtw_rxdesc_init(rsc, bf, next, is_last);
2678 
2679                 next = (next + 1)%RTW_RXQLEN;
2680                 RTW_DPRINTF(RTW_DEBUG_RECV, "%s: next = %d\n", __func__, next);
2681         }
2682         mutex_enter(&rsc->rxbuf_lock);
2683         rsc->rx_next = next;
2684         mutex_exit(&rsc->rxbuf_lock);
2685 }
2686 
2687 static void
2688 rtw_ring_recycling(rtw_softc_t *rsc, uint16_t isr, uint32_t pri)
2689 {
2690         struct rtw_txbuf *bf;
2691         struct rtw_txdesc *ds;
2692         uint32_t hstat;
2693         uint32_t  head = 0;
2694         uint32_t  cnt = 0, idx = 0;
2695 
2696         mutex_enter(&rsc->sc_txq[pri].txbuf_lock);
2697         head = RTW_READ(&rsc->sc_regs, RTW_TNPDA);
2698         if (head == rsc->hw_go) {
2699                 mutex_exit(&rsc->sc_txq[pri].txbuf_lock);
2700                 return;
2701         }
2702         RTW_DPRINTF(RTW_DEBUG_XMIT, "rtw_ring_recycling: enter ic_state=%x\n",
2703             rsc->sc_ic.ic_state);
2704 
2705         bf = list_head(&rsc->sc_txq[pri].tx_dirty_list);
2706         if (bf == NULL) {
2707                 RTW_DPRINTF(RTW_DEBUG_XMIT,
2708                     "rtw_ring_recycling: dirty bf[%d] NULL\n", pri);
2709                 mutex_exit(&rsc->sc_txq[pri].txbuf_lock);
2710                 return;
2711         }
2712 
2713         while ((bf != NULL) && (rsc->hw_go != head)) {
2714                 cnt++;
2715                 idx = (rsc->hw_go - rsc->hw_start) / sizeof (struct rtw_txdesc);
2716                 if (idx == 63)
2717                         rsc->hw_go = rsc->hw_start;
2718                 else
2719                         rsc->hw_go += sizeof (struct rtw_txdesc);
2720                 RTW_DMA_SYNC_DESC(rsc->sc_desc_dma,
2721                     RTW_DESC_OFFSET(hd_txmd, idx),
2722                     sizeof (struct rtw_txdesc),
2723                     DDI_DMA_SYNC_FORCPU);
2724 
2725                 RTW_DPRINTF(RTW_DEBUG_XMIT, "Head = 0x%x\n", head);
2726                 ds = bf->txdesc;
2727                 hstat = (ds->td_stat);
2728                 ds->td_len = ds->td_len & 0xfff;
2729                 RTW_DPRINTF(RTW_DEBUG_XMIT,
2730                     "%s rtw_ring_recycling: stat=%x, pri=%x\n",
2731                     __func__, hstat, pri);
2732                 if (hstat & RTW_TXSTAT_TOK)
2733                         rsc->sc_tx_ok++;
2734                 else {
2735                         RTW_DPRINTF(RTW_DEBUG_XMIT,
2736                             "TX err @%d, o %d, retry[%d], isr[0x%x], cnt %d\n",
2737                             idx, (hstat & RTW_TXSTAT_OWN)?1:0,
2738                             (hstat & RTW_TXSTAT_DRC_MASK), isr, cnt);
2739                         if ((hstat & RTW_TXSTAT_DRC_MASK) <= 4) {
2740                                 rsc->sc_tx_ok++;
2741                         } else {
2742                                 rsc->sc_tx_err++;
2743                         }
2744                 }
2745                 rsc->sc_tx_retr +=
2746                     (hstat & RTW_TXSTAT_DRC_MASK);
2747                 rsc->sc_xmtretry +=
2748                     (hstat & RTW_TXSTAT_DRC_MASK);
2749                 list_remove(&rsc->sc_txq[pri].tx_dirty_list, bf);
2750                 list_insert_tail(&rsc->sc_txq[pri].tx_free_list,
2751                     bf);
2752                 (rsc->sc_txq[pri].tx_nfree)++;
2753                 if (rsc->sc_need_reschedule == 1) {
2754                         mac_tx_update(rsc->sc_ic.ic_mach);
2755                         rsc->sc_need_reschedule = 0;
2756                 }
2757                 RTW_DPRINTF(RTW_DEBUG_XMIT,
2758                     "rtw_ring_recycling: nfree[%d]=%d\n",
2759                     pri, rsc->sc_txq[pri].tx_nfree);
2760                 bzero((uint8_t *)ds, sizeof (struct rtw_txdesc));
2761                 RTW_DMA_SYNC_DESC(rsc->sc_desc_dma,
2762                     RTW_DESC_OFFSET(hd_txmd, idx),
2763                     sizeof (struct rtw_txdesc),
2764                     DDI_DMA_SYNC_FORDEV);
2765                 bf = list_head(&rsc->sc_txq[pri].tx_dirty_list);
2766         }
2767         mutex_exit(&rsc->sc_txq[pri].txbuf_lock);
2768 }
2769 
2770 static void
2771 rtw_intr_timeout(rtw_softc_t *rsc)
2772 {
2773         rtw_resume_ticks(rsc);
2774 }
2775 
2776 static uint_t
2777 rtw_intr(caddr_t arg)
2778 {
2779         /* LINTED E_BAD_PTR_CAST_ALIGN */
2780         rtw_softc_t *rsc = (rtw_softc_t *)arg;
2781         struct rtw_regs *regs = &rsc->sc_regs;
2782         uint16_t isr = 0;
2783 
2784         mutex_enter(&rsc->sc_genlock);
2785         isr = RTW_READ16(regs, RTW_ISR);
2786         RTW_WRITE16(regs, RTW_ISR, isr);
2787 
2788         if (isr == 0) {
2789                 mutex_exit(&rsc->sc_genlock);
2790                 return (DDI_INTR_UNCLAIMED);
2791         }
2792 
2793 #ifdef DEBUG
2794 #define PRINTINTR(flag) { \
2795         if ((isr & flag) != 0) { \
2796                 RTW_DPRINTF(RTW_DEBUG_INTR, "|" #flag); \
2797         } \
2798 }
2799 
2800         if ((rtw_dbg_flags & RTW_DEBUG_INTR) != 0 && isr != 0) {
2801 
2802                 RTW_DPRINTF(RTW_DEBUG_INTR, "rtw: reg[ISR] = %x", isr);
2803 
2804                 PRINTINTR(RTW_INTR_TXFOVW);
2805                 PRINTINTR(RTW_INTR_TIMEOUT);
2806                 PRINTINTR(RTW_INTR_BCNINT);
2807                 PRINTINTR(RTW_INTR_ATIMINT);
2808                 PRINTINTR(RTW_INTR_TBDER);
2809                 PRINTINTR(RTW_INTR_TBDOK);
2810                 PRINTINTR(RTW_INTR_THPDER);
2811                 PRINTINTR(RTW_INTR_THPDOK);
2812                 PRINTINTR(RTW_INTR_TNPDER);
2813                 PRINTINTR(RTW_INTR_TNPDOK);
2814                 PRINTINTR(RTW_INTR_RXFOVW);
2815                 PRINTINTR(RTW_INTR_RDU);
2816                 PRINTINTR(RTW_INTR_TLPDER);
2817                 PRINTINTR(RTW_INTR_TLPDOK);
2818                 PRINTINTR(RTW_INTR_RER);
2819                 PRINTINTR(RTW_INTR_ROK);
2820         }
2821 #undef PRINTINTR
2822 #endif /* DEBUG */
2823 
2824         rsc->sc_intr++;
2825 
2826         if ((isr & RTW_INTR_RX) != 0) {
2827                 mutex_exit(&rsc->sc_genlock);
2828                 rtw_intr_rx(rsc);
2829                 mutex_enter(&rsc->sc_genlock);
2830         }
2831         if ((isr & RTW_INTR_TIMEOUT) != 0)
2832                 rtw_intr_timeout(rsc);
2833 
2834         if ((isr & RTW_INTR_TX) != 0)
2835                 rtw_ring_recycling(rsc, isr, 1);
2836         mutex_exit(&rsc->sc_genlock);
2837         return (DDI_INTR_CLAIMED);
2838 }
2839 
2840 static void
2841 rtw_stop(void *arg)
2842 {
2843         rtw_softc_t *rsc = (rtw_softc_t *)arg;
2844         struct rtw_regs *regs = &rsc->sc_regs;
2845 
2846         mutex_enter(&rsc->sc_genlock);
2847         rtw_disable_interrupts(regs);
2848         rtw_io_enable(rsc, RTW_CR_RE | RTW_CR_TE, 0);
2849         RTW_WRITE8(regs, RTW_TPPOLL, RTW_TPPOLL_SALL);
2850         rsc->sc_invalid = 1;
2851         mutex_exit(&rsc->sc_genlock);
2852 }
2853 
2854 static void
2855 rtw_m_stop(void *arg)
2856 {
2857         rtw_softc_t *rsc = (rtw_softc_t *)arg;
2858 
2859         (void) ieee80211_new_state(&rsc->sc_ic, IEEE80211_S_INIT, -1);
2860         rtw_stop(rsc);
2861 }
2862 
2863 /*
2864  * quiesce(9E) entry point.
2865  *
2866  * This function is called when the system is single-threaded at high
2867  * PIL with preemption disabled. Therefore, this function must not be
2868  * blocked.
2869  *
2870  * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
2871  * DDI_FAILURE indicates an error condition and should almost never happen.
2872  */
2873 int
2874 rtw_quiesce(dev_info_t *dip)
2875 {
2876         rtw_softc_t  *rsc = NULL;
2877         struct rtw_regs *regs;
2878 
2879         rsc = ddi_get_soft_state(rtw_soft_state_p, ddi_get_instance(dip));
2880         ASSERT(rsc != NULL);
2881         regs = &rsc->sc_regs;
2882 
2883         rtw_dbg_flags = 0;
2884         rtw_disable_interrupts(regs);
2885         rtw_io_enable(rsc, RTW_CR_RE | RTW_CR_TE, 0);
2886         RTW_WRITE8(regs, RTW_TPPOLL, RTW_TPPOLL_SALL);
2887 
2888         return (DDI_SUCCESS);
2889 }
2890 
2891 /*
2892  * callback functions for /get/set properties
2893  */
2894 static int
2895 rtw_m_setprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num,
2896     uint_t wldp_length, const void *wldp_buf)
2897 {
2898         rtw_softc_t *rsc = (rtw_softc_t *)arg;
2899         struct ieee80211com *ic = &rsc->sc_ic;
2900         int err;
2901 
2902         err = ieee80211_setprop(ic, pr_name, wldp_pr_num,
2903             wldp_length, wldp_buf);
2904         if (err == ENETRESET) {
2905                 if (ic->ic_des_esslen && (rsc->sc_invalid == 0)) {
2906                         (void) rtw_init(rsc);
2907                         (void) ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
2908                 }
2909                 err = 0;
2910         }
2911         return (err);
2912 }
2913 
2914 static int
2915 rtw_m_getprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num,
2916     uint_t wldp_length, void *wldp_buf)
2917 {
2918         rtw_softc_t *rsc = arg;
2919         int err;
2920 
2921         err = ieee80211_getprop(&rsc->sc_ic, pr_name, wldp_pr_num,
2922             wldp_length, wldp_buf);
2923 
2924         return (err);
2925 }
2926 
2927 static void
2928 rtw_m_propinfo(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num,
2929     mac_prop_info_handle_t prh)
2930 {
2931         rtw_softc_t *rsc = arg;
2932 
2933         ieee80211_propinfo(&rsc->sc_ic, pr_name, wldp_pr_num, prh);
2934 }
2935 
2936 static int
2937 rtw_m_start(void *arg)
2938 {
2939         rtw_softc_t *rsc = (rtw_softc_t *)arg;
2940         ieee80211com_t *ic = (ieee80211com_t *)rsc;
2941         int ret;
2942 #ifdef DEBUG
2943         rtw_print_regs(&rsc->sc_regs, "rtw", "rtw_start");
2944 #endif
2945 
2946         ret = rtw_init(rsc);
2947         if (ret) {
2948                 cmn_err(CE_WARN, "rtw: failed to do rtw_init\n");
2949                 return (EIO);
2950         }
2951         (void) ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
2952         return (0);
2953 }
2954 
2955 
2956 static int
2957 rtw_m_unicst(void *arg, const uint8_t *macaddr)
2958 {
2959         rtw_softc_t *rsc = (rtw_softc_t *)arg;
2960         ieee80211com_t *ic = (ieee80211com_t *)rsc;
2961         struct rtw_regs *regs = &rsc->sc_regs;
2962         uint32_t t;
2963 
2964         mutex_enter(&rsc->sc_genlock);
2965         bcopy(macaddr, ic->ic_macaddr, 6);
2966         t = ((*macaddr)<<24) | ((*(macaddr + 1))<<16) |
2967             ((*(macaddr + 2))<<8) | (*(macaddr + 3));
2968         RTW_WRITE(regs, RTW_IDR0, ntohl(t));
2969         t = ((*(macaddr + 4))<<24) | ((*(macaddr + 5))<<16);
2970         RTW_WRITE(regs, RTW_IDR1, ntohl(t));
2971         mutex_exit(&rsc->sc_genlock);
2972         return (0);
2973 }
2974 
2975 static int
2976 rtw_m_promisc(void *arg, boolean_t on)
2977 {
2978         rtw_softc_t *rsc = (rtw_softc_t *)arg;
2979         struct rtw_regs *regs = &rsc->sc_regs;
2980 
2981         mutex_enter(&rsc->sc_genlock);
2982 
2983         if (on)
2984                 rsc->sc_rcr |= RTW_RCR_PROMIC;
2985         else
2986                 rsc->sc_rcr &= ~RTW_RCR_PROMIC;
2987 
2988         RTW_WRITE(regs, RTW_RCR, rsc->sc_rcr);
2989 
2990         mutex_exit(&rsc->sc_genlock);
2991         return (0);
2992 }
2993 
2994 static int
2995 rtw_m_multicst(void *arg, boolean_t add, const uint8_t *macaddr)
2996 {
2997         rtw_softc_t *rsc = (rtw_softc_t *)arg;
2998         struct rtw_regs *regs = &rsc->sc_regs;
2999         uint32_t t;
3000 
3001         mutex_enter(&rsc->sc_genlock);
3002         if (add) {
3003                 rsc->sc_rcr |= RTW_RCR_AM;
3004                 t = ((*macaddr)<<24) | ((*(macaddr + 1))<<16) |
3005                     ((*(macaddr + 2))<<8) | (*(macaddr + 3));
3006                 RTW_WRITE(regs, RTW_MAR0, ntohl(t));
3007                 t = ((*(macaddr + 4))<<24) | ((*(macaddr + 5))<<16);
3008                 RTW_WRITE(regs, RTW_MAR1, ntohl(t));
3009                 RTW_WRITE(regs, RTW_RCR, rsc->sc_rcr);
3010                 RTW_SYNC(regs, RTW_MAR0, RTW_RCR);
3011         } else {
3012                 rsc->sc_rcr &= ~RTW_RCR_AM;
3013                 RTW_WRITE(regs, RTW_MAR0, 0);
3014                 RTW_WRITE(regs, RTW_MAR1, 0);
3015                 RTW_WRITE(regs, RTW_RCR, rsc->sc_rcr);
3016                 RTW_SYNC(regs, RTW_MAR0, RTW_RCR);
3017         }
3018         mutex_exit(&rsc->sc_genlock);
3019         return (0);
3020 }
3021 
3022 static void
3023 rtw_m_ioctl(void* arg, queue_t *wq, mblk_t *mp)
3024 {
3025         rtw_softc_t *rsc = arg;
3026         struct ieee80211com *ic = &rsc->sc_ic;
3027         int err;
3028 
3029         err = ieee80211_ioctl(ic, wq, mp);
3030         if (err == ENETRESET) {
3031                 if (ic->ic_des_esslen && (rsc->sc_invalid == 0)) {
3032                         (void) rtw_init(rsc);
3033                         (void) ieee80211_new_state(ic,
3034                             IEEE80211_S_SCAN, -1);
3035                 }
3036         }
3037 }
3038 
3039 static int
3040 rtw_m_stat(void *arg, uint_t stat, uint64_t *val)
3041 {
3042         rtw_softc_t *rsc = (rtw_softc_t *)arg;
3043         ieee80211com_t *ic = &rsc->sc_ic;
3044         struct ieee80211_node *in = 0;
3045         struct ieee80211_rateset *rs = 0;
3046 
3047         mutex_enter(&rsc->sc_genlock);
3048         switch (stat) {
3049         case MAC_STAT_IFSPEED:
3050                 in = ic->ic_bss;
3051                 rs = &in->in_rates;
3052                 *val = ((ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) ?
3053                     (rs->ir_rates[in->in_txrate] & IEEE80211_RATE_VAL)
3054                     : ic->ic_fixed_rate) / 2 * 1000000;
3055                 break;
3056         case MAC_STAT_NOXMTBUF:
3057                 *val = rsc->sc_noxmtbuf;
3058                 break;
3059         case MAC_STAT_NORCVBUF:
3060                 *val = rsc->sc_norcvbuf;
3061                 break;
3062         case MAC_STAT_RBYTES:
3063                 *val = rsc->sc_bytercv64;
3064                 break;
3065         case MAC_STAT_IPACKETS:
3066                 *val = rsc->sc_pktrcv64;
3067                 break;
3068         case MAC_STAT_OBYTES:
3069                 *val = rsc->sc_bytexmt64;
3070                 break;
3071         case MAC_STAT_OPACKETS:
3072                 *val = rsc->sc_pktxmt64;
3073                 break;
3074         case WIFI_STAT_TX_RETRANS:
3075                 *val = rsc->sc_xmtretry;
3076                 break;
3077         case WIFI_STAT_TX_FRAGS:
3078         case WIFI_STAT_MCAST_TX:
3079         case WIFI_STAT_RTS_SUCCESS:
3080         case WIFI_STAT_RTS_FAILURE:
3081         case WIFI_STAT_ACK_FAILURE:
3082         case WIFI_STAT_RX_FRAGS:
3083         case WIFI_STAT_MCAST_RX:
3084         case WIFI_STAT_RX_DUPS:
3085                 mutex_exit(&rsc->sc_genlock);
3086                 return (ieee80211_stat(ic, stat, val));
3087         default:
3088                 *val = 0;
3089                 break;
3090         }
3091         mutex_exit(&rsc->sc_genlock);
3092 
3093         return (0);
3094 }
3095 
3096 
3097 static void
3098 rtw_mutex_destroy(rtw_softc_t *rsc)
3099 {
3100         int i;
3101 
3102         mutex_destroy(&rsc->rxbuf_lock);
3103         mutex_destroy(&rsc->sc_txlock);
3104         for (i = 0; i < RTW_NTXPRI; i++) {
3105                 mutex_destroy(&rsc->sc_txq[RTW_NTXPRI - 1 - i].txbuf_lock);
3106         }
3107         mutex_destroy(&rsc->sc_genlock);
3108 }
3109 
3110 static int
3111 rtw_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd)
3112 {
3113         rtw_softc_t *rsc;
3114         ieee80211com_t *ic;
3115         uint8_t csz;
3116         uint32_t i;
3117         uint16_t vendor_id, device_id, command;
3118         int32_t err;
3119         char strbuf[32];
3120         wifi_data_t wd = { 0 };
3121         mac_register_t *macp;
3122         int instance = ddi_get_instance(devinfo);
3123 
3124         switch (cmd) {
3125         case DDI_ATTACH:
3126                 break;
3127         case DDI_RESUME:
3128                 rsc = ddi_get_soft_state(rtw_soft_state_p,
3129                     ddi_get_instance(devinfo));
3130                 ASSERT(rsc != NULL);
3131                 mutex_enter(&rsc->sc_genlock);
3132                 rsc->sc_flags &= ~RTW_F_SUSPEND;
3133                 mutex_exit(&rsc->sc_genlock);
3134                 if ((rsc->sc_flags & RTW_F_PLUMBED)) {
3135                         err = rtw_init(rsc);
3136                         if (err == 0) {
3137                                 mutex_enter(&rsc->sc_genlock);
3138                                 rsc->sc_flags &= ~RTW_F_PLUMBED;
3139                                 mutex_exit(&rsc->sc_genlock);
3140                         }
3141                 }
3142                 return (DDI_SUCCESS);
3143         default:
3144                 return (DDI_FAILURE);
3145         }
3146 
3147         if (ddi_soft_state_zalloc(rtw_soft_state_p,
3148             ddi_get_instance(devinfo)) != DDI_SUCCESS) {
3149                 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw: rtw_attach(): "
3150                     "Unable to alloc softstate\n");
3151                 return (DDI_FAILURE);
3152         }
3153 
3154         rsc = ddi_get_soft_state(rtw_soft_state_p, ddi_get_instance(devinfo));
3155         ic = &rsc->sc_ic;
3156         rsc->sc_dev = devinfo;
3157 
3158         err = ddi_regs_map_setup(devinfo, 0, (caddr_t *)&rsc->sc_cfg_base, 0, 0,
3159             &rtw_reg_accattr, &rsc->sc_cfg_handle);
3160         if (err != DDI_SUCCESS) {
3161                 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw: rtw_attach(): "
3162                     "ddi_regs_map_setup() failed");
3163                 goto attach_fail0;
3164         }
3165         csz = ddi_get8(rsc->sc_cfg_handle,
3166             (uint8_t *)(rsc->sc_cfg_base + PCI_CONF_CACHE_LINESZ));
3167         if (!csz)
3168                 csz = 16;
3169         rsc->sc_cachelsz = csz << 2;
3170         vendor_id = ddi_get16(rsc->sc_cfg_handle,
3171             (uint16_t *)((uintptr_t)rsc->sc_cfg_base + PCI_CONF_VENID));
3172         device_id = ddi_get16(rsc->sc_cfg_handle,
3173             (uint16_t *)((uintptr_t)rsc->sc_cfg_base + PCI_CONF_DEVID));
3174         RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw: rtw_attach(): vendor 0x%x, "
3175             "device id 0x%x, cache size %d\n", vendor_id, device_id, csz);
3176 
3177         /*
3178          * Enable response to memory space accesses,
3179          * and enabe bus master.
3180          */
3181         command = PCI_COMM_MAE | PCI_COMM_ME;
3182         ddi_put16(rsc->sc_cfg_handle,
3183             (uint16_t *)((uintptr_t)rsc->sc_cfg_base + PCI_CONF_COMM), command);
3184         RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw: rtw_attach(): "
3185             "set command reg to 0x%x \n", command);
3186 
3187         ddi_put8(rsc->sc_cfg_handle,
3188             (uint8_t *)(rsc->sc_cfg_base + PCI_CONF_LATENCY_TIMER), 0xa8);
3189 
3190         ddi_regs_map_free(&rsc->sc_cfg_handle);
3191 
3192         err = ddi_regs_map_setup(devinfo, 2, (caddr_t *)&rsc->sc_regs.r_base,
3193             0, 0, &rtw_reg_accattr, &rsc->sc_regs.r_handle);
3194         if (err != DDI_SUCCESS) {
3195                 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw: rtw_attach(): "
3196                     "ddi_regs_map_setup() failed");
3197                 goto attach_fail0;
3198         }
3199         RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw: r_base=%x, r_handle=%x\n",
3200             rsc->sc_regs.r_base, rsc->sc_regs.r_handle);
3201 
3202         err = rtw_dma_init(devinfo, rsc);
3203         if (err != DDI_SUCCESS) {
3204                 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw: rtw_attach(): "
3205                     "failed to init dma: %d\n", err);
3206                 goto attach_fail1;
3207         }
3208 
3209         /*
3210          * Stop the transmit and receive processes. First stop DMA,
3211          * then disable receiver and transmitter.
3212          */
3213         RTW_WRITE8(&rsc->sc_regs, RTW_TPPOLL, RTW_TPPOLL_SALL);
3214         rtw_io_enable(rsc, RTW_CR_RE | RTW_CR_TE, 0);
3215 
3216         /* Reset the chip to a known state. */
3217         if (rtw_reset(rsc) != 0) {
3218                 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw: rtw_attach(): "
3219                     "failed to reset\n");
3220                 goto attach_fail2;
3221         }
3222         rsc->sc_rcr = RTW_READ(&rsc->sc_regs, RTW_RCR);
3223 
3224         if ((rsc->sc_rcr & RTW_RCR_9356SEL) != 0)
3225                 rsc->sc_flags |= RTW_F_9356SROM;
3226 
3227         if (rtw_srom_read(&rsc->sc_regs, rsc->sc_flags, &rsc->sc_srom,
3228             "rtw") != 0) {
3229                 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw: rtw_attach(): "
3230                     "failed to read srom\n");
3231                 goto attach_fail2;
3232         }
3233 
3234         if (rtw_srom_parse(&rsc->sc_srom, &rsc->sc_flags, &rsc->sc_csthr,
3235             &rsc->sc_rfchipid, &rsc->sc_rcr, &rsc->sc_locale,
3236             "rtw") != 0) {
3237                 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw_attach():"
3238                     " malformed serial ROM\n");
3239                 goto attach_fail3;
3240         }
3241 
3242         RTW_DPRINTF(RTW_DEBUG_PHY, "rtw: %s PHY\n",
3243             ((rsc->sc_flags & RTW_F_DIGPHY) != 0) ? "digital" : "analog");
3244 
3245 
3246         rsc->sc_rf = rtw_rf_attach(rsc, rsc->sc_rfchipid,
3247             rsc->sc_flags & RTW_F_DIGPHY);
3248 
3249         if (rsc->sc_rf == NULL) {
3250                 cmn_err(CE_WARN, "rtw: rtw_attach(): could not attach RF\n");
3251                 goto attach_fail3;
3252         }
3253         rsc->sc_phydelay = rtw_check_phydelay(&rsc->sc_regs, rsc->sc_rcr);
3254 
3255         RTW_DPRINTF(RTW_DEBUG_ATTACH,
3256             "rtw: PHY delay %d\n", rsc->sc_phydelay);
3257 
3258         if (rsc->sc_locale == RTW_LOCALE_UNKNOWN)
3259                 rtw_identify_country(&rsc->sc_regs, &rsc->sc_locale,
3260                     "rtw");
3261 
3262         rtw_init_channels(rsc->sc_locale, &rsc->sc_ic.ic_sup_channels,
3263             "rtw");
3264 
3265         rtw_set80211props(ic);
3266 
3267         if (rtw_identify_sta(&rsc->sc_regs, ic->ic_macaddr,
3268             "rtw") != 0)
3269                 goto attach_fail4;
3270 
3271         ic->ic_xmit = rtw_send;
3272         ieee80211_attach(ic);
3273 
3274         rsc->sc_newstate = ic->ic_newstate;
3275         ic->ic_newstate = rtw_new_state;
3276         ieee80211_media_init(ic);
3277         ic->ic_def_txkey = 0;
3278 
3279         if (ddi_get_iblock_cookie(devinfo, 0, &(rsc->sc_iblock))
3280             != DDI_SUCCESS) {
3281                 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw: rtw_attach(): "
3282                     "Can not get iblock cookie for INT\n");
3283                 goto attach_fail5;
3284         }
3285 
3286         mutex_init(&rsc->sc_genlock, NULL, MUTEX_DRIVER, rsc->sc_iblock);
3287         for (i = 0; i < RTW_NTXPRI; i++) {
3288                 mutex_init(&rsc->sc_txq[i].txbuf_lock, NULL, MUTEX_DRIVER,
3289                     rsc->sc_iblock);
3290         }
3291         mutex_init(&rsc->rxbuf_lock, NULL, MUTEX_DRIVER, rsc->sc_iblock);
3292         mutex_init(&rsc->sc_txlock, NULL, MUTEX_DRIVER, rsc->sc_iblock);
3293 
3294         if (ddi_add_intr(devinfo, 0, &rsc->sc_iblock, NULL, rtw_intr,
3295             (caddr_t)(rsc)) != DDI_SUCCESS) {
3296                 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw: rtw_attach(): "
3297                     "Can not add intr for rtw driver\n");
3298                 goto attach_fail7;
3299         }
3300 
3301         /*
3302          * Provide initial settings for the WiFi plugin; whenever this
3303          * information changes, we need to call mac_plugindata_update()
3304          */
3305         wd.wd_opmode = ic->ic_opmode;
3306         wd.wd_secalloc = WIFI_SEC_NONE;
3307         IEEE80211_ADDR_COPY(wd.wd_bssid, ic->ic_bss->in_bssid);
3308 
3309         if ((macp = mac_alloc(MAC_VERSION)) == NULL) {
3310                 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw: rtw_attach(): "
3311                     "MAC version mismatch\n");
3312                 goto attach_fail8;
3313         }
3314 
3315         macp->m_type_ident   = MAC_PLUGIN_IDENT_WIFI;
3316         macp->m_driver               = rsc;
3317         macp->m_dip          = devinfo;
3318         macp->m_src_addr     = ic->ic_macaddr;
3319         macp->m_callbacks    = &rtw_m_callbacks;
3320         macp->m_min_sdu              = 0;
3321         macp->m_max_sdu              = IEEE80211_MTU;
3322         macp->m_pdata                = &wd;
3323         macp->m_pdata_size   = sizeof (wd);
3324 
3325         err = mac_register(macp, &ic->ic_mach);
3326         mac_free(macp);
3327         if (err != 0) {
3328                 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw: rtw_attach(): "
3329                     "mac_register err %x\n", err);
3330                 goto attach_fail8;
3331         }
3332 
3333         /* Create minor node of type DDI_NT_NET_WIFI */
3334         (void) snprintf(strbuf, sizeof (strbuf), "%s%d",
3335             "rtw", instance);
3336         err = ddi_create_minor_node(devinfo, strbuf, S_IFCHR,
3337             instance + 1, DDI_NT_NET_WIFI, 0);
3338         if (err != DDI_SUCCESS) {
3339                 RTW_DPRINTF(RTW_DEBUG_ATTACH, "WARN: rtw: rtw_attach(): "
3340                     "Create minor node failed - %d\n", err);
3341                 goto attach_fail9;
3342         }
3343         mac_link_update(ic->ic_mach, LINK_STATE_DOWN);
3344         rsc->sc_flags |= RTW_F_ATTACHED;
3345         rsc->sc_need_reschedule = 0;
3346         rsc->sc_invalid = 1;
3347         return (DDI_SUCCESS);
3348 attach_fail9:
3349         (void) mac_disable(ic->ic_mach);
3350         (void) mac_unregister(ic->ic_mach);
3351 attach_fail8:
3352         ddi_remove_intr(devinfo, 0, rsc->sc_iblock);
3353 attach_fail7:
3354 attach_fail6:
3355         rtw_mutex_destroy(rsc);
3356 attach_fail5:
3357         ieee80211_detach(ic);
3358 attach_fail4:
3359         rtw_rf_destroy(rsc->sc_rf);
3360 attach_fail3:
3361         rtw_srom_free(&rsc->sc_srom);
3362 attach_fail2:
3363         rtw_dma_free(rsc);
3364 attach_fail1:
3365         ddi_regs_map_free(&rsc->sc_regs.r_handle);
3366 attach_fail0:
3367         ddi_soft_state_free(rtw_soft_state_p, ddi_get_instance(devinfo));
3368         return (DDI_FAILURE);
3369 }
3370 
3371 static int32_t
3372 rtw_detach(dev_info_t *devinfo, ddi_detach_cmd_t cmd)
3373 {
3374         rtw_softc_t *rsc;
3375 
3376         rsc = ddi_get_soft_state(rtw_soft_state_p, ddi_get_instance(devinfo));
3377         ASSERT(rsc != NULL);
3378 
3379         switch (cmd) {
3380         case DDI_DETACH:
3381                 break;
3382         case DDI_SUSPEND:
3383                 ieee80211_new_state(&rsc->sc_ic, IEEE80211_S_INIT, -1);
3384                 mutex_enter(&rsc->sc_genlock);
3385                 rsc->sc_flags |= RTW_F_SUSPEND;
3386                 mutex_exit(&rsc->sc_genlock);
3387                 if (rsc->sc_invalid == 0) {
3388                         rtw_stop(rsc);
3389                         mutex_enter(&rsc->sc_genlock);
3390                         rsc->sc_flags |= RTW_F_PLUMBED;
3391                         mutex_exit(&rsc->sc_genlock);
3392                 }
3393                 return (DDI_SUCCESS);
3394         default:
3395                 return (DDI_FAILURE);
3396         }
3397         if (!(rsc->sc_flags & RTW_F_ATTACHED))
3398                 return (DDI_FAILURE);
3399 
3400         if (mac_disable(rsc->sc_ic.ic_mach) != 0)
3401                 return (DDI_FAILURE);
3402 
3403         /* free intterrupt resources */
3404         ddi_remove_intr(devinfo, 0, rsc->sc_iblock);
3405 
3406         rtw_mutex_destroy(rsc);
3407         ieee80211_detach((ieee80211com_t *)rsc);
3408         /*
3409          * Unregister from the MAC layer subsystem
3410          */
3411         (void) mac_unregister(rsc->sc_ic.ic_mach);
3412 
3413         rtw_rf_destroy(rsc->sc_rf);
3414         rtw_srom_free(&rsc->sc_srom);
3415         rtw_dma_free(rsc);
3416         ddi_remove_minor_node(devinfo, NULL);
3417         ddi_regs_map_free(&rsc->sc_regs.r_handle);
3418 
3419         ddi_soft_state_free(rtw_soft_state_p, ddi_get_instance(devinfo));
3420 
3421         return (DDI_SUCCESS);
3422 }