if_urtw.c revision 246614
1/*-
2 * Copyright (c) 2008 Weongyo Jeong <weongyo@FreeBSD.org>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <sys/cdefs.h>
18__FBSDID("$FreeBSD: head/sys/dev/usb/wlan/if_urtw.c 246614 2013-02-10 10:36:16Z hselasky $");
19#include <sys/param.h>
20#include <sys/sockio.h>
21#include <sys/sysctl.h>
22#include <sys/lock.h>
23#include <sys/mutex.h>
24#include <sys/mbuf.h>
25#include <sys/kernel.h>
26#include <sys/socket.h>
27#include <sys/systm.h>
28#include <sys/malloc.h>
29#include <sys/module.h>
30#include <sys/bus.h>
31#include <sys/endian.h>
32#include <sys/kdb.h>
33
34#include <machine/bus.h>
35#include <machine/resource.h>
36#include <sys/rman.h>
37
38#include <net/if.h>
39#include <net/if_arp.h>
40#include <net/ethernet.h>
41#include <net/if_dl.h>
42#include <net/if_media.h>
43#include <net/if_types.h>
44
45#ifdef INET
46#include <netinet/in.h>
47#include <netinet/in_systm.h>
48#include <netinet/in_var.h>
49#include <netinet/if_ether.h>
50#include <netinet/ip.h>
51#endif
52
53#include <net80211/ieee80211_var.h>
54#include <net80211/ieee80211_regdomain.h>
55#include <net80211/ieee80211_radiotap.h>
56
57#include <dev/usb/usb.h>
58#include <dev/usb/usbdi.h>
59#include "usbdevs.h"
60
61#include <dev/usb/wlan/if_urtwreg.h>
62#include <dev/usb/wlan/if_urtwvar.h>
63
64static SYSCTL_NODE(_hw_usb, OID_AUTO, urtw, CTLFLAG_RW, 0, "USB Realtek 8187L");
65#ifdef URTW_DEBUG
66int urtw_debug = 0;
67SYSCTL_INT(_hw_usb_urtw, OID_AUTO, debug, CTLFLAG_RW | CTLFLAG_TUN, &urtw_debug, 0,
68    "control debugging printfs");
69TUNABLE_INT("hw.usb.urtw.debug", &urtw_debug);
70enum {
71	URTW_DEBUG_XMIT		= 0x00000001,	/* basic xmit operation */
72	URTW_DEBUG_RECV		= 0x00000002,	/* basic recv operation */
73	URTW_DEBUG_RESET	= 0x00000004,	/* reset processing */
74	URTW_DEBUG_TX_PROC	= 0x00000008,	/* tx ISR proc */
75	URTW_DEBUG_RX_PROC	= 0x00000010,	/* rx ISR proc */
76	URTW_DEBUG_STATE	= 0x00000020,	/* 802.11 state transitions */
77	URTW_DEBUG_STAT		= 0x00000040,	/* statistic */
78	URTW_DEBUG_INIT		= 0x00000080,	/* initialization of dev */
79	URTW_DEBUG_TXSTATUS	= 0x00000100,	/* tx status */
80	URTW_DEBUG_ANY		= 0xffffffff
81};
82#define	DPRINTF(sc, m, fmt, ...) do {				\
83	if (sc->sc_debug & (m))					\
84		printf(fmt, __VA_ARGS__);			\
85} while (0)
86#else
87#define	DPRINTF(sc, m, fmt, ...) do {				\
88	(void) sc;						\
89} while (0)
90#endif
91static int urtw_preamble_mode = URTW_PREAMBLE_MODE_LONG;
92SYSCTL_INT(_hw_usb_urtw, OID_AUTO, preamble_mode, CTLFLAG_RW | CTLFLAG_TUN,
93    &urtw_preamble_mode, 0, "set the preable mode (long or short)");
94TUNABLE_INT("hw.usb.urtw.preamble_mode", &urtw_preamble_mode);
95
96/* recognized device vendors/products */
97#define urtw_lookup(v, p)						\
98	((const struct urtw_type *)usb_lookup(urtw_devs, v, p))
99#define	URTW_DEV_B(v,p)							\
100	{ USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, URTW_REV_RTL8187B) }
101#define	URTW_DEV_L(v,p)							\
102	{ USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, URTW_REV_RTL8187L) }
103#define	URTW_REV_RTL8187B	0
104#define	URTW_REV_RTL8187L	1
105static const STRUCT_USB_HOST_ID urtw_devs[] = {
106	URTW_DEV_B(NETGEAR, WG111V3),
107	URTW_DEV_B(REALTEK, RTL8187B_0),
108	URTW_DEV_B(REALTEK, RTL8187B_1),
109	URTW_DEV_B(REALTEK, RTL8187B_2),
110	URTW_DEV_B(SITECOMEU, WL168V4),
111	URTW_DEV_L(ASUS, P5B_WIFI),
112	URTW_DEV_L(BELKIN, F5D7050E),
113	URTW_DEV_L(LINKSYS4, WUSB54GCV2),
114	URTW_DEV_L(NETGEAR, WG111V2),
115	URTW_DEV_L(REALTEK, RTL8187),
116	URTW_DEV_L(SITECOMEU, WL168V1),
117	URTW_DEV_L(SURECOM, EP9001G2A),
118	{ USB_VPI(USB_VENDOR_OVISLINK, 0x8187, URTW_REV_RTL8187L) },
119	{ USB_VPI(USB_VENDOR_DICKSMITH, 0x9401, URTW_REV_RTL8187L) },
120	{ USB_VPI(USB_VENDOR_HP, 0xca02, URTW_REV_RTL8187L) },
121	{ USB_VPI(USB_VENDOR_LOGITEC, 0x010c, URTW_REV_RTL8187L) },
122	{ USB_VPI(USB_VENDOR_NETGEAR, 0x6100, URTW_REV_RTL8187L) },
123	{ USB_VPI(USB_VENDOR_SPHAIRON, 0x0150, URTW_REV_RTL8187L) },
124	{ USB_VPI(USB_VENDOR_QCOM, 0x6232, URTW_REV_RTL8187L) },
125#undef URTW_DEV_L
126#undef URTW_DEV_B
127};
128
129#define urtw_read8_m(sc, val, data)	do {			\
130	error = urtw_read8_c(sc, val, data);			\
131	if (error != 0)						\
132		goto fail;					\
133} while (0)
134#define urtw_write8_m(sc, val, data)	do {			\
135	error = urtw_write8_c(sc, val, data);			\
136	if (error != 0)						\
137		goto fail;					\
138} while (0)
139#define urtw_read16_m(sc, val, data)	do {			\
140	error = urtw_read16_c(sc, val, data);			\
141	if (error != 0)						\
142		goto fail;					\
143} while (0)
144#define urtw_write16_m(sc, val, data)	do {			\
145	error = urtw_write16_c(sc, val, data);			\
146	if (error != 0)						\
147		goto fail;					\
148} while (0)
149#define urtw_read32_m(sc, val, data)	do {			\
150	error = urtw_read32_c(sc, val, data);			\
151	if (error != 0)						\
152		goto fail;					\
153} while (0)
154#define urtw_write32_m(sc, val, data)	do {			\
155	error = urtw_write32_c(sc, val, data);			\
156	if (error != 0)						\
157		goto fail;					\
158} while (0)
159#define urtw_8187_write_phy_ofdm(sc, val, data)	do {		\
160	error = urtw_8187_write_phy_ofdm_c(sc, val, data);	\
161	if (error != 0)						\
162		goto fail;					\
163} while (0)
164#define urtw_8187_write_phy_cck(sc, val, data)	do {		\
165	error = urtw_8187_write_phy_cck_c(sc, val, data);	\
166	if (error != 0)						\
167		goto fail;					\
168} while (0)
169#define urtw_8225_write(sc, val, data)	do {			\
170	error = urtw_8225_write_c(sc, val, data);		\
171	if (error != 0)						\
172		goto fail;					\
173} while (0)
174
175struct urtw_pair {
176	uint32_t	reg;
177	uint32_t	val;
178};
179
180static uint8_t urtw_8225_agc[] = {
181	0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9d, 0x9c, 0x9b,
182	0x9a, 0x99, 0x98, 0x97, 0x96, 0x95, 0x94, 0x93, 0x92, 0x91, 0x90,
183	0x8f, 0x8e, 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86, 0x85,
184	0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a,
185	0x39, 0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f,
186	0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24,
187	0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19,
188	0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e,
189	0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03,
190	0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
191	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
192	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
193};
194
195static uint8_t urtw_8225z2_agc[] = {
196	0x5e, 0x5e, 0x5e, 0x5e, 0x5d, 0x5b, 0x59, 0x57, 0x55, 0x53, 0x51,
197	0x4f, 0x4d, 0x4b, 0x49, 0x47, 0x45, 0x43, 0x41, 0x3f, 0x3d, 0x3b,
198	0x39, 0x37, 0x35, 0x33, 0x31, 0x2f, 0x2d, 0x2b, 0x29, 0x27, 0x25,
199	0x23, 0x21, 0x1f, 0x1d, 0x1b, 0x19, 0x17, 0x15, 0x13, 0x11, 0x0f,
200	0x0d, 0x0b, 0x09, 0x07, 0x05, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01,
201	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x19, 0x19,
202	0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x20, 0x21, 0x22, 0x23,
203	0x24, 0x25, 0x26, 0x26, 0x27, 0x27, 0x28, 0x28, 0x29, 0x2a, 0x2a,
204	0x2a, 0x2b, 0x2b, 0x2b, 0x2c, 0x2c, 0x2c, 0x2d, 0x2d, 0x2d, 0x2d,
205	0x2e, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x2f, 0x30, 0x30, 0x31, 0x31,
206	0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
207	0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31
208};
209
210static uint32_t urtw_8225_channel[] = {
211	0x0000,		/* dummy channel 0  */
212	0x085c,		/* 1  */
213	0x08dc,		/* 2  */
214	0x095c,		/* 3  */
215	0x09dc,		/* 4  */
216	0x0a5c,		/* 5  */
217	0x0adc,		/* 6  */
218	0x0b5c,		/* 7  */
219	0x0bdc,		/* 8  */
220	0x0c5c,		/* 9  */
221	0x0cdc,		/* 10  */
222	0x0d5c,		/* 11  */
223	0x0ddc,		/* 12  */
224	0x0e5c,		/* 13  */
225	0x0f72,		/* 14  */
226};
227
228static uint8_t urtw_8225_gain[] = {
229	0x23, 0x88, 0x7c, 0xa5,		/* -82dbm  */
230	0x23, 0x88, 0x7c, 0xb5,		/* -82dbm  */
231	0x23, 0x88, 0x7c, 0xc5,		/* -82dbm  */
232	0x33, 0x80, 0x79, 0xc5,		/* -78dbm  */
233	0x43, 0x78, 0x76, 0xc5,		/* -74dbm  */
234	0x53, 0x60, 0x73, 0xc5,		/* -70dbm  */
235	0x63, 0x58, 0x70, 0xc5,		/* -66dbm  */
236};
237
238static struct urtw_pair urtw_8225_rf_part1[] = {
239	{ 0x00, 0x0067 }, { 0x01, 0x0fe0 }, { 0x02, 0x044d }, { 0x03, 0x0441 },
240	{ 0x04, 0x0486 }, { 0x05, 0x0bc0 }, { 0x06, 0x0ae6 }, { 0x07, 0x082a },
241	{ 0x08, 0x001f }, { 0x09, 0x0334 }, { 0x0a, 0x0fd4 }, { 0x0b, 0x0391 },
242	{ 0x0c, 0x0050 }, { 0x0d, 0x06db }, { 0x0e, 0x0029 }, { 0x0f, 0x0914 },
243};
244
245static struct urtw_pair urtw_8225_rf_part2[] = {
246	{ 0x00, 0x01 }, { 0x01, 0x02 }, { 0x02, 0x42 }, { 0x03, 0x00 },
247	{ 0x04, 0x00 }, { 0x05, 0x00 }, { 0x06, 0x40 }, { 0x07, 0x00 },
248	{ 0x08, 0x40 }, { 0x09, 0xfe }, { 0x0a, 0x09 }, { 0x0b, 0x80 },
249	{ 0x0c, 0x01 }, { 0x0e, 0xd3 }, { 0x0f, 0x38 }, { 0x10, 0x84 },
250	{ 0x11, 0x06 }, { 0x12, 0x20 }, { 0x13, 0x20 }, { 0x14, 0x00 },
251	{ 0x15, 0x40 }, { 0x16, 0x00 }, { 0x17, 0x40 }, { 0x18, 0xef },
252	{ 0x19, 0x19 }, { 0x1a, 0x20 }, { 0x1b, 0x76 }, { 0x1c, 0x04 },
253	{ 0x1e, 0x95 }, { 0x1f, 0x75 }, { 0x20, 0x1f }, { 0x21, 0x27 },
254	{ 0x22, 0x16 }, { 0x24, 0x46 }, { 0x25, 0x20 }, { 0x26, 0x90 },
255	{ 0x27, 0x88 }
256};
257
258static struct urtw_pair urtw_8225_rf_part3[] = {
259	{ 0x00, 0x98 }, { 0x03, 0x20 }, { 0x04, 0x7e }, { 0x05, 0x12 },
260	{ 0x06, 0xfc }, { 0x07, 0x78 }, { 0x08, 0x2e }, { 0x10, 0x9b },
261	{ 0x11, 0x88 }, { 0x12, 0x47 }, { 0x13, 0xd0 }, { 0x19, 0x00 },
262	{ 0x1a, 0xa0 }, { 0x1b, 0x08 }, { 0x40, 0x86 }, { 0x41, 0x8d },
263	{ 0x42, 0x15 }, { 0x43, 0x18 }, { 0x44, 0x1f }, { 0x45, 0x1e },
264	{ 0x46, 0x1a }, { 0x47, 0x15 }, { 0x48, 0x10 }, { 0x49, 0x0a },
265	{ 0x4a, 0x05 }, { 0x4b, 0x02 }, { 0x4c, 0x05 }
266};
267
268static uint16_t urtw_8225_rxgain[] = {
269	0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
270	0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
271	0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
272	0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
273	0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
274	0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
275	0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
276	0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
277	0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
278	0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
279	0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3,
280	0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb
281};
282
283static uint8_t urtw_8225_threshold[] = {
284	0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd,
285};
286
287static uint8_t urtw_8225_tx_gain_cck_ofdm[] = {
288	0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e
289};
290
291static uint8_t urtw_8225_txpwr_cck[] = {
292	0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02,
293	0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02,
294	0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02,
295	0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02,
296	0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03,
297	0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03
298};
299
300static uint8_t urtw_8225_txpwr_cck_ch14[] = {
301	0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00,
302	0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00,
303	0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00,
304	0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00,
305	0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00,
306	0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00
307};
308
309static uint8_t urtw_8225_txpwr_ofdm[]={
310	0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4
311};
312
313static uint8_t urtw_8225v2_gain_bg[]={
314	0x23, 0x15, 0xa5,		/* -82-1dbm  */
315	0x23, 0x15, 0xb5,		/* -82-2dbm  */
316	0x23, 0x15, 0xc5,		/* -82-3dbm  */
317	0x33, 0x15, 0xc5,		/* -78dbm  */
318	0x43, 0x15, 0xc5,		/* -74dbm  */
319	0x53, 0x15, 0xc5,		/* -70dbm  */
320	0x63, 0x15, 0xc5,		/* -66dbm  */
321};
322
323static struct urtw_pair urtw_8225v2_rf_part1[] = {
324	{ 0x00, 0x02bf }, { 0x01, 0x0ee0 }, { 0x02, 0x044d }, { 0x03, 0x0441 },
325	{ 0x04, 0x08c3 }, { 0x05, 0x0c72 }, { 0x06, 0x00e6 }, { 0x07, 0x082a },
326	{ 0x08, 0x003f }, { 0x09, 0x0335 }, { 0x0a, 0x09d4 }, { 0x0b, 0x07bb },
327	{ 0x0c, 0x0850 }, { 0x0d, 0x0cdf }, { 0x0e, 0x002b }, { 0x0f, 0x0114 }
328};
329
330static struct urtw_pair urtw_8225v2b_rf_part0[] = {
331	{ 0x00, 0x00b7 }, { 0x01, 0x0ee0 }, { 0x02, 0x044d }, { 0x03, 0x0441 },
332	{ 0x04, 0x08c3 }, { 0x05, 0x0c72 }, { 0x06, 0x00e6 }, { 0x07, 0x082a },
333	{ 0x08, 0x003f }, { 0x09, 0x0335 }, { 0x0a, 0x09d4 }, { 0x0b, 0x07bb },
334	{ 0x0c, 0x0850 }, { 0x0d, 0x0cdf }, { 0x0e, 0x002b }, { 0x0f, 0x0114 }
335};
336
337static struct urtw_pair urtw_8225v2b_rf_part1[] = {
338	{0x0f0, 0x32}, {0x0f1, 0x32}, {0x0f2, 0x00},
339	{0x0f3, 0x00}, {0x0f4, 0x32}, {0x0f5, 0x43},
340	{0x0f6, 0x00}, {0x0f7, 0x00}, {0x0f8, 0x46},
341	{0x0f9, 0xa4}, {0x0fa, 0x00}, {0x0fb, 0x00},
342	{0x0fc, 0x96}, {0x0fd, 0xa4}, {0x0fe, 0x00},
343	{0x0ff, 0x00}, {0x158, 0x4b}, {0x159, 0x00},
344	{0x15a, 0x4b}, {0x15b, 0x00}, {0x160, 0x4b},
345	{0x161, 0x09}, {0x162, 0x4b}, {0x163, 0x09},
346	{0x1ce, 0x0f}, {0x1cf, 0x00}, {0x1e0, 0xff},
347	{0x1e1, 0x0f}, {0x1e2, 0x00}, {0x1f0, 0x4e},
348	{0x1f1, 0x01}, {0x1f2, 0x02}, {0x1f3, 0x03},
349	{0x1f4, 0x04}, {0x1f5, 0x05}, {0x1f6, 0x06},
350	{0x1f7, 0x07}, {0x1f8, 0x08}, {0x24e, 0x00},
351	{0x20c, 0x04}, {0x221, 0x61}, {0x222, 0x68},
352	{0x223, 0x6f}, {0x224, 0x76}, {0x225, 0x7d},
353	{0x226, 0x84}, {0x227, 0x8d}, {0x24d, 0x08},
354	{0x250, 0x05}, {0x251, 0xf5}, {0x252, 0x04},
355	{0x253, 0xa0}, {0x254, 0x1f}, {0x255, 0x23},
356	{0x256, 0x45}, {0x257, 0x67}, {0x258, 0x08},
357	{0x259, 0x08}, {0x25a, 0x08}, {0x25b, 0x08},
358	{0x260, 0x08}, {0x261, 0x08}, {0x262, 0x08},
359	{0x263, 0x08}, {0x264, 0xcf}, {0x272, 0x56},
360	{0x273, 0x9a}, {0x034, 0xf0}, {0x035, 0x0f},
361	{0x05b, 0x40}, {0x084, 0x88}, {0x085, 0x24},
362	{0x088, 0x54}, {0x08b, 0xb8}, {0x08c, 0x07},
363	{0x08d, 0x00}, {0x094, 0x1b}, {0x095, 0x12},
364	{0x096, 0x00}, {0x097, 0x06}, {0x09d, 0x1a},
365	{0x09f, 0x10}, {0x0b4, 0x22}, {0x0be, 0x80},
366	{0x0db, 0x00}, {0x0ee, 0x00}, {0x091, 0x03},
367	{0x24c, 0x00}, {0x39f, 0x00}, {0x08c, 0x01},
368	{0x08d, 0x10}, {0x08e, 0x08}, {0x08f, 0x00}
369};
370
371static struct urtw_pair urtw_8225v2_rf_part2[] = {
372	{ 0x00, 0x01 }, { 0x01, 0x02 }, { 0x02, 0x42 }, { 0x03, 0x00 },
373	{ 0x04, 0x00 },	{ 0x05, 0x00 }, { 0x06, 0x40 }, { 0x07, 0x00 },
374	{ 0x08, 0x40 }, { 0x09, 0xfe }, { 0x0a, 0x08 }, { 0x0b, 0x80 },
375	{ 0x0c, 0x01 }, { 0x0d, 0x43 }, { 0x0e, 0xd3 }, { 0x0f, 0x38 },
376	{ 0x10, 0x84 }, { 0x11, 0x07 }, { 0x12, 0x20 }, { 0x13, 0x20 },
377	{ 0x14, 0x00 }, { 0x15, 0x40 }, { 0x16, 0x00 }, { 0x17, 0x40 },
378	{ 0x18, 0xef }, { 0x19, 0x19 }, { 0x1a, 0x20 }, { 0x1b, 0x15 },
379	{ 0x1c, 0x04 }, { 0x1d, 0xc5 }, { 0x1e, 0x95 }, { 0x1f, 0x75 },
380	{ 0x20, 0x1f }, { 0x21, 0x17 }, { 0x22, 0x16 }, { 0x23, 0x80 },
381	{ 0x24, 0x46 }, { 0x25, 0x00 }, { 0x26, 0x90 }, { 0x27, 0x88 }
382};
383
384static struct urtw_pair urtw_8225v2b_rf_part2[] = {
385	{ 0x00, 0x10 }, { 0x01, 0x0d }, { 0x02, 0x01 }, { 0x03, 0x00 },
386	{ 0x04, 0x14 }, { 0x05, 0xfb }, { 0x06, 0xfb }, { 0x07, 0x60 },
387	{ 0x08, 0x00 }, { 0x09, 0x60 }, { 0x0a, 0x00 }, { 0x0b, 0x00 },
388	{ 0x0c, 0x00 }, { 0x0d, 0x5c }, { 0x0e, 0x00 }, { 0x0f, 0x00 },
389	{ 0x10, 0x40 }, { 0x11, 0x00 }, { 0x12, 0x40 }, { 0x13, 0x00 },
390	{ 0x14, 0x00 }, { 0x15, 0x00 }, { 0x16, 0xa8 }, { 0x17, 0x26 },
391	{ 0x18, 0x32 }, { 0x19, 0x33 }, { 0x1a, 0x07 }, { 0x1b, 0xa5 },
392	{ 0x1c, 0x6f }, { 0x1d, 0x55 }, { 0x1e, 0xc8 }, { 0x1f, 0xb3 },
393	{ 0x20, 0x0a }, { 0x21, 0xe1 }, { 0x22, 0x2C }, { 0x23, 0x8a },
394	{ 0x24, 0x86 }, { 0x25, 0x83 }, { 0x26, 0x34 }, { 0x27, 0x0f },
395	{ 0x28, 0x4f }, { 0x29, 0x24 }, { 0x2a, 0x6f }, { 0x2b, 0xc2 },
396	{ 0x2c, 0x6b }, { 0x2d, 0x40 }, { 0x2e, 0x80 }, { 0x2f, 0x00 },
397	{ 0x30, 0xc0 }, { 0x31, 0xc1 }, { 0x32, 0x58 }, { 0x33, 0xf1 },
398	{ 0x34, 0x00 }, { 0x35, 0xe4 }, { 0x36, 0x90 }, { 0x37, 0x3e },
399	{ 0x38, 0x6d }, { 0x39, 0x3c }, { 0x3a, 0xfb }, { 0x3b, 0x07 }
400};
401
402static struct urtw_pair urtw_8225v2_rf_part3[] = {
403	{ 0x00, 0x98 }, { 0x03, 0x20 }, { 0x04, 0x7e }, { 0x05, 0x12 },
404	{ 0x06, 0xfc }, { 0x07, 0x78 }, { 0x08, 0x2e }, { 0x09, 0x11 },
405	{ 0x0a, 0x17 }, { 0x0b, 0x11 }, { 0x10, 0x9b }, { 0x11, 0x88 },
406	{ 0x12, 0x47 }, { 0x13, 0xd0 }, { 0x19, 0x00 }, { 0x1a, 0xa0 },
407	{ 0x1b, 0x08 }, { 0x1d, 0x00 }, { 0x40, 0x86 }, { 0x41, 0x9d },
408	{ 0x42, 0x15 }, { 0x43, 0x18 }, { 0x44, 0x36 }, { 0x45, 0x35 },
409	{ 0x46, 0x2e }, { 0x47, 0x25 }, { 0x48, 0x1c }, { 0x49, 0x12 },
410	{ 0x4a, 0x09 }, { 0x4b, 0x04 }, { 0x4c, 0x05 }
411};
412
413static uint16_t urtw_8225v2_rxgain[] = {
414	0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0008, 0x0009,
415	0x000a, 0x000b, 0x0102, 0x0103, 0x0104, 0x0105, 0x0140, 0x0141,
416	0x0142, 0x0143, 0x0144, 0x0145, 0x0180, 0x0181, 0x0182, 0x0183,
417	0x0184, 0x0185, 0x0188, 0x0189, 0x018a, 0x018b, 0x0243, 0x0244,
418	0x0245, 0x0280, 0x0281, 0x0282, 0x0283, 0x0284, 0x0285, 0x0288,
419	0x0289, 0x028a, 0x028b, 0x028c, 0x0342, 0x0343, 0x0344, 0x0345,
420	0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x0388, 0x0389,
421	0x038a, 0x038b, 0x038c, 0x038d, 0x0390, 0x0391, 0x0392, 0x0393,
422	0x0394, 0x0395, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d,
423	0x03a0, 0x03a1, 0x03a2, 0x03a3, 0x03a4, 0x03a5, 0x03a8, 0x03a9,
424	0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
425	0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
426};
427
428static uint16_t urtw_8225v2b_rxgain[] = {
429	0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
430	0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
431	0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
432	0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
433	0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
434	0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
435	0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
436	0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
437	0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
438	0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
439	0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
440	0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
441};
442
443static uint8_t urtw_8225v2_tx_gain_cck_ofdm[] = {
444	0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
445	0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
446	0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
447	0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
448	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
449	0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
450};
451
452static uint8_t urtw_8225v2_txpwr_cck[] = {
453	0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04
454};
455
456static uint8_t urtw_8225v2_txpwr_cck_ch14[] = {
457	0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00
458};
459
460static uint8_t urtw_8225v2b_txpwr_cck[] = {
461	0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04,
462	0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03,
463	0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03,
464	0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03
465};
466
467static uint8_t urtw_8225v2b_txpwr_cck_ch14[] = {
468	0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00,
469	0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
470	0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
471	0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00
472};
473
474static struct urtw_pair urtw_ratetable[] = {
475	{  2,  0 }, {   4,  1 }, { 11, 2 }, { 12, 4 }, { 18, 5 },
476	{ 22,  3 }, {  24,  6 }, { 36, 7 }, { 48, 8 }, { 72, 9 },
477	{ 96, 10 }, { 108, 11 }
478};
479
480static const uint8_t urtw_8187b_reg_table[][3] = {
481	{ 0xf0, 0x32, 0 }, { 0xf1, 0x32, 0 }, { 0xf2, 0x00, 0 },
482	{ 0xf3, 0x00, 0 }, { 0xf4, 0x32, 0 }, { 0xf5, 0x43, 0 },
483	{ 0xf6, 0x00, 0 }, { 0xf7, 0x00, 0 }, { 0xf8, 0x46, 0 },
484	{ 0xf9, 0xa4, 0 }, { 0xfa, 0x00, 0 }, { 0xfb, 0x00, 0 },
485	{ 0xfc, 0x96, 0 }, { 0xfd, 0xa4, 0 }, { 0xfe, 0x00, 0 },
486	{ 0xff, 0x00, 0 }, { 0x58, 0x4b, 1 }, { 0x59, 0x00, 1 },
487	{ 0x5a, 0x4b, 1 }, { 0x5b, 0x00, 1 }, { 0x60, 0x4b, 1 },
488	{ 0x61, 0x09, 1 }, { 0x62, 0x4b, 1 }, { 0x63, 0x09, 1 },
489	{ 0xce, 0x0f, 1 }, { 0xcf, 0x00, 1 }, { 0xe0, 0xff, 1 },
490	{ 0xe1, 0x0f, 1 }, { 0xe2, 0x00, 1 }, { 0xf0, 0x4e, 1 },
491	{ 0xf1, 0x01, 1 }, { 0xf2, 0x02, 1 }, { 0xf3, 0x03, 1 },
492	{ 0xf4, 0x04, 1 }, { 0xf5, 0x05, 1 }, { 0xf6, 0x06, 1 },
493	{ 0xf7, 0x07, 1 }, { 0xf8, 0x08, 1 }, { 0x4e, 0x00, 2 },
494	{ 0x0c, 0x04, 2 }, { 0x21, 0x61, 2 }, { 0x22, 0x68, 2 },
495	{ 0x23, 0x6f, 2 }, { 0x24, 0x76, 2 }, { 0x25, 0x7d, 2 },
496	{ 0x26, 0x84, 2 }, { 0x27, 0x8d, 2 }, { 0x4d, 0x08, 2 },
497	{ 0x50, 0x05, 2 }, { 0x51, 0xf5, 2 }, { 0x52, 0x04, 2 },
498	{ 0x53, 0xa0, 2 }, { 0x54, 0x1f, 2 }, { 0x55, 0x23, 2 },
499	{ 0x56, 0x45, 2 }, { 0x57, 0x67, 2 }, { 0x58, 0x08, 2 },
500	{ 0x59, 0x08, 2 }, { 0x5a, 0x08, 2 }, { 0x5b, 0x08, 2 },
501	{ 0x60, 0x08, 2 }, { 0x61, 0x08, 2 }, { 0x62, 0x08, 2 },
502	{ 0x63, 0x08, 2 }, { 0x64, 0xcf, 2 }, { 0x72, 0x56, 2 },
503	{ 0x73, 0x9a, 2 }, { 0x34, 0xf0, 0 }, { 0x35, 0x0f, 0 },
504	{ 0x5b, 0x40, 0 }, { 0x84, 0x88, 0 }, { 0x85, 0x24, 0 },
505	{ 0x88, 0x54, 0 }, { 0x8b, 0xb8, 0 }, { 0x8c, 0x07, 0 },
506	{ 0x8d, 0x00, 0 }, { 0x94, 0x1b, 0 }, { 0x95, 0x12, 0 },
507	{ 0x96, 0x00, 0 }, { 0x97, 0x06, 0 }, { 0x9d, 0x1a, 0 },
508	{ 0x9f, 0x10, 0 }, { 0xb4, 0x22, 0 }, { 0xbe, 0x80, 0 },
509	{ 0xdb, 0x00, 0 }, { 0xee, 0x00, 0 }, { 0x91, 0x03, 0 },
510	{ 0x4c, 0x00, 2 }, { 0x9f, 0x00, 3 }, { 0x8c, 0x01, 0 },
511	{ 0x8d, 0x10, 0 }, { 0x8e, 0x08, 0 }, { 0x8f, 0x00, 0 }
512};
513
514static usb_callback_t urtw_bulk_rx_callback;
515static usb_callback_t urtw_bulk_tx_callback;
516static usb_callback_t urtw_bulk_tx_status_callback;
517
518static const struct usb_config urtw_8187b_usbconfig[URTW_8187B_N_XFERS] = {
519	[URTW_8187B_BULK_RX] = {
520		.type = UE_BULK,
521		.endpoint = 0x83,
522		.direction = UE_DIR_IN,
523		.bufsize = MCLBYTES,
524		.flags = {
525			.ext_buffer = 1,
526			.pipe_bof = 1,
527			.short_xfer_ok = 1
528		},
529		.callback = urtw_bulk_rx_callback
530	},
531	[URTW_8187B_BULK_TX_STATUS] = {
532		.type = UE_BULK,
533		.endpoint = 0x89,
534		.direction = UE_DIR_IN,
535		.bufsize = sizeof(uint64_t),
536		.flags = {
537			.pipe_bof = 1,
538			.short_xfer_ok = 1
539		},
540		.callback = urtw_bulk_tx_status_callback
541	},
542	[URTW_8187B_BULK_TX_BE] = {
543		.type = UE_BULK,
544		.endpoint = URTW_8187B_TXPIPE_BE,
545		.direction = UE_DIR_OUT,
546		.bufsize = URTW_TX_MAXSIZE * URTW_TX_DATA_LIST_COUNT,
547		.flags = {
548			.force_short_xfer = 1,
549			.pipe_bof = 1,
550		},
551		.callback = urtw_bulk_tx_callback,
552		.timeout = URTW_DATA_TIMEOUT
553	},
554	[URTW_8187B_BULK_TX_BK] = {
555		.type = UE_BULK,
556		.endpoint = URTW_8187B_TXPIPE_BK,
557		.direction = UE_DIR_OUT,
558		.bufsize = URTW_TX_MAXSIZE,
559		.flags = {
560			.ext_buffer = 1,
561			.force_short_xfer = 1,
562			.pipe_bof = 1,
563		},
564		.callback = urtw_bulk_tx_callback,
565		.timeout = URTW_DATA_TIMEOUT
566	},
567	[URTW_8187B_BULK_TX_VI] = {
568		.type = UE_BULK,
569		.endpoint = URTW_8187B_TXPIPE_VI,
570		.direction = UE_DIR_OUT,
571		.bufsize = URTW_TX_MAXSIZE,
572		.flags = {
573			.ext_buffer = 1,
574			.force_short_xfer = 1,
575			.pipe_bof = 1,
576		},
577		.callback = urtw_bulk_tx_callback,
578		.timeout = URTW_DATA_TIMEOUT
579	},
580	[URTW_8187B_BULK_TX_VO] = {
581		.type = UE_BULK,
582		.endpoint = URTW_8187B_TXPIPE_VO,
583		.direction = UE_DIR_OUT,
584		.bufsize = URTW_TX_MAXSIZE,
585		.flags = {
586			.ext_buffer = 1,
587			.force_short_xfer = 1,
588			.pipe_bof = 1,
589		},
590		.callback = urtw_bulk_tx_callback,
591		.timeout = URTW_DATA_TIMEOUT
592	},
593	[URTW_8187B_BULK_TX_EP12] = {
594		.type = UE_BULK,
595		.endpoint = 0xc,
596		.direction = UE_DIR_OUT,
597		.bufsize = URTW_TX_MAXSIZE,
598		.flags = {
599			.ext_buffer = 1,
600			.force_short_xfer = 1,
601			.pipe_bof = 1,
602		},
603		.callback = urtw_bulk_tx_callback,
604		.timeout = URTW_DATA_TIMEOUT
605	}
606};
607
608static const struct usb_config urtw_8187l_usbconfig[URTW_8187L_N_XFERS] = {
609	[URTW_8187L_BULK_RX] = {
610		.type = UE_BULK,
611		.endpoint = 0x81,
612		.direction = UE_DIR_IN,
613		.bufsize = MCLBYTES,
614		.flags = {
615			.ext_buffer = 1,
616			.pipe_bof = 1,
617			.short_xfer_ok = 1
618		},
619		.callback = urtw_bulk_rx_callback
620	},
621	[URTW_8187L_BULK_TX_LOW] = {
622		.type = UE_BULK,
623		.endpoint = 0x2,
624		.direction = UE_DIR_OUT,
625		.bufsize = URTW_TX_MAXSIZE * URTW_TX_DATA_LIST_COUNT,
626		.flags = {
627			.force_short_xfer = 1,
628			.pipe_bof = 1,
629		},
630		.callback = urtw_bulk_tx_callback,
631		.timeout = URTW_DATA_TIMEOUT
632	},
633	[URTW_8187L_BULK_TX_NORMAL] = {
634		.type = UE_BULK,
635		.endpoint = 0x3,
636		.direction = UE_DIR_OUT,
637		.bufsize = URTW_TX_MAXSIZE,
638		.flags = {
639			.ext_buffer = 1,
640			.force_short_xfer = 1,
641			.pipe_bof = 1,
642		},
643		.callback = urtw_bulk_tx_callback,
644		.timeout = URTW_DATA_TIMEOUT
645	},
646};
647
648static struct ieee80211vap *urtw_vap_create(struct ieee80211com *,
649			    const char [IFNAMSIZ], int, enum ieee80211_opmode,
650			    int, const uint8_t [IEEE80211_ADDR_LEN],
651			    const uint8_t [IEEE80211_ADDR_LEN]);
652static void		urtw_vap_delete(struct ieee80211vap *);
653static void		urtw_init(void *);
654static void		urtw_stop(struct ifnet *);
655static void		urtw_stop_locked(struct ifnet *);
656static int		urtw_ioctl(struct ifnet *, u_long, caddr_t);
657static void		urtw_start(struct ifnet *);
658static int		urtw_alloc_rx_data_list(struct urtw_softc *);
659static int		urtw_alloc_tx_data_list(struct urtw_softc *);
660static int		urtw_raw_xmit(struct ieee80211_node *, struct mbuf *,
661			    const struct ieee80211_bpf_params *);
662static void		urtw_scan_start(struct ieee80211com *);
663static void		urtw_scan_end(struct ieee80211com *);
664static void		urtw_set_channel(struct ieee80211com *);
665static void		urtw_update_mcast(struct ifnet *);
666static int		urtw_tx_start(struct urtw_softc *,
667			    struct ieee80211_node *, struct mbuf *,
668			    struct urtw_data *, int);
669static int		urtw_newstate(struct ieee80211vap *,
670			    enum ieee80211_state, int);
671static void		urtw_led_ch(void *);
672static void		urtw_ledtask(void *, int);
673static void		urtw_watchdog(void *);
674static void		urtw_set_multi(void *);
675static int		urtw_isbmode(uint16_t);
676static uint16_t		urtw_rate2rtl(uint32_t);
677static uint16_t		urtw_rtl2rate(uint32_t);
678static usb_error_t	urtw_set_rate(struct urtw_softc *);
679static usb_error_t	urtw_update_msr(struct urtw_softc *);
680static usb_error_t	urtw_read8_c(struct urtw_softc *, int, uint8_t *);
681static usb_error_t	urtw_read16_c(struct urtw_softc *, int, uint16_t *);
682static usb_error_t	urtw_read32_c(struct urtw_softc *, int, uint32_t *);
683static usb_error_t	urtw_write8_c(struct urtw_softc *, int, uint8_t);
684static usb_error_t	urtw_write16_c(struct urtw_softc *, int, uint16_t);
685static usb_error_t	urtw_write32_c(struct urtw_softc *, int, uint32_t);
686static usb_error_t	urtw_eprom_cs(struct urtw_softc *, int);
687static usb_error_t	urtw_eprom_ck(struct urtw_softc *);
688static usb_error_t	urtw_eprom_sendbits(struct urtw_softc *, int16_t *,
689			    int);
690static usb_error_t	urtw_eprom_read32(struct urtw_softc *, uint32_t,
691			    uint32_t *);
692static usb_error_t	urtw_eprom_readbit(struct urtw_softc *, int16_t *);
693static usb_error_t	urtw_eprom_writebit(struct urtw_softc *, int16_t);
694static usb_error_t	urtw_get_macaddr(struct urtw_softc *);
695static usb_error_t	urtw_get_txpwr(struct urtw_softc *);
696static usb_error_t	urtw_get_rfchip(struct urtw_softc *);
697static usb_error_t	urtw_led_init(struct urtw_softc *);
698static usb_error_t	urtw_8185_rf_pins_enable(struct urtw_softc *);
699static usb_error_t	urtw_8185_tx_antenna(struct urtw_softc *, uint8_t);
700static usb_error_t	urtw_8187_write_phy(struct urtw_softc *, uint8_t,
701			    uint32_t);
702static usb_error_t	urtw_8187_write_phy_ofdm_c(struct urtw_softc *,
703			    uint8_t, uint32_t);
704static usb_error_t	urtw_8187_write_phy_cck_c(struct urtw_softc *, uint8_t,
705			    uint32_t);
706static usb_error_t	urtw_8225_setgain(struct urtw_softc *, int16_t);
707static usb_error_t	urtw_8225_usb_init(struct urtw_softc *);
708static usb_error_t	urtw_8225_write_c(struct urtw_softc *, uint8_t,
709			    uint16_t);
710static usb_error_t	urtw_8225_write_s16(struct urtw_softc *, uint8_t, int,
711			    uint16_t *);
712static usb_error_t	urtw_8225_read(struct urtw_softc *, uint8_t,
713			    uint32_t *);
714static usb_error_t	urtw_8225_rf_init(struct urtw_softc *);
715static usb_error_t	urtw_8225_rf_set_chan(struct urtw_softc *, int);
716static usb_error_t	urtw_8225_rf_set_sens(struct urtw_softc *, int);
717static usb_error_t	urtw_8225_set_txpwrlvl(struct urtw_softc *, int);
718static usb_error_t	urtw_8225_rf_stop(struct urtw_softc *);
719static usb_error_t	urtw_8225v2_rf_init(struct urtw_softc *);
720static usb_error_t	urtw_8225v2_rf_set_chan(struct urtw_softc *, int);
721static usb_error_t	urtw_8225v2_set_txpwrlvl(struct urtw_softc *, int);
722static usb_error_t	urtw_8225v2_setgain(struct urtw_softc *, int16_t);
723static usb_error_t	urtw_8225_isv2(struct urtw_softc *, int *);
724static usb_error_t	urtw_8225v2b_rf_init(struct urtw_softc *);
725static usb_error_t	urtw_8225v2b_rf_set_chan(struct urtw_softc *, int);
726static usb_error_t	urtw_read8e(struct urtw_softc *, int, uint8_t *);
727static usb_error_t	urtw_write8e(struct urtw_softc *, int, uint8_t);
728static usb_error_t	urtw_8180_set_anaparam(struct urtw_softc *, uint32_t);
729static usb_error_t	urtw_8185_set_anaparam2(struct urtw_softc *, uint32_t);
730static usb_error_t	urtw_intr_enable(struct urtw_softc *);
731static usb_error_t	urtw_intr_disable(struct urtw_softc *);
732static usb_error_t	urtw_reset(struct urtw_softc *);
733static usb_error_t	urtw_led_on(struct urtw_softc *, int);
734static usb_error_t	urtw_led_ctl(struct urtw_softc *, int);
735static usb_error_t	urtw_led_blink(struct urtw_softc *);
736static usb_error_t	urtw_led_mode0(struct urtw_softc *, int);
737static usb_error_t	urtw_led_mode1(struct urtw_softc *, int);
738static usb_error_t	urtw_led_mode2(struct urtw_softc *, int);
739static usb_error_t	urtw_led_mode3(struct urtw_softc *, int);
740static usb_error_t	urtw_rx_setconf(struct urtw_softc *);
741static usb_error_t	urtw_rx_enable(struct urtw_softc *);
742static usb_error_t	urtw_tx_enable(struct urtw_softc *sc);
743static void		urtw_free_tx_data_list(struct urtw_softc *);
744static void		urtw_free_rx_data_list(struct urtw_softc *);
745static void		urtw_free_data_list(struct urtw_softc *,
746			    struct urtw_data data[], int, int);
747static usb_error_t	urtw_adapter_start(struct urtw_softc *);
748static usb_error_t	urtw_adapter_start_b(struct urtw_softc *);
749static usb_error_t	urtw_set_mode(struct urtw_softc *, uint32_t);
750static usb_error_t	urtw_8187b_cmd_reset(struct urtw_softc *);
751static usb_error_t	urtw_do_request(struct urtw_softc *,
752			    struct usb_device_request *, void *);
753static usb_error_t	urtw_8225v2b_set_txpwrlvl(struct urtw_softc *, int);
754static usb_error_t	urtw_led_off(struct urtw_softc *, int);
755static void		urtw_abort_xfers(struct urtw_softc *);
756static struct urtw_data *
757			urtw_getbuf(struct urtw_softc *sc);
758static int		urtw_compute_txtime(uint16_t, uint16_t, uint8_t,
759			    uint8_t);
760static void		urtw_updateslot(struct ifnet *);
761static void		urtw_updateslottask(void *, int);
762static void		urtw_sysctl_node(struct urtw_softc *);
763
764static int
765urtw_match(device_t dev)
766{
767	struct usb_attach_arg *uaa = device_get_ivars(dev);
768
769	if (uaa->usb_mode != USB_MODE_HOST)
770		return (ENXIO);
771	if (uaa->info.bConfigIndex != URTW_CONFIG_INDEX)
772		return (ENXIO);
773	if (uaa->info.bIfaceIndex != URTW_IFACE_INDEX)
774		return (ENXIO);
775
776	return (usbd_lookup_id_by_uaa(urtw_devs, sizeof(urtw_devs), uaa));
777}
778
779static int
780urtw_attach(device_t dev)
781{
782	const struct usb_config *setup_start;
783	int ret = ENXIO;
784	struct urtw_softc *sc = device_get_softc(dev);
785	struct usb_attach_arg *uaa = device_get_ivars(dev);
786	struct ieee80211com *ic;
787	struct ifnet *ifp;
788	uint8_t bands, iface_index = URTW_IFACE_INDEX;		/* XXX */
789	uint16_t n_setup;
790	uint32_t data;
791	usb_error_t error;
792
793	device_set_usb_desc(dev);
794
795	sc->sc_dev = dev;
796	sc->sc_udev = uaa->device;
797	if (USB_GET_DRIVER_INFO(uaa) == URTW_REV_RTL8187B)
798		sc->sc_flags |= URTW_RTL8187B;
799#ifdef URTW_DEBUG
800	sc->sc_debug = urtw_debug;
801#endif
802
803	mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev), MTX_NETWORK_LOCK,
804	    MTX_DEF);
805	usb_callout_init_mtx(&sc->sc_led_ch, &sc->sc_mtx, 0);
806	TASK_INIT(&sc->sc_led_task, 0, urtw_ledtask, sc);
807	TASK_INIT(&sc->sc_updateslot_task, 0, urtw_updateslottask, sc);
808	callout_init(&sc->sc_watchdog_ch, 0);
809
810	if (sc->sc_flags & URTW_RTL8187B) {
811		setup_start = urtw_8187b_usbconfig;
812		n_setup = URTW_8187B_N_XFERS;
813	} else {
814		setup_start = urtw_8187l_usbconfig;
815		n_setup = URTW_8187L_N_XFERS;
816	}
817
818	error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_xfer,
819	    setup_start, n_setup, sc, &sc->sc_mtx);
820	if (error) {
821		device_printf(dev, "could not allocate USB transfers, "
822		    "err=%s\n", usbd_errstr(error));
823		ret = ENXIO;
824		goto fail0;
825	}
826
827	if (sc->sc_flags & URTW_RTL8187B) {
828		sc->sc_tx_dma_buf =
829		    usbd_xfer_get_frame_buffer(sc->sc_xfer[
830		    URTW_8187B_BULK_TX_BE], 0);
831	} else {
832		sc->sc_tx_dma_buf =
833		    usbd_xfer_get_frame_buffer(sc->sc_xfer[
834		    URTW_8187L_BULK_TX_LOW], 0);
835	}
836
837	URTW_LOCK(sc);
838
839	urtw_read32_m(sc, URTW_RX, &data);
840	sc->sc_epromtype = (data & URTW_RX_9356SEL) ? URTW_EEPROM_93C56 :
841	    URTW_EEPROM_93C46;
842
843	error = urtw_get_rfchip(sc);
844	if (error != 0)
845		goto fail;
846	error = urtw_get_macaddr(sc);
847	if (error != 0)
848		goto fail;
849	error = urtw_get_txpwr(sc);
850	if (error != 0)
851		goto fail;
852	error = urtw_led_init(sc);
853	if (error != 0)
854		goto fail;
855
856	URTW_UNLOCK(sc);
857
858	sc->sc_rts_retry = URTW_DEFAULT_RTS_RETRY;
859	sc->sc_tx_retry = URTW_DEFAULT_TX_RETRY;
860	sc->sc_currate = 3;
861	sc->sc_preamble_mode = urtw_preamble_mode;
862
863	ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
864	if (ifp == NULL) {
865		device_printf(sc->sc_dev, "can not allocate ifnet\n");
866		ret = ENOMEM;
867		goto fail1;
868	}
869
870	ifp->if_softc = sc;
871	if_initname(ifp, "urtw", device_get_unit(sc->sc_dev));
872	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
873	ifp->if_init = urtw_init;
874	ifp->if_ioctl = urtw_ioctl;
875	ifp->if_start = urtw_start;
876	/* XXX URTW_TX_DATA_LIST_COUNT */
877	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
878	ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
879	IFQ_SET_READY(&ifp->if_snd);
880
881	ic = ifp->if_l2com;
882	ic->ic_ifp = ifp;
883	ic->ic_phytype = IEEE80211_T_OFDM;	/* not only, but not used */
884	ic->ic_opmode = IEEE80211_M_STA;	/* default to BSS mode */
885
886	/* set device capabilities */
887	ic->ic_caps =
888	    IEEE80211_C_STA |		/* station mode */
889	    IEEE80211_C_MONITOR |	/* monitor mode supported */
890	    IEEE80211_C_TXPMGT |	/* tx power management */
891	    IEEE80211_C_SHPREAMBLE |	/* short preamble supported */
892	    IEEE80211_C_SHSLOT |	/* short slot time supported */
893	    IEEE80211_C_BGSCAN |	/* capable of bg scanning */
894	    IEEE80211_C_WPA;		/* 802.11i */
895
896	bands = 0;
897	setbit(&bands, IEEE80211_MODE_11B);
898	setbit(&bands, IEEE80211_MODE_11G);
899	ieee80211_init_channels(ic, NULL, &bands);
900
901	ieee80211_ifattach(ic, sc->sc_bssid);
902	ic->ic_raw_xmit = urtw_raw_xmit;
903	ic->ic_scan_start = urtw_scan_start;
904	ic->ic_scan_end = urtw_scan_end;
905	ic->ic_set_channel = urtw_set_channel;
906	ic->ic_updateslot = urtw_updateslot;
907	ic->ic_vap_create = urtw_vap_create;
908	ic->ic_vap_delete = urtw_vap_delete;
909	ic->ic_update_mcast = urtw_update_mcast;
910
911	ieee80211_radiotap_attach(ic,
912	    &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
913	    URTW_TX_RADIOTAP_PRESENT,
914	    &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
915	    URTW_RX_RADIOTAP_PRESENT);
916
917	urtw_sysctl_node(sc);
918
919	if (bootverbose)
920		ieee80211_announce(ic);
921	return (0);
922
923fail:	URTW_UNLOCK(sc);
924fail1:	usbd_transfer_unsetup(sc->sc_xfer, (sc->sc_flags & URTW_RTL8187B) ?
925	    URTW_8187B_N_XFERS : URTW_8187L_N_XFERS);
926fail0:
927	return (ret);
928}
929
930static int
931urtw_detach(device_t dev)
932{
933	struct urtw_softc *sc = device_get_softc(dev);
934	struct ifnet *ifp = sc->sc_ifp;
935	struct ieee80211com *ic = ifp->if_l2com;
936	unsigned int x;
937	unsigned int n_xfers;
938
939	/* Prevent further ioctls */
940	URTW_LOCK(sc);
941	sc->sc_flags |= URTW_DETACHED;
942	URTW_UNLOCK(sc);
943
944	urtw_stop(ifp);
945
946	ieee80211_draintask(ic, &sc->sc_updateslot_task);
947	ieee80211_draintask(ic, &sc->sc_led_task);
948
949	usb_callout_drain(&sc->sc_led_ch);
950	callout_drain(&sc->sc_watchdog_ch);
951
952	n_xfers = (sc->sc_flags & URTW_RTL8187B) ?
953	    URTW_8187B_N_XFERS : URTW_8187L_N_XFERS;
954
955	/* prevent further allocations from RX/TX data lists */
956	URTW_LOCK(sc);
957	STAILQ_INIT(&sc->sc_tx_active);
958	STAILQ_INIT(&sc->sc_tx_inactive);
959	STAILQ_INIT(&sc->sc_tx_pending);
960
961	STAILQ_INIT(&sc->sc_rx_active);
962	STAILQ_INIT(&sc->sc_rx_inactive);
963	URTW_UNLOCK(sc);
964
965	/* drain USB transfers */
966	for (x = 0; x != n_xfers; x++)
967		usbd_transfer_drain(sc->sc_xfer[x]);
968
969	/* free data buffers */
970	URTW_LOCK(sc);
971	urtw_free_tx_data_list(sc);
972	urtw_free_rx_data_list(sc);
973	URTW_UNLOCK(sc);
974
975	/* free USB transfers and some data buffers */
976	usbd_transfer_unsetup(sc->sc_xfer, n_xfers);
977
978	ieee80211_ifdetach(ic);
979	if_free(ifp);
980	mtx_destroy(&sc->sc_mtx);
981	return (0);
982}
983
984static void
985urtw_free_tx_data_list(struct urtw_softc *sc)
986{
987	urtw_free_data_list(sc, sc->sc_tx, URTW_TX_DATA_LIST_COUNT, 0);
988}
989
990static void
991urtw_free_rx_data_list(struct urtw_softc *sc)
992{
993	urtw_free_data_list(sc, sc->sc_rx, URTW_RX_DATA_LIST_COUNT, 1);
994}
995
996static void
997urtw_free_data_list(struct urtw_softc *sc, struct urtw_data data[], int ndata,
998    int fillmbuf)
999{
1000	int i;
1001
1002	for (i = 0; i < ndata; i++) {
1003		struct urtw_data *dp = &data[i];
1004
1005		if (fillmbuf == 1) {
1006			if (dp->m != NULL) {
1007				m_freem(dp->m);
1008				dp->m = NULL;
1009				dp->buf = NULL;
1010			}
1011		} else {
1012			dp->buf = NULL;
1013		}
1014		if (dp->ni != NULL) {
1015			ieee80211_free_node(dp->ni);
1016			dp->ni = NULL;
1017		}
1018	}
1019}
1020
1021static struct ieee80211vap *
1022urtw_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
1023    enum ieee80211_opmode opmode, int flags,
1024    const uint8_t bssid[IEEE80211_ADDR_LEN],
1025    const uint8_t mac[IEEE80211_ADDR_LEN])
1026{
1027	struct urtw_vap *uvp;
1028	struct ieee80211vap *vap;
1029
1030	if (!TAILQ_EMPTY(&ic->ic_vaps))		/* only one at a time */
1031		return (NULL);
1032	uvp = (struct urtw_vap *) malloc(sizeof(struct urtw_vap),
1033	    M_80211_VAP, M_NOWAIT | M_ZERO);
1034	if (uvp == NULL)
1035		return (NULL);
1036	vap = &uvp->vap;
1037	/* enable s/w bmiss handling for sta mode */
1038	ieee80211_vap_setup(ic, vap, name, unit, opmode,
1039	    flags | IEEE80211_CLONE_NOBEACONS, bssid, mac);
1040
1041	/* override state transition machine */
1042	uvp->newstate = vap->iv_newstate;
1043	vap->iv_newstate = urtw_newstate;
1044
1045	/* complete setup */
1046	ieee80211_vap_attach(vap, ieee80211_media_change,
1047	    ieee80211_media_status);
1048	ic->ic_opmode = opmode;
1049	return (vap);
1050}
1051
1052static void
1053urtw_vap_delete(struct ieee80211vap *vap)
1054{
1055	struct urtw_vap *uvp = URTW_VAP(vap);
1056
1057	ieee80211_vap_detach(vap);
1058	free(uvp, M_80211_VAP);
1059}
1060
1061static void
1062urtw_init_locked(void *arg)
1063{
1064	int ret;
1065	struct urtw_softc *sc = arg;
1066	struct ifnet *ifp = sc->sc_ifp;
1067	usb_error_t error;
1068
1069	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1070		urtw_stop_locked(ifp);
1071
1072	error = (sc->sc_flags & URTW_RTL8187B) ? urtw_adapter_start_b(sc) :
1073	    urtw_adapter_start(sc);
1074	if (error != 0)
1075		goto fail;
1076
1077	/* reset softc variables  */
1078	sc->sc_txtimer = 0;
1079
1080	if (!(sc->sc_flags & URTW_INIT_ONCE)) {
1081		ret = urtw_alloc_rx_data_list(sc);
1082		if (ret != 0)
1083			goto fail;
1084		ret = urtw_alloc_tx_data_list(sc);
1085		if (ret != 0)
1086			goto fail;
1087		sc->sc_flags |= URTW_INIT_ONCE;
1088	}
1089
1090	error = urtw_rx_enable(sc);
1091	if (error != 0)
1092		goto fail;
1093	error = urtw_tx_enable(sc);
1094	if (error != 0)
1095		goto fail;
1096
1097	if (sc->sc_flags & URTW_RTL8187B)
1098		usbd_transfer_start(sc->sc_xfer[URTW_8187B_BULK_TX_STATUS]);
1099
1100	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
1101	ifp->if_drv_flags |= IFF_DRV_RUNNING;
1102
1103	callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc);
1104fail:
1105	return;
1106}
1107
1108static void
1109urtw_init(void *arg)
1110{
1111	struct urtw_softc *sc = arg;
1112
1113	URTW_LOCK(sc);
1114	urtw_init_locked(arg);
1115	URTW_UNLOCK(sc);
1116}
1117
1118static usb_error_t
1119urtw_adapter_start_b(struct urtw_softc *sc)
1120{
1121#define N(a)	((int)(sizeof(a) / sizeof((a)[0])))
1122	uint8_t data8;
1123	usb_error_t error;
1124
1125	error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
1126	if (error)
1127		goto fail;
1128
1129	urtw_read8_m(sc, URTW_CONFIG3, &data8);
1130	urtw_write8_m(sc, URTW_CONFIG3,
1131	    data8 | URTW_CONFIG3_ANAPARAM_WRITE | URTW_CONFIG3_GNT_SELECT);
1132	urtw_write32_m(sc, URTW_ANAPARAM2, URTW_8187B_8225_ANAPARAM2_ON);
1133	urtw_write32_m(sc, URTW_ANAPARAM, URTW_8187B_8225_ANAPARAM_ON);
1134	urtw_write8_m(sc, URTW_ANAPARAM3, URTW_8187B_8225_ANAPARAM3_ON);
1135
1136	urtw_write8_m(sc, 0x61, 0x10);
1137	urtw_read8_m(sc, 0x62, &data8);
1138	urtw_write8_m(sc, 0x62, data8 & ~(1 << 5));
1139	urtw_write8_m(sc, 0x62, data8 | (1 << 5));
1140
1141	urtw_read8_m(sc, URTW_CONFIG3, &data8);
1142	data8 &= ~URTW_CONFIG3_ANAPARAM_WRITE;
1143	urtw_write8_m(sc, URTW_CONFIG3, data8);
1144
1145	error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
1146	if (error)
1147		goto fail;
1148
1149	error = urtw_8187b_cmd_reset(sc);
1150	if (error)
1151		goto fail;
1152
1153	error = sc->sc_rf_init(sc);
1154	if (error != 0)
1155		goto fail;
1156	urtw_write8_m(sc, URTW_CMD, URTW_CMD_RX_ENABLE | URTW_CMD_TX_ENABLE);
1157
1158	/* fix RTL8187B RX stall */
1159	error = urtw_intr_enable(sc);
1160	if (error)
1161		goto fail;
1162
1163	error = urtw_write8e(sc, 0x41, 0xf4);
1164	if (error)
1165		goto fail;
1166	error = urtw_write8e(sc, 0x40, 0x00);
1167	if (error)
1168		goto fail;
1169	error = urtw_write8e(sc, 0x42, 0x00);
1170	if (error)
1171		goto fail;
1172	error = urtw_write8e(sc, 0x42, 0x01);
1173	if (error)
1174		goto fail;
1175	error = urtw_write8e(sc, 0x40, 0x0f);
1176	if (error)
1177		goto fail;
1178	error = urtw_write8e(sc, 0x42, 0x00);
1179	if (error)
1180		goto fail;
1181	error = urtw_write8e(sc, 0x42, 0x01);
1182	if (error)
1183		goto fail;
1184
1185	urtw_read8_m(sc, 0xdb, &data8);
1186	urtw_write8_m(sc, 0xdb, data8 | (1 << 2));
1187	urtw_write16_m(sc, 0x372, 0x59fa);
1188	urtw_write16_m(sc, 0x374, 0x59d2);
1189	urtw_write16_m(sc, 0x376, 0x59d2);
1190	urtw_write16_m(sc, 0x378, 0x19fa);
1191	urtw_write16_m(sc, 0x37a, 0x19fa);
1192	urtw_write16_m(sc, 0x37c, 0x00d0);
1193	urtw_write8_m(sc, 0x61, 0);
1194
1195	urtw_write8_m(sc, 0x180, 0x0f);
1196	urtw_write8_m(sc, 0x183, 0x03);
1197	urtw_write8_m(sc, 0xda, 0x10);
1198	urtw_write8_m(sc, 0x24d, 0x08);
1199	urtw_write32_m(sc, URTW_HSSI_PARA, 0x0600321b);
1200
1201	urtw_write16_m(sc, 0x1ec, 0x800);	/* RX MAX SIZE */
1202fail:
1203	return (error);
1204#undef N
1205}
1206
1207static usb_error_t
1208urtw_adapter_start(struct urtw_softc *sc)
1209{
1210	usb_error_t error;
1211
1212	error = urtw_reset(sc);
1213	if (error)
1214		goto fail;
1215
1216	urtw_write8_m(sc, URTW_ADDR_MAGIC1, 0);
1217	urtw_write8_m(sc, URTW_GPIO, 0);
1218
1219	/* for led  */
1220	urtw_write8_m(sc, URTW_ADDR_MAGIC1, 4);
1221	error = urtw_led_ctl(sc, URTW_LED_CTL_POWER_ON);
1222	if (error != 0)
1223		goto fail;
1224
1225	error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
1226	if (error)
1227		goto fail;
1228	/* applying MAC address again.  */
1229	urtw_write32_m(sc, URTW_MAC0, ((uint32_t *)sc->sc_bssid)[0]);
1230	urtw_write16_m(sc, URTW_MAC4, ((uint32_t *)sc->sc_bssid)[1] & 0xffff);
1231	error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
1232	if (error)
1233		goto fail;
1234
1235	error = urtw_update_msr(sc);
1236	if (error)
1237		goto fail;
1238
1239	urtw_write32_m(sc, URTW_INT_TIMEOUT, 0);
1240	urtw_write8_m(sc, URTW_WPA_CONFIG, 0);
1241	urtw_write8_m(sc, URTW_RATE_FALLBACK, URTW_RATE_FALLBACK_ENABLE | 0x1);
1242	error = urtw_set_rate(sc);
1243	if (error != 0)
1244		goto fail;
1245
1246	error = sc->sc_rf_init(sc);
1247	if (error != 0)
1248		goto fail;
1249	if (sc->sc_rf_set_sens != NULL)
1250		sc->sc_rf_set_sens(sc, sc->sc_sens);
1251
1252	/* XXX correct? to call write16  */
1253	urtw_write16_m(sc, URTW_PSR, 1);
1254	urtw_write16_m(sc, URTW_ADDR_MAGIC2, 0x10);
1255	urtw_write8_m(sc, URTW_TALLY_SEL, 0x80);
1256	urtw_write8_m(sc, URTW_ADDR_MAGIC3, 0x60);
1257	/* XXX correct? to call write16  */
1258	urtw_write16_m(sc, URTW_PSR, 0);
1259	urtw_write8_m(sc, URTW_ADDR_MAGIC1, 4);
1260
1261	error = urtw_intr_enable(sc);
1262	if (error != 0)
1263		goto fail;
1264
1265fail:
1266	return (error);
1267}
1268
1269static usb_error_t
1270urtw_set_mode(struct urtw_softc *sc, uint32_t mode)
1271{
1272	uint8_t data;
1273	usb_error_t error;
1274
1275	urtw_read8_m(sc, URTW_EPROM_CMD, &data);
1276	data = (data & ~URTW_EPROM_CMD_MASK) | (mode << URTW_EPROM_CMD_SHIFT);
1277	data = data & ~(URTW_EPROM_CS | URTW_EPROM_CK);
1278	urtw_write8_m(sc, URTW_EPROM_CMD, data);
1279fail:
1280	return (error);
1281}
1282
1283static usb_error_t
1284urtw_8187b_cmd_reset(struct urtw_softc *sc)
1285{
1286	int i;
1287	uint8_t data8;
1288	usb_error_t error;
1289
1290	/* XXX the code can be duplicate with urtw_reset().  */
1291	urtw_read8_m(sc, URTW_CMD, &data8);
1292	data8 = (data8 & 0x2) | URTW_CMD_RST;
1293	urtw_write8_m(sc, URTW_CMD, data8);
1294
1295	for (i = 0; i < 20; i++) {
1296		usb_pause_mtx(&sc->sc_mtx, 2);
1297		urtw_read8_m(sc, URTW_CMD, &data8);
1298		if (!(data8 & URTW_CMD_RST))
1299			break;
1300	}
1301	if (i >= 20) {
1302		device_printf(sc->sc_dev, "reset timeout\n");
1303		goto fail;
1304	}
1305fail:
1306	return (error);
1307}
1308
1309static usb_error_t
1310urtw_do_request(struct urtw_softc *sc,
1311    struct usb_device_request *req, void *data)
1312{
1313	usb_error_t err;
1314	int ntries = 10;
1315
1316	URTW_ASSERT_LOCKED(sc);
1317
1318	while (ntries--) {
1319		err = usbd_do_request_flags(sc->sc_udev, &sc->sc_mtx,
1320		    req, data, 0, NULL, 250 /* ms */);
1321		if (err == 0)
1322			break;
1323
1324		DPRINTF(sc, URTW_DEBUG_INIT,
1325		    "Control request failed, %s (retrying)\n",
1326		    usbd_errstr(err));
1327		usb_pause_mtx(&sc->sc_mtx, hz / 100);
1328	}
1329	return (err);
1330}
1331
1332static void
1333urtw_stop_locked(struct ifnet *ifp)
1334{
1335	struct urtw_softc *sc = ifp->if_softc;
1336	uint8_t data8;
1337	usb_error_t error;
1338
1339	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
1340
1341	error = urtw_intr_disable(sc);
1342	if (error)
1343		goto fail;
1344	urtw_read8_m(sc, URTW_CMD, &data8);
1345	data8 &= ~(URTW_CMD_RX_ENABLE | URTW_CMD_TX_ENABLE);
1346	urtw_write8_m(sc, URTW_CMD, data8);
1347
1348	error = sc->sc_rf_stop(sc);
1349	if (error != 0)
1350		goto fail;
1351
1352	error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
1353	if (error)
1354		goto fail;
1355	urtw_read8_m(sc, URTW_CONFIG4, &data8);
1356	urtw_write8_m(sc, URTW_CONFIG4, data8 | URTW_CONFIG4_VCOOFF);
1357	error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
1358	if (error)
1359		goto fail;
1360fail:
1361	if (error)
1362		device_printf(sc->sc_dev, "failed to stop (%s)\n",
1363		    usbd_errstr(error));
1364
1365	usb_callout_stop(&sc->sc_led_ch);
1366	callout_stop(&sc->sc_watchdog_ch);
1367
1368	urtw_abort_xfers(sc);
1369}
1370
1371static void
1372urtw_stop(struct ifnet *ifp)
1373{
1374	struct urtw_softc *sc = ifp->if_softc;
1375
1376	URTW_LOCK(sc);
1377	urtw_stop_locked(ifp);
1378	URTW_UNLOCK(sc);
1379}
1380
1381static void
1382urtw_abort_xfers(struct urtw_softc *sc)
1383{
1384	int i, max;
1385
1386	URTW_ASSERT_LOCKED(sc);
1387
1388	max = (sc->sc_flags & URTW_RTL8187B) ? URTW_8187B_N_XFERS :
1389	    URTW_8187L_N_XFERS;
1390
1391	/* abort any pending transfers */
1392	for (i = 0; i < max; i++)
1393		usbd_transfer_stop(sc->sc_xfer[i]);
1394}
1395
1396static int
1397urtw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1398{
1399	struct urtw_softc *sc = ifp->if_softc;
1400	struct ieee80211com *ic = ifp->if_l2com;
1401	struct ifreq *ifr = (struct ifreq *) data;
1402	int error;
1403	int startall = 0;
1404
1405	URTW_LOCK(sc);
1406	error = (sc->sc_flags & URTW_DETACHED) ? ENXIO : 0;
1407	URTW_UNLOCK(sc);
1408	if (error)
1409		return (error);
1410
1411	switch (cmd) {
1412	case SIOCSIFFLAGS:
1413		if (ifp->if_flags & IFF_UP) {
1414			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
1415				if ((ifp->if_flags ^ sc->sc_if_flags) &
1416				    (IFF_ALLMULTI | IFF_PROMISC))
1417					urtw_set_multi(sc);
1418			} else {
1419				urtw_init(ifp->if_softc);
1420				startall = 1;
1421			}
1422		} else {
1423			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1424				urtw_stop(ifp);
1425		}
1426		sc->sc_if_flags = ifp->if_flags;
1427		if (startall)
1428			ieee80211_start_all(ic);
1429		break;
1430	case SIOCGIFMEDIA:
1431		error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
1432		break;
1433	case SIOCGIFADDR:
1434		error = ether_ioctl(ifp, cmd, data);
1435		break;
1436	default:
1437		error = EINVAL;
1438		break;
1439	}
1440	return (error);
1441}
1442
1443static void
1444urtw_start(struct ifnet *ifp)
1445{
1446	struct urtw_data *bf;
1447	struct urtw_softc *sc = ifp->if_softc;
1448	struct ieee80211_node *ni;
1449	struct mbuf *m;
1450
1451	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
1452		return;
1453
1454	URTW_LOCK(sc);
1455	for (;;) {
1456		IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
1457		if (m == NULL)
1458			break;
1459		bf = urtw_getbuf(sc);
1460		if (bf == NULL) {
1461			IFQ_DRV_PREPEND(&ifp->if_snd, m);
1462			break;
1463		}
1464
1465		ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
1466		m->m_pkthdr.rcvif = NULL;
1467
1468		if (urtw_tx_start(sc, ni, m, bf, URTW_PRIORITY_NORMAL) != 0) {
1469			ifp->if_oerrors++;
1470			STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
1471			ieee80211_free_node(ni);
1472			break;
1473		}
1474
1475		sc->sc_txtimer = 5;
1476		callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc);
1477	}
1478	URTW_UNLOCK(sc);
1479}
1480
1481static int
1482urtw_alloc_data_list(struct urtw_softc *sc, struct urtw_data data[],
1483    int ndata, int maxsz, void *dma_buf)
1484{
1485	int i, error;
1486
1487	for (i = 0; i < ndata; i++) {
1488		struct urtw_data *dp = &data[i];
1489
1490		dp->sc = sc;
1491		if (dma_buf == NULL) {
1492			dp->m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
1493			if (dp->m == NULL) {
1494				device_printf(sc->sc_dev,
1495				    "could not allocate rx mbuf\n");
1496				error = ENOMEM;
1497				goto fail;
1498			}
1499			dp->buf = mtod(dp->m, uint8_t *);
1500		} else {
1501			dp->m = NULL;
1502			dp->buf = ((uint8_t *)dma_buf) +
1503			    (i * maxsz);
1504		}
1505		dp->ni = NULL;
1506	}
1507	return (0);
1508
1509fail:	urtw_free_data_list(sc, data, ndata, 1);
1510	return (error);
1511}
1512
1513static int
1514urtw_alloc_rx_data_list(struct urtw_softc *sc)
1515{
1516	int error, i;
1517
1518	error = urtw_alloc_data_list(sc,
1519	    sc->sc_rx, URTW_RX_DATA_LIST_COUNT,
1520	    MCLBYTES, NULL /* mbufs */);
1521	if (error != 0)
1522		return (error);
1523
1524	STAILQ_INIT(&sc->sc_rx_active);
1525	STAILQ_INIT(&sc->sc_rx_inactive);
1526
1527	for (i = 0; i < URTW_RX_DATA_LIST_COUNT; i++)
1528		STAILQ_INSERT_HEAD(&sc->sc_rx_inactive, &sc->sc_rx[i], next);
1529
1530	return (0);
1531}
1532
1533static int
1534urtw_alloc_tx_data_list(struct urtw_softc *sc)
1535{
1536	int error, i;
1537
1538	error = urtw_alloc_data_list(sc,
1539	    sc->sc_tx, URTW_TX_DATA_LIST_COUNT, URTW_TX_MAXSIZE,
1540	    sc->sc_tx_dma_buf /* no mbufs */);
1541	if (error != 0)
1542		return (error);
1543
1544	STAILQ_INIT(&sc->sc_tx_active);
1545	STAILQ_INIT(&sc->sc_tx_inactive);
1546	STAILQ_INIT(&sc->sc_tx_pending);
1547
1548	for (i = 0; i < URTW_TX_DATA_LIST_COUNT; i++)
1549		STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, &sc->sc_tx[i],
1550		    next);
1551
1552	return (0);
1553}
1554
1555static int
1556urtw_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
1557    const struct ieee80211_bpf_params *params)
1558{
1559	struct ieee80211com *ic = ni->ni_ic;
1560	struct ifnet *ifp = ic->ic_ifp;
1561	struct urtw_data *bf;
1562	struct urtw_softc *sc = ifp->if_softc;
1563
1564	/* prevent management frames from being sent if we're not ready */
1565	if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
1566		m_freem(m);
1567		ieee80211_free_node(ni);
1568		return ENETDOWN;
1569	}
1570	URTW_LOCK(sc);
1571	bf = urtw_getbuf(sc);
1572	if (bf == NULL) {
1573		ieee80211_free_node(ni);
1574		m_freem(m);
1575		URTW_UNLOCK(sc);
1576		return (ENOBUFS);		/* XXX */
1577	}
1578
1579	ifp->if_opackets++;
1580	if (urtw_tx_start(sc, ni, m, bf, URTW_PRIORITY_LOW) != 0) {
1581		ieee80211_free_node(ni);
1582		ifp->if_oerrors++;
1583		STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
1584		URTW_UNLOCK(sc);
1585		return (EIO);
1586	}
1587	URTW_UNLOCK(sc);
1588
1589	sc->sc_txtimer = 5;
1590	return (0);
1591}
1592
1593static void
1594urtw_scan_start(struct ieee80211com *ic)
1595{
1596
1597	/* XXX do nothing?  */
1598}
1599
1600static void
1601urtw_scan_end(struct ieee80211com *ic)
1602{
1603
1604	/* XXX do nothing?  */
1605}
1606
1607static void
1608urtw_set_channel(struct ieee80211com *ic)
1609{
1610	struct urtw_softc *sc  = ic->ic_ifp->if_softc;
1611	struct ifnet *ifp = sc->sc_ifp;
1612	uint32_t data, orig;
1613	usb_error_t error;
1614
1615	/*
1616	 * if the user set a channel explicitly using ifconfig(8) this function
1617	 * can be called earlier than we're expected that in some cases the
1618	 * initialization would be failed if setting a channel is called before
1619	 * the init have done.
1620	 */
1621	if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
1622		return;
1623
1624	if (sc->sc_curchan != NULL && sc->sc_curchan == ic->ic_curchan)
1625		return;
1626
1627	URTW_LOCK(sc);
1628
1629	/*
1630	 * during changing th channel we need to temporarily be disable
1631	 * TX.
1632	 */
1633	urtw_read32_m(sc, URTW_TX_CONF, &orig);
1634	data = orig & ~URTW_TX_LOOPBACK_MASK;
1635	urtw_write32_m(sc, URTW_TX_CONF, data | URTW_TX_LOOPBACK_MAC);
1636
1637	error = sc->sc_rf_set_chan(sc, ieee80211_chan2ieee(ic, ic->ic_curchan));
1638	if (error != 0)
1639		goto fail;
1640	usb_pause_mtx(&sc->sc_mtx, 10);
1641	urtw_write32_m(sc, URTW_TX_CONF, orig);
1642
1643	urtw_write16_m(sc, URTW_ATIM_WND, 2);
1644	urtw_write16_m(sc, URTW_ATIM_TR_ITV, 100);
1645	urtw_write16_m(sc, URTW_BEACON_INTERVAL, 100);
1646	urtw_write16_m(sc, URTW_BEACON_INTERVAL_TIME, 100);
1647
1648fail:
1649	URTW_UNLOCK(sc);
1650
1651	sc->sc_curchan = ic->ic_curchan;
1652
1653	if (error != 0)
1654		device_printf(sc->sc_dev, "could not change the channel\n");
1655}
1656
1657static void
1658urtw_update_mcast(struct ifnet *ifp)
1659{
1660
1661	/* XXX do nothing?  */
1662}
1663
1664static int
1665urtw_tx_start(struct urtw_softc *sc, struct ieee80211_node *ni, struct mbuf *m0,
1666    struct urtw_data *data, int prior)
1667{
1668	struct ifnet *ifp = sc->sc_ifp;
1669	struct ieee80211_frame *wh = mtod(m0, struct ieee80211_frame *);
1670	struct ieee80211_key *k;
1671	const struct ieee80211_txparam *tp;
1672	struct ieee80211com *ic = ifp->if_l2com;
1673	struct ieee80211vap *vap = ni->ni_vap;
1674	struct usb_xfer *rtl8187b_pipes[URTW_8187B_TXPIPE_MAX] = {
1675		sc->sc_xfer[URTW_8187B_BULK_TX_BE],
1676		sc->sc_xfer[URTW_8187B_BULK_TX_BK],
1677		sc->sc_xfer[URTW_8187B_BULK_TX_VI],
1678		sc->sc_xfer[URTW_8187B_BULK_TX_VO]
1679	};
1680	struct usb_xfer *xfer;
1681	int dur = 0, rtsdur = 0, rtsenable = 0, ctsenable = 0, rate,
1682	    pkttime = 0, txdur = 0, isshort = 0, xferlen;
1683	uint16_t acktime, rtstime, ctstime;
1684	uint32_t flags;
1685	usb_error_t error;
1686
1687	URTW_ASSERT_LOCKED(sc);
1688
1689	/*
1690	 * Software crypto.
1691	 */
1692	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
1693		k = ieee80211_crypto_encap(ni, m0);
1694		if (k == NULL) {
1695			device_printf(sc->sc_dev,
1696			    "ieee80211_crypto_encap returns NULL.\n");
1697			/* XXX we don't expect the fragmented frames  */
1698			m_freem(m0);
1699			return (ENOBUFS);
1700		}
1701
1702		/* in case packet header moved, reset pointer */
1703		wh = mtod(m0, struct ieee80211_frame *);
1704	}
1705
1706	if (ieee80211_radiotap_active_vap(vap)) {
1707		struct urtw_tx_radiotap_header *tap = &sc->sc_txtap;
1708
1709		/* XXX Are variables correct?  */
1710		tap->wt_flags = 0;
1711		tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
1712		tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
1713
1714		ieee80211_radiotap_tx(vap, m0);
1715	}
1716
1717	if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_MGT ||
1718	    (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL) {
1719		tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
1720		rate = tp->mgmtrate;
1721	} else {
1722		tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)];
1723		/* for data frames */
1724		if (IEEE80211_IS_MULTICAST(wh->i_addr1))
1725			rate = tp->mcastrate;
1726		else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
1727			rate = tp->ucastrate;
1728		else
1729			rate = urtw_rtl2rate(sc->sc_currate);
1730	}
1731
1732	sc->sc_stats.txrates[sc->sc_currate]++;
1733
1734	if (IEEE80211_IS_MULTICAST(wh->i_addr1))
1735		txdur = pkttime = urtw_compute_txtime(m0->m_pkthdr.len +
1736		    IEEE80211_CRC_LEN, rate, 0, 0);
1737	else {
1738		acktime = urtw_compute_txtime(14, 2,0, 0);
1739		if ((m0->m_pkthdr.len + 4) > vap->iv_rtsthreshold) {
1740			rtsenable = 1;
1741			ctsenable = 0;
1742			rtstime = urtw_compute_txtime(URTW_ACKCTS_LEN, 2, 0, 0);
1743			ctstime = urtw_compute_txtime(14, 2, 0, 0);
1744			pkttime = urtw_compute_txtime(m0->m_pkthdr.len +
1745			    IEEE80211_CRC_LEN, rate, 0, isshort);
1746			rtsdur = ctstime + pkttime + acktime +
1747			    3 * URTW_ASIFS_TIME;
1748			txdur = rtstime + rtsdur;
1749		} else {
1750			rtsenable = ctsenable = rtsdur = 0;
1751			pkttime = urtw_compute_txtime(m0->m_pkthdr.len +
1752			    IEEE80211_CRC_LEN, rate, 0, isshort);
1753			txdur = pkttime + URTW_ASIFS_TIME + acktime;
1754		}
1755
1756		if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG)
1757			dur = urtw_compute_txtime(m0->m_pkthdr.len +
1758			    IEEE80211_CRC_LEN, rate, 0, isshort) +
1759			    3 * URTW_ASIFS_TIME +
1760			    2 * acktime;
1761		else
1762			dur = URTW_ASIFS_TIME + acktime;
1763	}
1764	*(uint16_t *)wh->i_dur = htole16(dur);
1765
1766	xferlen = m0->m_pkthdr.len;
1767	xferlen += (sc->sc_flags & URTW_RTL8187B) ? (4 * 8) : (4 * 3);
1768	if ((0 == xferlen % 64) || (0 == xferlen % 512))
1769		xferlen += 1;
1770
1771	memset(data->buf, 0, URTW_TX_MAXSIZE);
1772	flags = m0->m_pkthdr.len & 0xfff;
1773	flags |= URTW_TX_FLAG_NO_ENC;
1774	if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
1775	    (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE) &&
1776	    (sc->sc_preamble_mode == URTW_PREAMBLE_MODE_SHORT) &&
1777	    (sc->sc_currate != 0))
1778		flags |= URTW_TX_FLAG_SPLCP;
1779	if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG)
1780		flags |= URTW_TX_FLAG_MOREFRAG;
1781
1782	flags |= (sc->sc_currate & 0xf) << URTW_TX_FLAG_TXRATE_SHIFT;
1783
1784	if (sc->sc_flags & URTW_RTL8187B) {
1785		struct urtw_8187b_txhdr *tx;
1786
1787		tx = (struct urtw_8187b_txhdr *)data->buf;
1788		if (ctsenable)
1789			flags |= URTW_TX_FLAG_CTS;
1790		if (rtsenable) {
1791			flags |= URTW_TX_FLAG_RTS;
1792			flags |= (urtw_rate2rtl(11) & 0xf) <<
1793			    URTW_TX_FLAG_RTSRATE_SHIFT;
1794			tx->rtsdur = rtsdur;
1795		}
1796		tx->flag = htole32(flags);
1797		tx->txdur = txdur;
1798		if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
1799		    IEEE80211_FC0_TYPE_MGT &&
1800		    (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) ==
1801		    IEEE80211_FC0_SUBTYPE_PROBE_RESP)
1802			tx->retry = 1;
1803		else
1804			tx->retry = URTW_TX_MAXRETRY;
1805		m_copydata(m0, 0, m0->m_pkthdr.len, (uint8_t *)(tx + 1));
1806	} else {
1807		struct urtw_8187l_txhdr *tx;
1808
1809		tx = (struct urtw_8187l_txhdr *)data->buf;
1810		if (rtsenable) {
1811			flags |= URTW_TX_FLAG_RTS;
1812			tx->rtsdur = rtsdur;
1813		}
1814		flags |= (urtw_rate2rtl(11) & 0xf) << URTW_TX_FLAG_RTSRATE_SHIFT;
1815		tx->flag = htole32(flags);
1816		tx->retry = 3;		/* CW minimum  */
1817		tx->retry = 7 << 4;	/* CW maximum  */
1818		tx->retry = URTW_TX_MAXRETRY << 8;	/* retry limitation  */
1819		m_copydata(m0, 0, m0->m_pkthdr.len, (uint8_t *)(tx + 1));
1820	}
1821
1822	data->buflen = xferlen;
1823	data->ni = ni;
1824	data->m = m0;
1825
1826	if (sc->sc_flags & URTW_RTL8187B) {
1827		switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) {
1828		case IEEE80211_FC0_TYPE_CTL:
1829		case IEEE80211_FC0_TYPE_MGT:
1830			xfer = sc->sc_xfer[URTW_8187B_BULK_TX_EP12];
1831			break;
1832		default:
1833			KASSERT(M_WME_GETAC(m0) < URTW_8187B_TXPIPE_MAX,
1834			    ("unsupported WME pipe %d", M_WME_GETAC(m0)));
1835			xfer = rtl8187b_pipes[M_WME_GETAC(m0)];
1836			break;
1837		}
1838	} else
1839		xfer = (prior == URTW_PRIORITY_LOW) ?
1840		    sc->sc_xfer[URTW_8187L_BULK_TX_LOW] :
1841		    sc->sc_xfer[URTW_8187L_BULK_TX_NORMAL];
1842
1843	STAILQ_INSERT_TAIL(&sc->sc_tx_pending, data, next);
1844	usbd_transfer_start(xfer);
1845
1846	error = urtw_led_ctl(sc, URTW_LED_CTL_TX);
1847	if (error != 0)
1848		device_printf(sc->sc_dev, "could not control LED (%d)\n",
1849		    error);
1850	return (0);
1851}
1852
1853static int
1854urtw_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
1855{
1856	struct ieee80211com *ic = vap->iv_ic;
1857	struct urtw_softc *sc = ic->ic_ifp->if_softc;
1858	struct urtw_vap *uvp = URTW_VAP(vap);
1859	struct ieee80211_node *ni;
1860	usb_error_t error = 0;
1861
1862	DPRINTF(sc, URTW_DEBUG_STATE, "%s: %s -> %s\n", __func__,
1863	    ieee80211_state_name[vap->iv_state],
1864	    ieee80211_state_name[nstate]);
1865
1866	sc->sc_state = nstate;
1867
1868	IEEE80211_UNLOCK(ic);
1869	URTW_LOCK(sc);
1870	usb_callout_stop(&sc->sc_led_ch);
1871	callout_stop(&sc->sc_watchdog_ch);
1872
1873	switch (nstate) {
1874	case IEEE80211_S_INIT:
1875	case IEEE80211_S_SCAN:
1876	case IEEE80211_S_AUTH:
1877	case IEEE80211_S_ASSOC:
1878		break;
1879	case IEEE80211_S_RUN:
1880		ni = ieee80211_ref_node(vap->iv_bss);
1881		/* setting bssid.  */
1882		urtw_write32_m(sc, URTW_BSSID, ((uint32_t *)ni->ni_bssid)[0]);
1883		urtw_write16_m(sc, URTW_BSSID + 4,
1884		    ((uint16_t *)ni->ni_bssid)[2]);
1885		urtw_update_msr(sc);
1886		/* XXX maybe the below would be incorrect.  */
1887		urtw_write16_m(sc, URTW_ATIM_WND, 2);
1888		urtw_write16_m(sc, URTW_ATIM_TR_ITV, 100);
1889		urtw_write16_m(sc, URTW_BEACON_INTERVAL, 0x64);
1890		urtw_write16_m(sc, URTW_BEACON_INTERVAL_TIME, 100);
1891		error = urtw_led_ctl(sc, URTW_LED_CTL_LINK);
1892		if (error != 0)
1893			device_printf(sc->sc_dev,
1894			    "could not control LED (%d)\n", error);
1895		ieee80211_free_node(ni);
1896		break;
1897	default:
1898		break;
1899	}
1900fail:
1901	URTW_UNLOCK(sc);
1902	IEEE80211_LOCK(ic);
1903	return (uvp->newstate(vap, nstate, arg));
1904}
1905
1906static void
1907urtw_watchdog(void *arg)
1908{
1909	struct urtw_softc *sc = arg;
1910	struct ifnet *ifp = sc->sc_ifp;
1911
1912	if (sc->sc_txtimer > 0) {
1913		if (--sc->sc_txtimer == 0) {
1914			device_printf(sc->sc_dev, "device timeout\n");
1915			ifp->if_oerrors++;
1916			return;
1917		}
1918		callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc);
1919	}
1920}
1921
1922static void
1923urtw_set_multi(void *arg)
1924{
1925	struct urtw_softc *sc = arg;
1926	struct ifnet *ifp = sc->sc_ifp;
1927
1928	if (!(ifp->if_flags & IFF_UP))
1929		return;
1930
1931	/*
1932	 * XXX don't know how to set a device.  Lack of docs.  Just try to set
1933	 * IFF_ALLMULTI flag here.
1934	 */
1935	ifp->if_flags |= IFF_ALLMULTI;
1936}
1937
1938static usb_error_t
1939urtw_set_rate(struct urtw_softc *sc)
1940{
1941	int i, basic_rate, min_rr_rate, max_rr_rate;
1942	uint16_t data;
1943	usb_error_t error;
1944
1945	basic_rate = urtw_rate2rtl(48);
1946	min_rr_rate = urtw_rate2rtl(12);
1947	max_rr_rate = urtw_rate2rtl(48);
1948
1949	urtw_write8_m(sc, URTW_RESP_RATE,
1950	    max_rr_rate << URTW_RESP_MAX_RATE_SHIFT |
1951	    min_rr_rate << URTW_RESP_MIN_RATE_SHIFT);
1952
1953	urtw_read16_m(sc, URTW_BRSR, &data);
1954	data &= ~URTW_BRSR_MBR_8185;
1955
1956	for (i = 0; i <= basic_rate; i++)
1957		data |= (1 << i);
1958
1959	urtw_write16_m(sc, URTW_BRSR, data);
1960fail:
1961	return (error);
1962}
1963
1964static uint16_t
1965urtw_rate2rtl(uint32_t rate)
1966{
1967#define N(a)	((int)(sizeof(a) / sizeof((a)[0])))
1968	int i;
1969
1970	for (i = 0; i < N(urtw_ratetable); i++) {
1971		if (rate == urtw_ratetable[i].reg)
1972			return urtw_ratetable[i].val;
1973	}
1974
1975	return (3);
1976#undef N
1977}
1978
1979static uint16_t
1980urtw_rtl2rate(uint32_t rate)
1981{
1982#define N(a)	((int)(sizeof(a) / sizeof((a)[0])))
1983	int i;
1984
1985	for (i = 0; i < N(urtw_ratetable); i++) {
1986		if (rate == urtw_ratetable[i].val)
1987			return urtw_ratetable[i].reg;
1988	}
1989
1990	return (0);
1991#undef N
1992}
1993
1994static usb_error_t
1995urtw_update_msr(struct urtw_softc *sc)
1996{
1997	struct ifnet *ifp = sc->sc_ifp;
1998	struct ieee80211com *ic = ifp->if_l2com;
1999	uint8_t data;
2000	usb_error_t error;
2001
2002	urtw_read8_m(sc, URTW_MSR, &data);
2003	data &= ~URTW_MSR_LINK_MASK;
2004
2005	if (sc->sc_state == IEEE80211_S_RUN) {
2006		switch (ic->ic_opmode) {
2007		case IEEE80211_M_STA:
2008		case IEEE80211_M_MONITOR:
2009			data |= URTW_MSR_LINK_STA;
2010			if (sc->sc_flags & URTW_RTL8187B)
2011				data |= URTW_MSR_LINK_ENEDCA;
2012			break;
2013		case IEEE80211_M_IBSS:
2014			data |= URTW_MSR_LINK_ADHOC;
2015			break;
2016		case IEEE80211_M_HOSTAP:
2017			data |= URTW_MSR_LINK_HOSTAP;
2018			break;
2019		default:
2020			DPRINTF(sc, URTW_DEBUG_STATE,
2021			    "unsupported operation mode 0x%x\n",
2022			    ic->ic_opmode);
2023			error = USB_ERR_INVAL;
2024			goto fail;
2025		}
2026	} else
2027		data |= URTW_MSR_LINK_NONE;
2028
2029	urtw_write8_m(sc, URTW_MSR, data);
2030fail:
2031	return (error);
2032}
2033
2034static usb_error_t
2035urtw_read8_c(struct urtw_softc *sc, int val, uint8_t *data)
2036{
2037	struct usb_device_request req;
2038	usb_error_t error;
2039
2040	URTW_ASSERT_LOCKED(sc);
2041
2042	req.bmRequestType = UT_READ_VENDOR_DEVICE;
2043	req.bRequest = URTW_8187_GETREGS_REQ;
2044	USETW(req.wValue, (val & 0xff) | 0xff00);
2045	USETW(req.wIndex, (val >> 8) & 0x3);
2046	USETW(req.wLength, sizeof(uint8_t));
2047
2048	error = urtw_do_request(sc, &req, data);
2049	return (error);
2050}
2051
2052static usb_error_t
2053urtw_read16_c(struct urtw_softc *sc, int val, uint16_t *data)
2054{
2055	struct usb_device_request req;
2056	usb_error_t error;
2057
2058	URTW_ASSERT_LOCKED(sc);
2059
2060	req.bmRequestType = UT_READ_VENDOR_DEVICE;
2061	req.bRequest = URTW_8187_GETREGS_REQ;
2062	USETW(req.wValue, (val & 0xff) | 0xff00);
2063	USETW(req.wIndex, (val >> 8) & 0x3);
2064	USETW(req.wLength, sizeof(uint16_t));
2065
2066	error = urtw_do_request(sc, &req, data);
2067	return (error);
2068}
2069
2070static usb_error_t
2071urtw_read32_c(struct urtw_softc *sc, int val, uint32_t *data)
2072{
2073	struct usb_device_request req;
2074	usb_error_t error;
2075
2076	URTW_ASSERT_LOCKED(sc);
2077
2078	req.bmRequestType = UT_READ_VENDOR_DEVICE;
2079	req.bRequest = URTW_8187_GETREGS_REQ;
2080	USETW(req.wValue, (val & 0xff) | 0xff00);
2081	USETW(req.wIndex, (val >> 8) & 0x3);
2082	USETW(req.wLength, sizeof(uint32_t));
2083
2084	error = urtw_do_request(sc, &req, data);
2085	return (error);
2086}
2087
2088static usb_error_t
2089urtw_write8_c(struct urtw_softc *sc, int val, uint8_t data)
2090{
2091	struct usb_device_request req;
2092
2093	URTW_ASSERT_LOCKED(sc);
2094
2095	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
2096	req.bRequest = URTW_8187_SETREGS_REQ;
2097	USETW(req.wValue, (val & 0xff) | 0xff00);
2098	USETW(req.wIndex, (val >> 8) & 0x3);
2099	USETW(req.wLength, sizeof(uint8_t));
2100
2101	return (urtw_do_request(sc, &req, &data));
2102}
2103
2104static usb_error_t
2105urtw_write16_c(struct urtw_softc *sc, int val, uint16_t data)
2106{
2107	struct usb_device_request req;
2108
2109	URTW_ASSERT_LOCKED(sc);
2110
2111	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
2112	req.bRequest = URTW_8187_SETREGS_REQ;
2113	USETW(req.wValue, (val & 0xff) | 0xff00);
2114	USETW(req.wIndex, (val >> 8) & 0x3);
2115	USETW(req.wLength, sizeof(uint16_t));
2116
2117	return (urtw_do_request(sc, &req, &data));
2118}
2119
2120static usb_error_t
2121urtw_write32_c(struct urtw_softc *sc, int val, uint32_t data)
2122{
2123	struct usb_device_request req;
2124
2125	URTW_ASSERT_LOCKED(sc);
2126
2127	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
2128	req.bRequest = URTW_8187_SETREGS_REQ;
2129	USETW(req.wValue, (val & 0xff) | 0xff00);
2130	USETW(req.wIndex, (val >> 8) & 0x3);
2131	USETW(req.wLength, sizeof(uint32_t));
2132
2133	return (urtw_do_request(sc, &req, &data));
2134}
2135
2136static usb_error_t
2137urtw_get_macaddr(struct urtw_softc *sc)
2138{
2139	uint32_t data;
2140	usb_error_t error;
2141
2142	error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR, &data);
2143	if (error != 0)
2144		goto fail;
2145	sc->sc_bssid[0] = data & 0xff;
2146	sc->sc_bssid[1] = (data & 0xff00) >> 8;
2147	error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR + 1, &data);
2148	if (error != 0)
2149		goto fail;
2150	sc->sc_bssid[2] = data & 0xff;
2151	sc->sc_bssid[3] = (data & 0xff00) >> 8;
2152	error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR + 2, &data);
2153	if (error != 0)
2154		goto fail;
2155	sc->sc_bssid[4] = data & 0xff;
2156	sc->sc_bssid[5] = (data & 0xff00) >> 8;
2157fail:
2158	return (error);
2159}
2160
2161static usb_error_t
2162urtw_eprom_read32(struct urtw_softc *sc, uint32_t addr, uint32_t *data)
2163{
2164#define URTW_READCMD_LEN		3
2165	int addrlen, i;
2166	int16_t addrstr[8], data16, readcmd[] = { 1, 1, 0 };
2167	usb_error_t error;
2168
2169	/* NB: make sure the buffer is initialized  */
2170	*data = 0;
2171
2172	/* enable EPROM programming */
2173	urtw_write8_m(sc, URTW_EPROM_CMD, URTW_EPROM_CMD_PROGRAM_MODE);
2174	DELAY(URTW_EPROM_DELAY);
2175
2176	error = urtw_eprom_cs(sc, URTW_EPROM_ENABLE);
2177	if (error != 0)
2178		goto fail;
2179	error = urtw_eprom_ck(sc);
2180	if (error != 0)
2181		goto fail;
2182	error = urtw_eprom_sendbits(sc, readcmd, URTW_READCMD_LEN);
2183	if (error != 0)
2184		goto fail;
2185	if (sc->sc_epromtype == URTW_EEPROM_93C56) {
2186		addrlen = 8;
2187		addrstr[0] = addr & (1 << 7);
2188		addrstr[1] = addr & (1 << 6);
2189		addrstr[2] = addr & (1 << 5);
2190		addrstr[3] = addr & (1 << 4);
2191		addrstr[4] = addr & (1 << 3);
2192		addrstr[5] = addr & (1 << 2);
2193		addrstr[6] = addr & (1 << 1);
2194		addrstr[7] = addr & (1 << 0);
2195	} else {
2196		addrlen=6;
2197		addrstr[0] = addr & (1 << 5);
2198		addrstr[1] = addr & (1 << 4);
2199		addrstr[2] = addr & (1 << 3);
2200		addrstr[3] = addr & (1 << 2);
2201		addrstr[4] = addr & (1 << 1);
2202		addrstr[5] = addr & (1 << 0);
2203	}
2204	error = urtw_eprom_sendbits(sc, addrstr, addrlen);
2205	if (error != 0)
2206		goto fail;
2207
2208	error = urtw_eprom_writebit(sc, 0);
2209	if (error != 0)
2210		goto fail;
2211
2212	for (i = 0; i < 16; i++) {
2213		error = urtw_eprom_ck(sc);
2214		if (error != 0)
2215			goto fail;
2216		error = urtw_eprom_readbit(sc, &data16);
2217		if (error != 0)
2218			goto fail;
2219
2220		(*data) |= (data16 << (15 - i));
2221	}
2222
2223	error = urtw_eprom_cs(sc, URTW_EPROM_DISABLE);
2224	if (error != 0)
2225		goto fail;
2226	error = urtw_eprom_ck(sc);
2227	if (error != 0)
2228		goto fail;
2229
2230	/* now disable EPROM programming */
2231	urtw_write8_m(sc, URTW_EPROM_CMD, URTW_EPROM_CMD_NORMAL_MODE);
2232fail:
2233	return (error);
2234#undef URTW_READCMD_LEN
2235}
2236
2237static usb_error_t
2238urtw_eprom_cs(struct urtw_softc *sc, int able)
2239{
2240	uint8_t data;
2241	usb_error_t error;
2242
2243	urtw_read8_m(sc, URTW_EPROM_CMD, &data);
2244	if (able == URTW_EPROM_ENABLE)
2245		urtw_write8_m(sc, URTW_EPROM_CMD, data | URTW_EPROM_CS);
2246	else
2247		urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_CS);
2248	DELAY(URTW_EPROM_DELAY);
2249fail:
2250	return (error);
2251}
2252
2253static usb_error_t
2254urtw_eprom_ck(struct urtw_softc *sc)
2255{
2256	uint8_t data;
2257	usb_error_t error;
2258
2259	/* masking  */
2260	urtw_read8_m(sc, URTW_EPROM_CMD, &data);
2261	urtw_write8_m(sc, URTW_EPROM_CMD, data | URTW_EPROM_CK);
2262	DELAY(URTW_EPROM_DELAY);
2263	/* unmasking  */
2264	urtw_read8_m(sc, URTW_EPROM_CMD, &data);
2265	urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_CK);
2266	DELAY(URTW_EPROM_DELAY);
2267fail:
2268	return (error);
2269}
2270
2271static usb_error_t
2272urtw_eprom_readbit(struct urtw_softc *sc, int16_t *data)
2273{
2274	uint8_t data8;
2275	usb_error_t error;
2276
2277	urtw_read8_m(sc, URTW_EPROM_CMD, &data8);
2278	*data = (data8 & URTW_EPROM_READBIT) ? 1 : 0;
2279	DELAY(URTW_EPROM_DELAY);
2280
2281fail:
2282	return (error);
2283}
2284
2285static usb_error_t
2286urtw_eprom_writebit(struct urtw_softc *sc, int16_t bit)
2287{
2288	uint8_t data;
2289	usb_error_t error;
2290
2291	urtw_read8_m(sc, URTW_EPROM_CMD, &data);
2292	if (bit != 0)
2293		urtw_write8_m(sc, URTW_EPROM_CMD, data | URTW_EPROM_WRITEBIT);
2294	else
2295		urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_WRITEBIT);
2296	DELAY(URTW_EPROM_DELAY);
2297fail:
2298	return (error);
2299}
2300
2301static usb_error_t
2302urtw_eprom_sendbits(struct urtw_softc *sc, int16_t *buf, int buflen)
2303{
2304	int i = 0;
2305	usb_error_t error = 0;
2306
2307	for (i = 0; i < buflen; i++) {
2308		error = urtw_eprom_writebit(sc, buf[i]);
2309		if (error != 0)
2310			goto fail;
2311		error = urtw_eprom_ck(sc);
2312		if (error != 0)
2313			goto fail;
2314	}
2315fail:
2316	return (error);
2317}
2318
2319
2320static usb_error_t
2321urtw_get_txpwr(struct urtw_softc *sc)
2322{
2323	int i, j;
2324	uint32_t data;
2325	usb_error_t error;
2326
2327	error = urtw_eprom_read32(sc, URTW_EPROM_TXPW_BASE, &data);
2328	if (error != 0)
2329		goto fail;
2330	sc->sc_txpwr_cck_base = data & 0xf;
2331	sc->sc_txpwr_ofdm_base = (data >> 4) & 0xf;
2332
2333	for (i = 1, j = 0; i < 6; i += 2, j++) {
2334		error = urtw_eprom_read32(sc, URTW_EPROM_TXPW0 + j, &data);
2335		if (error != 0)
2336			goto fail;
2337		sc->sc_txpwr_cck[i] = data & 0xf;
2338		sc->sc_txpwr_cck[i + 1] = (data & 0xf00) >> 8;
2339		sc->sc_txpwr_ofdm[i] = (data & 0xf0) >> 4;
2340		sc->sc_txpwr_ofdm[i + 1] = (data & 0xf000) >> 12;
2341	}
2342	for (i = 1, j = 0; i < 4; i += 2, j++) {
2343		error = urtw_eprom_read32(sc, URTW_EPROM_TXPW1 + j, &data);
2344		if (error != 0)
2345			goto fail;
2346		sc->sc_txpwr_cck[i + 6] = data & 0xf;
2347		sc->sc_txpwr_cck[i + 6 + 1] = (data & 0xf00) >> 8;
2348		sc->sc_txpwr_ofdm[i + 6] = (data & 0xf0) >> 4;
2349		sc->sc_txpwr_ofdm[i + 6 + 1] = (data & 0xf000) >> 12;
2350	}
2351	if (sc->sc_flags & URTW_RTL8187B) {
2352		error = urtw_eprom_read32(sc, URTW_EPROM_TXPW2, &data);
2353		if (error != 0)
2354			goto fail;
2355		sc->sc_txpwr_cck[1 + 6 + 4] = data & 0xf;
2356		sc->sc_txpwr_ofdm[1 + 6 + 4] = (data & 0xf0) >> 4;
2357		error = urtw_eprom_read32(sc, 0x0a, &data);
2358		if (error != 0)
2359			goto fail;
2360		sc->sc_txpwr_cck[2 + 6 + 4] = data & 0xf;
2361		sc->sc_txpwr_ofdm[2 + 6 + 4] = (data & 0xf0) >> 4;
2362		error = urtw_eprom_read32(sc, 0x1c, &data);
2363		if (error != 0)
2364			goto fail;
2365		sc->sc_txpwr_cck[3 + 6 + 4] = data & 0xf;
2366		sc->sc_txpwr_cck[3 + 6 + 4 + 1] = (data & 0xf00) >> 8;
2367		sc->sc_txpwr_ofdm[3 + 6 + 4] = (data & 0xf0) >> 4;
2368		sc->sc_txpwr_ofdm[3 + 6 + 4 + 1] = (data & 0xf000) >> 12;
2369	} else {
2370		for (i = 1, j = 0; i < 4; i += 2, j++) {
2371			error = urtw_eprom_read32(sc, URTW_EPROM_TXPW2 + j,
2372			    &data);
2373			if (error != 0)
2374				goto fail;
2375			sc->sc_txpwr_cck[i + 6 + 4] = data & 0xf;
2376			sc->sc_txpwr_cck[i + 6 + 4 + 1] = (data & 0xf00) >> 8;
2377			sc->sc_txpwr_ofdm[i + 6 + 4] = (data & 0xf0) >> 4;
2378			sc->sc_txpwr_ofdm[i + 6 + 4 + 1] = (data & 0xf000) >> 12;
2379		}
2380	}
2381fail:
2382	return (error);
2383}
2384
2385
2386static usb_error_t
2387urtw_get_rfchip(struct urtw_softc *sc)
2388{
2389	int ret;
2390	uint8_t data8;
2391	uint32_t data;
2392	usb_error_t error;
2393
2394	if (sc->sc_flags & URTW_RTL8187B) {
2395		urtw_read8_m(sc, 0xe1, &data8);
2396		switch (data8) {
2397		case 0:
2398			sc->sc_flags |= URTW_RTL8187B_REV_B;
2399			break;
2400		case 1:
2401			sc->sc_flags |= URTW_RTL8187B_REV_D;
2402			break;
2403		case 2:
2404			sc->sc_flags |= URTW_RTL8187B_REV_E;
2405			break;
2406		default:
2407			device_printf(sc->sc_dev, "unknown type: %#x\n", data8);
2408			sc->sc_flags |= URTW_RTL8187B_REV_B;
2409			break;
2410		}
2411	} else {
2412		urtw_read32_m(sc, URTW_TX_CONF, &data);
2413		switch (data & URTW_TX_HWMASK) {
2414		case URTW_TX_R8187vD_B:
2415			sc->sc_flags |= URTW_RTL8187B;
2416			break;
2417		case URTW_TX_R8187vD:
2418			break;
2419		default:
2420			device_printf(sc->sc_dev, "unknown RTL8187L type: %#x\n",
2421			    data & URTW_TX_HWMASK);
2422			break;
2423		}
2424	}
2425
2426	error = urtw_eprom_read32(sc, URTW_EPROM_RFCHIPID, &data);
2427	if (error != 0)
2428		goto fail;
2429	switch (data & 0xff) {
2430	case URTW_EPROM_RFCHIPID_RTL8225U:
2431		error = urtw_8225_isv2(sc, &ret);
2432		if (error != 0)
2433			goto fail;
2434		if (ret == 0) {
2435			sc->sc_rf_init = urtw_8225_rf_init;
2436			sc->sc_rf_set_sens = urtw_8225_rf_set_sens;
2437			sc->sc_rf_set_chan = urtw_8225_rf_set_chan;
2438			sc->sc_rf_stop = urtw_8225_rf_stop;
2439		} else {
2440			sc->sc_rf_init = urtw_8225v2_rf_init;
2441			sc->sc_rf_set_chan = urtw_8225v2_rf_set_chan;
2442			sc->sc_rf_stop = urtw_8225_rf_stop;
2443		}
2444		sc->sc_max_sens = URTW_8225_RF_MAX_SENS;
2445		sc->sc_sens = URTW_8225_RF_DEF_SENS;
2446		break;
2447	case URTW_EPROM_RFCHIPID_RTL8225Z2:
2448		sc->sc_rf_init = urtw_8225v2b_rf_init;
2449		sc->sc_rf_set_chan = urtw_8225v2b_rf_set_chan;
2450		sc->sc_max_sens = URTW_8225_RF_MAX_SENS;
2451		sc->sc_sens = URTW_8225_RF_DEF_SENS;
2452		sc->sc_rf_stop = urtw_8225_rf_stop;
2453		break;
2454	default:
2455		DPRINTF(sc, URTW_DEBUG_STATE,
2456		    "unsupported RF chip %d\n", data & 0xff);
2457		error = USB_ERR_INVAL;
2458		goto fail;
2459	}
2460
2461	device_printf(sc->sc_dev, "%s rf %s hwrev %s\n",
2462	    (sc->sc_flags & URTW_RTL8187B) ? "rtl8187b" : "rtl8187l",
2463	    ((data & 0xff) == URTW_EPROM_RFCHIPID_RTL8225U) ? "rtl8225u" :
2464	    "rtl8225z2",
2465	    (sc->sc_flags & URTW_RTL8187B) ? ((data8 == 0) ? "b" :
2466		(data8 == 1) ? "d" : "e") : "none");
2467
2468fail:
2469	return (error);
2470}
2471
2472
2473static usb_error_t
2474urtw_led_init(struct urtw_softc *sc)
2475{
2476	uint32_t rev;
2477	usb_error_t error;
2478
2479	urtw_read8_m(sc, URTW_PSR, &sc->sc_psr);
2480	error = urtw_eprom_read32(sc, URTW_EPROM_SWREV, &rev);
2481	if (error != 0)
2482		goto fail;
2483
2484	switch (rev & URTW_EPROM_CID_MASK) {
2485	case URTW_EPROM_CID_ALPHA0:
2486		sc->sc_strategy = URTW_SW_LED_MODE1;
2487		break;
2488	case URTW_EPROM_CID_SERCOMM_PS:
2489		sc->sc_strategy = URTW_SW_LED_MODE3;
2490		break;
2491	case URTW_EPROM_CID_HW_LED:
2492		sc->sc_strategy = URTW_HW_LED;
2493		break;
2494	case URTW_EPROM_CID_RSVD0:
2495	case URTW_EPROM_CID_RSVD1:
2496	default:
2497		sc->sc_strategy = URTW_SW_LED_MODE0;
2498		break;
2499	}
2500
2501	sc->sc_gpio_ledpin = URTW_LED_PIN_GPIO0;
2502
2503fail:
2504	return (error);
2505}
2506
2507
2508static usb_error_t
2509urtw_8225_rf_init(struct urtw_softc *sc)
2510{
2511#define N(a)	((int)(sizeof(a) / sizeof((a)[0])))
2512	int i;
2513	uint16_t data;
2514	usb_error_t error;
2515
2516	error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
2517	if (error)
2518		goto fail;
2519
2520	error = urtw_8225_usb_init(sc);
2521	if (error)
2522		goto fail;
2523
2524	urtw_write32_m(sc, URTW_RF_TIMING, 0x000a8008);
2525	urtw_read16_m(sc, URTW_BRSR, &data);		/* XXX ??? */
2526	urtw_write16_m(sc, URTW_BRSR, 0xffff);
2527	urtw_write32_m(sc, URTW_RF_PARA, 0x100044);
2528
2529	error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
2530	if (error)
2531		goto fail;
2532	urtw_write8_m(sc, URTW_CONFIG3, 0x44);
2533	error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
2534	if (error)
2535		goto fail;
2536
2537	error = urtw_8185_rf_pins_enable(sc);
2538	if (error)
2539		goto fail;
2540	usb_pause_mtx(&sc->sc_mtx, 1000);
2541
2542	for (i = 0; i < N(urtw_8225_rf_part1); i++) {
2543		urtw_8225_write(sc, urtw_8225_rf_part1[i].reg,
2544		    urtw_8225_rf_part1[i].val);
2545		usb_pause_mtx(&sc->sc_mtx, 1);
2546	}
2547	usb_pause_mtx(&sc->sc_mtx, 100);
2548	urtw_8225_write(sc,
2549	    URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC1);
2550	usb_pause_mtx(&sc->sc_mtx, 200);
2551	urtw_8225_write(sc,
2552	    URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC2);
2553	usb_pause_mtx(&sc->sc_mtx, 200);
2554	urtw_8225_write(sc,
2555	    URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC3);
2556
2557	for (i = 0; i < 95; i++) {
2558		urtw_8225_write(sc, URTW_8225_ADDR_1_MAGIC, (uint8_t)(i + 1));
2559		urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC, urtw_8225_rxgain[i]);
2560	}
2561
2562	urtw_8225_write(sc,
2563	    URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC4);
2564	urtw_8225_write(sc,
2565	    URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC5);
2566
2567	for (i = 0; i < 128; i++) {
2568		urtw_8187_write_phy_ofdm(sc, 0xb, urtw_8225_agc[i]);
2569		usb_pause_mtx(&sc->sc_mtx, 1);
2570		urtw_8187_write_phy_ofdm(sc, 0xa, (uint8_t)i + 0x80);
2571		usb_pause_mtx(&sc->sc_mtx, 1);
2572	}
2573
2574	for (i = 0; i < N(urtw_8225_rf_part2); i++) {
2575		urtw_8187_write_phy_ofdm(sc, urtw_8225_rf_part2[i].reg,
2576		    urtw_8225_rf_part2[i].val);
2577		usb_pause_mtx(&sc->sc_mtx, 1);
2578	}
2579
2580	error = urtw_8225_setgain(sc, 4);
2581	if (error)
2582		goto fail;
2583
2584	for (i = 0; i < N(urtw_8225_rf_part3); i++) {
2585		urtw_8187_write_phy_cck(sc, urtw_8225_rf_part3[i].reg,
2586		    urtw_8225_rf_part3[i].val);
2587		usb_pause_mtx(&sc->sc_mtx, 1);
2588	}
2589
2590	urtw_write8_m(sc, URTW_TESTR, 0x0d);
2591
2592	error = urtw_8225_set_txpwrlvl(sc, 1);
2593	if (error)
2594		goto fail;
2595
2596	urtw_8187_write_phy_cck(sc, 0x10, 0x9b);
2597	usb_pause_mtx(&sc->sc_mtx, 1);
2598	urtw_8187_write_phy_ofdm(sc, 0x26, 0x90);
2599	usb_pause_mtx(&sc->sc_mtx, 1);
2600
2601	/* TX ant A, 0x0 for B */
2602	error = urtw_8185_tx_antenna(sc, 0x3);
2603	if (error)
2604		goto fail;
2605	urtw_write32_m(sc, URTW_HSSI_PARA, 0x3dc00002);
2606
2607	error = urtw_8225_rf_set_chan(sc, 1);
2608fail:
2609	return (error);
2610#undef N
2611}
2612
2613static usb_error_t
2614urtw_8185_rf_pins_enable(struct urtw_softc *sc)
2615{
2616	usb_error_t error = 0;
2617
2618	urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x1ff7);
2619fail:
2620	return (error);
2621}
2622
2623static usb_error_t
2624urtw_8185_tx_antenna(struct urtw_softc *sc, uint8_t ant)
2625{
2626	usb_error_t error;
2627
2628	urtw_write8_m(sc, URTW_TX_ANTENNA, ant);
2629	usb_pause_mtx(&sc->sc_mtx, 1);
2630fail:
2631	return (error);
2632}
2633
2634static usb_error_t
2635urtw_8187_write_phy_ofdm_c(struct urtw_softc *sc, uint8_t addr, uint32_t data)
2636{
2637
2638	data = data & 0xff;
2639	return urtw_8187_write_phy(sc, addr, data);
2640}
2641
2642static usb_error_t
2643urtw_8187_write_phy_cck_c(struct urtw_softc *sc, uint8_t addr, uint32_t data)
2644{
2645
2646	data = data & 0xff;
2647	return urtw_8187_write_phy(sc, addr, data | 0x10000);
2648}
2649
2650static usb_error_t
2651urtw_8187_write_phy(struct urtw_softc *sc, uint8_t addr, uint32_t data)
2652{
2653	uint32_t phyw;
2654	usb_error_t error;
2655
2656	phyw = ((data << 8) | (addr | 0x80));
2657	urtw_write8_m(sc, URTW_PHY_MAGIC4, ((phyw & 0xff000000) >> 24));
2658	urtw_write8_m(sc, URTW_PHY_MAGIC3, ((phyw & 0x00ff0000) >> 16));
2659	urtw_write8_m(sc, URTW_PHY_MAGIC2, ((phyw & 0x0000ff00) >> 8));
2660	urtw_write8_m(sc, URTW_PHY_MAGIC1, ((phyw & 0x000000ff)));
2661	usb_pause_mtx(&sc->sc_mtx, 1);
2662fail:
2663	return (error);
2664}
2665
2666static usb_error_t
2667urtw_8225_setgain(struct urtw_softc *sc, int16_t gain)
2668{
2669	usb_error_t error;
2670
2671	urtw_8187_write_phy_ofdm(sc, 0x0d, urtw_8225_gain[gain * 4]);
2672	urtw_8187_write_phy_ofdm(sc, 0x1b, urtw_8225_gain[gain * 4 + 2]);
2673	urtw_8187_write_phy_ofdm(sc, 0x1d, urtw_8225_gain[gain * 4 + 3]);
2674	urtw_8187_write_phy_ofdm(sc, 0x23, urtw_8225_gain[gain * 4 + 1]);
2675fail:
2676	return (error);
2677}
2678
2679static usb_error_t
2680urtw_8225_usb_init(struct urtw_softc *sc)
2681{
2682	uint8_t data;
2683	usb_error_t error;
2684
2685	urtw_write8_m(sc, URTW_RF_PINS_SELECT + 1, 0);
2686	urtw_write8_m(sc, URTW_GPIO, 0);
2687	error = urtw_read8e(sc, 0x53, &data);
2688	if (error)
2689		goto fail;
2690	error = urtw_write8e(sc, 0x53, data | (1 << 7));
2691	if (error)
2692		goto fail;
2693	urtw_write8_m(sc, URTW_RF_PINS_SELECT + 1, 4);
2694	urtw_write8_m(sc, URTW_GPIO, 0x20);
2695	urtw_write8_m(sc, URTW_GP_ENABLE, 0);
2696
2697	urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, 0x80);
2698	urtw_write16_m(sc, URTW_RF_PINS_SELECT, 0x80);
2699	urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x80);
2700
2701	usb_pause_mtx(&sc->sc_mtx, 500);
2702fail:
2703	return (error);
2704}
2705
2706static usb_error_t
2707urtw_8225_write_c(struct urtw_softc *sc, uint8_t addr, uint16_t data)
2708{
2709	uint16_t d80, d82, d84;
2710	usb_error_t error;
2711
2712	urtw_read16_m(sc, URTW_RF_PINS_OUTPUT, &d80);
2713	d80 &= URTW_RF_PINS_MAGIC1;
2714	urtw_read16_m(sc, URTW_RF_PINS_ENABLE, &d82);
2715	urtw_read16_m(sc, URTW_RF_PINS_SELECT, &d84);
2716	d84 &= URTW_RF_PINS_MAGIC2;
2717	urtw_write16_m(sc, URTW_RF_PINS_ENABLE, d82 | URTW_RF_PINS_MAGIC3);
2718	urtw_write16_m(sc, URTW_RF_PINS_SELECT, d84 | URTW_RF_PINS_MAGIC3);
2719	DELAY(10);
2720
2721	urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80 | URTW_BB_HOST_BANG_EN);
2722	DELAY(2);
2723	urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80);
2724	DELAY(10);
2725
2726	error = urtw_8225_write_s16(sc, addr, 0x8225, &data);
2727	if (error != 0)
2728		goto fail;
2729
2730	urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80 | URTW_BB_HOST_BANG_EN);
2731	DELAY(10);
2732	urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80 | URTW_BB_HOST_BANG_EN);
2733	urtw_write16_m(sc, URTW_RF_PINS_SELECT, d84);
2734	usb_pause_mtx(&sc->sc_mtx, 2);
2735fail:
2736	return (error);
2737}
2738
2739static usb_error_t
2740urtw_8225_write_s16(struct urtw_softc *sc, uint8_t addr, int index,
2741    uint16_t *data)
2742{
2743	uint8_t buf[2];
2744	uint16_t data16;
2745	struct usb_device_request req;
2746	usb_error_t error = 0;
2747
2748	data16 = *data;
2749
2750	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
2751	req.bRequest = URTW_8187_SETREGS_REQ;
2752	USETW(req.wValue, addr);
2753	USETW(req.wIndex, index);
2754	USETW(req.wLength, sizeof(uint16_t));
2755	buf[0] = (data16 & 0x00ff);
2756	buf[1] = (data16 & 0xff00) >> 8;
2757
2758	error = urtw_do_request(sc, &req, buf);
2759
2760	return (error);
2761}
2762
2763static usb_error_t
2764urtw_8225_rf_set_chan(struct urtw_softc *sc, int chan)
2765{
2766	usb_error_t error;
2767
2768	error = urtw_8225_set_txpwrlvl(sc, chan);
2769	if (error)
2770		goto fail;
2771	urtw_8225_write(sc, URTW_8225_ADDR_7_MAGIC, urtw_8225_channel[chan]);
2772	usb_pause_mtx(&sc->sc_mtx, 10);
2773fail:
2774	return (error);
2775}
2776
2777static usb_error_t
2778urtw_8225_rf_set_sens(struct urtw_softc *sc, int sens)
2779{
2780	usb_error_t error;
2781
2782	if (sens < 0 || sens > 6)
2783		return -1;
2784
2785	if (sens > 4)
2786		urtw_8225_write(sc,
2787		    URTW_8225_ADDR_C_MAGIC, URTW_8225_ADDR_C_DATA_MAGIC1);
2788	else
2789		urtw_8225_write(sc,
2790		    URTW_8225_ADDR_C_MAGIC, URTW_8225_ADDR_C_DATA_MAGIC2);
2791
2792	sens = 6 - sens;
2793	error = urtw_8225_setgain(sc, sens);
2794	if (error)
2795		goto fail;
2796
2797	urtw_8187_write_phy_cck(sc, 0x41, urtw_8225_threshold[sens]);
2798
2799fail:
2800	return (error);
2801}
2802
2803static usb_error_t
2804urtw_8225_set_txpwrlvl(struct urtw_softc *sc, int chan)
2805{
2806	int i, idx, set;
2807	uint8_t *cck_pwltable;
2808	uint8_t cck_pwrlvl_max, ofdm_pwrlvl_min, ofdm_pwrlvl_max;
2809	uint8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
2810	uint8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
2811	usb_error_t error;
2812
2813	cck_pwrlvl_max = 11;
2814	ofdm_pwrlvl_max = 25;	/* 12 -> 25  */
2815	ofdm_pwrlvl_min = 10;
2816
2817	/* CCK power setting */
2818	cck_pwrlvl = (cck_pwrlvl > cck_pwrlvl_max) ? cck_pwrlvl_max : cck_pwrlvl;
2819	idx = cck_pwrlvl % 6;
2820	set = cck_pwrlvl / 6;
2821	cck_pwltable = (chan == 14) ? urtw_8225_txpwr_cck_ch14 :
2822	    urtw_8225_txpwr_cck;
2823
2824	urtw_write8_m(sc, URTW_TX_GAIN_CCK,
2825	    urtw_8225_tx_gain_cck_ofdm[set] >> 1);
2826	for (i = 0; i < 8; i++) {
2827		urtw_8187_write_phy_cck(sc, 0x44 + i,
2828		    cck_pwltable[idx * 8 + i]);
2829	}
2830	usb_pause_mtx(&sc->sc_mtx, 1);
2831
2832	/* OFDM power setting */
2833	ofdm_pwrlvl = (ofdm_pwrlvl > (ofdm_pwrlvl_max - ofdm_pwrlvl_min)) ?
2834	    ofdm_pwrlvl_max : ofdm_pwrlvl + ofdm_pwrlvl_min;
2835	ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
2836
2837	idx = ofdm_pwrlvl % 6;
2838	set = ofdm_pwrlvl / 6;
2839
2840	error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
2841	if (error)
2842		goto fail;
2843	urtw_8187_write_phy_ofdm(sc, 2, 0x42);
2844	urtw_8187_write_phy_ofdm(sc, 6, 0);
2845	urtw_8187_write_phy_ofdm(sc, 8, 0);
2846
2847	urtw_write8_m(sc, URTW_TX_GAIN_OFDM,
2848	    urtw_8225_tx_gain_cck_ofdm[set] >> 1);
2849	urtw_8187_write_phy_ofdm(sc, 0x5, urtw_8225_txpwr_ofdm[idx]);
2850	urtw_8187_write_phy_ofdm(sc, 0x7, urtw_8225_txpwr_ofdm[idx]);
2851	usb_pause_mtx(&sc->sc_mtx, 1);
2852fail:
2853	return (error);
2854}
2855
2856
2857static usb_error_t
2858urtw_8225_rf_stop(struct urtw_softc *sc)
2859{
2860	uint8_t data;
2861	usb_error_t error;
2862
2863	urtw_8225_write(sc, 0x4, 0x1f);
2864
2865	error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
2866	if (error)
2867		goto fail;
2868
2869	urtw_read8_m(sc, URTW_CONFIG3, &data);
2870	urtw_write8_m(sc, URTW_CONFIG3, data | URTW_CONFIG3_ANAPARAM_WRITE);
2871	if (sc->sc_flags & URTW_RTL8187B) {
2872		urtw_write32_m(sc, URTW_ANAPARAM2,
2873		    URTW_8187B_8225_ANAPARAM2_OFF);
2874		urtw_write32_m(sc, URTW_ANAPARAM, URTW_8187B_8225_ANAPARAM_OFF);
2875		urtw_write32_m(sc, URTW_ANAPARAM3,
2876		    URTW_8187B_8225_ANAPARAM3_OFF);
2877	} else {
2878		urtw_write32_m(sc, URTW_ANAPARAM2, URTW_8225_ANAPARAM2_OFF);
2879		urtw_write32_m(sc, URTW_ANAPARAM, URTW_8225_ANAPARAM_OFF);
2880	}
2881
2882	urtw_write8_m(sc, URTW_CONFIG3, data & ~URTW_CONFIG3_ANAPARAM_WRITE);
2883	error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
2884	if (error)
2885		goto fail;
2886
2887fail:
2888	return (error);
2889}
2890
2891static usb_error_t
2892urtw_8225v2_rf_init(struct urtw_softc *sc)
2893{
2894#define N(a)	((int)(sizeof(a) / sizeof((a)[0])))
2895	int i;
2896	uint16_t data;
2897	uint32_t data32;
2898	usb_error_t error;
2899
2900	error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
2901	if (error)
2902		goto fail;
2903
2904	error = urtw_8225_usb_init(sc);
2905	if (error)
2906		goto fail;
2907
2908	urtw_write32_m(sc, URTW_RF_TIMING, 0x000a8008);
2909	urtw_read16_m(sc, URTW_BRSR, &data);		/* XXX ??? */
2910	urtw_write16_m(sc, URTW_BRSR, 0xffff);
2911	urtw_write32_m(sc, URTW_RF_PARA, 0x100044);
2912
2913	error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
2914	if (error)
2915		goto fail;
2916	urtw_write8_m(sc, URTW_CONFIG3, 0x44);
2917	error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
2918	if (error)
2919		goto fail;
2920
2921	error = urtw_8185_rf_pins_enable(sc);
2922	if (error)
2923		goto fail;
2924
2925	usb_pause_mtx(&sc->sc_mtx, 500);
2926
2927	for (i = 0; i < N(urtw_8225v2_rf_part1); i++) {
2928		urtw_8225_write(sc, urtw_8225v2_rf_part1[i].reg,
2929		    urtw_8225v2_rf_part1[i].val);
2930	}
2931	usb_pause_mtx(&sc->sc_mtx, 50);
2932
2933	urtw_8225_write(sc,
2934	    URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC1);
2935
2936	for (i = 0; i < 95; i++) {
2937		urtw_8225_write(sc, URTW_8225_ADDR_1_MAGIC, (uint8_t)(i + 1));
2938		urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC,
2939		    urtw_8225v2_rxgain[i]);
2940	}
2941
2942	urtw_8225_write(sc,
2943	    URTW_8225_ADDR_3_MAGIC, URTW_8225_ADDR_3_DATA_MAGIC1);
2944	urtw_8225_write(sc,
2945	    URTW_8225_ADDR_5_MAGIC, URTW_8225_ADDR_5_DATA_MAGIC1);
2946	urtw_8225_write(sc,
2947	    URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC2);
2948	urtw_8225_write(sc,
2949	    URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC1);
2950	usb_pause_mtx(&sc->sc_mtx, 100);
2951	urtw_8225_write(sc,
2952	    URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC2);
2953	usb_pause_mtx(&sc->sc_mtx, 100);
2954
2955	error = urtw_8225_read(sc, URTW_8225_ADDR_6_MAGIC, &data32);
2956	if (error != 0)
2957		goto fail;
2958	if (data32 != URTW_8225_ADDR_6_DATA_MAGIC1)
2959		device_printf(sc->sc_dev, "expect 0xe6!! (0x%x)\n", data32);
2960	if (!(data32 & URTW_8225_ADDR_6_DATA_MAGIC2)) {
2961		urtw_8225_write(sc,
2962		    URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC1);
2963		usb_pause_mtx(&sc->sc_mtx, 100);
2964		urtw_8225_write(sc,
2965		    URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC2);
2966		usb_pause_mtx(&sc->sc_mtx, 50);
2967		error = urtw_8225_read(sc, URTW_8225_ADDR_6_MAGIC, &data32);
2968		if (error != 0)
2969			goto fail;
2970		if (!(data32 & URTW_8225_ADDR_6_DATA_MAGIC2))
2971			device_printf(sc->sc_dev, "RF calibration failed\n");
2972	}
2973	usb_pause_mtx(&sc->sc_mtx, 100);
2974
2975	urtw_8225_write(sc,
2976	    URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC6);
2977	for (i = 0; i < 128; i++) {
2978		urtw_8187_write_phy_ofdm(sc, 0xb, urtw_8225_agc[i]);
2979		urtw_8187_write_phy_ofdm(sc, 0xa, (uint8_t)i + 0x80);
2980	}
2981
2982	for (i = 0; i < N(urtw_8225v2_rf_part2); i++) {
2983		urtw_8187_write_phy_ofdm(sc, urtw_8225v2_rf_part2[i].reg,
2984		    urtw_8225v2_rf_part2[i].val);
2985	}
2986
2987	error = urtw_8225v2_setgain(sc, 4);
2988	if (error)
2989		goto fail;
2990
2991	for (i = 0; i < N(urtw_8225v2_rf_part3); i++) {
2992		urtw_8187_write_phy_cck(sc, urtw_8225v2_rf_part3[i].reg,
2993		    urtw_8225v2_rf_part3[i].val);
2994	}
2995
2996	urtw_write8_m(sc, URTW_TESTR, 0x0d);
2997
2998	error = urtw_8225v2_set_txpwrlvl(sc, 1);
2999	if (error)
3000		goto fail;
3001
3002	urtw_8187_write_phy_cck(sc, 0x10, 0x9b);
3003	urtw_8187_write_phy_ofdm(sc, 0x26, 0x90);
3004
3005	/* TX ant A, 0x0 for B */
3006	error = urtw_8185_tx_antenna(sc, 0x3);
3007	if (error)
3008		goto fail;
3009	urtw_write32_m(sc, URTW_HSSI_PARA, 0x3dc00002);
3010
3011	error = urtw_8225_rf_set_chan(sc, 1);
3012fail:
3013	return (error);
3014#undef N
3015}
3016
3017static usb_error_t
3018urtw_8225v2_rf_set_chan(struct urtw_softc *sc, int chan)
3019{
3020	usb_error_t error;
3021
3022	error = urtw_8225v2_set_txpwrlvl(sc, chan);
3023	if (error)
3024		goto fail;
3025
3026	urtw_8225_write(sc, URTW_8225_ADDR_7_MAGIC, urtw_8225_channel[chan]);
3027	usb_pause_mtx(&sc->sc_mtx, 10);
3028fail:
3029	return (error);
3030}
3031
3032static usb_error_t
3033urtw_8225_read(struct urtw_softc *sc, uint8_t addr, uint32_t *data)
3034{
3035	int i;
3036	int16_t bit;
3037	uint8_t rlen = 12, wlen = 6;
3038	uint16_t o1, o2, o3, tmp;
3039	uint32_t d2w = ((uint32_t)(addr & 0x1f)) << 27;
3040	uint32_t mask = 0x80000000, value = 0;
3041	usb_error_t error;
3042
3043	urtw_read16_m(sc, URTW_RF_PINS_OUTPUT, &o1);
3044	urtw_read16_m(sc, URTW_RF_PINS_ENABLE, &o2);
3045	urtw_read16_m(sc, URTW_RF_PINS_SELECT, &o3);
3046	urtw_write16_m(sc, URTW_RF_PINS_ENABLE, o2 | URTW_RF_PINS_MAGIC4);
3047	urtw_write16_m(sc, URTW_RF_PINS_SELECT, o3 | URTW_RF_PINS_MAGIC4);
3048	o1 &= ~URTW_RF_PINS_MAGIC4;
3049	urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1 | URTW_BB_HOST_BANG_EN);
3050	DELAY(5);
3051	urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1);
3052	DELAY(5);
3053
3054	for (i = 0; i < (wlen / 2); i++, mask = mask >> 1) {
3055		bit = ((d2w & mask) != 0) ? 1 : 0;
3056
3057		urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1);
3058		DELAY(2);
3059		urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
3060		    URTW_BB_HOST_BANG_CLK);
3061		DELAY(2);
3062		urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
3063		    URTW_BB_HOST_BANG_CLK);
3064		DELAY(2);
3065		mask = mask >> 1;
3066		if (i == 2)
3067			break;
3068		bit = ((d2w & mask) != 0) ? 1 : 0;
3069		urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
3070		    URTW_BB_HOST_BANG_CLK);
3071		DELAY(2);
3072		urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
3073		    URTW_BB_HOST_BANG_CLK);
3074		DELAY(2);
3075		urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1);
3076		DELAY(1);
3077	}
3078	urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 | URTW_BB_HOST_BANG_RW |
3079	    URTW_BB_HOST_BANG_CLK);
3080	DELAY(2);
3081	urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 | URTW_BB_HOST_BANG_RW);
3082	DELAY(2);
3083	urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1 | URTW_BB_HOST_BANG_RW);
3084	DELAY(2);
3085
3086	mask = 0x800;
3087	for (i = 0; i < rlen; i++, mask = mask >> 1) {
3088		urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
3089		    o1 | URTW_BB_HOST_BANG_RW);
3090		DELAY(2);
3091		urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
3092		    o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK);
3093		DELAY(2);
3094		urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
3095		    o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK);
3096		DELAY(2);
3097		urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
3098		    o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK);
3099		DELAY(2);
3100
3101		urtw_read16_m(sc, URTW_RF_PINS_INPUT, &tmp);
3102		value |= ((tmp & URTW_BB_HOST_BANG_CLK) ? mask : 0);
3103		urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
3104		    o1 | URTW_BB_HOST_BANG_RW);
3105		DELAY(2);
3106	}
3107
3108	urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1 | URTW_BB_HOST_BANG_EN |
3109	    URTW_BB_HOST_BANG_RW);
3110	DELAY(2);
3111
3112	urtw_write16_m(sc, URTW_RF_PINS_ENABLE, o2);
3113	urtw_write16_m(sc, URTW_RF_PINS_SELECT, o3);
3114	urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, URTW_RF_PINS_OUTPUT_MAGIC1);
3115
3116	if (data != NULL)
3117		*data = value;
3118fail:
3119	return (error);
3120}
3121
3122
3123static usb_error_t
3124urtw_8225v2_set_txpwrlvl(struct urtw_softc *sc, int chan)
3125{
3126	int i;
3127	uint8_t *cck_pwrtable;
3128	uint8_t cck_pwrlvl_max = 15, ofdm_pwrlvl_max = 25, ofdm_pwrlvl_min = 10;
3129	uint8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
3130	uint8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
3131	usb_error_t error;
3132
3133	/* CCK power setting */
3134	cck_pwrlvl = (cck_pwrlvl > cck_pwrlvl_max) ? cck_pwrlvl_max : cck_pwrlvl;
3135	cck_pwrlvl += sc->sc_txpwr_cck_base;
3136	cck_pwrlvl = (cck_pwrlvl > 35) ? 35 : cck_pwrlvl;
3137	cck_pwrtable = (chan == 14) ? urtw_8225v2_txpwr_cck_ch14 :
3138	    urtw_8225v2_txpwr_cck;
3139
3140	for (i = 0; i < 8; i++)
3141		urtw_8187_write_phy_cck(sc, 0x44 + i, cck_pwrtable[i]);
3142
3143	urtw_write8_m(sc, URTW_TX_GAIN_CCK,
3144	    urtw_8225v2_tx_gain_cck_ofdm[cck_pwrlvl]);
3145	usb_pause_mtx(&sc->sc_mtx, 1);
3146
3147	/* OFDM power setting */
3148	ofdm_pwrlvl = (ofdm_pwrlvl > (ofdm_pwrlvl_max - ofdm_pwrlvl_min)) ?
3149		ofdm_pwrlvl_max : ofdm_pwrlvl + ofdm_pwrlvl_min;
3150	ofdm_pwrlvl += sc->sc_txpwr_ofdm_base;
3151	ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
3152
3153	error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
3154	if (error)
3155		goto fail;
3156
3157	urtw_8187_write_phy_ofdm(sc, 2, 0x42);
3158	urtw_8187_write_phy_ofdm(sc, 5, 0x0);
3159	urtw_8187_write_phy_ofdm(sc, 6, 0x40);
3160	urtw_8187_write_phy_ofdm(sc, 7, 0x0);
3161	urtw_8187_write_phy_ofdm(sc, 8, 0x40);
3162
3163	urtw_write8_m(sc, URTW_TX_GAIN_OFDM,
3164	    urtw_8225v2_tx_gain_cck_ofdm[ofdm_pwrlvl]);
3165	usb_pause_mtx(&sc->sc_mtx, 1);
3166fail:
3167	return (error);
3168}
3169
3170static usb_error_t
3171urtw_8225v2_setgain(struct urtw_softc *sc, int16_t gain)
3172{
3173	uint8_t *gainp;
3174	usb_error_t error;
3175
3176	/* XXX for A?  */
3177	gainp = urtw_8225v2_gain_bg;
3178	urtw_8187_write_phy_ofdm(sc, 0x0d, gainp[gain * 3]);
3179	usb_pause_mtx(&sc->sc_mtx, 1);
3180	urtw_8187_write_phy_ofdm(sc, 0x1b, gainp[gain * 3 + 1]);
3181	usb_pause_mtx(&sc->sc_mtx, 1);
3182	urtw_8187_write_phy_ofdm(sc, 0x1d, gainp[gain * 3 + 2]);
3183	usb_pause_mtx(&sc->sc_mtx, 1);
3184	urtw_8187_write_phy_ofdm(sc, 0x21, 0x17);
3185	usb_pause_mtx(&sc->sc_mtx, 1);
3186fail:
3187	return (error);
3188}
3189
3190static usb_error_t
3191urtw_8225_isv2(struct urtw_softc *sc, int *ret)
3192{
3193	uint32_t data;
3194	usb_error_t error;
3195
3196	*ret = 1;
3197
3198	urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, URTW_RF_PINS_MAGIC5);
3199	urtw_write16_m(sc, URTW_RF_PINS_SELECT, URTW_RF_PINS_MAGIC5);
3200	urtw_write16_m(sc, URTW_RF_PINS_ENABLE, URTW_RF_PINS_MAGIC5);
3201	usb_pause_mtx(&sc->sc_mtx, 500);
3202
3203	urtw_8225_write(sc, URTW_8225_ADDR_0_MAGIC,
3204	    URTW_8225_ADDR_0_DATA_MAGIC1);
3205
3206	error = urtw_8225_read(sc, URTW_8225_ADDR_8_MAGIC, &data);
3207	if (error != 0)
3208		goto fail;
3209	if (data != URTW_8225_ADDR_8_DATA_MAGIC1)
3210		*ret = 0;
3211	else {
3212		error = urtw_8225_read(sc, URTW_8225_ADDR_9_MAGIC, &data);
3213		if (error != 0)
3214			goto fail;
3215		if (data != URTW_8225_ADDR_9_DATA_MAGIC1)
3216			*ret = 0;
3217	}
3218
3219	urtw_8225_write(sc, URTW_8225_ADDR_0_MAGIC,
3220	    URTW_8225_ADDR_0_DATA_MAGIC2);
3221fail:
3222	return (error);
3223}
3224
3225static usb_error_t
3226urtw_8225v2b_rf_init(struct urtw_softc *sc)
3227{
3228#define N(a)	((int)(sizeof(a) / sizeof((a)[0])))
3229	int i;
3230	uint8_t data8;
3231	usb_error_t error;
3232
3233	error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3234	if (error)
3235		goto fail;
3236
3237	/*
3238	 * initialize extra registers on 8187
3239	 */
3240	urtw_write16_m(sc, URTW_BRSR_8187B, 0xfff);
3241
3242	/* retry limit */
3243	urtw_read8_m(sc, URTW_CW_CONF, &data8);
3244	data8 |= URTW_CW_CONF_PERPACKET_RETRY;
3245	urtw_write8_m(sc, URTW_CW_CONF, data8);
3246
3247	/* TX AGC */
3248	urtw_read8_m(sc, URTW_TX_AGC_CTL, &data8);
3249	data8 |= URTW_TX_AGC_CTL_PERPACKET_GAIN;
3250	urtw_write8_m(sc, URTW_TX_AGC_CTL, data8);
3251
3252	/* Auto Rate Fallback Control */
3253#define	URTW_ARFR	0x1e0
3254	urtw_write16_m(sc, URTW_ARFR, 0xfff);
3255	urtw_read8_m(sc, URTW_RATE_FALLBACK, &data8);
3256	urtw_write8_m(sc, URTW_RATE_FALLBACK,
3257	    data8 | URTW_RATE_FALLBACK_ENABLE);
3258
3259	urtw_read8_m(sc, URTW_MSR, &data8);
3260	urtw_write8_m(sc, URTW_MSR, data8 & 0xf3);
3261	urtw_read8_m(sc, URTW_MSR, &data8);
3262	urtw_write8_m(sc, URTW_MSR, data8 | URTW_MSR_LINK_ENEDCA);
3263	urtw_write8_m(sc, URTW_ACM_CONTROL, sc->sc_acmctl);
3264
3265	urtw_write16_m(sc, URTW_ATIM_WND, 2);
3266	urtw_write16_m(sc, URTW_BEACON_INTERVAL, 100);
3267#define	URTW_FEMR_FOR_8187B	0x1d4
3268	urtw_write16_m(sc, URTW_FEMR_FOR_8187B, 0xffff);
3269
3270	/* led type */
3271	urtw_read8_m(sc, URTW_CONFIG1, &data8);
3272	data8 = (data8 & 0x3f) | 0x80;
3273	urtw_write8_m(sc, URTW_CONFIG1, data8);
3274
3275	/* applying MAC address again.  */
3276	urtw_write32_m(sc, URTW_MAC0, ((uint32_t *)sc->sc_bssid)[0]);
3277	urtw_write16_m(sc, URTW_MAC4, ((uint32_t *)sc->sc_bssid)[1] & 0xffff);
3278
3279	error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3280	if (error)
3281		goto fail;
3282
3283	urtw_write8_m(sc, URTW_WPA_CONFIG, 0);
3284
3285	/*
3286	 * MAC configuration
3287	 */
3288	for (i = 0; i < N(urtw_8225v2b_rf_part1); i++)
3289		urtw_write8_m(sc, urtw_8225v2b_rf_part1[i].reg,
3290		    urtw_8225v2b_rf_part1[i].val);
3291	urtw_write16_m(sc, URTW_TID_AC_MAP, 0xfa50);
3292	urtw_write16_m(sc, URTW_INT_MIG, 0x0000);
3293	urtw_write32_m(sc, 0x1f0, 0);
3294	urtw_write32_m(sc, 0x1f4, 0);
3295	urtw_write8_m(sc, 0x1f8, 0);
3296	urtw_write32_m(sc, URTW_RF_TIMING, 0x4001);
3297
3298#define	URTW_RFSW_CTRL	0x272
3299	urtw_write16_m(sc, URTW_RFSW_CTRL, 0x569a);
3300
3301	/*
3302	 * initialize PHY
3303	 */
3304	error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3305	if (error)
3306		goto fail;
3307	urtw_read8_m(sc, URTW_CONFIG3, &data8);
3308	urtw_write8_m(sc, URTW_CONFIG3,
3309	    data8 | URTW_CONFIG3_ANAPARAM_WRITE);
3310
3311	error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3312	if (error)
3313		goto fail;
3314
3315	/* setup RFE initial timing */
3316	urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, 0x0480);
3317	urtw_write16_m(sc, URTW_RF_PINS_SELECT, 0x2488);
3318	urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x1fff);
3319	usb_pause_mtx(&sc->sc_mtx, 1100);
3320
3321	for (i = 0; i < N(urtw_8225v2b_rf_part0); i++) {
3322		urtw_8225_write(sc, urtw_8225v2b_rf_part0[i].reg,
3323		    urtw_8225v2b_rf_part0[i].val);
3324		usb_pause_mtx(&sc->sc_mtx, 1);
3325	}
3326	urtw_8225_write(sc, 0x00, 0x01b7);
3327
3328	for (i = 0; i < 95; i++) {
3329		urtw_8225_write(sc, URTW_8225_ADDR_1_MAGIC, (uint8_t)(i + 1));
3330		usb_pause_mtx(&sc->sc_mtx, 1);
3331		urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC,
3332		    urtw_8225v2b_rxgain[i]);
3333		usb_pause_mtx(&sc->sc_mtx, 1);
3334	}
3335
3336	urtw_8225_write(sc, URTW_8225_ADDR_3_MAGIC, 0x080);
3337	usb_pause_mtx(&sc->sc_mtx, 1);
3338	urtw_8225_write(sc, URTW_8225_ADDR_5_MAGIC, 0x004);
3339	usb_pause_mtx(&sc->sc_mtx, 1);
3340	urtw_8225_write(sc, URTW_8225_ADDR_0_MAGIC, 0x0b7);
3341	usb_pause_mtx(&sc->sc_mtx, 1);
3342	usb_pause_mtx(&sc->sc_mtx, 3000);
3343	urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC, 0xc4d);
3344	usb_pause_mtx(&sc->sc_mtx, 2000);
3345	urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC, 0x44d);
3346	usb_pause_mtx(&sc->sc_mtx, 1);
3347	urtw_8225_write(sc, URTW_8225_ADDR_0_MAGIC, 0x2bf);
3348	usb_pause_mtx(&sc->sc_mtx, 1);
3349
3350	urtw_write8_m(sc, URTW_TX_GAIN_CCK, 0x03);
3351	urtw_write8_m(sc, URTW_TX_GAIN_OFDM, 0x07);
3352	urtw_write8_m(sc, URTW_TX_ANTENNA, 0x03);
3353
3354	urtw_8187_write_phy_ofdm(sc, 0x80, 0x12);
3355	for (i = 0; i < 128; i++) {
3356		uint32_t addr, data;
3357
3358		data = (urtw_8225z2_agc[i] << 8) | 0x0000008f;
3359		addr = ((i + 0x80) << 8) | 0x0000008e;
3360
3361		urtw_8187_write_phy_ofdm(sc, data & 0x7f, (data >> 8) & 0xff);
3362		urtw_8187_write_phy_ofdm(sc, addr & 0x7f, (addr >> 8) & 0xff);
3363		urtw_8187_write_phy_ofdm(sc, 0x0e, 0x00);
3364	}
3365	urtw_8187_write_phy_ofdm(sc, 0x80, 0x10);
3366
3367	for (i = 0; i < N(urtw_8225v2b_rf_part2); i++)
3368		urtw_8187_write_phy_ofdm(sc, i, urtw_8225v2b_rf_part2[i].val);
3369
3370	urtw_write32_m(sc, URTW_8187B_AC_VO, (7 << 12) | (3 << 8) | 0x1c);
3371	urtw_write32_m(sc, URTW_8187B_AC_VI, (7 << 12) | (3 << 8) | 0x1c);
3372	urtw_write32_m(sc, URTW_8187B_AC_BE, (7 << 12) | (3 << 8) | 0x1c);
3373	urtw_write32_m(sc, URTW_8187B_AC_BK, (7 << 12) | (3 << 8) | 0x1c);
3374
3375	urtw_8187_write_phy_ofdm(sc, 0x97, 0x46);
3376	urtw_8187_write_phy_ofdm(sc, 0xa4, 0xb6);
3377	urtw_8187_write_phy_ofdm(sc, 0x85, 0xfc);
3378	urtw_8187_write_phy_cck(sc, 0xc1, 0x88);
3379
3380fail:
3381	return (error);
3382#undef N
3383}
3384
3385static usb_error_t
3386urtw_8225v2b_rf_set_chan(struct urtw_softc *sc, int chan)
3387{
3388	usb_error_t error;
3389
3390	error = urtw_8225v2b_set_txpwrlvl(sc, chan);
3391	if (error)
3392		goto fail;
3393
3394	urtw_8225_write(sc, URTW_8225_ADDR_7_MAGIC, urtw_8225_channel[chan]);
3395	usb_pause_mtx(&sc->sc_mtx, 10);
3396fail:
3397	return (error);
3398}
3399
3400static usb_error_t
3401urtw_8225v2b_set_txpwrlvl(struct urtw_softc *sc, int chan)
3402{
3403	int i;
3404	uint8_t *cck_pwrtable;
3405	uint8_t cck_pwrlvl_max = 15;
3406	uint8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
3407	uint8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
3408	usb_error_t error;
3409
3410	/* CCK power setting */
3411	cck_pwrlvl = (cck_pwrlvl > cck_pwrlvl_max) ?
3412	    ((sc->sc_flags & URTW_RTL8187B_REV_B) ? cck_pwrlvl_max : 22) :
3413	    (cck_pwrlvl + ((sc->sc_flags & URTW_RTL8187B_REV_B) ? 0 : 7));
3414	cck_pwrlvl += sc->sc_txpwr_cck_base;
3415	cck_pwrlvl = (cck_pwrlvl > 35) ? 35 : cck_pwrlvl;
3416	cck_pwrtable = (chan == 14) ? urtw_8225v2b_txpwr_cck_ch14 :
3417	    urtw_8225v2b_txpwr_cck;
3418
3419	if (sc->sc_flags & URTW_RTL8187B_REV_B)
3420		cck_pwrtable += (cck_pwrlvl <= 6) ? 0 :
3421		    ((cck_pwrlvl <= 11) ? 8 : 16);
3422	else
3423		cck_pwrtable += (cck_pwrlvl <= 5) ? 0 :
3424		    ((cck_pwrlvl <= 11) ? 8 : ((cck_pwrlvl <= 17) ? 16 : 24));
3425
3426	for (i = 0; i < 8; i++)
3427		urtw_8187_write_phy_cck(sc, 0x44 + i, cck_pwrtable[i]);
3428
3429	urtw_write8_m(sc, URTW_TX_GAIN_CCK,
3430	    urtw_8225v2_tx_gain_cck_ofdm[cck_pwrlvl] << 1);
3431	usb_pause_mtx(&sc->sc_mtx, 1);
3432
3433	/* OFDM power setting */
3434	ofdm_pwrlvl = (ofdm_pwrlvl > 15) ?
3435	    ((sc->sc_flags & URTW_RTL8187B_REV_B) ? 17 : 25) :
3436	    (ofdm_pwrlvl + ((sc->sc_flags & URTW_RTL8187B_REV_B) ? 2 : 10));
3437	ofdm_pwrlvl += sc->sc_txpwr_ofdm_base;
3438	ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
3439
3440	urtw_write8_m(sc, URTW_TX_GAIN_OFDM,
3441	    urtw_8225v2_tx_gain_cck_ofdm[ofdm_pwrlvl] << 1);
3442
3443	if (sc->sc_flags & URTW_RTL8187B_REV_B) {
3444		if (ofdm_pwrlvl <= 11) {
3445			urtw_8187_write_phy_ofdm(sc, 0x87, 0x60);
3446			urtw_8187_write_phy_ofdm(sc, 0x89, 0x60);
3447		} else {
3448			urtw_8187_write_phy_ofdm(sc, 0x87, 0x5c);
3449			urtw_8187_write_phy_ofdm(sc, 0x89, 0x5c);
3450		}
3451	} else {
3452		if (ofdm_pwrlvl <= 11) {
3453			urtw_8187_write_phy_ofdm(sc, 0x87, 0x5c);
3454			urtw_8187_write_phy_ofdm(sc, 0x89, 0x5c);
3455		} else if (ofdm_pwrlvl <= 17) {
3456			urtw_8187_write_phy_ofdm(sc, 0x87, 0x54);
3457			urtw_8187_write_phy_ofdm(sc, 0x89, 0x54);
3458		} else {
3459			urtw_8187_write_phy_ofdm(sc, 0x87, 0x50);
3460			urtw_8187_write_phy_ofdm(sc, 0x89, 0x50);
3461		}
3462	}
3463	usb_pause_mtx(&sc->sc_mtx, 1);
3464fail:
3465	return (error);
3466}
3467
3468static usb_error_t
3469urtw_read8e(struct urtw_softc *sc, int val, uint8_t *data)
3470{
3471	struct usb_device_request req;
3472	usb_error_t error;
3473
3474	req.bmRequestType = UT_READ_VENDOR_DEVICE;
3475	req.bRequest = URTW_8187_GETREGS_REQ;
3476	USETW(req.wValue, val | 0xfe00);
3477	USETW(req.wIndex, 0);
3478	USETW(req.wLength, sizeof(uint8_t));
3479
3480	error = urtw_do_request(sc, &req, data);
3481	return (error);
3482}
3483
3484static usb_error_t
3485urtw_write8e(struct urtw_softc *sc, int val, uint8_t data)
3486{
3487	struct usb_device_request req;
3488
3489	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
3490	req.bRequest = URTW_8187_SETREGS_REQ;
3491	USETW(req.wValue, val | 0xfe00);
3492	USETW(req.wIndex, 0);
3493	USETW(req.wLength, sizeof(uint8_t));
3494
3495	return (urtw_do_request(sc, &req, &data));
3496}
3497
3498static usb_error_t
3499urtw_8180_set_anaparam(struct urtw_softc *sc, uint32_t val)
3500{
3501	uint8_t data;
3502	usb_error_t error;
3503
3504	error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3505	if (error)
3506		goto fail;
3507
3508	urtw_read8_m(sc, URTW_CONFIG3, &data);
3509	urtw_write8_m(sc, URTW_CONFIG3, data | URTW_CONFIG3_ANAPARAM_WRITE);
3510	urtw_write32_m(sc, URTW_ANAPARAM, val);
3511	urtw_read8_m(sc, URTW_CONFIG3, &data);
3512	urtw_write8_m(sc, URTW_CONFIG3, data & ~URTW_CONFIG3_ANAPARAM_WRITE);
3513
3514	error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3515	if (error)
3516		goto fail;
3517fail:
3518	return (error);
3519}
3520
3521static usb_error_t
3522urtw_8185_set_anaparam2(struct urtw_softc *sc, uint32_t val)
3523{
3524	uint8_t data;
3525	usb_error_t error;
3526
3527	error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3528	if (error)
3529		goto fail;
3530
3531	urtw_read8_m(sc, URTW_CONFIG3, &data);
3532	urtw_write8_m(sc, URTW_CONFIG3, data | URTW_CONFIG3_ANAPARAM_WRITE);
3533	urtw_write32_m(sc, URTW_ANAPARAM2, val);
3534	urtw_read8_m(sc, URTW_CONFIG3, &data);
3535	urtw_write8_m(sc, URTW_CONFIG3, data & ~URTW_CONFIG3_ANAPARAM_WRITE);
3536
3537	error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3538	if (error)
3539		goto fail;
3540fail:
3541	return (error);
3542}
3543
3544static usb_error_t
3545urtw_intr_enable(struct urtw_softc *sc)
3546{
3547	usb_error_t error;
3548
3549	urtw_write16_m(sc, URTW_INTR_MASK, 0xffff);
3550fail:
3551	return (error);
3552}
3553
3554static usb_error_t
3555urtw_intr_disable(struct urtw_softc *sc)
3556{
3557	usb_error_t error;
3558
3559	urtw_write16_m(sc, URTW_INTR_MASK, 0);
3560fail:
3561	return (error);
3562}
3563
3564static usb_error_t
3565urtw_reset(struct urtw_softc *sc)
3566{
3567	uint8_t data;
3568	usb_error_t error;
3569
3570	error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
3571	if (error)
3572		goto fail;
3573	error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
3574	if (error)
3575		goto fail;
3576
3577	error = urtw_intr_disable(sc);
3578	if (error)
3579		goto fail;
3580	usb_pause_mtx(&sc->sc_mtx, 100);
3581
3582	error = urtw_write8e(sc, 0x18, 0x10);
3583	if (error != 0)
3584		goto fail;
3585	error = urtw_write8e(sc, 0x18, 0x11);
3586	if (error != 0)
3587		goto fail;
3588	error = urtw_write8e(sc, 0x18, 0x00);
3589	if (error != 0)
3590		goto fail;
3591	usb_pause_mtx(&sc->sc_mtx, 100);
3592
3593	urtw_read8_m(sc, URTW_CMD, &data);
3594	data = (data & 0x2) | URTW_CMD_RST;
3595	urtw_write8_m(sc, URTW_CMD, data);
3596	usb_pause_mtx(&sc->sc_mtx, 100);
3597
3598	urtw_read8_m(sc, URTW_CMD, &data);
3599	if (data & URTW_CMD_RST) {
3600		device_printf(sc->sc_dev, "reset timeout\n");
3601		goto fail;
3602	}
3603
3604	error = urtw_set_mode(sc, URTW_EPROM_CMD_LOAD);
3605	if (error)
3606		goto fail;
3607	usb_pause_mtx(&sc->sc_mtx, 100);
3608
3609	error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
3610	if (error)
3611		goto fail;
3612	error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
3613	if (error)
3614		goto fail;
3615fail:
3616	return (error);
3617}
3618
3619static usb_error_t
3620urtw_led_ctl(struct urtw_softc *sc, int mode)
3621{
3622	usb_error_t error = 0;
3623
3624	switch (sc->sc_strategy) {
3625	case URTW_SW_LED_MODE0:
3626		error = urtw_led_mode0(sc, mode);
3627		break;
3628	case URTW_SW_LED_MODE1:
3629		error = urtw_led_mode1(sc, mode);
3630		break;
3631	case URTW_SW_LED_MODE2:
3632		error = urtw_led_mode2(sc, mode);
3633		break;
3634	case URTW_SW_LED_MODE3:
3635		error = urtw_led_mode3(sc, mode);
3636		break;
3637	default:
3638		DPRINTF(sc, URTW_DEBUG_STATE,
3639		    "unsupported LED mode %d\n", sc->sc_strategy);
3640		error = USB_ERR_INVAL;
3641		break;
3642	}
3643
3644	return (error);
3645}
3646
3647static usb_error_t
3648urtw_led_mode0(struct urtw_softc *sc, int mode)
3649{
3650
3651	switch (mode) {
3652	case URTW_LED_CTL_POWER_ON:
3653		sc->sc_gpio_ledstate = URTW_LED_POWER_ON_BLINK;
3654		break;
3655	case URTW_LED_CTL_TX:
3656		if (sc->sc_gpio_ledinprogress == 1)
3657			return (0);
3658
3659		sc->sc_gpio_ledstate = URTW_LED_BLINK_NORMAL;
3660		sc->sc_gpio_blinktime = 2;
3661		break;
3662	case URTW_LED_CTL_LINK:
3663		sc->sc_gpio_ledstate = URTW_LED_ON;
3664		break;
3665	default:
3666		DPRINTF(sc, URTW_DEBUG_STATE,
3667		    "unsupported LED mode 0x%x", mode);
3668		return (USB_ERR_INVAL);
3669	}
3670
3671	switch (sc->sc_gpio_ledstate) {
3672	case URTW_LED_ON:
3673		if (sc->sc_gpio_ledinprogress != 0)
3674			break;
3675		urtw_led_on(sc, URTW_LED_GPIO);
3676		break;
3677	case URTW_LED_BLINK_NORMAL:
3678		if (sc->sc_gpio_ledinprogress != 0)
3679			break;
3680		sc->sc_gpio_ledinprogress = 1;
3681		sc->sc_gpio_blinkstate = (sc->sc_gpio_ledon != 0) ?
3682			URTW_LED_OFF : URTW_LED_ON;
3683		usb_callout_reset(&sc->sc_led_ch, hz, urtw_led_ch, sc);
3684		break;
3685	case URTW_LED_POWER_ON_BLINK:
3686		urtw_led_on(sc, URTW_LED_GPIO);
3687		usb_pause_mtx(&sc->sc_mtx, 100);
3688		urtw_led_off(sc, URTW_LED_GPIO);
3689		break;
3690	default:
3691		DPRINTF(sc, URTW_DEBUG_STATE,
3692		    "unknown LED status 0x%x", sc->sc_gpio_ledstate);
3693		return (USB_ERR_INVAL);
3694	}
3695	return (0);
3696}
3697
3698static usb_error_t
3699urtw_led_mode1(struct urtw_softc *sc, int mode)
3700{
3701	return (USB_ERR_INVAL);
3702}
3703
3704static usb_error_t
3705urtw_led_mode2(struct urtw_softc *sc, int mode)
3706{
3707	return (USB_ERR_INVAL);
3708}
3709
3710static usb_error_t
3711urtw_led_mode3(struct urtw_softc *sc, int mode)
3712{
3713	return (USB_ERR_INVAL);
3714}
3715
3716static usb_error_t
3717urtw_led_on(struct urtw_softc *sc, int type)
3718{
3719	usb_error_t error;
3720
3721	if (type == URTW_LED_GPIO) {
3722		switch (sc->sc_gpio_ledpin) {
3723		case URTW_LED_PIN_GPIO0:
3724			urtw_write8_m(sc, URTW_GPIO, 0x01);
3725			urtw_write8_m(sc, URTW_GP_ENABLE, 0x00);
3726			break;
3727		default:
3728			DPRINTF(sc, URTW_DEBUG_STATE,
3729			    "unsupported LED PIN type 0x%x",
3730			    sc->sc_gpio_ledpin);
3731			error = USB_ERR_INVAL;
3732			goto fail;
3733		}
3734	} else {
3735		DPRINTF(sc, URTW_DEBUG_STATE,
3736		    "unsupported LED type 0x%x", type);
3737		error = USB_ERR_INVAL;
3738		goto fail;
3739	}
3740
3741	sc->sc_gpio_ledon = 1;
3742fail:
3743	return (error);
3744}
3745
3746static usb_error_t
3747urtw_led_off(struct urtw_softc *sc, int type)
3748{
3749	usb_error_t error;
3750
3751	if (type == URTW_LED_GPIO) {
3752		switch (sc->sc_gpio_ledpin) {
3753		case URTW_LED_PIN_GPIO0:
3754			urtw_write8_m(sc, URTW_GPIO, URTW_GPIO_DATA_MAGIC1);
3755			urtw_write8_m(sc,
3756			    URTW_GP_ENABLE, URTW_GP_ENABLE_DATA_MAGIC1);
3757			break;
3758		default:
3759			DPRINTF(sc, URTW_DEBUG_STATE,
3760			    "unsupported LED PIN type 0x%x",
3761			    sc->sc_gpio_ledpin);
3762			error = USB_ERR_INVAL;
3763			goto fail;
3764		}
3765	} else {
3766		DPRINTF(sc, URTW_DEBUG_STATE,
3767		    "unsupported LED type 0x%x", type);
3768		error = USB_ERR_INVAL;
3769		goto fail;
3770	}
3771
3772	sc->sc_gpio_ledon = 0;
3773
3774fail:
3775	return (error);
3776}
3777
3778static void
3779urtw_led_ch(void *arg)
3780{
3781	struct urtw_softc *sc = arg;
3782	struct ifnet *ifp = sc->sc_ifp;
3783	struct ieee80211com *ic = ifp->if_l2com;
3784
3785	ieee80211_runtask(ic, &sc->sc_led_task);
3786}
3787
3788static void
3789urtw_ledtask(void *arg, int pending)
3790{
3791	struct urtw_softc *sc = arg;
3792
3793	if (sc->sc_strategy != URTW_SW_LED_MODE0) {
3794		DPRINTF(sc, URTW_DEBUG_STATE,
3795		    "could not process a LED strategy 0x%x",
3796		    sc->sc_strategy);
3797		return;
3798	}
3799
3800	URTW_LOCK(sc);
3801	urtw_led_blink(sc);
3802	URTW_UNLOCK(sc);
3803}
3804
3805static usb_error_t
3806urtw_led_blink(struct urtw_softc *sc)
3807{
3808	uint8_t ing = 0;
3809	usb_error_t error;
3810
3811	if (sc->sc_gpio_blinkstate == URTW_LED_ON)
3812		error = urtw_led_on(sc, URTW_LED_GPIO);
3813	else
3814		error = urtw_led_off(sc, URTW_LED_GPIO);
3815	sc->sc_gpio_blinktime--;
3816	if (sc->sc_gpio_blinktime == 0)
3817		ing = 1;
3818	else {
3819		if (sc->sc_gpio_ledstate != URTW_LED_BLINK_NORMAL &&
3820		    sc->sc_gpio_ledstate != URTW_LED_BLINK_SLOWLY &&
3821		    sc->sc_gpio_ledstate != URTW_LED_BLINK_CM3)
3822			ing = 1;
3823	}
3824	if (ing == 1) {
3825		if (sc->sc_gpio_ledstate == URTW_LED_ON &&
3826		    sc->sc_gpio_ledon == 0)
3827			error = urtw_led_on(sc, URTW_LED_GPIO);
3828		else if (sc->sc_gpio_ledstate == URTW_LED_OFF &&
3829		    sc->sc_gpio_ledon == 1)
3830			error = urtw_led_off(sc, URTW_LED_GPIO);
3831
3832		sc->sc_gpio_blinktime = 0;
3833		sc->sc_gpio_ledinprogress = 0;
3834		return (0);
3835	}
3836
3837	sc->sc_gpio_blinkstate = (sc->sc_gpio_blinkstate != URTW_LED_ON) ?
3838	    URTW_LED_ON : URTW_LED_OFF;
3839
3840	switch (sc->sc_gpio_ledstate) {
3841	case URTW_LED_BLINK_NORMAL:
3842		usb_callout_reset(&sc->sc_led_ch, hz, urtw_led_ch, sc);
3843		break;
3844	default:
3845		DPRINTF(sc, URTW_DEBUG_STATE,
3846		    "unknown LED status 0x%x",
3847		    sc->sc_gpio_ledstate);
3848		return (USB_ERR_INVAL);
3849	}
3850	return (0);
3851}
3852
3853static usb_error_t
3854urtw_rx_enable(struct urtw_softc *sc)
3855{
3856	uint8_t data;
3857	usb_error_t error;
3858
3859	usbd_transfer_start((sc->sc_flags & URTW_RTL8187B) ?
3860	    sc->sc_xfer[URTW_8187B_BULK_RX] : sc->sc_xfer[URTW_8187L_BULK_RX]);
3861
3862	error = urtw_rx_setconf(sc);
3863	if (error != 0)
3864		goto fail;
3865
3866	if ((sc->sc_flags & URTW_RTL8187B) == 0) {
3867		urtw_read8_m(sc, URTW_CMD, &data);
3868		urtw_write8_m(sc, URTW_CMD, data | URTW_CMD_RX_ENABLE);
3869	}
3870fail:
3871	return (error);
3872}
3873
3874static usb_error_t
3875urtw_tx_enable(struct urtw_softc *sc)
3876{
3877	uint8_t data8;
3878	uint32_t data;
3879	usb_error_t error;
3880
3881	if (sc->sc_flags & URTW_RTL8187B) {
3882		urtw_read32_m(sc, URTW_TX_CONF, &data);
3883		data &= ~URTW_TX_LOOPBACK_MASK;
3884		data &= ~(URTW_TX_DPRETRY_MASK | URTW_TX_RTSRETRY_MASK);
3885		data &= ~(URTW_TX_NOCRC | URTW_TX_MXDMA_MASK);
3886		data &= ~URTW_TX_SWPLCPLEN;
3887		data |= URTW_TX_HW_SEQNUM | URTW_TX_DISREQQSIZE |
3888		    (7 << 8) |	/* short retry limit */
3889		    (7 << 0) |	/* long retry limit */
3890		    (7 << 21);	/* MAX TX DMA */
3891		urtw_write32_m(sc, URTW_TX_CONF, data);
3892
3893		urtw_read8_m(sc, URTW_MSR, &data8);
3894		data8 |= URTW_MSR_LINK_ENEDCA;
3895		urtw_write8_m(sc, URTW_MSR, data8);
3896		return (error);
3897	}
3898
3899	urtw_read8_m(sc, URTW_CW_CONF, &data8);
3900	data8 &= ~(URTW_CW_CONF_PERPACKET_CW | URTW_CW_CONF_PERPACKET_RETRY);
3901	urtw_write8_m(sc, URTW_CW_CONF, data8);
3902
3903	urtw_read8_m(sc, URTW_TX_AGC_CTL, &data8);
3904	data8 &= ~URTW_TX_AGC_CTL_PERPACKET_GAIN;
3905	data8 &= ~URTW_TX_AGC_CTL_PERPACKET_ANTSEL;
3906	data8 &= ~URTW_TX_AGC_CTL_FEEDBACK_ANT;
3907	urtw_write8_m(sc, URTW_TX_AGC_CTL, data8);
3908
3909	urtw_read32_m(sc, URTW_TX_CONF, &data);
3910	data &= ~URTW_TX_LOOPBACK_MASK;
3911	data |= URTW_TX_LOOPBACK_NONE;
3912	data &= ~(URTW_TX_DPRETRY_MASK | URTW_TX_RTSRETRY_MASK);
3913	data |= sc->sc_tx_retry << URTW_TX_DPRETRY_SHIFT;
3914	data |= sc->sc_rts_retry << URTW_TX_RTSRETRY_SHIFT;
3915	data &= ~(URTW_TX_NOCRC | URTW_TX_MXDMA_MASK);
3916	data |= URTW_TX_MXDMA_2048 | URTW_TX_CWMIN | URTW_TX_DISCW;
3917	data &= ~URTW_TX_SWPLCPLEN;
3918	data |= URTW_TX_NOICV;
3919	urtw_write32_m(sc, URTW_TX_CONF, data);
3920
3921	urtw_read8_m(sc, URTW_CMD, &data8);
3922	urtw_write8_m(sc, URTW_CMD, data8 | URTW_CMD_TX_ENABLE);
3923fail:
3924	return (error);
3925}
3926
3927static usb_error_t
3928urtw_rx_setconf(struct urtw_softc *sc)
3929{
3930	struct ifnet *ifp = sc->sc_ifp;
3931	struct ieee80211com *ic = ifp->if_l2com;
3932	uint32_t data;
3933	usb_error_t error;
3934
3935	urtw_read32_m(sc, URTW_RX, &data);
3936	data = data &~ URTW_RX_FILTER_MASK;
3937	if (sc->sc_flags & URTW_RTL8187B) {
3938		data = data | URTW_RX_FILTER_MNG | URTW_RX_FILTER_DATA |
3939		    URTW_RX_FILTER_MCAST | URTW_RX_FILTER_BCAST |
3940		    URTW_RX_FILTER_NICMAC | URTW_RX_CHECK_BSSID |
3941		    URTW_RX_FIFO_THRESHOLD_NONE |
3942		    URTW_MAX_RX_DMA_2048 |
3943		    URTW_RX_AUTORESETPHY | URTW_RCR_ONLYERLPKT;
3944	} else {
3945		data = data | URTW_RX_FILTER_MNG | URTW_RX_FILTER_DATA;
3946		data = data | URTW_RX_FILTER_BCAST | URTW_RX_FILTER_MCAST;
3947
3948		if (ic->ic_opmode == IEEE80211_M_MONITOR) {
3949			data = data | URTW_RX_FILTER_ICVERR;
3950			data = data | URTW_RX_FILTER_PWR;
3951		}
3952		if (sc->sc_crcmon == 1 && ic->ic_opmode == IEEE80211_M_MONITOR)
3953			data = data | URTW_RX_FILTER_CRCERR;
3954
3955		if (ic->ic_opmode == IEEE80211_M_MONITOR ||
3956		    (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC))) {
3957			data = data | URTW_RX_FILTER_ALLMAC;
3958		} else {
3959			data = data | URTW_RX_FILTER_NICMAC;
3960			data = data | URTW_RX_CHECK_BSSID;
3961		}
3962
3963		data = data &~ URTW_RX_FIFO_THRESHOLD_MASK;
3964		data = data | URTW_RX_FIFO_THRESHOLD_NONE |
3965		    URTW_RX_AUTORESETPHY;
3966		data = data &~ URTW_MAX_RX_DMA_MASK;
3967		data = data | URTW_MAX_RX_DMA_2048 | URTW_RCR_ONLYERLPKT;
3968	}
3969
3970	urtw_write32_m(sc, URTW_RX, data);
3971fail:
3972	return (error);
3973}
3974
3975static struct mbuf *
3976urtw_rxeof(struct usb_xfer *xfer, struct urtw_data *data, int *rssi_p,
3977    int8_t *nf_p)
3978{
3979	int actlen, flen, rssi;
3980	struct ieee80211_frame *wh;
3981	struct mbuf *m, *mnew;
3982	struct urtw_softc *sc = data->sc;
3983	struct ifnet *ifp = sc->sc_ifp;
3984	struct ieee80211com *ic = ifp->if_l2com;
3985	uint8_t noise = 0, rate;
3986
3987	usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
3988
3989	if (actlen < (int)URTW_MIN_RXBUFSZ) {
3990		ifp->if_ierrors++;
3991		return (NULL);
3992	}
3993
3994	if (sc->sc_flags & URTW_RTL8187B) {
3995		struct urtw_8187b_rxhdr *rx;
3996
3997		rx = (struct urtw_8187b_rxhdr *)(data->buf +
3998		    (actlen - (sizeof(struct urtw_8187b_rxhdr))));
3999		flen = le32toh(rx->flag) & 0xfff;
4000		if (flen > actlen) {
4001			ifp->if_ierrors++;
4002			return (NULL);
4003		}
4004		rate = (le32toh(rx->flag) >> URTW_RX_FLAG_RXRATE_SHIFT) & 0xf;
4005		/* XXX correct? */
4006		rssi = rx->rssi & URTW_RX_RSSI_MASK;
4007		noise = rx->noise;
4008	} else {
4009		struct urtw_8187l_rxhdr *rx;
4010
4011		rx = (struct urtw_8187l_rxhdr *)(data->buf +
4012		    (actlen - (sizeof(struct urtw_8187l_rxhdr))));
4013		flen = le32toh(rx->flag) & 0xfff;
4014		if (flen > actlen) {
4015			ifp->if_ierrors++;
4016			return (NULL);
4017		}
4018
4019		rate = (le32toh(rx->flag) >> URTW_RX_FLAG_RXRATE_SHIFT) & 0xf;
4020		/* XXX correct? */
4021		rssi = rx->rssi & URTW_RX_8187L_RSSI_MASK;
4022		noise = rx->noise;
4023	}
4024
4025	mnew = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
4026	if (mnew == NULL) {
4027		ifp->if_ierrors++;
4028		return (NULL);
4029	}
4030
4031	m = data->m;
4032	data->m = mnew;
4033	data->buf = mtod(mnew, uint8_t *);
4034
4035	/* finalize mbuf */
4036	m->m_pkthdr.rcvif = ifp;
4037	m->m_pkthdr.len = m->m_len = flen - IEEE80211_CRC_LEN;
4038
4039	if (ieee80211_radiotap_active(ic)) {
4040		struct urtw_rx_radiotap_header *tap = &sc->sc_rxtap;
4041
4042		/* XXX Are variables correct?  */
4043		tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
4044		tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
4045		tap->wr_dbm_antsignal = (int8_t)rssi;
4046	}
4047
4048	wh = mtod(m, struct ieee80211_frame *);
4049	if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_DATA)
4050		sc->sc_currate = (rate > 0) ? rate : sc->sc_currate;
4051
4052	*rssi_p = rssi;
4053	*nf_p = noise;		/* XXX correct? */
4054
4055	return (m);
4056}
4057
4058static void
4059urtw_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
4060{
4061	struct urtw_softc *sc = usbd_xfer_softc(xfer);
4062	struct ifnet *ifp = sc->sc_ifp;
4063	struct ieee80211com *ic = ifp->if_l2com;
4064	struct ieee80211_frame *wh;
4065	struct ieee80211_node *ni;
4066	struct mbuf *m = NULL;
4067	struct urtw_data *data;
4068	int8_t nf = -95;
4069	int rssi = 1;
4070
4071	URTW_ASSERT_LOCKED(sc);
4072
4073	switch (USB_GET_STATE(xfer)) {
4074	case USB_ST_TRANSFERRED:
4075		data = STAILQ_FIRST(&sc->sc_rx_active);
4076		if (data == NULL)
4077			goto setup;
4078		STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next);
4079		m = urtw_rxeof(xfer, data, &rssi, &nf);
4080		STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next);
4081		/* FALLTHROUGH */
4082	case USB_ST_SETUP:
4083setup:
4084		data = STAILQ_FIRST(&sc->sc_rx_inactive);
4085		if (data == NULL) {
4086			KASSERT(m == NULL, ("mbuf isn't NULL"));
4087			return;
4088		}
4089		STAILQ_REMOVE_HEAD(&sc->sc_rx_inactive, next);
4090		STAILQ_INSERT_TAIL(&sc->sc_rx_active, data, next);
4091		usbd_xfer_set_frame_data(xfer, 0, data->buf,
4092		    usbd_xfer_max_len(xfer));
4093		usbd_transfer_submit(xfer);
4094
4095		/*
4096		 * To avoid LOR we should unlock our private mutex here to call
4097		 * ieee80211_input() because here is at the end of a USB
4098		 * callback and safe to unlock.
4099		 */
4100		URTW_UNLOCK(sc);
4101		if (m != NULL) {
4102			wh = mtod(m, struct ieee80211_frame *);
4103			ni = ieee80211_find_rxnode(ic,
4104			    (struct ieee80211_frame_min *)wh);
4105			if (ni != NULL) {
4106				(void) ieee80211_input(ni, m, rssi, nf);
4107				/* node is no longer needed */
4108				ieee80211_free_node(ni);
4109			} else
4110				(void) ieee80211_input_all(ic, m, rssi, nf);
4111			m = NULL;
4112		}
4113		URTW_LOCK(sc);
4114		break;
4115	default:
4116		/* needs it to the inactive queue due to a error.  */
4117		data = STAILQ_FIRST(&sc->sc_rx_active);
4118		if (data != NULL) {
4119			STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next);
4120			STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next);
4121		}
4122		if (error != USB_ERR_CANCELLED) {
4123			usbd_xfer_set_stall(xfer);
4124			ifp->if_ierrors++;
4125			goto setup;
4126		}
4127		break;
4128	}
4129}
4130
4131#define	URTW_STATUS_TYPE_TXCLOSE	1
4132#define	URTW_STATUS_TYPE_BEACON_INTR	0
4133
4134static void
4135urtw_txstatus_eof(struct usb_xfer *xfer)
4136{
4137	struct urtw_softc *sc = usbd_xfer_softc(xfer);
4138	struct ifnet *ifp = sc->sc_ifp;
4139	int actlen, type, pktretry, seq;
4140	uint64_t val;
4141
4142	usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
4143
4144	if (actlen != sizeof(uint64_t))
4145		return;
4146
4147	val = le64toh(sc->sc_txstatus);
4148	type = (val >> 30) & 0x3;
4149	if (type == URTW_STATUS_TYPE_TXCLOSE) {
4150		pktretry = val & 0xff;
4151		seq = (val >> 16) & 0xff;
4152		if (pktretry == URTW_TX_MAXRETRY)
4153			ifp->if_oerrors++;
4154		DPRINTF(sc, URTW_DEBUG_TXSTATUS, "pktretry %d seq %#x\n",
4155		    pktretry, seq);
4156	}
4157}
4158
4159static void
4160urtw_bulk_tx_status_callback(struct usb_xfer *xfer, usb_error_t error)
4161{
4162	struct urtw_softc *sc = usbd_xfer_softc(xfer);
4163	struct ifnet *ifp = sc->sc_ifp;
4164	void *dma_buf = usbd_xfer_get_frame_buffer(xfer, 0);
4165
4166	URTW_ASSERT_LOCKED(sc);
4167
4168	switch (USB_GET_STATE(xfer)) {
4169	case USB_ST_TRANSFERRED:
4170		urtw_txstatus_eof(xfer);
4171		/* FALLTHROUGH */
4172	case USB_ST_SETUP:
4173setup:
4174		memcpy(dma_buf, &sc->sc_txstatus, sizeof(uint64_t));
4175		usbd_xfer_set_frame_len(xfer, 0, sizeof(uint64_t));
4176		usbd_transfer_submit(xfer);
4177		break;
4178	default:
4179		if (error != USB_ERR_CANCELLED) {
4180			usbd_xfer_set_stall(xfer);
4181			ifp->if_ierrors++;
4182			goto setup;
4183		}
4184		break;
4185	}
4186}
4187
4188static void
4189urtw_txeof(struct usb_xfer *xfer, struct urtw_data *data)
4190{
4191	struct urtw_softc *sc = usbd_xfer_softc(xfer);
4192	struct ifnet *ifp = sc->sc_ifp;
4193	struct mbuf *m;
4194
4195	URTW_ASSERT_LOCKED(sc);
4196
4197	/*
4198	 * Do any tx complete callback.  Note this must be done before releasing
4199	 * the node reference.
4200	 */
4201	if (data->m) {
4202		m = data->m;
4203		if (m->m_flags & M_TXCB) {
4204			/* XXX status? */
4205			ieee80211_process_callback(data->ni, m, 0);
4206		}
4207		m_freem(m);
4208		data->m = NULL;
4209	}
4210	if (data->ni) {
4211		ieee80211_free_node(data->ni);
4212		data->ni = NULL;
4213	}
4214	sc->sc_txtimer = 0;
4215	ifp->if_opackets++;
4216	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
4217}
4218
4219static void
4220urtw_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error)
4221{
4222	struct urtw_softc *sc = usbd_xfer_softc(xfer);
4223	struct ifnet *ifp = sc->sc_ifp;
4224	struct urtw_data *data;
4225
4226	URTW_ASSERT_LOCKED(sc);
4227
4228	switch (USB_GET_STATE(xfer)) {
4229	case USB_ST_TRANSFERRED:
4230		data = STAILQ_FIRST(&sc->sc_tx_active);
4231		if (data == NULL)
4232			goto setup;
4233		STAILQ_REMOVE_HEAD(&sc->sc_tx_active, next);
4234		urtw_txeof(xfer, data);
4235		STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data, next);
4236		/* FALLTHROUGH */
4237	case USB_ST_SETUP:
4238setup:
4239		data = STAILQ_FIRST(&sc->sc_tx_pending);
4240		if (data == NULL) {
4241			DPRINTF(sc, URTW_DEBUG_XMIT,
4242			    "%s: empty pending queue\n", __func__);
4243			return;
4244		}
4245		STAILQ_REMOVE_HEAD(&sc->sc_tx_pending, next);
4246		STAILQ_INSERT_TAIL(&sc->sc_tx_active, data, next);
4247
4248		usbd_xfer_set_frame_data(xfer, 0, data->buf, data->buflen);
4249		usbd_transfer_submit(xfer);
4250
4251		URTW_UNLOCK(sc);
4252		urtw_start(ifp);
4253		URTW_LOCK(sc);
4254		break;
4255	default:
4256		data = STAILQ_FIRST(&sc->sc_tx_active);
4257		if (data == NULL)
4258			goto setup;
4259		if (data->ni != NULL) {
4260			ieee80211_free_node(data->ni);
4261			data->ni = NULL;
4262			ifp->if_oerrors++;
4263		}
4264		if (error != USB_ERR_CANCELLED) {
4265			usbd_xfer_set_stall(xfer);
4266			goto setup;
4267		}
4268		break;
4269	}
4270}
4271
4272static struct urtw_data *
4273_urtw_getbuf(struct urtw_softc *sc)
4274{
4275	struct urtw_data *bf;
4276
4277	bf = STAILQ_FIRST(&sc->sc_tx_inactive);
4278	if (bf != NULL)
4279		STAILQ_REMOVE_HEAD(&sc->sc_tx_inactive, next);
4280	else
4281		bf = NULL;
4282	if (bf == NULL)
4283		DPRINTF(sc, URTW_DEBUG_XMIT, "%s: %s\n", __func__,
4284		    "out of xmit buffers");
4285	return (bf);
4286}
4287
4288static struct urtw_data *
4289urtw_getbuf(struct urtw_softc *sc)
4290{
4291	struct urtw_data *bf;
4292
4293	URTW_ASSERT_LOCKED(sc);
4294
4295	bf = _urtw_getbuf(sc);
4296	if (bf == NULL) {
4297		struct ifnet *ifp = sc->sc_ifp;
4298
4299		DPRINTF(sc, URTW_DEBUG_XMIT, "%s: stop queue\n", __func__);
4300		ifp->if_drv_flags |= IFF_DRV_OACTIVE;
4301	}
4302	return (bf);
4303}
4304
4305static int
4306urtw_isbmode(uint16_t rate)
4307{
4308
4309	return ((rate <= 22 && rate != 12 && rate != 18) ||
4310	    rate == 44) ? (1) : (0);
4311}
4312
4313static uint16_t
4314urtw_rate2dbps(uint16_t rate)
4315{
4316
4317	switch(rate) {
4318	case 12:
4319	case 18:
4320	case 24:
4321	case 36:
4322	case 48:
4323	case 72:
4324	case 96:
4325	case 108:
4326		return (rate * 2);
4327	default:
4328		break;
4329	}
4330	return (24);
4331}
4332
4333static int
4334urtw_compute_txtime(uint16_t framelen, uint16_t rate,
4335    uint8_t ismgt, uint8_t isshort)
4336{
4337	uint16_t     ceiling, frametime, n_dbps;
4338
4339	if (urtw_isbmode(rate)) {
4340		if (ismgt || !isshort || rate == 2)
4341			frametime = (uint16_t)(144 + 48 +
4342			    (framelen * 8 / (rate / 2)));
4343		else
4344			frametime = (uint16_t)(72 + 24 +
4345			    (framelen * 8 / (rate / 2)));
4346		if ((framelen * 8 % (rate / 2)) != 0)
4347			frametime++;
4348	} else {
4349		n_dbps = urtw_rate2dbps(rate);
4350		ceiling = (16 + 8 * framelen + 6) / n_dbps
4351		    + (((16 + 8 * framelen + 6) % n_dbps) ? 1 : 0);
4352		frametime = (uint16_t)(16 + 4 + 4 * ceiling + 6);
4353	}
4354	return (frametime);
4355}
4356
4357/*
4358 * Callback from the 802.11 layer to update the
4359 * slot time based on the current setting.
4360 */
4361static void
4362urtw_updateslot(struct ifnet *ifp)
4363{
4364	struct urtw_softc *sc = ifp->if_softc;
4365	struct ieee80211com *ic = ifp->if_l2com;
4366
4367	ieee80211_runtask(ic, &sc->sc_updateslot_task);
4368}
4369
4370static void
4371urtw_updateslottask(void *arg, int pending)
4372{
4373	struct urtw_softc *sc = arg;
4374	struct ifnet *ifp = sc->sc_ifp;
4375	struct ieee80211com *ic = ifp->if_l2com;
4376	int error;
4377
4378	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
4379		return;
4380
4381	URTW_LOCK(sc);
4382	if (sc->sc_flags & URTW_RTL8187B) {
4383		urtw_write8_m(sc, URTW_SIFS, 0x22);
4384		if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan))
4385			urtw_write8_m(sc, URTW_SLOT, 0x9);
4386		else
4387			urtw_write8_m(sc, URTW_SLOT, 0x14);
4388		urtw_write8_m(sc, URTW_8187B_EIFS, 0x5b);
4389		urtw_write8_m(sc, URTW_CARRIER_SCOUNT, 0x5b);
4390	} else {
4391		urtw_write8_m(sc, URTW_SIFS, 0x22);
4392		if (sc->sc_state == IEEE80211_S_ASSOC &&
4393		    ic->ic_flags & IEEE80211_F_SHSLOT)
4394			urtw_write8_m(sc, URTW_SLOT, 0x9);
4395		else
4396			urtw_write8_m(sc, URTW_SLOT, 0x14);
4397		if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan)) {
4398			urtw_write8_m(sc, URTW_DIFS, 0x14);
4399			urtw_write8_m(sc, URTW_EIFS, 0x5b - 0x14);
4400			urtw_write8_m(sc, URTW_CW_VAL, 0x73);
4401		} else {
4402			urtw_write8_m(sc, URTW_DIFS, 0x24);
4403			urtw_write8_m(sc, URTW_EIFS, 0x5b - 0x24);
4404			urtw_write8_m(sc, URTW_CW_VAL, 0xa5);
4405		}
4406	}
4407fail:
4408	URTW_UNLOCK(sc);
4409}
4410
4411static void
4412urtw_sysctl_node(struct urtw_softc *sc)
4413{
4414#define	URTW_SYSCTL_STAT_ADD32(c, h, n, p, d)	\
4415	SYSCTL_ADD_UINT(c, h, OID_AUTO, n, CTLFLAG_RD, p, 0, d)
4416	struct sysctl_ctx_list *ctx;
4417	struct sysctl_oid_list *child, *parent;
4418	struct sysctl_oid *tree;
4419	struct urtw_stats *stats = &sc->sc_stats;
4420
4421	ctx = device_get_sysctl_ctx(sc->sc_dev);
4422	child = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->sc_dev));
4423
4424	tree = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "stats", CTLFLAG_RD,
4425	    NULL, "URTW statistics");
4426	parent = SYSCTL_CHILDREN(tree);
4427
4428	/* Tx statistics. */
4429	tree = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "tx", CTLFLAG_RD,
4430	    NULL, "Tx MAC statistics");
4431	child = SYSCTL_CHILDREN(tree);
4432	URTW_SYSCTL_STAT_ADD32(ctx, child, "1m", &stats->txrates[0],
4433	    "1 Mbit/s");
4434	URTW_SYSCTL_STAT_ADD32(ctx, child, "2m", &stats->txrates[1],
4435	    "2 Mbit/s");
4436	URTW_SYSCTL_STAT_ADD32(ctx, child, "5.5m", &stats->txrates[2],
4437	    "5.5 Mbit/s");
4438	URTW_SYSCTL_STAT_ADD32(ctx, child, "6m", &stats->txrates[4],
4439	    "6 Mbit/s");
4440	URTW_SYSCTL_STAT_ADD32(ctx, child, "9m", &stats->txrates[5],
4441	    "9 Mbit/s");
4442	URTW_SYSCTL_STAT_ADD32(ctx, child, "11m", &stats->txrates[3],
4443	    "11 Mbit/s");
4444	URTW_SYSCTL_STAT_ADD32(ctx, child, "12m", &stats->txrates[6],
4445	    "12 Mbit/s");
4446	URTW_SYSCTL_STAT_ADD32(ctx, child, "18m", &stats->txrates[7],
4447	    "18 Mbit/s");
4448	URTW_SYSCTL_STAT_ADD32(ctx, child, "24m", &stats->txrates[8],
4449	    "24 Mbit/s");
4450	URTW_SYSCTL_STAT_ADD32(ctx, child, "36m", &stats->txrates[9],
4451	    "36 Mbit/s");
4452	URTW_SYSCTL_STAT_ADD32(ctx, child, "48m", &stats->txrates[10],
4453	    "48 Mbit/s");
4454	URTW_SYSCTL_STAT_ADD32(ctx, child, "54m", &stats->txrates[11],
4455	    "54 Mbit/s");
4456#undef URTW_SYSCTL_STAT_ADD32
4457}
4458
4459static device_method_t urtw_methods[] = {
4460	DEVMETHOD(device_probe, urtw_match),
4461	DEVMETHOD(device_attach, urtw_attach),
4462	DEVMETHOD(device_detach, urtw_detach),
4463	DEVMETHOD_END
4464};
4465static driver_t urtw_driver = {
4466	.name = "urtw",
4467	.methods = urtw_methods,
4468	.size = sizeof(struct urtw_softc)
4469};
4470static devclass_t urtw_devclass;
4471
4472DRIVER_MODULE(urtw, uhub, urtw_driver, urtw_devclass, NULL, 0);
4473MODULE_DEPEND(urtw, wlan, 1, 1, 1);
4474MODULE_DEPEND(urtw, usb, 1, 1, 1);
4475MODULE_VERSION(urtw, 1);
4476