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