]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - sys/dev/mwl/if_mwl.c
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / sys / dev / mwl / if_mwl.c
1 /*-
2  * Copyright (c) 2007-2009 Sam Leffler, Errno Consulting
3  * Copyright (c) 2007-2008 Marvell Semiconductor, Inc.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer,
11  *    without modification.
12  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
13  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
14  *    redistribution must be conditioned upon including a substantially
15  *    similar Disclaimer requirement for further binary redistribution.
16  *
17  * NO WARRANTY
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
21  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
23  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
26  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28  * THE POSSIBILITY OF SUCH DAMAGES.
29  */
30
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33
34 /*
35  * Driver for the Marvell 88W8363 Wireless LAN controller.
36  */
37
38 #include "opt_inet.h"
39 #include "opt_mwl.h"
40
41 #include <sys/param.h>
42 #include <sys/systm.h> 
43 #include <sys/sysctl.h>
44 #include <sys/mbuf.h>   
45 #include <sys/malloc.h>
46 #include <sys/lock.h>
47 #include <sys/mutex.h>
48 #include <sys/kernel.h>
49 #include <sys/socket.h>
50 #include <sys/sockio.h>
51 #include <sys/errno.h>
52 #include <sys/callout.h>
53 #include <sys/bus.h>
54 #include <sys/endian.h>
55 #include <sys/kthread.h>
56 #include <sys/taskqueue.h>
57
58 #include <machine/bus.h>
59  
60 #include <net/if.h>
61 #include <net/if_dl.h>
62 #include <net/if_media.h>
63 #include <net/if_types.h>
64 #include <net/if_arp.h>
65 #include <net/ethernet.h>
66 #include <net/if_llc.h>
67
68 #include <net/bpf.h>
69
70 #include <net80211/ieee80211_var.h>
71 #include <net80211/ieee80211_regdomain.h>
72
73 #ifdef INET
74 #include <netinet/in.h>
75 #include <netinet/if_ether.h>
76 #endif /* INET */
77
78 #include <dev/mwl/if_mwlvar.h>
79 #include <dev/mwl/mwldiag.h>
80
81 /* idiomatic shorthands: MS = mask+shift, SM = shift+mask */
82 #define MS(v,x) (((v) & x) >> x##_S)
83 #define SM(v,x) (((v) << x##_S) & x)
84
85 static struct ieee80211vap *mwl_vap_create(struct ieee80211com *,
86                     const char name[IFNAMSIZ], int unit, int opmode,
87                     int flags, const uint8_t bssid[IEEE80211_ADDR_LEN],
88                     const uint8_t mac[IEEE80211_ADDR_LEN]);
89 static void     mwl_vap_delete(struct ieee80211vap *);
90 static int      mwl_setupdma(struct mwl_softc *);
91 static int      mwl_hal_reset(struct mwl_softc *sc);
92 static int      mwl_init_locked(struct mwl_softc *);
93 static void     mwl_init(void *);
94 static void     mwl_stop_locked(struct ifnet *, int);
95 static int      mwl_reset(struct ieee80211vap *, u_long);
96 static void     mwl_stop(struct ifnet *, int);
97 static void     mwl_start(struct ifnet *);
98 static int      mwl_raw_xmit(struct ieee80211_node *, struct mbuf *,
99                         const struct ieee80211_bpf_params *);
100 static int      mwl_media_change(struct ifnet *);
101 static void     mwl_watchdog(struct ifnet *);
102 static int      mwl_ioctl(struct ifnet *, u_long, caddr_t);
103 static void     mwl_radar_proc(void *, int);
104 static void     mwl_chanswitch_proc(void *, int);
105 static void     mwl_bawatchdog_proc(void *, int);
106 static int      mwl_key_alloc(struct ieee80211vap *,
107                         struct ieee80211_key *,
108                         ieee80211_keyix *, ieee80211_keyix *);
109 static int      mwl_key_delete(struct ieee80211vap *,
110                         const struct ieee80211_key *);
111 static int      mwl_key_set(struct ieee80211vap *, const struct ieee80211_key *,
112                         const uint8_t mac[IEEE80211_ADDR_LEN]);
113 static int      mwl_mode_init(struct mwl_softc *);
114 static void     mwl_update_mcast(struct ifnet *);
115 static void     mwl_update_promisc(struct ifnet *);
116 static void     mwl_updateslot(struct ifnet *);
117 static int      mwl_beacon_setup(struct ieee80211vap *);
118 static void     mwl_beacon_update(struct ieee80211vap *, int);
119 #ifdef MWL_HOST_PS_SUPPORT
120 static void     mwl_update_ps(struct ieee80211vap *, int);
121 static int      mwl_set_tim(struct ieee80211_node *, int);
122 #endif
123 static int      mwl_dma_setup(struct mwl_softc *);
124 static void     mwl_dma_cleanup(struct mwl_softc *);
125 static struct ieee80211_node *mwl_node_alloc(struct ieee80211vap *,
126                     const uint8_t [IEEE80211_ADDR_LEN]);
127 static void     mwl_node_cleanup(struct ieee80211_node *);
128 static void     mwl_node_drain(struct ieee80211_node *);
129 static void     mwl_node_getsignal(const struct ieee80211_node *,
130                         int8_t *, int8_t *);
131 static void     mwl_node_getmimoinfo(const struct ieee80211_node *,
132                         struct ieee80211_mimo_info *);
133 static int      mwl_rxbuf_init(struct mwl_softc *, struct mwl_rxbuf *);
134 static void     mwl_rx_proc(void *, int);
135 static void     mwl_txq_init(struct mwl_softc *sc, struct mwl_txq *, int);
136 static int      mwl_tx_setup(struct mwl_softc *, int, int);
137 static int      mwl_wme_update(struct ieee80211com *);
138 static void     mwl_tx_cleanupq(struct mwl_softc *, struct mwl_txq *);
139 static void     mwl_tx_cleanup(struct mwl_softc *);
140 static uint16_t mwl_calcformat(uint8_t rate, const struct ieee80211_node *);
141 static int      mwl_tx_start(struct mwl_softc *, struct ieee80211_node *,
142                              struct mwl_txbuf *, struct mbuf *);
143 static void     mwl_tx_proc(void *, int);
144 static int      mwl_chan_set(struct mwl_softc *, struct ieee80211_channel *);
145 static void     mwl_draintxq(struct mwl_softc *);
146 static void     mwl_cleartxq(struct mwl_softc *, struct ieee80211vap *);
147 static int      mwl_recv_action(struct ieee80211_node *,
148                         const struct ieee80211_frame *,
149                         const uint8_t *, const uint8_t *);
150 static int      mwl_addba_request(struct ieee80211_node *,
151                         struct ieee80211_tx_ampdu *, int dialogtoken,
152                         int baparamset, int batimeout);
153 static int      mwl_addba_response(struct ieee80211_node *,
154                         struct ieee80211_tx_ampdu *, int status,
155                         int baparamset, int batimeout);
156 static void     mwl_addba_stop(struct ieee80211_node *,
157                         struct ieee80211_tx_ampdu *);
158 static int      mwl_startrecv(struct mwl_softc *);
159 static MWL_HAL_APMODE mwl_getapmode(const struct ieee80211vap *,
160                         struct ieee80211_channel *);
161 static int      mwl_setapmode(struct ieee80211vap *, struct ieee80211_channel*);
162 static void     mwl_scan_start(struct ieee80211com *);
163 static void     mwl_scan_end(struct ieee80211com *);
164 static void     mwl_set_channel(struct ieee80211com *);
165 static int      mwl_peerstadb(struct ieee80211_node *,
166                         int aid, int staid, MWL_HAL_PEERINFO *pi);
167 static int      mwl_localstadb(struct ieee80211vap *);
168 static int      mwl_newstate(struct ieee80211vap *, enum ieee80211_state, int);
169 static int      allocstaid(struct mwl_softc *sc, int aid);
170 static void     delstaid(struct mwl_softc *sc, int staid);
171 static void     mwl_newassoc(struct ieee80211_node *, int);
172 static void     mwl_agestations(void *);
173 static int      mwl_setregdomain(struct ieee80211com *,
174                         struct ieee80211_regdomain *, int,
175                         struct ieee80211_channel []);
176 static void     mwl_getradiocaps(struct ieee80211com *, int, int *,
177                         struct ieee80211_channel []);
178 static int      mwl_getchannels(struct mwl_softc *);
179
180 static void     mwl_sysctlattach(struct mwl_softc *);
181 static void     mwl_announce(struct mwl_softc *);
182
183 SYSCTL_NODE(_hw, OID_AUTO, mwl, CTLFLAG_RD, 0, "Marvell driver parameters");
184
185 static  int mwl_rxdesc = MWL_RXDESC;            /* # rx desc's to allocate */
186 SYSCTL_INT(_hw_mwl, OID_AUTO, rxdesc, CTLFLAG_RW, &mwl_rxdesc,
187             0, "rx descriptors allocated");
188 static  int mwl_rxbuf = MWL_RXBUF;              /* # rx buffers to allocate */
189 SYSCTL_INT(_hw_mwl, OID_AUTO, rxbuf, CTLFLAG_RW, &mwl_rxbuf,
190             0, "rx buffers allocated");
191 TUNABLE_INT("hw.mwl.rxbuf", &mwl_rxbuf);
192 static  int mwl_txbuf = MWL_TXBUF;              /* # tx buffers to allocate */
193 SYSCTL_INT(_hw_mwl, OID_AUTO, txbuf, CTLFLAG_RW, &mwl_txbuf,
194             0, "tx buffers allocated");
195 TUNABLE_INT("hw.mwl.txbuf", &mwl_txbuf);
196 static  int mwl_txcoalesce = 8;         /* # tx packets to q before poking f/w*/
197 SYSCTL_INT(_hw_mwl, OID_AUTO, txcoalesce, CTLFLAG_RW, &mwl_txcoalesce,
198             0, "tx buffers to send at once");
199 TUNABLE_INT("hw.mwl.txcoalesce", &mwl_txcoalesce);
200 static  int mwl_rxquota = MWL_RXBUF;            /* # max buffers to process */
201 SYSCTL_INT(_hw_mwl, OID_AUTO, rxquota, CTLFLAG_RW, &mwl_rxquota,
202             0, "max rx buffers to process per interrupt");
203 TUNABLE_INT("hw.mwl.rxquota", &mwl_rxquota);
204 static  int mwl_rxdmalow = 3;                   /* # min buffers for wakeup */
205 SYSCTL_INT(_hw_mwl, OID_AUTO, rxdmalow, CTLFLAG_RW, &mwl_rxdmalow,
206             0, "min free rx buffers before restarting traffic");
207 TUNABLE_INT("hw.mwl.rxdmalow", &mwl_rxdmalow);
208
209 #ifdef MWL_DEBUG
210 static  int mwl_debug = 0;
211 SYSCTL_INT(_hw_mwl, OID_AUTO, debug, CTLFLAG_RW, &mwl_debug,
212             0, "control debugging printfs");
213 TUNABLE_INT("hw.mwl.debug", &mwl_debug);
214 enum {
215         MWL_DEBUG_XMIT          = 0x00000001,   /* basic xmit operation */
216         MWL_DEBUG_XMIT_DESC     = 0x00000002,   /* xmit descriptors */
217         MWL_DEBUG_RECV          = 0x00000004,   /* basic recv operation */
218         MWL_DEBUG_RECV_DESC     = 0x00000008,   /* recv descriptors */
219         MWL_DEBUG_RESET         = 0x00000010,   /* reset processing */
220         MWL_DEBUG_BEACON        = 0x00000020,   /* beacon handling */
221         MWL_DEBUG_INTR          = 0x00000040,   /* ISR */
222         MWL_DEBUG_TX_PROC       = 0x00000080,   /* tx ISR proc */
223         MWL_DEBUG_RX_PROC       = 0x00000100,   /* rx ISR proc */
224         MWL_DEBUG_KEYCACHE      = 0x00000200,   /* key cache management */
225         MWL_DEBUG_STATE         = 0x00000400,   /* 802.11 state transitions */
226         MWL_DEBUG_NODE          = 0x00000800,   /* node management */
227         MWL_DEBUG_RECV_ALL      = 0x00001000,   /* trace all frames (beacons) */
228         MWL_DEBUG_TSO           = 0x00002000,   /* TSO processing */
229         MWL_DEBUG_AMPDU         = 0x00004000,   /* BA stream handling */
230         MWL_DEBUG_ANY           = 0xffffffff
231 };
232 #define IS_BEACON(wh) \
233     ((wh->i_fc[0] & (IEEE80211_FC0_TYPE_MASK|IEEE80211_FC0_SUBTYPE_MASK)) == \
234          (IEEE80211_FC0_TYPE_MGT|IEEE80211_FC0_SUBTYPE_BEACON))
235 #define IFF_DUMPPKTS_RECV(sc, wh) \
236     (((sc->sc_debug & MWL_DEBUG_RECV) && \
237       ((sc->sc_debug & MWL_DEBUG_RECV_ALL) || !IS_BEACON(wh))) || \
238      (sc->sc_ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) == (IFF_DEBUG|IFF_LINK2))
239 #define IFF_DUMPPKTS_XMIT(sc) \
240         ((sc->sc_debug & MWL_DEBUG_XMIT) || \
241          (sc->sc_ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) == (IFF_DEBUG|IFF_LINK2))
242 #define DPRINTF(sc, m, fmt, ...) do {                           \
243         if (sc->sc_debug & (m))                                 \
244                 printf(fmt, __VA_ARGS__);                       \
245 } while (0)
246 #define KEYPRINTF(sc, hk, mac) do {                             \
247         if (sc->sc_debug & MWL_DEBUG_KEYCACHE)                  \
248                 mwl_keyprint(sc, __func__, hk, mac);            \
249 } while (0)
250 static  void mwl_printrxbuf(const struct mwl_rxbuf *bf, u_int ix);
251 static  void mwl_printtxbuf(const struct mwl_txbuf *bf, u_int qnum, u_int ix);
252 #else
253 #define IFF_DUMPPKTS_RECV(sc, wh) \
254         ((sc->sc_ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) == (IFF_DEBUG|IFF_LINK2))
255 #define IFF_DUMPPKTS_XMIT(sc) \
256         ((sc->sc_ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) == (IFF_DEBUG|IFF_LINK2))
257 #define DPRINTF(sc, m, fmt, ...) do {                           \
258         (void) sc;                                              \
259 } while (0)
260 #define KEYPRINTF(sc, k, mac) do {                              \
261         (void) sc;                                              \
262 } while (0)
263 #endif
264
265 MALLOC_DEFINE(M_MWLDEV, "mwldev", "mwl driver dma buffers");
266
267 /*
268  * Each packet has fixed front matter: a 2-byte length
269  * of the payload, followed by a 4-address 802.11 header
270  * (regardless of the actual header and always w/o any
271  * QoS header).  The payload then follows.
272  */
273 struct mwltxrec {
274         uint16_t fwlen;
275         struct ieee80211_frame_addr4 wh;
276 } __packed;
277
278 /*
279  * Read/Write shorthands for accesses to BAR 0.  Note
280  * that all BAR 1 operations are done in the "hal" and
281  * there should be no reference to them here.
282  */
283 static __inline uint32_t
284 RD4(struct mwl_softc *sc, bus_size_t off)
285 {
286         return bus_space_read_4(sc->sc_io0t, sc->sc_io0h, off);
287 }
288
289 static __inline void
290 WR4(struct mwl_softc *sc, bus_size_t off, uint32_t val)
291 {
292         bus_space_write_4(sc->sc_io0t, sc->sc_io0h, off, val);
293 }
294
295 int
296 mwl_attach(uint16_t devid, struct mwl_softc *sc)
297 {
298         struct ifnet *ifp;
299         struct ieee80211com *ic;
300         struct mwl_hal *mh;
301         int error = 0;
302
303         DPRINTF(sc, MWL_DEBUG_ANY, "%s: devid 0x%x\n", __func__, devid);
304
305         ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
306         if (ifp == NULL) {
307                 device_printf(sc->sc_dev, "can not if_alloc()\n");
308                 return ENOSPC;
309         }
310         ic = ifp->if_l2com;
311
312         /* set these up early for if_printf use */
313         if_initname(ifp, device_get_name(sc->sc_dev),
314                 device_get_unit(sc->sc_dev));
315
316         mh = mwl_hal_attach(sc->sc_dev, devid,
317             sc->sc_io1h, sc->sc_io1t, sc->sc_dmat);
318         if (mh == NULL) {
319                 if_printf(ifp, "unable to attach HAL\n");
320                 error = EIO;
321                 goto bad;
322         }
323         sc->sc_mh = mh;
324         /*
325          * Load firmware so we can get setup.  We arbitrarily
326          * pick station firmware; we'll re-load firmware as
327          * needed so setting up the wrong mode isn't a big deal.
328          */
329         if (mwl_hal_fwload(mh, NULL) != 0) {
330                 if_printf(ifp, "unable to setup builtin firmware\n");
331                 error = EIO;
332                 goto bad1;
333         }
334         if (mwl_hal_gethwspecs(mh, &sc->sc_hwspecs) != 0) {
335                 if_printf(ifp, "unable to fetch h/w specs\n");
336                 error = EIO;
337                 goto bad1;
338         }
339         error = mwl_getchannels(sc);
340         if (error != 0)
341                 goto bad1;
342
343         sc->sc_txantenna = 0;           /* h/w default */
344         sc->sc_rxantenna = 0;           /* h/w default */
345         sc->sc_invalid = 0;             /* ready to go, enable int handling */
346         sc->sc_ageinterval = MWL_AGEINTERVAL;
347
348         /*
349          * Allocate tx+rx descriptors and populate the lists.
350          * We immediately push the information to the firmware
351          * as otherwise it gets upset.
352          */
353         error = mwl_dma_setup(sc);
354         if (error != 0) {
355                 if_printf(ifp, "failed to setup descriptors: %d\n", error);
356                 goto bad1;
357         }
358         error = mwl_setupdma(sc);       /* push to firmware */
359         if (error != 0)                 /* NB: mwl_setupdma prints msg */
360                 goto bad1;
361
362         callout_init(&sc->sc_timer, CALLOUT_MPSAFE);
363
364         sc->sc_tq = taskqueue_create("mwl_taskq", M_NOWAIT,
365                 taskqueue_thread_enqueue, &sc->sc_tq);
366         taskqueue_start_threads(&sc->sc_tq, 1, PI_NET,
367                 "%s taskq", ifp->if_xname);
368
369         TASK_INIT(&sc->sc_rxtask, 0, mwl_rx_proc, sc);
370         TASK_INIT(&sc->sc_radartask, 0, mwl_radar_proc, sc);
371         TASK_INIT(&sc->sc_chanswitchtask, 0, mwl_chanswitch_proc, sc);
372         TASK_INIT(&sc->sc_bawatchdogtask, 0, mwl_bawatchdog_proc, sc);
373
374         /* NB: insure BK queue is the lowest priority h/w queue */
375         if (!mwl_tx_setup(sc, WME_AC_BK, MWL_WME_AC_BK)) {
376                 if_printf(ifp, "unable to setup xmit queue for %s traffic!\n",
377                         ieee80211_wme_acnames[WME_AC_BK]);
378                 error = EIO;
379                 goto bad2;
380         }
381         if (!mwl_tx_setup(sc, WME_AC_BE, MWL_WME_AC_BE) ||
382             !mwl_tx_setup(sc, WME_AC_VI, MWL_WME_AC_VI) ||
383             !mwl_tx_setup(sc, WME_AC_VO, MWL_WME_AC_VO)) {
384                 /*
385                  * Not enough hardware tx queues to properly do WME;
386                  * just punt and assign them all to the same h/w queue.
387                  * We could do a better job of this if, for example,
388                  * we allocate queues when we switch from station to
389                  * AP mode.
390                  */
391                 if (sc->sc_ac2q[WME_AC_VI] != NULL)
392                         mwl_tx_cleanupq(sc, sc->sc_ac2q[WME_AC_VI]);
393                 if (sc->sc_ac2q[WME_AC_BE] != NULL)
394                         mwl_tx_cleanupq(sc, sc->sc_ac2q[WME_AC_BE]);
395                 sc->sc_ac2q[WME_AC_BE] = sc->sc_ac2q[WME_AC_BK];
396                 sc->sc_ac2q[WME_AC_VI] = sc->sc_ac2q[WME_AC_BK];
397                 sc->sc_ac2q[WME_AC_VO] = sc->sc_ac2q[WME_AC_BK];
398         }
399         TASK_INIT(&sc->sc_txtask, 0, mwl_tx_proc, sc);
400
401         ifp->if_softc = sc;
402         ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST;
403         ifp->if_start = mwl_start;
404         ifp->if_watchdog = mwl_watchdog;
405         ifp->if_ioctl = mwl_ioctl;
406         ifp->if_init = mwl_init;
407         IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
408         ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
409         IFQ_SET_READY(&ifp->if_snd);
410
411         ic->ic_ifp = ifp;
412         /* XXX not right but it's not used anywhere important */
413         ic->ic_phytype = IEEE80211_T_OFDM;
414         ic->ic_opmode = IEEE80211_M_STA;
415         ic->ic_caps =
416                   IEEE80211_C_STA               /* station mode supported */
417                 | IEEE80211_C_HOSTAP            /* hostap mode */
418                 | IEEE80211_C_MONITOR           /* monitor mode */
419 #if 0
420                 | IEEE80211_C_IBSS              /* ibss, nee adhoc, mode */
421                 | IEEE80211_C_AHDEMO            /* adhoc demo mode */
422 #endif
423                 | IEEE80211_C_MBSS              /* mesh point link mode */
424                 | IEEE80211_C_WDS               /* WDS supported */
425                 | IEEE80211_C_SHPREAMBLE        /* short preamble supported */
426                 | IEEE80211_C_SHSLOT            /* short slot time supported */
427                 | IEEE80211_C_WME               /* WME/WMM supported */
428                 | IEEE80211_C_BURST             /* xmit bursting supported */
429                 | IEEE80211_C_WPA               /* capable of WPA1+WPA2 */
430                 | IEEE80211_C_BGSCAN            /* capable of bg scanning */
431                 | IEEE80211_C_TXFRAG            /* handle tx frags */
432                 | IEEE80211_C_TXPMGT            /* capable of txpow mgt */
433                 | IEEE80211_C_DFS               /* DFS supported */
434                 ;
435
436         ic->ic_htcaps =
437                   IEEE80211_HTCAP_SMPS_ENA      /* SM PS mode enabled */
438                 | IEEE80211_HTCAP_CHWIDTH40     /* 40MHz channel width */
439                 | IEEE80211_HTCAP_SHORTGI20     /* short GI in 20MHz */
440                 | IEEE80211_HTCAP_SHORTGI40     /* short GI in 40MHz */
441                 | IEEE80211_HTCAP_RXSTBC_2STREAM/* 1-2 spatial streams */
442 #if MWL_AGGR_SIZE == 7935
443                 | IEEE80211_HTCAP_MAXAMSDU_7935 /* max A-MSDU length */
444 #else
445                 | IEEE80211_HTCAP_MAXAMSDU_3839 /* max A-MSDU length */
446 #endif
447 #if 0
448                 | IEEE80211_HTCAP_PSMP          /* PSMP supported */
449                 | IEEE80211_HTCAP_40INTOLERANT  /* 40MHz intolerant */
450 #endif
451                 /* s/w capabilities */
452                 | IEEE80211_HTC_HT              /* HT operation */
453                 | IEEE80211_HTC_AMPDU           /* tx A-MPDU */
454                 | IEEE80211_HTC_AMSDU           /* tx A-MSDU */
455                 | IEEE80211_HTC_SMPS            /* SMPS available */
456                 ;
457
458         /*
459          * Mark h/w crypto support.
460          * XXX no way to query h/w support.
461          */
462         ic->ic_cryptocaps |= IEEE80211_CRYPTO_WEP
463                           |  IEEE80211_CRYPTO_AES_CCM
464                           |  IEEE80211_CRYPTO_TKIP
465                           |  IEEE80211_CRYPTO_TKIPMIC
466                           ;
467         /*
468          * Transmit requires space in the packet for a special
469          * format transmit record and optional padding between
470          * this record and the payload.  Ask the net80211 layer
471          * to arrange this when encapsulating packets so we can
472          * add it efficiently. 
473          */
474         ic->ic_headroom = sizeof(struct mwltxrec) -
475                 sizeof(struct ieee80211_frame);
476
477         /* call MI attach routine. */
478         ieee80211_ifattach(ic, sc->sc_hwspecs.macAddr);
479         ic->ic_setregdomain = mwl_setregdomain;
480         ic->ic_getradiocaps = mwl_getradiocaps;
481         /* override default methods */
482         ic->ic_raw_xmit = mwl_raw_xmit;
483         ic->ic_newassoc = mwl_newassoc;
484         ic->ic_updateslot = mwl_updateslot;
485         ic->ic_update_mcast = mwl_update_mcast;
486         ic->ic_update_promisc = mwl_update_promisc;
487         ic->ic_wme.wme_update = mwl_wme_update;
488
489         ic->ic_node_alloc = mwl_node_alloc;
490         sc->sc_node_cleanup = ic->ic_node_cleanup;
491         ic->ic_node_cleanup = mwl_node_cleanup;
492         sc->sc_node_drain = ic->ic_node_drain;
493         ic->ic_node_drain = mwl_node_drain;
494         ic->ic_node_getsignal = mwl_node_getsignal;
495         ic->ic_node_getmimoinfo = mwl_node_getmimoinfo;
496
497         ic->ic_scan_start = mwl_scan_start;
498         ic->ic_scan_end = mwl_scan_end;
499         ic->ic_set_channel = mwl_set_channel;
500
501         sc->sc_recv_action = ic->ic_recv_action;
502         ic->ic_recv_action = mwl_recv_action;
503         sc->sc_addba_request = ic->ic_addba_request;
504         ic->ic_addba_request = mwl_addba_request;
505         sc->sc_addba_response = ic->ic_addba_response;
506         ic->ic_addba_response = mwl_addba_response;
507         sc->sc_addba_stop = ic->ic_addba_stop;
508         ic->ic_addba_stop = mwl_addba_stop;
509
510         ic->ic_vap_create = mwl_vap_create;
511         ic->ic_vap_delete = mwl_vap_delete;
512
513         ieee80211_radiotap_attach(ic,
514             &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th),
515                 MWL_TX_RADIOTAP_PRESENT,
516             &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th),
517                 MWL_RX_RADIOTAP_PRESENT);
518         /*
519          * Setup dynamic sysctl's now that country code and
520          * regdomain are available from the hal.
521          */
522         mwl_sysctlattach(sc);
523
524         if (bootverbose)
525                 ieee80211_announce(ic);
526         mwl_announce(sc);
527         return 0;
528 bad2:
529         mwl_dma_cleanup(sc);
530 bad1:
531         mwl_hal_detach(mh);
532 bad:
533         if_free(ifp);
534         sc->sc_invalid = 1;
535         return error;
536 }
537
538 int
539 mwl_detach(struct mwl_softc *sc)
540 {
541         struct ifnet *ifp = sc->sc_ifp;
542         struct ieee80211com *ic = ifp->if_l2com;
543
544         DPRINTF(sc, MWL_DEBUG_ANY, "%s: if_flags %x\n",
545                 __func__, ifp->if_flags);
546
547         mwl_stop(ifp, 1);
548         /*
549          * NB: the order of these is important:
550          * o call the 802.11 layer before detaching the hal to
551          *   insure callbacks into the driver to delete global
552          *   key cache entries can be handled
553          * o reclaim the tx queue data structures after calling
554          *   the 802.11 layer as we'll get called back to reclaim
555          *   node state and potentially want to use them
556          * o to cleanup the tx queues the hal is called, so detach
557          *   it last
558          * Other than that, it's straightforward...
559          */
560         ieee80211_ifdetach(ic);
561         mwl_dma_cleanup(sc);
562         mwl_tx_cleanup(sc);
563         mwl_hal_detach(sc->sc_mh);
564         if_free(ifp);
565
566         return 0;
567 }
568
569 /*
570  * MAC address handling for multiple BSS on the same radio.
571  * The first vap uses the MAC address from the EEPROM.  For
572  * subsequent vap's we set the U/L bit (bit 1) in the MAC
573  * address and use the next six bits as an index.
574  */
575 static void
576 assign_address(struct mwl_softc *sc, uint8_t mac[IEEE80211_ADDR_LEN], int clone)
577 {
578         int i;
579
580         if (clone && mwl_hal_ismbsscapable(sc->sc_mh)) {
581                 /* NB: we only do this if h/w supports multiple bssid */
582                 for (i = 0; i < 32; i++)
583                         if ((sc->sc_bssidmask & (1<<i)) == 0)
584                                 break;
585                 if (i != 0)
586                         mac[0] |= (i << 2)|0x2;
587         } else
588                 i = 0;
589         sc->sc_bssidmask |= 1<<i;
590         if (i == 0)
591                 sc->sc_nbssid0++;
592 }
593
594 static void
595 reclaim_address(struct mwl_softc *sc, uint8_t mac[IEEE80211_ADDR_LEN])
596 {
597         int i = mac[0] >> 2;
598         if (i != 0 || --sc->sc_nbssid0 == 0)
599                 sc->sc_bssidmask &= ~(1<<i);
600 }
601
602 static struct ieee80211vap *
603 mwl_vap_create(struct ieee80211com *ic,
604         const char name[IFNAMSIZ], int unit, int opmode, int flags,
605         const uint8_t bssid[IEEE80211_ADDR_LEN],
606         const uint8_t mac0[IEEE80211_ADDR_LEN])
607 {
608         struct ifnet *ifp = ic->ic_ifp;
609         struct mwl_softc *sc = ifp->if_softc;
610         struct mwl_hal *mh = sc->sc_mh;
611         struct ieee80211vap *vap, *apvap;
612         struct mwl_hal_vap *hvap;
613         struct mwl_vap *mvp;
614         uint8_t mac[IEEE80211_ADDR_LEN];
615
616         IEEE80211_ADDR_COPY(mac, mac0);
617         switch (opmode) {
618         case IEEE80211_M_HOSTAP:
619         case IEEE80211_M_MBSS:
620                 if ((flags & IEEE80211_CLONE_MACADDR) == 0)
621                         assign_address(sc, mac, flags & IEEE80211_CLONE_BSSID);
622                 hvap = mwl_hal_newvap(mh, MWL_HAL_AP, mac);
623                 if (hvap == NULL) {
624                         if ((flags & IEEE80211_CLONE_MACADDR) == 0)
625                                 reclaim_address(sc, mac);
626                         return NULL;
627                 }
628                 break;
629         case IEEE80211_M_STA:
630                 if ((flags & IEEE80211_CLONE_MACADDR) == 0)
631                         assign_address(sc, mac, flags & IEEE80211_CLONE_BSSID);
632                 hvap = mwl_hal_newvap(mh, MWL_HAL_STA, mac);
633                 if (hvap == NULL) {
634                         if ((flags & IEEE80211_CLONE_MACADDR) == 0)
635                                 reclaim_address(sc, mac);
636                         return NULL;
637                 }
638                 /* no h/w beacon miss support; always use s/w */
639                 flags |= IEEE80211_CLONE_NOBEACONS;
640                 break;
641         case IEEE80211_M_WDS:
642                 hvap = NULL;            /* NB: we use associated AP vap */
643                 if (sc->sc_napvaps == 0)
644                         return NULL;    /* no existing AP vap */
645                 break;
646         case IEEE80211_M_MONITOR:
647                 hvap = NULL;
648                 break;
649         case IEEE80211_M_IBSS:
650         case IEEE80211_M_AHDEMO:
651         default:
652                 return NULL;
653         }
654
655         mvp = (struct mwl_vap *) malloc(sizeof(struct mwl_vap),
656             M_80211_VAP, M_NOWAIT | M_ZERO);
657         if (mvp == NULL) {
658                 if (hvap != NULL) {
659                         mwl_hal_delvap(hvap);
660                         if ((flags & IEEE80211_CLONE_MACADDR) == 0)
661                                 reclaim_address(sc, mac);
662                 }
663                 /* XXX msg */
664                 return NULL;
665         }
666         mvp->mv_hvap = hvap;
667         if (opmode == IEEE80211_M_WDS) {
668                 /*
669                  * WDS vaps must have an associated AP vap; find one.
670                  * XXX not right.
671                  */
672                 TAILQ_FOREACH(apvap, &ic->ic_vaps, iv_next)
673                         if (apvap->iv_opmode == IEEE80211_M_HOSTAP) {
674                                 mvp->mv_ap_hvap = MWL_VAP(apvap)->mv_hvap;
675                                 break;
676                         }
677                 KASSERT(mvp->mv_ap_hvap != NULL, ("no ap vap"));
678         }
679         vap = &mvp->mv_vap;
680         ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
681         if (hvap != NULL)
682                 IEEE80211_ADDR_COPY(vap->iv_myaddr, mac);
683         /* override with driver methods */
684         mvp->mv_newstate = vap->iv_newstate;
685         vap->iv_newstate = mwl_newstate;
686         vap->iv_max_keyix = 0;  /* XXX */
687         vap->iv_key_alloc = mwl_key_alloc;
688         vap->iv_key_delete = mwl_key_delete;
689         vap->iv_key_set = mwl_key_set;
690 #ifdef MWL_HOST_PS_SUPPORT
691         if (opmode == IEEE80211_M_HOSTAP || opmode == IEEE80211_M_MBSS) {
692                 vap->iv_update_ps = mwl_update_ps;
693                 mvp->mv_set_tim = vap->iv_set_tim;
694                 vap->iv_set_tim = mwl_set_tim;
695         }
696 #endif
697         vap->iv_reset = mwl_reset;
698         vap->iv_update_beacon = mwl_beacon_update;
699
700         /* override max aid so sta's cannot assoc when we're out of sta id's */
701         vap->iv_max_aid = MWL_MAXSTAID;
702         /* override default A-MPDU rx parameters */
703         vap->iv_ampdu_rxmax = IEEE80211_HTCAP_MAXRXAMPDU_64K;
704         vap->iv_ampdu_density = IEEE80211_HTCAP_MPDUDENSITY_4;
705
706         /* complete setup */
707         ieee80211_vap_attach(vap, mwl_media_change, ieee80211_media_status);
708
709         switch (vap->iv_opmode) {
710         case IEEE80211_M_HOSTAP:
711         case IEEE80211_M_MBSS:
712         case IEEE80211_M_STA:
713                 /*
714                  * Setup sta db entry for local address.
715                  */
716                 mwl_localstadb(vap);
717                 if (vap->iv_opmode == IEEE80211_M_HOSTAP ||
718                     vap->iv_opmode == IEEE80211_M_MBSS)
719                         sc->sc_napvaps++;
720                 else
721                         sc->sc_nstavaps++;
722                 break;
723         case IEEE80211_M_WDS:
724                 sc->sc_nwdsvaps++;
725                 break;
726         default:
727                 break;
728         }
729         /*
730          * Setup overall operating mode.
731          */
732         if (sc->sc_napvaps)
733                 ic->ic_opmode = IEEE80211_M_HOSTAP;
734         else if (sc->sc_nstavaps)
735                 ic->ic_opmode = IEEE80211_M_STA;
736         else
737                 ic->ic_opmode = opmode;
738
739         return vap;
740 }
741
742 static void
743 mwl_vap_delete(struct ieee80211vap *vap)
744 {
745         struct mwl_vap *mvp = MWL_VAP(vap);
746         struct ifnet *parent = vap->iv_ic->ic_ifp;
747         struct mwl_softc *sc = parent->if_softc;
748         struct mwl_hal *mh = sc->sc_mh;
749         struct mwl_hal_vap *hvap = mvp->mv_hvap;
750         enum ieee80211_opmode opmode = vap->iv_opmode;
751
752         /* XXX disallow ap vap delete if WDS still present */
753         if (parent->if_drv_flags & IFF_DRV_RUNNING) {
754                 /* quiesce h/w while we remove the vap */
755                 mwl_hal_intrset(mh, 0);         /* disable interrupts */
756         }
757         ieee80211_vap_detach(vap);
758         switch (opmode) {
759         case IEEE80211_M_HOSTAP:
760         case IEEE80211_M_MBSS:
761         case IEEE80211_M_STA:
762                 KASSERT(hvap != NULL, ("no hal vap handle"));
763                 (void) mwl_hal_delstation(hvap, vap->iv_myaddr);
764                 mwl_hal_delvap(hvap);
765                 if (opmode == IEEE80211_M_HOSTAP || opmode == IEEE80211_M_MBSS)
766                         sc->sc_napvaps--;
767                 else
768                         sc->sc_nstavaps--;
769                 /* XXX don't do it for IEEE80211_CLONE_MACADDR */
770                 reclaim_address(sc, vap->iv_myaddr);
771                 break;
772         case IEEE80211_M_WDS:
773                 sc->sc_nwdsvaps--;
774                 break;
775         default:
776                 break;
777         }
778         mwl_cleartxq(sc, vap);
779         free(mvp, M_80211_VAP);
780         if (parent->if_drv_flags & IFF_DRV_RUNNING)
781                 mwl_hal_intrset(mh, sc->sc_imask);
782 }
783
784 void
785 mwl_suspend(struct mwl_softc *sc)
786 {
787         struct ifnet *ifp = sc->sc_ifp;
788
789         DPRINTF(sc, MWL_DEBUG_ANY, "%s: if_flags %x\n",
790                 __func__, ifp->if_flags);
791
792         mwl_stop(ifp, 1);
793 }
794
795 void
796 mwl_resume(struct mwl_softc *sc)
797 {
798         struct ifnet *ifp = sc->sc_ifp;
799
800         DPRINTF(sc, MWL_DEBUG_ANY, "%s: if_flags %x\n",
801                 __func__, ifp->if_flags);
802
803         if (ifp->if_flags & IFF_UP)
804                 mwl_init(sc);
805 }
806
807 void
808 mwl_shutdown(void *arg)
809 {
810         struct mwl_softc *sc = arg;
811
812         mwl_stop(sc->sc_ifp, 1);
813 }
814
815 /*
816  * Interrupt handler.  Most of the actual processing is deferred.
817  */
818 void
819 mwl_intr(void *arg)
820 {
821         struct mwl_softc *sc = arg;
822         struct mwl_hal *mh = sc->sc_mh;
823         uint32_t status;
824
825         if (sc->sc_invalid) {
826                 /*
827                  * The hardware is not ready/present, don't touch anything.
828                  * Note this can happen early on if the IRQ is shared.
829                  */
830                 DPRINTF(sc, MWL_DEBUG_ANY, "%s: invalid; ignored\n", __func__);
831                 return;
832         }
833         /*
834          * Figure out the reason(s) for the interrupt.
835          */
836         mwl_hal_getisr(mh, &status);            /* NB: clears ISR too */
837         if (status == 0)                        /* must be a shared irq */
838                 return;
839
840         DPRINTF(sc, MWL_DEBUG_INTR, "%s: status 0x%x imask 0x%x\n",
841             __func__, status, sc->sc_imask);
842         if (status & MACREG_A2HRIC_BIT_RX_RDY)
843                 taskqueue_enqueue(sc->sc_tq, &sc->sc_rxtask);
844         if (status & MACREG_A2HRIC_BIT_TX_DONE)
845                 taskqueue_enqueue(sc->sc_tq, &sc->sc_txtask);
846         if (status & MACREG_A2HRIC_BIT_BA_WATCHDOG)
847                 taskqueue_enqueue(sc->sc_tq, &sc->sc_bawatchdogtask);
848         if (status & MACREG_A2HRIC_BIT_OPC_DONE)
849                 mwl_hal_cmddone(mh);
850         if (status & MACREG_A2HRIC_BIT_MAC_EVENT) {
851                 ;
852         }
853         if (status & MACREG_A2HRIC_BIT_ICV_ERROR) {
854                 /* TKIP ICV error */
855                 sc->sc_stats.mst_rx_badtkipicv++;
856         }
857         if (status & MACREG_A2HRIC_BIT_QUEUE_EMPTY) {
858                 /* 11n aggregation queue is empty, re-fill */
859                 ;
860         }
861         if (status & MACREG_A2HRIC_BIT_QUEUE_FULL) {
862                 ;
863         }
864         if (status & MACREG_A2HRIC_BIT_RADAR_DETECT) {
865                 /* radar detected, process event */
866                 taskqueue_enqueue(sc->sc_tq, &sc->sc_radartask);
867         }
868         if (status & MACREG_A2HRIC_BIT_CHAN_SWITCH) {
869                 /* DFS channel switch */
870                 taskqueue_enqueue(sc->sc_tq, &sc->sc_chanswitchtask);
871         }
872 }
873
874 static void
875 mwl_radar_proc(void *arg, int pending)
876 {
877         struct mwl_softc *sc = arg;
878         struct ifnet *ifp = sc->sc_ifp;
879         struct ieee80211com *ic = ifp->if_l2com;
880
881         DPRINTF(sc, MWL_DEBUG_ANY, "%s: radar detected, pending %u\n",
882             __func__, pending);
883
884         sc->sc_stats.mst_radardetect++;
885         /* XXX stop h/w BA streams? */
886
887         IEEE80211_LOCK(ic);
888         ieee80211_dfs_notify_radar(ic, ic->ic_curchan);
889         IEEE80211_UNLOCK(ic);
890 }
891
892 static void
893 mwl_chanswitch_proc(void *arg, int pending)
894 {
895         struct mwl_softc *sc = arg;
896         struct ifnet *ifp = sc->sc_ifp;
897         struct ieee80211com *ic = ifp->if_l2com;
898
899         DPRINTF(sc, MWL_DEBUG_ANY, "%s: channel switch notice, pending %u\n",
900             __func__, pending);
901
902         IEEE80211_LOCK(ic);
903         sc->sc_csapending = 0;
904         ieee80211_csa_completeswitch(ic);
905         IEEE80211_UNLOCK(ic);
906 }
907
908 static void
909 mwl_bawatchdog(const MWL_HAL_BASTREAM *sp)
910 {
911         struct ieee80211_node *ni = sp->data[0];
912
913         /* send DELBA and drop the stream */
914         ieee80211_ampdu_stop(ni, sp->data[1], IEEE80211_REASON_UNSPECIFIED);
915 }
916
917 static void
918 mwl_bawatchdog_proc(void *arg, int pending)
919 {
920         struct mwl_softc *sc = arg;
921         struct mwl_hal *mh = sc->sc_mh;
922         const MWL_HAL_BASTREAM *sp;
923         uint8_t bitmap, n;
924
925         sc->sc_stats.mst_bawatchdog++;
926
927         if (mwl_hal_getwatchdogbitmap(mh, &bitmap) != 0) {
928                 DPRINTF(sc, MWL_DEBUG_AMPDU,
929                     "%s: could not get bitmap\n", __func__);
930                 sc->sc_stats.mst_bawatchdog_failed++;
931                 return;
932         }
933         DPRINTF(sc, MWL_DEBUG_AMPDU, "%s: bitmap 0x%x\n", __func__, bitmap);
934         if (bitmap == 0xff) {
935                 n = 0;
936                 /* disable all ba streams */
937                 for (bitmap = 0; bitmap < 8; bitmap++) {
938                         sp = mwl_hal_bastream_lookup(mh, bitmap);
939                         if (sp != NULL) {
940                                 mwl_bawatchdog(sp);
941                                 n++;
942                         }
943                 }
944                 if (n == 0) {
945                         DPRINTF(sc, MWL_DEBUG_AMPDU,
946                             "%s: no BA streams found\n", __func__);
947                         sc->sc_stats.mst_bawatchdog_empty++;
948                 }
949         } else if (bitmap != 0xaa) {
950                 /* disable a single ba stream */
951                 sp = mwl_hal_bastream_lookup(mh, bitmap);
952                 if (sp != NULL) {
953                         mwl_bawatchdog(sp);
954                 } else {
955                         DPRINTF(sc, MWL_DEBUG_AMPDU,
956                             "%s: no BA stream %d\n", __func__, bitmap);
957                         sc->sc_stats.mst_bawatchdog_notfound++;
958                 }
959         }
960 }
961
962 /*
963  * Convert net80211 channel to a HAL channel.
964  */
965 static void
966 mwl_mapchan(MWL_HAL_CHANNEL *hc, const struct ieee80211_channel *chan)
967 {
968         hc->channel = chan->ic_ieee;
969
970         *(uint32_t *)&hc->channelFlags = 0;
971         if (IEEE80211_IS_CHAN_2GHZ(chan))
972                 hc->channelFlags.FreqBand = MWL_FREQ_BAND_2DOT4GHZ;
973         else if (IEEE80211_IS_CHAN_5GHZ(chan))
974                 hc->channelFlags.FreqBand = MWL_FREQ_BAND_5GHZ;
975         if (IEEE80211_IS_CHAN_HT40(chan)) {
976                 hc->channelFlags.ChnlWidth = MWL_CH_40_MHz_WIDTH;
977                 if (IEEE80211_IS_CHAN_HT40U(chan))
978                         hc->channelFlags.ExtChnlOffset = MWL_EXT_CH_ABOVE_CTRL_CH;
979                 else
980                         hc->channelFlags.ExtChnlOffset = MWL_EXT_CH_BELOW_CTRL_CH;
981         } else
982                 hc->channelFlags.ChnlWidth = MWL_CH_20_MHz_WIDTH;
983         /* XXX 10MHz channels */
984 }
985
986 /*
987  * Inform firmware of our tx/rx dma setup.  The BAR 0
988  * writes below are for compatibility with older firmware.
989  * For current firmware we send this information with a
990  * cmd block via mwl_hal_sethwdma.
991  */
992 static int
993 mwl_setupdma(struct mwl_softc *sc)
994 {
995         int error, i;
996
997         sc->sc_hwdma.rxDescRead = sc->sc_rxdma.dd_desc_paddr;
998         WR4(sc, sc->sc_hwspecs.rxDescRead, sc->sc_hwdma.rxDescRead);
999         WR4(sc, sc->sc_hwspecs.rxDescWrite, sc->sc_hwdma.rxDescRead);
1000
1001         for (i = 0; i < MWL_NUM_TX_QUEUES-MWL_NUM_ACK_QUEUES; i++) {
1002                 struct mwl_txq *txq = &sc->sc_txq[i];
1003                 sc->sc_hwdma.wcbBase[i] = txq->dma.dd_desc_paddr;
1004                 WR4(sc, sc->sc_hwspecs.wcbBase[i], sc->sc_hwdma.wcbBase[i]);
1005         }
1006         sc->sc_hwdma.maxNumTxWcb = mwl_txbuf;
1007         sc->sc_hwdma.maxNumWCB = MWL_NUM_TX_QUEUES-MWL_NUM_ACK_QUEUES;
1008
1009         error = mwl_hal_sethwdma(sc->sc_mh, &sc->sc_hwdma);
1010         if (error != 0) {
1011                 device_printf(sc->sc_dev,
1012                     "unable to setup tx/rx dma; hal status %u\n", error);
1013                 /* XXX */
1014         }
1015         return error;
1016 }
1017
1018 /*
1019  * Inform firmware of tx rate parameters.
1020  * Called after a channel change.
1021  */
1022 static int
1023 mwl_setcurchanrates(struct mwl_softc *sc)
1024 {
1025         struct ifnet *ifp = sc->sc_ifp;
1026         struct ieee80211com *ic = ifp->if_l2com;
1027         const struct ieee80211_rateset *rs;
1028         MWL_HAL_TXRATE rates;
1029
1030         memset(&rates, 0, sizeof(rates));
1031         rs = ieee80211_get_suprates(ic, ic->ic_curchan);
1032         /* rate used to send management frames */
1033         rates.MgtRate = rs->rs_rates[0] & IEEE80211_RATE_VAL;
1034         /* rate used to send multicast frames */
1035         rates.McastRate = rates.MgtRate;
1036
1037         return mwl_hal_settxrate_auto(sc->sc_mh, &rates);
1038 }
1039
1040 /*
1041  * Inform firmware of tx rate parameters.  Called whenever
1042  * user-settable params change and after a channel change.
1043  */
1044 static int
1045 mwl_setrates(struct ieee80211vap *vap)
1046 {
1047         struct mwl_vap *mvp = MWL_VAP(vap);
1048         struct ieee80211_node *ni = vap->iv_bss;
1049         const struct ieee80211_txparam *tp = ni->ni_txparms;
1050         MWL_HAL_TXRATE rates;
1051
1052         KASSERT(vap->iv_state == IEEE80211_S_RUN, ("state %d", vap->iv_state));
1053
1054         /*
1055          * Update the h/w rate map.
1056          * NB: 0x80 for MCS is passed through unchanged
1057          */
1058         memset(&rates, 0, sizeof(rates));
1059         /* rate used to send management frames */
1060         rates.MgtRate = tp->mgmtrate;
1061         /* rate used to send multicast frames */
1062         rates.McastRate = tp->mcastrate;
1063
1064         /* while here calculate EAPOL fixed rate cookie */
1065         mvp->mv_eapolformat = htole16(mwl_calcformat(rates.MgtRate, ni));
1066
1067         return mwl_hal_settxrate(mvp->mv_hvap,
1068             tp->ucastrate != IEEE80211_FIXED_RATE_NONE ?
1069                 RATE_FIXED : RATE_AUTO, &rates);
1070 }
1071
1072 /*
1073  * Setup a fixed xmit rate cookie for EAPOL frames.
1074  */
1075 static void
1076 mwl_seteapolformat(struct ieee80211vap *vap)
1077 {
1078         struct mwl_vap *mvp = MWL_VAP(vap);
1079         struct ieee80211_node *ni = vap->iv_bss;
1080         enum ieee80211_phymode mode;
1081         uint8_t rate;
1082
1083         KASSERT(vap->iv_state == IEEE80211_S_RUN, ("state %d", vap->iv_state));
1084
1085         mode = ieee80211_chan2mode(ni->ni_chan);
1086         /*
1087          * Use legacy rates when operating a mixed HT+non-HT bss.
1088          * NB: this may violate POLA for sta and wds vap's.
1089          */
1090         if (mode == IEEE80211_MODE_11NA &&
1091             (vap->iv_flags_ht & IEEE80211_FHT_PUREN) == 0)
1092                 rate = vap->iv_txparms[IEEE80211_MODE_11A].mgmtrate;
1093         else if (mode == IEEE80211_MODE_11NG &&
1094             (vap->iv_flags_ht & IEEE80211_FHT_PUREN) == 0)
1095                 rate = vap->iv_txparms[IEEE80211_MODE_11G].mgmtrate;
1096         else
1097                 rate = vap->iv_txparms[mode].mgmtrate;
1098
1099         mvp->mv_eapolformat = htole16(mwl_calcformat(rate, ni));
1100 }
1101
1102 /*
1103  * Map SKU+country code to region code for radar bin'ing.
1104  */
1105 static int
1106 mwl_map2regioncode(const struct ieee80211_regdomain *rd)
1107 {
1108         switch (rd->regdomain) {
1109         case SKU_FCC:
1110         case SKU_FCC3:
1111                 return DOMAIN_CODE_FCC;
1112         case SKU_CA:
1113                 return DOMAIN_CODE_IC;
1114         case SKU_ETSI:
1115         case SKU_ETSI2:
1116         case SKU_ETSI3:
1117                 if (rd->country == CTRY_SPAIN)
1118                         return DOMAIN_CODE_SPAIN;
1119                 if (rd->country == CTRY_FRANCE || rd->country == CTRY_FRANCE2)
1120                         return DOMAIN_CODE_FRANCE;
1121                 /* XXX force 1.3.1 radar type */
1122                 return DOMAIN_CODE_ETSI_131;
1123         case SKU_JAPAN:
1124                 return DOMAIN_CODE_MKK;
1125         case SKU_ROW:
1126                 return DOMAIN_CODE_DGT; /* Taiwan */
1127         case SKU_APAC:
1128         case SKU_APAC2:
1129         case SKU_APAC3:
1130                 return DOMAIN_CODE_AUS; /* Australia */
1131         }
1132         /* XXX KOREA? */
1133         return DOMAIN_CODE_FCC;                 /* XXX? */
1134 }
1135
1136 static int
1137 mwl_hal_reset(struct mwl_softc *sc)
1138 {
1139         struct ifnet *ifp = sc->sc_ifp;
1140         struct ieee80211com *ic = ifp->if_l2com;
1141         struct mwl_hal *mh = sc->sc_mh;
1142
1143         mwl_hal_setantenna(mh, WL_ANTENNATYPE_RX, sc->sc_rxantenna);
1144         mwl_hal_setantenna(mh, WL_ANTENNATYPE_TX, sc->sc_txantenna);
1145         mwl_hal_setradio(mh, 1, WL_AUTO_PREAMBLE);
1146         mwl_hal_setwmm(sc->sc_mh, (ic->ic_flags & IEEE80211_F_WME) != 0);
1147         mwl_chan_set(sc, ic->ic_curchan);
1148         /* NB: RF/RA performance tuned for indoor mode */
1149         mwl_hal_setrateadaptmode(mh, 0);
1150         mwl_hal_setoptimizationlevel(mh,
1151             (ic->ic_flags & IEEE80211_F_BURST) != 0);
1152
1153         mwl_hal_setregioncode(mh, mwl_map2regioncode(&ic->ic_regdomain));
1154
1155         mwl_hal_setaggampduratemode(mh, 1, 80);         /* XXX */
1156         mwl_hal_setcfend(mh, 0);                        /* XXX */
1157
1158         return 1;
1159 }
1160
1161 static int
1162 mwl_init_locked(struct mwl_softc *sc)
1163 {
1164         struct ifnet *ifp = sc->sc_ifp;
1165         struct mwl_hal *mh = sc->sc_mh;
1166         int error = 0;
1167
1168         DPRINTF(sc, MWL_DEBUG_ANY, "%s: if_flags 0x%x\n",
1169                 __func__, ifp->if_flags);
1170
1171         MWL_LOCK_ASSERT(sc);
1172
1173         /*
1174          * Stop anything previously setup.  This is safe
1175          * whether this is the first time through or not.
1176          */
1177         mwl_stop_locked(ifp, 0);
1178
1179         /*
1180          * Push vap-independent state to the firmware.
1181          */
1182         if (!mwl_hal_reset(sc)) {
1183                 if_printf(ifp, "unable to reset hardware\n");
1184                 return EIO;
1185         }
1186
1187         /*
1188          * Setup recv (once); transmit is already good to go.
1189          */
1190         error = mwl_startrecv(sc);
1191         if (error != 0) {
1192                 if_printf(ifp, "unable to start recv logic\n");
1193                 return error;
1194         }
1195
1196         /*
1197          * Enable interrupts.
1198          */
1199         sc->sc_imask = MACREG_A2HRIC_BIT_RX_RDY
1200                      | MACREG_A2HRIC_BIT_TX_DONE
1201                      | MACREG_A2HRIC_BIT_OPC_DONE
1202 #if 0
1203                      | MACREG_A2HRIC_BIT_MAC_EVENT
1204 #endif
1205                      | MACREG_A2HRIC_BIT_ICV_ERROR
1206                      | MACREG_A2HRIC_BIT_RADAR_DETECT
1207                      | MACREG_A2HRIC_BIT_CHAN_SWITCH
1208 #if 0
1209                      | MACREG_A2HRIC_BIT_QUEUE_EMPTY
1210 #endif
1211                      | MACREG_A2HRIC_BIT_BA_WATCHDOG
1212                      | MACREQ_A2HRIC_BIT_TX_ACK
1213                      ;
1214
1215         ifp->if_drv_flags |= IFF_DRV_RUNNING;
1216         mwl_hal_intrset(mh, sc->sc_imask);
1217
1218         return 0;
1219 }
1220
1221 static void
1222 mwl_init(void *arg)
1223 {
1224         struct mwl_softc *sc = arg;
1225         struct ifnet *ifp = sc->sc_ifp;
1226         struct ieee80211com *ic = ifp->if_l2com;
1227         int error = 0;
1228
1229         DPRINTF(sc, MWL_DEBUG_ANY, "%s: if_flags 0x%x\n",
1230                 __func__, ifp->if_flags);
1231
1232         MWL_LOCK(sc);
1233         error = mwl_init_locked(sc);
1234         MWL_UNLOCK(sc);
1235
1236         if (error == 0)
1237                 ieee80211_start_all(ic);        /* start all vap's */
1238 }
1239
1240 static void
1241 mwl_stop_locked(struct ifnet *ifp, int disable)
1242 {
1243         struct mwl_softc *sc = ifp->if_softc;
1244
1245         DPRINTF(sc, MWL_DEBUG_ANY, "%s: invalid %u if_flags 0x%x\n",
1246                 __func__, sc->sc_invalid, ifp->if_flags);
1247
1248         MWL_LOCK_ASSERT(sc);
1249         if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
1250                 /*
1251                  * Shutdown the hardware and driver.
1252                  */
1253                 ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
1254                 ifp->if_timer = 0;
1255                 mwl_draintxq(sc);
1256         }
1257 }
1258
1259 static void
1260 mwl_stop(struct ifnet *ifp, int disable)
1261 {
1262         struct mwl_softc *sc = ifp->if_softc;
1263
1264         MWL_LOCK(sc);
1265         mwl_stop_locked(ifp, disable);
1266         MWL_UNLOCK(sc);
1267 }
1268
1269 static int
1270 mwl_reset_vap(struct ieee80211vap *vap, int state)
1271 {
1272         struct mwl_hal_vap *hvap = MWL_VAP(vap)->mv_hvap;
1273         struct ieee80211com *ic = vap->iv_ic;
1274
1275         if (state == IEEE80211_S_RUN)
1276                 mwl_setrates(vap);
1277         /* XXX off by 1? */
1278         mwl_hal_setrtsthreshold(hvap, vap->iv_rtsthreshold);
1279         /* XXX auto? 20/40 split? */
1280         mwl_hal_sethtgi(hvap, (vap->iv_flags_ht &
1281             (IEEE80211_FHT_SHORTGI20|IEEE80211_FHT_SHORTGI40)) ? 1 : 0);
1282         mwl_hal_setnprot(hvap, ic->ic_htprotmode == IEEE80211_PROT_NONE ?
1283             HTPROTECT_NONE : HTPROTECT_AUTO);
1284         /* XXX txpower cap */
1285
1286         /* re-setup beacons */
1287         if (state == IEEE80211_S_RUN &&
1288             (vap->iv_opmode == IEEE80211_M_HOSTAP ||
1289              vap->iv_opmode == IEEE80211_M_MBSS ||
1290              vap->iv_opmode == IEEE80211_M_IBSS)) {
1291                 mwl_setapmode(vap, vap->iv_bss->ni_chan);
1292                 mwl_hal_setnprotmode(hvap,
1293                     MS(ic->ic_curhtprotmode, IEEE80211_HTINFO_OPMODE));
1294                 return mwl_beacon_setup(vap);
1295         }
1296         return 0;
1297 }
1298
1299 /*
1300  * Reset the hardware w/o losing operational state.
1301  * Used to to reset or reload hardware state for a vap.
1302  */
1303 static int
1304 mwl_reset(struct ieee80211vap *vap, u_long cmd)
1305 {
1306         struct mwl_hal_vap *hvap = MWL_VAP(vap)->mv_hvap;
1307         int error = 0;
1308
1309         if (hvap != NULL) {                     /* WDS, MONITOR, etc. */
1310                 struct ieee80211com *ic = vap->iv_ic;
1311                 struct ifnet *ifp = ic->ic_ifp;
1312                 struct mwl_softc *sc = ifp->if_softc;
1313                 struct mwl_hal *mh = sc->sc_mh;
1314
1315                 /* XXX handle DWDS sta vap change */
1316                 /* XXX do we need to disable interrupts? */
1317                 mwl_hal_intrset(mh, 0);         /* disable interrupts */
1318                 error = mwl_reset_vap(vap, vap->iv_state);
1319                 mwl_hal_intrset(mh, sc->sc_imask);
1320         }
1321         return error;
1322 }
1323
1324 /*
1325  * Allocate a tx buffer for sending a frame.  The
1326  * packet is assumed to have the WME AC stored so
1327  * we can use it to select the appropriate h/w queue.
1328  */
1329 static struct mwl_txbuf *
1330 mwl_gettxbuf(struct mwl_softc *sc, struct mwl_txq *txq)
1331 {
1332         struct mwl_txbuf *bf;
1333
1334         /*
1335          * Grab a TX buffer and associated resources.
1336          */
1337         MWL_TXQ_LOCK(txq);
1338         bf = STAILQ_FIRST(&txq->free);
1339         if (bf != NULL) {
1340                 STAILQ_REMOVE_HEAD(&txq->free, bf_list);
1341                 txq->nfree--;
1342         }
1343         MWL_TXQ_UNLOCK(txq);
1344         if (bf == NULL)
1345                 DPRINTF(sc, MWL_DEBUG_XMIT,
1346                     "%s: out of xmit buffers on q %d\n", __func__, txq->qnum);
1347         return bf;
1348 }
1349
1350 /*
1351  * Return a tx buffer to the queue it came from.  Note there
1352  * are two cases because we must preserve the order of buffers
1353  * as it reflects the fixed order of descriptors in memory
1354  * (the firmware pre-fetches descriptors so we cannot reorder).
1355  */
1356 static void
1357 mwl_puttxbuf_head(struct mwl_txq *txq, struct mwl_txbuf *bf)
1358 {
1359         bf->bf_m = NULL;
1360         bf->bf_node = NULL;
1361         MWL_TXQ_LOCK(txq);
1362         STAILQ_INSERT_HEAD(&txq->free, bf, bf_list);
1363         txq->nfree++;
1364         MWL_TXQ_UNLOCK(txq);
1365 }
1366
1367 static void
1368 mwl_puttxbuf_tail(struct mwl_txq *txq, struct mwl_txbuf *bf)
1369 {
1370         bf->bf_m = NULL;
1371         bf->bf_node = NULL;
1372         MWL_TXQ_LOCK(txq);
1373         STAILQ_INSERT_TAIL(&txq->free, bf, bf_list);
1374         txq->nfree++;
1375         MWL_TXQ_UNLOCK(txq);
1376 }
1377
1378 static void
1379 mwl_start(struct ifnet *ifp)
1380 {
1381         struct mwl_softc *sc = ifp->if_softc;
1382         struct ieee80211_node *ni;
1383         struct mwl_txbuf *bf;
1384         struct mbuf *m;
1385         struct mwl_txq *txq = NULL;     /* XXX silence gcc */
1386         int nqueued;
1387
1388         if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || sc->sc_invalid)
1389                 return;
1390         nqueued = 0;
1391         for (;;) {
1392                 bf = NULL;
1393                 IFQ_DEQUEUE(&ifp->if_snd, m);
1394                 if (m == NULL)
1395                         break;
1396                 /*
1397                  * Grab the node for the destination.
1398                  */
1399                 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
1400                 KASSERT(ni != NULL, ("no node"));
1401                 m->m_pkthdr.rcvif = NULL;       /* committed, clear ref */
1402                 /*
1403                  * Grab a TX buffer and associated resources.
1404                  * We honor the classification by the 802.11 layer.
1405                  */
1406                 txq = sc->sc_ac2q[M_WME_GETAC(m)];
1407                 bf = mwl_gettxbuf(sc, txq);
1408                 if (bf == NULL) {
1409                         m_freem(m);
1410                         ieee80211_free_node(ni);
1411 #ifdef MWL_TX_NODROP
1412                         sc->sc_stats.mst_tx_qstop++;
1413                         /* XXX blocks other traffic */
1414                         ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1415                         break;
1416 #else
1417                         DPRINTF(sc, MWL_DEBUG_XMIT,
1418                             "%s: tail drop on q %d\n", __func__, txq->qnum);
1419                         sc->sc_stats.mst_tx_qdrop++;
1420                         continue;
1421 #endif /* MWL_TX_NODROP */
1422                 }
1423
1424                 /*
1425                  * Pass the frame to the h/w for transmission.
1426                  */
1427                 if (mwl_tx_start(sc, ni, bf, m)) {
1428                         ifp->if_oerrors++;
1429                         mwl_puttxbuf_head(txq, bf);
1430                         ieee80211_free_node(ni);
1431                         continue;
1432                 }
1433                 nqueued++;
1434                 if (nqueued >= mwl_txcoalesce) {
1435                         /*
1436                          * Poke the firmware to process queued frames;
1437                          * see below about (lack of) locking.
1438                          */
1439                         nqueued = 0;
1440                         mwl_hal_txstart(sc->sc_mh, 0/*XXX*/);
1441                 }
1442         }
1443         if (nqueued) {
1444                 /*
1445                  * NB: We don't need to lock against tx done because
1446                  * this just prods the firmware to check the transmit
1447                  * descriptors.  The firmware will also start fetching
1448                  * descriptors by itself if it notices new ones are
1449                  * present when it goes to deliver a tx done interrupt
1450                  * to the host. So if we race with tx done processing
1451                  * it's ok.  Delivering the kick here rather than in
1452                  * mwl_tx_start is an optimization to avoid poking the
1453                  * firmware for each packet.
1454                  *
1455                  * NB: the queue id isn't used so 0 is ok.
1456                  */
1457                 mwl_hal_txstart(sc->sc_mh, 0/*XXX*/);
1458         }
1459 }
1460
1461 static int
1462 mwl_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
1463         const struct ieee80211_bpf_params *params)
1464 {
1465         struct ieee80211com *ic = ni->ni_ic;
1466         struct ifnet *ifp = ic->ic_ifp;
1467         struct mwl_softc *sc = ifp->if_softc;
1468         struct mwl_txbuf *bf;
1469         struct mwl_txq *txq;
1470
1471         if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || sc->sc_invalid) {
1472                 ieee80211_free_node(ni);
1473                 m_freem(m);
1474                 return ENETDOWN;
1475         }
1476         /*
1477          * Grab a TX buffer and associated resources.
1478          * Note that we depend on the classification
1479          * by the 802.11 layer to get to the right h/w
1480          * queue.  Management frames must ALWAYS go on
1481          * queue 1 but we cannot just force that here
1482          * because we may receive non-mgt frames.
1483          */
1484         txq = sc->sc_ac2q[M_WME_GETAC(m)];
1485         bf = mwl_gettxbuf(sc, txq);
1486         if (bf == NULL) {
1487                 sc->sc_stats.mst_tx_qstop++;
1488                 /* XXX blocks other traffic */
1489                 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1490                 ieee80211_free_node(ni);
1491                 m_freem(m);
1492                 return ENOBUFS;
1493         }
1494         /*
1495          * Pass the frame to the h/w for transmission.
1496          */
1497         if (mwl_tx_start(sc, ni, bf, m)) {
1498                 ifp->if_oerrors++;
1499                 mwl_puttxbuf_head(txq, bf);
1500
1501                 ieee80211_free_node(ni);
1502                 return EIO;             /* XXX */
1503         }
1504         /*
1505          * NB: We don't need to lock against tx done because
1506          * this just prods the firmware to check the transmit
1507          * descriptors.  The firmware will also start fetching
1508          * descriptors by itself if it notices new ones are
1509          * present when it goes to deliver a tx done interrupt
1510          * to the host. So if we race with tx done processing
1511          * it's ok.  Delivering the kick here rather than in
1512          * mwl_tx_start is an optimization to avoid poking the
1513          * firmware for each packet.
1514          *
1515          * NB: the queue id isn't used so 0 is ok.
1516          */
1517         mwl_hal_txstart(sc->sc_mh, 0/*XXX*/);
1518         return 0;
1519 }
1520
1521 static int
1522 mwl_media_change(struct ifnet *ifp)
1523 {
1524         struct ieee80211vap *vap = ifp->if_softc;
1525         int error;
1526
1527         error = ieee80211_media_change(ifp);
1528         /* NB: only the fixed rate can change and that doesn't need a reset */
1529         if (error == ENETRESET) {
1530                 mwl_setrates(vap);
1531                 error = 0;
1532         }
1533         return error;
1534 }
1535
1536 #ifdef MWL_DEBUG
1537 static void
1538 mwl_keyprint(struct mwl_softc *sc, const char *tag,
1539         const MWL_HAL_KEYVAL *hk, const uint8_t mac[IEEE80211_ADDR_LEN])
1540 {
1541         static const char *ciphers[] = {
1542                 "WEP",
1543                 "TKIP",
1544                 "AES-CCM",
1545         };
1546         int i, n;
1547
1548         printf("%s: [%u] %-7s", tag, hk->keyIndex, ciphers[hk->keyTypeId]);
1549         for (i = 0, n = hk->keyLen; i < n; i++)
1550                 printf(" %02x", hk->key.aes[i]);
1551         printf(" mac %s", ether_sprintf(mac));
1552         if (hk->keyTypeId == KEY_TYPE_ID_TKIP) {
1553                 printf(" %s", "rxmic");
1554                 for (i = 0; i < sizeof(hk->key.tkip.rxMic); i++)
1555                         printf(" %02x", hk->key.tkip.rxMic[i]);
1556                 printf(" txmic");
1557                 for (i = 0; i < sizeof(hk->key.tkip.txMic); i++)
1558                         printf(" %02x", hk->key.tkip.txMic[i]);
1559         }
1560         printf(" flags 0x%x\n", hk->keyFlags);
1561 }
1562 #endif
1563
1564 /*
1565  * Allocate a key cache slot for a unicast key.  The
1566  * firmware handles key allocation and every station is
1567  * guaranteed key space so we are always successful.
1568  */
1569 static int
1570 mwl_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k,
1571         ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix)
1572 {
1573         struct mwl_softc *sc = vap->iv_ic->ic_ifp->if_softc;
1574
1575         if (k->wk_keyix != IEEE80211_KEYIX_NONE ||
1576             (k->wk_flags & IEEE80211_KEY_GROUP)) {
1577                 if (!(&vap->iv_nw_keys[0] <= k &&
1578                       k < &vap->iv_nw_keys[IEEE80211_WEP_NKID])) {
1579                         /* should not happen */
1580                         DPRINTF(sc, MWL_DEBUG_KEYCACHE,
1581                                 "%s: bogus group key\n", __func__);
1582                         return 0;
1583                 }
1584                 /* give the caller what they requested */
1585                 *keyix = *rxkeyix = k - vap->iv_nw_keys;
1586         } else {
1587                 /*
1588                  * Firmware handles key allocation.
1589                  */
1590                 *keyix = *rxkeyix = 0;
1591         }
1592         return 1;
1593 }
1594
1595 /*
1596  * Delete a key entry allocated by mwl_key_alloc.
1597  */
1598 static int
1599 mwl_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k)
1600 {
1601         struct mwl_softc *sc = vap->iv_ic->ic_ifp->if_softc;
1602         struct mwl_hal_vap *hvap = MWL_VAP(vap)->mv_hvap;
1603         MWL_HAL_KEYVAL hk;
1604         const uint8_t bcastaddr[IEEE80211_ADDR_LEN] =
1605             { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
1606
1607         if (hvap == NULL) {
1608                 if (vap->iv_opmode != IEEE80211_M_WDS) {
1609                         /* XXX monitor mode? */
1610                         DPRINTF(sc, MWL_DEBUG_KEYCACHE,
1611                             "%s: no hvap for opmode %d\n", __func__,
1612                             vap->iv_opmode);
1613                         return 0;
1614                 }
1615                 hvap = MWL_VAP(vap)->mv_ap_hvap;
1616         }
1617
1618         DPRINTF(sc, MWL_DEBUG_KEYCACHE, "%s: delete key %u\n",
1619             __func__, k->wk_keyix);
1620
1621         memset(&hk, 0, sizeof(hk));
1622         hk.keyIndex = k->wk_keyix;
1623         switch (k->wk_cipher->ic_cipher) {
1624         case IEEE80211_CIPHER_WEP:
1625                 hk.keyTypeId = KEY_TYPE_ID_WEP;
1626                 break;
1627         case IEEE80211_CIPHER_TKIP:
1628                 hk.keyTypeId = KEY_TYPE_ID_TKIP;
1629                 break;
1630         case IEEE80211_CIPHER_AES_CCM:
1631                 hk.keyTypeId = KEY_TYPE_ID_AES;
1632                 break;
1633         default:
1634                 /* XXX should not happen */
1635                 DPRINTF(sc, MWL_DEBUG_KEYCACHE, "%s: unknown cipher %d\n",
1636                     __func__, k->wk_cipher->ic_cipher);
1637                 return 0;
1638         }
1639         return (mwl_hal_keyreset(hvap, &hk, bcastaddr) == 0);   /*XXX*/
1640 }
1641
1642 static __inline int
1643 addgroupflags(MWL_HAL_KEYVAL *hk, const struct ieee80211_key *k)
1644 {
1645         if (k->wk_flags & IEEE80211_KEY_GROUP) {
1646                 if (k->wk_flags & IEEE80211_KEY_XMIT)
1647                         hk->keyFlags |= KEY_FLAG_TXGROUPKEY;
1648                 if (k->wk_flags & IEEE80211_KEY_RECV)
1649                         hk->keyFlags |= KEY_FLAG_RXGROUPKEY;
1650                 return 1;
1651         } else
1652                 return 0;
1653 }
1654
1655 /*
1656  * Set the key cache contents for the specified key.  Key cache
1657  * slot(s) must already have been allocated by mwl_key_alloc.
1658  */
1659 static int
1660 mwl_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k,
1661         const uint8_t mac[IEEE80211_ADDR_LEN])
1662 {
1663 #define GRPXMIT (IEEE80211_KEY_XMIT | IEEE80211_KEY_GROUP)
1664 /* NB: static wep keys are marked GROUP+tx/rx; GTK will be tx or rx */
1665 #define IEEE80211_IS_STATICKEY(k) \
1666         (((k)->wk_flags & (GRPXMIT|IEEE80211_KEY_RECV)) == \
1667          (GRPXMIT|IEEE80211_KEY_RECV))
1668         struct mwl_softc *sc = vap->iv_ic->ic_ifp->if_softc;
1669         struct mwl_hal_vap *hvap = MWL_VAP(vap)->mv_hvap;
1670         const struct ieee80211_cipher *cip = k->wk_cipher;
1671         const uint8_t *macaddr;
1672         MWL_HAL_KEYVAL hk;
1673
1674         KASSERT((k->wk_flags & IEEE80211_KEY_SWCRYPT) == 0,
1675                 ("s/w crypto set?"));
1676
1677         if (hvap == NULL) {
1678                 if (vap->iv_opmode != IEEE80211_M_WDS) {
1679                         /* XXX monitor mode? */
1680                         DPRINTF(sc, MWL_DEBUG_KEYCACHE,
1681                             "%s: no hvap for opmode %d\n", __func__,
1682                             vap->iv_opmode);
1683                         return 0;
1684                 }
1685                 hvap = MWL_VAP(vap)->mv_ap_hvap;
1686         }
1687         memset(&hk, 0, sizeof(hk));
1688         hk.keyIndex = k->wk_keyix;
1689         switch (cip->ic_cipher) {
1690         case IEEE80211_CIPHER_WEP:
1691                 hk.keyTypeId = KEY_TYPE_ID_WEP;
1692                 hk.keyLen = k->wk_keylen;
1693                 if (k->wk_keyix == vap->iv_def_txkey)
1694                         hk.keyFlags = KEY_FLAG_WEP_TXKEY;
1695                 if (!IEEE80211_IS_STATICKEY(k)) {
1696                         /* NB: WEP is never used for the PTK */
1697                         (void) addgroupflags(&hk, k);
1698                 }
1699                 break;
1700         case IEEE80211_CIPHER_TKIP:
1701                 hk.keyTypeId = KEY_TYPE_ID_TKIP;
1702                 hk.key.tkip.tsc.high = (uint32_t)(k->wk_keytsc >> 16);
1703                 hk.key.tkip.tsc.low = (uint16_t)k->wk_keytsc;
1704                 hk.keyFlags = KEY_FLAG_TSC_VALID | KEY_FLAG_MICKEY_VALID;
1705                 hk.keyLen = k->wk_keylen + IEEE80211_MICBUF_SIZE;
1706                 if (!addgroupflags(&hk, k))
1707                         hk.keyFlags |= KEY_FLAG_PAIRWISE;
1708                 break;
1709         case IEEE80211_CIPHER_AES_CCM:
1710                 hk.keyTypeId = KEY_TYPE_ID_AES;
1711                 hk.keyLen = k->wk_keylen;
1712                 if (!addgroupflags(&hk, k))
1713                         hk.keyFlags |= KEY_FLAG_PAIRWISE;
1714                 break;
1715         default:
1716                 /* XXX should not happen */
1717                 DPRINTF(sc, MWL_DEBUG_KEYCACHE, "%s: unknown cipher %d\n",
1718                     __func__, k->wk_cipher->ic_cipher);
1719                 return 0;
1720         }
1721         /*
1722          * NB: tkip mic keys get copied here too; the layout
1723          *     just happens to match that in ieee80211_key.
1724          */
1725         memcpy(hk.key.aes, k->wk_key, hk.keyLen);
1726
1727         /*
1728          * Locate address of sta db entry for writing key;
1729          * the convention unfortunately is somewhat different
1730          * than how net80211, hostapd, and wpa_supplicant think.
1731          */
1732         if (vap->iv_opmode == IEEE80211_M_STA) {
1733                 /*
1734                  * NB: keys plumbed before the sta reaches AUTH state
1735                  * will be discarded or written to the wrong sta db
1736                  * entry because iv_bss is meaningless.  This is ok
1737                  * (right now) because we handle deferred plumbing of
1738                  * WEP keys when the sta reaches AUTH state.
1739                  */
1740                 macaddr = vap->iv_bss->ni_bssid;
1741         } else if (vap->iv_opmode == IEEE80211_M_WDS &&
1742             vap->iv_state != IEEE80211_S_RUN) {
1743                 /*
1744                  * Prior to RUN state a WDS vap will not it's BSS node
1745                  * setup so we will plumb the key to the wrong mac
1746                  * address (it'll be our local address).  Workaround
1747                  * this for the moment by grabbing the correct address.
1748                  */
1749                 macaddr = vap->iv_des_bssid;
1750         } else if ((k->wk_flags & GRPXMIT) == GRPXMIT)
1751                 macaddr = vap->iv_myaddr;
1752         else
1753                 macaddr = mac;
1754         KEYPRINTF(sc, &hk, macaddr);
1755         return (mwl_hal_keyset(hvap, &hk, macaddr) == 0);
1756 #undef IEEE80211_IS_STATICKEY
1757 #undef GRPXMIT
1758 }
1759
1760 /* unaligned little endian access */
1761 #define LE_READ_2(p)                            \
1762         ((uint16_t)                             \
1763          ((((const uint8_t *)(p))[0]      ) |   \
1764           (((const uint8_t *)(p))[1] <<  8)))
1765 #define LE_READ_4(p)                            \
1766         ((uint32_t)                             \
1767          ((((const uint8_t *)(p))[0]      ) |   \
1768           (((const uint8_t *)(p))[1] <<  8) |   \
1769           (((const uint8_t *)(p))[2] << 16) |   \
1770           (((const uint8_t *)(p))[3] << 24)))
1771
1772 /*
1773  * Set the multicast filter contents into the hardware.
1774  * XXX f/w has no support; just defer to the os.
1775  */
1776 static void
1777 mwl_setmcastfilter(struct mwl_softc *sc)
1778 {
1779         struct ifnet *ifp = sc->sc_ifp;
1780 #if 0
1781         struct ether_multi *enm;
1782         struct ether_multistep estep;
1783         uint8_t macs[IEEE80211_ADDR_LEN*MWL_HAL_MCAST_MAX];/* XXX stack use */
1784         uint8_t *mp;
1785         int nmc;
1786
1787         mp = macs;
1788         nmc = 0;
1789         ETHER_FIRST_MULTI(estep, &sc->sc_ec, enm);
1790         while (enm != NULL) {
1791                 /* XXX Punt on ranges. */
1792                 if (nmc == MWL_HAL_MCAST_MAX ||
1793                     !IEEE80211_ADDR_EQ(enm->enm_addrlo, enm->enm_addrhi)) {
1794                         ifp->if_flags |= IFF_ALLMULTI;
1795                         return;
1796                 }
1797                 IEEE80211_ADDR_COPY(mp, enm->enm_addrlo);
1798                 mp += IEEE80211_ADDR_LEN, nmc++;
1799                 ETHER_NEXT_MULTI(estep, enm);
1800         }
1801         ifp->if_flags &= ~IFF_ALLMULTI;
1802         mwl_hal_setmcast(sc->sc_mh, nmc, macs);
1803 #else
1804         /* XXX no mcast filter support; we get everything */
1805         ifp->if_flags |= IFF_ALLMULTI;
1806 #endif
1807 }
1808
1809 static int
1810 mwl_mode_init(struct mwl_softc *sc)
1811 {
1812         struct ifnet *ifp = sc->sc_ifp;
1813         struct ieee80211com *ic = ifp->if_l2com;
1814         struct mwl_hal *mh = sc->sc_mh;
1815
1816         /*
1817          * NB: Ignore promisc in hostap mode; it's set by the
1818          * bridge.  This is wrong but we have no way to
1819          * identify internal requests (from the bridge)
1820          * versus external requests such as for tcpdump.
1821          */
1822         mwl_hal_setpromisc(mh, (ifp->if_flags & IFF_PROMISC) &&
1823             ic->ic_opmode != IEEE80211_M_HOSTAP);
1824         mwl_setmcastfilter(sc);
1825
1826         return 0;
1827 }
1828
1829 /*
1830  * Callback from the 802.11 layer after a multicast state change.
1831  */
1832 static void
1833 mwl_update_mcast(struct ifnet *ifp)
1834 {
1835         struct mwl_softc *sc = ifp->if_softc;
1836
1837         mwl_setmcastfilter(sc);
1838 }
1839
1840 /*
1841  * Callback from the 802.11 layer after a promiscuous mode change.
1842  * Note this interface does not check the operating mode as this
1843  * is an internal callback and we are expected to honor the current
1844  * state (e.g. this is used for setting the interface in promiscuous
1845  * mode when operating in hostap mode to do ACS).
1846  */
1847 static void
1848 mwl_update_promisc(struct ifnet *ifp)
1849 {
1850         struct mwl_softc *sc = ifp->if_softc;
1851
1852         mwl_hal_setpromisc(sc->sc_mh, (ifp->if_flags & IFF_PROMISC) != 0);
1853 }
1854
1855 /*
1856  * Callback from the 802.11 layer to update the slot time
1857  * based on the current setting.  We use it to notify the
1858  * firmware of ERP changes and the f/w takes care of things
1859  * like slot time and preamble.
1860  */
1861 static void
1862 mwl_updateslot(struct ifnet *ifp)
1863 {
1864         struct mwl_softc *sc = ifp->if_softc;
1865         struct ieee80211com *ic = ifp->if_l2com;
1866         struct mwl_hal *mh = sc->sc_mh;
1867         int prot;
1868
1869         /* NB: can be called early; suppress needless cmds */
1870         if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
1871                 return;
1872
1873         /*
1874          * Calculate the ERP flags.  The firwmare will use
1875          * this to carry out the appropriate measures.
1876          */
1877         prot = 0;
1878         if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan)) {
1879                 if ((ic->ic_flags & IEEE80211_F_SHSLOT) == 0)
1880                         prot |= IEEE80211_ERP_NON_ERP_PRESENT;
1881                 if (ic->ic_flags & IEEE80211_F_USEPROT)
1882                         prot |= IEEE80211_ERP_USE_PROTECTION;
1883                 if (ic->ic_flags & IEEE80211_F_USEBARKER)
1884                         prot |= IEEE80211_ERP_LONG_PREAMBLE;
1885         }
1886
1887         DPRINTF(sc, MWL_DEBUG_RESET,
1888             "%s: chan %u MHz/flags 0x%x %s slot, (prot 0x%x ic_flags 0x%x)\n",
1889             __func__, ic->ic_curchan->ic_freq, ic->ic_curchan->ic_flags,
1890             ic->ic_flags & IEEE80211_F_SHSLOT ? "short" : "long", prot,
1891             ic->ic_flags);
1892
1893         mwl_hal_setgprot(mh, prot);
1894 }
1895
1896 /*
1897  * Setup the beacon frame.
1898  */
1899 static int
1900 mwl_beacon_setup(struct ieee80211vap *vap)
1901 {
1902         struct mwl_hal_vap *hvap = MWL_VAP(vap)->mv_hvap;
1903         struct ieee80211_node *ni = vap->iv_bss;
1904         struct ieee80211_beacon_offsets bo;
1905         struct mbuf *m;
1906
1907         m = ieee80211_beacon_alloc(ni, &bo);
1908         if (m == NULL)
1909                 return ENOBUFS;
1910         mwl_hal_setbeacon(hvap, mtod(m, const void *), m->m_len);
1911         m_free(m);
1912
1913         return 0;
1914 }
1915
1916 /*
1917  * Update the beacon frame in response to a change.
1918  */
1919 static void
1920 mwl_beacon_update(struct ieee80211vap *vap, int item)
1921 {
1922         struct mwl_hal_vap *hvap = MWL_VAP(vap)->mv_hvap;
1923         struct ieee80211com *ic = vap->iv_ic;
1924
1925         KASSERT(hvap != NULL, ("no beacon"));
1926         switch (item) {
1927         case IEEE80211_BEACON_ERP:
1928                 mwl_updateslot(ic->ic_ifp);
1929                 break;
1930         case IEEE80211_BEACON_HTINFO:
1931                 mwl_hal_setnprotmode(hvap,
1932                     MS(ic->ic_curhtprotmode, IEEE80211_HTINFO_OPMODE));
1933                 break;
1934         case IEEE80211_BEACON_CAPS:
1935         case IEEE80211_BEACON_WME:
1936         case IEEE80211_BEACON_APPIE:
1937         case IEEE80211_BEACON_CSA:
1938                 break;
1939         case IEEE80211_BEACON_TIM:
1940                 /* NB: firmware always forms TIM */
1941                 return;
1942         }
1943         /* XXX retain beacon frame and update */
1944         mwl_beacon_setup(vap);
1945 }
1946
1947 static void
1948 mwl_load_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
1949 {
1950         bus_addr_t *paddr = (bus_addr_t*) arg;
1951         KASSERT(error == 0, ("error %u on bus_dma callback", error));
1952         *paddr = segs->ds_addr;
1953 }
1954
1955 #ifdef MWL_HOST_PS_SUPPORT
1956 /*
1957  * Handle power save station occupancy changes.
1958  */
1959 static void
1960 mwl_update_ps(struct ieee80211vap *vap, int nsta)
1961 {
1962         struct mwl_vap *mvp = MWL_VAP(vap);
1963
1964         if (nsta == 0 || mvp->mv_last_ps_sta == 0)
1965                 mwl_hal_setpowersave_bss(mvp->mv_hvap, nsta);
1966         mvp->mv_last_ps_sta = nsta;
1967 }
1968
1969 /*
1970  * Handle associated station power save state changes.
1971  */
1972 static int
1973 mwl_set_tim(struct ieee80211_node *ni, int set)
1974 {
1975         struct ieee80211vap *vap = ni->ni_vap;
1976         struct mwl_vap *mvp = MWL_VAP(vap);
1977
1978         if (mvp->mv_set_tim(ni, set)) {         /* NB: state change */
1979                 mwl_hal_setpowersave_sta(mvp->mv_hvap,
1980                     IEEE80211_AID(ni->ni_associd), set);
1981                 return 1;
1982         } else
1983                 return 0;
1984 }
1985 #endif /* MWL_HOST_PS_SUPPORT */
1986
1987 static int
1988 mwl_desc_setup(struct mwl_softc *sc, const char *name,
1989         struct mwl_descdma *dd,
1990         int nbuf, size_t bufsize, int ndesc, size_t descsize)
1991 {
1992         struct ifnet *ifp = sc->sc_ifp;
1993         uint8_t *ds;
1994         int error;
1995
1996         DPRINTF(sc, MWL_DEBUG_RESET,
1997             "%s: %s DMA: %u bufs (%ju) %u desc/buf (%ju)\n",
1998             __func__, name, nbuf, (uintmax_t) bufsize,
1999             ndesc, (uintmax_t) descsize);
2000
2001         dd->dd_name = name;
2002         dd->dd_desc_len = nbuf * ndesc * descsize;
2003
2004         /*
2005          * Setup DMA descriptor area.
2006          */
2007         error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), /* parent */
2008                        PAGE_SIZE, 0,            /* alignment, bounds */
2009                        BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
2010                        BUS_SPACE_MAXADDR,       /* highaddr */
2011                        NULL, NULL,              /* filter, filterarg */
2012                        dd->dd_desc_len,         /* maxsize */
2013                        1,                       /* nsegments */
2014                        dd->dd_desc_len,         /* maxsegsize */
2015                        BUS_DMA_ALLOCNOW,        /* flags */
2016                        NULL,                    /* lockfunc */
2017                        NULL,                    /* lockarg */
2018                        &dd->dd_dmat);
2019         if (error != 0) {
2020                 if_printf(ifp, "cannot allocate %s DMA tag\n", dd->dd_name);
2021                 return error;
2022         }
2023
2024         /* allocate descriptors */
2025         error = bus_dmamap_create(dd->dd_dmat, BUS_DMA_NOWAIT, &dd->dd_dmamap);
2026         if (error != 0) {
2027                 if_printf(ifp, "unable to create dmamap for %s descriptors, "
2028                         "error %u\n", dd->dd_name, error);
2029                 goto fail0;
2030         }
2031
2032         error = bus_dmamem_alloc(dd->dd_dmat, (void**) &dd->dd_desc,
2033                                  BUS_DMA_NOWAIT | BUS_DMA_COHERENT, 
2034                                  &dd->dd_dmamap);
2035         if (error != 0) {
2036                 if_printf(ifp, "unable to alloc memory for %u %s descriptors, "
2037                         "error %u\n", nbuf * ndesc, dd->dd_name, error);
2038                 goto fail1;
2039         }
2040
2041         error = bus_dmamap_load(dd->dd_dmat, dd->dd_dmamap,
2042                                 dd->dd_desc, dd->dd_desc_len,
2043                                 mwl_load_cb, &dd->dd_desc_paddr,
2044                                 BUS_DMA_NOWAIT);
2045         if (error != 0) {
2046                 if_printf(ifp, "unable to map %s descriptors, error %u\n",
2047                         dd->dd_name, error);
2048                 goto fail2;
2049         }
2050
2051         ds = dd->dd_desc;
2052         memset(ds, 0, dd->dd_desc_len);
2053         DPRINTF(sc, MWL_DEBUG_RESET, "%s: %s DMA map: %p (%lu) -> %p (%lu)\n",
2054             __func__, dd->dd_name, ds, (u_long) dd->dd_desc_len,
2055             (caddr_t) dd->dd_desc_paddr, /*XXX*/ (u_long) dd->dd_desc_len);
2056
2057         return 0;
2058 fail2:
2059         bus_dmamem_free(dd->dd_dmat, dd->dd_desc, dd->dd_dmamap);
2060 fail1:
2061         bus_dmamap_destroy(dd->dd_dmat, dd->dd_dmamap);
2062 fail0:
2063         bus_dma_tag_destroy(dd->dd_dmat);
2064         memset(dd, 0, sizeof(*dd));
2065         return error;
2066 #undef DS2PHYS
2067 }
2068
2069 static void
2070 mwl_desc_cleanup(struct mwl_softc *sc, struct mwl_descdma *dd)
2071 {
2072         bus_dmamap_unload(dd->dd_dmat, dd->dd_dmamap);
2073         bus_dmamem_free(dd->dd_dmat, dd->dd_desc, dd->dd_dmamap);
2074         bus_dmamap_destroy(dd->dd_dmat, dd->dd_dmamap);
2075         bus_dma_tag_destroy(dd->dd_dmat);
2076
2077         memset(dd, 0, sizeof(*dd));
2078 }
2079
2080 /* 
2081  * Construct a tx q's free list.  The order of entries on
2082  * the list must reflect the physical layout of tx descriptors
2083  * because the firmware pre-fetches descriptors.
2084  *
2085  * XXX might be better to use indices into the buffer array.
2086  */
2087 static void
2088 mwl_txq_reset(struct mwl_softc *sc, struct mwl_txq *txq)
2089 {
2090         struct mwl_txbuf *bf;
2091         int i;
2092
2093         bf = txq->dma.dd_bufptr;
2094         STAILQ_INIT(&txq->free);
2095         for (i = 0; i < mwl_txbuf; i++, bf++)
2096                 STAILQ_INSERT_TAIL(&txq->free, bf, bf_list);
2097         txq->nfree = i;
2098 }
2099
2100 #define DS2PHYS(_dd, _ds) \
2101         ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc))
2102
2103 static int
2104 mwl_txdma_setup(struct mwl_softc *sc, struct mwl_txq *txq)
2105 {
2106         struct ifnet *ifp = sc->sc_ifp;
2107         int error, bsize, i;
2108         struct mwl_txbuf *bf;
2109         struct mwl_txdesc *ds;
2110
2111         error = mwl_desc_setup(sc, "tx", &txq->dma,
2112                         mwl_txbuf, sizeof(struct mwl_txbuf),
2113                         MWL_TXDESC, sizeof(struct mwl_txdesc));
2114         if (error != 0)
2115                 return error;
2116
2117         /* allocate and setup tx buffers */
2118         bsize = mwl_txbuf * sizeof(struct mwl_txbuf);
2119         bf = malloc(bsize, M_MWLDEV, M_NOWAIT | M_ZERO);
2120         if (bf == NULL) {
2121                 if_printf(ifp, "malloc of %u tx buffers failed\n",
2122                         mwl_txbuf);
2123                 return ENOMEM;
2124         }
2125         txq->dma.dd_bufptr = bf;
2126
2127         ds = txq->dma.dd_desc;
2128         for (i = 0; i < mwl_txbuf; i++, bf++, ds += MWL_TXDESC) {
2129                 bf->bf_desc = ds;
2130                 bf->bf_daddr = DS2PHYS(&txq->dma, ds);
2131                 error = bus_dmamap_create(sc->sc_dmat, BUS_DMA_NOWAIT,
2132                                 &bf->bf_dmamap);
2133                 if (error != 0) {
2134                         if_printf(ifp, "unable to create dmamap for tx "
2135                                 "buffer %u, error %u\n", i, error);
2136                         return error;
2137                 }
2138         }
2139         mwl_txq_reset(sc, txq);
2140         return 0;
2141 }
2142
2143 static void
2144 mwl_txdma_cleanup(struct mwl_softc *sc, struct mwl_txq *txq)
2145 {
2146         struct mwl_txbuf *bf;
2147         int i;
2148
2149         bf = txq->dma.dd_bufptr;
2150         for (i = 0; i < mwl_txbuf; i++, bf++) {
2151                 KASSERT(bf->bf_m == NULL, ("mbuf on free list"));
2152                 KASSERT(bf->bf_node == NULL, ("node on free list"));
2153                 if (bf->bf_dmamap != NULL)
2154                         bus_dmamap_destroy(sc->sc_dmat, bf->bf_dmamap);
2155         }
2156         STAILQ_INIT(&txq->free);
2157         txq->nfree = 0;
2158         if (txq->dma.dd_bufptr != NULL) {
2159                 free(txq->dma.dd_bufptr, M_MWLDEV);
2160                 txq->dma.dd_bufptr = NULL;
2161         }
2162         if (txq->dma.dd_desc_len != 0)
2163                 mwl_desc_cleanup(sc, &txq->dma);
2164 }
2165
2166 static int
2167 mwl_rxdma_setup(struct mwl_softc *sc)
2168 {
2169         struct ifnet *ifp = sc->sc_ifp;
2170         int error, jumbosize, bsize, i;
2171         struct mwl_rxbuf *bf;
2172         struct mwl_jumbo *rbuf;
2173         struct mwl_rxdesc *ds;
2174         caddr_t data;
2175
2176         error = mwl_desc_setup(sc, "rx", &sc->sc_rxdma,
2177                         mwl_rxdesc, sizeof(struct mwl_rxbuf),
2178                         1, sizeof(struct mwl_rxdesc));
2179         if (error != 0)
2180                 return error;
2181
2182         /*
2183          * Receive is done to a private pool of jumbo buffers.
2184          * This allows us to attach to mbuf's and avoid re-mapping
2185          * memory on each rx we post.  We allocate a large chunk
2186          * of memory and manage it in the driver.  The mbuf free
2187          * callback method is used to reclaim frames after sending
2188          * them up the stack.  By default we allocate 2x the number of
2189          * rx descriptors configured so we have some slop to hold
2190          * us while frames are processed.
2191          */
2192         if (mwl_rxbuf < 2*mwl_rxdesc) {
2193                 if_printf(ifp,
2194                     "too few rx dma buffers (%d); increasing to %d\n",
2195                     mwl_rxbuf, 2*mwl_rxdesc);
2196                 mwl_rxbuf = 2*mwl_rxdesc;
2197         }
2198         jumbosize = roundup(MWL_AGGR_SIZE, PAGE_SIZE);
2199         sc->sc_rxmemsize = mwl_rxbuf*jumbosize;
2200
2201         error = bus_dma_tag_create(sc->sc_dmat, /* parent */
2202                        PAGE_SIZE, 0,            /* alignment, bounds */
2203                        BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
2204                        BUS_SPACE_MAXADDR,       /* highaddr */
2205                        NULL, NULL,              /* filter, filterarg */
2206                        sc->sc_rxmemsize,        /* maxsize */
2207                        1,                       /* nsegments */
2208                        sc->sc_rxmemsize,        /* maxsegsize */
2209                        BUS_DMA_ALLOCNOW,        /* flags */
2210                        NULL,                    /* lockfunc */
2211                        NULL,                    /* lockarg */
2212                        &sc->sc_rxdmat);
2213         error = bus_dmamap_create(sc->sc_rxdmat, BUS_DMA_NOWAIT, &sc->sc_rxmap);
2214         if (error != 0) {
2215                 if_printf(ifp, "could not create rx DMA map\n");
2216                 return error;
2217         }
2218
2219         error = bus_dmamem_alloc(sc->sc_rxdmat, (void**) &sc->sc_rxmem,
2220                                  BUS_DMA_NOWAIT | BUS_DMA_COHERENT, 
2221                                  &sc->sc_rxmap);
2222         if (error != 0) {
2223                 if_printf(ifp, "could not alloc %ju bytes of rx DMA memory\n",
2224                     (uintmax_t) sc->sc_rxmemsize);
2225                 return error;
2226         }
2227
2228         error = bus_dmamap_load(sc->sc_rxdmat, sc->sc_rxmap,
2229                                 sc->sc_rxmem, sc->sc_rxmemsize,
2230                                 mwl_load_cb, &sc->sc_rxmem_paddr,
2231                                 BUS_DMA_NOWAIT);
2232         if (error != 0) {
2233                 if_printf(ifp, "could not load rx DMA map\n");
2234                 return error;
2235         }
2236
2237         /*
2238          * Allocate rx buffers and set them up.
2239          */
2240         bsize = mwl_rxdesc * sizeof(struct mwl_rxbuf);
2241         bf = malloc(bsize, M_MWLDEV, M_NOWAIT | M_ZERO);
2242         if (bf == NULL) {
2243                 if_printf(ifp, "malloc of %u rx buffers failed\n", bsize);
2244                 return error;
2245         }
2246         sc->sc_rxdma.dd_bufptr = bf;
2247
2248         STAILQ_INIT(&sc->sc_rxbuf);
2249         ds = sc->sc_rxdma.dd_desc;
2250         for (i = 0; i < mwl_rxdesc; i++, bf++, ds++) {
2251                 bf->bf_desc = ds;
2252                 bf->bf_daddr = DS2PHYS(&sc->sc_rxdma, ds);
2253                 /* pre-assign dma buffer */
2254                 bf->bf_data = ((uint8_t *)sc->sc_rxmem) + (i*jumbosize);
2255                 /* NB: tail is intentional to preserve descriptor order */
2256                 STAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list);
2257         }
2258
2259         /*
2260          * Place remainder of dma memory buffers on the free list.
2261          */
2262         SLIST_INIT(&sc->sc_rxfree);
2263         for (; i < mwl_rxbuf; i++) {
2264                 data = ((uint8_t *)sc->sc_rxmem) + (i*jumbosize);
2265                 rbuf = MWL_JUMBO_DATA2BUF(data);
2266                 SLIST_INSERT_HEAD(&sc->sc_rxfree, rbuf, next);
2267                 sc->sc_nrxfree++;
2268         }
2269         MWL_RXFREE_INIT(sc);
2270         return 0;
2271 }
2272 #undef DS2PHYS
2273
2274 static void
2275 mwl_rxdma_cleanup(struct mwl_softc *sc)
2276 {
2277         if (sc->sc_rxmap != NULL)
2278                 bus_dmamap_unload(sc->sc_rxdmat, sc->sc_rxmap);
2279         if (sc->sc_rxmem != NULL) {
2280                 bus_dmamem_free(sc->sc_rxdmat, sc->sc_rxmem, sc->sc_rxmap);
2281                 sc->sc_rxmem = NULL;
2282         }
2283         if (sc->sc_rxmap != NULL) {
2284                 bus_dmamap_destroy(sc->sc_rxdmat, sc->sc_rxmap);
2285                 sc->sc_rxmap = NULL;
2286         }
2287         if (sc->sc_rxdma.dd_bufptr != NULL) {
2288                 free(sc->sc_rxdma.dd_bufptr, M_MWLDEV);
2289                 sc->sc_rxdma.dd_bufptr = NULL;
2290         }
2291         if (sc->sc_rxdma.dd_desc_len != 0)
2292                 mwl_desc_cleanup(sc, &sc->sc_rxdma);
2293         MWL_RXFREE_DESTROY(sc);
2294 }
2295
2296 static int
2297 mwl_dma_setup(struct mwl_softc *sc)
2298 {
2299         int error, i;
2300
2301         error = mwl_rxdma_setup(sc);
2302         if (error != 0)
2303                 return error;
2304
2305         for (i = 0; i < MWL_NUM_TX_QUEUES; i++) {
2306                 error = mwl_txdma_setup(sc, &sc->sc_txq[i]);
2307                 if (error != 0) {
2308                         mwl_dma_cleanup(sc);
2309                         return error;
2310                 }
2311         }
2312         return 0;
2313 }
2314
2315 static void
2316 mwl_dma_cleanup(struct mwl_softc *sc)
2317 {
2318         int i;
2319
2320         for (i = 0; i < MWL_NUM_TX_QUEUES; i++)
2321                 mwl_txdma_cleanup(sc, &sc->sc_txq[i]);
2322         mwl_rxdma_cleanup(sc);
2323 }
2324
2325 static struct ieee80211_node *
2326 mwl_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
2327 {
2328         struct ieee80211com *ic = vap->iv_ic;
2329         struct mwl_softc *sc = ic->ic_ifp->if_softc;
2330         const size_t space = sizeof(struct mwl_node);
2331         struct mwl_node *mn;
2332
2333         mn = malloc(space, M_80211_NODE, M_NOWAIT|M_ZERO);
2334         if (mn == NULL) {
2335                 /* XXX stat+msg */
2336                 return NULL;
2337         }
2338         DPRINTF(sc, MWL_DEBUG_NODE, "%s: mn %p\n", __func__, mn);
2339         return &mn->mn_node;
2340 }
2341
2342 static void
2343 mwl_node_cleanup(struct ieee80211_node *ni)
2344 {
2345         struct ieee80211com *ic = ni->ni_ic;
2346         struct mwl_softc *sc = ic->ic_ifp->if_softc;
2347         struct mwl_node *mn = MWL_NODE(ni);
2348
2349         DPRINTF(sc, MWL_DEBUG_NODE, "%s: ni %p ic %p staid %d\n",
2350             __func__, ni, ni->ni_ic, mn->mn_staid);
2351
2352         if (mn->mn_staid != 0) {
2353                 struct ieee80211vap *vap = ni->ni_vap;
2354
2355                 if (mn->mn_hvap != NULL) {
2356                         if (vap->iv_opmode == IEEE80211_M_STA)
2357                                 mwl_hal_delstation(mn->mn_hvap, vap->iv_myaddr);
2358                         else
2359                                 mwl_hal_delstation(mn->mn_hvap, ni->ni_macaddr);
2360                 }
2361                 /*
2362                  * NB: legacy WDS peer sta db entry is installed using
2363                  * the associate ap's hvap; use it again to delete it.
2364                  * XXX can vap be NULL?
2365                  */
2366                 else if (vap->iv_opmode == IEEE80211_M_WDS &&
2367                     MWL_VAP(vap)->mv_ap_hvap != NULL)
2368                         mwl_hal_delstation(MWL_VAP(vap)->mv_ap_hvap,
2369                             ni->ni_macaddr);
2370                 delstaid(sc, mn->mn_staid);
2371                 mn->mn_staid = 0;
2372         }
2373         sc->sc_node_cleanup(ni);
2374 }
2375
2376 /*
2377  * Reclaim rx dma buffers from packets sitting on the ampdu
2378  * reorder queue for a station.  We replace buffers with a
2379  * system cluster (if available).
2380  */
2381 static void
2382 mwl_ampdu_rxdma_reclaim(struct ieee80211_rx_ampdu *rap)
2383 {
2384 #if 0
2385         int i, n, off;
2386         struct mbuf *m;
2387         void *cl;
2388
2389         n = rap->rxa_qframes;
2390         for (i = 0; i < rap->rxa_wnd && n > 0; i++) {
2391                 m = rap->rxa_m[i];
2392                 if (m == NULL)
2393                         continue;
2394                 n--;
2395                 /* our dma buffers have a well-known free routine */
2396                 if ((m->m_flags & M_EXT) == 0 ||
2397                     m->m_ext.ext_free != mwl_ext_free)
2398                         continue;
2399                 /*
2400                  * Try to allocate a cluster and move the data.
2401                  */
2402                 off = m->m_data - m->m_ext.ext_buf;
2403                 if (off + m->m_pkthdr.len > MCLBYTES) {
2404                         /* XXX no AMSDU for now */
2405                         continue;
2406                 }
2407                 cl = pool_cache_get_paddr(&mclpool_cache, 0,
2408                     &m->m_ext.ext_paddr);
2409                 if (cl != NULL) {
2410                         /*
2411                          * Copy the existing data to the cluster, remove
2412                          * the rx dma buffer, and attach the cluster in
2413                          * its place.  Note we preserve the offset to the
2414                          * data so frames being bridged can still prepend
2415                          * their headers without adding another mbuf.
2416                          */
2417                         memcpy((caddr_t) cl + off, m->m_data, m->m_pkthdr.len);
2418                         MEXTREMOVE(m);
2419                         MEXTADD(m, cl, MCLBYTES, 0, NULL, &mclpool_cache);
2420                         /* setup mbuf like _MCLGET does */
2421                         m->m_flags |= M_CLUSTER | M_EXT_RW;
2422                         _MOWNERREF(m, M_EXT | M_CLUSTER);
2423                         /* NB: m_data is clobbered by MEXTADDR, adjust */
2424                         m->m_data += off;
2425                 }
2426         }
2427 #endif
2428 }
2429
2430 /*
2431  * Callback to reclaim resources.  We first let the
2432  * net80211 layer do it's thing, then if we are still
2433  * blocked by a lack of rx dma buffers we walk the ampdu
2434  * reorder q's to reclaim buffers by copying to a system
2435  * cluster.
2436  */
2437 static void
2438 mwl_node_drain(struct ieee80211_node *ni)
2439 {
2440         struct ieee80211com *ic = ni->ni_ic;
2441         struct mwl_softc *sc = ic->ic_ifp->if_softc;
2442         struct mwl_node *mn = MWL_NODE(ni);
2443
2444         DPRINTF(sc, MWL_DEBUG_NODE, "%s: ni %p vap %p staid %d\n",
2445             __func__, ni, ni->ni_vap, mn->mn_staid);
2446
2447         /* NB: call up first to age out ampdu q's */
2448         sc->sc_node_drain(ni);
2449
2450         /* XXX better to not check low water mark? */
2451         if (sc->sc_rxblocked && mn->mn_staid != 0 &&
2452             (ni->ni_flags & IEEE80211_NODE_HT)) {
2453                 uint8_t tid;
2454                 /*
2455                  * Walk the reorder q and reclaim rx dma buffers by copying
2456                  * the packet contents into clusters.
2457                  */
2458                 for (tid = 0; tid < WME_NUM_TID; tid++) {
2459                         struct ieee80211_rx_ampdu *rap;
2460
2461                         rap = &ni->ni_rx_ampdu[tid];
2462                         if ((rap->rxa_flags & IEEE80211_AGGR_XCHGPEND) == 0)
2463                                 continue;
2464                         if (rap->rxa_qframes)
2465                                 mwl_ampdu_rxdma_reclaim(rap);
2466                 }
2467         }
2468 }
2469
2470 static void
2471 mwl_node_getsignal(const struct ieee80211_node *ni, int8_t *rssi, int8_t *noise)
2472 {
2473         *rssi = ni->ni_ic->ic_node_getrssi(ni);
2474 #ifdef MWL_ANT_INFO_SUPPORT
2475 #if 0
2476         /* XXX need to smooth data */
2477         *noise = -MWL_NODE_CONST(ni)->mn_ai.nf;
2478 #else
2479         *noise = -95;           /* XXX */
2480 #endif
2481 #else
2482         *noise = -95;           /* XXX */
2483 #endif
2484 }
2485
2486 /*
2487  * Convert Hardware per-antenna rssi info to common format:
2488  * Let a1, a2, a3 represent the amplitudes per chain
2489  * Let amax represent max[a1, a2, a3]
2490  * Rssi1_dBm = RSSI_dBm + 20*log10(a1/amax)
2491  * Rssi1_dBm = RSSI_dBm + 20*log10(a1) - 20*log10(amax)
2492  * We store a table that is 4*20*log10(idx) - the extra 4 is to store or
2493  * maintain some extra precision.
2494  *
2495  * Values are stored in .5 db format capped at 127.
2496  */
2497 static void
2498 mwl_node_getmimoinfo(const struct ieee80211_node *ni,
2499         struct ieee80211_mimo_info *mi)
2500 {
2501 #define CVT(_dst, _src) do {                                            \
2502         (_dst) = rssi + ((logdbtbl[_src] - logdbtbl[rssi_max]) >> 2);   \
2503         (_dst) = (_dst) > 64 ? 127 : ((_dst) << 1);                     \
2504 } while (0)
2505         static const int8_t logdbtbl[32] = {
2506                0,   0,  24,  38,  48,  56,  62,  68, 
2507               72,  76,  80,  83,  86,  89,  92,  94, 
2508               96,  98, 100, 102, 104, 106, 107, 109, 
2509              110, 112, 113, 115, 116, 117, 118, 119
2510         };
2511         const struct mwl_node *mn = MWL_NODE_CONST(ni);
2512         uint8_t rssi = mn->mn_ai.rsvd1/2;               /* XXX */
2513         uint32_t rssi_max;
2514
2515         rssi_max = mn->mn_ai.rssi_a;
2516         if (mn->mn_ai.rssi_b > rssi_max)
2517                 rssi_max = mn->mn_ai.rssi_b;
2518         if (mn->mn_ai.rssi_c > rssi_max)
2519                 rssi_max = mn->mn_ai.rssi_c;
2520
2521         CVT(mi->rssi[0], mn->mn_ai.rssi_a);
2522         CVT(mi->rssi[1], mn->mn_ai.rssi_b);
2523         CVT(mi->rssi[2], mn->mn_ai.rssi_c);
2524
2525         mi->noise[0] = mn->mn_ai.nf_a;
2526         mi->noise[1] = mn->mn_ai.nf_b;
2527         mi->noise[2] = mn->mn_ai.nf_c;
2528 #undef CVT
2529 }
2530
2531 static __inline void *
2532 mwl_getrxdma(struct mwl_softc *sc)
2533 {
2534         struct mwl_jumbo *buf;
2535         void *data;
2536
2537         /*
2538          * Allocate from jumbo pool.
2539          */
2540         MWL_RXFREE_LOCK(sc);
2541         buf = SLIST_FIRST(&sc->sc_rxfree);
2542         if (buf == NULL) {
2543                 DPRINTF(sc, MWL_DEBUG_ANY,
2544                     "%s: out of rx dma buffers\n", __func__);
2545                 sc->sc_stats.mst_rx_nodmabuf++;
2546                 data = NULL;
2547         } else {
2548                 SLIST_REMOVE_HEAD(&sc->sc_rxfree, next);
2549                 sc->sc_nrxfree--;
2550                 data = MWL_JUMBO_BUF2DATA(buf);
2551         }
2552         MWL_RXFREE_UNLOCK(sc);
2553         return data;
2554 }
2555
2556 static __inline void
2557 mwl_putrxdma(struct mwl_softc *sc, void *data)
2558 {
2559         struct mwl_jumbo *buf;
2560
2561         /* XXX bounds check data */
2562         MWL_RXFREE_LOCK(sc);
2563         buf = MWL_JUMBO_DATA2BUF(data);
2564         SLIST_INSERT_HEAD(&sc->sc_rxfree, buf, next);
2565         sc->sc_nrxfree++;
2566         MWL_RXFREE_UNLOCK(sc);
2567 }
2568
2569 static int
2570 mwl_rxbuf_init(struct mwl_softc *sc, struct mwl_rxbuf *bf)
2571 {
2572         struct mwl_rxdesc *ds;
2573
2574         ds = bf->bf_desc;
2575         if (bf->bf_data == NULL) {
2576                 bf->bf_data = mwl_getrxdma(sc);
2577                 if (bf->bf_data == NULL) {
2578                         /* mark descriptor to be skipped */
2579                         ds->RxControl = EAGLE_RXD_CTRL_OS_OWN;
2580                         /* NB: don't need PREREAD */
2581                         MWL_RXDESC_SYNC(sc, ds, BUS_DMASYNC_PREWRITE);
2582                         sc->sc_stats.mst_rxbuf_failed++;
2583                         return ENOMEM;
2584                 }
2585         }
2586         /*
2587          * NB: DMA buffer contents is known to be unmodified
2588          *     so there's no need to flush the data cache.
2589          */
2590
2591         /*
2592          * Setup descriptor.
2593          */
2594         ds->QosCtrl = 0;
2595         ds->RSSI = 0;
2596         ds->Status = EAGLE_RXD_STATUS_IDLE;
2597         ds->Channel = 0;
2598         ds->PktLen = htole16(MWL_AGGR_SIZE);
2599         ds->SQ2 = 0;
2600         ds->pPhysBuffData = htole32(MWL_JUMBO_DMA_ADDR(sc, bf->bf_data));
2601         /* NB: don't touch pPhysNext, set once */
2602         ds->RxControl = EAGLE_RXD_CTRL_DRIVER_OWN;
2603         MWL_RXDESC_SYNC(sc, ds, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
2604
2605         return 0;
2606 }
2607
2608 static void
2609 mwl_ext_free(void *data, void *arg)
2610 {
2611         struct mwl_softc *sc = arg;
2612
2613         /* XXX bounds check data */
2614         mwl_putrxdma(sc, data);
2615         /*
2616          * If we were previously blocked by a lack of rx dma buffers
2617          * check if we now have enough to restart rx interrupt handling.
2618          * NB: we know we are called at splvm which is above splnet.
2619          */
2620         if (sc->sc_rxblocked && sc->sc_nrxfree > mwl_rxdmalow) {
2621                 sc->sc_rxblocked = 0;
2622                 mwl_hal_intrset(sc->sc_mh, sc->sc_imask);
2623         }
2624 }
2625
2626 struct mwl_frame_bar {
2627         u_int8_t        i_fc[2];
2628         u_int8_t        i_dur[2];
2629         u_int8_t        i_ra[IEEE80211_ADDR_LEN];
2630         u_int8_t        i_ta[IEEE80211_ADDR_LEN];
2631         /* ctl, seq, FCS */
2632 } __packed;
2633
2634 /*
2635  * Like ieee80211_anyhdrsize, but handles BAR frames
2636  * specially so the logic below to piece the 802.11
2637  * header together works.
2638  */
2639 static __inline int
2640 mwl_anyhdrsize(const void *data)
2641 {
2642         const struct ieee80211_frame *wh = data;
2643
2644         if ((wh->i_fc[0]&IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL) {
2645                 switch (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) {
2646                 case IEEE80211_FC0_SUBTYPE_CTS:
2647                 case IEEE80211_FC0_SUBTYPE_ACK:
2648                         return sizeof(struct ieee80211_frame_ack);
2649                 case IEEE80211_FC0_SUBTYPE_BAR:
2650                         return sizeof(struct mwl_frame_bar);
2651                 }
2652                 return sizeof(struct ieee80211_frame_min);
2653         } else
2654                 return ieee80211_hdrsize(data);
2655 }
2656
2657 static void
2658 mwl_handlemicerror(struct ieee80211com *ic, const uint8_t *data)
2659 {
2660         const struct ieee80211_frame *wh;
2661         struct ieee80211_node *ni;
2662
2663         wh = (const struct ieee80211_frame *)(data + sizeof(uint16_t));
2664         ni = ieee80211_find_rxnode(ic, (const struct ieee80211_frame_min *) wh);
2665         if (ni != NULL) {
2666                 ieee80211_notify_michael_failure(ni->ni_vap, wh, 0);
2667                 ieee80211_free_node(ni);
2668         }
2669 }
2670
2671 /*
2672  * Convert hardware signal strength to rssi.  The value
2673  * provided by the device has the noise floor added in;
2674  * we need to compensate for this but we don't have that
2675  * so we use a fixed value.
2676  *
2677  * The offset of 8 is good for both 2.4 and 5GHz.  The LNA
2678  * offset is already set as part of the initial gain.  This
2679  * will give at least +/- 3dB for 2.4GHz and +/- 5dB for 5GHz.
2680  */
2681 static __inline int
2682 cvtrssi(uint8_t ssi)
2683 {
2684         int rssi = (int) ssi + 8;
2685         /* XXX hack guess until we have a real noise floor */
2686         rssi = 2*(87 - rssi);   /* NB: .5 dBm units */
2687         return (rssi < 0 ? 0 : rssi > 127 ? 127 : rssi);
2688 }
2689
2690 static void
2691 mwl_rx_proc(void *arg, int npending)
2692 {
2693 #define IEEE80211_DIR_DSTODS(wh) \
2694         ((((const struct ieee80211_frame *)wh)->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS)
2695         struct mwl_softc *sc = arg;
2696         struct ifnet *ifp = sc->sc_ifp;
2697         struct ieee80211com *ic = ifp->if_l2com;
2698         struct mwl_rxbuf *bf;
2699         struct mwl_rxdesc *ds;
2700         struct mbuf *m;
2701         struct ieee80211_qosframe *wh;
2702         struct ieee80211_qosframe_addr4 *wh4;
2703         struct ieee80211_node *ni;
2704         struct mwl_node *mn;
2705         int off, len, hdrlen, pktlen, rssi, ntodo;
2706         uint8_t *data, status;
2707         void *newdata;
2708         int16_t nf;
2709
2710         DPRINTF(sc, MWL_DEBUG_RX_PROC, "%s: pending %u rdptr 0x%x wrptr 0x%x\n",
2711             __func__, npending, RD4(sc, sc->sc_hwspecs.rxDescRead),
2712             RD4(sc, sc->sc_hwspecs.rxDescWrite));
2713         nf = -96;                       /* XXX */
2714         bf = sc->sc_rxnext;
2715         for (ntodo = mwl_rxquota; ntodo > 0; ntodo--) {
2716                 if (bf == NULL)
2717                         bf = STAILQ_FIRST(&sc->sc_rxbuf);
2718                 ds = bf->bf_desc;
2719                 data = bf->bf_data;
2720                 if (data == NULL) {
2721                         /*
2722                          * If data allocation failed previously there
2723                          * will be no buffer; try again to re-populate it.
2724                          * Note the firmware will not advance to the next
2725                          * descriptor with a dma buffer so we must mimic
2726                          * this or we'll get out of sync.
2727                          */ 
2728                         DPRINTF(sc, MWL_DEBUG_ANY,
2729                             "%s: rx buf w/o dma memory\n", __func__);
2730                         (void) mwl_rxbuf_init(sc, bf);
2731                         sc->sc_stats.mst_rx_dmabufmissing++;
2732                         break;
2733                 }
2734                 MWL_RXDESC_SYNC(sc, ds,
2735                     BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
2736                 if (ds->RxControl != EAGLE_RXD_CTRL_DMA_OWN)
2737                         break;
2738 #ifdef MWL_DEBUG
2739                 if (sc->sc_debug & MWL_DEBUG_RECV_DESC)
2740                         mwl_printrxbuf(bf, 0);
2741 #endif
2742                 status = ds->Status;
2743                 if (status & EAGLE_RXD_STATUS_DECRYPT_ERR_MASK) {
2744                         ifp->if_ierrors++;
2745                         sc->sc_stats.mst_rx_crypto++;
2746                         /*
2747                          * NB: Check EAGLE_RXD_STATUS_GENERAL_DECRYPT_ERR
2748                          *     for backwards compatibility.
2749                          */
2750                         if (status != EAGLE_RXD_STATUS_GENERAL_DECRYPT_ERR &&
2751                             (status & EAGLE_RXD_STATUS_TKIP_MIC_DECRYPT_ERR)) {
2752                                 /*
2753                                  * MIC error, notify upper layers.
2754                                  */
2755                                 bus_dmamap_sync(sc->sc_rxdmat, sc->sc_rxmap,
2756                                     BUS_DMASYNC_POSTREAD);
2757                                 mwl_handlemicerror(ic, data);
2758                                 sc->sc_stats.mst_rx_tkipmic++;
2759                         }
2760                         /* XXX too painful to tap packets */
2761                         goto rx_next;
2762                 }
2763                 /*
2764                  * Sync the data buffer.
2765                  */
2766                 len = le16toh(ds->PktLen);
2767                 bus_dmamap_sync(sc->sc_rxdmat, sc->sc_rxmap, BUS_DMASYNC_POSTREAD);
2768                 /*
2769                  * The 802.11 header is provided all or in part at the front;
2770                  * use it to calculate the true size of the header that we'll
2771                  * construct below.  We use this to figure out where to copy
2772                  * payload prior to constructing the header.
2773                  */
2774                 hdrlen = mwl_anyhdrsize(data + sizeof(uint16_t));
2775                 off = sizeof(uint16_t) + sizeof(struct ieee80211_frame_addr4);
2776
2777                 /* calculate rssi early so we can re-use for each aggregate */
2778                 rssi = cvtrssi(ds->RSSI);
2779
2780                 pktlen = hdrlen + (len - off);
2781                 /*
2782                  * NB: we know our frame is at least as large as
2783                  * IEEE80211_MIN_LEN because there is a 4-address
2784                  * frame at the front.  Hence there's no need to
2785                  * vet the packet length.  If the frame in fact
2786                  * is too small it should be discarded at the
2787                  * net80211 layer.
2788                  */
2789
2790                 /*
2791                  * Attach dma buffer to an mbuf.  We tried
2792                  * doing this based on the packet size (i.e.
2793                  * copying small packets) but it turns out to
2794                  * be a net loss.  The tradeoff might be system
2795                  * dependent (cache architecture is important).
2796                  */
2797                 MGETHDR(m, M_DONTWAIT, MT_DATA);
2798                 if (m == NULL) {
2799                         DPRINTF(sc, MWL_DEBUG_ANY,
2800                             "%s: no rx mbuf\n", __func__);
2801                         sc->sc_stats.mst_rx_nombuf++;
2802                         goto rx_next;
2803                 }
2804                 /*
2805                  * Acquire the replacement dma buffer before
2806                  * processing the frame.  If we're out of dma
2807                  * buffers we disable rx interrupts and wait
2808                  * for the free pool to reach mlw_rxdmalow buffers
2809                  * before starting to do work again.  If the firmware
2810                  * runs out of descriptors then it will toss frames
2811                  * which is better than our doing it as that can
2812                  * starve our processing.  It is also important that
2813                  * we always process rx'd frames in case they are
2814                  * A-MPDU as otherwise the host's view of the BA
2815                  * window may get out of sync with the firmware.
2816                  */
2817                 newdata = mwl_getrxdma(sc);
2818                 if (newdata == NULL) {
2819                         /* NB: stat+msg in mwl_getrxdma */
2820                         m_free(m);
2821                         /* disable RX interrupt and mark state */
2822                         mwl_hal_intrset(sc->sc_mh,
2823                             sc->sc_imask &~ MACREG_A2HRIC_BIT_RX_RDY);
2824                         sc->sc_rxblocked = 1;
2825                         ieee80211_drain(ic);
2826                         /* XXX check rxblocked and immediately start again? */
2827                         goto rx_stop;
2828                 }
2829                 bf->bf_data = newdata;
2830                 /*
2831                  * Attach the dma buffer to the mbuf;
2832                  * mwl_rxbuf_init will re-setup the rx
2833                  * descriptor using the replacement dma
2834                  * buffer we just installed above.
2835                  */
2836                 MEXTADD(m, data, MWL_AGGR_SIZE, mwl_ext_free,
2837                     data, sc, 0, EXT_NET_DRV);
2838                 m->m_data += off - hdrlen;
2839                 m->m_pkthdr.len = m->m_len = pktlen;
2840                 m->m_pkthdr.rcvif = ifp;
2841                 /* NB: dma buffer assumed read-only */
2842
2843                 /*
2844                  * Piece 802.11 header together.
2845                  */
2846                 wh = mtod(m, struct ieee80211_qosframe *);
2847                 /* NB: don't need to do this sometimes but ... */
2848                 /* XXX special case so we can memcpy after m_devget? */
2849                 ovbcopy(data + sizeof(uint16_t), wh, hdrlen);
2850                 if (IEEE80211_QOS_HAS_SEQ(wh)) {
2851                         if (IEEE80211_DIR_DSTODS(wh)) {
2852                                 wh4 = mtod(m,
2853                                     struct ieee80211_qosframe_addr4*);
2854                                 *(uint16_t *)wh4->i_qos = ds->QosCtrl;
2855                         } else {
2856                                 *(uint16_t *)wh->i_qos = ds->QosCtrl;
2857                         }
2858                 }
2859                 /*
2860                  * The f/w strips WEP header but doesn't clear
2861                  * the WEP bit; mark the packet with M_WEP so
2862                  * net80211 will treat the data as decrypted.
2863                  * While here also clear the PWR_MGT bit since
2864                  * power save is handled by the firmware and
2865                  * passing this up will potentially cause the
2866                  * upper layer to put a station in power save
2867                  * (except when configured with MWL_HOST_PS_SUPPORT).
2868                  */
2869                 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
2870                         m->m_flags |= M_WEP;
2871 #ifdef MWL_HOST_PS_SUPPORT
2872                 wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
2873 #else
2874                 wh->i_fc[1] &= ~(IEEE80211_FC1_WEP | IEEE80211_FC1_PWR_MGT);
2875 #endif
2876
2877                 if (ieee80211_radiotap_active(ic)) {
2878                         struct mwl_rx_radiotap_header *tap = &sc->sc_rx_th;
2879
2880                         tap->wr_flags = 0;
2881                         tap->wr_rate = ds->Rate;
2882                         tap->wr_antsignal = rssi + nf;
2883                         tap->wr_antnoise = nf;
2884                 }
2885                 if (IFF_DUMPPKTS_RECV(sc, wh)) {
2886                         ieee80211_dump_pkt(ic, mtod(m, caddr_t),
2887                             len, ds->Rate, rssi);
2888                 }
2889                 ifp->if_ipackets++;
2890
2891                 /* dispatch */
2892                 ni = ieee80211_find_rxnode(ic,
2893                     (const struct ieee80211_frame_min *) wh);
2894                 if (ni != NULL) {
2895                         mn = MWL_NODE(ni);
2896 #ifdef MWL_ANT_INFO_SUPPORT
2897                         mn->mn_ai.rssi_a = ds->ai.rssi_a;
2898                         mn->mn_ai.rssi_b = ds->ai.rssi_b;
2899                         mn->mn_ai.rssi_c = ds->ai.rssi_c;
2900                         mn->mn_ai.rsvd1 = rssi;
2901 #endif
2902                         /* tag AMPDU aggregates for reorder processing */
2903                         if (ni->ni_flags & IEEE80211_NODE_HT)
2904                                 m->m_flags |= M_AMPDU;
2905                         (void) ieee80211_input(ni, m, rssi, nf);
2906                         ieee80211_free_node(ni);
2907                 } else
2908                         (void) ieee80211_input_all(ic, m, rssi, nf);
2909 rx_next:
2910                 /* NB: ignore ENOMEM so we process more descriptors */
2911                 (void) mwl_rxbuf_init(sc, bf);
2912                 bf = STAILQ_NEXT(bf, bf_list);
2913         }
2914 rx_stop:
2915         sc->sc_rxnext = bf;
2916
2917         if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 &&
2918             !IFQ_IS_EMPTY(&ifp->if_snd)) {
2919                 /* NB: kick fw; the tx thread may have been preempted */
2920                 mwl_hal_txstart(sc->sc_mh, 0);
2921                 mwl_start(ifp);
2922         }
2923 #undef IEEE80211_DIR_DSTODS
2924 }
2925
2926 static void
2927 mwl_txq_init(struct mwl_softc *sc, struct mwl_txq *txq, int qnum)
2928 {
2929         struct mwl_txbuf *bf, *bn;
2930         struct mwl_txdesc *ds;
2931
2932         MWL_TXQ_LOCK_INIT(sc, txq);
2933         txq->qnum = qnum;
2934         txq->txpri = 0; /* XXX */
2935 #if 0
2936         /* NB: q setup by mwl_txdma_setup XXX */
2937         STAILQ_INIT(&txq->free);
2938 #endif
2939         STAILQ_FOREACH(bf, &txq->free, bf_list) {
2940                 bf->bf_txq = txq;
2941
2942                 ds = bf->bf_desc;
2943                 bn = STAILQ_NEXT(bf, bf_list);
2944                 if (bn == NULL)
2945                         bn = STAILQ_FIRST(&txq->free);
2946                 ds->pPhysNext = htole32(bn->bf_daddr);
2947         }
2948         STAILQ_INIT(&txq->active);
2949 }
2950
2951 /*
2952  * Setup a hardware data transmit queue for the specified
2953  * access control.  We record the mapping from ac's
2954  * to h/w queues for use by mwl_tx_start.
2955  */
2956 static int
2957 mwl_tx_setup(struct mwl_softc *sc, int ac, int mvtype)
2958 {
2959 #define N(a)    (sizeof(a)/sizeof(a[0]))
2960         struct mwl_txq *txq;
2961
2962         if (ac >= N(sc->sc_ac2q)) {
2963                 device_printf(sc->sc_dev, "AC %u out of range, max %zu!\n",
2964                         ac, N(sc->sc_ac2q));
2965                 return 0;
2966         }
2967         if (mvtype >= MWL_NUM_TX_QUEUES) {
2968                 device_printf(sc->sc_dev, "mvtype %u out of range, max %u!\n",
2969                         mvtype, MWL_NUM_TX_QUEUES);
2970                 return 0;
2971         }
2972         txq = &sc->sc_txq[mvtype];
2973         mwl_txq_init(sc, txq, mvtype);
2974         sc->sc_ac2q[ac] = txq;
2975         return 1;
2976 #undef N
2977 }
2978
2979 /*
2980  * Update WME parameters for a transmit queue.
2981  */
2982 static int
2983 mwl_txq_update(struct mwl_softc *sc, int ac)
2984 {
2985 #define MWL_EXPONENT_TO_VALUE(v)        ((1<<v)-1)
2986         struct ifnet *ifp = sc->sc_ifp;
2987         struct ieee80211com *ic = ifp->if_l2com;
2988         struct mwl_txq *txq = sc->sc_ac2q[ac];
2989         struct wmeParams *wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[ac];
2990         struct mwl_hal *mh = sc->sc_mh;
2991         int aifs, cwmin, cwmax, txoplim;
2992
2993         aifs = wmep->wmep_aifsn;
2994         /* XXX in sta mode need to pass log values for cwmin/max */
2995         cwmin = MWL_EXPONENT_TO_VALUE(wmep->wmep_logcwmin);
2996         cwmax = MWL_EXPONENT_TO_VALUE(wmep->wmep_logcwmax);
2997         txoplim = wmep->wmep_txopLimit;         /* NB: units of 32us */
2998
2999         if (mwl_hal_setedcaparams(mh, txq->qnum, cwmin, cwmax, aifs, txoplim)) {
3000                 device_printf(sc->sc_dev, "unable to update hardware queue "
3001                         "parameters for %s traffic!\n",
3002                         ieee80211_wme_acnames[ac]);
3003                 return 0;
3004         }
3005         return 1;
3006 #undef MWL_EXPONENT_TO_VALUE
3007 }
3008
3009 /*
3010  * Callback from the 802.11 layer to update WME parameters.
3011  */
3012 static int
3013 mwl_wme_update(struct ieee80211com *ic)
3014 {
3015         struct mwl_softc *sc = ic->ic_ifp->if_softc;
3016
3017         return !mwl_txq_update(sc, WME_AC_BE) ||
3018             !mwl_txq_update(sc, WME_AC_BK) ||
3019             !mwl_txq_update(sc, WME_AC_VI) ||
3020             !mwl_txq_update(sc, WME_AC_VO) ? EIO : 0;
3021 }
3022
3023 /*
3024  * Reclaim resources for a setup queue.
3025  */
3026 static void
3027 mwl_tx_cleanupq(struct mwl_softc *sc, struct mwl_txq *txq)
3028 {
3029         /* XXX hal work? */
3030         MWL_TXQ_LOCK_DESTROY(txq);
3031 }
3032
3033 /*
3034  * Reclaim all tx queue resources.
3035  */
3036 static void
3037 mwl_tx_cleanup(struct mwl_softc *sc)
3038 {
3039         int i;
3040
3041         for (i = 0; i < MWL_NUM_TX_QUEUES; i++)
3042                 mwl_tx_cleanupq(sc, &sc->sc_txq[i]);
3043 }
3044
3045 static int
3046 mwl_tx_dmasetup(struct mwl_softc *sc, struct mwl_txbuf *bf, struct mbuf *m0)
3047 {
3048         struct mbuf *m;
3049         int error;
3050
3051         /*
3052          * Load the DMA map so any coalescing is done.  This
3053          * also calculates the number of descriptors we need.
3054          */
3055         error = bus_dmamap_load_mbuf_sg(sc->sc_dmat, bf->bf_dmamap, m0,
3056                                      bf->bf_segs, &bf->bf_nseg,
3057                                      BUS_DMA_NOWAIT);
3058         if (error == EFBIG) {
3059                 /* XXX packet requires too many descriptors */
3060                 bf->bf_nseg = MWL_TXDESC+1;
3061         } else if (error != 0) {
3062                 sc->sc_stats.mst_tx_busdma++;
3063                 m_freem(m0);
3064                 return error;
3065         }
3066         /*
3067          * Discard null packets and check for packets that
3068          * require too many TX descriptors.  We try to convert
3069          * the latter to a cluster.
3070          */
3071         if (error == EFBIG) {           /* too many desc's, linearize */
3072                 sc->sc_stats.mst_tx_linear++;
3073 #if MWL_TXDESC > 1
3074                 m = m_collapse(m0, M_DONTWAIT, MWL_TXDESC);
3075 #else
3076                 m = m_defrag(m0, M_DONTWAIT);
3077 #endif
3078                 if (m == NULL) {
3079                         m_freem(m0);
3080                         sc->sc_stats.mst_tx_nombuf++;
3081                         return ENOMEM;
3082                 }
3083                 m0 = m;
3084                 error = bus_dmamap_load_mbuf_sg(sc->sc_dmat, bf->bf_dmamap, m0,
3085                                              bf->bf_segs, &bf->bf_nseg,
3086                                              BUS_DMA_NOWAIT);
3087                 if (error != 0) {
3088                         sc->sc_stats.mst_tx_busdma++;
3089                         m_freem(m0);
3090                         return error;
3091                 }
3092                 KASSERT(bf->bf_nseg <= MWL_TXDESC,
3093                     ("too many segments after defrag; nseg %u", bf->bf_nseg));
3094         } else if (bf->bf_nseg == 0) {          /* null packet, discard */
3095                 sc->sc_stats.mst_tx_nodata++;
3096                 m_freem(m0);
3097                 return EIO;
3098         }
3099         DPRINTF(sc, MWL_DEBUG_XMIT, "%s: m %p len %u\n",
3100                 __func__, m0, m0->m_pkthdr.len);
3101         bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap, BUS_DMASYNC_PREWRITE);
3102         bf->bf_m = m0;
3103
3104         return 0;
3105 }
3106
3107 static __inline int
3108 mwl_cvtlegacyrate(int rate)
3109 {
3110         switch (rate) {
3111         case 2:  return 0;
3112         case 4:  return 1;
3113         case 11: return 2;
3114         case 22: return 3;
3115         case 44: return 4;
3116         case 12: return 5;
3117         case 18: return 6;
3118         case 24: return 7;
3119         case 36: return 8;
3120         case 48: return 9;
3121         case 72: return 10;
3122         case 96: return 11;
3123         case 108:return 12;
3124         }
3125         return 0;
3126 }
3127
3128 /*
3129  * Calculate fixed tx rate information per client state;
3130  * this value is suitable for writing to the Format field
3131  * of a tx descriptor.
3132  */
3133 static uint16_t
3134 mwl_calcformat(uint8_t rate, const struct ieee80211_node *ni)
3135 {
3136         uint16_t fmt;
3137
3138         fmt = SM(3, EAGLE_TXD_ANTENNA)
3139             | (IEEE80211_IS_CHAN_HT40D(ni->ni_chan) ?
3140                 EAGLE_TXD_EXTCHAN_LO : EAGLE_TXD_EXTCHAN_HI);
3141         if (rate & IEEE80211_RATE_MCS) {        /* HT MCS */
3142                 fmt |= EAGLE_TXD_FORMAT_HT
3143                     /* NB: 0x80 implicitly stripped from ucastrate */
3144                     | SM(rate, EAGLE_TXD_RATE);
3145                 /* XXX short/long GI may be wrong; re-check */
3146                 if (IEEE80211_IS_CHAN_HT40(ni->ni_chan)) {
3147                         fmt |= EAGLE_TXD_CHW_40
3148                             | (ni->ni_htcap & IEEE80211_HTCAP_SHORTGI40 ?
3149                                 EAGLE_TXD_GI_SHORT : EAGLE_TXD_GI_LONG);
3150                 } else {
3151                         fmt |= EAGLE_TXD_CHW_20
3152                             | (ni->ni_htcap & IEEE80211_HTCAP_SHORTGI20 ?
3153                                 EAGLE_TXD_GI_SHORT : EAGLE_TXD_GI_LONG);
3154                 }
3155         } else {                        /* legacy rate */
3156                 fmt |= EAGLE_TXD_FORMAT_LEGACY
3157                     | SM(mwl_cvtlegacyrate(rate), EAGLE_TXD_RATE)
3158                     | EAGLE_TXD_CHW_20
3159                     /* XXX iv_flags & IEEE80211_F_SHPREAMBLE? */
3160                     | (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE ?
3161                         EAGLE_TXD_PREAMBLE_SHORT : EAGLE_TXD_PREAMBLE_LONG);
3162         }
3163         return fmt;
3164 }
3165
3166 static int
3167 mwl_tx_start(struct mwl_softc *sc, struct ieee80211_node *ni, struct mwl_txbuf *bf,
3168     struct mbuf *m0)
3169 {
3170 #define IEEE80211_DIR_DSTODS(wh) \
3171         ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS)
3172         struct ifnet *ifp = sc->sc_ifp;
3173         struct ieee80211com *ic = ifp->if_l2com;
3174         struct ieee80211vap *vap = ni->ni_vap;
3175         int error, iswep, ismcast;
3176         int hdrlen, copyhdrlen, pktlen;
3177         struct mwl_txdesc *ds;
3178         struct mwl_txq *txq;
3179         struct ieee80211_frame *wh;
3180         struct mwltxrec *tr;
3181         struct mwl_node *mn;
3182         uint16_t qos;
3183 #if MWL_TXDESC > 1
3184         int i;
3185 #endif
3186
3187         wh = mtod(m0, struct ieee80211_frame *);
3188         iswep = wh->i_fc[1] & IEEE80211_FC1_WEP;
3189         ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
3190         hdrlen = ieee80211_anyhdrsize(wh);
3191         copyhdrlen = hdrlen;
3192         pktlen = m0->m_pkthdr.len;
3193         if (IEEE80211_QOS_HAS_SEQ(wh)) {
3194                 if (IEEE80211_DIR_DSTODS(wh)) {
3195                         qos = *(uint16_t *)
3196                             (((struct ieee80211_qosframe_addr4 *) wh)->i_qos);
3197                         copyhdrlen -= sizeof(qos);
3198                 } else
3199                         qos = *(uint16_t *)
3200                             (((struct ieee80211_qosframe *) wh)->i_qos);
3201         } else
3202                 qos = 0;
3203
3204         if (iswep) {
3205                 const struct ieee80211_cipher *cip;
3206                 struct ieee80211_key *k;
3207
3208                 /*
3209                  * Construct the 802.11 header+trailer for an encrypted
3210                  * frame. The only reason this can fail is because of an
3211                  * unknown or unsupported cipher/key type.
3212                  *
3213                  * NB: we do this even though the firmware will ignore
3214                  *     what we've done for WEP and TKIP as we need the
3215                  *     ExtIV filled in for CCMP and this also adjusts
3216                  *     the headers which simplifies our work below.
3217                  */
3218                 k = ieee80211_crypto_encap(ni, m0);
3219                 if (k == NULL) {
3220                         /*
3221                          * This can happen when the key is yanked after the
3222                          * frame was queued.  Just discard the frame; the
3223                          * 802.11 layer counts failures and provides
3224                          * debugging/diagnostics.
3225                          */
3226                         m_freem(m0);
3227                         return EIO;
3228                 }
3229                 /*
3230                  * Adjust the packet length for the crypto additions
3231                  * done during encap and any other bits that the f/w
3232                  * will add later on.
3233                  */
3234                 cip = k->wk_cipher;
3235                 pktlen += cip->ic_header + cip->ic_miclen + cip->ic_trailer;
3236
3237                 /* packet header may have moved, reset our local pointer */
3238                 wh = mtod(m0, struct ieee80211_frame *);
3239         }
3240
3241         if (ieee80211_radiotap_active_vap(vap)) {
3242                 sc->sc_tx_th.wt_flags = 0;      /* XXX */
3243                 if (iswep)
3244                         sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
3245 #if 0
3246                 sc->sc_tx_th.wt_rate = ds->DataRate;
3247 #endif
3248                 sc->sc_tx_th.wt_txpower = ni->ni_txpower;
3249                 sc->sc_tx_th.wt_antenna = sc->sc_txantenna;
3250
3251                 ieee80211_radiotap_tx(vap, m0);
3252         }
3253         /*
3254          * Copy up/down the 802.11 header; the firmware requires
3255          * we present a 2-byte payload length followed by a
3256          * 4-address header (w/o QoS), followed (optionally) by
3257          * any WEP/ExtIV header (but only filled in for CCMP).
3258          * We are assured the mbuf has sufficient headroom to
3259          * prepend in-place by the setup of ic_headroom in
3260          * mwl_attach.
3261          */
3262         if (hdrlen < sizeof(struct mwltxrec)) {
3263                 const int space = sizeof(struct mwltxrec) - hdrlen;
3264                 if (M_LEADINGSPACE(m0) < space) {
3265                         /* NB: should never happen */
3266                         device_printf(sc->sc_dev,
3267                             "not enough headroom, need %d found %zd, "
3268                             "m_flags 0x%x m_len %d\n",
3269                             space, M_LEADINGSPACE(m0), m0->m_flags, m0->m_len);
3270                         ieee80211_dump_pkt(ic,
3271                             mtod(m0, const uint8_t *), m0->m_len, 0, -1);
3272                         m_freem(m0);
3273                         sc->sc_stats.mst_tx_noheadroom++;
3274                         return EIO;
3275                 }
3276                 M_PREPEND(m0, space, M_NOWAIT);
3277         }
3278         tr = mtod(m0, struct mwltxrec *);
3279         if (wh != (struct ieee80211_frame *) &tr->wh)
3280                 ovbcopy(wh, &tr->wh, hdrlen);
3281         /*
3282          * Note: the "firmware length" is actually the length
3283          * of the fully formed "802.11 payload".  That is, it's
3284          * everything except for the 802.11 header.  In particular
3285          * this includes all crypto material including the MIC!
3286          */
3287         tr->fwlen = htole16(pktlen - hdrlen);
3288
3289         /*
3290          * Load the DMA map so any coalescing is done.  This
3291          * also calculates the number of descriptors we need.
3292          */
3293         error = mwl_tx_dmasetup(sc, bf, m0);
3294         if (error != 0) {
3295                 /* NB: stat collected in mwl_tx_dmasetup */
3296                 DPRINTF(sc, MWL_DEBUG_XMIT,
3297                     "%s: unable to setup dma\n", __func__);
3298                 return error;
3299         }
3300         bf->bf_node = ni;                       /* NB: held reference */
3301         m0 = bf->bf_m;                          /* NB: may have changed */
3302         tr = mtod(m0, struct mwltxrec *);
3303         wh = (struct ieee80211_frame *)&tr->wh;
3304
3305         /*
3306          * Formulate tx descriptor.
3307          */
3308         ds = bf->bf_desc;
3309         txq = bf->bf_txq;
3310
3311         ds->QosCtrl = qos;                      /* NB: already little-endian */
3312 #if MWL_TXDESC == 1
3313         /*
3314          * NB: multiframes should be zero because the descriptors
3315          *     are initialized to zero.  This should handle the case
3316          *     where the driver is built with MWL_TXDESC=1 but we are
3317          *     using firmware with multi-segment support.
3318          */
3319         ds->PktPtr = htole32(bf->bf_segs[0].ds_addr);
3320         ds->PktLen = htole16(bf->bf_segs[0].ds_len);
3321 #else
3322         ds->multiframes = htole32(bf->bf_nseg);
3323         ds->PktLen = htole16(m0->m_pkthdr.len);
3324         for (i = 0; i < bf->bf_nseg; i++) {
3325                 ds->PktPtrArray[i] = htole32(bf->bf_segs[i].ds_addr);
3326                 ds->PktLenArray[i] = htole16(bf->bf_segs[i].ds_len);
3327         }
3328 #endif
3329         /* NB: pPhysNext, DataRate, and SapPktInfo setup once, don't touch */
3330         ds->Format = 0;
3331         ds->pad = 0;
3332         ds->ack_wcb_addr = 0;
3333
3334         mn = MWL_NODE(ni);
3335         /*
3336          * Select transmit rate.
3337          */
3338         switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) {
3339         case IEEE80211_FC0_TYPE_MGT:
3340                 sc->sc_stats.mst_tx_mgmt++;
3341                 /* fall thru... */
3342         case IEEE80211_FC0_TYPE_CTL:
3343                 /* NB: assign to BE q to avoid bursting */
3344                 ds->TxPriority = MWL_WME_AC_BE;
3345                 break;
3346         case IEEE80211_FC0_TYPE_DATA:
3347                 if (!ismcast) {
3348                         const struct ieee80211_txparam *tp = ni->ni_txparms;
3349                         /*
3350                          * EAPOL frames get forced to a fixed rate and w/o
3351                          * aggregation; otherwise check for any fixed rate
3352                          * for the client (may depend on association state).
3353                          */
3354                         if (m0->m_flags & M_EAPOL) {
3355                                 const struct mwl_vap *mvp = MWL_VAP_CONST(vap);
3356                                 ds->Format = mvp->mv_eapolformat;
3357                                 ds->pad = htole16(
3358                                     EAGLE_TXD_FIXED_RATE | EAGLE_TXD_DONT_AGGR);
3359                         } else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) {
3360                                 /* XXX pre-calculate per node */
3361                                 ds->Format = htole16(
3362                                     mwl_calcformat(tp->ucastrate, ni));
3363                                 ds->pad = htole16(EAGLE_TXD_FIXED_RATE);
3364                         }
3365                         /* NB: EAPOL frames will never have qos set */
3366                         if (qos == 0)
3367                                 ds->TxPriority = txq->qnum;
3368 #if MWL_MAXBA > 3
3369                         else if (mwl_bastream_match(&mn->mn_ba[3], qos))
3370                                 ds->TxPriority = mn->mn_ba[3].txq;
3371 #endif
3372 #if MWL_MAXBA > 2
3373                         else if (mwl_bastream_match(&mn->mn_ba[2], qos))
3374                                 ds->TxPriority = mn->mn_ba[2].txq;
3375 #endif
3376 #if MWL_MAXBA > 1
3377                         else if (mwl_bastream_match(&mn->mn_ba[1], qos))
3378                                 ds->TxPriority = mn->mn_ba[1].txq;
3379 #endif
3380 #if MWL_MAXBA > 0
3381                         else if (mwl_bastream_match(&mn->mn_ba[0], qos))
3382                                 ds->TxPriority = mn->mn_ba[0].txq;
3383 #endif
3384                         else
3385                                 ds->TxPriority = txq->qnum;
3386                 } else
3387                         ds->TxPriority = txq->qnum;
3388                 break;
3389         default:
3390                 if_printf(ifp, "bogus frame type 0x%x (%s)\n",
3391                         wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK, __func__);
3392                 sc->sc_stats.mst_tx_badframetype++;
3393                 m_freem(m0);
3394                 return EIO;
3395         }
3396
3397         if (IFF_DUMPPKTS_XMIT(sc))
3398                 ieee80211_dump_pkt(ic,
3399                     mtod(m0, const uint8_t *)+sizeof(uint16_t),
3400                     m0->m_len - sizeof(uint16_t), ds->DataRate, -1);
3401
3402         MWL_TXQ_LOCK(txq);
3403         ds->Status = htole32(EAGLE_TXD_STATUS_FW_OWNED);
3404         STAILQ_INSERT_TAIL(&txq->active, bf, bf_list);
3405         MWL_TXDESC_SYNC(txq, ds, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
3406
3407         ifp->if_opackets++;
3408         ifp->if_timer = 5;
3409         MWL_TXQ_UNLOCK(txq);
3410
3411         return 0;
3412 #undef  IEEE80211_DIR_DSTODS
3413 }
3414
3415 static __inline int
3416 mwl_cvtlegacyrix(int rix)
3417 {
3418 #define N(x)    (sizeof(x)/sizeof(x[0]))
3419         static const int ieeerates[] =
3420             { 2, 4, 11, 22, 44, 12, 18, 24, 36, 48, 72, 96, 108 };
3421         return (rix < N(ieeerates) ? ieeerates[rix] : 0);
3422 #undef N
3423 }
3424
3425 /*
3426  * Process completed xmit descriptors from the specified queue.
3427  */
3428 static int
3429 mwl_tx_processq(struct mwl_softc *sc, struct mwl_txq *txq)
3430 {
3431 #define EAGLE_TXD_STATUS_MCAST \
3432         (EAGLE_TXD_STATUS_MULTICAST_TX | EAGLE_TXD_STATUS_BROADCAST_TX)
3433         struct ifnet *ifp = sc->sc_ifp;
3434         struct ieee80211com *ic = ifp->if_l2com;
3435         struct mwl_txbuf *bf;
3436         struct mwl_txdesc *ds;
3437         struct ieee80211_node *ni;
3438         struct mwl_node *an;
3439         int nreaped;
3440         uint32_t status;
3441
3442         DPRINTF(sc, MWL_DEBUG_TX_PROC, "%s: tx queue %u\n", __func__, txq->qnum);
3443         for (nreaped = 0;; nreaped++) {
3444                 MWL_TXQ_LOCK(txq);
3445                 bf = STAILQ_FIRST(&txq->active);
3446                 if (bf == NULL) {
3447                         MWL_TXQ_UNLOCK(txq);
3448                         break;
3449                 }
3450                 ds = bf->bf_desc;
3451                 MWL_TXDESC_SYNC(txq, ds,
3452                     BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
3453                 if (ds->Status & htole32(EAGLE_TXD_STATUS_FW_OWNED)) {
3454                         MWL_TXQ_UNLOCK(txq);
3455                         break;
3456                 }
3457                 STAILQ_REMOVE_HEAD(&txq->active, bf_list);
3458                 MWL_TXQ_UNLOCK(txq);
3459
3460 #ifdef MWL_DEBUG
3461                 if (sc->sc_debug & MWL_DEBUG_XMIT_DESC)
3462                         mwl_printtxbuf(bf, txq->qnum, nreaped);
3463 #endif
3464                 ni = bf->bf_node;
3465                 if (ni != NULL) {
3466                         an = MWL_NODE(ni);
3467                         status = le32toh(ds->Status);
3468                         if (status & EAGLE_TXD_STATUS_OK) {
3469                                 uint16_t Format = le16toh(ds->Format);
3470                                 uint8_t txant = MS(Format, EAGLE_TXD_ANTENNA);
3471
3472                                 sc->sc_stats.mst_ant_tx[txant]++;
3473                                 if (status & EAGLE_TXD_STATUS_OK_RETRY)
3474                                         sc->sc_stats.mst_tx_retries++;
3475                                 if (status & EAGLE_TXD_STATUS_OK_MORE_RETRY)
3476                                         sc->sc_stats.mst_tx_mretries++;
3477                                 if (txq->qnum >= MWL_WME_AC_VO)
3478                                         ic->ic_wme.wme_hipri_traffic++;
3479                                 ni->ni_txrate = MS(Format, EAGLE_TXD_RATE);
3480                                 if ((Format & EAGLE_TXD_FORMAT_HT) == 0) {
3481                                         ni->ni_txrate = mwl_cvtlegacyrix(
3482                                             ni->ni_txrate);
3483                                 } else
3484                                         ni->ni_txrate |= IEEE80211_RATE_MCS;
3485                                 sc->sc_stats.mst_tx_rate = ni->ni_txrate;
3486                         } else {
3487                                 if (status & EAGLE_TXD_STATUS_FAILED_LINK_ERROR)
3488                                         sc->sc_stats.mst_tx_linkerror++;
3489                                 if (status & EAGLE_TXD_STATUS_FAILED_XRETRY)
3490                                         sc->sc_stats.mst_tx_xretries++;
3491                                 if (status & EAGLE_TXD_STATUS_FAILED_AGING)
3492                                         sc->sc_stats.mst_tx_aging++;
3493                                 if (bf->bf_m->m_flags & M_FF)
3494                                         sc->sc_stats.mst_ff_txerr++;
3495                         }
3496                         /*
3497                          * Do any tx complete callback.  Note this must
3498                          * be done before releasing the node reference.
3499                          * XXX no way to figure out if frame was ACK'd
3500                          */
3501                         if (bf->bf_m->m_flags & M_TXCB) {
3502                                 /* XXX strip fw len in case header inspected */
3503                                 m_adj(bf->bf_m, sizeof(uint16_t));
3504                                 ieee80211_process_callback(ni, bf->bf_m,
3505                                         (status & EAGLE_TXD_STATUS_OK) == 0);
3506                         }
3507                         /*
3508                          * Reclaim reference to node.
3509                          *
3510                          * NB: the node may be reclaimed here if, for example
3511                          *     this is a DEAUTH message that was sent and the
3512                          *     node was timed out due to inactivity.
3513                          */
3514                         ieee80211_free_node(ni);
3515                 }
3516                 ds->Status = htole32(EAGLE_TXD_STATUS_IDLE);
3517
3518                 bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap,
3519                     BUS_DMASYNC_POSTWRITE);
3520                 bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap);
3521                 m_freem(bf->bf_m);
3522
3523                 mwl_puttxbuf_tail(txq, bf);
3524         }
3525         return nreaped;
3526 #undef EAGLE_TXD_STATUS_MCAST
3527 }
3528
3529 /*
3530  * Deferred processing of transmit interrupt; special-cased
3531  * for four hardware queues, 0-3.
3532  */
3533 static void
3534 mwl_tx_proc(void *arg, int npending)
3535 {
3536         struct mwl_softc *sc = arg;
3537         struct ifnet *ifp = sc->sc_ifp;
3538         int nreaped;
3539
3540         /*
3541          * Process each active queue.
3542          */
3543         nreaped = 0;
3544         if (!STAILQ_EMPTY(&sc->sc_txq[0].active))
3545                 nreaped += mwl_tx_processq(sc, &sc->sc_txq[0]);
3546         if (!STAILQ_EMPTY(&sc->sc_txq[1].active))
3547                 nreaped += mwl_tx_processq(sc, &sc->sc_txq[1]);
3548         if (!STAILQ_EMPTY(&sc->sc_txq[2].active))
3549                 nreaped += mwl_tx_processq(sc, &sc->sc_txq[2]);
3550         if (!STAILQ_EMPTY(&sc->sc_txq[3].active))
3551                 nreaped += mwl_tx_processq(sc, &sc->sc_txq[3]);
3552
3553         if (nreaped != 0) {
3554                 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
3555                 ifp->if_timer = 0;
3556                 if (!IFQ_IS_EMPTY(&ifp->if_snd)) {
3557                         /* NB: kick fw; the tx thread may have been preempted */
3558                         mwl_hal_txstart(sc->sc_mh, 0);
3559                         mwl_start(ifp);
3560                 }
3561         }
3562 }
3563
3564 static void
3565 mwl_tx_draintxq(struct mwl_softc *sc, struct mwl_txq *txq)
3566 {
3567         struct ieee80211_node *ni;
3568         struct mwl_txbuf *bf;
3569         u_int ix;
3570
3571         /*
3572          * NB: this assumes output has been stopped and
3573          *     we do not need to block mwl_tx_tasklet
3574          */
3575         for (ix = 0;; ix++) {
3576                 MWL_TXQ_LOCK(txq);
3577                 bf = STAILQ_FIRST(&txq->active);
3578                 if (bf == NULL) {
3579                         MWL_TXQ_UNLOCK(txq);
3580                         break;
3581                 }
3582                 STAILQ_REMOVE_HEAD(&txq->active, bf_list);
3583                 MWL_TXQ_UNLOCK(txq);
3584 #ifdef MWL_DEBUG
3585                 if (sc->sc_debug & MWL_DEBUG_RESET) {
3586                         struct ifnet *ifp = sc->sc_ifp;
3587                         struct ieee80211com *ic = ifp->if_l2com;
3588                         const struct mwltxrec *tr =
3589                             mtod(bf->bf_m, const struct mwltxrec *);
3590                         mwl_printtxbuf(bf, txq->qnum, ix);
3591                         ieee80211_dump_pkt(ic, (const uint8_t *)&tr->wh,
3592                                 bf->bf_m->m_len - sizeof(tr->fwlen), 0, -1);
3593                 }
3594 #endif /* MWL_DEBUG */
3595                 bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap);
3596                 ni = bf->bf_node;
3597                 if (ni != NULL) {
3598                         /*
3599                          * Reclaim node reference.
3600                          */
3601                         ieee80211_free_node(ni);
3602                 }
3603                 m_freem(bf->bf_m);
3604
3605                 mwl_puttxbuf_tail(txq, bf);
3606         }
3607 }
3608
3609 /*
3610  * Drain the transmit queues and reclaim resources.
3611  */
3612 static void
3613 mwl_draintxq(struct mwl_softc *sc)
3614 {
3615         struct ifnet *ifp = sc->sc_ifp;
3616         int i;
3617
3618         for (i = 0; i < MWL_NUM_TX_QUEUES; i++)
3619                 mwl_tx_draintxq(sc, &sc->sc_txq[i]);
3620         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
3621         ifp->if_timer = 0;
3622 }
3623
3624 #ifdef MWL_DIAGAPI
3625 /*
3626  * Reset the transmit queues to a pristine state after a fw download.
3627  */
3628 static void
3629 mwl_resettxq(struct mwl_softc *sc)
3630 {
3631         int i;
3632
3633         for (i = 0; i < MWL_NUM_TX_QUEUES; i++)
3634                 mwl_txq_reset(sc, &sc->sc_txq[i]);
3635 }
3636 #endif /* MWL_DIAGAPI */
3637
3638 /*
3639  * Clear the transmit queues of any frames submitted for the
3640  * specified vap.  This is done when the vap is deleted so we
3641  * don't potentially reference the vap after it is gone.
3642  * Note we cannot remove the frames; we only reclaim the node
3643  * reference.
3644  */
3645 static void
3646 mwl_cleartxq(struct mwl_softc *sc, struct ieee80211vap *vap)
3647 {
3648         struct mwl_txq *txq;
3649         struct mwl_txbuf *bf;
3650         int i;
3651
3652         for (i = 0; i < MWL_NUM_TX_QUEUES; i++) {
3653                 txq = &sc->sc_txq[i];
3654                 MWL_TXQ_LOCK(txq);
3655                 STAILQ_FOREACH(bf, &txq->active, bf_list) {
3656                         struct ieee80211_node *ni = bf->bf_node;
3657                         if (ni != NULL && ni->ni_vap == vap) {
3658                                 bf->bf_node = NULL;
3659                                 ieee80211_free_node(ni);
3660                         }
3661                 }
3662                 MWL_TXQ_UNLOCK(txq);
3663         }
3664 }
3665
3666 static int
3667 mwl_recv_action(struct ieee80211_node *ni, const struct ieee80211_frame *wh,
3668         const uint8_t *frm, const uint8_t *efrm)
3669 {
3670         struct mwl_softc *sc = ni->ni_ic->ic_ifp->if_softc;
3671         const struct ieee80211_action *ia;
3672
3673         ia = (const struct ieee80211_action *) frm;
3674         if (ia->ia_category == IEEE80211_ACTION_CAT_HT &&
3675             ia->ia_action == IEEE80211_ACTION_HT_MIMOPWRSAVE) {
3676                 const struct ieee80211_action_ht_mimopowersave *mps =
3677                     (const struct ieee80211_action_ht_mimopowersave *) ia;
3678
3679                 mwl_hal_setmimops(sc->sc_mh, ni->ni_macaddr,
3680                     mps->am_control & IEEE80211_A_HT_MIMOPWRSAVE_ENA,
3681                     MS(mps->am_control, IEEE80211_A_HT_MIMOPWRSAVE_MODE));
3682                 return 0;
3683         } else
3684                 return sc->sc_recv_action(ni, wh, frm, efrm);
3685 }
3686
3687 static int
3688 mwl_addba_request(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
3689         int dialogtoken, int baparamset, int batimeout)
3690 {
3691         struct mwl_softc *sc = ni->ni_ic->ic_ifp->if_softc;
3692         struct ieee80211vap *vap = ni->ni_vap;
3693         struct mwl_node *mn = MWL_NODE(ni);
3694         struct mwl_bastate *bas;
3695
3696         bas = tap->txa_private;
3697         if (bas == NULL) {
3698                 const MWL_HAL_BASTREAM *sp;
3699                 /*
3700                  * Check for a free BA stream slot.
3701                  */
3702 #if MWL_MAXBA > 3
3703                 if (mn->mn_ba[3].bastream == NULL)
3704                         bas = &mn->mn_ba[3];
3705                 else
3706 #endif
3707 #if MWL_MAXBA > 2
3708                 if (mn->mn_ba[2].bastream == NULL)
3709                         bas = &mn->mn_ba[2];
3710                 else
3711 #endif
3712 #if MWL_MAXBA > 1
3713                 if (mn->mn_ba[1].bastream == NULL)
3714                         bas = &mn->mn_ba[1];
3715                 else
3716 #endif
3717 #if MWL_MAXBA > 0
3718                 if (mn->mn_ba[0].bastream == NULL)
3719                         bas = &mn->mn_ba[0];
3720                 else 
3721 #endif
3722                 {
3723                         /* sta already has max BA streams */
3724                         /* XXX assign BA stream to highest priority tid */
3725                         DPRINTF(sc, MWL_DEBUG_AMPDU,
3726                             "%s: already has max bastreams\n", __func__);
3727                         sc->sc_stats.mst_ampdu_reject++;
3728                         return 0;
3729                 }
3730                 /* NB: no held reference to ni */
3731                 sp = mwl_hal_bastream_alloc(MWL_VAP(vap)->mv_hvap,
3732                     (baparamset & IEEE80211_BAPS_POLICY_IMMEDIATE) != 0,
3733                     ni->ni_macaddr, WME_AC_TO_TID(tap->txa_ac), ni->ni_htparam,
3734                     ni, tap);
3735                 if (sp == NULL) {
3736                         /*
3737                          * No available stream, return 0 so no
3738                          * a-mpdu aggregation will be done.
3739                          */
3740                         DPRINTF(sc, MWL_DEBUG_AMPDU,
3741                             "%s: no bastream available\n", __func__);
3742                         sc->sc_stats.mst_ampdu_nostream++;
3743                         return 0;
3744                 }
3745                 DPRINTF(sc, MWL_DEBUG_AMPDU, "%s: alloc bastream %p\n",
3746                     __func__, sp);
3747                 /* NB: qos is left zero so we won't match in mwl_tx_start */
3748                 bas->bastream = sp;
3749                 tap->txa_private = bas;
3750         }
3751         /* fetch current seq# from the firmware; if available */
3752         if (mwl_hal_bastream_get_seqno(sc->sc_mh, bas->bastream,
3753             vap->iv_opmode == IEEE80211_M_STA ? vap->iv_myaddr : ni->ni_macaddr,
3754             &tap->txa_start) != 0)
3755                 tap->txa_start = 0;
3756         return sc->sc_addba_request(ni, tap, dialogtoken, baparamset, batimeout);
3757 }
3758
3759 static int
3760 mwl_addba_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
3761         int code, int baparamset, int batimeout)
3762 {
3763         struct mwl_softc *sc = ni->ni_ic->ic_ifp->if_softc;
3764         struct mwl_bastate *bas;
3765
3766         bas = tap->txa_private;
3767         if (bas == NULL) {
3768                 /* XXX should not happen */
3769                 DPRINTF(sc, MWL_DEBUG_AMPDU,
3770                     "%s: no BA stream allocated, AC %d\n",
3771                     __func__, tap->txa_ac);
3772                 sc->sc_stats.mst_addba_nostream++;
3773                 return 0;
3774         }
3775         if (code == IEEE80211_STATUS_SUCCESS) {
3776                 struct ieee80211vap *vap = ni->ni_vap;
3777                 int bufsiz, error;
3778
3779                 /*
3780                  * Tell the firmware to setup the BA stream;
3781                  * we know resources are available because we
3782                  * pre-allocated one before forming the request.
3783                  */
3784                 bufsiz = MS(baparamset, IEEE80211_BAPS_BUFSIZ);
3785                 if (bufsiz == 0)
3786                         bufsiz = IEEE80211_AGGR_BAWMAX;
3787                 error = mwl_hal_bastream_create(MWL_VAP(vap)->mv_hvap,
3788                     bas->bastream, bufsiz, bufsiz, tap->txa_start);
3789                 if (error != 0) {
3790                         /*
3791                          * Setup failed, return immediately so no a-mpdu
3792                          * aggregation will be done.
3793                          */
3794                         mwl_hal_bastream_destroy(sc->sc_mh, bas->bastream);
3795                         mwl_bastream_free(bas);
3796                         tap->txa_private = NULL;
3797
3798                         DPRINTF(sc, MWL_DEBUG_AMPDU,
3799                             "%s: create failed, error %d, bufsiz %d AC %d "
3800                             "htparam 0x%x\n", __func__, error, bufsiz,
3801                             tap->txa_ac, ni->ni_htparam);
3802                         sc->sc_stats.mst_bacreate_failed++;
3803                         return 0;
3804                 }
3805                 /* NB: cache txq to avoid ptr indirect */
3806                 mwl_bastream_setup(bas, tap->txa_ac, bas->bastream->txq);
3807                 DPRINTF(sc, MWL_DEBUG_AMPDU,
3808                     "%s: bastream %p assigned to txq %d AC %d bufsiz %d "
3809                     "htparam 0x%x\n", __func__, bas->bastream,
3810                     bas->txq, tap->txa_ac, bufsiz, ni->ni_htparam);
3811         } else {
3812                 /*
3813                  * Other side NAK'd us; return the resources.
3814                  */
3815                 DPRINTF(sc, MWL_DEBUG_AMPDU,
3816                     "%s: request failed with code %d, destroy bastream %p\n",
3817                     __func__, code, bas->bastream);
3818                 mwl_hal_bastream_destroy(sc->sc_mh, bas->bastream);
3819                 mwl_bastream_free(bas);
3820                 tap->txa_private = NULL;
3821         }
3822         /* NB: firmware sends BAR so we don't need to */
3823         return sc->sc_addba_response(ni, tap, code, baparamset, batimeout);
3824 }
3825
3826 static void
3827 mwl_addba_stop(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap)
3828 {
3829         struct mwl_softc *sc = ni->ni_ic->ic_ifp->if_softc;
3830         struct mwl_bastate *bas;
3831
3832         bas = tap->txa_private;
3833         if (bas != NULL) {
3834                 DPRINTF(sc, MWL_DEBUG_AMPDU, "%s: destroy bastream %p\n",
3835                     __func__, bas->bastream);
3836                 mwl_hal_bastream_destroy(sc->sc_mh, bas->bastream);
3837                 mwl_bastream_free(bas);
3838                 tap->txa_private = NULL;
3839         }
3840         sc->sc_addba_stop(ni, tap);
3841 }
3842
3843 /*
3844  * Setup the rx data structures.  This should only be
3845  * done once or we may get out of sync with the firmware.
3846  */
3847 static int
3848 mwl_startrecv(struct mwl_softc *sc)
3849 {
3850         if (!sc->sc_recvsetup) {
3851                 struct mwl_rxbuf *bf, *prev;
3852                 struct mwl_rxdesc *ds;
3853
3854                 prev = NULL;
3855                 STAILQ_FOREACH(bf, &sc->sc_rxbuf, bf_list) {
3856                         int error = mwl_rxbuf_init(sc, bf);
3857                         if (error != 0) {
3858                                 DPRINTF(sc, MWL_DEBUG_RECV,
3859                                         "%s: mwl_rxbuf_init failed %d\n",
3860                                         __func__, error);
3861                                 return error;
3862                         }
3863                         if (prev != NULL) {
3864                                 ds = prev->bf_desc;
3865                                 ds->pPhysNext = htole32(bf->bf_daddr);
3866                         }
3867                         prev = bf;
3868                 }
3869                 if (prev != NULL) {
3870                         ds = prev->bf_desc;
3871                         ds->pPhysNext =
3872                             htole32(STAILQ_FIRST(&sc->sc_rxbuf)->bf_daddr);
3873                 }
3874                 sc->sc_recvsetup = 1;
3875         }
3876         mwl_mode_init(sc);              /* set filters, etc. */
3877         return 0;
3878 }
3879
3880 static MWL_HAL_APMODE
3881 mwl_getapmode(const struct ieee80211vap *vap, struct ieee80211_channel *chan)
3882 {
3883         MWL_HAL_APMODE mode;
3884
3885         if (IEEE80211_IS_CHAN_HT(chan)) {
3886                 if (vap->iv_flags_ht & IEEE80211_FHT_PUREN)
3887                         mode = AP_MODE_N_ONLY;
3888                 else if (IEEE80211_IS_CHAN_5GHZ(chan))
3889                         mode = AP_MODE_AandN;
3890                 else if (vap->iv_flags & IEEE80211_F_PUREG)
3891                         mode = AP_MODE_GandN;
3892                 else
3893                         mode = AP_MODE_BandGandN;
3894         } else if (IEEE80211_IS_CHAN_ANYG(chan)) {
3895                 if (vap->iv_flags & IEEE80211_F_PUREG)
3896                         mode = AP_MODE_G_ONLY;
3897                 else
3898                         mode = AP_MODE_MIXED;
3899         } else if (IEEE80211_IS_CHAN_B(chan))
3900                 mode = AP_MODE_B_ONLY;
3901         else if (IEEE80211_IS_CHAN_A(chan))
3902                 mode = AP_MODE_A_ONLY;
3903         else
3904                 mode = AP_MODE_MIXED;           /* XXX should not happen? */
3905         return mode;
3906 }
3907
3908 static int
3909 mwl_setapmode(struct ieee80211vap *vap, struct ieee80211_channel *chan)
3910 {
3911         struct mwl_hal_vap *hvap = MWL_VAP(vap)->mv_hvap;
3912         return mwl_hal_setapmode(hvap, mwl_getapmode(vap, chan));
3913 }
3914
3915 /*
3916  * Set/change channels.
3917  */
3918 static int
3919 mwl_chan_set(struct mwl_softc *sc, struct ieee80211_channel *chan)
3920 {
3921         struct mwl_hal *mh = sc->sc_mh;
3922         struct ifnet *ifp = sc->sc_ifp;
3923         struct ieee80211com *ic = ifp->if_l2com;
3924         MWL_HAL_CHANNEL hchan;
3925         int maxtxpow;
3926
3927         DPRINTF(sc, MWL_DEBUG_RESET, "%s: chan %u MHz/flags 0x%x\n",
3928             __func__, chan->ic_freq, chan->ic_flags);
3929
3930         /*
3931          * Convert to a HAL channel description with
3932          * the flags constrained to reflect the current
3933          * operating mode.
3934          */
3935         mwl_mapchan(&hchan, chan);
3936         mwl_hal_intrset(mh, 0);         /* disable interrupts */
3937 #if 0
3938         mwl_draintxq(sc);               /* clear pending tx frames */
3939 #endif
3940         mwl_hal_setchannel(mh, &hchan);
3941         /*
3942          * Tx power is cap'd by the regulatory setting and
3943          * possibly a user-set limit.  We pass the min of
3944          * these to the hal to apply them to the cal data
3945          * for this channel.
3946          * XXX min bound?
3947          */
3948         maxtxpow = 2*chan->ic_maxregpower;
3949         if (maxtxpow > ic->ic_txpowlimit)
3950                 maxtxpow = ic->ic_txpowlimit;
3951         mwl_hal_settxpower(mh, &hchan, maxtxpow / 2);
3952         /* NB: potentially change mcast/mgt rates */
3953         mwl_setcurchanrates(sc);
3954
3955         /*
3956          * Update internal state.
3957          */
3958         sc->sc_tx_th.wt_chan_freq = htole16(chan->ic_freq);
3959         sc->sc_rx_th.wr_chan_freq = htole16(chan->ic_freq);
3960         if (IEEE80211_IS_CHAN_A(chan)) {
3961                 sc->sc_tx_th.wt_chan_flags = htole16(IEEE80211_CHAN_A);
3962                 sc->sc_rx_th.wr_chan_flags = htole16(IEEE80211_CHAN_A);
3963         } else if (IEEE80211_IS_CHAN_ANYG(chan)) {
3964                 sc->sc_tx_th.wt_chan_flags = htole16(IEEE80211_CHAN_G);
3965                 sc->sc_rx_th.wr_chan_flags = htole16(IEEE80211_CHAN_G);
3966         } else {
3967                 sc->sc_tx_th.wt_chan_flags = htole16(IEEE80211_CHAN_B);
3968                 sc->sc_rx_th.wr_chan_flags = htole16(IEEE80211_CHAN_B);
3969         }
3970         sc->sc_curchan = hchan;
3971         mwl_hal_intrset(mh, sc->sc_imask);
3972
3973         return 0;
3974 }
3975
3976 static void
3977 mwl_scan_start(struct ieee80211com *ic)
3978 {
3979         struct ifnet *ifp = ic->ic_ifp;
3980         struct mwl_softc *sc = ifp->if_softc;
3981
3982         DPRINTF(sc, MWL_DEBUG_STATE, "%s\n", __func__);
3983 }
3984
3985 static void
3986 mwl_scan_end(struct ieee80211com *ic)
3987 {
3988         struct ifnet *ifp = ic->ic_ifp;
3989         struct mwl_softc *sc = ifp->if_softc;
3990
3991         DPRINTF(sc, MWL_DEBUG_STATE, "%s\n", __func__);
3992 }
3993
3994 static void
3995 mwl_set_channel(struct ieee80211com *ic)
3996 {
3997         struct ifnet *ifp = ic->ic_ifp;
3998         struct mwl_softc *sc = ifp->if_softc;
3999
4000         (void) mwl_chan_set(sc, ic->ic_curchan);
4001 }
4002
4003 /* 
4004  * Handle a channel switch request.  We inform the firmware
4005  * and mark the global state to suppress various actions.
4006  * NB: we issue only one request to the fw; we may be called
4007  * multiple times if there are multiple vap's.
4008  */
4009 static void
4010 mwl_startcsa(struct ieee80211vap *vap)
4011 {
4012         struct ieee80211com *ic = vap->iv_ic;
4013         struct mwl_softc *sc = ic->ic_ifp->if_softc;
4014         MWL_HAL_CHANNEL hchan;
4015
4016         if (sc->sc_csapending)
4017                 return;
4018
4019         mwl_mapchan(&hchan, ic->ic_csa_newchan);
4020         /* 1 =>'s quiet channel */
4021         mwl_hal_setchannelswitchie(sc->sc_mh, &hchan, 1, ic->ic_csa_count);
4022         sc->sc_csapending = 1;
4023 }
4024
4025 /*
4026  * Plumb any static WEP key for the station.  This is
4027  * necessary as we must propagate the key from the
4028  * global key table of the vap to each sta db entry.
4029  */
4030 static void
4031 mwl_setanywepkey(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
4032 {
4033         if ((vap->iv_flags & (IEEE80211_F_PRIVACY|IEEE80211_F_WPA)) ==
4034                 IEEE80211_F_PRIVACY &&
4035             vap->iv_def_txkey != IEEE80211_KEYIX_NONE &&
4036             vap->iv_nw_keys[vap->iv_def_txkey].wk_keyix != IEEE80211_KEYIX_NONE)
4037                 (void) mwl_key_set(vap, &vap->iv_nw_keys[vap->iv_def_txkey], mac);
4038 }
4039
4040 static int
4041 mwl_peerstadb(struct ieee80211_node *ni, int aid, int staid, MWL_HAL_PEERINFO *pi)
4042 {
4043 #define WME(ie) ((const struct ieee80211_wme_info *) ie)
4044         struct ieee80211vap *vap = ni->ni_vap;
4045         struct mwl_hal_vap *hvap;
4046         int error;
4047
4048         if (vap->iv_opmode == IEEE80211_M_WDS) {
4049                 /*
4050                  * WDS vap's do not have a f/w vap; instead they piggyback
4051                  * on an AP vap and we must install the sta db entry and
4052                  * crypto state using that AP's handle (the WDS vap has none).
4053                  */
4054                 hvap = MWL_VAP(vap)->mv_ap_hvap;
4055         } else
4056                 hvap = MWL_VAP(vap)->mv_hvap;
4057         error = mwl_hal_newstation(hvap, ni->ni_macaddr,
4058             aid, staid, pi,
4059             ni->ni_flags & (IEEE80211_NODE_QOS | IEEE80211_NODE_HT),
4060             ni->ni_ies.wme_ie != NULL ? WME(ni->ni_ies.wme_ie)->wme_info : 0);
4061         if (error == 0) {
4062                 /*
4063                  * Setup security for this station.  For sta mode this is
4064                  * needed even though do the same thing on transition to
4065                  * AUTH state because the call to mwl_hal_newstation
4066                  * clobbers the crypto state we setup.
4067                  */
4068                 mwl_setanywepkey(vap, ni->ni_macaddr);
4069         }
4070         return error;
4071 #undef WME
4072 }
4073
4074 static void
4075 mwl_setglobalkeys(struct ieee80211vap *vap)
4076 {
4077         struct ieee80211_key *wk;
4078
4079         wk = &vap->iv_nw_keys[0];
4080         for (; wk < &vap->iv_nw_keys[IEEE80211_WEP_NKID]; wk++)
4081                 if (wk->wk_keyix != IEEE80211_KEYIX_NONE)
4082                         (void) mwl_key_set(vap, wk, vap->iv_myaddr);
4083 }
4084
4085 /*
4086  * Convert a legacy rate set to a firmware bitmask.
4087  */
4088 static uint32_t
4089 get_rate_bitmap(const struct ieee80211_rateset *rs)
4090 {
4091         uint32_t rates;
4092         int i;
4093
4094         rates = 0;
4095         for (i = 0; i < rs->rs_nrates; i++)
4096                 switch (rs->rs_rates[i] & IEEE80211_RATE_VAL) {
4097                 case 2:   rates |= 0x001; break;
4098                 case 4:   rates |= 0x002; break;
4099                 case 11:  rates |= 0x004; break;
4100                 case 22:  rates |= 0x008; break;
4101                 case 44:  rates |= 0x010; break;
4102                 case 12:  rates |= 0x020; break;
4103                 case 18:  rates |= 0x040; break;
4104                 case 24:  rates |= 0x080; break;
4105                 case 36:  rates |= 0x100; break;
4106                 case 48:  rates |= 0x200; break;
4107                 case 72:  rates |= 0x400; break;
4108                 case 96:  rates |= 0x800; break;
4109                 case 108: rates |= 0x1000; break;
4110                 }
4111         return rates;
4112 }
4113
4114 /*
4115  * Construct an HT firmware bitmask from an HT rate set.
4116  */
4117 static uint32_t
4118 get_htrate_bitmap(const struct ieee80211_htrateset *rs)
4119 {
4120         uint32_t rates;
4121         int i;
4122
4123         rates = 0;
4124         for (i = 0; i < rs->rs_nrates; i++) {
4125                 if (rs->rs_rates[i] < 16)
4126                         rates |= 1<<rs->rs_rates[i];
4127         }
4128         return rates;
4129 }
4130
4131 /*
4132  * Craft station database entry for station.
4133  * NB: use host byte order here, the hal handles byte swapping.
4134  */
4135 static MWL_HAL_PEERINFO *
4136 mkpeerinfo(MWL_HAL_PEERINFO *pi, const struct ieee80211_node *ni)
4137 {
4138         const struct ieee80211vap *vap = ni->ni_vap;
4139
4140         memset(pi, 0, sizeof(*pi));
4141         pi->LegacyRateBitMap = get_rate_bitmap(&ni->ni_rates);
4142         pi->CapInfo = ni->ni_capinfo;
4143         if (ni->ni_flags & IEEE80211_NODE_HT) {
4144                 /* HT capabilities, etc */
4145                 pi->HTCapabilitiesInfo = ni->ni_htcap;
4146                 /* XXX pi.HTCapabilitiesInfo */
4147                 pi->MacHTParamInfo = ni->ni_htparam;    
4148                 pi->HTRateBitMap = get_htrate_bitmap(&ni->ni_htrates);
4149                 pi->AddHtInfo.ControlChan = ni->ni_htctlchan;
4150                 pi->AddHtInfo.AddChan = ni->ni_ht2ndchan;
4151                 pi->AddHtInfo.OpMode = ni->ni_htopmode;
4152                 pi->AddHtInfo.stbc = ni->ni_htstbc;
4153
4154                 /* constrain according to local configuration */
4155                 if ((vap->iv_flags_ht & IEEE80211_FHT_SHORTGI40) == 0)
4156                         pi->HTCapabilitiesInfo &= ~IEEE80211_HTCAP_SHORTGI40;
4157                 if ((vap->iv_flags_ht & IEEE80211_FHT_SHORTGI20) == 0)
4158                         pi->HTCapabilitiesInfo &= ~IEEE80211_HTCAP_SHORTGI20;
4159                 if (ni->ni_chw != 40)
4160                         pi->HTCapabilitiesInfo &= ~IEEE80211_HTCAP_CHWIDTH40;
4161         }
4162         return pi;
4163 }
4164
4165 /*
4166  * Re-create the local sta db entry for a vap to ensure
4167  * up to date WME state is pushed to the firmware.  Because
4168  * this resets crypto state this must be followed by a
4169  * reload of any keys in the global key table.
4170  */
4171 static int
4172 mwl_localstadb(struct ieee80211vap *vap)
4173 {
4174 #define WME(ie) ((const struct ieee80211_wme_info *) ie)
4175         struct mwl_hal_vap *hvap = MWL_VAP(vap)->mv_hvap;
4176         struct ieee80211_node *bss;
4177         MWL_HAL_PEERINFO pi;
4178         int error;
4179
4180         switch (vap->iv_opmode) {
4181         case IEEE80211_M_STA:
4182                 bss = vap->iv_bss;
4183                 error = mwl_hal_newstation(hvap, vap->iv_myaddr, 0, 0,
4184                     vap->iv_state == IEEE80211_S_RUN ?
4185                         mkpeerinfo(&pi, bss) : NULL,
4186                     (bss->ni_flags & (IEEE80211_NODE_QOS | IEEE80211_NODE_HT)),
4187                     bss->ni_ies.wme_ie != NULL ?
4188                         WME(bss->ni_ies.wme_ie)->wme_info : 0);
4189                 if (error == 0)
4190                         mwl_setglobalkeys(vap);
4191                 break;
4192         case IEEE80211_M_HOSTAP:
4193         case IEEE80211_M_MBSS:
4194                 error = mwl_hal_newstation(hvap, vap->iv_myaddr,
4195                     0, 0, NULL, vap->iv_flags & IEEE80211_F_WME, 0);
4196                 if (error == 0)
4197                         mwl_setglobalkeys(vap);
4198                 break;
4199         default:
4200                 error = 0;
4201                 break;
4202         }
4203         return error;
4204 #undef WME
4205 }
4206
4207 static int
4208 mwl_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
4209 {
4210         struct mwl_vap *mvp = MWL_VAP(vap);
4211         struct mwl_hal_vap *hvap = mvp->mv_hvap;
4212         struct ieee80211com *ic = vap->iv_ic;
4213         struct ieee80211_node *ni = NULL;
4214         struct ifnet *ifp = ic->ic_ifp;
4215         struct mwl_softc *sc = ifp->if_softc;
4216         struct mwl_hal *mh = sc->sc_mh;
4217         enum ieee80211_state ostate = vap->iv_state;
4218         int error;
4219
4220         DPRINTF(sc, MWL_DEBUG_STATE, "%s: %s: %s -> %s\n",
4221             vap->iv_ifp->if_xname, __func__,
4222             ieee80211_state_name[ostate], ieee80211_state_name[nstate]);
4223
4224         callout_stop(&sc->sc_timer);
4225         /*
4226          * Clear current radar detection state.
4227          */
4228         if (ostate == IEEE80211_S_CAC) {
4229                 /* stop quiet mode radar detection */
4230                 mwl_hal_setradardetection(mh, DR_CHK_CHANNEL_AVAILABLE_STOP);
4231         } else if (sc->sc_radarena) {
4232                 /* stop in-service radar detection */
4233                 mwl_hal_setradardetection(mh, DR_DFS_DISABLE);
4234                 sc->sc_radarena = 0;
4235         }
4236         /*
4237          * Carry out per-state actions before doing net80211 work.
4238          */
4239         if (nstate == IEEE80211_S_INIT) {
4240                 /* NB: only ap+sta vap's have a fw entity */
4241                 if (hvap != NULL)
4242                         mwl_hal_stop(hvap);
4243         } else if (nstate == IEEE80211_S_SCAN) {
4244                 mwl_hal_start(hvap);
4245                 /* NB: this disables beacon frames */
4246                 mwl_hal_setinframode(hvap);
4247         } else if (nstate == IEEE80211_S_AUTH) {
4248                 /*
4249                  * Must create a sta db entry in case a WEP key needs to
4250                  * be plumbed.  This entry will be overwritten if we
4251                  * associate; otherwise it will be reclaimed on node free.
4252                  */
4253                 ni = vap->iv_bss;
4254                 MWL_NODE(ni)->mn_hvap = hvap;
4255                 (void) mwl_peerstadb(ni, 0, 0, NULL);
4256         } else if (nstate == IEEE80211_S_CSA) {
4257                 /* XXX move to below? */
4258                 if (vap->iv_opmode == IEEE80211_M_HOSTAP ||
4259                     vap->iv_opmode == IEEE80211_M_MBSS)
4260                         mwl_startcsa(vap);
4261         } else if (nstate == IEEE80211_S_CAC) {
4262                 /* XXX move to below? */
4263                 /* stop ap xmit and enable quiet mode radar detection */
4264                 mwl_hal_setradardetection(mh, DR_CHK_CHANNEL_AVAILABLE_START);
4265         }
4266
4267         /*
4268          * Invoke the parent method to do net80211 work.
4269          */
4270         error = mvp->mv_newstate(vap, nstate, arg);
4271
4272         /*
4273          * Carry out work that must be done after net80211 runs;
4274          * this work requires up to date state (e.g. iv_bss).
4275          */
4276         if (error == 0 && nstate == IEEE80211_S_RUN) {
4277                 /* NB: collect bss node again, it may have changed */
4278                 ni = vap->iv_bss;
4279
4280                 DPRINTF(sc, MWL_DEBUG_STATE,
4281                     "%s: %s(RUN): iv_flags 0x%08x bintvl %d bssid %s "
4282                     "capinfo 0x%04x chan %d\n",
4283                     vap->iv_ifp->if_xname, __func__, vap->iv_flags,
4284                     ni->ni_intval, ether_sprintf(ni->ni_bssid), ni->ni_capinfo,
4285                     ieee80211_chan2ieee(ic, ic->ic_curchan));
4286
4287                 /*
4288                  * Recreate local sta db entry to update WME/HT state.
4289                  */
4290                 mwl_localstadb(vap);
4291                 switch (vap->iv_opmode) {
4292                 case IEEE80211_M_HOSTAP:
4293                 case IEEE80211_M_MBSS:
4294                         if (ostate == IEEE80211_S_CAC) {
4295                                 /* enable in-service radar detection */
4296                                 mwl_hal_setradardetection(mh,
4297                                     DR_IN_SERVICE_MONITOR_START);
4298                                 sc->sc_radarena = 1;
4299                         }
4300                         /*
4301                          * Allocate and setup the beacon frame
4302                          * (and related state).
4303                          */
4304                         error = mwl_reset_vap(vap, IEEE80211_S_RUN);
4305                         if (error != 0) {
4306                                 DPRINTF(sc, MWL_DEBUG_STATE,
4307                                     "%s: beacon setup failed, error %d\n",
4308                                     __func__, error);
4309                                 goto bad;
4310                         }
4311                         /* NB: must be after setting up beacon */
4312                         mwl_hal_start(hvap);
4313                         break;
4314                 case IEEE80211_M_STA:
4315                         DPRINTF(sc, MWL_DEBUG_STATE, "%s: %s: aid 0x%x\n",
4316                             vap->iv_ifp->if_xname, __func__, ni->ni_associd);
4317                         /*
4318                          * Set state now that we're associated.
4319                          */
4320                         mwl_hal_setassocid(hvap, ni->ni_bssid, ni->ni_associd);
4321                         mwl_setrates(vap);
4322                         mwl_hal_setrtsthreshold(hvap, vap->iv_rtsthreshold);
4323                         if ((vap->iv_flags & IEEE80211_F_DWDS) &&
4324                             sc->sc_ndwdsvaps++ == 0)
4325                                 mwl_hal_setdwds(mh, 1);
4326                         break;
4327                 case IEEE80211_M_WDS:
4328                         DPRINTF(sc, MWL_DEBUG_STATE, "%s: %s: bssid %s\n",
4329                             vap->iv_ifp->if_xname, __func__,
4330                             ether_sprintf(ni->ni_bssid));
4331                         mwl_seteapolformat(vap);
4332                         break;
4333                 default:
4334                         break;
4335                 }
4336                 /*
4337                  * Set CS mode according to operating channel;
4338                  * this mostly an optimization for 5GHz.
4339                  *
4340                  * NB: must follow mwl_hal_start which resets csmode
4341                  */
4342                 if (IEEE80211_IS_CHAN_5GHZ(ic->ic_bsschan))
4343                         mwl_hal_setcsmode(mh, CSMODE_AGGRESSIVE);
4344                 else
4345                         mwl_hal_setcsmode(mh, CSMODE_AUTO_ENA);
4346                 /*
4347                  * Start timer to prod firmware.
4348                  */
4349                 if (sc->sc_ageinterval != 0)
4350                         callout_reset(&sc->sc_timer, sc->sc_ageinterval*hz,
4351                             mwl_agestations, sc);
4352         } else if (nstate == IEEE80211_S_SLEEP) {
4353                 /* XXX set chip in power save */
4354         } else if ((vap->iv_flags & IEEE80211_F_DWDS) &&
4355             --sc->sc_ndwdsvaps == 0)
4356                 mwl_hal_setdwds(mh, 0);
4357 bad:
4358         return error;
4359 }
4360
4361 /*
4362  * Manage station id's; these are separate from AID's
4363  * as AID's may have values out of the range of possible
4364  * station id's acceptable to the firmware.
4365  */
4366 static int
4367 allocstaid(struct mwl_softc *sc, int aid)
4368 {
4369         int staid;
4370
4371         if (!(0 < aid && aid < MWL_MAXSTAID) || isset(sc->sc_staid, aid)) {
4372                 /* NB: don't use 0 */
4373                 for (staid = 1; staid < MWL_MAXSTAID; staid++)
4374                         if (isclr(sc->sc_staid, staid))
4375                                 break;
4376         } else
4377                 staid = aid;
4378         setbit(sc->sc_staid, staid);
4379         return staid;
4380 }
4381
4382 static void
4383 delstaid(struct mwl_softc *sc, int staid)
4384 {
4385         clrbit(sc->sc_staid, staid);
4386 }
4387
4388 /*
4389  * Setup driver-specific state for a newly associated node.
4390  * Note that we're called also on a re-associate, the isnew
4391  * param tells us if this is the first time or not.
4392  */
4393 static void
4394 mwl_newassoc(struct ieee80211_node *ni, int isnew)
4395 {
4396         struct ieee80211vap *vap = ni->ni_vap;
4397         struct mwl_softc *sc = vap->iv_ic->ic_ifp->if_softc;
4398         struct mwl_node *mn = MWL_NODE(ni);
4399         MWL_HAL_PEERINFO pi;
4400         uint16_t aid;
4401         int error;
4402
4403         aid = IEEE80211_AID(ni->ni_associd);
4404         if (isnew) {
4405                 mn->mn_staid = allocstaid(sc, aid);
4406                 mn->mn_hvap = MWL_VAP(vap)->mv_hvap;
4407         } else {
4408                 mn = MWL_NODE(ni);
4409                 /* XXX reset BA stream? */
4410         }
4411         DPRINTF(sc, MWL_DEBUG_NODE, "%s: mac %s isnew %d aid %d staid %d\n",
4412             __func__, ether_sprintf(ni->ni_macaddr), isnew, aid, mn->mn_staid);
4413         error = mwl_peerstadb(ni, aid, mn->mn_staid, mkpeerinfo(&pi, ni));
4414         if (error != 0) {
4415                 DPRINTF(sc, MWL_DEBUG_NODE,
4416                     "%s: error %d creating sta db entry\n",
4417                     __func__, error);
4418                 /* XXX how to deal with error? */
4419         }
4420 }
4421
4422 /*
4423  * Periodically poke the firmware to age out station state
4424  * (power save queues, pending tx aggregates).
4425  */
4426 static void
4427 mwl_agestations(void *arg)
4428 {
4429         struct mwl_softc *sc = arg;
4430
4431         mwl_hal_setkeepalive(sc->sc_mh);
4432         if (sc->sc_ageinterval != 0)            /* NB: catch dynamic changes */
4433                 callout_schedule(&sc->sc_timer, sc->sc_ageinterval*hz);
4434 }
4435
4436 static const struct mwl_hal_channel *
4437 findhalchannel(const MWL_HAL_CHANNELINFO *ci, int ieee)
4438 {
4439         int i;
4440
4441         for (i = 0; i < ci->nchannels; i++) {
4442                 const struct mwl_hal_channel *hc = &ci->channels[i];
4443                 if (hc->ieee == ieee)
4444                         return hc;
4445         }
4446         return NULL;
4447 }
4448
4449 static int
4450 mwl_setregdomain(struct ieee80211com *ic, struct ieee80211_regdomain *rd,
4451         int nchan, struct ieee80211_channel chans[])
4452 {
4453         struct mwl_softc *sc = ic->ic_ifp->if_softc;
4454         struct mwl_hal *mh = sc->sc_mh;
4455         const MWL_HAL_CHANNELINFO *ci;
4456         int i;
4457
4458         for (i = 0; i < nchan; i++) {
4459                 struct ieee80211_channel *c = &chans[i];
4460                 const struct mwl_hal_channel *hc;
4461
4462                 if (IEEE80211_IS_CHAN_2GHZ(c)) {
4463                         mwl_hal_getchannelinfo(mh, MWL_FREQ_BAND_2DOT4GHZ,
4464                             IEEE80211_IS_CHAN_HT40(c) ?
4465                                 MWL_CH_40_MHz_WIDTH : MWL_CH_20_MHz_WIDTH, &ci);
4466                 } else if (IEEE80211_IS_CHAN_5GHZ(c)) {
4467                         mwl_hal_getchannelinfo(mh, MWL_FREQ_BAND_5GHZ,
4468                             IEEE80211_IS_CHAN_HT40(c) ?
4469                                 MWL_CH_40_MHz_WIDTH : MWL_CH_20_MHz_WIDTH, &ci);
4470                 } else {
4471                         if_printf(ic->ic_ifp,
4472                             "%s: channel %u freq %u/0x%x not 2.4/5GHz\n",
4473                             __func__, c->ic_ieee, c->ic_freq, c->ic_flags);
4474                         return EINVAL;
4475                 }
4476                 /* 
4477                  * Verify channel has cal data and cap tx power.
4478                  */
4479                 hc = findhalchannel(ci, c->ic_ieee);
4480                 if (hc != NULL) {
4481                         if (c->ic_maxpower > 2*hc->maxTxPow)
4482                                 c->ic_maxpower = 2*hc->maxTxPow;
4483                         goto next;
4484                 }
4485                 if (IEEE80211_IS_CHAN_HT40(c)) {
4486                         /*
4487                          * Look for the extension channel since the
4488                          * hal table only has the primary channel.
4489                          */
4490                         hc = findhalchannel(ci, c->ic_extieee);
4491                         if (hc != NULL) {
4492                                 if (c->ic_maxpower > 2*hc->maxTxPow)
4493                                         c->ic_maxpower = 2*hc->maxTxPow;
4494                                 goto next;
4495                         }
4496                 }
4497                 if_printf(ic->ic_ifp,
4498                     "%s: no cal data for channel %u ext %u freq %u/0x%x\n",
4499                     __func__, c->ic_ieee, c->ic_extieee,
4500                     c->ic_freq, c->ic_flags);
4501                 return EINVAL;
4502         next:
4503                 ;
4504         }
4505         return 0;
4506 }
4507
4508 #define IEEE80211_CHAN_HTG      (IEEE80211_CHAN_HT|IEEE80211_CHAN_G)
4509 #define IEEE80211_CHAN_HTA      (IEEE80211_CHAN_HT|IEEE80211_CHAN_A)
4510
4511 static void
4512 addchan(struct ieee80211_channel *c, int freq, int flags, int ieee, int txpow)
4513 {
4514         c->ic_freq = freq;
4515         c->ic_flags = flags;
4516         c->ic_ieee = ieee;
4517         c->ic_minpower = 0;
4518         c->ic_maxpower = 2*txpow;
4519         c->ic_maxregpower = txpow;
4520 }
4521
4522 static const struct ieee80211_channel *
4523 findchannel(const struct ieee80211_channel chans[], int nchans,
4524         int freq, int flags)
4525 {
4526         const struct ieee80211_channel *c;
4527         int i;
4528
4529         for (i = 0; i < nchans; i++) {
4530                 c = &chans[i];
4531                 if (c->ic_freq == freq && c->ic_flags == flags)
4532                         return c;
4533         }
4534         return NULL;
4535 }
4536
4537 static void
4538 addht40channels(struct ieee80211_channel chans[], int maxchans, int *nchans,
4539         const MWL_HAL_CHANNELINFO *ci, int flags)
4540 {
4541         struct ieee80211_channel *c;
4542         const struct ieee80211_channel *extc;
4543         const struct mwl_hal_channel *hc;
4544         int i;
4545
4546         c = &chans[*nchans];
4547
4548         flags &= ~IEEE80211_CHAN_HT;
4549         for (i = 0; i < ci->nchannels; i++) {
4550                 /*
4551                  * Each entry defines an HT40 channel pair; find the
4552                  * extension channel above and the insert the pair.
4553                  */
4554                 hc = &ci->channels[i];
4555                 extc = findchannel(chans, *nchans, hc->freq+20,
4556                     flags | IEEE80211_CHAN_HT20);
4557                 if (extc != NULL) {
4558                         if (*nchans >= maxchans)
4559                                 break;
4560                         addchan(c, hc->freq, flags | IEEE80211_CHAN_HT40U,
4561                             hc->ieee, hc->maxTxPow);
4562                         c->ic_extieee = extc->ic_ieee;
4563                         c++, (*nchans)++;
4564                         if (*nchans >= maxchans)
4565                                 break;
4566                         addchan(c, extc->ic_freq, flags | IEEE80211_CHAN_HT40D,
4567                             extc->ic_ieee, hc->maxTxPow);
4568                         c->ic_extieee = hc->ieee;
4569                         c++, (*nchans)++;
4570                 }
4571         }
4572 }
4573
4574 static void
4575 addchannels(struct ieee80211_channel chans[], int maxchans, int *nchans,
4576         const MWL_HAL_CHANNELINFO *ci, int flags)
4577 {
4578         struct ieee80211_channel *c;
4579         int i;
4580
4581         c = &chans[*nchans];
4582
4583         for (i = 0; i < ci->nchannels; i++) {
4584                 const struct mwl_hal_channel *hc;
4585
4586                 hc = &ci->channels[i];
4587                 if (*nchans >= maxchans)
4588                         break;
4589                 addchan(c, hc->freq, flags, hc->ieee, hc->maxTxPow);
4590                 c++, (*nchans)++;
4591                 if (flags == IEEE80211_CHAN_G || flags == IEEE80211_CHAN_HTG) {
4592                         /* g channel have a separate b-only entry */
4593                         if (*nchans >= maxchans)
4594                                 break;
4595                         c[0] = c[-1];
4596                         c[-1].ic_flags = IEEE80211_CHAN_B;
4597                         c++, (*nchans)++;
4598                 }
4599                 if (flags == IEEE80211_CHAN_HTG) {
4600                         /* HT g channel have a separate g-only entry */
4601                         if (*nchans >= maxchans)
4602                                 break;
4603                         c[-1].ic_flags = IEEE80211_CHAN_G;
4604                         c[0] = c[-1];
4605                         c[0].ic_flags &= ~IEEE80211_CHAN_HT;
4606                         c[0].ic_flags |= IEEE80211_CHAN_HT20;   /* HT20 */
4607                         c++, (*nchans)++;
4608                 }
4609                 if (flags == IEEE80211_CHAN_HTA) {
4610                         /* HT a channel have a separate a-only entry */
4611                         if (*nchans >= maxchans)
4612                                 break;
4613                         c[-1].ic_flags = IEEE80211_CHAN_A;
4614                         c[0] = c[-1];
4615                         c[0].ic_flags &= ~IEEE80211_CHAN_HT;
4616                         c[0].ic_flags |= IEEE80211_CHAN_HT20;   /* HT20 */
4617                         c++, (*nchans)++;
4618                 }
4619         }
4620 }
4621
4622 static void
4623 getchannels(struct mwl_softc *sc, int maxchans, int *nchans,
4624         struct ieee80211_channel chans[])
4625 {
4626         const MWL_HAL_CHANNELINFO *ci;
4627
4628         /*
4629          * Use the channel info from the hal to craft the
4630          * channel list.  Note that we pass back an unsorted
4631          * list; the caller is required to sort it for us
4632          * (if desired).
4633          */
4634         *nchans = 0;
4635         if (mwl_hal_getchannelinfo(sc->sc_mh,
4636             MWL_FREQ_BAND_2DOT4GHZ, MWL_CH_20_MHz_WIDTH, &ci) == 0)
4637                 addchannels(chans, maxchans, nchans, ci, IEEE80211_CHAN_HTG);
4638         if (mwl_hal_getchannelinfo(sc->sc_mh,
4639             MWL_FREQ_BAND_5GHZ, MWL_CH_20_MHz_WIDTH, &ci) == 0)
4640                 addchannels(chans, maxchans, nchans, ci, IEEE80211_CHAN_HTA);
4641         if (mwl_hal_getchannelinfo(sc->sc_mh,
4642             MWL_FREQ_BAND_2DOT4GHZ, MWL_CH_40_MHz_WIDTH, &ci) == 0)
4643                 addht40channels(chans, maxchans, nchans, ci, IEEE80211_CHAN_HTG);
4644         if (mwl_hal_getchannelinfo(sc->sc_mh,
4645             MWL_FREQ_BAND_5GHZ, MWL_CH_40_MHz_WIDTH, &ci) == 0)
4646                 addht40channels(chans, maxchans, nchans, ci, IEEE80211_CHAN_HTA);
4647 }
4648
4649 static void
4650 mwl_getradiocaps(struct ieee80211com *ic,
4651         int maxchans, int *nchans, struct ieee80211_channel chans[])
4652 {
4653         struct mwl_softc *sc = ic->ic_ifp->if_softc;
4654
4655         getchannels(sc, maxchans, nchans, chans);
4656 }
4657
4658 static int
4659 mwl_getchannels(struct mwl_softc *sc)
4660 {
4661         struct ifnet *ifp = sc->sc_ifp;
4662         struct ieee80211com *ic = ifp->if_l2com;
4663
4664         /*
4665          * Use the channel info from the hal to craft the
4666          * channel list for net80211.  Note that we pass up
4667          * an unsorted list; net80211 will sort it for us.
4668          */
4669         memset(ic->ic_channels, 0, sizeof(ic->ic_channels));
4670         ic->ic_nchans = 0;
4671         getchannels(sc, IEEE80211_CHAN_MAX, &ic->ic_nchans, ic->ic_channels);
4672
4673         ic->ic_regdomain.regdomain = SKU_DEBUG;
4674         ic->ic_regdomain.country = CTRY_DEFAULT;
4675         ic->ic_regdomain.location = 'I';
4676         ic->ic_regdomain.isocc[0] = ' ';        /* XXX? */
4677         ic->ic_regdomain.isocc[1] = ' ';
4678         return (ic->ic_nchans == 0 ? EIO : 0);
4679 }
4680 #undef IEEE80211_CHAN_HTA
4681 #undef IEEE80211_CHAN_HTG
4682
4683 #ifdef MWL_DEBUG
4684 static void
4685 mwl_printrxbuf(const struct mwl_rxbuf *bf, u_int ix)
4686 {
4687         const struct mwl_rxdesc *ds = bf->bf_desc;
4688         uint32_t status = le32toh(ds->Status);
4689
4690         printf("R[%2u] (DS.V:%p DS.P:%p) NEXT:%08x DATA:%08x RC:%02x%s\n"
4691                "      STAT:%02x LEN:%04x RSSI:%02x CHAN:%02x RATE:%02x QOS:%04x HT:%04x\n",
4692             ix, ds, (const struct mwl_desc *)bf->bf_daddr,
4693             le32toh(ds->pPhysNext), le32toh(ds->pPhysBuffData),
4694             ds->RxControl, 
4695             ds->RxControl != EAGLE_RXD_CTRL_DRIVER_OWN ?
4696                 "" : (status & EAGLE_RXD_STATUS_OK) ? " *" : " !",
4697             ds->Status, le16toh(ds->PktLen), ds->RSSI, ds->Channel,
4698             ds->Rate, le16toh(ds->QosCtrl), le16toh(ds->HtSig2));
4699 }
4700
4701 static void
4702 mwl_printtxbuf(const struct mwl_txbuf *bf, u_int qnum, u_int ix)
4703 {
4704         const struct mwl_txdesc *ds = bf->bf_desc;
4705         uint32_t status = le32toh(ds->Status);
4706
4707         printf("Q%u[%3u]", qnum, ix);
4708         printf(" (DS.V:%p DS.P:%p)\n",
4709             ds, (const struct mwl_txdesc *)bf->bf_daddr);
4710         printf("    NEXT:%08x DATA:%08x LEN:%04x STAT:%08x%s\n",
4711             le32toh(ds->pPhysNext),
4712             le32toh(ds->PktPtr), le16toh(ds->PktLen), status,
4713             status & EAGLE_TXD_STATUS_USED ?
4714                 "" : (status & 3) != 0 ? " *" : " !");
4715         printf("    RATE:%02x PRI:%x QOS:%04x SAP:%08x FORMAT:%04x\n",
4716             ds->DataRate, ds->TxPriority, le16toh(ds->QosCtrl),
4717             le32toh(ds->SapPktInfo), le16toh(ds->Format));
4718 #if MWL_TXDESC > 1
4719         printf("    MULTIFRAMES:%u LEN:%04x %04x %04x %04x %04x %04x\n"
4720             , le32toh(ds->multiframes)
4721             , le16toh(ds->PktLenArray[0]), le16toh(ds->PktLenArray[1])
4722             , le16toh(ds->PktLenArray[2]), le16toh(ds->PktLenArray[3])
4723             , le16toh(ds->PktLenArray[4]), le16toh(ds->PktLenArray[5])
4724         );
4725         printf("    DATA:%08x %08x %08x %08x %08x %08x\n"
4726             , le32toh(ds->PktPtrArray[0]), le32toh(ds->PktPtrArray[1])
4727             , le32toh(ds->PktPtrArray[2]), le32toh(ds->PktPtrArray[3])
4728             , le32toh(ds->PktPtrArray[4]), le32toh(ds->PktPtrArray[5])
4729         );
4730 #endif
4731 #if 0
4732 { const uint8_t *cp = (const uint8_t *) ds;
4733   int i;
4734   for (i = 0; i < sizeof(struct mwl_txdesc); i++) {
4735         printf("%02x ", cp[i]);
4736         if (((i+1) % 16) == 0)
4737                 printf("\n");
4738   }
4739   printf("\n");
4740 }
4741 #endif
4742 }
4743 #endif /* MWL_DEBUG */
4744
4745 #if 0
4746 static void
4747 mwl_txq_dump(struct mwl_txq *txq)
4748 {
4749         struct mwl_txbuf *bf;
4750         int i = 0;
4751
4752         MWL_TXQ_LOCK(txq);
4753         STAILQ_FOREACH(bf, &txq->active, bf_list) {
4754                 struct mwl_txdesc *ds = bf->bf_desc;
4755                 MWL_TXDESC_SYNC(txq, ds,
4756                     BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
4757 #ifdef MWL_DEBUG
4758                 mwl_printtxbuf(bf, txq->qnum, i);
4759 #endif
4760                 i++;
4761         }
4762         MWL_TXQ_UNLOCK(txq);
4763 }
4764 #endif
4765
4766 static void
4767 mwl_watchdog(struct ifnet *ifp)
4768 {
4769         struct mwl_softc *sc = ifp->if_softc;
4770
4771         if ((ifp->if_drv_flags & IFF_DRV_RUNNING) && !sc->sc_invalid) {
4772                 if (mwl_hal_setkeepalive(sc->sc_mh))
4773                         if_printf(ifp, "transmit timeout (firmware hung?)\n");
4774                 else
4775                         if_printf(ifp, "transmit timeout\n");
4776 #if 0
4777                 mwl_reset(ifp);
4778 mwl_txq_dump(&sc->sc_txq[0]);/*XXX*/
4779 #endif
4780                 ifp->if_oerrors++;
4781                 sc->sc_stats.mst_watchdog++;
4782         }
4783 }
4784
4785 #ifdef MWL_DIAGAPI
4786 /*
4787  * Diagnostic interface to the HAL.  This is used by various
4788  * tools to do things like retrieve register contents for
4789  * debugging.  The mechanism is intentionally opaque so that
4790  * it can change frequently w/o concern for compatiblity.
4791  */
4792 static int
4793 mwl_ioctl_diag(struct mwl_softc *sc, struct mwl_diag *md)
4794 {
4795         struct mwl_hal *mh = sc->sc_mh;
4796         u_int id = md->md_id & MWL_DIAG_ID;
4797         void *indata = NULL;
4798         void *outdata = NULL;
4799         u_int32_t insize = md->md_in_size;
4800         u_int32_t outsize = md->md_out_size;
4801         int error = 0;
4802
4803         if (md->md_id & MWL_DIAG_IN) {
4804                 /*
4805                  * Copy in data.
4806                  */
4807                 indata = malloc(insize, M_TEMP, M_NOWAIT);
4808                 if (indata == NULL) {
4809                         error = ENOMEM;
4810                         goto bad;
4811                 }
4812                 error = copyin(md->md_in_data, indata, insize);
4813                 if (error)
4814                         goto bad;
4815         }
4816         if (md->md_id & MWL_DIAG_DYN) {
4817                 /*
4818                  * Allocate a buffer for the results (otherwise the HAL
4819                  * returns a pointer to a buffer where we can read the
4820                  * results).  Note that we depend on the HAL leaving this
4821                  * pointer for us to use below in reclaiming the buffer;
4822                  * may want to be more defensive.
4823                  */
4824                 outdata = malloc(outsize, M_TEMP, M_NOWAIT);
4825                 if (outdata == NULL) {
4826                         error = ENOMEM;
4827                         goto bad;
4828                 }
4829         }
4830         if (mwl_hal_getdiagstate(mh, id, indata, insize, &outdata, &outsize)) {
4831                 if (outsize < md->md_out_size)
4832                         md->md_out_size = outsize;
4833                 if (outdata != NULL)
4834                         error = copyout(outdata, md->md_out_data,
4835                                         md->md_out_size);
4836         } else {
4837                 error = EINVAL;
4838         }
4839 bad:
4840         if ((md->md_id & MWL_DIAG_IN) && indata != NULL)
4841                 free(indata, M_TEMP);
4842         if ((md->md_id & MWL_DIAG_DYN) && outdata != NULL)
4843                 free(outdata, M_TEMP);
4844         return error;
4845 }
4846
4847 static int
4848 mwl_ioctl_reset(struct mwl_softc *sc, struct mwl_diag *md)
4849 {
4850         struct mwl_hal *mh = sc->sc_mh;
4851         int error;
4852
4853         MWL_LOCK_ASSERT(sc);
4854
4855         if (md->md_id == 0 && mwl_hal_fwload(mh, NULL) != 0) {
4856                 device_printf(sc->sc_dev, "unable to load firmware\n");
4857                 return EIO;
4858         }
4859         if (mwl_hal_gethwspecs(mh, &sc->sc_hwspecs) != 0) {
4860                 device_printf(sc->sc_dev, "unable to fetch h/w specs\n");
4861                 return EIO;
4862         }
4863         error = mwl_setupdma(sc);
4864         if (error != 0) {
4865                 /* NB: mwl_setupdma prints a msg */
4866                 return error;
4867         }
4868         /*
4869          * Reset tx/rx data structures; after reload we must
4870          * re-start the driver's notion of the next xmit/recv.
4871          */
4872         mwl_draintxq(sc);               /* clear pending frames */
4873         mwl_resettxq(sc);               /* rebuild tx q lists */
4874         sc->sc_rxnext = NULL;           /* force rx to start at the list head */
4875         return 0;
4876 }
4877 #endif /* MWL_DIAGAPI */
4878
4879 static int
4880 mwl_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
4881 {
4882 #define IS_RUNNING(ifp) \
4883         ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING))
4884         struct mwl_softc *sc = ifp->if_softc;
4885         struct ieee80211com *ic = ifp->if_l2com;
4886         struct ifreq *ifr = (struct ifreq *)data;
4887         int error = 0, startall;
4888
4889         switch (cmd) {
4890         case SIOCSIFFLAGS:
4891                 MWL_LOCK(sc);
4892                 startall = 0;
4893                 if (IS_RUNNING(ifp)) {
4894                         /*
4895                          * To avoid rescanning another access point,
4896                          * do not call mwl_init() here.  Instead,
4897                          * only reflect promisc mode settings.
4898                          */
4899                         mwl_mode_init(sc);
4900                 } else if (ifp->if_flags & IFF_UP) {
4901                         /*
4902                          * Beware of being called during attach/detach
4903                          * to reset promiscuous mode.  In that case we
4904                          * will still be marked UP but not RUNNING.
4905                          * However trying to re-init the interface
4906                          * is the wrong thing to do as we've already
4907                          * torn down much of our state.  There's
4908                          * probably a better way to deal with this.
4909                          */
4910                         if (!sc->sc_invalid) {
4911                                 mwl_init_locked(sc);    /* XXX lose error */
4912                                 startall = 1;
4913                         }
4914                 } else
4915                         mwl_stop_locked(ifp, 1);
4916                 MWL_UNLOCK(sc);
4917                 if (startall)
4918                         ieee80211_start_all(ic);
4919                 break;
4920         case SIOCGMVSTATS:
4921                 mwl_hal_gethwstats(sc->sc_mh, &sc->sc_stats.hw_stats);
4922                 /* NB: embed these numbers to get a consistent view */
4923                 sc->sc_stats.mst_tx_packets = ifp->if_opackets;
4924                 sc->sc_stats.mst_rx_packets = ifp->if_ipackets;
4925                 /*
4926                  * NB: Drop the softc lock in case of a page fault;
4927                  * we'll accept any potential inconsisentcy in the
4928                  * statistics.  The alternative is to copy the data
4929                  * to a local structure.
4930                  */
4931                 return copyout(&sc->sc_stats,
4932                                 ifr->ifr_data, sizeof (sc->sc_stats));
4933 #ifdef MWL_DIAGAPI
4934         case SIOCGMVDIAG:
4935                 /* XXX check privs */
4936                 return mwl_ioctl_diag(sc, (struct mwl_diag *) ifr);
4937         case SIOCGMVRESET:
4938                 /* XXX check privs */
4939                 MWL_LOCK(sc);
4940                 error = mwl_ioctl_reset(sc,(struct mwl_diag *) ifr); 
4941                 MWL_UNLOCK(sc);
4942                 break;
4943 #endif /* MWL_DIAGAPI */
4944         case SIOCGIFMEDIA:
4945                 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
4946                 break;
4947         case SIOCGIFADDR:
4948                 error = ether_ioctl(ifp, cmd, data);
4949                 break;
4950         default:
4951                 error = EINVAL;
4952                 break;
4953         }
4954         return error;
4955 #undef IS_RUNNING
4956 }
4957
4958 #ifdef  MWL_DEBUG
4959 static int
4960 mwl_sysctl_debug(SYSCTL_HANDLER_ARGS)
4961 {
4962         struct mwl_softc *sc = arg1;
4963         int debug, error;
4964
4965         debug = sc->sc_debug | (mwl_hal_getdebug(sc->sc_mh) << 24);
4966         error = sysctl_handle_int(oidp, &debug, 0, req);
4967         if (error || !req->newptr)
4968                 return error;
4969         mwl_hal_setdebug(sc->sc_mh, debug >> 24);
4970         sc->sc_debug = debug & 0x00ffffff;
4971         return 0;
4972 }
4973 #endif /* MWL_DEBUG */
4974
4975 static void
4976 mwl_sysctlattach(struct mwl_softc *sc)
4977 {
4978 #ifdef  MWL_DEBUG
4979         struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
4980         struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
4981
4982         sc->sc_debug = mwl_debug;
4983         SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
4984                 "debug", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
4985                 mwl_sysctl_debug, "I", "control debugging printfs");
4986 #endif
4987 }
4988
4989 /*
4990  * Announce various information on device/driver attach.
4991  */
4992 static void
4993 mwl_announce(struct mwl_softc *sc)
4994 {
4995         struct ifnet *ifp = sc->sc_ifp;
4996
4997         if_printf(ifp, "Rev A%d hardware, v%d.%d.%d.%d firmware (regioncode %d)\n",
4998                 sc->sc_hwspecs.hwVersion,
4999                 (sc->sc_hwspecs.fwReleaseNumber>>24) & 0xff,
5000                 (sc->sc_hwspecs.fwReleaseNumber>>16) & 0xff,
5001                 (sc->sc_hwspecs.fwReleaseNumber>>8) & 0xff,
5002                 (sc->sc_hwspecs.fwReleaseNumber>>0) & 0xff,
5003                 sc->sc_hwspecs.regionCode);
5004         sc->sc_fwrelease = sc->sc_hwspecs.fwReleaseNumber;
5005
5006         if (bootverbose) {
5007                 int i;
5008                 for (i = 0; i <= WME_AC_VO; i++) {
5009                         struct mwl_txq *txq = sc->sc_ac2q[i];
5010                         if_printf(ifp, "Use hw queue %u for %s traffic\n",
5011                                 txq->qnum, ieee80211_wme_acnames[i]);
5012                 }
5013         }
5014         if (bootverbose || mwl_rxdesc != MWL_RXDESC)
5015                 if_printf(ifp, "using %u rx descriptors\n", mwl_rxdesc);
5016         if (bootverbose || mwl_rxbuf != MWL_RXBUF)
5017                 if_printf(ifp, "using %u rx buffers\n", mwl_rxbuf);
5018         if (bootverbose || mwl_txbuf != MWL_TXBUF)
5019                 if_printf(ifp, "using %u tx buffers\n", mwl_txbuf);
5020         if (bootverbose && mwl_hal_ismbsscapable(sc->sc_mh))
5021                 if_printf(ifp, "multi-bss support\n");
5022 #ifdef MWL_TX_NODROP
5023         if (bootverbose)
5024                 if_printf(ifp, "no tx drop\n");
5025 #endif
5026 }