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