]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/mwl/if_mwl.c
Merge from head
[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 = k - vap->iv_nw_keys;
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         /*
1757          * NB: Ignore promisc in hostap mode; it's set by the
1758          * bridge.  This is wrong but we have no way to
1759          * identify internal requests (from the bridge)
1760          * versus external requests such as for tcpdump.
1761          */
1762         mwl_hal_setpromisc(mh, ic->ic_promisc > 0 &&
1763             ic->ic_opmode != IEEE80211_M_HOSTAP);
1764         mwl_setmcastfilter(sc);
1765
1766         return 0;
1767 }
1768
1769 /*
1770  * Callback from the 802.11 layer after a multicast state change.
1771  */
1772 static void
1773 mwl_update_mcast(struct ieee80211com *ic)
1774 {
1775         struct mwl_softc *sc = ic->ic_softc;
1776
1777         mwl_setmcastfilter(sc);
1778 }
1779
1780 /*
1781  * Callback from the 802.11 layer after a promiscuous mode change.
1782  * Note this interface does not check the operating mode as this
1783  * is an internal callback and we are expected to honor the current
1784  * state (e.g. this is used for setting the interface in promiscuous
1785  * mode when operating in hostap mode to do ACS).
1786  */
1787 static void
1788 mwl_update_promisc(struct ieee80211com *ic)
1789 {
1790         struct mwl_softc *sc = ic->ic_softc;
1791
1792         mwl_hal_setpromisc(sc->sc_mh, ic->ic_promisc > 0);
1793 }
1794
1795 /*
1796  * Callback from the 802.11 layer to update the slot time
1797  * based on the current setting.  We use it to notify the
1798  * firmware of ERP changes and the f/w takes care of things
1799  * like slot time and preamble.
1800  */
1801 static void
1802 mwl_updateslot(struct ieee80211com *ic)
1803 {
1804         struct mwl_softc *sc = ic->ic_softc;
1805         struct mwl_hal *mh = sc->sc_mh;
1806         int prot;
1807
1808         /* NB: can be called early; suppress needless cmds */
1809         if (!sc->sc_running)
1810                 return;
1811
1812         /*
1813          * Calculate the ERP flags.  The firwmare will use
1814          * this to carry out the appropriate measures.
1815          */
1816         prot = 0;
1817         if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan)) {
1818                 if ((ic->ic_flags & IEEE80211_F_SHSLOT) == 0)
1819                         prot |= IEEE80211_ERP_NON_ERP_PRESENT;
1820                 if (ic->ic_flags & IEEE80211_F_USEPROT)
1821                         prot |= IEEE80211_ERP_USE_PROTECTION;
1822                 if (ic->ic_flags & IEEE80211_F_USEBARKER)
1823                         prot |= IEEE80211_ERP_LONG_PREAMBLE;
1824         }
1825
1826         DPRINTF(sc, MWL_DEBUG_RESET,
1827             "%s: chan %u MHz/flags 0x%x %s slot, (prot 0x%x ic_flags 0x%x)\n",
1828             __func__, ic->ic_curchan->ic_freq, ic->ic_curchan->ic_flags,
1829             ic->ic_flags & IEEE80211_F_SHSLOT ? "short" : "long", prot,
1830             ic->ic_flags);
1831
1832         mwl_hal_setgprot(mh, prot);
1833 }
1834
1835 /*
1836  * Setup the beacon frame.
1837  */
1838 static int
1839 mwl_beacon_setup(struct ieee80211vap *vap)
1840 {
1841         struct mwl_hal_vap *hvap = MWL_VAP(vap)->mv_hvap;
1842         struct ieee80211_node *ni = vap->iv_bss;
1843         struct mbuf *m;
1844
1845         m = ieee80211_beacon_alloc(ni);
1846         if (m == NULL)
1847                 return ENOBUFS;
1848         mwl_hal_setbeacon(hvap, mtod(m, const void *), m->m_len);
1849         m_free(m);
1850
1851         return 0;
1852 }
1853
1854 /*
1855  * Update the beacon frame in response to a change.
1856  */
1857 static void
1858 mwl_beacon_update(struct ieee80211vap *vap, int item)
1859 {
1860         struct mwl_hal_vap *hvap = MWL_VAP(vap)->mv_hvap;
1861         struct ieee80211com *ic = vap->iv_ic;
1862
1863         KASSERT(hvap != NULL, ("no beacon"));
1864         switch (item) {
1865         case IEEE80211_BEACON_ERP:
1866                 mwl_updateslot(ic);
1867                 break;
1868         case IEEE80211_BEACON_HTINFO:
1869                 mwl_hal_setnprotmode(hvap,
1870                     MS(ic->ic_curhtprotmode, IEEE80211_HTINFO_OPMODE));
1871                 break;
1872         case IEEE80211_BEACON_CAPS:
1873         case IEEE80211_BEACON_WME:
1874         case IEEE80211_BEACON_APPIE:
1875         case IEEE80211_BEACON_CSA:
1876                 break;
1877         case IEEE80211_BEACON_TIM:
1878                 /* NB: firmware always forms TIM */
1879                 return;
1880         }
1881         /* XXX retain beacon frame and update */
1882         mwl_beacon_setup(vap);
1883 }
1884
1885 static void
1886 mwl_load_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
1887 {
1888         bus_addr_t *paddr = (bus_addr_t*) arg;
1889         KASSERT(error == 0, ("error %u on bus_dma callback", error));
1890         *paddr = segs->ds_addr;
1891 }
1892
1893 #ifdef MWL_HOST_PS_SUPPORT
1894 /*
1895  * Handle power save station occupancy changes.
1896  */
1897 static void
1898 mwl_update_ps(struct ieee80211vap *vap, int nsta)
1899 {
1900         struct mwl_vap *mvp = MWL_VAP(vap);
1901
1902         if (nsta == 0 || mvp->mv_last_ps_sta == 0)
1903                 mwl_hal_setpowersave_bss(mvp->mv_hvap, nsta);
1904         mvp->mv_last_ps_sta = nsta;
1905 }
1906
1907 /*
1908  * Handle associated station power save state changes.
1909  */
1910 static int
1911 mwl_set_tim(struct ieee80211_node *ni, int set)
1912 {
1913         struct ieee80211vap *vap = ni->ni_vap;
1914         struct mwl_vap *mvp = MWL_VAP(vap);
1915
1916         if (mvp->mv_set_tim(ni, set)) {         /* NB: state change */
1917                 mwl_hal_setpowersave_sta(mvp->mv_hvap,
1918                     IEEE80211_AID(ni->ni_associd), set);
1919                 return 1;
1920         } else
1921                 return 0;
1922 }
1923 #endif /* MWL_HOST_PS_SUPPORT */
1924
1925 static int
1926 mwl_desc_setup(struct mwl_softc *sc, const char *name,
1927         struct mwl_descdma *dd,
1928         int nbuf, size_t bufsize, int ndesc, size_t descsize)
1929 {
1930         uint8_t *ds;
1931         int error;
1932
1933         DPRINTF(sc, MWL_DEBUG_RESET,
1934             "%s: %s DMA: %u bufs (%ju) %u desc/buf (%ju)\n",
1935             __func__, name, nbuf, (uintmax_t) bufsize,
1936             ndesc, (uintmax_t) descsize);
1937
1938         dd->dd_name = name;
1939         dd->dd_desc_len = nbuf * ndesc * descsize;
1940
1941         /*
1942          * Setup DMA descriptor area.
1943          */
1944         error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), /* parent */
1945                        PAGE_SIZE, 0,            /* alignment, bounds */
1946                        BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
1947                        BUS_SPACE_MAXADDR,       /* highaddr */
1948                        NULL, NULL,              /* filter, filterarg */
1949                        dd->dd_desc_len,         /* maxsize */
1950                        1,                       /* nsegments */
1951                        dd->dd_desc_len,         /* maxsegsize */
1952                        BUS_DMA_ALLOCNOW,        /* flags */
1953                        NULL,                    /* lockfunc */
1954                        NULL,                    /* lockarg */
1955                        &dd->dd_dmat);
1956         if (error != 0) {
1957                 device_printf(sc->sc_dev, "cannot allocate %s DMA tag\n", dd->dd_name);
1958                 return error;
1959         }
1960
1961         /* allocate descriptors */
1962         error = bus_dmamem_alloc(dd->dd_dmat, (void**) &dd->dd_desc,
1963                                  BUS_DMA_NOWAIT | BUS_DMA_COHERENT, 
1964                                  &dd->dd_dmamap);
1965         if (error != 0) {
1966                 device_printf(sc->sc_dev, "unable to alloc memory for %u %s descriptors, "
1967                         "error %u\n", nbuf * ndesc, dd->dd_name, error);
1968                 goto fail1;
1969         }
1970
1971         error = bus_dmamap_load(dd->dd_dmat, dd->dd_dmamap,
1972                                 dd->dd_desc, dd->dd_desc_len,
1973                                 mwl_load_cb, &dd->dd_desc_paddr,
1974                                 BUS_DMA_NOWAIT);
1975         if (error != 0) {
1976                 device_printf(sc->sc_dev, "unable to map %s descriptors, error %u\n",
1977                         dd->dd_name, error);
1978                 goto fail2;
1979         }
1980
1981         ds = dd->dd_desc;
1982         memset(ds, 0, dd->dd_desc_len);
1983         DPRINTF(sc, MWL_DEBUG_RESET,
1984             "%s: %s DMA map: %p (%lu) -> 0x%jx (%lu)\n",
1985             __func__, dd->dd_name, ds, (u_long) dd->dd_desc_len,
1986             (uintmax_t) dd->dd_desc_paddr, /*XXX*/ (u_long) dd->dd_desc_len);
1987
1988         return 0;
1989 fail2:
1990         bus_dmamem_free(dd->dd_dmat, dd->dd_desc, dd->dd_dmamap);
1991 fail1:
1992         bus_dma_tag_destroy(dd->dd_dmat);
1993         memset(dd, 0, sizeof(*dd));
1994         return error;
1995 #undef DS2PHYS
1996 }
1997
1998 static void
1999 mwl_desc_cleanup(struct mwl_softc *sc, struct mwl_descdma *dd)
2000 {
2001         bus_dmamap_unload(dd->dd_dmat, dd->dd_dmamap);
2002         bus_dmamem_free(dd->dd_dmat, dd->dd_desc, dd->dd_dmamap);
2003         bus_dma_tag_destroy(dd->dd_dmat);
2004
2005         memset(dd, 0, sizeof(*dd));
2006 }
2007
2008 /* 
2009  * Construct a tx q's free list.  The order of entries on
2010  * the list must reflect the physical layout of tx descriptors
2011  * because the firmware pre-fetches descriptors.
2012  *
2013  * XXX might be better to use indices into the buffer array.
2014  */
2015 static void
2016 mwl_txq_reset(struct mwl_softc *sc, struct mwl_txq *txq)
2017 {
2018         struct mwl_txbuf *bf;
2019         int i;
2020
2021         bf = txq->dma.dd_bufptr;
2022         STAILQ_INIT(&txq->free);
2023         for (i = 0; i < mwl_txbuf; i++, bf++)
2024                 STAILQ_INSERT_TAIL(&txq->free, bf, bf_list);
2025         txq->nfree = i;
2026 }
2027
2028 #define DS2PHYS(_dd, _ds) \
2029         ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc))
2030
2031 static int
2032 mwl_txdma_setup(struct mwl_softc *sc, struct mwl_txq *txq)
2033 {
2034         int error, bsize, i;
2035         struct mwl_txbuf *bf;
2036         struct mwl_txdesc *ds;
2037
2038         error = mwl_desc_setup(sc, "tx", &txq->dma,
2039                         mwl_txbuf, sizeof(struct mwl_txbuf),
2040                         MWL_TXDESC, sizeof(struct mwl_txdesc));
2041         if (error != 0)
2042                 return error;
2043
2044         /* allocate and setup tx buffers */
2045         bsize = mwl_txbuf * sizeof(struct mwl_txbuf);
2046         bf = malloc(bsize, M_MWLDEV, M_NOWAIT | M_ZERO);
2047         if (bf == NULL) {
2048                 device_printf(sc->sc_dev, "malloc of %u tx buffers failed\n",
2049                         mwl_txbuf);
2050                 return ENOMEM;
2051         }
2052         txq->dma.dd_bufptr = bf;
2053
2054         ds = txq->dma.dd_desc;
2055         for (i = 0; i < mwl_txbuf; i++, bf++, ds += MWL_TXDESC) {
2056                 bf->bf_desc = ds;
2057                 bf->bf_daddr = DS2PHYS(&txq->dma, ds);
2058                 error = bus_dmamap_create(sc->sc_dmat, BUS_DMA_NOWAIT,
2059                                 &bf->bf_dmamap);
2060                 if (error != 0) {
2061                         device_printf(sc->sc_dev, "unable to create dmamap for tx "
2062                                 "buffer %u, error %u\n", i, error);
2063                         return error;
2064                 }
2065         }
2066         mwl_txq_reset(sc, txq);
2067         return 0;
2068 }
2069
2070 static void
2071 mwl_txdma_cleanup(struct mwl_softc *sc, struct mwl_txq *txq)
2072 {
2073         struct mwl_txbuf *bf;
2074         int i;
2075
2076         bf = txq->dma.dd_bufptr;
2077         for (i = 0; i < mwl_txbuf; i++, bf++) {
2078                 KASSERT(bf->bf_m == NULL, ("mbuf on free list"));
2079                 KASSERT(bf->bf_node == NULL, ("node on free list"));
2080                 if (bf->bf_dmamap != NULL)
2081                         bus_dmamap_destroy(sc->sc_dmat, bf->bf_dmamap);
2082         }
2083         STAILQ_INIT(&txq->free);
2084         txq->nfree = 0;
2085         if (txq->dma.dd_bufptr != NULL) {
2086                 free(txq->dma.dd_bufptr, M_MWLDEV);
2087                 txq->dma.dd_bufptr = NULL;
2088         }
2089         if (txq->dma.dd_desc_len != 0)
2090                 mwl_desc_cleanup(sc, &txq->dma);
2091 }
2092
2093 static int
2094 mwl_rxdma_setup(struct mwl_softc *sc)
2095 {
2096         int error, jumbosize, bsize, i;
2097         struct mwl_rxbuf *bf;
2098         struct mwl_jumbo *rbuf;
2099         struct mwl_rxdesc *ds;
2100         caddr_t data;
2101
2102         error = mwl_desc_setup(sc, "rx", &sc->sc_rxdma,
2103                         mwl_rxdesc, sizeof(struct mwl_rxbuf),
2104                         1, sizeof(struct mwl_rxdesc));
2105         if (error != 0)
2106                 return error;
2107
2108         /*
2109          * Receive is done to a private pool of jumbo buffers.
2110          * This allows us to attach to mbuf's and avoid re-mapping
2111          * memory on each rx we post.  We allocate a large chunk
2112          * of memory and manage it in the driver.  The mbuf free
2113          * callback method is used to reclaim frames after sending
2114          * them up the stack.  By default we allocate 2x the number of
2115          * rx descriptors configured so we have some slop to hold
2116          * us while frames are processed.
2117          */
2118         if (mwl_rxbuf < 2*mwl_rxdesc) {
2119                 device_printf(sc->sc_dev,
2120                     "too few rx dma buffers (%d); increasing to %d\n",
2121                     mwl_rxbuf, 2*mwl_rxdesc);
2122                 mwl_rxbuf = 2*mwl_rxdesc;
2123         }
2124         jumbosize = roundup(MWL_AGGR_SIZE, PAGE_SIZE);
2125         sc->sc_rxmemsize = mwl_rxbuf*jumbosize;
2126
2127         error = bus_dma_tag_create(sc->sc_dmat, /* parent */
2128                        PAGE_SIZE, 0,            /* alignment, bounds */
2129                        BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
2130                        BUS_SPACE_MAXADDR,       /* highaddr */
2131                        NULL, NULL,              /* filter, filterarg */
2132                        sc->sc_rxmemsize,        /* maxsize */
2133                        1,                       /* nsegments */
2134                        sc->sc_rxmemsize,        /* maxsegsize */
2135                        BUS_DMA_ALLOCNOW,        /* flags */
2136                        NULL,                    /* lockfunc */
2137                        NULL,                    /* lockarg */
2138                        &sc->sc_rxdmat);
2139         if (error != 0) {
2140                 device_printf(sc->sc_dev, "could not create rx DMA tag\n");
2141                 return error;
2142         }
2143
2144         error = bus_dmamem_alloc(sc->sc_rxdmat, (void**) &sc->sc_rxmem,
2145                                  BUS_DMA_NOWAIT | BUS_DMA_COHERENT, 
2146                                  &sc->sc_rxmap);
2147         if (error != 0) {
2148                 device_printf(sc->sc_dev, "could not alloc %ju bytes of rx DMA memory\n",
2149                     (uintmax_t) sc->sc_rxmemsize);
2150                 return error;
2151         }
2152
2153         error = bus_dmamap_load(sc->sc_rxdmat, sc->sc_rxmap,
2154                                 sc->sc_rxmem, sc->sc_rxmemsize,
2155                                 mwl_load_cb, &sc->sc_rxmem_paddr,
2156                                 BUS_DMA_NOWAIT);
2157         if (error != 0) {
2158                 device_printf(sc->sc_dev, "could not load rx DMA map\n");
2159                 return error;
2160         }
2161
2162         /*
2163          * Allocate rx buffers and set them up.
2164          */
2165         bsize = mwl_rxdesc * sizeof(struct mwl_rxbuf);
2166         bf = malloc(bsize, M_MWLDEV, M_NOWAIT | M_ZERO);
2167         if (bf == NULL) {
2168                 device_printf(sc->sc_dev, "malloc of %u rx buffers failed\n", bsize);
2169                 return error;
2170         }
2171         sc->sc_rxdma.dd_bufptr = bf;
2172
2173         STAILQ_INIT(&sc->sc_rxbuf);
2174         ds = sc->sc_rxdma.dd_desc;
2175         for (i = 0; i < mwl_rxdesc; i++, bf++, ds++) {
2176                 bf->bf_desc = ds;
2177                 bf->bf_daddr = DS2PHYS(&sc->sc_rxdma, ds);
2178                 /* pre-assign dma buffer */
2179                 bf->bf_data = ((uint8_t *)sc->sc_rxmem) + (i*jumbosize);
2180                 /* NB: tail is intentional to preserve descriptor order */
2181                 STAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list);
2182         }
2183
2184         /*
2185          * Place remainder of dma memory buffers on the free list.
2186          */
2187         SLIST_INIT(&sc->sc_rxfree);
2188         for (; i < mwl_rxbuf; i++) {
2189                 data = ((uint8_t *)sc->sc_rxmem) + (i*jumbosize);
2190                 rbuf = MWL_JUMBO_DATA2BUF(data);
2191                 SLIST_INSERT_HEAD(&sc->sc_rxfree, rbuf, next);
2192                 sc->sc_nrxfree++;
2193         }
2194         return 0;
2195 }
2196 #undef DS2PHYS
2197
2198 static void
2199 mwl_rxdma_cleanup(struct mwl_softc *sc)
2200 {
2201         if (sc->sc_rxmem_paddr != 0) {
2202                 bus_dmamap_unload(sc->sc_rxdmat, sc->sc_rxmap);
2203                 sc->sc_rxmem_paddr = 0;
2204         }
2205         if (sc->sc_rxmem != NULL) {
2206                 bus_dmamem_free(sc->sc_rxdmat, sc->sc_rxmem, sc->sc_rxmap);
2207                 sc->sc_rxmem = NULL;
2208         }
2209         if (sc->sc_rxdma.dd_bufptr != NULL) {
2210                 free(sc->sc_rxdma.dd_bufptr, M_MWLDEV);
2211                 sc->sc_rxdma.dd_bufptr = NULL;
2212         }
2213         if (sc->sc_rxdma.dd_desc_len != 0)
2214                 mwl_desc_cleanup(sc, &sc->sc_rxdma);
2215 }
2216
2217 static int
2218 mwl_dma_setup(struct mwl_softc *sc)
2219 {
2220         int error, i;
2221
2222         error = mwl_rxdma_setup(sc);
2223         if (error != 0) {
2224                 mwl_rxdma_cleanup(sc);
2225                 return error;
2226         }
2227
2228         for (i = 0; i < MWL_NUM_TX_QUEUES; i++) {
2229                 error = mwl_txdma_setup(sc, &sc->sc_txq[i]);
2230                 if (error != 0) {
2231                         mwl_dma_cleanup(sc);
2232                         return error;
2233                 }
2234         }
2235         return 0;
2236 }
2237
2238 static void
2239 mwl_dma_cleanup(struct mwl_softc *sc)
2240 {
2241         int i;
2242
2243         for (i = 0; i < MWL_NUM_TX_QUEUES; i++)
2244                 mwl_txdma_cleanup(sc, &sc->sc_txq[i]);
2245         mwl_rxdma_cleanup(sc);
2246 }
2247
2248 static struct ieee80211_node *
2249 mwl_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
2250 {
2251         struct ieee80211com *ic = vap->iv_ic;
2252         struct mwl_softc *sc = ic->ic_softc;
2253         const size_t space = sizeof(struct mwl_node);
2254         struct mwl_node *mn;
2255
2256         mn = malloc(space, M_80211_NODE, M_NOWAIT|M_ZERO);
2257         if (mn == NULL) {
2258                 /* XXX stat+msg */
2259                 return NULL;
2260         }
2261         DPRINTF(sc, MWL_DEBUG_NODE, "%s: mn %p\n", __func__, mn);
2262         return &mn->mn_node;
2263 }
2264
2265 static void
2266 mwl_node_cleanup(struct ieee80211_node *ni)
2267 {
2268         struct ieee80211com *ic = ni->ni_ic;
2269         struct mwl_softc *sc = ic->ic_softc;
2270         struct mwl_node *mn = MWL_NODE(ni);
2271
2272         DPRINTF(sc, MWL_DEBUG_NODE, "%s: ni %p ic %p staid %d\n",
2273             __func__, ni, ni->ni_ic, mn->mn_staid);
2274
2275         if (mn->mn_staid != 0) {
2276                 struct ieee80211vap *vap = ni->ni_vap;
2277
2278                 if (mn->mn_hvap != NULL) {
2279                         if (vap->iv_opmode == IEEE80211_M_STA)
2280                                 mwl_hal_delstation(mn->mn_hvap, vap->iv_myaddr);
2281                         else
2282                                 mwl_hal_delstation(mn->mn_hvap, ni->ni_macaddr);
2283                 }
2284                 /*
2285                  * NB: legacy WDS peer sta db entry is installed using
2286                  * the associate ap's hvap; use it again to delete it.
2287                  * XXX can vap be NULL?
2288                  */
2289                 else if (vap->iv_opmode == IEEE80211_M_WDS &&
2290                     MWL_VAP(vap)->mv_ap_hvap != NULL)
2291                         mwl_hal_delstation(MWL_VAP(vap)->mv_ap_hvap,
2292                             ni->ni_macaddr);
2293                 delstaid(sc, mn->mn_staid);
2294                 mn->mn_staid = 0;
2295         }
2296         sc->sc_node_cleanup(ni);
2297 }
2298
2299 /*
2300  * Reclaim rx dma buffers from packets sitting on the ampdu
2301  * reorder queue for a station.  We replace buffers with a
2302  * system cluster (if available).
2303  */
2304 static void
2305 mwl_ampdu_rxdma_reclaim(struct ieee80211_rx_ampdu *rap)
2306 {
2307 #if 0
2308         int i, n, off;
2309         struct mbuf *m;
2310         void *cl;
2311
2312         n = rap->rxa_qframes;
2313         for (i = 0; i < rap->rxa_wnd && n > 0; i++) {
2314                 m = rap->rxa_m[i];
2315                 if (m == NULL)
2316                         continue;
2317                 n--;
2318                 /* our dma buffers have a well-known free routine */
2319                 if ((m->m_flags & M_EXT) == 0 ||
2320                     m->m_ext.ext_free != mwl_ext_free)
2321                         continue;
2322                 /*
2323                  * Try to allocate a cluster and move the data.
2324                  */
2325                 off = m->m_data - m->m_ext.ext_buf;
2326                 if (off + m->m_pkthdr.len > MCLBYTES) {
2327                         /* XXX no AMSDU for now */
2328                         continue;
2329                 }
2330                 cl = pool_cache_get_paddr(&mclpool_cache, 0,
2331                     &m->m_ext.ext_paddr);
2332                 if (cl != NULL) {
2333                         /*
2334                          * Copy the existing data to the cluster, remove
2335                          * the rx dma buffer, and attach the cluster in
2336                          * its place.  Note we preserve the offset to the
2337                          * data so frames being bridged can still prepend
2338                          * their headers without adding another mbuf.
2339                          */
2340                         memcpy((caddr_t) cl + off, m->m_data, m->m_pkthdr.len);
2341                         MEXTREMOVE(m);
2342                         MEXTADD(m, cl, MCLBYTES, 0, NULL, &mclpool_cache);
2343                         /* setup mbuf like _MCLGET does */
2344                         m->m_flags |= M_CLUSTER | M_EXT_RW;
2345                         _MOWNERREF(m, M_EXT | M_CLUSTER);
2346                         /* NB: m_data is clobbered by MEXTADDR, adjust */
2347                         m->m_data += off;
2348                 }
2349         }
2350 #endif
2351 }
2352
2353 /*
2354  * Callback to reclaim resources.  We first let the
2355  * net80211 layer do it's thing, then if we are still
2356  * blocked by a lack of rx dma buffers we walk the ampdu
2357  * reorder q's to reclaim buffers by copying to a system
2358  * cluster.
2359  */
2360 static void
2361 mwl_node_drain(struct ieee80211_node *ni)
2362 {
2363         struct ieee80211com *ic = ni->ni_ic;
2364         struct mwl_softc *sc = ic->ic_softc;
2365         struct mwl_node *mn = MWL_NODE(ni);
2366
2367         DPRINTF(sc, MWL_DEBUG_NODE, "%s: ni %p vap %p staid %d\n",
2368             __func__, ni, ni->ni_vap, mn->mn_staid);
2369
2370         /* NB: call up first to age out ampdu q's */
2371         sc->sc_node_drain(ni);
2372
2373         /* XXX better to not check low water mark? */
2374         if (sc->sc_rxblocked && mn->mn_staid != 0 &&
2375             (ni->ni_flags & IEEE80211_NODE_HT)) {
2376                 uint8_t tid;
2377                 /*
2378                  * Walk the reorder q and reclaim rx dma buffers by copying
2379                  * the packet contents into clusters.
2380                  */
2381                 for (tid = 0; tid < WME_NUM_TID; tid++) {
2382                         struct ieee80211_rx_ampdu *rap;
2383
2384                         rap = &ni->ni_rx_ampdu[tid];
2385                         if ((rap->rxa_flags & IEEE80211_AGGR_XCHGPEND) == 0)
2386                                 continue;
2387                         if (rap->rxa_qframes)
2388                                 mwl_ampdu_rxdma_reclaim(rap);
2389                 }
2390         }
2391 }
2392
2393 static void
2394 mwl_node_getsignal(const struct ieee80211_node *ni, int8_t *rssi, int8_t *noise)
2395 {
2396         *rssi = ni->ni_ic->ic_node_getrssi(ni);
2397 #ifdef MWL_ANT_INFO_SUPPORT
2398 #if 0
2399         /* XXX need to smooth data */
2400         *noise = -MWL_NODE_CONST(ni)->mn_ai.nf;
2401 #else
2402         *noise = -95;           /* XXX */
2403 #endif
2404 #else
2405         *noise = -95;           /* XXX */
2406 #endif
2407 }
2408
2409 /*
2410  * Convert Hardware per-antenna rssi info to common format:
2411  * Let a1, a2, a3 represent the amplitudes per chain
2412  * Let amax represent max[a1, a2, a3]
2413  * Rssi1_dBm = RSSI_dBm + 20*log10(a1/amax)
2414  * Rssi1_dBm = RSSI_dBm + 20*log10(a1) - 20*log10(amax)
2415  * We store a table that is 4*20*log10(idx) - the extra 4 is to store or
2416  * maintain some extra precision.
2417  *
2418  * Values are stored in .5 db format capped at 127.
2419  */
2420 static void
2421 mwl_node_getmimoinfo(const struct ieee80211_node *ni,
2422         struct ieee80211_mimo_info *mi)
2423 {
2424 #define CVT(_dst, _src) do {                                            \
2425         (_dst) = rssi + ((logdbtbl[_src] - logdbtbl[rssi_max]) >> 2);   \
2426         (_dst) = (_dst) > 64 ? 127 : ((_dst) << 1);                     \
2427 } while (0)
2428         static const int8_t logdbtbl[32] = {
2429                0,   0,  24,  38,  48,  56,  62,  68, 
2430               72,  76,  80,  83,  86,  89,  92,  94, 
2431               96,  98, 100, 102, 104, 106, 107, 109, 
2432              110, 112, 113, 115, 116, 117, 118, 119
2433         };
2434         const struct mwl_node *mn = MWL_NODE_CONST(ni);
2435         uint8_t rssi = mn->mn_ai.rsvd1/2;               /* XXX */
2436         uint32_t rssi_max;
2437
2438         rssi_max = mn->mn_ai.rssi_a;
2439         if (mn->mn_ai.rssi_b > rssi_max)
2440                 rssi_max = mn->mn_ai.rssi_b;
2441         if (mn->mn_ai.rssi_c > rssi_max)
2442                 rssi_max = mn->mn_ai.rssi_c;
2443
2444         CVT(mi->rssi[0], mn->mn_ai.rssi_a);
2445         CVT(mi->rssi[1], mn->mn_ai.rssi_b);
2446         CVT(mi->rssi[2], mn->mn_ai.rssi_c);
2447
2448         mi->noise[0] = mn->mn_ai.nf_a;
2449         mi->noise[1] = mn->mn_ai.nf_b;
2450         mi->noise[2] = mn->mn_ai.nf_c;
2451 #undef CVT
2452 }
2453
2454 static __inline void *
2455 mwl_getrxdma(struct mwl_softc *sc)
2456 {
2457         struct mwl_jumbo *buf;
2458         void *data;
2459
2460         /*
2461          * Allocate from jumbo pool.
2462          */
2463         MWL_RXFREE_LOCK(sc);
2464         buf = SLIST_FIRST(&sc->sc_rxfree);
2465         if (buf == NULL) {
2466                 DPRINTF(sc, MWL_DEBUG_ANY,
2467                     "%s: out of rx dma buffers\n", __func__);
2468                 sc->sc_stats.mst_rx_nodmabuf++;
2469                 data = NULL;
2470         } else {
2471                 SLIST_REMOVE_HEAD(&sc->sc_rxfree, next);
2472                 sc->sc_nrxfree--;
2473                 data = MWL_JUMBO_BUF2DATA(buf);
2474         }
2475         MWL_RXFREE_UNLOCK(sc);
2476         return data;
2477 }
2478
2479 static __inline void
2480 mwl_putrxdma(struct mwl_softc *sc, void *data)
2481 {
2482         struct mwl_jumbo *buf;
2483
2484         /* XXX bounds check data */
2485         MWL_RXFREE_LOCK(sc);
2486         buf = MWL_JUMBO_DATA2BUF(data);
2487         SLIST_INSERT_HEAD(&sc->sc_rxfree, buf, next);
2488         sc->sc_nrxfree++;
2489         MWL_RXFREE_UNLOCK(sc);
2490 }
2491
2492 static int
2493 mwl_rxbuf_init(struct mwl_softc *sc, struct mwl_rxbuf *bf)
2494 {
2495         struct mwl_rxdesc *ds;
2496
2497         ds = bf->bf_desc;
2498         if (bf->bf_data == NULL) {
2499                 bf->bf_data = mwl_getrxdma(sc);
2500                 if (bf->bf_data == NULL) {
2501                         /* mark descriptor to be skipped */
2502                         ds->RxControl = EAGLE_RXD_CTRL_OS_OWN;
2503                         /* NB: don't need PREREAD */
2504                         MWL_RXDESC_SYNC(sc, ds, BUS_DMASYNC_PREWRITE);
2505                         sc->sc_stats.mst_rxbuf_failed++;
2506                         return ENOMEM;
2507                 }
2508         }
2509         /*
2510          * NB: DMA buffer contents is known to be unmodified
2511          *     so there's no need to flush the data cache.
2512          */
2513
2514         /*
2515          * Setup descriptor.
2516          */
2517         ds->QosCtrl = 0;
2518         ds->RSSI = 0;
2519         ds->Status = EAGLE_RXD_STATUS_IDLE;
2520         ds->Channel = 0;
2521         ds->PktLen = htole16(MWL_AGGR_SIZE);
2522         ds->SQ2 = 0;
2523         ds->pPhysBuffData = htole32(MWL_JUMBO_DMA_ADDR(sc, bf->bf_data));
2524         /* NB: don't touch pPhysNext, set once */
2525         ds->RxControl = EAGLE_RXD_CTRL_DRIVER_OWN;
2526         MWL_RXDESC_SYNC(sc, ds, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
2527
2528         return 0;
2529 }
2530
2531 static void
2532 mwl_ext_free(struct mbuf *m, void *data, void *arg)
2533 {
2534         struct mwl_softc *sc = arg;
2535
2536         /* XXX bounds check data */
2537         mwl_putrxdma(sc, data);
2538         /*
2539          * If we were previously blocked by a lack of rx dma buffers
2540          * check if we now have enough to restart rx interrupt handling.
2541          * NB: we know we are called at splvm which is above splnet.
2542          */
2543         if (sc->sc_rxblocked && sc->sc_nrxfree > mwl_rxdmalow) {
2544                 sc->sc_rxblocked = 0;
2545                 mwl_hal_intrset(sc->sc_mh, sc->sc_imask);
2546         }
2547 }
2548
2549 struct mwl_frame_bar {
2550         u_int8_t        i_fc[2];
2551         u_int8_t        i_dur[2];
2552         u_int8_t        i_ra[IEEE80211_ADDR_LEN];
2553         u_int8_t        i_ta[IEEE80211_ADDR_LEN];
2554         /* ctl, seq, FCS */
2555 } __packed;
2556
2557 /*
2558  * Like ieee80211_anyhdrsize, but handles BAR frames
2559  * specially so the logic below to piece the 802.11
2560  * header together works.
2561  */
2562 static __inline int
2563 mwl_anyhdrsize(const void *data)
2564 {
2565         const struct ieee80211_frame *wh = data;
2566
2567         if ((wh->i_fc[0]&IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL) {
2568                 switch (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) {
2569                 case IEEE80211_FC0_SUBTYPE_CTS:
2570                 case IEEE80211_FC0_SUBTYPE_ACK:
2571                         return sizeof(struct ieee80211_frame_ack);
2572                 case IEEE80211_FC0_SUBTYPE_BAR:
2573                         return sizeof(struct mwl_frame_bar);
2574                 }
2575                 return sizeof(struct ieee80211_frame_min);
2576         } else
2577                 return ieee80211_hdrsize(data);
2578 }
2579
2580 static void
2581 mwl_handlemicerror(struct ieee80211com *ic, const uint8_t *data)
2582 {
2583         const struct ieee80211_frame *wh;
2584         struct ieee80211_node *ni;
2585
2586         wh = (const struct ieee80211_frame *)(data + sizeof(uint16_t));
2587         ni = ieee80211_find_rxnode(ic, (const struct ieee80211_frame_min *) wh);
2588         if (ni != NULL) {
2589                 ieee80211_notify_michael_failure(ni->ni_vap, wh, 0);
2590                 ieee80211_free_node(ni);
2591         }
2592 }
2593
2594 /*
2595  * Convert hardware signal strength to rssi.  The value
2596  * provided by the device has the noise floor added in;
2597  * we need to compensate for this but we don't have that
2598  * so we use a fixed value.
2599  *
2600  * The offset of 8 is good for both 2.4 and 5GHz.  The LNA
2601  * offset is already set as part of the initial gain.  This
2602  * will give at least +/- 3dB for 2.4GHz and +/- 5dB for 5GHz.
2603  */
2604 static __inline int
2605 cvtrssi(uint8_t ssi)
2606 {
2607         int rssi = (int) ssi + 8;
2608         /* XXX hack guess until we have a real noise floor */
2609         rssi = 2*(87 - rssi);   /* NB: .5 dBm units */
2610         return (rssi < 0 ? 0 : rssi > 127 ? 127 : rssi);
2611 }
2612
2613 static void
2614 mwl_rx_proc(void *arg, int npending)
2615 {
2616         struct mwl_softc *sc = arg;
2617         struct ieee80211com *ic = &sc->sc_ic;
2618         struct mwl_rxbuf *bf;
2619         struct mwl_rxdesc *ds;
2620         struct mbuf *m;
2621         struct ieee80211_qosframe *wh;
2622         struct ieee80211_qosframe_addr4 *wh4;
2623         struct ieee80211_node *ni;
2624         struct mwl_node *mn;
2625         int off, len, hdrlen, pktlen, rssi, ntodo;
2626         uint8_t *data, status;
2627         void *newdata;
2628         int16_t nf;
2629
2630         DPRINTF(sc, MWL_DEBUG_RX_PROC, "%s: pending %u rdptr 0x%x wrptr 0x%x\n",
2631             __func__, npending, RD4(sc, sc->sc_hwspecs.rxDescRead),
2632             RD4(sc, sc->sc_hwspecs.rxDescWrite));
2633         nf = -96;                       /* XXX */
2634         bf = sc->sc_rxnext;
2635         for (ntodo = mwl_rxquota; ntodo > 0; ntodo--) {
2636                 if (bf == NULL)
2637                         bf = STAILQ_FIRST(&sc->sc_rxbuf);
2638                 ds = bf->bf_desc;
2639                 data = bf->bf_data;
2640                 if (data == NULL) {
2641                         /*
2642                          * If data allocation failed previously there
2643                          * will be no buffer; try again to re-populate it.
2644                          * Note the firmware will not advance to the next
2645                          * descriptor with a dma buffer so we must mimic
2646                          * this or we'll get out of sync.
2647                          */ 
2648                         DPRINTF(sc, MWL_DEBUG_ANY,
2649                             "%s: rx buf w/o dma memory\n", __func__);
2650                         (void) mwl_rxbuf_init(sc, bf);
2651                         sc->sc_stats.mst_rx_dmabufmissing++;
2652                         break;
2653                 }
2654                 MWL_RXDESC_SYNC(sc, ds,
2655                     BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
2656                 if (ds->RxControl != EAGLE_RXD_CTRL_DMA_OWN)
2657                         break;
2658 #ifdef MWL_DEBUG
2659                 if (sc->sc_debug & MWL_DEBUG_RECV_DESC)
2660                         mwl_printrxbuf(bf, 0);
2661 #endif
2662                 status = ds->Status;
2663                 if (status & EAGLE_RXD_STATUS_DECRYPT_ERR_MASK) {
2664                         counter_u64_add(ic->ic_ierrors, 1);
2665                         sc->sc_stats.mst_rx_crypto++;
2666                         /*
2667                          * NB: Check EAGLE_RXD_STATUS_GENERAL_DECRYPT_ERR
2668                          *     for backwards compatibility.
2669                          */
2670                         if (status != EAGLE_RXD_STATUS_GENERAL_DECRYPT_ERR &&
2671                             (status & EAGLE_RXD_STATUS_TKIP_MIC_DECRYPT_ERR)) {
2672                                 /*
2673                                  * MIC error, notify upper layers.
2674                                  */
2675                                 bus_dmamap_sync(sc->sc_rxdmat, sc->sc_rxmap,
2676                                     BUS_DMASYNC_POSTREAD);
2677                                 mwl_handlemicerror(ic, data);
2678                                 sc->sc_stats.mst_rx_tkipmic++;
2679                         }
2680                         /* XXX too painful to tap packets */
2681                         goto rx_next;
2682                 }
2683                 /*
2684                  * Sync the data buffer.
2685                  */
2686                 len = le16toh(ds->PktLen);
2687                 bus_dmamap_sync(sc->sc_rxdmat, sc->sc_rxmap, BUS_DMASYNC_POSTREAD);
2688                 /*
2689                  * The 802.11 header is provided all or in part at the front;
2690                  * use it to calculate the true size of the header that we'll
2691                  * construct below.  We use this to figure out where to copy
2692                  * payload prior to constructing the header.
2693                  */
2694                 hdrlen = mwl_anyhdrsize(data + sizeof(uint16_t));
2695                 off = sizeof(uint16_t) + sizeof(struct ieee80211_frame_addr4);
2696
2697                 /* calculate rssi early so we can re-use for each aggregate */
2698                 rssi = cvtrssi(ds->RSSI);
2699
2700                 pktlen = hdrlen + (len - off);
2701                 /*
2702                  * NB: we know our frame is at least as large as
2703                  * IEEE80211_MIN_LEN because there is a 4-address
2704                  * frame at the front.  Hence there's no need to
2705                  * vet the packet length.  If the frame in fact
2706                  * is too small it should be discarded at the
2707                  * net80211 layer.
2708                  */
2709
2710                 /*
2711                  * Attach dma buffer to an mbuf.  We tried
2712                  * doing this based on the packet size (i.e.
2713                  * copying small packets) but it turns out to
2714                  * be a net loss.  The tradeoff might be system
2715                  * dependent (cache architecture is important).
2716                  */
2717                 MGETHDR(m, M_NOWAIT, MT_DATA);
2718                 if (m == NULL) {
2719                         DPRINTF(sc, MWL_DEBUG_ANY,
2720                             "%s: no rx mbuf\n", __func__);
2721                         sc->sc_stats.mst_rx_nombuf++;
2722                         goto rx_next;
2723                 }
2724                 /*
2725                  * Acquire the replacement dma buffer before
2726                  * processing the frame.  If we're out of dma
2727                  * buffers we disable rx interrupts and wait
2728                  * for the free pool to reach mlw_rxdmalow buffers
2729                  * before starting to do work again.  If the firmware
2730                  * runs out of descriptors then it will toss frames
2731                  * which is better than our doing it as that can
2732                  * starve our processing.  It is also important that
2733                  * we always process rx'd frames in case they are
2734                  * A-MPDU as otherwise the host's view of the BA
2735                  * window may get out of sync with the firmware.
2736                  */
2737                 newdata = mwl_getrxdma(sc);
2738                 if (newdata == NULL) {
2739                         /* NB: stat+msg in mwl_getrxdma */
2740                         m_free(m);
2741                         /* disable RX interrupt and mark state */
2742                         mwl_hal_intrset(sc->sc_mh,
2743                             sc->sc_imask &~ MACREG_A2HRIC_BIT_RX_RDY);
2744                         sc->sc_rxblocked = 1;
2745                         ieee80211_drain(ic);
2746                         /* XXX check rxblocked and immediately start again? */
2747                         goto rx_stop;
2748                 }
2749                 bf->bf_data = newdata;
2750                 /*
2751                  * Attach the dma buffer to the mbuf;
2752                  * mwl_rxbuf_init will re-setup the rx
2753                  * descriptor using the replacement dma
2754                  * buffer we just installed above.
2755                  */
2756                 MEXTADD(m, data, MWL_AGGR_SIZE, mwl_ext_free,
2757                     data, sc, 0, EXT_NET_DRV);
2758                 m->m_data += off - hdrlen;
2759                 m->m_pkthdr.len = m->m_len = pktlen;
2760                 /* NB: dma buffer assumed read-only */
2761
2762                 /*
2763                  * Piece 802.11 header together.
2764                  */
2765                 wh = mtod(m, struct ieee80211_qosframe *);
2766                 /* NB: don't need to do this sometimes but ... */
2767                 /* XXX special case so we can memcpy after m_devget? */
2768                 ovbcopy(data + sizeof(uint16_t), wh, hdrlen);
2769                 if (IEEE80211_QOS_HAS_SEQ(wh)) {
2770                         if (IEEE80211_IS_DSTODS(wh)) {
2771                                 wh4 = mtod(m,
2772                                     struct ieee80211_qosframe_addr4*);
2773                                 *(uint16_t *)wh4->i_qos = ds->QosCtrl;
2774                         } else {
2775                                 *(uint16_t *)wh->i_qos = ds->QosCtrl;
2776                         }
2777                 }
2778                 /*
2779                  * The f/w strips WEP header but doesn't clear
2780                  * the WEP bit; mark the packet with M_WEP so
2781                  * net80211 will treat the data as decrypted.
2782                  * While here also clear the PWR_MGT bit since
2783                  * power save is handled by the firmware and
2784                  * passing this up will potentially cause the
2785                  * upper layer to put a station in power save
2786                  * (except when configured with MWL_HOST_PS_SUPPORT).
2787                  */
2788                 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
2789                         m->m_flags |= M_WEP;
2790 #ifdef MWL_HOST_PS_SUPPORT
2791                 wh->i_fc[1] &= ~IEEE80211_FC1_PROTECTED;
2792 #else
2793                 wh->i_fc[1] &= ~(IEEE80211_FC1_PROTECTED |
2794                     IEEE80211_FC1_PWR_MGT);
2795 #endif
2796
2797                 if (ieee80211_radiotap_active(ic)) {
2798                         struct mwl_rx_radiotap_header *tap = &sc->sc_rx_th;
2799
2800                         tap->wr_flags = 0;
2801                         tap->wr_rate = ds->Rate;
2802                         tap->wr_antsignal = rssi + nf;
2803                         tap->wr_antnoise = nf;
2804                 }
2805                 if (IFF_DUMPPKTS_RECV(sc, wh)) {
2806                         ieee80211_dump_pkt(ic, mtod(m, caddr_t),
2807                             len, ds->Rate, rssi);
2808                 }
2809                 /* dispatch */
2810                 ni = ieee80211_find_rxnode(ic,
2811                     (const struct ieee80211_frame_min *) wh);
2812                 if (ni != NULL) {
2813                         mn = MWL_NODE(ni);
2814 #ifdef MWL_ANT_INFO_SUPPORT
2815                         mn->mn_ai.rssi_a = ds->ai.rssi_a;
2816                         mn->mn_ai.rssi_b = ds->ai.rssi_b;
2817                         mn->mn_ai.rssi_c = ds->ai.rssi_c;
2818                         mn->mn_ai.rsvd1 = rssi;
2819 #endif
2820                         /* tag AMPDU aggregates for reorder processing */
2821                         if (ni->ni_flags & IEEE80211_NODE_HT)
2822                                 m->m_flags |= M_AMPDU;
2823                         (void) ieee80211_input(ni, m, rssi, nf);
2824                         ieee80211_free_node(ni);
2825                 } else
2826                         (void) ieee80211_input_all(ic, m, rssi, nf);
2827 rx_next:
2828                 /* NB: ignore ENOMEM so we process more descriptors */
2829                 (void) mwl_rxbuf_init(sc, bf);
2830                 bf = STAILQ_NEXT(bf, bf_list);
2831         }
2832 rx_stop:
2833         sc->sc_rxnext = bf;
2834
2835         if (mbufq_first(&sc->sc_snd) != NULL) {
2836                 /* NB: kick fw; the tx thread may have been preempted */
2837                 mwl_hal_txstart(sc->sc_mh, 0);
2838                 mwl_start(sc);
2839         }
2840 }
2841
2842 static void
2843 mwl_txq_init(struct mwl_softc *sc, struct mwl_txq *txq, int qnum)
2844 {
2845         struct mwl_txbuf *bf, *bn;
2846         struct mwl_txdesc *ds;
2847
2848         MWL_TXQ_LOCK_INIT(sc, txq);
2849         txq->qnum = qnum;
2850         txq->txpri = 0; /* XXX */
2851 #if 0
2852         /* NB: q setup by mwl_txdma_setup XXX */
2853         STAILQ_INIT(&txq->free);
2854 #endif
2855         STAILQ_FOREACH(bf, &txq->free, bf_list) {
2856                 bf->bf_txq = txq;
2857
2858                 ds = bf->bf_desc;
2859                 bn = STAILQ_NEXT(bf, bf_list);
2860                 if (bn == NULL)
2861                         bn = STAILQ_FIRST(&txq->free);
2862                 ds->pPhysNext = htole32(bn->bf_daddr);
2863         }
2864         STAILQ_INIT(&txq->active);
2865 }
2866
2867 /*
2868  * Setup a hardware data transmit queue for the specified
2869  * access control.  We record the mapping from ac's
2870  * to h/w queues for use by mwl_tx_start.
2871  */
2872 static int
2873 mwl_tx_setup(struct mwl_softc *sc, int ac, int mvtype)
2874 {
2875         struct mwl_txq *txq;
2876
2877         if (ac >= nitems(sc->sc_ac2q)) {
2878                 device_printf(sc->sc_dev, "AC %u out of range, max %zu!\n",
2879                         ac, nitems(sc->sc_ac2q));
2880                 return 0;
2881         }
2882         if (mvtype >= MWL_NUM_TX_QUEUES) {
2883                 device_printf(sc->sc_dev, "mvtype %u out of range, max %u!\n",
2884                         mvtype, MWL_NUM_TX_QUEUES);
2885                 return 0;
2886         }
2887         txq = &sc->sc_txq[mvtype];
2888         mwl_txq_init(sc, txq, mvtype);
2889         sc->sc_ac2q[ac] = txq;
2890         return 1;
2891 }
2892
2893 /*
2894  * Update WME parameters for a transmit queue.
2895  */
2896 static int
2897 mwl_txq_update(struct mwl_softc *sc, int ac)
2898 {
2899 #define MWL_EXPONENT_TO_VALUE(v)        ((1<<v)-1)
2900         struct ieee80211com *ic = &sc->sc_ic;
2901         struct mwl_txq *txq = sc->sc_ac2q[ac];
2902         struct wmeParams *wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[ac];
2903         struct mwl_hal *mh = sc->sc_mh;
2904         int aifs, cwmin, cwmax, txoplim;
2905
2906         aifs = wmep->wmep_aifsn;
2907         /* XXX in sta mode need to pass log values for cwmin/max */
2908         cwmin = MWL_EXPONENT_TO_VALUE(wmep->wmep_logcwmin);
2909         cwmax = MWL_EXPONENT_TO_VALUE(wmep->wmep_logcwmax);
2910         txoplim = wmep->wmep_txopLimit;         /* NB: units of 32us */
2911
2912         if (mwl_hal_setedcaparams(mh, txq->qnum, cwmin, cwmax, aifs, txoplim)) {
2913                 device_printf(sc->sc_dev, "unable to update hardware queue "
2914                         "parameters for %s traffic!\n",
2915                         ieee80211_wme_acnames[ac]);
2916                 return 0;
2917         }
2918         return 1;
2919 #undef MWL_EXPONENT_TO_VALUE
2920 }
2921
2922 /*
2923  * Callback from the 802.11 layer to update WME parameters.
2924  */
2925 static int
2926 mwl_wme_update(struct ieee80211com *ic)
2927 {
2928         struct mwl_softc *sc = ic->ic_softc;
2929
2930         return !mwl_txq_update(sc, WME_AC_BE) ||
2931             !mwl_txq_update(sc, WME_AC_BK) ||
2932             !mwl_txq_update(sc, WME_AC_VI) ||
2933             !mwl_txq_update(sc, WME_AC_VO) ? EIO : 0;
2934 }
2935
2936 /*
2937  * Reclaim resources for a setup queue.
2938  */
2939 static void
2940 mwl_tx_cleanupq(struct mwl_softc *sc, struct mwl_txq *txq)
2941 {
2942         /* XXX hal work? */
2943         MWL_TXQ_LOCK_DESTROY(txq);
2944 }
2945
2946 /*
2947  * Reclaim all tx queue resources.
2948  */
2949 static void
2950 mwl_tx_cleanup(struct mwl_softc *sc)
2951 {
2952         int i;
2953
2954         for (i = 0; i < MWL_NUM_TX_QUEUES; i++)
2955                 mwl_tx_cleanupq(sc, &sc->sc_txq[i]);
2956 }
2957
2958 static int
2959 mwl_tx_dmasetup(struct mwl_softc *sc, struct mwl_txbuf *bf, struct mbuf *m0)
2960 {
2961         struct mbuf *m;
2962         int error;
2963
2964         /*
2965          * Load the DMA map so any coalescing is done.  This
2966          * also calculates the number of descriptors we need.
2967          */
2968         error = bus_dmamap_load_mbuf_sg(sc->sc_dmat, bf->bf_dmamap, m0,
2969                                      bf->bf_segs, &bf->bf_nseg,
2970                                      BUS_DMA_NOWAIT);
2971         if (error == EFBIG) {
2972                 /* XXX packet requires too many descriptors */
2973                 bf->bf_nseg = MWL_TXDESC+1;
2974         } else if (error != 0) {
2975                 sc->sc_stats.mst_tx_busdma++;
2976                 m_freem(m0);
2977                 return error;
2978         }
2979         /*
2980          * Discard null packets and check for packets that
2981          * require too many TX descriptors.  We try to convert
2982          * the latter to a cluster.
2983          */
2984         if (error == EFBIG) {           /* too many desc's, linearize */
2985                 sc->sc_stats.mst_tx_linear++;
2986 #if MWL_TXDESC > 1
2987                 m = m_collapse(m0, M_NOWAIT, MWL_TXDESC);
2988 #else
2989                 m = m_defrag(m0, M_NOWAIT);
2990 #endif
2991                 if (m == NULL) {
2992                         m_freem(m0);
2993                         sc->sc_stats.mst_tx_nombuf++;
2994                         return ENOMEM;
2995                 }
2996                 m0 = m;
2997                 error = bus_dmamap_load_mbuf_sg(sc->sc_dmat, bf->bf_dmamap, m0,
2998                                              bf->bf_segs, &bf->bf_nseg,
2999                                              BUS_DMA_NOWAIT);
3000                 if (error != 0) {
3001                         sc->sc_stats.mst_tx_busdma++;
3002                         m_freem(m0);
3003                         return error;
3004                 }
3005                 KASSERT(bf->bf_nseg <= MWL_TXDESC,
3006                     ("too many segments after defrag; nseg %u", bf->bf_nseg));
3007         } else if (bf->bf_nseg == 0) {          /* null packet, discard */
3008                 sc->sc_stats.mst_tx_nodata++;
3009                 m_freem(m0);
3010                 return EIO;
3011         }
3012         DPRINTF(sc, MWL_DEBUG_XMIT, "%s: m %p len %u\n",
3013                 __func__, m0, m0->m_pkthdr.len);
3014         bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap, BUS_DMASYNC_PREWRITE);
3015         bf->bf_m = m0;
3016
3017         return 0;
3018 }
3019
3020 static __inline int
3021 mwl_cvtlegacyrate(int rate)
3022 {
3023         switch (rate) {
3024         case 2:  return 0;
3025         case 4:  return 1;
3026         case 11: return 2;
3027         case 22: return 3;
3028         case 44: return 4;
3029         case 12: return 5;
3030         case 18: return 6;
3031         case 24: return 7;
3032         case 36: return 8;
3033         case 48: return 9;
3034         case 72: return 10;
3035         case 96: return 11;
3036         case 108:return 12;
3037         }
3038         return 0;
3039 }
3040
3041 /*
3042  * Calculate fixed tx rate information per client state;
3043  * this value is suitable for writing to the Format field
3044  * of a tx descriptor.
3045  */
3046 static uint16_t
3047 mwl_calcformat(uint8_t rate, const struct ieee80211_node *ni)
3048 {
3049         uint16_t fmt;
3050
3051         fmt = SM(3, EAGLE_TXD_ANTENNA)
3052             | (IEEE80211_IS_CHAN_HT40D(ni->ni_chan) ?
3053                 EAGLE_TXD_EXTCHAN_LO : EAGLE_TXD_EXTCHAN_HI);
3054         if (rate & IEEE80211_RATE_MCS) {        /* HT MCS */
3055                 fmt |= EAGLE_TXD_FORMAT_HT
3056                     /* NB: 0x80 implicitly stripped from ucastrate */
3057                     | SM(rate, EAGLE_TXD_RATE);
3058                 /* XXX short/long GI may be wrong; re-check */
3059                 if (IEEE80211_IS_CHAN_HT40(ni->ni_chan)) {
3060                         fmt |= EAGLE_TXD_CHW_40
3061                             | (ni->ni_htcap & IEEE80211_HTCAP_SHORTGI40 ?
3062                                 EAGLE_TXD_GI_SHORT : EAGLE_TXD_GI_LONG);
3063                 } else {
3064                         fmt |= EAGLE_TXD_CHW_20
3065                             | (ni->ni_htcap & IEEE80211_HTCAP_SHORTGI20 ?
3066                                 EAGLE_TXD_GI_SHORT : EAGLE_TXD_GI_LONG);
3067                 }
3068         } else {                        /* legacy rate */
3069                 fmt |= EAGLE_TXD_FORMAT_LEGACY
3070                     | SM(mwl_cvtlegacyrate(rate), EAGLE_TXD_RATE)
3071                     | EAGLE_TXD_CHW_20
3072                     /* XXX iv_flags & IEEE80211_F_SHPREAMBLE? */
3073                     | (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE ?
3074                         EAGLE_TXD_PREAMBLE_SHORT : EAGLE_TXD_PREAMBLE_LONG);
3075         }
3076         return fmt;
3077 }
3078
3079 static int
3080 mwl_tx_start(struct mwl_softc *sc, struct ieee80211_node *ni, struct mwl_txbuf *bf,
3081     struct mbuf *m0)
3082 {
3083         struct ieee80211com *ic = &sc->sc_ic;
3084         struct ieee80211vap *vap = ni->ni_vap;
3085         int error, iswep, ismcast;
3086         int hdrlen, copyhdrlen, pktlen;
3087         struct mwl_txdesc *ds;
3088         struct mwl_txq *txq;
3089         struct ieee80211_frame *wh;
3090         struct mwltxrec *tr;
3091         struct mwl_node *mn;
3092         uint16_t qos;
3093 #if MWL_TXDESC > 1
3094         int i;
3095 #endif
3096
3097         wh = mtod(m0, struct ieee80211_frame *);
3098         iswep = wh->i_fc[1] & IEEE80211_FC1_PROTECTED;
3099         ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
3100         hdrlen = ieee80211_anyhdrsize(wh);
3101         copyhdrlen = hdrlen;
3102         pktlen = m0->m_pkthdr.len;
3103         if (IEEE80211_QOS_HAS_SEQ(wh)) {
3104                 if (IEEE80211_IS_DSTODS(wh)) {
3105                         qos = *(uint16_t *)
3106                             (((struct ieee80211_qosframe_addr4 *) wh)->i_qos);
3107                         copyhdrlen -= sizeof(qos);
3108                 } else
3109                         qos = *(uint16_t *)
3110                             (((struct ieee80211_qosframe *) wh)->i_qos);
3111         } else
3112                 qos = 0;
3113
3114         if (iswep) {
3115                 const struct ieee80211_cipher *cip;
3116                 struct ieee80211_key *k;
3117
3118                 /*
3119                  * Construct the 802.11 header+trailer for an encrypted
3120                  * frame. The only reason this can fail is because of an
3121                  * unknown or unsupported cipher/key type.
3122                  *
3123                  * NB: we do this even though the firmware will ignore
3124                  *     what we've done for WEP and TKIP as we need the
3125                  *     ExtIV filled in for CCMP and this also adjusts
3126                  *     the headers which simplifies our work below.
3127                  */
3128                 k = ieee80211_crypto_encap(ni, m0);
3129                 if (k == NULL) {
3130                         /*
3131                          * This can happen when the key is yanked after the
3132                          * frame was queued.  Just discard the frame; the
3133                          * 802.11 layer counts failures and provides
3134                          * debugging/diagnostics.
3135                          */
3136                         m_freem(m0);
3137                         return EIO;
3138                 }
3139                 /*
3140                  * Adjust the packet length for the crypto additions
3141                  * done during encap and any other bits that the f/w
3142                  * will add later on.
3143                  */
3144                 cip = k->wk_cipher;
3145                 pktlen += cip->ic_header + cip->ic_miclen + cip->ic_trailer;
3146
3147                 /* packet header may have moved, reset our local pointer */
3148                 wh = mtod(m0, struct ieee80211_frame *);
3149         }
3150
3151         if (ieee80211_radiotap_active_vap(vap)) {
3152                 sc->sc_tx_th.wt_flags = 0;      /* XXX */
3153                 if (iswep)
3154                         sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
3155 #if 0
3156                 sc->sc_tx_th.wt_rate = ds->DataRate;
3157 #endif
3158                 sc->sc_tx_th.wt_txpower = ni->ni_txpower;
3159                 sc->sc_tx_th.wt_antenna = sc->sc_txantenna;
3160
3161                 ieee80211_radiotap_tx(vap, m0);
3162         }
3163         /*
3164          * Copy up/down the 802.11 header; the firmware requires
3165          * we present a 2-byte payload length followed by a
3166          * 4-address header (w/o QoS), followed (optionally) by
3167          * any WEP/ExtIV header (but only filled in for CCMP).
3168          * We are assured the mbuf has sufficient headroom to
3169          * prepend in-place by the setup of ic_headroom in
3170          * mwl_attach.
3171          */
3172         if (hdrlen < sizeof(struct mwltxrec)) {
3173                 const int space = sizeof(struct mwltxrec) - hdrlen;
3174                 if (M_LEADINGSPACE(m0) < space) {
3175                         /* NB: should never happen */
3176                         device_printf(sc->sc_dev,
3177                             "not enough headroom, need %d found %zd, "
3178                             "m_flags 0x%x m_len %d\n",
3179                             space, M_LEADINGSPACE(m0), m0->m_flags, m0->m_len);
3180                         ieee80211_dump_pkt(ic,
3181                             mtod(m0, const uint8_t *), m0->m_len, 0, -1);
3182                         m_freem(m0);
3183                         sc->sc_stats.mst_tx_noheadroom++;
3184                         return EIO;
3185                 }
3186                 M_PREPEND(m0, space, M_NOWAIT);
3187         }
3188         tr = mtod(m0, struct mwltxrec *);
3189         if (wh != (struct ieee80211_frame *) &tr->wh)
3190                 ovbcopy(wh, &tr->wh, hdrlen);
3191         /*
3192          * Note: the "firmware length" is actually the length
3193          * of the fully formed "802.11 payload".  That is, it's
3194          * everything except for the 802.11 header.  In particular
3195          * this includes all crypto material including the MIC!
3196          */
3197         tr->fwlen = htole16(pktlen - hdrlen);
3198
3199         /*
3200          * Load the DMA map so any coalescing is done.  This
3201          * also calculates the number of descriptors we need.
3202          */
3203         error = mwl_tx_dmasetup(sc, bf, m0);
3204         if (error != 0) {
3205                 /* NB: stat collected in mwl_tx_dmasetup */
3206                 DPRINTF(sc, MWL_DEBUG_XMIT,
3207                     "%s: unable to setup dma\n", __func__);
3208                 return error;
3209         }
3210         bf->bf_node = ni;                       /* NB: held reference */
3211         m0 = bf->bf_m;                          /* NB: may have changed */
3212         tr = mtod(m0, struct mwltxrec *);
3213         wh = (struct ieee80211_frame *)&tr->wh;
3214
3215         /*
3216          * Formulate tx descriptor.
3217          */
3218         ds = bf->bf_desc;
3219         txq = bf->bf_txq;
3220
3221         ds->QosCtrl = qos;                      /* NB: already little-endian */
3222 #if MWL_TXDESC == 1
3223         /*
3224          * NB: multiframes should be zero because the descriptors
3225          *     are initialized to zero.  This should handle the case
3226          *     where the driver is built with MWL_TXDESC=1 but we are
3227          *     using firmware with multi-segment support.
3228          */
3229         ds->PktPtr = htole32(bf->bf_segs[0].ds_addr);
3230         ds->PktLen = htole16(bf->bf_segs[0].ds_len);
3231 #else
3232         ds->multiframes = htole32(bf->bf_nseg);
3233         ds->PktLen = htole16(m0->m_pkthdr.len);
3234         for (i = 0; i < bf->bf_nseg; i++) {
3235                 ds->PktPtrArray[i] = htole32(bf->bf_segs[i].ds_addr);
3236                 ds->PktLenArray[i] = htole16(bf->bf_segs[i].ds_len);
3237         }
3238 #endif
3239         /* NB: pPhysNext, DataRate, and SapPktInfo setup once, don't touch */
3240         ds->Format = 0;
3241         ds->pad = 0;
3242         ds->ack_wcb_addr = 0;
3243
3244         mn = MWL_NODE(ni);
3245         /*
3246          * Select transmit rate.
3247          */
3248         switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) {
3249         case IEEE80211_FC0_TYPE_MGT:
3250                 sc->sc_stats.mst_tx_mgmt++;
3251                 /* fall thru... */
3252         case IEEE80211_FC0_TYPE_CTL:
3253                 /* NB: assign to BE q to avoid bursting */
3254                 ds->TxPriority = MWL_WME_AC_BE;
3255                 break;
3256         case IEEE80211_FC0_TYPE_DATA:
3257                 if (!ismcast) {
3258                         const struct ieee80211_txparam *tp = ni->ni_txparms;
3259                         /*
3260                          * EAPOL frames get forced to a fixed rate and w/o
3261                          * aggregation; otherwise check for any fixed rate
3262                          * for the client (may depend on association state).
3263                          */
3264                         if (m0->m_flags & M_EAPOL) {
3265                                 const struct mwl_vap *mvp = MWL_VAP_CONST(vap);
3266                                 ds->Format = mvp->mv_eapolformat;
3267                                 ds->pad = htole16(
3268                                     EAGLE_TXD_FIXED_RATE | EAGLE_TXD_DONT_AGGR);
3269                         } else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) {
3270                                 /* XXX pre-calculate per node */
3271                                 ds->Format = htole16(
3272                                     mwl_calcformat(tp->ucastrate, ni));
3273                                 ds->pad = htole16(EAGLE_TXD_FIXED_RATE);
3274                         }
3275                         /* NB: EAPOL frames will never have qos set */
3276                         if (qos == 0)
3277                                 ds->TxPriority = txq->qnum;
3278 #if MWL_MAXBA > 3
3279                         else if (mwl_bastream_match(&mn->mn_ba[3], qos))
3280                                 ds->TxPriority = mn->mn_ba[3].txq;
3281 #endif
3282 #if MWL_MAXBA > 2
3283                         else if (mwl_bastream_match(&mn->mn_ba[2], qos))
3284                                 ds->TxPriority = mn->mn_ba[2].txq;
3285 #endif
3286 #if MWL_MAXBA > 1
3287                         else if (mwl_bastream_match(&mn->mn_ba[1], qos))
3288                                 ds->TxPriority = mn->mn_ba[1].txq;
3289 #endif
3290 #if MWL_MAXBA > 0
3291                         else if (mwl_bastream_match(&mn->mn_ba[0], qos))
3292                                 ds->TxPriority = mn->mn_ba[0].txq;
3293 #endif
3294                         else
3295                                 ds->TxPriority = txq->qnum;
3296                 } else
3297                         ds->TxPriority = txq->qnum;
3298                 break;
3299         default:
3300                 device_printf(sc->sc_dev, "bogus frame type 0x%x (%s)\n",
3301                         wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK, __func__);
3302                 sc->sc_stats.mst_tx_badframetype++;
3303                 m_freem(m0);
3304                 return EIO;
3305         }
3306
3307         if (IFF_DUMPPKTS_XMIT(sc))
3308                 ieee80211_dump_pkt(ic,
3309                     mtod(m0, const uint8_t *)+sizeof(uint16_t),
3310                     m0->m_len - sizeof(uint16_t), ds->DataRate, -1);
3311
3312         MWL_TXQ_LOCK(txq);
3313         ds->Status = htole32(EAGLE_TXD_STATUS_FW_OWNED);
3314         STAILQ_INSERT_TAIL(&txq->active, bf, bf_list);
3315         MWL_TXDESC_SYNC(txq, ds, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
3316
3317         sc->sc_tx_timer = 5;
3318         MWL_TXQ_UNLOCK(txq);
3319
3320         return 0;
3321 }
3322
3323 static __inline int
3324 mwl_cvtlegacyrix(int rix)
3325 {
3326         static const int ieeerates[] =
3327             { 2, 4, 11, 22, 44, 12, 18, 24, 36, 48, 72, 96, 108 };
3328         return (rix < nitems(ieeerates) ? ieeerates[rix] : 0);
3329 }
3330
3331 /*
3332  * Process completed xmit descriptors from the specified queue.
3333  */
3334 static int
3335 mwl_tx_processq(struct mwl_softc *sc, struct mwl_txq *txq)
3336 {
3337 #define EAGLE_TXD_STATUS_MCAST \
3338         (EAGLE_TXD_STATUS_MULTICAST_TX | EAGLE_TXD_STATUS_BROADCAST_TX)
3339         struct ieee80211com *ic = &sc->sc_ic;
3340         struct mwl_txbuf *bf;
3341         struct mwl_txdesc *ds;
3342         struct ieee80211_node *ni;
3343         struct mwl_node *an;
3344         int nreaped;
3345         uint32_t status;
3346
3347         DPRINTF(sc, MWL_DEBUG_TX_PROC, "%s: tx queue %u\n", __func__, txq->qnum);
3348         for (nreaped = 0;; nreaped++) {
3349                 MWL_TXQ_LOCK(txq);
3350                 bf = STAILQ_FIRST(&txq->active);
3351                 if (bf == NULL) {
3352                         MWL_TXQ_UNLOCK(txq);
3353                         break;
3354                 }
3355                 ds = bf->bf_desc;
3356                 MWL_TXDESC_SYNC(txq, ds,
3357                     BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
3358                 if (ds->Status & htole32(EAGLE_TXD_STATUS_FW_OWNED)) {
3359                         MWL_TXQ_UNLOCK(txq);
3360                         break;
3361                 }
3362                 STAILQ_REMOVE_HEAD(&txq->active, bf_list);
3363                 MWL_TXQ_UNLOCK(txq);
3364
3365 #ifdef MWL_DEBUG
3366                 if (sc->sc_debug & MWL_DEBUG_XMIT_DESC)
3367                         mwl_printtxbuf(bf, txq->qnum, nreaped);
3368 #endif
3369                 ni = bf->bf_node;
3370                 if (ni != NULL) {
3371                         an = MWL_NODE(ni);
3372                         status = le32toh(ds->Status);
3373                         if (status & EAGLE_TXD_STATUS_OK) {
3374                                 uint16_t Format = le16toh(ds->Format);
3375                                 uint8_t txant = MS(Format, EAGLE_TXD_ANTENNA);
3376
3377                                 sc->sc_stats.mst_ant_tx[txant]++;
3378                                 if (status & EAGLE_TXD_STATUS_OK_RETRY)
3379                                         sc->sc_stats.mst_tx_retries++;
3380                                 if (status & EAGLE_TXD_STATUS_OK_MORE_RETRY)
3381                                         sc->sc_stats.mst_tx_mretries++;
3382                                 if (txq->qnum >= MWL_WME_AC_VO)
3383                                         ic->ic_wme.wme_hipri_traffic++;
3384                                 ni->ni_txrate = MS(Format, EAGLE_TXD_RATE);
3385                                 if ((Format & EAGLE_TXD_FORMAT_HT) == 0) {
3386                                         ni->ni_txrate = mwl_cvtlegacyrix(
3387                                             ni->ni_txrate);
3388                                 } else
3389                                         ni->ni_txrate |= IEEE80211_RATE_MCS;
3390                                 sc->sc_stats.mst_tx_rate = ni->ni_txrate;
3391                         } else {
3392                                 if (status & EAGLE_TXD_STATUS_FAILED_LINK_ERROR)
3393                                         sc->sc_stats.mst_tx_linkerror++;
3394                                 if (status & EAGLE_TXD_STATUS_FAILED_XRETRY)
3395                                         sc->sc_stats.mst_tx_xretries++;
3396                                 if (status & EAGLE_TXD_STATUS_FAILED_AGING)
3397                                         sc->sc_stats.mst_tx_aging++;
3398                                 if (bf->bf_m->m_flags & M_FF)
3399                                         sc->sc_stats.mst_ff_txerr++;
3400                         }
3401                         if (bf->bf_m->m_flags & M_TXCB)
3402                                 /* XXX strip fw len in case header inspected */
3403                                 m_adj(bf->bf_m, sizeof(uint16_t));
3404                         ieee80211_tx_complete(ni, bf->bf_m,
3405                             (status & EAGLE_TXD_STATUS_OK) == 0);
3406                 } else
3407                         m_freem(bf->bf_m);
3408                 ds->Status = htole32(EAGLE_TXD_STATUS_IDLE);
3409
3410                 bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap,
3411                     BUS_DMASYNC_POSTWRITE);
3412                 bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap);
3413
3414                 mwl_puttxbuf_tail(txq, bf);
3415         }
3416         return nreaped;
3417 #undef EAGLE_TXD_STATUS_MCAST
3418 }
3419
3420 /*
3421  * Deferred processing of transmit interrupt; special-cased
3422  * for four hardware queues, 0-3.
3423  */
3424 static void
3425 mwl_tx_proc(void *arg, int npending)
3426 {
3427         struct mwl_softc *sc = arg;
3428         int nreaped;
3429
3430         /*
3431          * Process each active queue.
3432          */
3433         nreaped = 0;
3434         if (!STAILQ_EMPTY(&sc->sc_txq[0].active))
3435                 nreaped += mwl_tx_processq(sc, &sc->sc_txq[0]);
3436         if (!STAILQ_EMPTY(&sc->sc_txq[1].active))
3437                 nreaped += mwl_tx_processq(sc, &sc->sc_txq[1]);
3438         if (!STAILQ_EMPTY(&sc->sc_txq[2].active))
3439                 nreaped += mwl_tx_processq(sc, &sc->sc_txq[2]);
3440         if (!STAILQ_EMPTY(&sc->sc_txq[3].active))
3441                 nreaped += mwl_tx_processq(sc, &sc->sc_txq[3]);
3442
3443         if (nreaped != 0) {
3444                 sc->sc_tx_timer = 0;
3445                 if (mbufq_first(&sc->sc_snd) != NULL) {
3446                         /* NB: kick fw; the tx thread may have been preempted */
3447                         mwl_hal_txstart(sc->sc_mh, 0);
3448                         mwl_start(sc);
3449                 }
3450         }
3451 }
3452
3453 static void
3454 mwl_tx_draintxq(struct mwl_softc *sc, struct mwl_txq *txq)
3455 {
3456         struct ieee80211_node *ni;
3457         struct mwl_txbuf *bf;
3458         u_int ix;
3459
3460         /*
3461          * NB: this assumes output has been stopped and
3462          *     we do not need to block mwl_tx_tasklet
3463          */
3464         for (ix = 0;; ix++) {
3465                 MWL_TXQ_LOCK(txq);
3466                 bf = STAILQ_FIRST(&txq->active);
3467                 if (bf == NULL) {
3468                         MWL_TXQ_UNLOCK(txq);
3469                         break;
3470                 }
3471                 STAILQ_REMOVE_HEAD(&txq->active, bf_list);
3472                 MWL_TXQ_UNLOCK(txq);
3473 #ifdef MWL_DEBUG
3474                 if (sc->sc_debug & MWL_DEBUG_RESET) {
3475                         struct ieee80211com *ic = &sc->sc_ic;
3476                         const struct mwltxrec *tr =
3477                             mtod(bf->bf_m, const struct mwltxrec *);
3478                         mwl_printtxbuf(bf, txq->qnum, ix);
3479                         ieee80211_dump_pkt(ic, (const uint8_t *)&tr->wh,
3480                                 bf->bf_m->m_len - sizeof(tr->fwlen), 0, -1);
3481                 }
3482 #endif /* MWL_DEBUG */
3483                 bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap);
3484                 ni = bf->bf_node;
3485                 if (ni != NULL) {
3486                         /*
3487                          * Reclaim node reference.
3488                          */
3489                         ieee80211_free_node(ni);
3490                 }
3491                 m_freem(bf->bf_m);
3492
3493                 mwl_puttxbuf_tail(txq, bf);
3494         }
3495 }
3496
3497 /*
3498  * Drain the transmit queues and reclaim resources.
3499  */
3500 static void
3501 mwl_draintxq(struct mwl_softc *sc)
3502 {
3503         int i;
3504
3505         for (i = 0; i < MWL_NUM_TX_QUEUES; i++)
3506                 mwl_tx_draintxq(sc, &sc->sc_txq[i]);
3507         sc->sc_tx_timer = 0;
3508 }
3509
3510 #ifdef MWL_DIAGAPI
3511 /*
3512  * Reset the transmit queues to a pristine state after a fw download.
3513  */
3514 static void
3515 mwl_resettxq(struct mwl_softc *sc)
3516 {
3517         int i;
3518
3519         for (i = 0; i < MWL_NUM_TX_QUEUES; i++)
3520                 mwl_txq_reset(sc, &sc->sc_txq[i]);
3521 }
3522 #endif /* MWL_DIAGAPI */
3523
3524 /*
3525  * Clear the transmit queues of any frames submitted for the
3526  * specified vap.  This is done when the vap is deleted so we
3527  * don't potentially reference the vap after it is gone.
3528  * Note we cannot remove the frames; we only reclaim the node
3529  * reference.
3530  */
3531 static void
3532 mwl_cleartxq(struct mwl_softc *sc, struct ieee80211vap *vap)
3533 {
3534         struct mwl_txq *txq;
3535         struct mwl_txbuf *bf;
3536         int i;
3537
3538         for (i = 0; i < MWL_NUM_TX_QUEUES; i++) {
3539                 txq = &sc->sc_txq[i];
3540                 MWL_TXQ_LOCK(txq);
3541                 STAILQ_FOREACH(bf, &txq->active, bf_list) {
3542                         struct ieee80211_node *ni = bf->bf_node;
3543                         if (ni != NULL && ni->ni_vap == vap) {
3544                                 bf->bf_node = NULL;
3545                                 ieee80211_free_node(ni);
3546                         }
3547                 }
3548                 MWL_TXQ_UNLOCK(txq);
3549         }
3550 }
3551
3552 static int
3553 mwl_recv_action(struct ieee80211_node *ni, const struct ieee80211_frame *wh,
3554         const uint8_t *frm, const uint8_t *efrm)
3555 {
3556         struct mwl_softc *sc = ni->ni_ic->ic_softc;
3557         const struct ieee80211_action *ia;
3558
3559         ia = (const struct ieee80211_action *) frm;
3560         if (ia->ia_category == IEEE80211_ACTION_CAT_HT &&
3561             ia->ia_action == IEEE80211_ACTION_HT_MIMOPWRSAVE) {
3562                 const struct ieee80211_action_ht_mimopowersave *mps =
3563                     (const struct ieee80211_action_ht_mimopowersave *) ia;
3564
3565                 mwl_hal_setmimops(sc->sc_mh, ni->ni_macaddr,
3566                     mps->am_control & IEEE80211_A_HT_MIMOPWRSAVE_ENA,
3567                     MS(mps->am_control, IEEE80211_A_HT_MIMOPWRSAVE_MODE));
3568                 return 0;
3569         } else
3570                 return sc->sc_recv_action(ni, wh, frm, efrm);
3571 }
3572
3573 static int
3574 mwl_addba_request(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
3575         int dialogtoken, int baparamset, int batimeout)
3576 {
3577         struct mwl_softc *sc = ni->ni_ic->ic_softc;
3578         struct ieee80211vap *vap = ni->ni_vap;
3579         struct mwl_node *mn = MWL_NODE(ni);
3580         struct mwl_bastate *bas;
3581
3582         bas = tap->txa_private;
3583         if (bas == NULL) {
3584                 const MWL_HAL_BASTREAM *sp;
3585                 /*
3586                  * Check for a free BA stream slot.
3587                  */
3588 #if MWL_MAXBA > 3
3589                 if (mn->mn_ba[3].bastream == NULL)
3590                         bas = &mn->mn_ba[3];
3591                 else
3592 #endif
3593 #if MWL_MAXBA > 2
3594                 if (mn->mn_ba[2].bastream == NULL)
3595                         bas = &mn->mn_ba[2];
3596                 else
3597 #endif
3598 #if MWL_MAXBA > 1
3599                 if (mn->mn_ba[1].bastream == NULL)
3600                         bas = &mn->mn_ba[1];
3601                 else
3602 #endif
3603 #if MWL_MAXBA > 0
3604                 if (mn->mn_ba[0].bastream == NULL)
3605                         bas = &mn->mn_ba[0];
3606                 else 
3607 #endif
3608                 {
3609                         /* sta already has max BA streams */
3610                         /* XXX assign BA stream to highest priority tid */
3611                         DPRINTF(sc, MWL_DEBUG_AMPDU,
3612                             "%s: already has max bastreams\n", __func__);
3613                         sc->sc_stats.mst_ampdu_reject++;
3614                         return 0;
3615                 }
3616                 /* NB: no held reference to ni */
3617                 sp = mwl_hal_bastream_alloc(MWL_VAP(vap)->mv_hvap,
3618                     (baparamset & IEEE80211_BAPS_POLICY_IMMEDIATE) != 0,
3619                     ni->ni_macaddr, tap->txa_tid, ni->ni_htparam,
3620                     ni, tap);
3621                 if (sp == NULL) {
3622                         /*
3623                          * No available stream, return 0 so no
3624                          * a-mpdu aggregation will be done.
3625                          */
3626                         DPRINTF(sc, MWL_DEBUG_AMPDU,
3627                             "%s: no bastream available\n", __func__);
3628                         sc->sc_stats.mst_ampdu_nostream++;
3629                         return 0;
3630                 }
3631                 DPRINTF(sc, MWL_DEBUG_AMPDU, "%s: alloc bastream %p\n",
3632                     __func__, sp);
3633                 /* NB: qos is left zero so we won't match in mwl_tx_start */
3634                 bas->bastream = sp;
3635                 tap->txa_private = bas;
3636         }
3637         /* fetch current seq# from the firmware; if available */
3638         if (mwl_hal_bastream_get_seqno(sc->sc_mh, bas->bastream,
3639             vap->iv_opmode == IEEE80211_M_STA ? vap->iv_myaddr : ni->ni_macaddr,
3640             &tap->txa_start) != 0)
3641                 tap->txa_start = 0;
3642         return sc->sc_addba_request(ni, tap, dialogtoken, baparamset, batimeout);
3643 }
3644
3645 static int
3646 mwl_addba_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
3647         int code, int baparamset, int batimeout)
3648 {
3649         struct mwl_softc *sc = ni->ni_ic->ic_softc;
3650         struct mwl_bastate *bas;
3651
3652         bas = tap->txa_private;
3653         if (bas == NULL) {
3654                 /* XXX should not happen */
3655                 DPRINTF(sc, MWL_DEBUG_AMPDU,
3656                     "%s: no BA stream allocated, TID %d\n",
3657                     __func__, tap->txa_tid);
3658                 sc->sc_stats.mst_addba_nostream++;
3659                 return 0;
3660         }
3661         if (code == IEEE80211_STATUS_SUCCESS) {
3662                 struct ieee80211vap *vap = ni->ni_vap;
3663                 int bufsiz, error;
3664
3665                 /*
3666                  * Tell the firmware to setup the BA stream;
3667                  * we know resources are available because we
3668                  * pre-allocated one before forming the request.
3669                  */
3670                 bufsiz = MS(baparamset, IEEE80211_BAPS_BUFSIZ);
3671                 if (bufsiz == 0)
3672                         bufsiz = IEEE80211_AGGR_BAWMAX;
3673                 error = mwl_hal_bastream_create(MWL_VAP(vap)->mv_hvap,
3674                     bas->bastream, bufsiz, bufsiz, tap->txa_start);
3675                 if (error != 0) {
3676                         /*
3677                          * Setup failed, return immediately so no a-mpdu
3678                          * aggregation will be done.
3679                          */
3680                         mwl_hal_bastream_destroy(sc->sc_mh, bas->bastream);
3681                         mwl_bastream_free(bas);
3682                         tap->txa_private = NULL;
3683
3684                         DPRINTF(sc, MWL_DEBUG_AMPDU,
3685                             "%s: create failed, error %d, bufsiz %d TID %d "
3686                             "htparam 0x%x\n", __func__, error, bufsiz,
3687                             tap->txa_tid, ni->ni_htparam);
3688                         sc->sc_stats.mst_bacreate_failed++;
3689                         return 0;
3690                 }
3691                 /* NB: cache txq to avoid ptr indirect */
3692                 mwl_bastream_setup(bas, tap->txa_tid, bas->bastream->txq);
3693                 DPRINTF(sc, MWL_DEBUG_AMPDU,
3694                     "%s: bastream %p assigned to txq %d TID %d bufsiz %d "
3695                     "htparam 0x%x\n", __func__, bas->bastream,
3696                     bas->txq, tap->txa_tid, bufsiz, ni->ni_htparam);
3697         } else {
3698                 /*
3699                  * Other side NAK'd us; return the resources.
3700                  */
3701                 DPRINTF(sc, MWL_DEBUG_AMPDU,
3702                     "%s: request failed with code %d, destroy bastream %p\n",
3703                     __func__, code, bas->bastream);
3704                 mwl_hal_bastream_destroy(sc->sc_mh, bas->bastream);
3705                 mwl_bastream_free(bas);
3706                 tap->txa_private = NULL;
3707         }
3708         /* NB: firmware sends BAR so we don't need to */
3709         return sc->sc_addba_response(ni, tap, code, baparamset, batimeout);
3710 }
3711
3712 static void
3713 mwl_addba_stop(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap)
3714 {
3715         struct mwl_softc *sc = ni->ni_ic->ic_softc;
3716         struct mwl_bastate *bas;
3717
3718         bas = tap->txa_private;
3719         if (bas != NULL) {
3720                 DPRINTF(sc, MWL_DEBUG_AMPDU, "%s: destroy bastream %p\n",
3721                     __func__, bas->bastream);
3722                 mwl_hal_bastream_destroy(sc->sc_mh, bas->bastream);
3723                 mwl_bastream_free(bas);
3724                 tap->txa_private = NULL;
3725         }
3726         sc->sc_addba_stop(ni, tap);
3727 }
3728
3729 /*
3730  * Setup the rx data structures.  This should only be
3731  * done once or we may get out of sync with the firmware.
3732  */
3733 static int
3734 mwl_startrecv(struct mwl_softc *sc)
3735 {
3736         if (!sc->sc_recvsetup) {
3737                 struct mwl_rxbuf *bf, *prev;
3738                 struct mwl_rxdesc *ds;
3739
3740                 prev = NULL;
3741                 STAILQ_FOREACH(bf, &sc->sc_rxbuf, bf_list) {
3742                         int error = mwl_rxbuf_init(sc, bf);
3743                         if (error != 0) {
3744                                 DPRINTF(sc, MWL_DEBUG_RECV,
3745                                         "%s: mwl_rxbuf_init failed %d\n",
3746                                         __func__, error);
3747                                 return error;
3748                         }
3749                         if (prev != NULL) {
3750                                 ds = prev->bf_desc;
3751                                 ds->pPhysNext = htole32(bf->bf_daddr);
3752                         }
3753                         prev = bf;
3754                 }
3755                 if (prev != NULL) {
3756                         ds = prev->bf_desc;
3757                         ds->pPhysNext =
3758                             htole32(STAILQ_FIRST(&sc->sc_rxbuf)->bf_daddr);
3759                 }
3760                 sc->sc_recvsetup = 1;
3761         }
3762         mwl_mode_init(sc);              /* set filters, etc. */
3763         return 0;
3764 }
3765
3766 static MWL_HAL_APMODE
3767 mwl_getapmode(const struct ieee80211vap *vap, struct ieee80211_channel *chan)
3768 {
3769         MWL_HAL_APMODE mode;
3770
3771         if (IEEE80211_IS_CHAN_HT(chan)) {
3772                 if (vap->iv_flags_ht & IEEE80211_FHT_PUREN)
3773                         mode = AP_MODE_N_ONLY;
3774                 else if (IEEE80211_IS_CHAN_5GHZ(chan))
3775                         mode = AP_MODE_AandN;
3776                 else if (vap->iv_flags & IEEE80211_F_PUREG)
3777                         mode = AP_MODE_GandN;
3778                 else
3779                         mode = AP_MODE_BandGandN;
3780         } else if (IEEE80211_IS_CHAN_ANYG(chan)) {
3781                 if (vap->iv_flags & IEEE80211_F_PUREG)
3782                         mode = AP_MODE_G_ONLY;
3783                 else
3784                         mode = AP_MODE_MIXED;
3785         } else if (IEEE80211_IS_CHAN_B(chan))
3786                 mode = AP_MODE_B_ONLY;
3787         else if (IEEE80211_IS_CHAN_A(chan))
3788                 mode = AP_MODE_A_ONLY;
3789         else
3790                 mode = AP_MODE_MIXED;           /* XXX should not happen? */
3791         return mode;
3792 }
3793
3794 static int
3795 mwl_setapmode(struct ieee80211vap *vap, struct ieee80211_channel *chan)
3796 {
3797         struct mwl_hal_vap *hvap = MWL_VAP(vap)->mv_hvap;
3798         return mwl_hal_setapmode(hvap, mwl_getapmode(vap, chan));
3799 }
3800
3801 /*
3802  * Set/change channels.
3803  */
3804 static int
3805 mwl_chan_set(struct mwl_softc *sc, struct ieee80211_channel *chan)
3806 {
3807         struct mwl_hal *mh = sc->sc_mh;
3808         struct ieee80211com *ic = &sc->sc_ic;
3809         MWL_HAL_CHANNEL hchan;
3810         int maxtxpow;
3811
3812         DPRINTF(sc, MWL_DEBUG_RESET, "%s: chan %u MHz/flags 0x%x\n",
3813             __func__, chan->ic_freq, chan->ic_flags);
3814
3815         /*
3816          * Convert to a HAL channel description with
3817          * the flags constrained to reflect the current
3818          * operating mode.
3819          */
3820         mwl_mapchan(&hchan, chan);
3821         mwl_hal_intrset(mh, 0);         /* disable interrupts */
3822 #if 0
3823         mwl_draintxq(sc);               /* clear pending tx frames */
3824 #endif
3825         mwl_hal_setchannel(mh, &hchan);
3826         /*
3827          * Tx power is cap'd by the regulatory setting and
3828          * possibly a user-set limit.  We pass the min of
3829          * these to the hal to apply them to the cal data
3830          * for this channel.
3831          * XXX min bound?
3832          */
3833         maxtxpow = 2*chan->ic_maxregpower;
3834         if (maxtxpow > ic->ic_txpowlimit)
3835                 maxtxpow = ic->ic_txpowlimit;
3836         mwl_hal_settxpower(mh, &hchan, maxtxpow / 2);
3837         /* NB: potentially change mcast/mgt rates */
3838         mwl_setcurchanrates(sc);
3839
3840         /*
3841          * Update internal state.
3842          */
3843         sc->sc_tx_th.wt_chan_freq = htole16(chan->ic_freq);
3844         sc->sc_rx_th.wr_chan_freq = htole16(chan->ic_freq);
3845         if (IEEE80211_IS_CHAN_A(chan)) {
3846                 sc->sc_tx_th.wt_chan_flags = htole16(IEEE80211_CHAN_A);
3847                 sc->sc_rx_th.wr_chan_flags = htole16(IEEE80211_CHAN_A);
3848         } else if (IEEE80211_IS_CHAN_ANYG(chan)) {
3849                 sc->sc_tx_th.wt_chan_flags = htole16(IEEE80211_CHAN_G);
3850                 sc->sc_rx_th.wr_chan_flags = htole16(IEEE80211_CHAN_G);
3851         } else {
3852                 sc->sc_tx_th.wt_chan_flags = htole16(IEEE80211_CHAN_B);
3853                 sc->sc_rx_th.wr_chan_flags = htole16(IEEE80211_CHAN_B);
3854         }
3855         sc->sc_curchan = hchan;
3856         mwl_hal_intrset(mh, sc->sc_imask);
3857
3858         return 0;
3859 }
3860
3861 static void
3862 mwl_scan_start(struct ieee80211com *ic)
3863 {
3864         struct mwl_softc *sc = ic->ic_softc;
3865
3866         DPRINTF(sc, MWL_DEBUG_STATE, "%s\n", __func__);
3867 }
3868
3869 static void
3870 mwl_scan_end(struct ieee80211com *ic)
3871 {
3872         struct mwl_softc *sc = ic->ic_softc;
3873
3874         DPRINTF(sc, MWL_DEBUG_STATE, "%s\n", __func__);
3875 }
3876
3877 static void
3878 mwl_set_channel(struct ieee80211com *ic)
3879 {
3880         struct mwl_softc *sc = ic->ic_softc;
3881
3882         (void) mwl_chan_set(sc, ic->ic_curchan);
3883 }
3884
3885 /* 
3886  * Handle a channel switch request.  We inform the firmware
3887  * and mark the global state to suppress various actions.
3888  * NB: we issue only one request to the fw; we may be called
3889  * multiple times if there are multiple vap's.
3890  */
3891 static void
3892 mwl_startcsa(struct ieee80211vap *vap)
3893 {
3894         struct ieee80211com *ic = vap->iv_ic;
3895         struct mwl_softc *sc = ic->ic_softc;
3896         MWL_HAL_CHANNEL hchan;
3897
3898         if (sc->sc_csapending)
3899                 return;
3900
3901         mwl_mapchan(&hchan, ic->ic_csa_newchan);
3902         /* 1 =>'s quiet channel */
3903         mwl_hal_setchannelswitchie(sc->sc_mh, &hchan, 1, ic->ic_csa_count);
3904         sc->sc_csapending = 1;
3905 }
3906
3907 /*
3908  * Plumb any static WEP key for the station.  This is
3909  * necessary as we must propagate the key from the
3910  * global key table of the vap to each sta db entry.
3911  */
3912 static void
3913 mwl_setanywepkey(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
3914 {
3915         if ((vap->iv_flags & (IEEE80211_F_PRIVACY|IEEE80211_F_WPA)) ==
3916                 IEEE80211_F_PRIVACY &&
3917             vap->iv_def_txkey != IEEE80211_KEYIX_NONE &&
3918             vap->iv_nw_keys[vap->iv_def_txkey].wk_keyix != IEEE80211_KEYIX_NONE)
3919                 (void) _mwl_key_set(vap, &vap->iv_nw_keys[vap->iv_def_txkey],
3920                                     mac);
3921 }
3922
3923 static int
3924 mwl_peerstadb(struct ieee80211_node *ni, int aid, int staid, MWL_HAL_PEERINFO *pi)
3925 {
3926 #define WME(ie) ((const struct ieee80211_wme_info *) ie)
3927         struct ieee80211vap *vap = ni->ni_vap;
3928         struct mwl_hal_vap *hvap;
3929         int error;
3930
3931         if (vap->iv_opmode == IEEE80211_M_WDS) {
3932                 /*
3933                  * WDS vap's do not have a f/w vap; instead they piggyback
3934                  * on an AP vap and we must install the sta db entry and
3935                  * crypto state using that AP's handle (the WDS vap has none).
3936                  */
3937                 hvap = MWL_VAP(vap)->mv_ap_hvap;
3938         } else
3939                 hvap = MWL_VAP(vap)->mv_hvap;
3940         error = mwl_hal_newstation(hvap, ni->ni_macaddr,
3941             aid, staid, pi,
3942             ni->ni_flags & (IEEE80211_NODE_QOS | IEEE80211_NODE_HT),
3943             ni->ni_ies.wme_ie != NULL ? WME(ni->ni_ies.wme_ie)->wme_info : 0);
3944         if (error == 0) {
3945                 /*
3946                  * Setup security for this station.  For sta mode this is
3947                  * needed even though do the same thing on transition to
3948                  * AUTH state because the call to mwl_hal_newstation
3949                  * clobbers the crypto state we setup.
3950                  */
3951                 mwl_setanywepkey(vap, ni->ni_macaddr);
3952         }
3953         return error;
3954 #undef WME
3955 }
3956
3957 static void
3958 mwl_setglobalkeys(struct ieee80211vap *vap)
3959 {
3960         struct ieee80211_key *wk;
3961
3962         wk = &vap->iv_nw_keys[0];
3963         for (; wk < &vap->iv_nw_keys[IEEE80211_WEP_NKID]; wk++)
3964                 if (wk->wk_keyix != IEEE80211_KEYIX_NONE)
3965                         (void) _mwl_key_set(vap, wk, vap->iv_myaddr);
3966 }
3967
3968 /*
3969  * Convert a legacy rate set to a firmware bitmask.
3970  */
3971 static uint32_t
3972 get_rate_bitmap(const struct ieee80211_rateset *rs)
3973 {
3974         uint32_t rates;
3975         int i;
3976
3977         rates = 0;
3978         for (i = 0; i < rs->rs_nrates; i++)
3979                 switch (rs->rs_rates[i] & IEEE80211_RATE_VAL) {
3980                 case 2:   rates |= 0x001; break;
3981                 case 4:   rates |= 0x002; break;
3982                 case 11:  rates |= 0x004; break;
3983                 case 22:  rates |= 0x008; break;
3984                 case 44:  rates |= 0x010; break;
3985                 case 12:  rates |= 0x020; break;
3986                 case 18:  rates |= 0x040; break;
3987                 case 24:  rates |= 0x080; break;
3988                 case 36:  rates |= 0x100; break;
3989                 case 48:  rates |= 0x200; break;
3990                 case 72:  rates |= 0x400; break;
3991                 case 96:  rates |= 0x800; break;
3992                 case 108: rates |= 0x1000; break;
3993                 }
3994         return rates;
3995 }
3996
3997 /*
3998  * Construct an HT firmware bitmask from an HT rate set.
3999  */
4000 static uint32_t
4001 get_htrate_bitmap(const struct ieee80211_htrateset *rs)
4002 {
4003         uint32_t rates;
4004         int i;
4005
4006         rates = 0;
4007         for (i = 0; i < rs->rs_nrates; i++) {
4008                 if (rs->rs_rates[i] < 16)
4009                         rates |= 1<<rs->rs_rates[i];
4010         }
4011         return rates;
4012 }
4013
4014 /*
4015  * Craft station database entry for station.
4016  * NB: use host byte order here, the hal handles byte swapping.
4017  */
4018 static MWL_HAL_PEERINFO *
4019 mkpeerinfo(MWL_HAL_PEERINFO *pi, const struct ieee80211_node *ni)
4020 {
4021         const struct ieee80211vap *vap = ni->ni_vap;
4022
4023         memset(pi, 0, sizeof(*pi));
4024         pi->LegacyRateBitMap = get_rate_bitmap(&ni->ni_rates);
4025         pi->CapInfo = ni->ni_capinfo;
4026         if (ni->ni_flags & IEEE80211_NODE_HT) {
4027                 /* HT capabilities, etc */
4028                 pi->HTCapabilitiesInfo = ni->ni_htcap;
4029                 /* XXX pi.HTCapabilitiesInfo */
4030                 pi->MacHTParamInfo = ni->ni_htparam;    
4031                 pi->HTRateBitMap = get_htrate_bitmap(&ni->ni_htrates);
4032                 pi->AddHtInfo.ControlChan = ni->ni_htctlchan;
4033                 pi->AddHtInfo.AddChan = ni->ni_ht2ndchan;
4034                 pi->AddHtInfo.OpMode = ni->ni_htopmode;
4035                 pi->AddHtInfo.stbc = ni->ni_htstbc;
4036
4037                 /* constrain according to local configuration */
4038                 if ((vap->iv_flags_ht & IEEE80211_FHT_SHORTGI40) == 0)
4039                         pi->HTCapabilitiesInfo &= ~IEEE80211_HTCAP_SHORTGI40;
4040                 if ((vap->iv_flags_ht & IEEE80211_FHT_SHORTGI20) == 0)
4041                         pi->HTCapabilitiesInfo &= ~IEEE80211_HTCAP_SHORTGI20;
4042                 if (ni->ni_chw != 40)
4043                         pi->HTCapabilitiesInfo &= ~IEEE80211_HTCAP_CHWIDTH40;
4044         }
4045         return pi;
4046 }
4047
4048 /*
4049  * Re-create the local sta db entry for a vap to ensure
4050  * up to date WME state is pushed to the firmware.  Because
4051  * this resets crypto state this must be followed by a
4052  * reload of any keys in the global key table.
4053  */
4054 static int
4055 mwl_localstadb(struct ieee80211vap *vap)
4056 {
4057 #define WME(ie) ((const struct ieee80211_wme_info *) ie)
4058         struct mwl_hal_vap *hvap = MWL_VAP(vap)->mv_hvap;
4059         struct ieee80211_node *bss;
4060         MWL_HAL_PEERINFO pi;
4061         int error;
4062
4063         switch (vap->iv_opmode) {
4064         case IEEE80211_M_STA:
4065                 bss = vap->iv_bss;
4066                 error = mwl_hal_newstation(hvap, vap->iv_myaddr, 0, 0,
4067                     vap->iv_state == IEEE80211_S_RUN ?
4068                         mkpeerinfo(&pi, bss) : NULL,
4069                     (bss->ni_flags & (IEEE80211_NODE_QOS | IEEE80211_NODE_HT)),
4070                     bss->ni_ies.wme_ie != NULL ?
4071                         WME(bss->ni_ies.wme_ie)->wme_info : 0);
4072                 if (error == 0)
4073                         mwl_setglobalkeys(vap);
4074                 break;
4075         case IEEE80211_M_HOSTAP:
4076         case IEEE80211_M_MBSS:
4077                 error = mwl_hal_newstation(hvap, vap->iv_myaddr,
4078                     0, 0, NULL, vap->iv_flags & IEEE80211_F_WME, 0);
4079                 if (error == 0)
4080                         mwl_setglobalkeys(vap);
4081                 break;
4082         default:
4083                 error = 0;
4084                 break;
4085         }
4086         return error;
4087 #undef WME
4088 }
4089
4090 static int
4091 mwl_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
4092 {
4093         struct mwl_vap *mvp = MWL_VAP(vap);
4094         struct mwl_hal_vap *hvap = mvp->mv_hvap;
4095         struct ieee80211com *ic = vap->iv_ic;
4096         struct ieee80211_node *ni = NULL;
4097         struct mwl_softc *sc = ic->ic_softc;
4098         struct mwl_hal *mh = sc->sc_mh;
4099         enum ieee80211_state ostate = vap->iv_state;
4100         int error;
4101
4102         DPRINTF(sc, MWL_DEBUG_STATE, "%s: %s: %s -> %s\n",
4103             vap->iv_ifp->if_xname, __func__,
4104             ieee80211_state_name[ostate], ieee80211_state_name[nstate]);
4105
4106         callout_stop(&sc->sc_timer);
4107         /*
4108          * Clear current radar detection state.
4109          */
4110         if (ostate == IEEE80211_S_CAC) {
4111                 /* stop quiet mode radar detection */
4112                 mwl_hal_setradardetection(mh, DR_CHK_CHANNEL_AVAILABLE_STOP);
4113         } else if (sc->sc_radarena) {
4114                 /* stop in-service radar detection */
4115                 mwl_hal_setradardetection(mh, DR_DFS_DISABLE);
4116                 sc->sc_radarena = 0;
4117         }
4118         /*
4119          * Carry out per-state actions before doing net80211 work.
4120          */
4121         if (nstate == IEEE80211_S_INIT) {
4122                 /* NB: only ap+sta vap's have a fw entity */
4123                 if (hvap != NULL)
4124                         mwl_hal_stop(hvap);
4125         } else if (nstate == IEEE80211_S_SCAN) {
4126                 mwl_hal_start(hvap);
4127                 /* NB: this disables beacon frames */
4128                 mwl_hal_setinframode(hvap);
4129         } else if (nstate == IEEE80211_S_AUTH) {
4130                 /*
4131                  * Must create a sta db entry in case a WEP key needs to
4132                  * be plumbed.  This entry will be overwritten if we
4133                  * associate; otherwise it will be reclaimed on node free.
4134                  */
4135                 ni = vap->iv_bss;
4136                 MWL_NODE(ni)->mn_hvap = hvap;
4137                 (void) mwl_peerstadb(ni, 0, 0, NULL);
4138         } else if (nstate == IEEE80211_S_CSA) {
4139                 /* XXX move to below? */
4140                 if (vap->iv_opmode == IEEE80211_M_HOSTAP ||
4141                     vap->iv_opmode == IEEE80211_M_MBSS)
4142                         mwl_startcsa(vap);
4143         } else if (nstate == IEEE80211_S_CAC) {
4144                 /* XXX move to below? */
4145                 /* stop ap xmit and enable quiet mode radar detection */
4146                 mwl_hal_setradardetection(mh, DR_CHK_CHANNEL_AVAILABLE_START);
4147         }
4148
4149         /*
4150          * Invoke the parent method to do net80211 work.
4151          */
4152         error = mvp->mv_newstate(vap, nstate, arg);
4153
4154         /*
4155          * Carry out work that must be done after net80211 runs;
4156          * this work requires up to date state (e.g. iv_bss).
4157          */
4158         if (error == 0 && nstate == IEEE80211_S_RUN) {
4159                 /* NB: collect bss node again, it may have changed */
4160                 ni = vap->iv_bss;
4161
4162                 DPRINTF(sc, MWL_DEBUG_STATE,
4163                     "%s: %s(RUN): iv_flags 0x%08x bintvl %d bssid %s "
4164                     "capinfo 0x%04x chan %d\n",
4165                     vap->iv_ifp->if_xname, __func__, vap->iv_flags,
4166                     ni->ni_intval, ether_sprintf(ni->ni_bssid), ni->ni_capinfo,
4167                     ieee80211_chan2ieee(ic, ic->ic_curchan));
4168
4169                 /*
4170                  * Recreate local sta db entry to update WME/HT state.
4171                  */
4172                 mwl_localstadb(vap);
4173                 switch (vap->iv_opmode) {
4174                 case IEEE80211_M_HOSTAP:
4175                 case IEEE80211_M_MBSS:
4176                         if (ostate == IEEE80211_S_CAC) {
4177                                 /* enable in-service radar detection */
4178                                 mwl_hal_setradardetection(mh,
4179                                     DR_IN_SERVICE_MONITOR_START);
4180                                 sc->sc_radarena = 1;
4181                         }
4182                         /*
4183                          * Allocate and setup the beacon frame
4184                          * (and related state).
4185                          */
4186                         error = mwl_reset_vap(vap, IEEE80211_S_RUN);
4187                         if (error != 0) {
4188                                 DPRINTF(sc, MWL_DEBUG_STATE,
4189                                     "%s: beacon setup failed, error %d\n",
4190                                     __func__, error);
4191                                 goto bad;
4192                         }
4193                         /* NB: must be after setting up beacon */
4194                         mwl_hal_start(hvap);
4195                         break;
4196                 case IEEE80211_M_STA:
4197                         DPRINTF(sc, MWL_DEBUG_STATE, "%s: %s: aid 0x%x\n",
4198                             vap->iv_ifp->if_xname, __func__, ni->ni_associd);
4199                         /*
4200                          * Set state now that we're associated.
4201                          */
4202                         mwl_hal_setassocid(hvap, ni->ni_bssid, ni->ni_associd);
4203                         mwl_setrates(vap);
4204                         mwl_hal_setrtsthreshold(hvap, vap->iv_rtsthreshold);
4205                         if ((vap->iv_flags & IEEE80211_F_DWDS) &&
4206                             sc->sc_ndwdsvaps++ == 0)
4207                                 mwl_hal_setdwds(mh, 1);
4208                         break;
4209                 case IEEE80211_M_WDS:
4210                         DPRINTF(sc, MWL_DEBUG_STATE, "%s: %s: bssid %s\n",
4211                             vap->iv_ifp->if_xname, __func__,
4212                             ether_sprintf(ni->ni_bssid));
4213                         mwl_seteapolformat(vap);
4214                         break;
4215                 default:
4216                         break;
4217                 }
4218                 /*
4219                  * Set CS mode according to operating channel;
4220                  * this mostly an optimization for 5GHz.
4221                  *
4222                  * NB: must follow mwl_hal_start which resets csmode
4223                  */
4224                 if (IEEE80211_IS_CHAN_5GHZ(ic->ic_bsschan))
4225                         mwl_hal_setcsmode(mh, CSMODE_AGGRESSIVE);
4226                 else
4227                         mwl_hal_setcsmode(mh, CSMODE_AUTO_ENA);
4228                 /*
4229                  * Start timer to prod firmware.
4230                  */
4231                 if (sc->sc_ageinterval != 0)
4232                         callout_reset(&sc->sc_timer, sc->sc_ageinterval*hz,
4233                             mwl_agestations, sc);
4234         } else if (nstate == IEEE80211_S_SLEEP) {
4235                 /* XXX set chip in power save */
4236         } else if ((vap->iv_flags & IEEE80211_F_DWDS) &&
4237             --sc->sc_ndwdsvaps == 0)
4238                 mwl_hal_setdwds(mh, 0);
4239 bad:
4240         return error;
4241 }
4242
4243 /*
4244  * Manage station id's; these are separate from AID's
4245  * as AID's may have values out of the range of possible
4246  * station id's acceptable to the firmware.
4247  */
4248 static int
4249 allocstaid(struct mwl_softc *sc, int aid)
4250 {
4251         int staid;
4252
4253         if (!(0 < aid && aid < MWL_MAXSTAID) || isset(sc->sc_staid, aid)) {
4254                 /* NB: don't use 0 */
4255                 for (staid = 1; staid < MWL_MAXSTAID; staid++)
4256                         if (isclr(sc->sc_staid, staid))
4257                                 break;
4258         } else
4259                 staid = aid;
4260         setbit(sc->sc_staid, staid);
4261         return staid;
4262 }
4263
4264 static void
4265 delstaid(struct mwl_softc *sc, int staid)
4266 {
4267         clrbit(sc->sc_staid, staid);
4268 }
4269
4270 /*
4271  * Setup driver-specific state for a newly associated node.
4272  * Note that we're called also on a re-associate, the isnew
4273  * param tells us if this is the first time or not.
4274  */
4275 static void
4276 mwl_newassoc(struct ieee80211_node *ni, int isnew)
4277 {
4278         struct ieee80211vap *vap = ni->ni_vap;
4279         struct mwl_softc *sc = vap->iv_ic->ic_softc;
4280         struct mwl_node *mn = MWL_NODE(ni);
4281         MWL_HAL_PEERINFO pi;
4282         uint16_t aid;
4283         int error;
4284
4285         aid = IEEE80211_AID(ni->ni_associd);
4286         if (isnew) {
4287                 mn->mn_staid = allocstaid(sc, aid);
4288                 mn->mn_hvap = MWL_VAP(vap)->mv_hvap;
4289         } else {
4290                 mn = MWL_NODE(ni);
4291                 /* XXX reset BA stream? */
4292         }
4293         DPRINTF(sc, MWL_DEBUG_NODE, "%s: mac %s isnew %d aid %d staid %d\n",
4294             __func__, ether_sprintf(ni->ni_macaddr), isnew, aid, mn->mn_staid);
4295         error = mwl_peerstadb(ni, aid, mn->mn_staid, mkpeerinfo(&pi, ni));
4296         if (error != 0) {
4297                 DPRINTF(sc, MWL_DEBUG_NODE,
4298                     "%s: error %d creating sta db entry\n",
4299                     __func__, error);
4300                 /* XXX how to deal with error? */
4301         }
4302 }
4303
4304 /*
4305  * Periodically poke the firmware to age out station state
4306  * (power save queues, pending tx aggregates).
4307  */
4308 static void
4309 mwl_agestations(void *arg)
4310 {
4311         struct mwl_softc *sc = arg;
4312
4313         mwl_hal_setkeepalive(sc->sc_mh);
4314         if (sc->sc_ageinterval != 0)            /* NB: catch dynamic changes */
4315                 callout_schedule(&sc->sc_timer, sc->sc_ageinterval*hz);
4316 }
4317
4318 static const struct mwl_hal_channel *
4319 findhalchannel(const MWL_HAL_CHANNELINFO *ci, int ieee)
4320 {
4321         int i;
4322
4323         for (i = 0; i < ci->nchannels; i++) {
4324                 const struct mwl_hal_channel *hc = &ci->channels[i];
4325                 if (hc->ieee == ieee)
4326                         return hc;
4327         }
4328         return NULL;
4329 }
4330
4331 static int
4332 mwl_setregdomain(struct ieee80211com *ic, struct ieee80211_regdomain *rd,
4333         int nchan, struct ieee80211_channel chans[])
4334 {
4335         struct mwl_softc *sc = ic->ic_softc;
4336         struct mwl_hal *mh = sc->sc_mh;
4337         const MWL_HAL_CHANNELINFO *ci;
4338         int i;
4339
4340         for (i = 0; i < nchan; i++) {
4341                 struct ieee80211_channel *c = &chans[i];
4342                 const struct mwl_hal_channel *hc;
4343
4344                 if (IEEE80211_IS_CHAN_2GHZ(c)) {
4345                         mwl_hal_getchannelinfo(mh, MWL_FREQ_BAND_2DOT4GHZ,
4346                             IEEE80211_IS_CHAN_HT40(c) ?
4347                                 MWL_CH_40_MHz_WIDTH : MWL_CH_20_MHz_WIDTH, &ci);
4348                 } else if (IEEE80211_IS_CHAN_5GHZ(c)) {
4349                         mwl_hal_getchannelinfo(mh, MWL_FREQ_BAND_5GHZ,
4350                             IEEE80211_IS_CHAN_HT40(c) ?
4351                                 MWL_CH_40_MHz_WIDTH : MWL_CH_20_MHz_WIDTH, &ci);
4352                 } else {
4353                         device_printf(sc->sc_dev,
4354                             "%s: channel %u freq %u/0x%x not 2.4/5GHz\n",
4355                             __func__, c->ic_ieee, c->ic_freq, c->ic_flags);
4356                         return EINVAL;
4357                 }
4358                 /* 
4359                  * Verify channel has cal data and cap tx power.
4360                  */
4361                 hc = findhalchannel(ci, c->ic_ieee);
4362                 if (hc != NULL) {
4363                         if (c->ic_maxpower > 2*hc->maxTxPow)
4364                                 c->ic_maxpower = 2*hc->maxTxPow;
4365                         goto next;
4366                 }
4367                 if (IEEE80211_IS_CHAN_HT40(c)) {
4368                         /*
4369                          * Look for the extension channel since the
4370                          * hal table only has the primary channel.
4371                          */
4372                         hc = findhalchannel(ci, c->ic_extieee);
4373                         if (hc != NULL) {
4374                                 if (c->ic_maxpower > 2*hc->maxTxPow)
4375                                         c->ic_maxpower = 2*hc->maxTxPow;
4376                                 goto next;
4377                         }
4378                 }
4379                 device_printf(sc->sc_dev,
4380                     "%s: no cal data for channel %u ext %u freq %u/0x%x\n",
4381                     __func__, c->ic_ieee, c->ic_extieee,
4382                     c->ic_freq, c->ic_flags);
4383                 return EINVAL;
4384         next:
4385                 ;
4386         }
4387         return 0;
4388 }
4389
4390 #define IEEE80211_CHAN_HTG      (IEEE80211_CHAN_HT|IEEE80211_CHAN_G)
4391 #define IEEE80211_CHAN_HTA      (IEEE80211_CHAN_HT|IEEE80211_CHAN_A)
4392
4393 static void
4394 addchan(struct ieee80211_channel *c, int freq, int flags, int ieee, int txpow)
4395 {
4396         c->ic_freq = freq;
4397         c->ic_flags = flags;
4398         c->ic_ieee = ieee;
4399         c->ic_minpower = 0;
4400         c->ic_maxpower = 2*txpow;
4401         c->ic_maxregpower = txpow;
4402 }
4403
4404 static const struct ieee80211_channel *
4405 findchannel(const struct ieee80211_channel chans[], int nchans,
4406         int freq, int flags)
4407 {
4408         const struct ieee80211_channel *c;
4409         int i;
4410
4411         for (i = 0; i < nchans; i++) {
4412                 c = &chans[i];
4413                 if (c->ic_freq == freq && c->ic_flags == flags)
4414                         return c;
4415         }
4416         return NULL;
4417 }
4418
4419 static void
4420 addht40channels(struct ieee80211_channel chans[], int maxchans, int *nchans,
4421         const MWL_HAL_CHANNELINFO *ci, int flags)
4422 {
4423         struct ieee80211_channel *c;
4424         const struct ieee80211_channel *extc;
4425         const struct mwl_hal_channel *hc;
4426         int i;
4427
4428         c = &chans[*nchans];
4429
4430         flags &= ~IEEE80211_CHAN_HT;
4431         for (i = 0; i < ci->nchannels; i++) {
4432                 /*
4433                  * Each entry defines an HT40 channel pair; find the
4434                  * extension channel above and the insert the pair.
4435                  */
4436                 hc = &ci->channels[i];
4437                 extc = findchannel(chans, *nchans, hc->freq+20,
4438                     flags | IEEE80211_CHAN_HT20);
4439                 if (extc != NULL) {
4440                         if (*nchans >= maxchans)
4441                                 break;
4442                         addchan(c, hc->freq, flags | IEEE80211_CHAN_HT40U,
4443                             hc->ieee, hc->maxTxPow);
4444                         c->ic_extieee = extc->ic_ieee;
4445                         c++, (*nchans)++;
4446                         if (*nchans >= maxchans)
4447                                 break;
4448                         addchan(c, extc->ic_freq, flags | IEEE80211_CHAN_HT40D,
4449                             extc->ic_ieee, hc->maxTxPow);
4450                         c->ic_extieee = hc->ieee;
4451                         c++, (*nchans)++;
4452                 }
4453         }
4454 }
4455
4456 static void
4457 addchannels(struct ieee80211_channel chans[], int maxchans, int *nchans,
4458         const MWL_HAL_CHANNELINFO *ci, int flags)
4459 {
4460         struct ieee80211_channel *c;
4461         int i;
4462
4463         c = &chans[*nchans];
4464
4465         for (i = 0; i < ci->nchannels; i++) {
4466                 const struct mwl_hal_channel *hc;
4467
4468                 hc = &ci->channels[i];
4469                 if (*nchans >= maxchans)
4470                         break;
4471                 addchan(c, hc->freq, flags, hc->ieee, hc->maxTxPow);
4472                 c++, (*nchans)++;
4473                 if (flags == IEEE80211_CHAN_G || flags == IEEE80211_CHAN_HTG) {
4474                         /* g channel have a separate b-only entry */
4475                         if (*nchans >= maxchans)
4476                                 break;
4477                         c[0] = c[-1];
4478                         c[-1].ic_flags = IEEE80211_CHAN_B;
4479                         c++, (*nchans)++;
4480                 }
4481                 if (flags == IEEE80211_CHAN_HTG) {
4482                         /* HT g channel have a separate g-only entry */
4483                         if (*nchans >= maxchans)
4484                                 break;
4485                         c[-1].ic_flags = IEEE80211_CHAN_G;
4486                         c[0] = c[-1];
4487                         c[0].ic_flags &= ~IEEE80211_CHAN_HT;
4488                         c[0].ic_flags |= IEEE80211_CHAN_HT20;   /* HT20 */
4489                         c++, (*nchans)++;
4490                 }
4491                 if (flags == IEEE80211_CHAN_HTA) {
4492                         /* HT a channel have a separate a-only entry */
4493                         if (*nchans >= maxchans)
4494                                 break;
4495                         c[-1].ic_flags = IEEE80211_CHAN_A;
4496                         c[0] = c[-1];
4497                         c[0].ic_flags &= ~IEEE80211_CHAN_HT;
4498                         c[0].ic_flags |= IEEE80211_CHAN_HT20;   /* HT20 */
4499                         c++, (*nchans)++;
4500                 }
4501         }
4502 }
4503
4504 static void
4505 getchannels(struct mwl_softc *sc, int maxchans, int *nchans,
4506         struct ieee80211_channel chans[])
4507 {
4508         const MWL_HAL_CHANNELINFO *ci;
4509
4510         /*
4511          * Use the channel info from the hal to craft the
4512          * channel list.  Note that we pass back an unsorted
4513          * list; the caller is required to sort it for us
4514          * (if desired).
4515          */
4516         *nchans = 0;
4517         if (mwl_hal_getchannelinfo(sc->sc_mh,
4518             MWL_FREQ_BAND_2DOT4GHZ, MWL_CH_20_MHz_WIDTH, &ci) == 0)
4519                 addchannels(chans, maxchans, nchans, ci, IEEE80211_CHAN_HTG);
4520         if (mwl_hal_getchannelinfo(sc->sc_mh,
4521             MWL_FREQ_BAND_5GHZ, MWL_CH_20_MHz_WIDTH, &ci) == 0)
4522                 addchannels(chans, maxchans, nchans, ci, IEEE80211_CHAN_HTA);
4523         if (mwl_hal_getchannelinfo(sc->sc_mh,
4524             MWL_FREQ_BAND_2DOT4GHZ, MWL_CH_40_MHz_WIDTH, &ci) == 0)
4525                 addht40channels(chans, maxchans, nchans, ci, IEEE80211_CHAN_HTG);
4526         if (mwl_hal_getchannelinfo(sc->sc_mh,
4527             MWL_FREQ_BAND_5GHZ, MWL_CH_40_MHz_WIDTH, &ci) == 0)
4528                 addht40channels(chans, maxchans, nchans, ci, IEEE80211_CHAN_HTA);
4529 }
4530
4531 static void
4532 mwl_getradiocaps(struct ieee80211com *ic,
4533         int maxchans, int *nchans, struct ieee80211_channel chans[])
4534 {
4535         struct mwl_softc *sc = ic->ic_softc;
4536
4537         getchannels(sc, maxchans, nchans, chans);
4538 }
4539
4540 static int
4541 mwl_getchannels(struct mwl_softc *sc)
4542 {
4543         struct ieee80211com *ic = &sc->sc_ic;
4544
4545         /*
4546          * Use the channel info from the hal to craft the
4547          * channel list for net80211.  Note that we pass up
4548          * an unsorted list; net80211 will sort it for us.
4549          */
4550         memset(ic->ic_channels, 0, sizeof(ic->ic_channels));
4551         ic->ic_nchans = 0;
4552         getchannels(sc, IEEE80211_CHAN_MAX, &ic->ic_nchans, ic->ic_channels);
4553
4554         ic->ic_regdomain.regdomain = SKU_DEBUG;
4555         ic->ic_regdomain.country = CTRY_DEFAULT;
4556         ic->ic_regdomain.location = 'I';
4557         ic->ic_regdomain.isocc[0] = ' ';        /* XXX? */
4558         ic->ic_regdomain.isocc[1] = ' ';
4559         return (ic->ic_nchans == 0 ? EIO : 0);
4560 }
4561 #undef IEEE80211_CHAN_HTA
4562 #undef IEEE80211_CHAN_HTG
4563
4564 #ifdef MWL_DEBUG
4565 static void
4566 mwl_printrxbuf(const struct mwl_rxbuf *bf, u_int ix)
4567 {
4568         const struct mwl_rxdesc *ds = bf->bf_desc;
4569         uint32_t status = le32toh(ds->Status);
4570
4571         printf("R[%2u] (DS.V:%p DS.P:0x%jx) NEXT:%08x DATA:%08x RC:%02x%s\n"
4572                "      STAT:%02x LEN:%04x RSSI:%02x CHAN:%02x RATE:%02x QOS:%04x HT:%04x\n",
4573             ix, ds, (uintmax_t)bf->bf_daddr, le32toh(ds->pPhysNext),
4574             le32toh(ds->pPhysBuffData), ds->RxControl, 
4575             ds->RxControl != EAGLE_RXD_CTRL_DRIVER_OWN ?
4576                 "" : (status & EAGLE_RXD_STATUS_OK) ? " *" : " !",
4577             ds->Status, le16toh(ds->PktLen), ds->RSSI, ds->Channel,
4578             ds->Rate, le16toh(ds->QosCtrl), le16toh(ds->HtSig2));
4579 }
4580
4581 static void
4582 mwl_printtxbuf(const struct mwl_txbuf *bf, u_int qnum, u_int ix)
4583 {
4584         const struct mwl_txdesc *ds = bf->bf_desc;
4585         uint32_t status = le32toh(ds->Status);
4586
4587         printf("Q%u[%3u]", qnum, ix);
4588         printf(" (DS.V:%p DS.P:0x%jx)\n", ds, (uintmax_t)bf->bf_daddr);
4589         printf("    NEXT:%08x DATA:%08x LEN:%04x STAT:%08x%s\n",
4590             le32toh(ds->pPhysNext),
4591             le32toh(ds->PktPtr), le16toh(ds->PktLen), status,
4592             status & EAGLE_TXD_STATUS_USED ?
4593                 "" : (status & 3) != 0 ? " *" : " !");
4594         printf("    RATE:%02x PRI:%x QOS:%04x SAP:%08x FORMAT:%04x\n",
4595             ds->DataRate, ds->TxPriority, le16toh(ds->QosCtrl),
4596             le32toh(ds->SapPktInfo), le16toh(ds->Format));
4597 #if MWL_TXDESC > 1
4598         printf("    MULTIFRAMES:%u LEN:%04x %04x %04x %04x %04x %04x\n"
4599             , le32toh(ds->multiframes)
4600             , le16toh(ds->PktLenArray[0]), le16toh(ds->PktLenArray[1])
4601             , le16toh(ds->PktLenArray[2]), le16toh(ds->PktLenArray[3])
4602             , le16toh(ds->PktLenArray[4]), le16toh(ds->PktLenArray[5])
4603         );
4604         printf("    DATA:%08x %08x %08x %08x %08x %08x\n"
4605             , le32toh(ds->PktPtrArray[0]), le32toh(ds->PktPtrArray[1])
4606             , le32toh(ds->PktPtrArray[2]), le32toh(ds->PktPtrArray[3])
4607             , le32toh(ds->PktPtrArray[4]), le32toh(ds->PktPtrArray[5])
4608         );
4609 #endif
4610 #if 0
4611 { const uint8_t *cp = (const uint8_t *) ds;
4612   int i;
4613   for (i = 0; i < sizeof(struct mwl_txdesc); i++) {
4614         printf("%02x ", cp[i]);
4615         if (((i+1) % 16) == 0)
4616                 printf("\n");
4617   }
4618   printf("\n");
4619 }
4620 #endif
4621 }
4622 #endif /* MWL_DEBUG */
4623
4624 #if 0
4625 static void
4626 mwl_txq_dump(struct mwl_txq *txq)
4627 {
4628         struct mwl_txbuf *bf;
4629         int i = 0;
4630
4631         MWL_TXQ_LOCK(txq);
4632         STAILQ_FOREACH(bf, &txq->active, bf_list) {
4633                 struct mwl_txdesc *ds = bf->bf_desc;
4634                 MWL_TXDESC_SYNC(txq, ds,
4635                     BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
4636 #ifdef MWL_DEBUG
4637                 mwl_printtxbuf(bf, txq->qnum, i);
4638 #endif
4639                 i++;
4640         }
4641         MWL_TXQ_UNLOCK(txq);
4642 }
4643 #endif
4644
4645 static void
4646 mwl_watchdog(void *arg)
4647 {
4648         struct mwl_softc *sc = arg;
4649
4650         callout_reset(&sc->sc_watchdog, hz, mwl_watchdog, sc);
4651         if (sc->sc_tx_timer == 0 || --sc->sc_tx_timer > 0)
4652                 return;
4653
4654         if (sc->sc_running && !sc->sc_invalid) {
4655                 if (mwl_hal_setkeepalive(sc->sc_mh))
4656                         device_printf(sc->sc_dev,
4657                             "transmit timeout (firmware hung?)\n");
4658                 else
4659                         device_printf(sc->sc_dev,
4660                             "transmit timeout\n");
4661 #if 0
4662                 mwl_reset(sc);
4663 mwl_txq_dump(&sc->sc_txq[0]);/*XXX*/
4664 #endif
4665                 counter_u64_add(sc->sc_ic.ic_oerrors, 1);
4666                 sc->sc_stats.mst_watchdog++;
4667         }
4668 }
4669
4670 #ifdef MWL_DIAGAPI
4671 /*
4672  * Diagnostic interface to the HAL.  This is used by various
4673  * tools to do things like retrieve register contents for
4674  * debugging.  The mechanism is intentionally opaque so that
4675  * it can change frequently w/o concern for compatiblity.
4676  */
4677 static int
4678 mwl_ioctl_diag(struct mwl_softc *sc, struct mwl_diag *md)
4679 {
4680         struct mwl_hal *mh = sc->sc_mh;
4681         u_int id = md->md_id & MWL_DIAG_ID;
4682         void *indata = NULL;
4683         void *outdata = NULL;
4684         u_int32_t insize = md->md_in_size;
4685         u_int32_t outsize = md->md_out_size;
4686         int error = 0;
4687
4688         if (md->md_id & MWL_DIAG_IN) {
4689                 /*
4690                  * Copy in data.
4691                  */
4692                 indata = malloc(insize, M_TEMP, M_NOWAIT);
4693                 if (indata == NULL) {
4694                         error = ENOMEM;
4695                         goto bad;
4696                 }
4697                 error = copyin(md->md_in_data, indata, insize);
4698                 if (error)
4699                         goto bad;
4700         }
4701         if (md->md_id & MWL_DIAG_DYN) {
4702                 /*
4703                  * Allocate a buffer for the results (otherwise the HAL
4704                  * returns a pointer to a buffer where we can read the
4705                  * results).  Note that we depend on the HAL leaving this
4706                  * pointer for us to use below in reclaiming the buffer;
4707                  * may want to be more defensive.
4708                  */
4709                 outdata = malloc(outsize, M_TEMP, M_NOWAIT);
4710                 if (outdata == NULL) {
4711                         error = ENOMEM;
4712                         goto bad;
4713                 }
4714         }
4715         if (mwl_hal_getdiagstate(mh, id, indata, insize, &outdata, &outsize)) {
4716                 if (outsize < md->md_out_size)
4717                         md->md_out_size = outsize;
4718                 if (outdata != NULL)
4719                         error = copyout(outdata, md->md_out_data,
4720                                         md->md_out_size);
4721         } else {
4722                 error = EINVAL;
4723         }
4724 bad:
4725         if ((md->md_id & MWL_DIAG_IN) && indata != NULL)
4726                 free(indata, M_TEMP);
4727         if ((md->md_id & MWL_DIAG_DYN) && outdata != NULL)
4728                 free(outdata, M_TEMP);
4729         return error;
4730 }
4731
4732 static int
4733 mwl_ioctl_reset(struct mwl_softc *sc, struct mwl_diag *md)
4734 {
4735         struct mwl_hal *mh = sc->sc_mh;
4736         int error;
4737
4738         MWL_LOCK_ASSERT(sc);
4739
4740         if (md->md_id == 0 && mwl_hal_fwload(mh, NULL) != 0) {
4741                 device_printf(sc->sc_dev, "unable to load firmware\n");
4742                 return EIO;
4743         }
4744         if (mwl_hal_gethwspecs(mh, &sc->sc_hwspecs) != 0) {
4745                 device_printf(sc->sc_dev, "unable to fetch h/w specs\n");
4746                 return EIO;
4747         }
4748         error = mwl_setupdma(sc);
4749         if (error != 0) {
4750                 /* NB: mwl_setupdma prints a msg */
4751                 return error;
4752         }
4753         /*
4754          * Reset tx/rx data structures; after reload we must
4755          * re-start the driver's notion of the next xmit/recv.
4756          */
4757         mwl_draintxq(sc);               /* clear pending frames */
4758         mwl_resettxq(sc);               /* rebuild tx q lists */
4759         sc->sc_rxnext = NULL;           /* force rx to start at the list head */
4760         return 0;
4761 }
4762 #endif /* MWL_DIAGAPI */
4763
4764 static void
4765 mwl_parent(struct ieee80211com *ic)
4766 {
4767         struct mwl_softc *sc = ic->ic_softc;
4768         int startall = 0;
4769
4770         MWL_LOCK(sc);
4771         if (ic->ic_nrunning > 0) {
4772                 if (sc->sc_running) {
4773                         /*
4774                          * To avoid rescanning another access point,
4775                          * do not call mwl_init() here.  Instead,
4776                          * only reflect promisc mode settings.
4777                          */
4778                         mwl_mode_init(sc);
4779                 } else {
4780                         /*
4781                          * Beware of being called during attach/detach
4782                          * to reset promiscuous mode.  In that case we
4783                          * will still be marked UP but not RUNNING.
4784                          * However trying to re-init the interface
4785                          * is the wrong thing to do as we've already
4786                          * torn down much of our state.  There's
4787                          * probably a better way to deal with this.
4788                          */
4789                         if (!sc->sc_invalid) {
4790                                 mwl_init(sc);   /* XXX lose error */
4791                                 startall = 1;
4792                         }
4793                 }
4794         } else
4795                 mwl_stop(sc);
4796         MWL_UNLOCK(sc);
4797         if (startall)
4798                 ieee80211_start_all(ic);
4799 }
4800
4801 static int
4802 mwl_ioctl(struct ieee80211com *ic, u_long cmd, void *data)
4803 {
4804         struct mwl_softc *sc = ic->ic_softc;
4805         struct ifreq *ifr = data;
4806         int error = 0;
4807
4808         switch (cmd) {
4809         case SIOCGMVSTATS:
4810                 mwl_hal_gethwstats(sc->sc_mh, &sc->sc_stats.hw_stats);
4811 #if 0
4812                 /* NB: embed these numbers to get a consistent view */
4813                 sc->sc_stats.mst_tx_packets =
4814                     ifp->if_get_counter(ifp, IFCOUNTER_OPACKETS);
4815                 sc->sc_stats.mst_rx_packets =
4816                     ifp->if_get_counter(ifp, IFCOUNTER_IPACKETS);
4817 #endif
4818                 /*
4819                  * NB: Drop the softc lock in case of a page fault;
4820                  * we'll accept any potential inconsisentcy in the
4821                  * statistics.  The alternative is to copy the data
4822                  * to a local structure.
4823                  */
4824                 return (copyout(&sc->sc_stats,
4825                                 ifr->ifr_data, sizeof (sc->sc_stats)));
4826 #ifdef MWL_DIAGAPI
4827         case SIOCGMVDIAG:
4828                 /* XXX check privs */
4829                 return mwl_ioctl_diag(sc, (struct mwl_diag *) ifr);
4830         case SIOCGMVRESET:
4831                 /* XXX check privs */
4832                 MWL_LOCK(sc);
4833                 error = mwl_ioctl_reset(sc,(struct mwl_diag *) ifr); 
4834                 MWL_UNLOCK(sc);
4835                 break;
4836 #endif /* MWL_DIAGAPI */
4837         default:
4838                 error = ENOTTY;
4839                 break;
4840         }
4841         return (error);
4842 }
4843
4844 #ifdef  MWL_DEBUG
4845 static int
4846 mwl_sysctl_debug(SYSCTL_HANDLER_ARGS)
4847 {
4848         struct mwl_softc *sc = arg1;
4849         int debug, error;
4850
4851         debug = sc->sc_debug | (mwl_hal_getdebug(sc->sc_mh) << 24);
4852         error = sysctl_handle_int(oidp, &debug, 0, req);
4853         if (error || !req->newptr)
4854                 return error;
4855         mwl_hal_setdebug(sc->sc_mh, debug >> 24);
4856         sc->sc_debug = debug & 0x00ffffff;
4857         return 0;
4858 }
4859 #endif /* MWL_DEBUG */
4860
4861 static void
4862 mwl_sysctlattach(struct mwl_softc *sc)
4863 {
4864 #ifdef  MWL_DEBUG
4865         struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
4866         struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
4867
4868         sc->sc_debug = mwl_debug;
4869         SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
4870                 "debug", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
4871                 mwl_sysctl_debug, "I", "control debugging printfs");
4872 #endif
4873 }
4874
4875 /*
4876  * Announce various information on device/driver attach.
4877  */
4878 static void
4879 mwl_announce(struct mwl_softc *sc)
4880 {
4881
4882         device_printf(sc->sc_dev, "Rev A%d hardware, v%d.%d.%d.%d firmware (regioncode %d)\n",
4883                 sc->sc_hwspecs.hwVersion,
4884                 (sc->sc_hwspecs.fwReleaseNumber>>24) & 0xff,
4885                 (sc->sc_hwspecs.fwReleaseNumber>>16) & 0xff,
4886                 (sc->sc_hwspecs.fwReleaseNumber>>8) & 0xff,
4887                 (sc->sc_hwspecs.fwReleaseNumber>>0) & 0xff,
4888                 sc->sc_hwspecs.regionCode);
4889         sc->sc_fwrelease = sc->sc_hwspecs.fwReleaseNumber;
4890
4891         if (bootverbose) {
4892                 int i;
4893                 for (i = 0; i <= WME_AC_VO; i++) {
4894                         struct mwl_txq *txq = sc->sc_ac2q[i];
4895                         device_printf(sc->sc_dev, "Use hw queue %u for %s traffic\n",
4896                                 txq->qnum, ieee80211_wme_acnames[i]);
4897                 }
4898         }
4899         if (bootverbose || mwl_rxdesc != MWL_RXDESC)
4900                 device_printf(sc->sc_dev, "using %u rx descriptors\n", mwl_rxdesc);
4901         if (bootverbose || mwl_rxbuf != MWL_RXBUF)
4902                 device_printf(sc->sc_dev, "using %u rx buffers\n", mwl_rxbuf);
4903         if (bootverbose || mwl_txbuf != MWL_TXBUF)
4904                 device_printf(sc->sc_dev, "using %u tx buffers\n", mwl_txbuf);
4905         if (bootverbose && mwl_hal_ismbsscapable(sc->sc_mh))
4906                 device_printf(sc->sc_dev, "multi-bss support\n");
4907 #ifdef MWL_TX_NODROP
4908         if (bootverbose)
4909                 device_printf(sc->sc_dev, "no tx drop\n");
4910 #endif
4911 }