Home | History | Annotate | Line # | Download | only in ic
rtw.c revision 1.7
      1  1.7   dyoung /* $NetBSD: rtw.c,v 1.7 2004/12/20 00:28:02 dyoung Exp $ */
      2  1.1   dyoung /*-
      3  1.1   dyoung  * Copyright (c) 2004, 2005 David Young.  All rights reserved.
      4  1.1   dyoung  *
      5  1.1   dyoung  * Programmed for NetBSD by David Young.
      6  1.1   dyoung  *
      7  1.1   dyoung  * Redistribution and use in source and binary forms, with or without
      8  1.1   dyoung  * modification, are permitted provided that the following conditions
      9  1.1   dyoung  * are met:
     10  1.1   dyoung  * 1. Redistributions of source code must retain the above copyright
     11  1.1   dyoung  *    notice, this list of conditions and the following disclaimer.
     12  1.1   dyoung  * 2. Redistributions in binary form must reproduce the above copyright
     13  1.1   dyoung  *    notice, this list of conditions and the following disclaimer in the
     14  1.1   dyoung  *    documentation and/or other materials provided with the distribution.
     15  1.1   dyoung  * 3. The name of David Young may not be used to endorse or promote
     16  1.1   dyoung  *    products derived from this software without specific prior
     17  1.1   dyoung  *    written permission.
     18  1.1   dyoung  *
     19  1.1   dyoung  * THIS SOFTWARE IS PROVIDED BY David Young ``AS IS'' AND ANY
     20  1.1   dyoung  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     21  1.1   dyoung  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
     22  1.1   dyoung  * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL David
     23  1.1   dyoung  * Young BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     24  1.1   dyoung  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
     25  1.1   dyoung  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     26  1.1   dyoung  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     27  1.1   dyoung  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     28  1.1   dyoung  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     29  1.1   dyoung  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
     30  1.1   dyoung  * OF SUCH DAMAGE.
     31  1.1   dyoung  */
     32  1.1   dyoung /*
     33  1.1   dyoung  * Device driver for the Realtek RTL8180 802.11 MAC/BBP.
     34  1.1   dyoung  */
     35  1.1   dyoung 
     36  1.1   dyoung #include <sys/cdefs.h>
     37  1.7   dyoung __KERNEL_RCSID(0, "$NetBSD: rtw.c,v 1.7 2004/12/20 00:28:02 dyoung Exp $");
     38  1.1   dyoung 
     39  1.1   dyoung #include "bpfilter.h"
     40  1.1   dyoung 
     41  1.1   dyoung #include <sys/param.h>
     42  1.4   dyoung #include <sys/sysctl.h>
     43  1.1   dyoung #include <sys/systm.h>
     44  1.1   dyoung #include <sys/callout.h>
     45  1.1   dyoung #include <sys/mbuf.h>
     46  1.1   dyoung #include <sys/malloc.h>
     47  1.1   dyoung #include <sys/kernel.h>
     48  1.1   dyoung #if 0
     49  1.1   dyoung #include <sys/socket.h>
     50  1.1   dyoung #include <sys/ioctl.h>
     51  1.1   dyoung #include <sys/errno.h>
     52  1.1   dyoung #include <sys/device.h>
     53  1.1   dyoung #endif
     54  1.1   dyoung #include <sys/time.h>
     55  1.1   dyoung #include <sys/types.h>
     56  1.1   dyoung 
     57  1.1   dyoung #include <machine/endian.h>
     58  1.1   dyoung #include <machine/bus.h>
     59  1.1   dyoung #include <machine/intr.h>	/* splnet */
     60  1.1   dyoung 
     61  1.1   dyoung #include <uvm/uvm_extern.h>
     62  1.1   dyoung 
     63  1.1   dyoung #include <net/if.h>
     64  1.1   dyoung #include <net/if_media.h>
     65  1.1   dyoung #include <net/if_ether.h>
     66  1.1   dyoung 
     67  1.1   dyoung #include <net80211/ieee80211_var.h>
     68  1.1   dyoung #include <net80211/ieee80211_compat.h>
     69  1.1   dyoung #include <net80211/ieee80211_radiotap.h>
     70  1.1   dyoung 
     71  1.1   dyoung #if NBPFILTER > 0
     72  1.1   dyoung #include <net/bpf.h>
     73  1.1   dyoung #endif
     74  1.1   dyoung 
     75  1.1   dyoung #include <dev/ic/rtwreg.h>
     76  1.1   dyoung #include <dev/ic/rtwvar.h>
     77  1.1   dyoung #include <dev/ic/rtwphyio.h>
     78  1.1   dyoung #include <dev/ic/rtwphy.h>
     79  1.1   dyoung 
     80  1.1   dyoung #include <dev/ic/smc93cx6var.h>
     81  1.1   dyoung 
     82  1.1   dyoung #define	KASSERT2(__cond, __msg)		\
     83  1.1   dyoung 	do {				\
     84  1.1   dyoung 		if (!(__cond))		\
     85  1.1   dyoung 			panic __msg ;	\
     86  1.1   dyoung 	} while (0)
     87  1.1   dyoung 
     88  1.4   dyoung int rtw_rfprog_fallback = 0;
     89  1.4   dyoung int rtw_host_rfio = 0;
     90  1.4   dyoung int rtw_flush_rfio = 1;
     91  1.4   dyoung int rtw_rfio_delay = 0;
     92  1.4   dyoung 
     93  1.1   dyoung #ifdef RTW_DEBUG
     94  1.1   dyoung int rtw_debug = 2;
     95  1.1   dyoung #endif /* RTW_DEBUG */
     96  1.1   dyoung 
     97  1.1   dyoung #define NEXT_ATTACH_STATE(sc, state) do {				\
     98  1.1   dyoung 	DPRINTF(sc, ("%s: attach state %s\n", __func__, #state));	\
     99  1.1   dyoung 	sc->sc_attach_state = state;					\
    100  1.1   dyoung } while (0)
    101  1.1   dyoung 
    102  1.1   dyoung int rtw_dwelltime = 1000;	/* milliseconds */
    103  1.1   dyoung 
    104  1.5   dyoung static void rtw_start(struct ifnet *);
    105  1.5   dyoung 
    106  1.4   dyoung static int rtw_sysctl_verify_rfio(SYSCTLFN_PROTO);
    107  1.4   dyoung static int rtw_sysctl_verify_rfio_delay(SYSCTLFN_PROTO);
    108  1.4   dyoung static int rtw_sysctl_verify_rfprog(SYSCTLFN_PROTO);
    109  1.4   dyoung #ifdef RTW_DEBUG
    110  1.4   dyoung static int rtw_sysctl_verify_debug(SYSCTLFN_PROTO);
    111  1.4   dyoung #endif /* RTW_DEBUG */
    112  1.4   dyoung 
    113  1.4   dyoung /*
    114  1.4   dyoung  * Setup sysctl(3) MIB, hw.rtw.*
    115  1.4   dyoung  *
    116  1.4   dyoung  * TBD condition CTLFLAG_PERMANENT on being an LKM or not
    117  1.4   dyoung  */
    118  1.4   dyoung SYSCTL_SETUP(sysctl_rtw, "sysctl rtw(4) subtree setup")
    119  1.4   dyoung {
    120  1.4   dyoung 	int rc;
    121  1.4   dyoung 	struct sysctlnode *cnode, *rnode;
    122  1.4   dyoung 
    123  1.4   dyoung 	if ((rc = sysctl_createv(clog, 0, NULL, &rnode,
    124  1.4   dyoung 	    CTLFLAG_PERMANENT, CTLTYPE_NODE, "hw", NULL,
    125  1.4   dyoung 	    NULL, 0, NULL, 0, CTL_HW, CTL_EOL)) != 0)
    126  1.4   dyoung 		goto err;
    127  1.4   dyoung 
    128  1.4   dyoung 	if ((rc = sysctl_createv(clog, 0, &rnode, &rnode,
    129  1.4   dyoung 	    CTLFLAG_PERMANENT, CTLTYPE_NODE, "rtw",
    130  1.4   dyoung 	    "Realtek RTL818x 802.11 controls",
    131  1.4   dyoung 	    NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0)
    132  1.4   dyoung 		goto err;
    133  1.4   dyoung 
    134  1.4   dyoung #ifdef RTW_DEBUG
    135  1.4   dyoung 	/* control debugging printfs */
    136  1.4   dyoung 	if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
    137  1.4   dyoung 	    CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
    138  1.4   dyoung 	    "debug", SYSCTL_DESCR("Enable RTL818x debugging output"),
    139  1.4   dyoung 	    rtw_sysctl_verify_debug, 0, &rtw_debug, 0,
    140  1.4   dyoung 	    CTL_CREATE, CTL_EOL)) != 0)
    141  1.4   dyoung 		goto err;
    142  1.4   dyoung #endif /* RTW_DEBUG */
    143  1.4   dyoung 	/* set fallback RF programming method */
    144  1.4   dyoung 	if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
    145  1.4   dyoung 	    CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
    146  1.4   dyoung 	    "rfprog_fallback",
    147  1.4   dyoung 	    SYSCTL_DESCR("Set fallback RF programming method"),
    148  1.4   dyoung 	    rtw_sysctl_verify_rfprog, 0, &rtw_rfprog_fallback, 0,
    149  1.4   dyoung 	    CTL_CREATE, CTL_EOL)) != 0)
    150  1.4   dyoung 		goto err;
    151  1.4   dyoung 
    152  1.4   dyoung 	/* force host to flush I/O by reading RTW_PHYADDR */
    153  1.4   dyoung 	if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
    154  1.4   dyoung 	    CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
    155  1.4   dyoung 	    "flush_rfio", SYSCTL_DESCR("Enable RF I/O flushing"),
    156  1.4   dyoung 	    rtw_sysctl_verify_rfio, 0, &rtw_flush_rfio, 0,
    157  1.4   dyoung 	    CTL_CREATE, CTL_EOL)) != 0)
    158  1.4   dyoung 		goto err;
    159  1.4   dyoung 
    160  1.4   dyoung 	/* force host to control RF I/O bus */
    161  1.4   dyoung 	if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
    162  1.4   dyoung 	    CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
    163  1.4   dyoung 	    "host_rfio", SYSCTL_DESCR("Enable host control of RF I/O"),
    164  1.4   dyoung 	    rtw_sysctl_verify_rfio, 0, &rtw_host_rfio, 0,
    165  1.4   dyoung 	    CTL_CREATE, CTL_EOL)) != 0)
    166  1.4   dyoung 		goto err;
    167  1.4   dyoung 
    168  1.4   dyoung 	/* control RF I/O delay */
    169  1.4   dyoung 	if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
    170  1.4   dyoung 	    CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
    171  1.4   dyoung 	    "rfio_delay", SYSCTL_DESCR("Set RF I/O delay"),
    172  1.4   dyoung 	    rtw_sysctl_verify_rfio_delay, 0, &rtw_rfio_delay, 0,
    173  1.4   dyoung 	    CTL_CREATE, CTL_EOL)) != 0)
    174  1.4   dyoung 		goto err;
    175  1.4   dyoung 
    176  1.4   dyoung 	return;
    177  1.4   dyoung err:
    178  1.4   dyoung 	printf("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
    179  1.4   dyoung }
    180  1.4   dyoung 
    181  1.4   dyoung static int
    182  1.4   dyoung rtw_sysctl_verify(SYSCTLFN_ARGS, int lower, int upper)
    183  1.4   dyoung {
    184  1.4   dyoung 	int error, t;
    185  1.4   dyoung 	struct sysctlnode node;
    186  1.4   dyoung 
    187  1.4   dyoung 	node = *rnode;
    188  1.4   dyoung 	t = *(int*)rnode->sysctl_data;
    189  1.4   dyoung 	node.sysctl_data = &t;
    190  1.4   dyoung 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    191  1.4   dyoung 	if (error || newp == NULL)
    192  1.4   dyoung 		return (error);
    193  1.4   dyoung 
    194  1.4   dyoung 	if (t < lower || t > upper)
    195  1.4   dyoung 		return (EINVAL);
    196  1.4   dyoung 
    197  1.4   dyoung 	*(int*)rnode->sysctl_data = t;
    198  1.4   dyoung 
    199  1.4   dyoung 	return (0);
    200  1.4   dyoung }
    201  1.4   dyoung 
    202  1.4   dyoung static int
    203  1.4   dyoung rtw_sysctl_verify_rfio_delay(SYSCTLFN_ARGS)
    204  1.4   dyoung {
    205  1.4   dyoung 	return rtw_sysctl_verify(SYSCTLFN_CALL(rnode), 0, 1000000);
    206  1.4   dyoung }
    207  1.4   dyoung 
    208  1.4   dyoung static int
    209  1.4   dyoung rtw_sysctl_verify_rfprog(SYSCTLFN_ARGS)
    210  1.4   dyoung {
    211  1.4   dyoung 	return rtw_sysctl_verify(SYSCTLFN_CALL(rnode), 0,
    212  1.4   dyoung 	    MASK_AND_RSHIFT(RTW_CONFIG4_RFTYPE_MASK, RTW_CONFIG4_RFTYPE_MASK));
    213  1.4   dyoung }
    214  1.4   dyoung 
    215  1.4   dyoung static int
    216  1.4   dyoung rtw_sysctl_verify_rfio(SYSCTLFN_ARGS)
    217  1.4   dyoung {
    218  1.4   dyoung 	return rtw_sysctl_verify(SYSCTLFN_CALL(rnode), 0, 1);
    219  1.4   dyoung }
    220  1.4   dyoung 
    221  1.1   dyoung #ifdef RTW_DEBUG
    222  1.4   dyoung static int
    223  1.4   dyoung rtw_sysctl_verify_debug(SYSCTLFN_ARGS)
    224  1.4   dyoung {
    225  1.4   dyoung 	return rtw_sysctl_verify(SYSCTLFN_CALL(rnode), 0, 2);
    226  1.4   dyoung }
    227  1.4   dyoung 
    228  1.1   dyoung static void
    229  1.1   dyoung rtw_print_regs(struct rtw_regs *regs, const char *dvname, const char *where)
    230  1.1   dyoung {
    231  1.1   dyoung #define PRINTREG32(sc, reg) \
    232  1.1   dyoung 	RTW_DPRINTF2(("%s: reg[ " #reg " / %03x ] = %08x\n", \
    233  1.1   dyoung 	    dvname, reg, RTW_READ(regs, reg)))
    234  1.1   dyoung 
    235  1.1   dyoung #define PRINTREG16(sc, reg) \
    236  1.1   dyoung 	RTW_DPRINTF2(("%s: reg[ " #reg " / %03x ] = %04x\n", \
    237  1.1   dyoung 	    dvname, reg, RTW_READ16(regs, reg)))
    238  1.1   dyoung 
    239  1.1   dyoung #define PRINTREG8(sc, reg) \
    240  1.1   dyoung 	RTW_DPRINTF2(("%s: reg[ " #reg " / %03x ] = %02x\n", \
    241  1.1   dyoung 	    dvname, reg, RTW_READ8(regs, reg)))
    242  1.1   dyoung 
    243  1.1   dyoung 	RTW_DPRINTF2(("%s: %s\n", dvname, where));
    244  1.1   dyoung 
    245  1.1   dyoung 	PRINTREG32(regs, RTW_IDR0);
    246  1.1   dyoung 	PRINTREG32(regs, RTW_IDR1);
    247  1.1   dyoung 	PRINTREG32(regs, RTW_MAR0);
    248  1.1   dyoung 	PRINTREG32(regs, RTW_MAR1);
    249  1.1   dyoung 	PRINTREG32(regs, RTW_TSFTRL);
    250  1.1   dyoung 	PRINTREG32(regs, RTW_TSFTRH);
    251  1.1   dyoung 	PRINTREG32(regs, RTW_TLPDA);
    252  1.1   dyoung 	PRINTREG32(regs, RTW_TNPDA);
    253  1.1   dyoung 	PRINTREG32(regs, RTW_THPDA);
    254  1.1   dyoung 	PRINTREG32(regs, RTW_TCR);
    255  1.1   dyoung 	PRINTREG32(regs, RTW_RCR);
    256  1.1   dyoung 	PRINTREG32(regs, RTW_TINT);
    257  1.1   dyoung 	PRINTREG32(regs, RTW_TBDA);
    258  1.1   dyoung 	PRINTREG32(regs, RTW_ANAPARM);
    259  1.1   dyoung 	PRINTREG32(regs, RTW_BB);
    260  1.1   dyoung 	PRINTREG32(regs, RTW_PHYCFG);
    261  1.1   dyoung 	PRINTREG32(regs, RTW_WAKEUP0L);
    262  1.1   dyoung 	PRINTREG32(regs, RTW_WAKEUP0H);
    263  1.1   dyoung 	PRINTREG32(regs, RTW_WAKEUP1L);
    264  1.1   dyoung 	PRINTREG32(regs, RTW_WAKEUP1H);
    265  1.1   dyoung 	PRINTREG32(regs, RTW_WAKEUP2LL);
    266  1.1   dyoung 	PRINTREG32(regs, RTW_WAKEUP2LH);
    267  1.1   dyoung 	PRINTREG32(regs, RTW_WAKEUP2HL);
    268  1.1   dyoung 	PRINTREG32(regs, RTW_WAKEUP2HH);
    269  1.1   dyoung 	PRINTREG32(regs, RTW_WAKEUP3LL);
    270  1.1   dyoung 	PRINTREG32(regs, RTW_WAKEUP3LH);
    271  1.1   dyoung 	PRINTREG32(regs, RTW_WAKEUP3HL);
    272  1.1   dyoung 	PRINTREG32(regs, RTW_WAKEUP3HH);
    273  1.1   dyoung 	PRINTREG32(regs, RTW_WAKEUP4LL);
    274  1.1   dyoung 	PRINTREG32(regs, RTW_WAKEUP4LH);
    275  1.1   dyoung 	PRINTREG32(regs, RTW_WAKEUP4HL);
    276  1.1   dyoung 	PRINTREG32(regs, RTW_WAKEUP4HH);
    277  1.1   dyoung 	PRINTREG32(regs, RTW_DK0);
    278  1.1   dyoung 	PRINTREG32(regs, RTW_DK1);
    279  1.1   dyoung 	PRINTREG32(regs, RTW_DK2);
    280  1.1   dyoung 	PRINTREG32(regs, RTW_DK3);
    281  1.1   dyoung 	PRINTREG32(regs, RTW_RETRYCTR);
    282  1.1   dyoung 	PRINTREG32(regs, RTW_RDSAR);
    283  1.1   dyoung 	PRINTREG32(regs, RTW_FER);
    284  1.1   dyoung 	PRINTREG32(regs, RTW_FEMR);
    285  1.1   dyoung 	PRINTREG32(regs, RTW_FPSR);
    286  1.1   dyoung 	PRINTREG32(regs, RTW_FFER);
    287  1.1   dyoung 
    288  1.1   dyoung 	/* 16-bit registers */
    289  1.1   dyoung 	PRINTREG16(regs, RTW_BRSR);
    290  1.1   dyoung 	PRINTREG16(regs, RTW_IMR);
    291  1.1   dyoung 	PRINTREG16(regs, RTW_ISR);
    292  1.1   dyoung 	PRINTREG16(regs, RTW_BCNITV);
    293  1.1   dyoung 	PRINTREG16(regs, RTW_ATIMWND);
    294  1.1   dyoung 	PRINTREG16(regs, RTW_BINTRITV);
    295  1.1   dyoung 	PRINTREG16(regs, RTW_ATIMTRITV);
    296  1.1   dyoung 	PRINTREG16(regs, RTW_CRC16ERR);
    297  1.1   dyoung 	PRINTREG16(regs, RTW_CRC0);
    298  1.1   dyoung 	PRINTREG16(regs, RTW_CRC1);
    299  1.1   dyoung 	PRINTREG16(regs, RTW_CRC2);
    300  1.1   dyoung 	PRINTREG16(regs, RTW_CRC3);
    301  1.1   dyoung 	PRINTREG16(regs, RTW_CRC4);
    302  1.1   dyoung 	PRINTREG16(regs, RTW_CWR);
    303  1.1   dyoung 
    304  1.1   dyoung 	/* 8-bit registers */
    305  1.1   dyoung 	PRINTREG8(regs, RTW_CR);
    306  1.1   dyoung 	PRINTREG8(regs, RTW_9346CR);
    307  1.1   dyoung 	PRINTREG8(regs, RTW_CONFIG0);
    308  1.1   dyoung 	PRINTREG8(regs, RTW_CONFIG1);
    309  1.1   dyoung 	PRINTREG8(regs, RTW_CONFIG2);
    310  1.1   dyoung 	PRINTREG8(regs, RTW_MSR);
    311  1.1   dyoung 	PRINTREG8(regs, RTW_CONFIG3);
    312  1.1   dyoung 	PRINTREG8(regs, RTW_CONFIG4);
    313  1.1   dyoung 	PRINTREG8(regs, RTW_TESTR);
    314  1.1   dyoung 	PRINTREG8(regs, RTW_PSR);
    315  1.1   dyoung 	PRINTREG8(regs, RTW_SCR);
    316  1.1   dyoung 	PRINTREG8(regs, RTW_PHYDELAY);
    317  1.1   dyoung 	PRINTREG8(regs, RTW_CRCOUNT);
    318  1.1   dyoung 	PRINTREG8(regs, RTW_PHYADDR);
    319  1.1   dyoung 	PRINTREG8(regs, RTW_PHYDATAW);
    320  1.1   dyoung 	PRINTREG8(regs, RTW_PHYDATAR);
    321  1.1   dyoung 	PRINTREG8(regs, RTW_CONFIG5);
    322  1.1   dyoung 	PRINTREG8(regs, RTW_TPPOLL);
    323  1.1   dyoung 
    324  1.1   dyoung 	PRINTREG16(regs, RTW_BSSID16);
    325  1.1   dyoung 	PRINTREG32(regs, RTW_BSSID32);
    326  1.1   dyoung #undef PRINTREG32
    327  1.1   dyoung #undef PRINTREG16
    328  1.1   dyoung #undef PRINTREG8
    329  1.1   dyoung }
    330  1.1   dyoung #endif /* RTW_DEBUG */
    331  1.1   dyoung 
    332  1.1   dyoung void
    333  1.3   dyoung rtw_continuous_tx_enable(struct rtw_softc *sc, int enable)
    334  1.1   dyoung {
    335  1.3   dyoung 	struct rtw_regs *regs = &sc->sc_regs;
    336  1.3   dyoung 
    337  1.1   dyoung 	u_int32_t tcr;
    338  1.1   dyoung 	tcr = RTW_READ(regs, RTW_TCR);
    339  1.1   dyoung 	tcr &= ~RTW_TCR_LBK_MASK;
    340  1.1   dyoung 	if (enable)
    341  1.1   dyoung 		tcr |= RTW_TCR_LBK_CONT;
    342  1.1   dyoung 	else
    343  1.1   dyoung 		tcr |= RTW_TCR_LBK_NORMAL;
    344  1.1   dyoung 	RTW_WRITE(regs, RTW_TCR, tcr);
    345  1.1   dyoung 	RTW_SYNC(regs, RTW_TCR, RTW_TCR);
    346  1.3   dyoung 	rtw_set_access(sc, RTW_ACCESS_ANAPARM);
    347  1.4   dyoung 	rtw_txdac_enable(sc, !enable);
    348  1.4   dyoung 	rtw_set_access(sc, RTW_ACCESS_ANAPARM);	/* XXX Voodoo from Linux. */
    349  1.3   dyoung 	rtw_set_access(sc, RTW_ACCESS_NONE);
    350  1.3   dyoung }
    351  1.3   dyoung 
    352  1.3   dyoung static const char *
    353  1.3   dyoung rtw_access_string(enum rtw_access access)
    354  1.3   dyoung {
    355  1.3   dyoung 	switch (access) {
    356  1.3   dyoung 	case RTW_ACCESS_NONE:
    357  1.3   dyoung 		return "none";
    358  1.3   dyoung 	case RTW_ACCESS_CONFIG:
    359  1.3   dyoung 		return "config";
    360  1.3   dyoung 	case RTW_ACCESS_ANAPARM:
    361  1.3   dyoung 		return "anaparm";
    362  1.3   dyoung 	default:
    363  1.3   dyoung 		return "unknown";
    364  1.3   dyoung 	}
    365  1.3   dyoung }
    366  1.3   dyoung 
    367  1.3   dyoung static void
    368  1.3   dyoung rtw_set_access1(struct rtw_regs *regs,
    369  1.3   dyoung     enum rtw_access oaccess, enum rtw_access naccess)
    370  1.3   dyoung {
    371  1.3   dyoung 	KASSERT(naccess >= RTW_ACCESS_NONE && naccess <= RTW_ACCESS_ANAPARM);
    372  1.3   dyoung 	KASSERT(oaccess >= RTW_ACCESS_NONE && oaccess <= RTW_ACCESS_ANAPARM);
    373  1.3   dyoung 
    374  1.3   dyoung 	if (naccess == oaccess)
    375  1.3   dyoung 		return;
    376  1.3   dyoung 
    377  1.3   dyoung 	switch (naccess) {
    378  1.3   dyoung 	case RTW_ACCESS_NONE:
    379  1.3   dyoung 		switch (oaccess) {
    380  1.3   dyoung 		case RTW_ACCESS_ANAPARM:
    381  1.3   dyoung 			rtw_anaparm_enable(regs, 0);
    382  1.3   dyoung 			/*FALLTHROUGH*/
    383  1.3   dyoung 		case RTW_ACCESS_CONFIG:
    384  1.3   dyoung 			rtw_config0123_enable(regs, 0);
    385  1.3   dyoung 			/*FALLTHROUGH*/
    386  1.3   dyoung 		case RTW_ACCESS_NONE:
    387  1.3   dyoung 			break;
    388  1.3   dyoung 		}
    389  1.3   dyoung 		break;
    390  1.3   dyoung 	case RTW_ACCESS_CONFIG:
    391  1.3   dyoung 		switch (oaccess) {
    392  1.3   dyoung 		case RTW_ACCESS_NONE:
    393  1.3   dyoung 			rtw_config0123_enable(regs, 1);
    394  1.3   dyoung 			/*FALLTHROUGH*/
    395  1.3   dyoung 		case RTW_ACCESS_CONFIG:
    396  1.3   dyoung 			break;
    397  1.3   dyoung 		case RTW_ACCESS_ANAPARM:
    398  1.3   dyoung 			rtw_anaparm_enable(regs, 0);
    399  1.3   dyoung 			break;
    400  1.3   dyoung 		}
    401  1.3   dyoung 		break;
    402  1.3   dyoung 	case RTW_ACCESS_ANAPARM:
    403  1.3   dyoung 		switch (oaccess) {
    404  1.3   dyoung 		case RTW_ACCESS_NONE:
    405  1.3   dyoung 			rtw_config0123_enable(regs, 1);
    406  1.3   dyoung 			/*FALLTHROUGH*/
    407  1.3   dyoung 		case RTW_ACCESS_CONFIG:
    408  1.3   dyoung 			rtw_anaparm_enable(regs, 1);
    409  1.3   dyoung 			/*FALLTHROUGH*/
    410  1.3   dyoung 		case RTW_ACCESS_ANAPARM:
    411  1.3   dyoung 			break;
    412  1.3   dyoung 		}
    413  1.3   dyoung 		break;
    414  1.1   dyoung 	}
    415  1.1   dyoung }
    416  1.1   dyoung 
    417  1.3   dyoung void
    418  1.3   dyoung rtw_set_access(struct rtw_softc *sc, enum rtw_access access)
    419  1.3   dyoung {
    420  1.3   dyoung 	rtw_set_access1(&sc->sc_regs, sc->sc_access, access);
    421  1.3   dyoung 	RTW_DPRINTF(("%s: access %s -> %s\n", sc->sc_dev.dv_xname,
    422  1.3   dyoung 	    rtw_access_string(sc->sc_access),
    423  1.3   dyoung 	    rtw_access_string(access)));
    424  1.3   dyoung 	sc->sc_access = access;
    425  1.3   dyoung }
    426  1.3   dyoung 
    427  1.1   dyoung /*
    428  1.1   dyoung  * Enable registers, switch register banks.
    429  1.1   dyoung  */
    430  1.1   dyoung void
    431  1.1   dyoung rtw_config0123_enable(struct rtw_regs *regs, int enable)
    432  1.1   dyoung {
    433  1.1   dyoung 	u_int8_t ecr;
    434  1.1   dyoung 	ecr = RTW_READ8(regs, RTW_9346CR);
    435  1.1   dyoung 	ecr &= ~(RTW_9346CR_EEM_MASK | RTW_9346CR_EECS | RTW_9346CR_EESK);
    436  1.1   dyoung 	if (enable)
    437  1.1   dyoung 		ecr |= RTW_9346CR_EEM_CONFIG;
    438  1.1   dyoung 	else
    439  1.1   dyoung 		ecr |= RTW_9346CR_EEM_NORMAL;
    440  1.1   dyoung 	RTW_WRITE8(regs, RTW_9346CR, ecr);
    441  1.1   dyoung 	RTW_SYNC(regs, RTW_9346CR, RTW_9346CR);
    442  1.1   dyoung }
    443  1.1   dyoung 
    444  1.1   dyoung /* requires rtw_config0123_enable(, 1) */
    445  1.1   dyoung void
    446  1.1   dyoung rtw_anaparm_enable(struct rtw_regs *regs, int enable)
    447  1.1   dyoung {
    448  1.1   dyoung 	u_int8_t cfg3;
    449  1.1   dyoung 
    450  1.1   dyoung 	cfg3 = RTW_READ8(regs, RTW_CONFIG3);
    451  1.3   dyoung 	cfg3 |= RTW_CONFIG3_CLKRUNEN;
    452  1.3   dyoung 	if (enable)
    453  1.3   dyoung 		cfg3 |= RTW_CONFIG3_PARMEN;
    454  1.3   dyoung 	else
    455  1.1   dyoung 		cfg3 &= ~RTW_CONFIG3_PARMEN;
    456  1.1   dyoung 	RTW_WRITE8(regs, RTW_CONFIG3, cfg3);
    457  1.1   dyoung 	RTW_SYNC(regs, RTW_CONFIG3, RTW_CONFIG3);
    458  1.1   dyoung }
    459  1.1   dyoung 
    460  1.1   dyoung /* requires rtw_anaparm_enable(, 1) */
    461  1.1   dyoung void
    462  1.4   dyoung rtw_txdac_enable(struct rtw_softc *sc, int enable)
    463  1.1   dyoung {
    464  1.1   dyoung 	u_int32_t anaparm;
    465  1.4   dyoung 	struct rtw_regs *regs = &sc->sc_regs;
    466  1.1   dyoung 
    467  1.1   dyoung 	anaparm = RTW_READ(regs, RTW_ANAPARM);
    468  1.1   dyoung 	if (enable)
    469  1.1   dyoung 		anaparm &= ~RTW_ANAPARM_TXDACOFF;
    470  1.1   dyoung 	else
    471  1.1   dyoung 		anaparm |= RTW_ANAPARM_TXDACOFF;
    472  1.1   dyoung 	RTW_WRITE(regs, RTW_ANAPARM, anaparm);
    473  1.1   dyoung 	RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM);
    474  1.1   dyoung }
    475  1.1   dyoung 
    476  1.1   dyoung static __inline int
    477  1.7   dyoung rtw_chip_reset1(struct rtw_regs *regs, const char *dvname)
    478  1.1   dyoung {
    479  1.3   dyoung 	u_int8_t cr;
    480  1.1   dyoung 	int i;
    481  1.1   dyoung 
    482  1.1   dyoung 	RTW_WRITE8(regs, RTW_CR, RTW_CR_RST);
    483  1.1   dyoung 
    484  1.1   dyoung 	RTW_WBR(regs, RTW_CR, RTW_CR);
    485  1.1   dyoung 
    486  1.1   dyoung 	for (i = 0; i < 10000; i++) {
    487  1.1   dyoung 		if ((cr = RTW_READ8(regs, RTW_CR) & RTW_CR_RST) == 0) {
    488  1.7   dyoung 			RTW_DPRINTF(("%s: reset in %dus\n", dvname, i));
    489  1.1   dyoung 			return 0;
    490  1.1   dyoung 		}
    491  1.1   dyoung 		RTW_RBR(regs, RTW_CR, RTW_CR);
    492  1.1   dyoung 		DELAY(1); /* 1us */
    493  1.1   dyoung 	}
    494  1.1   dyoung 
    495  1.7   dyoung 	printf("%s: reset failed\n", dvname);
    496  1.1   dyoung 	return ETIMEDOUT;
    497  1.1   dyoung }
    498  1.1   dyoung 
    499  1.1   dyoung static __inline int
    500  1.7   dyoung rtw_chip_reset(struct rtw_regs *regs, const char *dvname)
    501  1.3   dyoung {
    502  1.3   dyoung 	uint32_t tcr;
    503  1.3   dyoung 
    504  1.3   dyoung 	/* from Linux driver */
    505  1.3   dyoung 	tcr = RTW_TCR_CWMIN | RTW_TCR_MXDMA_2048 |
    506  1.3   dyoung 	      LSHIFT(7, RTW_TCR_SRL_MASK) | LSHIFT(7, RTW_TCR_LRL_MASK);
    507  1.3   dyoung 
    508  1.3   dyoung 	RTW_WRITE(regs, RTW_TCR, tcr);
    509  1.3   dyoung 
    510  1.3   dyoung 	RTW_WBW(regs, RTW_CR, RTW_TCR);
    511  1.3   dyoung 
    512  1.3   dyoung 	return rtw_chip_reset1(regs, dvname);
    513  1.3   dyoung }
    514  1.3   dyoung 
    515  1.3   dyoung static __inline int
    516  1.7   dyoung rtw_recall_eeprom(struct rtw_regs *regs, const char *dvname)
    517  1.1   dyoung {
    518  1.1   dyoung 	int i;
    519  1.1   dyoung 	u_int8_t ecr;
    520  1.1   dyoung 
    521  1.1   dyoung 	ecr = RTW_READ8(regs, RTW_9346CR);
    522  1.1   dyoung 	ecr = (ecr & ~RTW_9346CR_EEM_MASK) | RTW_9346CR_EEM_AUTOLOAD;
    523  1.1   dyoung 	RTW_WRITE8(regs, RTW_9346CR, ecr);
    524  1.1   dyoung 
    525  1.1   dyoung 	RTW_WBR(regs, RTW_9346CR, RTW_9346CR);
    526  1.1   dyoung 
    527  1.1   dyoung 	/* wait 2.5ms for completion */
    528  1.1   dyoung 	for (i = 0; i < 25; i++) {
    529  1.1   dyoung 		ecr = RTW_READ8(regs, RTW_9346CR);
    530  1.1   dyoung 		if ((ecr & RTW_9346CR_EEM_MASK) == RTW_9346CR_EEM_NORMAL) {
    531  1.7   dyoung 			RTW_DPRINTF(("%s: recall EEPROM in %dus\n", dvname,
    532  1.1   dyoung 			    i * 100));
    533  1.1   dyoung 			return 0;
    534  1.1   dyoung 		}
    535  1.1   dyoung 		RTW_RBR(regs, RTW_9346CR, RTW_9346CR);
    536  1.1   dyoung 		DELAY(100);
    537  1.1   dyoung 	}
    538  1.7   dyoung 	printf("%s: recall EEPROM failed\n", dvname);
    539  1.1   dyoung 	return ETIMEDOUT;
    540  1.1   dyoung }
    541  1.1   dyoung 
    542  1.1   dyoung static __inline int
    543  1.1   dyoung rtw_reset(struct rtw_softc *sc)
    544  1.1   dyoung {
    545  1.1   dyoung 	int rc;
    546  1.4   dyoung 	uint8_t config1;
    547  1.1   dyoung 
    548  1.7   dyoung 	if ((rc = rtw_chip_reset(&sc->sc_regs, sc->sc_dev.dv_xname)) != 0)
    549  1.1   dyoung 		return rc;
    550  1.1   dyoung 
    551  1.7   dyoung 	if ((rc = rtw_recall_eeprom(&sc->sc_regs, sc->sc_dev.dv_xname)) != 0)
    552  1.1   dyoung 		;
    553  1.1   dyoung 
    554  1.4   dyoung 	config1 = RTW_READ8(&sc->sc_regs, RTW_CONFIG1);
    555  1.4   dyoung 	RTW_WRITE8(&sc->sc_regs, RTW_CONFIG1, config1 & ~RTW_CONFIG1_PMEN);
    556  1.1   dyoung 	/* TBD turn off maximum power saving? */
    557  1.1   dyoung 
    558  1.1   dyoung 	return 0;
    559  1.1   dyoung }
    560  1.1   dyoung 
    561  1.1   dyoung static __inline int
    562  1.1   dyoung rtw_txdesc_dmamaps_create(bus_dma_tag_t dmat, struct rtw_txctl *descs,
    563  1.1   dyoung     u_int ndescs)
    564  1.1   dyoung {
    565  1.1   dyoung 	int i, rc = 0;
    566  1.1   dyoung 	for (i = 0; i < ndescs; i++) {
    567  1.1   dyoung 		rc = bus_dmamap_create(dmat, MCLBYTES, RTW_MAXPKTSEGS, MCLBYTES,
    568  1.1   dyoung 		    0, 0, &descs[i].stx_dmamap);
    569  1.1   dyoung 		if (rc != 0)
    570  1.1   dyoung 			break;
    571  1.1   dyoung 	}
    572  1.1   dyoung 	return rc;
    573  1.1   dyoung }
    574  1.1   dyoung 
    575  1.1   dyoung static __inline int
    576  1.1   dyoung rtw_rxdesc_dmamaps_create(bus_dma_tag_t dmat, struct rtw_rxctl *descs,
    577  1.1   dyoung     u_int ndescs)
    578  1.1   dyoung {
    579  1.1   dyoung 	int i, rc = 0;
    580  1.1   dyoung 	for (i = 0; i < ndescs; i++) {
    581  1.1   dyoung 		rc = bus_dmamap_create(dmat, MCLBYTES, 1, MCLBYTES, 0, 0,
    582  1.1   dyoung 		    &descs[i].srx_dmamap);
    583  1.1   dyoung 		if (rc != 0)
    584  1.1   dyoung 			break;
    585  1.1   dyoung 	}
    586  1.1   dyoung 	return rc;
    587  1.1   dyoung }
    588  1.1   dyoung 
    589  1.1   dyoung static __inline void
    590  1.3   dyoung rtw_rxctls_setup(struct rtw_rxctl *descs)
    591  1.1   dyoung {
    592  1.1   dyoung 	int i;
    593  1.1   dyoung 	for (i = 0; i < RTW_RXQLEN; i++)
    594  1.3   dyoung 		descs[i].srx_mbuf = NULL;
    595  1.1   dyoung }
    596  1.1   dyoung 
    597  1.1   dyoung static __inline void
    598  1.1   dyoung rtw_rxdesc_dmamaps_destroy(bus_dma_tag_t dmat, struct rtw_rxctl *descs,
    599  1.1   dyoung     u_int ndescs)
    600  1.1   dyoung {
    601  1.1   dyoung 	int i;
    602  1.1   dyoung 	for (i = 0; i < ndescs; i++) {
    603  1.1   dyoung 		if (descs[i].srx_dmamap != NULL)
    604  1.1   dyoung 			bus_dmamap_destroy(dmat, descs[i].srx_dmamap);
    605  1.1   dyoung 	}
    606  1.1   dyoung }
    607  1.1   dyoung 
    608  1.1   dyoung static __inline void
    609  1.1   dyoung rtw_txdesc_dmamaps_destroy(bus_dma_tag_t dmat, struct rtw_txctl *descs,
    610  1.1   dyoung     u_int ndescs)
    611  1.1   dyoung {
    612  1.1   dyoung 	int i;
    613  1.1   dyoung 	for (i = 0; i < ndescs; i++) {
    614  1.1   dyoung 		if (descs[i].stx_dmamap != NULL)
    615  1.1   dyoung 			bus_dmamap_destroy(dmat, descs[i].stx_dmamap);
    616  1.1   dyoung 	}
    617  1.1   dyoung }
    618  1.1   dyoung 
    619  1.1   dyoung static __inline void
    620  1.1   dyoung rtw_srom_free(struct rtw_srom *sr)
    621  1.1   dyoung {
    622  1.1   dyoung 	sr->sr_size = 0;
    623  1.1   dyoung 	if (sr->sr_content == NULL)
    624  1.1   dyoung 		return;
    625  1.1   dyoung 	free(sr->sr_content, M_DEVBUF);
    626  1.1   dyoung 	sr->sr_content = NULL;
    627  1.1   dyoung }
    628  1.1   dyoung 
    629  1.1   dyoung static void
    630  1.1   dyoung rtw_srom_defaults(struct rtw_srom *sr, u_int32_t *flags, u_int8_t *cs_threshold,
    631  1.7   dyoung     enum rtw_rfchipid *rfchipid, u_int32_t *rcr)
    632  1.1   dyoung {
    633  1.1   dyoung 	*flags |= (RTW_F_DIGPHY|RTW_F_ANTDIV);
    634  1.1   dyoung 	*cs_threshold = RTW_SR_ENERGYDETTHR_DEFAULT;
    635  1.1   dyoung 	*rcr |= RTW_RCR_ENCS1;
    636  1.1   dyoung 	*rfchipid = RTW_RFCHIPID_PHILIPS;
    637  1.1   dyoung }
    638  1.1   dyoung 
    639  1.1   dyoung static int
    640  1.1   dyoung rtw_srom_parse(struct rtw_srom *sr, u_int32_t *flags, u_int8_t *cs_threshold,
    641  1.1   dyoung     enum rtw_rfchipid *rfchipid, u_int32_t *rcr, enum rtw_locale *locale,
    642  1.7   dyoung     const char *dvname)
    643  1.1   dyoung {
    644  1.1   dyoung 	int i;
    645  1.1   dyoung 	const char *rfname, *paname;
    646  1.1   dyoung 	char scratch[sizeof("unknown 0xXX")];
    647  1.1   dyoung 	u_int16_t version;
    648  1.1   dyoung 	u_int8_t mac[IEEE80211_ADDR_LEN];
    649  1.1   dyoung 
    650  1.1   dyoung 	*flags &= ~(RTW_F_DIGPHY|RTW_F_DFLANTB|RTW_F_ANTDIV);
    651  1.1   dyoung 	*rcr &= ~(RTW_RCR_ENCS1 | RTW_RCR_ENCS2);
    652  1.1   dyoung 
    653  1.1   dyoung 	version = RTW_SR_GET16(sr, RTW_SR_VERSION);
    654  1.7   dyoung 	printf("%s: SROM version %d.%d", dvname, version >> 8, version & 0xff);
    655  1.1   dyoung 
    656  1.1   dyoung 	if (version <= 0x0101) {
    657  1.1   dyoung 		printf(" is not understood, limping along with defaults\n");
    658  1.7   dyoung 		rtw_srom_defaults(sr, flags, cs_threshold, rfchipid, rcr);
    659  1.1   dyoung 		return 0;
    660  1.1   dyoung 	}
    661  1.1   dyoung 	printf("\n");
    662  1.1   dyoung 
    663  1.1   dyoung 	for (i = 0; i < IEEE80211_ADDR_LEN; i++)
    664  1.1   dyoung 		mac[i] = RTW_SR_GET(sr, RTW_SR_MAC + i);
    665  1.1   dyoung 
    666  1.7   dyoung 	RTW_DPRINTF(("%s: EEPROM MAC %s\n", dvname, ether_sprintf(mac)));
    667  1.1   dyoung 
    668  1.1   dyoung 	*cs_threshold = RTW_SR_GET(sr, RTW_SR_ENERGYDETTHR);
    669  1.1   dyoung 
    670  1.1   dyoung 	if ((RTW_SR_GET(sr, RTW_SR_CONFIG2) & RTW_CONFIG2_ANT) != 0)
    671  1.1   dyoung 		*flags |= RTW_F_ANTDIV;
    672  1.1   dyoung 
    673  1.1   dyoung 	if ((RTW_SR_GET(sr, RTW_SR_RFPARM) & RTW_SR_RFPARM_DIGPHY) != 0)
    674  1.1   dyoung 		*flags |= RTW_F_DIGPHY;
    675  1.1   dyoung 	if ((RTW_SR_GET(sr, RTW_SR_RFPARM) & RTW_SR_RFPARM_DFLANTB) != 0)
    676  1.1   dyoung 		*flags |= RTW_F_DFLANTB;
    677  1.1   dyoung 
    678  1.1   dyoung 	*rcr |= LSHIFT(MASK_AND_RSHIFT(RTW_SR_GET(sr, RTW_SR_RFPARM),
    679  1.1   dyoung 	    RTW_SR_RFPARM_CS_MASK), RTW_RCR_ENCS1);
    680  1.1   dyoung 
    681  1.1   dyoung 	*rfchipid = RTW_SR_GET(sr, RTW_SR_RFCHIPID);
    682  1.1   dyoung 	switch (*rfchipid) {
    683  1.1   dyoung 	case RTW_RFCHIPID_GCT:		/* this combo seen in the wild */
    684  1.1   dyoung 		rfname = "GCT GRF5101";
    685  1.1   dyoung 		paname = "Winspring WS9901";
    686  1.1   dyoung 		break;
    687  1.1   dyoung 	case RTW_RFCHIPID_MAXIM:
    688  1.1   dyoung 		rfname = "Maxim MAX2820";	/* guess */
    689  1.1   dyoung 		paname = "Maxim MAX2422";	/* guess */
    690  1.1   dyoung 		break;
    691  1.1   dyoung 	case RTW_RFCHIPID_INTERSIL:
    692  1.1   dyoung 		rfname = "Intersil HFA3873";	/* guess */
    693  1.1   dyoung 		paname = "Intersil <unknown>";
    694  1.1   dyoung 		break;
    695  1.1   dyoung 	case RTW_RFCHIPID_PHILIPS:	/* this combo seen in the wild */
    696  1.1   dyoung 		rfname = "Philips SA2400A";
    697  1.1   dyoung 		paname = "Philips SA2411";
    698  1.1   dyoung 		break;
    699  1.1   dyoung 	case RTW_RFCHIPID_RFMD:
    700  1.1   dyoung 		/* this is the same front-end as an atw(4)! */
    701  1.1   dyoung 		rfname = "RFMD RF2948B, "	/* mentioned in Realtek docs */
    702  1.1   dyoung 			 "LNA: RFMD RF2494, "	/* mentioned in Realtek docs */
    703  1.1   dyoung 			 "SYN: Silicon Labs Si4126";	/* inferred from
    704  1.1   dyoung 			 				 * reference driver
    705  1.1   dyoung 							 */
    706  1.1   dyoung 		paname = "RFMD RF2189";		/* mentioned in Realtek docs */
    707  1.1   dyoung 		break;
    708  1.1   dyoung 	case RTW_RFCHIPID_RESERVED:
    709  1.1   dyoung 		rfname = paname = "reserved";
    710  1.1   dyoung 		break;
    711  1.1   dyoung 	default:
    712  1.1   dyoung 		snprintf(scratch, sizeof(scratch), "unknown 0x%02x", *rfchipid);
    713  1.1   dyoung 		rfname = paname = scratch;
    714  1.1   dyoung 	}
    715  1.7   dyoung 	printf("%s: RF: %s, PA: %s\n", dvname, rfname, paname);
    716  1.1   dyoung 
    717  1.1   dyoung 	switch (RTW_SR_GET(sr, RTW_SR_CONFIG0) & RTW_CONFIG0_GL_MASK) {
    718  1.1   dyoung 	case RTW_CONFIG0_GL_USA:
    719  1.1   dyoung 		*locale = RTW_LOCALE_USA;
    720  1.1   dyoung 		break;
    721  1.1   dyoung 	case RTW_CONFIG0_GL_EUROPE:
    722  1.1   dyoung 		*locale = RTW_LOCALE_EUROPE;
    723  1.1   dyoung 		break;
    724  1.1   dyoung 	case RTW_CONFIG0_GL_JAPAN:
    725  1.1   dyoung 		*locale = RTW_LOCALE_JAPAN;
    726  1.1   dyoung 		break;
    727  1.1   dyoung 	default:
    728  1.1   dyoung 		*locale = RTW_LOCALE_UNKNOWN;
    729  1.1   dyoung 		break;
    730  1.1   dyoung 	}
    731  1.1   dyoung 	return 0;
    732  1.1   dyoung }
    733  1.1   dyoung 
    734  1.1   dyoung /* Returns -1 on failure. */
    735  1.1   dyoung static int
    736  1.1   dyoung rtw_srom_read(struct rtw_regs *regs, u_int32_t flags, struct rtw_srom *sr,
    737  1.7   dyoung     const char *dvname)
    738  1.1   dyoung {
    739  1.1   dyoung 	int rc;
    740  1.1   dyoung 	struct seeprom_descriptor sd;
    741  1.1   dyoung 	u_int8_t ecr;
    742  1.1   dyoung 
    743  1.1   dyoung 	(void)memset(&sd, 0, sizeof(sd));
    744  1.1   dyoung 
    745  1.1   dyoung 	ecr = RTW_READ8(regs, RTW_9346CR);
    746  1.1   dyoung 
    747  1.1   dyoung 	if ((flags & RTW_F_9356SROM) != 0) {
    748  1.7   dyoung 		RTW_DPRINTF(("%s: 93c56 SROM\n", dvname));
    749  1.1   dyoung 		sr->sr_size = 256;
    750  1.1   dyoung 		sd.sd_chip = C56_66;
    751  1.1   dyoung 	} else {
    752  1.7   dyoung 		RTW_DPRINTF(("%s: 93c46 SROM\n", dvname));
    753  1.1   dyoung 		sr->sr_size = 128;
    754  1.1   dyoung 		sd.sd_chip = C46;
    755  1.1   dyoung 	}
    756  1.1   dyoung 
    757  1.1   dyoung 	ecr &= ~(RTW_9346CR_EEDI | RTW_9346CR_EEDO | RTW_9346CR_EESK |
    758  1.1   dyoung 	    RTW_9346CR_EEM_MASK);
    759  1.1   dyoung 	ecr |= RTW_9346CR_EEM_PROGRAM;
    760  1.1   dyoung 
    761  1.1   dyoung 	RTW_WRITE8(regs, RTW_9346CR, ecr);
    762  1.1   dyoung 
    763  1.1   dyoung 	sr->sr_content = malloc(sr->sr_size, M_DEVBUF, M_NOWAIT);
    764  1.1   dyoung 
    765  1.1   dyoung 	if (sr->sr_content == NULL) {
    766  1.7   dyoung 		printf("%s: unable to allocate SROM buffer\n", dvname);
    767  1.1   dyoung 		return ENOMEM;
    768  1.1   dyoung 	}
    769  1.1   dyoung 
    770  1.1   dyoung 	(void)memset(sr->sr_content, 0, sr->sr_size);
    771  1.1   dyoung 
    772  1.1   dyoung 	/* RTL8180 has a single 8-bit register for controlling the
    773  1.1   dyoung 	 * 93cx6 SROM.  There is no "ready" bit. The RTL8180
    774  1.1   dyoung 	 * input/output sense is the reverse of read_seeprom's.
    775  1.1   dyoung 	 */
    776  1.1   dyoung 	sd.sd_tag = regs->r_bt;
    777  1.1   dyoung 	sd.sd_bsh = regs->r_bh;
    778  1.1   dyoung 	sd.sd_regsize = 1;
    779  1.1   dyoung 	sd.sd_control_offset = RTW_9346CR;
    780  1.1   dyoung 	sd.sd_status_offset = RTW_9346CR;
    781  1.1   dyoung 	sd.sd_dataout_offset = RTW_9346CR;
    782  1.1   dyoung 	sd.sd_CK = RTW_9346CR_EESK;
    783  1.1   dyoung 	sd.sd_CS = RTW_9346CR_EECS;
    784  1.1   dyoung 	sd.sd_DI = RTW_9346CR_EEDO;
    785  1.1   dyoung 	sd.sd_DO = RTW_9346CR_EEDI;
    786  1.1   dyoung 	/* make read_seeprom enter EEPROM read/write mode */
    787  1.1   dyoung 	sd.sd_MS = ecr;
    788  1.1   dyoung 	sd.sd_RDY = 0;
    789  1.1   dyoung #if 0
    790  1.1   dyoung 	sd.sd_clkdelay = 50;
    791  1.1   dyoung #endif
    792  1.1   dyoung 
    793  1.1   dyoung 	if (!read_seeprom(&sd, sr->sr_content, 0, sr->sr_size/2)) {
    794  1.7   dyoung 		printf("%s: could not read SROM\n", dvname);
    795  1.1   dyoung 		free(sr->sr_content, M_DEVBUF);
    796  1.1   dyoung 		sr->sr_content = NULL;
    797  1.1   dyoung 		return -1;	/* XXX */
    798  1.1   dyoung 	}
    799  1.1   dyoung 
    800  1.1   dyoung 	/* end EEPROM read/write mode */
    801  1.1   dyoung 	RTW_WRITE8(regs, RTW_9346CR,
    802  1.1   dyoung 	    (ecr & ~RTW_9346CR_EEM_MASK) | RTW_9346CR_EEM_NORMAL);
    803  1.1   dyoung 	RTW_WBRW(regs, RTW_9346CR, RTW_9346CR);
    804  1.1   dyoung 
    805  1.1   dyoung 	if ((rc = rtw_recall_eeprom(regs, dvname)) != 0)
    806  1.1   dyoung 		return rc;
    807  1.1   dyoung 
    808  1.1   dyoung #ifdef RTW_DEBUG
    809  1.1   dyoung 	{
    810  1.1   dyoung 		int i;
    811  1.7   dyoung 		RTW_DPRINTF(("\n%s: serial ROM:\n\t", dvname));
    812  1.1   dyoung 		for (i = 0; i < sr->sr_size/2; i++) {
    813  1.1   dyoung 			if (((i % 8) == 0) && (i != 0))
    814  1.1   dyoung 				RTW_DPRINTF(("\n\t"));
    815  1.1   dyoung 			RTW_DPRINTF((" %04x", sr->sr_content[i]));
    816  1.1   dyoung 		}
    817  1.1   dyoung 		RTW_DPRINTF(("\n"));
    818  1.1   dyoung 	}
    819  1.1   dyoung #endif /* RTW_DEBUG */
    820  1.1   dyoung 	return 0;
    821  1.1   dyoung }
    822  1.1   dyoung 
    823  1.4   dyoung static void
    824  1.4   dyoung rtw_set_rfprog(struct rtw_regs *regs, enum rtw_rfchipid rfchipid,
    825  1.4   dyoung     const char *dvname)
    826  1.4   dyoung {
    827  1.4   dyoung 	u_int8_t cfg4;
    828  1.4   dyoung 	const char *method;
    829  1.4   dyoung 
    830  1.4   dyoung 	cfg4 = RTW_READ8(regs, RTW_CONFIG4) & ~RTW_CONFIG4_RFTYPE_MASK;
    831  1.4   dyoung 
    832  1.4   dyoung 	switch (rfchipid) {
    833  1.4   dyoung 	default:
    834  1.4   dyoung 		cfg4 |= LSHIFT(rtw_rfprog_fallback, RTW_CONFIG4_RFTYPE_MASK);
    835  1.4   dyoung 		method = "fallback";
    836  1.4   dyoung 		break;
    837  1.4   dyoung 	case RTW_RFCHIPID_INTERSIL:
    838  1.4   dyoung 		cfg4 |= RTW_CONFIG4_RFTYPE_INTERSIL;
    839  1.4   dyoung 		method = "Intersil";
    840  1.4   dyoung 		break;
    841  1.4   dyoung 	case RTW_RFCHIPID_PHILIPS:
    842  1.4   dyoung 		cfg4 |= RTW_CONFIG4_RFTYPE_PHILIPS;
    843  1.4   dyoung 		method = "Philips";
    844  1.4   dyoung 		break;
    845  1.4   dyoung 	case RTW_RFCHIPID_RFMD:
    846  1.4   dyoung 		cfg4 |= RTW_CONFIG4_RFTYPE_RFMD;
    847  1.4   dyoung 		method = "RFMD";
    848  1.4   dyoung 		break;
    849  1.4   dyoung 	}
    850  1.4   dyoung 
    851  1.4   dyoung 	RTW_WRITE8(regs, RTW_CONFIG4, cfg4);
    852  1.4   dyoung 
    853  1.4   dyoung 	printf("%s: %s RF programming method, %#02x\n", dvname, method,
    854  1.4   dyoung 	    RTW_READ8(regs, RTW_CONFIG4));
    855  1.4   dyoung }
    856  1.4   dyoung 
    857  1.1   dyoung #if 0
    858  1.1   dyoung static __inline int
    859  1.1   dyoung rtw_identify_rf(struct rtw_regs *regs, enum rtw_rftype *rftype,
    860  1.7   dyoung     const char *dvname)
    861  1.1   dyoung {
    862  1.1   dyoung 	u_int8_t cfg4;
    863  1.1   dyoung 	const char *name;
    864  1.1   dyoung 
    865  1.1   dyoung 	cfg4 = RTW_READ8(regs, RTW_CONFIG4);
    866  1.1   dyoung 
    867  1.1   dyoung 	switch (cfg4 & RTW_CONFIG4_RFTYPE_MASK) {
    868  1.1   dyoung 	case RTW_CONFIG4_RFTYPE_PHILIPS:
    869  1.1   dyoung 		*rftype = RTW_RFTYPE_PHILIPS;
    870  1.1   dyoung 		name = "Philips";
    871  1.1   dyoung 		break;
    872  1.1   dyoung 	case RTW_CONFIG4_RFTYPE_INTERSIL:
    873  1.1   dyoung 		*rftype = RTW_RFTYPE_INTERSIL;
    874  1.1   dyoung 		name = "Intersil";
    875  1.1   dyoung 		break;
    876  1.1   dyoung 	case RTW_CONFIG4_RFTYPE_RFMD:
    877  1.1   dyoung 		*rftype = RTW_RFTYPE_RFMD;
    878  1.1   dyoung 		name = "RFMD";
    879  1.1   dyoung 		break;
    880  1.1   dyoung 	default:
    881  1.1   dyoung 		name = "<unknown>";
    882  1.1   dyoung 		return ENXIO;
    883  1.1   dyoung 	}
    884  1.1   dyoung 
    885  1.7   dyoung 	printf("%s: RF prog type %s\n", dvname, name);
    886  1.1   dyoung 	return 0;
    887  1.1   dyoung }
    888  1.1   dyoung #endif
    889  1.1   dyoung 
    890  1.1   dyoung static __inline void
    891  1.1   dyoung rtw_init_channels(enum rtw_locale locale,
    892  1.1   dyoung     struct ieee80211_channel (*chans)[IEEE80211_CHAN_MAX+1],
    893  1.7   dyoung     const char *dvname)
    894  1.1   dyoung {
    895  1.1   dyoung 	int i;
    896  1.1   dyoung 	const char *name = NULL;
    897  1.1   dyoung #define ADD_CHANNEL(_chans, _chan) do {			\
    898  1.1   dyoung 	(*_chans)[_chan].ic_flags = IEEE80211_CHAN_B;		\
    899  1.1   dyoung 	(*_chans)[_chan].ic_freq =				\
    900  1.1   dyoung 	    ieee80211_ieee2mhz(_chan, (*_chans)[_chan].ic_flags);\
    901  1.1   dyoung } while (0)
    902  1.1   dyoung 
    903  1.1   dyoung 	switch (locale) {
    904  1.1   dyoung 	case RTW_LOCALE_USA:	/* 1-11 */
    905  1.1   dyoung 		name = "USA";
    906  1.1   dyoung 		for (i = 1; i <= 11; i++)
    907  1.1   dyoung 			ADD_CHANNEL(chans, i);
    908  1.1   dyoung 		break;
    909  1.1   dyoung 	case RTW_LOCALE_JAPAN:	/* 1-14 */
    910  1.1   dyoung 		name = "Japan";
    911  1.1   dyoung 		ADD_CHANNEL(chans, 14);
    912  1.1   dyoung 		for (i = 1; i <= 14; i++)
    913  1.1   dyoung 			ADD_CHANNEL(chans, i);
    914  1.1   dyoung 		break;
    915  1.1   dyoung 	case RTW_LOCALE_EUROPE:	/* 1-13 */
    916  1.1   dyoung 		name = "Europe";
    917  1.1   dyoung 		for (i = 1; i <= 13; i++)
    918  1.1   dyoung 			ADD_CHANNEL(chans, i);
    919  1.1   dyoung 		break;
    920  1.1   dyoung 	default:			/* 10-11 allowed by most countries */
    921  1.1   dyoung 		name = "<unknown>";
    922  1.1   dyoung 		for (i = 10; i <= 11; i++)
    923  1.1   dyoung 			ADD_CHANNEL(chans, i);
    924  1.1   dyoung 		break;
    925  1.1   dyoung 	}
    926  1.7   dyoung 	printf("%s: Geographic Location %s\n", dvname, name);
    927  1.1   dyoung #undef ADD_CHANNEL
    928  1.1   dyoung }
    929  1.1   dyoung 
    930  1.1   dyoung static __inline void
    931  1.1   dyoung rtw_identify_country(struct rtw_regs *regs, enum rtw_locale *locale,
    932  1.7   dyoung     const char *dvname)
    933  1.1   dyoung {
    934  1.1   dyoung 	u_int8_t cfg0 = RTW_READ8(regs, RTW_CONFIG0);
    935  1.1   dyoung 
    936  1.1   dyoung 	switch (cfg0 & RTW_CONFIG0_GL_MASK) {
    937  1.1   dyoung 	case RTW_CONFIG0_GL_USA:
    938  1.1   dyoung 		*locale = RTW_LOCALE_USA;
    939  1.1   dyoung 		break;
    940  1.1   dyoung 	case RTW_CONFIG0_GL_JAPAN:
    941  1.1   dyoung 		*locale = RTW_LOCALE_JAPAN;
    942  1.1   dyoung 		break;
    943  1.1   dyoung 	case RTW_CONFIG0_GL_EUROPE:
    944  1.1   dyoung 		*locale = RTW_LOCALE_EUROPE;
    945  1.1   dyoung 		break;
    946  1.1   dyoung 	default:
    947  1.1   dyoung 		*locale = RTW_LOCALE_UNKNOWN;
    948  1.1   dyoung 		break;
    949  1.1   dyoung 	}
    950  1.1   dyoung }
    951  1.1   dyoung 
    952  1.1   dyoung static __inline int
    953  1.1   dyoung rtw_identify_sta(struct rtw_regs *regs, u_int8_t (*addr)[IEEE80211_ADDR_LEN],
    954  1.7   dyoung     const char *dvname)
    955  1.1   dyoung {
    956  1.1   dyoung 	static const u_int8_t empty_macaddr[IEEE80211_ADDR_LEN] = {
    957  1.1   dyoung 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    958  1.1   dyoung 	};
    959  1.1   dyoung 	u_int32_t idr0 = RTW_READ(regs, RTW_IDR0),
    960  1.1   dyoung 	          idr1 = RTW_READ(regs, RTW_IDR1);
    961  1.1   dyoung 
    962  1.1   dyoung 	(*addr)[0] = MASK_AND_RSHIFT(idr0, BITS(0,  7));
    963  1.1   dyoung 	(*addr)[1] = MASK_AND_RSHIFT(idr0, BITS(8,  15));
    964  1.1   dyoung 	(*addr)[2] = MASK_AND_RSHIFT(idr0, BITS(16, 23));
    965  1.1   dyoung 	(*addr)[3] = MASK_AND_RSHIFT(idr0, BITS(24 ,31));
    966  1.1   dyoung 
    967  1.1   dyoung 	(*addr)[4] = MASK_AND_RSHIFT(idr1, BITS(0,  7));
    968  1.1   dyoung 	(*addr)[5] = MASK_AND_RSHIFT(idr1, BITS(8, 15));
    969  1.1   dyoung 
    970  1.1   dyoung 	if (IEEE80211_ADDR_EQ(addr, empty_macaddr)) {
    971  1.1   dyoung 		printf("%s: could not get mac address, attach failed\n",
    972  1.7   dyoung 		    dvname);
    973  1.1   dyoung 		return ENXIO;
    974  1.1   dyoung 	}
    975  1.1   dyoung 
    976  1.7   dyoung 	printf("%s: 802.11 address %s\n", dvname, ether_sprintf(*addr));
    977  1.1   dyoung 
    978  1.1   dyoung 	return 0;
    979  1.1   dyoung }
    980  1.1   dyoung 
    981  1.1   dyoung static u_int8_t
    982  1.1   dyoung rtw_chan2txpower(struct rtw_srom *sr, struct ieee80211com *ic,
    983  1.1   dyoung     struct ieee80211_channel *chan)
    984  1.1   dyoung {
    985  1.1   dyoung 	u_int idx = RTW_SR_TXPOWER1 + ieee80211_chan2ieee(ic, chan) - 1;
    986  1.1   dyoung 	KASSERT2(idx >= RTW_SR_TXPOWER1 && idx <= RTW_SR_TXPOWER14,
    987  1.1   dyoung 	    ("%s: channel %d out of range", __func__,
    988  1.1   dyoung 	     idx - RTW_SR_TXPOWER1 + 1));
    989  1.1   dyoung 	return RTW_SR_GET(sr, idx);
    990  1.1   dyoung }
    991  1.1   dyoung 
    992  1.1   dyoung static void
    993  1.3   dyoung rtw_txdesc_blk_init_all(struct rtw_txdesc_blk *htcs)
    994  1.1   dyoung {
    995  1.1   dyoung 	int pri;
    996  1.1   dyoung 	u_int ndesc[RTW_NTXPRI] =
    997  1.1   dyoung 	    {RTW_NTXDESCLO, RTW_NTXDESCMD, RTW_NTXDESCHI, RTW_NTXDESCBCN};
    998  1.1   dyoung 
    999  1.1   dyoung 	for (pri = 0; pri < RTW_NTXPRI; pri++) {
   1000  1.3   dyoung 		htcs[pri].htc_nfree = ndesc[pri];
   1001  1.3   dyoung 		htcs[pri].htc_next = 0;
   1002  1.1   dyoung 	}
   1003  1.1   dyoung }
   1004  1.1   dyoung 
   1005  1.1   dyoung static int
   1006  1.1   dyoung rtw_txctl_blk_init(struct rtw_txctl_blk *stc)
   1007  1.1   dyoung {
   1008  1.1   dyoung 	int i;
   1009  1.1   dyoung 	struct rtw_txctl *stx;
   1010  1.1   dyoung 
   1011  1.1   dyoung 	SIMPLEQ_INIT(&stc->stc_dirtyq);
   1012  1.1   dyoung 	SIMPLEQ_INIT(&stc->stc_freeq);
   1013  1.1   dyoung 	for (i = 0; i < stc->stc_ndesc; i++) {
   1014  1.1   dyoung 		stx = &stc->stc_desc[i];
   1015  1.1   dyoung 		stx->stx_mbuf = NULL;
   1016  1.1   dyoung 		SIMPLEQ_INSERT_TAIL(&stc->stc_freeq, stx, stx_q);
   1017  1.1   dyoung 	}
   1018  1.1   dyoung 	return 0;
   1019  1.1   dyoung }
   1020  1.1   dyoung 
   1021  1.1   dyoung static void
   1022  1.3   dyoung rtw_txctl_blk_init_all(struct rtw_txctl_blk *stcs)
   1023  1.1   dyoung {
   1024  1.1   dyoung 	int pri;
   1025  1.3   dyoung 	for (pri = 0; pri < RTW_NTXPRI; pri++)
   1026  1.3   dyoung 		rtw_txctl_blk_init(&stcs[pri]);
   1027  1.1   dyoung }
   1028  1.1   dyoung 
   1029  1.1   dyoung static __inline void
   1030  1.1   dyoung rtw_rxdescs_sync(bus_dma_tag_t dmat, bus_dmamap_t dmap, u_int desc0, u_int
   1031  1.1   dyoung     nsync, int ops)
   1032  1.1   dyoung {
   1033  1.1   dyoung 	/* sync to end of ring */
   1034  1.1   dyoung 	if (desc0 + nsync > RTW_NRXDESC) {
   1035  1.1   dyoung 		bus_dmamap_sync(dmat, dmap,
   1036  1.1   dyoung 		    offsetof(struct rtw_descs, hd_rx[desc0]),
   1037  1.1   dyoung 		    sizeof(struct rtw_rxdesc) * (RTW_NRXDESC - desc0), ops);
   1038  1.1   dyoung 		nsync -= (RTW_NRXDESC - desc0);
   1039  1.1   dyoung 		desc0 = 0;
   1040  1.1   dyoung 	}
   1041  1.1   dyoung 
   1042  1.1   dyoung 	/* sync what remains */
   1043  1.1   dyoung 	bus_dmamap_sync(dmat, dmap,
   1044  1.1   dyoung 	    offsetof(struct rtw_descs, hd_rx[desc0]),
   1045  1.1   dyoung 	    sizeof(struct rtw_rxdesc) * nsync, ops);
   1046  1.1   dyoung }
   1047  1.1   dyoung 
   1048  1.1   dyoung static void
   1049  1.1   dyoung rtw_txdescs_sync(bus_dma_tag_t dmat, bus_dmamap_t dmap,
   1050  1.1   dyoung     struct rtw_txdesc_blk *htc, u_int desc0, u_int nsync, int ops)
   1051  1.1   dyoung {
   1052  1.1   dyoung 	/* sync to end of ring */
   1053  1.1   dyoung 	if (desc0 + nsync > htc->htc_ndesc) {
   1054  1.1   dyoung 		bus_dmamap_sync(dmat, dmap,
   1055  1.1   dyoung 		    htc->htc_ofs + sizeof(struct rtw_txdesc) * desc0,
   1056  1.1   dyoung 		    sizeof(struct rtw_txdesc) * (htc->htc_ndesc - desc0),
   1057  1.1   dyoung 		    ops);
   1058  1.1   dyoung 		nsync -= (htc->htc_ndesc - desc0);
   1059  1.1   dyoung 		desc0 = 0;
   1060  1.1   dyoung 	}
   1061  1.1   dyoung 
   1062  1.1   dyoung 	/* sync what remains */
   1063  1.1   dyoung 	bus_dmamap_sync(dmat, dmap,
   1064  1.1   dyoung 	    htc->htc_ofs + sizeof(struct rtw_txdesc) * desc0,
   1065  1.1   dyoung 	    sizeof(struct rtw_txdesc) * nsync, ops);
   1066  1.1   dyoung }
   1067  1.1   dyoung 
   1068  1.1   dyoung static void
   1069  1.1   dyoung rtw_txdescs_sync_all(bus_dma_tag_t dmat, bus_dmamap_t dmap,
   1070  1.3   dyoung     struct rtw_txdesc_blk *htcs)
   1071  1.1   dyoung {
   1072  1.1   dyoung 	int pri;
   1073  1.1   dyoung 	for (pri = 0; pri < RTW_NTXPRI; pri++) {
   1074  1.1   dyoung 		rtw_txdescs_sync(dmat, dmap,
   1075  1.3   dyoung 		    &htcs[pri], 0, htcs[pri].htc_ndesc,
   1076  1.1   dyoung 		    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
   1077  1.1   dyoung 	}
   1078  1.1   dyoung }
   1079  1.1   dyoung 
   1080  1.1   dyoung static void
   1081  1.1   dyoung rtw_rxbufs_release(bus_dma_tag_t dmat, struct rtw_rxctl *desc)
   1082  1.1   dyoung {
   1083  1.1   dyoung 	int i;
   1084  1.1   dyoung 	struct rtw_rxctl *srx;
   1085  1.1   dyoung 
   1086  1.1   dyoung 	for (i = 0; i < RTW_NRXDESC; i++) {
   1087  1.1   dyoung 		srx = &desc[i];
   1088  1.5   dyoung 		bus_dmamap_sync(dmat, srx->srx_dmamap, 0,
   1089  1.5   dyoung 		    srx->srx_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
   1090  1.1   dyoung 		bus_dmamap_unload(dmat, srx->srx_dmamap);
   1091  1.1   dyoung 		m_freem(srx->srx_mbuf);
   1092  1.1   dyoung 		srx->srx_mbuf = NULL;
   1093  1.1   dyoung 	}
   1094  1.1   dyoung }
   1095  1.1   dyoung 
   1096  1.1   dyoung static __inline int
   1097  1.1   dyoung rtw_rxbuf_alloc(bus_dma_tag_t dmat, struct rtw_rxctl *srx)
   1098  1.1   dyoung {
   1099  1.1   dyoung 	int rc;
   1100  1.1   dyoung 	struct mbuf *m;
   1101  1.1   dyoung 
   1102  1.1   dyoung 	MGETHDR(m, M_DONTWAIT, MT_DATA);
   1103  1.1   dyoung 	if (m == NULL)
   1104  1.1   dyoung 		return ENOMEM;
   1105  1.1   dyoung 
   1106  1.1   dyoung 	MCLGET(m, M_DONTWAIT);
   1107  1.1   dyoung 	if (m == NULL)
   1108  1.1   dyoung 		return ENOMEM;
   1109  1.1   dyoung 
   1110  1.1   dyoung 	m->m_pkthdr.len = m->m_len = m->m_ext.ext_size;
   1111  1.1   dyoung 
   1112  1.1   dyoung 	rc = bus_dmamap_load_mbuf(dmat, srx->srx_dmamap, m, BUS_DMA_NOWAIT);
   1113  1.1   dyoung 	if (rc != 0)
   1114  1.1   dyoung 		return rc;
   1115  1.1   dyoung 
   1116  1.1   dyoung 	srx->srx_mbuf = m;
   1117  1.1   dyoung 
   1118  1.1   dyoung 	return 0;
   1119  1.1   dyoung }
   1120  1.1   dyoung 
   1121  1.1   dyoung static int
   1122  1.1   dyoung rtw_rxctl_init_all(bus_dma_tag_t dmat, struct rtw_rxctl *desc,
   1123  1.7   dyoung     u_int *next, const char *dvname)
   1124  1.1   dyoung {
   1125  1.1   dyoung 	int i, rc;
   1126  1.1   dyoung 	struct rtw_rxctl *srx;
   1127  1.1   dyoung 
   1128  1.1   dyoung 	for (i = 0; i < RTW_NRXDESC; i++) {
   1129  1.1   dyoung 		srx = &desc[i];
   1130  1.1   dyoung 		if ((rc = rtw_rxbuf_alloc(dmat, srx)) == 0)
   1131  1.1   dyoung 			continue;
   1132  1.1   dyoung 		printf("%s: failed rtw_rxbuf_alloc after %d buffers, rc = %d\n",
   1133  1.7   dyoung 		    dvname, i, rc);
   1134  1.1   dyoung 		if (i == 0) {
   1135  1.1   dyoung 			rtw_rxbufs_release(dmat, desc);
   1136  1.1   dyoung 			return rc;
   1137  1.1   dyoung 		}
   1138  1.1   dyoung 	}
   1139  1.1   dyoung 	*next = 0;
   1140  1.1   dyoung 	return 0;
   1141  1.1   dyoung }
   1142  1.1   dyoung 
   1143  1.1   dyoung static __inline void
   1144  1.1   dyoung rtw_rxdesc_init(bus_dma_tag_t dmat, bus_dmamap_t dmam,
   1145  1.1   dyoung     struct rtw_rxdesc *hrx, struct rtw_rxctl *srx, int idx)
   1146  1.1   dyoung {
   1147  1.1   dyoung 	int is_last = (idx == RTW_NRXDESC - 1);
   1148  1.1   dyoung 	uint32_t ctl;
   1149  1.1   dyoung 
   1150  1.1   dyoung 	hrx->hrx_buf = htole32(srx->srx_dmamap->dm_segs[0].ds_addr);
   1151  1.1   dyoung 
   1152  1.1   dyoung 	ctl = LSHIFT(srx->srx_mbuf->m_len, RTW_RXCTL_LENGTH_MASK) |
   1153  1.1   dyoung 	    RTW_RXCTL_OWN | RTW_RXCTL_FS | RTW_RXCTL_LS;
   1154  1.1   dyoung 
   1155  1.1   dyoung 	if (is_last)
   1156  1.1   dyoung 		ctl |= RTW_RXCTL_EOR;
   1157  1.1   dyoung 
   1158  1.1   dyoung 	hrx->hrx_ctl = htole32(ctl);
   1159  1.1   dyoung 
   1160  1.1   dyoung 	/* sync the mbuf */
   1161  1.1   dyoung 	bus_dmamap_sync(dmat, srx->srx_dmamap, 0, srx->srx_dmamap->dm_mapsize,
   1162  1.1   dyoung 	    BUS_DMASYNC_PREREAD);
   1163  1.1   dyoung 
   1164  1.1   dyoung 	/* sync the descriptor */
   1165  1.1   dyoung 	bus_dmamap_sync(dmat, dmam, RTW_DESC_OFFSET(hd_rx, idx),
   1166  1.1   dyoung 	    sizeof(struct rtw_rxdesc),
   1167  1.1   dyoung 	    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
   1168  1.1   dyoung }
   1169  1.1   dyoung 
   1170  1.1   dyoung static void
   1171  1.1   dyoung rtw_rxdesc_init_all(bus_dma_tag_t dmat, bus_dmamap_t dmam,
   1172  1.1   dyoung     struct rtw_rxdesc *desc, struct rtw_rxctl *ctl)
   1173  1.1   dyoung {
   1174  1.1   dyoung 	int i;
   1175  1.1   dyoung 	struct rtw_rxdesc *hrx;
   1176  1.1   dyoung 	struct rtw_rxctl *srx;
   1177  1.1   dyoung 
   1178  1.1   dyoung 	for (i = 0; i < RTW_NRXDESC; i++) {
   1179  1.1   dyoung 		hrx = &desc[i];
   1180  1.1   dyoung 		srx = &ctl[i];
   1181  1.1   dyoung 		rtw_rxdesc_init(dmat, dmam, hrx, srx, i);
   1182  1.1   dyoung 	}
   1183  1.1   dyoung }
   1184  1.1   dyoung 
   1185  1.1   dyoung static void
   1186  1.1   dyoung rtw_io_enable(struct rtw_regs *regs, u_int8_t flags, int enable)
   1187  1.1   dyoung {
   1188  1.1   dyoung 	u_int8_t cr;
   1189  1.1   dyoung 
   1190  1.1   dyoung 	RTW_DPRINTF(("%s: %s 0x%02x\n", __func__,
   1191  1.1   dyoung 	    enable ? "enable" : "disable", flags));
   1192  1.1   dyoung 
   1193  1.1   dyoung 	cr = RTW_READ8(regs, RTW_CR);
   1194  1.1   dyoung 
   1195  1.1   dyoung 	/* XXX reference source does not enable MULRW */
   1196  1.1   dyoung #if 0
   1197  1.1   dyoung 	/* enable PCI Read/Write Multiple */
   1198  1.1   dyoung 	cr |= RTW_CR_MULRW;
   1199  1.1   dyoung #endif
   1200  1.1   dyoung 
   1201  1.1   dyoung 	RTW_RBW(regs, RTW_CR, RTW_CR);	/* XXX paranoia? */
   1202  1.1   dyoung 	if (enable)
   1203  1.1   dyoung 		cr |= flags;
   1204  1.1   dyoung 	else
   1205  1.1   dyoung 		cr &= ~flags;
   1206  1.1   dyoung 	RTW_WRITE8(regs, RTW_CR, cr);
   1207  1.1   dyoung 	RTW_SYNC(regs, RTW_CR, RTW_CR);
   1208  1.1   dyoung }
   1209  1.1   dyoung 
   1210  1.1   dyoung static void
   1211  1.1   dyoung rtw_intr_rx(struct rtw_softc *sc, u_int16_t isr)
   1212  1.1   dyoung {
   1213  1.1   dyoung 	u_int next;
   1214  1.1   dyoung 	int rate, rssi;
   1215  1.1   dyoung 	u_int32_t hrssi, hstat, htsfth, htsftl;
   1216  1.1   dyoung 	struct rtw_rxdesc *hrx;
   1217  1.1   dyoung 	struct rtw_rxctl *srx;
   1218  1.1   dyoung 	struct mbuf *m;
   1219  1.1   dyoung 
   1220  1.1   dyoung 	struct ieee80211_node *ni;
   1221  1.1   dyoung 	struct ieee80211_frame *wh;
   1222  1.1   dyoung 
   1223  1.1   dyoung 	for (next = sc->sc_rxnext; ; next = (next + 1) % RTW_RXQLEN) {
   1224  1.1   dyoung 		rtw_rxdescs_sync(sc->sc_dmat, sc->sc_desc_dmamap,
   1225  1.1   dyoung 		    next, 1, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
   1226  1.1   dyoung 		hrx = &sc->sc_rxdesc[next];
   1227  1.1   dyoung 		srx = &sc->sc_rxctl[next];
   1228  1.1   dyoung 
   1229  1.1   dyoung 		hstat = le32toh(hrx->hrx_stat);
   1230  1.1   dyoung 		hrssi = le32toh(hrx->hrx_rssi);
   1231  1.1   dyoung 		htsfth = le32toh(hrx->hrx_tsfth);
   1232  1.1   dyoung 		htsftl = le32toh(hrx->hrx_tsftl);
   1233  1.1   dyoung 
   1234  1.1   dyoung 		RTW_DPRINTF2(("%s: rxdesc[%d] hstat %#08x hrssi %#08x "
   1235  1.1   dyoung 		    "htsft %#08x%08x\n", __func__, next,
   1236  1.1   dyoung 		    hstat, hrssi, htsfth, htsftl));
   1237  1.1   dyoung 
   1238  1.1   dyoung 		if ((hstat & RTW_RXSTAT_OWN) != 0) /* belongs to NIC */
   1239  1.1   dyoung 			break;
   1240  1.1   dyoung 
   1241  1.1   dyoung 		if ((hstat & RTW_RXSTAT_IOERROR) != 0) {
   1242  1.1   dyoung 			printf("%s: DMA error/FIFO overflow %08x, "
   1243  1.1   dyoung 			    "rx descriptor %d\n", sc->sc_dev.dv_xname,
   1244  1.1   dyoung 			    hstat & RTW_RXSTAT_IOERROR, next);
   1245  1.1   dyoung 			goto next;
   1246  1.1   dyoung 		}
   1247  1.1   dyoung 
   1248  1.1   dyoung 		switch (hstat & RTW_RXSTAT_RATE_MASK) {
   1249  1.1   dyoung 		case RTW_RXSTAT_RATE_1MBPS:
   1250  1.1   dyoung 			rate = 10;
   1251  1.1   dyoung 			break;
   1252  1.1   dyoung 		case RTW_RXSTAT_RATE_2MBPS:
   1253  1.1   dyoung 			rate = 20;
   1254  1.1   dyoung 			break;
   1255  1.1   dyoung 		case RTW_RXSTAT_RATE_5MBPS:
   1256  1.1   dyoung 			rate = 55;
   1257  1.1   dyoung 			break;
   1258  1.1   dyoung 		default:
   1259  1.1   dyoung #ifdef RTW_DEBUG
   1260  1.1   dyoung 			if (rtw_debug > 1)
   1261  1.1   dyoung 				printf("%s: interpreting rate #%d as 11 MB/s\n",
   1262  1.1   dyoung 				    sc->sc_dev.dv_xname,
   1263  1.1   dyoung 				    MASK_AND_RSHIFT(hstat,
   1264  1.1   dyoung 				        RTW_RXSTAT_RATE_MASK));
   1265  1.1   dyoung #endif /* RTW_DEBUG */
   1266  1.1   dyoung 			/*FALLTHROUGH*/
   1267  1.1   dyoung 		case RTW_RXSTAT_RATE_11MBPS:
   1268  1.1   dyoung 			rate = 110;
   1269  1.1   dyoung 			break;
   1270  1.1   dyoung 		}
   1271  1.1   dyoung 
   1272  1.1   dyoung 		RTW_DPRINTF2(("%s: rate %d\n", __func__, rate));
   1273  1.1   dyoung 
   1274  1.1   dyoung #ifdef RTW_DEBUG
   1275  1.1   dyoung #define PRINTSTAT(flag) do { \
   1276  1.1   dyoung 	if ((hstat & flag) != 0) { \
   1277  1.1   dyoung 		printf("%s" #flag, delim); \
   1278  1.1   dyoung 		delim = ","; \
   1279  1.1   dyoung 	} \
   1280  1.1   dyoung } while (0)
   1281  1.1   dyoung 		if (rtw_debug > 1) {
   1282  1.1   dyoung 			const char *delim = "<";
   1283  1.1   dyoung 			printf("%s: ", sc->sc_dev.dv_xname);
   1284  1.1   dyoung 			if ((hstat & RTW_RXSTAT_DEBUG) != 0) {
   1285  1.1   dyoung 				printf("status %08x<", hstat);
   1286  1.1   dyoung 				PRINTSTAT(RTW_RXSTAT_SPLCP);
   1287  1.1   dyoung 				PRINTSTAT(RTW_RXSTAT_MAR);
   1288  1.1   dyoung 				PRINTSTAT(RTW_RXSTAT_PAR);
   1289  1.1   dyoung 				PRINTSTAT(RTW_RXSTAT_BAR);
   1290  1.1   dyoung 				PRINTSTAT(RTW_RXSTAT_PWRMGT);
   1291  1.1   dyoung 				PRINTSTAT(RTW_RXSTAT_CRC32);
   1292  1.1   dyoung 				PRINTSTAT(RTW_RXSTAT_ICV);
   1293  1.1   dyoung 				printf(">, ");
   1294  1.1   dyoung 			}
   1295  1.1   dyoung 			printf("rate %d.%d Mb/s, time %08x%08x\n",
   1296  1.1   dyoung 			    rate / 10, rate % 10, htsfth, htsftl);
   1297  1.1   dyoung 		}
   1298  1.1   dyoung #endif /* RTW_DEBUG */
   1299  1.1   dyoung 
   1300  1.1   dyoung 		if ((hstat & RTW_RXSTAT_RES) != 0 &&
   1301  1.1   dyoung 		    sc->sc_ic.ic_opmode != IEEE80211_M_MONITOR)
   1302  1.1   dyoung 			goto next;
   1303  1.1   dyoung 
   1304  1.1   dyoung 		/* if bad flags, skip descriptor */
   1305  1.1   dyoung 		if ((hstat & RTW_RXSTAT_ONESEG) != RTW_RXSTAT_ONESEG) {
   1306  1.1   dyoung 			printf("%s: too many rx segments\n",
   1307  1.1   dyoung 			    sc->sc_dev.dv_xname);
   1308  1.1   dyoung 			goto next;
   1309  1.1   dyoung 		}
   1310  1.1   dyoung 
   1311  1.1   dyoung 		m = srx->srx_mbuf;
   1312  1.1   dyoung 
   1313  1.1   dyoung 		/* if temporarily out of memory, re-use mbuf */
   1314  1.1   dyoung 		if (rtw_rxbuf_alloc(sc->sc_dmat, srx) != 0) {
   1315  1.1   dyoung 			printf("%s: rtw_rxbuf_alloc(, %d) failed, "
   1316  1.1   dyoung 			    "dropping this packet\n", sc->sc_dev.dv_xname,
   1317  1.1   dyoung 			    next);
   1318  1.1   dyoung 			goto next;
   1319  1.1   dyoung 		}
   1320  1.1   dyoung 
   1321  1.1   dyoung 		if (sc->sc_rfchipid == RTW_RFCHIPID_PHILIPS)
   1322  1.1   dyoung 			rssi = MASK_AND_RSHIFT(hrssi, RTW_RXRSSI_RSSI);
   1323  1.1   dyoung 		else {
   1324  1.1   dyoung 			rssi = MASK_AND_RSHIFT(hrssi, RTW_RXRSSI_IMR_RSSI);
   1325  1.1   dyoung 			/* TBD find out each front-end's LNA gain in the
   1326  1.1   dyoung 			 * front-end's units
   1327  1.1   dyoung 			 */
   1328  1.1   dyoung 			if ((hrssi & RTW_RXRSSI_IMR_LNA) == 0)
   1329  1.1   dyoung 				rssi |= 0x80;
   1330  1.1   dyoung 		}
   1331  1.1   dyoung 
   1332  1.1   dyoung 		m->m_pkthdr.len = m->m_len =
   1333  1.1   dyoung 		    MASK_AND_RSHIFT(hstat, RTW_RXSTAT_LENGTH_MASK);
   1334  1.1   dyoung 		m->m_flags |= M_HASFCS;
   1335  1.1   dyoung 
   1336  1.3   dyoung 		if (m->m_pkthdr.len < IEEE80211_MIN_LEN) {
   1337  1.3   dyoung 			sc->sc_ic.ic_stats.is_rx_tooshort++;
   1338  1.3   dyoung 			goto next;
   1339  1.3   dyoung 		}
   1340  1.1   dyoung 		wh = mtod(m, struct ieee80211_frame *);
   1341  1.1   dyoung 		/* TBD use _MAR, _BAR, _PAR flags as hints to _find_rxnode? */
   1342  1.1   dyoung 		ni = ieee80211_find_rxnode(&sc->sc_ic, wh);
   1343  1.1   dyoung 
   1344  1.1   dyoung 		sc->sc_tsfth = htsfth;
   1345  1.1   dyoung 
   1346  1.1   dyoung 		ieee80211_input(&sc->sc_if, m, ni, rssi, htsftl);
   1347  1.1   dyoung 		ieee80211_release_node(&sc->sc_ic, ni);
   1348  1.1   dyoung next:
   1349  1.1   dyoung 		rtw_rxdesc_init(sc->sc_dmat, sc->sc_desc_dmamap,
   1350  1.1   dyoung 		    hrx, srx, next);
   1351  1.1   dyoung 	}
   1352  1.1   dyoung 	sc->sc_rxnext = next;
   1353  1.3   dyoung 
   1354  1.1   dyoung 	return;
   1355  1.1   dyoung }
   1356  1.1   dyoung 
   1357  1.1   dyoung static void
   1358  1.5   dyoung rtw_txbuf_release(bus_dma_tag_t dmat, struct ieee80211com *ic,
   1359  1.5   dyoung     struct rtw_txctl *stx)
   1360  1.5   dyoung {
   1361  1.5   dyoung 	struct mbuf *m;
   1362  1.5   dyoung 	struct ieee80211_node *ni;
   1363  1.5   dyoung 	bus_dmamap_t dmamap;
   1364  1.5   dyoung 
   1365  1.5   dyoung 	dmamap = stx->stx_dmamap;
   1366  1.5   dyoung 	m = stx->stx_mbuf;
   1367  1.5   dyoung 	ni = stx->stx_ni;
   1368  1.5   dyoung 	stx->stx_dmamap = NULL;
   1369  1.5   dyoung 	stx->stx_mbuf = NULL;
   1370  1.5   dyoung 	stx->stx_ni = NULL;
   1371  1.5   dyoung 
   1372  1.5   dyoung 	bus_dmamap_sync(dmat, dmamap, 0, dmamap->dm_mapsize,
   1373  1.5   dyoung 	    BUS_DMASYNC_POSTWRITE);
   1374  1.5   dyoung 	bus_dmamap_unload(dmat, dmamap);
   1375  1.5   dyoung 	m_freem(m);
   1376  1.5   dyoung 	ieee80211_release_node(ic, ni);
   1377  1.5   dyoung }
   1378  1.5   dyoung 
   1379  1.5   dyoung static void
   1380  1.5   dyoung rtw_txbufs_release(bus_dma_tag_t dmat, struct ieee80211com *ic,
   1381  1.5   dyoung     struct rtw_txctl_blk *stc)
   1382  1.5   dyoung {
   1383  1.5   dyoung 	struct rtw_txctl *stx;
   1384  1.5   dyoung 
   1385  1.5   dyoung 	while ((stx = SIMPLEQ_FIRST(&stc->stc_dirtyq)) != NULL) {
   1386  1.5   dyoung 		rtw_txbuf_release(dmat, ic, stx);
   1387  1.5   dyoung 		SIMPLEQ_REMOVE_HEAD(&stc->stc_dirtyq, stx_q);
   1388  1.6   dyoung 		SIMPLEQ_INSERT_TAIL(&stc->stc_freeq, stx, stx_q);
   1389  1.5   dyoung 	}
   1390  1.5   dyoung }
   1391  1.5   dyoung 
   1392  1.5   dyoung static __inline void
   1393  1.5   dyoung rtw_collect_txpkt(struct rtw_softc *sc, struct rtw_txdesc_blk *htc,
   1394  1.5   dyoung     struct rtw_txctl *stx, int ndesc)
   1395  1.5   dyoung {
   1396  1.5   dyoung 	int data_retry, rts_retry;
   1397  1.5   dyoung 	struct rtw_txdesc *htx0, *htxn;
   1398  1.5   dyoung 	const char *condstring;
   1399  1.5   dyoung 
   1400  1.5   dyoung 	rtw_txbuf_release(sc->sc_dmat, &sc->sc_ic, stx);
   1401  1.5   dyoung 
   1402  1.5   dyoung 	htc->htc_nfree += ndesc;
   1403  1.5   dyoung 
   1404  1.5   dyoung 	htx0 = &htc->htc_desc[stx->stx_first];
   1405  1.5   dyoung 	htxn = &htc->htc_desc[stx->stx_last];
   1406  1.5   dyoung 
   1407  1.5   dyoung 	rts_retry = MASK_AND_RSHIFT(le32toh(htx0->htx_stat),
   1408  1.5   dyoung 	    RTW_TXSTAT_RTSRETRY_MASK);
   1409  1.5   dyoung 	data_retry = MASK_AND_RSHIFT(le32toh(htx0->htx_stat),
   1410  1.5   dyoung 	    RTW_TXSTAT_DRC_MASK);
   1411  1.5   dyoung 
   1412  1.5   dyoung 	sc->sc_if.if_collisions += rts_retry + data_retry;
   1413  1.5   dyoung 
   1414  1.5   dyoung 	if ((htx0->htx_stat & htole32(RTW_TXSTAT_TOK)) != 0)
   1415  1.5   dyoung 		condstring = "ok";
   1416  1.5   dyoung 	else {
   1417  1.5   dyoung 		sc->sc_if.if_oerrors++;
   1418  1.5   dyoung 		condstring = "error";
   1419  1.5   dyoung 	}
   1420  1.5   dyoung 
   1421  1.5   dyoung 	DPRINTF2(sc, ("%s: stx %p txdesc[%d, %d] %s tries rts %u data %u\n",
   1422  1.5   dyoung 	    sc->sc_dev.dv_xname, stx, stx->stx_first, stx->stx_last,
   1423  1.5   dyoung 	    condstring, rts_retry, data_retry));
   1424  1.5   dyoung }
   1425  1.5   dyoung 
   1426  1.5   dyoung /* Collect transmitted packets. */
   1427  1.5   dyoung static __inline void
   1428  1.5   dyoung rtw_collect_txring(struct rtw_softc *sc, struct rtw_txctl_blk *stc,
   1429  1.5   dyoung     struct rtw_txdesc_blk *htc)
   1430  1.5   dyoung {
   1431  1.5   dyoung 	int ndesc;
   1432  1.5   dyoung 	struct rtw_txctl *stx;
   1433  1.5   dyoung 
   1434  1.5   dyoung 	while ((stx = SIMPLEQ_FIRST(&stc->stc_dirtyq)) != NULL) {
   1435  1.5   dyoung 		ndesc = 1 + stx->stx_last - stx->stx_first;
   1436  1.5   dyoung 		if (stx->stx_last < stx->stx_first)
   1437  1.5   dyoung 			ndesc += htc->htc_ndesc;
   1438  1.5   dyoung 
   1439  1.6   dyoung 		KASSERT(ndesc > 0);
   1440  1.6   dyoung 
   1441  1.5   dyoung 		rtw_txdescs_sync(sc->sc_dmat, sc->sc_desc_dmamap, htc,
   1442  1.5   dyoung 		    stx->stx_first, ndesc,
   1443  1.5   dyoung 		    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
   1444  1.5   dyoung 
   1445  1.5   dyoung 		if ((htc->htc_desc[stx->stx_first].htx_stat &
   1446  1.5   dyoung 		    htole32(RTW_TXSTAT_OWN)) != 0)
   1447  1.5   dyoung 			break;
   1448  1.5   dyoung 
   1449  1.5   dyoung 		rtw_collect_txpkt(sc, htc, stx, ndesc);
   1450  1.5   dyoung 		SIMPLEQ_REMOVE_HEAD(&stc->stc_dirtyq, stx_q);
   1451  1.6   dyoung 		SIMPLEQ_INSERT_TAIL(&stc->stc_freeq, stx, stx_q);
   1452  1.5   dyoung 		sc->sc_if.if_flags &= ~IFF_OACTIVE;
   1453  1.5   dyoung 	}
   1454  1.5   dyoung 	if (stx == NULL)
   1455  1.5   dyoung 		stc->stc_tx_timer = 0;
   1456  1.5   dyoung }
   1457  1.5   dyoung 
   1458  1.5   dyoung static void
   1459  1.1   dyoung rtw_intr_tx(struct rtw_softc *sc, u_int16_t isr)
   1460  1.1   dyoung {
   1461  1.5   dyoung 	int pri;
   1462  1.5   dyoung 	struct rtw_txctl_blk	*stc;
   1463  1.5   dyoung 	struct rtw_txdesc_blk	*htc;
   1464  1.5   dyoung 
   1465  1.5   dyoung 	for (pri = 0; pri < RTW_NTXPRI; pri++) {
   1466  1.5   dyoung 		stc = &sc->sc_txctl_blk[pri];
   1467  1.5   dyoung 		htc = &sc->sc_txdesc_blk[pri];
   1468  1.5   dyoung 
   1469  1.5   dyoung 		rtw_collect_txring(sc, stc, htc);
   1470  1.5   dyoung 
   1471  1.5   dyoung 		rtw_start(&sc->sc_if);
   1472  1.5   dyoung 	}
   1473  1.5   dyoung 
   1474  1.1   dyoung 	/* TBD */
   1475  1.1   dyoung 	return;
   1476  1.1   dyoung }
   1477  1.1   dyoung 
   1478  1.1   dyoung static void
   1479  1.1   dyoung rtw_intr_beacon(struct rtw_softc *sc, u_int16_t isr)
   1480  1.1   dyoung {
   1481  1.1   dyoung 	/* TBD */
   1482  1.1   dyoung 	return;
   1483  1.1   dyoung }
   1484  1.1   dyoung 
   1485  1.1   dyoung static void
   1486  1.1   dyoung rtw_intr_atim(struct rtw_softc *sc)
   1487  1.1   dyoung {
   1488  1.1   dyoung 	/* TBD */
   1489  1.1   dyoung 	return;
   1490  1.1   dyoung }
   1491  1.1   dyoung 
   1492  1.1   dyoung static void
   1493  1.3   dyoung rtw_hwring_setup(struct rtw_softc *sc)
   1494  1.3   dyoung {
   1495  1.3   dyoung 	struct rtw_regs *regs = &sc->sc_regs;
   1496  1.3   dyoung 	RTW_WRITE(regs, RTW_RDSAR, RTW_RING_BASE(sc, hd_rx));
   1497  1.3   dyoung 	RTW_WRITE(regs, RTW_TLPDA, RTW_RING_BASE(sc, hd_txlo));
   1498  1.3   dyoung 	RTW_WRITE(regs, RTW_TNPDA, RTW_RING_BASE(sc, hd_txmd));
   1499  1.3   dyoung 	RTW_WRITE(regs, RTW_THPDA, RTW_RING_BASE(sc, hd_txhi));
   1500  1.3   dyoung 	RTW_WRITE(regs, RTW_TBDA, RTW_RING_BASE(sc, hd_bcn));
   1501  1.3   dyoung }
   1502  1.3   dyoung 
   1503  1.3   dyoung static void
   1504  1.3   dyoung rtw_swring_setup(struct rtw_softc *sc)
   1505  1.3   dyoung {
   1506  1.3   dyoung 	rtw_txdesc_blk_init_all(&sc->sc_txdesc_blk[0]);
   1507  1.3   dyoung 
   1508  1.3   dyoung 	rtw_txctl_blk_init_all(&sc->sc_txctl_blk[0]);
   1509  1.3   dyoung 
   1510  1.3   dyoung 	rtw_rxctl_init_all(sc->sc_dmat, sc->sc_rxctl, &sc->sc_rxnext,
   1511  1.7   dyoung 	    sc->sc_dev.dv_xname);
   1512  1.3   dyoung 	rtw_rxdesc_init_all(sc->sc_dmat, sc->sc_desc_dmamap,
   1513  1.3   dyoung 	    sc->sc_rxdesc, sc->sc_rxctl);
   1514  1.3   dyoung 
   1515  1.3   dyoung 	rtw_txdescs_sync_all(sc->sc_dmat, sc->sc_desc_dmamap,
   1516  1.3   dyoung 	    &sc->sc_txdesc_blk[0]);
   1517  1.3   dyoung #if 0	/* redundant with rtw_rxdesc_init_all */
   1518  1.3   dyoung 	rtw_rxdescs_sync(sc->sc_dmat, sc->sc_desc_dmamap,
   1519  1.3   dyoung 	    0, RTW_NRXDESC, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
   1520  1.3   dyoung #endif
   1521  1.3   dyoung }
   1522  1.3   dyoung 
   1523  1.3   dyoung static void
   1524  1.3   dyoung rtw_kick(struct rtw_softc *sc)
   1525  1.3   dyoung {
   1526  1.5   dyoung 	int pri;
   1527  1.3   dyoung 	struct rtw_regs *regs = &sc->sc_regs;
   1528  1.5   dyoung 
   1529  1.3   dyoung 	rtw_io_enable(regs, RTW_CR_RE | RTW_CR_TE, 0);
   1530  1.3   dyoung 	RTW_WRITE16(regs, RTW_IMR, 0);
   1531  1.3   dyoung 	rtw_rxbufs_release(sc->sc_dmat, &sc->sc_rxctl[0]);
   1532  1.5   dyoung 	for (pri = 0; pri < RTW_NTXPRI; pri++) {
   1533  1.5   dyoung 		rtw_txbufs_release(sc->sc_dmat, &sc->sc_ic,
   1534  1.5   dyoung 		    &sc->sc_txctl_blk[pri]);
   1535  1.5   dyoung 	}
   1536  1.3   dyoung 	rtw_swring_setup(sc);
   1537  1.3   dyoung 	rtw_hwring_setup(sc);
   1538  1.3   dyoung 	RTW_WRITE16(regs, RTW_IMR, sc->sc_inten);
   1539  1.3   dyoung 	rtw_io_enable(regs, RTW_CR_RE | RTW_CR_TE, 1);
   1540  1.3   dyoung }
   1541  1.3   dyoung 
   1542  1.3   dyoung static void
   1543  1.1   dyoung rtw_intr_ioerror(struct rtw_softc *sc, u_int16_t isr)
   1544  1.1   dyoung {
   1545  1.1   dyoung 	if ((isr & (RTW_INTR_RDU|RTW_INTR_RXFOVW)) != 0) {
   1546  1.3   dyoung 		rtw_kick(sc);
   1547  1.1   dyoung 	}
   1548  1.1   dyoung 	if ((isr & RTW_INTR_TXFOVW) != 0)
   1549  1.1   dyoung 		;	/* TBD restart transmit engine */
   1550  1.1   dyoung 	return;
   1551  1.1   dyoung }
   1552  1.1   dyoung 
   1553  1.1   dyoung static __inline void
   1554  1.1   dyoung rtw_suspend_ticks(struct rtw_softc *sc)
   1555  1.1   dyoung {
   1556  1.1   dyoung 	printf("%s: suspending ticks\n", sc->sc_dev.dv_xname);
   1557  1.1   dyoung 	sc->sc_do_tick = 0;
   1558  1.1   dyoung }
   1559  1.1   dyoung 
   1560  1.1   dyoung static __inline void
   1561  1.1   dyoung rtw_resume_ticks(struct rtw_softc *sc)
   1562  1.1   dyoung {
   1563  1.1   dyoung 	u_int32_t tsftrl0, tsftrl1, next_tick;
   1564  1.1   dyoung 
   1565  1.1   dyoung 	tsftrl0 = RTW_READ(&sc->sc_regs, RTW_TSFTRL);
   1566  1.1   dyoung 
   1567  1.1   dyoung 	tsftrl1 = RTW_READ(&sc->sc_regs, RTW_TSFTRL);
   1568  1.4   dyoung 	next_tick = tsftrl1 + 1000000;
   1569  1.1   dyoung 	RTW_WRITE(&sc->sc_regs, RTW_TINT, next_tick);
   1570  1.1   dyoung 
   1571  1.1   dyoung 	sc->sc_do_tick = 1;
   1572  1.1   dyoung 
   1573  1.1   dyoung 	printf("%s: resume ticks delta %#08x now %#08x next %#08x\n",
   1574  1.1   dyoung 	    sc->sc_dev.dv_xname, tsftrl1 - tsftrl0, tsftrl1, next_tick);
   1575  1.1   dyoung }
   1576  1.1   dyoung 
   1577  1.1   dyoung static void
   1578  1.1   dyoung rtw_intr_timeout(struct rtw_softc *sc)
   1579  1.1   dyoung {
   1580  1.1   dyoung 	printf("%s: timeout\n", sc->sc_dev.dv_xname);
   1581  1.1   dyoung 	if (sc->sc_do_tick)
   1582  1.1   dyoung 		rtw_resume_ticks(sc);
   1583  1.1   dyoung 	return;
   1584  1.1   dyoung }
   1585  1.1   dyoung 
   1586  1.1   dyoung int
   1587  1.1   dyoung rtw_intr(void *arg)
   1588  1.1   dyoung {
   1589  1.3   dyoung 	int i;
   1590  1.1   dyoung 	struct rtw_softc *sc = arg;
   1591  1.1   dyoung 	struct rtw_regs *regs = &sc->sc_regs;
   1592  1.1   dyoung 	u_int16_t isr;
   1593  1.1   dyoung 
   1594  1.1   dyoung 	/*
   1595  1.1   dyoung 	 * If the interface isn't running, the interrupt couldn't
   1596  1.1   dyoung 	 * possibly have come from us.
   1597  1.1   dyoung 	 */
   1598  1.3   dyoung 	if ((sc->sc_flags & RTW_F_ENABLED) == 0 ||
   1599  1.3   dyoung 	    (sc->sc_if.if_flags & IFF_RUNNING) == 0 ||
   1600  1.1   dyoung 	    (sc->sc_dev.dv_flags & DVF_ACTIVE) == 0) {
   1601  1.1   dyoung 		RTW_DPRINTF2(("%s: stray interrupt\n", sc->sc_dev.dv_xname));
   1602  1.1   dyoung 		return (0);
   1603  1.1   dyoung 	}
   1604  1.1   dyoung 
   1605  1.3   dyoung 	for (i = 0; i < 10; i++) {
   1606  1.1   dyoung 		isr = RTW_READ16(regs, RTW_ISR);
   1607  1.1   dyoung 
   1608  1.1   dyoung 		RTW_WRITE16(regs, RTW_ISR, isr);
   1609  1.1   dyoung 
   1610  1.1   dyoung 		if (sc->sc_intr_ack != NULL)
   1611  1.1   dyoung 			(*sc->sc_intr_ack)(regs);
   1612  1.1   dyoung 
   1613  1.1   dyoung 		if (isr == 0)
   1614  1.1   dyoung 			break;
   1615  1.1   dyoung 
   1616  1.1   dyoung #ifdef RTW_DEBUG
   1617  1.1   dyoung #define PRINTINTR(flag) do { \
   1618  1.1   dyoung 	if ((isr & flag) != 0) { \
   1619  1.1   dyoung 		printf("%s" #flag, delim); \
   1620  1.1   dyoung 		delim = ","; \
   1621  1.1   dyoung 	} \
   1622  1.1   dyoung } while (0)
   1623  1.1   dyoung 
   1624  1.1   dyoung 		if (rtw_debug > 1 && isr != 0) {
   1625  1.1   dyoung 			const char *delim = "<";
   1626  1.1   dyoung 
   1627  1.1   dyoung 			printf("%s: reg[ISR] = %x", sc->sc_dev.dv_xname, isr);
   1628  1.1   dyoung 
   1629  1.1   dyoung 			PRINTINTR(RTW_INTR_TXFOVW);
   1630  1.1   dyoung 			PRINTINTR(RTW_INTR_TIMEOUT);
   1631  1.1   dyoung 			PRINTINTR(RTW_INTR_BCNINT);
   1632  1.1   dyoung 			PRINTINTR(RTW_INTR_ATIMINT);
   1633  1.1   dyoung 			PRINTINTR(RTW_INTR_TBDER);
   1634  1.1   dyoung 			PRINTINTR(RTW_INTR_TBDOK);
   1635  1.1   dyoung 			PRINTINTR(RTW_INTR_THPDER);
   1636  1.1   dyoung 			PRINTINTR(RTW_INTR_THPDOK);
   1637  1.1   dyoung 			PRINTINTR(RTW_INTR_TNPDER);
   1638  1.1   dyoung 			PRINTINTR(RTW_INTR_TNPDOK);
   1639  1.1   dyoung 			PRINTINTR(RTW_INTR_RXFOVW);
   1640  1.1   dyoung 			PRINTINTR(RTW_INTR_RDU);
   1641  1.1   dyoung 			PRINTINTR(RTW_INTR_TLPDER);
   1642  1.1   dyoung 			PRINTINTR(RTW_INTR_TLPDOK);
   1643  1.1   dyoung 			PRINTINTR(RTW_INTR_RER);
   1644  1.1   dyoung 			PRINTINTR(RTW_INTR_ROK);
   1645  1.1   dyoung 
   1646  1.1   dyoung 			printf(">\n");
   1647  1.1   dyoung 		}
   1648  1.1   dyoung #undef PRINTINTR
   1649  1.1   dyoung #endif /* RTW_DEBUG */
   1650  1.1   dyoung 
   1651  1.1   dyoung 		if ((isr & RTW_INTR_RX) != 0)
   1652  1.1   dyoung 			rtw_intr_rx(sc, isr & RTW_INTR_RX);
   1653  1.1   dyoung 		if ((isr & RTW_INTR_TX) != 0)
   1654  1.1   dyoung 			rtw_intr_tx(sc, isr & RTW_INTR_TX);
   1655  1.1   dyoung 		if ((isr & RTW_INTR_BEACON) != 0)
   1656  1.1   dyoung 			rtw_intr_beacon(sc, isr & RTW_INTR_BEACON);
   1657  1.1   dyoung 		if ((isr & RTW_INTR_ATIMINT) != 0)
   1658  1.1   dyoung 			rtw_intr_atim(sc);
   1659  1.1   dyoung 		if ((isr & RTW_INTR_IOERROR) != 0)
   1660  1.1   dyoung 			rtw_intr_ioerror(sc, isr & RTW_INTR_IOERROR);
   1661  1.1   dyoung 		if ((isr & RTW_INTR_TIMEOUT) != 0)
   1662  1.1   dyoung 			rtw_intr_timeout(sc);
   1663  1.1   dyoung 	}
   1664  1.1   dyoung 
   1665  1.1   dyoung 	return 1;
   1666  1.1   dyoung }
   1667  1.1   dyoung 
   1668  1.1   dyoung static void
   1669  1.1   dyoung rtw_stop(struct ifnet *ifp, int disable)
   1670  1.1   dyoung {
   1671  1.5   dyoung 	int pri, s;
   1672  1.1   dyoung 	struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc;
   1673  1.1   dyoung 	struct ieee80211com *ic = &sc->sc_ic;
   1674  1.1   dyoung 	struct rtw_regs *regs = &sc->sc_regs;
   1675  1.1   dyoung 
   1676  1.3   dyoung 	if ((sc->sc_flags & RTW_F_ENABLED) == 0)
   1677  1.3   dyoung 		return;
   1678  1.3   dyoung 
   1679  1.1   dyoung 	rtw_suspend_ticks(sc);
   1680  1.1   dyoung 
   1681  1.3   dyoung 	s = splnet();
   1682  1.3   dyoung 
   1683  1.1   dyoung 	ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
   1684  1.1   dyoung 
   1685  1.3   dyoung 	if ((sc->sc_flags & RTW_F_INVALID) == 0) {
   1686  1.3   dyoung 		/* Disable interrupts. */
   1687  1.3   dyoung 		RTW_WRITE16(regs, RTW_IMR, 0);
   1688  1.3   dyoung 
   1689  1.3   dyoung 		/* Stop the transmit and receive processes. First stop DMA,
   1690  1.3   dyoung 		 * then disable receiver and transmitter.
   1691  1.3   dyoung 		 */
   1692  1.3   dyoung 		RTW_WRITE8(regs, RTW_TPPOLL,
   1693  1.3   dyoung 		    RTW_TPPOLL_SBQ|RTW_TPPOLL_SHPQ|RTW_TPPOLL_SNPQ|
   1694  1.3   dyoung 		    RTW_TPPOLL_SLPQ);
   1695  1.1   dyoung 
   1696  1.3   dyoung 		rtw_io_enable(&sc->sc_regs, RTW_CR_RE|RTW_CR_TE, 0);
   1697  1.3   dyoung 	}
   1698  1.1   dyoung 
   1699  1.5   dyoung 	for (pri = 0; pri < RTW_NTXPRI; pri++) {
   1700  1.5   dyoung 		rtw_txbufs_release(sc->sc_dmat, &sc->sc_ic,
   1701  1.5   dyoung 		    &sc->sc_txctl_blk[pri]);
   1702  1.5   dyoung 	}
   1703  1.1   dyoung 
   1704  1.1   dyoung 	if (disable) {
   1705  1.1   dyoung 		rtw_disable(sc);
   1706  1.1   dyoung 		rtw_rxbufs_release(sc->sc_dmat, &sc->sc_rxctl[0]);
   1707  1.1   dyoung 	}
   1708  1.1   dyoung 
   1709  1.1   dyoung 	/* Mark the interface as not running.  Cancel the watchdog timer. */
   1710  1.1   dyoung 	ifp->if_flags &= ~IFF_RUNNING;
   1711  1.1   dyoung 	ifp->if_timer = 0;
   1712  1.3   dyoung 
   1713  1.3   dyoung 	splx(s);
   1714  1.3   dyoung 
   1715  1.1   dyoung 	return;
   1716  1.1   dyoung }
   1717  1.1   dyoung 
   1718  1.1   dyoung const char *
   1719  1.1   dyoung rtw_pwrstate_string(enum rtw_pwrstate power)
   1720  1.1   dyoung {
   1721  1.1   dyoung 	switch (power) {
   1722  1.1   dyoung 	case RTW_ON:
   1723  1.1   dyoung 		return "on";
   1724  1.1   dyoung 	case RTW_SLEEP:
   1725  1.1   dyoung 		return "sleep";
   1726  1.1   dyoung 	case RTW_OFF:
   1727  1.1   dyoung 		return "off";
   1728  1.1   dyoung 	default:
   1729  1.1   dyoung 		return "unknown";
   1730  1.1   dyoung 	}
   1731  1.1   dyoung }
   1732  1.1   dyoung 
   1733  1.1   dyoung /* XXX I am using the RFMD settings gleaned from the reference
   1734  1.1   dyoung  * driver.
   1735  1.1   dyoung  */
   1736  1.1   dyoung static void
   1737  1.1   dyoung rtw_maxim_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power,
   1738  1.1   dyoung     int before_rf)
   1739  1.1   dyoung {
   1740  1.1   dyoung 	u_int32_t anaparm;
   1741  1.1   dyoung 
   1742  1.1   dyoung 	RTW_DPRINTF(("%s: power state %s, %s RF\n", __func__,
   1743  1.1   dyoung 	    rtw_pwrstate_string(power), (before_rf) ? "before" : "after"));
   1744  1.1   dyoung 
   1745  1.1   dyoung 	anaparm = RTW_READ(regs, RTW_ANAPARM);
   1746  1.1   dyoung 	anaparm &= ~(RTW_ANAPARM_RFPOW0_MASK|RTW_ANAPARM_RFPOW1_MASK);
   1747  1.1   dyoung 	anaparm &= ~RTW_ANAPARM_TXDACOFF;
   1748  1.1   dyoung 
   1749  1.1   dyoung 	switch (power) {
   1750  1.1   dyoung 	case RTW_OFF:
   1751  1.1   dyoung 		if (before_rf)
   1752  1.1   dyoung 			return;
   1753  1.1   dyoung 		anaparm |= RTW_ANAPARM_RFPOW0_RFMD_OFF;
   1754  1.1   dyoung 		anaparm |= RTW_ANAPARM_RFPOW1_RFMD_OFF;
   1755  1.1   dyoung 		anaparm |= RTW_ANAPARM_TXDACOFF;
   1756  1.1   dyoung 		break;
   1757  1.1   dyoung 	case RTW_SLEEP:
   1758  1.1   dyoung 		if (!before_rf)
   1759  1.1   dyoung 			return;
   1760  1.1   dyoung 		anaparm |= RTW_ANAPARM_RFPOW0_RFMD_SLEEP;
   1761  1.1   dyoung 		anaparm |= RTW_ANAPARM_RFPOW1_RFMD_SLEEP;
   1762  1.1   dyoung 		anaparm |= RTW_ANAPARM_TXDACOFF;
   1763  1.1   dyoung 		break;
   1764  1.1   dyoung 	case RTW_ON:
   1765  1.1   dyoung 		if (!before_rf)
   1766  1.1   dyoung 			return;
   1767  1.1   dyoung 		anaparm |= RTW_ANAPARM_RFPOW0_RFMD_ON;
   1768  1.1   dyoung 		anaparm |= RTW_ANAPARM_RFPOW1_RFMD_ON;
   1769  1.1   dyoung 		break;
   1770  1.1   dyoung 	}
   1771  1.1   dyoung 	RTW_WRITE(regs, RTW_ANAPARM, anaparm);
   1772  1.1   dyoung 	RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM);
   1773  1.1   dyoung }
   1774  1.1   dyoung 
   1775  1.1   dyoung static void
   1776  1.1   dyoung rtw_philips_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power,
   1777  1.1   dyoung     int before_rf)
   1778  1.1   dyoung {
   1779  1.1   dyoung 	u_int32_t anaparm;
   1780  1.1   dyoung 
   1781  1.1   dyoung 	RTW_DPRINTF(("%s: power state %s, %s RF\n", __func__,
   1782  1.1   dyoung 	    rtw_pwrstate_string(power), (before_rf) ? "before" : "after"));
   1783  1.1   dyoung 
   1784  1.1   dyoung 	anaparm = RTW_READ(regs, RTW_ANAPARM);
   1785  1.1   dyoung 	anaparm &= ~(RTW_ANAPARM_RFPOW0_MASK|RTW_ANAPARM_RFPOW1_MASK);
   1786  1.1   dyoung 	anaparm &= ~RTW_ANAPARM_TXDACOFF;
   1787  1.1   dyoung 
   1788  1.1   dyoung 	switch (power) {
   1789  1.1   dyoung 	case RTW_OFF:
   1790  1.1   dyoung 		if (before_rf)
   1791  1.1   dyoung 			return;
   1792  1.1   dyoung 		anaparm |= RTW_ANAPARM_RFPOW0_PHILIPS_OFF;
   1793  1.1   dyoung 		anaparm |= RTW_ANAPARM_RFPOW1_PHILIPS_OFF;
   1794  1.1   dyoung 		anaparm |= RTW_ANAPARM_TXDACOFF;
   1795  1.1   dyoung 		break;
   1796  1.1   dyoung 	case RTW_SLEEP:
   1797  1.1   dyoung 		if (!before_rf)
   1798  1.1   dyoung 			return;
   1799  1.1   dyoung 		anaparm |= RTW_ANAPARM_RFPOW0_PHILIPS_SLEEP;
   1800  1.1   dyoung 		anaparm |= RTW_ANAPARM_RFPOW1_PHILIPS_SLEEP;
   1801  1.1   dyoung 		anaparm |= RTW_ANAPARM_TXDACOFF;
   1802  1.1   dyoung 		break;
   1803  1.1   dyoung 	case RTW_ON:
   1804  1.1   dyoung 		if (!before_rf)
   1805  1.1   dyoung 			return;
   1806  1.1   dyoung 		anaparm |= RTW_ANAPARM_RFPOW0_PHILIPS_ON;
   1807  1.1   dyoung 		anaparm |= RTW_ANAPARM_RFPOW1_PHILIPS_ON;
   1808  1.1   dyoung 		break;
   1809  1.1   dyoung 	}
   1810  1.1   dyoung 	RTW_WRITE(regs, RTW_ANAPARM, anaparm);
   1811  1.1   dyoung 	RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM);
   1812  1.1   dyoung }
   1813  1.1   dyoung 
   1814  1.1   dyoung static void
   1815  1.1   dyoung rtw_pwrstate0(struct rtw_softc *sc, enum rtw_pwrstate power, int before_rf)
   1816  1.1   dyoung {
   1817  1.1   dyoung 	struct rtw_regs *regs = &sc->sc_regs;
   1818  1.1   dyoung 
   1819  1.3   dyoung 	rtw_set_access(sc, RTW_ACCESS_ANAPARM);
   1820  1.1   dyoung 
   1821  1.1   dyoung 	(*sc->sc_pwrstate_cb)(regs, power, before_rf);
   1822  1.1   dyoung 
   1823  1.3   dyoung 	rtw_set_access(sc, RTW_ACCESS_NONE);
   1824  1.1   dyoung 
   1825  1.1   dyoung 	return;
   1826  1.1   dyoung }
   1827  1.1   dyoung 
   1828  1.1   dyoung static int
   1829  1.1   dyoung rtw_pwrstate(struct rtw_softc *sc, enum rtw_pwrstate power)
   1830  1.1   dyoung {
   1831  1.1   dyoung 	int rc;
   1832  1.1   dyoung 
   1833  1.1   dyoung 	RTW_DPRINTF2(("%s: %s->%s\n", __func__,
   1834  1.1   dyoung 	    rtw_pwrstate_string(sc->sc_pwrstate), rtw_pwrstate_string(power)));
   1835  1.1   dyoung 
   1836  1.1   dyoung 	if (sc->sc_pwrstate == power)
   1837  1.1   dyoung 		return 0;
   1838  1.1   dyoung 
   1839  1.1   dyoung 	rtw_pwrstate0(sc, power, 1);
   1840  1.1   dyoung 	rc = rtw_rf_pwrstate(sc->sc_rf, power);
   1841  1.1   dyoung 	rtw_pwrstate0(sc, power, 0);
   1842  1.1   dyoung 
   1843  1.1   dyoung 	switch (power) {
   1844  1.1   dyoung 	case RTW_ON:
   1845  1.4   dyoung 		/* TBD set LEDs */
   1846  1.1   dyoung 		break;
   1847  1.1   dyoung 	case RTW_SLEEP:
   1848  1.1   dyoung 		/* TBD */
   1849  1.1   dyoung 		break;
   1850  1.1   dyoung 	case RTW_OFF:
   1851  1.1   dyoung 		/* TBD */
   1852  1.1   dyoung 		break;
   1853  1.1   dyoung 	}
   1854  1.1   dyoung 	if (rc == 0)
   1855  1.1   dyoung 		sc->sc_pwrstate = power;
   1856  1.1   dyoung 	else
   1857  1.1   dyoung 		sc->sc_pwrstate = RTW_OFF;
   1858  1.1   dyoung 	return rc;
   1859  1.1   dyoung }
   1860  1.1   dyoung 
   1861  1.1   dyoung static int
   1862  1.1   dyoung rtw_tune(struct rtw_softc *sc)
   1863  1.1   dyoung {
   1864  1.1   dyoung 	struct ieee80211com *ic = &sc->sc_ic;
   1865  1.1   dyoung 	u_int chan;
   1866  1.1   dyoung 	int rc;
   1867  1.1   dyoung 	int antdiv = sc->sc_flags & RTW_F_ANTDIV,
   1868  1.1   dyoung 	    dflantb = sc->sc_flags & RTW_F_DFLANTB;
   1869  1.1   dyoung 
   1870  1.1   dyoung 	KASSERT(ic->ic_bss->ni_chan != NULL);
   1871  1.1   dyoung 
   1872  1.1   dyoung 	chan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
   1873  1.1   dyoung 	if (chan == IEEE80211_CHAN_ANY)
   1874  1.1   dyoung 		panic("%s: chan == IEEE80211_CHAN_ANY\n", __func__);
   1875  1.1   dyoung 
   1876  1.1   dyoung 	if (chan == sc->sc_cur_chan) {
   1877  1.1   dyoung 		RTW_DPRINTF(("%s: already tuned chan #%d\n", __func__, chan));
   1878  1.1   dyoung 		return 0;
   1879  1.1   dyoung 	}
   1880  1.1   dyoung 
   1881  1.1   dyoung 	rtw_suspend_ticks(sc);
   1882  1.1   dyoung 
   1883  1.1   dyoung 	rtw_io_enable(&sc->sc_regs, RTW_CR_RE | RTW_CR_TE, 0);
   1884  1.1   dyoung 
   1885  1.1   dyoung 	/* TBD wait for Tx to complete */
   1886  1.1   dyoung 
   1887  1.1   dyoung 	KASSERT((sc->sc_flags & RTW_F_ENABLED) != 0);
   1888  1.1   dyoung 
   1889  1.1   dyoung 	if ((rc = rtw_phy_init(&sc->sc_regs, sc->sc_rf,
   1890  1.1   dyoung 	    rtw_chan2txpower(&sc->sc_srom, ic, ic->ic_bss->ni_chan),
   1891  1.1   dyoung 	    sc->sc_csthr, ic->ic_bss->ni_chan->ic_freq, antdiv,
   1892  1.1   dyoung 	    dflantb, RTW_ON)) != 0) {
   1893  1.1   dyoung 		/* XXX condition on powersaving */
   1894  1.1   dyoung 		printf("%s: phy init failed\n", sc->sc_dev.dv_xname);
   1895  1.1   dyoung 	}
   1896  1.1   dyoung 
   1897  1.1   dyoung 	sc->sc_cur_chan = chan;
   1898  1.1   dyoung 
   1899  1.1   dyoung 	rtw_io_enable(&sc->sc_regs, RTW_CR_RE | RTW_CR_TE, 1);
   1900  1.1   dyoung 
   1901  1.1   dyoung 	rtw_resume_ticks(sc);
   1902  1.1   dyoung 
   1903  1.1   dyoung 	return rc;
   1904  1.1   dyoung }
   1905  1.1   dyoung 
   1906  1.1   dyoung void
   1907  1.1   dyoung rtw_disable(struct rtw_softc *sc)
   1908  1.1   dyoung {
   1909  1.1   dyoung 	int rc;
   1910  1.1   dyoung 
   1911  1.1   dyoung 	if ((sc->sc_flags & RTW_F_ENABLED) == 0)
   1912  1.1   dyoung 		return;
   1913  1.1   dyoung 
   1914  1.1   dyoung 	/* turn off PHY */
   1915  1.1   dyoung 	if ((rc = rtw_pwrstate(sc, RTW_OFF)) != 0)
   1916  1.1   dyoung 		printf("%s: failed to turn off PHY (%d)\n",
   1917  1.1   dyoung 		    sc->sc_dev.dv_xname, rc);
   1918  1.1   dyoung 
   1919  1.1   dyoung 	if (sc->sc_disable != NULL)
   1920  1.1   dyoung 		(*sc->sc_disable)(sc);
   1921  1.1   dyoung 
   1922  1.1   dyoung 	sc->sc_flags &= ~RTW_F_ENABLED;
   1923  1.1   dyoung }
   1924  1.1   dyoung 
   1925  1.1   dyoung int
   1926  1.1   dyoung rtw_enable(struct rtw_softc *sc)
   1927  1.1   dyoung {
   1928  1.1   dyoung 	if ((sc->sc_flags & RTW_F_ENABLED) == 0) {
   1929  1.1   dyoung 		if (sc->sc_enable != NULL && (*sc->sc_enable)(sc) != 0) {
   1930  1.1   dyoung 			printf("%s: device enable failed\n",
   1931  1.1   dyoung 			    sc->sc_dev.dv_xname);
   1932  1.1   dyoung 			return (EIO);
   1933  1.1   dyoung 		}
   1934  1.1   dyoung 		sc->sc_flags |= RTW_F_ENABLED;
   1935  1.1   dyoung 	}
   1936  1.1   dyoung 	return (0);
   1937  1.1   dyoung }
   1938  1.1   dyoung 
   1939  1.1   dyoung static void
   1940  1.1   dyoung rtw_transmit_config(struct rtw_regs *regs)
   1941  1.1   dyoung {
   1942  1.1   dyoung 	u_int32_t tcr;
   1943  1.1   dyoung 
   1944  1.1   dyoung 	tcr = RTW_READ(regs, RTW_TCR);
   1945  1.1   dyoung 
   1946  1.1   dyoung 	tcr |= RTW_TCR_SAT;		/* send ACK as fast as possible */
   1947  1.1   dyoung 	tcr &= ~RTW_TCR_LBK_MASK;
   1948  1.1   dyoung 	tcr |= RTW_TCR_LBK_NORMAL;	/* normal operating mode */
   1949  1.1   dyoung 
   1950  1.1   dyoung 	/* set short/long retry limits */
   1951  1.1   dyoung 	tcr &= ~(RTW_TCR_SRL_MASK|RTW_TCR_LRL_MASK);
   1952  1.1   dyoung 	tcr |= LSHIFT(7, RTW_TCR_SRL_MASK) | LSHIFT(7, RTW_TCR_LRL_MASK);
   1953  1.1   dyoung 
   1954  1.1   dyoung 	tcr |= RTW_TCR_CRC;	/* NIC appends CRC32 */
   1955  1.1   dyoung 
   1956  1.1   dyoung 	RTW_WRITE(regs, RTW_TCR, tcr);
   1957  1.1   dyoung }
   1958  1.1   dyoung 
   1959  1.1   dyoung static __inline void
   1960  1.1   dyoung rtw_enable_interrupts(struct rtw_softc *sc)
   1961  1.1   dyoung {
   1962  1.1   dyoung 	struct rtw_regs *regs = &sc->sc_regs;
   1963  1.1   dyoung 
   1964  1.1   dyoung 	sc->sc_inten = RTW_INTR_RX|RTW_INTR_TX|RTW_INTR_BEACON|RTW_INTR_ATIMINT;
   1965  1.1   dyoung 	sc->sc_inten |= RTW_INTR_IOERROR|RTW_INTR_TIMEOUT;
   1966  1.1   dyoung 
   1967  1.1   dyoung 	RTW_WRITE16(regs, RTW_IMR, sc->sc_inten);
   1968  1.1   dyoung 	RTW_WRITE16(regs, RTW_ISR, 0xffff);
   1969  1.1   dyoung 
   1970  1.1   dyoung 	/* XXX necessary? */
   1971  1.1   dyoung 	if (sc->sc_intr_ack != NULL)
   1972  1.1   dyoung 		(*sc->sc_intr_ack)(regs);
   1973  1.1   dyoung }
   1974  1.1   dyoung 
   1975  1.1   dyoung /* XXX is the endianness correct? test. */
   1976  1.1   dyoung #define	rtw_calchash(addr) \
   1977  1.1   dyoung 	(ether_crc32_le((addr), IEEE80211_ADDR_LEN) & BITS(5, 0))
   1978  1.1   dyoung 
   1979  1.1   dyoung static void
   1980  1.1   dyoung rtw_pktfilt_load(struct rtw_softc *sc)
   1981  1.1   dyoung {
   1982  1.1   dyoung 	struct rtw_regs *regs = &sc->sc_regs;
   1983  1.1   dyoung 	struct ieee80211com *ic = &sc->sc_ic;
   1984  1.1   dyoung 	struct ethercom *ec = &ic->ic_ec;
   1985  1.1   dyoung 	struct ifnet *ifp = &sc->sc_ic.ic_if;
   1986  1.1   dyoung 	int hash;
   1987  1.1   dyoung 	u_int32_t hashes[2] = { 0, 0 };
   1988  1.1   dyoung 	struct ether_multi *enm;
   1989  1.1   dyoung 	struct ether_multistep step;
   1990  1.1   dyoung 
   1991  1.1   dyoung 	/* XXX might be necessary to stop Rx/Tx engines while setting filters */
   1992  1.1   dyoung 
   1993  1.1   dyoung #define RTW_RCR_MONITOR (RTW_RCR_ACRC32|RTW_RCR_APM|RTW_RCR_AAP|RTW_RCR_AB)
   1994  1.1   dyoung 
   1995  1.1   dyoung 	if (ic->ic_opmode == IEEE80211_M_MONITOR)
   1996  1.1   dyoung 		sc->sc_rcr |= RTW_RCR_MONITOR;
   1997  1.1   dyoung 	else
   1998  1.1   dyoung 		sc->sc_rcr &= ~RTW_RCR_MONITOR;
   1999  1.1   dyoung 
   2000  1.1   dyoung 	/* XXX reference sources BEGIN */
   2001  1.1   dyoung 	sc->sc_rcr |= RTW_RCR_ENMARP | RTW_RCR_AICV | RTW_RCR_ACRC32;
   2002  1.1   dyoung 	sc->sc_rcr |= RTW_RCR_AB | RTW_RCR_AM | RTW_RCR_APM;
   2003  1.1   dyoung #if 0
   2004  1.1   dyoung 	/* receive broadcasts in our BSS */
   2005  1.1   dyoung 	sc->sc_rcr |= RTW_RCR_ADD3;
   2006  1.1   dyoung #endif
   2007  1.1   dyoung 	/* XXX reference sources END */
   2008  1.1   dyoung 
   2009  1.1   dyoung 	/* receive pwrmgmt frames. */
   2010  1.1   dyoung 	sc->sc_rcr |= RTW_RCR_APWRMGT;
   2011  1.1   dyoung 	/* receive mgmt/ctrl/data frames. */
   2012  1.1   dyoung 	sc->sc_rcr |= RTW_RCR_AMF | RTW_RCR_ACF | RTW_RCR_ADF;
   2013  1.1   dyoung 	/* initialize Rx DMA threshold, Tx DMA burst size */
   2014  1.1   dyoung 	sc->sc_rcr |= RTW_RCR_RXFTH_WHOLE | RTW_RCR_MXDMA_1024;
   2015  1.1   dyoung 
   2016  1.1   dyoung 	ifp->if_flags &= ~IFF_ALLMULTI;
   2017  1.1   dyoung 
   2018  1.1   dyoung 	if (ifp->if_flags & IFF_PROMISC) {
   2019  1.1   dyoung 		sc->sc_rcr |= RTW_RCR_AB;	/* accept all broadcast */
   2020  1.1   dyoung allmulti:
   2021  1.1   dyoung 		ifp->if_flags |= IFF_ALLMULTI;
   2022  1.1   dyoung 		goto setit;
   2023  1.1   dyoung 	}
   2024  1.1   dyoung 
   2025  1.1   dyoung 	/*
   2026  1.1   dyoung 	 * Program the 64-bit multicast hash filter.
   2027  1.1   dyoung 	 */
   2028  1.1   dyoung 	ETHER_FIRST_MULTI(step, ec, enm);
   2029  1.1   dyoung 	while (enm != NULL) {
   2030  1.1   dyoung 		/* XXX */
   2031  1.1   dyoung 		if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
   2032  1.1   dyoung 		    ETHER_ADDR_LEN) != 0)
   2033  1.1   dyoung 			goto allmulti;
   2034  1.1   dyoung 
   2035  1.1   dyoung 		hash = rtw_calchash(enm->enm_addrlo);
   2036  1.1   dyoung 		hashes[hash >> 5] |= 1 << (hash & 0x1f);
   2037  1.1   dyoung 		ETHER_NEXT_MULTI(step, enm);
   2038  1.1   dyoung 	}
   2039  1.1   dyoung 
   2040  1.1   dyoung 	if (ifp->if_flags & IFF_BROADCAST) {
   2041  1.1   dyoung 		hash = rtw_calchash(etherbroadcastaddr);
   2042  1.1   dyoung 		hashes[hash >> 5] |= 1 << (hash & 0x1f);
   2043  1.1   dyoung 	}
   2044  1.1   dyoung 
   2045  1.1   dyoung 	/* all bits set => hash is useless */
   2046  1.1   dyoung 	if (~(hashes[0] & hashes[1]) == 0)
   2047  1.1   dyoung 		goto allmulti;
   2048  1.1   dyoung 
   2049  1.1   dyoung  setit:
   2050  1.1   dyoung 	if (ifp->if_flags & IFF_ALLMULTI)
   2051  1.1   dyoung 		sc->sc_rcr |= RTW_RCR_AM;	/* accept all multicast */
   2052  1.1   dyoung 
   2053  1.1   dyoung 	if (ic->ic_state == IEEE80211_S_SCAN)
   2054  1.1   dyoung 		sc->sc_rcr |= RTW_RCR_AB;	/* accept all broadcast */
   2055  1.1   dyoung 
   2056  1.1   dyoung 	hashes[0] = hashes[1] = 0xffffffff;
   2057  1.1   dyoung 
   2058  1.1   dyoung 	RTW_WRITE(regs, RTW_MAR0, hashes[0]);
   2059  1.1   dyoung 	RTW_WRITE(regs, RTW_MAR1, hashes[1]);
   2060  1.1   dyoung 	RTW_WRITE(regs, RTW_RCR, sc->sc_rcr);
   2061  1.1   dyoung 	RTW_SYNC(regs, RTW_MAR0, RTW_RCR); /* RTW_MAR0 < RTW_MAR1 < RTW_RCR */
   2062  1.1   dyoung 
   2063  1.1   dyoung 	DPRINTF(sc, ("%s: RTW_MAR0 %08x RTW_MAR1 %08x RTW_RCR %08x\n",
   2064  1.1   dyoung 	    sc->sc_dev.dv_xname, RTW_READ(regs, RTW_MAR0),
   2065  1.1   dyoung 	    RTW_READ(regs, RTW_MAR1), RTW_READ(regs, RTW_RCR)));
   2066  1.1   dyoung 
   2067  1.1   dyoung 	return;
   2068  1.1   dyoung }
   2069  1.1   dyoung 
   2070  1.1   dyoung static int
   2071  1.1   dyoung rtw_init(struct ifnet *ifp)
   2072  1.1   dyoung {
   2073  1.1   dyoung 	struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc;
   2074  1.1   dyoung 	struct ieee80211com *ic = &sc->sc_ic;
   2075  1.1   dyoung 	struct rtw_regs *regs = &sc->sc_regs;
   2076  1.4   dyoung 	int rc = 0;
   2077  1.1   dyoung 
   2078  1.1   dyoung 	if ((rc = rtw_enable(sc)) != 0)
   2079  1.1   dyoung 		goto out;
   2080  1.1   dyoung 
   2081  1.1   dyoung 	/* Cancel pending I/O and reset. */
   2082  1.1   dyoung 	rtw_stop(ifp, 0);
   2083  1.1   dyoung 
   2084  1.1   dyoung 	ic->ic_bss->ni_chan = ic->ic_ibss_chan;
   2085  1.1   dyoung 	DPRINTF(sc, ("%s: channel %d freq %d flags 0x%04x\n",
   2086  1.1   dyoung 	    __func__, ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan),
   2087  1.1   dyoung 	    ic->ic_bss->ni_chan->ic_freq, ic->ic_bss->ni_chan->ic_flags));
   2088  1.1   dyoung 
   2089  1.1   dyoung 	if ((rc = rtw_pwrstate(sc, RTW_OFF)) != 0)
   2090  1.1   dyoung 		goto out;
   2091  1.1   dyoung 
   2092  1.3   dyoung 	rtw_swring_setup(sc);
   2093  1.1   dyoung 
   2094  1.1   dyoung 	rtw_transmit_config(regs);
   2095  1.1   dyoung 
   2096  1.3   dyoung 	rtw_set_access(sc, RTW_ACCESS_CONFIG);
   2097  1.1   dyoung 
   2098  1.4   dyoung 	RTW_WRITE8(regs, RTW_MSR, 0x0);	/* no link */
   2099  1.1   dyoung 
   2100  1.4   dyoung 	/* long PLCP header, 1Mbps basic rate */
   2101  1.4   dyoung 	RTW_WRITE16(regs, RTW_BRSR, 0x0);
   2102  1.1   dyoung 
   2103  1.3   dyoung 	rtw_set_access(sc, RTW_ACCESS_ANAPARM);
   2104  1.3   dyoung 	rtw_set_access(sc, RTW_ACCESS_NONE);
   2105  1.1   dyoung 
   2106  1.1   dyoung #if 0
   2107  1.1   dyoung 	RTW_WRITE(regs, RTW_FEMR, RTW_FEMR_GWAKE|RTW_FEMR_WKUP|RTW_FEMR_INTR);
   2108  1.1   dyoung #endif
   2109  1.1   dyoung 	/* XXX from reference sources */
   2110  1.1   dyoung 	RTW_WRITE(regs, RTW_FEMR, 0xffff);
   2111  1.1   dyoung 
   2112  1.4   dyoung 	rtw_set_rfprog(regs, sc->sc_rfchipid, sc->sc_dev.dv_xname);
   2113  1.4   dyoung 
   2114  1.4   dyoung 	RTW_WRITE8(regs, RTW_PHYDELAY, sc->sc_phydelay);
   2115  1.1   dyoung 	/* from Linux driver */
   2116  1.4   dyoung 	RTW_WRITE8(regs, RTW_CRCOUNT, RTW_CRCOUNT_MAGIC);
   2117  1.1   dyoung 
   2118  1.1   dyoung 	rtw_enable_interrupts(sc);
   2119  1.1   dyoung 
   2120  1.1   dyoung 	rtw_pktfilt_load(sc);
   2121  1.1   dyoung 
   2122  1.3   dyoung 	rtw_hwring_setup(sc);
   2123  1.1   dyoung 
   2124  1.1   dyoung 	rtw_io_enable(regs, RTW_CR_RE|RTW_CR_TE, 1);
   2125  1.1   dyoung 
   2126  1.1   dyoung 	ifp->if_flags |= IFF_RUNNING;
   2127  1.1   dyoung 	ic->ic_state = IEEE80211_S_INIT;
   2128  1.1   dyoung 
   2129  1.1   dyoung 	RTW_WRITE16(regs, RTW_BSSID16, 0x0);
   2130  1.1   dyoung 	RTW_WRITE(regs, RTW_BSSID32, 0x0);
   2131  1.1   dyoung 
   2132  1.4   dyoung 	rtw_resume_ticks(sc);
   2133  1.1   dyoung 
   2134  1.4   dyoung 	/* I'm guessing that MSR is protected as CONFIG[0123] are. */
   2135  1.4   dyoung 	rtw_set_access(sc, RTW_ACCESS_CONFIG);
   2136  1.1   dyoung 
   2137  1.1   dyoung 	switch (ic->ic_opmode) {
   2138  1.1   dyoung 	case IEEE80211_M_AHDEMO:
   2139  1.1   dyoung 	case IEEE80211_M_IBSS:
   2140  1.1   dyoung 		RTW_WRITE8(regs, RTW_MSR, RTW_MSR_NETYPE_ADHOC_OK);
   2141  1.1   dyoung 		break;
   2142  1.1   dyoung 	case IEEE80211_M_HOSTAP:
   2143  1.1   dyoung 		RTW_WRITE8(regs, RTW_MSR, RTW_MSR_NETYPE_AP_OK);
   2144  1.4   dyoung 		break;
   2145  1.1   dyoung 	case IEEE80211_M_MONITOR:
   2146  1.1   dyoung 		/* XXX */
   2147  1.1   dyoung 		RTW_WRITE8(regs, RTW_MSR, RTW_MSR_NETYPE_NOLINK);
   2148  1.4   dyoung 		break;
   2149  1.1   dyoung 	case IEEE80211_M_STA:
   2150  1.1   dyoung 		RTW_WRITE8(regs, RTW_MSR, RTW_MSR_NETYPE_INFRA_OK);
   2151  1.1   dyoung 		break;
   2152  1.1   dyoung 	}
   2153  1.4   dyoung 
   2154  1.4   dyoung 	rtw_set_access(sc, RTW_ACCESS_NONE);
   2155  1.4   dyoung 
   2156  1.4   dyoung 	if (ic->ic_opmode == IEEE80211_M_MONITOR)
   2157  1.4   dyoung 		return ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
   2158  1.4   dyoung 	else
   2159  1.4   dyoung 		return ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
   2160  1.4   dyoung 
   2161  1.1   dyoung out:
   2162  1.1   dyoung 	return rc;
   2163  1.1   dyoung }
   2164  1.1   dyoung 
   2165  1.1   dyoung static int
   2166  1.1   dyoung rtw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
   2167  1.1   dyoung {
   2168  1.1   dyoung 	int rc = 0;
   2169  1.1   dyoung 	struct rtw_softc *sc = ifp->if_softc;
   2170  1.1   dyoung 	struct ifreq *ifr = (struct ifreq *)data;
   2171  1.1   dyoung 
   2172  1.1   dyoung 	switch (cmd) {
   2173  1.1   dyoung 	case SIOCSIFFLAGS:
   2174  1.1   dyoung 		if ((ifp->if_flags & IFF_UP) != 0) {
   2175  1.1   dyoung 			if ((sc->sc_flags & RTW_F_ENABLED) != 0) {
   2176  1.1   dyoung 				rtw_pktfilt_load(sc);
   2177  1.1   dyoung 			} else
   2178  1.1   dyoung 				rc = rtw_init(ifp);
   2179  1.1   dyoung #ifdef RTW_DEBUG
   2180  1.1   dyoung 			rtw_print_regs(&sc->sc_regs, ifp->if_xname, __func__);
   2181  1.1   dyoung #endif /* RTW_DEBUG */
   2182  1.1   dyoung 		} else if ((sc->sc_flags & RTW_F_ENABLED) != 0) {
   2183  1.1   dyoung #ifdef RTW_DEBUG
   2184  1.1   dyoung 			rtw_print_regs(&sc->sc_regs, ifp->if_xname, __func__);
   2185  1.1   dyoung #endif /* RTW_DEBUG */
   2186  1.1   dyoung 			rtw_stop(ifp, 1);
   2187  1.1   dyoung 		}
   2188  1.1   dyoung 		break;
   2189  1.1   dyoung 	case SIOCADDMULTI:
   2190  1.1   dyoung 	case SIOCDELMULTI:
   2191  1.1   dyoung 		if (cmd == SIOCADDMULTI)
   2192  1.1   dyoung 			rc = ether_addmulti(ifr, &sc->sc_ic.ic_ec);
   2193  1.1   dyoung 		else
   2194  1.1   dyoung 			rc = ether_delmulti(ifr, &sc->sc_ic.ic_ec);
   2195  1.1   dyoung 		if (rc == ENETRESET) {
   2196  1.2  thorpej 			if (ifp->if_flags & IFF_RUNNING)
   2197  1.1   dyoung 				rtw_pktfilt_load(sc);
   2198  1.1   dyoung 			rc = 0;
   2199  1.1   dyoung 		}
   2200  1.1   dyoung 		break;
   2201  1.1   dyoung 	default:
   2202  1.1   dyoung 		if ((rc = ieee80211_ioctl(ifp, cmd, data)) == ENETRESET) {
   2203  1.1   dyoung 			if ((sc->sc_flags & RTW_F_ENABLED) != 0)
   2204  1.1   dyoung 				rc = rtw_init(ifp);
   2205  1.1   dyoung 			else
   2206  1.1   dyoung 				rc = 0;
   2207  1.1   dyoung 		}
   2208  1.1   dyoung 		break;
   2209  1.1   dyoung 	}
   2210  1.1   dyoung 	return rc;
   2211  1.1   dyoung }
   2212  1.1   dyoung 
   2213  1.1   dyoung /* Point *mp at the next 802.11 frame to transmit.  Point *stcp
   2214  1.1   dyoung  * at the driver's selection of transmit control block for the packet.
   2215  1.1   dyoung  */
   2216  1.1   dyoung static __inline int
   2217  1.5   dyoung rtw_dequeue(struct ifnet *ifp, struct rtw_txctl_blk **stcp,
   2218  1.5   dyoung     struct rtw_txdesc_blk **htcp, struct mbuf **mp,
   2219  1.1   dyoung     struct ieee80211_node **nip)
   2220  1.1   dyoung {
   2221  1.5   dyoung 	struct rtw_txctl_blk *stc;
   2222  1.5   dyoung 	struct rtw_txdesc_blk *htc;
   2223  1.1   dyoung 	struct mbuf *m0;
   2224  1.1   dyoung 	struct rtw_softc *sc;
   2225  1.1   dyoung 	struct ieee80211com *ic;
   2226  1.1   dyoung 
   2227  1.1   dyoung 	sc = (struct rtw_softc *)ifp->if_softc;
   2228  1.1   dyoung 
   2229  1.5   dyoung 	DPRINTF2(sc, ("%s: enter %s\n", sc->sc_dev.dv_xname, __func__));
   2230  1.1   dyoung 	*mp = NULL;
   2231  1.1   dyoung 
   2232  1.5   dyoung 	stc = &sc->sc_txctl_blk[RTW_TXPRIMD];
   2233  1.5   dyoung 	htc = &sc->sc_txdesc_blk[RTW_TXPRIMD];
   2234  1.5   dyoung 
   2235  1.5   dyoung 	if (SIMPLEQ_EMPTY(&stc->stc_freeq) || htc->htc_nfree == 0) {
   2236  1.5   dyoung 		DPRINTF2(sc, ("%s: out of descriptors\n", __func__));
   2237  1.5   dyoung 		ifp->if_flags |= IFF_OACTIVE;
   2238  1.5   dyoung 		return 0;
   2239  1.5   dyoung 	}
   2240  1.5   dyoung 
   2241  1.5   dyoung 	ic = &sc->sc_ic;
   2242  1.5   dyoung 
   2243  1.1   dyoung 	if (!IF_IS_EMPTY(&ic->ic_mgtq)) {
   2244  1.1   dyoung 		IF_DEQUEUE(&ic->ic_mgtq, m0);
   2245  1.1   dyoung 		*nip = (struct ieee80211_node *)m0->m_pkthdr.rcvif;
   2246  1.1   dyoung 		m0->m_pkthdr.rcvif = NULL;
   2247  1.5   dyoung 		DPRINTF2(sc, ("%s: dequeue mgt frame\n", __func__));
   2248  1.5   dyoung 	} else if (ic->ic_state != IEEE80211_S_RUN) {
   2249  1.5   dyoung 		DPRINTF2(sc, ("%s: not running\n", __func__));
   2250  1.1   dyoung 		return 0;
   2251  1.5   dyoung 	} else if (!IF_IS_EMPTY(&ic->ic_pwrsaveq)) {
   2252  1.1   dyoung 		IF_DEQUEUE(&ic->ic_pwrsaveq, m0);
   2253  1.1   dyoung 		*nip = (struct ieee80211_node *)m0->m_pkthdr.rcvif;
   2254  1.1   dyoung 		m0->m_pkthdr.rcvif = NULL;
   2255  1.5   dyoung 		DPRINTF2(sc, ("%s: dequeue pwrsave frame\n", __func__));
   2256  1.1   dyoung 	} else {
   2257  1.1   dyoung 		IFQ_POLL(&ifp->if_snd, m0);
   2258  1.5   dyoung 		if (m0 == NULL) {
   2259  1.5   dyoung 			DPRINTF2(sc, ("%s: no frame\n", __func__));
   2260  1.1   dyoung 			return 0;
   2261  1.5   dyoung 		}
   2262  1.5   dyoung 		DPRINTF2(sc, ("%s: dequeue data frame\n", __func__));
   2263  1.1   dyoung 		IFQ_DEQUEUE(&ifp->if_snd, m0);
   2264  1.1   dyoung 		ifp->if_opackets++;
   2265  1.1   dyoung #if NBPFILTER > 0
   2266  1.1   dyoung 		if (ifp->if_bpf)
   2267  1.1   dyoung 			bpf_mtap(ifp->if_bpf, m0);
   2268  1.1   dyoung #endif
   2269  1.1   dyoung 		if ((m0 = ieee80211_encap(ifp, m0, nip)) == NULL) {
   2270  1.5   dyoung 			DPRINTF2(sc, ("%s: encap error\n", __func__));
   2271  1.1   dyoung 			ifp->if_oerrors++;
   2272  1.1   dyoung 			return -1;
   2273  1.1   dyoung 		}
   2274  1.1   dyoung 	}
   2275  1.5   dyoung 	DPRINTF2(sc, ("%s: leave\n", __func__));
   2276  1.5   dyoung 	*stcp = stc;
   2277  1.5   dyoung 	*htcp = htc;
   2278  1.1   dyoung 	*mp = m0;
   2279  1.1   dyoung 	return 0;
   2280  1.1   dyoung }
   2281  1.1   dyoung 
   2282  1.5   dyoung /* TBD factor with atw_start */
   2283  1.5   dyoung static struct mbuf *
   2284  1.5   dyoung rtw_dmamap_load_txbuf(bus_dma_tag_t dmat, bus_dmamap_t dmam, struct mbuf *chain,
   2285  1.5   dyoung     u_int ndescfree, short *ifflagsp, const char *dvname)
   2286  1.5   dyoung {
   2287  1.5   dyoung 	int first, rc;
   2288  1.5   dyoung 	struct mbuf *m, *m0;
   2289  1.5   dyoung 
   2290  1.5   dyoung 	m0 = chain;
   2291  1.5   dyoung 
   2292  1.5   dyoung 	/*
   2293  1.5   dyoung 	 * Load the DMA map.  Copy and try (once) again if the packet
   2294  1.5   dyoung 	 * didn't fit in the alloted number of segments.
   2295  1.5   dyoung 	 */
   2296  1.5   dyoung 	for (first = 1;
   2297  1.5   dyoung 	     ((rc = bus_dmamap_load_mbuf(dmat, dmam, m0,
   2298  1.5   dyoung 			  BUS_DMA_WRITE|BUS_DMA_NOWAIT)) != 0 ||
   2299  1.5   dyoung 	      dmam->dm_nsegs > ndescfree) && first;
   2300  1.5   dyoung 	     first = 0) {
   2301  1.5   dyoung 		if (rc == 0)
   2302  1.5   dyoung 			bus_dmamap_unload(dmat, dmam);
   2303  1.5   dyoung 		MGETHDR(m, M_DONTWAIT, MT_DATA);
   2304  1.5   dyoung 		if (m == NULL) {
   2305  1.5   dyoung 			printf("%s: unable to allocate Tx mbuf\n",
   2306  1.5   dyoung 			    dvname);
   2307  1.5   dyoung 			break;
   2308  1.5   dyoung 		}
   2309  1.5   dyoung 		if (m0->m_pkthdr.len > MHLEN) {
   2310  1.5   dyoung 			MCLGET(m, M_DONTWAIT);
   2311  1.5   dyoung 			if ((m->m_flags & M_EXT) == 0) {
   2312  1.5   dyoung 				printf("%s: cannot allocate Tx cluster\n",
   2313  1.5   dyoung 				    dvname);
   2314  1.5   dyoung 				m_freem(m);
   2315  1.5   dyoung 				break;
   2316  1.5   dyoung 			}
   2317  1.5   dyoung 		}
   2318  1.5   dyoung 		m_copydata(m0, 0, m0->m_pkthdr.len, mtod(m, caddr_t));
   2319  1.5   dyoung 		m->m_pkthdr.len = m->m_len = m0->m_pkthdr.len;
   2320  1.5   dyoung 		m_freem(m0);
   2321  1.5   dyoung 		m0 = m;
   2322  1.5   dyoung 		m = NULL;
   2323  1.5   dyoung 	}
   2324  1.5   dyoung 	if (rc != 0) {
   2325  1.5   dyoung 		printf("%s: cannot load Tx buffer, rc = %d\n", dvname, rc);
   2326  1.5   dyoung 		m_freem(m0);
   2327  1.5   dyoung 		return NULL;
   2328  1.5   dyoung 	} else if (dmam->dm_nsegs > ndescfree) {
   2329  1.5   dyoung 		*ifflagsp |= IFF_OACTIVE;
   2330  1.5   dyoung 		bus_dmamap_unload(dmat, dmam);
   2331  1.5   dyoung 		m_freem(m0);
   2332  1.5   dyoung 		return NULL;
   2333  1.5   dyoung 	}
   2334  1.5   dyoung 	return m0;
   2335  1.5   dyoung }
   2336  1.5   dyoung 
   2337  1.1   dyoung static void
   2338  1.1   dyoung rtw_start(struct ifnet *ifp)
   2339  1.1   dyoung {
   2340  1.5   dyoung 	int desc, i, lastdesc, npkt, rate;
   2341  1.5   dyoung 	uint32_t proto_txctl0, txctl0, txctl1;
   2342  1.5   dyoung 	bus_dmamap_t		dmamap;
   2343  1.5   dyoung 	struct ieee80211com	*ic;
   2344  1.5   dyoung 	struct ieee80211_duration *d0;
   2345  1.5   dyoung 	struct ieee80211_frame	*wh;
   2346  1.5   dyoung 	struct ieee80211_node	*ni;
   2347  1.5   dyoung 	struct mbuf		*m0;
   2348  1.5   dyoung 	struct rtw_softc	*sc;
   2349  1.5   dyoung 	struct rtw_txctl_blk	*stc;
   2350  1.5   dyoung 	struct rtw_txdesc_blk	*htc;
   2351  1.5   dyoung 	struct rtw_txctl	*stx;
   2352  1.5   dyoung 	struct rtw_txdesc	*htx;
   2353  1.1   dyoung 
   2354  1.1   dyoung 	sc = (struct rtw_softc *)ifp->if_softc;
   2355  1.5   dyoung 	ic = &sc->sc_ic;
   2356  1.1   dyoung 
   2357  1.5   dyoung 	DPRINTF2(sc, ("%s: enter %s\n", sc->sc_dev.dv_xname, __func__));
   2358  1.5   dyoung 
   2359  1.5   dyoung 	/* XXX do real rate control */
   2360  1.5   dyoung 	proto_txctl0 = RTW_TXCTL0_RTSRATE_1MBPS;
   2361  1.5   dyoung 
   2362  1.5   dyoung 	switch (rate = MAX(2, ieee80211_get_rate(ic))) {
   2363  1.5   dyoung 	case 2:
   2364  1.5   dyoung 		proto_txctl0 |= RTW_TXCTL0_RATE_1MBPS;
   2365  1.5   dyoung 		break;
   2366  1.5   dyoung 	case 4:
   2367  1.5   dyoung 		proto_txctl0 |= RTW_TXCTL0_RATE_2MBPS;
   2368  1.5   dyoung 		break;
   2369  1.5   dyoung 	case 11:
   2370  1.5   dyoung 		proto_txctl0 |= RTW_TXCTL0_RATE_5MBPS;
   2371  1.5   dyoung 		break;
   2372  1.5   dyoung 	case 22:
   2373  1.5   dyoung 		proto_txctl0 |= RTW_TXCTL0_RATE_11MBPS;
   2374  1.5   dyoung 		break;
   2375  1.5   dyoung 	}
   2376  1.5   dyoung 
   2377  1.5   dyoung 	if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0)
   2378  1.5   dyoung 		proto_txctl0 |= RTW_TXCTL0_SPLCP;
   2379  1.5   dyoung 
   2380  1.5   dyoung 	for (;;) {
   2381  1.5   dyoung 		if (rtw_dequeue(ifp, &stc, &htc, &m0, &ni) == -1)
   2382  1.1   dyoung 			continue;
   2383  1.1   dyoung 		if (m0 == NULL)
   2384  1.1   dyoung 			break;
   2385  1.5   dyoung 		stx = SIMPLEQ_FIRST(&stc->stc_freeq);
   2386  1.5   dyoung 
   2387  1.5   dyoung 		dmamap = stx->stx_dmamap;
   2388  1.5   dyoung 
   2389  1.5   dyoung 		m0 = rtw_dmamap_load_txbuf(sc->sc_dmat, dmamap, m0,
   2390  1.5   dyoung 		    htc->htc_nfree, &ifp->if_flags, sc->sc_dev.dv_xname);
   2391  1.5   dyoung 
   2392  1.5   dyoung 		if (m0 == NULL || dmamap->dm_nsegs == 0) {
   2393  1.5   dyoung 			DPRINTF2(sc, ("%s: fail dmamap load\n", __func__));
   2394  1.5   dyoung 			goto post_dequeue_err;
   2395  1.5   dyoung 		}
   2396  1.5   dyoung 
   2397  1.5   dyoung 		txctl0 = proto_txctl0 |
   2398  1.5   dyoung 		    LSHIFT(m0->m_pkthdr.len, RTW_TXCTL0_TPKTSIZE_MASK);
   2399  1.5   dyoung 
   2400  1.5   dyoung 		wh = mtod(m0, struct ieee80211_frame *);
   2401  1.5   dyoung 
   2402  1.5   dyoung 		if (ieee80211_compute_duration(wh,
   2403  1.5   dyoung 		    m0->m_pkthdr.len - sizeof(wh),
   2404  1.5   dyoung 		    ic->ic_flags, ic->ic_fragthreshold,
   2405  1.5   dyoung 		    rate, &stx->stx_d0, &stx->stx_dn, &npkt) == -1) {
   2406  1.5   dyoung 			DPRINTF2(sc, ("%s: fail compute duration\n", __func__));
   2407  1.5   dyoung 			goto post_load_err;
   2408  1.5   dyoung 		}
   2409  1.5   dyoung 
   2410  1.5   dyoung 		/* XXX >= ? */
   2411  1.5   dyoung 		if (m0->m_pkthdr.len > ic->ic_rtsthreshold)
   2412  1.5   dyoung 			txctl0 |= RTW_TXCTL0_RTSEN;
   2413  1.5   dyoung 
   2414  1.5   dyoung 		d0 = &stx->stx_d0;
   2415  1.5   dyoung 
   2416  1.5   dyoung 		txctl1 = LSHIFT(d0->d_plcp_len, RTW_TXCTL1_LENGTH_MASK) |
   2417  1.5   dyoung 		    LSHIFT(d0->d_rts_dur, RTW_TXCTL1_RTSDUR_MASK);
   2418  1.5   dyoung 
   2419  1.5   dyoung 		if ((d0->d_plcp_svc & IEEE80211_PLCP_SERVICE_LENEXT) != 0)
   2420  1.5   dyoung 			txctl1 |= RTW_TXCTL1_LENGEXT;
   2421  1.5   dyoung 
   2422  1.5   dyoung 		/* TBD fragmentation */
   2423  1.5   dyoung 
   2424  1.5   dyoung 		stx->stx_first = htc->htc_next;
   2425  1.5   dyoung 
   2426  1.5   dyoung 		rtw_txdescs_sync(sc->sc_dmat, sc->sc_desc_dmamap,
   2427  1.5   dyoung 		    htc, stx->stx_first, dmamap->dm_nsegs,
   2428  1.5   dyoung 		    BUS_DMASYNC_PREWRITE);
   2429  1.5   dyoung 
   2430  1.5   dyoung 		for (i = 0, lastdesc = desc = stx->stx_first;
   2431  1.5   dyoung 		     i < dmamap->dm_nsegs;
   2432  1.5   dyoung 		     i++, desc = RTW_NEXT_IDX(htc, desc)) {
   2433  1.5   dyoung 			if (dmamap->dm_segs[i].ds_len > RTW_TXLEN_LENGTH_MASK) {
   2434  1.5   dyoung 				DPRINTF2(sc, ("%s: seg too long\n", __func__));
   2435  1.5   dyoung 				goto post_load_err;
   2436  1.5   dyoung 			}
   2437  1.5   dyoung 			htx = &htc->htc_desc[desc];
   2438  1.5   dyoung 			htx->htx_ctl0 = htole32(txctl0);
   2439  1.5   dyoung 			if (i != 0)
   2440  1.5   dyoung 				htx->htx_ctl0 |= htole32(RTW_TXCTL0_OWN);
   2441  1.5   dyoung 			htx->htx_ctl1 = htole32(txctl1);
   2442  1.5   dyoung 			htx->htx_buf = htole32(dmamap->dm_segs[i].ds_addr);
   2443  1.5   dyoung 			htx->htx_len = htole32(dmamap->dm_segs[i].ds_len);
   2444  1.5   dyoung 			lastdesc = desc;
   2445  1.5   dyoung 			DPRINTF2(sc, ("%s: stx %p txdesc[%d] ctl0 %#08x "
   2446  1.5   dyoung 			    "ctl1 %#08x buf %#08x len %#08x\n",
   2447  1.5   dyoung 			    sc->sc_dev.dv_xname, stx, desc, htx->htx_ctl0,
   2448  1.5   dyoung 			    htx->htx_ctl1, htx->htx_buf, htx->htx_len));
   2449  1.5   dyoung 		}
   2450  1.5   dyoung 
   2451  1.5   dyoung 		htc->htc_desc[lastdesc].htx_ctl0 |= htole32(RTW_TXCTL0_LS);
   2452  1.5   dyoung 		htc->htc_desc[stx->stx_first].htx_ctl0 |=
   2453  1.5   dyoung 		   htole32(RTW_TXCTL0_FS);
   2454  1.5   dyoung 
   2455  1.5   dyoung 		DPRINTF2(sc, ("%s: stx %p FS on txdesc[%d], LS on txdesc[%d]\n",
   2456  1.5   dyoung 		    sc->sc_dev.dv_xname, stx, lastdesc, stx->stx_first));
   2457  1.5   dyoung 
   2458  1.5   dyoung 		stx->stx_ni = ni;
   2459  1.5   dyoung 		stx->stx_mbuf = m0;
   2460  1.5   dyoung 		stx->stx_last = lastdesc;
   2461  1.5   dyoung 
   2462  1.5   dyoung 		htc->htc_nfree -= dmamap->dm_nsegs;
   2463  1.5   dyoung 		htc->htc_next = desc;
   2464  1.5   dyoung 
   2465  1.5   dyoung 		rtw_txdescs_sync(sc->sc_dmat, sc->sc_desc_dmamap,
   2466  1.5   dyoung 		    htc, stx->stx_first, dmamap->dm_nsegs,
   2467  1.5   dyoung 		    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
   2468  1.5   dyoung 
   2469  1.5   dyoung 		htc->htc_desc[stx->stx_first].htx_ctl0 |=
   2470  1.5   dyoung 		    htole32(RTW_TXCTL0_OWN);
   2471  1.5   dyoung 
   2472  1.5   dyoung 		DPRINTF2(sc, ("%s: stx %p OWN on txdesc[%d]\n",
   2473  1.5   dyoung 		    sc->sc_dev.dv_xname, stx, stx->stx_first));
   2474  1.5   dyoung 
   2475  1.5   dyoung 		rtw_txdescs_sync(sc->sc_dmat, sc->sc_desc_dmamap,
   2476  1.5   dyoung 		    htc, stx->stx_first, 1,
   2477  1.5   dyoung 		    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
   2478  1.5   dyoung 
   2479  1.5   dyoung 		SIMPLEQ_REMOVE_HEAD(&stc->stc_freeq, stx_q);
   2480  1.5   dyoung 		SIMPLEQ_INSERT_TAIL(&stc->stc_dirtyq, stx, stx_q);
   2481  1.5   dyoung 
   2482  1.6   dyoung 		stc->stc_tx_timer = 5;
   2483  1.6   dyoung 		ifp->if_timer = 1;
   2484  1.6   dyoung 
   2485  1.5   dyoung 		/* TBD poke just one txmtr? */
   2486  1.5   dyoung 		RTW_WRITE8(&sc->sc_regs, RTW_TPPOLL,
   2487  1.5   dyoung 		    RTW_TPPOLL_NPQ | RTW_TPPOLL_LPQ | RTW_TPPOLL_HPQ |
   2488  1.5   dyoung 		    RTW_TPPOLL_BQ);
   2489  1.1   dyoung 	}
   2490  1.5   dyoung 	DPRINTF2(sc, ("%s: leave\n", __func__));
   2491  1.5   dyoung 	return;
   2492  1.5   dyoung post_load_err:
   2493  1.5   dyoung 	bus_dmamap_unload(sc->sc_dmat, dmamap);
   2494  1.5   dyoung 	m_freem(m0);
   2495  1.5   dyoung post_dequeue_err:
   2496  1.5   dyoung 	ieee80211_release_node(&sc->sc_ic, ni);
   2497  1.1   dyoung 	return;
   2498  1.1   dyoung }
   2499  1.1   dyoung 
   2500  1.1   dyoung static void
   2501  1.1   dyoung rtw_watchdog(struct ifnet *ifp)
   2502  1.1   dyoung {
   2503  1.5   dyoung 	int pri;
   2504  1.5   dyoung 	struct rtw_softc *sc;
   2505  1.5   dyoung 	struct rtw_txctl_blk *stc;
   2506  1.5   dyoung 
   2507  1.5   dyoung 	sc = ifp->if_softc;
   2508  1.5   dyoung 
   2509  1.5   dyoung 	ifp->if_timer = 0;
   2510  1.5   dyoung 
   2511  1.5   dyoung 	if ((sc->sc_flags & RTW_F_ENABLED) == 0)
   2512  1.5   dyoung 		return;
   2513  1.5   dyoung 
   2514  1.5   dyoung 	for (pri = 0; pri < RTW_NTXPRI; pri++) {
   2515  1.5   dyoung 		stc = &sc->sc_txctl_blk[pri];
   2516  1.5   dyoung 
   2517  1.5   dyoung 		if (stc->stc_tx_timer == 0)
   2518  1.5   dyoung 			continue;
   2519  1.5   dyoung 
   2520  1.5   dyoung 		if (--stc->stc_tx_timer == 0) {
   2521  1.5   dyoung 			if (SIMPLEQ_EMPTY(&stc->stc_dirtyq))
   2522  1.5   dyoung 				continue;
   2523  1.5   dyoung 			printf("%s: transmit timeout, priority %d\n",
   2524  1.5   dyoung 			    ifp->if_xname, pri);
   2525  1.5   dyoung 			ifp->if_oerrors++;
   2526  1.5   dyoung 			/* XXX be gentle */
   2527  1.5   dyoung 			(void)rtw_init(ifp);
   2528  1.5   dyoung 			rtw_start(ifp);
   2529  1.5   dyoung 		} else
   2530  1.5   dyoung 			ifp->if_timer = 1;
   2531  1.5   dyoung 	}
   2532  1.1   dyoung 	/* TBD */
   2533  1.1   dyoung 	return;
   2534  1.1   dyoung }
   2535  1.1   dyoung 
   2536  1.1   dyoung static void
   2537  1.1   dyoung rtw_start_beacon(struct rtw_softc *sc, int enable)
   2538  1.1   dyoung {
   2539  1.1   dyoung 	/* TBD */
   2540  1.1   dyoung 	return;
   2541  1.1   dyoung }
   2542  1.1   dyoung 
   2543  1.1   dyoung static void
   2544  1.1   dyoung rtw_next_scan(void *arg)
   2545  1.1   dyoung {
   2546  1.1   dyoung 	struct ieee80211com *ic = arg;
   2547  1.1   dyoung 	int s;
   2548  1.1   dyoung 
   2549  1.1   dyoung 	/* don't call rtw_start w/o network interrupts blocked */
   2550  1.1   dyoung 	s = splnet();
   2551  1.1   dyoung 	if (ic->ic_state == IEEE80211_S_SCAN)
   2552  1.1   dyoung 		ieee80211_next_scan(ic);
   2553  1.1   dyoung 	splx(s);
   2554  1.1   dyoung }
   2555  1.1   dyoung 
   2556  1.1   dyoung /* Synchronize the hardware state with the software state. */
   2557  1.1   dyoung static int
   2558  1.1   dyoung rtw_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
   2559  1.1   dyoung {
   2560  1.1   dyoung 	struct ifnet *ifp = &ic->ic_if;
   2561  1.1   dyoung 	struct rtw_softc *sc = ifp->if_softc;
   2562  1.1   dyoung 	enum ieee80211_state ostate;
   2563  1.1   dyoung 	int error;
   2564  1.1   dyoung 
   2565  1.1   dyoung 	ostate = ic->ic_state;
   2566  1.1   dyoung 
   2567  1.1   dyoung 	if (nstate == IEEE80211_S_INIT) {
   2568  1.1   dyoung 		callout_stop(&sc->sc_scan_ch);
   2569  1.1   dyoung 		sc->sc_cur_chan = IEEE80211_CHAN_ANY;
   2570  1.1   dyoung 		rtw_start_beacon(sc, 0);
   2571  1.1   dyoung 		return (*sc->sc_mtbl.mt_newstate)(ic, nstate, arg);
   2572  1.1   dyoung 	}
   2573  1.1   dyoung 
   2574  1.1   dyoung 	if (ostate == IEEE80211_S_INIT && nstate != IEEE80211_S_INIT)
   2575  1.1   dyoung 		rtw_pwrstate(sc, RTW_ON);
   2576  1.1   dyoung 
   2577  1.1   dyoung 	if ((error = rtw_tune(sc)) != 0)
   2578  1.1   dyoung 		return error;
   2579  1.1   dyoung 
   2580  1.1   dyoung 	switch (nstate) {
   2581  1.1   dyoung 	case IEEE80211_S_ASSOC:
   2582  1.1   dyoung 		break;
   2583  1.1   dyoung 	case IEEE80211_S_INIT:
   2584  1.1   dyoung 		panic("%s: unexpected state IEEE80211_S_INIT\n", __func__);
   2585  1.1   dyoung 		break;
   2586  1.1   dyoung 	case IEEE80211_S_SCAN:
   2587  1.1   dyoung #if 0
   2588  1.1   dyoung 		memset(sc->sc_bssid, 0, IEEE80211_ADDR_LEN);
   2589  1.1   dyoung 		rtw_write_bssid(sc);
   2590  1.1   dyoung #endif
   2591  1.1   dyoung 
   2592  1.1   dyoung 		callout_reset(&sc->sc_scan_ch, rtw_dwelltime * hz / 1000,
   2593  1.1   dyoung 		    rtw_next_scan, ic);
   2594  1.1   dyoung 
   2595  1.1   dyoung 		break;
   2596  1.1   dyoung 	case IEEE80211_S_RUN:
   2597  1.1   dyoung 		if (ic->ic_opmode == IEEE80211_M_STA)
   2598  1.1   dyoung 			break;
   2599  1.1   dyoung 		/*FALLTHROUGH*/
   2600  1.1   dyoung 	case IEEE80211_S_AUTH:
   2601  1.1   dyoung #if 0
   2602  1.1   dyoung 		rtw_write_bssid(sc);
   2603  1.1   dyoung 		rtw_write_bcn_thresh(sc);
   2604  1.1   dyoung 		rtw_write_ssid(sc);
   2605  1.1   dyoung 		rtw_write_sup_rates(sc);
   2606  1.1   dyoung #endif
   2607  1.1   dyoung 		if (ic->ic_opmode == IEEE80211_M_AHDEMO ||
   2608  1.1   dyoung 		    ic->ic_opmode == IEEE80211_M_MONITOR)
   2609  1.1   dyoung 			break;
   2610  1.1   dyoung 
   2611  1.1   dyoung 		/* TBD set listen interval, beacon interval */
   2612  1.1   dyoung 
   2613  1.1   dyoung #if 0
   2614  1.1   dyoung 		rtw_tsf(sc);
   2615  1.1   dyoung #endif
   2616  1.1   dyoung 		break;
   2617  1.1   dyoung 	}
   2618  1.1   dyoung 
   2619  1.1   dyoung 	if (nstate != IEEE80211_S_SCAN)
   2620  1.1   dyoung 		callout_stop(&sc->sc_scan_ch);
   2621  1.1   dyoung 
   2622  1.1   dyoung 	if (nstate == IEEE80211_S_RUN &&
   2623  1.1   dyoung 	    (ic->ic_opmode == IEEE80211_M_HOSTAP ||
   2624  1.1   dyoung 	     ic->ic_opmode == IEEE80211_M_IBSS))
   2625  1.1   dyoung 		rtw_start_beacon(sc, 1);
   2626  1.1   dyoung 	else
   2627  1.1   dyoung 		rtw_start_beacon(sc, 0);
   2628  1.1   dyoung 
   2629  1.1   dyoung 	return (*sc->sc_mtbl.mt_newstate)(ic, nstate, arg);
   2630  1.1   dyoung }
   2631  1.1   dyoung 
   2632  1.1   dyoung static void
   2633  1.1   dyoung rtw_recv_beacon(struct ieee80211com *ic, struct mbuf *m0,
   2634  1.1   dyoung     struct ieee80211_node *ni, int subtype, int rssi, u_int32_t rstamp)
   2635  1.1   dyoung {
   2636  1.1   dyoung 	/* TBD */
   2637  1.1   dyoung 	return;
   2638  1.1   dyoung }
   2639  1.1   dyoung 
   2640  1.1   dyoung static void
   2641  1.1   dyoung rtw_recv_mgmt(struct ieee80211com *ic, struct mbuf *m,
   2642  1.1   dyoung     struct ieee80211_node *ni, int subtype, int rssi, u_int32_t rstamp)
   2643  1.1   dyoung {
   2644  1.1   dyoung 	struct rtw_softc *sc = (struct rtw_softc*)ic->ic_softc;
   2645  1.1   dyoung 
   2646  1.1   dyoung 	switch (subtype) {
   2647  1.1   dyoung 	case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
   2648  1.1   dyoung 		/* do nothing: hardware answers probe request XXX */
   2649  1.1   dyoung 		break;
   2650  1.1   dyoung 	case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
   2651  1.1   dyoung 	case IEEE80211_FC0_SUBTYPE_BEACON:
   2652  1.1   dyoung 		rtw_recv_beacon(ic, m, ni, subtype, rssi, rstamp);
   2653  1.1   dyoung 		break;
   2654  1.1   dyoung 	default:
   2655  1.1   dyoung 		(*sc->sc_mtbl.mt_recv_mgmt)(ic, m, ni, subtype, rssi, rstamp);
   2656  1.1   dyoung 		break;
   2657  1.1   dyoung 	}
   2658  1.1   dyoung 	return;
   2659  1.1   dyoung }
   2660  1.1   dyoung 
   2661  1.1   dyoung static struct ieee80211_node *
   2662  1.1   dyoung rtw_node_alloc(struct ieee80211com *ic)
   2663  1.1   dyoung {
   2664  1.1   dyoung 	struct rtw_softc *sc = (struct rtw_softc *)ic->ic_if.if_softc;
   2665  1.1   dyoung 	struct ieee80211_node *ni = (*sc->sc_mtbl.mt_node_alloc)(ic);
   2666  1.1   dyoung 
   2667  1.1   dyoung 	DPRINTF(sc, ("%s: alloc node %p\n", sc->sc_dev.dv_xname, ni));
   2668  1.1   dyoung 	return ni;
   2669  1.1   dyoung }
   2670  1.1   dyoung 
   2671  1.1   dyoung static void
   2672  1.1   dyoung rtw_node_free(struct ieee80211com *ic, struct ieee80211_node *ni)
   2673  1.1   dyoung {
   2674  1.1   dyoung 	struct rtw_softc *sc = (struct rtw_softc *)ic->ic_if.if_softc;
   2675  1.1   dyoung 
   2676  1.1   dyoung 	DPRINTF(sc, ("%s: freeing node %p %s\n", sc->sc_dev.dv_xname, ni,
   2677  1.1   dyoung 	    ether_sprintf(ni->ni_bssid)));
   2678  1.1   dyoung 	(*sc->sc_mtbl.mt_node_free)(ic, ni);
   2679  1.1   dyoung }
   2680  1.1   dyoung 
   2681  1.1   dyoung static int
   2682  1.1   dyoung rtw_media_change(struct ifnet *ifp)
   2683  1.1   dyoung {
   2684  1.1   dyoung 	int error;
   2685  1.1   dyoung 
   2686  1.1   dyoung 	error = ieee80211_media_change(ifp);
   2687  1.1   dyoung 	if (error == ENETRESET) {
   2688  1.1   dyoung 		if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) ==
   2689  1.1   dyoung 		    (IFF_RUNNING|IFF_UP))
   2690  1.1   dyoung 			rtw_init(ifp);		/* XXX lose error */
   2691  1.1   dyoung 		error = 0;
   2692  1.1   dyoung 	}
   2693  1.1   dyoung 	return error;
   2694  1.1   dyoung }
   2695  1.1   dyoung 
   2696  1.1   dyoung static void
   2697  1.1   dyoung rtw_media_status(struct ifnet *ifp, struct ifmediareq *imr)
   2698  1.1   dyoung {
   2699  1.1   dyoung 	struct rtw_softc *sc = ifp->if_softc;
   2700  1.1   dyoung 
   2701  1.1   dyoung 	if ((sc->sc_flags & RTW_F_ENABLED) == 0) {
   2702  1.1   dyoung 		imr->ifm_active = IFM_IEEE80211 | IFM_NONE;
   2703  1.1   dyoung 		imr->ifm_status = 0;
   2704  1.1   dyoung 		return;
   2705  1.1   dyoung 	}
   2706  1.1   dyoung 	ieee80211_media_status(ifp, imr);
   2707  1.1   dyoung }
   2708  1.1   dyoung 
   2709  1.1   dyoung void
   2710  1.1   dyoung rtw_power(int why, void *arg)
   2711  1.1   dyoung {
   2712  1.1   dyoung 	struct rtw_softc *sc = arg;
   2713  1.1   dyoung 	struct ifnet *ifp = &sc->sc_ic.ic_if;
   2714  1.1   dyoung 	int s;
   2715  1.1   dyoung 
   2716  1.1   dyoung 	DPRINTF(sc, ("%s: rtw_power(%d,)\n", sc->sc_dev.dv_xname, why));
   2717  1.1   dyoung 
   2718  1.1   dyoung 	s = splnet();
   2719  1.1   dyoung 	switch (why) {
   2720  1.1   dyoung 	case PWR_STANDBY:
   2721  1.1   dyoung 		/* XXX do nothing. */
   2722  1.1   dyoung 		break;
   2723  1.1   dyoung 	case PWR_SUSPEND:
   2724  1.1   dyoung 		rtw_stop(ifp, 0);
   2725  1.1   dyoung 		if (sc->sc_power != NULL)
   2726  1.1   dyoung 			(*sc->sc_power)(sc, why);
   2727  1.1   dyoung 		break;
   2728  1.1   dyoung 	case PWR_RESUME:
   2729  1.1   dyoung 		if (ifp->if_flags & IFF_UP) {
   2730  1.1   dyoung 			if (sc->sc_power != NULL)
   2731  1.1   dyoung 				(*sc->sc_power)(sc, why);
   2732  1.1   dyoung 			rtw_init(ifp);
   2733  1.1   dyoung 		}
   2734  1.1   dyoung 		break;
   2735  1.1   dyoung 	case PWR_SOFTSUSPEND:
   2736  1.1   dyoung 	case PWR_SOFTSTANDBY:
   2737  1.1   dyoung 	case PWR_SOFTRESUME:
   2738  1.1   dyoung 		break;
   2739  1.1   dyoung 	}
   2740  1.1   dyoung 	splx(s);
   2741  1.1   dyoung }
   2742  1.1   dyoung 
   2743  1.1   dyoung /* rtw_shutdown: make sure the interface is stopped at reboot time. */
   2744  1.1   dyoung void
   2745  1.1   dyoung rtw_shutdown(void *arg)
   2746  1.1   dyoung {
   2747  1.1   dyoung 	struct rtw_softc *sc = arg;
   2748  1.1   dyoung 
   2749  1.1   dyoung 	rtw_stop(&sc->sc_ic.ic_if, 1);
   2750  1.1   dyoung }
   2751  1.1   dyoung 
   2752  1.1   dyoung static __inline void
   2753  1.7   dyoung rtw_setifprops(struct ifnet *ifp, const char *dvname, void *softc)
   2754  1.1   dyoung {
   2755  1.7   dyoung 	(void)memcpy(ifp->if_xname, dvname, IFNAMSIZ);
   2756  1.1   dyoung 	ifp->if_softc = softc;
   2757  1.1   dyoung 	ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST |
   2758  1.1   dyoung 	    IFF_NOTRAILERS;
   2759  1.1   dyoung 	ifp->if_ioctl = rtw_ioctl;
   2760  1.1   dyoung 	ifp->if_start = rtw_start;
   2761  1.1   dyoung 	ifp->if_watchdog = rtw_watchdog;
   2762  1.1   dyoung 	ifp->if_init = rtw_init;
   2763  1.1   dyoung 	ifp->if_stop = rtw_stop;
   2764  1.1   dyoung }
   2765  1.1   dyoung 
   2766  1.1   dyoung static __inline void
   2767  1.1   dyoung rtw_set80211props(struct ieee80211com *ic)
   2768  1.1   dyoung {
   2769  1.1   dyoung 	int nrate;
   2770  1.1   dyoung 	ic->ic_phytype = IEEE80211_T_DS;
   2771  1.1   dyoung 	ic->ic_opmode = IEEE80211_M_STA;
   2772  1.1   dyoung 	ic->ic_caps = IEEE80211_C_PMGT | IEEE80211_C_IBSS |
   2773  1.1   dyoung 	    IEEE80211_C_HOSTAP | IEEE80211_C_MONITOR | IEEE80211_C_WEP;
   2774  1.1   dyoung 
   2775  1.1   dyoung 	nrate = 0;
   2776  1.1   dyoung 	ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] = 2;
   2777  1.1   dyoung 	ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] = 4;
   2778  1.1   dyoung 	ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] = 11;
   2779  1.1   dyoung 	ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] = 22;
   2780  1.1   dyoung 	ic->ic_sup_rates[IEEE80211_MODE_11B].rs_nrates = nrate;
   2781  1.1   dyoung }
   2782  1.1   dyoung 
   2783  1.1   dyoung static __inline void
   2784  1.1   dyoung rtw_set80211methods(struct rtw_mtbl *mtbl, struct ieee80211com *ic)
   2785  1.1   dyoung {
   2786  1.1   dyoung 	mtbl->mt_newstate = ic->ic_newstate;
   2787  1.1   dyoung 	ic->ic_newstate = rtw_newstate;
   2788  1.1   dyoung 
   2789  1.1   dyoung 	mtbl->mt_recv_mgmt = ic->ic_recv_mgmt;
   2790  1.1   dyoung 	ic->ic_recv_mgmt = rtw_recv_mgmt;
   2791  1.1   dyoung 
   2792  1.1   dyoung 	mtbl->mt_node_free = ic->ic_node_free;
   2793  1.1   dyoung 	ic->ic_node_free = rtw_node_free;
   2794  1.1   dyoung 
   2795  1.1   dyoung 	mtbl->mt_node_alloc = ic->ic_node_alloc;
   2796  1.1   dyoung 	ic->ic_node_alloc = rtw_node_alloc;
   2797  1.1   dyoung }
   2798  1.1   dyoung 
   2799  1.1   dyoung static __inline void
   2800  1.7   dyoung rtw_establish_hooks(struct rtw_hooks *hooks, const char *dvname,
   2801  1.1   dyoung     void *arg)
   2802  1.1   dyoung {
   2803  1.1   dyoung 	/*
   2804  1.1   dyoung 	 * Make sure the interface is shutdown during reboot.
   2805  1.1   dyoung 	 */
   2806  1.1   dyoung 	hooks->rh_shutdown = shutdownhook_establish(rtw_shutdown, arg);
   2807  1.1   dyoung 	if (hooks->rh_shutdown == NULL)
   2808  1.1   dyoung 		printf("%s: WARNING: unable to establish shutdown hook\n",
   2809  1.7   dyoung 		    dvname);
   2810  1.1   dyoung 
   2811  1.1   dyoung 	/*
   2812  1.1   dyoung 	 * Add a suspend hook to make sure we come back up after a
   2813  1.1   dyoung 	 * resume.
   2814  1.1   dyoung 	 */
   2815  1.1   dyoung 	hooks->rh_power = powerhook_establish(rtw_power, arg);
   2816  1.1   dyoung 	if (hooks->rh_power == NULL)
   2817  1.1   dyoung 		printf("%s: WARNING: unable to establish power hook\n",
   2818  1.7   dyoung 		    dvname);
   2819  1.1   dyoung }
   2820  1.1   dyoung 
   2821  1.1   dyoung static __inline void
   2822  1.7   dyoung rtw_disestablish_hooks(struct rtw_hooks *hooks, const char *dvname,
   2823  1.1   dyoung     void *arg)
   2824  1.1   dyoung {
   2825  1.1   dyoung 	if (hooks->rh_shutdown != NULL)
   2826  1.1   dyoung 		shutdownhook_disestablish(hooks->rh_shutdown);
   2827  1.1   dyoung 
   2828  1.1   dyoung 	if (hooks->rh_power != NULL)
   2829  1.1   dyoung 		powerhook_disestablish(hooks->rh_power);
   2830  1.1   dyoung }
   2831  1.1   dyoung 
   2832  1.1   dyoung static __inline void
   2833  1.1   dyoung rtw_init_radiotap(struct rtw_softc *sc)
   2834  1.1   dyoung {
   2835  1.1   dyoung 	memset(&sc->sc_rxtapu, 0, sizeof(sc->sc_rxtapu));
   2836  1.1   dyoung 	sc->sc_rxtap.rr_ihdr.it_len = sizeof(sc->sc_rxtapu);
   2837  1.1   dyoung 	sc->sc_rxtap.rr_ihdr.it_present = RTW_RX_RADIOTAP_PRESENT;
   2838  1.1   dyoung 
   2839  1.1   dyoung 	memset(&sc->sc_txtapu, 0, sizeof(sc->sc_txtapu));
   2840  1.1   dyoung 	sc->sc_txtap.rt_ihdr.it_len = sizeof(sc->sc_txtapu);
   2841  1.1   dyoung 	sc->sc_txtap.rt_ihdr.it_present = RTW_TX_RADIOTAP_PRESENT;
   2842  1.1   dyoung }
   2843  1.1   dyoung 
   2844  1.1   dyoung static int
   2845  1.1   dyoung rtw_txctl_blk_setup(struct rtw_txctl_blk *stc, u_int qlen)
   2846  1.1   dyoung {
   2847  1.1   dyoung 	SIMPLEQ_INIT(&stc->stc_dirtyq);
   2848  1.1   dyoung 	SIMPLEQ_INIT(&stc->stc_freeq);
   2849  1.1   dyoung 	stc->stc_ndesc = qlen;
   2850  1.1   dyoung 	stc->stc_desc = malloc(qlen * sizeof(*stc->stc_desc), M_DEVBUF,
   2851  1.1   dyoung 	    M_NOWAIT);
   2852  1.1   dyoung 	if (stc->stc_desc == NULL)
   2853  1.1   dyoung 		return ENOMEM;
   2854  1.1   dyoung 	return 0;
   2855  1.1   dyoung }
   2856  1.1   dyoung 
   2857  1.1   dyoung static void
   2858  1.1   dyoung rtw_txctl_blk_cleanup_all(struct rtw_softc *sc)
   2859  1.1   dyoung {
   2860  1.1   dyoung 	struct rtw_txctl_blk *stc;
   2861  1.1   dyoung 	int qlen[RTW_NTXPRI] =
   2862  1.1   dyoung 	     {RTW_TXQLENLO, RTW_TXQLENMD, RTW_TXQLENHI, RTW_TXQLENBCN};
   2863  1.1   dyoung 	int pri;
   2864  1.1   dyoung 
   2865  1.1   dyoung 	for (pri = 0; pri < sizeof(qlen)/sizeof(qlen[0]); pri++) {
   2866  1.1   dyoung 		stc = &sc->sc_txctl_blk[pri];
   2867  1.1   dyoung 		free(stc->stc_desc, M_DEVBUF);
   2868  1.1   dyoung 		stc->stc_desc = NULL;
   2869  1.1   dyoung 	}
   2870  1.1   dyoung }
   2871  1.1   dyoung 
   2872  1.1   dyoung static int
   2873  1.1   dyoung rtw_txctl_blk_setup_all(struct rtw_softc *sc)
   2874  1.1   dyoung {
   2875  1.1   dyoung 	int pri, rc = 0;
   2876  1.1   dyoung 	int qlen[RTW_NTXPRI] =
   2877  1.1   dyoung 	     {RTW_TXQLENLO, RTW_TXQLENMD, RTW_TXQLENHI, RTW_TXQLENBCN};
   2878  1.1   dyoung 
   2879  1.1   dyoung 	for (pri = 0; pri < sizeof(qlen)/sizeof(qlen[0]); pri++) {
   2880  1.1   dyoung 		rc = rtw_txctl_blk_setup(&sc->sc_txctl_blk[pri], qlen[pri]);
   2881  1.1   dyoung 		if (rc != 0)
   2882  1.1   dyoung 			break;
   2883  1.1   dyoung 	}
   2884  1.1   dyoung 	return rc;
   2885  1.1   dyoung }
   2886  1.1   dyoung 
   2887  1.1   dyoung static void
   2888  1.1   dyoung rtw_txdesc_blk_setup(struct rtw_txdesc_blk *htc, struct rtw_txdesc *desc,
   2889  1.1   dyoung     u_int ndesc, bus_addr_t ofs, bus_addr_t physbase)
   2890  1.1   dyoung {
   2891  1.1   dyoung 	int i;
   2892  1.1   dyoung 
   2893  1.1   dyoung 	htc->htc_ndesc = ndesc;
   2894  1.1   dyoung 	htc->htc_desc = desc;
   2895  1.1   dyoung 	htc->htc_physbase = physbase;
   2896  1.1   dyoung 	htc->htc_ofs = ofs;
   2897  1.1   dyoung 
   2898  1.1   dyoung 	(void)memset(htc->htc_desc, 0,
   2899  1.1   dyoung 	    sizeof(htc->htc_desc[0]) * htc->htc_ndesc);
   2900  1.1   dyoung 
   2901  1.1   dyoung 	for (i = 0; i < htc->htc_ndesc; i++) {
   2902  1.1   dyoung 		htc->htc_desc[i].htx_next = htole32(RTW_NEXT_DESC(htc, i));
   2903  1.1   dyoung 	}
   2904  1.1   dyoung }
   2905  1.1   dyoung 
   2906  1.1   dyoung static void
   2907  1.1   dyoung rtw_txdesc_blk_setup_all(struct rtw_softc *sc)
   2908  1.1   dyoung {
   2909  1.1   dyoung 	rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRILO],
   2910  1.1   dyoung 	    &sc->sc_descs->hd_txlo[0], RTW_NTXDESCLO,
   2911  1.1   dyoung 	    RTW_RING_OFFSET(hd_txlo), RTW_RING_BASE(sc, hd_txlo));
   2912  1.1   dyoung 
   2913  1.1   dyoung 	rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIMD],
   2914  1.1   dyoung 	    &sc->sc_descs->hd_txmd[0], RTW_NTXDESCMD,
   2915  1.1   dyoung 	    RTW_RING_OFFSET(hd_txmd), RTW_RING_BASE(sc, hd_txmd));
   2916  1.1   dyoung 
   2917  1.1   dyoung 	rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIHI],
   2918  1.1   dyoung 	    &sc->sc_descs->hd_txhi[0], RTW_NTXDESCHI,
   2919  1.1   dyoung 	    RTW_RING_OFFSET(hd_txhi), RTW_RING_BASE(sc, hd_txhi));
   2920  1.1   dyoung 
   2921  1.1   dyoung 	rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIBCN],
   2922  1.1   dyoung 	    &sc->sc_descs->hd_bcn[0], RTW_NTXDESCBCN,
   2923  1.1   dyoung 	    RTW_RING_OFFSET(hd_bcn), RTW_RING_BASE(sc, hd_bcn));
   2924  1.1   dyoung }
   2925  1.1   dyoung 
   2926  1.1   dyoung static struct rtw_rf *
   2927  1.1   dyoung rtw_rf_attach(struct rtw_softc *sc, enum rtw_rfchipid rfchipid,
   2928  1.1   dyoung     rtw_rf_write_t rf_write, int digphy)
   2929  1.1   dyoung {
   2930  1.1   dyoung 	struct rtw_rf *rf;
   2931  1.1   dyoung 
   2932  1.1   dyoung 	switch (rfchipid) {
   2933  1.1   dyoung 	case RTW_RFCHIPID_MAXIM:
   2934  1.1   dyoung 		rf = rtw_max2820_create(&sc->sc_regs, rf_write, 0);
   2935  1.1   dyoung 		sc->sc_pwrstate_cb = rtw_maxim_pwrstate;
   2936  1.1   dyoung 		break;
   2937  1.1   dyoung 	case RTW_RFCHIPID_PHILIPS:
   2938  1.1   dyoung 		rf = rtw_sa2400_create(&sc->sc_regs, rf_write, digphy);
   2939  1.1   dyoung 		sc->sc_pwrstate_cb = rtw_philips_pwrstate;
   2940  1.1   dyoung 		break;
   2941  1.1   dyoung 	default:
   2942  1.1   dyoung 		return NULL;
   2943  1.1   dyoung 	}
   2944  1.1   dyoung 	rf->rf_continuous_tx_cb =
   2945  1.1   dyoung 	    (rtw_continuous_tx_cb_t)rtw_continuous_tx_enable;
   2946  1.1   dyoung 	rf->rf_continuous_tx_arg = (void *)sc;
   2947  1.1   dyoung 	return rf;
   2948  1.1   dyoung }
   2949  1.1   dyoung 
   2950  1.1   dyoung /* Revision C and later use a different PHY delay setting than
   2951  1.1   dyoung  * revisions A and B.
   2952  1.1   dyoung  */
   2953  1.1   dyoung static u_int8_t
   2954  1.1   dyoung rtw_check_phydelay(struct rtw_regs *regs, u_int32_t rcr0)
   2955  1.1   dyoung {
   2956  1.1   dyoung #define REVAB (RTW_RCR_MXDMA_UNLIMITED | RTW_RCR_AICV)
   2957  1.1   dyoung #define REVC (REVAB | RTW_RCR_RXFTH_WHOLE)
   2958  1.1   dyoung 
   2959  1.1   dyoung 	u_int8_t phydelay = LSHIFT(0x6, RTW_PHYDELAY_PHYDELAY);
   2960  1.1   dyoung 
   2961  1.1   dyoung 	RTW_WRITE(regs, RTW_RCR, REVAB);
   2962  1.1   dyoung 	RTW_WRITE(regs, RTW_RCR, REVC);
   2963  1.1   dyoung 
   2964  1.1   dyoung 	RTW_WBR(regs, RTW_RCR, RTW_RCR);
   2965  1.1   dyoung 	if ((RTW_READ(regs, RTW_RCR) & REVC) == REVC)
   2966  1.1   dyoung 		phydelay |= RTW_PHYDELAY_REVC_MAGIC;
   2967  1.1   dyoung 
   2968  1.1   dyoung 	RTW_WRITE(regs, RTW_RCR, rcr0);	/* restore RCR */
   2969  1.1   dyoung 
   2970  1.1   dyoung 	return phydelay;
   2971  1.1   dyoung #undef REVC
   2972  1.1   dyoung }
   2973  1.1   dyoung 
   2974  1.1   dyoung void
   2975  1.1   dyoung rtw_attach(struct rtw_softc *sc)
   2976  1.1   dyoung {
   2977  1.1   dyoung 	rtw_rf_write_t rf_write;
   2978  1.1   dyoung 	struct rtw_txctl_blk *stc;
   2979  1.1   dyoung 	int pri, rc, vers;
   2980  1.1   dyoung 
   2981  1.1   dyoung #if 0
   2982  1.1   dyoung 	CASSERT(RTW_DESC_ALIGNMENT % sizeof(struct rtw_txdesc) == 0,
   2983  1.1   dyoung 	    "RTW_DESC_ALIGNMENT is not a multiple of "
   2984  1.1   dyoung 	    "sizeof(struct rtw_txdesc)");
   2985  1.1   dyoung 
   2986  1.1   dyoung 	CASSERT(RTW_DESC_ALIGNMENT % sizeof(struct rtw_rxdesc) == 0,
   2987  1.1   dyoung 	    "RTW_DESC_ALIGNMENT is not a multiple of "
   2988  1.1   dyoung 	    "sizeof(struct rtw_rxdesc)");
   2989  1.1   dyoung 
   2990  1.1   dyoung 	CASSERT(RTW_DESC_ALIGNMENT % RTW_MAXPKTSEGS == 0,
   2991  1.1   dyoung 	    "RTW_DESC_ALIGNMENT is not a multiple of RTW_MAXPKTSEGS");
   2992  1.1   dyoung #endif
   2993  1.1   dyoung 
   2994  1.1   dyoung 	NEXT_ATTACH_STATE(sc, DETACHED);
   2995  1.1   dyoung 
   2996  1.1   dyoung 	switch (RTW_READ(&sc->sc_regs, RTW_TCR) & RTW_TCR_HWVERID_MASK) {
   2997  1.1   dyoung 	case RTW_TCR_HWVERID_F:
   2998  1.1   dyoung 		vers = 'F';
   2999  1.1   dyoung 		rf_write = rtw_rf_hostwrite;
   3000  1.1   dyoung 		break;
   3001  1.1   dyoung 	case RTW_TCR_HWVERID_D:
   3002  1.1   dyoung 		vers = 'D';
   3003  1.4   dyoung 		if (rtw_host_rfio)
   3004  1.4   dyoung 			rf_write = rtw_rf_hostwrite;
   3005  1.4   dyoung 		else
   3006  1.4   dyoung 			rf_write = rtw_rf_macwrite;
   3007  1.1   dyoung 		break;
   3008  1.1   dyoung 	default:
   3009  1.1   dyoung 		vers = '?';
   3010  1.1   dyoung 		rf_write = rtw_rf_macwrite;
   3011  1.1   dyoung 		break;
   3012  1.1   dyoung 	}
   3013  1.1   dyoung 	printf("%s: hardware version %c\n", sc->sc_dev.dv_xname, vers);
   3014  1.1   dyoung 
   3015  1.1   dyoung 	rc = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct rtw_descs),
   3016  1.1   dyoung 	    RTW_DESC_ALIGNMENT, 0, &sc->sc_desc_segs, 1, &sc->sc_desc_nsegs,
   3017  1.1   dyoung 	    0);
   3018  1.1   dyoung 
   3019  1.1   dyoung 	if (rc != 0) {
   3020  1.1   dyoung 		printf("%s: could not allocate hw descriptors, error %d\n",
   3021  1.1   dyoung 		     sc->sc_dev.dv_xname, rc);
   3022  1.1   dyoung 		goto err;
   3023  1.1   dyoung 	}
   3024  1.1   dyoung 
   3025  1.1   dyoung 	NEXT_ATTACH_STATE(sc, FINISH_DESC_ALLOC);
   3026  1.1   dyoung 
   3027  1.1   dyoung 	rc = bus_dmamem_map(sc->sc_dmat, &sc->sc_desc_segs,
   3028  1.1   dyoung 	    sc->sc_desc_nsegs, sizeof(struct rtw_descs),
   3029  1.1   dyoung 	    (caddr_t*)&sc->sc_descs, BUS_DMA_COHERENT);
   3030  1.1   dyoung 
   3031  1.1   dyoung 	if (rc != 0) {
   3032  1.1   dyoung 		printf("%s: could not map hw descriptors, error %d\n",
   3033  1.1   dyoung 		    sc->sc_dev.dv_xname, rc);
   3034  1.1   dyoung 		goto err;
   3035  1.1   dyoung 	}
   3036  1.1   dyoung 	NEXT_ATTACH_STATE(sc, FINISH_DESC_MAP);
   3037  1.1   dyoung 
   3038  1.1   dyoung 	rc = bus_dmamap_create(sc->sc_dmat, sizeof(struct rtw_descs), 1,
   3039  1.1   dyoung 	    sizeof(struct rtw_descs), 0, 0, &sc->sc_desc_dmamap);
   3040  1.1   dyoung 
   3041  1.1   dyoung 	if (rc != 0) {
   3042  1.1   dyoung 		printf("%s: could not create DMA map for hw descriptors, "
   3043  1.1   dyoung 		    "error %d\n", sc->sc_dev.dv_xname, rc);
   3044  1.1   dyoung 		goto err;
   3045  1.1   dyoung 	}
   3046  1.1   dyoung 	NEXT_ATTACH_STATE(sc, FINISH_DESCMAP_CREATE);
   3047  1.1   dyoung 
   3048  1.1   dyoung 	rc = bus_dmamap_load(sc->sc_dmat, sc->sc_desc_dmamap, sc->sc_descs,
   3049  1.1   dyoung 	    sizeof(struct rtw_descs), NULL, 0);
   3050  1.1   dyoung 
   3051  1.1   dyoung 	if (rc != 0) {
   3052  1.1   dyoung 		printf("%s: could not load DMA map for hw descriptors, "
   3053  1.1   dyoung 		    "error %d\n", sc->sc_dev.dv_xname, rc);
   3054  1.1   dyoung 		goto err;
   3055  1.1   dyoung 	}
   3056  1.1   dyoung 	NEXT_ATTACH_STATE(sc, FINISH_DESCMAP_LOAD);
   3057  1.1   dyoung 
   3058  1.1   dyoung 	if (rtw_txctl_blk_setup_all(sc) != 0)
   3059  1.1   dyoung 		goto err;
   3060  1.1   dyoung 	NEXT_ATTACH_STATE(sc, FINISH_TXCTLBLK_SETUP);
   3061  1.1   dyoung 
   3062  1.1   dyoung 	rtw_txdesc_blk_setup_all(sc);
   3063  1.1   dyoung 
   3064  1.1   dyoung 	NEXT_ATTACH_STATE(sc, FINISH_TXDESCBLK_SETUP);
   3065  1.1   dyoung 
   3066  1.1   dyoung 	sc->sc_rxdesc = &sc->sc_descs->hd_rx[0];
   3067  1.1   dyoung 
   3068  1.3   dyoung 	rtw_rxctls_setup(&sc->sc_rxctl[0]);
   3069  1.1   dyoung 
   3070  1.1   dyoung 	for (pri = 0; pri < RTW_NTXPRI; pri++) {
   3071  1.1   dyoung 		stc = &sc->sc_txctl_blk[pri];
   3072  1.1   dyoung 
   3073  1.1   dyoung 		if ((rc = rtw_txdesc_dmamaps_create(sc->sc_dmat,
   3074  1.1   dyoung 		    &stc->stc_desc[0], stc->stc_ndesc)) != 0) {
   3075  1.1   dyoung 			printf("%s: could not load DMA map for "
   3076  1.1   dyoung 			    "hw tx descriptors, error %d\n",
   3077  1.1   dyoung 			    sc->sc_dev.dv_xname, rc);
   3078  1.1   dyoung 			goto err;
   3079  1.1   dyoung 		}
   3080  1.1   dyoung 	}
   3081  1.1   dyoung 
   3082  1.1   dyoung 	NEXT_ATTACH_STATE(sc, FINISH_TXMAPS_CREATE);
   3083  1.1   dyoung 	if ((rc = rtw_rxdesc_dmamaps_create(sc->sc_dmat, &sc->sc_rxctl[0],
   3084  1.1   dyoung 	                                    RTW_RXQLEN)) != 0) {
   3085  1.1   dyoung 		printf("%s: could not load DMA map for hw rx descriptors, "
   3086  1.1   dyoung 		    "error %d\n", sc->sc_dev.dv_xname, rc);
   3087  1.1   dyoung 		goto err;
   3088  1.1   dyoung 	}
   3089  1.1   dyoung 	NEXT_ATTACH_STATE(sc, FINISH_RXMAPS_CREATE);
   3090  1.1   dyoung 
   3091  1.1   dyoung 	/* Reset the chip to a known state. */
   3092  1.1   dyoung 	if (rtw_reset(sc) != 0)
   3093  1.1   dyoung 		goto err;
   3094  1.1   dyoung 	NEXT_ATTACH_STATE(sc, FINISH_RESET);
   3095  1.1   dyoung 
   3096  1.1   dyoung 	sc->sc_rcr = RTW_READ(&sc->sc_regs, RTW_RCR);
   3097  1.1   dyoung 
   3098  1.1   dyoung 	if ((sc->sc_rcr & RTW_RCR_9356SEL) != 0)
   3099  1.1   dyoung 		sc->sc_flags |= RTW_F_9356SROM;
   3100  1.1   dyoung 
   3101  1.1   dyoung 	if (rtw_srom_read(&sc->sc_regs, sc->sc_flags, &sc->sc_srom,
   3102  1.7   dyoung 	    sc->sc_dev.dv_xname) != 0)
   3103  1.1   dyoung 		goto err;
   3104  1.1   dyoung 
   3105  1.1   dyoung 	NEXT_ATTACH_STATE(sc, FINISH_READ_SROM);
   3106  1.1   dyoung 
   3107  1.1   dyoung 	if (rtw_srom_parse(&sc->sc_srom, &sc->sc_flags, &sc->sc_csthr,
   3108  1.1   dyoung 	    &sc->sc_rfchipid, &sc->sc_rcr, &sc->sc_locale,
   3109  1.7   dyoung 	    sc->sc_dev.dv_xname) != 0) {
   3110  1.1   dyoung 		printf("%s: attach failed, malformed serial ROM\n",
   3111  1.1   dyoung 		    sc->sc_dev.dv_xname);
   3112  1.1   dyoung 		goto err;
   3113  1.1   dyoung 	}
   3114  1.1   dyoung 
   3115  1.1   dyoung 	RTW_DPRINTF(("%s: CS threshold %u\n", sc->sc_dev.dv_xname,
   3116  1.1   dyoung 	    sc->sc_csthr));
   3117  1.1   dyoung 
   3118  1.1   dyoung 	NEXT_ATTACH_STATE(sc, FINISH_PARSE_SROM);
   3119  1.1   dyoung 
   3120  1.1   dyoung 	sc->sc_rf = rtw_rf_attach(sc, sc->sc_rfchipid, rf_write,
   3121  1.1   dyoung 	    sc->sc_flags & RTW_F_DIGPHY);
   3122  1.1   dyoung 
   3123  1.1   dyoung 	if (sc->sc_rf == NULL) {
   3124  1.1   dyoung 		printf("%s: attach failed, could not attach RF\n",
   3125  1.1   dyoung 		    sc->sc_dev.dv_xname);
   3126  1.1   dyoung 		goto err;
   3127  1.1   dyoung 	}
   3128  1.1   dyoung 
   3129  1.1   dyoung #if 0
   3130  1.1   dyoung 	if (rtw_identify_rf(&sc->sc_regs, &sc->sc_rftype,
   3131  1.7   dyoung 	    sc->sc_dev.dv_xname) != 0) {
   3132  1.1   dyoung 		printf("%s: attach failed, unknown RF unidentified\n",
   3133  1.1   dyoung 		    sc->sc_dev.dv_xname);
   3134  1.1   dyoung 		goto err;
   3135  1.1   dyoung 	}
   3136  1.1   dyoung #endif
   3137  1.1   dyoung 
   3138  1.1   dyoung 	NEXT_ATTACH_STATE(sc, FINISH_RF_ATTACH);
   3139  1.1   dyoung 
   3140  1.1   dyoung 	sc->sc_phydelay = rtw_check_phydelay(&sc->sc_regs, sc->sc_rcr);
   3141  1.1   dyoung 
   3142  1.1   dyoung 	RTW_DPRINTF(("%s: PHY delay %d\n", sc->sc_dev.dv_xname,
   3143  1.1   dyoung 	    sc->sc_phydelay));
   3144  1.1   dyoung 
   3145  1.1   dyoung 	if (sc->sc_locale == RTW_LOCALE_UNKNOWN)
   3146  1.1   dyoung 		rtw_identify_country(&sc->sc_regs, &sc->sc_locale,
   3147  1.7   dyoung 		    sc->sc_dev.dv_xname);
   3148  1.1   dyoung 
   3149  1.1   dyoung 	rtw_init_channels(sc->sc_locale, &sc->sc_ic.ic_channels,
   3150  1.7   dyoung 	    sc->sc_dev.dv_xname);
   3151  1.1   dyoung 
   3152  1.1   dyoung 	if (rtw_identify_sta(&sc->sc_regs, &sc->sc_ic.ic_myaddr,
   3153  1.7   dyoung 	    sc->sc_dev.dv_xname) != 0)
   3154  1.1   dyoung 		goto err;
   3155  1.1   dyoung 	NEXT_ATTACH_STATE(sc, FINISH_ID_STA);
   3156  1.1   dyoung 
   3157  1.7   dyoung 	rtw_setifprops(&sc->sc_if, sc->sc_dev.dv_xname, (void*)sc);
   3158  1.1   dyoung 
   3159  1.1   dyoung 	IFQ_SET_READY(&sc->sc_if.if_snd);
   3160  1.1   dyoung 
   3161  1.1   dyoung 	rtw_set80211props(&sc->sc_ic);
   3162  1.1   dyoung 
   3163  1.1   dyoung 	/*
   3164  1.1   dyoung 	 * Call MI attach routines.
   3165  1.1   dyoung 	 */
   3166  1.1   dyoung 	if_attach(&sc->sc_if);
   3167  1.1   dyoung 	ieee80211_ifattach(&sc->sc_if);
   3168  1.1   dyoung 
   3169  1.1   dyoung 	rtw_set80211methods(&sc->sc_mtbl, &sc->sc_ic);
   3170  1.1   dyoung 
   3171  1.1   dyoung 	/* possibly we should fill in our own sc_send_prresp, since
   3172  1.1   dyoung 	 * the RTL8180 is probably sending probe responses in ad hoc
   3173  1.1   dyoung 	 * mode.
   3174  1.1   dyoung 	 */
   3175  1.1   dyoung 
   3176  1.1   dyoung 	/* complete initialization */
   3177  1.1   dyoung 	ieee80211_media_init(&sc->sc_if, rtw_media_change, rtw_media_status);
   3178  1.1   dyoung 	callout_init(&sc->sc_scan_ch);
   3179  1.1   dyoung 
   3180  1.1   dyoung #if NBPFILTER > 0
   3181  1.1   dyoung 	bpfattach2(&sc->sc_if, DLT_IEEE802_11_RADIO,
   3182  1.1   dyoung 	    sizeof(struct ieee80211_frame) + 64, &sc->sc_radiobpf);
   3183  1.1   dyoung #endif
   3184  1.1   dyoung 
   3185  1.7   dyoung 	rtw_establish_hooks(&sc->sc_hooks, sc->sc_dev.dv_xname, (void*)sc);
   3186  1.1   dyoung 
   3187  1.1   dyoung 	rtw_init_radiotap(sc);
   3188  1.1   dyoung 
   3189  1.1   dyoung 	NEXT_ATTACH_STATE(sc, FINISHED);
   3190  1.1   dyoung 
   3191  1.1   dyoung 	return;
   3192  1.1   dyoung err:
   3193  1.1   dyoung 	rtw_detach(sc);
   3194  1.1   dyoung 	return;
   3195  1.1   dyoung }
   3196  1.1   dyoung 
   3197  1.1   dyoung int
   3198  1.1   dyoung rtw_detach(struct rtw_softc *sc)
   3199  1.1   dyoung {
   3200  1.1   dyoung 	int pri;
   3201  1.1   dyoung 
   3202  1.1   dyoung 	switch (sc->sc_attach_state) {
   3203  1.1   dyoung 	case FINISHED:
   3204  1.3   dyoung 		rtw_stop(&sc->sc_if, 1);
   3205  1.3   dyoung 
   3206  1.7   dyoung 		rtw_disestablish_hooks(&sc->sc_hooks, sc->sc_dev.dv_xname,
   3207  1.1   dyoung 		    (void*)sc);
   3208  1.1   dyoung 		callout_stop(&sc->sc_scan_ch);
   3209  1.1   dyoung 		ieee80211_ifdetach(&sc->sc_if);
   3210  1.1   dyoung 		if_detach(&sc->sc_if);
   3211  1.1   dyoung 		break;
   3212  1.1   dyoung 	case FINISH_ID_STA:
   3213  1.1   dyoung 	case FINISH_RF_ATTACH:
   3214  1.1   dyoung 		rtw_rf_destroy(sc->sc_rf);
   3215  1.1   dyoung 		sc->sc_rf = NULL;
   3216  1.1   dyoung 		/*FALLTHROUGH*/
   3217  1.1   dyoung 	case FINISH_PARSE_SROM:
   3218  1.1   dyoung 	case FINISH_READ_SROM:
   3219  1.1   dyoung 		rtw_srom_free(&sc->sc_srom);
   3220  1.1   dyoung 		/*FALLTHROUGH*/
   3221  1.1   dyoung 	case FINISH_RESET:
   3222  1.1   dyoung 	case FINISH_RXMAPS_CREATE:
   3223  1.1   dyoung 		rtw_rxdesc_dmamaps_destroy(sc->sc_dmat, &sc->sc_rxctl[0],
   3224  1.1   dyoung 		    RTW_RXQLEN);
   3225  1.1   dyoung 		/*FALLTHROUGH*/
   3226  1.1   dyoung 	case FINISH_TXMAPS_CREATE:
   3227  1.1   dyoung 		for (pri = 0; pri < RTW_NTXPRI; pri++) {
   3228  1.1   dyoung 			rtw_txdesc_dmamaps_destroy(sc->sc_dmat,
   3229  1.1   dyoung 			    sc->sc_txctl_blk[pri].stc_desc,
   3230  1.1   dyoung 			    sc->sc_txctl_blk[pri].stc_ndesc);
   3231  1.1   dyoung 		}
   3232  1.1   dyoung 		/*FALLTHROUGH*/
   3233  1.1   dyoung 	case FINISH_TXDESCBLK_SETUP:
   3234  1.1   dyoung 	case FINISH_TXCTLBLK_SETUP:
   3235  1.1   dyoung 		rtw_txctl_blk_cleanup_all(sc);
   3236  1.1   dyoung 		/*FALLTHROUGH*/
   3237  1.1   dyoung 	case FINISH_DESCMAP_LOAD:
   3238  1.1   dyoung 		bus_dmamap_unload(sc->sc_dmat, sc->sc_desc_dmamap);
   3239  1.1   dyoung 		/*FALLTHROUGH*/
   3240  1.1   dyoung 	case FINISH_DESCMAP_CREATE:
   3241  1.1   dyoung 		bus_dmamap_destroy(sc->sc_dmat, sc->sc_desc_dmamap);
   3242  1.1   dyoung 		/*FALLTHROUGH*/
   3243  1.1   dyoung 	case FINISH_DESC_MAP:
   3244  1.1   dyoung 		bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_descs,
   3245  1.1   dyoung 		    sizeof(struct rtw_descs));
   3246  1.1   dyoung 		/*FALLTHROUGH*/
   3247  1.1   dyoung 	case FINISH_DESC_ALLOC:
   3248  1.1   dyoung 		bus_dmamem_free(sc->sc_dmat, &sc->sc_desc_segs,
   3249  1.1   dyoung 		    sc->sc_desc_nsegs);
   3250  1.1   dyoung 		/*FALLTHROUGH*/
   3251  1.1   dyoung 	case DETACHED:
   3252  1.1   dyoung 		NEXT_ATTACH_STATE(sc, DETACHED);
   3253  1.1   dyoung 		break;
   3254  1.1   dyoung 	}
   3255  1.1   dyoung 	return 0;
   3256  1.1   dyoung }
   3257  1.1   dyoung 
   3258  1.1   dyoung int
   3259  1.1   dyoung rtw_activate(struct device *self, enum devact act)
   3260  1.1   dyoung {
   3261  1.1   dyoung 	struct rtw_softc *sc = (struct rtw_softc *)self;
   3262  1.1   dyoung 	int rc = 0, s;
   3263  1.1   dyoung 
   3264  1.1   dyoung 	s = splnet();
   3265  1.1   dyoung 	switch (act) {
   3266  1.1   dyoung 	case DVACT_ACTIVATE:
   3267  1.1   dyoung 		rc = EOPNOTSUPP;
   3268  1.1   dyoung 		break;
   3269  1.1   dyoung 
   3270  1.1   dyoung 	case DVACT_DEACTIVATE:
   3271  1.1   dyoung 		if_deactivate(&sc->sc_ic.ic_if);
   3272  1.1   dyoung 		break;
   3273  1.1   dyoung 	}
   3274  1.1   dyoung 	splx(s);
   3275  1.1   dyoung 	return rc;
   3276  1.1   dyoung }
   3277