xref: /illumos-gate/usr/src/uts/common/io/urtw/urtw.c (revision 581cede61ac9c14d8d4ea452562a567189eead78)
1 /*
2  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 /*
7  * Copyright (c) 2008 Weongyo Jeong
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer,
15  *    without modification.
16  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
17  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
18  *    redistribution must be conditioned upon including a substantially
19  *    similar Disclaimer requirement for further binary redistribution.
20  *
21  * NO WARRANTY
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
25  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
26  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
27  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
30  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32  * THE POSSIBILITY OF SUCH DAMAGES.
33  */
34 #include <sys/sysmacros.h>
35 #include <sys/strsubr.h>
36 #include <sys/strsun.h>
37 #include <sys/mac_provider.h>
38 #include <sys/mac_wifi.h>
39 #include <sys/net80211.h>
40 #define	USBDRV_MAJOR_VER	2
41 #define	USBDRV_MINOR_VER	0
42 #include <sys/usb/usba.h>
43 #include <sys/usb/usba/usba_types.h>
44 
45 #include "urtw_reg.h"
46 #include "urtw_var.h"
47 
48 static void *urtw_soft_state_p = NULL;
49 
50 #define	URTW_TXBUF_SIZE  	(IEEE80211_MAX_LEN)
51 #define	URTW_RXBUF_SIZE  	(URTW_TXBUF_SIZE)
52 /*
53  * device operations
54  */
55 static int urtw_attach(dev_info_t *, ddi_attach_cmd_t);
56 static int urtw_detach(dev_info_t *, ddi_detach_cmd_t);
57 
58 /*
59  * Module Loading Data & Entry Points
60  */
61 DDI_DEFINE_STREAM_OPS(urtw_dev_ops, nulldev, nulldev, urtw_attach,
62     urtw_detach, nodev, NULL, D_MP, NULL, ddi_quiesce_not_needed);
63 
64 static struct modldrv urtw_modldrv = {
65 	&mod_driverops,		/* Type of module.  This one is a driver */
66 	"RTL8187L/B driver v1.2",	/* short description */
67 	&urtw_dev_ops		/* driver specific ops */
68 };
69 
70 static struct modlinkage modlinkage = {
71 	MODREV_1,
72 	(void *)&urtw_modldrv,
73 	NULL
74 };
75 
76 static int	urtw_m_stat(void *,  uint_t, uint64_t *);
77 static int	urtw_m_start(void *);
78 static void	urtw_m_stop(void *);
79 static int	urtw_m_promisc(void *, boolean_t);
80 static int	urtw_m_multicst(void *, boolean_t, const uint8_t *);
81 static int	urtw_m_unicst(void *, const uint8_t *);
82 static mblk_t	*urtw_m_tx(void *, mblk_t *);
83 static void	urtw_m_ioctl(void *, queue_t *, mblk_t *);
84 static int	urtw_m_setprop(void *, const char *, mac_prop_id_t,
85     uint_t, const void *);
86 static int urtw_m_getprop(void *, const char *, mac_prop_id_t,
87     uint_t, uint_t, void *, uint_t *);
88 
89 static mac_callbacks_t urtw_m_callbacks = {
90 	MC_IOCTL | MC_SETPROP | MC_GETPROP,
91 	urtw_m_stat,
92 	urtw_m_start,
93 	urtw_m_stop,
94 	urtw_m_promisc,
95 	urtw_m_multicst,
96 	urtw_m_unicst,
97 	urtw_m_tx,
98 	urtw_m_ioctl,
99 	NULL,
100 	NULL,
101 	NULL,
102 	urtw_m_setprop,
103 	urtw_m_getprop
104 };
105 
106 static int  urtw_tx_start(struct urtw_softc *, mblk_t *, int);
107 static int  urtw_rx_start(struct urtw_softc *);
108 
109 
110 /*
111  * Supported rates for 802.11b/g modes (in 500Kbps unit).
112  */
113 static const struct ieee80211_rateset urtw_rateset_11b =
114 	{ 4, { 2, 4, 11, 22 } };
115 
116 static const struct ieee80211_rateset urtw_rateset_11g =
117 	{ 12, { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 } };
118 
119 #define	USB_VENDOR_DICKSMITH	0x1371		/* Dick Smith Electronics */
120 #define	USB_VENDOR_LOGITEC	0x0789		/* Logitec */
121 #define	USB_VENDOR_NETGEAR	0x0846		/* BayNETGEAR */
122 #define	USB_VENDOR_REALTEK	0x0bda		/* Realtek */
123 #define	USB_VENDOR_SPHAIRON	0x114b		/* Sphairon Access Systems */
124 #define	USB_VENDOR_SURECOM	0x0769		/* Surecom Technology */
125 #define	USB_VENDOR_BELKIN	0x050d		/* Belkin Components */
126 #define	USB_VENDOR_SITECOMEU	0x0df6		/* Sitecom Europe */
127 
128 #define	USB_PRODUCT_SPHAIRON_RTL8187	0x0150		/* RTL8187 */
129 #define	USB_PRODUCT_DICKSMITH_RTL8187	0x9401		/* RTL8187 */
130 #define	USB_PRODUCT_LOGITEC_RTL8187	0x010c		/* RTL8187 */
131 #define	USB_PRODUCT_REALTEK_RTL8187	0x8187		/* RTL8187 */
132 #define	USB_PRODUCT_NETGEAR_WG111V2	0x6a00		/* WG111v2 */
133 #define	USB_PRODUCT_SURECOM_EP9001G2A	0x11f2		/* EP-9001-G rev 2A */
134 #define	USB_PRODUCT_BELKIN_F5D7050E	0x705e		/* F5D705E 54g */
135 #define	USB_PRODUCT_NETGEAR_WG111V3	0x4260		/* WG111v3 */
136 #define	USB_PRODUCT_REALTEK_RTL8187B_0	0x8189		/* RTL8187B */
137 #define	USB_PRODUCT_REALTEK_RTL8187B_1	0x8197		/* RTL8187B */
138 #define	USB_PRODUCT_REALTEK_RTL8187B_2	0x8198		/* RTL8187B */
139 #define	USB_PRODUCT_SITECOMEU_WL168	0x0028		/* WL-168 */
140 
141 #define	USB_PRODUCT_ANY	0xffff
142 
143 struct usb_devno {
144 	uint16_t v;
145 	uint16_t p;
146 };
147 
148 /*
149  * Recognized device vendors/products.
150  */
151 static struct urtw_type {
152 	struct usb_devno	dev;
153 	uint8_t			rev;
154 } urtw_devs[] = {
155 #define	URTW_DEV_RTL8187(v, p)	\
156 	    { { USB_VENDOR_##v, USB_PRODUCT_##v##_##p }, URTW_HWREV_8187 }
157 #define	URTW_DEV_RTL8187B(v, p)	\
158 	    { { USB_VENDOR_##v, USB_PRODUCT_##v##_##p }, URTW_HWREV_8187B }
159 	/* Realtek RTL8187 devices. */
160 	URTW_DEV_RTL8187(DICKSMITH,	RTL8187),
161 	URTW_DEV_RTL8187(LOGITEC,	RTL8187),
162 	URTW_DEV_RTL8187(NETGEAR,	WG111V2),
163 	URTW_DEV_RTL8187(REALTEK,	RTL8187),
164 	URTW_DEV_RTL8187(SPHAIRON,	RTL8187),
165 	URTW_DEV_RTL8187(SURECOM,	EP9001G2A),
166 	/* Realtek RTL8187B devices. */
167 	URTW_DEV_RTL8187B(BELKIN,	F5D7050E),
168 	URTW_DEV_RTL8187B(NETGEAR,	WG111V3),
169 	URTW_DEV_RTL8187B(REALTEK,	RTL8187B_0),
170 	URTW_DEV_RTL8187B(REALTEK,	RTL8187B_1),
171 	URTW_DEV_RTL8187B(REALTEK,	RTL8187B_2),
172 	URTW_DEV_RTL8187B(SITECOMEU,	WL168)
173 #undef	URTW_DEV_RTL8187
174 #undef	URTW_DEV_RTL8187B
175 };
176 
177 /*
178  * Search for a vendor/product pair in an array.  The item size is
179  * given as an argument.
180  */
181 struct urtw_type *
182 usb_match_device(struct urtw_type *tbl, uint32_t nentries,
183 	uint16_t vendor, uint16_t product)
184 {
185 	while (nentries-- > 0) {
186 		uint16_t tproduct = tbl[nentries].dev.p;
187 		if (tbl[nentries].dev.v == vendor &&
188 		    (tproduct == product || tproduct == USB_PRODUCT_ANY))
189 		return (&tbl[nentries]);
190 	}
191 	return (NULL);
192 }
193 
194 #define	usb_lookup(tbl, vendor, product) \
195 	usb_match_device(tbl, sizeof (tbl) / sizeof ((tbl)[0]), \
196 		(vendor), (product))
197 
198 #define	urtw_lookup(v, p)	(usb_lookup(urtw_devs, v, p))
199 
200 struct urtw_pair {
201 	uint32_t	reg;
202 	uint32_t	val;
203 };
204 
205 struct urtw_pair_idx {
206 	uint8_t		reg;
207 	uint8_t		val;
208 	uint8_t		idx;
209 };
210 
211 static struct urtw_pair_idx urtw_8187b_regtbl[] = {
212 	{ 0xf0, 0x32, 0 }, { 0xf1, 0x32, 0 }, { 0xf2, 0x00, 0 },
213 	{ 0xf3, 0x00, 0 }, { 0xf4, 0x32, 0 }, { 0xf5, 0x43, 0 },
214 	{ 0xf6, 0x00, 0 }, { 0xf7, 0x00, 0 }, { 0xf8, 0x46, 0 },
215 	{ 0xf9, 0xa4, 0 }, { 0xfa, 0x00, 0 }, { 0xfb, 0x00, 0 },
216 	{ 0xfc, 0x96, 0 }, { 0xfd, 0xa4, 0 }, { 0xfe, 0x00, 0 },
217 	{ 0xff, 0x00, 0 },
218 
219 	{ 0x58, 0x4b, 1 }, { 0x59, 0x00, 1 }, { 0x5a, 0x4b, 1 },
220 	{ 0x5b, 0x00, 1 }, { 0x60, 0x4b, 1 }, { 0x61, 0x09, 1 },
221 	{ 0x62, 0x4b, 1 }, { 0x63, 0x09, 1 }, { 0xce, 0x0f, 1 },
222 	{ 0xcf, 0x00, 1 }, { 0xe0, 0xff, 1 }, { 0xe1, 0x0f, 1 },
223 	{ 0xe2, 0x00, 1 }, { 0xf0, 0x4e, 1 }, { 0xf1, 0x01, 1 },
224 	{ 0xf2, 0x02, 1 }, { 0xf3, 0x03, 1 }, { 0xf4, 0x04, 1 },
225 	{ 0xf5, 0x05, 1 }, { 0xf6, 0x06, 1 }, { 0xf7, 0x07, 1 },
226 	{ 0xf8, 0x08, 1 },
227 
228 	{ 0x4e, 0x00, 2 }, { 0x0c, 0x04, 2 }, { 0x21, 0x61, 2 },
229 	{ 0x22, 0x68, 2 }, { 0x23, 0x6f, 2 }, { 0x24, 0x76, 2 },
230 	{ 0x25, 0x7d, 2 }, { 0x26, 0x84, 2 }, { 0x27, 0x8d, 2 },
231 	{ 0x4d, 0x08, 2 }, { 0x50, 0x05, 2 }, { 0x51, 0xf5, 2 },
232 	{ 0x52, 0x04, 2 }, { 0x53, 0xa0, 2 }, { 0x54, 0x1f, 2 },
233 	{ 0x55, 0x23, 2 }, { 0x56, 0x45, 2 }, { 0x57, 0x67, 2 },
234 	{ 0x58, 0x08, 2 }, { 0x59, 0x08, 2 }, { 0x5a, 0x08, 2 },
235 	{ 0x5b, 0x08, 2 }, { 0x60, 0x08, 2 }, { 0x61, 0x08, 2 },
236 	{ 0x62, 0x08, 2 }, { 0x63, 0x08, 2 }, { 0x64, 0xcf, 2 },
237 	{ 0x72, 0x56, 2 }, { 0x73, 0x9a, 2 },
238 
239 	{ 0x34, 0xf0, 0 }, { 0x35, 0x0f, 0 }, { 0x5b, 0x40, 0 },
240 	{ 0x84, 0x88, 0 }, { 0x85, 0x24, 0 }, { 0x88, 0x54, 0 },
241 	{ 0x8b, 0xb8, 0 }, { 0x8c, 0x07, 0 }, { 0x8d, 0x00, 0 },
242 	{ 0x94, 0x1b, 0 }, { 0x95, 0x12, 0 }, { 0x96, 0x00, 0 },
243 	{ 0x97, 0x06, 0 }, { 0x9d, 0x1a, 0 }, { 0x9f, 0x10, 0 },
244 	{ 0xb4, 0x22, 0 }, { 0xbe, 0x80, 0 }, { 0xdb, 0x00, 0 },
245 	{ 0xee, 0x00, 0 }, { 0x91, 0x03, 0 },
246 
247 	{ 0x4c, 0x00, 2 }, { 0x9f, 0x00, 3 }, { 0x8c, 0x01, 0 },
248 	{ 0x8d, 0x10, 0 }, { 0x8e, 0x08, 0 }, { 0x8f, 0x00, 0 }
249 };
250 
251 static uint8_t urtw_8225_agc[] = {
252 	0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9d, 0x9c, 0x9b,
253 	0x9a, 0x99, 0x98, 0x97, 0x96, 0x95, 0x94, 0x93, 0x92, 0x91, 0x90,
254 	0x8f, 0x8e, 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86, 0x85,
255 	0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a,
256 	0x39, 0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f,
257 	0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24,
258 	0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19,
259 	0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e,
260 	0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03,
261 	0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
262 	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
263 	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
264 };
265 
266 static uint8_t urtw_8225v2_agc[] = {
267 	0x5e, 0x5e, 0x5e, 0x5e, 0x5d, 0x5b, 0x59, 0x57,
268 	0x55, 0x53, 0x51, 0x4f, 0x4d, 0x4b, 0x49, 0x47,
269 	0x45, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x39, 0x37,
270 	0x35, 0x33, 0x31, 0x2f, 0x2d, 0x2b, 0x29, 0x27,
271 	0x25, 0x23, 0x21, 0x1f, 0x1d, 0x1b, 0x19, 0x17,
272 	0x15, 0x13, 0x11, 0x0f, 0x0d, 0x0b, 0x09, 0x07,
273 	0x05, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
274 	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
275 	0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
276 	0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,
277 	0x26, 0x27, 0x27, 0x28, 0x28, 0x29, 0x2a, 0x2a,
278 	0x2a, 0x2b, 0x2b, 0x2b, 0x2c, 0x2c, 0x2c, 0x2d,
279 	0x2d, 0x2d, 0x2d, 0x2e, 0x2e, 0x2e, 0x2e, 0x2f,
280 	0x2f, 0x2f, 0x30, 0x30, 0x31, 0x31, 0x31, 0x31,
281 	0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
282 	0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31
283 };
284 
285 static uint8_t urtw_8225v2_ofdm[] = {
286 	0x10, 0x0d, 0x01, 0x00, 0x14, 0xfb, 0xfb, 0x60,
287 	0x00, 0x60, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00,
288 	0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0xa8, 0x26,
289 	0x32, 0x33, 0x07, 0xa5, 0x6f, 0x55, 0xc8, 0xb3,
290 	0x0a, 0xe1, 0x2c, 0x8a, 0x86, 0x83, 0x34, 0x0f,
291 	0x4f, 0x24, 0x6f, 0xc2, 0x6b, 0x40, 0x80, 0x00,
292 	0xc0, 0xc1, 0x58, 0xf1, 0x00, 0xe4, 0x90, 0x3e,
293 	0x6d, 0x3c, 0xfb, 0x07
294 };
295 
296 static uint32_t urtw_8225_channel[] = {
297 	0x0000,		/* dummy channel 0  */
298 	0x085c,		/* 1  */
299 	0x08dc,		/* 2  */
300 	0x095c,		/* 3  */
301 	0x09dc,		/* 4  */
302 	0x0a5c,		/* 5  */
303 	0x0adc,		/* 6  */
304 	0x0b5c,		/* 7  */
305 	0x0bdc,		/* 8  */
306 	0x0c5c,		/* 9  */
307 	0x0cdc,		/* 10  */
308 	0x0d5c,		/* 11  */
309 	0x0ddc,		/* 12  */
310 	0x0e5c,		/* 13  */
311 	0x0f72,		/* 14  */
312 };
313 
314 static uint8_t urtw_8225_gain[] = {
315 	0x23, 0x88, 0x7c, 0xa5,		/* -82dbm  */
316 	0x23, 0x88, 0x7c, 0xb5,		/* -82dbm  */
317 	0x23, 0x88, 0x7c, 0xc5,		/* -82dbm  */
318 	0x33, 0x80, 0x79, 0xc5,		/* -78dbm  */
319 	0x43, 0x78, 0x76, 0xc5,		/* -74dbm  */
320 	0x53, 0x60, 0x73, 0xc5,		/* -70dbm  */
321 	0x63, 0x58, 0x70, 0xc5,		/* -66dbm  */
322 };
323 
324 static struct urtw_pair urtw_8225_rf_part1[] = {
325 	{ 0x00, 0x0067 }, { 0x01, 0x0fe0 }, { 0x02, 0x044d }, { 0x03, 0x0441 },
326 	{ 0x04, 0x0486 }, { 0x05, 0x0bc0 }, { 0x06, 0x0ae6 }, { 0x07, 0x082a },
327 	{ 0x08, 0x001f }, { 0x09, 0x0334 }, { 0x0a, 0x0fd4 }, { 0x0b, 0x0391 },
328 	{ 0x0c, 0x0050 }, { 0x0d, 0x06db }, { 0x0e, 0x0029 }, { 0x0f, 0x0914 },
329 };
330 
331 static struct urtw_pair urtw_8225_rf_part2[] = {
332 	{ 0x00, 0x01 }, { 0x01, 0x02 }, { 0x02, 0x42 }, { 0x03, 0x00 },
333 	{ 0x04, 0x00 }, { 0x05, 0x00 }, { 0x06, 0x40 }, { 0x07, 0x00 },
334 	{ 0x08, 0x40 }, { 0x09, 0xfe }, { 0x0a, 0x09 }, { 0x0b, 0x80 },
335 	{ 0x0c, 0x01 }, { 0x0e, 0xd3 }, { 0x0f, 0x38 }, { 0x10, 0x84 },
336 	{ 0x11, 0x06 }, { 0x12, 0x20 }, { 0x13, 0x20 }, { 0x14, 0x00 },
337 	{ 0x15, 0x40 }, { 0x16, 0x00 }, { 0x17, 0x40 }, { 0x18, 0xef },
338 	{ 0x19, 0x19 }, { 0x1a, 0x20 }, { 0x1b, 0x76 }, { 0x1c, 0x04 },
339 	{ 0x1e, 0x95 }, { 0x1f, 0x75 }, { 0x20, 0x1f }, { 0x21, 0x27 },
340 	{ 0x22, 0x16 }, { 0x24, 0x46 }, { 0x25, 0x20 }, { 0x26, 0x90 },
341 	{ 0x27, 0x88 }
342 };
343 
344 static struct urtw_pair urtw_8225_rf_part3[] = {
345 	{ 0x00, 0x98 }, { 0x03, 0x20 }, { 0x04, 0x7e }, { 0x05, 0x12 },
346 	{ 0x06, 0xfc }, { 0x07, 0x78 }, { 0x08, 0x2e }, { 0x10, 0x9b },
347 	{ 0x11, 0x88 }, { 0x12, 0x47 }, { 0x13, 0xd0 }, { 0x19, 0x00 },
348 	{ 0x1a, 0xa0 }, { 0x1b, 0x08 }, { 0x40, 0x86 }, { 0x41, 0x8d },
349 	{ 0x42, 0x15 }, { 0x43, 0x18 }, { 0x44, 0x1f }, { 0x45, 0x1e },
350 	{ 0x46, 0x1a }, { 0x47, 0x15 }, { 0x48, 0x10 }, { 0x49, 0x0a },
351 	{ 0x4a, 0x05 }, { 0x4b, 0x02 }, { 0x4c, 0x05 }
352 };
353 
354 static uint16_t urtw_8225_rxgain[] = {
355 	0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
356 	0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
357 	0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
358 	0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
359 	0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
360 	0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
361 	0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
362 	0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
363 	0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
364 	0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
365 	0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3,
366 	0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb
367 };
368 
369 static uint8_t urtw_8225_threshold[] = {
370 	0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd,
371 };
372 
373 static uint8_t urtw_8225_tx_gain_cck_ofdm[] = {
374 	0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e
375 };
376 
377 static uint8_t urtw_8225_txpwr_cck[] = {
378 	0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02,
379 	0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02,
380 	0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02,
381 	0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02,
382 	0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03,
383 	0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03
384 };
385 
386 static uint8_t urtw_8225_txpwr_cck_ch14[] = {
387 	0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00,
388 	0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00,
389 	0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00,
390 	0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00,
391 	0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00,
392 	0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00
393 };
394 
395 static uint8_t urtw_8225_txpwr_ofdm[] = {
396 	0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4
397 };
398 
399 static uint8_t urtw_8225v2_gain_bg[] = {
400 	0x23, 0x15, 0xa5,		/* -82-1dbm  */
401 	0x23, 0x15, 0xb5,		/* -82-2dbm  */
402 	0x23, 0x15, 0xc5,		/* -82-3dbm  */
403 	0x33, 0x15, 0xc5,		/* -78dbm  */
404 	0x43, 0x15, 0xc5,		/* -74dbm  */
405 	0x53, 0x15, 0xc5,		/* -70dbm  */
406 	0x63, 0x15, 0xc5,		/* -66dbm  */
407 };
408 
409 static struct urtw_pair urtw_8225v2_rf_part1[] = {
410 	{ 0x00, 0x02bf }, { 0x01, 0x0ee0 }, { 0x02, 0x044d }, { 0x03, 0x0441 },
411 	{ 0x04, 0x08c3 }, { 0x05, 0x0c72 }, { 0x06, 0x00e6 }, { 0x07, 0x082a },
412 	{ 0x08, 0x003f }, { 0x09, 0x0335 }, { 0x0a, 0x09d4 }, { 0x0b, 0x07bb },
413 	{ 0x0c, 0x0850 }, { 0x0d, 0x0cdf }, { 0x0e, 0x002b }, { 0x0f, 0x0114 }
414 };
415 
416 static struct urtw_pair urtw_8225v2_rf_part2[] = {
417 	{ 0x00, 0x01 }, { 0x01, 0x02 }, { 0x02, 0x42 }, { 0x03, 0x00 },
418 	{ 0x04, 0x00 },	{ 0x05, 0x00 }, { 0x06, 0x40 }, { 0x07, 0x00 },
419 	{ 0x08, 0x40 }, { 0x09, 0xfe }, { 0x0a, 0x08 }, { 0x0b, 0x80 },
420 	{ 0x0c, 0x01 }, { 0x0d, 0x43 }, { 0x0e, 0xd3 }, { 0x0f, 0x38 },
421 	{ 0x10, 0x84 }, { 0x11, 0x07 }, { 0x12, 0x20 }, { 0x13, 0x20 },
422 	{ 0x14, 0x00 }, { 0x15, 0x40 }, { 0x16, 0x00 }, { 0x17, 0x40 },
423 	{ 0x18, 0xef }, { 0x19, 0x19 }, { 0x1a, 0x20 }, { 0x1b, 0x15 },
424 	{ 0x1c, 0x04 }, { 0x1d, 0xc5 }, { 0x1e, 0x95 }, { 0x1f, 0x75 },
425 	{ 0x20, 0x1f }, { 0x21, 0x17 }, { 0x22, 0x16 }, { 0x23, 0x80 },
426 	{ 0x24, 0x46 }, { 0x25, 0x00 }, { 0x26, 0x90 }, { 0x27, 0x88 }
427 };
428 
429 static struct urtw_pair urtw_8225v2_rf_part3[] = {
430 	{ 0x00, 0x98 }, { 0x03, 0x20 }, { 0x04, 0x7e }, { 0x05, 0x12 },
431 	{ 0x06, 0xfc }, { 0x07, 0x78 }, { 0x08, 0x2e }, { 0x09, 0x11 },
432 	{ 0x0a, 0x17 }, { 0x0b, 0x11 }, { 0x10, 0x9b }, { 0x11, 0x88 },
433 	{ 0x12, 0x47 }, { 0x13, 0xd0 }, { 0x19, 0x00 }, { 0x1a, 0xa0 },
434 	{ 0x1b, 0x08 }, { 0x1d, 0x00 }, { 0x40, 0x86 }, { 0x41, 0x9d },
435 	{ 0x42, 0x15 }, { 0x43, 0x18 }, { 0x44, 0x36 }, { 0x45, 0x35 },
436 	{ 0x46, 0x2e }, { 0x47, 0x25 }, { 0x48, 0x1c }, { 0x49, 0x12 },
437 	{ 0x4a, 0x09 }, { 0x4b, 0x04 }, { 0x4c, 0x05 }
438 };
439 
440 static uint16_t urtw_8225v2_rxgain[] = {
441 	0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
442 	0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
443 	0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
444 	0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
445 	0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
446 	0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
447 	0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
448 	0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
449 	0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
450 	0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
451 	0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
452 	0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
453 };
454 
455 static uint8_t urtw_8225v2_tx_gain_cck_ofdm[] = {
456 	0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
457 	0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
458 	0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
459 	0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
460 	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
461 	0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
462 };
463 
464 static uint8_t urtw_8225v2_txpwr_cck[] = {
465 	0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04,
466 	0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03,
467 	0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03,
468 	0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03
469 };
470 
471 static uint8_t urtw_8225v2_txpwr_cck_ch14[] = {
472 	0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00,
473 	0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
474 	0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
475 	0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00
476 };
477 
478 static struct urtw_pair urtw_8225v2_b_rf[] = {
479 	{ 0x00, 0x00b7 }, { 0x01, 0x0ee0 }, { 0x02, 0x044d }, { 0x03, 0x0441 },
480 	{ 0x04, 0x08c3 }, { 0x05, 0x0c72 }, { 0x06, 0x00e6 }, { 0x07, 0x082a },
481 	{ 0x08, 0x003f }, { 0x09, 0x0335 }, { 0x0a, 0x09d4 }, { 0x0b, 0x07bb },
482 	{ 0x0c, 0x0850 }, { 0x0d, 0x0cdf }, { 0x0e, 0x002b }, { 0x0f, 0x0114 },
483 	{ 0x00, 0x01b7 }
484 };
485 
486 static struct urtw_pair urtw_ratetable[] = {
487 	{  2,  0 }, {   4,  1 }, { 11, 2 }, { 12, 4 }, { 18, 5 },
488 	{ 22,  3 }, {  24,  6 }, { 36, 7 }, { 48, 8 }, { 72, 9 },
489 	{ 96, 10 }, { 108, 11 }
490 };
491 
492 static int		urtw_8187_init(void *);
493 static void		urtw_stop(struct urtw_softc *);
494 static int		urtw_set_channel(struct urtw_softc *);
495 static void
496 urtw_rxeof(usb_pipe_handle_t, usb_bulk_req_t *);
497 static int
498 urtw_newstate(struct ieee80211com *, enum ieee80211_state, int);
499 static usbd_status
500 urtw_read8_c(struct urtw_softc *, int, uint8_t *, uint8_t);
501 static usbd_status
502 urtw_read16_c(struct urtw_softc *, int, uint16_t *, uint8_t);
503 static usbd_status
504 urtw_read32_c(struct urtw_softc *, int, uint32_t *, uint8_t);
505 static usbd_status
506 urtw_write8_c(struct urtw_softc *, int, uint8_t, uint8_t);
507 static usbd_status
508 urtw_write16_c(struct urtw_softc *, int, uint16_t, uint8_t);
509 static usbd_status
510 urtw_write32_c(struct urtw_softc *, int, uint32_t, uint8_t);
511 static usbd_status	urtw_eprom_cs(struct urtw_softc *, int);
512 static usbd_status	urtw_eprom_ck(struct urtw_softc *);
513 static usbd_status	urtw_eprom_sendbits(struct urtw_softc *, int16_t *,
514 			    int);
515 static usbd_status	urtw_eprom_read32(struct urtw_softc *, uint32_t,
516 			    uint32_t *);
517 static usbd_status	urtw_eprom_readbit(struct urtw_softc *, int16_t *);
518 static usbd_status	urtw_eprom_writebit(struct urtw_softc *, int16_t);
519 static usbd_status	urtw_get_macaddr(struct urtw_softc *);
520 static usbd_status	urtw_get_txpwr(struct urtw_softc *);
521 static usbd_status	urtw_get_rfchip(struct urtw_softc *);
522 static usbd_status	urtw_led_init(struct urtw_softc *);
523 static usbd_status
524 urtw_8225_read(struct urtw_softc *, uint8_t, uint32_t *);
525 static usbd_status	urtw_8225_rf_init(struct urtw_rf *);
526 static usbd_status	urtw_8225_rf_set_chan(struct urtw_rf *, int);
527 static usbd_status	urtw_8225_rf_set_sens(struct urtw_rf *);
528 static usbd_status	urtw_8225v2_rf_init(struct urtw_rf *);
529 static usbd_status	urtw_8225v2_rf_set_chan(struct urtw_rf *, int);
530 static usbd_status	urtw_open_pipes(struct urtw_softc *);
531 static void urtw_close_pipes(struct urtw_softc *);
532 static void urtw_led_launch(void *);
533 
534 static void	urtw_8187b_update_wmm(struct urtw_softc *);
535 static usbd_status	urtw_8187b_reset(struct urtw_softc *);
536 static int	urtw_8187b_init(void *);
537 static void	urtw_8225v2_b_config_mac(struct urtw_softc *);
538 static void	urtw_8225v2_b_init_rfe(struct urtw_softc *);
539 static usbd_status	urtw_8225v2_b_update_chan(struct urtw_softc *);
540 static usbd_status	urtw_8225v2_b_rf_init(struct urtw_rf *);
541 static usbd_status	urtw_8225v2_b_rf_set_chan(struct urtw_rf *, int);
542 static void urtw_8225v2_b_set_txpwrlvl(struct urtw_softc *, int);
543 
544 #ifdef DEBUG
545 
546 #define	URTW_DEBUG_XMIT		0x00000001
547 #define	URTW_DEBUG_RECV		0x00000002
548 #define	URTW_DEBUG_LED 		0x00000004
549 #define	URTW_DEBUG_GLD 		0x00000008
550 #define	URTW_DEBUG_RF		0x00000010
551 #define	URTW_DEBUG_ATTACH 	0x00000020
552 #define	URTW_DEBUG_ACTIVE 	0x00000040
553 #define	URTW_DEBUG_HWTYPE	0x00000080
554 #define	URTW_DEBUG_DEVREQ	0x00000100
555 #define	URTW_DEBUG_HOTPLUG	0x00000200
556 #define	URTW_DEBUG_STATE	0x00000400
557 #define	URTW_DEBUG_TX_PROC	0x00000800
558 #define	URTW_DEBUG_RX_PROC 	0x00001000
559 #define	URTW_DEBUG_EEPROM	0x00002000
560 #define	URTW_DEBUG_RESET	0x00004000
561 #define	URTW_DEBUG_ANY		0xffffffff
562 
563 uint32_t urtw8187_dbg_flags = 0;
564 static void
565 urtw8187_dbg(dev_info_t *dip, int level, const char *fmt, ...)
566 {
567 	char		msg_buffer[255];
568 	va_list	ap;
569 
570 	if (dip == NULL) {
571 		return;
572 	}
573 
574 	va_start(ap, fmt);
575 	(void) vsprintf(msg_buffer, fmt, ap);
576 	cmn_err(level, "%s%d: %s", ddi_get_name(dip),
577 	    ddi_get_instance(dip), msg_buffer);
578 	va_end(ap);
579 }
580 
581 #define	URTW8187_DBG(l, x) do {\
582 	_NOTE(CONSTANTCONDITION) \
583 	if ((l) & urtw8187_dbg_flags) \
584 		urtw8187_dbg x;\
585 	_NOTE(CONSTANTCONDITION) \
586 } while (0)
587 #else
588 #define	URTW8187_DBG(l, x)
589 #endif
590 
591 static usbd_status
592 urtw_led_init(struct urtw_softc *sc)
593 {
594 	uint32_t rev;
595 	usbd_status error;
596 
597 	if (error = urtw_read8_c(sc, URTW_PSR, &sc->sc_psr, 0))
598 		goto fail;
599 	error = urtw_eprom_read32(sc, URTW_EPROM_SWREV, &rev);
600 	if (error != 0)
601 		goto fail;
602 
603 	switch (rev & URTW_EPROM_CID_MASK) {
604 	case URTW_EPROM_CID_ALPHA0:
605 		sc->sc_strategy = URTW_SW_LED_MODE1;
606 		break;
607 	case URTW_EPROM_CID_SERCOMM_PS:
608 		sc->sc_strategy = URTW_SW_LED_MODE3;
609 		break;
610 	case URTW_EPROM_CID_HW_LED:
611 		sc->sc_strategy = URTW_HW_LED;
612 		break;
613 	case URTW_EPROM_CID_RSVD0:
614 	case URTW_EPROM_CID_RSVD1:
615 	default:
616 		sc->sc_strategy = URTW_SW_LED_MODE0;
617 		break;
618 	}
619 
620 	sc->sc_gpio_ledpin = URTW_LED_PIN_GPIO0;
621 
622 fail:
623 	return (error);
624 }
625 
626 static usbd_status
627 urtw_8225_write_s16(struct urtw_softc *sc, uint8_t addr, int index,
628     uint16_t *data)
629 {
630 	usb_ctrl_setup_t req;
631 	usb_cr_t cr;
632 	usb_cb_flags_t cf;
633 	mblk_t *mp = 0;
634 	uint16_t data16;
635 	usbd_status error;
636 
637 	data16 = *data;
638 	bzero(&req, sizeof (req));
639 	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
640 	req.bRequest = URTW_8187_SETREGS_REQ;
641 	req.wValue = addr;
642 	req.wIndex = (uint16_t)index;
643 	req.wLength = sizeof (uint16_t);
644 	req.attrs = USB_ATTRS_NONE;
645 
646 	mp = allocb(sizeof (uint16_t), BPRI_MED);
647 	if (mp == 0) {
648 		cmn_err(CE_WARN, "urtw_8225_write_s16: allocb failed\n");
649 		return (-1);
650 	}
651 	*(mp->b_rptr) = (data16 & 0x00ff);
652 	*(mp->b_rptr + 1) = (data16 & 0xff00) >> 8;
653 	mp->b_wptr += sizeof (uint16_t);
654 	error = usb_pipe_ctrl_xfer_wait(sc->sc_udev->dev_default_ph, &req, &mp,
655 	    &cr, &cf, 0);
656 	if (error != USB_SUCCESS) {
657 		URTW8187_DBG(URTW_DEBUG_DEVREQ, (sc->sc_dev, CE_CONT,
658 		    "urtw_8225_write_s16: could not set regs:"
659 		    "cr:%s(%d), cf:(%x)\n", usb_str_cr(cr), cr, cf));
660 	}
661 	if (mp)
662 		freemsg(mp);
663 	return (error);
664 
665 }
666 
667 static usbd_status
668 urtw_8225_read(struct urtw_softc *sc, uint8_t addr, uint32_t *data)
669 {
670 	int i;
671 	int16_t bit;
672 	uint8_t rlen = 12, wlen = 6;
673 	uint16_t o1, o2, o3, tmp;
674 	uint32_t d2w = ((uint32_t)(addr & 0x1f)) << 27;
675 	uint32_t mask = 0x80000000, value = 0;
676 	usbd_status error;
677 
678 	if (error = urtw_read16_c(sc, URTW_RF_PINS_OUTPUT, &o1, 0))
679 		goto fail;
680 	if (error = urtw_read16_c(sc, URTW_RF_PINS_ENABLE, &o2, 0))
681 		goto fail;
682 	if (error = urtw_read16_c(sc, URTW_RF_PINS_SELECT, &o3, 0))
683 		goto fail;
684 	if (error = urtw_write16_c(sc, URTW_RF_PINS_ENABLE, o2 | 0xf, 0))
685 		goto fail;
686 	if (error = urtw_write16_c(sc, URTW_RF_PINS_SELECT, o3 | 0xf, 0))
687 		goto fail;
688 	o1 &= ~0xf;
689 	if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT,
690 	    o1 | URTW_BB_HOST_BANG_EN, 0))
691 		goto fail;
692 	DELAY(5);
693 	if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT, o1, 0))
694 		goto fail;
695 	DELAY(5);
696 
697 	for (i = 0; i < (wlen / 2); i++, mask = mask >> 1) {
698 		bit = ((d2w & mask) != 0) ? 1 : 0;
699 
700 		if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT,
701 		    bit | o1, 0))
702 			goto fail;
703 		DELAY(2);
704 		if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT,
705 		    bit | o1 | URTW_BB_HOST_BANG_CLK, 0))
706 			goto fail;
707 		DELAY(2);
708 		if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT,
709 		    bit | o1 | URTW_BB_HOST_BANG_CLK, 0))
710 			goto fail;
711 		DELAY(2);
712 		mask = mask >> 1;
713 		if (i == 2)
714 			break;
715 		bit = ((d2w & mask) != 0) ? 1 : 0;
716 		if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT,
717 		    bit | o1 | URTW_BB_HOST_BANG_CLK, 0))
718 			goto fail;
719 		DELAY(2);
720 		if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT,
721 		    bit | o1 | URTW_BB_HOST_BANG_CLK, 0))
722 			goto fail;
723 		DELAY(2);
724 		if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT,
725 		    bit | o1, 0))
726 			goto fail;
727 		DELAY(1);
728 	}
729 	if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT,
730 	    bit | o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK, 0))
731 		goto fail;
732 	DELAY(2);
733 	if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT,
734 	    bit | o1 | URTW_BB_HOST_BANG_RW, 0))
735 		goto fail;
736 	DELAY(2);
737 	if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT,
738 	    o1 | URTW_BB_HOST_BANG_RW, 0))
739 		goto fail;
740 	DELAY(2);
741 
742 	mask = 0x800;
743 	for (i = 0; i < rlen; i++, mask = mask >> 1) {
744 		if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT,
745 		    o1 | URTW_BB_HOST_BANG_RW, 0))
746 			goto fail;
747 		DELAY(2);
748 		if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT,
749 		    o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK, 0))
750 			goto fail;
751 		DELAY(2);
752 		if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT,
753 		    o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK, 0))
754 			goto fail;
755 		DELAY(2);
756 		if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT,
757 		    o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK, 0))
758 			goto fail;
759 		DELAY(2);
760 
761 		if (error = urtw_read16_c(sc, URTW_RF_PINS_INPUT, &tmp, 0))
762 			goto fail;
763 		value |= ((tmp & URTW_BB_HOST_BANG_CLK) ? mask : 0);
764 		if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT,
765 		    o1 | URTW_BB_HOST_BANG_RW, 0))
766 			goto fail;
767 		DELAY(2);
768 	}
769 
770 	if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT,
771 	    o1 | URTW_BB_HOST_BANG_EN |
772 	    URTW_BB_HOST_BANG_RW, 0))
773 		goto fail;
774 	DELAY(2);
775 
776 	if (error = urtw_write16_c(sc, URTW_RF_PINS_ENABLE, o2, 0))
777 		goto fail;
778 	if (error = urtw_write16_c(sc, URTW_RF_PINS_SELECT, o3, 0))
779 		goto fail;
780 	error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT, 0x3a0, 0);
781 
782 	if (data != NULL)
783 		*data = value;
784 fail:
785 	return (error);
786 }
787 
788 static void
789 urtw_delay_ms(int t)
790 {
791 	DELAY(t * 1000);
792 }
793 
794 static usbd_status
795 urtw_8225_write_c(struct urtw_softc *sc, uint8_t addr, uint16_t data)
796 {
797 	uint16_t d80, d82, d84;
798 	usbd_status error;
799 
800 	if (error = urtw_read16_c(sc, URTW_RF_PINS_OUTPUT, &d80, 0))
801 		goto fail;
802 	d80 &= 0xfff3;
803 	if (error = urtw_read16_c(sc, URTW_RF_PINS_ENABLE, &d82, 0))
804 		goto fail;
805 	if (error = urtw_read16_c(sc, URTW_RF_PINS_SELECT, &d84, 0))
806 		goto fail;
807 	d84 &= 0xfff0;
808 	if (error = urtw_write16_c(sc, URTW_RF_PINS_ENABLE,
809 	    d82 | 0x0007, 0))
810 		goto fail;
811 	if (error = urtw_write16_c(sc, URTW_RF_PINS_SELECT,
812 	    d84 | 0x0007, 0))
813 		goto fail;
814 
815 	if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT,
816 	    d80 | URTW_BB_HOST_BANG_EN, 0))
817 		goto fail;
818 	urtw_delay_ms(2);
819 	if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT, d80, 0))
820 		goto fail;
821 
822 	error = urtw_8225_write_s16(sc, addr, 0x8225, &data);
823 	if (error != 0)
824 		goto fail;
825 
826 	if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT,
827 	    d80 | URTW_BB_HOST_BANG_EN, 0))
828 		goto fail;
829 	if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT,
830 	    d80 | URTW_BB_HOST_BANG_EN, 0))
831 		goto fail;
832 	error = urtw_write16_c(sc, URTW_RF_PINS_SELECT, d84, 0);
833 	urtw_delay_ms(2);
834 fail:
835 	return (error);
836 }
837 
838 static usbd_status
839 urtw_8225_isv2(struct urtw_softc *sc, int *ret)
840 {
841 	uint32_t data;
842 	usbd_status error;
843 
844 	*ret = 1;
845 
846 	if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT, 0x0080, 0))
847 		goto fail;
848 	if (error = urtw_write16_c(sc, URTW_RF_PINS_SELECT, 0x0080, 0))
849 		goto fail;
850 	if (error = urtw_write16_c(sc, URTW_RF_PINS_ENABLE, 0x0080, 0))
851 		goto fail;
852 	urtw_delay_ms(300);
853 
854 	if (error = urtw_8225_write_c(sc, 0x0, 0x1b7))
855 		goto fail;
856 
857 	error = urtw_8225_read(sc, 0x8, &data);
858 	if (error != 0)
859 		goto fail;
860 	if (data != 0x588)
861 		*ret = 0;
862 	else {
863 		error = urtw_8225_read(sc, 0x9, &data);
864 		if (error != 0)
865 			goto fail;
866 		if (data != 0x700)
867 			*ret = 0;
868 	}
869 
870 	error = urtw_8225_write_c(sc, 0x0, 0xb7);
871 fail:
872 	return (error);
873 }
874 
875 static usbd_status
876 urtw_get_rfchip(struct urtw_softc *sc)
877 {
878 	struct urtw_rf *rf = &sc->sc_rf;
879 	int ret;
880 	uint32_t data;
881 	usbd_status error;
882 
883 	rf->rf_sc = sc;
884 
885 	if (sc->sc_hwrev & URTW_HWREV_8187) {
886 		error = urtw_eprom_read32(sc, URTW_EPROM_RFCHIPID, &data);
887 		if (error != 0) {
888 			cmn_err(CE_WARN, "RF ID read failed\n");
889 			return (-1);
890 		}
891 		switch (data & 0xff) {
892 		case URTW_EPROM_RFCHIPID_RTL8225U:
893 			error = urtw_8225_isv2(sc, &ret);
894 			if (error != 0) {
895 				URTW8187_DBG(URTW_DEBUG_HWTYPE,
896 				    (sc->sc_dev, CE_CONT,
897 				    "8225 version check failed\n"));
898 				goto fail;
899 			}
900 			if (ret == 0) {
901 				URTW8187_DBG(URTW_DEBUG_HWTYPE,
902 				    (sc->sc_dev, CE_CONT,
903 				    "8225 detected\n"));
904 				rf->init = urtw_8225_rf_init;
905 				rf->set_chan = urtw_8225_rf_set_chan;
906 				rf->set_sens = urtw_8225_rf_set_sens;
907 			} else {
908 				URTW8187_DBG(URTW_DEBUG_HWTYPE,
909 				    (sc->sc_dev, CE_CONT,
910 				    "8225 v2 detected\n"));
911 				rf->init = urtw_8225v2_rf_init;
912 				rf->set_chan = urtw_8225v2_rf_set_chan;
913 				rf->set_sens = NULL;
914 			}
915 			break;
916 		default:
917 			goto fail;
918 		}
919 	} else {
920 		URTW8187_DBG(URTW_DEBUG_HWTYPE,
921 		    (sc->sc_dev, CE_CONT,
922 		    "8225 v2 [b] detected\n"));
923 		rf->init = urtw_8225v2_b_rf_init;
924 		rf->set_chan = urtw_8225v2_b_rf_set_chan;
925 		rf->set_sens = NULL;
926 	}
927 
928 	rf->max_sens = URTW_8225_RF_MAX_SENS;
929 	rf->sens = URTW_8225_RF_DEF_SENS;
930 
931 	return (0);
932 
933 fail:
934 	cmn_err(CE_WARN, "unsupported RF chip %d\n", data & 0xff);
935 	return (-1);
936 }
937 
938 static usbd_status
939 urtw_get_txpwr(struct urtw_softc *sc)
940 {
941 	int i, j;
942 	uint32_t data;
943 	usbd_status error;
944 
945 	error = urtw_eprom_read32(sc, URTW_EPROM_TXPW_BASE, &data);
946 	if (error != 0)
947 		goto fail;
948 	sc->sc_txpwr_cck_base = data & 0xf;
949 	sc->sc_txpwr_ofdm_base = (data >> 4) & 0xf;
950 
951 	for (i = 1, j = 0; i < 6; i += 2, j++) {
952 		error = urtw_eprom_read32(sc, URTW_EPROM_TXPW0 + j, &data);
953 		if (error != 0)
954 			goto fail;
955 		sc->sc_txpwr_cck[i] = data & 0xf;
956 		sc->sc_txpwr_cck[i + 1] = (data & 0xf00) >> 8;
957 		sc->sc_txpwr_ofdm[i] = (data & 0xf0) >> 4;
958 		sc->sc_txpwr_ofdm[i + 1] = (data & 0xf000) >> 12;
959 	}
960 	for (i = 1, j = 0; i < 4; i += 2, j++) {
961 		error = urtw_eprom_read32(sc, URTW_EPROM_TXPW1 + j, &data);
962 		if (error != 0)
963 			goto fail;
964 		sc->sc_txpwr_cck[i + 6] = data & 0xf;
965 		sc->sc_txpwr_cck[i + 6 + 1] = (data & 0xf00) >> 8;
966 		sc->sc_txpwr_ofdm[i + 6] = (data & 0xf0) >> 4;
967 		sc->sc_txpwr_ofdm[i + 6 + 1] = (data & 0xf000) >> 12;
968 	}
969 	if (sc->sc_hwrev & URTW_HWREV_8187) {
970 		for (i = 1, j = 0; i < 4; i += 2, j++) {
971 			error = urtw_eprom_read32(sc, URTW_EPROM_TXPW2 + j,
972 			    &data);
973 			if (error != 0)
974 				goto fail;
975 			sc->sc_txpwr_cck[i + 6 + 4] = data & 0xf;
976 			sc->sc_txpwr_cck[i + 6 + 4 + 1] = (data & 0xf00) >> 8;
977 			sc->sc_txpwr_ofdm[i + 6 + 4] = (data & 0xf0) >> 4;
978 			sc->sc_txpwr_ofdm[i + 6 + 4 + 1] =
979 			    (data & 0xf000) >> 12;
980 		}
981 	} else {
982 		/* Channel 11. */
983 		error = urtw_eprom_read32(sc, 0x1b, &data);
984 		if (error != 0)
985 			goto fail;
986 		sc->sc_txpwr_cck[11] = data & 0xf;
987 		sc->sc_txpwr_ofdm[11] = (data & 0xf0) >> 4;
988 
989 		/* Channel 12. */
990 		error = urtw_eprom_read32(sc, 0xa, &data);
991 		if (error != 0)
992 			goto fail;
993 		sc->sc_txpwr_cck[12] = data & 0xf;
994 		sc->sc_txpwr_ofdm[12] = (data & 0xf0) >> 4;
995 
996 		/* Channel 13, 14. */
997 		error = urtw_eprom_read32(sc, 0x1c, &data);
998 		if (error != 0)
999 			goto fail;
1000 		sc->sc_txpwr_cck[13] = data & 0xf;
1001 		sc->sc_txpwr_ofdm[13] = (data & 0xf0) >> 4;
1002 		sc->sc_txpwr_cck[14] = (data & 0xf00) >> 8;
1003 		sc->sc_txpwr_ofdm[14] = (data & 0xf000) >> 12;
1004 	}
1005 fail:
1006 	return (error);
1007 }
1008 
1009 
1010 static usbd_status
1011 urtw_get_macaddr(struct urtw_softc *sc)
1012 {
1013 	uint32_t data;
1014 	usbd_status error;
1015 	uint8_t *m = 0;
1016 
1017 	error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR, &data);
1018 	if (error != 0)
1019 		goto fail;
1020 	sc->sc_bssid[0] = data & 0xff;
1021 	sc->sc_bssid[1] = (data & 0xff00) >> 8;
1022 	error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR + 1, &data);
1023 	if (error != 0)
1024 		goto fail;
1025 	sc->sc_bssid[2] = data & 0xff;
1026 	sc->sc_bssid[3] = (data & 0xff00) >> 8;
1027 	error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR + 2, &data);
1028 	if (error != 0)
1029 		goto fail;
1030 	sc->sc_bssid[4] = data & 0xff;
1031 	sc->sc_bssid[5] = (data & 0xff00) >> 8;
1032 	bcopy(sc->sc_bssid, sc->sc_ic.ic_macaddr, IEEE80211_ADDR_LEN);
1033 	m = sc->sc_bssid;
1034 	URTW8187_DBG(URTW_DEBUG_HWTYPE, (sc->sc_dev, CE_CONT,
1035 	    "MAC: %x:%x:%x:%x:%x:%x\n",
1036 	    m[0], m[1], m[2], m[3], m[4], m[5]));
1037 fail:
1038 	return (error);
1039 }
1040 
1041 static usbd_status
1042 urtw_eprom_read32(struct urtw_softc *sc, uint32_t addr, uint32_t *data)
1043 {
1044 #define	URTW_READCMD_LEN	3
1045 	int addrlen, i;
1046 	int16_t addrstr[8], data16, readcmd[] = { 1, 1, 0 };
1047 	usbd_status error;
1048 
1049 	/* NB: make sure the buffer is initialized  */
1050 	*data = 0;
1051 
1052 	/* enable EPROM programming */
1053 	if (error = urtw_write8_c(sc, URTW_EPROM_CMD,
1054 	    URTW_EPROM_CMD_PROGRAM_MODE, 0))
1055 		goto fail;
1056 	DELAY(URTW_EPROM_DELAY);
1057 
1058 	error = urtw_eprom_cs(sc, URTW_EPROM_ENABLE);
1059 	if (error != 0)
1060 		goto fail;
1061 	error = urtw_eprom_ck(sc);
1062 	if (error != 0)
1063 		goto fail;
1064 	error = urtw_eprom_sendbits(sc, readcmd, URTW_READCMD_LEN);
1065 	if (error != 0)
1066 		goto fail;
1067 	if (sc->sc_epromtype == URTW_EEPROM_93C56) {
1068 		addrlen = 8;
1069 		addrstr[0] = addr & (1 << 7);
1070 		addrstr[1] = addr & (1 << 6);
1071 		addrstr[2] = addr & (1 << 5);
1072 		addrstr[3] = addr & (1 << 4);
1073 		addrstr[4] = addr & (1 << 3);
1074 		addrstr[5] = addr & (1 << 2);
1075 		addrstr[6] = addr & (1 << 1);
1076 		addrstr[7] = addr & (1 << 0);
1077 	} else {
1078 		addrlen = 6;
1079 		addrstr[0] = addr & (1 << 5);
1080 		addrstr[1] = addr & (1 << 4);
1081 		addrstr[2] = addr & (1 << 3);
1082 		addrstr[3] = addr & (1 << 2);
1083 		addrstr[4] = addr & (1 << 1);
1084 		addrstr[5] = addr & (1 << 0);
1085 	}
1086 	error = urtw_eprom_sendbits(sc, addrstr, addrlen);
1087 	if (error != 0)
1088 		goto fail;
1089 
1090 	error = urtw_eprom_writebit(sc, 0);
1091 	if (error != 0)
1092 		goto fail;
1093 
1094 	for (i = 0; i < 16; i++) {
1095 		error = urtw_eprom_ck(sc);
1096 		if (error != 0)
1097 			goto fail;
1098 		error = urtw_eprom_readbit(sc, &data16);
1099 		if (error != 0)
1100 			goto fail;
1101 
1102 		(*data) |= (data16 << (15 - i));
1103 	}
1104 
1105 	error = urtw_eprom_cs(sc, URTW_EPROM_DISABLE);
1106 	if (error != 0)
1107 		goto fail;
1108 	error = urtw_eprom_ck(sc);
1109 	if (error != 0)
1110 		goto fail;
1111 
1112 	/* now disable EPROM programming */
1113 	error = urtw_write8_c(sc, URTW_EPROM_CMD,
1114 	    URTW_EPROM_CMD_NORMAL_MODE, 0);
1115 fail:
1116 	return (error);
1117 #undef URTW_READCMD_LEN
1118 }
1119 
1120 static usbd_status
1121 urtw_eprom_readbit(struct urtw_softc *sc, int16_t *data)
1122 {
1123 	uint8_t data8;
1124 	usbd_status error;
1125 
1126 	error = urtw_read8_c(sc, URTW_EPROM_CMD, &data8, 0);
1127 	*data = (data8 & URTW_EPROM_READBIT) ? 1 : 0;
1128 	DELAY(URTW_EPROM_DELAY);
1129 	return (error);
1130 }
1131 
1132 static usbd_status
1133 urtw_eprom_sendbits(struct urtw_softc *sc, int16_t *buf, int buflen)
1134 {
1135 	int i = 0;
1136 	usbd_status error;
1137 
1138 	for (i = 0; i < buflen; i++) {
1139 		error = urtw_eprom_writebit(sc, buf[i]);
1140 		if (error != 0)
1141 			goto fail;
1142 		error = urtw_eprom_ck(sc);
1143 		if (error != 0)
1144 			goto fail;
1145 	}
1146 fail:
1147 	return (error);
1148 }
1149 
1150 static usbd_status
1151 urtw_eprom_writebit(struct urtw_softc *sc, int16_t bit)
1152 {
1153 	uint8_t data;
1154 	usbd_status error;
1155 
1156 	if (error = urtw_read8_c(sc, URTW_EPROM_CMD, &data, 0))
1157 		goto fail;
1158 	if (bit != 0)
1159 		error = urtw_write8_c(sc, URTW_EPROM_CMD,
1160 		    data | URTW_EPROM_WRITEBIT, 0);
1161 	else
1162 		error = urtw_write8_c(sc, URTW_EPROM_CMD,
1163 		    data & ~URTW_EPROM_WRITEBIT, 0);
1164 	DELAY(URTW_EPROM_DELAY);
1165 fail:
1166 	return (error);
1167 }
1168 
1169 static usbd_status
1170 urtw_eprom_ck(struct urtw_softc *sc)
1171 {
1172 	uint8_t data;
1173 	usbd_status error;
1174 
1175 	/* masking  */
1176 	if (error = urtw_read8_c(sc, URTW_EPROM_CMD, &data, 0))
1177 		goto fail;
1178 	if (error = urtw_write8_c(sc, URTW_EPROM_CMD, data | URTW_EPROM_CK, 0))
1179 		goto fail;
1180 	DELAY(URTW_EPROM_DELAY);
1181 	/* unmasking  */
1182 	if (error = urtw_read8_c(sc, URTW_EPROM_CMD, &data, 0))
1183 		goto fail;
1184 	error = urtw_write8_c(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_CK, 0);
1185 	DELAY(URTW_EPROM_DELAY);
1186 fail:
1187 	return (error);
1188 }
1189 
1190 static usbd_status
1191 urtw_eprom_cs(struct urtw_softc *sc, int able)
1192 {
1193 	uint8_t data;
1194 	usbd_status error;
1195 
1196 	if (error = urtw_read8_c(sc, URTW_EPROM_CMD, &data, 0))
1197 		goto fail;
1198 	if (able == URTW_EPROM_ENABLE)
1199 		error = urtw_write8_c(sc, URTW_EPROM_CMD,
1200 		    data | URTW_EPROM_CS, 0);
1201 	else
1202 		error = urtw_write8_c(sc, URTW_EPROM_CMD,
1203 		    data & ~URTW_EPROM_CS, 0);
1204 	DELAY(URTW_EPROM_DELAY);
1205 fail:
1206 	return (error);
1207 }
1208 
1209 static usbd_status
1210 urtw_read8_c(struct urtw_softc *sc, int val, uint8_t *data, uint8_t idx)
1211 {
1212 	usb_ctrl_setup_t req;
1213 	usb_cr_t cr;
1214 	usb_cb_flags_t cf;
1215 	mblk_t *mp = NULL;
1216 	usbd_status error;
1217 
1218 	bzero(&req, sizeof (req));
1219 	req.bmRequestType = UT_READ_VENDOR_DEVICE;
1220 	req.bRequest = URTW_8187_GETREGS_REQ;
1221 	req.wValue = val | 0xff00;
1222 	req.wIndex = idx & 0x03;
1223 	req.wLength = sizeof (uint8_t);
1224 
1225 	error = usb_pipe_ctrl_xfer_wait(sc->sc_udev->dev_default_ph, &req, &mp,
1226 	    &cr, &cf, 0);
1227 
1228 	if (error != USB_SUCCESS) {
1229 		URTW8187_DBG(URTW_DEBUG_DEVREQ, (sc->sc_dev, CE_CONT,
1230 		    "urtw_read8_c: get regs req failed :"
1231 		    " cr:%s(%d), cf:(%x)\n", usb_str_cr(cr), cr, cf));
1232 		return (error);
1233 	}
1234 	bcopy(mp->b_rptr, data, sizeof (uint8_t));
1235 	if (mp)
1236 		freemsg(mp);
1237 	return (error);
1238 }
1239 
1240 static usbd_status
1241 urtw_read8e(struct urtw_softc *sc, int val, uint8_t *data)
1242 {
1243 	usb_ctrl_setup_t req;
1244 	usb_cr_t cr;
1245 	usb_cb_flags_t cf;
1246 	mblk_t *mp = NULL;
1247 	usbd_status error;
1248 
1249 	bzero(&req, sizeof (req));
1250 	req.bmRequestType = UT_READ_VENDOR_DEVICE;
1251 	req.bRequest = URTW_8187_GETREGS_REQ;
1252 	req.wValue = val | 0xfe00;
1253 	req.wIndex = 0;
1254 	req.wLength = sizeof (uint8_t);
1255 	req.attrs = USB_ATTRS_AUTOCLEARING;
1256 	error = usb_pipe_ctrl_xfer_wait(sc->sc_udev->dev_default_ph, &req, &mp,
1257 	    &cr, &cf, 0);
1258 
1259 	if (error != USB_SUCCESS) {
1260 		URTW8187_DBG(URTW_DEBUG_DEVREQ, (sc->sc_dev, CE_CONT,
1261 		    "urtw_read8e: get regs req failed :"
1262 		    " cr:%s(%d), cf:(%x)\n", usb_str_cr(cr), cr, cf));
1263 		return (error);
1264 	}
1265 
1266 	if (mp) {
1267 		bcopy(mp->b_rptr, data, sizeof (uint8_t));
1268 		freemsg(mp);
1269 	}
1270 	return (error);
1271 }
1272 
1273 static usbd_status
1274 urtw_read16_c(struct urtw_softc *sc, int val, uint16_t *data, uint8_t idx)
1275 {
1276 	usb_ctrl_setup_t req;
1277 	usb_cr_t cr;
1278 	usb_cb_flags_t cf;
1279 	mblk_t *mp = NULL;
1280 	usbd_status error;
1281 
1282 	bzero(&req, sizeof (req));
1283 	req.bmRequestType = UT_READ_VENDOR_DEVICE;
1284 	req.bRequest = URTW_8187_GETREGS_REQ;
1285 	req.wValue = val | 0xff00;
1286 	req.wIndex = idx & 0x03;
1287 	req.wLength = sizeof (uint16_t);
1288 	req.attrs = USB_ATTRS_AUTOCLEARING;
1289 	error = usb_pipe_ctrl_xfer_wait(sc->sc_udev->dev_default_ph, &req, &mp,
1290 	    &cr, &cf, 0);
1291 
1292 	if (error != USB_SUCCESS) {
1293 		URTW8187_DBG(URTW_DEBUG_DEVREQ, (sc->sc_dev, CE_CONT,
1294 		    "urtw_read16_c: get regs req failed :"
1295 		    " cr:%s(%d), cf:(%x)\n",
1296 		    usb_str_cr(cr), cr, cf));
1297 		return (error);
1298 	}
1299 	if (mp) {
1300 		bcopy(mp->b_rptr, data, sizeof (uint16_t));
1301 		freemsg(mp);
1302 	}
1303 	return (error);
1304 }
1305 
1306 static usbd_status
1307 urtw_read32_c(struct urtw_softc *sc, int val, uint32_t *data, uint8_t idx)
1308 {
1309 	usb_ctrl_setup_t req;
1310 	usb_cr_t cr;
1311 	usb_cb_flags_t cf;
1312 	mblk_t *mp = NULL;
1313 	usbd_status error;
1314 
1315 	bzero(&req, sizeof (req));
1316 	req.bmRequestType = UT_READ_VENDOR_DEVICE;
1317 	req.bRequest = URTW_8187_GETREGS_REQ;
1318 	req.wValue = val | 0xff00;
1319 	req.wIndex = idx & 0x03;
1320 	req.wLength = sizeof (uint32_t);
1321 	req.attrs = USB_ATTRS_AUTOCLEARING;
1322 
1323 	error = usb_pipe_ctrl_xfer_wait(sc->sc_udev->dev_default_ph, &req, &mp,
1324 	    &cr, &cf, 0);
1325 
1326 	if (error != USB_SUCCESS) {
1327 		URTW8187_DBG(URTW_DEBUG_DEVREQ, (sc->sc_dev, CE_CONT,
1328 		    "urtw_read32_c: get regs req failed :"
1329 		    " cr:%s(%d), cf:(%x)\n", usb_str_cr(cr), cr, cf));
1330 		return (error);
1331 	}
1332 
1333 	if (mp) {
1334 		bcopy(mp->b_rptr, data, sizeof (uint32_t));
1335 		freemsg(mp);
1336 	}
1337 	return (error);
1338 }
1339 
1340 static usbd_status
1341 urtw_write8_c(struct urtw_softc *sc, int val, uint8_t data, uint8_t idx)
1342 {
1343 	usb_ctrl_setup_t req;
1344 	usb_cr_t cr;
1345 	usb_cb_flags_t cf;
1346 	mblk_t *mp = 0;
1347 	int error;
1348 
1349 	bzero(&req, sizeof (req));
1350 	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
1351 	req.bRequest = URTW_8187_SETREGS_REQ;
1352 	req.wValue = val | 0xff00;
1353 	req.wIndex = idx & 0x03;
1354 	req.wLength = sizeof (uint8_t);
1355 	req.attrs = USB_ATTRS_NONE;
1356 
1357 	mp = allocb(sizeof (uint32_t), BPRI_MED);
1358 	if (mp == NULL) {
1359 		cmn_err(CE_CONT, "urtw_write8_c: failed alloc mblk.");
1360 		return (-1);
1361 	}
1362 	*(uint8_t *)(mp->b_rptr) = data;
1363 	mp->b_wptr += sizeof (uint8_t);
1364 	error = usb_pipe_ctrl_xfer_wait(sc->sc_udev->dev_default_ph, &req, &mp,
1365 	    &cr, &cf, 0);
1366 	if (error != USB_SUCCESS) {
1367 		URTW8187_DBG(URTW_DEBUG_DEVREQ, (sc->sc_dev, CE_CONT,
1368 		    "urtw_write8_c: could not set regs:"
1369 		    "cr:%s(%d), cf:(%x)\n", usb_str_cr(cr), cr, cf));
1370 	}
1371 	if (mp)
1372 		freemsg(mp);
1373 	return (error);
1374 }
1375 
1376 static usbd_status
1377 urtw_write8e(struct urtw_softc *sc, int val, uint8_t data)
1378 {
1379 	usb_ctrl_setup_t req;
1380 	usb_cr_t cr;
1381 	usb_cb_flags_t cf;
1382 	mblk_t *mp = 0;
1383 	int error;
1384 
1385 	bzero(&req, sizeof (req));
1386 	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
1387 	req.bRequest = URTW_8187_SETREGS_REQ;
1388 	req.wValue = val | 0xfe00;
1389 	req.wIndex = 0;
1390 	req.wLength = sizeof (uint8_t);
1391 	req.attrs = USB_ATTRS_NONE;
1392 
1393 	mp = allocb(sizeof (uint8_t), BPRI_MED);
1394 	if (mp == NULL) {
1395 		cmn_err(CE_CONT, "urtw_write8e: failed alloc mblk.");
1396 		return (-1);
1397 	}
1398 	*(mp->b_rptr) = data;
1399 	mp->b_wptr += sizeof (uint8_t);
1400 
1401 	error = usb_pipe_ctrl_xfer_wait(sc->sc_udev->dev_default_ph, &req, &mp,
1402 	    &cr, &cf, 0);
1403 	if (error != USB_SUCCESS) {
1404 		URTW8187_DBG(URTW_DEBUG_DEVREQ, (sc->sc_dev, CE_CONT,
1405 		    "urtw_write8e: could not set regs:"
1406 		    "cr:%s(%d), cf:(%x)\n",
1407 		    usb_str_cr(cr), cr, cf));
1408 	}
1409 	if (mp)
1410 		freemsg(mp);
1411 	return (error);
1412 }
1413 
1414 static usbd_status
1415 urtw_write16_c(struct urtw_softc *sc, int val, uint16_t data, uint8_t idx)
1416 {
1417 	usb_ctrl_setup_t req;
1418 	usb_cr_t cr;
1419 	usb_cb_flags_t cf;
1420 	mblk_t *mp = 0;
1421 	int error;
1422 
1423 	bzero(&req, sizeof (req));
1424 	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
1425 	req.bRequest = URTW_8187_SETREGS_REQ;
1426 	req.wValue = val | 0xff00;
1427 	req.wIndex = idx & 0x03;
1428 	req.wLength = sizeof (uint16_t);
1429 	req.attrs = USB_ATTRS_NONE;
1430 
1431 	mp = allocb(sizeof (uint16_t), BPRI_MED);
1432 	if (mp == NULL) {
1433 		cmn_err(CE_CONT, "urtw_write16_c: failed alloc mblk.");
1434 		return (-1);
1435 	}
1436 	*(uint16_t *)(uintptr_t)(mp->b_rptr) = data;
1437 	mp->b_wptr += sizeof (uint16_t);
1438 	error = usb_pipe_ctrl_xfer_wait(sc->sc_udev->dev_default_ph, &req, &mp,
1439 	    &cr, &cf, 0);
1440 	if (error != USB_SUCCESS) {
1441 		URTW8187_DBG(URTW_DEBUG_DEVREQ, (sc->sc_dev, CE_CONT,
1442 		    "urtw_write16_c: could not set regs:"
1443 		    "cr:%s(%d), cf:(%x)\n",
1444 		    usb_str_cr(cr), cr, cf));
1445 	}
1446 	if (mp)
1447 		freemsg(mp);
1448 	return (error);
1449 }
1450 
1451 static usbd_status
1452 urtw_write32_c(struct urtw_softc *sc, int val, uint32_t data, uint8_t idx)
1453 {
1454 	usb_ctrl_setup_t req;
1455 	usb_cr_t cr;
1456 	usb_cb_flags_t cf;
1457 	mblk_t *mp = 0;
1458 	int error;
1459 
1460 	bzero(&req, sizeof (req));
1461 	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
1462 	req.bRequest = URTW_8187_SETREGS_REQ;
1463 	req.wValue = val | 0xff00;
1464 	req.wIndex = idx & 0x03;
1465 	req.wLength = sizeof (uint32_t);
1466 	req.attrs = USB_ATTRS_NONE;
1467 
1468 	mp = allocb(sizeof (uint32_t), BPRI_MED);
1469 	if (mp == NULL) {
1470 		cmn_err(CE_CONT, "urtw_write32_c: failed alloc mblk.");
1471 		return (-1);
1472 	}
1473 	*(uint32_t *)(uintptr_t)(mp->b_rptr) = data;
1474 	mp->b_wptr += sizeof (uint32_t);
1475 	error = usb_pipe_ctrl_xfer_wait(sc->sc_udev->dev_default_ph, &req, &mp,
1476 	    &cr, &cf, 0);
1477 	if (error != USB_SUCCESS) {
1478 		URTW8187_DBG(URTW_DEBUG_DEVREQ, (sc->sc_dev, CE_CONT,
1479 		    "urtw_write32_c: could not set regs:"
1480 		    "cr:%s(%d), cf:(%x)\n",
1481 		    usb_str_cr(cr), cr, cf));
1482 	}
1483 
1484 	if (mp)
1485 		freemsg(mp);
1486 	return (error);
1487 }
1488 
1489 static usbd_status
1490 urtw_set_mode(struct urtw_softc *sc, uint32_t mode)
1491 {
1492 	uint8_t data;
1493 	usbd_status error;
1494 
1495 	if (error = urtw_read8_c(sc, URTW_EPROM_CMD, &data, 0))
1496 		goto fail;
1497 	data = (data & ~URTW_EPROM_CMD_MASK) | (mode << URTW_EPROM_CMD_SHIFT);
1498 	data = data & ~(URTW_EPROM_CS | URTW_EPROM_CK);
1499 	error = urtw_write8_c(sc, URTW_EPROM_CMD, data, 0);
1500 fail:
1501 	return (error);
1502 }
1503 
1504 static usbd_status
1505 urtw_8180_set_anaparam(struct urtw_softc *sc, uint32_t val)
1506 {
1507 	uint8_t data;
1508 	usbd_status error;
1509 
1510 	error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
1511 	if (error)
1512 		goto fail;
1513 
1514 	if (error = urtw_read8_c(sc, URTW_CONFIG3, &data, 0))
1515 		goto fail;
1516 	if (error = urtw_write8_c(sc, URTW_CONFIG3,
1517 	    data | URTW_CONFIG3_ANAPARAM_WRITE, 0))
1518 		goto fail;
1519 	if (error = urtw_write32_c(sc, URTW_ANAPARAM, val, 0))
1520 		goto fail;
1521 	if (error = urtw_read8_c(sc, URTW_CONFIG3, &data, 0))
1522 		goto fail;
1523 	if (error = urtw_write8_c(sc, URTW_CONFIG3,
1524 	    data & ~URTW_CONFIG3_ANAPARAM_WRITE, 0))
1525 		goto fail;
1526 
1527 	error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
1528 	if (error)
1529 		goto fail;
1530 fail:
1531 	return (error);
1532 }
1533 
1534 static usbd_status
1535 urtw_8185_set_anaparam2(struct urtw_softc *sc, uint32_t val)
1536 {
1537 	uint8_t data;
1538 	usbd_status error;
1539 
1540 	error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
1541 	if (error)
1542 		goto fail;
1543 
1544 	if (error = urtw_read8_c(sc, URTW_CONFIG3, &data, 0))
1545 		goto fail;
1546 	if (error = urtw_write8_c(sc, URTW_CONFIG3,
1547 	    data | URTW_CONFIG3_ANAPARAM_WRITE, 0))
1548 		goto fail;
1549 	if (error = urtw_write32_c(sc, URTW_ANAPARAM2, val, 0))
1550 		goto fail;
1551 	if (error = urtw_read8_c(sc, URTW_CONFIG3, &data, 0))
1552 		goto fail;
1553 	if (error = urtw_write8_c(sc, URTW_CONFIG3,
1554 	    data & ~URTW_CONFIG3_ANAPARAM_WRITE, 0))
1555 		goto fail;
1556 
1557 	error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
1558 	if (error)
1559 		goto fail;
1560 fail:
1561 	return (error);
1562 }
1563 
1564 static usbd_status
1565 urtw_intr_disable(struct urtw_softc *sc)
1566 {
1567 	usbd_status error;
1568 
1569 	error = urtw_write16_c(sc, URTW_INTR_MASK, 0, 0);
1570 	return (error);
1571 }
1572 
1573 static usbd_status
1574 urtw_8187_reset(struct urtw_softc *sc)
1575 {
1576 	uint8_t data;
1577 	usbd_status error;
1578 
1579 	error = urtw_8180_set_anaparam(sc, URTW_8187_8225_ANAPARAM_ON);
1580 	if (error)
1581 		goto fail;
1582 	error = urtw_8185_set_anaparam2(sc, URTW_8187_8225_ANAPARAM2_ON);
1583 	if (error)
1584 		goto fail;
1585 
1586 	error = urtw_intr_disable(sc);
1587 	if (error)
1588 		goto fail;
1589 	urtw_delay_ms(50);
1590 
1591 	error = urtw_write8e(sc, 0x18, 0x10);
1592 	if (error != 0)
1593 		goto fail;
1594 	error = urtw_write8e(sc, 0x18, 0x11);
1595 	if (error != 0)
1596 		goto fail;
1597 	error = urtw_write8e(sc, 0x18, 0x00);
1598 	if (error != 0)
1599 		goto fail;
1600 	urtw_delay_ms(50);
1601 
1602 	if (error = urtw_read8_c(sc, URTW_CMD, &data, 0))
1603 		goto fail;
1604 	data = (data & 2) | URTW_CMD_RST;
1605 	if (error = urtw_write8_c(sc, URTW_CMD, data, 0))
1606 		goto fail;
1607 	urtw_delay_ms(50);
1608 
1609 	if (error = urtw_read8_c(sc, URTW_CMD, &data, 0))
1610 		goto fail;
1611 	if (data & URTW_CMD_RST) {
1612 		cmn_err(CE_CONT, "urtw reset timeout\n");
1613 		goto fail;
1614 	}
1615 	error = urtw_set_mode(sc, URTW_EPROM_CMD_LOAD);
1616 	if (error)
1617 		goto fail;
1618 	urtw_delay_ms(50);
1619 
1620 	error = urtw_8180_set_anaparam(sc, URTW_8187_8225_ANAPARAM_ON);
1621 	if (error)
1622 		goto fail;
1623 	error = urtw_8185_set_anaparam2(sc, URTW_8187_8225_ANAPARAM2_ON);
1624 	if (error)
1625 		goto fail;
1626 fail:
1627 	return (error);
1628 }
1629 
1630 static usbd_status
1631 urtw_led_on(struct urtw_softc *sc, int type)
1632 {
1633 	if (type == URTW_LED_GPIO) {
1634 		switch (sc->sc_gpio_ledpin) {
1635 		case URTW_LED_PIN_GPIO0:
1636 			(void) urtw_write8_c(sc, URTW_GPIO, 0x01, 0);
1637 			(void) urtw_write8_c(sc, URTW_GP_ENABLE, 0x00, 0);
1638 			break;
1639 		default:
1640 			cmn_err(CE_WARN, "unsupported LED PIN type 0x%x",
1641 			    sc->sc_gpio_ledpin);
1642 			/* never reach  */
1643 		}
1644 	} else {
1645 		cmn_err(CE_WARN, "unsupported LED type 0x%x", type);
1646 		/* never reach  */
1647 	}
1648 
1649 	sc->sc_gpio_ledon = 1;
1650 	return (0);
1651 }
1652 
1653 static usbd_status
1654 urtw_led_off(struct urtw_softc *sc, int type)
1655 {
1656 	if (type == URTW_LED_GPIO) {
1657 		switch (sc->sc_gpio_ledpin) {
1658 		case URTW_LED_PIN_GPIO0:
1659 			(void) urtw_write8_c(sc, URTW_GPIO, 0x01, 0);
1660 			(void) urtw_write8_c(sc, URTW_GP_ENABLE, 0x01, 0);
1661 			break;
1662 		default:
1663 			cmn_err(CE_WARN, "unsupported LED PIN type 0x%x",
1664 			    sc->sc_gpio_ledpin);
1665 			/* never reach  */
1666 		}
1667 	} else {
1668 		cmn_err(CE_WARN, "unsupported LED type 0x%x", type);
1669 		/* never reach  */
1670 	}
1671 
1672 	sc->sc_gpio_ledon = 0;
1673 	return (0);
1674 }
1675 
1676 static usbd_status
1677 urtw_led_mode0(struct urtw_softc *sc, int mode)
1678 {
1679 	URTW8187_DBG(URTW_DEBUG_LED, (sc->sc_dev, CE_CONT,
1680 	    "urtw_led_mode0: mode = %d\n", mode));
1681 	switch (mode) {
1682 	case URTW_LED_CTL_POWER_ON:
1683 		sc->sc_gpio_ledstate = URTW_LED_POWER_ON_BLINK;
1684 		break;
1685 	case URTW_LED_CTL_TX:
1686 		if (sc->sc_gpio_ledinprogress == 1)
1687 			return (0);
1688 		sc->sc_gpio_ledstate = URTW_LED_BLINK_NORMAL;
1689 		sc->sc_gpio_blinktime =
1690 		    (sc->sc_ic.ic_state == IEEE80211_S_RUN ? 4:2);
1691 		break;
1692 	case URTW_LED_CTL_LINK:
1693 		sc->sc_gpio_ledstate = URTW_LED_ON;
1694 		break;
1695 	default:
1696 		cmn_err(CE_CONT, "unsupported LED mode 0x%x", mode);
1697 		/* never reach  */
1698 	}
1699 
1700 	switch (sc->sc_gpio_ledstate) {
1701 	case URTW_LED_ON:
1702 		if (sc->sc_gpio_ledinprogress != 0)
1703 			break;
1704 		(void) urtw_led_on(sc, URTW_LED_GPIO);
1705 		break;
1706 	case URTW_LED_BLINK_NORMAL:
1707 		if (sc->sc_gpio_ledinprogress != 0)
1708 			break;
1709 		sc->sc_gpio_ledinprogress = 1;
1710 		sc->sc_gpio_blinkstate = (sc->sc_gpio_ledon != 0) ?
1711 		    URTW_LED_OFF : URTW_LED_ON;
1712 		URTW_LEDLOCK(sc);
1713 		if (sc->sc_led_ch == 0) {
1714 			URTW8187_DBG(URTW_DEBUG_LED, (sc->sc_dev, CE_CONT,
1715 			    "urtw_led_mode0: restart led timer\n"));
1716 			sc->sc_led_ch = timeout(urtw_led_launch,
1717 			    (void *)sc,
1718 			    drv_usectohz((sc->sc_ic.ic_state ==
1719 			    IEEE80211_S_RUN) ?
1720 			    URTW_LED_LINKON_BLINK :
1721 			    URTW_LED_LINKOFF_BLINK));
1722 			sc->sc_gpio_ledinprogress = 0;
1723 		}
1724 		URTW_LEDUNLOCK(sc);
1725 		break;
1726 	case URTW_LED_POWER_ON_BLINK:
1727 		(void) urtw_led_on(sc, URTW_LED_GPIO);
1728 		urtw_delay_ms(100);
1729 		(void) urtw_led_off(sc, URTW_LED_GPIO);
1730 		break;
1731 	default:
1732 		URTW8187_DBG(URTW_DEBUG_LED, (sc->sc_dev, CE_CONT,
1733 		    "urtw_led_mode0: unknown LED status 0x%x",
1734 		    sc->sc_gpio_ledstate));
1735 	}
1736 	return (0);
1737 }
1738 
1739 static usbd_status
1740 urtw_led_mode1(struct urtw_softc *sc, int mode)
1741 {
1742 	cmn_err(CE_WARN, "urtw sc %p, mode %d not supported", (void *)sc, mode);
1743 	return (USBD_INVAL);
1744 }
1745 
1746 static usbd_status
1747 urtw_led_mode2(struct urtw_softc *sc, int mode)
1748 {
1749 	cmn_err(CE_WARN, "urtw sc %p, mode %d not supported", (void *)sc, mode);
1750 	return (USBD_INVAL);
1751 }
1752 
1753 static usbd_status
1754 urtw_led_mode3(struct urtw_softc *sc, int mode)
1755 {
1756 	cmn_err(CE_WARN, "urtw sc %p, mode %d not supported", (void *)sc, mode);
1757 	return (USBD_INVAL);
1758 }
1759 
1760 static usbd_status
1761 urtw_led_blink(struct urtw_softc *sc)
1762 {
1763 	uint8_t ing = 0;
1764 
1765 	URTW8187_DBG(URTW_DEBUG_LED, (sc->sc_dev, CE_CONT,
1766 	    "urtw_led_blink: gpio_blinkstate %d\n",
1767 	    sc->sc_gpio_blinkstate));
1768 	if (sc->sc_gpio_blinkstate == URTW_LED_ON)
1769 		(void) urtw_led_on(sc, URTW_LED_GPIO);
1770 	else
1771 		(void) urtw_led_off(sc, URTW_LED_GPIO);
1772 	sc->sc_gpio_blinktime--;
1773 	if (sc->sc_gpio_blinktime == 0)
1774 		ing = 1;
1775 	else {
1776 		if (sc->sc_gpio_ledstate != URTW_LED_BLINK_NORMAL &&
1777 		    sc->sc_gpio_ledstate != URTW_LED_BLINK_SLOWLY &&
1778 		    sc->sc_gpio_ledstate != URTW_LED_BLINK_CM3)
1779 			ing = 1;
1780 	}
1781 	if (ing == 1) {
1782 		if (sc->sc_gpio_ledstate == URTW_LED_ON &&
1783 		    sc->sc_gpio_ledon == 0)
1784 			(void) urtw_led_on(sc, URTW_LED_GPIO);
1785 		else if (sc->sc_gpio_ledstate == URTW_LED_OFF &&
1786 		    sc->sc_gpio_ledon == 1)
1787 			(void) urtw_led_off(sc, URTW_LED_GPIO);
1788 
1789 		sc->sc_gpio_blinktime = 0;
1790 		sc->sc_gpio_ledinprogress = 0;
1791 		return (0);
1792 	}
1793 
1794 	sc->sc_gpio_blinkstate = (sc->sc_gpio_blinkstate != URTW_LED_ON) ?
1795 	    URTW_LED_ON : URTW_LED_OFF;
1796 
1797 	switch (sc->sc_gpio_ledstate) {
1798 	case URTW_LED_BLINK_NORMAL:
1799 		URTW8187_DBG(URTW_DEBUG_LED, (sc->sc_dev, CE_CONT,
1800 		    "URTW_LED_BLINK_NORMAL\n"));
1801 		return (1);
1802 	default:
1803 		URTW8187_DBG(URTW_DEBUG_LED, (sc->sc_dev, CE_CONT,
1804 		    "unknown LED status 0x%x", sc->sc_gpio_ledstate));
1805 	}
1806 	return (0);
1807 }
1808 
1809 static usbd_status
1810 urtw_led_ctl(struct urtw_softc *sc, int mode)
1811 {
1812 	usbd_status error = 0;
1813 
1814 	switch (sc->sc_strategy) {
1815 	case URTW_SW_LED_MODE0:
1816 		error = urtw_led_mode0(sc, mode);
1817 		break;
1818 	case URTW_SW_LED_MODE1:
1819 		error = urtw_led_mode1(sc, mode);
1820 		break;
1821 	case URTW_SW_LED_MODE2:
1822 		error = urtw_led_mode2(sc, mode);
1823 		break;
1824 	case URTW_SW_LED_MODE3:
1825 		error = urtw_led_mode3(sc, mode);
1826 		break;
1827 	default:
1828 		cmn_err(CE_CONT, "unsupported LED mode %d\n", sc->sc_strategy);
1829 		/* never reach  */
1830 		return (-1);
1831 	}
1832 
1833 	return (error);
1834 }
1835 
1836 static usbd_status
1837 urtw_update_msr(struct urtw_softc *sc, int nstate)
1838 {
1839 	struct ieee80211com *ic = &sc->sc_ic;
1840 	uint8_t data;
1841 	usbd_status error;
1842 
1843 	if (error = urtw_read8_c(sc, URTW_MSR, &data, 0))
1844 		goto fail;
1845 	data &= ~URTW_MSR_LINK_MASK;
1846 
1847 	/* Should always be set. */
1848 	if (sc->sc_hwrev & URTW_HWREV_8187B)
1849 		data |= URTW_MSR_LINK_ENEDCA;
1850 
1851 	if (nstate == IEEE80211_S_RUN) {
1852 		switch (ic->ic_opmode) {
1853 		case IEEE80211_M_STA:
1854 		case IEEE80211_M_MONITOR:
1855 			data |= URTW_MSR_LINK_STA;
1856 			break;
1857 		case IEEE80211_M_IBSS:
1858 			data |= URTW_MSR_LINK_ADHOC;
1859 			break;
1860 		case IEEE80211_M_HOSTAP:
1861 			data |= URTW_MSR_LINK_HOSTAP;
1862 			break;
1863 		default:
1864 			cmn_err(CE_CONT, "unsupported operation mode 0x%x\n",
1865 			    ic->ic_opmode);
1866 			return (-1);
1867 		}
1868 	} else
1869 		data |= URTW_MSR_LINK_NONE;
1870 
1871 	error = urtw_write8_c(sc, URTW_MSR, data, 0);
1872 fail:
1873 	return (error);
1874 }
1875 
1876 static uint16_t
1877 urtw_rate2rtl(int rate)
1878 {
1879 #define	N(a)	(sizeof (a) / sizeof ((a)[0]))
1880 	int i;
1881 
1882 	for (i = 0; i < N(urtw_ratetable); i++) {
1883 		if (rate == urtw_ratetable[i].reg)
1884 			return (urtw_ratetable[i].val);
1885 	}
1886 	return (3);
1887 #undef N
1888 }
1889 
1890 static uint16_t
1891 urtw_rtl2rate(int rate)
1892 {
1893 #define	N(a)	(sizeof (a) / sizeof ((a)[0]))
1894 	int i;
1895 
1896 	for (i = 0; i < N(urtw_ratetable); i++) {
1897 		if (rate == urtw_ratetable[i].val)
1898 			return (urtw_ratetable[i].reg);
1899 	}
1900 
1901 	return (0);
1902 #undef N
1903 }
1904 
1905 static usbd_status
1906 urtw_set_rate(struct urtw_softc *sc)
1907 {
1908 	int i, basic_rate, min_rr_rate, max_rr_rate;
1909 	uint16_t data;
1910 	usbd_status error;
1911 
1912 	basic_rate = urtw_rate2rtl(48);
1913 	min_rr_rate = urtw_rate2rtl(12);
1914 	max_rr_rate = urtw_rate2rtl(48);
1915 	if (error = urtw_write8_c(sc, URTW_RESP_RATE,
1916 	    max_rr_rate << URTW_RESP_MAX_RATE_SHIFT |
1917 	    min_rr_rate << URTW_RESP_MIN_RATE_SHIFT, 0))
1918 		goto fail;
1919 
1920 	if (error = urtw_read16_c(sc, URTW_BRSR, &data, 0))
1921 		goto fail;
1922 	data &= ~URTW_BRSR_MBR_8185;
1923 
1924 	for (i = 0; i <= basic_rate; i++)
1925 		data |= (1 << i);
1926 
1927 	error = urtw_write16_c(sc, URTW_BRSR, data, 0);
1928 fail:
1929 	return (error);
1930 }
1931 
1932 static usbd_status
1933 urtw_intr_enable(struct urtw_softc *sc)
1934 {
1935 	usbd_status error;
1936 
1937 	error = urtw_write16_c(sc, URTW_INTR_MASK, 0xffff, 0);
1938 	return (error);
1939 }
1940 
1941 static usbd_status
1942 urtw_rx_setconf(struct urtw_softc *sc)
1943 {
1944 	struct ieee80211com *ic = &sc->sc_ic;
1945 	uint32_t data, a, b;
1946 	usbd_status error;
1947 
1948 	if (urtw_read32_c(sc, URTW_RX, &data, 0))
1949 		goto fail;
1950 	data = data &~ URTW_RX_FILTER_MASK;
1951 	data = data | URTW_RX_FILTER_MNG | URTW_RX_FILTER_DATA;
1952 	data = data | URTW_RX_FILTER_BCAST | URTW_RX_FILTER_MCAST;
1953 
1954 	if (ic->ic_opmode == IEEE80211_M_MONITOR) {
1955 		data = data | URTW_RX_FILTER_ICVERR;
1956 		data = data | URTW_RX_FILTER_PWR;
1957 	}
1958 	if (sc->sc_crcmon == 1 && ic->ic_opmode == IEEE80211_M_MONITOR)
1959 		data = data | URTW_RX_FILTER_CRCERR;
1960 	data = data | URTW_RX_FILTER_NICMAC;
1961 	data = data | URTW_RX_CHECK_BSSID;
1962 	data = data &~ URTW_RX_FIFO_THRESHOLD_MASK;
1963 	data = data | URTW_RX_FIFO_THRESHOLD_NONE | URTW_RX_AUTORESETPHY;
1964 	data = data &~ URTW_MAX_RX_DMA_MASK;
1965 	a = URTW_MAX_RX_DMA_2048;
1966 	b = 0x80000000;
1967 	data = data | a | b;
1968 
1969 	error = urtw_write32_c(sc, URTW_RX, data, 0);
1970 fail:
1971 	return (error);
1972 }
1973 
1974 static usbd_status
1975 urtw_rx_enable(struct urtw_softc *sc)
1976 {
1977 	int i;
1978 	usbd_status error;
1979 	uint8_t data;
1980 
1981 	sc->rx_queued = 0;
1982 	for (i = 0; i < URTW_RX_DATA_LIST_COUNT; i++) {
1983 		if (urtw_rx_start(sc) != 0) {
1984 			return (USB_FAILURE);
1985 		}
1986 	}
1987 
1988 	error = urtw_rx_setconf(sc);
1989 	if (error != 0)
1990 		goto fail;
1991 
1992 	if (error = urtw_read8_c(sc, URTW_CMD, &data, 0))
1993 		goto fail;
1994 	error = urtw_write8_c(sc, URTW_CMD, data | URTW_CMD_RX_ENABLE, 0);
1995 fail:
1996 	return (error);
1997 }
1998 
1999 void
2000 urtw_tx_enable(struct urtw_softc *sc)
2001 {
2002 	uint8_t data8;
2003 	uint32_t data;
2004 
2005 	if (sc->sc_hwrev & URTW_HWREV_8187) {
2006 		(void) urtw_read8_c(sc, URTW_CW_CONF, &data8, 0);
2007 		data8 &= ~(URTW_CW_CONF_PERPACKET_CW |
2008 		    URTW_CW_CONF_PERPACKET_RETRY);
2009 		(void) urtw_write8_c(sc, URTW_CW_CONF, data8, 0);
2010 		(void) urtw_read8_c(sc, URTW_TX_AGC_CTL, &data8, 0);
2011 		data8 &= ~URTW_TX_AGC_CTL_PERPACKET_GAIN;
2012 		data8 &= ~URTW_TX_AGC_CTL_PERPACKET_ANTSEL;
2013 		data8 &= ~URTW_TX_AGC_CTL_FEEDBACK_ANT;
2014 		(void) urtw_write8_c(sc, URTW_TX_AGC_CTL, data8, 0);
2015 
2016 		(void) urtw_read32_c(sc, URTW_TX_CONF, &data, 0);
2017 		data &= ~URTW_TX_LOOPBACK_MASK;
2018 		data |= URTW_TX_LOOPBACK_NONE;
2019 		data &= ~(URTW_TX_DPRETRY_MASK | URTW_TX_RTSRETRY_MASK);
2020 		data |= sc->sc_tx_retry << URTW_TX_DPRETRY_SHIFT;
2021 		data |= sc->sc_rts_retry << URTW_TX_RTSRETRY_SHIFT;
2022 		data &= ~(URTW_TX_NOCRC | URTW_TX_MXDMA_MASK);
2023 		data |= URTW_TX_MXDMA_2048 | URTW_TX_CWMIN | URTW_TX_DISCW;
2024 		data &= ~URTW_TX_SWPLCPLEN;
2025 		data |= URTW_TX_NOICV;
2026 		(void) urtw_write32_c(sc, URTW_TX_CONF, data, 0);
2027 	} else {
2028 		data = URTW_TX_DURPROCMODE | URTW_TX_DISREQQSIZE |
2029 		    URTW_TX_MXDMA_2048 | URTW_TX_SHORTRETRY |
2030 		    URTW_TX_LONGRETRY;
2031 		(void) urtw_write32_c(sc, URTW_TX_CONF, data, 0);
2032 	}
2033 
2034 	(void) urtw_read8_c(sc, URTW_CMD, &data8, 0);
2035 	(void) urtw_write8_c(sc, URTW_CMD, data8 | URTW_CMD_TX_ENABLE, 0);
2036 }
2037 
2038 static int
2039 urtw_8187_init(void *arg)
2040 {
2041 	struct urtw_softc *sc = arg;
2042 	usbd_status error;
2043 	struct urtw_rf *rf = &sc->sc_rf;
2044 	int i;
2045 
2046 	urtw_stop(sc);
2047 	URTW_LOCK(sc);
2048 	error = urtw_8187_reset(sc);
2049 	if (error)
2050 		goto fail;
2051 
2052 	(void) urtw_write8_c(sc, 0x85, 0, 0);
2053 	(void) urtw_write8_c(sc, URTW_GPIO, 0, 0);
2054 
2055 	/* for led */
2056 	(void) urtw_write8_c(sc, 0x85, 4, 0);
2057 	error = urtw_led_ctl(sc, URTW_LED_CTL_POWER_ON);
2058 	if (error != 0)
2059 		goto fail;
2060 
2061 	error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
2062 	if (error)
2063 		goto fail;
2064 
2065 	/* applying MAC address again.  */
2066 	for (i = 0; i < IEEE80211_ADDR_LEN; i++)
2067 		(void) urtw_write8_c(sc, URTW_MAC0 + i,
2068 		    sc->sc_ic.ic_macaddr[i], 0);
2069 	error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
2070 	if (error)
2071 		goto fail;
2072 
2073 	error = urtw_update_msr(sc, IEEE80211_S_INIT);
2074 	if (error)
2075 		goto fail;
2076 
2077 	(void) urtw_write32_c(sc, URTW_INT_TIMEOUT, 0, 0);
2078 	(void) urtw_write8_c(sc, URTW_WPA_CONFIG, 0, 0);
2079 	(void) urtw_write8_c(sc, URTW_RATE_FALLBACK, 0x81, 0);
2080 	error = urtw_set_rate(sc);
2081 	if (error != 0)
2082 		goto fail;
2083 
2084 	error = rf->init(rf);
2085 	if (error != 0)
2086 		goto fail;
2087 	if (rf->set_sens != NULL)
2088 		rf->set_sens(rf);
2089 
2090 	(void) urtw_write16_c(sc, 0x5e, 1, 0);
2091 	(void) urtw_write16_c(sc, 0xfe, 0x10, 0);
2092 	(void) urtw_write8_c(sc, URTW_TALLY_SEL, 0x80, 0);
2093 	(void) urtw_write8_c(sc, 0xff, 0x60, 0);
2094 	(void) urtw_write16_c(sc, 0x5e, 0, 0);
2095 	(void) urtw_write8_c(sc, 0x85, 4, 0);
2096 
2097 	error = urtw_intr_enable(sc);
2098 	if (error != 0)
2099 		goto fail;
2100 
2101 	error = urtw_open_pipes(sc);
2102 	if (error != 0)
2103 		goto fail;
2104 	sc->sc_tx_low_queued = 0;
2105 	sc->sc_tx_normal_queued = 0;
2106 	error = urtw_rx_enable(sc);
2107 	if (error != 0)
2108 		goto fail;
2109 	urtw_tx_enable(sc);
2110 
2111 	if (error == 0) {
2112 		URTW8187_DBG(URTW_DEBUG_ACTIVE, (sc->sc_dev,
2113 		    CE_CONT, "urtw_8187_init: succesfully done\n"));
2114 		sc->sc_flags |= URTW_FLAG_RUNNING;
2115 		URTW_UNLOCK(sc);
2116 		return (error);
2117 	}
2118 
2119 fail:
2120 	URTW_UNLOCK(sc);
2121 	urtw_stop(sc);
2122 	return (EIO);
2123 }
2124 
2125 
2126 static usbd_status
2127 urtw_8225_usb_init(struct urtw_softc *sc)
2128 {
2129 	uint8_t data;
2130 	usbd_status error;
2131 
2132 	if (error = urtw_write8_c(sc, URTW_RF_PINS_SELECT + 1, 0, 0))
2133 		goto fail;
2134 	if (error = urtw_write8_c(sc, URTW_GPIO, 0, 0))
2135 		goto fail;
2136 	if (error = urtw_read8e(sc, 0x53, &data))
2137 		goto fail;
2138 	if (error = urtw_write8e(sc, 0x53, data | (1 << 7)))
2139 		goto fail;
2140 	if (error = urtw_write8_c(sc, URTW_RF_PINS_SELECT + 1, 4, 0))
2141 		goto fail;
2142 	if (error = urtw_write8_c(sc, URTW_GPIO, 0x20, 0))
2143 		goto fail;
2144 	if (error = urtw_write8_c(sc, URTW_GP_ENABLE, 0, 0))
2145 		goto fail;
2146 	if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT, 0x80, 0))
2147 		goto fail;
2148 	if (error = urtw_write16_c(sc, URTW_RF_PINS_SELECT, 0x80, 0))
2149 		goto fail;
2150 	error = urtw_write16_c(sc, URTW_RF_PINS_ENABLE, 0x80, 0);
2151 
2152 	urtw_delay_ms(100);
2153 fail:
2154 	return (error);
2155 }
2156 
2157 static usbd_status
2158 urtw_8185_rf_pins_enable(struct urtw_softc *sc)
2159 {
2160 	usbd_status error = 0;
2161 
2162 	error = urtw_write16_c(sc, URTW_RF_PINS_ENABLE, 0x1ff7, 0);
2163 	return (error);
2164 }
2165 
2166 static usbd_status
2167 urtw_8187_write_phy(struct urtw_softc *sc, uint8_t addr, uint32_t data)
2168 {
2169 	uint32_t phyw;
2170 	usbd_status error;
2171 
2172 	phyw = ((data << 8) | (addr | 0x80));
2173 	if (error = urtw_write8_c(sc, 0x7f, ((phyw & 0xff000000) >> 24), 0))
2174 		goto fail;
2175 	if (error = urtw_write8_c(sc, 0x7e, ((phyw & 0x00ff0000) >> 16), 0))
2176 		goto fail;
2177 	if (error = urtw_write8_c(sc, 0x7d, ((phyw & 0x0000ff00) >> 8), 0))
2178 		goto fail;
2179 	error = urtw_write8_c(sc, 0x7c, (phyw & 0x000000ff), 0);
2180 	/*
2181 	 * Delay removed from 8185 to 8187.
2182 	 * usbd_delay_ms(sc->sc_udev, 1);
2183 	 */
2184 fail:
2185 	return (error);
2186 }
2187 
2188 static usbd_status
2189 urtw_8187_write_phy_ofdm_c(struct urtw_softc *sc, uint8_t addr, uint32_t data)
2190 {
2191 	data = data & 0xff;
2192 	return (urtw_8187_write_phy(sc, addr, data));
2193 }
2194 
2195 static usbd_status
2196 urtw_8187_write_phy_cck_c(struct urtw_softc *sc, uint8_t addr, uint32_t data)
2197 {
2198 	data = data & 0xff;
2199 	return (urtw_8187_write_phy(sc, addr, (data | 0x10000)));
2200 }
2201 
2202 static usbd_status
2203 urtw_8225_setgain(struct urtw_softc *sc, int16_t gain)
2204 {
2205 	usbd_status error;
2206 
2207 	if (error = urtw_8187_write_phy_ofdm_c(sc, 0x0d,
2208 	    urtw_8225_gain[gain * 4]))
2209 		goto fail;
2210 	if (error = urtw_8187_write_phy_ofdm_c(sc, 0x1b,
2211 	    urtw_8225_gain[gain * 4 + 2]))
2212 		goto fail;
2213 	if (error = urtw_8187_write_phy_ofdm_c(sc, 0x1d,
2214 	    urtw_8225_gain[gain * 4 + 3]))
2215 		goto fail;
2216 	error = urtw_8187_write_phy_ofdm_c(sc, 0x23,
2217 	    urtw_8225_gain[gain * 4 + 1]);
2218 fail:
2219 	return (error);
2220 }
2221 
2222 static usbd_status
2223 urtw_8225_set_txpwrlvl(struct urtw_softc *sc, int chan)
2224 {
2225 	int i, idx, set;
2226 	uint8_t *cck_pwltable;
2227 	uint8_t cck_pwrlvl_max, ofdm_pwrlvl_min, ofdm_pwrlvl_max;
2228 	uint8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
2229 	uint8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
2230 	usbd_status error;
2231 
2232 	cck_pwrlvl_max = 11;
2233 	ofdm_pwrlvl_max = 25;	/* 12 -> 25  */
2234 	ofdm_pwrlvl_min = 10;
2235 
2236 	/* CCK power setting */
2237 	cck_pwrlvl = (cck_pwrlvl > cck_pwrlvl_max) ?
2238 	    cck_pwrlvl_max : cck_pwrlvl;
2239 	idx = cck_pwrlvl % 6;
2240 	set = cck_pwrlvl / 6;
2241 	cck_pwltable = (chan == 14) ? urtw_8225_txpwr_cck_ch14 :
2242 	    urtw_8225_txpwr_cck;
2243 
2244 	if (error = urtw_write8_c(sc, URTW_TX_GAIN_CCK,
2245 	    urtw_8225_tx_gain_cck_ofdm[set] >> 1, 0))
2246 		goto fail;
2247 	for (i = 0; i < 8; i++) {
2248 		if (error = urtw_8187_write_phy_cck_c(sc, 0x44 + i,
2249 		    cck_pwltable[idx * 8 + i]))
2250 			goto fail;
2251 	}
2252 	urtw_delay_ms(1);
2253 	/* OFDM power setting */
2254 	ofdm_pwrlvl = (ofdm_pwrlvl > (ofdm_pwrlvl_max - ofdm_pwrlvl_min)) ?
2255 	    ofdm_pwrlvl_max : ofdm_pwrlvl + ofdm_pwrlvl_min;
2256 	ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
2257 	idx = ofdm_pwrlvl % 6;
2258 	set = ofdm_pwrlvl / 6;
2259 
2260 	error = urtw_8185_set_anaparam2(sc, URTW_8187_8225_ANAPARAM2_ON);
2261 	if (error)
2262 		goto fail;
2263 	if (error = urtw_8187_write_phy_ofdm_c(sc, 2, 0x42))
2264 		goto fail;
2265 	if (error = urtw_8187_write_phy_ofdm_c(sc, 6, 0))
2266 		goto fail;
2267 	if (error = urtw_8187_write_phy_ofdm_c(sc, 8, 0))
2268 		goto fail;
2269 
2270 	if (error = urtw_write8_c(sc, URTW_TX_GAIN_OFDM,
2271 	    urtw_8225_tx_gain_cck_ofdm[set] >> 1, 0))
2272 		goto fail;
2273 	if (error = urtw_8187_write_phy_ofdm_c(sc, 0x5,
2274 	    urtw_8225_txpwr_ofdm[idx]))
2275 		goto fail;
2276 	error = urtw_8187_write_phy_ofdm_c(sc, 0x7,
2277 	    urtw_8225_txpwr_ofdm[idx]);
2278 	urtw_delay_ms(1);
2279 fail:
2280 	return (error);
2281 }
2282 
2283 static usbd_status
2284 urtw_8185_tx_antenna(struct urtw_softc *sc, uint8_t ant)
2285 {
2286 	usbd_status error;
2287 
2288 	error = urtw_write8_c(sc, URTW_TX_ANTENNA, ant, 0);
2289 	urtw_delay_ms(1);
2290 	return (error);
2291 }
2292 
2293 static usbd_status
2294 urtw_8225_rf_init(struct urtw_rf *rf)
2295 {
2296 #define	N(a)	(sizeof (a) / sizeof ((a)[0]))
2297 	int i;
2298 	uint16_t data;
2299 	usbd_status error;
2300 	struct urtw_softc *sc = rf->rf_sc;
2301 
2302 	error = urtw_8180_set_anaparam(sc, URTW_8187_8225_ANAPARAM_ON);
2303 	if (error)
2304 		goto fail;
2305 
2306 	if (error = urtw_8225_usb_init(sc))
2307 		goto fail;
2308 	if (error = urtw_write32_c(sc, URTW_RF_TIMING, 0x000a8008, 0))
2309 		goto fail;
2310 	if (error = urtw_read16_c(sc, URTW_BRSR, &data, 0))
2311 		goto fail;
2312 	if (error = urtw_write16_c(sc, URTW_BRSR, 0xffff, 0))
2313 		goto fail;
2314 	if (error = urtw_write32_c(sc, URTW_RF_PARA, 0x100044, 0))
2315 		goto fail;
2316 
2317 	if (error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG))
2318 		goto fail;
2319 	if (error = urtw_write8_c(sc, URTW_CONFIG3, 0x44, 0))
2320 		goto fail;
2321 	if (error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL))
2322 		goto fail;
2323 	if (error = urtw_8185_rf_pins_enable(sc))
2324 		goto fail;
2325 	urtw_delay_ms(100);
2326 
2327 	for (i = 0; i < N(urtw_8225_rf_part1); i++) {
2328 		if (error = urtw_8225_write_c(sc, urtw_8225_rf_part1[i].reg,
2329 		    urtw_8225_rf_part1[i].val))
2330 			goto fail;
2331 		urtw_delay_ms(1);
2332 	}
2333 	urtw_delay_ms(50);
2334 	if (error = urtw_8225_write_c(sc, 0x2, 0xc4d))
2335 		goto fail;
2336 	urtw_delay_ms(50);
2337 	if (error = urtw_8225_write_c(sc, 0x2, 0x44d))
2338 		goto fail;
2339 	urtw_delay_ms(50);
2340 	if (error = urtw_8225_write_c(sc, 0x0, 0x127))
2341 		goto fail;
2342 
2343 	for (i = 0; i < 95; i++) {
2344 		if (error = urtw_8225_write_c(sc, 0x1, (uint8_t)(i + 1)))
2345 			goto fail;
2346 		if (error = urtw_8225_write_c(sc, 0x2, urtw_8225_rxgain[i]))
2347 			goto fail;
2348 	}
2349 
2350 	if (error = urtw_8225_write_c(sc, 0x0, 0x27))
2351 		goto fail;
2352 	if (error = urtw_8225_write_c(sc, 0x0, 0x22f))
2353 		goto fail;
2354 
2355 	for (i = 0; i < 128; i++) {
2356 		if (error = urtw_8187_write_phy_ofdm_c(sc, 0xb,
2357 		    urtw_8225_agc[i]))
2358 			goto fail;
2359 		urtw_delay_ms(1);
2360 		if (error = urtw_8187_write_phy_ofdm_c(sc, 0xa,
2361 		    (uint8_t)i + 0x80))
2362 			goto fail;
2363 		urtw_delay_ms(1);
2364 	}
2365 
2366 	for (i = 0; i < N(urtw_8225_rf_part2); i++) {
2367 		if (error = urtw_8187_write_phy_ofdm_c(sc,
2368 		    urtw_8225_rf_part2[i].reg,
2369 		    urtw_8225_rf_part2[i].val))
2370 			goto fail;
2371 		urtw_delay_ms(1);
2372 	}
2373 	error = urtw_8225_setgain(sc, 4);
2374 	if (error)
2375 		goto fail;
2376 
2377 	for (i = 0; i < N(urtw_8225_rf_part3); i++) {
2378 		if (error = urtw_8187_write_phy_cck_c(sc,
2379 		    urtw_8225_rf_part3[i].reg,
2380 		    urtw_8225_rf_part3[i].val))
2381 			goto fail;
2382 		urtw_delay_ms(1);
2383 	}
2384 
2385 	if (error = urtw_write8_c(sc, 0x5b, 0x0d, 0))
2386 		goto fail;
2387 	if (error = urtw_8225_set_txpwrlvl(sc, 1))
2388 		goto fail;
2389 	if (error = urtw_8187_write_phy_cck_c(sc, 0x10, 0x9b))
2390 		goto fail;
2391 	urtw_delay_ms(1);
2392 	if (error = urtw_8187_write_phy_ofdm_c(sc, 0x26, 0x90))
2393 		goto fail;
2394 	urtw_delay_ms(1);
2395 
2396 	/* TX ant A, 0x0 for B */
2397 	if (error = urtw_8185_tx_antenna(sc, 0x3))
2398 		goto fail;
2399 	if (error = urtw_write32_c(sc, 0x94, 0x3dc00002, 0))
2400 		goto fail;
2401 
2402 	error = urtw_8225_rf_set_chan(rf,
2403 	    ieee80211_chan2ieee(&sc->sc_ic, sc->sc_ic.ic_curchan));
2404 fail:
2405 	return (error);
2406 #undef N
2407 }
2408 
2409 static usbd_status
2410 urtw_8225_rf_set_chan(struct urtw_rf *rf, int chan)
2411 {
2412 #define	IEEE80211_CHAN_G	\
2413 	(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN)
2414 #define	IEEE80211_IS_CHAN_G(_c)		\
2415 	(((_c)->ich_flags & IEEE80211_CHAN_G) == IEEE80211_CHAN_G)
2416 
2417 	struct urtw_softc *sc = rf->rf_sc;
2418 	struct ieee80211com *ic = &sc->sc_ic;
2419 	struct ieee80211_channel *c = ic->ic_curchan;
2420 	short gset = (IEEE80211_IS_CHAN_G(c)) ? 1 : 0;
2421 	usbd_status error;
2422 
2423 	if (error = urtw_8225_set_txpwrlvl(sc, chan))
2424 		goto fail;
2425 	if (urtw_8225_write_c(sc, 0x7, urtw_8225_channel[chan]))
2426 		goto fail;
2427 	urtw_delay_ms(10);
2428 
2429 	if (error = urtw_write8_c(sc, URTW_SIFS, 0x22, 0))
2430 		goto fail;
2431 
2432 	if (ic->ic_state == IEEE80211_S_ASSOC &&
2433 	    ic->ic_flags & IEEE80211_F_SHSLOT)
2434 		if (error = urtw_write8_c(sc, URTW_SLOT, 0x9, 0))
2435 			goto fail;
2436 	else
2437 		if (error = urtw_write8_c(sc, URTW_SLOT, 0x14, 0))
2438 			goto fail;
2439 	if (gset) {
2440 		/* for G */
2441 		if (error = urtw_write8_c(sc, URTW_DIFS, 0x14, 0))
2442 			goto fail;
2443 		if (error = urtw_write8_c(sc, URTW_EIFS, 0x5b - 0x14, 0))
2444 			goto fail;
2445 		error = urtw_write8_c(sc, URTW_CW_VAL, 0x73, 0);
2446 	} else {
2447 		/* for B */
2448 		if (error = urtw_write8_c(sc, URTW_DIFS, 0x24, 0))
2449 			goto fail;
2450 		if (error = urtw_write8_c(sc, URTW_EIFS, 0x5b - 0x24, 0))
2451 			goto fail;
2452 		error = urtw_write8_c(sc, URTW_CW_VAL, 0xa5, 0);
2453 	}
2454 
2455 fail:
2456 	return (error);
2457 }
2458 
2459 static usbd_status
2460 urtw_8225_rf_set_sens(struct urtw_rf *rf)
2461 {
2462 	usbd_status error;
2463 	struct urtw_softc *sc = rf->rf_sc;
2464 
2465 	if (rf->sens < 0 || rf->sens > 6)
2466 		return (-1);
2467 
2468 	if (rf->sens > 4)
2469 		if (error = urtw_8225_write_c(sc, 0x0c, 0x850))
2470 			goto fail;
2471 	else
2472 		if (error = urtw_8225_write_c(sc, 0x0c, 0x50))
2473 			goto fail;
2474 
2475 	rf->sens = 6 - rf->sens;
2476 	if (error = urtw_8225_setgain(sc, rf->sens))
2477 		goto fail;
2478 	error = urtw_8187_write_phy_cck_c(sc, 0x41,
2479 	    urtw_8225_threshold[rf->sens]);
2480 fail:
2481 	return (error);
2482 }
2483 
2484 static void
2485 urtw_stop(struct urtw_softc *sc)
2486 {
2487 	URTW_LOCK(sc);
2488 	sc->sc_flags &= ~URTW_FLAG_RUNNING;
2489 	URTW_UNLOCK(sc);
2490 	urtw_close_pipes(sc);
2491 }
2492 
2493 static int
2494 urtw_isbmode(uint16_t rate)
2495 {
2496 
2497 	rate = urtw_rtl2rate(rate);
2498 
2499 	return ((rate <= 22 && rate != 12 && rate != 18)?(1) : (0));
2500 }
2501 
2502 /* ARGSUSED */
2503 static void
2504 urtw_rxeof(usb_pipe_handle_t pipe, usb_bulk_req_t *req)
2505 {
2506 	struct urtw_softc *sc = (struct urtw_softc *)req->bulk_client_private;
2507 	struct ieee80211com *ic = &sc->sc_ic;
2508 	int actlen, len,  flen,  rssi;
2509 	uint8_t *desc, rate;
2510 	struct ieee80211_frame *wh;
2511 	struct ieee80211_node *ni = 0;
2512 	mblk_t *mp = 0;
2513 	uint8_t *rxbuf;
2514 
2515 	mp = req->bulk_data;
2516 	req->bulk_data = NULL;
2517 	if (req->bulk_completion_reason != USB_CR_OK ||
2518 	    mp == NULL) {
2519 		sc->sc_rx_err++;
2520 		URTW8187_DBG(URTW_DEBUG_RX_PROC, (sc->sc_dev, CE_CONT,
2521 		    "urtw_rxeof failed! %d, mp %p\n",
2522 		    req->bulk_completion_reason, mp));
2523 		req->bulk_data = mp;
2524 		goto fail;
2525 	}
2526 
2527 	actlen = MBLKL(mp);
2528 	rxbuf = (uint8_t *)mp->b_rptr;
2529 
2530 	if (sc->sc_hwrev & URTW_HWREV_8187)
2531 		/* 4 dword and 4 byte CRC  */
2532 		len = actlen - (4 * 4);
2533 	else
2534 		/* 5 dword and 4 byte CRC */
2535 		len = actlen - (4 * 5);
2536 
2537 	desc = rxbuf + len;
2538 	flen = ((desc[1] & 0x0f) << 8) + (desc[0] & 0xff);
2539 	if (flen > actlen) {
2540 		cmn_err(CE_CONT, "urtw_rxeof: impossible: flen %d, actlen %d\n",
2541 		    flen, actlen);
2542 		sc->sc_rx_err++;
2543 		req->bulk_data = mp;
2544 		goto fail;
2545 	}
2546 
2547 	rate = (desc[2] & 0xf0) >> 4;
2548 	if (sc->sc_hwrev & URTW_HWREV_8187) {
2549 		rssi = (desc[6] & 0xfe) >> 1;
2550 
2551 		/* XXX correct? */
2552 		if (!urtw_isbmode(rate)) {
2553 			rssi = (rssi > 90) ? 90 : ((rssi < 25) ? 25 : rssi);
2554 			rssi = ((90 - rssi) * 100) / 65;
2555 		} else {
2556 			rssi = (rssi > 90) ? 95 : ((rssi < 30) ? 30 : rssi);
2557 			rssi = ((95 - rssi) * 100) / 65;
2558 		}
2559 	} else {
2560 		rssi = 14 + desc[13]/2;
2561 		if (rssi >= 95)
2562 			rssi = 95;
2563 		URTW8187_DBG(URTW_DEBUG_RX_PROC, (sc->sc_dev, CE_CONT,
2564 		    "urtw_rxeof: rssi %u\n", rssi));
2565 	}
2566 
2567 	mp->b_wptr = mp->b_rptr + flen - 4;
2568 	wh = (struct ieee80211_frame *)mp->b_rptr;
2569 	if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK)
2570 	    == IEEE80211_FC0_TYPE_DATA) {
2571 		sc->sc_currate = (rate > 0) ? rate : sc->sc_currate;
2572 		URTW8187_DBG(URTW_DEBUG_RX_PROC, (sc->sc_dev, CE_CONT,
2573 		    "urtw_rxeof: update sc_currate to %u\n",
2574 		    sc->sc_currate));
2575 	}
2576 	ni = ieee80211_find_rxnode(ic, wh);
2577 
2578 	/* send the frame to the 802.11 layer */
2579 	(void) ieee80211_input(ic, mp, ni, rssi, 0);
2580 
2581 	/* node is no longer needed */
2582 	ieee80211_free_node(ni);
2583 fail:
2584 	mutex_enter(&sc->rx_lock);
2585 	sc->rx_queued--;
2586 	mutex_exit(&sc->rx_lock);
2587 	usb_free_bulk_req(req);
2588 	if (URTW_IS_RUNNING(sc) && !URTW_IS_SUSPENDING(sc))
2589 		(void) urtw_rx_start(sc);
2590 }
2591 
2592 static usbd_status
2593 urtw_8225v2_setgain(struct urtw_softc *sc, int16_t gain)
2594 {
2595 	uint8_t *gainp;
2596 	usbd_status error;
2597 
2598 	/* XXX for A?  */
2599 	gainp = urtw_8225v2_gain_bg;
2600 	if (error = urtw_8187_write_phy_ofdm_c(sc, 0x0d, gainp[gain * 3]))
2601 		goto fail;
2602 	urtw_delay_ms(1);
2603 	if (error = urtw_8187_write_phy_ofdm_c(sc, 0x1b, gainp[gain * 3 + 1]))
2604 	urtw_delay_ms(1);
2605 	if (error = urtw_8187_write_phy_ofdm_c(sc, 0x1d, gainp[gain * 3 + 2]))
2606 		goto fail;
2607 	urtw_delay_ms(1);
2608 	if (error = urtw_8187_write_phy_ofdm_c(sc, 0x21, 0x17))
2609 		goto fail;
2610 	urtw_delay_ms(1);
2611 fail:
2612 	return (error);
2613 }
2614 
2615 static usbd_status
2616 urtw_8225v2_set_txpwrlvl(struct urtw_softc *sc, int chan)
2617 {
2618 	int i;
2619 	uint8_t *cck_pwrtable;
2620 	uint8_t cck_pwrlvl_max = 15, ofdm_pwrlvl_max = 25, ofdm_pwrlvl_min = 10;
2621 	uint8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
2622 	uint8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
2623 	usbd_status error;
2624 
2625 	/* CCK power setting */
2626 	cck_pwrlvl = (cck_pwrlvl > cck_pwrlvl_max) ?
2627 	    cck_pwrlvl_max : cck_pwrlvl;
2628 	cck_pwrlvl += sc->sc_txpwr_cck_base;
2629 	cck_pwrlvl = (cck_pwrlvl > 35) ? 35 : cck_pwrlvl;
2630 	cck_pwrtable = (chan == 14) ? urtw_8225v2_txpwr_cck_ch14 :
2631 	    urtw_8225v2_txpwr_cck;
2632 
2633 	for (i = 0; i < 8; i++) {
2634 		if (error = urtw_8187_write_phy_cck_c(sc, 0x44 + i,
2635 		    cck_pwrtable[i]))
2636 			goto fail;
2637 	}
2638 	if (error = urtw_write8_c(sc, URTW_TX_GAIN_CCK,
2639 	    urtw_8225v2_tx_gain_cck_ofdm[cck_pwrlvl], 0))
2640 		goto fail;
2641 	urtw_delay_ms(1);
2642 
2643 	/* OFDM power setting */
2644 	ofdm_pwrlvl = (ofdm_pwrlvl > (ofdm_pwrlvl_max - ofdm_pwrlvl_min)) ?
2645 	    ofdm_pwrlvl_max : ofdm_pwrlvl + ofdm_pwrlvl_min;
2646 	ofdm_pwrlvl += sc->sc_txpwr_ofdm_base;
2647 	ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
2648 
2649 	error = urtw_8185_set_anaparam2(sc, URTW_8187_8225_ANAPARAM2_ON);
2650 	if (error)
2651 		goto fail;
2652 
2653 	if (error = urtw_8187_write_phy_ofdm_c(sc, 2, 0x42))
2654 		goto fail;
2655 	if (error = urtw_8187_write_phy_ofdm_c(sc, 5, 0x0))
2656 		goto fail;
2657 	if (error = urtw_8187_write_phy_ofdm_c(sc, 6, 0x40))
2658 		goto fail;
2659 	if (error = urtw_8187_write_phy_ofdm_c(sc, 7, 0x0))
2660 		goto fail;
2661 	if (error = urtw_8187_write_phy_ofdm_c(sc, 8, 0x40))
2662 		goto fail;
2663 
2664 	error = urtw_write8_c(sc, URTW_TX_GAIN_OFDM,
2665 	    urtw_8225v2_tx_gain_cck_ofdm[ofdm_pwrlvl], 0);
2666 	urtw_delay_ms(1);
2667 fail:
2668 	return (error);
2669 }
2670 
2671 static usbd_status
2672 urtw_8225v2_rf_init(struct urtw_rf *rf)
2673 {
2674 #define	N(a)	(sizeof (a)/ sizeof ((a)[0]))
2675 	int i;
2676 	uint16_t data;
2677 	uint32_t data32;
2678 	usbd_status error;
2679 	struct urtw_softc *sc = rf->rf_sc;
2680 
2681 	if (error = urtw_8180_set_anaparam(sc, URTW_8187_8225_ANAPARAM_ON))
2682 		goto fail;
2683 	if (error = urtw_8225_usb_init(sc))
2684 		goto fail;
2685 	if (error = urtw_write32_c(sc, URTW_RF_TIMING, 0x000a8008, 0))
2686 		goto fail;
2687 	if (error = urtw_read16_c(sc, URTW_BRSR, &data, 0))
2688 		goto fail;
2689 	if (error = urtw_write16_c(sc, URTW_BRSR, 0xffff, 0))
2690 		goto fail;
2691 	if (error = urtw_write32_c(sc, URTW_RF_PARA, 0x100044, 0))
2692 		goto fail;
2693 	if (error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG))
2694 		goto fail;
2695 	if (error = urtw_write8_c(sc, URTW_CONFIG3, 0x44, 0))
2696 		goto fail;
2697 	if (error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL))
2698 		goto fail;
2699 	if (error = urtw_8185_rf_pins_enable(sc))
2700 		goto fail;
2701 
2702 	urtw_delay_ms(500);
2703 
2704 	for (i = 0; i < N(urtw_8225v2_rf_part1); i++) {
2705 		if (error = urtw_8225_write_c(sc, urtw_8225v2_rf_part1[i].reg,
2706 		    urtw_8225v2_rf_part1[i].val))
2707 			goto fail;
2708 		urtw_delay_ms(1);
2709 	}
2710 	urtw_delay_ms(100);
2711 
2712 	if (error = urtw_8225_write_c(sc, 0x0, 0x1b7))
2713 		goto fail;
2714 
2715 	for (i = 0; i < 95; i++) {
2716 		if (error = urtw_8225_write_c(sc, 0x1, (uint8_t)(i + 1)))
2717 			goto fail;
2718 		urtw_delay_ms(1);
2719 		if (error = urtw_8225_write_c(sc, 0x2, urtw_8225v2_rxgain[i]))
2720 			goto fail;
2721 		urtw_delay_ms(1);
2722 	}
2723 
2724 	if (error = urtw_8225_write_c(sc, 0x3, 0x2))
2725 		goto fail;
2726 	urtw_delay_ms(1);
2727 	if (error = urtw_8225_write_c(sc, 0x5, 0x4))
2728 		goto fail;
2729 	urtw_delay_ms(1);
2730 	if (error = urtw_8225_write_c(sc, 0x0, 0xb7))
2731 		goto fail;
2732 	urtw_delay_ms(1);
2733 	if (error = urtw_8225_write_c(sc, 0x2, 0xc4d))
2734 		goto fail;
2735 	urtw_delay_ms(100);
2736 	if (error = urtw_8225_write_c(sc, 0x2, 0x44d))
2737 		goto fail;
2738 	urtw_delay_ms(100);
2739 
2740 	if (error = urtw_8225_read(sc, 0x6, &data32))
2741 		goto fail;
2742 	if (data32 != 0xe6) {
2743 		error = (-1);
2744 		cmn_err(CE_WARN, "expect 0xe6!! (0x%x)\n", data32);
2745 		goto fail;
2746 	}
2747 	if (!(data32 & 0x80)) {
2748 		if (error = urtw_8225_write_c(sc, 0x02, 0x0c4d))
2749 			goto fail;
2750 		urtw_delay_ms(200);
2751 		if (error = urtw_8225_write_c(sc, 0x02, 0x044d))
2752 			goto fail;
2753 		urtw_delay_ms(100);
2754 		if (error = urtw_8225_read(sc, 0x6, &data32))
2755 			goto fail;
2756 		if (!(data32 & 0x80))
2757 			cmn_err(CE_CONT, "RF calibration failed\n");
2758 	}
2759 	urtw_delay_ms(200);
2760 
2761 	if (error = urtw_8225_write_c(sc, 0x0, 0x2bf))
2762 		goto fail;
2763 	for (i = 0; i < 128; i++) {
2764 		if (error = urtw_8187_write_phy_ofdm_c(sc, 0xb,
2765 		    urtw_8225_agc[i]))
2766 			goto fail;
2767 		urtw_delay_ms(1);
2768 		if (error = urtw_8187_write_phy_ofdm_c(sc, 0xa,
2769 		    (uint8_t)i + 0x80))
2770 			goto fail;
2771 		urtw_delay_ms(1);
2772 	}
2773 	urtw_delay_ms(1);
2774 
2775 	for (i = 0; i < N(urtw_8225v2_rf_part2); i++) {
2776 		if (error = urtw_8187_write_phy_ofdm_c(sc,
2777 		    urtw_8225v2_rf_part2[i].reg,
2778 		    urtw_8225v2_rf_part2[i].val))
2779 			goto fail;
2780 		urtw_delay_ms(1);
2781 	}
2782 	error = urtw_8225v2_setgain(sc, 4);
2783 	if (error)
2784 		goto fail;
2785 
2786 	for (i = 0; i < N(urtw_8225v2_rf_part3); i++) {
2787 		if (error = urtw_8187_write_phy_cck_c(sc,
2788 		    urtw_8225v2_rf_part3[i].reg,
2789 		    urtw_8225v2_rf_part3[i].val))
2790 			goto fail;
2791 		urtw_delay_ms(1);
2792 	}
2793 
2794 	if (error = urtw_write8_c(sc, 0x5b, 0x0d, 0))
2795 		goto fail;
2796 	if (error = urtw_8225v2_set_txpwrlvl(sc, 1))
2797 		goto fail;
2798 	if (error = urtw_8187_write_phy_cck_c(sc, 0x10, 0x9b))
2799 		goto fail;
2800 	urtw_delay_ms(1);
2801 	if (error = urtw_8187_write_phy_ofdm_c(sc, 0x26, 0x90))
2802 		goto fail;
2803 	urtw_delay_ms(1);
2804 
2805 	/* TX ant A, 0x0 for B */
2806 	if (error = urtw_8185_tx_antenna(sc, 0x3))
2807 		goto fail;
2808 	if (error = urtw_write32_c(sc, 0x94, 0x3dc00002, 0))
2809 		goto fail;
2810 
2811 	error = urtw_8225_rf_set_chan(rf,
2812 	    ieee80211_chan2ieee(&sc->sc_ic, sc->sc_ic.ic_curchan));
2813 fail:
2814 	return (error);
2815 #undef N
2816 }
2817 
2818 static usbd_status
2819 urtw_8225v2_rf_set_chan(struct urtw_rf *rf, int chan)
2820 {
2821 	struct urtw_softc *sc = rf->rf_sc;
2822 	struct ieee80211com *ic = &sc->sc_ic;
2823 	struct ieee80211_channel *c = ic->ic_curchan;
2824 	short gset = (IEEE80211_IS_CHAN_G(c)) ? 1 : 0;
2825 	usbd_status error;
2826 
2827 	if (error = urtw_8225v2_set_txpwrlvl(sc, chan))
2828 		goto fail;
2829 
2830 	if (error = urtw_8225_write_c(sc, 0x7, urtw_8225_channel[chan]))
2831 		goto fail;
2832 
2833 	urtw_delay_ms(10);
2834 
2835 	if (error = urtw_write8_c(sc, URTW_SIFS, 0x22, 0))
2836 		goto fail;
2837 
2838 	if (ic->ic_state == IEEE80211_S_ASSOC &&
2839 	    ic->ic_flags & IEEE80211_F_SHSLOT) {
2840 		if (error = urtw_write8_c(sc, URTW_SLOT, 0x9, 0))
2841 			goto fail;
2842 	} else
2843 		if (error = urtw_write8_c(sc, URTW_SLOT, 0x14, 0))
2844 			goto fail;
2845 	if (gset) {
2846 		/* for G */
2847 		if (error = urtw_write8_c(sc, URTW_DIFS, 0x14, 0))
2848 			goto fail;
2849 		if (error = urtw_write8_c(sc, URTW_EIFS, 0x5b - 0x14, 0))
2850 			goto fail;
2851 		if (error = urtw_write8_c(sc, URTW_CW_VAL, 0x73, 0))
2852 			goto fail;
2853 	} else {
2854 		/* for B */
2855 		if (error = urtw_write8_c(sc, URTW_DIFS, 0x24, 0))
2856 			goto fail;
2857 		if (error = urtw_write8_c(sc, URTW_EIFS, 0x5b - 0x24, 0))
2858 			goto fail;
2859 		if (error = urtw_write8_c(sc, URTW_CW_VAL, 0xa5, 0))
2860 			goto fail;
2861 	}
2862 
2863 fail:
2864 	return (error);
2865 }
2866 
2867 static int
2868 urtw_set_channel(struct urtw_softc *sc)
2869 {
2870 	struct ieee80211com *ic = &sc->sc_ic;
2871 	struct urtw_rf *rf = &sc->sc_rf;
2872 	uint32_t data;
2873 	usbd_status error;
2874 
2875 	if (error = urtw_read32_c(sc, URTW_TX_CONF, &data, 0))
2876 		goto fail;
2877 	data &= ~URTW_TX_LOOPBACK_MASK;
2878 	if (error = urtw_write32_c(sc, URTW_TX_CONF,
2879 	    data | URTW_TX_LOOPBACK_MAC, 0))
2880 		goto fail;
2881 	error = rf->set_chan(rf, ieee80211_chan2ieee(ic, ic->ic_curchan));
2882 	if (error)
2883 		goto fail;
2884 	urtw_delay_ms(20);
2885 	error = urtw_write32_c(sc, URTW_TX_CONF,
2886 	    data | URTW_TX_LOOPBACK_NONE, 0);
2887 fail:
2888 	return (error);
2889 }
2890 
2891 /* ARGSUSED */
2892 static void
2893 urtw_txeof_low(usb_pipe_handle_t pipe, usb_bulk_req_t *req)
2894 {
2895 	struct urtw_softc *sc = (struct urtw_softc *)req->bulk_client_private;
2896 	struct ieee80211com *ic = &sc->sc_ic;
2897 
2898 	URTW8187_DBG(URTW_DEBUG_TX_PROC, (sc->sc_dev, CE_CONT,
2899 	    "urtw_txeof_low(): cr:%s(%d), flags:0x%x, tx_queued:%d",
2900 	    usb_str_cr(req->bulk_completion_reason),
2901 	    req->bulk_completion_reason,
2902 	    req->bulk_cb_flags,
2903 	    sc->sc_tx_low_queued));
2904 	mutex_enter(&sc->tx_lock);
2905 	if (req->bulk_completion_reason != USB_CR_OK) {
2906 		ic->ic_stats.is_tx_failed++;
2907 		goto fail;
2908 	}
2909 
2910 	if (sc->sc_need_sched) {
2911 		sc->sc_need_sched = 0;
2912 		mac_tx_update(ic->ic_mach);
2913 	}
2914 fail:
2915 	sc->sc_tx_low_queued--;
2916 	mutex_exit(&sc->tx_lock);
2917 	usb_free_bulk_req(req);
2918 }
2919 
2920 /* ARGSUSED */
2921 static void
2922 urtw_txeof_normal(usb_pipe_handle_t pipe, usb_bulk_req_t *req)
2923 {
2924 	struct urtw_softc *sc = (struct urtw_softc *)req->bulk_client_private;
2925 	struct ieee80211com *ic = &sc->sc_ic;
2926 
2927 	URTW8187_DBG(URTW_DEBUG_ACTIVE, (sc->sc_dev, CE_CONT,
2928 	    "urtw_txeof_normal(): cr:%s(%d), flags:0x%x, tx_queued:%d",
2929 	    usb_str_cr(req->bulk_completion_reason),
2930 	    req->bulk_completion_reason,
2931 	    req->bulk_cb_flags,
2932 	    sc->sc_tx_normal_queued));
2933 
2934 	mutex_enter(&sc->tx_lock);
2935 	if (req->bulk_completion_reason != USB_CR_OK) {
2936 		ic->ic_stats.is_tx_failed++;
2937 		goto fail;
2938 	}
2939 
2940 	if (sc->sc_need_sched) {
2941 		sc->sc_need_sched = 0;
2942 		mac_tx_update(ic->ic_mach);
2943 	}
2944 fail:
2945 	sc->sc_tx_normal_queued--;
2946 	mutex_exit(&sc->tx_lock);
2947 	usb_free_bulk_req(req);
2948 }
2949 
2950 
2951 static int
2952 urtw_get_rate(struct ieee80211com *ic)
2953 {
2954 	uint8_t (*rates)[IEEE80211_RATE_MAXSIZE];
2955 	int rate;
2956 
2957 	rates = &ic->ic_bss->in_rates.ir_rates;
2958 
2959 	if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE)
2960 		rate = ic->ic_fixed_rate;
2961 	else if (ic->ic_state == IEEE80211_S_RUN)
2962 		rate = (*rates)[ic->ic_bss->in_txrate];
2963 	else
2964 		rate = 0;
2965 	return (rate & IEEE80211_RATE_VAL);
2966 }
2967 
2968 void
2969 urtw_8187b_update_wmm(struct urtw_softc *sc)
2970 {
2971 	struct ieee80211com *ic = &sc->sc_ic;
2972 	struct ieee80211_channel *c = ic->ic_curchan;
2973 	uint32_t data;
2974 	uint8_t aifs, sifs, slot, ecwmin, ecwmax;
2975 
2976 	sifs = 0xa;
2977 	if (IEEE80211_IS_CHAN_G(c))
2978 		slot = 0x9;
2979 	else
2980 		slot = 0x14;
2981 
2982 	aifs = (2 * slot) + sifs;
2983 	ecwmin = 3;
2984 	ecwmax = 7;
2985 
2986 	data = ((uint32_t)aifs << 0) |		/* AIFS, offset 0 */
2987 	    ((uint32_t)ecwmin << 8) |		/* ECW minimum, offset 8 */
2988 	    ((uint32_t)ecwmax << 12);		/* ECW maximum, offset 16 */
2989 
2990 	(void) urtw_write32_c(sc, URTW_AC_VO, data, 0);
2991 	(void) urtw_write32_c(sc, URTW_AC_VI, data, 0);
2992 	(void) urtw_write32_c(sc, URTW_AC_BE, data, 0);
2993 	(void) urtw_write32_c(sc, URTW_AC_BK, data, 0);
2994 }
2995 
2996 usbd_status
2997 urtw_8187b_reset(struct urtw_softc *sc)
2998 {
2999 	uint8_t data;
3000 	usbd_status error;
3001 
3002 	error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3003 	if (error)
3004 		goto fail;
3005 
3006 	(void) urtw_read8_c(sc, URTW_CONFIG3, &data, 0);
3007 	(void) urtw_write8_c(sc, URTW_CONFIG3,
3008 	    data | URTW_CONFIG3_ANAPARAM_WRITE |
3009 	    URTW_CONFIG3_GNT_SELECT, 0);
3010 
3011 	(void) urtw_write32_c(sc, URTW_ANAPARAM2,
3012 	    URTW_8187B_8225_ANAPARAM2_ON, 0);
3013 	(void) urtw_write32_c(sc, URTW_ANAPARAM,
3014 	    URTW_8187B_8225_ANAPARAM_ON, 0);
3015 	(void) urtw_write8_c(sc, URTW_ANAPARAM3,
3016 	    URTW_8187B_8225_ANAPARAM3_ON, 0);
3017 
3018 	(void) urtw_write8_c(sc, 0x61, 0x10, 0);
3019 	(void) urtw_read8_c(sc, 0x62, &data, 0);
3020 	(void) urtw_write8_c(sc, 0x62, data & ~(1 << 5), 0);
3021 	(void) urtw_write8_c(sc, 0x62, data | (1 << 5), 0);
3022 
3023 	(void) urtw_read8_c(sc, URTW_CONFIG3, &data, 0);
3024 	(void) urtw_write8_c(sc, URTW_CONFIG3,
3025 	    data & ~URTW_CONFIG3_ANAPARAM_WRITE, 0);
3026 
3027 	error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3028 	if (error)
3029 		goto fail;
3030 
3031 	(void) urtw_read8_c(sc, URTW_CMD, &data, 0);
3032 	data = (data & 2) | URTW_CMD_RST;
3033 	(void) urtw_write8_c(sc, URTW_CMD, data, 0);
3034 	urtw_delay_ms(100);
3035 
3036 	(void) urtw_read8_c(sc, URTW_CMD, &data, 0);
3037 	if (data & URTW_CMD_RST) {
3038 		cmn_err(CE_WARN, "urtw: 8187b reset timeout\n");
3039 		goto fail;
3040 	}
3041 
3042 fail:
3043 	return (error);
3044 }
3045 
3046 static int
3047 urtw_8187b_init(void *arg)
3048 {
3049 	struct urtw_softc *sc = arg;
3050 	struct urtw_rf *rf = &sc->sc_rf;
3051 	struct ieee80211com *ic = &sc->sc_ic;
3052 	int i;
3053 	uint8_t data;
3054 	usbd_status error;
3055 
3056 	urtw_stop(sc);
3057 	URTW_LOCK(sc);
3058 	urtw_8187b_update_wmm(sc);
3059 	error = urtw_8187b_reset(sc);
3060 	if (error)
3061 		goto fail;
3062 
3063 	error = urtw_open_pipes(sc);
3064 	if (error != 0)
3065 		goto fail;
3066 	/* Applying MAC address again. */
3067 	error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3068 	if (error)
3069 		goto fail;
3070 	for (i = 0; i < IEEE80211_ADDR_LEN; i++)
3071 		(void) urtw_write8_c(sc, URTW_MAC0 + i,
3072 		    ic->ic_macaddr[i], 0);
3073 	error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3074 	if (error)
3075 		goto fail;
3076 
3077 	error = urtw_update_msr(sc, IEEE80211_S_INIT);
3078 	if (error)
3079 		goto fail;
3080 
3081 	error = rf->init(rf);
3082 	if (error != 0)
3083 		goto fail;
3084 	error = urtw_intr_enable(sc);
3085 	if (error != 0)
3086 		goto fail;
3087 
3088 	error = urtw_write8e(sc, 0x41, 0xf4);
3089 	if (error != 0)
3090 		goto fail;
3091 	error = urtw_write8e(sc, 0x40, 0x00);
3092 	if (error != 0)
3093 		goto fail;
3094 	error = urtw_write8e(sc, 0x42, 0x00);
3095 	if (error != 0)
3096 		goto fail;
3097 	error = urtw_write8e(sc, 0x42, 0x01);
3098 	if (error != 0)
3099 		goto fail;
3100 	error = urtw_write8e(sc, 0x40, 0x0f);
3101 	if (error != 0)
3102 		goto fail;
3103 	error = urtw_write8e(sc, 0x42, 0x00);
3104 	if (error != 0)
3105 		goto fail;
3106 	error = urtw_write8e(sc, 0x42, 0x01);
3107 	if (error != 0)
3108 		goto fail;
3109 
3110 	(void) urtw_read8_c(sc, 0xdb, &data, 0);
3111 	(void) urtw_write8_c(sc, 0xdb, data | (1 << 2), 0);
3112 	(void) urtw_write16_c(sc, 0x72, 0x59fa, 3);
3113 	(void) urtw_write16_c(sc, 0x74, 0x59d2, 3);
3114 	(void) urtw_write16_c(sc, 0x76, 0x59d2, 3);
3115 	(void) urtw_write16_c(sc, 0x78, 0x19fa, 3);
3116 	(void) urtw_write16_c(sc, 0x7a, 0x19fa, 3);
3117 	(void) urtw_write16_c(sc, 0x7c, 0x00d0, 3);
3118 	(void) urtw_write8_c(sc, 0x61, 0, 0);
3119 	(void) urtw_write8_c(sc, 0x80, 0x0f, 1);
3120 	(void) urtw_write8_c(sc, 0x83, 0x03, 1);
3121 	(void) urtw_write8_c(sc, 0xda, 0x10, 0);
3122 	(void) urtw_write8_c(sc, 0x4d, 0x08, 2);
3123 
3124 	(void) urtw_write32_c(sc, URTW_HSSI_PARA, 0x0600321b, 0);
3125 	(void) urtw_write16_c(sc, 0xec, 0x0800, 1);
3126 	(void) urtw_write8_c(sc, URTW_ACM_CONTROL, 0, 0);
3127 
3128 	sc->sc_tx_low_queued = 0;
3129 	sc->sc_tx_normal_queued = 0;
3130 	error = urtw_rx_enable(sc);
3131 	if (error != 0)
3132 		goto fail;
3133 	urtw_tx_enable(sc);
3134 
3135 	if (error == 0) {
3136 		URTW8187_DBG(URTW_DEBUG_ACTIVE, (sc->sc_dev,
3137 		    CE_CONT, "urtw_8187b_init: done\n"));
3138 		sc->sc_flags |= URTW_FLAG_RUNNING;
3139 		URTW_UNLOCK(sc);
3140 		return (error);
3141 	}
3142 
3143 fail:
3144 	cmn_err(CE_WARN, "urtw_8187b_init failed\n");
3145 	URTW_UNLOCK(sc);
3146 	urtw_stop(sc);
3147 	return (EIO);
3148 }
3149 
3150 void
3151 urtw_8225v2_b_config_mac(struct urtw_softc *sc)
3152 {
3153 	int i;
3154 	int nitems = sizeof (urtw_8187b_regtbl)
3155 	    / sizeof ((urtw_8187b_regtbl)[0]);
3156 
3157 	for (i = 0; i < nitems; i++) {
3158 		(void) urtw_write8_c(sc, urtw_8187b_regtbl[i].reg,
3159 		    urtw_8187b_regtbl[i].val, urtw_8187b_regtbl[i].idx);
3160 	}
3161 
3162 	(void) urtw_write16_c(sc, URTW_TID_AC_MAP, 0xfa50, 0);
3163 	(void) urtw_write16_c(sc, URTW_INT_MIG, 0, 0);
3164 
3165 	(void) urtw_write32_c(sc, 0xf0, 0, 1);
3166 	(void) urtw_write32_c(sc, 0xf4, 0, 1);
3167 	(void) urtw_write8_c(sc, 0xf8, 0, 1);
3168 
3169 	(void) urtw_write32_c(sc, URTW_RF_TIMING, 0x00004001, 0);
3170 }
3171 
3172 void
3173 urtw_8225v2_b_init_rfe(struct urtw_softc *sc)
3174 {
3175 	(void) urtw_write16_c(sc, URTW_RF_PINS_OUTPUT, 0x0480, 0);
3176 	(void) urtw_write16_c(sc, URTW_RF_PINS_SELECT, 0x2488, 0);
3177 	(void) urtw_write16_c(sc, URTW_RF_PINS_ENABLE, 0x1fff, 0);
3178 	urtw_delay_ms(100);
3179 }
3180 
3181 usbd_status
3182 urtw_8225v2_b_update_chan(struct urtw_softc *sc)
3183 {
3184 	struct ieee80211com *ic = &sc->sc_ic;
3185 	struct ieee80211_channel *c = ic->ic_curchan;
3186 	uint8_t aifs, difs, eifs, sifs, slot;
3187 
3188 	(void) urtw_write8_c(sc, URTW_SIFS, 0x22, 0);
3189 
3190 	sifs = 0xa;
3191 	if (IEEE80211_IS_CHAN_G(c)) {
3192 		slot = 0x9;
3193 		difs = 0x1c;
3194 		eifs = 0x5b;
3195 	} else {
3196 		slot = 0x14;
3197 		difs = 0x32;
3198 		eifs = 0x5b;
3199 	}
3200 	aifs = (2 * slot) + sifs;
3201 
3202 	(void) urtw_write8_c(sc, URTW_SLOT, slot, 0);
3203 
3204 	(void) urtw_write8_c(sc, URTW_AC_VO, aifs, 0);
3205 	(void) urtw_write8_c(sc, URTW_AC_VI, aifs, 0);
3206 	(void) urtw_write8_c(sc, URTW_AC_BE, aifs, 0);
3207 	(void) urtw_write8_c(sc, URTW_AC_BK, aifs, 0);
3208 
3209 	(void) urtw_write8_c(sc, URTW_DIFS, difs, 0);
3210 	(void) urtw_write8_c(sc, URTW_8187B_EIFS, eifs, 0);
3211 	return (0);
3212 }
3213 
3214 usbd_status
3215 urtw_8225v2_b_rf_init(struct urtw_rf *rf)
3216 {
3217 	struct urtw_softc *sc = rf->rf_sc;
3218 	int i, nitems;
3219 	uint8_t data;
3220 	usbd_status error;
3221 
3222 	/* Set up ACK rate, retry limit, TX AGC, TX antenna. */
3223 	(void) urtw_write16_c(sc, URTW_8187B_BRSR, 0x0fff, 0);
3224 	(void) urtw_read8_c(sc, URTW_CW_CONF, &data, 0);
3225 	(void) urtw_write8_c(sc, URTW_CW_CONF, data |
3226 	    URTW_CW_CONF_PERPACKET_RETRY, 0);
3227 	(void) urtw_read8_c(sc, URTW_TX_AGC_CTL, &data, 0);
3228 	(void) urtw_write8_c(sc, URTW_TX_AGC_CTL, data |
3229 	    URTW_TX_AGC_CTL_PERPACKET_GAIN |
3230 	    URTW_TX_AGC_CTL_PERPACKET_ANTSEL, 0);
3231 
3232 	/* Auto rate fallback control. */
3233 	(void) urtw_write16_c(sc, URTW_ARFR, 0x0fff, 1);	/* 1M ~ 54M */
3234 	(void) urtw_read8_c(sc, URTW_RATE_FALLBACK, &data, 0);
3235 	(void) urtw_write8_c(sc, URTW_RATE_FALLBACK, data |
3236 	    URTW_RATE_FALLBACK_ENABLE, 0);
3237 
3238 	(void) urtw_write16_c(sc, URTW_BEACON_INTERVAL, 0x3ff, 0);
3239 	(void) urtw_write16_c(sc, URTW_ATIM_WND, 2, 0);
3240 	(void) urtw_write16_c(sc, URTW_FEMR, 0xffff, 1);
3241 
3242 	error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3243 	if (error)
3244 		goto fail;
3245 	(void) urtw_read8_c(sc, URTW_CONFIG1, &data, 0);
3246 	(void) urtw_write8_c(sc, URTW_CONFIG1, (data & 0x3f) | 0x80, 0);
3247 	error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3248 	if (error)
3249 		goto fail;
3250 
3251 	(void) urtw_write8_c(sc, URTW_WPA_CONFIG, 0, 0);
3252 	urtw_8225v2_b_config_mac(sc);
3253 	(void) urtw_write16_c(sc, URTW_RFSW_CTRL, 0x569a, 2);
3254 
3255 	error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3256 	if (error)
3257 		goto fail;
3258 	(void) urtw_read8_c(sc, URTW_CONFIG3, &data, 0);
3259 	(void) urtw_write8_c(sc, URTW_CONFIG3,
3260 	    data | URTW_CONFIG3_ANAPARAM_WRITE, 0);
3261 	error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3262 	if (error)
3263 		goto fail;
3264 
3265 	urtw_8225v2_b_init_rfe(sc);
3266 
3267 	nitems = sizeof (urtw_8225v2_b_rf) / sizeof ((urtw_8225v2_b_rf)[0]);
3268 	for (i = 0; i < nitems; i++) {
3269 		(void) urtw_8225_write_c(sc, urtw_8225v2_b_rf[i].reg,
3270 		    urtw_8225v2_b_rf[i].val);
3271 	}
3272 
3273 	nitems = sizeof (urtw_8225v2_rxgain) / sizeof ((urtw_8225v2_rxgain)[0]);
3274 	for (i = 0; i < nitems; i++) {
3275 		(void) urtw_8225_write_c(sc, 0x1, (uint8_t)(i + 1));
3276 		(void) urtw_8225_write_c(sc, 0x2, urtw_8225v2_rxgain[i]);
3277 	}
3278 
3279 	(void) urtw_8225_write_c(sc, 0x03, 0x080);
3280 	(void) urtw_8225_write_c(sc, 0x05, 0x004);
3281 	(void) urtw_8225_write_c(sc, 0x00, 0x0b7);
3282 	(void) urtw_8225_write_c(sc, 0x02, 0xc4d);
3283 	urtw_delay_ms(10);
3284 	(void) urtw_8225_write_c(sc, 0x02, 0x44d);
3285 	urtw_delay_ms(10);
3286 	(void) urtw_8225_write_c(sc, 0x00, 0x2bf);
3287 	urtw_delay_ms(10);
3288 
3289 	(void) urtw_write8_c(sc, URTW_TX_GAIN_CCK, 0x03, 0);
3290 	(void) urtw_write8_c(sc, URTW_TX_GAIN_OFDM, 0x07, 0);
3291 	(void) urtw_write8_c(sc, URTW_TX_ANTENNA, 0x03, 0);
3292 
3293 	(void) urtw_8187_write_phy_ofdm_c(sc, 0x80, 0x12);
3294 	nitems = sizeof (urtw_8225v2_agc) / sizeof ((urtw_8225v2_agc)[0]);
3295 	for (i = 0; i < nitems; i++) {
3296 		(void) urtw_8187_write_phy_ofdm_c(sc, 0x0f, urtw_8225v2_agc[i]);
3297 		(void) urtw_8187_write_phy_ofdm_c(sc, 0x0e, (uint8_t)i + 0x80);
3298 		(void) urtw_8187_write_phy_ofdm_c(sc, 0x0e, 0);
3299 	}
3300 	(void) urtw_8187_write_phy_ofdm_c(sc, 0x80, 0x10);
3301 
3302 	nitems = sizeof (urtw_8225v2_ofdm) / sizeof ((urtw_8225v2_ofdm)[0]);
3303 	for (i = 0; i < nitems; i++) {
3304 		(void) urtw_8187_write_phy_ofdm_c(sc, i, urtw_8225v2_ofdm[i]);
3305 	}
3306 	(void) urtw_8225v2_b_update_chan(sc);
3307 
3308 	(void) urtw_8187_write_phy_ofdm_c(sc, 0x97, 0x46);
3309 	(void) urtw_8187_write_phy_ofdm_c(sc, 0xa4, 0xb6);
3310 	(void) urtw_8187_write_phy_ofdm_c(sc, 0x85, 0xfc);
3311 	(void) urtw_8187_write_phy_cck_c(sc, 0xc1, 0x88);
3312 
3313 	error = urtw_8225v2_b_rf_set_chan(rf,
3314 	    ieee80211_chan2ieee(&sc->sc_ic, sc->sc_ic.ic_curchan));
3315 fail:
3316 	return (error);
3317 }
3318 
3319 static usbd_status
3320 urtw_8225v2_b_rf_set_chan(struct urtw_rf *rf, int chan)
3321 {
3322 	struct urtw_softc *sc = rf->rf_sc;
3323 	int error = 0;
3324 
3325 	urtw_8225v2_b_set_txpwrlvl(sc, chan);
3326 	error = urtw_8225_write_c(sc, 0x7, urtw_8225_channel[chan]);
3327 	if (error)
3328 		goto fail;
3329 	/*
3330 	 * Delay removed from 8185 to 8187.
3331 	 * usbd_delay_ms(sc->sc_udev, 10);
3332 	 */
3333 
3334 	error = urtw_write16_c(sc, URTW_AC_VO, 0x5114, 0);
3335 	if (error)
3336 		goto fail;
3337 	error = urtw_write16_c(sc, URTW_AC_VI, 0x5114, 0);
3338 	if (error)
3339 		goto fail;
3340 	error = urtw_write16_c(sc, URTW_AC_BE, 0x5114, 0);
3341 	if (error)
3342 		goto fail;
3343 	error = urtw_write16_c(sc, URTW_AC_BK, 0x5114, 0);
3344 fail:
3345 	return (error);
3346 }
3347 
3348 void
3349 urtw_8225v2_b_set_txpwrlvl(struct urtw_softc *sc, int chan)
3350 {
3351 	int i;
3352 	uint8_t *cck_pwrtable;
3353 	uint8_t cck_pwrlvl_min, cck_pwrlvl_max, ofdm_pwrlvl_min,
3354 	    ofdm_pwrlvl_max;
3355 	int8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
3356 	int8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
3357 
3358 	if (sc->sc_hwrev & URTW_HWREV_8187B_B) {
3359 		cck_pwrlvl_min = 0;
3360 		cck_pwrlvl_max = 15;
3361 		ofdm_pwrlvl_min = 2;
3362 		ofdm_pwrlvl_max = 17;
3363 	} else {
3364 		cck_pwrlvl_min = 7;
3365 		cck_pwrlvl_max = 22;
3366 		ofdm_pwrlvl_min = 10;
3367 		ofdm_pwrlvl_max = 25;
3368 	}
3369 
3370 	/* CCK power setting */
3371 	cck_pwrlvl = (cck_pwrlvl > (cck_pwrlvl_max - cck_pwrlvl_min)) ?
3372 	    cck_pwrlvl_max : (cck_pwrlvl + cck_pwrlvl_min);
3373 
3374 	cck_pwrlvl += sc->sc_txpwr_cck_base;
3375 	cck_pwrlvl = (cck_pwrlvl > 35) ? 35 : cck_pwrlvl;
3376 	cck_pwrlvl = (cck_pwrlvl < 0) ? 0 : cck_pwrlvl;
3377 
3378 	cck_pwrtable = (chan == 14) ? urtw_8225v2_txpwr_cck_ch14 :
3379 	    urtw_8225v2_txpwr_cck;
3380 
3381 	if (sc->sc_hwrev & URTW_HWREV_8187B_B) {
3382 		if (cck_pwrlvl > 7 && cck_pwrlvl <= 11)
3383 			cck_pwrtable += 8;
3384 		if (cck_pwrlvl > 11)
3385 			cck_pwrtable += 16;
3386 	} else {
3387 		if (cck_pwrlvl > 5 && cck_pwrlvl <= 11)
3388 			cck_pwrtable += 8;
3389 		if (cck_pwrlvl > 12 && cck_pwrlvl <= 17)
3390 			cck_pwrtable += 16;
3391 		if (cck_pwrlvl > 17)
3392 			cck_pwrtable += 24;
3393 	}
3394 
3395 	for (i = 0; i < 8; i++) {
3396 		(void) urtw_8187_write_phy_cck_c(sc, 0x44 + i, cck_pwrtable[i]);
3397 	}
3398 
3399 	(void) urtw_write8_c(sc, URTW_TX_GAIN_CCK,
3400 	    urtw_8225v2_tx_gain_cck_ofdm[cck_pwrlvl] << 1, 0);
3401 	/*
3402 	 * Delay removed from 8185 to 8187.
3403 	 * usbd_delay_ms(sc->sc_udev, 1);
3404 	 */
3405 
3406 	/* OFDM power setting */
3407 	ofdm_pwrlvl = (ofdm_pwrlvl > (ofdm_pwrlvl_max - ofdm_pwrlvl_min)) ?
3408 	    ofdm_pwrlvl_max : ofdm_pwrlvl + ofdm_pwrlvl_min;
3409 
3410 	ofdm_pwrlvl += sc->sc_txpwr_ofdm_base;
3411 	ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
3412 	ofdm_pwrlvl = (ofdm_pwrlvl < 0) ? 0 : ofdm_pwrlvl;
3413 
3414 	(void) urtw_write8_c(sc, URTW_TX_GAIN_OFDM,
3415 	    urtw_8225v2_tx_gain_cck_ofdm[ofdm_pwrlvl] << 1, 0);
3416 
3417 	if (sc->sc_hwrev & URTW_HWREV_8187B_B) {
3418 		if (ofdm_pwrlvl <= 11) {
3419 			(void) urtw_8187_write_phy_ofdm_c(sc, 0x87, 0x60);
3420 			(void) urtw_8187_write_phy_ofdm_c(sc, 0x89, 0x60);
3421 		} else {
3422 			(void) urtw_8187_write_phy_ofdm_c(sc, 0x87, 0x5c);
3423 			(void) urtw_8187_write_phy_ofdm_c(sc, 0x89, 0x5c);
3424 		}
3425 	} else {
3426 		if (ofdm_pwrlvl <= 11) {
3427 			(void) urtw_8187_write_phy_ofdm_c(sc, 0x87, 0x5c);
3428 			(void) urtw_8187_write_phy_ofdm_c(sc, 0x89, 0x5c);
3429 		} else if (ofdm_pwrlvl <= 17) {
3430 			(void) urtw_8187_write_phy_ofdm_c(sc, 0x87, 0x54);
3431 			(void) urtw_8187_write_phy_ofdm_c(sc, 0x89, 0x54);
3432 		} else {
3433 			(void) urtw_8187_write_phy_ofdm_c(sc, 0x87, 0x50);
3434 			(void) urtw_8187_write_phy_ofdm_c(sc, 0x89, 0x50);
3435 		}
3436 	}
3437 
3438 	/*
3439 	 * Delay removed from 8185 to 8187.
3440 	 * usbd_delay_ms(sc->sc_udev, 1);
3441 	 */
3442 }
3443 
3444 
3445 static int
3446 urtw_send(ieee80211com_t *ic, mblk_t *mp, uint8_t type)
3447 {
3448 	struct urtw_softc *sc = (struct urtw_softc *)ic;
3449 	struct ieee80211_frame *wh;
3450 	struct ieee80211_key *k;
3451 	struct ieee80211_node *ni = NULL;
3452 	uint8_t *buf;
3453 	mblk_t *m = 0, *m0, *mtx;
3454 	int off, mblen, xferlen, err = 0, priority = 0;
3455 
3456 	mutex_enter(&sc->tx_lock);
3457 	priority = (type == IEEE80211_FC0_TYPE_DATA) ?
3458 	    LOW_PRIORITY_PIPE: NORMAL_PRIORITY_PIPE;
3459 
3460 	if (URTW_IS_SUSPENDING(sc)) {
3461 		err = 0;
3462 		goto failed;
3463 	}
3464 
3465 	if (((priority)? sc->sc_tx_normal_queued : sc->sc_tx_low_queued) >=
3466 	    URTW_TX_DATA_LIST_COUNT) {
3467 		URTW8187_DBG(URTW_DEBUG_XMIT, (sc->sc_dev, CE_CONT,
3468 		    "urtw_send(): no TX buffer!\n"));
3469 		sc->sc_tx_nobuf++;
3470 		err = ENOMEM;
3471 		goto failed;
3472 	}
3473 
3474 	m = allocb(URTW_TXBUF_SIZE, BPRI_MED);
3475 	if (m == NULL) {
3476 		cmn_err(CE_WARN, "urtw_send(): can't alloc mblk.\n");
3477 		err = ENOMEM;
3478 		goto failed;
3479 	}
3480 
3481 	for (off = 0, m0 = mp; m0 != NULL; m0 = m0->b_cont) {
3482 		mblen = (uintptr_t)m0->b_wptr - (uintptr_t)m0->b_rptr;
3483 		(void) bcopy(m0->b_rptr, m->b_rptr + off, mblen);
3484 		off += mblen;
3485 	}
3486 	m->b_wptr += off;
3487 
3488 	wh = (struct ieee80211_frame *)m->b_rptr;
3489 
3490 	ni = ieee80211_find_txnode(ic, wh->i_addr1);
3491 	if (ni == NULL) {
3492 		err = ENXIO;
3493 		ic->ic_stats.is_tx_failed++;
3494 		goto failed;
3495 	}
3496 
3497 	if ((type & IEEE80211_FC0_TYPE_MASK) ==
3498 	    IEEE80211_FC0_TYPE_DATA) {
3499 		(void) ieee80211_encap(ic, m, ni);
3500 	}
3501 
3502 	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
3503 		k = ieee80211_crypto_encap(ic, m);
3504 		if (k == NULL) {
3505 			ic->ic_stats.is_tx_failed++;
3506 			err = ENXIO;
3507 			goto failed;
3508 		}
3509 		/* packet header may have moved, reset our local pointer */
3510 		wh = (struct ieee80211_frame *)m->b_rptr;
3511 	}
3512 
3513 	if (sc->sc_hwrev & URTW_HWREV_8187)
3514 		xferlen = MBLKL(m) + 4 * 3;
3515 	else
3516 		xferlen = MBLKL(m) + 4 * 8;
3517 
3518 	if ((0 == xferlen % 64) || (0 == xferlen % 512))
3519 		xferlen += 1;
3520 
3521 	mtx = allocb(xferlen, BPRI_MED);
3522 	buf = mtx->b_rptr;
3523 
3524 	bzero(buf, xferlen);
3525 	buf[0] = MBLKL(m) & 0xff;
3526 	buf[1] = (MBLKL(m) & 0x0f00) >> 8;
3527 	buf[1] |= (1 << 7);
3528 
3529 	/* XXX sc_preamble_mode is always 2.  */
3530 	if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG)
3531 		buf[2] |= (1 << 1);
3532 	/* RTS rate - 10 means we use a basic rate.  */
3533 	buf[2] |= (urtw_rate2rtl(2) << 3);
3534 	/*
3535 	 * XXX currently TX rate control depends on the rate value of
3536 	 * RX descriptor because I don't know how to we can control TX rate
3537 	 * in more smart way.  Please fix me you find a thing.
3538 	 */
3539 	if ((type & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_DATA) {
3540 		buf[3] = urtw_rate2rtl(MAX(2, urtw_get_rate(ic)));
3541 	} else
3542 		buf[3] = sc->sc_currate;
3543 
3544 	if (sc->sc_hwrev & URTW_HWREV_8187) {
3545 		buf[8] = 3;		/* CW minimum  */
3546 		buf[8] |= (7 << 4);	/* CW maximum  */
3547 		buf[9] |= 11;		/* retry limitation  */
3548 		bcopy(m->b_rptr, &buf[12], MBLKL(m));
3549 	} else {
3550 		buf[21] |= 11;		/* retry limitation */
3551 		bcopy(m->b_rptr, &buf[32], MBLKL(m));
3552 	}
3553 
3554 	(void) urtw_led_ctl(sc, URTW_LED_CTL_TX);
3555 	mtx->b_wptr = mtx->b_rptr + xferlen;
3556 
3557 	URTW8187_DBG(URTW_DEBUG_XMIT, (sc->sc_dev, CE_CONT,
3558 	    "sending frame len=%u rate=%u xfer len=%u\n",
3559 	    MBLKL(m), buf[3], xferlen));
3560 
3561 	err = urtw_tx_start(sc, mtx, priority);
3562 	if (!err) {
3563 		ic->ic_stats.is_tx_frags++;
3564 		ic->ic_stats.is_tx_bytes += MBLKL(m);
3565 	} else {
3566 		ic->ic_stats.is_tx_failed++;
3567 	}
3568 
3569 failed:
3570 	if (ni != NULL)
3571 		ieee80211_free_node(ni);
3572 
3573 	if ((mp) &&
3574 	    ((type & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_DATA ||
3575 	    err == DDI_SUCCESS)) {
3576 		freemsg(mp);
3577 	}
3578 	if (m) freemsg(m);
3579 
3580 	if (((type & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_DATA) &&
3581 	    (err != 0)) {
3582 		sc->sc_need_sched = 1;
3583 	}
3584 	mutex_exit(&sc->tx_lock);
3585 	return (err);
3586 }
3587 
3588 static void
3589 urtw_next_scan(void *arg)
3590 {
3591 	ieee80211com_t *ic = arg;
3592 	struct urtw_softc *sc = (struct urtw_softc *)arg;
3593 
3594 	if (URTW_IS_NOT_RUNNING(sc)) {
3595 		sc->sc_scan_id = 0;
3596 		return;
3597 	}
3598 
3599 	if (ic->ic_state == IEEE80211_S_SCAN) {
3600 		(void) ieee80211_next_scan(ic);
3601 	}
3602 	sc->sc_scan_id = 0;
3603 }
3604 
3605 static void
3606 urtw_led_launch(void *arg)
3607 {
3608 	struct urtw_softc *sc = arg;
3609 	ieee80211com_t *ic = &sc->sc_ic;
3610 	int error = 0;
3611 
3612 	URTW_LEDLOCK(sc);
3613 	if ((sc->sc_strategy != URTW_SW_LED_MODE0) ||
3614 	    URTW_IS_NOT_RUNNING(sc) ||
3615 	    URTW_IS_SUSPENDING(sc)) {
3616 		URTW8187_DBG(URTW_DEBUG_LED, (sc->sc_dev, CE_CONT,
3617 		    "failed process LED strategy 0x%x, run?%d",
3618 		    sc->sc_strategy,
3619 		    sc->sc_flags));
3620 		sc->sc_led_ch = 0;
3621 		sc->sc_gpio_ledinprogress = 0;
3622 		URTW_LEDUNLOCK(sc);
3623 		return;
3624 	}
3625 	error = urtw_led_blink(sc);
3626 	if (error) {
3627 		sc->sc_led_ch = timeout(urtw_led_launch, (void *)sc,
3628 		    drv_usectohz((ic->ic_state == IEEE80211_S_RUN) ?
3629 		    URTW_LED_LINKON_BLINK: URTW_LED_LINKOFF_BLINK));
3630 		URTW8187_DBG(URTW_DEBUG_LED, (sc->sc_dev, CE_CONT,
3631 		    "try again led launch"));
3632 	} else {
3633 		sc->sc_led_ch = 0;
3634 		URTW8187_DBG(URTW_DEBUG_LED, (sc->sc_dev, CE_CONT,
3635 		    "exit led launch"));
3636 	}
3637 	URTW_LEDUNLOCK(sc);
3638 }
3639 
3640 static int
3641 urtw_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
3642 {
3643 	struct urtw_softc *sc = (struct urtw_softc *)ic;
3644 	struct ieee80211_node *ni;
3645 	int error = 0;
3646 
3647 	if (sc->sc_scan_id != 0) {
3648 		(void) untimeout(sc->sc_scan_id);
3649 		sc->sc_scan_id = 0;
3650 	}
3651 	URTW_LOCK(sc);
3652 	switch (nstate) {
3653 	case IEEE80211_S_INIT:
3654 		URTW8187_DBG(URTW_DEBUG_STATE,
3655 		    (sc->sc_dev, CE_CONT, "-> IEEE80211_S_INIT...arg(%d)\n",
3656 		    arg));
3657 		if (sc->sc_flags & URTW_FLAG_HP)
3658 			break;
3659 		(void) urtw_update_msr(sc, nstate);
3660 		(void) urtw_led_off(sc, URTW_LED_GPIO);
3661 		break;
3662 
3663 	case IEEE80211_S_SCAN:
3664 		URTW8187_DBG(URTW_DEBUG_STATE,
3665 		    (sc->sc_dev, CE_CONT,
3666 		    "-> IEEE80211_S_SCAN...arg(%d)...[%d]\n",
3667 		    arg, ieee80211_chan2ieee(ic, ic->ic_curchan)));
3668 		error = urtw_set_channel(sc);
3669 		if (error) {
3670 			URTW8187_DBG(URTW_DEBUG_STATE,
3671 			    (sc->sc_dev, CE_CONT, "scan setchan failed"));
3672 			break;
3673 		}
3674 		sc->sc_scan_id = timeout(urtw_next_scan, (void *)sc,
3675 		    drv_usectohz(sc->dwelltime * 1000));
3676 		break;
3677 
3678 	case IEEE80211_S_AUTH:
3679 		URTW8187_DBG(URTW_DEBUG_STATE, (sc->sc_dev, CE_CONT,
3680 		    "-> IEEE80211_S_AUTH ...arg(%d), chan (%d)\n", arg,
3681 		    ieee80211_chan2ieee(ic, ic->ic_curchan)));
3682 		error = urtw_set_channel(sc);
3683 		if (error) {
3684 			URTW8187_DBG(URTW_DEBUG_STATE,
3685 			    (sc->sc_dev,  CE_CONT, "auth setchan failed"));
3686 		}
3687 		break;
3688 
3689 	case IEEE80211_S_ASSOC:
3690 		URTW8187_DBG(URTW_DEBUG_STATE, (sc->sc_dev, CE_CONT,
3691 		    "-> IEEE80211_S_ASSOC ...arg(%d), chan (%d)\n", arg,
3692 		    ieee80211_chan2ieee(ic, ic->ic_curchan)));
3693 		error = urtw_set_channel(sc);
3694 		if (error) {
3695 			URTW8187_DBG(URTW_DEBUG_STATE,
3696 			    (sc->sc_dev, CE_CONT, "assoc setchan failed"));
3697 		}
3698 		break;
3699 
3700 	case IEEE80211_S_RUN:
3701 		URTW8187_DBG(URTW_DEBUG_STATE,
3702 		    (sc->sc_dev, CE_CONT,
3703 		    "-> IEEE80211_S_RUN ...arg(%d), chan (%d)\n",
3704 		    arg, ieee80211_chan2ieee(ic, ic->ic_curchan)));
3705 		error = urtw_set_channel(sc);
3706 		if (error) {
3707 			URTW8187_DBG(URTW_DEBUG_STATE,
3708 			    (sc->sc_dev, CE_CONT, "run setchan failed"));
3709 			goto fail;
3710 		}
3711 		ni = ic->ic_bss;
3712 		/* setting bssid.  */
3713 		(void) urtw_write32_c(sc, URTW_BSSID,
3714 		    ((uint32_t *)(uintptr_t)ni->in_bssid)[0], 0);
3715 		(void) urtw_write16_c(sc, URTW_BSSID + 4,
3716 		    ((uint16_t *)(uintptr_t)ni->in_bssid)[2], 0);
3717 		(void) urtw_update_msr(sc, nstate);
3718 
3719 		ni->in_txrate = ni->in_rates.ir_nrates - 1;
3720 		break;
3721 	}
3722 fail:
3723 	URTW_UNLOCK(sc);
3724 
3725 	if (error) {
3726 		URTW8187_DBG(URTW_DEBUG_STATE, (sc->sc_dev, CE_CONT,
3727 		    "-> newstate error...arg(%d)\n", error));
3728 		return (EIO);
3729 	}
3730 	error = sc->sc_newstate(ic, nstate, arg);
3731 	return (error);
3732 }
3733 
3734 static void
3735 urtw_close_pipes(struct urtw_softc *sc)
3736 {
3737 	usb_flags_t flags = USB_FLAGS_SLEEP;
3738 
3739 	if (sc->sc_rxpipe != NULL) {
3740 		usb_pipe_reset(sc->sc_dev,
3741 		    sc->sc_rxpipe, flags, NULL, 0);
3742 		usb_pipe_close(sc->sc_dev,
3743 		    sc->sc_rxpipe, flags, NULL, 0);
3744 		sc->sc_rxpipe = NULL;
3745 	}
3746 
3747 	if (sc->sc_txpipe_low != NULL) {
3748 		usb_pipe_reset(sc->sc_dev,
3749 		    sc->sc_txpipe_low, flags, NULL, 0);
3750 		usb_pipe_close(sc->sc_dev,
3751 		    sc->sc_txpipe_low, flags, NULL, 0);
3752 		sc->sc_txpipe_low = NULL;
3753 	}
3754 
3755 	if (sc->sc_txpipe_normal != NULL) {
3756 		usb_pipe_reset(sc->sc_dev,
3757 		    sc->sc_txpipe_normal, flags, NULL, 0);
3758 		usb_pipe_close(sc->sc_dev,
3759 		    sc->sc_txpipe_normal, flags, NULL, 0);
3760 		sc->sc_txpipe_normal = NULL;
3761 	}
3762 }
3763 
3764 static int
3765 urtw_open_pipes(struct urtw_softc *sc)
3766 {
3767 	usb_ep_data_t *ep_node;
3768 	usb_pipe_policy_t policy;
3769 	int err;
3770 	uint_t skip = 0;
3771 
3772 	if (sc->sc_rxpipe || sc->sc_txpipe_low || sc->sc_txpipe_normal)
3773 		return (USB_SUCCESS);
3774 
3775 	if ((sc->sc_hwrev & URTW_HWREV_8187) == 0) {
3776 		skip = 2;
3777 	}
3778 	ep_node = usb_lookup_ep_data(sc->sc_dev, sc->sc_udev, 0, 0,
3779 	    LOW_PRIORITY_PIPE + skip, USB_EP_ATTR_BULK, USB_EP_DIR_OUT);
3780 
3781 	bzero(&policy, sizeof (usb_pipe_policy_t));
3782 	policy.pp_max_async_reqs = URTW_TX_DATA_LIST_COUNT;
3783 
3784 	if ((err = usb_pipe_open(sc->sc_dev,
3785 	    &ep_node->ep_descr, &policy, USB_FLAGS_SLEEP,
3786 	    &sc->sc_txpipe_low)) != USB_SUCCESS) {
3787 		URTW8187_DBG(URTW_DEBUG_ACTIVE, (sc->sc_dev, CE_CONT,
3788 		    "urtw_open_pipes(): %x low priority pipe open failed\n",
3789 		    err));
3790 		goto fail;
3791 	}
3792 
3793 	ep_node = usb_lookup_ep_data(sc->sc_dev, sc->sc_udev, 0, 0,
3794 	    NORMAL_PRIORITY_PIPE + skip, USB_EP_ATTR_BULK, USB_EP_DIR_OUT);
3795 
3796 	bzero(&policy, sizeof (usb_pipe_policy_t));
3797 	policy.pp_max_async_reqs = URTW_TX_DATA_LIST_COUNT;
3798 
3799 	if ((err = usb_pipe_open(sc->sc_dev,
3800 	    &ep_node->ep_descr, &policy, USB_FLAGS_SLEEP,
3801 	    &sc->sc_txpipe_normal)) != USB_SUCCESS) {
3802 		URTW8187_DBG(URTW_DEBUG_ACTIVE, (sc->sc_dev, CE_CONT,
3803 		    "urtw_open_pipes(): %x failed to open high tx pipe\n",
3804 		    err));
3805 		goto fail;
3806 	}
3807 
3808 	ep_node = usb_lookup_ep_data(sc->sc_dev, sc->sc_udev, 0, 0, 0,
3809 	    USB_EP_ATTR_BULK, USB_EP_DIR_IN);
3810 
3811 	bzero(&policy, sizeof (usb_pipe_policy_t));
3812 	policy.pp_max_async_reqs = URTW_RX_DATA_LIST_COUNT;
3813 
3814 	if ((err = usb_pipe_open(sc->sc_dev,
3815 	    &ep_node->ep_descr, &policy, USB_FLAGS_SLEEP,
3816 	    &sc->sc_rxpipe)) != USB_SUCCESS) {
3817 		URTW8187_DBG(URTW_DEBUG_ACTIVE, (sc->sc_dev, CE_CONT,
3818 		    "urtw_open_pipes(): %x failed to open rx pipe\n", err));
3819 		goto fail;
3820 	}
3821 
3822 	return (USB_SUCCESS);
3823 
3824 fail:
3825 	urtw_close_pipes(sc);
3826 	return (USB_FAILURE);
3827 }
3828 
3829 static int
3830 urtw_tx_start(struct urtw_softc *sc, mblk_t *mp, int priority)
3831 {
3832 	usb_bulk_req_t *req;
3833 	int err;
3834 
3835 	req = usb_alloc_bulk_req(sc->sc_dev, 0, USB_FLAGS_SLEEP);
3836 	if (req == NULL) {
3837 		URTW8187_DBG(URTW_DEBUG_TX_PROC, (sc->sc_dev, CE_CONT,
3838 		    "urtw_tx_start(): failed to allocate req"));
3839 		freemsg(mp);
3840 		return (-1);
3841 	}
3842 
3843 	req->bulk_len = MBLKL(mp);
3844 	req->bulk_data = mp;
3845 	req->bulk_client_private = (usb_opaque_t)sc;
3846 	req->bulk_timeout = URTW_TX_TIMEOUT;
3847 	req->bulk_attributes = USB_ATTRS_AUTOCLEARING;
3848 	req->bulk_cb = (priority)?urtw_txeof_normal : urtw_txeof_low;
3849 	req->bulk_exc_cb = (priority)?urtw_txeof_normal: urtw_txeof_low;
3850 	req->bulk_completion_reason = 0;
3851 	req->bulk_cb_flags = 0;
3852 
3853 	if ((err = usb_pipe_bulk_xfer(
3854 	    (priority)?sc->sc_txpipe_normal:sc->sc_txpipe_low, req, 0))
3855 	    != USB_SUCCESS) {
3856 		sc->sc_ic.ic_stats.is_tx_failed++;
3857 		URTW8187_DBG(URTW_DEBUG_TX_PROC, (sc->sc_dev, CE_CONT,
3858 		    "urtw_tx_start: failed to do tx xfer, %d", err));
3859 		usb_free_bulk_req(req);
3860 		return (EIO);
3861 	}
3862 
3863 	if (priority) {
3864 		sc->sc_tx_normal_queued++;
3865 	} else {
3866 		sc->sc_tx_low_queued++;
3867 	}
3868 
3869 	return (0);
3870 }
3871 
3872 static int
3873 urtw_rx_start(struct urtw_softc *sc)
3874 {
3875 	usb_bulk_req_t *req;
3876 	int err;
3877 
3878 	req = usb_alloc_bulk_req(sc->sc_dev, URTW_RXBUF_SIZE, USB_FLAGS_SLEEP);
3879 	if (req == NULL) {
3880 		URTW8187_DBG(URTW_DEBUG_RECV, (sc->sc_dev, CE_CONT,
3881 		    "urtw_rx_start(): failed to allocate req"));
3882 		return (-1);
3883 	}
3884 
3885 	req->bulk_len		= URTW_RXBUF_SIZE;
3886 	req->bulk_client_private = (usb_opaque_t)sc;
3887 	req->bulk_timeout	= 0;
3888 	req->bulk_attributes	= USB_ATTRS_SHORT_XFER_OK |
3889 	    USB_ATTRS_AUTOCLEARING;
3890 	req->bulk_cb		= urtw_rxeof;
3891 	req->bulk_exc_cb	= urtw_rxeof;
3892 	req->bulk_completion_reason = 0;
3893 	req->bulk_cb_flags	= 0;
3894 
3895 	err = usb_pipe_bulk_xfer(sc->sc_rxpipe, req, 0);
3896 
3897 	if (err != USB_SUCCESS) {
3898 		URTW8187_DBG(URTW_DEBUG_RECV, (sc->sc_dev, CE_CONT,
3899 		    "urtw_rx_start: failed to do rx xfer, %d", err));
3900 		usb_free_bulk_req(req);
3901 		return (-1);
3902 	}
3903 
3904 	mutex_enter(&sc->rx_lock);
3905 	sc->rx_queued++;
3906 	mutex_exit(&sc->rx_lock);
3907 
3908 	return (0);
3909 }
3910 
3911 static int
3912 urtw_disconnect(dev_info_t *devinfo)
3913 {
3914 	struct urtw_softc *sc;
3915 
3916 	sc = ddi_get_soft_state(urtw_soft_state_p, ddi_get_instance(devinfo));
3917 	URTW8187_DBG(URTW_DEBUG_HOTPLUG,
3918 	    (sc->sc_dev, CE_CONT, "urtw_offline()\n"));
3919 
3920 	if (URTW_IS_RUNNING(sc)) {
3921 		urtw_stop(sc);
3922 		URTW_LOCK(sc);
3923 		sc->sc_flags |= URTW_FLAG_PLUGIN_ONLINE;
3924 		URTW_UNLOCK(sc);
3925 	}
3926 	sc->sc_flags |= URTW_FLAG_HP;
3927 	ieee80211_new_state(&sc->sc_ic, IEEE80211_S_INIT, -1);
3928 	ieee80211_stop_watchdog(&sc->sc_ic);
3929 	return (DDI_SUCCESS);
3930 }
3931 
3932 static int
3933 urtw_reconnect(dev_info_t *devinfo)
3934 {
3935 	struct urtw_softc *sc;
3936 	int error = 0;
3937 	sc = ddi_get_soft_state(urtw_soft_state_p, ddi_get_instance(devinfo));
3938 	if (usb_check_same_device(sc->sc_dev, NULL, USB_LOG_L2, -1,
3939 	    USB_CHK_ALL, NULL) != USB_SUCCESS)
3940 		return (DDI_FAILURE);
3941 	URTW8187_DBG(URTW_DEBUG_HOTPLUG, (sc->sc_dev, CE_CONT,
3942 	    "urtw_online()\n"));
3943 	sc->sc_flags &= ~URTW_FLAG_HP;
3944 	if (URTW_IS_PLUGIN_ONLINE(sc)) {
3945 		error = sc->urtw_init(sc);
3946 		if (!error) {
3947 			URTW_LOCK(sc);
3948 			sc->sc_flags &= ~URTW_FLAG_PLUGIN_ONLINE;
3949 			URTW_UNLOCK(sc);
3950 		}
3951 	}
3952 	return (error? DDI_FAILURE: DDI_SUCCESS);
3953 }
3954 
3955 static mblk_t *
3956 urtw_m_tx(void *arg, mblk_t *mp)
3957 {
3958 	struct urtw_softc *sc = (struct urtw_softc *)arg;
3959 	struct ieee80211com *ic = &sc->sc_ic;
3960 	mblk_t *next;
3961 
3962 	if ((ic->ic_state != IEEE80211_S_RUN) ||
3963 	    URTW_IS_SUSPENDING(sc)) {
3964 		freemsgchain(mp);
3965 		return (NULL);
3966 	}
3967 
3968 	while (mp != NULL) {
3969 		next = mp->b_next;
3970 		mp->b_next = NULL;
3971 		if (urtw_send(ic, mp, IEEE80211_FC0_TYPE_DATA) != DDI_SUCCESS) {
3972 			mp->b_next = next;
3973 			break;
3974 		}
3975 		mp = next;
3976 	}
3977 	return (mp);
3978 }
3979 
3980 static int
3981 urtw_m_start(void *arg)
3982 {
3983 	struct urtw_softc *sc = (struct urtw_softc *)arg;
3984 	int error = 0;
3985 
3986 	URTW8187_DBG(URTW_DEBUG_ACTIVE,
3987 	    (sc->sc_dev, CE_CONT, "urtw_m_start\n"));
3988 	error = sc->urtw_init(sc);
3989 	return (error);
3990 }
3991 
3992 static void
3993 urtw_m_stop(void *arg)
3994 {
3995 	struct urtw_softc *sc = (struct urtw_softc *)arg;
3996 
3997 	URTW8187_DBG(URTW_DEBUG_ACTIVE, (sc->sc_dev, CE_CONT,
3998 	    "urtw_m_stop()\n"));
3999 	ieee80211_new_state(&sc->sc_ic, IEEE80211_S_INIT, -1);
4000 	ieee80211_stop_watchdog(&sc->sc_ic);
4001 	(void) urtw_stop(sc);
4002 }
4003 
4004 /*ARGSUSED*/
4005 static int
4006 urtw_m_unicst(void *arg, const uint8_t *macaddr)
4007 {
4008 	return (ENOTSUP);
4009 }
4010 
4011 /*ARGSUSED*/
4012 static int
4013 urtw_m_multicst(void *arg, boolean_t add, const uint8_t *macaddr)
4014 {
4015 	return (ENOTSUP);
4016 }
4017 
4018 /*ARGSUSED*/
4019 static int
4020 urtw_m_promisc(void *arg, boolean_t on)
4021 {
4022 	return (0);
4023 }
4024 
4025 static int
4026 urtw_m_getprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num,
4027     uint_t pr_flags, uint_t wldp_length, void *wldp_buf, uint_t *perm)
4028 {
4029 	struct urtw_softc *sc = (struct urtw_softc *)arg;
4030 	int err = 0;
4031 
4032 	err = ieee80211_getprop(&sc->sc_ic, pr_name, wldp_pr_num,
4033 	    pr_flags, wldp_length, wldp_buf, perm);
4034 	return (err);
4035 }
4036 
4037 static int
4038 urtw_m_setprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num,
4039     uint_t wldp_length, const void *wldp_buf)
4040 {
4041 	struct urtw_softc *sc = (struct urtw_softc *)arg;
4042 	struct ieee80211com *ic = &sc->sc_ic;
4043 	int err;
4044 
4045 	err = ieee80211_setprop(ic, pr_name, wldp_pr_num,
4046 	    wldp_length, wldp_buf);
4047 	URTW_LOCK(sc);
4048 	if (err == ENETRESET) {
4049 		if (URTW_IS_RUNNING(sc) && ic->ic_des_esslen) {
4050 			URTW_UNLOCK(sc);
4051 			err = sc->urtw_init(sc);
4052 			if (err) {
4053 				URTW8187_DBG(URTW_DEBUG_ACTIVE,
4054 				    (sc->sc_dev, CE_CONT,
4055 				    "urtw: setprop failed\n"));
4056 				return (err);
4057 			}
4058 			(void) ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
4059 			URTW_LOCK(sc);
4060 		}
4061 		err = 0;
4062 	}
4063 	URTW_UNLOCK(sc);
4064 	return (err);
4065 }
4066 
4067 static void
4068 urtw_m_ioctl(void* arg, queue_t *wq, mblk_t *mp)
4069 {
4070 	struct urtw_softc *sc = (struct urtw_softc *)arg;
4071 	struct ieee80211com *ic = &sc->sc_ic;
4072 	int err;
4073 
4074 	err = ieee80211_ioctl(ic, wq, mp);
4075 	URTW_LOCK(sc);
4076 	if (err == ENETRESET) {
4077 		if (URTW_IS_RUNNING(sc) && ic->ic_des_esslen) {
4078 			URTW_UNLOCK(sc);
4079 			err = sc->urtw_init(sc);
4080 			if (err) {
4081 				URTW8187_DBG(URTW_DEBUG_ACTIVE,
4082 				    (sc->sc_dev,
4083 				    CE_CONT, "urtw: dev init failed\n"));
4084 				return;
4085 			}
4086 			(void) ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
4087 			URTW_LOCK(sc);
4088 		}
4089 	}
4090 	URTW_UNLOCK(sc);
4091 }
4092 
4093 static int
4094 urtw_m_stat(void *arg, uint_t stat, uint64_t *val)
4095 {
4096 	struct urtw_softc *sc  = (struct urtw_softc *)arg;
4097 	ieee80211com_t	*ic = &sc->sc_ic;
4098 	ieee80211_node_t *ni = 0;
4099 	struct ieee80211_rateset *rs = 0;
4100 
4101 	URTW_LOCK(sc);
4102 	switch (stat) {
4103 	case MAC_STAT_IFSPEED:
4104 		ni = ic->ic_bss;
4105 		rs = &ni->in_rates;
4106 		*val = ((ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) ?
4107 		    (rs->ir_rates[ni->in_txrate] & IEEE80211_RATE_VAL)
4108 		    : ic->ic_fixed_rate) / 2 * 1000000;
4109 		break;
4110 	case MAC_STAT_NOXMTBUF:
4111 		*val = sc->sc_tx_nobuf;
4112 		break;
4113 	case MAC_STAT_NORCVBUF:
4114 		*val = sc->sc_rx_nobuf;
4115 		break;
4116 	case MAC_STAT_IERRORS:
4117 		*val = sc->sc_rx_err;
4118 		break;
4119 	case MAC_STAT_RBYTES:
4120 		*val = ic->ic_stats.is_rx_bytes;
4121 		break;
4122 	case MAC_STAT_IPACKETS:
4123 		*val = ic->ic_stats.is_rx_frags;
4124 		break;
4125 	case MAC_STAT_OBYTES:
4126 		*val = ic->ic_stats.is_tx_bytes;
4127 		break;
4128 	case MAC_STAT_OPACKETS:
4129 		*val = ic->ic_stats.is_tx_frags;
4130 		break;
4131 	case MAC_STAT_OERRORS:
4132 		*val = ic->ic_stats.is_tx_failed;
4133 		break;
4134 	case WIFI_STAT_TX_FRAGS:
4135 	case WIFI_STAT_MCAST_TX:
4136 	case WIFI_STAT_TX_FAILED:
4137 	case WIFI_STAT_TX_RETRANS:
4138 	case WIFI_STAT_RTS_SUCCESS:
4139 	case WIFI_STAT_RTS_FAILURE:
4140 	case WIFI_STAT_ACK_FAILURE:
4141 	case WIFI_STAT_RX_FRAGS:
4142 	case WIFI_STAT_MCAST_RX:
4143 	case WIFI_STAT_FCS_ERRORS:
4144 	case WIFI_STAT_WEP_ERRORS:
4145 	case WIFI_STAT_RX_DUPS:
4146 		URTW_UNLOCK(sc);
4147 		return (ieee80211_stat(ic, stat, val));
4148 	default:
4149 		URTW_UNLOCK(sc);
4150 		return (ENOTSUP);
4151 	}
4152 	URTW_UNLOCK(sc);
4153 
4154 	return (0);
4155 }
4156 
4157 static void
4158 urtw_watchdog(void *arg)
4159 {
4160 	struct urtw_softc *sc = arg;
4161 	struct ieee80211com *ic = &sc->sc_ic;
4162 
4163 	ieee80211_stop_watchdog(ic);
4164 
4165 	URTW_LOCK(sc);
4166 	if (URTW_IS_NOT_RUNNING(sc)) {
4167 		URTW_UNLOCK(sc);
4168 		return;
4169 	}
4170 
4171 	URTW_UNLOCK(sc);
4172 	switch (ic->ic_state) {
4173 		case IEEE80211_S_AUTH:
4174 		case IEEE80211_S_ASSOC:
4175 			if (ic->ic_bss->in_fails > 0) {
4176 				ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
4177 				URTW8187_DBG(URTW_DEBUG_ACTIVE,
4178 				    (sc->sc_dev, CE_CONT,
4179 				    "urtw: watchdog begin\n"));
4180 			} else
4181 				ieee80211_watchdog(ic);
4182 			break;
4183 	}
4184 }
4185 
4186 
4187 static int
4188 urtw_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd)
4189 {
4190 	struct urtw_softc *sc;
4191 	struct ieee80211com *ic;
4192 	int error, i, instance;
4193 	uint32_t data = 0;
4194 	uint8_t data8 = 0;
4195 	char strbuf[32];
4196 	wifi_data_t wd = { 0 };
4197 	mac_register_t *macp;
4198 	struct urtw_type *e = 0;
4199 	char *urtw_name = NULL;
4200 
4201 	switch (cmd) {
4202 	case DDI_ATTACH:
4203 		break;
4204 	case DDI_RESUME:
4205 		sc = ddi_get_soft_state(urtw_soft_state_p,
4206 		    ddi_get_instance(devinfo));
4207 		ASSERT(sc != NULL);
4208 		URTW8187_DBG(URTW_DEBUG_ACTIVE,
4209 		    (sc->sc_dev, CE_CONT, "urtw: resume\n"));
4210 		URTW_LOCK(sc);
4211 		sc->sc_flags &= ~URTW_FLAG_SUSPEND;
4212 		URTW_UNLOCK(sc);
4213 		if (URTW_IS_PLUGIN_ONLINE(sc)) {
4214 			error = sc->urtw_init(sc);
4215 			if (error == 0) {
4216 				URTW_LOCK(sc);
4217 				sc->sc_flags &= ~URTW_FLAG_PLUGIN_ONLINE;
4218 				URTW_UNLOCK(sc);
4219 			}
4220 		}
4221 		return (DDI_SUCCESS);
4222 	default:
4223 		return (DDI_FAILURE);
4224 	}
4225 
4226 	instance = ddi_get_instance(devinfo);
4227 
4228 	if (ddi_soft_state_zalloc(urtw_soft_state_p, instance) != DDI_SUCCESS) {
4229 		cmn_err(CE_WARN, "urtw_attach:unable to alloc soft_state_p\n");
4230 		return (DDI_FAILURE);
4231 	}
4232 
4233 	sc = ddi_get_soft_state(urtw_soft_state_p, instance);
4234 	ic = (ieee80211com_t *)&sc->sc_ic;
4235 	sc->sc_dev = devinfo;
4236 
4237 	if (usb_client_attach(devinfo, USBDRV_VERSION, 0) != USB_SUCCESS) {
4238 		cmn_err(CE_WARN, "urtw_attach: usb_client_attach failed\n");
4239 		goto fail1;
4240 	}
4241 
4242 	if (usb_get_dev_data(devinfo, &sc->sc_udev,
4243 	    USB_PARSE_LVL_ALL, 0) != USB_SUCCESS) {
4244 		sc->sc_udev = NULL;
4245 		goto fail2;
4246 	}
4247 
4248 	mutex_init(&sc->sc_genlock, NULL, MUTEX_DRIVER, NULL);
4249 	mutex_init(&sc->tx_lock, NULL, MUTEX_DRIVER, NULL);
4250 	mutex_init(&sc->rx_lock, NULL, MUTEX_DRIVER, NULL);
4251 	mutex_init(&sc->sc_ledlock, NULL, MUTEX_DRIVER, NULL);
4252 
4253 	e = urtw_lookup(sc->sc_udev->dev_descr->idVendor,
4254 	    sc->sc_udev->dev_descr->idProduct);
4255 	if (e == NULL) {
4256 		cmn_err(CE_WARN, "(urtw) unknown device\n");
4257 		goto fail2;
4258 	}
4259 	sc->sc_hwrev = e->rev;
4260 
4261 	if (sc->sc_hwrev & URTW_HWREV_8187) {
4262 		(void) urtw_read32_c(sc, URTW_TX_CONF, &data, 0);
4263 		data &= URTW_TX_HWREV_MASK;
4264 		switch (data) {
4265 		case URTW_TX_HWREV_8187_D:
4266 			sc->sc_hwrev |= URTW_HWREV_8187_D;
4267 			urtw_name = "RTL8187 rev. D";
4268 			break;
4269 		case URTW_TX_HWREV_8187B_D:
4270 			/*
4271 			 * Detect Realtek RTL8187B devices that use
4272 			 * USB IDs of RTL8187.
4273 			 */
4274 			sc->sc_hwrev = URTW_HWREV_8187B | URTW_HWREV_8187B_B;
4275 			urtw_name = "RTL8187B rev. B (early)";
4276 			break;
4277 		default:
4278 			sc->sc_hwrev |= URTW_HWREV_8187_B;
4279 			urtw_name = "RTL8187 rev. B (default)";
4280 			break;
4281 		}
4282 	} else {
4283 		/* RTL8187B hwrev register. */
4284 		(void) urtw_read8_c(sc, URTW_8187B_HWREV, &data8, 0);
4285 		switch (data8) {
4286 		case URTW_8187B_HWREV_8187B_B:
4287 			sc->sc_hwrev |= URTW_HWREV_8187B_B;
4288 			urtw_name = "RTL8187B rev. B";
4289 			break;
4290 		case URTW_8187B_HWREV_8187B_D:
4291 			sc->sc_hwrev |= URTW_HWREV_8187B_D;
4292 			urtw_name = "RTL8187B rev. D";
4293 			break;
4294 		case URTW_8187B_HWREV_8187B_E:
4295 			sc->sc_hwrev |= URTW_HWREV_8187B_E;
4296 			urtw_name = "RTL8187B rev. E";
4297 			break;
4298 		default:
4299 			sc->sc_hwrev |= URTW_HWREV_8187B_B;
4300 			urtw_name = "RTL8187B rev. B (default)";
4301 			break;
4302 		}
4303 	}
4304 
4305 	URTW8187_DBG(URTW_DEBUG_HWTYPE, (sc->sc_dev, CE_CONT,
4306 	    "urtw_attach: actual device is %s\n", urtw_name));
4307 	if (sc->sc_hwrev & URTW_HWREV_8187) {
4308 		sc->urtw_init = urtw_8187_init;
4309 	} else {
4310 		sc->urtw_init = urtw_8187b_init;
4311 	}
4312 
4313 	if (urtw_read32_c(sc, URTW_RX, &data, 0))
4314 		goto fail3;
4315 	sc->sc_epromtype = (data & URTW_RX_9356SEL) ? URTW_EEPROM_93C56 :
4316 	    URTW_EEPROM_93C46;
4317 	if (sc->sc_epromtype == URTW_EEPROM_93C56)
4318 		URTW8187_DBG(URTW_DEBUG_HWTYPE, (sc->sc_dev, CE_CONT,
4319 		    "urtw_attach: eprom is 93C56\n"));
4320 	else
4321 		URTW8187_DBG(URTW_DEBUG_HWTYPE, (sc->sc_dev, CE_CONT,
4322 		    "urtw_attach: eprom is 93C46\n"));
4323 	error = urtw_get_rfchip(sc);
4324 	if (error != 0)
4325 		goto fail3;
4326 	error = urtw_get_macaddr(sc);
4327 	if (error != 0)
4328 		goto fail3;
4329 	error = urtw_get_txpwr(sc);
4330 	if (error != 0)
4331 		goto fail3;
4332 	error = urtw_led_init(sc);		/* XXX incompleted  */
4333 	if (error != 0)
4334 		goto fail3;
4335 
4336 	sc->sc_rts_retry = URTW_DEFAULT_RTS_RETRY;
4337 	sc->sc_tx_retry = URTW_DEFAULT_TX_RETRY;
4338 	sc->sc_currate = 3;
4339 	/* XXX for what?  */
4340 	sc->sc_preamble_mode = 2;
4341 
4342 	ic->ic_phytype = IEEE80211_T_OFDM;	/* not only, but not used */
4343 	ic->ic_opmode = IEEE80211_M_STA;	/* default to BSS mode */
4344 	ic->ic_state = IEEE80211_S_INIT;
4345 
4346 	ic->ic_maxrssi = 95;
4347 	ic->ic_xmit = urtw_send;
4348 
4349 	ic->ic_caps |= IEEE80211_C_WPA | /* Support WPA/WPA2 */
4350 	    IEEE80211_C_TXPMGT |	/* tx power management */
4351 	    IEEE80211_C_SHPREAMBLE |	/* short preamble supported */
4352 	    IEEE80211_C_SHSLOT;	/* short slot time supported */
4353 	/* set supported .11b and .11g rates */
4354 	ic->ic_sup_rates[IEEE80211_MODE_11B] = urtw_rateset_11b;
4355 	ic->ic_sup_rates[IEEE80211_MODE_11G] = urtw_rateset_11g;
4356 
4357 	/* set supported .11b and .11g channels (1 through 11) */
4358 	for (i = 1; i <= 11; i++) {
4359 		ic->ic_sup_channels[i].ich_freq =
4360 		    ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
4361 		ic->ic_sup_channels[i].ich_flags =
4362 		    IEEE80211_CHAN_CCK | IEEE80211_CHAN_DYN |
4363 		    IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM;
4364 	}
4365 
4366 	ieee80211_attach(ic);
4367 	ic->ic_ibss_chan = &ic->ic_sup_channels[1];
4368 	ic->ic_curchan = ic->ic_ibss_chan;
4369 
4370 	/* register WPA door */
4371 	ieee80211_register_door(ic, ddi_driver_name(devinfo),
4372 	    ddi_get_instance(devinfo));
4373 
4374 	/* override state transition machine */
4375 	sc->sc_newstate = ic->ic_newstate;
4376 	ic->ic_newstate = urtw_newstate;
4377 	ic->ic_watchdog = urtw_watchdog;
4378 	ieee80211_media_init(ic);
4379 	ic->ic_def_txkey = 0;
4380 
4381 	sc->dwelltime = 250;
4382 	sc->sc_flags = 0;
4383 
4384 	/*
4385 	 * Provide initial settings for the WiFi plugin; whenever this
4386 	 * information changes, we need to call mac_plugindata_update()
4387 	 */
4388 	wd.wd_opmode = ic->ic_opmode;
4389 	wd.wd_secalloc = WIFI_SEC_NONE;
4390 	IEEE80211_ADDR_COPY(wd.wd_bssid, ic->ic_bss->in_bssid);
4391 
4392 	if ((macp = mac_alloc(MAC_VERSION)) == NULL) {
4393 		URTW8187_DBG(URTW_DEBUG_ATTACH, (sc->sc_dev, CE_CONT,
4394 		    "MAC version alloc failed\n"));
4395 		goto fail4;
4396 	}
4397 
4398 	macp->m_type_ident = MAC_PLUGIN_IDENT_WIFI;
4399 	macp->m_driver = sc;
4400 	macp->m_dip = devinfo;
4401 	macp->m_src_addr = ic->ic_macaddr;
4402 	macp->m_callbacks = &urtw_m_callbacks;
4403 	macp->m_min_sdu	= 0;
4404 	macp->m_max_sdu	= IEEE80211_MTU;
4405 	macp->m_pdata = &wd;
4406 	macp->m_pdata_size = sizeof (wd);
4407 
4408 	error = mac_register(macp, &ic->ic_mach);
4409 	mac_free(macp);
4410 	if (error != 0) {
4411 		cmn_err(CE_WARN, "urtw_attach: mac_register() err %x\n", error);
4412 		goto fail4;
4413 	}
4414 
4415 	if (usb_register_hotplug_cbs(devinfo, urtw_disconnect,
4416 	    urtw_reconnect) != USB_SUCCESS) {
4417 		cmn_err(CE_WARN, "urtw_attach: failed to register events");
4418 		goto fail5;
4419 	}
4420 
4421 	/*
4422 	 * Create minor node of type DDI_NT_NET_WIFI
4423 	 */
4424 	(void) snprintf(strbuf, sizeof (strbuf), "%s%d",
4425 	    "urtw", instance);
4426 	error = ddi_create_minor_node(devinfo, strbuf, S_IFCHR,
4427 	    instance + 1, DDI_NT_NET_WIFI, 0);
4428 
4429 	if (error != DDI_SUCCESS)
4430 		cmn_err(CE_WARN, "urtw: ddi_create_minor_node() failed\n");
4431 	/*
4432 	 * Notify link is down now
4433 	 */
4434 	mac_link_update(ic->ic_mach, LINK_STATE_DOWN);
4435 
4436 	URTW8187_DBG(URTW_DEBUG_ATTACH, (sc->sc_dev, CE_CONT,
4437 	    "urtw_attach: successfully.\n"));
4438 	return (DDI_SUCCESS);
4439 fail5:
4440 	(void) mac_disable(ic->ic_mach);
4441 	(void) mac_unregister(ic->ic_mach);
4442 fail4:
4443 	ieee80211_detach(ic);
4444 fail3:
4445 	mutex_destroy(&sc->sc_genlock);
4446 	mutex_destroy(&sc->tx_lock);
4447 	mutex_destroy(&sc->rx_lock);
4448 	mutex_destroy(&sc->sc_ledlock);
4449 fail2:
4450 	usb_client_detach(sc->sc_dev, sc->sc_udev);
4451 fail1:
4452 	ddi_soft_state_free(urtw_soft_state_p, ddi_get_instance(devinfo));
4453 
4454 	return (DDI_FAILURE);
4455 }
4456 
4457 static int
4458 urtw_detach(dev_info_t *devinfo, ddi_detach_cmd_t cmd)
4459 {
4460 	struct urtw_softc *sc;
4461 
4462 	sc = ddi_get_soft_state(urtw_soft_state_p, ddi_get_instance(devinfo));
4463 	URTW8187_DBG(URTW_DEBUG_ATTACH, (sc->sc_dev,
4464 	    CE_CONT, "urtw_detach()\n"));
4465 
4466 	switch (cmd) {
4467 	case DDI_DETACH:
4468 		break;
4469 	case DDI_SUSPEND:
4470 		URTW8187_DBG(URTW_DEBUG_ATTACH,
4471 		    (sc->sc_dev, CE_CONT, "urtw: suspend\n"));
4472 
4473 		ieee80211_new_state(&sc->sc_ic, IEEE80211_S_INIT, -1);
4474 		ieee80211_stop_watchdog(&sc->sc_ic);
4475 
4476 		URTW_LOCK(sc);
4477 		sc->sc_flags |= URTW_FLAG_SUSPEND;
4478 		URTW_UNLOCK(sc);
4479 		if (URTW_IS_RUNNING(sc)) {
4480 			urtw_stop(sc);
4481 			URTW_LOCK(sc);
4482 			sc->sc_flags |= URTW_FLAG_PLUGIN_ONLINE;
4483 			URTW_UNLOCK(sc);
4484 		}
4485 		return (DDI_SUCCESS);
4486 	default:
4487 		return (DDI_FAILURE);
4488 	}
4489 
4490 	if (mac_disable(sc->sc_ic.ic_mach) != 0)
4491 		return (DDI_FAILURE);
4492 	urtw_stop(sc);
4493 	/*
4494 	 * Unregister from the MAC layer subsystem
4495 	 */
4496 	(void) mac_unregister(sc->sc_ic.ic_mach);
4497 
4498 	ieee80211_detach(&sc->sc_ic);
4499 	usb_unregister_hotplug_cbs(devinfo);
4500 	usb_client_detach(devinfo, sc->sc_udev);
4501 	mutex_destroy(&sc->sc_genlock);
4502 	mutex_destroy(&sc->tx_lock);
4503 	mutex_destroy(&sc->rx_lock);
4504 	mutex_destroy(&sc->sc_ledlock);
4505 	sc->sc_udev = NULL;
4506 
4507 	ddi_remove_minor_node(devinfo, NULL);
4508 	ddi_soft_state_free(urtw_soft_state_p, ddi_get_instance(devinfo));
4509 
4510 	return (DDI_SUCCESS);
4511 }
4512 
4513 int
4514 _info(struct modinfo *modinfop)
4515 {
4516 	return (mod_info(&modlinkage, modinfop));
4517 }
4518 
4519 int
4520 _init(void)
4521 {
4522 	int status;
4523 
4524 	status = ddi_soft_state_init(&urtw_soft_state_p,
4525 	    sizeof (struct urtw_softc), 1);
4526 	if (status != 0)
4527 		return (status);
4528 
4529 	mac_init_ops(&urtw_dev_ops, "urtw");
4530 	status = mod_install(&modlinkage);
4531 	if (status != 0) {
4532 		mac_fini_ops(&urtw_dev_ops);
4533 		ddi_soft_state_fini(&urtw_soft_state_p);
4534 	}
4535 	return (status);
4536 }
4537 
4538 int
4539 _fini(void)
4540 {
4541 	int status;
4542 
4543 	status = mod_remove(&modlinkage);
4544 	if (status == 0) {
4545 		mac_fini_ops(&urtw_dev_ops);
4546 		ddi_soft_state_fini(&urtw_soft_state_p);
4547 	}
4548 	return (status);
4549 }
4550