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