xref: /titanic_51/usr/src/uts/common/io/rwd/rt2661.c (revision fd0939ef389f48c901faf4bf0b60b82d4bc58b64)
1 /*
2  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 /*
7  * Copyright (c) 2006
8  *	Damien Bergamini <damien.bergamini@free.fr>
9  *
10  * Permission to use, copy, modify, and distribute this software for any
11  * purpose with or without fee is hereby granted, provided that the above
12  * copyright notice and this permission notice appear in all copies.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
15  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
17  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
20  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21  */
22 
23 /*
24  * Ralink Technology RT2561, RT2561S and RT2661  chipset driver
25  * http://www.ralinktech.com/
26  */
27 
28 #include <sys/types.h>
29 #include <sys/byteorder.h>
30 #include <sys/conf.h>
31 #include <sys/cmn_err.h>
32 #include <sys/stat.h>
33 #include <sys/ddi.h>
34 #include <sys/sunddi.h>
35 #include <sys/strsubr.h>
36 #include <sys/ethernet.h>
37 #include <inet/common.h>
38 #include <inet/nd.h>
39 #include <inet/mi.h>
40 #include <sys/note.h>
41 #include <sys/stream.h>
42 #include <sys/strsun.h>
43 #include <sys/modctl.h>
44 #include <sys/devops.h>
45 #include <sys/dlpi.h>
46 #include <sys/mac_provider.h>
47 #include <sys/mac_wifi.h>
48 #include <sys/net80211.h>
49 #include <sys/net80211_proto.h>
50 #include <sys/varargs.h>
51 #include <sys/policy.h>
52 #include <sys/pci.h>
53 #include <sys/crypto/common.h>
54 #include <sys/crypto/api.h>
55 #include <inet/wifi_ioctl.h>
56 
57 #include "rt2661_reg.h"
58 #include "rt2661_var.h"
59 #include "rt2661_ucode.h"
60 
61 #define	RT2661_DBG_80211	(1 << 0)
62 #define	RT2661_DBG_DMA		(1 << 1)
63 #define	RT2661_DBG_EEPROM	(1 << 2)
64 #define	RT2661_DBG_FW		(1 << 3)
65 #define	RT2661_DBG_HW		(1 << 4)
66 #define	RT2661_DBG_INTR		(1 << 5)
67 #define	RT2661_DBG_RX		(1 << 6)
68 #define	RT2661_DBG_SCAN		(1 << 7)
69 #define	RT2661_DBG_TX		(1 << 8)
70 #define	RT2661_DBG_RADIO	(1 << 9)
71 #define	RT2661_DBG_RESUME	(1 << 10)
72 #define	RT2661_DBG_MSG		(1 << 11)
73 
74 uint32_t rt2661_dbg_flags = 0;
75 
76 #ifdef DEBUG
77 #define	RWD_DEBUG \
78 	rt2661_debug
79 #else
80 #define	RWD_DEBUG
81 #endif
82 
83 static void *rt2661_soft_state_p = NULL;
84 
85 static const uint8_t *ucode = NULL;
86 int usize;
87 
88 static const struct {
89 	uint32_t	reg;
90 	uint32_t	val;
91 } rt2661_def_mac[] = {
92 	RT2661_DEF_MAC
93 };
94 
95 static const struct {
96 	uint8_t	reg;
97 	uint8_t	val;
98 } rt2661_def_bbp[] = {
99 	RT2661_DEF_BBP
100 };
101 
102 static const struct rfprog {
103 	uint8_t		chan;
104 	uint32_t	r1, r2, r3, r4;
105 }  rt2661_rf5225_1[] = {
106 	RT2661_RF5225_1
107 }, rt2661_rf5225_2[] = {
108 	RT2661_RF5225_2
109 };
110 
111 /*
112  * PIO access attributes for registers
113  */
114 static ddi_device_acc_attr_t rt2661_csr_accattr = {
115 	DDI_DEVICE_ATTR_V0,
116 	DDI_STRUCTURE_LE_ACC,
117 	DDI_STRICTORDER_ACC
118 };
119 
120 /*
121  * DMA access attributes for descriptors: NOT to be byte swapped.
122  */
123 static ddi_device_acc_attr_t rt2661_desc_accattr = {
124 	DDI_DEVICE_ATTR_V0,
125 	DDI_STRUCTURE_LE_ACC,
126 	DDI_STRICTORDER_ACC
127 };
128 
129 static ddi_device_acc_attr_t rt2661_buf_accattr = {
130 	DDI_DEVICE_ATTR_V0,
131 	DDI_NEVERSWAP_ACC,
132 	DDI_STRICTORDER_ACC,
133 	DDI_DEFAULT_ACC
134 };
135 
136 /*
137  * Describes the chip's DMA engine
138  */
139 static ddi_dma_attr_t rt2661_dma_attr = {
140 	DMA_ATTR_V0,			/* dma_attr version */
141 	0x0,				/* dma_attr_addr_lo */
142 	0xffffffffU,			/* dma_attr_addr_hi */
143 	0xffffffffU,			/* dma_attr_count_max */
144 	1,				/* dma_attr_align */
145 	0x00000fff,			/* dma_attr_burstsizes */
146 	1,				/* dma_attr_minxfer */
147 	0xffffffffU,			/* dma_attr_maxxfer */
148 	0xffffffffU,			/* dma_attr_seg */
149 	1,				/* dma_attr_sgllen */
150 	1,				/* dma_attr_granular */
151 	0				/* dma_attr_flags */
152 };
153 
154 static const struct ieee80211_rateset rt2661_rateset_11b =
155 	{ 4, { 2, 4, 11, 22 } };
156 
157 static const struct ieee80211_rateset rt2661_rateset_11g =
158 	{ 12, { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 } };
159 
160 
161 static const char *rt2661_get_rf(int);
162 
163 static void	rt2661_read_eeprom(struct rt2661_softc *);
164 static uint16_t	rt2661_eeprom_read(struct rt2661_softc *, uint8_t);
165 static int	rt2661_load_microcode(struct rt2661_softc *,
166 		    const uint8_t *, int);
167 
168 static int	rt2661_alloc_dma_mem(dev_info_t *, ddi_dma_attr_t *, size_t,
169 		    ddi_device_acc_attr_t *, uint_t, uint_t, struct dma_area *);
170 static void	rt2661_free_dma_mem(struct dma_area *);
171 static int	rt2661_alloc_tx_ring(struct rt2661_softc *,
172 		    struct rt2661_tx_ring *, int);
173 static void	rt2661_reset_tx_ring(struct rt2661_softc *,
174 		    struct rt2661_tx_ring *);
175 static void	rt2661_free_tx_ring(struct rt2661_softc *,
176 		    struct rt2661_tx_ring *);
177 static int	rt2661_alloc_rx_ring(struct rt2661_softc *,
178 		    struct rt2661_rx_ring *, int);
179 static void	rt2661_reset_rx_ring(struct rt2661_softc *,
180 		    struct rt2661_rx_ring *);
181 static void	rt2661_free_rx_ring(struct rt2661_softc *,
182 		    struct rt2661_rx_ring *);
183 static void	rt2661_tx_dma_intr(struct rt2661_softc *,
184 		    struct rt2661_tx_ring *);
185 static void	rt2661_tx_intr(struct rt2661_softc *);
186 static void	rt2661_rx_intr(struct rt2661_softc *);
187 static uint_t	rt2661_softintr(caddr_t, caddr_t);
188 static void	rt2661_mcu_wakeup(struct rt2661_softc *);
189 static void	rt2661_mcu_cmd_intr(struct rt2661_softc *);
190 static uint_t	rt2661_intr(caddr_t, caddr_t);
191 
192 static uint16_t	rt2661_txtime(int, int, uint32_t);
193 static int	rt2661_ack_rate(struct ieee80211com *, int);
194 static uint8_t	rt2661_plcp_signal(int);
195 static void	rt2661_setup_tx_desc(struct rt2661_softc *,
196 		    struct rt2661_tx_desc *, uint32_t, uint16_t, int,
197 		    int, int);
198 
199 static int	rt2661_get_rssi(struct rt2661_softc *, uint8_t);
200 
201 static int	rt2661_send(ieee80211com_t *, mblk_t *);
202 static int	rt2661_mgmt_send(ieee80211com_t *, mblk_t *, uint8_t);
203 
204 static void	rt2661_amrr_node_init(const struct rt2661_amrr *,
205 		    struct rt2661_amrr_node *);
206 static void	rt2661_amrr_choose(struct rt2661_amrr *,
207 		    struct ieee80211_node *, struct rt2661_amrr_node *);
208 
209 static void	rt2661_update_promisc(struct rt2661_softc *);
210 static void	rt2661_updateslot(struct ieee80211com *, int);
211 static void	rt2661_set_slottime(struct rt2661_softc *);
212 static void	rt2661_enable_mrr(struct rt2661_softc *);
213 static void	rt2661_set_txpreamble(struct rt2661_softc *);
214 static void	rt2661_set_basicrates(struct rt2661_softc *);
215 static void	rt2661_set_bssid(struct rt2661_softc *, const uint8_t *);
216 static void	rt2661_newassoc(struct ieee80211com *, struct ieee80211_node *);
217 static void	rt2661_updatestats(void *);
218 static void	rt2661_rx_tune(struct rt2661_softc *);
219 static void	rt2661_enable_tsf_sync(struct rt2661_softc *);
220 static int	rt2661_newstate(struct ieee80211com *,
221 		    enum ieee80211_state, int);
222 
223 static void	rt2661_set_macaddr(struct rt2661_softc *, const uint8_t *);
224 static int	rt2661_bbp_init(struct rt2661_softc *);
225 static uint8_t	rt2661_bbp_read(struct rt2661_softc *, uint8_t);
226 static void	rt2661_bbp_write(struct rt2661_softc *, uint8_t, uint8_t);
227 static void	rt2661_select_band(struct rt2661_softc *,
228 		    struct ieee80211_channel *);
229 static void	rt2661_select_antenna(struct rt2661_softc *);
230 static void	rt2661_rf_write(struct rt2661_softc *, uint8_t, uint32_t);
231 static void	rt2661_set_chan(struct rt2661_softc *,
232 		    struct ieee80211_channel *);
233 
234 static void	rt2661_stop_locked(struct rt2661_softc *);
235 static int	rt2661_init(struct rt2661_softc *);
236 static void	rt2661_stop(struct rt2661_softc *);
237 /*
238  * device operations
239  */
240 static int rt2661_attach(dev_info_t *, ddi_attach_cmd_t);
241 static int rt2661_detach(dev_info_t *, ddi_detach_cmd_t);
242 static int rt2661_quiesce(dev_info_t *);
243 
244 /*
245  * Module Loading Data & Entry Points
246  */
247 DDI_DEFINE_STREAM_OPS(rwd_dev_ops, nulldev, nulldev, rt2661_attach,
248     rt2661_detach, nodev, NULL, D_MP, NULL, rt2661_quiesce);
249 
250 static struct modldrv rwd_modldrv = {
251 	&mod_driverops,		/* Type of module.  This one is a driver */
252 	"Ralink RT2661 driver v1.1",	/* short description */
253 	&rwd_dev_ops		/* driver specific ops */
254 };
255 
256 static struct modlinkage modlinkage = {
257 	MODREV_1,
258 	(void *)&rwd_modldrv,
259 	NULL
260 };
261 
262 static int	rt2661_m_stat(void *,  uint_t, uint64_t *);
263 static int	rt2661_m_start(void *);
264 static void	rt2661_m_stop(void *);
265 static int	rt2661_m_promisc(void *, boolean_t);
266 static int	rt2661_m_multicst(void *, boolean_t, const uint8_t *);
267 static int	rt2661_m_unicst(void *, const uint8_t *);
268 static mblk_t	*rt2661_m_tx(void *, mblk_t *);
269 static void	rt2661_m_ioctl(void *, queue_t *, mblk_t *);
270 static int	rt2661_m_setprop(void *arg, const char *pr_name,
271 		    mac_prop_id_t wldp_pr_num,
272 		    uint_t wldp_length, const void *wldp_buf);
273 static int	rt2661_m_getprop(void *arg, const char *pr_name,
274 		    mac_prop_id_t wldp_pr_num, uint_t pr_flags,
275 		    uint_t wldp_length, void *wldp_buf, uint_t *);
276 
277 static mac_callbacks_t rt2661_m_callbacks = {
278 	MC_IOCTL | MC_SETPROP | MC_GETPROP,
279 	rt2661_m_stat,
280 	rt2661_m_start,
281 	rt2661_m_stop,
282 	rt2661_m_promisc,
283 	rt2661_m_multicst,
284 	rt2661_m_unicst,
285 	rt2661_m_tx,
286 	rt2661_m_ioctl,
287 	NULL,
288 	NULL,
289 	NULL,
290 	rt2661_m_setprop,
291 	rt2661_m_getprop
292 };
293 
294 #ifdef DEBUG
295 void
296 rt2661_debug(uint32_t dbg_flags, const int8_t *fmt, ...)
297 {
298 	va_list args;
299 
300 	if (dbg_flags & rt2661_dbg_flags) {
301 		va_start(args, fmt);
302 		vcmn_err(CE_CONT, fmt, args);
303 		va_end(args);
304 	}
305 }
306 #endif
307 
308 /*
309  * Read 16 bits at address 'addr' from the serial EEPROM (either 93C46 or
310  * 93C66).
311  */
312 static uint16_t
313 rt2661_eeprom_read(struct rt2661_softc *sc, uint8_t addr)
314 {
315 	uint32_t tmp;
316 	uint16_t val;
317 	int n;
318 
319 	/* clock C once before the first command */
320 	RT2661_EEPROM_CTL(sc, 0);
321 
322 	RT2661_EEPROM_CTL(sc, RT2661_S);
323 	RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_C);
324 	RT2661_EEPROM_CTL(sc, RT2661_S);
325 
326 	/* write start bit (1) */
327 	RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_D);
328 	RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_D | RT2661_C);
329 
330 	/* write READ opcode (10) */
331 	RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_D);
332 	RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_D | RT2661_C);
333 	RT2661_EEPROM_CTL(sc, RT2661_S);
334 	RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_C);
335 
336 	/* write address (A5-A0 or A7-A0) */
337 	n = (RT2661_READ(sc, RT2661_E2PROM_CSR) & RT2661_93C46) ? 5 : 7;
338 	for (; n >= 0; n--) {
339 		RT2661_EEPROM_CTL(sc, RT2661_S |
340 		    (((addr >> n) & 1) << RT2661_SHIFT_D));
341 		RT2661_EEPROM_CTL(sc, RT2661_S |
342 		    (((addr >> n) & 1) << RT2661_SHIFT_D) | RT2661_C);
343 	}
344 
345 	RT2661_EEPROM_CTL(sc, RT2661_S);
346 
347 	/* read data Q15-Q0 */
348 	val = 0;
349 	for (n = 15; n >= 0; n--) {
350 		RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_C);
351 		tmp = RT2661_READ(sc, RT2661_E2PROM_CSR);
352 		val |= ((tmp & RT2661_Q) >> RT2661_SHIFT_Q) << n;
353 		RT2661_EEPROM_CTL(sc, RT2661_S);
354 	}
355 
356 	RT2661_EEPROM_CTL(sc, 0);
357 
358 	/* clear Chip Select and clock C */
359 	RT2661_EEPROM_CTL(sc, RT2661_S);
360 	RT2661_EEPROM_CTL(sc, 0);
361 	RT2661_EEPROM_CTL(sc, RT2661_C);
362 
363 	return (val);
364 }
365 
366 
367 static void
368 rt2661_read_eeprom(struct rt2661_softc *sc)
369 {
370 	struct ieee80211com *ic = &sc->sc_ic;
371 	uint16_t val;
372 	int i;
373 
374 	/* read MAC address */
375 	val = rt2661_eeprom_read(sc, RT2661_EEPROM_MAC01);
376 	ic->ic_macaddr[0] = val & 0xff;
377 	ic->ic_macaddr[1] = val >> 8;
378 
379 	val = rt2661_eeprom_read(sc, RT2661_EEPROM_MAC23);
380 	ic->ic_macaddr[2] = val & 0xff;
381 	ic->ic_macaddr[3] = val >> 8;
382 
383 	val = rt2661_eeprom_read(sc, RT2661_EEPROM_MAC45);
384 	ic->ic_macaddr[4] = val & 0xff;
385 	ic->ic_macaddr[5] = val >> 8;
386 
387 	val = rt2661_eeprom_read(sc, RT2661_EEPROM_ANTENNA);
388 	/* XXX: test if different from 0xffff? */
389 	sc->rf_rev   = (val >> 11) & 0x1f;
390 	sc->hw_radio = (val >> 10) & 0x1;
391 	sc->rx_ant   = (val >> 4)  & 0x3;
392 	sc->tx_ant   = (val >> 2)  & 0x3;
393 	sc->nb_ant   = val & 0x3;
394 
395 	RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_read_eeprom(): "
396 	    "RF revision=%d\n", sc->rf_rev);
397 
398 	val = rt2661_eeprom_read(sc, RT2661_EEPROM_CONFIG2);
399 	sc->ext_5ghz_lna = (val >> 6) & 0x1;
400 	sc->ext_2ghz_lna = (val >> 4) & 0x1;
401 
402 	RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_read_eeprom(): "
403 	    "External 2GHz LNA=%d\nExternal 5GHz LNA=%d\n",
404 	    sc->ext_2ghz_lna, sc->ext_5ghz_lna);
405 
406 	val = rt2661_eeprom_read(sc, RT2661_EEPROM_RSSI_2GHZ_OFFSET);
407 	if ((val & 0xff) != 0xff)
408 		sc->rssi_2ghz_corr = (int8_t)(val & 0xff);
409 
410 	val = rt2661_eeprom_read(sc, RT2661_EEPROM_RSSI_5GHZ_OFFSET);
411 	if ((val & 0xff) != 0xff)
412 		sc->rssi_5ghz_corr = (int8_t)(val & 0xff);
413 
414 	/* adjust RSSI correction for external low-noise amplifier */
415 	if (sc->ext_2ghz_lna)
416 		sc->rssi_2ghz_corr -= 14;
417 	if (sc->ext_5ghz_lna)
418 		sc->rssi_5ghz_corr -= 14;
419 
420 	RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_read_eeprom(): "
421 	    "RSSI 2GHz corr=%d\nRSSI 5GHz corr=%d\n",
422 	    sc->rssi_2ghz_corr, sc->rssi_5ghz_corr);
423 
424 	val = rt2661_eeprom_read(sc, RT2661_EEPROM_FREQ_OFFSET);
425 	if ((val >> 8) != 0xff)
426 		sc->rfprog = (val >> 8) & 0x3;
427 	if ((val & 0xff) != 0xff)
428 		sc->rffreq = val & 0xff;
429 
430 	RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_read_eeprom(): "
431 	    "RF prog=%d\nRF freq=%d\n", sc->rfprog, sc->rffreq);
432 
433 	/* read Tx power for all a/b/g channels */
434 	for (i = 0; i < 19; i++) {
435 		val = rt2661_eeprom_read(sc, RT2661_EEPROM_TXPOWER + i);
436 		sc->txpow[i * 2] = (int8_t)(val >> 8);
437 		RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_read_eeprom(): "
438 		    "Channel=%d Tx power=%d\n",
439 		    rt2661_rf5225_1[i * 2].chan, sc->txpow[i * 2]);
440 		sc->txpow[i * 2 + 1] = (int8_t)(val & 0xff);
441 		RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_read_eeprom(): "
442 		    "Channel=%d Tx power=%d\n",
443 		    rt2661_rf5225_1[i * 2 + 1].chan, sc->txpow[i * 2 + 1]);
444 	}
445 
446 	/* read vendor-specific BBP values */
447 	for (i = 0; i < 16; i++) {
448 		val = rt2661_eeprom_read(sc, RT2661_EEPROM_BBP_BASE + i);
449 		if (val == 0 || val == 0xffff)
450 			continue;
451 		sc->bbp_prom[i].reg = val >> 8;
452 		sc->bbp_prom[i].val = val & 0xff;
453 		RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_read_eeprom(): "
454 		    "BBP R%d=%02x\n", sc->bbp_prom[i].reg,
455 		    sc->bbp_prom[i].val);
456 	}
457 }
458 
459 static const char *
460 rt2661_get_rf(int rev)
461 {
462 	switch (rev) {
463 	case RT2661_RF_5225:	return "RT5225";
464 	case RT2661_RF_5325:	return "RT5325 (MIMO XR)";
465 	case RT2661_RF_2527:	return "RT2527";
466 	case RT2661_RF_2529:	return "RT2529 (MIMO XR)";
467 	default:		return "unknown";
468 	}
469 }
470 
471 static int
472 rt2661_load_microcode(struct rt2661_softc *sc, const uint8_t *ucode_p, int size)
473 {
474 	int ntries;
475 	uint32_t off, i;
476 	const uint8_t *fptr;
477 
478 	fptr = ucode_p;
479 	off = RT2661_MCU_CODE_BASE;
480 
481 	/* reset 8051 */
482 	RT2661_WRITE(sc, RT2661_MCU_CNTL_CSR, RT2661_MCU_RESET);
483 
484 	/* cancel any pending Host to MCU command */
485 	RT2661_WRITE(sc, RT2661_H2M_MAILBOX_CSR, 0);
486 	RT2661_WRITE(sc, RT2661_M2H_CMD_DONE_CSR, 0xffffffff);
487 	RT2661_WRITE(sc, RT2661_HOST_CMD_CSR, 0);
488 
489 	/* write 8051's microcode */
490 	RT2661_WRITE(sc, RT2661_MCU_CNTL_CSR,
491 	    RT2661_MCU_RESET | RT2661_MCU_SEL);
492 	/* RT2661_WRITE_REGION_1(sc, RT2661_MCU_CODE_BASE, ucode, size); */
493 
494 	for (i = 0; i < size; i++) {
495 		RT2661_MEM_WRITE1(sc, off++, *fptr++);
496 	}
497 
498 	RT2661_WRITE(sc, RT2661_MCU_CNTL_CSR, RT2661_MCU_RESET);
499 
500 	/* kick 8051's ass */
501 	RT2661_WRITE(sc, RT2661_MCU_CNTL_CSR, 0);
502 
503 	/* wait for 8051 to initialize */
504 	for (ntries = 0; ntries < 500; ntries++) {
505 		if (RT2661_READ(sc, RT2661_MCU_CNTL_CSR) & RT2661_MCU_READY)
506 			break;
507 		DELAY(100);
508 	}
509 	if (ntries == 500) {
510 		RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_load_microcode(): "
511 		    "timeout waiting for MCU to initialize\n");
512 		return (RT2661_FAILURE);
513 	}
514 
515 	RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_load_microcode(): "
516 	    "MCU initialized successfully\n");
517 	return (RT2661_SUCCESS);
518 }
519 
520 /*
521  * Allocate an DMA memory and a DMA handle for accessing it
522  */
523 static int
524 rt2661_alloc_dma_mem(dev_info_t *devinfo, ddi_dma_attr_t *dma_attr,
525 	size_t memsize, ddi_device_acc_attr_t *attr_p, uint_t alloc_flags,
526 	uint_t bind_flags, struct dma_area *dma_p)
527 {
528 	int err;
529 
530 	/*
531 	 * Allocate handle
532 	 */
533 	err = ddi_dma_alloc_handle(devinfo, dma_attr,
534 	    DDI_DMA_SLEEP, NULL, &dma_p->dma_hdl);
535 	if (err != DDI_SUCCESS) {
536 		RWD_DEBUG(RT2661_DBG_MSG, "rwd: rwd_allo_dma_mem(): "
537 		    "failed to alloc handle\n");
538 		goto fail1;
539 	}
540 
541 	/*
542 	 * Allocate memory
543 	 */
544 	err = ddi_dma_mem_alloc(dma_p->dma_hdl, memsize, attr_p,
545 	    alloc_flags, DDI_DMA_SLEEP, NULL, &dma_p->mem_va,
546 	    &dma_p->alength, &dma_p->acc_hdl);
547 	if (err != DDI_SUCCESS) {
548 		RWD_DEBUG(RT2661_DBG_MSG, "rwd: rwd_alloc_dma_mem(): "
549 		    "failed to alloc mem\n");
550 		goto fail2;
551 	}
552 
553 	/*
554 	 * Bind the two together
555 	 */
556 	err = ddi_dma_addr_bind_handle(dma_p->dma_hdl, NULL,
557 	    dma_p->mem_va, dma_p->alength, bind_flags,
558 	    DDI_DMA_SLEEP, NULL, &dma_p->cookie, &dma_p->ncookies);
559 	if (err != DDI_DMA_MAPPED) {
560 		RWD_DEBUG(RT2661_DBG_MSG, "rwd: rwd_alloc_dma_mem(): "
561 		    "failed to bind handle\n");
562 		goto fail3;
563 	}
564 
565 	if (dma_p->ncookies != 1) {
566 		RWD_DEBUG(RT2661_DBG_MSG, "rwd: rwd_alloc_dma_mem(): "
567 		    "failed to alloc cookies\n");
568 		goto fail4;
569 	}
570 
571 	dma_p->nslots = ~0U;
572 	dma_p->size = ~0U;
573 	dma_p->token = ~0U;
574 	dma_p->offset = 0;
575 	return (DDI_SUCCESS);
576 
577 fail4:
578 	(void) ddi_dma_unbind_handle(dma_p->dma_hdl);
579 fail3:
580 	ddi_dma_mem_free(&dma_p->acc_hdl);
581 fail2:
582 	ddi_dma_free_handle(&dma_p->dma_hdl);
583 fail1:
584 	return (err);
585 }
586 
587 static void
588 rt2661_free_dma_mem(struct dma_area *dma_p)
589 {
590 	if (dma_p->dma_hdl != NULL) {
591 		(void) ddi_dma_unbind_handle(dma_p->dma_hdl);
592 		if (dma_p->acc_hdl != NULL) {
593 			ddi_dma_mem_free(&dma_p->acc_hdl);
594 			dma_p->acc_hdl = NULL;
595 		}
596 		ddi_dma_free_handle(&dma_p->dma_hdl);
597 		dma_p->ncookies = 0;
598 		dma_p->dma_hdl = NULL;
599 	}
600 }
601 
602 /*ARGSUSED*/
603 static int
604 rt2661_alloc_tx_ring(struct rt2661_softc *sc,
605     struct rt2661_tx_ring *ring, int count)
606 {
607 	struct rt2661_tx_desc *desc;
608 	struct rt2661_tx_data *data;
609 	int i, err, size, len;
610 
611 	size = count * RT2661_TX_DESC_SIZE;
612 	len = count * sizeof (struct rt2661_tx_data);
613 
614 	ring->count = count;
615 	ring->queued = 0;
616 	ring->cur = 0;
617 	ring->next = 0;
618 	ring->stat = 0;
619 
620 	err = rt2661_alloc_dma_mem(sc->sc_dev, &rt2661_dma_attr, size,
621 	    &rt2661_desc_accattr, DDI_DMA_CONSISTENT,
622 	    DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
623 	    &ring->txdesc_dma);
624 	if (err != DDI_SUCCESS) {
625 		RWD_DEBUG(RT2661_DBG_DMA, "rwd: rt2661_alloc_tx_ring(): "
626 		    "failed to alloc dma mem\n");
627 		goto fail1;
628 	}
629 
630 	ring->desc = (struct rt2661_tx_desc *)ring->txdesc_dma.mem_va;
631 	(void) bzero(ring->desc, size);
632 	ring->paddr = ring->txdesc_dma.cookie.dmac_address;
633 
634 	ring->data = kmem_zalloc(len, KM_NOSLEEP);
635 	if (ring->data == NULL) {
636 		RWD_DEBUG(RT2661_DBG_DMA, "rwd: rt2661_alloc_tx_ring(): "
637 		    "failed to alloc tx buffer\n");
638 		goto fail2;
639 	}
640 
641 	for (i = 0; i < count; i++) {
642 		desc = &ring->desc[i];
643 		data = &ring->data[i];
644 		err = rt2661_alloc_dma_mem(sc->sc_dev,
645 		    &rt2661_dma_attr, sc->sc_dmabuf_size,
646 		    &rt2661_buf_accattr, DDI_DMA_CONSISTENT,
647 		    DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
648 		    &data->txdata_dma);
649 		if (err != DDI_SUCCESS) {
650 			RWD_DEBUG(RT2661_DBG_DMA,
651 			    "rwd: rt2661_alloc_tx_ring(): "
652 			    "failed to alloc tx buffer dma\n");
653 			while (i >= 0) {
654 				rt2661_free_dma_mem(&ring->data[i].txdata_dma);
655 				i--;
656 			}
657 			goto fail3;
658 		}
659 		desc->addr[0] = data->txdata_dma.cookie.dmac_address;
660 		data->buf = data->txdata_dma.mem_va;
661 		data->paddr = data->txdata_dma.cookie.dmac_address;
662 	}
663 
664 	(void) ddi_dma_sync(ring->txdesc_dma.dma_hdl,
665 	    0, size, DDI_DMA_SYNC_FORDEV);
666 	return (DDI_SUCCESS);
667 fail3:
668 	if (ring->data)
669 		kmem_free(ring->data,
670 		    count * sizeof (struct rt2661_tx_data));
671 fail2:
672 	rt2661_free_dma_mem(&ring->txdesc_dma);
673 fail1:
674 	return (err);
675 }
676 
677 static void
678 rt2661_reset_tx_ring(struct rt2661_softc *sc, struct rt2661_tx_ring *ring)
679 {
680 	struct rt2661_tx_desc *desc;
681 	struct rt2661_tx_data *data;
682 	int i;
683 
684 	for (i = 0; i < ring->count; i++) {
685 		desc = &ring->desc[i];
686 		data = &ring->data[i];
687 
688 		if (data->ni != NULL) {
689 			ieee80211_free_node(data->ni);
690 			data->ni = NULL;
691 		}
692 
693 		desc->flags = 0;
694 	}
695 
696 	if (!RT2661_IS_FASTREBOOT(sc))
697 		(void) ddi_dma_sync(ring->txdesc_dma.dma_hdl, 0,
698 		    ring->count * sizeof (struct rt2661_tx_desc),
699 		    DDI_DMA_SYNC_FORDEV);
700 
701 	ring->queued = 0;
702 	ring->cur = ring->next = ring->stat = 0;
703 }
704 
705 
706 /*ARGSUSED*/
707 static void
708 rt2661_free_tx_ring(struct rt2661_softc *sc, struct rt2661_tx_ring *ring)
709 {
710 	struct rt2661_tx_data *data;
711 	int i;
712 
713 	if (ring->desc != NULL) {
714 		rt2661_free_dma_mem(&ring->txdesc_dma);
715 	}
716 
717 	if (ring->data != NULL) {
718 		for (i = 0; i < ring->count; i++) {
719 			data = &ring->data[i];
720 			rt2661_free_dma_mem(&data->txdata_dma);
721 			if (data->ni != NULL) {
722 				ieee80211_free_node(data->ni);
723 				data->ni = NULL;
724 			}
725 		}
726 		kmem_free(ring->data,
727 		    ring->count * sizeof (struct rt2661_tx_data));
728 	}
729 }
730 
731 /*ARGSUSED*/
732 static int
733 rt2661_alloc_rx_ring(struct rt2661_softc *sc,
734     struct rt2661_rx_ring *ring, int count)
735 {
736 	struct rt2661_rx_desc *desc;
737 	struct rt2661_rx_data *data;
738 	int i, err, len, size;
739 
740 	size = count * RT2661_RX_DESC_SIZE;
741 	len = count * sizeof (struct rt2661_rx_data);
742 
743 	ring->count = count;
744 	ring->cur = 0;
745 	ring->next = 0;
746 
747 	err = rt2661_alloc_dma_mem(sc->sc_dev, &rt2661_dma_attr, size,
748 	    &rt2661_desc_accattr, DDI_DMA_CONSISTENT,
749 	    DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
750 	    &ring->rxdesc_dma);
751 	if (err != DDI_SUCCESS) {
752 		RWD_DEBUG(RT2661_DBG_DMA, "rwd: rt2661_alloc_rx_ring(): "
753 		    "failed to alloc dma mem\n");
754 		goto fail1;
755 	}
756 
757 	ring->desc = (struct rt2661_rx_desc *)ring->rxdesc_dma.mem_va;
758 	(void) bzero(ring->desc, size);
759 	ring->paddr = ring->rxdesc_dma.cookie.dmac_address;
760 
761 	ring->data = kmem_zalloc(len, KM_NOSLEEP);
762 	if (ring->data == NULL) {
763 		RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_alloc_rx_ring(): "
764 		    "failed to alloc rx buffer\n");
765 		goto fail2;
766 	}
767 
768 	for (i = 0; i < count; i++) {
769 		desc = &ring->desc[i];
770 		data = &ring->data[i];
771 		err = rt2661_alloc_dma_mem(sc->sc_dev,
772 		    &rt2661_dma_attr, sc->sc_dmabuf_size,
773 		    &rt2661_buf_accattr, DDI_DMA_CONSISTENT,
774 		    DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
775 		    &data->rxdata_dma);
776 		if (err != DDI_SUCCESS) {
777 			RWD_DEBUG(RT2661_DBG_DMA,
778 			    "rwd: rt2661_alloc_rx_ring(): "
779 			    "failed to alloc rx buffer dma\n");
780 			while (i >= 0) {
781 				rt2661_free_dma_mem(&ring->data[i].rxdata_dma);
782 				i--;
783 			}
784 			goto fail3;
785 		}
786 		data->buf = data->rxdata_dma.mem_va;
787 		data->paddr = data->rxdata_dma.cookie.dmac_address;
788 		desc->flags = LE_32(RT2661_RX_BUSY);
789 		desc->physaddr = LE_32(data->paddr);
790 	}
791 
792 	(void) ddi_dma_sync(ring->rxdesc_dma.dma_hdl,
793 	    0, size, DDI_DMA_SYNC_FORDEV);
794 	return (DDI_SUCCESS);
795 fail3:
796 	if (ring->data)
797 		kmem_free(ring->data,
798 		    count * sizeof (struct rt2661_rx_data));
799 fail2:
800 	rt2661_free_dma_mem(&ring->rxdesc_dma);
801 fail1:
802 	return (err);
803 }
804 
805 static void
806 rt2661_reset_rx_ring(struct rt2661_softc *sc, struct rt2661_rx_ring *ring)
807 {
808 	int i;
809 
810 	for (i = 0; i < ring->count; i++)
811 		ring->desc[i].flags = LE_32(RT2661_RX_BUSY);
812 
813 	if (!RT2661_IS_FASTREBOOT(sc))
814 		(void) ddi_dma_sync(ring->rxdesc_dma.dma_hdl, 0,
815 		    ring->count * sizeof (struct rt2661_rx_ring),
816 		    DDI_DMA_SYNC_FORKERNEL);
817 
818 	ring->cur = ring->next = 0;
819 }
820 
821 /*ARGSUSED*/
822 static void
823 rt2661_free_rx_ring(struct rt2661_softc *sc, struct rt2661_rx_ring *ring)
824 {
825 	struct rt2661_rx_data *data;
826 	int i;
827 
828 	if (ring->desc != NULL) {
829 		rt2661_free_dma_mem(&ring->rxdesc_dma);
830 	}
831 
832 	if (ring->data != NULL) {
833 		for (i = 0; i < ring->count; i++) {
834 			data = &ring->data[i];
835 			rt2661_free_dma_mem(&data->rxdata_dma);
836 		}
837 		kmem_free(ring->data,
838 		    ring->count * sizeof (struct rt2661_rx_data));
839 	}
840 }
841 
842 static void
843 rt2661_tx_dma_intr(struct rt2661_softc *sc, struct rt2661_tx_ring *ring)
844 {
845 	struct rt2661_tx_desc *desc;
846 	struct rt2661_tx_data *data;
847 
848 	for (;;) {
849 		desc = &ring->desc[ring->next];
850 		data = &ring->data[ring->next];
851 
852 		(void) ddi_dma_sync(ring->txdesc_dma.dma_hdl,
853 		    ring->next * RT2661_TX_DESC_SIZE,
854 		    RT2661_TX_DESC_SIZE,
855 		    DDI_DMA_SYNC_FORKERNEL);
856 
857 		if ((LE_32(desc->flags) & RT2661_TX_BUSY) ||
858 		    !(LE_32(desc->flags) & RT2661_TX_VALID))
859 			break;
860 
861 		(void) ddi_dma_sync(data->txdata_dma.dma_hdl,
862 		    0, sc->sc_dmabuf_size,
863 		    DDI_DMA_SYNC_FORDEV);
864 
865 		/* descriptor is no longer valid */
866 		desc->flags &= ~LE_32(RT2661_TX_VALID);
867 
868 		(void) ddi_dma_sync(ring->txdesc_dma.dma_hdl,
869 		    ring->next * RT2661_TX_DESC_SIZE,
870 		    RT2661_TX_DESC_SIZE,
871 		    DDI_DMA_SYNC_FORDEV);
872 
873 		RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_tx_dma_intr(): "
874 		    "tx dma done q=%p idx=%u\n", ring, ring->next);
875 
876 		if (++ring->next >= ring->count) /* faster than % count */
877 			ring->next = 0;
878 	}
879 }
880 
881 static void
882 rt2661_tx_intr(struct rt2661_softc *sc)
883 {
884 	struct ieee80211com *ic = &sc->sc_ic;
885 	struct rt2661_tx_ring *ring;
886 	struct rt2661_tx_data *data;
887 	struct rt2661_node *rn;
888 
889 	uint32_t val;
890 	int qid, retrycnt;
891 
892 	for (;;) {
893 		val = RT2661_READ(sc, RT2661_STA_CSR4);
894 		if (!(val & RT2661_TX_STAT_VALID))
895 			break;
896 
897 		/* retrieve the queue in which this frame was send */
898 		qid = RT2661_TX_QID(val);
899 		ring = (qid <= 3) ? &sc->txq[qid] : &sc->mgtq;
900 
901 		/* retrieve rate control algorithm context */
902 		data = &ring->data[ring->stat];
903 		rn = (struct rt2661_node *)data->ni;
904 
905 		/* if no frame has been sent, ignore */
906 		if (rn == NULL) {
907 			RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_tx_intr(): "
908 			    "no frame has been send, ignore\n");
909 			continue;
910 		}
911 
912 		switch (RT2661_TX_RESULT(val)) {
913 		case RT2661_TX_SUCCESS:
914 			retrycnt = RT2661_TX_RETRYCNT(val);
915 
916 			RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_tx_intr(): "
917 			    "data frame sent successfully after "
918 			    "%d retries\n", retrycnt);
919 			rn->amn.amn_txcnt++;
920 			if (retrycnt > 0) {
921 				rn->amn.amn_retrycnt++;
922 				sc->sc_tx_retries++;
923 			}
924 			break;
925 		case RT2661_TX_RETRY_FAIL:
926 			RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_tx_intr(): "
927 			    "sending data frame failed (too much retries)\n");
928 			rn->amn.amn_txcnt++;
929 			rn->amn.amn_retrycnt++;
930 			break;
931 		default:
932 			/* other failure */
933 			RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_tx_intr():"
934 			    "sending data frame failed 0x%08x\n", val);
935 		}
936 
937 		RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_tx_intr(): "
938 		    "tx done q=%d idx=%u\n", qid, ring->stat);
939 
940 		ieee80211_free_node(data->ni);
941 		data->ni = NULL;
942 
943 		ring->queued--;
944 
945 		/* faster than % count */
946 		if (++ring->stat >= ring->count)
947 			ring->stat = 0;
948 
949 		if (sc->sc_need_sched) {
950 			sc->sc_need_sched = 0;
951 			mac_tx_update(ic->ic_mach);
952 		}
953 	}
954 	sc->sc_tx_timer = 0;
955 }
956 
957 static void
958 rt2661_rx_intr(struct rt2661_softc *sc)
959 {
960 	struct ieee80211com *ic = &sc->sc_ic;
961 	struct rt2661_rx_ring *ring;
962 	struct rt2661_rx_desc *desc;
963 	struct rt2661_rx_data *data;
964 	struct ieee80211_frame *wh;
965 	struct ieee80211_node *ni;
966 
967 	mblk_t *m;
968 	uint8_t *rxbuf;
969 	uint32_t pktlen;
970 
971 	mutex_enter(&sc->sc_rxlock);
972 	ring = &sc->rxq;
973 
974 	for (;;) {
975 		int rssi;
976 
977 		desc = &ring->desc[ring->cur];
978 		data = &ring->data[ring->cur];
979 
980 		(void) ddi_dma_sync(ring->rxdesc_dma.dma_hdl,
981 		    ring->cur * RT2661_RX_DESC_SIZE,
982 		    RT2661_RX_DESC_SIZE,
983 		    DDI_DMA_SYNC_FORKERNEL);
984 
985 
986 		if (LE_32(desc->flags) & RT2661_RX_BUSY)
987 			break;
988 
989 		if ((LE_32(desc->flags) & RT2661_RX_PHY_ERROR) ||
990 		    (LE_32(desc->flags) & RT2661_RX_CRC_ERROR)) {
991 			/*
992 			 * This should not happen since we did not request
993 			 * to receive those frames when we filled TXRX_CSR0.
994 			 */
995 			RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_rx_intr(): "
996 			    "PHY or CRC error flags 0x%08x\n",
997 			    LE_32(desc->flags));
998 			sc->sc_rx_err++;
999 			goto skip;
1000 		}
1001 
1002 		if ((LE_32(desc->flags) & RT2661_RX_CIPHER_MASK) != 0) {
1003 			sc->sc_rx_err++;
1004 			goto skip;
1005 		}
1006 
1007 		(void) ddi_dma_sync(data->rxdata_dma.dma_hdl,
1008 		    0, sc->sc_dmabuf_size,
1009 		    DDI_DMA_SYNC_FORCPU);
1010 
1011 		rxbuf = (uint8_t *)data->rxdata_dma.mem_va;
1012 		desc->physaddr = LE_32(data->rxdata_dma.cookie.dmac_address);
1013 		pktlen = (LE_32(desc->flags) >> 16) & 0xfff;
1014 		if ((pktlen < sizeof (struct ieee80211_frame_min)) ||
1015 		    (pktlen > sc->sc_dmabuf_size)) {
1016 			RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_rx_intr(): "
1017 			    "bad fram length=%u\n", pktlen);
1018 			sc->sc_rx_err++;
1019 			goto skip;
1020 		}
1021 
1022 		if ((m = allocb(pktlen, BPRI_MED)) == NULL) {
1023 			RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_rx_intr(): "
1024 			    "allocate mblk failed.\n");
1025 			sc->sc_rx_nobuf++;
1026 			goto skip;
1027 		}
1028 
1029 		bcopy(rxbuf, m->b_rptr, pktlen);
1030 		m->b_wptr += pktlen;
1031 
1032 		wh = (struct ieee80211_frame *)m->b_rptr;
1033 		ni = ieee80211_find_rxnode(ic, wh);
1034 
1035 		rssi = rt2661_get_rssi(sc, desc->rssi);
1036 		/* send the frame to the 802.11 layer */
1037 		(void) ieee80211_input(ic, m, ni, rssi + 95, 0);
1038 
1039 		sc->avg_rssi = (rssi + 7 * sc->avg_rssi) / 8;
1040 
1041 		/* node is no longer needed */
1042 		ieee80211_free_node(ni);
1043 skip:
1044 		desc->flags |= LE_32(RT2661_RX_BUSY);
1045 
1046 		(void) ddi_dma_sync(ring->rxdesc_dma.dma_hdl,
1047 		    ring->cur * RT2661_RX_DESC_SIZE,
1048 		    RT2661_RX_DESC_SIZE,
1049 		    DDI_DMA_SYNC_FORDEV);
1050 
1051 		RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_rx_intr(): "
1052 		    "rx intr idx=%u\n", sc->rxq.cur);
1053 		ring->cur = (ring->cur + 1) % RT2661_RX_RING_COUNT;
1054 	}
1055 	mutex_exit(&sc->sc_rxlock);
1056 }
1057 
1058 /*ARGSUSED*/
1059 static uint_t
1060 rt2661_softintr(caddr_t data, caddr_t unused)
1061 {
1062 	struct rt2661_softc *sc = (struct rt2661_softc *)data;
1063 
1064 	if (sc->sc_rx_pend) {
1065 		sc->sc_rx_pend = 0;
1066 		rt2661_rx_intr(sc);
1067 		return (DDI_INTR_CLAIMED);
1068 	}
1069 	return (DDI_INTR_UNCLAIMED);
1070 }
1071 
1072 static int
1073 rt2661_tx_cmd(struct rt2661_softc *sc, uint8_t cmd, uint16_t arg)
1074 {
1075 	if (RT2661_READ(sc, RT2661_H2M_MAILBOX_CSR) & RT2661_H2M_BUSY)
1076 		return (EIO);	/* there is already a command pending */
1077 
1078 	RT2661_WRITE(sc, RT2661_H2M_MAILBOX_CSR,
1079 	    RT2661_H2M_BUSY | RT2661_TOKEN_NO_INTR << 16 | arg);
1080 
1081 	RT2661_WRITE(sc, RT2661_HOST_CMD_CSR, RT2661_KICK_CMD | cmd);
1082 
1083 	return (0);
1084 }
1085 
1086 static void
1087 rt2661_mcu_wakeup(struct rt2661_softc *sc)
1088 {
1089 	RT2661_WRITE(sc, RT2661_MAC_CSR11, 5 << 16);
1090 
1091 	RT2661_WRITE(sc, RT2661_SOFT_RESET_CSR, 0x7);
1092 	RT2661_WRITE(sc, RT2661_IO_CNTL_CSR, 0x18);
1093 	RT2661_WRITE(sc, RT2661_PCI_USEC_CSR, 0x20);
1094 
1095 	/* send wakeup command to MCU */
1096 	(void) rt2661_tx_cmd(sc, RT2661_MCU_CMD_WAKEUP, 0);
1097 }
1098 
1099 static void
1100 rt2661_mcu_cmd_intr(struct rt2661_softc *sc)
1101 {
1102 	(void) RT2661_READ(sc, RT2661_M2H_CMD_DONE_CSR);
1103 	RT2661_WRITE(sc, RT2661_M2H_CMD_DONE_CSR, 0xffffffff);
1104 }
1105 
1106 /*ARGSUSED*/
1107 static uint_t
1108 rt2661_intr(caddr_t arg, caddr_t unused)
1109 {
1110 	struct rt2661_softc *sc = (struct rt2661_softc *)arg;
1111 	uint32_t r1, r2;
1112 
1113 	RT2661_GLOCK(sc);
1114 
1115 	if (!RT2661_IS_RUNNING(sc) || RT2661_IS_SUSPEND(sc)) {
1116 		RT2661_GUNLOCK(sc);
1117 		return (DDI_INTR_UNCLAIMED);
1118 	}
1119 
1120 	r1 = RT2661_READ(sc, RT2661_INT_SOURCE_CSR);
1121 	r2 = RT2661_READ(sc, RT2661_MCU_INT_SOURCE_CSR);
1122 	if (r1 == 0 && r2 == 0) {
1123 		RT2661_GUNLOCK(sc);
1124 		return (DDI_INTR_UNCLAIMED);	/* not for us */
1125 	}
1126 
1127 	/* disable MAC and MCU interrupts */
1128 	RT2661_WRITE(sc, RT2661_INT_MASK_CSR, 0xffffff7f);
1129 	RT2661_WRITE(sc, RT2661_MCU_INT_MASK_CSR, 0xffffffff);
1130 
1131 	/* acknowledge interrupts */
1132 	RT2661_WRITE(sc, RT2661_INT_SOURCE_CSR, r1);
1133 	RT2661_WRITE(sc, RT2661_MCU_INT_SOURCE_CSR, r2);
1134 
1135 	if (r1 & RT2661_MGT_DONE) {
1136 		RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_intr(): "
1137 		    "RT2661_MGT_DONE\n");
1138 		rt2661_tx_dma_intr(sc, &sc->mgtq);
1139 	}
1140 
1141 	if (r1 & RT2661_RX_DONE) {
1142 		RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_intr(): "
1143 		    "RT2661_RX_DONE\n");
1144 		sc->sc_rx_pend = 1;
1145 		(void) ddi_intr_trigger_softint(sc->sc_softintr_hdl, NULL);
1146 	}
1147 
1148 	if (r1 & RT2661_TX0_DMA_DONE) {
1149 		RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_intr(): "
1150 		    "RT2661_TX0_DMA_DONE\n");
1151 		rt2661_tx_dma_intr(sc, &sc->txq[0]);
1152 	}
1153 
1154 	if (r1 & RT2661_TX1_DMA_DONE) {
1155 		RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_intr(): "
1156 		    "RT2661_TX1_DMA_DONE\n");
1157 		rt2661_tx_dma_intr(sc, &sc->txq[1]);
1158 	}
1159 
1160 	if (r1 & RT2661_TX2_DMA_DONE) {
1161 		RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_intr(): "
1162 		    "RT2661_TX2_DMA_DONE\n");
1163 		rt2661_tx_dma_intr(sc, &sc->txq[2]);
1164 	}
1165 
1166 	if (r1 & RT2661_TX3_DMA_DONE) {
1167 		RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_intr(): "
1168 		    "RT2661_TX3_DMA_DONE\n");
1169 		rt2661_tx_dma_intr(sc, &sc->txq[3]);
1170 	}
1171 
1172 	if (r1 & RT2661_TX_DONE) {
1173 		RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_intr(): "
1174 		    "RT2661_TX_DONE\n");
1175 		rt2661_tx_intr(sc);
1176 	}
1177 
1178 	if (r2 & RT2661_MCU_CMD_DONE) {
1179 		RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_intr(): "
1180 		    "RT2661_MCU_CMD_DONE\n");
1181 		rt2661_mcu_cmd_intr(sc);
1182 	}
1183 
1184 	if (r2 & RT2661_MCU_WAKEUP) {
1185 		RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_intr(): "
1186 		    "RT2661_MCU_WAKEUP\n");
1187 		rt2661_mcu_wakeup(sc);
1188 	}
1189 
1190 	/* re-enable MAC and MCU interrupts */
1191 	RT2661_WRITE(sc, RT2661_INT_MASK_CSR, 0x0000ff10);
1192 	RT2661_WRITE(sc, RT2661_MCU_INT_MASK_CSR, 0);
1193 
1194 	RT2661_GUNLOCK(sc);
1195 	return (RT2661_SUCCESS);
1196 }
1197 
1198 /*
1199  * Retrieve the "Received Signal Strength Indicator" from the raw values
1200  * contained in Rx descriptors.  The computation depends on which band the
1201  * frame was received.  Correction values taken from the reference driver.
1202  */
1203 static int
1204 rt2661_get_rssi(struct rt2661_softc *sc, uint8_t raw)
1205 {
1206 	int lna, agc, rssi;
1207 
1208 	lna = (raw >> 5) & 0x3;
1209 	agc = raw & 0x1f;
1210 
1211 	rssi = 2 * agc;
1212 
1213 	if (IEEE80211_IS_CHAN_2GHZ(sc->sc_curchan)) {
1214 		rssi += sc->rssi_2ghz_corr;
1215 
1216 		if (lna == 1)
1217 			rssi -= 64;
1218 		else if (lna == 2)
1219 			rssi -= 74;
1220 		else if (lna == 3)
1221 			rssi -= 90;
1222 	} else {
1223 		rssi += sc->rssi_5ghz_corr;
1224 
1225 		if (lna == 1)
1226 			rssi -= 64;
1227 		else if (lna == 2)
1228 			rssi -= 86;
1229 		else if (lna == 3)
1230 			rssi -= 100;
1231 	}
1232 	return (rssi);
1233 }
1234 
1235 /* quickly determine if a given rate is CCK or OFDM */
1236 #define	RT2661_RATE_IS_OFDM(rate) ((rate) >= 12 && (rate) != 22)
1237 
1238 #define	RT2661_ACK_SIZE	14	/* 10 + 4(FCS) */
1239 #define	RT2661_CTS_SIZE	14	/* 10 + 4(FCS) */
1240 
1241 #define	RT2661_SIFS	10	/* us */
1242 
1243 /*
1244  * Return the expected ack rate for a frame transmitted at rate `rate'.
1245  * XXX: this should depend on the destination node basic rate set.
1246  */
1247 static int
1248 rt2661_ack_rate(struct ieee80211com *ic, int rate)
1249 {
1250 	switch (rate) {
1251 	/* CCK rates */
1252 	case 2:
1253 		return (2);
1254 	case 4:
1255 	case 11:
1256 	case 22:
1257 		return ((ic->ic_curmode == IEEE80211_MODE_11B) ? 4 : rate);
1258 
1259 	/* OFDM rates */
1260 	case 12:
1261 	case 18:
1262 		return (12);
1263 	case 24:
1264 	case 36:
1265 		return (24);
1266 	case 48:
1267 	case 72:
1268 	case 96:
1269 	case 108:
1270 		return (48);
1271 	}
1272 
1273 	/* default to 1Mbps */
1274 	return (2);
1275 }
1276 
1277 /*
1278  * Compute the duration (in us) needed to transmit `len' bytes at rate `rate'.
1279  * The function automatically determines the operating mode depending on the
1280  * given rate. `flags' indicates whether short preamble is in use or not.
1281  */
1282 static uint16_t
1283 rt2661_txtime(int len, int rate, uint32_t flags)
1284 {
1285 	uint16_t txtime;
1286 
1287 	if (RT2661_RATE_IS_OFDM(rate)) {
1288 		/* IEEE Std 802.11a-1999, pp. 37 */
1289 		txtime = (8 + 4 * len + 3 + rate - 1) / rate;
1290 		txtime = 16 + 4 + 4 * txtime + 6;
1291 	} else {
1292 		/* IEEE Std 802.11b-1999, pp. 28 */
1293 		txtime = (16 * len + rate - 1) / rate;
1294 		if (rate != 2 && (flags & IEEE80211_F_SHPREAMBLE))
1295 			txtime +=  72 + 24;
1296 		else
1297 			txtime += 144 + 48;
1298 	}
1299 
1300 	return (txtime);
1301 }
1302 
1303 static uint8_t
1304 rt2661_plcp_signal(int rate)
1305 {
1306 	switch (rate) {
1307 	/* CCK rates (returned values are device-dependent) */
1308 	case 2:
1309 		return (0x0);
1310 	case 4:
1311 		return (0x1);
1312 	case 11:
1313 		return (0x2);
1314 	case 22:
1315 		return (0x3);
1316 
1317 	/* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
1318 	case 12:
1319 		return (0xb);
1320 	case 18:
1321 		return (0xf);
1322 	case 24:
1323 		return (0xa);
1324 	case 36:
1325 		return (0xe);
1326 	case 48:
1327 		return (0x9);
1328 	case 72:
1329 		return (0xd);
1330 	case 96:
1331 		return (0x8);
1332 	case 108:
1333 		return (0xc);
1334 
1335 	/* unsupported rates (should not get there) */
1336 	default:
1337 		return (0xff);
1338 	}
1339 }
1340 
1341 static void
1342 rt2661_setup_tx_desc(struct rt2661_softc *sc, struct rt2661_tx_desc *desc,
1343     uint32_t flags, uint16_t xflags, int len, int rate, int ac)
1344 {
1345 	struct ieee80211com *ic = &sc->sc_ic;
1346 	uint16_t plcp_length;
1347 	int remainder;
1348 
1349 	desc->flags = LE_32(flags);
1350 	desc->flags |= LE_32(len << 16);
1351 	desc->flags |= LE_32(RT2661_TX_BUSY | RT2661_TX_VALID);
1352 
1353 	desc->xflags = LE_16(xflags);
1354 	desc->xflags |= LE_16(1 << 13);
1355 
1356 	desc->wme = LE_16(
1357 	    RT2661_QID(ac) |
1358 	    RT2661_AIFSN(2) |
1359 	    RT2661_LOGCWMIN(4) |
1360 	    RT2661_LOGCWMAX(10));
1361 
1362 	/*
1363 	 * Remember in which queue this frame was sent. This field is driver
1364 	 * private data only. It will be made available by the NIC in STA_CSR4
1365 	 * on Tx interrupts.
1366 	 */
1367 	desc->qid = (uint8_t)ac;
1368 
1369 	/* setup PLCP fields */
1370 	desc->plcp_signal  = rt2661_plcp_signal(rate);
1371 	desc->plcp_service = 4;
1372 
1373 	len += IEEE80211_CRC_LEN;
1374 
1375 	if (RT2661_RATE_IS_OFDM(rate)) {
1376 		desc->flags |= LE_32(RT2661_TX_OFDM);
1377 
1378 		plcp_length = len & 0xfff;
1379 		desc->plcp_length_hi = plcp_length >> 6;
1380 		desc->plcp_length_lo = plcp_length & 0x3f;
1381 	} else {
1382 		plcp_length = (16 * len + rate - 1) / rate;
1383 		if (rate == 22) {
1384 			remainder = (16 * len) % 22;
1385 			if (remainder != 0 && remainder < 7)
1386 				desc->plcp_service |= RT2661_PLCP_LENGEXT;
1387 		}
1388 		desc->plcp_length_hi = plcp_length >> 8;
1389 		desc->plcp_length_lo = plcp_length & 0xff;
1390 
1391 		if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
1392 			desc->plcp_signal |= 0x08;
1393 	}
1394 
1395 	/* RT2x61 supports scatter with up to 5 segments */
1396 	desc->len [0] = LE_16(len);
1397 }
1398 
1399 static int
1400 rt2661_send(ieee80211com_t *ic, mblk_t *mp)
1401 {
1402 	struct rt2661_softc *sc = (struct rt2661_softc *)ic;
1403 	struct rt2661_tx_ring *ring;
1404 	struct rt2661_tx_desc *desc;
1405 	struct rt2661_tx_data *data;
1406 	struct ieee80211_frame *wh;
1407 	struct ieee80211_node *ni;
1408 
1409 	int err, off, rate;
1410 	int mblen, pktlen;
1411 	mblk_t *m, *m0;
1412 	uint16_t dur;
1413 	uint32_t flags = 0;
1414 
1415 	mutex_enter(&sc->sc_txlock);
1416 	ring = &sc->txq[0];
1417 	err = DDI_SUCCESS;
1418 
1419 	if (ring->queued > RT2661_TX_RING_COUNT - 8) {
1420 		sc->sc_need_sched = 1;
1421 		sc->sc_tx_nobuf++;
1422 		err = ENOMEM;
1423 		goto fail1;
1424 	}
1425 
1426 	m = allocb(msgdsize(mp) + 32, BPRI_MED);
1427 	if (m == NULL) {
1428 		RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_send():"
1429 		    "can't alloc mblk.\n");
1430 		err = DDI_FAILURE;
1431 		goto fail1;
1432 	}
1433 
1434 	for (off = 0, m0 = mp; m0 != NULL; m0 = m0->b_cont) {
1435 		mblen = MBLKL(m0);
1436 		(void) bcopy(m0->b_rptr, m->b_rptr + off, mblen);
1437 		off += mblen;
1438 	}
1439 	m->b_wptr += off;
1440 
1441 	wh = (struct ieee80211_frame *)m->b_rptr;
1442 	ni = ieee80211_find_txnode(ic, wh->i_addr1);
1443 	if (ni == NULL) {
1444 		err = DDI_FAILURE;
1445 		sc->sc_tx_err++;
1446 		goto fail2;
1447 	}
1448 
1449 	(void) ieee80211_encap(ic, m, ni);
1450 
1451 	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
1452 		struct ieee80211_key *k;
1453 		k = ieee80211_crypto_encap(ic, m);
1454 		if (k == NULL) {
1455 			sc->sc_tx_err++;
1456 			err = DDI_FAILURE;
1457 			goto fail3;
1458 		}
1459 		/* packet header may have moved, reset our local pointer */
1460 		wh = (struct ieee80211_frame *)m->b_rptr;
1461 	}
1462 
1463 	pktlen = msgdsize(m);
1464 
1465 	desc = &ring->desc[ring->cur];
1466 	data = &ring->data[ring->cur];
1467 	data->ni = ieee80211_ref_node(ni);
1468 
1469 	/* pickup a rate */
1470 	if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
1471 		/* multicast frames are sent at the lowest avail. rate */
1472 		rate = ni->in_rates.ir_rates[0];
1473 	} else if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE) {
1474 		rate = ic->ic_sup_rates[ic->ic_curmode].
1475 		    ir_rates[ic->ic_fixed_rate];
1476 	} else
1477 		rate = ni->in_rates.ir_rates[ni->in_txrate];
1478 	if (rate == 0)
1479 		rate = 2;	/* XXX should not happen */
1480 	rate &= IEEE80211_RATE_VAL;
1481 
1482 	if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
1483 		flags |= RT2661_TX_NEED_ACK;
1484 
1485 		dur = rt2661_txtime(RT2661_ACK_SIZE,
1486 		    rt2661_ack_rate(ic, rate), ic->ic_flags) + sc->sifs;
1487 		*(uint16_t *)wh->i_dur = LE_16(dur);
1488 	}
1489 
1490 	bcopy(m->b_rptr, data->buf, pktlen);
1491 	rt2661_setup_tx_desc(sc, desc, flags, 0, pktlen, rate, 0);
1492 
1493 	(void) ddi_dma_sync(data->txdata_dma.dma_hdl,
1494 	    0, pktlen,
1495 	    DDI_DMA_SYNC_FORDEV);
1496 
1497 	(void) ddi_dma_sync(ring->txdesc_dma.dma_hdl,
1498 	    ring->cur * RT2661_TX_DESC_SIZE,
1499 	    RT2661_TX_DESC_SIZE,
1500 	    DDI_DMA_SYNC_FORDEV);
1501 
1502 	RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_send(): "
1503 	    "sending data frame len=%u idx=%u rate=%u\n",
1504 	    pktlen, ring->cur, rate);
1505 
1506 	/* kick Tx */
1507 	ring->queued++;
1508 	ring->cur = (ring->cur + 1) % RT2661_TX_RING_COUNT;
1509 	RT2661_WRITE(sc, RT2661_TX_CNTL_CSR, 1 << 0);
1510 
1511 	ic->ic_stats.is_tx_frags++;
1512 	ic->ic_stats.is_tx_bytes += pktlen;
1513 fail3:
1514 	ieee80211_free_node(ni);
1515 fail2:
1516 	freemsg(m);
1517 fail1:
1518 	if (err == DDI_SUCCESS)
1519 		freemsg(mp);
1520 	mutex_exit(&sc->sc_txlock);
1521 	return (err);
1522 }
1523 
1524 /*ARGSUSED*/
1525 static int
1526 rt2661_mgmt_send(ieee80211com_t *ic, mblk_t *mp, uint8_t type)
1527 {
1528 	struct rt2661_softc *sc = (struct rt2661_softc *)ic;
1529 	struct rt2661_tx_ring *ring;
1530 	struct rt2661_tx_desc *desc;
1531 	struct rt2661_tx_data *data;
1532 	struct ieee80211_frame *wh;
1533 	struct ieee80211_node *ni;
1534 
1535 	int err, off, rate;
1536 	int mblen, pktlen;
1537 	mblk_t *m, *m0;
1538 	uint16_t dur;
1539 	uint32_t flags = 0;
1540 
1541 	if ((!RT2661_IS_RUNNING(sc)) || RT2661_IS_SUSPEND(sc)) {
1542 		err = ENXIO;
1543 		goto fail1;
1544 	}
1545 
1546 	ring = &sc->mgtq;
1547 	err = DDI_SUCCESS;
1548 
1549 	if (ring->queued >= RT2661_MGT_RING_COUNT) {
1550 		sc->sc_tx_nobuf++;
1551 		err = ENOMEM;
1552 		goto fail1;
1553 	}
1554 
1555 	m = allocb(msgdsize(mp) + 32, BPRI_MED);
1556 	if (m == NULL) {
1557 		RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_mgmt_send():"
1558 		    "can't alloc mblk.\n");
1559 		err = DDI_FAILURE;
1560 		goto fail1;
1561 	}
1562 
1563 	for (off = 0, m0 = mp; m0 != NULL; m0 = m0->b_cont) {
1564 		mblen = MBLKL(m0);
1565 		(void) bcopy(m0->b_rptr, m->b_rptr + off, mblen);
1566 		off += mblen;
1567 	}
1568 	m->b_wptr += off;
1569 
1570 	wh = (struct ieee80211_frame *)m->b_rptr;
1571 	ni = ieee80211_find_txnode(ic, wh->i_addr1);
1572 	if (ni == NULL) {
1573 		err = DDI_FAILURE;
1574 		sc->sc_tx_err++;
1575 		goto fail2;
1576 	}
1577 
1578 	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
1579 		struct ieee80211_key *k;
1580 		k = ieee80211_crypto_encap(ic, m);
1581 		if (k == NULL) {
1582 			sc->sc_tx_err++;
1583 			err = DDI_FAILURE;
1584 			goto fail3;
1585 		}
1586 		/* packet header may have moved, reset our local pointer */
1587 		wh = (struct ieee80211_frame *)m->b_rptr;
1588 	}
1589 
1590 	pktlen = msgdsize(m);
1591 
1592 	desc = &ring->desc[ring->cur];
1593 	data = &ring->data[ring->cur];
1594 	data->ni = ieee80211_ref_node(ni);
1595 
1596 	/* send mgt frames at the lowest available rate */
1597 	rate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 2;
1598 
1599 	if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
1600 		flags |= RT2661_TX_NEED_ACK;
1601 
1602 		dur = rt2661_txtime(RT2661_ACK_SIZE,
1603 		    rate, ic->ic_flags) + sc->sifs;
1604 		*(uint16_t *)wh->i_dur = LE_16(dur);
1605 
1606 		/* tell hardware to add timestamp in probe responses */
1607 		if ((wh->i_fc[0] &
1608 		    (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
1609 		    (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP))
1610 			flags |= RT2661_TX_TIMESTAMP;
1611 	}
1612 
1613 	bcopy(m->b_rptr, data->buf, pktlen);
1614 	rt2661_setup_tx_desc(sc, desc, flags, 0, pktlen, rate, RT2661_QID_MGT);
1615 
1616 	(void) ddi_dma_sync(data->txdata_dma.dma_hdl,
1617 	    0, pktlen,
1618 	    DDI_DMA_SYNC_FORDEV);
1619 
1620 	(void) ddi_dma_sync(ring->txdesc_dma.dma_hdl,
1621 	    ring->cur * RT2661_TX_DESC_SIZE,
1622 	    RT2661_TX_DESC_SIZE,
1623 	    DDI_DMA_SYNC_FORDEV);
1624 
1625 	RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_mgmt_send(): "
1626 	    "sending mgmt frame len=%u idx=%u rate=%u\n",
1627 	    pktlen, ring->cur, rate);
1628 
1629 	/* kick Tx */
1630 	ring->queued++;
1631 	ring->cur = (ring->cur + 1) % RT2661_MGT_RING_COUNT;
1632 	RT2661_WRITE(sc, RT2661_TX_CNTL_CSR, RT2661_KICK_MGT);
1633 
1634 	ic->ic_stats.is_tx_frags++;
1635 	ic->ic_stats.is_tx_bytes += pktlen;
1636 
1637 fail3:
1638 	ieee80211_free_node(ni);
1639 fail2:
1640 	freemsg(m);
1641 fail1:
1642 	freemsg(mp);
1643 	return (err);
1644 }
1645 
1646 static void
1647 rt2661_amrr_node_init(const struct rt2661_amrr *amrr,
1648     struct rt2661_amrr_node *amn)
1649 {
1650 	amn->amn_success = 0;
1651 	amn->amn_recovery = 0;
1652 	amn->amn_txcnt = amn->amn_retrycnt = 0;
1653 	amn->amn_success_threshold = amrr->amrr_min_success_threshold;
1654 }
1655 
1656 static void
1657 rt2661_amrr_choose(struct rt2661_amrr *amrr, struct ieee80211_node *ni,
1658     struct rt2661_amrr_node *amn)
1659 {
1660 #define	RV(rate)	((rate) & IEEE80211_RATE_VAL)
1661 #define	is_success(amn)	\
1662 	((amn)->amn_retrycnt < (amn)->amn_txcnt / 10)
1663 #define	is_failure(amn)	\
1664 	((amn)->amn_retrycnt > (amn)->amn_txcnt / 3)
1665 #define	is_enough(amn)		\
1666 	((amn)->amn_txcnt > 10)
1667 #define	is_min_rate(ni)		\
1668 	((ni)->in_txrate == 0)
1669 #define	is_max_rate(ni)		\
1670 	((ni)->in_txrate == (ni)->in_rates.ir_nrates - 1)
1671 #define	increase_rate(ni)	\
1672 	((ni)->in_txrate++)
1673 #define	decrease_rate(ni)	\
1674 	((ni)->in_txrate--)
1675 #define	reset_cnt(amn)		\
1676 	{ (amn)->amn_txcnt = (amn)->amn_retrycnt = 0; }
1677 
1678 	int need_change = 0;
1679 
1680 	if (is_success(amn) && is_enough(amn)) {
1681 		amn->amn_success++;
1682 		if (amn->amn_success >= amn->amn_success_threshold &&
1683 		    !is_max_rate(ni)) {
1684 			amn->amn_recovery = 1;
1685 			amn->amn_success = 0;
1686 			increase_rate(ni);
1687 			RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_amrr_choose(): "
1688 			    "increase rate = %d, #tx = %d, #retries = %d\n",
1689 			    RV(ni->in_rates.ir_rates[ni->in_txrate]),
1690 			    amn->amn_txcnt, amn->amn_retrycnt);
1691 			need_change = 1;
1692 		} else
1693 			amn->amn_recovery = 0;
1694 	} else if (is_failure(amn)) {
1695 		amn->amn_success = 0;
1696 		if (!is_min_rate(ni)) {
1697 			if (amn->amn_recovery) {
1698 				amn->amn_success_threshold *= 2;
1699 				if (amn->amn_success_threshold >
1700 				    amrr->amrr_max_success_threshold)
1701 					amn->amn_success_threshold =
1702 					    amrr->amrr_max_success_threshold;
1703 			} else {
1704 				amn->amn_success_threshold =
1705 				    amrr->amrr_min_success_threshold;
1706 			}
1707 			decrease_rate(ni);
1708 			RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_amrr_choose(): "
1709 			    "decrease rate = %d, #tx = %d, #retries = %d\n",
1710 			    RV(ni->in_rates.ir_rates[ni->in_txrate]),
1711 			    amn->amn_txcnt, amn->amn_retrycnt);
1712 			need_change = 1;
1713 		}
1714 		amn->amn_recovery = 0;
1715 	}
1716 
1717 	if (is_enough(amn) || need_change)
1718 		reset_cnt(amn);
1719 #undef RV
1720 
1721 }
1722 
1723 static void
1724 rt2661_update_promisc(struct rt2661_softc *sc)
1725 {
1726 	uint32_t tmp;
1727 
1728 	tmp = RT2661_READ(sc, RT2661_TXRX_CSR0);
1729 
1730 	tmp &= ~RT2661_DROP_NOT_TO_ME;
1731 	if (!(sc->sc_rcr & RT2661_RCR_PROMISC))
1732 		tmp |= RT2661_DROP_NOT_TO_ME;
1733 
1734 	RT2661_WRITE(sc, RT2661_TXRX_CSR0, tmp);
1735 	RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_update_promisc(): "
1736 	    "%s promiscuous mode\n",
1737 	    (sc->sc_rcr & RT2661_RCR_PROMISC) ? "entering" : "leaving");
1738 }
1739 
1740 static void
1741 rt2661_updateslot(struct ieee80211com *ic, int onoff)
1742 {
1743 	struct rt2661_softc *sc = (struct rt2661_softc *)ic;
1744 	uint8_t slottime;
1745 	uint32_t tmp;
1746 
1747 	slottime = (onoff ? 9 : 20);
1748 
1749 	tmp = RT2661_READ(sc, RT2661_MAC_CSR9);
1750 	tmp = (tmp & ~0xff) | slottime;
1751 	RT2661_WRITE(sc, RT2661_MAC_CSR9, tmp);
1752 
1753 	RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_updateslot(): "
1754 	    "setting slot time to %uus\n", slottime);
1755 }
1756 
1757 static void
1758 rt2661_set_slottime(struct rt2661_softc *sc)
1759 {
1760 	struct ieee80211com *ic = &sc->sc_ic;
1761 	uint8_t slottime;
1762 	uint32_t tmp;
1763 
1764 	slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20;
1765 
1766 	tmp = RT2661_READ(sc, RT2661_MAC_CSR9);
1767 	tmp = (tmp & ~0xff) | slottime;
1768 	RT2661_WRITE(sc, RT2661_MAC_CSR9, tmp);
1769 
1770 	RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_set_slottime(): "
1771 	    "setting slot time to %uus\n", slottime);
1772 }
1773 
1774 
1775 /*
1776  * Enable multi-rate retries for frames sent at OFDM rates.
1777  * In 802.11b/g mode, allow fallback to CCK rates.
1778  */
1779 static void
1780 rt2661_enable_mrr(struct rt2661_softc *sc)
1781 {
1782 	struct ieee80211com *ic = &sc->sc_ic;
1783 	uint32_t tmp;
1784 
1785 	tmp = RT2661_READ(sc, RT2661_TXRX_CSR4);
1786 
1787 	tmp &= ~RT2661_MRR_CCK_FALLBACK;
1788 	if (!IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
1789 		tmp |= RT2661_MRR_CCK_FALLBACK;
1790 	tmp |= RT2661_MRR_ENABLED;
1791 
1792 	RT2661_WRITE(sc, RT2661_TXRX_CSR4, tmp);
1793 }
1794 
1795 static void
1796 rt2661_set_txpreamble(struct rt2661_softc *sc)
1797 {
1798 	uint32_t tmp;
1799 
1800 	tmp = RT2661_READ(sc, RT2661_TXRX_CSR4);
1801 
1802 	tmp &= ~RT2661_SHORT_PREAMBLE;
1803 	if (sc->sc_ic.ic_flags & IEEE80211_F_SHPREAMBLE)
1804 		tmp |= RT2661_SHORT_PREAMBLE;
1805 
1806 	RT2661_WRITE(sc, RT2661_TXRX_CSR4, tmp);
1807 }
1808 
1809 static void
1810 rt2661_set_basicrates(struct rt2661_softc *sc)
1811 {
1812 	struct ieee80211com *ic = &sc->sc_ic;
1813 
1814 	/* update basic rate set */
1815 	if (ic->ic_curmode == IEEE80211_MODE_11B) {
1816 		/* 11b basic rates: 1, 2Mbps */
1817 		RT2661_WRITE(sc, RT2661_TXRX_CSR5, 0x3);
1818 	} else if (ic->ic_curmode == IEEE80211_MODE_11A) {
1819 		/* 11a basic rates: 6, 12, 24Mbps */
1820 		RT2661_WRITE(sc, RT2661_TXRX_CSR5, 0x150);
1821 	} else {
1822 		/* 11b/g basic rates: 1, 2, 5.5, 11Mbps */
1823 		RT2661_WRITE(sc, RT2661_TXRX_CSR5, 0xf);
1824 	}
1825 }
1826 
1827 static void
1828 rt2661_set_bssid(struct rt2661_softc *sc, const uint8_t *bssid)
1829 {
1830 	uint32_t tmp;
1831 
1832 	tmp = bssid[0] | bssid[1] << 8 | bssid[2] << 16 | bssid[3] << 24;
1833 	RT2661_WRITE(sc, RT2661_MAC_CSR4, tmp);
1834 
1835 	tmp = bssid[4] | bssid[5] << 8 | RT2661_ONE_BSSID << 16;
1836 	RT2661_WRITE(sc, RT2661_MAC_CSR5, tmp);
1837 }
1838 
1839 /*
1840  * Enable TSF synchronization and tell h/w to start sending beacons for IBSS
1841  * and HostAP operating modes.
1842  */
1843 static void
1844 rt2661_enable_tsf_sync(struct rt2661_softc *sc)
1845 {
1846 	struct ieee80211com *ic = &sc->sc_ic;
1847 	uint32_t tmp;
1848 
1849 	tmp = RT2661_READ(sc, RT2661_TXRX_CSR9) & 0xff000000;
1850 
1851 	/* set beacon interval (in 1/16ms unit) */
1852 	tmp |= ic->ic_bss->in_intval * 16;
1853 
1854 	tmp |= RT2661_TSF_TICKING | RT2661_ENABLE_TBTT;
1855 	if (ic->ic_opmode == IEEE80211_M_STA)
1856 		tmp |= RT2661_TSF_MODE(1);
1857 
1858 	RT2661_WRITE(sc, RT2661_TXRX_CSR9, tmp);
1859 }
1860 
1861 
1862 static void
1863 rt2661_next_scan(void *arg)
1864 {
1865 	struct rt2661_softc *sc = arg;
1866 	struct ieee80211com *ic = &sc->sc_ic;
1867 
1868 	if (ic->ic_state == IEEE80211_S_SCAN)
1869 		(void) ieee80211_next_scan(ic);
1870 }
1871 
1872 static void
1873 rt2661_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni)
1874 {
1875 	struct rt2661_softc *sc = (struct rt2661_softc *)ic;
1876 	int i;
1877 
1878 	rt2661_amrr_node_init(&sc->amrr, &((struct rt2661_node *)ni)->amn);
1879 
1880 	/* set rate to some reasonable initial value */
1881 	i = ni->in_rates.ir_nrates - 1;
1882 	while (i > 0 && ((ni->in_rates.ir_rates[i] & IEEE80211_RATE_VAL) > 72))
1883 		i--;
1884 
1885 	ni->in_txrate = i;
1886 }
1887 
1888 static void
1889 rt2661_iter_func(void *arg, struct ieee80211_node *ni)
1890 {
1891 	struct rt2661_softc *sc = arg;
1892 	struct rt2661_node *rn = (struct rt2661_node *)ni;
1893 
1894 	rt2661_amrr_choose(&sc->amrr, ni, &rn->amn);
1895 
1896 }
1897 
1898 /*
1899  * Dynamically tune Rx sensitivity (BBP register 17) based on average RSSI and
1900  * false CCA count.  This function is called periodically (every seconds) when
1901  * in the RUN state.  Values taken from the reference driver.
1902  */
1903 static void
1904 rt2661_rx_tune(struct rt2661_softc *sc)
1905 {
1906 	uint8_t	bbp17;
1907 	uint16_t cca;
1908 	int lo, hi, dbm;
1909 
1910 	/*
1911 	 * Tuning range depends on operating band and on the presence of an
1912 	 * external low-noise amplifier.
1913 	 */
1914 	lo = 0x20;
1915 	if (IEEE80211_IS_CHAN_5GHZ(sc->sc_curchan))
1916 		lo += 0x08;
1917 	if ((IEEE80211_IS_CHAN_2GHZ(sc->sc_curchan) && sc->ext_2ghz_lna) ||
1918 	    (IEEE80211_IS_CHAN_5GHZ(sc->sc_curchan) && sc->ext_5ghz_lna))
1919 		lo += 0x10;
1920 	hi = lo + 0x20;
1921 
1922 	dbm = sc->avg_rssi;
1923 	/* retrieve false CCA count since last call (clear on read) */
1924 	cca = RT2661_READ(sc, RT2661_STA_CSR1) & 0xffff;
1925 
1926 	RWD_DEBUG(RT2661_DBG_INTR, "rwd: rt2661_rx_tune(): "
1927 	    "RSSI=%ddBm false CCA=%d\n", dbm, cca);
1928 
1929 	if (dbm < -74) {
1930 		/* very bad RSSI, tune using false CCA count */
1931 		bbp17 = sc->bbp17; /* current value */
1932 
1933 		hi -= 2 * (-74 - dbm);
1934 		if (hi < lo)
1935 			hi = lo;
1936 
1937 		if (bbp17 > hi)
1938 			bbp17 = (uint8_t)hi;
1939 		else if (cca > 512)
1940 			bbp17 = (uint8_t)min(bbp17 + 1, hi);
1941 		else if (cca < 100)
1942 			bbp17 = (uint8_t)max(bbp17 - 1, lo);
1943 
1944 	} else if (dbm < -66) {
1945 		bbp17 = lo + 0x08;
1946 	} else if (dbm < -58) {
1947 		bbp17 = lo + 0x10;
1948 	} else if (dbm < -35) {
1949 		bbp17 = (uint8_t)hi;
1950 	} else {	/* very good RSSI >= -35dBm */
1951 		bbp17 = 0x60;	/* very low sensitivity */
1952 	}
1953 
1954 	if (bbp17 != sc->bbp17) {
1955 		RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_rx_tune(): "
1956 		    "BBP17 %x->%x\n", sc->bbp17, bbp17);
1957 		rt2661_bbp_write(sc, 17, bbp17);
1958 		sc->bbp17 = bbp17;
1959 	}
1960 }
1961 
1962 /*
1963  * This function is called periodically (every 500ms) in RUN state to update
1964  * various settings like rate control statistics or Rx sensitivity.
1965  */
1966 static void
1967 rt2661_updatestats(void *arg)
1968 {
1969 	struct rt2661_softc *sc = arg;
1970 	struct ieee80211com *ic = &sc->sc_ic;
1971 
1972 	if (ic->ic_opmode == IEEE80211_M_STA)
1973 		rt2661_iter_func(sc, ic->ic_bss);
1974 	else
1975 		ieee80211_iterate_nodes(&ic->ic_sta, rt2661_iter_func, arg);
1976 
1977 	/* update rx sensitivity every 1 sec */
1978 	if (++sc->ncalls & 1)
1979 		rt2661_rx_tune(sc);
1980 
1981 	sc->sc_rssadapt_id = timeout(rt2661_updatestats, (void *)sc,
1982 	    drv_usectohz(200 * 1000));
1983 }
1984 
1985 static int
1986 rt2661_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
1987 {
1988 	struct rt2661_softc *sc = (struct rt2661_softc *)ic;
1989 	enum ieee80211_state ostate;
1990 	struct ieee80211_node *ni;
1991 	uint32_t tmp;
1992 	int err;
1993 
1994 	RT2661_GLOCK(sc);
1995 
1996 	ostate = ic->ic_state;
1997 	sc->sc_ostate = ostate;
1998 
1999 	RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt26661_newstate(): "
2000 	    "%x -> %x\n", ostate, nstate);
2001 
2002 	if (sc->sc_scan_id != 0) {
2003 		(void) untimeout(sc->sc_scan_id);
2004 		sc->sc_scan_id = 0;
2005 	}
2006 
2007 	if (sc->sc_rssadapt_id) {
2008 		(void) untimeout(sc->sc_rssadapt_id);
2009 		sc->sc_rssadapt_id = 0;
2010 	}
2011 
2012 	switch (nstate) {
2013 	case IEEE80211_S_INIT:
2014 		if (ostate == IEEE80211_S_RUN) {
2015 			/* abort TSF synchronization */
2016 			tmp = RT2661_READ(sc, RT2661_TXRX_CSR9);
2017 			RT2661_WRITE(sc, RT2661_TXRX_CSR9, tmp & ~0x00ffffff);
2018 		}
2019 		break;
2020 	case IEEE80211_S_SCAN:
2021 		rt2661_set_chan(sc, ic->ic_curchan);
2022 		sc->sc_scan_id = timeout(rt2661_next_scan, (void *)sc,
2023 		    drv_usectohz(200000));
2024 		break;
2025 	case IEEE80211_S_AUTH:
2026 	case IEEE80211_S_ASSOC:
2027 		rt2661_set_chan(sc, ic->ic_curchan);
2028 		break;
2029 	case IEEE80211_S_RUN:
2030 		rt2661_set_chan(sc, ic->ic_curchan);
2031 
2032 		ni = ic->ic_bss;
2033 		if (ic->ic_opmode != IEEE80211_M_MONITOR) {
2034 			rt2661_set_slottime(sc);
2035 			rt2661_enable_mrr(sc);
2036 			rt2661_set_txpreamble(sc);
2037 			rt2661_set_basicrates(sc);
2038 			rt2661_set_bssid(sc, ni->in_bssid);
2039 		}
2040 
2041 		if (ic->ic_opmode == IEEE80211_M_STA) {
2042 			/* fake a join to init the tx rate */
2043 			rt2661_newassoc(ic, ni);
2044 		}
2045 
2046 		if (ic->ic_opmode != IEEE80211_M_MONITOR) {
2047 			sc->ncalls = 0;
2048 			sc->avg_rssi = -95;	/* reset EMA */
2049 			sc->sc_rssadapt_id = timeout(rt2661_updatestats,
2050 			    (void *)sc, drv_usectohz(200 * 1000));
2051 			rt2661_enable_tsf_sync(sc);
2052 		}
2053 		break;
2054 	default:
2055 		break;
2056 	}
2057 
2058 	RT2661_GUNLOCK(sc);
2059 
2060 	err = sc->sc_newstate(ic, nstate, arg);
2061 	return (err);
2062 }
2063 
2064 /*ARGSUSED*/
2065 static struct ieee80211_node *
2066 rt2661_node_alloc(ieee80211com_t *ic)
2067 {
2068 	struct rt2661_node *rn;
2069 
2070 	rn = kmem_zalloc(sizeof (struct rt2661_node), KM_SLEEP);
2071 	return ((rn != NULL) ? &rn->ni : NULL);
2072 }
2073 
2074 static void
2075 rt2661_node_free(struct ieee80211_node *in)
2076 {
2077 	struct ieee80211com *ic = in->in_ic;
2078 
2079 	ic->ic_node_cleanup(in);
2080 	if (in->in_wpa_ie != NULL)
2081 		ieee80211_free(in->in_wpa_ie);
2082 	kmem_free(in, sizeof (struct rt2661_node));
2083 }
2084 
2085 static void
2086 rt2661_stop_locked(struct rt2661_softc *sc)
2087 {
2088 	uint32_t tmp;
2089 
2090 	if (RT2661_IS_RUNNING(sc)) {
2091 		sc->sc_tx_timer = 0;
2092 
2093 		/* abort Tx (for all 5 Tx rings) */
2094 		RT2661_WRITE(sc, RT2661_TX_CNTL_CSR, 0x1f << 16);
2095 
2096 		/* disable Rx (value remains after reset!) */
2097 		tmp = RT2661_READ(sc, RT2661_TXRX_CSR0);
2098 		RT2661_WRITE(sc, RT2661_TXRX_CSR0, tmp | RT2661_DISABLE_RX);
2099 
2100 		/* reset ASIC */
2101 		RT2661_WRITE(sc, RT2661_MAC_CSR1, 3);
2102 		RT2661_WRITE(sc, RT2661_MAC_CSR1, 0);
2103 
2104 		/* disable interrupts */
2105 		RT2661_WRITE(sc, RT2661_INT_MASK_CSR, 0xffffff7f);
2106 		RT2661_WRITE(sc, RT2661_MCU_INT_MASK_CSR, 0xffffffff);
2107 
2108 		/* clear any pending interrupt */
2109 		RT2661_WRITE(sc, RT2661_INT_SOURCE_CSR, 0xffffffff);
2110 		RT2661_WRITE(sc, RT2661_MCU_INT_SOURCE_CSR, 0xffffffff);
2111 
2112 		/* reset Tx and Rx rings */
2113 		rt2661_reset_tx_ring(sc, &sc->txq[0]);
2114 		rt2661_reset_tx_ring(sc, &sc->txq[1]);
2115 		rt2661_reset_tx_ring(sc, &sc->txq[2]);
2116 		rt2661_reset_tx_ring(sc, &sc->txq[3]);
2117 		rt2661_reset_tx_ring(sc, &sc->mgtq);
2118 		rt2661_reset_rx_ring(sc, &sc->rxq);
2119 	}
2120 }
2121 
2122 static void
2123 rt2661_set_macaddr(struct rt2661_softc *sc, const uint8_t *addr)
2124 {
2125 	uint32_t tmp;
2126 
2127 	tmp = addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24;
2128 	RT2661_WRITE(sc, RT2661_MAC_CSR2, tmp);
2129 
2130 	tmp = addr[4] | addr[5] << 8 | 0xff << 16;
2131 	RT2661_WRITE(sc, RT2661_MAC_CSR3, tmp);
2132 }
2133 
2134 static uint8_t
2135 rt2661_bbp_read(struct rt2661_softc *sc, uint8_t reg)
2136 {
2137 	uint32_t val;
2138 	int ntries;
2139 
2140 	for (ntries = 0; ntries < 100; ntries++) {
2141 		if (!(RT2661_READ(sc, RT2661_PHY_CSR3) & RT2661_BBP_BUSY))
2142 			break;
2143 		DELAY(1);
2144 	}
2145 	if (ntries == 100) {
2146 		RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_bbp_read(): "
2147 		    "could not read from BBP\n");
2148 		return (0);
2149 	}
2150 
2151 	val = RT2661_BBP_BUSY | RT2661_BBP_READ | reg << 8;
2152 	RT2661_WRITE(sc, RT2661_PHY_CSR3, val);
2153 
2154 	for (ntries = 0; ntries < 100; ntries++) {
2155 		val = RT2661_READ(sc, RT2661_PHY_CSR3);
2156 		if (!(val & RT2661_BBP_BUSY))
2157 			return (val & 0xff);
2158 		DELAY(1);
2159 	}
2160 
2161 	RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_bbp_read(): "
2162 	    "could not read from BBP\n");
2163 	return (0);
2164 }
2165 
2166 static int
2167 rt2661_bbp_init(struct rt2661_softc *sc)
2168 {
2169 #define	N(a)	(sizeof (a) / sizeof ((a)[0]))
2170 
2171 	int i, ntries;
2172 	uint8_t	val;
2173 
2174 	/* wait for BBP to be ready */
2175 	for (ntries = 0; ntries < 100; ntries++) {
2176 		val = rt2661_bbp_read(sc, 0);
2177 		if (val != 0 && val != 0xff)
2178 			break;
2179 		DELAY(100);
2180 	}
2181 	if (ntries == 100) {
2182 		RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_bbp_init(): "
2183 		    "timeout waiting for BBP\n");
2184 		return (RT2661_FAILURE);
2185 	}
2186 
2187 	/* initialize BBP registers to default values */
2188 	for (i = 0; i < N(rt2661_def_bbp); i++) {
2189 		rt2661_bbp_write(sc, rt2661_def_bbp[i].reg,
2190 		    rt2661_def_bbp[i].val);
2191 	}
2192 
2193 	/* write vendor-specific BBP values (from EEPROM) */
2194 	for (i = 0; i < 16; i++) {
2195 		if (sc->bbp_prom[i].reg == 0)
2196 			continue;
2197 		rt2661_bbp_write(sc, sc->bbp_prom[i].reg, sc->bbp_prom[i].val);
2198 	}
2199 
2200 	return (RT2661_SUCCESS);
2201 #undef N
2202 }
2203 
2204 static void
2205 rt2661_bbp_write(struct rt2661_softc *sc, uint8_t reg, uint8_t val)
2206 {
2207 	uint32_t tmp;
2208 	int ntries;
2209 
2210 	for (ntries = 0; ntries < 100; ntries++) {
2211 		if (!(RT2661_READ(sc, RT2661_PHY_CSR3) & RT2661_BBP_BUSY))
2212 			break;
2213 		DELAY(1);
2214 	}
2215 	if (ntries == 100) {
2216 		RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_bbp_write(): "
2217 		    "could not write to BBP\n");
2218 		return;
2219 	}
2220 
2221 	tmp = RT2661_BBP_BUSY | (reg & 0x7f) << 8 | val;
2222 	RT2661_WRITE(sc, RT2661_PHY_CSR3, tmp);
2223 
2224 	RWD_DEBUG(RT2661_DBG_HW, "rwd: rt2661_bbp_write(): "
2225 	    "BBP R%u <- 0x%02x\n", reg, val);
2226 }
2227 
2228 /*
2229  * Reprogram MAC/BBP to switch to a new band.  Values taken from the reference
2230  * driver.
2231  */
2232 static void
2233 rt2661_select_band(struct rt2661_softc *sc, struct ieee80211_channel *c)
2234 {
2235 	uint8_t bbp17, bbp35, bbp96, bbp97, bbp98, bbp104;
2236 	uint32_t tmp;
2237 
2238 	/* update all BBP registers that depend on the band */
2239 	bbp17 = 0x20; bbp96 = 0x48; bbp104 = 0x2c;
2240 	bbp35 = 0x50; bbp97 = 0x48; bbp98  = 0x48;
2241 	if (IEEE80211_IS_CHAN_5GHZ(c)) {
2242 		bbp17 += 0x08; bbp96 += 0x10; bbp104 += 0x0c;
2243 		bbp35 += 0x10; bbp97 += 0x10; bbp98  += 0x10;
2244 	}
2245 	if ((IEEE80211_IS_CHAN_2GHZ(c) && sc->ext_2ghz_lna) ||
2246 	    (IEEE80211_IS_CHAN_5GHZ(c) && sc->ext_5ghz_lna)) {
2247 		bbp17 += 0x10; bbp96 += 0x10; bbp104 += 0x10;
2248 	}
2249 
2250 	sc->bbp17 = bbp17;
2251 	rt2661_bbp_write(sc,  17, bbp17);
2252 	rt2661_bbp_write(sc,  96, bbp96);
2253 	rt2661_bbp_write(sc, 104, bbp104);
2254 
2255 	if ((IEEE80211_IS_CHAN_2GHZ(c) && sc->ext_2ghz_lna) ||
2256 	    (IEEE80211_IS_CHAN_5GHZ(c) && sc->ext_5ghz_lna)) {
2257 		rt2661_bbp_write(sc, 75, 0x80);
2258 		rt2661_bbp_write(sc, 86, 0x80);
2259 		rt2661_bbp_write(sc, 88, 0x80);
2260 	}
2261 
2262 	rt2661_bbp_write(sc, 35, bbp35);
2263 	rt2661_bbp_write(sc, 97, bbp97);
2264 	rt2661_bbp_write(sc, 98, bbp98);
2265 
2266 	tmp = RT2661_READ(sc, RT2661_PHY_CSR0);
2267 	tmp &= ~(RT2661_PA_PE_2GHZ | RT2661_PA_PE_5GHZ);
2268 	if (IEEE80211_IS_CHAN_2GHZ(c))
2269 		tmp |= RT2661_PA_PE_2GHZ;
2270 	else
2271 		tmp |= RT2661_PA_PE_5GHZ;
2272 	RT2661_WRITE(sc, RT2661_PHY_CSR0, tmp);
2273 
2274 	/* 802.11a uses a 16 microseconds short interframe space */
2275 	sc->sifs = IEEE80211_IS_CHAN_5GHZ(c) ? 16 : 10;
2276 }
2277 
2278 static void
2279 rt2661_select_antenna(struct rt2661_softc *sc)
2280 {
2281 	uint8_t bbp4, bbp77;
2282 	uint32_t tmp;
2283 
2284 	bbp4  = rt2661_bbp_read(sc,  4);
2285 	bbp77 = rt2661_bbp_read(sc, 77);
2286 
2287 	/* TBD */
2288 
2289 	/* make sure Rx is disabled before switching antenna */
2290 	tmp = RT2661_READ(sc, RT2661_TXRX_CSR0);
2291 	RT2661_WRITE(sc, RT2661_TXRX_CSR0, tmp | RT2661_DISABLE_RX);
2292 
2293 	rt2661_bbp_write(sc,  4, bbp4);
2294 	rt2661_bbp_write(sc, 77, bbp77);
2295 
2296 	/* restore Rx filter */
2297 	RT2661_WRITE(sc, RT2661_TXRX_CSR0, tmp);
2298 }
2299 
2300 static void
2301 rt2661_rf_write(struct rt2661_softc *sc, uint8_t reg, uint32_t val)
2302 {
2303 	uint32_t tmp;
2304 	int ntries;
2305 
2306 	for (ntries = 0; ntries < 100; ntries++) {
2307 		if (!(RT2661_READ(sc, RT2661_PHY_CSR4) & RT2661_RF_BUSY))
2308 			break;
2309 		DELAY(1);
2310 	}
2311 	if (ntries == 100) {
2312 		RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_rf_write(): "
2313 		    "could not write to RF\n");
2314 		return;
2315 	}
2316 
2317 	tmp = RT2661_RF_BUSY | RT2661_RF_21BIT | (val & 0x1fffff) << 2 |
2318 	    (reg & 3);
2319 	RT2661_WRITE(sc, RT2661_PHY_CSR4, tmp);
2320 
2321 	/* remember last written value in sc */
2322 	sc->rf_regs[reg] = val;
2323 
2324 	RWD_DEBUG(RT2661_DBG_FW, "rwd: rt2661_rf_write(): "
2325 	    "RF R[%u] <- 0x%05x\n", reg & 3, val & 0x1fffff);
2326 }
2327 
2328 static void
2329 rt2661_set_chan(struct rt2661_softc *sc, struct ieee80211_channel *c)
2330 {
2331 	struct ieee80211com *ic = &sc->sc_ic;
2332 	const struct rfprog *rfprog;
2333 	uint8_t bbp3, bbp94 = RT2661_BBPR94_DEFAULT;
2334 	int8_t power;
2335 	uint_t i, chan;
2336 
2337 	chan = ieee80211_chan2ieee(ic, c);
2338 	if (chan == 0 || chan == IEEE80211_CHAN_ANY)
2339 		return;
2340 
2341 	/* select the appropriate RF settings based on what EEPROM says */
2342 	rfprog = (sc->rfprog == 0) ? rt2661_rf5225_1 : rt2661_rf5225_2;
2343 
2344 	/* find the settings for this channel (we know it exists) */
2345 	i = 0;
2346 	while (rfprog[i].chan != chan)
2347 		i++;
2348 
2349 	power = sc->txpow[i];
2350 	if (power < 0) {
2351 		bbp94 += power;
2352 		power = 0;
2353 	} else if (power > 31) {
2354 		bbp94 += power - 31;
2355 		power = 31;
2356 	}
2357 
2358 	/*
2359 	 * If we are switching from the 2GHz band to the 5GHz band or
2360 	 * vice-versa, BBP registers need to be reprogrammed.
2361 	 */
2362 	if (ic->ic_flags != sc->sc_curchan->ich_flags) {
2363 		rt2661_select_band(sc, c);
2364 		rt2661_select_antenna(sc);
2365 	}
2366 	sc->sc_curchan = c;
2367 
2368 	rt2661_rf_write(sc, RT2661_RF1, rfprog[i].r1);
2369 	rt2661_rf_write(sc, RT2661_RF2, rfprog[i].r2);
2370 	rt2661_rf_write(sc, RT2661_RF3, rfprog[i].r3 | power << 7);
2371 	rt2661_rf_write(sc, RT2661_RF4, rfprog[i].r4 | sc->rffreq << 10);
2372 
2373 	DELAY(200);
2374 
2375 	rt2661_rf_write(sc, RT2661_RF1, rfprog[i].r1);
2376 	rt2661_rf_write(sc, RT2661_RF2, rfprog[i].r2);
2377 	rt2661_rf_write(sc, RT2661_RF3, rfprog[i].r3 | power << 7 | 1);
2378 	rt2661_rf_write(sc, RT2661_RF4, rfprog[i].r4 | sc->rffreq << 10);
2379 
2380 	DELAY(200);
2381 
2382 	rt2661_rf_write(sc, RT2661_RF1, rfprog[i].r1);
2383 	rt2661_rf_write(sc, RT2661_RF2, rfprog[i].r2);
2384 	rt2661_rf_write(sc, RT2661_RF3, rfprog[i].r3 | power << 7);
2385 	rt2661_rf_write(sc, RT2661_RF4, rfprog[i].r4 | sc->rffreq << 10);
2386 
2387 	/* enable smart mode for MIMO-capable RFs */
2388 	bbp3 = rt2661_bbp_read(sc, 3);
2389 
2390 	bbp3 &= ~RT2661_SMART_MODE;
2391 	if (sc->rf_rev == RT2661_RF_5325 || sc->rf_rev == RT2661_RF_2529)
2392 		bbp3 |= RT2661_SMART_MODE;
2393 
2394 	rt2661_bbp_write(sc, 3, bbp3);
2395 
2396 	if (bbp94 != RT2661_BBPR94_DEFAULT)
2397 		rt2661_bbp_write(sc, 94, bbp94);
2398 
2399 	/* 5GHz radio needs a 1ms delay here */
2400 	if (IEEE80211_IS_CHAN_5GHZ(c))
2401 		DELAY(1000);
2402 }
2403 
2404 static int
2405 rt2661_init(struct rt2661_softc *sc)
2406 {
2407 #define	N(a)	(sizeof (a) / sizeof ((a)[0]))
2408 
2409 	struct ieee80211com *ic = &sc->sc_ic;
2410 	uint32_t tmp, sta[3], *fptr;
2411 	int i, err, off, ntries;
2412 
2413 	RT2661_GLOCK(sc);
2414 
2415 	rt2661_stop_locked(sc);
2416 
2417 	if (!RT2661_IS_FWLOADED(sc)) {
2418 		err = rt2661_load_microcode(sc, ucode, usize);
2419 		if (err != RT2661_SUCCESS) {
2420 			RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
2421 			    "could not load 8051 microcode\n");
2422 			return (DDI_FAILURE);
2423 		}
2424 		sc->sc_flags |= RT2661_F_FWLOADED;
2425 	}
2426 
2427 	/* initialize Tx rings */
2428 	RT2661_WRITE(sc, RT2661_AC1_BASE_CSR, sc->txq[1].paddr);
2429 	RT2661_WRITE(sc, RT2661_AC0_BASE_CSR, sc->txq[0].paddr);
2430 	RT2661_WRITE(sc, RT2661_AC2_BASE_CSR, sc->txq[2].paddr);
2431 	RT2661_WRITE(sc, RT2661_AC3_BASE_CSR, sc->txq[3].paddr);
2432 
2433 	/* initialize Mgt ring */
2434 	RT2661_WRITE(sc, RT2661_MGT_BASE_CSR, sc->mgtq.paddr);
2435 
2436 	/* initialize Rx ring */
2437 	RT2661_WRITE(sc, RT2661_RX_BASE_CSR, sc->rxq.paddr);
2438 
2439 	/* initialize Tx rings sizes */
2440 	RT2661_WRITE(sc, RT2661_TX_RING_CSR0,
2441 	    RT2661_TX_RING_COUNT << 24 |
2442 	    RT2661_TX_RING_COUNT << 16 |
2443 	    RT2661_TX_RING_COUNT <<  8 |
2444 	    RT2661_TX_RING_COUNT);
2445 
2446 	RT2661_WRITE(sc, RT2661_TX_RING_CSR1,
2447 	    RT2661_TX_DESC_WSIZE << 16 |
2448 	    RT2661_TX_RING_COUNT <<  8 |
2449 	    RT2661_MGT_RING_COUNT);
2450 
2451 	/* initialize Rx rings */
2452 	RT2661_WRITE(sc, RT2661_RX_RING_CSR,
2453 	    RT2661_RX_DESC_BACK  << 16 |
2454 	    RT2661_RX_DESC_WSIZE <<  8 |
2455 	    RT2661_RX_RING_COUNT);
2456 
2457 	/* XXX: some magic here */
2458 	RT2661_WRITE(sc, RT2661_TX_DMA_DST_CSR, 0xaa);
2459 
2460 	/* load base addresses of all 5 Tx rings (4 data + 1 mgt) */
2461 	RT2661_WRITE(sc, RT2661_LOAD_TX_RING_CSR, 0x1f);
2462 
2463 	/* load base address of Rx ring */
2464 	RT2661_WRITE(sc, RT2661_RX_CNTL_CSR, 2);
2465 
2466 	/* initialize MAC registers to default values */
2467 	for (i = 0; i < N(rt2661_def_mac); i++)
2468 		RT2661_WRITE(sc, rt2661_def_mac[i].reg, rt2661_def_mac[i].val);
2469 
2470 	rt2661_set_macaddr(sc, ic->ic_macaddr);
2471 
2472 	/* set host ready */
2473 	RT2661_WRITE(sc, RT2661_MAC_CSR1, 3);
2474 	RT2661_WRITE(sc, RT2661_MAC_CSR1, 0);
2475 
2476 	/* wait for BBP/RF to wakeup */
2477 	for (ntries = 0; ntries < 1000; ntries++) {
2478 		if (RT2661_READ(sc, RT2661_MAC_CSR12) & 8)
2479 			break;
2480 		DELAY(1000);
2481 	}
2482 	if (ntries == 1000) {
2483 		RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
2484 		    "timeout waiting for BBP/RF to wakeup\n");
2485 		rt2661_stop_locked(sc);
2486 		RT2661_GUNLOCK(sc);
2487 		return (DDI_FAILURE);
2488 	}
2489 
2490 	if (rt2661_bbp_init(sc) != RT2661_SUCCESS) {
2491 		rt2661_stop_locked(sc);
2492 		RT2661_GUNLOCK(sc);
2493 		return (DDI_FAILURE);
2494 	}
2495 
2496 	/* select default channel */
2497 	sc->sc_curchan = ic->ic_bss->in_chan = ic->ic_curchan;
2498 	rt2661_select_band(sc, sc->sc_curchan);
2499 	rt2661_select_antenna(sc);
2500 	rt2661_set_chan(sc, sc->sc_curchan);
2501 
2502 	/* update Rx filter */
2503 	tmp = RT2661_READ(sc, RT2661_TXRX_CSR0) & 0xffff;
2504 
2505 	tmp |= RT2661_DROP_PHY_ERROR | RT2661_DROP_CRC_ERROR;
2506 	if (ic->ic_opmode != IEEE80211_M_MONITOR) {
2507 		tmp |= RT2661_DROP_CTL | RT2661_DROP_VER_ERROR |
2508 		    RT2661_DROP_ACKCTS;
2509 		if (ic->ic_opmode != IEEE80211_M_HOSTAP)
2510 			tmp |= RT2661_DROP_TODS;
2511 		if (!(sc->sc_rcr & RT2661_RCR_PROMISC))
2512 			tmp |= RT2661_DROP_NOT_TO_ME;
2513 	}
2514 
2515 	RT2661_WRITE(sc, RT2661_TXRX_CSR0, tmp);
2516 
2517 	/* clear STA registers */
2518 	off = RT2661_STA_CSR0;
2519 	fptr = sta;
2520 	for (i = 0; i < N(sta); i++) {
2521 		*fptr = RT2661_MEM_READ1(sc, off++);
2522 	}
2523 
2524 	/* initialize ASIC */
2525 	RT2661_WRITE(sc, RT2661_MAC_CSR1, 4);
2526 
2527 	/* clear any pending interrupt */
2528 	RT2661_WRITE(sc, RT2661_INT_SOURCE_CSR, 0xffffffff);
2529 
2530 	/* enable interrupts */
2531 	RT2661_WRITE(sc, RT2661_INT_MASK_CSR, 0x0000ff10);
2532 	RT2661_WRITE(sc, RT2661_MCU_INT_MASK_CSR, 0);
2533 
2534 	/* kick Rx */
2535 	RT2661_WRITE(sc, RT2661_RX_CNTL_CSR, 1);
2536 	RT2661_GUNLOCK(sc);
2537 
2538 #undef N
2539 	return (DDI_SUCCESS);
2540 }
2541 
2542 static void
2543 rt2661_stop(struct rt2661_softc *sc)
2544 {
2545 	if (!RT2661_IS_FASTREBOOT(sc))
2546 		RT2661_GLOCK(sc);
2547 	rt2661_stop_locked(sc);
2548 	if (!RT2661_IS_FASTREBOOT(sc))
2549 		RT2661_GUNLOCK(sc);
2550 }
2551 
2552 static int
2553 rt2661_m_start(void *arg)
2554 {
2555 	struct rt2661_softc *sc = (struct rt2661_softc *)arg;
2556 	struct ieee80211com *ic = &sc->sc_ic;
2557 	int err;
2558 
2559 	err = rt2661_init(sc);
2560 	if (err != DDI_SUCCESS) {
2561 		RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_m_start():"
2562 		    "Hardware initialization failed\n");
2563 		goto fail1;
2564 	}
2565 
2566 	ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
2567 
2568 	RT2661_GLOCK(sc);
2569 	sc->sc_flags |= RT2661_F_RUNNING;
2570 	RT2661_GUNLOCK(sc);
2571 
2572 	return (DDI_SUCCESS);
2573 fail1:
2574 	rt2661_stop(sc);
2575 	return (err);
2576 }
2577 
2578 static void
2579 rt2661_m_stop(void *arg)
2580 {
2581 	struct rt2661_softc *sc = (struct rt2661_softc *)arg;
2582 
2583 	(void) rt2661_stop(sc);
2584 
2585 	ieee80211_new_state(&sc->sc_ic, IEEE80211_S_INIT, -1);
2586 
2587 	RT2661_GLOCK(sc);
2588 	sc->sc_flags &= ~RT2661_F_RUNNING;
2589 	RT2661_GUNLOCK(sc);
2590 }
2591 
2592 static void
2593 rt2661_m_ioctl(void* arg, queue_t *wq, mblk_t *mp)
2594 {
2595 	struct rt2661_softc *sc = (struct rt2661_softc *)arg;
2596 	struct ieee80211com *ic = &sc->sc_ic;
2597 	int err;
2598 
2599 	err = ieee80211_ioctl(ic, wq, mp);
2600 	RT2661_GLOCK(sc);
2601 	if (err == ENETRESET) {
2602 		if (ic->ic_des_esslen) {
2603 			if (RT2661_IS_RUNNING(sc)) {
2604 				RT2661_GUNLOCK(sc);
2605 				(void) rt2661_init(sc);
2606 				(void) ieee80211_new_state(ic,
2607 				    IEEE80211_S_SCAN, -1);
2608 				RT2661_GLOCK(sc);
2609 			}
2610 		}
2611 	}
2612 	RT2661_GUNLOCK(sc);
2613 }
2614 
2615 /*
2616  * Call back function for get/set proporty
2617  */
2618 static int
2619 rt2661_m_getprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num,
2620     uint_t pr_flags, uint_t wldp_length, void *wldp_buf, uint_t *perm)
2621 {
2622 	struct rt2661_softc *sc = (struct rt2661_softc *)arg;
2623 	int err = 0;
2624 
2625 	err = ieee80211_getprop(&sc->sc_ic, pr_name, wldp_pr_num,
2626 	    pr_flags, wldp_length, wldp_buf, perm);
2627 
2628 	return (err);
2629 }
2630 
2631 static int
2632 rt2661_m_setprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num,
2633     uint_t wldp_length, const void *wldp_buf)
2634 {
2635 	struct rt2661_softc *sc = (struct rt2661_softc *)arg;
2636 	ieee80211com_t *ic = &sc->sc_ic;
2637 	int err;
2638 
2639 	err = ieee80211_setprop(ic, pr_name, wldp_pr_num, wldp_length,
2640 	    wldp_buf);
2641 	RT2661_GLOCK(sc);
2642 	if (err == ENETRESET) {
2643 		if (ic->ic_des_esslen) {
2644 			if (RT2661_IS_RUNNING(sc)) {
2645 				RT2661_GUNLOCK(sc);
2646 				(void) rt2661_init(sc);
2647 				(void) ieee80211_new_state(ic,
2648 				    IEEE80211_S_SCAN, -1);
2649 				RT2661_GLOCK(sc);
2650 			}
2651 		}
2652 		err = 0;
2653 	}
2654 	RT2661_GUNLOCK(sc);
2655 	return (err);
2656 }
2657 
2658 static mblk_t *
2659 rt2661_m_tx(void *arg, mblk_t *mp)
2660 {
2661 	struct rt2661_softc *sc = (struct rt2661_softc *)arg;
2662 	struct ieee80211com *ic = &sc->sc_ic;
2663 	mblk_t *next;
2664 
2665 	if (RT2661_IS_SUSPEND(sc)) {
2666 		freemsgchain(mp);
2667 		return (NULL);
2668 	}
2669 
2670 	/*
2671 	 * No data frames go out unless we're associated; this
2672 	 * should not happen as the 802.11 layer does not enable
2673 	 * the xmit queue until we enter the RUN state.
2674 	 */
2675 	if (ic->ic_state != IEEE80211_S_RUN) {
2676 		RWD_DEBUG(RT2661_DBG_TX, "rwd: rt2661_tx_data(): "
2677 		    "discard, state %u\n", ic->ic_state);
2678 		freemsgchain(mp);
2679 		return (NULL);
2680 	}
2681 
2682 	while (mp != NULL) {
2683 		next = mp->b_next;
2684 		mp->b_next = NULL;
2685 		if (rt2661_send(ic, mp) !=
2686 		    DDI_SUCCESS) {
2687 			mp->b_next = next;
2688 			break;
2689 		}
2690 		mp = next;
2691 	}
2692 	return (mp);
2693 }
2694 
2695 /*ARGSUSED*/
2696 static int
2697 rt2661_m_unicst(void *arg, const uint8_t *macaddr)
2698 {
2699 	return (ENOTSUP);
2700 }
2701 
2702 /*ARGSUSED*/
2703 static int
2704 rt2661_m_multicst(void *arg, boolean_t add, const uint8_t *mca)
2705 {
2706 	return (ENOTSUP);
2707 }
2708 
2709 /*ARGSUSED*/
2710 static int
2711 rt2661_m_promisc(void *arg, boolean_t on)
2712 {
2713 	struct rt2661_softc *sc = (struct rt2661_softc *)arg;
2714 
2715 	if (on) {
2716 		sc->sc_rcr |= RT2661_RCR_PROMISC;
2717 		sc->sc_rcr |= RT2661_RCR_MULTI;
2718 	} else {
2719 		sc->sc_rcr &= ~RT2661_RCR_PROMISC;
2720 		sc->sc_rcr &= ~RT2661_RCR_MULTI;
2721 	}
2722 
2723 	rt2661_update_promisc(sc);
2724 	return (0);
2725 }
2726 
2727 static int
2728 rt2661_m_stat(void *arg, uint_t stat, uint64_t *val)
2729 {
2730 	struct rt2661_softc *sc  = (struct rt2661_softc *)arg;
2731 	struct ieee80211com *ic = &sc->sc_ic;
2732 	struct ieee80211_node *ni = ic->ic_bss;
2733 	struct ieee80211_rateset *rs = &ni->in_rates;
2734 
2735 	RT2661_GLOCK(sc);
2736 	switch (stat) {
2737 	case MAC_STAT_IFSPEED:
2738 		*val = ((ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) ?
2739 		    (rs->ir_rates[ni->in_txrate] & IEEE80211_RATE_VAL)
2740 		    : ic->ic_fixed_rate) / 2 * 1000000;
2741 		break;
2742 	case MAC_STAT_NOXMTBUF:
2743 		*val = sc->sc_tx_nobuf;
2744 		break;
2745 	case MAC_STAT_NORCVBUF:
2746 		*val = sc->sc_rx_nobuf;
2747 		break;
2748 	case MAC_STAT_IERRORS:
2749 		*val = sc->sc_rx_err;
2750 		break;
2751 	case MAC_STAT_RBYTES:
2752 		*val = ic->ic_stats.is_rx_bytes;
2753 		break;
2754 	case MAC_STAT_IPACKETS:
2755 		*val = ic->ic_stats.is_rx_frags;
2756 		break;
2757 	case MAC_STAT_OBYTES:
2758 		*val = ic->ic_stats.is_tx_bytes;
2759 		break;
2760 	case MAC_STAT_OPACKETS:
2761 		*val = ic->ic_stats.is_tx_frags;
2762 		break;
2763 	case MAC_STAT_OERRORS:
2764 	case WIFI_STAT_TX_FAILED:
2765 		*val = sc->sc_tx_err;
2766 		break;
2767 	case WIFI_STAT_TX_RETRANS:
2768 		*val = sc->sc_tx_retries;
2769 		break;
2770 	case WIFI_STAT_FCS_ERRORS:
2771 	case WIFI_STAT_WEP_ERRORS:
2772 	case WIFI_STAT_TX_FRAGS:
2773 	case WIFI_STAT_MCAST_TX:
2774 	case WIFI_STAT_RTS_SUCCESS:
2775 	case WIFI_STAT_RTS_FAILURE:
2776 	case WIFI_STAT_ACK_FAILURE:
2777 	case WIFI_STAT_RX_FRAGS:
2778 	case WIFI_STAT_MCAST_RX:
2779 	case WIFI_STAT_RX_DUPS:
2780 		RT2661_GUNLOCK(sc);
2781 		return (ieee80211_stat(ic, stat, val));
2782 	default:
2783 		RT2661_GUNLOCK(sc);
2784 		return (ENOTSUP);
2785 	}
2786 	RT2661_GUNLOCK(sc);
2787 
2788 	return (0);
2789 }
2790 
2791 static int
2792 rt2661_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd)
2793 {
2794 	struct rt2661_softc *sc;
2795 	struct ieee80211com *ic;
2796 
2797 	int i, ac, err, ntries, instance;
2798 	int intr_type, intr_count, intr_actual;
2799 	char strbuf[32];
2800 	uint8_t cachelsz;
2801 	uint16_t command, vendor_id, device_id;
2802 	uint32_t val;
2803 
2804 	wifi_data_t wd = { 0 };
2805 	mac_register_t *macp;
2806 
2807 	switch (cmd) {
2808 	case DDI_ATTACH:
2809 		break;
2810 	case DDI_RESUME:
2811 		sc = ddi_get_soft_state(rt2661_soft_state_p,
2812 		    ddi_get_instance(devinfo));
2813 		ASSERT(sc != NULL);
2814 		RT2661_GLOCK(sc);
2815 		sc->sc_flags &= ~RT2661_F_SUSPEND;
2816 		RT2661_GUNLOCK(sc);
2817 		if (RT2661_IS_RUNNING(sc))
2818 			(void) rt2661_init(sc);
2819 		RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
2820 		    "resume now\n");
2821 		return (DDI_SUCCESS);
2822 	default:
2823 		return (DDI_FAILURE);
2824 	}
2825 
2826 	instance = ddi_get_instance(devinfo);
2827 
2828 	err = ddi_soft_state_zalloc(rt2661_soft_state_p, instance);
2829 	if (err != DDI_SUCCESS) {
2830 		RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
2831 		    "unable to alloc soft_state_p\n");
2832 		return (err);
2833 	}
2834 
2835 	sc = ddi_get_soft_state(rt2661_soft_state_p, instance);
2836 	ic = (struct ieee80211com *)&sc->sc_ic;
2837 	sc->sc_dev = devinfo;
2838 
2839 	/* PCI configuration */
2840 	err = ddi_regs_map_setup(devinfo, 0, &sc->sc_cfg_base, 0, 0,
2841 	    &rt2661_csr_accattr, &sc->sc_cfg_handle);
2842 	if (err != DDI_SUCCESS) {
2843 		RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
2844 		    "ddi_regs_map_setup() failed");
2845 		goto fail1;
2846 	}
2847 
2848 	cachelsz = ddi_get8(sc->sc_cfg_handle,
2849 	    (uint8_t *)(sc->sc_cfg_base + PCI_CONF_CACHE_LINESZ));
2850 	if (cachelsz == 0)
2851 		cachelsz = 0x10;
2852 	sc->sc_cachelsz = cachelsz << 2;
2853 	sc->sc_dmabuf_size = roundup(IEEE80211_MAX_LEN, sc->sc_cachelsz);
2854 
2855 	vendor_id = ddi_get16(sc->sc_cfg_handle,
2856 	    (uint16_t *)((uintptr_t)(sc->sc_cfg_base) + PCI_CONF_VENID));
2857 	device_id = ddi_get16(sc->sc_cfg_handle,
2858 	    (uint16_t *)((uintptr_t)(sc->sc_cfg_base) + PCI_CONF_DEVID));
2859 	RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
2860 	    "vendor 0x%x, device id 0x%x, cache size %d\n",
2861 	    vendor_id, device_id, cachelsz);
2862 
2863 	/*
2864 	 * Enable response to memory space accesses,
2865 	 * and enabe bus master.
2866 	 */
2867 	command = PCI_COMM_MAE | PCI_COMM_ME;
2868 	ddi_put16(sc->sc_cfg_handle,
2869 	    (uint16_t *)((uintptr_t)(sc->sc_cfg_base) + PCI_CONF_COMM),
2870 	    command);
2871 	ddi_put8(sc->sc_cfg_handle,
2872 	    (uint8_t *)(sc->sc_cfg_base + PCI_CONF_LATENCY_TIMER), 0xa8);
2873 	ddi_put8(sc->sc_cfg_handle,
2874 	    (uint8_t *)(sc->sc_cfg_base + PCI_CONF_ILINE), 0x10);
2875 
2876 	/* pci i/o space */
2877 	err = ddi_regs_map_setup(devinfo, 1,
2878 	    &sc->sc_io_base, 0, 0, &rt2661_csr_accattr, &sc->sc_io_handle);
2879 	if (err != DDI_SUCCESS) {
2880 		RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
2881 		    "ddi_regs_map_setup() failed");
2882 		goto fail2;
2883 	}
2884 	RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
2885 	    "PCI configuration is done successfully\n");
2886 
2887 	err = ddi_intr_get_supported_types(devinfo, &intr_type);
2888 	if ((err != DDI_SUCCESS) || (!(intr_type & DDI_INTR_TYPE_FIXED))) {
2889 		RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
2890 		    "fixed type interrupt is not supported\n");
2891 		goto fail3;
2892 	}
2893 
2894 	err = ddi_intr_get_nintrs(devinfo, DDI_INTR_TYPE_FIXED, &intr_count);
2895 	if ((err != DDI_SUCCESS) || (intr_count != 1)) {
2896 		RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
2897 		    "no fixed interrupts\n");
2898 		goto fail3;
2899 	}
2900 
2901 	sc->sc_intr_htable = kmem_zalloc(sizeof (ddi_intr_handle_t), KM_SLEEP);
2902 
2903 	err = ddi_intr_alloc(devinfo, sc->sc_intr_htable,
2904 	    DDI_INTR_TYPE_FIXED, 0, intr_count, &intr_actual, 0);
2905 	if ((err != DDI_SUCCESS) || (intr_actual != 1)) {
2906 		RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
2907 		    "ddi_intr_alloc() failed 0x%x\n", err);
2908 		goto faili4;
2909 	}
2910 
2911 	err = ddi_intr_get_pri(sc->sc_intr_htable[0], &sc->sc_intr_pri);
2912 	if (err != DDI_SUCCESS) {
2913 		RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
2914 		    "ddi_intr_get_pri() failed 0x%x\n", err);
2915 		goto faili5;
2916 	}
2917 
2918 	sc->amrr.amrr_min_success_threshold =  1;
2919 	sc->amrr.amrr_max_success_threshold = 15;
2920 
2921 	/* wait for NIC to initialize */
2922 	for (ntries = 0; ntries < 1000; ntries++) {
2923 		if ((val = RT2661_READ(sc, RT2661_MAC_CSR0)) != 0)
2924 			break;
2925 		DELAY(1000);
2926 	}
2927 	if (ntries == 1000) {
2928 		RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
2929 		    "timeout waiting for NIC to initialize\n");
2930 		goto faili5;
2931 	}
2932 
2933 	/* retrieve RF rev. no and various other things from EEPROM */
2934 	rt2661_read_eeprom(sc);
2935 
2936 	RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
2937 	    "MAC/BBP RT%X, RF %s\n"
2938 	    "MAC address is: %x:%x:%x:%x:%x:%x\n", val,
2939 	    rt2661_get_rf(sc->rf_rev),
2940 	    ic->ic_macaddr[0], ic->ic_macaddr[1], ic->ic_macaddr[2],
2941 	    ic->ic_macaddr[3], ic->ic_macaddr[4], ic->ic_macaddr[5]);
2942 
2943 	/*
2944 	 * Load 8051 microcode into NIC.
2945 	 */
2946 	switch (device_id) {
2947 	case 0x0301:
2948 		ucode = rt2561s_ucode;
2949 		usize = sizeof (rt2561s_ucode);
2950 		break;
2951 	case 0x0302:
2952 		ucode = rt2561_ucode;
2953 		usize = sizeof (rt2561_ucode);
2954 		break;
2955 	case 0x0401:
2956 		ucode = rt2661_ucode;
2957 		usize = sizeof (rt2661_ucode);
2958 		break;
2959 	}
2960 
2961 	err = rt2661_load_microcode(sc, ucode, usize);
2962 	if (err != RT2661_SUCCESS) {
2963 		RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
2964 		    "could not load 8051 microcode\n");
2965 		goto faili5;
2966 	}
2967 
2968 	sc->sc_flags = 0;
2969 	sc->sc_flags |= RT2661_F_FWLOADED;
2970 
2971 	/*
2972 	 * Allocate Tx and Rx rings.
2973 	 */
2974 	for (ac = 0; ac < 4; ac++) {
2975 		err = rt2661_alloc_tx_ring(sc, &sc->txq[ac],
2976 		    RT2661_TX_RING_COUNT);
2977 		if (err != RT2661_SUCCESS) {
2978 			RWD_DEBUG(RT2661_DBG_DMA, "rwd: rt2661_attach(): "
2979 			    "could not allocate Tx ring %d\n", ac);
2980 			goto fail4;
2981 		}
2982 	}
2983 
2984 	err = rt2661_alloc_tx_ring(sc, &sc->mgtq, RT2661_MGT_RING_COUNT);
2985 	if (err != RT2661_SUCCESS) {
2986 		RWD_DEBUG(RT2661_DBG_DMA, "rwd: rt2661_attach(): "
2987 		    "could not allocate Mgt ring\n");
2988 		goto fail5;
2989 	}
2990 
2991 	err = rt2661_alloc_rx_ring(sc, &sc->rxq, RT2661_RX_RING_COUNT);
2992 	if (err != RT2661_SUCCESS) {
2993 		RWD_DEBUG(RT2661_DBG_DMA, "rwd: rt2661_attach(): "
2994 		    "could not allocate Rx ring\n");
2995 		goto fail6;
2996 	}
2997 
2998 	mutex_init(&sc->sc_genlock, NULL, MUTEX_DRIVER, NULL);
2999 	mutex_init(&sc->sc_txlock, NULL, MUTEX_DRIVER, NULL);
3000 	mutex_init(&sc->sc_rxlock, NULL, MUTEX_DRIVER, NULL);
3001 
3002 	ic->ic_phytype = IEEE80211_T_OFDM;
3003 	ic->ic_opmode = IEEE80211_M_STA;
3004 	ic->ic_state = IEEE80211_S_INIT;
3005 
3006 	/* set device capabilities */
3007 	ic->ic_caps =
3008 	    IEEE80211_C_TXPMGT |
3009 	    IEEE80211_C_SHPREAMBLE |
3010 	    IEEE80211_C_SHSLOT;
3011 
3012 	/* WPA/WPA2 support */
3013 	ic->ic_caps |= IEEE80211_C_WPA;
3014 
3015 	/* set supported .11b and .11g rates */
3016 	ic->ic_sup_rates[IEEE80211_MODE_11B] = rt2661_rateset_11b;
3017 	ic->ic_sup_rates[IEEE80211_MODE_11G] = rt2661_rateset_11g;
3018 
3019 	/* set supported .11b and .11g channels (1 through 14) */
3020 	for (i = 1; i <= 14; i++) {
3021 		ic->ic_sup_channels[i].ich_freq =
3022 		    ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
3023 		ic->ic_sup_channels[i].ich_flags =
3024 		    IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM |
3025 		    IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ;
3026 	}
3027 
3028 	ic->ic_maxrssi = 63;
3029 	ic->ic_xmit = rt2661_mgmt_send;
3030 
3031 	ieee80211_attach(ic);
3032 
3033 	/* register WPA door */
3034 	ieee80211_register_door(ic, ddi_driver_name(devinfo),
3035 	    ddi_get_instance(devinfo));
3036 
3037 	ic->ic_node_alloc = rt2661_node_alloc;
3038 	ic->ic_node_free = rt2661_node_free;
3039 	ic->ic_set_shortslot = rt2661_updateslot;
3040 
3041 	/* override state transition machine */
3042 	sc->sc_newstate = ic->ic_newstate;
3043 	ic->ic_newstate = rt2661_newstate;
3044 	ieee80211_media_init(ic);
3045 	ic->ic_def_txkey = 0;
3046 
3047 	err = ddi_intr_add_softint(devinfo, &sc->sc_softintr_hdl,
3048 	    DDI_INTR_SOFTPRI_MAX, rt2661_softintr, (caddr_t)sc);
3049 	if (err != DDI_SUCCESS) {
3050 		RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
3051 		    "ddi_add_softintr() failed");
3052 		goto fail7;
3053 	}
3054 
3055 	err = ddi_intr_add_handler(sc->sc_intr_htable[0], rt2661_intr,
3056 	    (caddr_t)sc, NULL);
3057 	if (err != DDI_SUCCESS) {
3058 		RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
3059 		    "ddi_intr_addr_handle() failed\n");
3060 		goto fail8;
3061 	}
3062 
3063 	err = ddi_intr_enable(sc->sc_intr_htable[0]);
3064 	if (err != DDI_SUCCESS) {
3065 		RWD_DEBUG(RT2661_DBG_MSG, "rwd; rt2661_attach(): "
3066 		    "ddi_intr_enable() failed\n");
3067 		goto fail9;
3068 	}
3069 
3070 	/*
3071 	 * Provide initial settings for the WiFi plugin; whenever this
3072 	 * information changes, we need to call mac_plugindata_update()
3073 	 */
3074 	wd.wd_opmode = ic->ic_opmode;
3075 	wd.wd_secalloc = WIFI_SEC_NONE;
3076 	IEEE80211_ADDR_COPY(wd.wd_bssid, ic->ic_bss->in_bssid);
3077 
3078 	if ((macp = mac_alloc(MAC_VERSION)) == NULL) {
3079 		RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
3080 		    "MAC version mismatch\n");
3081 		goto fail10;
3082 	}
3083 
3084 	macp->m_type_ident	= MAC_PLUGIN_IDENT_WIFI;
3085 	macp->m_driver		= sc;
3086 	macp->m_dip		= devinfo;
3087 	macp->m_src_addr	= ic->ic_macaddr;
3088 	macp->m_callbacks	= &rt2661_m_callbacks;
3089 	macp->m_min_sdu		= 0;
3090 	macp->m_max_sdu		= IEEE80211_MTU;
3091 	macp->m_pdata		= &wd;
3092 	macp->m_pdata_size	= sizeof (wd);
3093 
3094 	err = mac_register(macp, &ic->ic_mach);
3095 	mac_free(macp);
3096 	if (err != 0) {
3097 		RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
3098 		    "mac_register err %x\n", err);
3099 		goto fail10;
3100 	}
3101 
3102 	/*
3103 	 * Create minor node of type DDI_NT_NET_WIFI
3104 	 */
3105 	(void) snprintf(strbuf, sizeof (strbuf), "%s%d",
3106 	    "rwd", instance);
3107 	err = ddi_create_minor_node(devinfo, strbuf, S_IFCHR,
3108 	    instance + 1, DDI_NT_NET_WIFI, 0);
3109 
3110 	/*
3111 	 * Notify link is down now
3112 	 */
3113 	mac_link_update(ic->ic_mach, LINK_STATE_DOWN);
3114 
3115 	RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_attach(): "
3116 	    "attach successfully\n");
3117 	return (DDI_SUCCESS);
3118 
3119 fail10:
3120 	(void) ddi_intr_disable(sc->sc_intr_htable[0]);
3121 fail9:
3122 	(void) ddi_intr_remove_handler(sc->sc_intr_htable[0]);
3123 fail8:
3124 	(void) ddi_intr_remove_softint(sc->sc_softintr_hdl);
3125 	sc->sc_softintr_hdl = NULL;
3126 fail7:
3127 	mutex_destroy(&sc->sc_genlock);
3128 	mutex_destroy(&sc->sc_txlock);
3129 	mutex_destroy(&sc->sc_rxlock);
3130 fail6:
3131 	rt2661_free_rx_ring(sc, &sc->rxq);
3132 fail5:
3133 	rt2661_free_tx_ring(sc, &sc->mgtq);
3134 fail4:
3135 	while (--ac >= 0)
3136 		rt2661_free_tx_ring(sc, &sc->txq[ac]);
3137 faili5:
3138 	(void) ddi_intr_free(sc->sc_intr_htable[0]);
3139 faili4:
3140 	kmem_free(sc->sc_intr_htable, sizeof (ddi_intr_handle_t));
3141 fail3:
3142 	ddi_regs_map_free(&sc->sc_io_handle);
3143 fail2:
3144 	ddi_regs_map_free(&sc->sc_cfg_handle);
3145 fail1:
3146 	return (DDI_FAILURE);
3147 }
3148 
3149 static int
3150 rt2661_detach(dev_info_t *devinfo, ddi_detach_cmd_t cmd)
3151 {
3152 
3153 	struct rt2661_softc *sc;
3154 
3155 	sc = ddi_get_soft_state(rt2661_soft_state_p, ddi_get_instance(devinfo));
3156 
3157 	switch (cmd) {
3158 	case DDI_DETACH:
3159 		break;
3160 	case DDI_SUSPEND:
3161 		if (RT2661_IS_RUNNING(sc))
3162 			rt2661_stop(sc);
3163 		RT2661_GLOCK(sc);
3164 		sc->sc_flags |= RT2661_F_SUSPEND;
3165 		sc->sc_flags &= ~RT2661_F_FWLOADED;
3166 		RT2661_GUNLOCK(sc);
3167 		RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_detach(): "
3168 		    "suspend now\n");
3169 		return (DDI_SUCCESS);
3170 	default:
3171 		return (DDI_FAILURE);
3172 	}
3173 
3174 	if (mac_disable(sc->sc_ic.ic_mach) != 0)
3175 		return (DDI_FAILURE);
3176 
3177 	/*
3178 	 * Unregister from the MAC layer subsystem
3179 	 */
3180 	(void) mac_unregister(sc->sc_ic.ic_mach);
3181 
3182 	(void) ddi_intr_remove_softint(sc->sc_softintr_hdl);
3183 	sc->sc_softintr_hdl = NULL;
3184 	(void) ddi_intr_disable(sc->sc_intr_htable[0]);
3185 	(void) ddi_intr_remove_handler(sc->sc_intr_htable[0]);
3186 	(void) ddi_intr_free(sc->sc_intr_htable[0]);
3187 	kmem_free(sc->sc_intr_htable, sizeof (ddi_intr_handle_t));
3188 
3189 	/*
3190 	 * detach ieee80211 layer
3191 	 */
3192 	ieee80211_detach(&sc->sc_ic);
3193 
3194 	mutex_destroy(&sc->sc_genlock);
3195 	mutex_destroy(&sc->sc_txlock);
3196 	mutex_destroy(&sc->sc_rxlock);
3197 
3198 	rt2661_free_tx_ring(sc, &sc->txq[0]);
3199 	rt2661_free_tx_ring(sc, &sc->txq[1]);
3200 	rt2661_free_tx_ring(sc, &sc->txq[2]);
3201 	rt2661_free_tx_ring(sc, &sc->txq[3]);
3202 	rt2661_free_tx_ring(sc, &sc->mgtq);
3203 	rt2661_free_rx_ring(sc, &sc->rxq);
3204 
3205 	ddi_regs_map_free(&sc->sc_io_handle);
3206 	ddi_regs_map_free(&sc->sc_cfg_handle);
3207 
3208 	ddi_remove_minor_node(devinfo, NULL);
3209 	ddi_soft_state_free(rt2661_soft_state_p, ddi_get_instance(devinfo));
3210 
3211 	RWD_DEBUG(RT2661_DBG_MSG, "rwd: rt2661_detach(): "
3212 	    "detach successfully\n");
3213 	return (DDI_SUCCESS);
3214 }
3215 
3216 static int
3217 rt2661_quiesce(dev_info_t *dip)
3218 {
3219 	struct rt2661_softc *sc;
3220 
3221 	sc = ddi_get_soft_state(rt2661_soft_state_p, ddi_get_instance(dip));
3222 	if (sc == NULL)
3223 		return (DDI_FAILURE);
3224 
3225 #ifdef DEBUG
3226 	rt2661_dbg_flags = 0;
3227 #endif
3228 
3229 	/*
3230 	 * No more blocking is allowed while we are in quiesce(9E) entry point
3231 	 */
3232 	sc->sc_flags |= RT2661_F_QUIESCE;
3233 
3234 	/*
3235 	 * Disable all interrupts
3236 	 */
3237 	rt2661_stop(sc);
3238 	return (DDI_SUCCESS);
3239 }
3240 
3241 int
3242 _info(struct modinfo *modinfop)
3243 {
3244 	return (mod_info(&modlinkage, modinfop));
3245 }
3246 
3247 int
3248 _init(void)
3249 {
3250 	int status;
3251 
3252 	status = ddi_soft_state_init(&rt2661_soft_state_p,
3253 	    sizeof (struct rt2661_softc), 1);
3254 	if (status != 0)
3255 		return (status);
3256 
3257 	mac_init_ops(&rwd_dev_ops, "rwd");
3258 	status = mod_install(&modlinkage);
3259 	if (status != 0) {
3260 		mac_fini_ops(&rwd_dev_ops);
3261 		ddi_soft_state_fini(&rt2661_soft_state_p);
3262 	}
3263 	return (status);
3264 }
3265 
3266 int
3267 _fini(void)
3268 {
3269 	int status;
3270 
3271 	status = mod_remove(&modlinkage);
3272 	if (status == 0) {
3273 		mac_fini_ops(&rwd_dev_ops);
3274 		ddi_soft_state_fini(&rt2661_soft_state_p);
3275 	}
3276 	return (status);
3277 }
3278