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