The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ic/rtw.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* $NetBSD: rtw.c,v 1.45 2005/03/02 05:20:43 dyoung Exp $ */
    2 /*-
    3  * Copyright (c) 2004, 2005 David Young.  All rights reserved.
    4  *
    5  * Programmed for NetBSD by David Young.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  * 3. The name of David Young may not be used to endorse or promote
   16  *    products derived from this software without specific prior
   17  *    written permission.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY David Young ``AS IS'' AND ANY
   20  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
   21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
   22  * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL David
   23  * Young BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
   25  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   27  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   28  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
   30  * OF SUCH DAMAGE.
   31  */
   32 /*
   33  * Device driver for the Realtek RTL8180 802.11 MAC/BBP.
   34  */
   35 
   36 #include <sys/cdefs.h>
   37 __KERNEL_RCSID(0, "$NetBSD: rtw.c,v 1.45 2005/03/02 05:20:43 dyoung Exp $");
   38 
   39 #include "bpfilter.h"
   40 
   41 #include <sys/param.h>
   42 #include <sys/sysctl.h>
   43 #include <sys/systm.h>
   44 #include <sys/callout.h>
   45 #include <sys/mbuf.h>
   46 #include <sys/malloc.h>
   47 #include <sys/kernel.h>
   48 #include <sys/time.h>
   49 #include <sys/types.h>
   50 
   51 #include <machine/endian.h>
   52 #include <machine/bus.h>
   53 #include <machine/intr.h>       /* splnet */
   54 
   55 #include <uvm/uvm_extern.h>
   56 
   57 #include <net/if.h>
   58 #include <net/if_media.h>
   59 #include <net/if_ether.h>
   60 
   61 #include <net80211/ieee80211_var.h>
   62 #include <net80211/ieee80211_compat.h>
   63 #include <net80211/ieee80211_radiotap.h>
   64 
   65 #if NBPFILTER > 0
   66 #include <net/bpf.h>
   67 #endif
   68 
   69 #include <dev/ic/rtwreg.h>
   70 #include <dev/ic/rtwvar.h>
   71 #include <dev/ic/rtwphyio.h>
   72 #include <dev/ic/rtwphy.h>
   73 
   74 #include <dev/ic/smc93cx6var.h>
   75 
   76 #define KASSERT2(__cond, __msg)         \
   77         do {                            \
   78                 if (!(__cond))          \
   79                         panic __msg ;   \
   80         } while (0)
   81 
   82 int rtw_rfprog_fallback = 0;
   83 int rtw_host_rfio = 0;
   84 
   85 #ifdef RTW_DEBUG
   86 int rtw_debug = 0;
   87 int rtw_rxbufs_limit = RTW_RXQLEN;
   88 #endif /* RTW_DEBUG */
   89 
   90 #define NEXT_ATTACH_STATE(sc, state) do {                       \
   91         DPRINTF(sc, RTW_DEBUG_ATTACH,                           \
   92             ("%s: attach state %s\n", __func__, #state));       \
   93         sc->sc_attach_state = state;                            \
   94 } while (0)
   95 
   96 int rtw_dwelltime = 200;        /* milliseconds */
   97 
   98 static void rtw_start(struct ifnet *);
   99 
  100 static void rtw_led_attach(struct rtw_led_state *, void *);
  101 static void rtw_led_init(struct rtw_regs *);
  102 static void rtw_led_slowblink(void *);
  103 static void rtw_led_fastblink(void *);
  104 static void rtw_led_set(struct rtw_led_state *, struct rtw_regs *, int);
  105 
  106 static int rtw_sysctl_verify_rfio(SYSCTLFN_PROTO);
  107 static int rtw_sysctl_verify_rfprog(SYSCTLFN_PROTO);
  108 #ifdef RTW_DEBUG
  109 static void rtw_print_txdesc(struct rtw_softc *, const char *,
  110     struct rtw_txsoft *, struct rtw_txdesc_blk *, int);
  111 static int rtw_sysctl_verify_debug(SYSCTLFN_PROTO);
  112 static int rtw_sysctl_verify_rxbufs_limit(SYSCTLFN_PROTO);
  113 #endif /* RTW_DEBUG */
  114 
  115 /*
  116  * Setup sysctl(3) MIB, hw.rtw.*
  117  *
  118  * TBD condition CTLFLAG_PERMANENT on being an LKM or not
  119  */
  120 SYSCTL_SETUP(sysctl_rtw, "sysctl rtw(4) subtree setup")
  121 {
  122         int rc;
  123         struct sysctlnode *cnode, *rnode;
  124 
  125         if ((rc = sysctl_createv(clog, 0, NULL, &rnode,
  126             CTLFLAG_PERMANENT, CTLTYPE_NODE, "hw", NULL,
  127             NULL, 0, NULL, 0, CTL_HW, CTL_EOL)) != 0)
  128                 goto err;
  129 
  130         if ((rc = sysctl_createv(clog, 0, &rnode, &rnode,
  131             CTLFLAG_PERMANENT, CTLTYPE_NODE, "rtw",
  132             "Realtek RTL818x 802.11 controls",
  133             NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0)
  134                 goto err;
  135 
  136 #ifdef RTW_DEBUG
  137         /* control debugging printfs */
  138         if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
  139             CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
  140             "debug", SYSCTL_DESCR("Enable RTL818x debugging output"),
  141             rtw_sysctl_verify_debug, 0, &rtw_debug, 0,
  142             CTL_CREATE, CTL_EOL)) != 0)
  143                 goto err;
  144 
  145         /* Limit rx buffers, for simulating resource exhaustion. */
  146         if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
  147             CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
  148             "rxbufs_limit",
  149             SYSCTL_DESCR("Set rx buffers limit"),
  150             rtw_sysctl_verify_rxbufs_limit, 0, &rtw_rxbufs_limit, 0,
  151             CTL_CREATE, CTL_EOL)) != 0)
  152                 goto err;
  153 
  154 #endif /* RTW_DEBUG */
  155         /* set fallback RF programming method */
  156         if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
  157             CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
  158             "rfprog_fallback",
  159             SYSCTL_DESCR("Set fallback RF programming method"),
  160             rtw_sysctl_verify_rfprog, 0, &rtw_rfprog_fallback, 0,
  161             CTL_CREATE, CTL_EOL)) != 0)
  162                 goto err;
  163 
  164         /* force host to control RF I/O bus */
  165         if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
  166             CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
  167             "host_rfio", SYSCTL_DESCR("Enable host control of RF I/O"),
  168             rtw_sysctl_verify_rfio, 0, &rtw_host_rfio, 0,
  169             CTL_CREATE, CTL_EOL)) != 0)
  170                 goto err;
  171 
  172         return;
  173 err:
  174         printf("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
  175 }
  176 
  177 static int
  178 rtw_sysctl_verify(SYSCTLFN_ARGS, int lower, int upper)
  179 {
  180         int error, t;
  181         struct sysctlnode node;
  182 
  183         node = *rnode;
  184         t = *(int*)rnode->sysctl_data;
  185         node.sysctl_data = &t;
  186         error = sysctl_lookup(SYSCTLFN_CALL(&node));
  187         if (error || newp == NULL)
  188                 return (error);
  189 
  190         if (t < lower || t > upper)
  191                 return (EINVAL);
  192 
  193         *(int*)rnode->sysctl_data = t;
  194 
  195         return (0);
  196 }
  197 
  198 static int
  199 rtw_sysctl_verify_rfprog(SYSCTLFN_ARGS)
  200 {
  201         return rtw_sysctl_verify(SYSCTLFN_CALL(rnode), 0,
  202             MASK_AND_RSHIFT(RTW_CONFIG4_RFTYPE_MASK, RTW_CONFIG4_RFTYPE_MASK));
  203 }
  204 
  205 static int
  206 rtw_sysctl_verify_rfio(SYSCTLFN_ARGS)
  207 {
  208         return rtw_sysctl_verify(SYSCTLFN_CALL(rnode), 0, 1);
  209 }
  210 
  211 #ifdef RTW_DEBUG
  212 static int
  213 rtw_sysctl_verify_debug(SYSCTLFN_ARGS)
  214 {
  215         return rtw_sysctl_verify(SYSCTLFN_CALL(rnode), 0, RTW_DEBUG_MAX);
  216 }
  217 
  218 static int
  219 rtw_sysctl_verify_rxbufs_limit(SYSCTLFN_ARGS)
  220 {
  221         return rtw_sysctl_verify(SYSCTLFN_CALL(rnode), 0, RTW_RXQLEN);
  222 }
  223 
  224 static void
  225 rtw_print_regs(struct rtw_regs *regs, const char *dvname, const char *where)
  226 {
  227 #define PRINTREG32(sc, reg)                             \
  228         RTW_DPRINTF(RTW_DEBUG_REGDUMP,                  \
  229             ("%s: reg[ " #reg " / %03x ] = %08x\n",     \
  230             dvname, reg, RTW_READ(regs, reg)))
  231 
  232 #define PRINTREG16(sc, reg)                             \
  233         RTW_DPRINTF(RTW_DEBUG_REGDUMP,                  \
  234             ("%s: reg[ " #reg " / %03x ] = %04x\n",     \
  235             dvname, reg, RTW_READ16(regs, reg)))
  236 
  237 #define PRINTREG8(sc, reg)                              \
  238         RTW_DPRINTF(RTW_DEBUG_REGDUMP,                  \
  239             ("%s: reg[ " #reg " / %03x ] = %02x\n",     \
  240             dvname, reg, RTW_READ8(regs, reg)))
  241 
  242         RTW_DPRINTF(RTW_DEBUG_REGDUMP, ("%s: %s\n", dvname, where));
  243 
  244         PRINTREG32(regs, RTW_IDR0);
  245         PRINTREG32(regs, RTW_IDR1);
  246         PRINTREG32(regs, RTW_MAR0);
  247         PRINTREG32(regs, RTW_MAR1);
  248         PRINTREG32(regs, RTW_TSFTRL);
  249         PRINTREG32(regs, RTW_TSFTRH);
  250         PRINTREG32(regs, RTW_TLPDA);
  251         PRINTREG32(regs, RTW_TNPDA);
  252         PRINTREG32(regs, RTW_THPDA);
  253         PRINTREG32(regs, RTW_TCR);
  254         PRINTREG32(regs, RTW_RCR);
  255         PRINTREG32(regs, RTW_TINT);
  256         PRINTREG32(regs, RTW_TBDA);
  257         PRINTREG32(regs, RTW_ANAPARM);
  258         PRINTREG32(regs, RTW_BB);
  259         PRINTREG32(regs, RTW_PHYCFG);
  260         PRINTREG32(regs, RTW_WAKEUP0L);
  261         PRINTREG32(regs, RTW_WAKEUP0H);
  262         PRINTREG32(regs, RTW_WAKEUP1L);
  263         PRINTREG32(regs, RTW_WAKEUP1H);
  264         PRINTREG32(regs, RTW_WAKEUP2LL);
  265         PRINTREG32(regs, RTW_WAKEUP2LH);
  266         PRINTREG32(regs, RTW_WAKEUP2HL);
  267         PRINTREG32(regs, RTW_WAKEUP2HH);
  268         PRINTREG32(regs, RTW_WAKEUP3LL);
  269         PRINTREG32(regs, RTW_WAKEUP3LH);
  270         PRINTREG32(regs, RTW_WAKEUP3HL);
  271         PRINTREG32(regs, RTW_WAKEUP3HH);
  272         PRINTREG32(regs, RTW_WAKEUP4LL);
  273         PRINTREG32(regs, RTW_WAKEUP4LH);
  274         PRINTREG32(regs, RTW_WAKEUP4HL);
  275         PRINTREG32(regs, RTW_WAKEUP4HH);
  276         PRINTREG32(regs, RTW_DK0);
  277         PRINTREG32(regs, RTW_DK1);
  278         PRINTREG32(regs, RTW_DK2);
  279         PRINTREG32(regs, RTW_DK3);
  280         PRINTREG32(regs, RTW_RETRYCTR);
  281         PRINTREG32(regs, RTW_RDSAR);
  282         PRINTREG32(regs, RTW_FER);
  283         PRINTREG32(regs, RTW_FEMR);
  284         PRINTREG32(regs, RTW_FPSR);
  285         PRINTREG32(regs, RTW_FFER);
  286 
  287         /* 16-bit registers */
  288         PRINTREG16(regs, RTW_BRSR);
  289         PRINTREG16(regs, RTW_IMR);
  290         PRINTREG16(regs, RTW_ISR);
  291         PRINTREG16(regs, RTW_BCNITV);
  292         PRINTREG16(regs, RTW_ATIMWND);
  293         PRINTREG16(regs, RTW_BINTRITV);
  294         PRINTREG16(regs, RTW_ATIMTRITV);
  295         PRINTREG16(regs, RTW_CRC16ERR);
  296         PRINTREG16(regs, RTW_CRC0);
  297         PRINTREG16(regs, RTW_CRC1);
  298         PRINTREG16(regs, RTW_CRC2);
  299         PRINTREG16(regs, RTW_CRC3);
  300         PRINTREG16(regs, RTW_CRC4);
  301         PRINTREG16(regs, RTW_CWR);
  302 
  303         /* 8-bit registers */
  304         PRINTREG8(regs, RTW_CR);
  305         PRINTREG8(regs, RTW_9346CR);
  306         PRINTREG8(regs, RTW_CONFIG0);
  307         PRINTREG8(regs, RTW_CONFIG1);
  308         PRINTREG8(regs, RTW_CONFIG2);
  309         PRINTREG8(regs, RTW_MSR);
  310         PRINTREG8(regs, RTW_CONFIG3);
  311         PRINTREG8(regs, RTW_CONFIG4);
  312         PRINTREG8(regs, RTW_TESTR);
  313         PRINTREG8(regs, RTW_PSR);
  314         PRINTREG8(regs, RTW_SCR);
  315         PRINTREG8(regs, RTW_PHYDELAY);
  316         PRINTREG8(regs, RTW_CRCOUNT);
  317         PRINTREG8(regs, RTW_PHYADDR);
  318         PRINTREG8(regs, RTW_PHYDATAW);
  319         PRINTREG8(regs, RTW_PHYDATAR);
  320         PRINTREG8(regs, RTW_CONFIG5);
  321         PRINTREG8(regs, RTW_TPPOLL);
  322 
  323         PRINTREG16(regs, RTW_BSSID16);
  324         PRINTREG32(regs, RTW_BSSID32);
  325 #undef PRINTREG32
  326 #undef PRINTREG16
  327 #undef PRINTREG8
  328 }
  329 #endif /* RTW_DEBUG */
  330 
  331 void
  332 rtw_continuous_tx_enable(struct rtw_softc *sc, int enable)
  333 {
  334         struct rtw_regs *regs = &sc->sc_regs;
  335 
  336         uint32_t tcr;
  337         tcr = RTW_READ(regs, RTW_TCR);
  338         tcr &= ~RTW_TCR_LBK_MASK;
  339         if (enable)
  340                 tcr |= RTW_TCR_LBK_CONT;
  341         else
  342                 tcr |= RTW_TCR_LBK_NORMAL;
  343         RTW_WRITE(regs, RTW_TCR, tcr);
  344         RTW_SYNC(regs, RTW_TCR, RTW_TCR);
  345         rtw_set_access(regs, RTW_ACCESS_ANAPARM);
  346         rtw_txdac_enable(sc, !enable);
  347         rtw_set_access(regs, RTW_ACCESS_ANAPARM);/* XXX Voodoo from Linux. */
  348         rtw_set_access(regs, RTW_ACCESS_NONE);
  349 }
  350 
  351 #ifdef RTW_DEBUG
  352 static const char *
  353 rtw_access_string(enum rtw_access access)
  354 {
  355         switch (access) {
  356         case RTW_ACCESS_NONE:
  357                 return "none";
  358         case RTW_ACCESS_CONFIG:
  359                 return "config";
  360         case RTW_ACCESS_ANAPARM:
  361                 return "anaparm";
  362         default:
  363                 return "unknown";
  364         }
  365 }
  366 #endif /* RTW_DEBUG */
  367 
  368 static void
  369 rtw_set_access1(struct rtw_regs *regs, enum rtw_access naccess)
  370 {
  371         KASSERT(naccess >= RTW_ACCESS_NONE && naccess <= RTW_ACCESS_ANAPARM);
  372         KASSERT(regs->r_access >= RTW_ACCESS_NONE &&
  373                 regs->r_access <= RTW_ACCESS_ANAPARM);
  374 
  375         if (naccess == regs->r_access)
  376                 return;
  377 
  378         switch (naccess) {
  379         case RTW_ACCESS_NONE:
  380                 switch (regs->r_access) {
  381                 case RTW_ACCESS_ANAPARM:
  382                         rtw_anaparm_enable(regs, 0);
  383                         /*FALLTHROUGH*/
  384                 case RTW_ACCESS_CONFIG:
  385                         rtw_config0123_enable(regs, 0);
  386                         /*FALLTHROUGH*/
  387                 case RTW_ACCESS_NONE:
  388                         break;
  389                 }
  390                 break;
  391         case RTW_ACCESS_CONFIG:
  392                 switch (regs->r_access) {
  393                 case RTW_ACCESS_NONE:
  394                         rtw_config0123_enable(regs, 1);
  395                         /*FALLTHROUGH*/
  396                 case RTW_ACCESS_CONFIG:
  397                         break;
  398                 case RTW_ACCESS_ANAPARM:
  399                         rtw_anaparm_enable(regs, 0);
  400                         break;
  401                 }
  402                 break;
  403         case RTW_ACCESS_ANAPARM:
  404                 switch (regs->r_access) {
  405                 case RTW_ACCESS_NONE:
  406                         rtw_config0123_enable(regs, 1);
  407                         /*FALLTHROUGH*/
  408                 case RTW_ACCESS_CONFIG:
  409                         rtw_anaparm_enable(regs, 1);
  410                         /*FALLTHROUGH*/
  411                 case RTW_ACCESS_ANAPARM:
  412                         break;
  413                 }
  414                 break;
  415         }
  416 }
  417 
  418 void
  419 rtw_set_access(struct rtw_regs *regs, enum rtw_access access)
  420 {
  421         rtw_set_access1(regs, access);
  422         RTW_DPRINTF(RTW_DEBUG_ACCESS,
  423             ("%s: access %s -> %s\n", __func__,
  424             rtw_access_string(regs->r_access),
  425             rtw_access_string(access)));
  426         regs->r_access = access;
  427 }
  428 
  429 /*
  430  * Enable registers, switch register banks.
  431  */
  432 void
  433 rtw_config0123_enable(struct rtw_regs *regs, int enable)
  434 {
  435         uint8_t ecr;
  436         ecr = RTW_READ8(regs, RTW_9346CR);
  437         ecr &= ~(RTW_9346CR_EEM_MASK | RTW_9346CR_EECS | RTW_9346CR_EESK);
  438         if (enable)
  439                 ecr |= RTW_9346CR_EEM_CONFIG;
  440         else {
  441                 RTW_WBW(regs, RTW_9346CR, MAX(RTW_CONFIG0, RTW_CONFIG3));
  442                 ecr |= RTW_9346CR_EEM_NORMAL;
  443         }
  444         RTW_WRITE8(regs, RTW_9346CR, ecr);
  445         RTW_SYNC(regs, RTW_9346CR, RTW_9346CR);
  446 }
  447 
  448 /* requires rtw_config0123_enable(, 1) */
  449 void
  450 rtw_anaparm_enable(struct rtw_regs *regs, int enable)
  451 {
  452         uint8_t cfg3;
  453 
  454         cfg3 = RTW_READ8(regs, RTW_CONFIG3);
  455         cfg3 |= RTW_CONFIG3_CLKRUNEN;
  456         if (enable)
  457                 cfg3 |= RTW_CONFIG3_PARMEN;
  458         else
  459                 cfg3 &= ~RTW_CONFIG3_PARMEN;
  460         RTW_WRITE8(regs, RTW_CONFIG3, cfg3);
  461         RTW_SYNC(regs, RTW_CONFIG3, RTW_CONFIG3);
  462 }
  463 
  464 /* requires rtw_anaparm_enable(, 1) */
  465 void
  466 rtw_txdac_enable(struct rtw_softc *sc, int enable)
  467 {
  468         uint32_t anaparm;
  469         struct rtw_regs *regs = &sc->sc_regs;
  470 
  471         anaparm = RTW_READ(regs, RTW_ANAPARM);
  472         if (enable)
  473                 anaparm &= ~RTW_ANAPARM_TXDACOFF;
  474         else
  475                 anaparm |= RTW_ANAPARM_TXDACOFF;
  476         RTW_WRITE(regs, RTW_ANAPARM, anaparm);
  477         RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM);
  478 }
  479 
  480 static __inline int
  481 rtw_chip_reset1(struct rtw_regs *regs, const char *dvname)
  482 {
  483         uint8_t cr;
  484         int i;
  485 
  486         RTW_WRITE8(regs, RTW_CR, RTW_CR_RST);
  487 
  488         RTW_WBR(regs, RTW_CR, RTW_CR);
  489 
  490         for (i = 0; i < 1000; i++) {
  491                 if ((cr = RTW_READ8(regs, RTW_CR) & RTW_CR_RST) == 0) {
  492                         RTW_DPRINTF(RTW_DEBUG_RESET,
  493                             ("%s: reset in %dus\n", dvname, i));
  494                         return 0;
  495                 }
  496                 RTW_RBR(regs, RTW_CR, RTW_CR);
  497                 DELAY(10); /* 10us */
  498         }
  499 
  500         printf("%s: reset failed\n", dvname);
  501         return ETIMEDOUT;
  502 }
  503 
  504 static __inline int
  505 rtw_chip_reset(struct rtw_regs *regs, const char *dvname)
  506 {
  507         uint32_t tcr;
  508 
  509         /* from Linux driver */
  510         tcr = RTW_TCR_CWMIN | RTW_TCR_MXDMA_2048 |
  511               LSHIFT(7, RTW_TCR_SRL_MASK) | LSHIFT(7, RTW_TCR_LRL_MASK);
  512 
  513         RTW_WRITE(regs, RTW_TCR, tcr);
  514 
  515         RTW_WBW(regs, RTW_CR, RTW_TCR);
  516 
  517         return rtw_chip_reset1(regs, dvname);
  518 }
  519 
  520 static void
  521 rtw_wep_setkeys(struct rtw_softc *sc, struct ieee80211_wepkey *wk, int txkey)
  522 {
  523         uint8_t cfg0, scr;
  524         int i, j, tx_key_len;
  525         struct rtw_regs *regs;
  526         union rtw_keys *rk;
  527 
  528         regs = &sc->sc_regs;
  529         rk = &sc->sc_keys;
  530 
  531         (void)memset(rk->rk_keys, 0, sizeof(rk->rk_keys));
  532 
  533         scr = RTW_READ8(regs, RTW_SCR);
  534         cfg0 = RTW_READ8(regs, RTW_CONFIG0);
  535         scr &= ~(RTW_SCR_KM_MASK | RTW_SCR_TXSECON | RTW_SCR_RXSECON);
  536         cfg0 &= ~(RTW_CONFIG0_WEP104 | RTW_CONFIG0_WEP40);
  537 
  538         rtw_set_access(regs, RTW_ACCESS_CONFIG);
  539 
  540         if ((sc->sc_ic.ic_flags & IEEE80211_F_PRIVACY) == 0)
  541                 goto out;
  542 
  543         tx_key_len = wk[txkey].wk_len;
  544 
  545         switch (tx_key_len) {
  546         case 5:
  547                 scr |= RTW_SCR_TXSECON | RTW_SCR_RXSECON | RTW_SCR_KM_WEP40;
  548                 break;
  549         case 13:
  550                 scr |= RTW_SCR_TXSECON | RTW_SCR_RXSECON | RTW_SCR_KM_WEP104;
  551                 break;
  552         default:
  553                 goto out;
  554         }
  555 
  556         cfg0 |= RTW_CONFIG0_WEP104 | RTW_CONFIG0_WEP40;
  557 
  558         for (i = j = 0; i < IEEE80211_WEP_NKID; i++) {
  559                 if (i == txkey)
  560                         sc->sc_txkey = j;
  561                 else if (wk[i].wk_len != tx_key_len)
  562                         continue;
  563                 (void)memcpy(rk->rk_keys[j++], wk[i].wk_key, wk[i].wk_len);
  564         }
  565 
  566 out:
  567         bus_space_write_region_4(regs->r_bt, regs->r_bh,
  568             RTW_DK0, rk->rk_words,
  569             sizeof(rk->rk_words) / sizeof(rk->rk_words[0]));
  570 
  571         bus_space_barrier(regs->r_bt, regs->r_bh, RTW_DK0,
  572             sizeof(rk->rk_words) / sizeof(rk->rk_words[0]),
  573             BUS_SPACE_BARRIER_SYNC);
  574 
  575         RTW_WRITE8(regs, RTW_CONFIG0, cfg0);
  576         RTW_WBW(regs, RTW_CONFIG0, RTW_SCR);
  577         RTW_WRITE8(regs, RTW_SCR, scr);
  578         RTW_SYNC(regs, RTW_SCR, RTW_SCR);
  579         rtw_set_access(regs, RTW_ACCESS_NONE);
  580 }
  581 
  582 static __inline int
  583 rtw_recall_eeprom(struct rtw_regs *regs, const char *dvname)
  584 {
  585         int i;
  586         uint8_t ecr;
  587 
  588         ecr = RTW_READ8(regs, RTW_9346CR);
  589         ecr = (ecr & ~RTW_9346CR_EEM_MASK) | RTW_9346CR_EEM_AUTOLOAD;
  590         RTW_WRITE8(regs, RTW_9346CR, ecr);
  591 
  592         RTW_WBR(regs, RTW_9346CR, RTW_9346CR);
  593 
  594         /* wait 2.5ms for completion */
  595         for (i = 0; i < 25; i++) {
  596                 ecr = RTW_READ8(regs, RTW_9346CR);
  597                 if ((ecr & RTW_9346CR_EEM_MASK) == RTW_9346CR_EEM_NORMAL) {
  598                         RTW_DPRINTF(RTW_DEBUG_RESET,
  599                             ("%s: recall EEPROM in %dus\n", dvname, i * 100));
  600                         return 0;
  601                 }
  602                 RTW_RBR(regs, RTW_9346CR, RTW_9346CR);
  603                 DELAY(100);
  604         }
  605         printf("%s: recall EEPROM failed\n", dvname);
  606         return ETIMEDOUT;
  607 }
  608 
  609 static __inline int
  610 rtw_reset(struct rtw_softc *sc)
  611 {
  612         int rc;
  613         uint8_t config1;
  614 
  615         if ((rc = rtw_chip_reset(&sc->sc_regs, sc->sc_dev.dv_xname)) != 0)
  616                 return rc;
  617 
  618         if ((rc = rtw_recall_eeprom(&sc->sc_regs, sc->sc_dev.dv_xname)) != 0)
  619                 ;
  620 
  621         config1 = RTW_READ8(&sc->sc_regs, RTW_CONFIG1);
  622         RTW_WRITE8(&sc->sc_regs, RTW_CONFIG1, config1 & ~RTW_CONFIG1_PMEN);
  623         /* TBD turn off maximum power saving? */
  624 
  625         return 0;
  626 }
  627 
  628 static __inline int
  629 rtw_txdesc_dmamaps_create(bus_dma_tag_t dmat, struct rtw_txsoft *descs,
  630     u_int ndescs)
  631 {
  632         int i, rc = 0;
  633         for (i = 0; i < ndescs; i++) {
  634                 rc = bus_dmamap_create(dmat, MCLBYTES, RTW_MAXPKTSEGS, MCLBYTES,
  635                     0, 0, &descs[i].ts_dmamap);
  636                 if (rc != 0)
  637                         break;
  638         }
  639         return rc;
  640 }
  641 
  642 static __inline int
  643 rtw_rxdesc_dmamaps_create(bus_dma_tag_t dmat, struct rtw_rxsoft *descs,
  644     u_int ndescs)
  645 {
  646         int i, rc = 0;
  647         for (i = 0; i < ndescs; i++) {
  648                 rc = bus_dmamap_create(dmat, MCLBYTES, 1, MCLBYTES, 0, 0,
  649                     &descs[i].rs_dmamap);
  650                 if (rc != 0)
  651                         break;
  652         }
  653         return rc;
  654 }
  655 
  656 static __inline void
  657 rtw_rxdesc_dmamaps_destroy(bus_dma_tag_t dmat, struct rtw_rxsoft *descs,
  658     u_int ndescs)
  659 {
  660         int i;
  661         for (i = 0; i < ndescs; i++) {
  662                 if (descs[i].rs_dmamap != NULL)
  663                         bus_dmamap_destroy(dmat, descs[i].rs_dmamap);
  664         }
  665 }
  666 
  667 static __inline void
  668 rtw_txdesc_dmamaps_destroy(bus_dma_tag_t dmat, struct rtw_txsoft *descs,
  669     u_int ndescs)
  670 {
  671         int i;
  672         for (i = 0; i < ndescs; i++) {
  673                 if (descs[i].ts_dmamap != NULL)
  674                         bus_dmamap_destroy(dmat, descs[i].ts_dmamap);
  675         }
  676 }
  677 
  678 static __inline void
  679 rtw_srom_free(struct rtw_srom *sr)
  680 {
  681         sr->sr_size = 0;
  682         if (sr->sr_content == NULL)
  683                 return;
  684         free(sr->sr_content, M_DEVBUF);
  685         sr->sr_content = NULL;
  686 }
  687 
  688 static void
  689 rtw_srom_defaults(struct rtw_srom *sr, uint32_t *flags, uint8_t *cs_threshold,
  690     enum rtw_rfchipid *rfchipid, uint32_t *rcr)
  691 {
  692         *flags |= (RTW_F_DIGPHY|RTW_F_ANTDIV);
  693         *cs_threshold = RTW_SR_ENERGYDETTHR_DEFAULT;
  694         *rcr |= RTW_RCR_ENCS1;
  695         *rfchipid = RTW_RFCHIPID_PHILIPS;
  696 }
  697 
  698 static int
  699 rtw_srom_parse(struct rtw_srom *sr, uint32_t *flags, uint8_t *cs_threshold,
  700     enum rtw_rfchipid *rfchipid, uint32_t *rcr, enum rtw_locale *locale,
  701     const char *dvname)
  702 {
  703         int i;
  704         const char *rfname, *paname;
  705         char scratch[sizeof("unknown 0xXX")];
  706         uint16_t version;
  707         uint8_t mac[IEEE80211_ADDR_LEN];
  708 
  709         *flags &= ~(RTW_F_DIGPHY|RTW_F_DFLANTB|RTW_F_ANTDIV);
  710         *rcr &= ~(RTW_RCR_ENCS1 | RTW_RCR_ENCS2);
  711 
  712         version = RTW_SR_GET16(sr, RTW_SR_VERSION);
  713         printf("%s: SROM version %d.%d", dvname, version >> 8, version & 0xff);
  714 
  715         if (version <= 0x0101) {
  716                 printf(" is not understood, limping along with defaults\n");
  717                 rtw_srom_defaults(sr, flags, cs_threshold, rfchipid, rcr);
  718                 return 0;
  719         }
  720         printf("\n");
  721 
  722         for (i = 0; i < IEEE80211_ADDR_LEN; i++)
  723                 mac[i] = RTW_SR_GET(sr, RTW_SR_MAC + i);
  724 
  725         RTW_DPRINTF(RTW_DEBUG_ATTACH,
  726             ("%s: EEPROM MAC %s\n", dvname, ether_sprintf(mac)));
  727 
  728         *cs_threshold = RTW_SR_GET(sr, RTW_SR_ENERGYDETTHR);
  729 
  730         if ((RTW_SR_GET(sr, RTW_SR_CONFIG2) & RTW_CONFIG2_ANT) != 0)
  731                 *flags |= RTW_F_ANTDIV;
  732 
  733         /* Note well: the sense of the RTW_SR_RFPARM_DIGPHY bit seems
  734          * to be reversed.
  735          */
  736         if ((RTW_SR_GET(sr, RTW_SR_RFPARM) & RTW_SR_RFPARM_DIGPHY) == 0)
  737                 *flags |= RTW_F_DIGPHY;
  738         if ((RTW_SR_GET(sr, RTW_SR_RFPARM) & RTW_SR_RFPARM_DFLANTB) != 0)
  739                 *flags |= RTW_F_DFLANTB;
  740 
  741         *rcr |= LSHIFT(MASK_AND_RSHIFT(RTW_SR_GET(sr, RTW_SR_RFPARM),
  742             RTW_SR_RFPARM_CS_MASK), RTW_RCR_ENCS1);
  743 
  744         *rfchipid = RTW_SR_GET(sr, RTW_SR_RFCHIPID);
  745         switch (*rfchipid) {
  746         case RTW_RFCHIPID_GCT:          /* this combo seen in the wild */
  747                 rfname = "GCT GRF5101";
  748                 paname = "Winspring WS9901";
  749                 break;
  750         case RTW_RFCHIPID_MAXIM:
  751                 rfname = "Maxim MAX2820";       /* guess */
  752                 paname = "Maxim MAX2422";       /* guess */
  753                 break;
  754         case RTW_RFCHIPID_INTERSIL:
  755                 rfname = "Intersil HFA3873";    /* guess */
  756                 paname = "Intersil <unknown>";
  757                 break;
  758         case RTW_RFCHIPID_PHILIPS:      /* this combo seen in the wild */
  759                 rfname = "Philips SA2400A";
  760                 paname = "Philips SA2411";
  761                 break;
  762         case RTW_RFCHIPID_RFMD:
  763                 /* this is the same front-end as an atw(4)! */
  764                 rfname = "RFMD RF2948B, "       /* mentioned in Realtek docs */
  765                          "LNA: RFMD RF2494, "   /* mentioned in Realtek docs */
  766                          "SYN: Silicon Labs Si4126";    /* inferred from
  767                                                          * reference driver
  768                                                          */
  769                 paname = "RFMD RF2189";         /* mentioned in Realtek docs */
  770                 break;
  771         case RTW_RFCHIPID_RESERVED:
  772                 rfname = paname = "reserved";
  773                 break;
  774         default:
  775                 snprintf(scratch, sizeof(scratch), "unknown 0x%02x", *rfchipid);
  776                 rfname = paname = scratch;
  777         }
  778         printf("%s: RF: %s, PA: %s\n", dvname, rfname, paname);
  779 
  780         switch (RTW_SR_GET(sr, RTW_SR_CONFIG0) & RTW_CONFIG0_GL_MASK) {
  781         case RTW_CONFIG0_GL_USA:
  782                 *locale = RTW_LOCALE_USA;
  783                 break;
  784         case RTW_CONFIG0_GL_EUROPE:
  785                 *locale = RTW_LOCALE_EUROPE;
  786                 break;
  787         case RTW_CONFIG0_GL_JAPAN:
  788                 *locale = RTW_LOCALE_JAPAN;
  789                 break;
  790         default:
  791                 *locale = RTW_LOCALE_UNKNOWN;
  792                 break;
  793         }
  794         return 0;
  795 }
  796 
  797 /* Returns -1 on failure. */
  798 static int
  799 rtw_srom_read(struct rtw_regs *regs, uint32_t flags, struct rtw_srom *sr,
  800     const char *dvname)
  801 {
  802         int rc;
  803         struct seeprom_descriptor sd;
  804         uint8_t ecr;
  805 
  806         (void)memset(&sd, 0, sizeof(sd));
  807 
  808         ecr = RTW_READ8(regs, RTW_9346CR);
  809 
  810         if ((flags & RTW_F_9356SROM) != 0) {
  811                 RTW_DPRINTF(RTW_DEBUG_ATTACH, ("%s: 93c56 SROM\n", dvname));
  812                 sr->sr_size = 256;
  813                 sd.sd_chip = C56_66;
  814         } else {
  815                 RTW_DPRINTF(RTW_DEBUG_ATTACH, ("%s: 93c46 SROM\n", dvname));
  816                 sr->sr_size = 128;
  817                 sd.sd_chip = C46;
  818         }
  819 
  820         ecr &= ~(RTW_9346CR_EEDI | RTW_9346CR_EEDO | RTW_9346CR_EESK |
  821             RTW_9346CR_EEM_MASK | RTW_9346CR_EECS);
  822         ecr |= RTW_9346CR_EEM_PROGRAM;
  823 
  824         RTW_WRITE8(regs, RTW_9346CR, ecr);
  825 
  826         sr->sr_content = malloc(sr->sr_size, M_DEVBUF, M_NOWAIT);
  827 
  828         if (sr->sr_content == NULL) {
  829                 printf("%s: unable to allocate SROM buffer\n", dvname);
  830                 return ENOMEM;
  831         }
  832 
  833         (void)memset(sr->sr_content, 0, sr->sr_size);
  834 
  835         /* RTL8180 has a single 8-bit register for controlling the
  836          * 93cx6 SROM.  There is no "ready" bit. The RTL8180
  837          * input/output sense is the reverse of read_seeprom's.
  838          */
  839         sd.sd_tag = regs->r_bt;
  840         sd.sd_bsh = regs->r_bh;
  841         sd.sd_regsize = 1;
  842         sd.sd_control_offset = RTW_9346CR;
  843         sd.sd_status_offset = RTW_9346CR;
  844         sd.sd_dataout_offset = RTW_9346CR;
  845         sd.sd_CK = RTW_9346CR_EESK;
  846         sd.sd_CS = RTW_9346CR_EECS;
  847         sd.sd_DI = RTW_9346CR_EEDO;
  848         sd.sd_DO = RTW_9346CR_EEDI;
  849         /* make read_seeprom enter EEPROM read/write mode */
  850         sd.sd_MS = ecr;
  851         sd.sd_RDY = 0;
  852 
  853         /* TBD bus barriers */
  854         if (!read_seeprom(&sd, sr->sr_content, 0, sr->sr_size/2)) {
  855                 printf("%s: could not read SROM\n", dvname);
  856                 free(sr->sr_content, M_DEVBUF);
  857                 sr->sr_content = NULL;
  858                 return -1;      /* XXX */
  859         }
  860 
  861         /* end EEPROM read/write mode */
  862         RTW_WRITE8(regs, RTW_9346CR,
  863             (ecr & ~RTW_9346CR_EEM_MASK) | RTW_9346CR_EEM_NORMAL);
  864         RTW_WBRW(regs, RTW_9346CR, RTW_9346CR);
  865 
  866         if ((rc = rtw_recall_eeprom(regs, dvname)) != 0)
  867                 return rc;
  868 
  869 #ifdef RTW_DEBUG
  870         {
  871                 int i;
  872                 RTW_DPRINTF(RTW_DEBUG_ATTACH,
  873                     ("\n%s: serial ROM:\n\t", dvname));
  874                 for (i = 0; i < sr->sr_size/2; i++) {
  875                         if (((i % 8) == 0) && (i != 0))
  876                                 RTW_DPRINTF(RTW_DEBUG_ATTACH, ("\n\t"));
  877                         RTW_DPRINTF(RTW_DEBUG_ATTACH,
  878                             (" %04x", sr->sr_content[i]));
  879                 }
  880                 RTW_DPRINTF(RTW_DEBUG_ATTACH, ("\n"));
  881         }
  882 #endif /* RTW_DEBUG */
  883         return 0;
  884 }
  885 
  886 static void
  887 rtw_set_rfprog(struct rtw_regs *regs, enum rtw_rfchipid rfchipid,
  888     const char *dvname)
  889 {
  890         uint8_t cfg4;
  891         const char *method;
  892 
  893         cfg4 = RTW_READ8(regs, RTW_CONFIG4) & ~RTW_CONFIG4_RFTYPE_MASK;
  894 
  895         switch (rfchipid) {
  896         default:
  897                 cfg4 |= LSHIFT(rtw_rfprog_fallback, RTW_CONFIG4_RFTYPE_MASK);
  898                 method = "fallback";
  899                 break;
  900         case RTW_RFCHIPID_INTERSIL:
  901                 cfg4 |= RTW_CONFIG4_RFTYPE_INTERSIL;
  902                 method = "Intersil";
  903                 break;
  904         case RTW_RFCHIPID_PHILIPS:
  905                 cfg4 |= RTW_CONFIG4_RFTYPE_PHILIPS;
  906                 method = "Philips";
  907                 break;
  908         case RTW_RFCHIPID_GCT:  /* XXX a guess */
  909         case RTW_RFCHIPID_RFMD:
  910                 cfg4 |= RTW_CONFIG4_RFTYPE_RFMD;
  911                 method = "RFMD";
  912                 break;
  913         }
  914 
  915         RTW_WRITE8(regs, RTW_CONFIG4, cfg4);
  916 
  917         RTW_WBR(regs, RTW_CONFIG4, RTW_CONFIG4);
  918 
  919         RTW_DPRINTF(RTW_DEBUG_INIT,
  920             ("%s: %s RF programming method, %#02x\n", dvname, method,
  921             RTW_READ8(regs, RTW_CONFIG4)));
  922 }
  923 
  924 static __inline void
  925 rtw_init_channels(enum rtw_locale locale,
  926     struct ieee80211_channel (*chans)[IEEE80211_CHAN_MAX+1],
  927     const char *dvname)
  928 {
  929         int i;
  930         const char *name = NULL;
  931 #define ADD_CHANNEL(_chans, _chan) do {                 \
  932         (*_chans)[_chan].ic_flags = IEEE80211_CHAN_B;           \
  933         (*_chans)[_chan].ic_freq =                              \
  934             ieee80211_ieee2mhz(_chan, (*_chans)[_chan].ic_flags);\
  935 } while (0)
  936 
  937         switch (locale) {
  938         case RTW_LOCALE_USA:    /* 1-11 */
  939                 name = "USA";
  940                 for (i = 1; i <= 11; i++)
  941                         ADD_CHANNEL(chans, i);
  942                 break;
  943         case RTW_LOCALE_JAPAN:  /* 1-14 */
  944                 name = "Japan";
  945                 ADD_CHANNEL(chans, 14);
  946                 for (i = 1; i <= 14; i++)
  947                         ADD_CHANNEL(chans, i);
  948                 break;
  949         case RTW_LOCALE_EUROPE: /* 1-13 */
  950                 name = "Europe";
  951                 for (i = 1; i <= 13; i++)
  952                         ADD_CHANNEL(chans, i);
  953                 break;
  954         default:                        /* 10-11 allowed by most countries */
  955                 name = "<unknown>";
  956                 for (i = 10; i <= 11; i++)
  957                         ADD_CHANNEL(chans, i);
  958                 break;
  959         }
  960         printf("%s: Geographic Location %s\n", dvname, name);
  961 #undef ADD_CHANNEL
  962 }
  963 
  964 static __inline void
  965 rtw_identify_country(struct rtw_regs *regs, enum rtw_locale *locale,
  966     const char *dvname)
  967 {
  968         uint8_t cfg0 = RTW_READ8(regs, RTW_CONFIG0);
  969 
  970         switch (cfg0 & RTW_CONFIG0_GL_MASK) {
  971         case RTW_CONFIG0_GL_USA:
  972                 *locale = RTW_LOCALE_USA;
  973                 break;
  974         case RTW_CONFIG0_GL_JAPAN:
  975                 *locale = RTW_LOCALE_JAPAN;
  976                 break;
  977         case RTW_CONFIG0_GL_EUROPE:
  978                 *locale = RTW_LOCALE_EUROPE;
  979                 break;
  980         default:
  981                 *locale = RTW_LOCALE_UNKNOWN;
  982                 break;
  983         }
  984 }
  985 
  986 static __inline int
  987 rtw_identify_sta(struct rtw_regs *regs, uint8_t (*addr)[IEEE80211_ADDR_LEN],
  988     const char *dvname)
  989 {
  990         static const uint8_t empty_macaddr[IEEE80211_ADDR_LEN] = {
  991                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  992         };
  993         uint32_t idr0 = RTW_READ(regs, RTW_IDR0),
  994                   idr1 = RTW_READ(regs, RTW_IDR1);
  995 
  996         (*addr)[0] = MASK_AND_RSHIFT(idr0, BITS(0,  7));
  997         (*addr)[1] = MASK_AND_RSHIFT(idr0, BITS(8,  15));
  998         (*addr)[2] = MASK_AND_RSHIFT(idr0, BITS(16, 23));
  999         (*addr)[3] = MASK_AND_RSHIFT(idr0, BITS(24 ,31));
 1000 
 1001         (*addr)[4] = MASK_AND_RSHIFT(idr1, BITS(0,  7));
 1002         (*addr)[5] = MASK_AND_RSHIFT(idr1, BITS(8, 15));
 1003 
 1004         if (IEEE80211_ADDR_EQ(addr, empty_macaddr)) {
 1005                 printf("%s: could not get mac address, attach failed\n",
 1006                     dvname);
 1007                 return ENXIO;
 1008         }
 1009 
 1010         printf("%s: 802.11 address %s\n", dvname, ether_sprintf(*addr));
 1011 
 1012         return 0;
 1013 }
 1014 
 1015 static uint8_t
 1016 rtw_chan2txpower(struct rtw_srom *sr, struct ieee80211com *ic,
 1017     struct ieee80211_channel *chan)
 1018 {
 1019         u_int idx = RTW_SR_TXPOWER1 + ieee80211_chan2ieee(ic, chan) - 1;
 1020         KASSERT2(idx >= RTW_SR_TXPOWER1 && idx <= RTW_SR_TXPOWER14,
 1021             ("%s: channel %d out of range", __func__,
 1022              idx - RTW_SR_TXPOWER1 + 1));
 1023         return RTW_SR_GET(sr, idx);
 1024 }
 1025 
 1026 static void
 1027 rtw_txdesc_blk_init_all(struct rtw_txdesc_blk *tdb)
 1028 {
 1029         int pri;
 1030         u_int ndesc[RTW_NTXPRI] =
 1031             {RTW_NTXDESCLO, RTW_NTXDESCMD, RTW_NTXDESCHI, RTW_NTXDESCBCN};
 1032 
 1033         for (pri = 0; pri < RTW_NTXPRI; pri++) {
 1034                 tdb[pri].tdb_nfree = ndesc[pri];
 1035                 tdb[pri].tdb_next = 0;
 1036         }
 1037 }
 1038 
 1039 static int
 1040 rtw_txsoft_blk_init(struct rtw_txsoft_blk *tsb)
 1041 {
 1042         int i;
 1043         struct rtw_txsoft *ts;
 1044 
 1045         SIMPLEQ_INIT(&tsb->tsb_dirtyq);
 1046         SIMPLEQ_INIT(&tsb->tsb_freeq);
 1047         for (i = 0; i < tsb->tsb_ndesc; i++) {
 1048                 ts = &tsb->tsb_desc[i];
 1049                 ts->ts_mbuf = NULL;
 1050                 SIMPLEQ_INSERT_TAIL(&tsb->tsb_freeq, ts, ts_q);
 1051         }
 1052         return 0;
 1053 }
 1054 
 1055 static void
 1056 rtw_txsoft_blk_init_all(struct rtw_txsoft_blk *tsb)
 1057 {
 1058         int pri;
 1059         for (pri = 0; pri < RTW_NTXPRI; pri++)
 1060                 rtw_txsoft_blk_init(&tsb[pri]);
 1061 }
 1062 
 1063 static __inline void
 1064 rtw_rxdescs_sync(struct rtw_rxdesc_blk *rdb, int desc0, int nsync, int ops)
 1065 {
 1066         KASSERT(nsync <= rdb->rdb_ndesc);
 1067         /* sync to end of ring */
 1068         if (desc0 + nsync > rdb->rdb_ndesc) {
 1069                 bus_dmamap_sync(rdb->rdb_dmat, rdb->rdb_dmamap,
 1070                     offsetof(struct rtw_descs, hd_rx[desc0]),
 1071                     sizeof(struct rtw_rxdesc) * (rdb->rdb_ndesc - desc0), ops);
 1072                 nsync -= (rdb->rdb_ndesc - desc0);
 1073                 desc0 = 0;
 1074         }
 1075 
 1076         KASSERT(desc0 < rdb->rdb_ndesc);
 1077         KASSERT(nsync <= rdb->rdb_ndesc);
 1078         KASSERT(desc0 + nsync <= rdb->rdb_ndesc);
 1079 
 1080         /* sync what remains */
 1081         bus_dmamap_sync(rdb->rdb_dmat, rdb->rdb_dmamap,
 1082             offsetof(struct rtw_descs, hd_rx[desc0]),
 1083             sizeof(struct rtw_rxdesc) * nsync, ops);
 1084 }
 1085 
 1086 static void
 1087 rtw_txdescs_sync(struct rtw_txdesc_blk *tdb, u_int desc0, u_int nsync, int ops)
 1088 {
 1089         /* sync to end of ring */
 1090         if (desc0 + nsync > tdb->tdb_ndesc) {
 1091                 bus_dmamap_sync(tdb->tdb_dmat, tdb->tdb_dmamap,
 1092                     tdb->tdb_ofs + sizeof(struct rtw_txdesc) * desc0,
 1093                     sizeof(struct rtw_txdesc) * (tdb->tdb_ndesc - desc0),
 1094                     ops);
 1095                 nsync -= (tdb->tdb_ndesc - desc0);
 1096                 desc0 = 0;
 1097         }
 1098 
 1099         /* sync what remains */
 1100         bus_dmamap_sync(tdb->tdb_dmat, tdb->tdb_dmamap,
 1101             tdb->tdb_ofs + sizeof(struct rtw_txdesc) * desc0,
 1102             sizeof(struct rtw_txdesc) * nsync, ops);
 1103 }
 1104 
 1105 static void
 1106 rtw_txdescs_sync_all(struct rtw_txdesc_blk *tdb)
 1107 {
 1108         int pri;
 1109         for (pri = 0; pri < RTW_NTXPRI; pri++) {
 1110                 rtw_txdescs_sync(&tdb[pri], 0, tdb[pri].tdb_ndesc,
 1111                     BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
 1112         }
 1113 }
 1114 
 1115 static void
 1116 rtw_rxbufs_release(bus_dma_tag_t dmat, struct rtw_rxsoft *desc)
 1117 {
 1118         int i;
 1119         struct rtw_rxsoft *rs;
 1120 
 1121         for (i = 0; i < RTW_RXQLEN; i++) {
 1122                 rs = &desc[i];
 1123                 if (rs->rs_mbuf == NULL)
 1124                         continue;
 1125                 bus_dmamap_sync(dmat, rs->rs_dmamap, 0,
 1126                     rs->rs_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
 1127                 bus_dmamap_unload(dmat, rs->rs_dmamap);
 1128                 m_freem(rs->rs_mbuf);
 1129                 rs->rs_mbuf = NULL;
 1130         }
 1131 }
 1132 
 1133 static __inline int
 1134 rtw_rxsoft_alloc(bus_dma_tag_t dmat, struct rtw_rxsoft *rs)
 1135 {
 1136         int rc;
 1137         struct mbuf *m;
 1138 
 1139         MGETHDR(m, M_DONTWAIT, MT_DATA);
 1140         if (m == NULL)
 1141                 return ENOBUFS;
 1142 
 1143         MCLGET(m, M_DONTWAIT);
 1144         if ((m->m_flags & M_EXT) == 0) {
 1145                 m_freem(m);
 1146                 return ENOBUFS;
 1147         }
 1148 
 1149         m->m_pkthdr.len = m->m_len = m->m_ext.ext_size;
 1150 
 1151         if (rs->rs_mbuf != NULL)
 1152                 bus_dmamap_unload(dmat, rs->rs_dmamap);
 1153 
 1154         rs->rs_mbuf = NULL;
 1155 
 1156         rc = bus_dmamap_load_mbuf(dmat, rs->rs_dmamap, m, BUS_DMA_NOWAIT);
 1157         if (rc != 0) {
 1158                 m_freem(m);
 1159                 return -1;
 1160         }
 1161 
 1162         rs->rs_mbuf = m;
 1163 
 1164         return 0;
 1165 }
 1166 
 1167 static int
 1168 rtw_rxsoft_init_all(bus_dma_tag_t dmat, struct rtw_rxsoft *desc,
 1169     int *ndesc, const char *dvname)
 1170 {
 1171         int i, rc = 0;
 1172         struct rtw_rxsoft *rs;
 1173 
 1174         for (i = 0; i < RTW_RXQLEN; i++) {
 1175                 rs = &desc[i];
 1176                 /* we're in rtw_init, so there should be no mbufs allocated */
 1177                 KASSERT(rs->rs_mbuf == NULL);
 1178 #ifdef RTW_DEBUG
 1179                 if (i == rtw_rxbufs_limit) {
 1180                         printf("%s: TEST hit %d-buffer limit\n", dvname, i);
 1181                         rc = ENOBUFS;
 1182                         break;
 1183                 }
 1184 #endif /* RTW_DEBUG */
 1185                 if ((rc = rtw_rxsoft_alloc(dmat, rs)) != 0) {
 1186                         printf("%s: rtw_rxsoft_alloc failed, %d buffers, "
 1187                                "rc %d\n", dvname, i, rc);
 1188                         break;
 1189                 }
 1190         }
 1191         *ndesc = i;
 1192         return rc;
 1193 }
 1194 
 1195 static __inline void
 1196 rtw_rxdesc_init(struct rtw_rxdesc_blk *rdb, struct rtw_rxsoft *rs,
 1197     int idx, int kick)
 1198 {
 1199         int is_last = (idx == rdb->rdb_ndesc - 1);
 1200         uint32_t ctl, octl, obuf;
 1201         struct rtw_rxdesc *rd = &rdb->rdb_desc[idx];
 1202 
 1203         obuf = rd->rd_buf;
 1204         rd->rd_buf = htole32(rs->rs_dmamap->dm_segs[0].ds_addr);
 1205 
 1206         ctl = LSHIFT(rs->rs_mbuf->m_len, RTW_RXCTL_LENGTH_MASK) |
 1207             RTW_RXCTL_OWN | RTW_RXCTL_FS | RTW_RXCTL_LS;
 1208 
 1209         if (is_last)
 1210                 ctl |= RTW_RXCTL_EOR;
 1211 
 1212         octl = rd->rd_ctl;
 1213         rd->rd_ctl = htole32(ctl);
 1214 
 1215         RTW_DPRINTF(
 1216             kick ? (RTW_DEBUG_RECV_DESC | RTW_DEBUG_IO_KICK)
 1217                  : RTW_DEBUG_RECV_DESC,
 1218             ("%s: rd %p buf %08x -> %08x ctl %08x -> %08x\n", __func__, rd,
 1219              le32toh(obuf), le32toh(rd->rd_buf), le32toh(octl),
 1220              le32toh(rd->rd_ctl)));
 1221 
 1222         /* sync the mbuf */
 1223         bus_dmamap_sync(rdb->rdb_dmat, rs->rs_dmamap, 0,
 1224             rs->rs_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD);
 1225 
 1226         /* sync the descriptor */
 1227         bus_dmamap_sync(rdb->rdb_dmat, rdb->rdb_dmamap,
 1228             RTW_DESC_OFFSET(hd_rx, idx), sizeof(struct rtw_rxdesc),
 1229             BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
 1230 }
 1231 
 1232 static void
 1233 rtw_rxdesc_init_all(struct rtw_rxdesc_blk *rdb, struct rtw_rxsoft *ctl, int kick)
 1234 {
 1235         int i;
 1236         struct rtw_rxdesc *rd;
 1237         struct rtw_rxsoft *rs;
 1238 
 1239         for (i = 0; i < rdb->rdb_ndesc; i++) {
 1240                 rd = &rdb->rdb_desc[i];
 1241                 rs = &ctl[i];
 1242                 rtw_rxdesc_init(rdb, rs, i, kick);
 1243         }
 1244         rdb->rdb_next = 0;
 1245 }
 1246 
 1247 static void
 1248 rtw_io_enable(struct rtw_regs *regs, uint8_t flags, int enable)
 1249 {
 1250         uint8_t cr;
 1251 
 1252         RTW_DPRINTF(RTW_DEBUG_IOSTATE, ("%s: %s 0x%02x\n", __func__,
 1253             enable ? "enable" : "disable", flags));
 1254 
 1255         cr = RTW_READ8(regs, RTW_CR);
 1256 
 1257         /* XXX reference source does not enable MULRW */
 1258 #if 0
 1259         /* enable PCI Read/Write Multiple */
 1260         cr |= RTW_CR_MULRW;
 1261 #endif
 1262 
 1263         RTW_RBW(regs, RTW_CR, RTW_CR);  /* XXX paranoia? */
 1264         if (enable)
 1265                 cr |= flags;
 1266         else
 1267                 cr &= ~flags;
 1268         RTW_WRITE8(regs, RTW_CR, cr);
 1269         RTW_SYNC(regs, RTW_CR, RTW_CR);
 1270 }
 1271 
 1272 static void
 1273 rtw_intr_rx(struct rtw_softc *sc, uint16_t isr)
 1274 {
 1275 #define IS_BEACON(__fc0)                                                \
 1276     ((__fc0 & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==\
 1277      (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_BEACON))
 1278 
 1279         static const int ratetbl[4] = {2, 4, 11, 22};   /* convert rates:
 1280                                                          * hardware -> net80211
 1281                                                          */
 1282         u_int next, nproc = 0;
 1283         int hwrate, len, rate, rssi, sq;
 1284         uint32_t hrssi, hstat, htsfth, htsftl;
 1285         struct rtw_rxdesc *rd;
 1286         struct rtw_rxsoft *rs;
 1287         struct rtw_rxdesc_blk *rdb;
 1288         struct mbuf *m;
 1289 
 1290         struct ieee80211_node *ni;
 1291         struct ieee80211_frame *wh;
 1292 
 1293         rdb = &sc->sc_rxdesc_blk;
 1294 
 1295         KASSERT(rdb->rdb_next < rdb->rdb_ndesc);
 1296 
 1297         for (next = rdb->rdb_next; ; next = (next + 1) % rdb->rdb_ndesc) {
 1298                 rtw_rxdescs_sync(rdb, next, 1,
 1299                     BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
 1300                 rd = &rdb->rdb_desc[next];
 1301                 rs = &sc->sc_rxsoft[next];
 1302 
 1303                 hstat = le32toh(rd->rd_stat);
 1304                 hrssi = le32toh(rd->rd_rssi);
 1305                 htsfth = le32toh(rd->rd_tsfth);
 1306                 htsftl = le32toh(rd->rd_tsftl);
 1307 
 1308                 RTW_DPRINTF(RTW_DEBUG_RECV_DESC,
 1309                     ("%s: rxdesc[%d] hstat %08x hrssi %08x htsft %08x%08x\n",
 1310                     __func__, next, hstat, hrssi, htsfth, htsftl));
 1311 
 1312                 ++nproc;
 1313 
 1314                 /* still belongs to NIC */
 1315                 if ((hstat & RTW_RXSTAT_OWN) != 0) {
 1316                         if (nproc > 1)
 1317                                 break;
 1318 
 1319                         /* sometimes the NIC skips to the 0th descriptor */
 1320                         rtw_rxdescs_sync(rdb, 0, 1,
 1321                             BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
 1322                         rd = &rdb->rdb_desc[0];
 1323                         if ((rd->rd_stat & htole32(RTW_RXSTAT_OWN)) != 0)
 1324                                 break;
 1325                         RTW_DPRINTF(RTW_DEBUG_BUGS,
 1326                             ("%s: NIC skipped from rxdesc[%u] to rxdesc[0]\n",
 1327                              sc->sc_dev.dv_xname, next));
 1328                         next = rdb->rdb_ndesc - 1;
 1329                         continue;
 1330                 }
 1331 
 1332 #ifdef RTW_DEBUG
 1333 #define PRINTSTAT(flag) do { \
 1334         if ((hstat & flag) != 0) { \
 1335                 printf("%s" #flag, delim); \
 1336                 delim = ","; \
 1337         } \
 1338 } while (0)
 1339                 if ((rtw_debug & RTW_DEBUG_RECV_DESC) != 0) {
 1340                         const char *delim = "<";
 1341                         printf("%s: ", sc->sc_dev.dv_xname);
 1342                         if ((hstat & RTW_RXSTAT_DEBUG) != 0) {
 1343                                 printf("status %08x", hstat);
 1344                                 PRINTSTAT(RTW_RXSTAT_SPLCP);
 1345                                 PRINTSTAT(RTW_RXSTAT_MAR);
 1346                                 PRINTSTAT(RTW_RXSTAT_PAR);
 1347                                 PRINTSTAT(RTW_RXSTAT_BAR);
 1348                                 PRINTSTAT(RTW_RXSTAT_PWRMGT);
 1349                                 PRINTSTAT(RTW_RXSTAT_CRC32);
 1350                                 PRINTSTAT(RTW_RXSTAT_ICV);
 1351                                 printf(">, ");
 1352                         }
 1353                 }
 1354 #endif /* RTW_DEBUG */
 1355 
 1356                 if ((hstat & RTW_RXSTAT_IOERROR) != 0) {
 1357                         printf("%s: DMA error/FIFO overflow %08x, "
 1358                             "rx descriptor %d\n", sc->sc_dev.dv_xname,
 1359                             hstat & RTW_RXSTAT_IOERROR, next);
 1360                         sc->sc_if.if_ierrors++;
 1361                         goto next;
 1362                 }
 1363 
 1364                 len = MASK_AND_RSHIFT(hstat, RTW_RXSTAT_LENGTH_MASK);
 1365                 if (len < IEEE80211_MIN_LEN) {
 1366                         sc->sc_ic.ic_stats.is_rx_tooshort++;
 1367                         goto next;
 1368                 }
 1369 
 1370                 /* CRC is included with the packet; trim it off. */
 1371                 len -= IEEE80211_CRC_LEN;
 1372 
 1373                 hwrate = MASK_AND_RSHIFT(hstat, RTW_RXSTAT_RATE_MASK);
 1374                 if (hwrate >= sizeof(ratetbl) / sizeof(ratetbl[0])) {
 1375                         printf("%s: unknown rate #%d\n", sc->sc_dev.dv_xname,
 1376                             MASK_AND_RSHIFT(hstat, RTW_RXSTAT_RATE_MASK));
 1377                         sc->sc_if.if_ierrors++;
 1378                         goto next;
 1379                 }
 1380                 rate = ratetbl[hwrate];
 1381 
 1382 #ifdef RTW_DEBUG
 1383                 RTW_DPRINTF(RTW_DEBUG_RECV_DESC,
 1384                     ("rate %d.%d Mb/s, time %08x%08x\n", (rate * 5) / 10,
 1385                      (rate * 5) % 10, htsfth, htsftl));
 1386 #endif /* RTW_DEBUG */
 1387 
 1388                 if ((hstat & RTW_RXSTAT_RES) != 0 &&
 1389                     sc->sc_ic.ic_opmode != IEEE80211_M_MONITOR)
 1390                         goto next;
 1391 
 1392                 /* if bad flags, skip descriptor */
 1393                 if ((hstat & RTW_RXSTAT_ONESEG) != RTW_RXSTAT_ONESEG) {
 1394                         printf("%s: too many rx segments\n",
 1395                             sc->sc_dev.dv_xname);
 1396                         goto next;
 1397                 }
 1398 
 1399                 bus_dmamap_sync(sc->sc_dmat, rs->rs_dmamap, 0,
 1400                     rs->rs_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
 1401 
 1402                 m = rs->rs_mbuf;
 1403 
 1404                 /* if temporarily out of memory, re-use mbuf */
 1405                 switch (rtw_rxsoft_alloc(sc->sc_dmat, rs)) {
 1406                 case 0:
 1407                         break;
 1408                 case ENOBUFS:
 1409                         printf("%s: rtw_rxsoft_alloc(, %d) failed, "
 1410                             "dropping packet\n", sc->sc_dev.dv_xname, next);
 1411                         goto next;
 1412                 default:
 1413                         /* XXX shorten rx ring, instead? */
 1414                         panic("%s: could not load DMA map\n",
 1415                             sc->sc_dev.dv_xname);
 1416                 }
 1417 
 1418                 if (sc->sc_rfchipid == RTW_RFCHIPID_PHILIPS)
 1419                         rssi = MASK_AND_RSHIFT(hrssi, RTW_RXRSSI_RSSI);
 1420                 else {
 1421                         rssi = MASK_AND_RSHIFT(hrssi, RTW_RXRSSI_IMR_RSSI);
 1422                         /* TBD find out each front-end's LNA gain in the
 1423                          * front-end's units
 1424                          */
 1425                         if ((hrssi & RTW_RXRSSI_IMR_LNA) == 0)
 1426                                 rssi |= 0x80;
 1427                 }
 1428                 sq = MASK_AND_RSHIFT(hrssi, RTW_RXRSSI_SQ);
 1429 
 1430                 /* Note well: now we cannot recycle the rs_mbuf unless
 1431                  * we restore its original length.
 1432                  */
 1433                 m->m_pkthdr.rcvif = &sc->sc_if;
 1434                 m->m_pkthdr.len = m->m_len = len;
 1435 
 1436                 wh = mtod(m, struct ieee80211_frame *);
 1437 
 1438                 if (!IS_BEACON(wh->i_fc[0]))
 1439                         sc->sc_led_state.ls_event |= RTW_LED_S_RX;
 1440                 /* TBD use _MAR, _BAR, _PAR flags as hints to _find_rxnode? */
 1441                 ni = ieee80211_find_rxnode(&sc->sc_ic, wh);
 1442 
 1443                 sc->sc_tsfth = htsfth;
 1444 
 1445 #ifdef RTW_DEBUG
 1446                 if ((sc->sc_if.if_flags & (IFF_DEBUG|IFF_LINK2)) ==
 1447                     (IFF_DEBUG|IFF_LINK2)) {
 1448                         ieee80211_dump_pkt(mtod(m, uint8_t *), m->m_pkthdr.len,
 1449                             rate, rssi);
 1450                 }
 1451 #endif /* RTW_DEBUG */
 1452 
 1453 #if NBPFILTER > 0
 1454                 if (sc->sc_radiobpf != NULL) {
 1455                         struct ieee80211com *ic = &sc->sc_ic;
 1456                         struct rtw_rx_radiotap_header *rr = &sc->sc_rxtap;
 1457 
 1458                         rr->rr_tsft =
 1459                             htole64(((uint64_t)htsfth << 32) | htsftl);
 1460 
 1461                         if ((hstat & RTW_RXSTAT_SPLCP) != 0)
 1462                                 rr->rr_flags = IEEE80211_RADIOTAP_F_SHORTPRE;
 1463 
 1464                         rr->rr_flags = 0;
 1465                         rr->rr_rate = rate;
 1466                         rr->rr_chan_freq =
 1467                             htole16(ic->ic_bss->ni_chan->ic_freq);
 1468                         rr->rr_chan_flags =
 1469                             htole16(ic->ic_bss->ni_chan->ic_flags);
 1470                         rr->rr_antsignal = rssi;
 1471                         rr->rr_barker_lock = htole16(sq);
 1472 
 1473                         bpf_mtap2(sc->sc_radiobpf, (caddr_t)rr,
 1474                             sizeof(sc->sc_rxtapu), m);
 1475                 }
 1476 #endif /* NPBFILTER > 0 */
 1477 
 1478                 ieee80211_input(&sc->sc_if, m, ni, rssi, htsftl);
 1479                 ieee80211_release_node(&sc->sc_ic, ni);
 1480 next:
 1481                 rtw_rxdesc_init(rdb, rs, next, 0);
 1482         }
 1483         rdb->rdb_next = next;
 1484 
 1485         KASSERT(rdb->rdb_next < rdb->rdb_ndesc);
 1486 
 1487         return;
 1488 #undef IS_BEACON
 1489 }
 1490 
 1491 static void
 1492 rtw_txsoft_release(bus_dma_tag_t dmat, struct ieee80211com *ic,
 1493     struct rtw_txsoft *ts)
 1494 {
 1495         struct mbuf *m;
 1496         struct ieee80211_node *ni;
 1497 
 1498         m = ts->ts_mbuf;
 1499         ni = ts->ts_ni;
 1500         KASSERT(m != NULL);
 1501         KASSERT(ni != NULL);
 1502         ts->ts_mbuf = NULL;
 1503         ts->ts_ni = NULL;
 1504 
 1505         bus_dmamap_sync(dmat, ts->ts_dmamap, 0, ts->ts_dmamap->dm_mapsize,
 1506             BUS_DMASYNC_POSTWRITE);
 1507         bus_dmamap_unload(dmat, ts->ts_dmamap);
 1508         m_freem(m);
 1509         ieee80211_release_node(ic, ni);
 1510 }
 1511 
 1512 static void
 1513 rtw_txsofts_release(bus_dma_tag_t dmat, struct ieee80211com *ic,
 1514     struct rtw_txsoft_blk *tsb)
 1515 {
 1516         struct rtw_txsoft *ts;
 1517 
 1518         while ((ts = SIMPLEQ_FIRST(&tsb->tsb_dirtyq)) != NULL) {
 1519                 rtw_txsoft_release(dmat, ic, ts);
 1520                 SIMPLEQ_REMOVE_HEAD(&tsb->tsb_dirtyq, ts_q);
 1521                 SIMPLEQ_INSERT_TAIL(&tsb->tsb_freeq, ts, ts_q);
 1522         }
 1523 }
 1524 
 1525 static __inline void
 1526 rtw_collect_txpkt(struct rtw_softc *sc, struct rtw_txdesc_blk *tdb,
 1527     struct rtw_txsoft *ts, int ndesc)
 1528 {
 1529         uint32_t hstat;
 1530         int data_retry, rts_retry;
 1531         struct rtw_txdesc *tdn;
 1532         const char *condstring;
 1533 
 1534         rtw_txsoft_release(sc->sc_dmat, &sc->sc_ic, ts);
 1535 
 1536         tdb->tdb_nfree += ndesc;
 1537 
 1538         tdn = &tdb->tdb_desc[ts->ts_last];
 1539 
 1540         hstat = le32toh(tdn->td_stat);
 1541         rts_retry = MASK_AND_RSHIFT(hstat, RTW_TXSTAT_RTSRETRY_MASK);
 1542         data_retry = MASK_AND_RSHIFT(hstat, RTW_TXSTAT_DRC_MASK);
 1543 
 1544         sc->sc_if.if_collisions += rts_retry + data_retry;
 1545 
 1546         if ((hstat & RTW_TXSTAT_TOK) != 0)
 1547                 condstring = "ok";
 1548         else {
 1549                 sc->sc_if.if_oerrors++;
 1550                 condstring = "error";
 1551         }
 1552 
 1553         DPRINTF(sc, RTW_DEBUG_XMIT_DESC,
 1554             ("%s: ts %p txdesc[%d, %d] %s tries rts %u data %u\n",
 1555             sc->sc_dev.dv_xname, ts, ts->ts_first, ts->ts_last,
 1556             condstring, rts_retry, data_retry));
 1557 }
 1558 
 1559 /* Collect transmitted packets. */
 1560 static __inline void
 1561 rtw_collect_txring(struct rtw_softc *sc, struct rtw_txsoft_blk *tsb,
 1562     struct rtw_txdesc_blk *tdb)
 1563 {
 1564         int ndesc;
 1565         struct rtw_txsoft *ts;
 1566 
 1567         while ((ts = SIMPLEQ_FIRST(&tsb->tsb_dirtyq)) != NULL) {
 1568                 ndesc = 1 + ts->ts_last - ts->ts_first;
 1569                 if (ts->ts_last < ts->ts_first)
 1570                         ndesc += tdb->tdb_ndesc;
 1571 
 1572                 KASSERT(ndesc > 0);
 1573 
 1574                 rtw_txdescs_sync(tdb, ts->ts_first, ndesc,
 1575                     BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
 1576 
 1577                 if ((tdb->tdb_desc[ts->ts_last].td_stat &
 1578                     htole32(RTW_TXSTAT_OWN)) != 0)
 1579                         break;
 1580 
 1581                 if (&sc->sc_txdesc_blk[RTW_TXPRIBCN] == tdb) {
 1582                         RTW_DPRINTF(RTW_DEBUG_BEACON,
 1583                             ("%s: collected beacon\n", __func__));
 1584                 }
 1585 
 1586                 rtw_collect_txpkt(sc, tdb, ts, ndesc);
 1587                 SIMPLEQ_REMOVE_HEAD(&tsb->tsb_dirtyq, ts_q);
 1588                 SIMPLEQ_INSERT_TAIL(&tsb->tsb_freeq, ts, ts_q);
 1589                 sc->sc_if.if_flags &= ~IFF_OACTIVE;
 1590         }
 1591         if (ts == NULL)
 1592                 tsb->tsb_tx_timer = 0;
 1593 }
 1594 
 1595 static void
 1596 rtw_intr_tx(struct rtw_softc *sc, uint16_t isr)
 1597 {
 1598         int pri;
 1599         struct rtw_txsoft_blk   *tsb;
 1600         struct rtw_txdesc_blk   *tdb;
 1601 
 1602         for (pri = 0; pri < RTW_NTXPRI; pri++) {
 1603                 tsb = &sc->sc_txsoft_blk[pri];
 1604                 tdb = &sc->sc_txdesc_blk[pri];
 1605 
 1606                 rtw_collect_txring(sc, tsb, tdb);
 1607 
 1608                 if ((isr & RTW_INTR_TX) != 0)
 1609                         rtw_start(&sc->sc_if);
 1610         }
 1611 
 1612         /* TBD */
 1613         return;
 1614 }
 1615 
 1616 static void
 1617 rtw_intr_beacon(struct rtw_softc *sc, uint16_t isr)
 1618 {
 1619         /* TBD */
 1620         return;
 1621 }
 1622 
 1623 static void
 1624 rtw_intr_atim(struct rtw_softc *sc)
 1625 {
 1626         /* TBD */
 1627         return;
 1628 }
 1629 
 1630 #ifdef RTW_DEBUG
 1631 static void
 1632 rtw_dump_rings(struct rtw_softc *sc)
 1633 {
 1634         struct rtw_txdesc_blk *tdb;
 1635         struct rtw_rxdesc *rd;
 1636         struct rtw_rxdesc_blk *rdb;
 1637         int desc, pri;
 1638 
 1639         if ((rtw_debug & RTW_DEBUG_IO_KICK) == 0)
 1640                 return;
 1641 
 1642         for (pri = 0; pri < RTW_NTXPRI; pri++) {
 1643                 tdb = &sc->sc_txdesc_blk[pri];
 1644                 printf("%s: txpri %d ndesc %d nfree %d\n", __func__, pri,
 1645                     tdb->tdb_ndesc, tdb->tdb_nfree);
 1646                 for (desc = 0; desc < tdb->tdb_ndesc; desc++)
 1647                         rtw_print_txdesc(sc, ".", NULL, tdb, desc);
 1648         }
 1649 
 1650         rdb = &sc->sc_rxdesc_blk;
 1651 
 1652         for (desc = 0; desc < RTW_RXQLEN; desc++) {
 1653                 rd = &rdb->rdb_desc[desc];
 1654                 printf("%s: %sctl %08x rsvd0/rssi %08x buf/tsftl %08x "
 1655                     "rsvd1/tsfth %08x\n", __func__,
 1656                     (desc >= rdb->rdb_ndesc) ? "UNUSED " : "",
 1657                     le32toh(rd->rd_ctl), le32toh(rd->rd_rssi),
 1658                     le32toh(rd->rd_buf), le32toh(rd->rd_tsfth));
 1659         }
 1660 }
 1661 #endif /* RTW_DEBUG */
 1662 
 1663 static void
 1664 rtw_hwring_setup(struct rtw_softc *sc)
 1665 {
 1666         struct rtw_regs *regs = &sc->sc_regs;
 1667         RTW_WRITE(regs, RTW_RDSAR, RTW_RING_BASE(sc, hd_rx));
 1668         RTW_WRITE(regs, RTW_TLPDA, RTW_RING_BASE(sc, hd_txlo));
 1669         RTW_WRITE(regs, RTW_TNPDA, RTW_RING_BASE(sc, hd_txmd));
 1670         RTW_WRITE(regs, RTW_THPDA, RTW_RING_BASE(sc, hd_txhi));
 1671         RTW_WRITE(regs, RTW_TBDA, RTW_RING_BASE(sc, hd_bcn));
 1672         RTW_SYNC(regs, RTW_TLPDA, RTW_RDSAR);
 1673         RTW_DPRINTF(RTW_DEBUG_XMIT_DESC,
 1674             ("%s: reg[TLPDA] <- %" PRIxPTR "\n", __func__,
 1675              (uintptr_t)RTW_RING_BASE(sc, hd_txlo)));
 1676         RTW_DPRINTF(RTW_DEBUG_XMIT_DESC,
 1677             ("%s: reg[TNPDA] <- %" PRIxPTR "\n", __func__,
 1678              (uintptr_t)RTW_RING_BASE(sc, hd_txmd)));
 1679         RTW_DPRINTF(RTW_DEBUG_XMIT_DESC,
 1680             ("%s: reg[THPDA] <- %" PRIxPTR "\n", __func__,
 1681              (uintptr_t)RTW_RING_BASE(sc, hd_txhi)));
 1682         RTW_DPRINTF(RTW_DEBUG_XMIT_DESC,
 1683             ("%s: reg[TBDA] <- %" PRIxPTR "\n", __func__,
 1684              (uintptr_t)RTW_RING_BASE(sc, hd_bcn)));
 1685         RTW_DPRINTF(RTW_DEBUG_RECV_DESC,
 1686             ("%s: reg[RDSAR] <- %" PRIxPTR "\n", __func__,
 1687              (uintptr_t)RTW_RING_BASE(sc, hd_rx)));
 1688 }
 1689 
 1690 static int
 1691 rtw_swring_setup(struct rtw_softc *sc)
 1692 {
 1693         int rc;
 1694         struct rtw_rxdesc_blk *rdb;
 1695 
 1696         rtw_txdesc_blk_init_all(&sc->sc_txdesc_blk[0]);
 1697 
 1698         rtw_txsoft_blk_init_all(&sc->sc_txsoft_blk[0]);
 1699 
 1700         rdb = &sc->sc_rxdesc_blk;
 1701         if ((rc = rtw_rxsoft_init_all(sc->sc_dmat, sc->sc_rxsoft, &rdb->rdb_ndesc,
 1702              sc->sc_dev.dv_xname)) != 0 && rdb->rdb_ndesc == 0) {
 1703                 printf("%s: could not allocate rx buffers\n",
 1704                     sc->sc_dev.dv_xname);
 1705                 return rc;
 1706         }
 1707 
 1708         rdb = &sc->sc_rxdesc_blk;
 1709         rtw_rxdescs_sync(rdb, 0, rdb->rdb_ndesc,
 1710             BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
 1711         rtw_rxdesc_init_all(rdb, sc->sc_rxsoft, 1);
 1712 
 1713         rtw_txdescs_sync_all(&sc->sc_txdesc_blk[0]);
 1714         return 0;
 1715 }
 1716 
 1717 static void
 1718 rtw_txdesc_blk_reset(struct rtw_txdesc_blk *tdb)
 1719 {
 1720         int i;
 1721 
 1722         (void)memset(tdb->tdb_desc, 0,
 1723             sizeof(tdb->tdb_desc[0]) * tdb->tdb_ndesc);
 1724         for (i = 0; i < tdb->tdb_ndesc; i++)
 1725                 tdb->tdb_desc[i].td_next = htole32(RTW_NEXT_DESC(tdb, i));
 1726         tdb->tdb_nfree = tdb->tdb_ndesc;
 1727         tdb->tdb_next = 0;
 1728 }
 1729 
 1730 static void
 1731 rtw_txdescs_reset(struct rtw_softc *sc)
 1732 {
 1733         int pri;
 1734         struct rtw_txdesc_blk *tdb;
 1735 
 1736         for (pri = 0; pri < RTW_NTXPRI; pri++) {
 1737                 tdb = &sc->sc_txdesc_blk[pri];
 1738                 rtw_txsofts_release(sc->sc_dmat, &sc->sc_ic,
 1739                     &sc->sc_txsoft_blk[pri]);
 1740                 rtw_txdesc_blk_reset(tdb);
 1741                 rtw_txdescs_sync(tdb, 0, tdb->tdb_ndesc,
 1742                     BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
 1743         }
 1744 }
 1745 
 1746 static void
 1747 rtw_rxdescs_reset(struct rtw_softc *sc)
 1748 {
 1749         rtw_rxdesc_init_all(&sc->sc_rxdesc_blk, &sc->sc_rxsoft[0], 1);
 1750 }
 1751 
 1752 static void
 1753 rtw_intr_ioerror(struct rtw_softc *sc, uint16_t isr)
 1754 {
 1755         struct rtw_regs *regs = &sc->sc_regs;
 1756 
 1757         if ((isr & RTW_INTR_TXFOVW) != 0)
 1758                 printf("%s: tx fifo overflow\n", sc->sc_dev.dv_xname);
 1759 
 1760         if ((isr & (RTW_INTR_RDU|RTW_INTR_RXFOVW)) == 0)
 1761                 return;
 1762 
 1763         RTW_DPRINTF(RTW_DEBUG_BUGS, ("%s: restarting xmit/recv, isr %" PRIx16
 1764             "\n", sc->sc_dev.dv_xname, isr));
 1765 
 1766 #ifdef RTW_DEBUG
 1767         rtw_dump_rings(sc);
 1768 #endif /* RTW_DEBUG */
 1769 
 1770         rtw_io_enable(regs, RTW_CR_RE | RTW_CR_TE, 0);
 1771 
 1772         /* Collect rx'd packets.  Refresh rx buffers. */
 1773         rtw_intr_rx(sc, 0);
 1774         /* Collect tx'd packets. */
 1775         rtw_intr_tx(sc, 0);
 1776 
 1777         RTW_WRITE16(regs, RTW_IMR, 0);
 1778         RTW_SYNC(regs, RTW_IMR, RTW_IMR);
 1779 
 1780         rtw_chip_reset1(regs, sc->sc_dev.dv_xname);
 1781 
 1782         rtw_rxdescs_reset(sc);
 1783         rtw_txdescs_reset(sc);
 1784 
 1785         rtw_hwring_setup(sc);
 1786 
 1787 #ifdef RTW_DEBUG
 1788         rtw_dump_rings(sc);
 1789 #endif /* RTW_DEBUG */
 1790 
 1791         RTW_WRITE16(regs, RTW_IMR, sc->sc_inten);
 1792         RTW_SYNC(regs, RTW_IMR, RTW_IMR);
 1793         rtw_io_enable(regs, RTW_CR_RE | RTW_CR_TE, 1);
 1794         sc->sc_if.if_flags &= ~IFF_OACTIVE;
 1795 }
 1796 
 1797 static __inline void
 1798 rtw_suspend_ticks(struct rtw_softc *sc)
 1799 {
 1800         RTW_DPRINTF(RTW_DEBUG_TIMEOUT,
 1801             ("%s: suspending ticks\n", sc->sc_dev.dv_xname));
 1802         sc->sc_do_tick = 0;
 1803 }
 1804 
 1805 static __inline void
 1806 rtw_resume_ticks(struct rtw_softc *sc)
 1807 {
 1808         uint32_t tsftrl0, tsftrl1, next_tick;
 1809 
 1810         tsftrl0 = RTW_READ(&sc->sc_regs, RTW_TSFTRL);
 1811 
 1812         tsftrl1 = RTW_READ(&sc->sc_regs, RTW_TSFTRL);
 1813         next_tick = tsftrl1 + 1000000;
 1814         RTW_WRITE(&sc->sc_regs, RTW_TINT, next_tick);
 1815 
 1816         sc->sc_do_tick = 1;
 1817 
 1818         RTW_DPRINTF(RTW_DEBUG_TIMEOUT,
 1819             ("%s: resume ticks delta %#08x now %#08x next %#08x\n",
 1820             sc->sc_dev.dv_xname, tsftrl1 - tsftrl0, tsftrl1, next_tick));
 1821 }
 1822 
 1823 static void
 1824 rtw_intr_timeout(struct rtw_softc *sc)
 1825 {
 1826         RTW_DPRINTF(RTW_DEBUG_TIMEOUT, ("%s: timeout\n", sc->sc_dev.dv_xname));
 1827         if (sc->sc_do_tick)
 1828                 rtw_resume_ticks(sc);
 1829         return;
 1830 }
 1831 
 1832 int
 1833 rtw_intr(void *arg)
 1834 {
 1835         int i;
 1836         struct rtw_softc *sc = arg;
 1837         struct rtw_regs *regs = &sc->sc_regs;
 1838         uint16_t isr;
 1839 
 1840         /*
 1841          * If the interface isn't running, the interrupt couldn't
 1842          * possibly have come from us.
 1843          */
 1844         if ((sc->sc_flags & RTW_F_ENABLED) == 0 ||
 1845             (sc->sc_if.if_flags & IFF_RUNNING) == 0 ||
 1846             (sc->sc_dev.dv_flags & DVF_ACTIVE) == 0) {
 1847                 RTW_DPRINTF(RTW_DEBUG_INTR, ("%s: stray interrupt\n", sc->sc_dev.dv_xname));
 1848                 return (0);
 1849         }
 1850 
 1851         for (i = 0; i < 10; i++) {
 1852                 isr = RTW_READ16(regs, RTW_ISR);
 1853 
 1854                 RTW_WRITE16(regs, RTW_ISR, isr);
 1855                 RTW_WBR(regs, RTW_ISR, RTW_ISR);
 1856 
 1857                 if (sc->sc_intr_ack != NULL)
 1858                         (*sc->sc_intr_ack)(regs);
 1859 
 1860                 if (isr == 0)
 1861                         break;
 1862 
 1863 #ifdef RTW_DEBUG
 1864 #define PRINTINTR(flag) do { \
 1865         if ((isr & flag) != 0) { \
 1866                 printf("%s" #flag, delim); \
 1867                 delim = ","; \
 1868         } \
 1869 } while (0)
 1870 
 1871                 if ((rtw_debug & RTW_DEBUG_INTR) != 0 && isr != 0) {
 1872                         const char *delim = "<";
 1873 
 1874                         printf("%s: reg[ISR] = %x", sc->sc_dev.dv_xname, isr);
 1875 
 1876                         PRINTINTR(RTW_INTR_TXFOVW);
 1877                         PRINTINTR(RTW_INTR_TIMEOUT);
 1878                         PRINTINTR(RTW_INTR_BCNINT);
 1879                         PRINTINTR(RTW_INTR_ATIMINT);
 1880                         PRINTINTR(RTW_INTR_TBDER);
 1881                         PRINTINTR(RTW_INTR_TBDOK);
 1882                         PRINTINTR(RTW_INTR_THPDER);
 1883                         PRINTINTR(RTW_INTR_THPDOK);
 1884                         PRINTINTR(RTW_INTR_TNPDER);
 1885                         PRINTINTR(RTW_INTR_TNPDOK);
 1886                         PRINTINTR(RTW_INTR_RXFOVW);
 1887                         PRINTINTR(RTW_INTR_RDU);
 1888                         PRINTINTR(RTW_INTR_TLPDER);
 1889                         PRINTINTR(RTW_INTR_TLPDOK);
 1890                         PRINTINTR(RTW_INTR_RER);
 1891                         PRINTINTR(RTW_INTR_ROK);
 1892 
 1893                         printf(">\n");
 1894                 }
 1895 #undef PRINTINTR
 1896 #endif /* RTW_DEBUG */
 1897 
 1898                 if ((isr & RTW_INTR_RX) != 0)
 1899                         rtw_intr_rx(sc, isr & RTW_INTR_RX);
 1900                 if ((isr & RTW_INTR_TX) != 0)
 1901                         rtw_intr_tx(sc, isr & RTW_INTR_TX);
 1902                 if ((isr & RTW_INTR_BEACON) != 0)
 1903                         rtw_intr_beacon(sc, isr & RTW_INTR_BEACON);
 1904                 if ((isr & RTW_INTR_ATIMINT) != 0)
 1905                         rtw_intr_atim(sc);
 1906                 if ((isr & RTW_INTR_IOERROR) != 0)
 1907                         rtw_intr_ioerror(sc, isr & RTW_INTR_IOERROR);
 1908                 if ((isr & RTW_INTR_TIMEOUT) != 0)
 1909                         rtw_intr_timeout(sc);
 1910         }
 1911 
 1912         return 1;
 1913 }
 1914 
 1915 /* Must be called at splnet. */
 1916 static void
 1917 rtw_stop(struct ifnet *ifp, int disable)
 1918 {
 1919         int pri;
 1920         struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc;
 1921         struct ieee80211com *ic = &sc->sc_ic;
 1922         struct rtw_regs *regs = &sc->sc_regs;
 1923 
 1924         if ((sc->sc_flags & RTW_F_ENABLED) == 0)
 1925                 return;
 1926 
 1927         rtw_suspend_ticks(sc);
 1928 
 1929         ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
 1930 
 1931         if ((sc->sc_flags & RTW_F_INVALID) == 0) {
 1932                 /* Disable interrupts. */
 1933                 RTW_WRITE16(regs, RTW_IMR, 0);
 1934 
 1935                 RTW_WBW(regs, RTW_TPPOLL, RTW_IMR);
 1936 
 1937                 /* Stop the transmit and receive processes. First stop DMA,
 1938                  * then disable receiver and transmitter.
 1939                  */
 1940                 RTW_WRITE8(regs, RTW_TPPOLL, RTW_TPPOLL_SALL);
 1941 
 1942                 RTW_SYNC(regs, RTW_TPPOLL, RTW_IMR);
 1943 
 1944                 rtw_io_enable(&sc->sc_regs, RTW_CR_RE|RTW_CR_TE, 0);
 1945         }
 1946 
 1947         for (pri = 0; pri < RTW_NTXPRI; pri++) {
 1948                 rtw_txsofts_release(sc->sc_dmat, &sc->sc_ic,
 1949                     &sc->sc_txsoft_blk[pri]);
 1950         }
 1951 
 1952         rtw_rxbufs_release(sc->sc_dmat, &sc->sc_rxsoft[0]);
 1953 
 1954         if (disable)
 1955                 rtw_disable(sc);
 1956 
 1957         /* Mark the interface as not running.  Cancel the watchdog timer. */
 1958         ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
 1959         ifp->if_timer = 0;
 1960 
 1961         return;
 1962 }
 1963 
 1964 const char *
 1965 rtw_pwrstate_string(enum rtw_pwrstate power)
 1966 {
 1967         switch (power) {
 1968         case RTW_ON:
 1969                 return "on";
 1970         case RTW_SLEEP:
 1971                 return "sleep";
 1972         case RTW_OFF:
 1973                 return "off";
 1974         default:
 1975                 return "unknown";
 1976         }
 1977 }
 1978 
 1979 /* XXX For Maxim, I am using the RFMD settings gleaned from the
 1980  * reference driver, plus a magic Maxim "ON" value that comes from
 1981  * the Realtek document "Windows PG for Rtl8180."
 1982  */
 1983 static void
 1984 rtw_maxim_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power,
 1985     int before_rf, int digphy)
 1986 {
 1987         uint32_t anaparm;
 1988 
 1989         anaparm = RTW_READ(regs, RTW_ANAPARM);
 1990         anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF);
 1991 
 1992         switch (power) {
 1993         case RTW_OFF:
 1994                 if (before_rf)
 1995                         return;
 1996                 anaparm |= RTW_ANAPARM_RFPOW_MAXIM_OFF;
 1997                 anaparm |= RTW_ANAPARM_TXDACOFF;
 1998                 break;
 1999         case RTW_SLEEP:
 2000                 if (!before_rf)
 2001                         return;
 2002                 anaparm |= RTW_ANAPARM_RFPOW_MAXIM_SLEEP;
 2003                 anaparm |= RTW_ANAPARM_TXDACOFF;
 2004                 break;
 2005         case RTW_ON:
 2006                 if (!before_rf)
 2007                         return;
 2008                 anaparm |= RTW_ANAPARM_RFPOW_MAXIM_ON;
 2009                 break;
 2010         }
 2011         RTW_DPRINTF(RTW_DEBUG_PWR,
 2012             ("%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n",
 2013             __func__, rtw_pwrstate_string(power),
 2014             (before_rf) ? "before" : "after", anaparm));
 2015 
 2016         RTW_WRITE(regs, RTW_ANAPARM, anaparm);
 2017         RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM);
 2018 }
 2019 
 2020 /* XXX I am using the RFMD settings gleaned from the reference
 2021  * driver.  They agree
 2022  */
 2023 static void
 2024 rtw_rfmd_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power,
 2025     int before_rf, int digphy)
 2026 {
 2027         uint32_t anaparm;
 2028 
 2029         anaparm = RTW_READ(regs, RTW_ANAPARM);
 2030         anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF);
 2031 
 2032         switch (power) {
 2033         case RTW_OFF:
 2034                 if (before_rf)
 2035                         return;
 2036                 anaparm |= RTW_ANAPARM_RFPOW_RFMD_OFF;
 2037                 anaparm |= RTW_ANAPARM_TXDACOFF;
 2038                 break;
 2039         case RTW_SLEEP:
 2040                 if (!before_rf)
 2041                         return;
 2042                 anaparm |= RTW_ANAPARM_RFPOW_RFMD_SLEEP;
 2043                 anaparm |= RTW_ANAPARM_TXDACOFF;
 2044                 break;
 2045         case RTW_ON:
 2046                 if (!before_rf)
 2047                         return;
 2048                 anaparm |= RTW_ANAPARM_RFPOW_RFMD_ON;
 2049                 break;
 2050         }
 2051         RTW_DPRINTF(RTW_DEBUG_PWR,
 2052             ("%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n",
 2053             __func__, rtw_pwrstate_string(power),
 2054             (before_rf) ? "before" : "after", anaparm));
 2055 
 2056         RTW_WRITE(regs, RTW_ANAPARM, anaparm);
 2057         RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM);
 2058 }
 2059 
 2060 static void
 2061 rtw_philips_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power,
 2062     int before_rf, int digphy)
 2063 {
 2064         uint32_t anaparm;
 2065 
 2066         anaparm = RTW_READ(regs, RTW_ANAPARM);
 2067         anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF);
 2068 
 2069         switch (power) {
 2070         case RTW_OFF:
 2071                 if (before_rf)
 2072                         return;
 2073                 anaparm |= RTW_ANAPARM_RFPOW_PHILIPS_OFF;
 2074                 anaparm |= RTW_ANAPARM_TXDACOFF;
 2075                 break;
 2076         case RTW_SLEEP:
 2077                 if (!before_rf)
 2078                         return;
 2079                 anaparm |= RTW_ANAPARM_RFPOW_PHILIPS_SLEEP;
 2080                 anaparm |= RTW_ANAPARM_TXDACOFF;
 2081                 break;
 2082         case RTW_ON:
 2083                 if (!before_rf)
 2084                         return;
 2085                 if (digphy) {
 2086                         anaparm |= RTW_ANAPARM_RFPOW_DIG_PHILIPS_ON;
 2087                         /* XXX guess */
 2088                         anaparm |= RTW_ANAPARM_TXDACOFF;
 2089                 } else
 2090                         anaparm |= RTW_ANAPARM_RFPOW_ANA_PHILIPS_ON;
 2091                 break;
 2092         }
 2093         RTW_DPRINTF(RTW_DEBUG_PWR,
 2094             ("%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n",
 2095             __func__, rtw_pwrstate_string(power),
 2096             (before_rf) ? "before" : "after", anaparm));
 2097 
 2098         RTW_WRITE(regs, RTW_ANAPARM, anaparm);
 2099         RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM);
 2100 }
 2101 
 2102 static void
 2103 rtw_pwrstate0(struct rtw_softc *sc, enum rtw_pwrstate power, int before_rf,
 2104     int digphy)
 2105 {
 2106         struct rtw_regs *regs = &sc->sc_regs;
 2107 
 2108         rtw_set_access(regs, RTW_ACCESS_ANAPARM);
 2109 
 2110         (*sc->sc_pwrstate_cb)(regs, power, before_rf, digphy);
 2111 
 2112         rtw_set_access(regs, RTW_ACCESS_NONE);
 2113 
 2114         return;
 2115 }
 2116 
 2117 static int
 2118 rtw_pwrstate(struct rtw_softc *sc, enum rtw_pwrstate power)
 2119 {
 2120         int rc;
 2121 
 2122         RTW_DPRINTF(RTW_DEBUG_PWR,
 2123             ("%s: %s->%s\n", __func__,
 2124             rtw_pwrstate_string(sc->sc_pwrstate), rtw_pwrstate_string(power)));
 2125 
 2126         if (sc->sc_pwrstate == power)
 2127                 return 0;
 2128 
 2129         rtw_pwrstate0(sc, power, 1, sc->sc_flags & RTW_F_DIGPHY);
 2130         rc = rtw_rf_pwrstate(sc->sc_rf, power);
 2131         rtw_pwrstate0(sc, power, 0, sc->sc_flags & RTW_F_DIGPHY);
 2132 
 2133         switch (power) {
 2134         case RTW_ON:
 2135                 /* TBD set LEDs */
 2136                 break;
 2137         case RTW_SLEEP:
 2138                 /* TBD */
 2139                 break;
 2140         case RTW_OFF:
 2141                 /* TBD */
 2142                 break;
 2143         }
 2144         if (rc == 0)
 2145                 sc->sc_pwrstate = power;
 2146         else
 2147                 sc->sc_pwrstate = RTW_OFF;
 2148         return rc;
 2149 }
 2150 
 2151 static int
 2152 rtw_tune(struct rtw_softc *sc)
 2153 {
 2154         struct ieee80211com *ic = &sc->sc_ic;
 2155         u_int chan;
 2156         int rc;
 2157         int antdiv = sc->sc_flags & RTW_F_ANTDIV,
 2158             dflantb = sc->sc_flags & RTW_F_DFLANTB;
 2159 
 2160         KASSERT(ic->ic_bss->ni_chan != NULL);
 2161 
 2162         chan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
 2163         if (chan == IEEE80211_CHAN_ANY)
 2164                 panic("%s: chan == IEEE80211_CHAN_ANY\n", __func__);
 2165 
 2166         if (chan == sc->sc_cur_chan) {
 2167                 RTW_DPRINTF(RTW_DEBUG_TUNE,
 2168                     ("%s: already tuned chan #%d\n", __func__, chan));
 2169                 return 0;
 2170         }
 2171 
 2172         rtw_suspend_ticks(sc);
 2173 
 2174         rtw_io_enable(&sc->sc_regs, RTW_CR_RE | RTW_CR_TE, 0);
 2175 
 2176         /* TBD wait for Tx to complete */
 2177 
 2178         KASSERT((sc->sc_flags & RTW_F_ENABLED) != 0);
 2179 
 2180         if ((rc = rtw_phy_init(&sc->sc_regs, sc->sc_rf,
 2181             rtw_chan2txpower(&sc->sc_srom, ic, ic->ic_bss->ni_chan),
 2182             sc->sc_csthr, ic->ic_bss->ni_chan->ic_freq, antdiv,
 2183             dflantb, RTW_ON)) != 0) {
 2184                 /* XXX condition on powersaving */
 2185                 printf("%s: phy init failed\n", sc->sc_dev.dv_xname);
 2186         }
 2187 
 2188         sc->sc_cur_chan = chan;
 2189 
 2190         rtw_io_enable(&sc->sc_regs, RTW_CR_RE | RTW_CR_TE, 1);
 2191 
 2192         rtw_resume_ticks(sc);
 2193 
 2194         return rc;
 2195 }
 2196 
 2197 void
 2198 rtw_disable(struct rtw_softc *sc)
 2199 {
 2200         int rc;
 2201 
 2202         if ((sc->sc_flags & RTW_F_ENABLED) == 0)
 2203                 return;
 2204 
 2205         /* turn off PHY */
 2206         if ((sc->sc_flags & RTW_F_INVALID) == 0 &&
 2207             (rc = rtw_pwrstate(sc, RTW_OFF)) != 0) {
 2208                 printf("%s: failed to turn off PHY (%d)\n",
 2209                     sc->sc_dev.dv_xname, rc);
 2210         }
 2211 
 2212         if (sc->sc_disable != NULL)
 2213                 (*sc->sc_disable)(sc);
 2214 
 2215         sc->sc_flags &= ~RTW_F_ENABLED;
 2216 }
 2217 
 2218 int
 2219 rtw_enable(struct rtw_softc *sc)
 2220 {
 2221         if ((sc->sc_flags & RTW_F_ENABLED) == 0) {
 2222                 if (sc->sc_enable != NULL && (*sc->sc_enable)(sc) != 0) {
 2223                         printf("%s: device enable failed\n",
 2224                             sc->sc_dev.dv_xname);
 2225                         return (EIO);
 2226                 }
 2227                 sc->sc_flags |= RTW_F_ENABLED;
 2228         }
 2229         return (0);
 2230 }
 2231 
 2232 static void
 2233 rtw_transmit_config(struct rtw_regs *regs)
 2234 {
 2235         uint32_t tcr;
 2236 
 2237         tcr = RTW_READ(regs, RTW_TCR);
 2238 
 2239         tcr |= RTW_TCR_CWMIN;
 2240         tcr &= ~RTW_TCR_MXDMA_MASK;
 2241         tcr |= RTW_TCR_MXDMA_256;
 2242         tcr |= RTW_TCR_SAT;             /* send ACK as fast as possible */
 2243         tcr &= ~RTW_TCR_LBK_MASK;
 2244         tcr |= RTW_TCR_LBK_NORMAL;      /* normal operating mode */
 2245 
 2246         /* set short/long retry limits */
 2247         tcr &= ~(RTW_TCR_SRL_MASK|RTW_TCR_LRL_MASK);
 2248         tcr |= LSHIFT(4, RTW_TCR_SRL_MASK) | LSHIFT(4, RTW_TCR_LRL_MASK);
 2249 
 2250         tcr &= ~RTW_TCR_CRC;    /* NIC appends CRC32 */
 2251 
 2252         RTW_WRITE(regs, RTW_TCR, tcr);
 2253         RTW_SYNC(regs, RTW_TCR, RTW_TCR);
 2254 }
 2255 
 2256 static __inline void
 2257 rtw_enable_interrupts(struct rtw_softc *sc)
 2258 {
 2259         struct rtw_regs *regs = &sc->sc_regs;
 2260 
 2261         sc->sc_inten = RTW_INTR_RX|RTW_INTR_TX|RTW_INTR_BEACON|RTW_INTR_ATIMINT;
 2262         sc->sc_inten |= RTW_INTR_IOERROR|RTW_INTR_TIMEOUT;
 2263 
 2264         RTW_WRITE16(regs, RTW_IMR, sc->sc_inten);
 2265         RTW_WBW(regs, RTW_IMR, RTW_ISR);
 2266         RTW_WRITE16(regs, RTW_ISR, 0xffff);
 2267         RTW_SYNC(regs, RTW_IMR, RTW_ISR);
 2268 
 2269         /* XXX necessary? */
 2270         if (sc->sc_intr_ack != NULL)
 2271                 (*sc->sc_intr_ack)(regs);
 2272 }
 2273 
 2274 static void
 2275 rtw_set_nettype(struct rtw_softc *sc, enum ieee80211_opmode opmode)
 2276 {
 2277         uint8_t msr;
 2278 
 2279         /* I'm guessing that MSR is protected as CONFIG[0123] are. */
 2280         rtw_set_access(&sc->sc_regs, RTW_ACCESS_CONFIG);
 2281 
 2282         msr = RTW_READ8(&sc->sc_regs, RTW_MSR) & ~RTW_MSR_NETYPE_MASK;
 2283 
 2284         switch (opmode) {
 2285         case IEEE80211_M_AHDEMO:
 2286         case IEEE80211_M_IBSS:
 2287                 msr |= RTW_MSR_NETYPE_ADHOC_OK;
 2288                 break;
 2289         case IEEE80211_M_HOSTAP:
 2290                 msr |= RTW_MSR_NETYPE_AP_OK;
 2291                 break;
 2292         case IEEE80211_M_MONITOR:
 2293                 /* XXX */
 2294                 msr |= RTW_MSR_NETYPE_NOLINK;
 2295                 break;
 2296         case IEEE80211_M_STA:
 2297                 msr |= RTW_MSR_NETYPE_INFRA_OK;
 2298                 break;
 2299         }
 2300         RTW_WRITE8(&sc->sc_regs, RTW_MSR, msr);
 2301 
 2302         rtw_set_access(&sc->sc_regs, RTW_ACCESS_NONE);
 2303 }
 2304 
 2305 #define rtw_calchash(addr) \
 2306         (ether_crc32_be((addr), IEEE80211_ADDR_LEN) >> 26)
 2307 
 2308 static void
 2309 rtw_pktfilt_load(struct rtw_softc *sc)
 2310 {
 2311         struct rtw_regs *regs = &sc->sc_regs;
 2312         struct ieee80211com *ic = &sc->sc_ic;
 2313         struct ethercom *ec = &ic->ic_ec;
 2314         struct ifnet *ifp = &sc->sc_ic.ic_if;
 2315         int hash;
 2316         uint32_t hashes[2] = { 0, 0 };
 2317         struct ether_multi *enm;
 2318         struct ether_multistep step;
 2319 
 2320         /* XXX might be necessary to stop Rx/Tx engines while setting filters */
 2321 
 2322         sc->sc_rcr &= ~RTW_RCR_PKTFILTER_MASK;
 2323         sc->sc_rcr &= ~(RTW_RCR_MXDMA_MASK | RTW_RCR_RXFTH_MASK);
 2324 
 2325         sc->sc_rcr |= RTW_RCR_PKTFILTER_DEFAULT;
 2326         /* MAC auto-reset PHY (huh?) */
 2327         sc->sc_rcr |= RTW_RCR_ENMARP;
 2328         /* DMA whole Rx packets, only.  Set Tx DMA burst size to 1024 bytes. */
 2329         sc->sc_rcr |= RTW_RCR_MXDMA_1024 | RTW_RCR_RXFTH_WHOLE;
 2330 
 2331         switch (ic->ic_opmode) {
 2332         case IEEE80211_M_MONITOR:
 2333                 sc->sc_rcr |= RTW_RCR_MONITOR;
 2334                 break;
 2335         case IEEE80211_M_AHDEMO:
 2336         case IEEE80211_M_IBSS:
 2337                 /* receive broadcasts in our BSS */
 2338                 sc->sc_rcr |= RTW_RCR_ADD3;
 2339                 break;
 2340         default:
 2341                 break;
 2342         }
 2343 
 2344         ifp->if_flags &= ~IFF_ALLMULTI;
 2345 
 2346         /* XXX accept all broadcast if scanning */
 2347         if ((ifp->if_flags & IFF_BROADCAST) != 0)
 2348                 sc->sc_rcr |= RTW_RCR_AB;       /* accept all broadcast */
 2349 
 2350         if (ifp->if_flags & IFF_PROMISC) {
 2351                 sc->sc_rcr |= RTW_RCR_AB;       /* accept all broadcast */
 2352 allmulti:
 2353                 ifp->if_flags |= IFF_ALLMULTI;
 2354                 goto setit;
 2355         }
 2356 
 2357         /*
 2358          * Program the 64-bit multicast hash filter.
 2359          */
 2360         ETHER_FIRST_MULTI(step, ec, enm);
 2361         while (enm != NULL) {
 2362                 /* XXX */
 2363                 if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
 2364                     ETHER_ADDR_LEN) != 0)
 2365                         goto allmulti;
 2366 
 2367                 hash = rtw_calchash(enm->enm_addrlo);
 2368                 hashes[hash >> 5] |= (1 << (hash & 0x1f));
 2369                 sc->sc_rcr |= RTW_RCR_AM;
 2370                 ETHER_NEXT_MULTI(step, enm);
 2371         }
 2372 
 2373         /* all bits set => hash is useless */
 2374         if (~(hashes[0] & hashes[1]) == 0)
 2375                 goto allmulti;
 2376 
 2377  setit:
 2378         if (ifp->if_flags & IFF_ALLMULTI) {
 2379                 sc->sc_rcr |= RTW_RCR_AM;       /* accept all multicast */
 2380                 hashes[0] = hashes[1] = 0xffffffff;
 2381         }
 2382 
 2383         RTW_WRITE(regs, RTW_MAR0, hashes[0]);
 2384         RTW_WRITE(regs, RTW_MAR1, hashes[1]);
 2385         RTW_WRITE(regs, RTW_RCR, sc->sc_rcr);
 2386         RTW_SYNC(regs, RTW_MAR0, RTW_RCR); /* RTW_MAR0 < RTW_MAR1 < RTW_RCR */
 2387 
 2388         DPRINTF(sc, RTW_DEBUG_PKTFILT,
 2389             ("%s: RTW_MAR0 %08x RTW_MAR1 %08x RTW_RCR %08x\n",
 2390             sc->sc_dev.dv_xname, RTW_READ(regs, RTW_MAR0),
 2391             RTW_READ(regs, RTW_MAR1), RTW_READ(regs, RTW_RCR)));
 2392 
 2393         return;
 2394 }
 2395 
 2396 #define IEEE80211_BEACON_TIMESTAMP_LEN          8
 2397 #define IEEE80211_BEACON_BINTVL_LEN             2
 2398 #define IEEE80211_BEACON_CAPINFO_LEN            2
 2399 #define IEEE80211_TLV_SSID_LEN(__esslen)        (2 + (__esslen))
 2400 #define IEEE80211_TLV_SUPRATES_LEN(__nrates)    (2 + (__nrates))
 2401 #define IEEE80211_TLV_XSUPRATES_LEN(__nrates)   (2 + (__nrates))
 2402 #define IEEE80211_TLV_DSPARMS_LEN               3
 2403 #define IEEE80211_TLV_IBSSPARMS                 4
 2404 #define IEEE80211_TLV_MIN_TIM                   6
 2405 
 2406 #define IEEE80211_TLV_ALLRATES_LEN(__nrates)    \
 2407         (((__nrates) > IEEE80211_RATE_SIZE) ? 4 + (__nrates) : 2 + (__nrates))
 2408 
 2409 /* TBD factor with ieee80211_getmbuf */
 2410 static struct mbuf *
 2411 rtw_getmbuf(int flags, int type, u_int pktlen)
 2412 {
 2413         struct mbuf *m;
 2414 
 2415         KASSERT2(pktlen <= MCLBYTES, ("802.11 packet too large: %u", pktlen));
 2416         MGETHDR(m, flags, type);
 2417         if (m == NULL || pktlen <= MHLEN)
 2418                 return m;
 2419         MCLGET(m, flags);
 2420         if ((m->m_flags & M_EXT) != 0)
 2421                 return m;
 2422         m_free(m);
 2423         return NULL;
 2424 }
 2425 
 2426 /* TBD factor with ath_beacon_alloc */
 2427 static struct mbuf *
 2428 rtw_beacon_alloc(struct rtw_softc *sc, struct ieee80211_node *ni)
 2429 {
 2430         struct ieee80211com *ic = &sc->sc_ic;
 2431         struct ifnet *ifp = &ic->ic_if;
 2432         struct ieee80211_frame *wh;
 2433         struct mbuf *m;
 2434         int pktlen;
 2435         uint8_t *frm;
 2436         uint16_t capinfo;
 2437         struct ieee80211_rateset *rs;
 2438 
 2439         /*
 2440          * NB: the beacon data buffer must be 32-bit aligned;
 2441          * we assume the mbuf routines will return us something
 2442          * with this alignment (perhaps should assert).
 2443          */
 2444         rs = &ni->ni_rates;
 2445         pktlen = sizeof(struct ieee80211_frame)
 2446                + IEEE80211_BEACON_TIMESTAMP_LEN
 2447                + IEEE80211_BEACON_BINTVL_LEN
 2448                + IEEE80211_BEACON_CAPINFO_LEN
 2449                + IEEE80211_TLV_SSID_LEN(ni->ni_esslen)
 2450                + IEEE80211_TLV_ALLRATES_LEN(rs->rs_nrates)
 2451                + IEEE80211_TLV_DSPARMS_LEN
 2452                + MAX(IEEE80211_TLV_IBSSPARMS, IEEE80211_TLV_MIN_TIM);
 2453 
 2454         m = rtw_getmbuf(M_DONTWAIT, MT_DATA, pktlen);
 2455         if (m == NULL) {
 2456                 RTW_DPRINTF(RTW_DEBUG_BEACON,
 2457                         ("%s: cannot get mbuf/cluster; size %u\n",
 2458                         __func__, pktlen));
 2459 #if 0
 2460                 sc->sc_stats.ast_be_nombuf++;
 2461 #endif
 2462                 return NULL;
 2463         }
 2464 
 2465         wh = mtod(m, struct ieee80211_frame *);
 2466         wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |
 2467             IEEE80211_FC0_SUBTYPE_BEACON;
 2468         wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
 2469         *(u_int16_t *)wh->i_dur = 0;
 2470         memcpy(wh->i_addr1, ifp->if_broadcastaddr, IEEE80211_ADDR_LEN);
 2471         memcpy(wh->i_addr2, ic->ic_myaddr, IEEE80211_ADDR_LEN);
 2472         memcpy(wh->i_addr3, ni->ni_bssid, IEEE80211_ADDR_LEN);
 2473         *(u_int16_t *)wh->i_seq = 0;
 2474 
 2475         /*
 2476          * beacon frame format
 2477          *      [8] time stamp
 2478          *      [2] beacon interval
 2479          *      [2] cabability information
 2480          *      [tlv] ssid
 2481          *      [tlv] supported rates
 2482          *      [tlv] parameter set (IBSS)
 2483          *      [tlv] extended supported rates
 2484          */
 2485         frm = (u_int8_t *)&wh[1];
 2486         /* timestamp is set by hardware */
 2487         memset(frm, 0, IEEE80211_BEACON_TIMESTAMP_LEN);
 2488         frm += IEEE80211_BEACON_TIMESTAMP_LEN;
 2489         *(u_int16_t *)frm = htole16(ni->ni_intval);
 2490         frm += IEEE80211_BEACON_BINTVL_LEN;
 2491         if (ic->ic_opmode == IEEE80211_M_IBSS)
 2492                 capinfo = IEEE80211_CAPINFO_IBSS;
 2493         else
 2494                 capinfo = IEEE80211_CAPINFO_ESS;
 2495         if (ic->ic_flags & IEEE80211_F_PRIVACY)
 2496                 capinfo |= IEEE80211_CAPINFO_PRIVACY;
 2497         if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
 2498             IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
 2499                 capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE;
 2500         if (ic->ic_flags & IEEE80211_F_SHSLOT)
 2501                 capinfo |= IEEE80211_CAPINFO_SHORT_SLOTTIME;
 2502         *(u_int16_t *)frm = htole16(capinfo);
 2503         frm += IEEE80211_BEACON_CAPINFO_LEN;
 2504         *frm++ = IEEE80211_ELEMID_SSID;
 2505         *frm++ = ni->ni_esslen;
 2506         memcpy(frm, ni->ni_essid, ni->ni_esslen);
 2507         frm += ni->ni_esslen;
 2508         frm = ieee80211_add_rates(frm, rs);
 2509         *frm++ = IEEE80211_ELEMID_DSPARMS;
 2510         *frm++ = 1;
 2511         *frm++ = ieee80211_chan2ieee(ic, ni->ni_chan);
 2512         if (ic->ic_opmode == IEEE80211_M_IBSS) {
 2513                 *frm++ = IEEE80211_ELEMID_IBSSPARMS;
 2514                 *frm++ = 2;
 2515                 *frm++ = 0; *frm++ = 0;         /* TODO: ATIM window */
 2516         } else {
 2517                 /* TODO: TIM */
 2518                 *frm++ = IEEE80211_ELEMID_TIM;
 2519                 *frm++ = 4;     /* length */
 2520                 *frm++ = 0;     /* DTIM count */
 2521                 *frm++ = 1;     /* DTIM period */
 2522                 *frm++ = 0;     /* bitmap control */
 2523                 *frm++ = 0;     /* Partial Virtual Bitmap (variable length) */
 2524         }
 2525         frm = ieee80211_add_xrates(frm, rs);
 2526         m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
 2527         m->m_pkthdr.rcvif = (void *)ni;
 2528         KASSERT2(m->m_pkthdr.len <= pktlen,
 2529                 ("beacon bigger than expected, len %u calculated %u",
 2530                 m->m_pkthdr.len, pktlen));
 2531 
 2532         RTW_DPRINTF(RTW_DEBUG_BEACON,
 2533             ("%s: m %p len %u\n", __func__, m, m->m_len));
 2534 
 2535         return m;
 2536 }
 2537 
 2538 /* Must be called at splnet. */
 2539 static int
 2540 rtw_init(struct ifnet *ifp)
 2541 {
 2542         struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc;
 2543         struct ieee80211com *ic = &sc->sc_ic;
 2544         struct rtw_regs *regs = &sc->sc_regs;
 2545         int rc = 0;
 2546 
 2547         if ((rc = rtw_enable(sc)) != 0)
 2548                 goto out;
 2549 
 2550         /* Cancel pending I/O and reset. */
 2551         rtw_stop(ifp, 0);
 2552 
 2553         ic->ic_bss->ni_chan = ic->ic_ibss_chan;
 2554         DPRINTF(sc, RTW_DEBUG_TUNE, ("%s: channel %d freq %d flags 0x%04x\n",
 2555             __func__, ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan),
 2556             ic->ic_bss->ni_chan->ic_freq, ic->ic_bss->ni_chan->ic_flags));
 2557 
 2558         if ((rc = rtw_pwrstate(sc, RTW_OFF)) != 0)
 2559                 goto out;
 2560 
 2561         if ((rc = rtw_swring_setup(sc)) != 0)
 2562                 goto out;
 2563 
 2564         rtw_transmit_config(regs);
 2565 
 2566         rtw_set_access(regs, RTW_ACCESS_CONFIG);
 2567 
 2568         RTW_WRITE8(regs, RTW_MSR, 0x0); /* no link */
 2569         RTW_WBW(regs, RTW_MSR, RTW_BRSR);
 2570 
 2571         /* long PLCP header, 1Mb/2Mb basic rate */
 2572         RTW_WRITE16(regs, RTW_BRSR, RTW_BRSR_MBR8180_2MBPS);
 2573         RTW_SYNC(regs, RTW_BRSR, RTW_BRSR);
 2574 
 2575         rtw_set_access(regs, RTW_ACCESS_ANAPARM);
 2576         rtw_set_access(regs, RTW_ACCESS_NONE);
 2577 
 2578         /* XXX from reference sources */
 2579         RTW_WRITE(regs, RTW_FEMR, 0xffff);
 2580         RTW_SYNC(regs, RTW_FEMR, RTW_FEMR);
 2581 
 2582         rtw_set_rfprog(regs, sc->sc_rfchipid, sc->sc_dev.dv_xname);
 2583 
 2584         RTW_WRITE8(regs, RTW_PHYDELAY, sc->sc_phydelay);
 2585         /* from Linux driver */
 2586         RTW_WRITE8(regs, RTW_CRCOUNT, RTW_CRCOUNT_MAGIC);
 2587 
 2588         RTW_SYNC(regs, RTW_PHYDELAY, RTW_CRCOUNT);
 2589 
 2590         rtw_enable_interrupts(sc);
 2591 
 2592         rtw_pktfilt_load(sc);
 2593 
 2594         rtw_hwring_setup(sc);
 2595 
 2596         rtw_wep_setkeys(sc, ic->ic_nw_keys, ic->ic_wep_txkey);
 2597 
 2598         rtw_io_enable(regs, RTW_CR_RE|RTW_CR_TE, 1);
 2599 
 2600         ifp->if_flags |= IFF_RUNNING;
 2601         ic->ic_state = IEEE80211_S_INIT;
 2602 
 2603         RTW_WRITE16(regs, RTW_BSSID16, 0x0);
 2604         RTW_WRITE(regs, RTW_BSSID32, 0x0);
 2605 
 2606         rtw_resume_ticks(sc);
 2607 
 2608         rtw_set_nettype(sc, IEEE80211_M_MONITOR);
 2609 
 2610         if (ic->ic_opmode == IEEE80211_M_MONITOR)
 2611                 return ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
 2612         else
 2613                 return ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
 2614 
 2615 out:
 2616         printf("%s: interface not running\n", sc->sc_dev.dv_xname);
 2617         return rc;
 2618 }
 2619 
 2620 static __inline void
 2621 rtw_led_init(struct rtw_regs *regs)
 2622 {
 2623         uint8_t cfg0, cfg1;
 2624 
 2625         rtw_set_access(regs, RTW_ACCESS_CONFIG);
 2626 
 2627         cfg0 = RTW_READ8(regs, RTW_CONFIG0);
 2628         cfg0 |= RTW_CONFIG0_LEDGPOEN;
 2629         RTW_WRITE8(regs, RTW_CONFIG0, cfg0);
 2630 
 2631         cfg1 = RTW_READ8(regs, RTW_CONFIG1);
 2632         RTW_DPRINTF(RTW_DEBUG_LED,
 2633             ("%s: read %" PRIx8 " from reg[CONFIG1]\n", __func__, cfg1));
 2634 
 2635         cfg1 &= ~RTW_CONFIG1_LEDS_MASK;
 2636         cfg1 |= RTW_CONFIG1_LEDS_TX_RX;
 2637         RTW_WRITE8(regs, RTW_CONFIG1, cfg1);
 2638 
 2639         rtw_set_access(regs, RTW_ACCESS_NONE);
 2640 }
 2641 
 2642 /*
 2643  * IEEE80211_S_INIT:            LED1 off
 2644  *
 2645  * IEEE80211_S_AUTH,
 2646  * IEEE80211_S_ASSOC,
 2647  * IEEE80211_S_SCAN:            LED1 blinks @ 1 Hz, blinks at 5Hz for tx/rx
 2648  *
 2649  * IEEE80211_S_RUN:             LED1 on, blinks @ 5Hz for tx/rx
 2650  */
 2651 static void
 2652 rtw_led_newstate(struct rtw_softc *sc, enum ieee80211_state nstate)
 2653 {
 2654         struct rtw_led_state *ls;
 2655 
 2656         ls = &sc->sc_led_state;
 2657 
 2658         switch (nstate) {
 2659         case IEEE80211_S_INIT:
 2660                 rtw_led_init(&sc->sc_regs);
 2661                 callout_stop(&ls->ls_slow_ch);
 2662                 callout_stop(&ls->ls_fast_ch);
 2663                 ls->ls_slowblink = 0;
 2664                 ls->ls_actblink = 0;
 2665                 ls->ls_default = 0;
 2666                 break;
 2667         case IEEE80211_S_SCAN:
 2668                 callout_schedule(&ls->ls_slow_ch, RTW_LED_SLOW_TICKS);
 2669                 callout_schedule(&ls->ls_fast_ch, RTW_LED_FAST_TICKS);
 2670                 /*FALLTHROUGH*/
 2671         case IEEE80211_S_AUTH:
 2672         case IEEE80211_S_ASSOC:
 2673                 ls->ls_default = RTW_LED1;
 2674                 ls->ls_actblink = RTW_LED1;
 2675                 ls->ls_slowblink = RTW_LED1;
 2676                 break;
 2677         case IEEE80211_S_RUN:
 2678                 ls->ls_slowblink = 0;
 2679                 break;
 2680         }
 2681         rtw_led_set(ls, &sc->sc_regs, sc->sc_hwverid);
 2682 }
 2683 
 2684 static void
 2685 rtw_led_set(struct rtw_led_state *ls, struct rtw_regs *regs, int hwverid)
 2686 {
 2687         uint8_t led_condition;
 2688         bus_size_t ofs;
 2689         uint8_t mask, newval, val;
 2690 
 2691         led_condition = ls->ls_default;
 2692 
 2693         if (ls->ls_state & RTW_LED_S_SLOW)
 2694                 led_condition ^= ls->ls_slowblink;
 2695         if (ls->ls_state & (RTW_LED_S_RX|RTW_LED_S_TX))
 2696                 led_condition ^= ls->ls_actblink;
 2697 
 2698         RTW_DPRINTF(RTW_DEBUG_LED,
 2699             ("%s: LED condition %" PRIx8 "\n", __func__, led_condition));
 2700 
 2701         switch (hwverid) {
 2702         default:
 2703         case 'F':
 2704                 ofs = RTW_PSR;
 2705                 newval = mask = RTW_PSR_LEDGPO0 | RTW_PSR_LEDGPO1;
 2706                 if (led_condition & RTW_LED0)
 2707                         newval &= ~RTW_PSR_LEDGPO0;
 2708                 if (led_condition & RTW_LED1)
 2709                         newval &= ~RTW_PSR_LEDGPO1;
 2710                 break;
 2711         case 'D':
 2712                 ofs = RTW_9346CR;
 2713                 mask = RTW_9346CR_EEM_MASK | RTW_9346CR_EEDI | RTW_9346CR_EECS;
 2714                 newval = RTW_9346CR_EEM_PROGRAM;
 2715                 if (led_condition & RTW_LED0)
 2716                         newval |= RTW_9346CR_EEDI;
 2717                 if (led_condition & RTW_LED1)
 2718                         newval |= RTW_9346CR_EECS;
 2719                 break;
 2720         }
 2721         val = RTW_READ8(regs, ofs);
 2722         RTW_DPRINTF(RTW_DEBUG_LED,
 2723             ("%s: read %" PRIx8 " from reg[%#02" PRIxPTR "]\n", __func__, val,
 2724              (uintptr_t)ofs));
 2725         val &= ~mask;
 2726         val |= newval;
 2727         RTW_WRITE8(regs, ofs, val);
 2728         RTW_DPRINTF(RTW_DEBUG_LED,
 2729             ("%s: wrote %" PRIx8 " to reg[%#02" PRIxPTR "]\n", __func__, val,
 2730              (uintptr_t)ofs));
 2731         RTW_SYNC(regs, ofs, ofs);
 2732 }
 2733 
 2734 static void
 2735 rtw_led_fastblink(void *arg)
 2736 {
 2737         int ostate, s;
 2738         struct rtw_softc *sc = (struct rtw_softc *)arg;
 2739         struct rtw_led_state *ls = &sc->sc_led_state;
 2740 
 2741         s = splnet();
 2742         ostate = ls->ls_state;
 2743         ls->ls_state ^= ls->ls_event;
 2744 
 2745         if ((ls->ls_event & RTW_LED_S_TX) == 0)
 2746                 ls->ls_state &= ~RTW_LED_S_TX;
 2747 
 2748         if ((ls->ls_event & RTW_LED_S_RX) == 0)
 2749                 ls->ls_state &= ~RTW_LED_S_RX;
 2750 
 2751         ls->ls_event = 0;
 2752 
 2753         if (ostate != ls->ls_state)
 2754                 rtw_led_set(ls, &sc->sc_regs, sc->sc_hwverid);
 2755         splx(s);
 2756 
 2757         callout_schedule(&ls->ls_fast_ch, RTW_LED_FAST_TICKS);
 2758 }
 2759 
 2760 static void
 2761 rtw_led_slowblink(void *arg)
 2762 {
 2763         int s;
 2764         struct rtw_softc *sc = (struct rtw_softc *)arg;
 2765         struct rtw_led_state *ls = &sc->sc_led_state;
 2766 
 2767         s = splnet();
 2768         ls->ls_state ^= RTW_LED_S_SLOW;
 2769         rtw_led_set(ls, &sc->sc_regs, sc->sc_hwverid);
 2770         splx(s);
 2771         callout_schedule(&ls->ls_slow_ch, RTW_LED_SLOW_TICKS);
 2772 }
 2773 
 2774 static __inline void
 2775 rtw_led_attach(struct rtw_led_state *ls, void *arg)
 2776 {
 2777         callout_init(&ls->ls_fast_ch);
 2778         callout_init(&ls->ls_slow_ch);
 2779         callout_setfunc(&ls->ls_fast_ch, rtw_led_fastblink, arg);
 2780         callout_setfunc(&ls->ls_slow_ch, rtw_led_slowblink, arg);
 2781 }
 2782 
 2783 static int
 2784 rtw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
 2785 {
 2786         int rc = 0, s;
 2787         struct rtw_softc *sc = ifp->if_softc;
 2788         struct ifreq *ifr = (struct ifreq *)data;
 2789 
 2790         s = splnet();
 2791         switch (cmd) {
 2792         case SIOCSIFFLAGS:
 2793                 if ((ifp->if_flags & IFF_UP) != 0) {
 2794                         if ((sc->sc_flags & RTW_F_ENABLED) != 0) {
 2795                                 rtw_pktfilt_load(sc);
 2796                         } else
 2797                                 rc = rtw_init(ifp);
 2798                         RTW_PRINT_REGS(&sc->sc_regs, ifp->if_xname, __func__);
 2799                 } else if ((sc->sc_flags & RTW_F_ENABLED) != 0) {
 2800                         RTW_PRINT_REGS(&sc->sc_regs, ifp->if_xname, __func__);
 2801                         rtw_stop(ifp, 1);
 2802                 }
 2803                 break;
 2804         case SIOCADDMULTI:
 2805         case SIOCDELMULTI:
 2806                 if (cmd == SIOCADDMULTI)
 2807                         rc = ether_addmulti(ifr, &sc->sc_ic.ic_ec);
 2808                 else
 2809                         rc = ether_delmulti(ifr, &sc->sc_ic.ic_ec);
 2810                 if (rc != ENETRESET)
 2811                         break;
 2812                 if (ifp->if_flags & IFF_RUNNING)
 2813                         rtw_pktfilt_load(sc);
 2814                 rc = 0;
 2815                 break;
 2816         case SIOCS80211NWKEY:
 2817                 if ((rc = ieee80211_ioctl(ifp, cmd, data)) != ENETRESET)
 2818                         break;
 2819                 rc = 0;
 2820                 if ((ifp->if_flags & IFF_RUNNING) == 0)
 2821                         break;
 2822                 rtw_wep_setkeys(sc, sc->sc_ic.ic_nw_keys,
 2823                     sc->sc_ic.ic_wep_txkey);
 2824                 break;
 2825         default:
 2826                 if ((rc = ieee80211_ioctl(ifp, cmd, data)) != ENETRESET)
 2827                         break;
 2828                 if ((sc->sc_flags & RTW_F_ENABLED) != 0)
 2829                         rc = rtw_init(ifp);
 2830                 else
 2831                         rc = 0;
 2832                 break;
 2833         }
 2834         splx(s);
 2835         return rc;
 2836 }
 2837 
 2838 /* Select a transmit ring with at least one h/w and s/w descriptor free.
 2839  * Return 0 on success, -1 on failure.
 2840  */
 2841 static __inline int
 2842 rtw_txring_choose(struct rtw_softc *sc, struct rtw_txsoft_blk **tsbp,
 2843     struct rtw_txdesc_blk **tdbp, int pri)
 2844 {
 2845         struct rtw_txsoft_blk *tsb;
 2846         struct rtw_txdesc_blk *tdb;
 2847 
 2848         KASSERT(pri >= 0 && pri < RTW_NTXPRI);
 2849 
 2850         tsb = &sc->sc_txsoft_blk[pri];
 2851         tdb = &sc->sc_txdesc_blk[pri];
 2852 
 2853         if (SIMPLEQ_EMPTY(&tsb->tsb_freeq) || tdb->tdb_nfree == 0) {
 2854                 *tsbp = NULL;
 2855                 *tdbp = NULL;
 2856                 return -1;
 2857         }
 2858         *tsbp = tsb;
 2859         *tdbp = tdb;
 2860         return 0;
 2861 }
 2862 
 2863 static __inline struct mbuf *
 2864 rtw_80211_dequeue(struct rtw_softc *sc, struct ifqueue *ifq, int pri,
 2865     struct rtw_txsoft_blk **tsbp, struct rtw_txdesc_blk **tdbp,
 2866     struct ieee80211_node **nip, short *if_flagsp)
 2867 {
 2868         struct mbuf *m;
 2869 
 2870         if (IF_IS_EMPTY(ifq))
 2871                 return NULL;
 2872         if (rtw_txring_choose(sc, tsbp, tdbp, pri) == -1) {
 2873                 *if_flagsp |= IFF_OACTIVE;
 2874                 return NULL;
 2875         }
 2876         IF_DEQUEUE(ifq, m);
 2877         *nip = (struct ieee80211_node *)m->m_pkthdr.rcvif;
 2878         m->m_pkthdr.rcvif = NULL;
 2879         return m;
 2880 }
 2881 
 2882 /* Point *mp at the next 802.11 frame to transmit.  Point *tsbp
 2883  * at the driver's selection of transmit control block for the packet.
 2884  */
 2885 static __inline int
 2886 rtw_dequeue(struct ifnet *ifp, struct rtw_txsoft_blk **tsbp,
 2887     struct rtw_txdesc_blk **tdbp, struct mbuf **mp,
 2888     struct ieee80211_node **nip)
 2889 {
 2890         struct mbuf *m0;
 2891         struct rtw_softc *sc;
 2892         short *if_flagsp;
 2893 
 2894         sc = (struct rtw_softc *)ifp->if_softc;
 2895 
 2896         DPRINTF(sc, RTW_DEBUG_XMIT,
 2897             ("%s: enter %s\n", sc->sc_dev.dv_xname, __func__));
 2898 
 2899         if_flagsp = &ifp->if_flags;
 2900 
 2901         if (sc->sc_ic.ic_state == IEEE80211_S_RUN &&
 2902             (*mp = rtw_80211_dequeue(sc, &sc->sc_beaconq, RTW_TXPRIBCN, tsbp,
 2903                                      tdbp, nip, if_flagsp)) != NULL) {
 2904                 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: dequeue beacon frame\n",
 2905                     __func__));
 2906                 return 0;
 2907         }
 2908 
 2909         if ((*mp = rtw_80211_dequeue(sc, &sc->sc_ic.ic_mgtq, RTW_TXPRIMD, tsbp,
 2910                                      tdbp, nip, if_flagsp)) != NULL) {
 2911                 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: dequeue mgt frame\n",
 2912                     __func__));
 2913                 return 0;
 2914         }
 2915 
 2916         if (sc->sc_ic.ic_state != IEEE80211_S_RUN) {
 2917                 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: not running\n", __func__));
 2918                 return 0;
 2919         }
 2920 
 2921         if ((*mp = rtw_80211_dequeue(sc, &sc->sc_ic.ic_pwrsaveq, RTW_TXPRIHI,
 2922                                      tsbp, tdbp, nip, if_flagsp)) != NULL) {
 2923                 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: dequeue pwrsave frame\n",
 2924                     __func__));
 2925                 return 0;
 2926         }
 2927 
 2928         if (rtw_txring_choose(sc, tsbp, tdbp, RTW_TXPRIMD) == -1) {
 2929                 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: no descriptor\n", __func__));
 2930                 *if_flagsp |= IFF_OACTIVE;
 2931                 return 0;
 2932         }
 2933 
 2934         *mp = NULL;
 2935 
 2936         IFQ_DEQUEUE(&ifp->if_snd, m0);
 2937         if (m0 == NULL) {
 2938                 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: no frame/ring ready\n",
 2939                     __func__));
 2940                 return 0;
 2941         }
 2942         DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: dequeue data frame\n", __func__));
 2943         ifp->if_opackets++;
 2944 #if NBPFILTER > 0
 2945         if (ifp->if_bpf)
 2946                 bpf_mtap(ifp->if_bpf, m0);
 2947 #endif
 2948         if ((m0 = ieee80211_encap(ifp, m0, nip)) == NULL) {
 2949                 DPRINTF(sc, RTW_DEBUG_XMIT,
 2950                     ("%s: encap error\n", __func__));
 2951                 ifp->if_oerrors++;
 2952                 return -1;
 2953         }
 2954         DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: leave\n", __func__));
 2955         *mp = m0;
 2956         return 0;
 2957 }
 2958 
 2959 static int
 2960 rtw_seg_too_short(bus_dmamap_t dmamap)
 2961 {
 2962         int i;
 2963         for (i = 0; i < dmamap->dm_nsegs; i++) {
 2964                 if (dmamap->dm_segs[i].ds_len < 4) {
 2965                         printf("%s: segment too short\n", __func__);
 2966                         return 1;
 2967                 }
 2968         }
 2969         return 0;
 2970 }
 2971 
 2972 /* TBD factor with atw_start */
 2973 static struct mbuf *
 2974 rtw_dmamap_load_txbuf(bus_dma_tag_t dmat, bus_dmamap_t dmam, struct mbuf *chain,
 2975     u_int ndescfree, short *ifflagsp, const char *dvname)
 2976 {
 2977         int first, rc;
 2978         struct mbuf *m, *m0;
 2979 
 2980         m0 = chain;
 2981 
 2982         /*
 2983          * Load the DMA map.  Copy and try (once) again if the packet
 2984          * didn't fit in the alloted number of segments.
 2985          */
 2986         for (first = 1;
 2987              ((rc = bus_dmamap_load_mbuf(dmat, dmam, m0,
 2988                           BUS_DMA_WRITE|BUS_DMA_NOWAIT)) != 0 ||
 2989               dmam->dm_nsegs > ndescfree || rtw_seg_too_short(dmam)) && first;
 2990              first = 0) {
 2991                 if (rc == 0)
 2992                         bus_dmamap_unload(dmat, dmam);
 2993                 MGETHDR(m, M_DONTWAIT, MT_DATA);
 2994                 if (m == NULL) {
 2995                         printf("%s: unable to allocate Tx mbuf\n",
 2996                             dvname);
 2997                         break;
 2998                 }
 2999                 if (m0->m_pkthdr.len > MHLEN) {
 3000                         MCLGET(m, M_DONTWAIT);
 3001                         if ((m->m_flags & M_EXT) == 0) {
 3002                                 printf("%s: cannot allocate Tx cluster\n",
 3003                                     dvname);
 3004                                 m_freem(m);
 3005                                 break;
 3006                         }
 3007                 }
 3008                 m_copydata(m0, 0, m0->m_pkthdr.len, mtod(m, caddr_t));
 3009                 m->m_pkthdr.len = m->m_len = m0->m_pkthdr.len;
 3010                 m_freem(m0);
 3011                 m0 = m;
 3012                 m = NULL;
 3013         }
 3014         if (rc != 0) {
 3015                 printf("%s: cannot load Tx buffer, rc = %d\n", dvname, rc);
 3016                 m_freem(m0);
 3017                 return NULL;
 3018         } else if (rtw_seg_too_short(dmam)) {
 3019                 printf("%s: cannot load Tx buffer, segment too short\n",
 3020                     dvname);
 3021                 bus_dmamap_unload(dmat, dmam);
 3022                 m_freem(m0);
 3023                 return NULL;
 3024         } else if (dmam->dm_nsegs > ndescfree) {
 3025                 *ifflagsp |= IFF_OACTIVE;
 3026                 bus_dmamap_unload(dmat, dmam);
 3027                 m_freem(m0);
 3028                 return NULL;
 3029         }
 3030         return m0;
 3031 }
 3032 
 3033 #ifdef RTW_DEBUG
 3034 static void
 3035 rtw_print_txdesc(struct rtw_softc *sc, const char *action,
 3036     struct rtw_txsoft *ts, struct rtw_txdesc_blk *tdb, int desc)
 3037 {
 3038         struct rtw_txdesc *td = &tdb->tdb_desc[desc];
 3039         DPRINTF(sc, RTW_DEBUG_XMIT_DESC, ("%s: %p %s txdesc[%d] ctl0 %#08x "
 3040             "ctl1 %#08x buf %#08x len %#08x\n",
 3041             sc->sc_dev.dv_xname, ts, action, desc,
 3042             le32toh(td->td_ctl0),
 3043             le32toh(td->td_ctl1), le32toh(td->td_buf),
 3044             le32toh(td->td_len)));
 3045 }
 3046 #endif /* RTW_DEBUG */
 3047 
 3048 static void
 3049 rtw_start(struct ifnet *ifp)
 3050 {
 3051         uint8_t tppoll;
 3052         int desc, i, lastdesc, npkt, rate;
 3053         uint32_t proto_ctl0, ctl0, ctl1;
 3054         bus_dmamap_t            dmamap;
 3055         struct ieee80211com     *ic;
 3056         struct ieee80211_duration *d0;
 3057         struct ieee80211_frame  *wh;
 3058         struct ieee80211_node   *ni;
 3059         struct mbuf             *m0;
 3060         struct rtw_softc        *sc;
 3061         struct rtw_txsoft_blk   *tsb;
 3062         struct rtw_txdesc_blk   *tdb;
 3063         struct rtw_txsoft       *ts;
 3064         struct rtw_txdesc       *td;
 3065 
 3066         sc = (struct rtw_softc *)ifp->if_softc;
 3067         ic = &sc->sc_ic;
 3068 
 3069         DPRINTF(sc, RTW_DEBUG_XMIT,
 3070             ("%s: enter %s\n", sc->sc_dev.dv_xname, __func__));
 3071 
 3072         if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING)
 3073                 goto out;
 3074 
 3075         /* XXX do real rate control */
 3076         proto_ctl0 = RTW_TXCTL0_RTSRATE_1MBPS;
 3077 
 3078         if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0)
 3079                 proto_ctl0 |= RTW_TXCTL0_SPLCP;
 3080 
 3081         for (;;) {
 3082                 if (rtw_dequeue(ifp, &tsb, &tdb, &m0, &ni) == -1)
 3083                         continue;
 3084                 if (m0 == NULL)
 3085                         break;
 3086                 ts = SIMPLEQ_FIRST(&tsb->tsb_freeq);
 3087 
 3088                 dmamap = ts->ts_dmamap;
 3089 
 3090                 m0 = rtw_dmamap_load_txbuf(sc->sc_dmat, dmamap, m0,
 3091                     tdb->tdb_nfree, &ifp->if_flags, sc->sc_dev.dv_xname);
 3092 
 3093                 if (m0 == NULL || dmamap->dm_nsegs == 0) {
 3094                         DPRINTF(sc, RTW_DEBUG_XMIT,
 3095                             ("%s: fail dmamap load\n", __func__));
 3096                         goto post_dequeue_err;
 3097                 }
 3098 
 3099                 wh = mtod(m0, struct ieee80211_frame *);
 3100 
 3101                 /* XXX do real rate control */
 3102                 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
 3103                     IEEE80211_FC0_TYPE_MGT)
 3104                         rate = 2;
 3105                 else
 3106                         rate = MAX(2, ieee80211_get_rate(ic));
 3107 
 3108 #ifdef RTW_DEBUG
 3109                 if ((sc->sc_if.if_flags & (IFF_DEBUG|IFF_LINK2)) ==
 3110                     (IFF_DEBUG|IFF_LINK2)) {
 3111                         ieee80211_dump_pkt(mtod(m0, uint8_t *),
 3112                             (dmamap->dm_nsegs == 1) ? m0->m_pkthdr.len
 3113                                                     : sizeof(wh),
 3114                             rate, 0);
 3115                 }
 3116 #endif /* RTW_DEBUG */
 3117                 ctl0 = proto_ctl0 |
 3118                     LSHIFT(m0->m_pkthdr.len, RTW_TXCTL0_TPKTSIZE_MASK);
 3119 
 3120                 switch (rate) {
 3121                 default:
 3122                 case 2:
 3123                         ctl0 |= RTW_TXCTL0_RATE_1MBPS;
 3124                         break;
 3125                 case 4:
 3126                         ctl0 |= RTW_TXCTL0_RATE_2MBPS;
 3127                         break;
 3128                 case 11:
 3129                         ctl0 |= RTW_TXCTL0_RATE_5MBPS;
 3130                         break;
 3131                 case 22:
 3132                         ctl0 |= RTW_TXCTL0_RATE_11MBPS;
 3133                         break;
 3134                 }
 3135 
 3136                 /* XXX >= ? Compare after fragmentation? */
 3137                 if (m0->m_pkthdr.len > ic->ic_rtsthreshold)
 3138                         ctl0 |= RTW_TXCTL0_RTSEN;
 3139 
 3140                 if ((wh->i_fc[1] & IEEE80211_FC1_WEP) != 0)
 3141                         ctl0 |= LSHIFT(sc->sc_txkey, RTW_TXCTL0_KEYID_MASK);
 3142 
 3143                 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
 3144                     IEEE80211_FC0_TYPE_MGT) {
 3145                         ctl0 &= ~(RTW_TXCTL0_SPLCP | RTW_TXCTL0_RTSEN);
 3146                         if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) ==
 3147                             IEEE80211_FC0_SUBTYPE_BEACON)
 3148                                 ctl0 |= RTW_TXCTL0_BEACON;
 3149                 }
 3150 
 3151                 if (ieee80211_compute_duration(wh, m0->m_pkthdr.len,
 3152                     ic->ic_flags, ic->ic_fragthreshold,
 3153                     rate, &ts->ts_d0, &ts->ts_dn, &npkt,
 3154                     (sc->sc_if.if_flags & (IFF_DEBUG|IFF_LINK2)) ==
 3155                     (IFF_DEBUG|IFF_LINK2)) == -1) {
 3156                         DPRINTF(sc, RTW_DEBUG_XMIT,
 3157                             ("%s: fail compute duration\n", __func__));
 3158                         goto post_load_err;
 3159                 }
 3160 
 3161                 d0 = &ts->ts_d0;
 3162 
 3163                 *(uint16_t*)wh->i_dur = htole16(d0->d_data_dur);
 3164 
 3165                 ctl1 = LSHIFT(d0->d_plcp_len, RTW_TXCTL1_LENGTH_MASK) |
 3166                     LSHIFT(d0->d_rts_dur, RTW_TXCTL1_RTSDUR_MASK);
 3167 
 3168                 if (d0->d_residue)
 3169                         ctl1 |= RTW_TXCTL1_LENGEXT;
 3170 
 3171                 /* TBD fragmentation */
 3172 
 3173                 ts->ts_first = tdb->tdb_next;
 3174 
 3175                 rtw_txdescs_sync(tdb, ts->ts_first, dmamap->dm_nsegs,
 3176                     BUS_DMASYNC_PREWRITE);
 3177 
 3178                 KASSERT(ts->ts_first < tdb->tdb_ndesc);
 3179 
 3180 #if NBPFILTER > 0
 3181                 if (ic->ic_rawbpf != NULL)
 3182                         bpf_mtap((caddr_t)ic->ic_rawbpf, m0);
 3183 
 3184                 if (sc->sc_radiobpf != NULL) {
 3185                         struct rtw_tx_radiotap_header *rt = &sc->sc_txtap;
 3186 
 3187                         rt->rt_flags = 0;
 3188                         rt->rt_rate = rate;
 3189                         rt->rt_chan_freq =
 3190                             htole16(ic->ic_bss->ni_chan->ic_freq);
 3191                         rt->rt_chan_flags =
 3192                             htole16(ic->ic_bss->ni_chan->ic_flags);
 3193 
 3194                         bpf_mtap2(sc->sc_radiobpf, (caddr_t)rt,
 3195                             sizeof(sc->sc_txtapu), m0);
 3196                 }
 3197 #endif /* NPBFILTER > 0 */
 3198 
 3199                 for (i = 0, lastdesc = desc = ts->ts_first;
 3200                      i < dmamap->dm_nsegs;
 3201                      i++, desc = RTW_NEXT_IDX(tdb, desc)) {
 3202                         if (dmamap->dm_segs[i].ds_len > RTW_TXLEN_LENGTH_MASK) {
 3203                                 DPRINTF(sc, RTW_DEBUG_XMIT_DESC,
 3204                                     ("%s: seg too long\n", __func__));
 3205                                 goto post_load_err;
 3206                         }
 3207                         td = &tdb->tdb_desc[desc];
 3208                         td->td_ctl0 = htole32(ctl0);
 3209                         if (i != 0)
 3210                                 td->td_ctl0 |= htole32(RTW_TXCTL0_OWN);
 3211                         td->td_ctl1 = htole32(ctl1);
 3212                         td->td_buf = htole32(dmamap->dm_segs[i].ds_addr);
 3213                         td->td_len = htole32(dmamap->dm_segs[i].ds_len);
 3214                         lastdesc = desc;
 3215 #ifdef RTW_DEBUG
 3216                         rtw_print_txdesc(sc, "load", ts, tdb, desc);
 3217 #endif /* RTW_DEBUG */
 3218                 }
 3219 
 3220                 KASSERT(desc < tdb->tdb_ndesc);
 3221 
 3222                 ts->ts_ni = ni;
 3223                 ts->ts_mbuf = m0;
 3224                 ts->ts_last = lastdesc;
 3225                 tdb->tdb_desc[ts->ts_last].td_ctl0 |= htole32(RTW_TXCTL0_LS);
 3226                 tdb->tdb_desc[ts->ts_first].td_ctl0 |=
 3227                    htole32(RTW_TXCTL0_FS);
 3228 
 3229 #ifdef RTW_DEBUG
 3230                 rtw_print_txdesc(sc, "FS on", ts, tdb, ts->ts_first);
 3231                 rtw_print_txdesc(sc, "LS on", ts, tdb, ts->ts_last);
 3232 #endif /* RTW_DEBUG */
 3233 
 3234                 tdb->tdb_nfree -= dmamap->dm_nsegs;
 3235                 tdb->tdb_next = desc;
 3236 
 3237                 rtw_txdescs_sync(tdb, ts->ts_first, dmamap->dm_nsegs,
 3238                     BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
 3239 
 3240                 tdb->tdb_desc[ts->ts_first].td_ctl0 |=
 3241                     htole32(RTW_TXCTL0_OWN);
 3242 
 3243 #ifdef RTW_DEBUG
 3244                 rtw_print_txdesc(sc, "OWN on", ts, tdb, ts->ts_first);
 3245 #endif /* RTW_DEBUG */
 3246 
 3247                 rtw_txdescs_sync(tdb, ts->ts_first, 1,
 3248                     BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
 3249 
 3250                 SIMPLEQ_REMOVE_HEAD(&tsb->tsb_freeq, ts_q);
 3251                 SIMPLEQ_INSERT_TAIL(&tsb->tsb_dirtyq, ts, ts_q);
 3252 
 3253                 if (tsb != &sc->sc_txsoft_blk[RTW_TXPRIBCN]) {
 3254                         sc->sc_led_state.ls_event |= RTW_LED_S_TX;
 3255                         tsb->tsb_tx_timer = 5;
 3256                         ifp->if_timer = 1;
 3257                 }
 3258                 tppoll = RTW_READ8(&sc->sc_regs, RTW_TPPOLL);
 3259                 tppoll &= ~RTW_TPPOLL_SALL;
 3260                 tppoll |= tsb->tsb_poll & RTW_TPPOLL_ALL;
 3261                 RTW_WRITE8(&sc->sc_regs, RTW_TPPOLL, tppoll);
 3262                 RTW_SYNC(&sc->sc_regs, RTW_TPPOLL, RTW_TPPOLL);
 3263         }
 3264 out:
 3265         DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: leave\n", __func__));
 3266         return;
 3267 post_load_err:
 3268         bus_dmamap_unload(sc->sc_dmat, dmamap);
 3269         m_freem(m0);
 3270 post_dequeue_err:
 3271         ieee80211_release_node(&sc->sc_ic, ni);
 3272         return;
 3273 }
 3274 
 3275 static void
 3276 rtw_watchdog(struct ifnet *ifp)
 3277 {
 3278         int pri;
 3279         struct rtw_softc *sc;
 3280         struct rtw_txsoft_blk *tsb;
 3281 
 3282         sc = ifp->if_softc;
 3283 
 3284         ifp->if_timer = 0;
 3285 
 3286         if ((sc->sc_flags & RTW_F_ENABLED) == 0)
 3287                 return;
 3288 
 3289         for (pri = 0; pri < RTW_NTXPRI; pri++) {
 3290                 tsb = &sc->sc_txsoft_blk[pri];
 3291 
 3292                 if (tsb->tsb_tx_timer == 0)
 3293                         continue;
 3294 
 3295                 if (--tsb->tsb_tx_timer == 0) {
 3296                         if (SIMPLEQ_EMPTY(&tsb->tsb_dirtyq))
 3297                                 continue;
 3298                         printf("%s: transmit timeout, priority %d\n",
 3299                             ifp->if_xname, pri);
 3300                         ifp->if_oerrors++;
 3301                         /* Stop Tx DMA, disable transmitter, clear
 3302                          * Tx rings, and restart.
 3303                          *
 3304                          * TBD Stop/restart just the broken ring?
 3305                          */
 3306                         RTW_WRITE8(&sc->sc_regs, RTW_TPPOLL, RTW_TPPOLL_SALL);
 3307                         RTW_SYNC(&sc->sc_regs, RTW_TPPOLL, RTW_TPPOLL);
 3308                         rtw_io_enable(&sc->sc_regs, RTW_CR_TE, 0);
 3309                         rtw_txdescs_reset(sc);
 3310                         rtw_io_enable(&sc->sc_regs, RTW_CR_TE, 1);
 3311                         sc->sc_if.if_flags &= ~IFF_OACTIVE;
 3312                         rtw_start(ifp);
 3313                 } else
 3314                         ifp->if_timer = 1;
 3315         }
 3316         ieee80211_watchdog(ifp);
 3317         return;
 3318 }
 3319 
 3320 static void
 3321 rtw_next_scan(void *arg)
 3322 {
 3323         struct ieee80211com *ic = arg;
 3324         int s;
 3325 
 3326         /* don't call rtw_start w/o network interrupts blocked */
 3327         s = splnet();
 3328         if (ic->ic_state == IEEE80211_S_SCAN)
 3329                 ieee80211_next_scan(ic);
 3330         splx(s);
 3331 }
 3332 
 3333 static void
 3334 rtw_join_bss(struct rtw_softc *sc, uint8_t *bssid, uint16_t intval0)
 3335 {
 3336         uint16_t bcnitv, intval;
 3337         int i;
 3338         struct rtw_regs *regs = &sc->sc_regs;
 3339 
 3340         for (i = 0; i < IEEE80211_ADDR_LEN; i++)
 3341                 RTW_WRITE8(regs, RTW_BSSID + i, bssid[i]);
 3342 
 3343         RTW_SYNC(regs, RTW_BSSID16, RTW_BSSID32);
 3344 
 3345         rtw_set_access(regs, RTW_ACCESS_CONFIG);
 3346 
 3347         intval = MIN(intval0, PRESHIFT(RTW_BCNITV_BCNITV_MASK));
 3348 
 3349         bcnitv = RTW_READ16(regs, RTW_BCNITV) & ~RTW_BCNITV_BCNITV_MASK;
 3350         bcnitv |= LSHIFT(intval, RTW_BCNITV_BCNITV_MASK);
 3351         RTW_WRITE16(regs, RTW_BCNITV, bcnitv);
 3352         /* magic from Linux */
 3353         RTW_WRITE16(regs, RTW_ATIMWND, LSHIFT(1, RTW_ATIMWND_ATIMWND));
 3354         RTW_WRITE16(regs, RTW_ATIMTRITV, LSHIFT(2, RTW_ATIMTRITV_ATIMTRITV));
 3355 
 3356         rtw_set_access(regs, RTW_ACCESS_NONE);
 3357 
 3358         /* TBD WEP */
 3359         RTW_WRITE8(regs, RTW_SCR, 0);
 3360 
 3361         rtw_io_enable(regs, RTW_CR_RE | RTW_CR_TE, 1);
 3362 }
 3363 
 3364 /* Synchronize the hardware state with the software state. */
 3365 static int
 3366 rtw_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
 3367 {
 3368         struct ifnet *ifp = &ic->ic_if;
 3369         struct rtw_softc *sc = ifp->if_softc;
 3370         struct mbuf *m;
 3371         enum ieee80211_state ostate;
 3372         int error;
 3373 
 3374         ostate = ic->ic_state;
 3375 
 3376         rtw_led_newstate(sc, nstate);
 3377 
 3378         if (nstate == IEEE80211_S_INIT) {
 3379                 callout_stop(&sc->sc_scan_ch);
 3380                 sc->sc_cur_chan = IEEE80211_CHAN_ANY;
 3381                 return (*sc->sc_mtbl.mt_newstate)(ic, nstate, arg);
 3382         }
 3383 
 3384         if (ostate == IEEE80211_S_INIT && nstate != IEEE80211_S_INIT)
 3385                 rtw_pwrstate(sc, RTW_ON);
 3386 
 3387         if ((error = rtw_tune(sc)) != 0)
 3388                 return error;
 3389 
 3390         switch (nstate) {
 3391         case IEEE80211_S_INIT:
 3392                 panic("%s: unexpected state IEEE80211_S_INIT\n", __func__);
 3393                 break;
 3394         case IEEE80211_S_SCAN:
 3395                 if (ostate != IEEE80211_S_SCAN) {
 3396                         (void)memset(ic->ic_bss->ni_bssid, 0,
 3397                             IEEE80211_ADDR_LEN);
 3398                         rtw_set_nettype(sc, IEEE80211_M_MONITOR);
 3399                 }
 3400 
 3401                 callout_reset(&sc->sc_scan_ch, rtw_dwelltime * hz / 1000,
 3402                     rtw_next_scan, ic);
 3403 
 3404                 break;
 3405         case IEEE80211_S_RUN:
 3406                 switch (ic->ic_opmode) {
 3407                 case IEEE80211_M_HOSTAP:
 3408                 case IEEE80211_M_IBSS:
 3409                         rtw_set_nettype(sc, IEEE80211_M_MONITOR);
 3410                         m = rtw_beacon_alloc(sc, ic->ic_bss);
 3411                         if (m == NULL) {
 3412                                 printf("%s: could not allocate beacon\n",
 3413                                     sc->sc_dev.dv_xname);
 3414                         } else
 3415                                 IF_ENQUEUE(&sc->sc_beaconq, m);
 3416                         /*FALLTHROUGH*/
 3417                 case IEEE80211_M_AHDEMO:
 3418                 case IEEE80211_M_STA:
 3419                         rtw_join_bss(sc, ic->ic_bss->ni_bssid,
 3420                             ic->ic_bss->ni_intval);
 3421                         break;
 3422                 case IEEE80211_M_MONITOR:
 3423                         break;
 3424                 }
 3425                 rtw_set_nettype(sc, ic->ic_opmode);
 3426                 break;
 3427         case IEEE80211_S_ASSOC:
 3428         case IEEE80211_S_AUTH:
 3429                 break;
 3430         }
 3431 
 3432         if (nstate != IEEE80211_S_SCAN)
 3433                 callout_stop(&sc->sc_scan_ch);
 3434 
 3435         /* Start beacon transmission. */
 3436         if (nstate == IEEE80211_S_RUN &&
 3437             (ic->ic_opmode == IEEE80211_M_HOSTAP ||
 3438              ic->ic_opmode == IEEE80211_M_IBSS))
 3439                 rtw_start(&sc->sc_if);
 3440 
 3441         return (*sc->sc_mtbl.mt_newstate)(ic, nstate, arg);
 3442 }
 3443 
 3444 /* Extend a 32-bit TSF timestamp to a 64-bit timestamp. */
 3445 static uint64_t
 3446 rtw_tsf_extend(struct rtw_regs *regs, uint32_t rstamp)
 3447 {
 3448         uint32_t tsftl, tsfth;
 3449 
 3450         tsfth = RTW_READ(regs, RTW_TSFTRH);
 3451         tsftl = RTW_READ(regs, RTW_TSFTRL);
 3452         if (tsftl < rstamp)     /* Compensate for rollover. */
 3453                 tsfth--;
 3454         return ((uint64_t)tsfth << 32) | rstamp;
 3455 }
 3456 
 3457 static void
 3458 rtw_ibss_merge(struct rtw_softc *sc, struct ieee80211_node *ni, uint32_t rstamp)
 3459 {
 3460         uint8_t tppoll;
 3461         struct ieee80211com *ic = &sc->sc_ic;
 3462 
 3463         if (le64toh(ni->ni_tsf) >= rtw_tsf_extend(&sc->sc_regs, rstamp) &&
 3464             ieee80211_ibss_merge(ic, ni) == ENETRESET) {
 3465                 /* Stop beacon queue.  Kick state machine to synchronize
 3466                  * with the new IBSS.
 3467                  */
 3468                 tppoll = RTW_READ8(&sc->sc_regs, RTW_TPPOLL);
 3469                 tppoll |= RTW_TPPOLL_SBQ;
 3470                 RTW_WRITE8(&sc->sc_regs, RTW_TPPOLL, tppoll);
 3471                 (void)ieee80211_new_state(&sc->sc_ic, IEEE80211_S_RUN, -1);
 3472         }
 3473         return;
 3474 }
 3475 
 3476 static void
 3477 rtw_recv_mgmt(struct ieee80211com *ic, struct mbuf *m,
 3478     struct ieee80211_node *ni, int subtype, int rssi, uint32_t rstamp)
 3479 {
 3480         struct rtw_softc *sc = (struct rtw_softc*)ic->ic_softc;
 3481 
 3482         (*sc->sc_mtbl.mt_recv_mgmt)(ic, m, ni, subtype, rssi, rstamp);
 3483 
 3484         switch (subtype) {
 3485         case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
 3486         case IEEE80211_FC0_SUBTYPE_BEACON:
 3487                 if (ic->ic_opmode != IEEE80211_M_IBSS ||
 3488                     ic->ic_state != IEEE80211_S_RUN)
 3489                         return;
 3490                 rtw_ibss_merge(sc, ni, rstamp);
 3491                 break;
 3492         default:
 3493                 break;
 3494         }
 3495         return;
 3496 }
 3497 
 3498 static struct ieee80211_node *
 3499 rtw_node_alloc(struct ieee80211com *ic)
 3500 {
 3501         struct rtw_softc *sc = (struct rtw_softc *)ic->ic_if.if_softc;
 3502         struct ieee80211_node *ni = (*sc->sc_mtbl.mt_node_alloc)(ic);
 3503 
 3504         DPRINTF(sc, RTW_DEBUG_NODE,
 3505             ("%s: alloc node %p\n", sc->sc_dev.dv_xname, ni));
 3506         return ni;
 3507 }
 3508 
 3509 static void
 3510 rtw_node_free(struct ieee80211com *ic, struct ieee80211_node *ni)
 3511 {
 3512         struct rtw_softc *sc = (struct rtw_softc *)ic->ic_if.if_softc;
 3513 
 3514         DPRINTF(sc, RTW_DEBUG_NODE,
 3515             ("%s: freeing node %p %s\n", sc->sc_dev.dv_xname, ni,
 3516             ether_sprintf(ni->ni_bssid)));
 3517         (*sc->sc_mtbl.mt_node_free)(ic, ni);
 3518 }
 3519 
 3520 static int
 3521 rtw_media_change(struct ifnet *ifp)
 3522 {
 3523         int error;
 3524 
 3525         error = ieee80211_media_change(ifp);
 3526         if (error == ENETRESET) {
 3527                 if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) ==
 3528                     (IFF_RUNNING|IFF_UP))
 3529                         rtw_init(ifp);          /* XXX lose error */
 3530                 error = 0;
 3531         }
 3532         return error;
 3533 }
 3534 
 3535 static void
 3536 rtw_media_status(struct ifnet *ifp, struct ifmediareq *imr)
 3537 {
 3538         struct rtw_softc *sc = ifp->if_softc;
 3539 
 3540         if ((sc->sc_flags & RTW_F_ENABLED) == 0) {
 3541                 imr->ifm_active = IFM_IEEE80211 | IFM_NONE;
 3542                 imr->ifm_status = 0;
 3543                 return;
 3544         }
 3545         ieee80211_media_status(ifp, imr);
 3546 }
 3547 
 3548 void
 3549 rtw_power(int why, void *arg)
 3550 {
 3551         struct rtw_softc *sc = arg;
 3552         struct ifnet *ifp = &sc->sc_ic.ic_if;
 3553         int s;
 3554 
 3555         DPRINTF(sc, RTW_DEBUG_PWR,
 3556             ("%s: rtw_power(%d,)\n", sc->sc_dev.dv_xname, why));
 3557 
 3558         s = splnet();
 3559         switch (why) {
 3560         case PWR_STANDBY:
 3561                 /* XXX do nothing. */
 3562                 break;
 3563         case PWR_SUSPEND:
 3564                 rtw_stop(ifp, 0);
 3565                 if (sc->sc_power != NULL)
 3566                         (*sc->sc_power)(sc, why);
 3567                 break;
 3568         case PWR_RESUME:
 3569                 if (ifp->if_flags & IFF_UP) {
 3570                         if (sc->sc_power != NULL)
 3571                                 (*sc->sc_power)(sc, why);
 3572                         rtw_init(ifp);
 3573                 }
 3574                 break;
 3575         case PWR_SOFTSUSPEND:
 3576         case PWR_SOFTSTANDBY:
 3577         case PWR_SOFTRESUME:
 3578                 break;
 3579         }
 3580         splx(s);
 3581 }
 3582 
 3583 /* rtw_shutdown: make sure the interface is stopped at reboot time. */
 3584 void
 3585 rtw_shutdown(void *arg)
 3586 {
 3587         struct rtw_softc *sc = arg;
 3588 
 3589         rtw_stop(&sc->sc_ic.ic_if, 1);
 3590 }
 3591 
 3592 static __inline void
 3593 rtw_setifprops(struct ifnet *ifp, const char *dvname, void *softc)
 3594 {
 3595         (void)memcpy(ifp->if_xname, dvname, IFNAMSIZ);
 3596         ifp->if_softc = softc;
 3597         ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST |
 3598             IFF_NOTRAILERS;
 3599         ifp->if_ioctl = rtw_ioctl;
 3600         ifp->if_start = rtw_start;
 3601         ifp->if_watchdog = rtw_watchdog;
 3602         ifp->if_init = rtw_init;
 3603         ifp->if_stop = rtw_stop;
 3604 }
 3605 
 3606 static __inline void
 3607 rtw_set80211props(struct ieee80211com *ic)
 3608 {
 3609         int nrate;
 3610         ic->ic_phytype = IEEE80211_T_DS;
 3611         ic->ic_opmode = IEEE80211_M_STA;
 3612         ic->ic_caps = IEEE80211_C_PMGT | IEEE80211_C_IBSS |
 3613             IEEE80211_C_HOSTAP | IEEE80211_C_MONITOR | IEEE80211_C_WEP;
 3614 
 3615         nrate = 0;
 3616         ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] =
 3617             IEEE80211_RATE_BASIC | 2;
 3618         ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] =
 3619             IEEE80211_RATE_BASIC | 4;
 3620         ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] = 11;
 3621         ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] = 22;
 3622         ic->ic_sup_rates[IEEE80211_MODE_11B].rs_nrates = nrate;
 3623 }
 3624 
 3625 static __inline void
 3626 rtw_set80211methods(struct rtw_mtbl *mtbl, struct ieee80211com *ic)
 3627 {
 3628         mtbl->mt_newstate = ic->ic_newstate;
 3629         ic->ic_newstate = rtw_newstate;
 3630 
 3631         mtbl->mt_recv_mgmt = ic->ic_recv_mgmt;
 3632         ic->ic_recv_mgmt = rtw_recv_mgmt;
 3633 
 3634         mtbl->mt_node_free = ic->ic_node_free;
 3635         ic->ic_node_free = rtw_node_free;
 3636 
 3637         mtbl->mt_node_alloc = ic->ic_node_alloc;
 3638         ic->ic_node_alloc = rtw_node_alloc;
 3639 }
 3640 
 3641 static __inline void
 3642 rtw_establish_hooks(struct rtw_hooks *hooks, const char *dvname,
 3643     void *arg)
 3644 {
 3645         /*
 3646          * Make sure the interface is shutdown during reboot.
 3647          */
 3648         hooks->rh_shutdown = shutdownhook_establish(rtw_shutdown, arg);
 3649         if (hooks->rh_shutdown == NULL)
 3650                 printf("%s: WARNING: unable to establish shutdown hook\n",
 3651                     dvname);
 3652 
 3653         /*
 3654          * Add a suspend hook to make sure we come back up after a
 3655          * resume.
 3656          */
 3657         hooks->rh_power = powerhook_establish(rtw_power, arg);
 3658         if (hooks->rh_power == NULL)
 3659                 printf("%s: WARNING: unable to establish power hook\n",
 3660                     dvname);
 3661 }
 3662 
 3663 static __inline void
 3664 rtw_disestablish_hooks(struct rtw_hooks *hooks, const char *dvname,
 3665     void *arg)
 3666 {
 3667         if (hooks->rh_shutdown != NULL)
 3668                 shutdownhook_disestablish(hooks->rh_shutdown);
 3669 
 3670         if (hooks->rh_power != NULL)
 3671                 powerhook_disestablish(hooks->rh_power);
 3672 }
 3673 
 3674 static __inline void
 3675 rtw_init_radiotap(struct rtw_softc *sc)
 3676 {
 3677         memset(&sc->sc_rxtapu, 0, sizeof(sc->sc_rxtapu));
 3678         sc->sc_rxtap.rr_ihdr.it_len = htole16(sizeof(sc->sc_rxtapu));
 3679         sc->sc_rxtap.rr_ihdr.it_present = htole32(RTW_RX_RADIOTAP_PRESENT);
 3680 
 3681         memset(&sc->sc_txtapu, 0, sizeof(sc->sc_txtapu));
 3682         sc->sc_txtap.rt_ihdr.it_len = htole16(sizeof(sc->sc_txtapu));
 3683         sc->sc_txtap.rt_ihdr.it_present = htole32(RTW_TX_RADIOTAP_PRESENT);
 3684 }
 3685 
 3686 static int
 3687 rtw_txsoft_blk_setup(struct rtw_txsoft_blk *tsb, u_int qlen)
 3688 {
 3689         SIMPLEQ_INIT(&tsb->tsb_dirtyq);
 3690         SIMPLEQ_INIT(&tsb->tsb_freeq);
 3691         tsb->tsb_ndesc = qlen;
 3692         tsb->tsb_desc = malloc(qlen * sizeof(*tsb->tsb_desc), M_DEVBUF,
 3693             M_NOWAIT);
 3694         if (tsb->tsb_desc == NULL)
 3695                 return ENOMEM;
 3696         return 0;
 3697 }
 3698 
 3699 static void
 3700 rtw_txsoft_blk_cleanup_all(struct rtw_softc *sc)
 3701 {
 3702         int pri;
 3703         struct rtw_txsoft_blk *tsb;
 3704 
 3705         for (pri = 0; pri < RTW_NTXPRI; pri++) {
 3706                 tsb = &sc->sc_txsoft_blk[pri];
 3707                 free(tsb->tsb_desc, M_DEVBUF);
 3708                 tsb->tsb_desc = NULL;
 3709         }
 3710 }
 3711 
 3712 static int
 3713 rtw_txsoft_blk_setup_all(struct rtw_softc *sc)
 3714 {
 3715         int pri, rc = 0;
 3716         int qlen[RTW_NTXPRI] =
 3717              {RTW_TXQLENLO, RTW_TXQLENMD, RTW_TXQLENHI, RTW_TXQLENBCN};
 3718         struct rtw_txsoft_blk *tsbs;
 3719 
 3720         tsbs = sc->sc_txsoft_blk;
 3721 
 3722         for (pri = 0; pri < RTW_NTXPRI; pri++) {
 3723                 rc = rtw_txsoft_blk_setup(&tsbs[pri], qlen[pri]);
 3724                 if (rc != 0)
 3725                         break;
 3726         }
 3727         tsbs[RTW_TXPRILO].tsb_poll = RTW_TPPOLL_LPQ | RTW_TPPOLL_SLPQ;
 3728         tsbs[RTW_TXPRIMD].tsb_poll = RTW_TPPOLL_NPQ | RTW_TPPOLL_SNPQ;
 3729         tsbs[RTW_TXPRIHI].tsb_poll = RTW_TPPOLL_HPQ | RTW_TPPOLL_SHPQ;
 3730         tsbs[RTW_TXPRIBCN].tsb_poll = RTW_TPPOLL_BQ | RTW_TPPOLL_SBQ;
 3731         return rc;
 3732 }
 3733 
 3734 static void
 3735 rtw_txdesc_blk_setup(struct rtw_txdesc_blk *tdb, struct rtw_txdesc *desc,
 3736     u_int ndesc, bus_addr_t ofs, bus_addr_t physbase)
 3737 {
 3738         tdb->tdb_ndesc = ndesc;
 3739         tdb->tdb_desc = desc;
 3740         tdb->tdb_physbase = physbase;
 3741         tdb->tdb_ofs = ofs;
 3742 
 3743         (void)memset(tdb->tdb_desc, 0,
 3744             sizeof(tdb->tdb_desc[0]) * tdb->tdb_ndesc);
 3745 
 3746         rtw_txdesc_blk_reset(tdb);
 3747 }
 3748 
 3749 static void
 3750 rtw_txdesc_blk_setup_all(struct rtw_softc *sc)
 3751 {
 3752         rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRILO],
 3753             &sc->sc_descs->hd_txlo[0], RTW_NTXDESCLO,
 3754             RTW_RING_OFFSET(hd_txlo), RTW_RING_BASE(sc, hd_txlo));
 3755 
 3756         rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIMD],
 3757             &sc->sc_descs->hd_txmd[0], RTW_NTXDESCMD,
 3758             RTW_RING_OFFSET(hd_txmd), RTW_RING_BASE(sc, hd_txmd));
 3759 
 3760         rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIHI],
 3761             &sc->sc_descs->hd_txhi[0], RTW_NTXDESCHI,
 3762             RTW_RING_OFFSET(hd_txhi), RTW_RING_BASE(sc, hd_txhi));
 3763 
 3764         rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIBCN],
 3765             &sc->sc_descs->hd_bcn[0], RTW_NTXDESCBCN,
 3766             RTW_RING_OFFSET(hd_bcn), RTW_RING_BASE(sc, hd_bcn));
 3767 }
 3768 
 3769 static struct rtw_rf *
 3770 rtw_rf_attach(struct rtw_softc *sc, enum rtw_rfchipid rfchipid, int digphy)
 3771 {
 3772         rtw_rf_write_t rf_write;
 3773         struct rtw_rf *rf;
 3774 
 3775         switch (rfchipid) {
 3776         default:
 3777                 rf_write = rtw_rf_hostwrite;
 3778                 break;
 3779         case RTW_RFCHIPID_INTERSIL:
 3780         case RTW_RFCHIPID_PHILIPS:
 3781         case RTW_RFCHIPID_GCT:  /* XXX a guess */
 3782         case RTW_RFCHIPID_RFMD:
 3783                 rf_write = (rtw_host_rfio) ? rtw_rf_hostwrite : rtw_rf_macwrite;
 3784                 break;
 3785         }
 3786 
 3787         switch (rfchipid) {
 3788         case RTW_RFCHIPID_MAXIM:
 3789                 rf = rtw_max2820_create(&sc->sc_regs, rf_write, 0);
 3790                 sc->sc_pwrstate_cb = rtw_maxim_pwrstate;
 3791                 break;
 3792         case RTW_RFCHIPID_PHILIPS:
 3793                 rf = rtw_sa2400_create(&sc->sc_regs, rf_write, digphy);
 3794                 sc->sc_pwrstate_cb = rtw_philips_pwrstate;
 3795                 break;
 3796         case RTW_RFCHIPID_RFMD:
 3797                 /* XXX RFMD has no RF constructor */
 3798                 sc->sc_pwrstate_cb = rtw_rfmd_pwrstate;
 3799                 /*FALLTHROUGH*/
 3800         default:
 3801                 return NULL;
 3802         }
 3803         rf->rf_continuous_tx_cb =
 3804             (rtw_continuous_tx_cb_t)rtw_continuous_tx_enable;
 3805         rf->rf_continuous_tx_arg = (void *)sc;
 3806         return rf;
 3807 }
 3808 
 3809 /* Revision C and later use a different PHY delay setting than
 3810  * revisions A and B.
 3811  */
 3812 static uint8_t
 3813 rtw_check_phydelay(struct rtw_regs *regs, uint32_t rcr0)
 3814 {
 3815 #define REVAB (RTW_RCR_MXDMA_UNLIMITED | RTW_RCR_AICV)
 3816 #define REVC (REVAB | RTW_RCR_RXFTH_WHOLE)
 3817 
 3818         uint8_t phydelay = LSHIFT(0x6, RTW_PHYDELAY_PHYDELAY);
 3819 
 3820         RTW_WRITE(regs, RTW_RCR, REVAB);
 3821         RTW_WBW(regs, RTW_RCR, RTW_RCR);
 3822         RTW_WRITE(regs, RTW_RCR, REVC);
 3823 
 3824         RTW_WBR(regs, RTW_RCR, RTW_RCR);
 3825         if ((RTW_READ(regs, RTW_RCR) & REVC) == REVC)
 3826                 phydelay |= RTW_PHYDELAY_REVC_MAGIC;
 3827 
 3828         RTW_WRITE(regs, RTW_RCR, rcr0); /* restore RCR */
 3829         RTW_SYNC(regs, RTW_RCR, RTW_RCR);
 3830 
 3831         return phydelay;
 3832 #undef REVC
 3833 }
 3834 
 3835 void
 3836 rtw_attach(struct rtw_softc *sc)
 3837 {
 3838         struct rtw_txsoft_blk *tsb;
 3839         int pri, rc;
 3840 
 3841         NEXT_ATTACH_STATE(sc, DETACHED);
 3842 
 3843         switch (RTW_READ(&sc->sc_regs, RTW_TCR) & RTW_TCR_HWVERID_MASK) {
 3844         case RTW_TCR_HWVERID_F:
 3845                 sc->sc_hwverid = 'F';
 3846                 break;
 3847         case RTW_TCR_HWVERID_D:
 3848                 sc->sc_hwverid = 'D';
 3849                 break;
 3850         default:
 3851                 sc->sc_hwverid = '?';
 3852                 break;
 3853         }
 3854         printf("%s: hardware version %c\n", sc->sc_dev.dv_xname,
 3855             sc->sc_hwverid);
 3856 
 3857         rc = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct rtw_descs),
 3858             RTW_DESC_ALIGNMENT, 0, &sc->sc_desc_segs, 1, &sc->sc_desc_nsegs,
 3859             0);
 3860 
 3861         if (rc != 0) {
 3862                 printf("%s: could not allocate hw descriptors, error %d\n",
 3863                      sc->sc_dev.dv_xname, rc);
 3864                 goto err;
 3865         }
 3866 
 3867         NEXT_ATTACH_STATE(sc, FINISH_DESC_ALLOC);
 3868 
 3869         rc = bus_dmamem_map(sc->sc_dmat, &sc->sc_desc_segs,
 3870             sc->sc_desc_nsegs, sizeof(struct rtw_descs),
 3871             (caddr_t*)&sc->sc_descs, BUS_DMA_COHERENT);
 3872 
 3873         if (rc != 0) {
 3874                 printf("%s: could not map hw descriptors, error %d\n",
 3875                     sc->sc_dev.dv_xname, rc);
 3876                 goto err;
 3877         }
 3878         NEXT_ATTACH_STATE(sc, FINISH_DESC_MAP);
 3879 
 3880         rc = bus_dmamap_create(sc->sc_dmat, sizeof(struct rtw_descs), 1,
 3881             sizeof(struct rtw_descs), 0, 0, &sc->sc_desc_dmamap);
 3882 
 3883         if (rc != 0) {
 3884                 printf("%s: could not create DMA map for hw descriptors, "
 3885                     "error %d\n", sc->sc_dev.dv_xname, rc);
 3886                 goto err;
 3887         }
 3888         NEXT_ATTACH_STATE(sc, FINISH_DESCMAP_CREATE);
 3889 
 3890         sc->sc_rxdesc_blk.rdb_dmat = sc->sc_dmat;
 3891         sc->sc_rxdesc_blk.rdb_dmamap = sc->sc_desc_dmamap;
 3892 
 3893         for (pri = 0; pri < RTW_NTXPRI; pri++) {
 3894                 sc->sc_txdesc_blk[pri].tdb_dmat = sc->sc_dmat;
 3895                 sc->sc_txdesc_blk[pri].tdb_dmamap = sc->sc_desc_dmamap;
 3896         }
 3897 
 3898         rc = bus_dmamap_load(sc->sc_dmat, sc->sc_desc_dmamap, sc->sc_descs,
 3899             sizeof(struct rtw_descs), NULL, 0);
 3900 
 3901         if (rc != 0) {
 3902                 printf("%s: could not load DMA map for hw descriptors, "
 3903                     "error %d\n", sc->sc_dev.dv_xname, rc);
 3904                 goto err;
 3905         }
 3906         NEXT_ATTACH_STATE(sc, FINISH_DESCMAP_LOAD);
 3907 
 3908         if (rtw_txsoft_blk_setup_all(sc) != 0)
 3909                 goto err;
 3910         NEXT_ATTACH_STATE(sc, FINISH_TXCTLBLK_SETUP);
 3911 
 3912         rtw_txdesc_blk_setup_all(sc);
 3913 
 3914         NEXT_ATTACH_STATE(sc, FINISH_TXDESCBLK_SETUP);
 3915 
 3916         sc->sc_rxdesc_blk.rdb_desc = &sc->sc_descs->hd_rx[0];
 3917 
 3918         for (pri = 0; pri < RTW_NTXPRI; pri++) {
 3919                 tsb = &sc->sc_txsoft_blk[pri];
 3920 
 3921                 if ((rc = rtw_txdesc_dmamaps_create(sc->sc_dmat,
 3922                     &tsb->tsb_desc[0], tsb->tsb_ndesc)) != 0) {
 3923                         printf("%s: could not load DMA map for "
 3924                             "hw tx descriptors, error %d\n",
 3925                             sc->sc_dev.dv_xname, rc);
 3926                         goto err;
 3927                 }
 3928         }
 3929 
 3930         NEXT_ATTACH_STATE(sc, FINISH_TXMAPS_CREATE);
 3931         if ((rc = rtw_rxdesc_dmamaps_create(sc->sc_dmat, &sc->sc_rxsoft[0],
 3932                                             RTW_RXQLEN)) != 0) {
 3933                 printf("%s: could not load DMA map for hw rx descriptors, "
 3934                     "error %d\n", sc->sc_dev.dv_xname, rc);
 3935                 goto err;
 3936         }
 3937         NEXT_ATTACH_STATE(sc, FINISH_RXMAPS_CREATE);
 3938 
 3939         /* Reset the chip to a known state. */
 3940         if (rtw_reset(sc) != 0)
 3941                 goto err;
 3942         NEXT_ATTACH_STATE(sc, FINISH_RESET);
 3943 
 3944         sc->sc_rcr = RTW_READ(&sc->sc_regs, RTW_RCR);
 3945 
 3946         if ((sc->sc_rcr & RTW_RCR_9356SEL) != 0)
 3947                 sc->sc_flags |= RTW_F_9356SROM;
 3948 
 3949         if (rtw_srom_read(&sc->sc_regs, sc->sc_flags, &sc->sc_srom,
 3950             sc->sc_dev.dv_xname) != 0)
 3951                 goto err;
 3952 
 3953         NEXT_ATTACH_STATE(sc, FINISH_READ_SROM);
 3954 
 3955         if (rtw_srom_parse(&sc->sc_srom, &sc->sc_flags, &sc->sc_csthr,
 3956             &sc->sc_rfchipid, &sc->sc_rcr, &sc->sc_locale,
 3957             sc->sc_dev.dv_xname) != 0) {
 3958                 printf("%s: attach failed, malformed serial ROM\n",
 3959                     sc->sc_dev.dv_xname);
 3960                 goto err;
 3961         }
 3962 
 3963         printf("%s: %s PHY\n", sc->sc_dev.dv_xname,
 3964             ((sc->sc_flags & RTW_F_DIGPHY) != 0) ? "digital" : "analog");
 3965 
 3966         printf("%s: CS threshold %u\n", sc->sc_dev.dv_xname, sc->sc_csthr);
 3967 
 3968         NEXT_ATTACH_STATE(sc, FINISH_PARSE_SROM);
 3969 
 3970         sc->sc_rf = rtw_rf_attach(sc, sc->sc_rfchipid,
 3971             sc->sc_flags & RTW_F_DIGPHY);
 3972 
 3973         if (sc->sc_rf == NULL) {
 3974                 printf("%s: attach failed, could not attach RF\n",
 3975                     sc->sc_dev.dv_xname);
 3976                 goto err;
 3977         }
 3978 
 3979         NEXT_ATTACH_STATE(sc, FINISH_RF_ATTACH);
 3980 
 3981         sc->sc_phydelay = rtw_check_phydelay(&sc->sc_regs, sc->sc_rcr);
 3982 
 3983         RTW_DPRINTF(RTW_DEBUG_ATTACH,
 3984             ("%s: PHY delay %d\n", sc->sc_dev.dv_xname, sc->sc_phydelay));
 3985 
 3986         if (sc->sc_locale == RTW_LOCALE_UNKNOWN)
 3987                 rtw_identify_country(&sc->sc_regs, &sc->sc_locale,
 3988                     sc->sc_dev.dv_xname);
 3989 
 3990         rtw_init_channels(sc->sc_locale, &sc->sc_ic.ic_channels,
 3991             sc->sc_dev.dv_xname);
 3992 
 3993         if (rtw_identify_sta(&sc->sc_regs, &sc->sc_ic.ic_myaddr,
 3994             sc->sc_dev.dv_xname) != 0)
 3995                 goto err;
 3996         NEXT_ATTACH_STATE(sc, FINISH_ID_STA);
 3997 
 3998         rtw_setifprops(&sc->sc_if, sc->sc_dev.dv_xname, (void*)sc);
 3999 
 4000         IFQ_SET_READY(&sc->sc_if.if_snd);
 4001 
 4002         rtw_set80211props(&sc->sc_ic);
 4003 
 4004         rtw_led_attach(&sc->sc_led_state, (void *)sc);
 4005 
 4006         /*
 4007          * Call MI attach routines.
 4008          */
 4009         if_attach(&sc->sc_if);
 4010         ieee80211_ifattach(&sc->sc_if);
 4011 
 4012         rtw_set80211methods(&sc->sc_mtbl, &sc->sc_ic);
 4013 
 4014         /* possibly we should fill in our own sc_send_prresp, since
 4015          * the RTL8180 is probably sending probe responses in ad hoc
 4016          * mode.
 4017          */
 4018 
 4019         /* complete initialization */
 4020         ieee80211_media_init(&sc->sc_if, rtw_media_change, rtw_media_status);
 4021         callout_init(&sc->sc_scan_ch);
 4022 
 4023         rtw_init_radiotap(sc);
 4024 
 4025 #if NBPFILTER > 0
 4026         bpfattach2(&sc->sc_if, DLT_IEEE802_11_RADIO,
 4027             sizeof(struct ieee80211_frame) + 64, &sc->sc_radiobpf);
 4028 #endif
 4029 
 4030         rtw_establish_hooks(&sc->sc_hooks, sc->sc_dev.dv_xname, (void*)sc);
 4031 
 4032         NEXT_ATTACH_STATE(sc, FINISHED);
 4033 
 4034         return;
 4035 err:
 4036         rtw_detach(sc);
 4037         return;
 4038 }
 4039 
 4040 int
 4041 rtw_detach(struct rtw_softc *sc)
 4042 {
 4043         int pri;
 4044 
 4045         sc->sc_flags |= RTW_F_INVALID;
 4046 
 4047         switch (sc->sc_attach_state) {
 4048         case FINISHED:
 4049                 rtw_stop(&sc->sc_if, 1);
 4050 
 4051                 rtw_disestablish_hooks(&sc->sc_hooks, sc->sc_dev.dv_xname,
 4052                     (void*)sc);
 4053                 callout_stop(&sc->sc_scan_ch);
 4054                 ieee80211_ifdetach(&sc->sc_if);
 4055                 if_detach(&sc->sc_if);
 4056                 break;
 4057         case FINISH_ID_STA:
 4058         case FINISH_RF_ATTACH:
 4059                 rtw_rf_destroy(sc->sc_rf);
 4060                 sc->sc_rf = NULL;
 4061                 /*FALLTHROUGH*/
 4062         case FINISH_PARSE_SROM:
 4063         case FINISH_READ_SROM:
 4064                 rtw_srom_free(&sc->sc_srom);
 4065                 /*FALLTHROUGH*/
 4066         case FINISH_RESET:
 4067         case FINISH_RXMAPS_CREATE:
 4068                 rtw_rxdesc_dmamaps_destroy(sc->sc_dmat, &sc->sc_rxsoft[0],
 4069                     RTW_RXQLEN);
 4070                 /*FALLTHROUGH*/
 4071         case FINISH_TXMAPS_CREATE:
 4072                 for (pri = 0; pri < RTW_NTXPRI; pri++) {
 4073                         rtw_txdesc_dmamaps_destroy(sc->sc_dmat,
 4074                             sc->sc_txsoft_blk[pri].tsb_desc,
 4075                             sc->sc_txsoft_blk[pri].tsb_ndesc);
 4076                 }
 4077                 /*FALLTHROUGH*/
 4078         case FINISH_TXDESCBLK_SETUP:
 4079         case FINISH_TXCTLBLK_SETUP:
 4080                 rtw_txsoft_blk_cleanup_all(sc);
 4081                 /*FALLTHROUGH*/
 4082         case FINISH_DESCMAP_LOAD:
 4083                 bus_dmamap_unload(sc->sc_dmat, sc->sc_desc_dmamap);
 4084                 /*FALLTHROUGH*/
 4085         case FINISH_DESCMAP_CREATE:
 4086                 bus_dmamap_destroy(sc->sc_dmat, sc->sc_desc_dmamap);
 4087                 /*FALLTHROUGH*/
 4088         case FINISH_DESC_MAP:
 4089                 bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_descs,
 4090                     sizeof(struct rtw_descs));
 4091                 /*FALLTHROUGH*/
 4092         case FINISH_DESC_ALLOC:
 4093                 bus_dmamem_free(sc->sc_dmat, &sc->sc_desc_segs,
 4094                     sc->sc_desc_nsegs);
 4095                 /*FALLTHROUGH*/
 4096         case DETACHED:
 4097                 NEXT_ATTACH_STATE(sc, DETACHED);
 4098                 break;
 4099         }
 4100         return 0;
 4101 }
 4102 
 4103 int
 4104 rtw_activate(struct device *self, enum devact act)
 4105 {
 4106         struct rtw_softc *sc = (struct rtw_softc *)self;
 4107         int rc = 0, s;
 4108 
 4109         s = splnet();
 4110         switch (act) {
 4111         case DVACT_ACTIVATE:
 4112                 rc = EOPNOTSUPP;
 4113                 break;
 4114 
 4115         case DVACT_DEACTIVATE:
 4116                 if_deactivate(&sc->sc_ic.ic_if);
 4117                 break;
 4118         }
 4119         splx(s);
 4120         return rc;
 4121 }

Cache object: b3478bfda26c74e5bf4ef74c9df1611e


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.