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