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