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