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