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