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