1/*
2 * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
3 * Use is subject to license terms.
4 */
5
6/*
7 * Copyright (c) 2005-2007 Damien Bergamini <damien.bergamini@free.fr>
8 * Copyright (c) 2006 Niall O'Higgins <niallo@openbsd.org>
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 RT2501USB/RT2601USB chipset driver
25 * http://www.ralinktech.com.tw/
26 */
27#include <sys/types.h>
28#include <sys/cmn_err.h>
29#include <sys/strsubr.h>
30#include <sys/modctl.h>
31#include <sys/devops.h>
32#include <sys/mac_provider.h>
33#include <sys/mac_wifi.h>
34#include <sys/net80211.h>
35#include <sys/byteorder.h>
36
37#define	USBDRV_MAJOR_VER	2
38#define	USBDRV_MINOR_VER	0
39#include <sys/usb/usba.h>
40#include <sys/usb/usba/usba_types.h>
41
42#include "rum_reg.h"
43#include "rum_var.h"
44#include "rt2573_ucode.h"
45
46static void *rum_soft_state_p = NULL;
47
48#define	RAL_TXBUF_SIZE  	(IEEE80211_MAX_LEN)
49#define	RAL_RXBUF_SIZE  	(IEEE80211_MAX_LEN)
50
51/* quickly determine if a given rate is CCK or OFDM */
52#define	RUM_RATE_IS_OFDM(rate)	((rate) >= 12 && (rate) != 22)
53#define	RUM_ACK_SIZE	14	/* 10 + 4(FCS) */
54#define	RUM_CTS_SIZE	14	/* 10 + 4(FCS) */
55
56#define	RUM_N(a)		(sizeof (a) / sizeof ((a)[0]))
57
58/*
59 * Supported rates for 802.11a/b/g modes (in 500Kbps unit).
60 */
61static const struct ieee80211_rateset rum_rateset_11a =
62	{ 8, { 12, 18, 24, 36, 48, 72, 96, 108 } };
63
64static const struct ieee80211_rateset rum_rateset_11b =
65	{ 4, { 2, 4, 11, 22 } };
66
67static const struct ieee80211_rateset rum_rateset_11g =
68	{ 12, { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 } };
69
70static const struct {
71	uint32_t	reg;
72	uint32_t	val;
73} rum_def_mac[] = {
74	{ RT2573_TXRX_CSR0,  0x025fb032 },
75	{ RT2573_TXRX_CSR1,  0x9eaa9eaf },
76	{ RT2573_TXRX_CSR2,  0x8a8b8c8d },
77	{ RT2573_TXRX_CSR3,  0x00858687 },
78	{ RT2573_TXRX_CSR7,  0x2e31353b },
79	{ RT2573_TXRX_CSR8,  0x2a2a2a2c },
80	{ RT2573_TXRX_CSR15, 0x0000000f },
81	{ RT2573_MAC_CSR6,   0x00000fff },
82	{ RT2573_MAC_CSR8,   0x016c030a },
83	{ RT2573_MAC_CSR10,  0x00000718 },
84	{ RT2573_MAC_CSR12,  0x00000004 },
85	{ RT2573_MAC_CSR13,  0x00007f00 },
86	{ RT2573_SEC_CSR0,   0x00000000 },
87	{ RT2573_SEC_CSR1,   0x00000000 },
88	{ RT2573_SEC_CSR5,   0x00000000 },
89	{ RT2573_PHY_CSR1,   0x000023b0 },
90	{ RT2573_PHY_CSR5,   0x00040a06 },
91	{ RT2573_PHY_CSR6,   0x00080606 },
92	{ RT2573_PHY_CSR7,   0x00000408 },
93	{ RT2573_AIFSN_CSR,  0x00002273 },
94	{ RT2573_CWMIN_CSR,  0x00002344 },
95	{ RT2573_CWMAX_CSR,  0x000034aa }
96};
97
98static const struct {
99	uint8_t	reg;
100	uint8_t	val;
101} rum_def_bbp[] = {
102	{   3, 0x80 },
103	{  15, 0x30 },
104	{  17, 0x20 },
105	{  21, 0xc8 },
106	{  22, 0x38 },
107	{  23, 0x06 },
108	{  24, 0xfe },
109	{  25, 0x0a },
110	{  26, 0x0d },
111	{  32, 0x0b },
112	{  34, 0x12 },
113	{  37, 0x07 },
114	{  39, 0xf8 },
115	{  41, 0x60 },
116	{  53, 0x10 },
117	{  54, 0x18 },
118	{  60, 0x10 },
119	{  61, 0x04 },
120	{  62, 0x04 },
121	{  75, 0xfe },
122	{  86, 0xfe },
123	{  88, 0xfe },
124	{  90, 0x0f },
125	{  99, 0x00 },
126	{ 102, 0x16 },
127	{ 107, 0x04 }
128};
129
130static const struct rfprog {
131	uint8_t		chan;
132	uint32_t	r1, r2, r3, r4;
133}  rum_rf5226[] = {
134	{   1, 0x00b03, 0x001e1, 0x1a014, 0x30282 },
135	{   2, 0x00b03, 0x001e1, 0x1a014, 0x30287 },
136	{   3, 0x00b03, 0x001e2, 0x1a014, 0x30282 },
137	{   4, 0x00b03, 0x001e2, 0x1a014, 0x30287 },
138	{   5, 0x00b03, 0x001e3, 0x1a014, 0x30282 },
139	{   6, 0x00b03, 0x001e3, 0x1a014, 0x30287 },
140	{   7, 0x00b03, 0x001e4, 0x1a014, 0x30282 },
141	{   8, 0x00b03, 0x001e4, 0x1a014, 0x30287 },
142	{   9, 0x00b03, 0x001e5, 0x1a014, 0x30282 },
143	{  10, 0x00b03, 0x001e5, 0x1a014, 0x30287 },
144	{  11, 0x00b03, 0x001e6, 0x1a014, 0x30282 },
145	{  12, 0x00b03, 0x001e6, 0x1a014, 0x30287 },
146	{  13, 0x00b03, 0x001e7, 0x1a014, 0x30282 },
147	{  14, 0x00b03, 0x001e8, 0x1a014, 0x30284 },
148
149	{  34, 0x00b03, 0x20266, 0x36014, 0x30282 },
150	{  38, 0x00b03, 0x20267, 0x36014, 0x30284 },
151	{  42, 0x00b03, 0x20268, 0x36014, 0x30286 },
152	{  46, 0x00b03, 0x20269, 0x36014, 0x30288 },
153
154	{  36, 0x00b03, 0x00266, 0x26014, 0x30288 },
155	{  40, 0x00b03, 0x00268, 0x26014, 0x30280 },
156	{  44, 0x00b03, 0x00269, 0x26014, 0x30282 },
157	{  48, 0x00b03, 0x0026a, 0x26014, 0x30284 },
158	{  52, 0x00b03, 0x0026b, 0x26014, 0x30286 },
159	{  56, 0x00b03, 0x0026c, 0x26014, 0x30288 },
160	{  60, 0x00b03, 0x0026e, 0x26014, 0x30280 },
161	{  64, 0x00b03, 0x0026f, 0x26014, 0x30282 },
162
163	{ 100, 0x00b03, 0x0028a, 0x2e014, 0x30280 },
164	{ 104, 0x00b03, 0x0028b, 0x2e014, 0x30282 },
165	{ 108, 0x00b03, 0x0028c, 0x2e014, 0x30284 },
166	{ 112, 0x00b03, 0x0028d, 0x2e014, 0x30286 },
167	{ 116, 0x00b03, 0x0028e, 0x2e014, 0x30288 },
168	{ 120, 0x00b03, 0x002a0, 0x2e014, 0x30280 },
169	{ 124, 0x00b03, 0x002a1, 0x2e014, 0x30282 },
170	{ 128, 0x00b03, 0x002a2, 0x2e014, 0x30284 },
171	{ 132, 0x00b03, 0x002a3, 0x2e014, 0x30286 },
172	{ 136, 0x00b03, 0x002a4, 0x2e014, 0x30288 },
173	{ 140, 0x00b03, 0x002a6, 0x2e014, 0x30280 },
174
175	{ 149, 0x00b03, 0x002a8, 0x2e014, 0x30287 },
176	{ 153, 0x00b03, 0x002a9, 0x2e014, 0x30289 },
177	{ 157, 0x00b03, 0x002ab, 0x2e014, 0x30281 },
178	{ 161, 0x00b03, 0x002ac, 0x2e014, 0x30283 },
179	{ 165, 0x00b03, 0x002ad, 0x2e014, 0x30285 }
180}, rum_rf5225[] = {
181	{   1, 0x00b33, 0x011e1, 0x1a014, 0x30282 },
182	{   2, 0x00b33, 0x011e1, 0x1a014, 0x30287 },
183	{   3, 0x00b33, 0x011e2, 0x1a014, 0x30282 },
184	{   4, 0x00b33, 0x011e2, 0x1a014, 0x30287 },
185	{   5, 0x00b33, 0x011e3, 0x1a014, 0x30282 },
186	{   6, 0x00b33, 0x011e3, 0x1a014, 0x30287 },
187	{   7, 0x00b33, 0x011e4, 0x1a014, 0x30282 },
188	{   8, 0x00b33, 0x011e4, 0x1a014, 0x30287 },
189	{   9, 0x00b33, 0x011e5, 0x1a014, 0x30282 },
190	{  10, 0x00b33, 0x011e5, 0x1a014, 0x30287 },
191	{  11, 0x00b33, 0x011e6, 0x1a014, 0x30282 },
192	{  12, 0x00b33, 0x011e6, 0x1a014, 0x30287 },
193	{  13, 0x00b33, 0x011e7, 0x1a014, 0x30282 },
194	{  14, 0x00b33, 0x011e8, 0x1a014, 0x30284 },
195
196	{  34, 0x00b33, 0x01266, 0x26014, 0x30282 },
197	{  38, 0x00b33, 0x01267, 0x26014, 0x30284 },
198	{  42, 0x00b33, 0x01268, 0x26014, 0x30286 },
199	{  46, 0x00b33, 0x01269, 0x26014, 0x30288 },
200
201	{  36, 0x00b33, 0x01266, 0x26014, 0x30288 },
202	{  40, 0x00b33, 0x01268, 0x26014, 0x30280 },
203	{  44, 0x00b33, 0x01269, 0x26014, 0x30282 },
204	{  48, 0x00b33, 0x0126a, 0x26014, 0x30284 },
205	{  52, 0x00b33, 0x0126b, 0x26014, 0x30286 },
206	{  56, 0x00b33, 0x0126c, 0x26014, 0x30288 },
207	{  60, 0x00b33, 0x0126e, 0x26014, 0x30280 },
208	{  64, 0x00b33, 0x0126f, 0x26014, 0x30282 },
209
210	{ 100, 0x00b33, 0x0128a, 0x2e014, 0x30280 },
211	{ 104, 0x00b33, 0x0128b, 0x2e014, 0x30282 },
212	{ 108, 0x00b33, 0x0128c, 0x2e014, 0x30284 },
213	{ 112, 0x00b33, 0x0128d, 0x2e014, 0x30286 },
214	{ 116, 0x00b33, 0x0128e, 0x2e014, 0x30288 },
215	{ 120, 0x00b33, 0x012a0, 0x2e014, 0x30280 },
216	{ 124, 0x00b33, 0x012a1, 0x2e014, 0x30282 },
217	{ 128, 0x00b33, 0x012a2, 0x2e014, 0x30284 },
218	{ 132, 0x00b33, 0x012a3, 0x2e014, 0x30286 },
219	{ 136, 0x00b33, 0x012a4, 0x2e014, 0x30288 },
220	{ 140, 0x00b33, 0x012a6, 0x2e014, 0x30280 },
221
222	{ 149, 0x00b33, 0x012a8, 0x2e014, 0x30287 },
223	{ 153, 0x00b33, 0x012a9, 0x2e014, 0x30289 },
224	{ 157, 0x00b33, 0x012ab, 0x2e014, 0x30281 },
225	{ 161, 0x00b33, 0x012ac, 0x2e014, 0x30283 },
226	{ 165, 0x00b33, 0x012ad, 0x2e014, 0x30285 }
227};
228
229/*
230 * device operations
231 */
232static int rum_attach(dev_info_t *, ddi_attach_cmd_t);
233static int rum_detach(dev_info_t *, ddi_detach_cmd_t);
234
235/*
236 * Module Loading Data & Entry Points
237 */
238DDI_DEFINE_STREAM_OPS(rum_dev_ops, nulldev, nulldev, rum_attach,
239    rum_detach, nodev, NULL, D_MP, NULL, ddi_quiesce_not_needed);
240
241static struct modldrv rum_modldrv = {
242	&mod_driverops,		/* Type of module.  This one is a driver */
243	"rum driver v1.2",	/* short description */
244	&rum_dev_ops		/* driver specific ops */
245};
246
247static struct modlinkage modlinkage = {
248	MODREV_1,
249	(void *)&rum_modldrv,
250	NULL
251};
252
253static int	rum_m_stat(void *,  uint_t, uint64_t *);
254static int	rum_m_start(void *);
255static void	rum_m_stop(void *);
256static int	rum_m_promisc(void *, boolean_t);
257static int	rum_m_multicst(void *, boolean_t, const uint8_t *);
258static int	rum_m_unicst(void *, const uint8_t *);
259static mblk_t	*rum_m_tx(void *, mblk_t *);
260static void	rum_m_ioctl(void *, queue_t *, mblk_t *);
261static int	rum_m_setprop(void *, const char *, mac_prop_id_t,
262    uint_t, const void *);
263static int	rum_m_getprop(void *, const char *, mac_prop_id_t,
264    uint_t, void *);
265static void	rum_m_propinfo(void *, const char *, mac_prop_id_t,
266    mac_prop_info_handle_t);
267
268static mac_callbacks_t rum_m_callbacks = {
269	MC_IOCTL | MC_SETPROP | MC_GETPROP | MC_PROPINFO,
270	rum_m_stat,
271	rum_m_start,
272	rum_m_stop,
273	rum_m_promisc,
274	rum_m_multicst,
275	rum_m_unicst,
276	rum_m_tx,
277	NULL,
278	rum_m_ioctl,
279	NULL,		/* mc_getcapab */
280	NULL,
281	NULL,
282	rum_m_setprop,
283	rum_m_getprop,
284	rum_m_propinfo
285};
286
287static void rum_amrr_start(struct rum_softc *, struct ieee80211_node *);
288static int  rum_tx_trigger(struct rum_softc *, mblk_t *);
289static int  rum_rx_trigger(struct rum_softc *);
290
291uint32_t rum_dbg_flags = 0;
292
293void
294ral_debug(uint32_t dbg_flags, const int8_t *fmt, ...)
295{
296	va_list args;
297
298	if (dbg_flags & rum_dbg_flags) {
299		va_start(args, fmt);
300		vcmn_err(CE_CONT, fmt, args);
301		va_end(args);
302	}
303}
304
305static void
306rum_read_multi(struct rum_softc *sc, uint16_t reg, void *buf, int len)
307{
308	usb_ctrl_setup_t req;
309	usb_cr_t cr;
310	usb_cb_flags_t cf;
311	mblk_t *mp;
312	int err;
313
314	bzero(&req, sizeof (req));
315	req.bmRequestType = USB_DEV_REQ_TYPE_VENDOR | USB_DEV_REQ_DEV_TO_HOST;
316	req.bRequest = RT2573_READ_MULTI_MAC;
317	req.wValue = 0;
318	req.wIndex = reg;
319	req.wLength = (uint16_t)len;
320	req.attrs = USB_ATTRS_AUTOCLEARING;
321
322	mp = NULL;
323	err = usb_pipe_ctrl_xfer_wait(sc->sc_udev->dev_default_ph, &req, &mp,
324	    &cr, &cf, 0);
325
326	if (err != USB_SUCCESS) {
327		ral_debug(RAL_DBG_ERR,
328		    "rum_read_multi(): could not read MAC register:"
329		    "cr:%s(%d), cf:(%x)\n",
330		    usb_str_cr(cr), cr, cf);
331		return;
332	}
333
334	bcopy(mp->b_rptr, buf, len);
335	freemsg(mp);
336}
337
338static uint32_t
339rum_read(struct rum_softc *sc, uint16_t reg)
340{
341	uint32_t val;
342
343	rum_read_multi(sc, reg, &val, sizeof (val));
344
345	return (LE_32(val));
346}
347
348static void
349rum_write_multi(struct rum_softc *sc, uint16_t reg, void *buf, size_t len)
350{
351	usb_ctrl_setup_t req;
352	usb_cr_t cr;
353	usb_cb_flags_t cf;
354	mblk_t *mp;
355	int err;
356
357	bzero(&req, sizeof (req));
358	req.bmRequestType = USB_DEV_REQ_TYPE_VENDOR | USB_DEV_REQ_HOST_TO_DEV;
359	req.bRequest = RT2573_WRITE_MULTI_MAC;
360	req.wValue = 0;
361	req.wIndex = reg;
362	req.wLength = (uint16_t)len;
363	req.attrs = USB_ATTRS_NONE;
364
365	if ((mp = allocb(len, BPRI_HI)) == NULL) {
366		ral_debug(RAL_DBG_ERR, "rum_write_multi(): failed alloc mblk.");
367		return;
368	}
369
370	bcopy(buf, mp->b_wptr, len);
371	mp->b_wptr += len;
372
373	err = usb_pipe_ctrl_xfer_wait(sc->sc_udev->dev_default_ph, &req, &mp,
374	    &cr, &cf, 0);
375
376	if (err != USB_SUCCESS) {
377		ral_debug(RAL_DBG_USB,
378		    "rum_write_multi(): could not write MAC register:"
379		    "cr:%s(%d), cf:(%x)\n",
380		    usb_str_cr(cr), cr, cf);
381	}
382
383	freemsg(mp);
384}
385
386static void
387rum_write(struct rum_softc *sc, uint16_t reg, uint32_t val)
388{
389	uint32_t tmp = LE_32(val);
390
391	rum_write_multi(sc, reg, &tmp, sizeof (tmp));
392}
393
394#define	UGETDW(w) ((w)[0] | ((w)[1] << 8) | ((w)[2] << 16) | ((w)[3] << 24))
395
396static int
397rum_load_microcode(struct rum_softc *sc)
398{
399	usb_ctrl_setup_t req;
400	usb_cr_t cr;
401	usb_cb_flags_t cf;
402	int err;
403
404	const uint8_t *ucode;
405	int size;
406	uint16_t reg = RT2573_MCU_CODE_BASE;
407
408	ucode = rt2573_ucode;
409	size  = sizeof (rt2573_ucode);
410
411	/* copy firmware image into NIC */
412	for (; size >= 4; reg += 4, ucode += 4, size -= 4) {
413		rum_write(sc, reg, UGETDW(ucode));
414		/* rum_write(sc, reg, *(uint32_t *)(ucode)); */
415	}
416
417	bzero(&req, sizeof (req));
418	req.bmRequestType = USB_DEV_REQ_TYPE_VENDOR | USB_DEV_REQ_HOST_TO_DEV;
419	req.bRequest = RT2573_MCU_CNTL;
420	req.wValue = RT2573_MCU_RUN;
421	req.wIndex = 0;
422	req.wLength = 0;
423	req.attrs = USB_ATTRS_NONE;
424
425	err = usb_pipe_ctrl_xfer_wait(sc->sc_udev->dev_default_ph, &req, NULL,
426	    &cr, &cf, 0);
427
428	if (err != USB_SUCCESS) {
429		ral_debug(RAL_DBG_ERR,
430		    "rum_load_microcode(): could not run firmware: "
431		    "cr:%s(%d), cf:(%x)\n",
432		    usb_str_cr(cr), cr, cf);
433	}
434
435	ral_debug(RAL_DBG_MSG,
436	    "rum_load_microcode(%d): done\n", sizeof (rt2573_ucode));
437
438	return (err);
439}
440
441static void
442rum_eeprom_read(struct rum_softc *sc, uint16_t addr, void *buf, int len)
443{
444	usb_ctrl_setup_t req;
445	usb_cr_t cr;
446	usb_cb_flags_t cf;
447	mblk_t *mp;
448	int err;
449
450	bzero(&req, sizeof (req));
451	req.bmRequestType = USB_DEV_REQ_TYPE_VENDOR | USB_DEV_REQ_DEV_TO_HOST;
452	req.bRequest = RT2573_READ_EEPROM;
453	req.wValue = 0;
454	req.wIndex = addr;
455	req.wLength = (uint16_t)len;
456
457	mp = NULL;
458	err = usb_pipe_ctrl_xfer_wait(sc->sc_udev->dev_default_ph, &req, &mp,
459	    &cr, &cf, 0);
460
461	if (err != USB_SUCCESS) {
462		ral_debug(RAL_DBG_USB,
463		    "rum_eeprom_read(): could not read EEPROM:"
464		    "cr:%s(%d), cf:(%x)\n",
465		    usb_str_cr(cr), cr, cf);
466		return;
467	}
468
469	bcopy(mp->b_rptr, buf, len);
470	freemsg(mp);
471}
472
473/* ARGSUSED */
474static void
475rum_txeof(usb_pipe_handle_t pipe, usb_bulk_req_t *req)
476{
477	struct rum_softc *sc = (struct rum_softc *)req->bulk_client_private;
478	struct ieee80211com *ic = &sc->sc_ic;
479
480	ral_debug(RAL_DBG_TX,
481	    "rum_txeof(): cr:%s(%d), flags:0x%x, tx_queued:%d",
482	    usb_str_cr(req->bulk_completion_reason),
483	    req->bulk_completion_reason,
484	    req->bulk_cb_flags,
485	    sc->tx_queued);
486
487	if (req->bulk_completion_reason != USB_CR_OK)
488		sc->sc_tx_err++;
489
490	mutex_enter(&sc->tx_lock);
491
492	sc->tx_queued--;
493	sc->sc_tx_timer = 0;
494
495	if (sc->sc_need_sched) {
496		sc->sc_need_sched = 0;
497		mac_tx_update(ic->ic_mach);
498	}
499
500	mutex_exit(&sc->tx_lock);
501	usb_free_bulk_req(req);
502}
503
504/* ARGSUSED */
505static void
506rum_rxeof(usb_pipe_handle_t pipe, usb_bulk_req_t *req)
507{
508	struct rum_softc *sc = (struct rum_softc *)req->bulk_client_private;
509	struct ieee80211com *ic = &sc->sc_ic;
510
511	struct rum_rx_desc *desc;
512	struct ieee80211_frame *wh;
513	struct ieee80211_node *ni;
514
515	mblk_t *m, *mp;
516	int len, pktlen;
517	char *rxbuf;
518
519	mp = req->bulk_data;
520	req->bulk_data = NULL;
521
522	ral_debug(RAL_DBG_RX,
523	    "rum_rxeof(): cr:%s(%d), flags:0x%x, rx_queued:%d",
524	    usb_str_cr(req->bulk_completion_reason),
525	    req->bulk_completion_reason,
526	    req->bulk_cb_flags,
527	    sc->rx_queued);
528
529	if (req->bulk_completion_reason != USB_CR_OK) {
530		sc->sc_rx_err++;
531		goto fail;
532	}
533
534	len = msgdsize(mp);
535	rxbuf = (char *)mp->b_rptr;
536
537
538	if (len < RT2573_RX_DESC_SIZE + sizeof (struct ieee80211_frame_min)) {
539		ral_debug(RAL_DBG_ERR,
540		    "rum_rxeof(): xfer too short %d\n", len);
541		sc->sc_rx_err++;
542		goto fail;
543	}
544
545	/* rx descriptor is located at the head, different from RT2500USB */
546	desc = (struct rum_rx_desc *)rxbuf;
547
548	if (LE_32(desc->flags) & RT2573_RX_CRC_ERROR) {
549		/*
550		 * This should not happen since we did not request to receive
551		 * those frames when we filled RT2573_TXRX_CSR0.
552		 */
553		ral_debug(RAL_DBG_ERR, "CRC error\n");
554		sc->sc_rx_err++;
555		goto fail;
556	}
557
558	pktlen = (LE_32(desc->flags) >> 16) & 0xfff;
559
560	if (pktlen > (len - RT2573_RX_DESC_SIZE)) {
561		ral_debug(RAL_DBG_ERR,
562		    "rum_rxeof(): pktlen mismatch <%d, %d>.\n", pktlen, len);
563		goto fail;
564	}
565
566	if ((m = allocb(pktlen, BPRI_MED)) == NULL) {
567		ral_debug(RAL_DBG_ERR,
568		    "rum_rxeof(): allocate mblk failed.\n");
569		sc->sc_rx_nobuf++;
570		goto fail;
571	}
572
573	bcopy(rxbuf + RT2573_RX_DESC_SIZE, m->b_rptr, pktlen);
574	m->b_wptr += pktlen;
575
576	wh = (struct ieee80211_frame *)m->b_rptr;
577	ni = ieee80211_find_rxnode(ic, wh);
578
579	/* send the frame to the 802.11 layer */
580	(void) ieee80211_input(ic, m, ni, desc->rssi, 0);
581
582	/* node is no longer needed */
583	ieee80211_free_node(ni);
584
585fail:
586	mutex_enter(&sc->rx_lock);
587	sc->rx_queued--;
588	mutex_exit(&sc->rx_lock);
589
590	freemsg(mp);
591	usb_free_bulk_req(req);
592
593	if (RAL_IS_RUNNING(sc))
594		(void) rum_rx_trigger(sc);
595}
596
597/*
598 * Return the expected ack rate for a frame transmitted at rate `rate'.
599 */
600static int
601rum_ack_rate(struct ieee80211com *ic, int rate)
602{
603	switch (rate) {
604	/* CCK rates */
605	case 2:
606		return (2);
607	case 4:
608	case 11:
609	case 22:
610		return ((ic->ic_curmode == IEEE80211_MODE_11B) ? 4 : rate);
611
612	/* OFDM rates */
613	case 12:
614	case 18:
615		return (12);
616	case 24:
617	case 36:
618		return (24);
619	case 48:
620	case 72:
621	case 96:
622	case 108:
623		return (48);
624	}
625
626	/* default to 1Mbps */
627	return (2);
628}
629
630/*
631 * Compute the duration (in us) needed to transmit `len' bytes at rate `rate'.
632 * The function automatically determines the operating mode depending on the
633 * given rate. `flags' indicates whether short preamble is in use or not.
634 */
635static uint16_t
636rum_txtime(int len, int rate, uint32_t flags)
637{
638	uint16_t txtime;
639
640	if (RUM_RATE_IS_OFDM(rate)) {
641		/* IEEE Std 802.11a-1999, pp. 37 */
642		txtime = (8 + 4 * len + 3 + rate - 1) / rate;
643		txtime = 16 + 4 + 4 * txtime + 6;
644	} else {
645		/* IEEE Std 802.11b-1999, pp. 28 */
646		txtime = (16 * len + rate - 1) / rate;
647		if (rate != 2 && (flags & IEEE80211_F_SHPREAMBLE))
648			txtime +=  72 + 24;
649		else
650			txtime += 144 + 48;
651	}
652	return (txtime);
653}
654
655static uint8_t
656rum_plcp_signal(int rate)
657{
658	switch (rate) {
659	/* CCK rates (returned values are device-dependent) */
660	case 2:		return (0x0);
661	case 4:		return (0x1);
662	case 11:	return (0x2);
663	case 22:	return (0x3);
664
665	/* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
666	case 12:	return (0xb);
667	case 18:	return (0xf);
668	case 24:	return (0xa);
669	case 36:	return (0xe);
670	case 48:	return (0x9);
671	case 72:	return (0xd);
672	case 96:	return (0x8);
673	case 108:	return (0xc);
674
675	/* unsupported rates (should not get there) */
676	default:	return (0xff);
677	}
678}
679
680static void
681rum_setup_tx_desc(struct rum_softc *sc, struct rum_tx_desc *desc,
682    uint32_t flags, uint16_t xflags, int len, int rate)
683{
684	struct ieee80211com *ic = &sc->sc_ic;
685	uint16_t plcp_length;
686	int remainder;
687
688	desc->flags = LE_32(flags);
689	desc->flags |= LE_32(RT2573_TX_VALID);
690	desc->flags |= LE_32(len << 16);
691
692	desc->xflags = LE_16(xflags);
693
694	desc->wme = LE_16(RT2573_QID(0) | RT2573_AIFSN(2) |
695	    RT2573_LOGCWMIN(4) | RT2573_LOGCWMAX(10));
696
697	/* setup PLCP fields */
698	desc->plcp_signal  = rum_plcp_signal(rate);
699	desc->plcp_service = 4;
700
701	len += IEEE80211_CRC_LEN;
702	if (RUM_RATE_IS_OFDM(rate)) {
703		desc->flags |= LE_32(RT2573_TX_OFDM);
704
705		plcp_length = len & 0xfff;
706		desc->plcp_length_hi = plcp_length >> 6;
707		desc->plcp_length_lo = plcp_length & 0x3f;
708	} else {
709		plcp_length = (16 * len + rate - 1) / rate;
710		if (rate == 22) {
711			remainder = (16 * len) % 22;
712			if (remainder != 0 && remainder < 7)
713				desc->plcp_service |= RT2573_PLCP_LENGEXT;
714		}
715		desc->plcp_length_hi = plcp_length >> 8;
716		desc->plcp_length_lo = plcp_length & 0xff;
717
718		if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
719			desc->plcp_signal |= 0x08;
720	}
721}
722
723#define	RUM_TX_TIMEOUT	5
724
725static int
726rum_send(ieee80211com_t *ic, mblk_t *mp, uint8_t type)
727{
728	struct rum_softc *sc = (struct rum_softc *)ic;
729	struct rum_tx_desc *desc;
730
731	struct ieee80211_frame *wh;
732	struct ieee80211_key *k;
733
734	uint16_t dur;
735	uint32_t flags = 0;
736	int rate, err = DDI_SUCCESS, rv;
737
738	struct ieee80211_node *ni = NULL;
739	mblk_t *m, *m0;
740	int off, mblen, pktlen, xferlen;
741
742	/* discard packets while suspending or not inited */
743	if (!RAL_IS_RUNNING(sc)) {
744		freemsg(mp);
745		return (ENXIO);
746	}
747
748	mutex_enter(&sc->tx_lock);
749
750	if (sc->tx_queued > RAL_TX_LIST_COUNT) {
751		ral_debug(RAL_DBG_TX, "rum_send(): "
752		    "no TX buffer available!\n");
753		if ((type & IEEE80211_FC0_TYPE_MASK) ==
754		    IEEE80211_FC0_TYPE_DATA) {
755			sc->sc_need_sched = 1;
756		}
757		sc->sc_tx_nobuf++;
758		err = ENOMEM;
759		goto fail;
760	}
761
762	m = allocb(RAL_TXBUF_SIZE + RT2573_TX_DESC_SIZE, BPRI_MED);
763	if (m == NULL) {
764		ral_debug(RAL_DBG_ERR, "rum_send(): can't alloc mblk.\n");
765		err = DDI_FAILURE;
766		goto fail;
767	}
768
769	m->b_rptr += RT2573_TX_DESC_SIZE;	/* skip TX descriptor */
770	m->b_wptr += RT2573_TX_DESC_SIZE;
771
772	for (off = 0, m0 = mp; m0 != NULL; m0 = m0->b_cont) {
773		mblen = (uintptr_t)m0->b_wptr - (uintptr_t)m0->b_rptr;
774		(void) memcpy(m->b_rptr + off, m0->b_rptr, mblen);
775		off += mblen;
776	}
777	m->b_wptr += off;
778
779	wh = (struct ieee80211_frame *)m->b_rptr;
780
781	ni = ieee80211_find_txnode(ic, wh->i_addr1);
782	if (ni == NULL) {
783		err = DDI_FAILURE;
784		sc->sc_tx_err++;
785		freemsg(m);
786		goto fail;
787	}
788
789	if ((type & IEEE80211_FC0_TYPE_MASK) ==
790	    IEEE80211_FC0_TYPE_DATA) {
791		(void) ieee80211_encap(ic, m, ni);
792	}
793
794	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
795		k = ieee80211_crypto_encap(ic, m);
796		if (k == NULL) {
797			sc->sc_tx_err++;
798			err = DDI_FAILURE;
799			freemsg(m);
800			goto fail;
801		}
802		/* packet header may have moved, reset our local pointer */
803		wh = (struct ieee80211_frame *)m->b_rptr;
804	}
805
806	m->b_rptr -= RT2573_TX_DESC_SIZE;	/* restore */
807	desc = (struct rum_tx_desc *)m->b_rptr;
808
809	if ((type & IEEE80211_FC0_TYPE_MASK) ==
810	    IEEE80211_FC0_TYPE_DATA) {	/* DATA */
811		if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE)
812			rate = ic->ic_bss->in_rates.ir_rates[ic->ic_fixed_rate];
813		else
814			rate = ni->in_rates.ir_rates[ni->in_txrate];
815
816		rate &= IEEE80211_RATE_VAL;
817		if (rate <= 0) {
818			rate = 2;	/* basic rate */
819		}
820
821
822		if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
823			flags |= RT2573_TX_NEED_ACK;
824			flags |= RT2573_TX_MORE_FRAG;
825
826			dur = rum_txtime(RUM_ACK_SIZE, rum_ack_rate(ic, rate),
827			    ic->ic_flags) + sc->sifs;
828			*(uint16_t *)(uintptr_t)wh->i_dur = LE_16(dur);
829		}
830	} else {	/* MGMT */
831		rate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 2;
832
833		if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
834			flags |= RT2573_TX_NEED_ACK;
835
836			dur = rum_txtime(RUM_ACK_SIZE, rum_ack_rate(ic, rate),
837			    ic->ic_flags) + sc->sifs;
838			*(uint16_t *)(uintptr_t)wh->i_dur = LE_16(dur);
839
840			/* tell hardware to add timestamp for probe responses */
841			if ((wh->i_fc[0] &
842			    (IEEE80211_FC0_TYPE_MASK |
843			    IEEE80211_FC0_SUBTYPE_MASK)) ==
844			    (IEEE80211_FC0_TYPE_MGT |
845			    IEEE80211_FC0_SUBTYPE_PROBE_RESP))
846				flags |= RT2573_TX_TIMESTAMP;
847		}
848	}
849
850	pktlen = msgdsize(m) - RT2573_TX_DESC_SIZE;
851	rum_setup_tx_desc(sc, desc, flags, 0, pktlen, rate);
852
853	/* align end on a 4-bytes boundary */
854	xferlen = (RT2573_TX_DESC_SIZE + pktlen + 3) & ~3;
855
856	/*
857	 * No space left in the last URB to store the extra 4 bytes, force
858	 * sending of another URB.
859	 */
860	if ((xferlen % 64) == 0)
861		xferlen += 4;
862
863	m->b_wptr = m->b_rptr + xferlen;
864
865	ral_debug(RAL_DBG_TX, "sending data frame len=%u rate=%u xfer len=%u\n",
866	    pktlen, rate, xferlen);
867
868	rv = rum_tx_trigger(sc, m);
869
870	if (rv == 0) {
871		ic->ic_stats.is_tx_frags++;
872		ic->ic_stats.is_tx_bytes += pktlen;
873	}
874
875fail:
876	if (ni != NULL)
877		ieee80211_free_node(ni);
878
879	if ((type & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_DATA ||
880	    err == 0) {
881		freemsg(mp);
882	}
883
884	mutex_exit(&sc->tx_lock);
885
886	return (err);
887}
888
889static mblk_t *
890rum_m_tx(void *arg, mblk_t *mp)
891{
892	struct rum_softc *sc = (struct rum_softc *)arg;
893	struct ieee80211com *ic = &sc->sc_ic;
894	mblk_t *next;
895
896	/*
897	 * No data frames go out unless we're associated; this
898	 * should not happen as the 802.11 layer does not enable
899	 * the xmit queue until we enter the RUN state.
900	 */
901	if (ic->ic_state != IEEE80211_S_RUN) {
902		ral_debug(RAL_DBG_ERR, "rum_m_tx(): "
903		    "discard, state %u\n", ic->ic_state);
904		freemsgchain(mp);
905		return (NULL);
906	}
907
908	while (mp != NULL) {
909		next = mp->b_next;
910		mp->b_next = NULL;
911		if (rum_send(ic, mp, IEEE80211_FC0_TYPE_DATA) != DDI_SUCCESS) {
912			mp->b_next = next;
913			freemsgchain(mp);
914			return (NULL);
915		}
916		mp = next;
917	}
918	return (mp);
919}
920
921static void
922rum_bbp_write(struct rum_softc *sc, uint8_t reg, uint8_t val)
923{
924	uint32_t tmp;
925	int ntries;
926
927	for (ntries = 0; ntries < 5; ntries++) {
928		if (!(rum_read(sc, RT2573_PHY_CSR3) & RT2573_BBP_BUSY))
929			break;
930	}
931	if (ntries == 5) {
932		ral_debug(RAL_DBG_ERR,
933		    "rum_bbp_write(): could not write to BBP\n");
934		return;
935	}
936
937	tmp = RT2573_BBP_BUSY | (reg & 0x7f) << 8 | val;
938	rum_write(sc, RT2573_PHY_CSR3, tmp);
939}
940
941static uint8_t
942rum_bbp_read(struct rum_softc *sc, uint8_t reg)
943{
944	uint32_t val;
945	int ntries;
946
947	for (ntries = 0; ntries < 5; ntries++) {
948		if (!(rum_read(sc, RT2573_PHY_CSR3) & RT2573_BBP_BUSY))
949			break;
950	}
951	if (ntries == 5) {
952		ral_debug(RAL_DBG_ERR, "rum_bbp_read(): could not read BBP\n");
953		return (0);
954	}
955
956	val = RT2573_BBP_BUSY | RT2573_BBP_READ | reg << 8;
957	rum_write(sc, RT2573_PHY_CSR3, val);
958
959	for (ntries = 0; ntries < 100; ntries++) {
960		val = rum_read(sc, RT2573_PHY_CSR3);
961		if (!(val & RT2573_BBP_BUSY))
962			return (val & 0xff);
963		drv_usecwait(1);
964	}
965
966	ral_debug(RAL_DBG_ERR, "rum_bbp_read(): could not read BBP\n");
967	return (0);
968}
969
970static void
971rum_rf_write(struct rum_softc *sc, uint8_t reg, uint32_t val)
972{
973	uint32_t tmp;
974	int ntries;
975
976	for (ntries = 0; ntries < 5; ntries++) {
977		if (!(rum_read(sc, RT2573_PHY_CSR4) & RT2573_RF_BUSY))
978			break;
979	}
980	if (ntries == 5) {
981		ral_debug(RAL_DBG_ERR,
982		    "rum_rf_write(): could not write to RF\n");
983		return;
984	}
985
986	tmp = RT2573_RF_BUSY | RT2573_RF_20BIT | (val & 0xfffff) << 2 |
987	    (reg & 3);
988	rum_write(sc, RT2573_PHY_CSR4, tmp);
989
990	/* remember last written value in sc */
991	sc->rf_regs[reg] = val;
992
993	ral_debug(RAL_DBG_HW, "RF R[%u] <- 0x%05x\n", reg & 3, val & 0xfffff);
994}
995
996static void
997rum_select_antenna(struct rum_softc *sc)
998{
999	uint8_t bbp4, bbp77;
1000	uint32_t tmp;
1001
1002	bbp4  = rum_bbp_read(sc, 4);
1003	bbp77 = rum_bbp_read(sc, 77);
1004
1005	/* make sure Rx is disabled before switching antenna */
1006	tmp = rum_read(sc, RT2573_TXRX_CSR0);
1007	rum_write(sc, RT2573_TXRX_CSR0, tmp | RT2573_DISABLE_RX);
1008
1009	rum_bbp_write(sc,  4, bbp4);
1010	rum_bbp_write(sc, 77, bbp77);
1011
1012	rum_write(sc, RT2573_TXRX_CSR0, tmp);
1013}
1014
1015/*
1016 * Enable multi-rate retries for frames sent at OFDM rates.
1017 * In 802.11b/g mode, allow fallback to CCK rates.
1018 */
1019static void
1020rum_enable_mrr(struct rum_softc *sc)
1021{
1022	struct ieee80211com *ic = &sc->sc_ic;
1023	uint32_t tmp;
1024
1025	tmp = rum_read(sc, RT2573_TXRX_CSR4);
1026
1027	tmp &= ~RT2573_MRR_CCK_FALLBACK;
1028	if (!IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
1029		tmp |= RT2573_MRR_CCK_FALLBACK;
1030	tmp |= RT2573_MRR_ENABLED;
1031
1032	rum_write(sc, RT2573_TXRX_CSR4, tmp);
1033}
1034
1035static void
1036rum_set_txpreamble(struct rum_softc *sc)
1037{
1038	uint32_t tmp;
1039
1040	tmp = rum_read(sc, RT2573_TXRX_CSR4);
1041
1042	tmp &= ~RT2573_SHORT_PREAMBLE;
1043	if (sc->sc_ic.ic_flags & IEEE80211_F_SHPREAMBLE)
1044		tmp |= RT2573_SHORT_PREAMBLE;
1045
1046	rum_write(sc, RT2573_TXRX_CSR4, tmp);
1047}
1048
1049static void
1050rum_set_basicrates(struct rum_softc *sc)
1051{
1052	struct ieee80211com *ic = &sc->sc_ic;
1053
1054	/* update basic rate set */
1055	if (ic->ic_curmode == IEEE80211_MODE_11B) {
1056		/* 11b basic rates: 1, 2Mbps */
1057		rum_write(sc, RT2573_TXRX_CSR5, 0x3);
1058	} else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_bss->in_chan)) {
1059		/* 11a basic rates: 6, 12, 24Mbps */
1060		rum_write(sc, RT2573_TXRX_CSR5, 0x150);
1061	} else {
1062		/* 11b/g basic rates: 1, 2, 5.5, 11Mbps */
1063		rum_write(sc, RT2573_TXRX_CSR5, 0xf);
1064	}
1065}
1066
1067/*
1068 * Reprogram MAC/BBP to switch to a new band.  Values taken from the reference
1069 * driver.
1070 */
1071static void
1072rum_select_band(struct rum_softc *sc, struct ieee80211_channel *c)
1073{
1074	uint8_t bbp17, bbp35, bbp96, bbp97, bbp98, bbp104;
1075	uint32_t tmp;
1076
1077	/* update all BBP registers that depend on the band */
1078	bbp17 = 0x20; bbp96 = 0x48; bbp104 = 0x2c;
1079	bbp35 = 0x50; bbp97 = 0x48; bbp98  = 0x48;
1080	if (IEEE80211_IS_CHAN_5GHZ(c)) {
1081		bbp17 += 0x08; bbp96 += 0x10; bbp104 += 0x0c;
1082		bbp35 += 0x10; bbp97 += 0x10; bbp98  += 0x10;
1083	}
1084	if ((IEEE80211_IS_CHAN_2GHZ(c) && sc->ext_2ghz_lna) ||
1085	    (IEEE80211_IS_CHAN_5GHZ(c) && sc->ext_5ghz_lna)) {
1086		bbp17 += 0x10; bbp96 += 0x10; bbp104 += 0x10;
1087	}
1088
1089	sc->bbp17 = bbp17;
1090	rum_bbp_write(sc,  17, bbp17);
1091	rum_bbp_write(sc,  96, bbp96);
1092	rum_bbp_write(sc, 104, bbp104);
1093
1094	if ((IEEE80211_IS_CHAN_2GHZ(c) && sc->ext_2ghz_lna) ||
1095	    (IEEE80211_IS_CHAN_5GHZ(c) && sc->ext_5ghz_lna)) {
1096		rum_bbp_write(sc, 75, 0x80);
1097		rum_bbp_write(sc, 86, 0x80);
1098		rum_bbp_write(sc, 88, 0x80);
1099	}
1100
1101	rum_bbp_write(sc, 35, bbp35);
1102	rum_bbp_write(sc, 97, bbp97);
1103	rum_bbp_write(sc, 98, bbp98);
1104
1105	tmp = rum_read(sc, RT2573_PHY_CSR0);
1106	tmp &= ~(RT2573_PA_PE_2GHZ | RT2573_PA_PE_5GHZ);
1107	if (IEEE80211_IS_CHAN_2GHZ(c))
1108		tmp |= RT2573_PA_PE_2GHZ;
1109	else
1110		tmp |= RT2573_PA_PE_5GHZ;
1111	rum_write(sc, RT2573_PHY_CSR0, tmp);
1112
1113	/* 802.11a uses a 16 microseconds short interframe space */
1114	sc->sifs = IEEE80211_IS_CHAN_5GHZ(c) ? 16 : 10;
1115}
1116
1117static void
1118rum_set_chan(struct rum_softc *sc, struct ieee80211_channel *c)
1119{
1120	struct ieee80211com *ic = &sc->sc_ic;
1121	const struct rfprog *rfprog;
1122	uint8_t bbp3, bbp94 = RT2573_BBPR94_DEFAULT;
1123	int8_t power;
1124	uint_t i, chan;
1125
1126	chan = ieee80211_chan2ieee(ic, c);
1127	if (chan == 0 || chan == IEEE80211_CHAN_ANY)
1128		return;
1129
1130	/* select the appropriate RF settings based on what EEPROM says */
1131	rfprog = (sc->rf_rev == RT2573_RF_5225 ||
1132	    sc->rf_rev == RT2573_RF_2527) ? rum_rf5225 : rum_rf5226;
1133
1134	/* find the settings for this channel (we know it exists) */
1135	for (i = 0; rfprog[i].chan != chan; i++) {
1136	}
1137
1138	power = sc->txpow[i];
1139	if (power < 0) {
1140		bbp94 += power;
1141		power = 0;
1142	} else if (power > 31) {
1143		bbp94 += power - 31;
1144		power = 31;
1145	}
1146
1147	/*
1148	 * If we are switching from the 2GHz band to the 5GHz band or
1149	 * vice-versa, BBP registers need to be reprogrammed.
1150	 */
1151	if (c->ich_flags != ic->ic_curchan->ich_flags) {
1152		rum_select_band(sc, c);
1153		rum_select_antenna(sc);
1154	}
1155	ic->ic_curchan = c;
1156
1157	rum_rf_write(sc, RT2573_RF1, rfprog[i].r1);
1158	rum_rf_write(sc, RT2573_RF2, rfprog[i].r2);
1159	rum_rf_write(sc, RT2573_RF3, rfprog[i].r3 | power << 7);
1160	rum_rf_write(sc, RT2573_RF4, rfprog[i].r4 | sc->rffreq << 10);
1161
1162	rum_rf_write(sc, RT2573_RF1, rfprog[i].r1);
1163	rum_rf_write(sc, RT2573_RF2, rfprog[i].r2);
1164	rum_rf_write(sc, RT2573_RF3, rfprog[i].r3 | power << 7 | 1);
1165	rum_rf_write(sc, RT2573_RF4, rfprog[i].r4 | sc->rffreq << 10);
1166
1167	rum_rf_write(sc, RT2573_RF1, rfprog[i].r1);
1168	rum_rf_write(sc, RT2573_RF2, rfprog[i].r2);
1169	rum_rf_write(sc, RT2573_RF3, rfprog[i].r3 | power << 7);
1170	rum_rf_write(sc, RT2573_RF4, rfprog[i].r4 | sc->rffreq << 10);
1171
1172	drv_usecwait(10);
1173
1174	/* enable smart mode for MIMO-capable RFs */
1175	bbp3 = rum_bbp_read(sc, 3);
1176
1177	bbp3 &= ~RT2573_SMART_MODE;
1178	if (sc->rf_rev == RT2573_RF_5225 || sc->rf_rev == RT2573_RF_2527)
1179		bbp3 |= RT2573_SMART_MODE;
1180
1181	rum_bbp_write(sc, 3, bbp3);
1182
1183	if (bbp94 != RT2573_BBPR94_DEFAULT)
1184		rum_bbp_write(sc, 94, bbp94);
1185}
1186
1187/*
1188 * Enable TSF synchronization and tell h/w to start sending beacons for IBSS
1189 * and HostAP operating modes.
1190 */
1191static void
1192rum_enable_tsf_sync(struct rum_softc *sc)
1193{
1194	struct ieee80211com *ic = &sc->sc_ic;
1195	uint32_t tmp;
1196
1197	if (ic->ic_opmode != IEEE80211_M_STA) {
1198		/*
1199		 * Change default 16ms TBTT adjustment to 8ms.
1200		 * Must be done before enabling beacon generation.
1201		 */
1202		rum_write(sc, RT2573_TXRX_CSR10, 1 << 12 | 8);
1203	}
1204
1205	tmp = rum_read(sc, RT2573_TXRX_CSR9) & 0xff000000;
1206
1207	/* set beacon interval (in 1/16ms unit) */
1208	tmp |= ic->ic_bss->in_intval * 16;
1209
1210	tmp |= RT2573_TSF_TICKING | RT2573_ENABLE_TBTT;
1211	if (ic->ic_opmode == IEEE80211_M_STA)
1212		tmp |= RT2573_TSF_MODE(1);
1213	else
1214		tmp |= RT2573_TSF_MODE(2) | RT2573_GENERATE_BEACON;
1215
1216	rum_write(sc, RT2573_TXRX_CSR9, tmp);
1217}
1218
1219/* ARGSUSED */
1220static void
1221rum_update_slot(struct ieee80211com *ic, int onoff)
1222{
1223	struct rum_softc *sc = (struct rum_softc *)ic;
1224	uint8_t slottime;
1225	uint32_t tmp;
1226
1227	slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20;
1228
1229	tmp = rum_read(sc, RT2573_MAC_CSR9);
1230	tmp = (tmp & ~0xff) | slottime;
1231	rum_write(sc, RT2573_MAC_CSR9, tmp);
1232
1233	ral_debug(RAL_DBG_HW, "setting slot time to %uus\n", slottime);
1234}
1235
1236static void
1237rum_set_bssid(struct rum_softc *sc, const uint8_t *bssid)
1238{
1239	uint32_t tmp;
1240
1241	tmp = bssid[0] | bssid[1] << 8 | bssid[2] << 16 | bssid[3] << 24;
1242	rum_write(sc, RT2573_MAC_CSR4, tmp);
1243
1244	tmp = bssid[4] | bssid[5] << 8 | RT2573_ONE_BSSID << 16;
1245	rum_write(sc, RT2573_MAC_CSR5, tmp);
1246}
1247
1248static void
1249rum_set_macaddr(struct rum_softc *sc, const uint8_t *addr)
1250{
1251	uint32_t tmp;
1252
1253	tmp = addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24;
1254	rum_write(sc, RT2573_MAC_CSR2, tmp);
1255
1256	tmp = addr[4] | addr[5] << 8 | 0xff << 16;
1257	rum_write(sc, RT2573_MAC_CSR3, tmp);
1258
1259	ral_debug(RAL_DBG_HW,
1260	    "setting MAC address to " MACSTR "\n", MAC2STR(addr));
1261}
1262
1263static void
1264rum_update_promisc(struct rum_softc *sc)
1265{
1266	uint32_t tmp;
1267
1268	tmp = rum_read(sc, RT2573_TXRX_CSR0);
1269
1270	tmp &= ~RT2573_DROP_NOT_TO_ME;
1271	if (!(sc->sc_rcr & RAL_RCR_PROMISC))
1272		tmp |= RT2573_DROP_NOT_TO_ME;
1273
1274	rum_write(sc, RT2573_TXRX_CSR0, tmp);
1275
1276	ral_debug(RAL_DBG_HW, "%s promiscuous mode\n",
1277	    (sc->sc_rcr & RAL_RCR_PROMISC) ?  "entering" : "leaving");
1278}
1279
1280static const char *
1281rum_get_rf(int rev)
1282{
1283	switch (rev) {
1284	case RT2573_RF_2527:	return ("RT2527 (MIMO XR)");
1285	case RT2573_RF_2528:	return ("RT2528");
1286	case RT2573_RF_5225:	return ("RT5225 (MIMO XR)");
1287	case RT2573_RF_5226:	return ("RT5226");
1288	default:		return ("unknown");
1289	}
1290}
1291
1292static void
1293rum_read_eeprom(struct rum_softc *sc)
1294{
1295	struct ieee80211com *ic = &sc->sc_ic;
1296	uint16_t val;
1297
1298	/* read MAC address */
1299	rum_eeprom_read(sc, RT2573_EEPROM_ADDRESS, ic->ic_macaddr, 6);
1300
1301	rum_eeprom_read(sc, RT2573_EEPROM_ANTENNA, &val, 2);
1302	val = LE_16(val);
1303	sc->rf_rev =   (val >> 11) & 0x1f;
1304	sc->hw_radio = (val >> 10) & 0x1;
1305	sc->rx_ant =   (val >> 4)  & 0x3;
1306	sc->tx_ant =   (val >> 2)  & 0x3;
1307	sc->nb_ant =   val & 0x3;
1308
1309	ral_debug(RAL_DBG_HW, "RF revision=%d\n", sc->rf_rev);
1310
1311	rum_eeprom_read(sc, RT2573_EEPROM_CONFIG2, &val, 2);
1312	val = LE_16(val);
1313	sc->ext_5ghz_lna = (val >> 6) & 0x1;
1314	sc->ext_2ghz_lna = (val >> 4) & 0x1;
1315
1316	ral_debug(RAL_DBG_HW, "External 2GHz LNA=%d\nExternal 5GHz LNA=%d\n",
1317	    sc->ext_2ghz_lna, sc->ext_5ghz_lna);
1318
1319	rum_eeprom_read(sc, RT2573_EEPROM_RSSI_2GHZ_OFFSET, &val, 2);
1320	val = LE_16(val);
1321	if ((val & 0xff) != 0xff)
1322		sc->rssi_2ghz_corr = (int8_t)(val & 0xff);	/* signed */
1323
1324	rum_eeprom_read(sc, RT2573_EEPROM_RSSI_5GHZ_OFFSET, &val, 2);
1325	val = LE_16(val);
1326	if ((val & 0xff) != 0xff)
1327		sc->rssi_5ghz_corr = (int8_t)(val & 0xff);	/* signed */
1328
1329	ral_debug(RAL_DBG_HW, "RSSI 2GHz corr=%d\nRSSI 5GHz corr=%d\n",
1330	    sc->rssi_2ghz_corr, sc->rssi_5ghz_corr);
1331
1332	rum_eeprom_read(sc, RT2573_EEPROM_FREQ_OFFSET, &val, 2);
1333	val = LE_16(val);
1334	if ((val & 0xff) != 0xff)
1335		sc->rffreq = val & 0xff;
1336
1337	ral_debug(RAL_DBG_HW, "RF freq=%d\n", sc->rffreq);
1338
1339	/* read Tx power for all a/b/g channels */
1340	rum_eeprom_read(sc, RT2573_EEPROM_TXPOWER, sc->txpow, 14);
1341	/* default Tx power for 802.11a channels */
1342	(void) memset(sc->txpow + 14, 24, sizeof (sc->txpow) - 14);
1343
1344	/* read default values for BBP registers */
1345	rum_eeprom_read(sc, RT2573_EEPROM_BBP_BASE, sc->bbp_prom, 2 * 16);
1346}
1347
1348static int
1349rum_bbp_init(struct rum_softc *sc)
1350{
1351	int i, ntries;
1352
1353	/* wait for BBP to be ready */
1354	for (ntries = 0; ntries < 100; ntries++) {
1355		const uint8_t val = rum_bbp_read(sc, 0);
1356		if (val != 0 && val != 0xff)
1357			break;
1358		drv_usecwait(1000);
1359	}
1360	if (ntries == 100) {
1361		ral_debug(RAL_DBG_ERR, "timeout waiting for BBP\n");
1362		return (EIO);
1363	}
1364
1365	/* initialize BBP registers to default values */
1366	for (i = 0; i < RUM_N(rum_def_bbp); i++)
1367		rum_bbp_write(sc, rum_def_bbp[i].reg, rum_def_bbp[i].val);
1368
1369	/* write vendor-specific BBP values (from EEPROM) */
1370	for (i = 0; i < 16; i++) {
1371		if (sc->bbp_prom[i].reg == 0 || sc->bbp_prom[i].reg == 0xff)
1372			continue;
1373		rum_bbp_write(sc, sc->bbp_prom[i].reg, sc->bbp_prom[i].val);
1374	}
1375
1376	return (0);
1377}
1378
1379/*
1380 * This function is called periodically (every 200ms) during scanning to
1381 * switch from one channel to another.
1382 */
1383static void
1384rum_next_scan(void *arg)
1385{
1386	struct rum_softc *sc = arg;
1387	struct ieee80211com *ic = &sc->sc_ic;
1388
1389	if (ic->ic_state == IEEE80211_S_SCAN)
1390		ieee80211_next_scan(ic);
1391}
1392
1393static int
1394rum_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
1395{
1396	struct rum_softc *sc = (struct rum_softc *)ic;
1397	enum ieee80211_state ostate;
1398	struct ieee80211_node *ni;
1399	int err;
1400	uint32_t tmp;
1401
1402	RAL_LOCK(sc);
1403
1404	ostate = ic->ic_state;
1405
1406	if (sc->sc_scan_id != 0) {
1407		(void) untimeout(sc->sc_scan_id);
1408		sc->sc_scan_id = 0;
1409	}
1410
1411	if (sc->sc_amrr_id != 0) {
1412		(void) untimeout(sc->sc_amrr_id);
1413		sc->sc_amrr_id = 0;
1414	}
1415
1416	switch (nstate) {
1417	case IEEE80211_S_INIT:
1418		if (ostate == IEEE80211_S_RUN) {
1419			/* abort TSF synchronization */
1420			tmp = rum_read(sc, RT2573_TXRX_CSR9);
1421			rum_write(sc, RT2573_TXRX_CSR9, tmp & ~0x00ffffff);
1422		}
1423		break;
1424
1425	case IEEE80211_S_SCAN:
1426		rum_set_chan(sc, ic->ic_curchan);
1427		sc->sc_scan_id = timeout(rum_next_scan, (void *)sc,
1428		    drv_usectohz(sc->dwelltime * 1000));
1429		break;
1430
1431	case IEEE80211_S_AUTH:
1432		rum_set_chan(sc, ic->ic_curchan);
1433		break;
1434
1435	case IEEE80211_S_ASSOC:
1436		rum_set_chan(sc, ic->ic_curchan);
1437		break;
1438
1439	case IEEE80211_S_RUN:
1440		rum_set_chan(sc, ic->ic_curchan);
1441
1442		ni = ic->ic_bss;
1443
1444		if (ic->ic_opmode != IEEE80211_M_MONITOR) {
1445			rum_update_slot(ic, 1);
1446			rum_enable_mrr(sc);
1447			rum_set_txpreamble(sc);
1448			rum_set_basicrates(sc);
1449			rum_set_bssid(sc, ni->in_bssid);
1450		}
1451
1452		if (ic->ic_opmode != IEEE80211_M_MONITOR)
1453			rum_enable_tsf_sync(sc);
1454
1455		/* enable automatic rate adaptation in STA mode */
1456		if (ic->ic_opmode == IEEE80211_M_STA &&
1457		    ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE)
1458			rum_amrr_start(sc, ni);
1459		break;
1460	}
1461
1462	RAL_UNLOCK(sc);
1463
1464	err = sc->sc_newstate(ic, nstate, arg);
1465	/*
1466	 * Finally, start any timers.
1467	 */
1468	if (nstate == IEEE80211_S_RUN)
1469		ieee80211_start_watchdog(ic, 1);
1470
1471	return (err);
1472}
1473
1474static void
1475rum_close_pipes(struct rum_softc *sc)
1476{
1477	usb_flags_t flags = USB_FLAGS_SLEEP;
1478
1479	if (sc->sc_rx_pipeh != NULL) {
1480		usb_pipe_reset(sc->sc_dev, sc->sc_rx_pipeh, flags, NULL, 0);
1481		usb_pipe_close(sc->sc_dev, sc->sc_rx_pipeh, flags, NULL, 0);
1482		sc->sc_rx_pipeh = NULL;
1483	}
1484
1485	if (sc->sc_tx_pipeh != NULL) {
1486		usb_pipe_reset(sc->sc_dev, sc->sc_tx_pipeh, flags, NULL, 0);
1487		usb_pipe_close(sc->sc_dev, sc->sc_tx_pipeh, flags, NULL, 0);
1488		sc->sc_tx_pipeh = NULL;
1489	}
1490}
1491
1492static int
1493rum_open_pipes(struct rum_softc *sc)
1494{
1495	usb_ep_data_t *ep_node;
1496	usb_pipe_policy_t policy;
1497	int err;
1498
1499	ep_node = usb_lookup_ep_data(sc->sc_dev, sc->sc_udev, 0, 0, 0,
1500	    USB_EP_ATTR_BULK, USB_EP_DIR_OUT);
1501
1502	bzero(&policy, sizeof (usb_pipe_policy_t));
1503	policy.pp_max_async_reqs = RAL_TX_LIST_COUNT;
1504
1505	if ((err = usb_pipe_open(sc->sc_dev,
1506	    &ep_node->ep_descr, &policy, USB_FLAGS_SLEEP,
1507	    &sc->sc_tx_pipeh)) != USB_SUCCESS) {
1508		ral_debug(RAL_DBG_ERR,
1509		    "rum_open_pipes(): %x failed to open tx pipe\n", err);
1510		goto fail;
1511	}
1512
1513	ep_node = usb_lookup_ep_data(sc->sc_dev, sc->sc_udev, 0, 0, 0,
1514	    USB_EP_ATTR_BULK, USB_EP_DIR_IN);
1515
1516	bzero(&policy, sizeof (usb_pipe_policy_t));
1517	policy.pp_max_async_reqs = RAL_RX_LIST_COUNT + 32;
1518
1519	if ((err = usb_pipe_open(sc->sc_dev,
1520	    &ep_node->ep_descr, &policy, USB_FLAGS_SLEEP,
1521	    &sc->sc_rx_pipeh)) != USB_SUCCESS) {
1522		ral_debug(RAL_DBG_ERR,
1523		    "rum_open_pipes(): %x failed to open rx pipe\n", err);
1524		goto fail;
1525	}
1526
1527	return (USB_SUCCESS);
1528
1529fail:
1530	if (sc->sc_rx_pipeh != NULL) {
1531		usb_pipe_close(sc->sc_dev, sc->sc_rx_pipeh,
1532		    USB_FLAGS_SLEEP, NULL, 0);
1533		sc->sc_rx_pipeh = NULL;
1534	}
1535
1536	if (sc->sc_tx_pipeh != NULL) {
1537		usb_pipe_close(sc->sc_dev, sc->sc_tx_pipeh,
1538		    USB_FLAGS_SLEEP, NULL, 0);
1539		sc->sc_tx_pipeh = NULL;
1540	}
1541
1542	return (USB_FAILURE);
1543}
1544
1545static int
1546rum_tx_trigger(struct rum_softc *sc, mblk_t *mp)
1547{
1548	usb_bulk_req_t *req;
1549	int err;
1550
1551	sc->sc_tx_timer = RUM_TX_TIMEOUT;
1552
1553	req = usb_alloc_bulk_req(sc->sc_dev, 0, USB_FLAGS_SLEEP);
1554	if (req == NULL) {
1555		ral_debug(RAL_DBG_ERR,
1556		    "rum_tx_trigger(): failed to allocate req");
1557		freemsg(mp);
1558		return (-1);
1559	}
1560
1561	req->bulk_len		= msgdsize(mp);
1562	req->bulk_data		= mp;
1563	req->bulk_client_private = (usb_opaque_t)sc;
1564	req->bulk_timeout	= RUM_TX_TIMEOUT;
1565	req->bulk_attributes	= USB_ATTRS_AUTOCLEARING;
1566	req->bulk_cb		= rum_txeof;
1567	req->bulk_exc_cb	= rum_txeof;
1568	req->bulk_completion_reason = 0;
1569	req->bulk_cb_flags	= 0;
1570
1571	if ((err = usb_pipe_bulk_xfer(sc->sc_tx_pipeh, req, 0))
1572	    != USB_SUCCESS) {
1573
1574		ral_debug(RAL_DBG_ERR, "rum_tx_trigger(): "
1575		    "failed to do tx xfer, %d", err);
1576		usb_free_bulk_req(req);
1577		return (-1);
1578	}
1579
1580	sc->tx_queued++;
1581
1582	return (0);
1583}
1584
1585static int
1586rum_rx_trigger(struct rum_softc *sc)
1587{
1588	usb_bulk_req_t *req;
1589	int err;
1590
1591	req = usb_alloc_bulk_req(sc->sc_dev, RAL_RXBUF_SIZE, USB_FLAGS_SLEEP);
1592	if (req == NULL) {
1593		ral_debug(RAL_DBG_ERR,
1594		    "rum_rx_trigger(): failed to allocate req");
1595		return (-1);
1596	}
1597
1598	req->bulk_len		= RAL_RXBUF_SIZE;
1599	req->bulk_client_private = (usb_opaque_t)sc;
1600	req->bulk_timeout	= 0;
1601	req->bulk_attributes	= USB_ATTRS_SHORT_XFER_OK
1602	    | USB_ATTRS_AUTOCLEARING;
1603	req->bulk_cb		= rum_rxeof;
1604	req->bulk_exc_cb	= rum_rxeof;
1605	req->bulk_completion_reason = 0;
1606	req->bulk_cb_flags	= 0;
1607
1608	err = usb_pipe_bulk_xfer(sc->sc_rx_pipeh, req, 0);
1609
1610	if (err != USB_SUCCESS) {
1611		ral_debug(RAL_DBG_ERR, "rum_rx_trigger(): "
1612		    "failed to do rx xfer, %d", err);
1613		usb_free_bulk_req(req);
1614
1615		return (-1);
1616	}
1617
1618	mutex_enter(&sc->rx_lock);
1619	sc->rx_queued++;
1620	mutex_exit(&sc->rx_lock);
1621
1622	return (0);
1623}
1624
1625static void
1626rum_init_tx_queue(struct rum_softc *sc)
1627{
1628	sc->tx_queued = 0;
1629}
1630
1631static int
1632rum_init_rx_queue(struct rum_softc *sc)
1633{
1634	int	i;
1635
1636	sc->rx_queued = 0;
1637
1638	for (i = 0; i < RAL_RX_LIST_COUNT; i++) {
1639		if (rum_rx_trigger(sc) != 0) {
1640			return (USB_FAILURE);
1641		}
1642	}
1643
1644	return (USB_SUCCESS);
1645}
1646
1647static void
1648rum_stop(struct rum_softc *sc)
1649{
1650	struct ieee80211com *ic = &sc->sc_ic;
1651	uint32_t tmp;
1652
1653	ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
1654	ieee80211_stop_watchdog(ic);	/* stop the watchdog */
1655
1656	RAL_LOCK(sc);
1657
1658	sc->sc_tx_timer = 0;
1659	sc->sc_flags &= ~RAL_FLAG_RUNNING;	/* STOP */
1660
1661	/* disable Rx */
1662	tmp = rum_read(sc, RT2573_TXRX_CSR0);
1663	rum_write(sc, RT2573_TXRX_CSR0, tmp | RT2573_DISABLE_RX);
1664
1665	/* reset ASIC */
1666	rum_write(sc, RT2573_MAC_CSR1, 3);
1667	rum_write(sc, RT2573_MAC_CSR1, 0);
1668
1669	rum_close_pipes(sc);
1670
1671	RAL_UNLOCK(sc);
1672}
1673
1674static int
1675rum_init(struct rum_softc *sc)
1676{
1677	struct ieee80211com *ic = &sc->sc_ic;
1678	uint32_t tmp;
1679	int i, ntries;
1680
1681	rum_stop(sc);
1682
1683	/* initialize MAC registers to default values */
1684	for (i = 0; i < RUM_N(rum_def_mac); i++)
1685		rum_write(sc, rum_def_mac[i].reg, rum_def_mac[i].val);
1686
1687	/* set host ready */
1688	rum_write(sc, RT2573_MAC_CSR1, 3);
1689	rum_write(sc, RT2573_MAC_CSR1, 0);
1690
1691	/* wait for BBP/RF to wakeup */
1692	for (ntries = 0; ntries < 1000; ntries++) {
1693		if (rum_read(sc, RT2573_MAC_CSR12) & 8)
1694			break;
1695		rum_write(sc, RT2573_MAC_CSR12, 4);	/* force wakeup */
1696		drv_usecwait(1000);
1697	}
1698	if (ntries == 1000) {
1699		ral_debug(RAL_DBG_ERR,
1700		    "rum_init(): timeout waiting for BBP/RF to wakeup\n");
1701		goto fail;
1702	}
1703
1704	if (rum_bbp_init(sc) != 0)
1705		goto fail;
1706
1707	/* select default channel */
1708	rum_select_band(sc, ic->ic_curchan);
1709	rum_select_antenna(sc);
1710	rum_set_chan(sc, ic->ic_curchan);
1711
1712	/* clear STA registers */
1713	rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof (sc->sta));
1714
1715	rum_set_macaddr(sc, ic->ic_macaddr);
1716
1717	/* initialize ASIC */
1718	rum_write(sc, RT2573_MAC_CSR1, 4);
1719
1720	if (rum_open_pipes(sc) != USB_SUCCESS) {
1721		ral_debug(RAL_DBG_ERR, "rum_init(): "
1722		    "could not open pipes.\n");
1723		goto fail;
1724	}
1725
1726	rum_init_tx_queue(sc);
1727
1728	if (rum_init_rx_queue(sc) != USB_SUCCESS)
1729		goto fail;
1730
1731	/* update Rx filter */
1732	tmp = rum_read(sc, RT2573_TXRX_CSR0) & 0xffff;
1733	tmp |= RT2573_DROP_PHY_ERROR | RT2573_DROP_CRC_ERROR;
1734	if (ic->ic_opmode != IEEE80211_M_MONITOR) {
1735		tmp |= RT2573_DROP_CTL | RT2573_DROP_VER_ERROR |
1736		    RT2573_DROP_ACKCTS;
1737		if (ic->ic_opmode != IEEE80211_M_HOSTAP)
1738			tmp |= RT2573_DROP_TODS;
1739		if (!(sc->sc_rcr & RAL_RCR_PROMISC))
1740			tmp |= RT2573_DROP_NOT_TO_ME;
1741	}
1742
1743	rum_write(sc, RT2573_TXRX_CSR0, tmp);
1744	sc->sc_flags |= RAL_FLAG_RUNNING;	/* RUNNING */
1745
1746	return (DDI_SUCCESS);
1747fail:
1748	rum_stop(sc);
1749	return (DDI_FAILURE);
1750}
1751
1752static int
1753rum_disconnect(dev_info_t *devinfo)
1754{
1755	struct rum_softc *sc;
1756	struct ieee80211com *ic;
1757
1758	/*
1759	 * We can't call rum_stop() here, since the hardware is removed,
1760	 * we can't access the register anymore.
1761	 */
1762	sc = ddi_get_soft_state(rum_soft_state_p, ddi_get_instance(devinfo));
1763	ASSERT(sc != NULL);
1764
1765	if (!RAL_IS_RUNNING(sc))	/* different device or not inited */
1766		return (DDI_SUCCESS);
1767
1768	ic = &sc->sc_ic;
1769	ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
1770	ieee80211_stop_watchdog(ic);	/* stop the watchdog */
1771
1772	RAL_LOCK(sc);
1773
1774	sc->sc_tx_timer = 0;
1775	sc->sc_flags &= ~RAL_FLAG_RUNNING;	/* STOP */
1776
1777	rum_close_pipes(sc);
1778
1779	RAL_UNLOCK(sc);
1780
1781	return (DDI_SUCCESS);
1782}
1783
1784static int
1785rum_reconnect(dev_info_t *devinfo)
1786{
1787	struct rum_softc *sc;
1788	int err;
1789
1790	sc = ddi_get_soft_state(rum_soft_state_p, ddi_get_instance(devinfo));
1791	ASSERT(sc != NULL);
1792
1793	/* check device changes after disconnect */
1794	if (usb_check_same_device(sc->sc_dev, NULL, USB_LOG_L2, -1,
1795	    USB_CHK_BASIC | USB_CHK_CFG, NULL) != USB_SUCCESS) {
1796		ral_debug(RAL_DBG_ERR, "different device connected\n");
1797		return (DDI_FAILURE);
1798	}
1799
1800	err = rum_load_microcode(sc);
1801	if (err != USB_SUCCESS) {
1802		ral_debug(RAL_DBG_ERR, "could not load 8051 microcode\n");
1803		goto fail;
1804	}
1805
1806	err = rum_init(sc);
1807fail:
1808	return (err);
1809}
1810
1811static void
1812rum_resume(struct rum_softc *sc)
1813{
1814	int err;
1815
1816	/* check device changes after suspend */
1817	if (usb_check_same_device(sc->sc_dev, NULL, USB_LOG_L2, -1,
1818	    USB_CHK_BASIC | USB_CHK_CFG, NULL) != USB_SUCCESS) {
1819		ral_debug(RAL_DBG_ERR, "no or different device connected\n");
1820		return;
1821	}
1822
1823	err = rum_load_microcode(sc);
1824	if (err != USB_SUCCESS) {
1825		ral_debug(RAL_DBG_ERR, "could not load 8051 microcode\n");
1826		return;
1827	}
1828
1829	(void) rum_init(sc);
1830}
1831
1832#define	RUM_AMRR_MIN_SUCCESS_THRESHOLD	1
1833#define	RUM_AMRR_MAX_SUCCESS_THRESHOLD	10
1834
1835/*
1836 * Naive implementation of the Adaptive Multi Rate Retry algorithm:
1837 * "IEEE 802.11 Rate Adaptation: A Practical Approach"
1838 * Mathieu Lacage, Hossein Manshaei, Thierry Turletti
1839 * INRIA Sophia - Projet Planete
1840 * http://www-sop.inria.fr/rapports/sophia/RR-5208.html
1841 *
1842 * This algorithm is particularly well suited for rum since it does not
1843 * require per-frame retry statistics.  Note however that since h/w does
1844 * not provide per-frame stats, we can't do per-node rate adaptation and
1845 * thus automatic rate adaptation is only enabled in STA operating mode.
1846 */
1847#define	is_success(amrr)	\
1848	((amrr)->retrycnt < (amrr)->txcnt / 10)
1849#define	is_failure(amrr)	\
1850	((amrr)->retrycnt > (amrr)->txcnt / 3)
1851#define	is_enough(amrr)		\
1852	((amrr)->txcnt > 10)
1853#define	is_min_rate(ni)		\
1854	((ni)->in_txrate == 0)
1855#define	is_max_rate(ni)		\
1856	((ni)->in_txrate == (ni)->in_rates.ir_nrates - 1)
1857#define	increase_rate(ni)	\
1858	((ni)->in_txrate++)
1859#define	decrease_rate(ni)	\
1860	((ni)->in_txrate--)
1861#define	reset_cnt(amrr)	do {	\
1862	(amrr)->txcnt = (amrr)->retrycnt = 0;	\
1863	_NOTE(CONSTCOND)	\
1864} while (/* CONSTCOND */0)
1865
1866static void
1867rum_ratectl(struct rum_amrr *amrr, struct ieee80211_node *ni)
1868{
1869	int need_change = 0;
1870
1871	if (is_success(amrr) && is_enough(amrr)) {
1872		amrr->success++;
1873		if (amrr->success >= amrr->success_threshold &&
1874		    !is_max_rate(ni)) {
1875			amrr->recovery = 1;
1876			amrr->success = 0;
1877			increase_rate(ni);
1878			need_change = 1;
1879		} else {
1880			amrr->recovery = 0;
1881		}
1882	} else if (is_failure(amrr)) {
1883		amrr->success = 0;
1884		if (!is_min_rate(ni)) {
1885			if (amrr->recovery) {
1886				amrr->success_threshold *= 2;
1887				if (amrr->success_threshold >
1888				    RUM_AMRR_MAX_SUCCESS_THRESHOLD)
1889					amrr->success_threshold =
1890					    RUM_AMRR_MAX_SUCCESS_THRESHOLD;
1891			} else {
1892				amrr->success_threshold =
1893				    RUM_AMRR_MIN_SUCCESS_THRESHOLD;
1894			}
1895			decrease_rate(ni);
1896			need_change = 1;
1897		}
1898		amrr->recovery = 0;	/* original paper was incorrect */
1899	}
1900
1901	if (is_enough(amrr) || need_change)
1902		reset_cnt(amrr);
1903}
1904
1905static void
1906rum_amrr_timeout(void *arg)
1907{
1908	struct rum_softc *sc = (struct rum_softc *)arg;
1909	struct rum_amrr *amrr = &sc->amrr;
1910
1911	rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof (sc->sta));
1912
1913	/* count TX retry-fail as Tx errors */
1914	sc->sc_tx_err += LE_32(sc->sta[5]) >> 16;
1915	sc->sc_tx_retries += ((LE_32(sc->sta[4]) >> 16) +
1916	    (LE_32(sc->sta[5]) & 0xffff));
1917
1918	amrr->retrycnt =
1919	    (LE_32(sc->sta[4]) >> 16) +		/* TX one-retry ok count */
1920	    (LE_32(sc->sta[5]) & 0xffff) +	/* TX more-retry ok count */
1921	    (LE_32(sc->sta[5]) >> 16);		/* TX retry-fail count */
1922
1923	amrr->txcnt =
1924	    amrr->retrycnt +
1925	    (LE_32(sc->sta[4]) & 0xffff);	/* TX no-retry ok count */
1926
1927	rum_ratectl(amrr, sc->sc_ic.ic_bss);
1928
1929	sc->sc_amrr_id = timeout(rum_amrr_timeout, (void *)sc,
1930	    drv_usectohz(1000 * 1000)); /* 1 second */
1931}
1932
1933static void
1934rum_amrr_start(struct rum_softc *sc, struct ieee80211_node *ni)
1935{
1936	struct rum_amrr *amrr = &sc->amrr;
1937	int i;
1938
1939	/* clear statistic registers (STA_CSR0 to STA_CSR5) */
1940	rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof (sc->sta));
1941
1942	amrr->success = 0;
1943	amrr->recovery = 0;
1944	amrr->txcnt = amrr->retrycnt = 0;
1945	amrr->success_threshold = RUM_AMRR_MIN_SUCCESS_THRESHOLD;
1946
1947	/* set rate to some reasonable initial value */
1948	for (i = ni->in_rates.ir_nrates - 1;
1949	    i > 0 && (ni->in_rates.ir_rates[i] & IEEE80211_RATE_VAL) > 72;
1950	    i--) {
1951	}
1952
1953	ni->in_txrate = i;
1954
1955	sc->sc_amrr_id = timeout(rum_amrr_timeout, (void *)sc,
1956	    drv_usectohz(1000 * 1000)); /* 1 second */
1957}
1958
1959void
1960rum_watchdog(void *arg)
1961{
1962	struct rum_softc *sc = arg;
1963	struct ieee80211com *ic = &sc->sc_ic;
1964	int ntimer = 0;
1965
1966	RAL_LOCK(sc);
1967	ic->ic_watchdog_timer = 0;
1968
1969	if (!RAL_IS_RUNNING(sc)) {
1970		RAL_UNLOCK(sc);
1971		return;
1972	}
1973
1974	if (sc->sc_tx_timer > 0) {
1975		if (--sc->sc_tx_timer == 0) {
1976			ral_debug(RAL_DBG_ERR, "tx timer timeout\n");
1977			RAL_UNLOCK(sc);
1978			(void) rum_init(sc);
1979			(void) ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
1980			return;
1981		}
1982	}
1983
1984	if (ic->ic_state == IEEE80211_S_RUN)
1985		ntimer = 1;
1986
1987	RAL_UNLOCK(sc);
1988
1989	ieee80211_watchdog(ic);
1990
1991	if (ntimer)
1992		ieee80211_start_watchdog(ic, ntimer);
1993}
1994
1995static int
1996rum_m_start(void *arg)
1997{
1998	struct rum_softc *sc = (struct rum_softc *)arg;
1999	int err;
2000
2001	/*
2002	 * initialize RT2501USB hardware
2003	 */
2004	err = rum_init(sc);
2005	if (err != DDI_SUCCESS) {
2006		ral_debug(RAL_DBG_ERR, "device configuration failed\n");
2007		goto fail;
2008	}
2009	sc->sc_flags |= RAL_FLAG_RUNNING;	/* RUNNING */
2010	return (err);
2011
2012fail:
2013	rum_stop(sc);
2014	return (err);
2015}
2016
2017static void
2018rum_m_stop(void *arg)
2019{
2020	struct rum_softc *sc = (struct rum_softc *)arg;
2021
2022	(void) rum_stop(sc);
2023	sc->sc_flags &= ~RAL_FLAG_RUNNING;	/* STOP */
2024}
2025
2026static int
2027rum_m_unicst(void *arg, const uint8_t *macaddr)
2028{
2029	struct rum_softc *sc = (struct rum_softc *)arg;
2030	struct ieee80211com *ic = &sc->sc_ic;
2031
2032	ral_debug(RAL_DBG_MSG, "rum_m_unicst(): " MACSTR "\n",
2033	    MAC2STR(macaddr));
2034
2035	IEEE80211_ADDR_COPY(ic->ic_macaddr, macaddr);
2036	(void) rum_set_macaddr(sc, (uint8_t *)macaddr);
2037	(void) rum_init(sc);
2038
2039	return (0);
2040}
2041
2042/*ARGSUSED*/
2043static int
2044rum_m_multicst(void *arg, boolean_t add, const uint8_t *mca)
2045{
2046	return (0);
2047}
2048
2049static int
2050rum_m_promisc(void *arg, boolean_t on)
2051{
2052	struct rum_softc *sc = (struct rum_softc *)arg;
2053
2054	if (on) {
2055		sc->sc_rcr |= RAL_RCR_PROMISC;
2056		sc->sc_rcr |= RAL_RCR_MULTI;
2057	} else {
2058		sc->sc_rcr &= ~RAL_RCR_PROMISC;
2059		sc->sc_rcr &= ~RAL_RCR_MULTI;
2060	}
2061
2062	rum_update_promisc(sc);
2063	return (0);
2064}
2065
2066/*
2067 * callback functions for /get/set properties
2068 */
2069static int
2070rum_m_setprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num,
2071    uint_t wldp_length, const void *wldp_buf)
2072{
2073	struct rum_softc *sc = (struct rum_softc *)arg;
2074	struct ieee80211com *ic = &sc->sc_ic;
2075	int err;
2076
2077	err = ieee80211_setprop(ic, pr_name, wldp_pr_num,
2078	    wldp_length, wldp_buf);
2079	RAL_LOCK(sc);
2080	if (err == ENETRESET) {
2081		if (RAL_IS_RUNNING(sc)) {
2082			RAL_UNLOCK(sc);
2083			(void) rum_init(sc);
2084			(void) ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
2085			RAL_LOCK(sc);
2086		}
2087		err = 0;
2088	}
2089	RAL_UNLOCK(sc);
2090
2091	return (err);
2092}
2093
2094static int
2095rum_m_getprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num,
2096    uint_t wldp_length, void *wldp_buf)
2097{
2098	struct rum_softc *sc = (struct rum_softc *)arg;
2099	int err;
2100
2101	err = ieee80211_getprop(&sc->sc_ic, pr_name, wldp_pr_num,
2102	    wldp_length, wldp_buf);
2103
2104	return (err);
2105}
2106
2107static void
2108rum_m_propinfo(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num,
2109    mac_prop_info_handle_t prh)
2110{
2111	struct rum_softc *sc = (struct rum_softc *)arg;
2112
2113	ieee80211_propinfo(&sc->sc_ic, pr_name, wldp_pr_num, prh);
2114}
2115
2116static void
2117rum_m_ioctl(void* arg, queue_t *wq, mblk_t *mp)
2118{
2119	struct rum_softc *sc = (struct rum_softc *)arg;
2120	struct ieee80211com *ic = &sc->sc_ic;
2121	int err;
2122
2123	err = ieee80211_ioctl(ic, wq, mp);
2124	RAL_LOCK(sc);
2125	if (err == ENETRESET) {
2126		if (RAL_IS_RUNNING(sc)) {
2127			RAL_UNLOCK(sc);
2128			(void) rum_init(sc);
2129			(void) ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
2130			RAL_LOCK(sc);
2131		}
2132	}
2133	RAL_UNLOCK(sc);
2134}
2135
2136static int
2137rum_m_stat(void *arg, uint_t stat, uint64_t *val)
2138{
2139	struct rum_softc *sc  = (struct rum_softc *)arg;
2140	ieee80211com_t	*ic = &sc->sc_ic;
2141	ieee80211_node_t *ni;
2142	struct ieee80211_rateset *rs;
2143
2144	RAL_LOCK(sc);
2145
2146	ni = ic->ic_bss;
2147	rs = &ni->in_rates;
2148
2149	switch (stat) {
2150	case MAC_STAT_IFSPEED:
2151		*val = ((ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) ?
2152		    (rs->ir_rates[ni->in_txrate] & IEEE80211_RATE_VAL)
2153		    : ic->ic_fixed_rate) * 500000ull;
2154		break;
2155	case MAC_STAT_NOXMTBUF:
2156		*val = sc->sc_tx_nobuf;
2157		break;
2158	case MAC_STAT_NORCVBUF:
2159		*val = sc->sc_rx_nobuf;
2160		break;
2161	case MAC_STAT_IERRORS:
2162		*val = sc->sc_rx_err;
2163		break;
2164	case MAC_STAT_RBYTES:
2165		*val = ic->ic_stats.is_rx_bytes;
2166		break;
2167	case MAC_STAT_IPACKETS:
2168		*val = ic->ic_stats.is_rx_frags;
2169		break;
2170	case MAC_STAT_OBYTES:
2171		*val = ic->ic_stats.is_tx_bytes;
2172		break;
2173	case MAC_STAT_OPACKETS:
2174		*val = ic->ic_stats.is_tx_frags;
2175		break;
2176	case MAC_STAT_OERRORS:
2177	case WIFI_STAT_TX_FAILED:
2178		*val = sc->sc_tx_err;
2179		break;
2180	case WIFI_STAT_TX_RETRANS:
2181		*val = sc->sc_tx_retries;
2182		break;
2183	case WIFI_STAT_FCS_ERRORS:
2184	case WIFI_STAT_WEP_ERRORS:
2185	case WIFI_STAT_TX_FRAGS:
2186	case WIFI_STAT_MCAST_TX:
2187	case WIFI_STAT_RTS_SUCCESS:
2188	case WIFI_STAT_RTS_FAILURE:
2189	case WIFI_STAT_ACK_FAILURE:
2190	case WIFI_STAT_RX_FRAGS:
2191	case WIFI_STAT_MCAST_RX:
2192	case WIFI_STAT_RX_DUPS:
2193		RAL_UNLOCK(sc);
2194		return (ieee80211_stat(ic, stat, val));
2195	default:
2196		RAL_UNLOCK(sc);
2197		return (ENOTSUP);
2198	}
2199	RAL_UNLOCK(sc);
2200
2201	return (0);
2202}
2203
2204static int
2205rum_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd)
2206{
2207	struct rum_softc *sc;
2208	struct ieee80211com *ic;
2209	int err, i, ntries;
2210	uint32_t tmp;
2211	int instance;
2212
2213	char strbuf[32];
2214
2215	wifi_data_t wd = { 0 };
2216	mac_register_t *macp;
2217
2218	switch (cmd) {
2219	case DDI_ATTACH:
2220		break;
2221	case DDI_RESUME:
2222		sc = ddi_get_soft_state(rum_soft_state_p,
2223		    ddi_get_instance(devinfo));
2224		ASSERT(sc != NULL);
2225		rum_resume(sc);
2226		return (DDI_SUCCESS);
2227	default:
2228		return (DDI_FAILURE);
2229	}
2230
2231	instance = ddi_get_instance(devinfo);
2232
2233	if (ddi_soft_state_zalloc(rum_soft_state_p, instance) != DDI_SUCCESS) {
2234		ral_debug(RAL_DBG_MSG, "rum_attach(): "
2235		    "unable to alloc soft_state_p\n");
2236		return (DDI_FAILURE);
2237	}
2238
2239	sc = ddi_get_soft_state(rum_soft_state_p, instance);
2240	ic = (ieee80211com_t *)&sc->sc_ic;
2241	sc->sc_dev = devinfo;
2242
2243	if (usb_client_attach(devinfo, USBDRV_VERSION, 0) != USB_SUCCESS) {
2244		ral_debug(RAL_DBG_ERR,
2245		    "rum_attach(): usb_client_attach failed\n");
2246		goto fail1;
2247	}
2248
2249	if (usb_get_dev_data(devinfo, &sc->sc_udev,
2250	    USB_PARSE_LVL_ALL, 0) != USB_SUCCESS) {
2251		sc->sc_udev = NULL;
2252		goto fail2;
2253	}
2254
2255	mutex_init(&sc->sc_genlock, NULL, MUTEX_DRIVER, NULL);
2256	mutex_init(&sc->tx_lock, NULL, MUTEX_DRIVER, NULL);
2257	mutex_init(&sc->rx_lock, NULL, MUTEX_DRIVER, NULL);
2258
2259	/* retrieve RT2573 rev. no */
2260	for (ntries = 0; ntries < 1000; ntries++) {
2261		if ((tmp = rum_read(sc, RT2573_MAC_CSR0)) != 0)
2262			break;
2263		drv_usecwait(1000);
2264	}
2265	if (ntries == 1000) {
2266		ral_debug(RAL_DBG_ERR,
2267		    "rum_attach(): timeout waiting for chip to settle\n");
2268		goto fail3;
2269	}
2270
2271	/* retrieve MAC address and various other things from EEPROM */
2272	rum_read_eeprom(sc);
2273
2274	ral_debug(RAL_DBG_MSG, "rum: MAC/BBP RT2573 (rev 0x%05x), RF %s\n",
2275	    tmp, rum_get_rf(sc->rf_rev));
2276
2277	err = rum_load_microcode(sc);
2278	if (err != USB_SUCCESS) {
2279		ral_debug(RAL_DBG_ERR, "could not load 8051 microcode\n");
2280		goto fail3;
2281	}
2282
2283	ic->ic_phytype = IEEE80211_T_OFDM;	/* not only, but not used */
2284	ic->ic_opmode = IEEE80211_M_STA;	/* default to BSS mode */
2285	ic->ic_state = IEEE80211_S_INIT;
2286
2287	ic->ic_maxrssi = 63;
2288	ic->ic_set_shortslot = rum_update_slot;
2289	ic->ic_xmit = rum_send;
2290
2291	/* set device capabilities */
2292	ic->ic_caps =
2293	    IEEE80211_C_TXPMGT |	/* tx power management */
2294	    IEEE80211_C_SHPREAMBLE |	/* short preamble supported */
2295	    IEEE80211_C_SHSLOT;		/* short slot time supported */
2296
2297	ic->ic_caps |= IEEE80211_C_WPA; /* Support WPA/WPA2 */
2298
2299#define	IEEE80211_CHAN_A	\
2300	(IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM)
2301
2302	if (sc->rf_rev == RT2573_RF_5225 || sc->rf_rev == RT2573_RF_5226) {
2303		/* set supported .11a rates */
2304		ic->ic_sup_rates[IEEE80211_MODE_11A] = rum_rateset_11a;
2305
2306		/* set supported .11a channels */
2307		for (i = 34; i <= 46; i += 4) {
2308			ic->ic_sup_channels[i].ich_freq =
2309			    ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ);
2310			ic->ic_sup_channels[i].ich_flags = IEEE80211_CHAN_A;
2311		}
2312		for (i = 36; i <= 64; i += 4) {
2313			ic->ic_sup_channels[i].ich_freq =
2314			    ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ);
2315			ic->ic_sup_channels[i].ich_flags = IEEE80211_CHAN_A;
2316		}
2317		for (i = 100; i <= 140; i += 4) {
2318			ic->ic_sup_channels[i].ich_freq =
2319			    ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ);
2320			ic->ic_sup_channels[i].ich_flags = IEEE80211_CHAN_A;
2321		}
2322		for (i = 149; i <= 165; i += 4) {
2323			ic->ic_sup_channels[i].ich_freq =
2324			    ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ);
2325			ic->ic_sup_channels[i].ich_flags = IEEE80211_CHAN_A;
2326		}
2327	}
2328
2329	/* set supported .11b and .11g rates */
2330	ic->ic_sup_rates[IEEE80211_MODE_11B] = rum_rateset_11b;
2331	ic->ic_sup_rates[IEEE80211_MODE_11G] = rum_rateset_11g;
2332
2333	/* set supported .11b and .11g channels (1 through 14) */
2334	for (i = 1; i <= 14; i++) {
2335		ic->ic_sup_channels[i].ich_freq =
2336		    ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
2337		ic->ic_sup_channels[i].ich_flags =
2338		    IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM |
2339		    IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ;
2340	}
2341
2342	ieee80211_attach(ic);
2343
2344	/* register WPA door */
2345	ieee80211_register_door(ic, ddi_driver_name(devinfo),
2346	    ddi_get_instance(devinfo));
2347
2348	/* override state transition machine */
2349	sc->sc_newstate = ic->ic_newstate;
2350	ic->ic_newstate = rum_newstate;
2351	ic->ic_watchdog = rum_watchdog;
2352	ieee80211_media_init(ic);
2353	ic->ic_def_txkey = 0;
2354
2355	sc->sc_rcr = 0;
2356	sc->dwelltime = 300;
2357	sc->sc_flags = 0;
2358
2359	/*
2360	 * Provide initial settings for the WiFi plugin; whenever this
2361	 * information changes, we need to call mac_plugindata_update()
2362	 */
2363	wd.wd_opmode = ic->ic_opmode;
2364	wd.wd_secalloc = WIFI_SEC_NONE;
2365	IEEE80211_ADDR_COPY(wd.wd_bssid, ic->ic_bss->in_bssid);
2366
2367	if ((macp = mac_alloc(MAC_VERSION)) == NULL) {
2368		ral_debug(RAL_DBG_ERR, "rum_attach(): "
2369		    "MAC version mismatch\n");
2370		goto fail3;
2371	}
2372
2373	macp->m_type_ident	= MAC_PLUGIN_IDENT_WIFI;
2374	macp->m_driver		= sc;
2375	macp->m_dip		= devinfo;
2376	macp->m_src_addr	= ic->ic_macaddr;
2377	macp->m_callbacks	= &rum_m_callbacks;
2378	macp->m_min_sdu		= 0;
2379	macp->m_max_sdu		= IEEE80211_MTU;
2380	macp->m_pdata		= &wd;
2381	macp->m_pdata_size	= sizeof (wd);
2382
2383	err = mac_register(macp, &ic->ic_mach);
2384	mac_free(macp);
2385	if (err != 0) {
2386		ral_debug(RAL_DBG_ERR, "rum_attach(): "
2387		    "mac_register() err %x\n", err);
2388		goto fail3;
2389	}
2390
2391	if (usb_register_hotplug_cbs(devinfo, rum_disconnect,
2392	    rum_reconnect) != USB_SUCCESS) {
2393		ral_debug(RAL_DBG_ERR,
2394		    "rum_attach() failed to register events");
2395		goto fail4;
2396	}
2397
2398	/*
2399	 * Create minor node of type DDI_NT_NET_WIFI
2400	 */
2401	(void) snprintf(strbuf, sizeof (strbuf), "%s%d",
2402	    "rum", instance);
2403	err = ddi_create_minor_node(devinfo, strbuf, S_IFCHR,
2404	    instance + 1, DDI_NT_NET_WIFI, 0);
2405
2406	if (err != DDI_SUCCESS)
2407		ral_debug(RAL_DBG_ERR, "ddi_create_minor_node() failed\n");
2408
2409	/*
2410	 * Notify link is down now
2411	 */
2412	mac_link_update(ic->ic_mach, LINK_STATE_DOWN);
2413	return (DDI_SUCCESS);
2414
2415fail4:
2416	(void) mac_unregister(ic->ic_mach);
2417fail3:
2418	mutex_destroy(&sc->sc_genlock);
2419	mutex_destroy(&sc->tx_lock);
2420	mutex_destroy(&sc->rx_lock);
2421fail2:
2422	usb_client_detach(sc->sc_dev, sc->sc_udev);
2423fail1:
2424	ddi_soft_state_free(rum_soft_state_p, ddi_get_instance(devinfo));
2425
2426	return (DDI_FAILURE);
2427}
2428
2429static int
2430rum_detach(dev_info_t *devinfo, ddi_detach_cmd_t cmd)
2431{
2432	struct rum_softc *sc;
2433
2434	sc = ddi_get_soft_state(rum_soft_state_p, ddi_get_instance(devinfo));
2435	ASSERT(sc != NULL);
2436
2437	switch (cmd) {
2438	case DDI_DETACH:
2439		break;
2440	case DDI_SUSPEND:
2441		if (RAL_IS_RUNNING(sc))
2442			(void) rum_stop(sc);
2443		return (DDI_SUCCESS);
2444	default:
2445		return (DDI_FAILURE);
2446	}
2447
2448	rum_stop(sc);
2449	usb_unregister_hotplug_cbs(devinfo);
2450
2451	/*
2452	 * Unregister from the MAC layer subsystem
2453	 */
2454	if (mac_unregister(sc->sc_ic.ic_mach) != 0)
2455		return (DDI_FAILURE);
2456
2457	/*
2458	 * detach ieee80211 layer
2459	 */
2460	ieee80211_detach(&sc->sc_ic);
2461
2462	mutex_destroy(&sc->sc_genlock);
2463	mutex_destroy(&sc->tx_lock);
2464	mutex_destroy(&sc->rx_lock);
2465
2466	/* pipes will be closed in rum_stop() */
2467	usb_client_detach(devinfo, sc->sc_udev);
2468	sc->sc_udev = NULL;
2469
2470	ddi_remove_minor_node(devinfo, NULL);
2471	ddi_soft_state_free(rum_soft_state_p, ddi_get_instance(devinfo));
2472
2473	return (DDI_SUCCESS);
2474}
2475
2476int
2477_info(struct modinfo *modinfop)
2478{
2479	return (mod_info(&modlinkage, modinfop));
2480}
2481
2482int
2483_init(void)
2484{
2485	int status;
2486
2487	status = ddi_soft_state_init(&rum_soft_state_p,
2488	    sizeof (struct rum_softc), 1);
2489	if (status != 0)
2490		return (status);
2491
2492	mac_init_ops(&rum_dev_ops, "rum");
2493	status = mod_install(&modlinkage);
2494	if (status != 0) {
2495		mac_fini_ops(&rum_dev_ops);
2496		ddi_soft_state_fini(&rum_soft_state_p);
2497	}
2498	return (status);
2499}
2500
2501int
2502_fini(void)
2503{
2504	int status;
2505
2506	status = mod_remove(&modlinkage);
2507	if (status == 0) {
2508		mac_fini_ops(&rum_dev_ops);
2509		ddi_soft_state_fini(&rum_soft_state_p);
2510	}
2511	return (status);
2512}
2513