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