xref: /illumos-gate/usr/src/uts/common/io/rum/rum.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) 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 
46 static 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  */
61 static const struct ieee80211_rateset rum_rateset_11a =
62 	{ 8, { 12, 18, 24, 36, 48, 72, 96, 108 } };
63 
64 static const struct ieee80211_rateset rum_rateset_11b =
65 	{ 4, { 2, 4, 11, 22 } };
66 
67 static const struct ieee80211_rateset rum_rateset_11g =
68 	{ 12, { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 } };
69 
70 static 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 
98 static 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 
130 static 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  */
232 static int rum_attach(dev_info_t *, ddi_attach_cmd_t);
233 static int rum_detach(dev_info_t *, ddi_detach_cmd_t);
234 
235 /*
236  * Module Loading Data & Entry Points
237  */
238 DDI_DEFINE_STREAM_OPS(rum_dev_ops, nulldev, nulldev, rum_attach,
239     rum_detach, nodev, NULL, D_MP, NULL, ddi_quiesce_not_needed);
240 
241 static 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 
247 static struct modlinkage modlinkage = {
248 	MODREV_1,
249 	(void *)&rum_modldrv,
250 	NULL
251 };
252 
253 static int	rum_m_stat(void *,  uint_t, uint64_t *);
254 static int	rum_m_start(void *);
255 static void	rum_m_stop(void *);
256 static int	rum_m_promisc(void *, boolean_t);
257 static int	rum_m_multicst(void *, boolean_t, const uint8_t *);
258 static int	rum_m_unicst(void *, const uint8_t *);
259 static mblk_t	*rum_m_tx(void *, mblk_t *);
260 static void	rum_m_ioctl(void *, queue_t *, mblk_t *);
261 static int	rum_m_setprop(void *, const char *, mac_prop_id_t,
262     uint_t, const void *);
263 static int	rum_m_getprop(void *, const char *, mac_prop_id_t,
264     uint_t, void *);
265 static void	rum_m_propinfo(void *, const char *, mac_prop_id_t,
266     mac_prop_info_handle_t);
267 
268 static 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 
287 static void rum_amrr_start(struct rum_softc *, struct ieee80211_node *);
288 static int  rum_tx_trigger(struct rum_softc *, mblk_t *);
289 static int  rum_rx_trigger(struct rum_softc *);
290 
291 uint32_t rum_dbg_flags = 0;
292 
293 void
ral_debug(uint32_t dbg_flags,const int8_t * fmt,...)294 ral_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 
305 static void
rum_read_multi(struct rum_softc * sc,uint16_t reg,void * buf,int len)306 rum_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 
338 static uint32_t
rum_read(struct rum_softc * sc,uint16_t reg)339 rum_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 
348 static void
rum_write_multi(struct rum_softc * sc,uint16_t reg,void * buf,size_t len)349 rum_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 
386 static void
rum_write(struct rum_softc * sc,uint16_t reg,uint32_t val)387 rum_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 
396 static int
rum_load_microcode(struct rum_softc * sc)397 rum_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 
441 static void
rum_eeprom_read(struct rum_softc * sc,uint16_t addr,void * buf,int len)442 rum_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 */
474 static void
rum_txeof(usb_pipe_handle_t pipe,usb_bulk_req_t * req)475 rum_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 */
505 static void
rum_rxeof(usb_pipe_handle_t pipe,usb_bulk_req_t * req)506 rum_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 
585 fail:
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  */
600 static int
rum_ack_rate(struct ieee80211com * ic,int rate)601 rum_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  */
635 static uint16_t
rum_txtime(int len,int rate,uint32_t flags)636 rum_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 
655 static uint8_t
rum_plcp_signal(int rate)656 rum_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 
680 static void
rum_setup_tx_desc(struct rum_softc * sc,struct rum_tx_desc * desc,uint32_t flags,uint16_t xflags,int len,int rate)681 rum_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 
725 static int
rum_send(ieee80211com_t * ic,mblk_t * mp,uint8_t type)726 rum_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 
875 fail:
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 
889 static mblk_t *
rum_m_tx(void * arg,mblk_t * mp)890 rum_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 
921 static void
rum_bbp_write(struct rum_softc * sc,uint8_t reg,uint8_t val)922 rum_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 
941 static uint8_t
rum_bbp_read(struct rum_softc * sc,uint8_t reg)942 rum_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 
970 static void
rum_rf_write(struct rum_softc * sc,uint8_t reg,uint32_t val)971 rum_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 
996 static void
rum_select_antenna(struct rum_softc * sc)997 rum_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  */
1019 static void
rum_enable_mrr(struct rum_softc * sc)1020 rum_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 
1035 static void
rum_set_txpreamble(struct rum_softc * sc)1036 rum_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 
1049 static void
rum_set_basicrates(struct rum_softc * sc)1050 rum_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  */
1071 static void
rum_select_band(struct rum_softc * sc,struct ieee80211_channel * c)1072 rum_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 
1117 static void
rum_set_chan(struct rum_softc * sc,struct ieee80211_channel * c)1118 rum_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  */
1191 static void
rum_enable_tsf_sync(struct rum_softc * sc)1192 rum_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 */
1220 static void
rum_update_slot(struct ieee80211com * ic,int onoff)1221 rum_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 
1236 static void
rum_set_bssid(struct rum_softc * sc,const uint8_t * bssid)1237 rum_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 
1248 static void
rum_set_macaddr(struct rum_softc * sc,const uint8_t * addr)1249 rum_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 
1263 static void
rum_update_promisc(struct rum_softc * sc)1264 rum_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 
1280 static const char *
rum_get_rf(int rev)1281 rum_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 
1292 static void
rum_read_eeprom(struct rum_softc * sc)1293 rum_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 
1348 static int
rum_bbp_init(struct rum_softc * sc)1349 rum_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  */
1383 static void
rum_next_scan(void * arg)1384 rum_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 
1393 static int
rum_newstate(struct ieee80211com * ic,enum ieee80211_state nstate,int arg)1394 rum_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 
1474 static void
rum_close_pipes(struct rum_softc * sc)1475 rum_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 
1492 static int
rum_open_pipes(struct rum_softc * sc)1493 rum_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 
1529 fail:
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 
1545 static int
rum_tx_trigger(struct rum_softc * sc,mblk_t * mp)1546 rum_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 
1585 static int
rum_rx_trigger(struct rum_softc * sc)1586 rum_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 
1625 static void
rum_init_tx_queue(struct rum_softc * sc)1626 rum_init_tx_queue(struct rum_softc *sc)
1627 {
1628 	sc->tx_queued = 0;
1629 }
1630 
1631 static int
rum_init_rx_queue(struct rum_softc * sc)1632 rum_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 
1647 static void
rum_stop(struct rum_softc * sc)1648 rum_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 
1674 static int
rum_init(struct rum_softc * sc)1675 rum_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);
1747 fail:
1748 	rum_stop(sc);
1749 	return (DDI_FAILURE);
1750 }
1751 
1752 static int
rum_disconnect(dev_info_t * devinfo)1753 rum_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 
1784 static int
rum_reconnect(dev_info_t * devinfo)1785 rum_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);
1807 fail:
1808 	return (err);
1809 }
1810 
1811 static void
rum_resume(struct rum_softc * sc)1812 rum_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 
1866 static void
rum_ratectl(struct rum_amrr * amrr,struct ieee80211_node * ni)1867 rum_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 
1905 static void
rum_amrr_timeout(void * arg)1906 rum_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 
1933 static void
rum_amrr_start(struct rum_softc * sc,struct ieee80211_node * ni)1934 rum_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 
1959 void
rum_watchdog(void * arg)1960 rum_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 
1995 static int
rum_m_start(void * arg)1996 rum_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 
2012 fail:
2013 	rum_stop(sc);
2014 	return (err);
2015 }
2016 
2017 static void
rum_m_stop(void * arg)2018 rum_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 
2026 static int
rum_m_unicst(void * arg,const uint8_t * macaddr)2027 rum_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*/
2043 static int
rum_m_multicst(void * arg,boolean_t add,const uint8_t * mca)2044 rum_m_multicst(void *arg, boolean_t add, const uint8_t *mca)
2045 {
2046 	return (0);
2047 }
2048 
2049 static int
rum_m_promisc(void * arg,boolean_t on)2050 rum_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  */
2069 static int
rum_m_setprop(void * arg,const char * pr_name,mac_prop_id_t wldp_pr_num,uint_t wldp_length,const void * wldp_buf)2070 rum_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 
2094 static int
rum_m_getprop(void * arg,const char * pr_name,mac_prop_id_t wldp_pr_num,uint_t wldp_length,void * wldp_buf)2095 rum_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 
2107 static void
rum_m_propinfo(void * arg,const char * pr_name,mac_prop_id_t wldp_pr_num,mac_prop_info_handle_t prh)2108 rum_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 
2116 static void
rum_m_ioctl(void * arg,queue_t * wq,mblk_t * mp)2117 rum_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 
2136 static int
rum_m_stat(void * arg,uint_t stat,uint64_t * val)2137 rum_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 
2204 static int
rum_attach(dev_info_t * devinfo,ddi_attach_cmd_t cmd)2205 rum_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 
2415 fail4:
2416 	(void) mac_unregister(ic->ic_mach);
2417 fail3:
2418 	mutex_destroy(&sc->sc_genlock);
2419 	mutex_destroy(&sc->tx_lock);
2420 	mutex_destroy(&sc->rx_lock);
2421 fail2:
2422 	usb_client_detach(sc->sc_dev, sc->sc_udev);
2423 fail1:
2424 	ddi_soft_state_free(rum_soft_state_p, ddi_get_instance(devinfo));
2425 
2426 	return (DDI_FAILURE);
2427 }
2428 
2429 static int
rum_detach(dev_info_t * devinfo,ddi_detach_cmd_t cmd)2430 rum_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 
2476 int
_info(struct modinfo * modinfop)2477 _info(struct modinfo *modinfop)
2478 {
2479 	return (mod_info(&modlinkage, modinfop));
2480 }
2481 
2482 int
_init(void)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 
2501 int
_fini(void)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