2 * Copyright (c) 2008 Weongyo Jeong <weongyo@FreeBSD.org>
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.
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.
17 #include <sys/cdefs.h>
18 __FBSDID("$FreeBSD$");
22 #include <sys/param.h>
23 #include <sys/sockio.h>
24 #include <sys/sysctl.h>
26 #include <sys/mutex.h>
28 #include <sys/kernel.h>
29 #include <sys/socket.h>
30 #include <sys/systm.h>
31 #include <sys/malloc.h>
32 #include <sys/module.h>
34 #include <sys/endian.h>
38 #include <net/if_var.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>
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>
53 #include <net80211/ieee80211_var.h>
54 #include <net80211/ieee80211_regdomain.h>
55 #include <net80211/ieee80211_radiotap.h>
57 #include <dev/usb/usb.h>
58 #include <dev/usb/usbdi.h>
61 #include <dev/usb/wlan/if_urtwreg.h>
62 #include <dev/usb/wlan/if_urtwvar.h>
64 /* copy some rate indices from if_rtwn_ridx.h */
65 #define URTW_RIDX_CCK5 2
66 #define URTW_RIDX_CCK11 3
67 #define URTW_RIDX_OFDM6 4
68 #define URTW_RIDX_OFDM24 8
70 static SYSCTL_NODE(_hw_usb, OID_AUTO, urtw, CTLFLAG_RW, 0, "USB Realtek 8187L");
73 SYSCTL_INT(_hw_usb_urtw, OID_AUTO, debug, CTLFLAG_RWTUN, &urtw_debug, 0,
74 "control debugging printfs");
76 URTW_DEBUG_XMIT = 0x00000001, /* basic xmit operation */
77 URTW_DEBUG_RECV = 0x00000002, /* basic recv operation */
78 URTW_DEBUG_RESET = 0x00000004, /* reset processing */
79 URTW_DEBUG_TX_PROC = 0x00000008, /* tx ISR proc */
80 URTW_DEBUG_RX_PROC = 0x00000010, /* rx ISR proc */
81 URTW_DEBUG_STATE = 0x00000020, /* 802.11 state transitions */
82 URTW_DEBUG_STAT = 0x00000040, /* statistic */
83 URTW_DEBUG_INIT = 0x00000080, /* initialization of dev */
84 URTW_DEBUG_TXSTATUS = 0x00000100, /* tx status */
85 URTW_DEBUG_ANY = 0xffffffff
87 #define DPRINTF(sc, m, fmt, ...) do { \
88 if (sc->sc_debug & (m)) \
89 printf(fmt, __VA_ARGS__); \
92 #define DPRINTF(sc, m, fmt, ...) do { \
96 static int urtw_preamble_mode = URTW_PREAMBLE_MODE_LONG;
97 SYSCTL_INT(_hw_usb_urtw, OID_AUTO, preamble_mode, CTLFLAG_RWTUN,
98 &urtw_preamble_mode, 0, "set the preable mode (long or short)");
100 /* recognized device vendors/products */
101 #define urtw_lookup(v, p) \
102 ((const struct urtw_type *)usb_lookup(urtw_devs, v, p))
103 #define URTW_DEV_B(v,p) \
104 { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, URTW_REV_RTL8187B) }
105 #define URTW_DEV_L(v,p) \
106 { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, URTW_REV_RTL8187L) }
107 #define URTW_REV_RTL8187B 0
108 #define URTW_REV_RTL8187L 1
109 static const STRUCT_USB_HOST_ID urtw_devs[] = {
110 URTW_DEV_B(NETGEAR, WG111V3),
111 URTW_DEV_B(REALTEK, RTL8187B_0),
112 URTW_DEV_B(REALTEK, RTL8187B_1),
113 URTW_DEV_B(REALTEK, RTL8187B_2),
114 URTW_DEV_B(SITECOMEU, WL168V4),
115 URTW_DEV_L(ASUS, P5B_WIFI),
116 URTW_DEV_L(BELKIN, F5D7050E),
117 URTW_DEV_L(LINKSYS4, WUSB54GCV2),
118 URTW_DEV_L(NETGEAR, WG111V2),
119 URTW_DEV_L(REALTEK, RTL8187),
120 URTW_DEV_L(SITECOMEU, WL168V1),
121 URTW_DEV_L(SURECOM, EP9001G2A),
122 { USB_VPI(USB_VENDOR_OVISLINK, 0x8187, URTW_REV_RTL8187L) },
123 { USB_VPI(USB_VENDOR_DICKSMITH, 0x9401, URTW_REV_RTL8187L) },
124 { USB_VPI(USB_VENDOR_HP, 0xca02, URTW_REV_RTL8187L) },
125 { USB_VPI(USB_VENDOR_LOGITEC, 0x010c, URTW_REV_RTL8187L) },
126 { USB_VPI(USB_VENDOR_NETGEAR, 0x6100, URTW_REV_RTL8187L) },
127 { USB_VPI(USB_VENDOR_SPHAIRON, 0x0150, URTW_REV_RTL8187L) },
128 { USB_VPI(USB_VENDOR_QCOM, 0x6232, URTW_REV_RTL8187L) },
133 #define urtw_read8_m(sc, val, data) do { \
134 error = urtw_read8_c(sc, val, data); \
138 #define urtw_write8_m(sc, val, data) do { \
139 error = urtw_write8_c(sc, val, data); \
143 #define urtw_read16_m(sc, val, data) do { \
144 error = urtw_read16_c(sc, val, data); \
148 #define urtw_write16_m(sc, val, data) do { \
149 error = urtw_write16_c(sc, val, data); \
153 #define urtw_read32_m(sc, val, data) do { \
154 error = urtw_read32_c(sc, val, data); \
158 #define urtw_write32_m(sc, val, data) do { \
159 error = urtw_write32_c(sc, val, data); \
163 #define urtw_8187_write_phy_ofdm(sc, val, data) do { \
164 error = urtw_8187_write_phy_ofdm_c(sc, val, data); \
168 #define urtw_8187_write_phy_cck(sc, val, data) do { \
169 error = urtw_8187_write_phy_cck_c(sc, val, data); \
173 #define urtw_8225_write(sc, val, data) do { \
174 error = urtw_8225_write_c(sc, val, data); \
184 static uint8_t urtw_8225_agc[] = {
185 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9d, 0x9c, 0x9b,
186 0x9a, 0x99, 0x98, 0x97, 0x96, 0x95, 0x94, 0x93, 0x92, 0x91, 0x90,
187 0x8f, 0x8e, 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86, 0x85,
188 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a,
189 0x39, 0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f,
190 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24,
191 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19,
192 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e,
193 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03,
194 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
195 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
196 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
199 static uint8_t urtw_8225z2_agc[] = {
200 0x5e, 0x5e, 0x5e, 0x5e, 0x5d, 0x5b, 0x59, 0x57, 0x55, 0x53, 0x51,
201 0x4f, 0x4d, 0x4b, 0x49, 0x47, 0x45, 0x43, 0x41, 0x3f, 0x3d, 0x3b,
202 0x39, 0x37, 0x35, 0x33, 0x31, 0x2f, 0x2d, 0x2b, 0x29, 0x27, 0x25,
203 0x23, 0x21, 0x1f, 0x1d, 0x1b, 0x19, 0x17, 0x15, 0x13, 0x11, 0x0f,
204 0x0d, 0x0b, 0x09, 0x07, 0x05, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01,
205 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x19, 0x19,
206 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x20, 0x21, 0x22, 0x23,
207 0x24, 0x25, 0x26, 0x26, 0x27, 0x27, 0x28, 0x28, 0x29, 0x2a, 0x2a,
208 0x2a, 0x2b, 0x2b, 0x2b, 0x2c, 0x2c, 0x2c, 0x2d, 0x2d, 0x2d, 0x2d,
209 0x2e, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x2f, 0x30, 0x30, 0x31, 0x31,
210 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
211 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31
214 static uint32_t urtw_8225_channel[] = {
215 0x0000, /* dummy channel 0 */
232 static uint8_t urtw_8225_gain[] = {
233 0x23, 0x88, 0x7c, 0xa5, /* -82dbm */
234 0x23, 0x88, 0x7c, 0xb5, /* -82dbm */
235 0x23, 0x88, 0x7c, 0xc5, /* -82dbm */
236 0x33, 0x80, 0x79, 0xc5, /* -78dbm */
237 0x43, 0x78, 0x76, 0xc5, /* -74dbm */
238 0x53, 0x60, 0x73, 0xc5, /* -70dbm */
239 0x63, 0x58, 0x70, 0xc5, /* -66dbm */
242 static struct urtw_pair urtw_8225_rf_part1[] = {
243 { 0x00, 0x0067 }, { 0x01, 0x0fe0 }, { 0x02, 0x044d }, { 0x03, 0x0441 },
244 { 0x04, 0x0486 }, { 0x05, 0x0bc0 }, { 0x06, 0x0ae6 }, { 0x07, 0x082a },
245 { 0x08, 0x001f }, { 0x09, 0x0334 }, { 0x0a, 0x0fd4 }, { 0x0b, 0x0391 },
246 { 0x0c, 0x0050 }, { 0x0d, 0x06db }, { 0x0e, 0x0029 }, { 0x0f, 0x0914 },
249 static struct urtw_pair urtw_8225_rf_part2[] = {
250 { 0x00, 0x01 }, { 0x01, 0x02 }, { 0x02, 0x42 }, { 0x03, 0x00 },
251 { 0x04, 0x00 }, { 0x05, 0x00 }, { 0x06, 0x40 }, { 0x07, 0x00 },
252 { 0x08, 0x40 }, { 0x09, 0xfe }, { 0x0a, 0x09 }, { 0x0b, 0x80 },
253 { 0x0c, 0x01 }, { 0x0e, 0xd3 }, { 0x0f, 0x38 }, { 0x10, 0x84 },
254 { 0x11, 0x06 }, { 0x12, 0x20 }, { 0x13, 0x20 }, { 0x14, 0x00 },
255 { 0x15, 0x40 }, { 0x16, 0x00 }, { 0x17, 0x40 }, { 0x18, 0xef },
256 { 0x19, 0x19 }, { 0x1a, 0x20 }, { 0x1b, 0x76 }, { 0x1c, 0x04 },
257 { 0x1e, 0x95 }, { 0x1f, 0x75 }, { 0x20, 0x1f }, { 0x21, 0x27 },
258 { 0x22, 0x16 }, { 0x24, 0x46 }, { 0x25, 0x20 }, { 0x26, 0x90 },
262 static struct urtw_pair urtw_8225_rf_part3[] = {
263 { 0x00, 0x98 }, { 0x03, 0x20 }, { 0x04, 0x7e }, { 0x05, 0x12 },
264 { 0x06, 0xfc }, { 0x07, 0x78 }, { 0x08, 0x2e }, { 0x10, 0x9b },
265 { 0x11, 0x88 }, { 0x12, 0x47 }, { 0x13, 0xd0 }, { 0x19, 0x00 },
266 { 0x1a, 0xa0 }, { 0x1b, 0x08 }, { 0x40, 0x86 }, { 0x41, 0x8d },
267 { 0x42, 0x15 }, { 0x43, 0x18 }, { 0x44, 0x1f }, { 0x45, 0x1e },
268 { 0x46, 0x1a }, { 0x47, 0x15 }, { 0x48, 0x10 }, { 0x49, 0x0a },
269 { 0x4a, 0x05 }, { 0x4b, 0x02 }, { 0x4c, 0x05 }
272 static uint16_t urtw_8225_rxgain[] = {
273 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
274 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
275 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
276 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
277 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
278 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
279 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
280 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
281 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
282 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
283 0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3,
284 0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb
287 static uint8_t urtw_8225_threshold[] = {
288 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd,
291 static uint8_t urtw_8225_tx_gain_cck_ofdm[] = {
292 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e
295 static uint8_t urtw_8225_txpwr_cck[] = {
296 0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02,
297 0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02,
298 0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02,
299 0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02,
300 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03,
301 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03
304 static uint8_t urtw_8225_txpwr_cck_ch14[] = {
305 0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00,
306 0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00,
307 0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00,
308 0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00,
309 0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00,
310 0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00
313 static uint8_t urtw_8225_txpwr_ofdm[]={
314 0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4
317 static uint8_t urtw_8225v2_gain_bg[]={
318 0x23, 0x15, 0xa5, /* -82-1dbm */
319 0x23, 0x15, 0xb5, /* -82-2dbm */
320 0x23, 0x15, 0xc5, /* -82-3dbm */
321 0x33, 0x15, 0xc5, /* -78dbm */
322 0x43, 0x15, 0xc5, /* -74dbm */
323 0x53, 0x15, 0xc5, /* -70dbm */
324 0x63, 0x15, 0xc5, /* -66dbm */
327 static struct urtw_pair urtw_8225v2_rf_part1[] = {
328 { 0x00, 0x02bf }, { 0x01, 0x0ee0 }, { 0x02, 0x044d }, { 0x03, 0x0441 },
329 { 0x04, 0x08c3 }, { 0x05, 0x0c72 }, { 0x06, 0x00e6 }, { 0x07, 0x082a },
330 { 0x08, 0x003f }, { 0x09, 0x0335 }, { 0x0a, 0x09d4 }, { 0x0b, 0x07bb },
331 { 0x0c, 0x0850 }, { 0x0d, 0x0cdf }, { 0x0e, 0x002b }, { 0x0f, 0x0114 }
334 static struct urtw_pair urtw_8225v2b_rf_part0[] = {
335 { 0x00, 0x00b7 }, { 0x01, 0x0ee0 }, { 0x02, 0x044d }, { 0x03, 0x0441 },
336 { 0x04, 0x08c3 }, { 0x05, 0x0c72 }, { 0x06, 0x00e6 }, { 0x07, 0x082a },
337 { 0x08, 0x003f }, { 0x09, 0x0335 }, { 0x0a, 0x09d4 }, { 0x0b, 0x07bb },
338 { 0x0c, 0x0850 }, { 0x0d, 0x0cdf }, { 0x0e, 0x002b }, { 0x0f, 0x0114 }
341 static struct urtw_pair urtw_8225v2b_rf_part1[] = {
342 {0x0f0, 0x32}, {0x0f1, 0x32}, {0x0f2, 0x00},
343 {0x0f3, 0x00}, {0x0f4, 0x32}, {0x0f5, 0x43},
344 {0x0f6, 0x00}, {0x0f7, 0x00}, {0x0f8, 0x46},
345 {0x0f9, 0xa4}, {0x0fa, 0x00}, {0x0fb, 0x00},
346 {0x0fc, 0x96}, {0x0fd, 0xa4}, {0x0fe, 0x00},
347 {0x0ff, 0x00}, {0x158, 0x4b}, {0x159, 0x00},
348 {0x15a, 0x4b}, {0x15b, 0x00}, {0x160, 0x4b},
349 {0x161, 0x09}, {0x162, 0x4b}, {0x163, 0x09},
350 {0x1ce, 0x0f}, {0x1cf, 0x00}, {0x1e0, 0xff},
351 {0x1e1, 0x0f}, {0x1e2, 0x00}, {0x1f0, 0x4e},
352 {0x1f1, 0x01}, {0x1f2, 0x02}, {0x1f3, 0x03},
353 {0x1f4, 0x04}, {0x1f5, 0x05}, {0x1f6, 0x06},
354 {0x1f7, 0x07}, {0x1f8, 0x08}, {0x24e, 0x00},
355 {0x20c, 0x04}, {0x221, 0x61}, {0x222, 0x68},
356 {0x223, 0x6f}, {0x224, 0x76}, {0x225, 0x7d},
357 {0x226, 0x84}, {0x227, 0x8d}, {0x24d, 0x08},
358 {0x250, 0x05}, {0x251, 0xf5}, {0x252, 0x04},
359 {0x253, 0xa0}, {0x254, 0x1f}, {0x255, 0x23},
360 {0x256, 0x45}, {0x257, 0x67}, {0x258, 0x08},
361 {0x259, 0x08}, {0x25a, 0x08}, {0x25b, 0x08},
362 {0x260, 0x08}, {0x261, 0x08}, {0x262, 0x08},
363 {0x263, 0x08}, {0x264, 0xcf}, {0x272, 0x56},
364 {0x273, 0x9a}, {0x034, 0xf0}, {0x035, 0x0f},
365 {0x05b, 0x40}, {0x084, 0x88}, {0x085, 0x24},
366 {0x088, 0x54}, {0x08b, 0xb8}, {0x08c, 0x07},
367 {0x08d, 0x00}, {0x094, 0x1b}, {0x095, 0x12},
368 {0x096, 0x00}, {0x097, 0x06}, {0x09d, 0x1a},
369 {0x09f, 0x10}, {0x0b4, 0x22}, {0x0be, 0x80},
370 {0x0db, 0x00}, {0x0ee, 0x00}, {0x091, 0x03},
371 {0x24c, 0x00}, {0x39f, 0x00}, {0x08c, 0x01},
372 {0x08d, 0x10}, {0x08e, 0x08}, {0x08f, 0x00}
375 static struct urtw_pair urtw_8225v2_rf_part2[] = {
376 { 0x00, 0x01 }, { 0x01, 0x02 }, { 0x02, 0x42 }, { 0x03, 0x00 },
377 { 0x04, 0x00 }, { 0x05, 0x00 }, { 0x06, 0x40 }, { 0x07, 0x00 },
378 { 0x08, 0x40 }, { 0x09, 0xfe }, { 0x0a, 0x08 }, { 0x0b, 0x80 },
379 { 0x0c, 0x01 }, { 0x0d, 0x43 }, { 0x0e, 0xd3 }, { 0x0f, 0x38 },
380 { 0x10, 0x84 }, { 0x11, 0x07 }, { 0x12, 0x20 }, { 0x13, 0x20 },
381 { 0x14, 0x00 }, { 0x15, 0x40 }, { 0x16, 0x00 }, { 0x17, 0x40 },
382 { 0x18, 0xef }, { 0x19, 0x19 }, { 0x1a, 0x20 }, { 0x1b, 0x15 },
383 { 0x1c, 0x04 }, { 0x1d, 0xc5 }, { 0x1e, 0x95 }, { 0x1f, 0x75 },
384 { 0x20, 0x1f }, { 0x21, 0x17 }, { 0x22, 0x16 }, { 0x23, 0x80 },
385 { 0x24, 0x46 }, { 0x25, 0x00 }, { 0x26, 0x90 }, { 0x27, 0x88 }
388 static struct urtw_pair urtw_8225v2b_rf_part2[] = {
389 { 0x00, 0x10 }, { 0x01, 0x0d }, { 0x02, 0x01 }, { 0x03, 0x00 },
390 { 0x04, 0x14 }, { 0x05, 0xfb }, { 0x06, 0xfb }, { 0x07, 0x60 },
391 { 0x08, 0x00 }, { 0x09, 0x60 }, { 0x0a, 0x00 }, { 0x0b, 0x00 },
392 { 0x0c, 0x00 }, { 0x0d, 0x5c }, { 0x0e, 0x00 }, { 0x0f, 0x00 },
393 { 0x10, 0x40 }, { 0x11, 0x00 }, { 0x12, 0x40 }, { 0x13, 0x00 },
394 { 0x14, 0x00 }, { 0x15, 0x00 }, { 0x16, 0xa8 }, { 0x17, 0x26 },
395 { 0x18, 0x32 }, { 0x19, 0x33 }, { 0x1a, 0x07 }, { 0x1b, 0xa5 },
396 { 0x1c, 0x6f }, { 0x1d, 0x55 }, { 0x1e, 0xc8 }, { 0x1f, 0xb3 },
397 { 0x20, 0x0a }, { 0x21, 0xe1 }, { 0x22, 0x2C }, { 0x23, 0x8a },
398 { 0x24, 0x86 }, { 0x25, 0x83 }, { 0x26, 0x34 }, { 0x27, 0x0f },
399 { 0x28, 0x4f }, { 0x29, 0x24 }, { 0x2a, 0x6f }, { 0x2b, 0xc2 },
400 { 0x2c, 0x6b }, { 0x2d, 0x40 }, { 0x2e, 0x80 }, { 0x2f, 0x00 },
401 { 0x30, 0xc0 }, { 0x31, 0xc1 }, { 0x32, 0x58 }, { 0x33, 0xf1 },
402 { 0x34, 0x00 }, { 0x35, 0xe4 }, { 0x36, 0x90 }, { 0x37, 0x3e },
403 { 0x38, 0x6d }, { 0x39, 0x3c }, { 0x3a, 0xfb }, { 0x3b, 0x07 }
406 static struct urtw_pair urtw_8225v2_rf_part3[] = {
407 { 0x00, 0x98 }, { 0x03, 0x20 }, { 0x04, 0x7e }, { 0x05, 0x12 },
408 { 0x06, 0xfc }, { 0x07, 0x78 }, { 0x08, 0x2e }, { 0x09, 0x11 },
409 { 0x0a, 0x17 }, { 0x0b, 0x11 }, { 0x10, 0x9b }, { 0x11, 0x88 },
410 { 0x12, 0x47 }, { 0x13, 0xd0 }, { 0x19, 0x00 }, { 0x1a, 0xa0 },
411 { 0x1b, 0x08 }, { 0x1d, 0x00 }, { 0x40, 0x86 }, { 0x41, 0x9d },
412 { 0x42, 0x15 }, { 0x43, 0x18 }, { 0x44, 0x36 }, { 0x45, 0x35 },
413 { 0x46, 0x2e }, { 0x47, 0x25 }, { 0x48, 0x1c }, { 0x49, 0x12 },
414 { 0x4a, 0x09 }, { 0x4b, 0x04 }, { 0x4c, 0x05 }
417 static uint16_t urtw_8225v2_rxgain[] = {
418 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0008, 0x0009,
419 0x000a, 0x000b, 0x0102, 0x0103, 0x0104, 0x0105, 0x0140, 0x0141,
420 0x0142, 0x0143, 0x0144, 0x0145, 0x0180, 0x0181, 0x0182, 0x0183,
421 0x0184, 0x0185, 0x0188, 0x0189, 0x018a, 0x018b, 0x0243, 0x0244,
422 0x0245, 0x0280, 0x0281, 0x0282, 0x0283, 0x0284, 0x0285, 0x0288,
423 0x0289, 0x028a, 0x028b, 0x028c, 0x0342, 0x0343, 0x0344, 0x0345,
424 0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x0388, 0x0389,
425 0x038a, 0x038b, 0x038c, 0x038d, 0x0390, 0x0391, 0x0392, 0x0393,
426 0x0394, 0x0395, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d,
427 0x03a0, 0x03a1, 0x03a2, 0x03a3, 0x03a4, 0x03a5, 0x03a8, 0x03a9,
428 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
429 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
432 static uint16_t urtw_8225v2b_rxgain[] = {
433 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
434 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
435 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
436 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
437 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
438 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
439 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
440 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
441 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
442 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
443 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
444 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
447 static uint8_t urtw_8225v2_tx_gain_cck_ofdm[] = {
448 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
449 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
450 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
451 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
452 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
453 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
456 static uint8_t urtw_8225v2_txpwr_cck[] = {
457 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04
460 static uint8_t urtw_8225v2_txpwr_cck_ch14[] = {
461 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00
464 static uint8_t urtw_8225v2b_txpwr_cck[] = {
465 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04,
466 0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03,
467 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03,
468 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03
471 static uint8_t urtw_8225v2b_txpwr_cck_ch14[] = {
472 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00,
473 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
474 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
475 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00
478 static struct urtw_pair urtw_ratetable[] = {
479 { 2, 0 }, { 4, 1 }, { 11, 2 }, { 12, 4 }, { 18, 5 },
480 { 22, 3 }, { 24, 6 }, { 36, 7 }, { 48, 8 }, { 72, 9 },
481 { 96, 10 }, { 108, 11 }
485 static const uint8_t urtw_8187b_reg_table[][3] = {
486 { 0xf0, 0x32, 0 }, { 0xf1, 0x32, 0 }, { 0xf2, 0x00, 0 },
487 { 0xf3, 0x00, 0 }, { 0xf4, 0x32, 0 }, { 0xf5, 0x43, 0 },
488 { 0xf6, 0x00, 0 }, { 0xf7, 0x00, 0 }, { 0xf8, 0x46, 0 },
489 { 0xf9, 0xa4, 0 }, { 0xfa, 0x00, 0 }, { 0xfb, 0x00, 0 },
490 { 0xfc, 0x96, 0 }, { 0xfd, 0xa4, 0 }, { 0xfe, 0x00, 0 },
491 { 0xff, 0x00, 0 }, { 0x58, 0x4b, 1 }, { 0x59, 0x00, 1 },
492 { 0x5a, 0x4b, 1 }, { 0x5b, 0x00, 1 }, { 0x60, 0x4b, 1 },
493 { 0x61, 0x09, 1 }, { 0x62, 0x4b, 1 }, { 0x63, 0x09, 1 },
494 { 0xce, 0x0f, 1 }, { 0xcf, 0x00, 1 }, { 0xe0, 0xff, 1 },
495 { 0xe1, 0x0f, 1 }, { 0xe2, 0x00, 1 }, { 0xf0, 0x4e, 1 },
496 { 0xf1, 0x01, 1 }, { 0xf2, 0x02, 1 }, { 0xf3, 0x03, 1 },
497 { 0xf4, 0x04, 1 }, { 0xf5, 0x05, 1 }, { 0xf6, 0x06, 1 },
498 { 0xf7, 0x07, 1 }, { 0xf8, 0x08, 1 }, { 0x4e, 0x00, 2 },
499 { 0x0c, 0x04, 2 }, { 0x21, 0x61, 2 }, { 0x22, 0x68, 2 },
500 { 0x23, 0x6f, 2 }, { 0x24, 0x76, 2 }, { 0x25, 0x7d, 2 },
501 { 0x26, 0x84, 2 }, { 0x27, 0x8d, 2 }, { 0x4d, 0x08, 2 },
502 { 0x50, 0x05, 2 }, { 0x51, 0xf5, 2 }, { 0x52, 0x04, 2 },
503 { 0x53, 0xa0, 2 }, { 0x54, 0x1f, 2 }, { 0x55, 0x23, 2 },
504 { 0x56, 0x45, 2 }, { 0x57, 0x67, 2 }, { 0x58, 0x08, 2 },
505 { 0x59, 0x08, 2 }, { 0x5a, 0x08, 2 }, { 0x5b, 0x08, 2 },
506 { 0x60, 0x08, 2 }, { 0x61, 0x08, 2 }, { 0x62, 0x08, 2 },
507 { 0x63, 0x08, 2 }, { 0x64, 0xcf, 2 }, { 0x72, 0x56, 2 },
508 { 0x73, 0x9a, 2 }, { 0x34, 0xf0, 0 }, { 0x35, 0x0f, 0 },
509 { 0x5b, 0x40, 0 }, { 0x84, 0x88, 0 }, { 0x85, 0x24, 0 },
510 { 0x88, 0x54, 0 }, { 0x8b, 0xb8, 0 }, { 0x8c, 0x07, 0 },
511 { 0x8d, 0x00, 0 }, { 0x94, 0x1b, 0 }, { 0x95, 0x12, 0 },
512 { 0x96, 0x00, 0 }, { 0x97, 0x06, 0 }, { 0x9d, 0x1a, 0 },
513 { 0x9f, 0x10, 0 }, { 0xb4, 0x22, 0 }, { 0xbe, 0x80, 0 },
514 { 0xdb, 0x00, 0 }, { 0xee, 0x00, 0 }, { 0x91, 0x03, 0 },
515 { 0x4c, 0x00, 2 }, { 0x9f, 0x00, 3 }, { 0x8c, 0x01, 0 },
516 { 0x8d, 0x10, 0 }, { 0x8e, 0x08, 0 }, { 0x8f, 0x00, 0 }
520 static usb_callback_t urtw_bulk_rx_callback;
521 static usb_callback_t urtw_bulk_tx_callback;
522 static usb_callback_t urtw_bulk_tx_status_callback;
524 static const struct usb_config urtw_8187b_usbconfig[URTW_8187B_N_XFERS] = {
525 [URTW_8187B_BULK_RX] = {
528 .direction = UE_DIR_IN,
535 .callback = urtw_bulk_rx_callback
537 [URTW_8187B_BULK_TX_STATUS] = {
540 .direction = UE_DIR_IN,
541 .bufsize = sizeof(uint64_t),
546 .callback = urtw_bulk_tx_status_callback
548 [URTW_8187B_BULK_TX_BE] = {
550 .endpoint = URTW_8187B_TXPIPE_BE,
551 .direction = UE_DIR_OUT,
552 .bufsize = URTW_TX_MAXSIZE * URTW_TX_DATA_LIST_COUNT,
554 .force_short_xfer = 1,
557 .callback = urtw_bulk_tx_callback,
558 .timeout = URTW_DATA_TIMEOUT
560 [URTW_8187B_BULK_TX_BK] = {
562 .endpoint = URTW_8187B_TXPIPE_BK,
563 .direction = UE_DIR_OUT,
564 .bufsize = URTW_TX_MAXSIZE,
567 .force_short_xfer = 1,
570 .callback = urtw_bulk_tx_callback,
571 .timeout = URTW_DATA_TIMEOUT
573 [URTW_8187B_BULK_TX_VI] = {
575 .endpoint = URTW_8187B_TXPIPE_VI,
576 .direction = UE_DIR_OUT,
577 .bufsize = URTW_TX_MAXSIZE,
580 .force_short_xfer = 1,
583 .callback = urtw_bulk_tx_callback,
584 .timeout = URTW_DATA_TIMEOUT
586 [URTW_8187B_BULK_TX_VO] = {
588 .endpoint = URTW_8187B_TXPIPE_VO,
589 .direction = UE_DIR_OUT,
590 .bufsize = URTW_TX_MAXSIZE,
593 .force_short_xfer = 1,
596 .callback = urtw_bulk_tx_callback,
597 .timeout = URTW_DATA_TIMEOUT
599 [URTW_8187B_BULK_TX_EP12] = {
602 .direction = UE_DIR_OUT,
603 .bufsize = URTW_TX_MAXSIZE,
606 .force_short_xfer = 1,
609 .callback = urtw_bulk_tx_callback,
610 .timeout = URTW_DATA_TIMEOUT
614 static const struct usb_config urtw_8187l_usbconfig[URTW_8187L_N_XFERS] = {
615 [URTW_8187L_BULK_RX] = {
618 .direction = UE_DIR_IN,
625 .callback = urtw_bulk_rx_callback
627 [URTW_8187L_BULK_TX_LOW] = {
630 .direction = UE_DIR_OUT,
631 .bufsize = URTW_TX_MAXSIZE * URTW_TX_DATA_LIST_COUNT,
633 .force_short_xfer = 1,
636 .callback = urtw_bulk_tx_callback,
637 .timeout = URTW_DATA_TIMEOUT
639 [URTW_8187L_BULK_TX_NORMAL] = {
642 .direction = UE_DIR_OUT,
643 .bufsize = URTW_TX_MAXSIZE,
646 .force_short_xfer = 1,
649 .callback = urtw_bulk_tx_callback,
650 .timeout = URTW_DATA_TIMEOUT
654 static struct ieee80211vap *urtw_vap_create(struct ieee80211com *,
655 const char [IFNAMSIZ], int, enum ieee80211_opmode,
656 int, const uint8_t [IEEE80211_ADDR_LEN],
657 const uint8_t [IEEE80211_ADDR_LEN]);
658 static void urtw_vap_delete(struct ieee80211vap *);
659 static void urtw_init(struct urtw_softc *);
660 static void urtw_stop(struct urtw_softc *);
661 static void urtw_parent(struct ieee80211com *);
662 static int urtw_transmit(struct ieee80211com *, struct mbuf *);
663 static void urtw_start(struct urtw_softc *);
664 static int urtw_alloc_rx_data_list(struct urtw_softc *);
665 static int urtw_alloc_tx_data_list(struct urtw_softc *);
666 static int urtw_raw_xmit(struct ieee80211_node *, struct mbuf *,
667 const struct ieee80211_bpf_params *);
668 static void urtw_scan_start(struct ieee80211com *);
669 static void urtw_scan_end(struct ieee80211com *);
670 static void urtw_getradiocaps(struct ieee80211com *, int, int *,
671 struct ieee80211_channel[]);
672 static void urtw_set_channel(struct ieee80211com *);
673 static void urtw_update_mcast(struct ieee80211com *);
674 static int urtw_tx_start(struct urtw_softc *,
675 struct ieee80211_node *, struct mbuf *,
676 struct urtw_data *, int);
677 static int urtw_newstate(struct ieee80211vap *,
678 enum ieee80211_state, int);
679 static void urtw_led_ch(void *);
680 static void urtw_ledtask(void *, int);
681 static void urtw_watchdog(void *);
682 static void urtw_set_multi(void *);
683 static int urtw_isbmode(uint16_t);
684 static uint16_t urtw_rtl2rate(uint32_t);
685 static usb_error_t urtw_set_rate(struct urtw_softc *);
686 static usb_error_t urtw_update_msr(struct urtw_softc *);
687 static usb_error_t urtw_read8_c(struct urtw_softc *, int, uint8_t *);
688 static usb_error_t urtw_read16_c(struct urtw_softc *, int, uint16_t *);
689 static usb_error_t urtw_read32_c(struct urtw_softc *, int, uint32_t *);
690 static usb_error_t urtw_write8_c(struct urtw_softc *, int, uint8_t);
691 static usb_error_t urtw_write16_c(struct urtw_softc *, int, uint16_t);
692 static usb_error_t urtw_write32_c(struct urtw_softc *, int, uint32_t);
693 static usb_error_t urtw_eprom_cs(struct urtw_softc *, int);
694 static usb_error_t urtw_eprom_ck(struct urtw_softc *);
695 static usb_error_t urtw_eprom_sendbits(struct urtw_softc *, int16_t *,
697 static usb_error_t urtw_eprom_read32(struct urtw_softc *, uint32_t,
699 static usb_error_t urtw_eprom_readbit(struct urtw_softc *, int16_t *);
700 static usb_error_t urtw_eprom_writebit(struct urtw_softc *, int16_t);
701 static usb_error_t urtw_get_macaddr(struct urtw_softc *);
702 static usb_error_t urtw_get_txpwr(struct urtw_softc *);
703 static usb_error_t urtw_get_rfchip(struct urtw_softc *);
704 static usb_error_t urtw_led_init(struct urtw_softc *);
705 static usb_error_t urtw_8185_rf_pins_enable(struct urtw_softc *);
706 static usb_error_t urtw_8185_tx_antenna(struct urtw_softc *, uint8_t);
707 static usb_error_t urtw_8187_write_phy(struct urtw_softc *, uint8_t,
709 static usb_error_t urtw_8187_write_phy_ofdm_c(struct urtw_softc *,
711 static usb_error_t urtw_8187_write_phy_cck_c(struct urtw_softc *, uint8_t,
713 static usb_error_t urtw_8225_setgain(struct urtw_softc *, int16_t);
714 static usb_error_t urtw_8225_usb_init(struct urtw_softc *);
715 static usb_error_t urtw_8225_write_c(struct urtw_softc *, uint8_t,
717 static usb_error_t urtw_8225_write_s16(struct urtw_softc *, uint8_t, int,
719 static usb_error_t urtw_8225_read(struct urtw_softc *, uint8_t,
721 static usb_error_t urtw_8225_rf_init(struct urtw_softc *);
722 static usb_error_t urtw_8225_rf_set_chan(struct urtw_softc *, int);
723 static usb_error_t urtw_8225_rf_set_sens(struct urtw_softc *, int);
724 static usb_error_t urtw_8225_set_txpwrlvl(struct urtw_softc *, int);
725 static usb_error_t urtw_8225_rf_stop(struct urtw_softc *);
726 static usb_error_t urtw_8225v2_rf_init(struct urtw_softc *);
727 static usb_error_t urtw_8225v2_rf_set_chan(struct urtw_softc *, int);
728 static usb_error_t urtw_8225v2_set_txpwrlvl(struct urtw_softc *, int);
729 static usb_error_t urtw_8225v2_setgain(struct urtw_softc *, int16_t);
730 static usb_error_t urtw_8225_isv2(struct urtw_softc *, int *);
731 static usb_error_t urtw_8225v2b_rf_init(struct urtw_softc *);
732 static usb_error_t urtw_8225v2b_rf_set_chan(struct urtw_softc *, int);
733 static usb_error_t urtw_read8e(struct urtw_softc *, int, uint8_t *);
734 static usb_error_t urtw_write8e(struct urtw_softc *, int, uint8_t);
735 static usb_error_t urtw_8180_set_anaparam(struct urtw_softc *, uint32_t);
736 static usb_error_t urtw_8185_set_anaparam2(struct urtw_softc *, uint32_t);
737 static usb_error_t urtw_intr_enable(struct urtw_softc *);
738 static usb_error_t urtw_intr_disable(struct urtw_softc *);
739 static usb_error_t urtw_reset(struct urtw_softc *);
740 static usb_error_t urtw_led_on(struct urtw_softc *, int);
741 static usb_error_t urtw_led_ctl(struct urtw_softc *, int);
742 static usb_error_t urtw_led_blink(struct urtw_softc *);
743 static usb_error_t urtw_led_mode0(struct urtw_softc *, int);
744 static usb_error_t urtw_led_mode1(struct urtw_softc *, int);
745 static usb_error_t urtw_led_mode2(struct urtw_softc *, int);
746 static usb_error_t urtw_led_mode3(struct urtw_softc *, int);
747 static usb_error_t urtw_rx_setconf(struct urtw_softc *);
748 static usb_error_t urtw_rx_enable(struct urtw_softc *);
749 static usb_error_t urtw_tx_enable(struct urtw_softc *sc);
750 static void urtw_free_tx_data_list(struct urtw_softc *);
751 static void urtw_free_rx_data_list(struct urtw_softc *);
752 static void urtw_free_data_list(struct urtw_softc *,
753 struct urtw_data data[], int, int);
754 static usb_error_t urtw_adapter_start(struct urtw_softc *);
755 static usb_error_t urtw_adapter_start_b(struct urtw_softc *);
756 static usb_error_t urtw_set_mode(struct urtw_softc *, uint32_t);
757 static usb_error_t urtw_8187b_cmd_reset(struct urtw_softc *);
758 static usb_error_t urtw_do_request(struct urtw_softc *,
759 struct usb_device_request *, void *);
760 static usb_error_t urtw_8225v2b_set_txpwrlvl(struct urtw_softc *, int);
761 static usb_error_t urtw_led_off(struct urtw_softc *, int);
762 static void urtw_abort_xfers(struct urtw_softc *);
763 static struct urtw_data *
764 urtw_getbuf(struct urtw_softc *sc);
765 static int urtw_compute_txtime(uint16_t, uint16_t, uint8_t,
767 static void urtw_updateslot(struct ieee80211com *);
768 static void urtw_updateslottask(void *, int);
769 static void urtw_sysctl_node(struct urtw_softc *);
772 urtw_match(device_t dev)
774 struct usb_attach_arg *uaa = device_get_ivars(dev);
776 if (uaa->usb_mode != USB_MODE_HOST)
778 if (uaa->info.bConfigIndex != URTW_CONFIG_INDEX)
780 if (uaa->info.bIfaceIndex != URTW_IFACE_INDEX)
783 return (usbd_lookup_id_by_uaa(urtw_devs, sizeof(urtw_devs), uaa));
787 urtw_attach(device_t dev)
789 const struct usb_config *setup_start;
791 struct urtw_softc *sc = device_get_softc(dev);
792 struct usb_attach_arg *uaa = device_get_ivars(dev);
793 struct ieee80211com *ic = &sc->sc_ic;
794 uint8_t iface_index = URTW_IFACE_INDEX; /* XXX */
799 device_set_usb_desc(dev);
802 sc->sc_udev = uaa->device;
803 if (USB_GET_DRIVER_INFO(uaa) == URTW_REV_RTL8187B)
804 sc->sc_flags |= URTW_RTL8187B;
806 sc->sc_debug = urtw_debug;
809 mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev), MTX_NETWORK_LOCK,
811 usb_callout_init_mtx(&sc->sc_led_ch, &sc->sc_mtx, 0);
812 TASK_INIT(&sc->sc_led_task, 0, urtw_ledtask, sc);
813 TASK_INIT(&sc->sc_updateslot_task, 0, urtw_updateslottask, sc);
814 callout_init(&sc->sc_watchdog_ch, 0);
815 mbufq_init(&sc->sc_snd, ifqmaxlen);
817 if (sc->sc_flags & URTW_RTL8187B) {
818 setup_start = urtw_8187b_usbconfig;
819 n_setup = URTW_8187B_N_XFERS;
821 setup_start = urtw_8187l_usbconfig;
822 n_setup = URTW_8187L_N_XFERS;
825 error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_xfer,
826 setup_start, n_setup, sc, &sc->sc_mtx);
828 device_printf(dev, "could not allocate USB transfers, "
829 "err=%s\n", usbd_errstr(error));
834 if (sc->sc_flags & URTW_RTL8187B) {
836 usbd_xfer_get_frame_buffer(sc->sc_xfer[
837 URTW_8187B_BULK_TX_BE], 0);
840 usbd_xfer_get_frame_buffer(sc->sc_xfer[
841 URTW_8187L_BULK_TX_LOW], 0);
846 urtw_read32_m(sc, URTW_RX, &data);
847 sc->sc_epromtype = (data & URTW_RX_9356SEL) ? URTW_EEPROM_93C56 :
850 error = urtw_get_rfchip(sc);
853 error = urtw_get_macaddr(sc);
856 error = urtw_get_txpwr(sc);
859 error = urtw_led_init(sc);
865 sc->sc_rts_retry = URTW_DEFAULT_RTS_RETRY;
866 sc->sc_tx_retry = URTW_DEFAULT_TX_RETRY;
867 sc->sc_currate = URTW_RIDX_CCK11;
868 sc->sc_preamble_mode = urtw_preamble_mode;
871 ic->ic_name = device_get_nameunit(dev);
872 ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
873 ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
875 /* set device capabilities */
877 IEEE80211_C_STA | /* station mode */
878 IEEE80211_C_MONITOR | /* monitor mode supported */
879 IEEE80211_C_TXPMGT | /* tx power management */
880 IEEE80211_C_SHPREAMBLE | /* short preamble supported */
881 IEEE80211_C_SHSLOT | /* short slot time supported */
882 IEEE80211_C_BGSCAN | /* capable of bg scanning */
883 IEEE80211_C_WPA; /* 802.11i */
885 /* XXX TODO: setup regdomain if URTW_EPROM_CHANPLAN_BY_HW bit is set.*/
887 urtw_getradiocaps(ic, IEEE80211_CHAN_MAX, &ic->ic_nchans,
890 ieee80211_ifattach(ic);
891 ic->ic_raw_xmit = urtw_raw_xmit;
892 ic->ic_scan_start = urtw_scan_start;
893 ic->ic_scan_end = urtw_scan_end;
894 ic->ic_getradiocaps = urtw_getradiocaps;
895 ic->ic_set_channel = urtw_set_channel;
896 ic->ic_updateslot = urtw_updateslot;
897 ic->ic_vap_create = urtw_vap_create;
898 ic->ic_vap_delete = urtw_vap_delete;
899 ic->ic_update_mcast = urtw_update_mcast;
900 ic->ic_parent = urtw_parent;
901 ic->ic_transmit = urtw_transmit;
903 ieee80211_radiotap_attach(ic,
904 &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
905 URTW_TX_RADIOTAP_PRESENT,
906 &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
907 URTW_RX_RADIOTAP_PRESENT);
909 urtw_sysctl_node(sc);
912 ieee80211_announce(ic);
917 usbd_transfer_unsetup(sc->sc_xfer, (sc->sc_flags & URTW_RTL8187B) ?
918 URTW_8187B_N_XFERS : URTW_8187L_N_XFERS);
924 urtw_detach(device_t dev)
926 struct urtw_softc *sc = device_get_softc(dev);
927 struct ieee80211com *ic = &sc->sc_ic;
929 unsigned int n_xfers;
931 /* Prevent further ioctls */
933 sc->sc_flags |= URTW_DETACHED;
937 ieee80211_draintask(ic, &sc->sc_updateslot_task);
938 ieee80211_draintask(ic, &sc->sc_led_task);
940 usb_callout_drain(&sc->sc_led_ch);
941 callout_drain(&sc->sc_watchdog_ch);
943 n_xfers = (sc->sc_flags & URTW_RTL8187B) ?
944 URTW_8187B_N_XFERS : URTW_8187L_N_XFERS;
946 /* prevent further allocations from RX/TX data lists */
948 STAILQ_INIT(&sc->sc_tx_active);
949 STAILQ_INIT(&sc->sc_tx_inactive);
950 STAILQ_INIT(&sc->sc_tx_pending);
952 STAILQ_INIT(&sc->sc_rx_active);
953 STAILQ_INIT(&sc->sc_rx_inactive);
956 /* drain USB transfers */
957 for (x = 0; x != n_xfers; x++)
958 usbd_transfer_drain(sc->sc_xfer[x]);
960 /* free data buffers */
962 urtw_free_tx_data_list(sc);
963 urtw_free_rx_data_list(sc);
966 /* free USB transfers and some data buffers */
967 usbd_transfer_unsetup(sc->sc_xfer, n_xfers);
969 ieee80211_ifdetach(ic);
970 mbufq_drain(&sc->sc_snd);
971 mtx_destroy(&sc->sc_mtx);
976 urtw_free_tx_data_list(struct urtw_softc *sc)
978 urtw_free_data_list(sc, sc->sc_tx, URTW_TX_DATA_LIST_COUNT, 0);
982 urtw_free_rx_data_list(struct urtw_softc *sc)
984 urtw_free_data_list(sc, sc->sc_rx, URTW_RX_DATA_LIST_COUNT, 1);
988 urtw_free_data_list(struct urtw_softc *sc, struct urtw_data data[], int ndata,
993 for (i = 0; i < ndata; i++) {
994 struct urtw_data *dp = &data[i];
1005 if (dp->ni != NULL) {
1006 ieee80211_free_node(dp->ni);
1012 static struct ieee80211vap *
1013 urtw_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
1014 enum ieee80211_opmode opmode, int flags,
1015 const uint8_t bssid[IEEE80211_ADDR_LEN],
1016 const uint8_t mac[IEEE80211_ADDR_LEN])
1018 struct urtw_vap *uvp;
1019 struct ieee80211vap *vap;
1021 if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
1023 uvp = malloc(sizeof(struct urtw_vap), M_80211_VAP, M_WAITOK | M_ZERO);
1025 /* enable s/w bmiss handling for sta mode */
1027 if (ieee80211_vap_setup(ic, vap, name, unit, opmode,
1028 flags | IEEE80211_CLONE_NOBEACONS, bssid) != 0) {
1030 free(uvp, M_80211_VAP);
1034 /* override state transition machine */
1035 uvp->newstate = vap->iv_newstate;
1036 vap->iv_newstate = urtw_newstate;
1038 /* complete setup */
1039 ieee80211_vap_attach(vap, ieee80211_media_change,
1040 ieee80211_media_status, mac);
1041 ic->ic_opmode = opmode;
1046 urtw_vap_delete(struct ieee80211vap *vap)
1048 struct urtw_vap *uvp = URTW_VAP(vap);
1050 ieee80211_vap_detach(vap);
1051 free(uvp, M_80211_VAP);
1055 urtw_init(struct urtw_softc *sc)
1060 URTW_ASSERT_LOCKED(sc);
1062 if (sc->sc_flags & URTW_RUNNING)
1065 error = (sc->sc_flags & URTW_RTL8187B) ? urtw_adapter_start_b(sc) :
1066 urtw_adapter_start(sc);
1070 /* reset softc variables */
1073 if (!(sc->sc_flags & URTW_INIT_ONCE)) {
1074 ret = urtw_alloc_rx_data_list(sc);
1077 ret = urtw_alloc_tx_data_list(sc);
1080 sc->sc_flags |= URTW_INIT_ONCE;
1083 error = urtw_rx_enable(sc);
1086 error = urtw_tx_enable(sc);
1090 if (sc->sc_flags & URTW_RTL8187B)
1091 usbd_transfer_start(sc->sc_xfer[URTW_8187B_BULK_TX_STATUS]);
1093 sc->sc_flags |= URTW_RUNNING;
1095 callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc);
1101 urtw_adapter_start_b(struct urtw_softc *sc)
1106 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
1110 urtw_read8_m(sc, URTW_CONFIG3, &data8);
1111 urtw_write8_m(sc, URTW_CONFIG3,
1112 data8 | URTW_CONFIG3_ANAPARAM_WRITE | URTW_CONFIG3_GNT_SELECT);
1113 urtw_write32_m(sc, URTW_ANAPARAM2, URTW_8187B_8225_ANAPARAM2_ON);
1114 urtw_write32_m(sc, URTW_ANAPARAM, URTW_8187B_8225_ANAPARAM_ON);
1115 urtw_write8_m(sc, URTW_ANAPARAM3, URTW_8187B_8225_ANAPARAM3_ON);
1117 urtw_write8_m(sc, 0x61, 0x10);
1118 urtw_read8_m(sc, 0x62, &data8);
1119 urtw_write8_m(sc, 0x62, data8 & ~(1 << 5));
1120 urtw_write8_m(sc, 0x62, data8 | (1 << 5));
1122 urtw_read8_m(sc, URTW_CONFIG3, &data8);
1123 data8 &= ~URTW_CONFIG3_ANAPARAM_WRITE;
1124 urtw_write8_m(sc, URTW_CONFIG3, data8);
1126 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
1130 error = urtw_8187b_cmd_reset(sc);
1134 error = sc->sc_rf_init(sc);
1137 urtw_write8_m(sc, URTW_CMD, URTW_CMD_RX_ENABLE | URTW_CMD_TX_ENABLE);
1139 /* fix RTL8187B RX stall */
1140 error = urtw_intr_enable(sc);
1144 error = urtw_write8e(sc, 0x41, 0xf4);
1147 error = urtw_write8e(sc, 0x40, 0x00);
1150 error = urtw_write8e(sc, 0x42, 0x00);
1153 error = urtw_write8e(sc, 0x42, 0x01);
1156 error = urtw_write8e(sc, 0x40, 0x0f);
1159 error = urtw_write8e(sc, 0x42, 0x00);
1162 error = urtw_write8e(sc, 0x42, 0x01);
1166 urtw_read8_m(sc, 0xdb, &data8);
1167 urtw_write8_m(sc, 0xdb, data8 | (1 << 2));
1168 urtw_write16_m(sc, 0x372, 0x59fa);
1169 urtw_write16_m(sc, 0x374, 0x59d2);
1170 urtw_write16_m(sc, 0x376, 0x59d2);
1171 urtw_write16_m(sc, 0x378, 0x19fa);
1172 urtw_write16_m(sc, 0x37a, 0x19fa);
1173 urtw_write16_m(sc, 0x37c, 0x00d0);
1174 urtw_write8_m(sc, 0x61, 0);
1176 urtw_write8_m(sc, 0x180, 0x0f);
1177 urtw_write8_m(sc, 0x183, 0x03);
1178 urtw_write8_m(sc, 0xda, 0x10);
1179 urtw_write8_m(sc, 0x24d, 0x08);
1180 urtw_write32_m(sc, URTW_HSSI_PARA, 0x0600321b);
1182 urtw_write16_m(sc, 0x1ec, 0x800); /* RX MAX SIZE */
1188 urtw_adapter_start(struct urtw_softc *sc)
1190 struct ieee80211com *ic = &sc->sc_ic;
1193 error = urtw_reset(sc);
1197 urtw_write8_m(sc, URTW_ADDR_MAGIC1, 0);
1198 urtw_write8_m(sc, URTW_GPIO, 0);
1201 urtw_write8_m(sc, URTW_ADDR_MAGIC1, 4);
1202 error = urtw_led_ctl(sc, URTW_LED_CTL_POWER_ON);
1206 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
1209 /* applying MAC address again. */
1210 urtw_write32_m(sc, URTW_MAC0, ((uint32_t *)ic->ic_macaddr)[0]);
1211 urtw_write16_m(sc, URTW_MAC4, ((uint32_t *)ic->ic_macaddr)[1] & 0xffff);
1212 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
1216 error = urtw_update_msr(sc);
1220 urtw_write32_m(sc, URTW_INT_TIMEOUT, 0);
1221 urtw_write8_m(sc, URTW_WPA_CONFIG, 0);
1222 urtw_write8_m(sc, URTW_RATE_FALLBACK, URTW_RATE_FALLBACK_ENABLE | 0x1);
1223 error = urtw_set_rate(sc);
1227 error = sc->sc_rf_init(sc);
1230 if (sc->sc_rf_set_sens != NULL)
1231 sc->sc_rf_set_sens(sc, sc->sc_sens);
1233 /* XXX correct? to call write16 */
1234 urtw_write16_m(sc, URTW_PSR, 1);
1235 urtw_write16_m(sc, URTW_ADDR_MAGIC2, 0x10);
1236 urtw_write8_m(sc, URTW_TALLY_SEL, 0x80);
1237 urtw_write8_m(sc, URTW_ADDR_MAGIC3, 0x60);
1238 /* XXX correct? to call write16 */
1239 urtw_write16_m(sc, URTW_PSR, 0);
1240 urtw_write8_m(sc, URTW_ADDR_MAGIC1, 4);
1242 error = urtw_intr_enable(sc);
1251 urtw_set_mode(struct urtw_softc *sc, uint32_t mode)
1256 urtw_read8_m(sc, URTW_EPROM_CMD, &data);
1257 data = (data & ~URTW_EPROM_CMD_MASK) | (mode << URTW_EPROM_CMD_SHIFT);
1258 data = data & ~(URTW_EPROM_CS | URTW_EPROM_CK);
1259 urtw_write8_m(sc, URTW_EPROM_CMD, data);
1265 urtw_8187b_cmd_reset(struct urtw_softc *sc)
1271 /* XXX the code can be duplicate with urtw_reset(). */
1272 urtw_read8_m(sc, URTW_CMD, &data8);
1273 data8 = (data8 & 0x2) | URTW_CMD_RST;
1274 urtw_write8_m(sc, URTW_CMD, data8);
1276 for (i = 0; i < 20; i++) {
1277 usb_pause_mtx(&sc->sc_mtx, 2);
1278 urtw_read8_m(sc, URTW_CMD, &data8);
1279 if (!(data8 & URTW_CMD_RST))
1283 device_printf(sc->sc_dev, "reset timeout\n");
1291 urtw_do_request(struct urtw_softc *sc,
1292 struct usb_device_request *req, void *data)
1297 URTW_ASSERT_LOCKED(sc);
1300 err = usbd_do_request_flags(sc->sc_udev, &sc->sc_mtx,
1301 req, data, 0, NULL, 250 /* ms */);
1305 DPRINTF(sc, URTW_DEBUG_INIT,
1306 "Control request failed, %s (retrying)\n",
1308 usb_pause_mtx(&sc->sc_mtx, hz / 100);
1314 urtw_stop(struct urtw_softc *sc)
1319 URTW_ASSERT_LOCKED(sc);
1321 sc->sc_flags &= ~URTW_RUNNING;
1323 error = urtw_intr_disable(sc);
1326 urtw_read8_m(sc, URTW_CMD, &data8);
1327 data8 &= ~(URTW_CMD_RX_ENABLE | URTW_CMD_TX_ENABLE);
1328 urtw_write8_m(sc, URTW_CMD, data8);
1330 error = sc->sc_rf_stop(sc);
1334 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
1337 urtw_read8_m(sc, URTW_CONFIG4, &data8);
1338 urtw_write8_m(sc, URTW_CONFIG4, data8 | URTW_CONFIG4_VCOOFF);
1339 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
1344 device_printf(sc->sc_dev, "failed to stop (%s)\n",
1345 usbd_errstr(error));
1347 usb_callout_stop(&sc->sc_led_ch);
1348 callout_stop(&sc->sc_watchdog_ch);
1350 urtw_abort_xfers(sc);
1354 urtw_abort_xfers(struct urtw_softc *sc)
1358 URTW_ASSERT_LOCKED(sc);
1360 max = (sc->sc_flags & URTW_RTL8187B) ? URTW_8187B_N_XFERS :
1363 /* abort any pending transfers */
1364 for (i = 0; i < max; i++)
1365 usbd_transfer_stop(sc->sc_xfer[i]);
1369 urtw_parent(struct ieee80211com *ic)
1371 struct urtw_softc *sc = ic->ic_softc;
1375 if (sc->sc_flags & URTW_DETACHED) {
1380 if (ic->ic_nrunning > 0) {
1381 if (sc->sc_flags & URTW_RUNNING) {
1382 if (ic->ic_promisc > 0 || ic->ic_allmulti > 0)
1388 } else if (sc->sc_flags & URTW_RUNNING)
1392 ieee80211_start_all(ic);
1396 urtw_transmit(struct ieee80211com *ic, struct mbuf *m)
1398 struct urtw_softc *sc = ic->ic_softc;
1402 if ((sc->sc_flags & URTW_RUNNING) == 0) {
1406 error = mbufq_enqueue(&sc->sc_snd, m);
1418 urtw_start(struct urtw_softc *sc)
1420 struct urtw_data *bf;
1421 struct ieee80211_node *ni;
1424 URTW_ASSERT_LOCKED(sc);
1426 if ((sc->sc_flags & URTW_RUNNING) == 0)
1429 while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
1430 bf = urtw_getbuf(sc);
1432 mbufq_prepend(&sc->sc_snd, m);
1436 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
1437 m->m_pkthdr.rcvif = NULL;
1439 if (urtw_tx_start(sc, ni, m, bf, URTW_PRIORITY_NORMAL) != 0) {
1440 if_inc_counter(ni->ni_vap->iv_ifp,
1441 IFCOUNTER_OERRORS, 1);
1442 STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
1443 ieee80211_free_node(ni);
1448 callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc);
1453 urtw_alloc_data_list(struct urtw_softc *sc, struct urtw_data data[],
1454 int ndata, int maxsz, void *dma_buf)
1458 for (i = 0; i < ndata; i++) {
1459 struct urtw_data *dp = &data[i];
1462 if (dma_buf == NULL) {
1463 dp->m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
1464 if (dp->m == NULL) {
1465 device_printf(sc->sc_dev,
1466 "could not allocate rx mbuf\n");
1470 dp->buf = mtod(dp->m, uint8_t *);
1473 dp->buf = ((uint8_t *)dma_buf) +
1480 fail: urtw_free_data_list(sc, data, ndata, 1);
1485 urtw_alloc_rx_data_list(struct urtw_softc *sc)
1489 error = urtw_alloc_data_list(sc,
1490 sc->sc_rx, URTW_RX_DATA_LIST_COUNT,
1491 MCLBYTES, NULL /* mbufs */);
1495 STAILQ_INIT(&sc->sc_rx_active);
1496 STAILQ_INIT(&sc->sc_rx_inactive);
1498 for (i = 0; i < URTW_RX_DATA_LIST_COUNT; i++)
1499 STAILQ_INSERT_HEAD(&sc->sc_rx_inactive, &sc->sc_rx[i], next);
1505 urtw_alloc_tx_data_list(struct urtw_softc *sc)
1509 error = urtw_alloc_data_list(sc,
1510 sc->sc_tx, URTW_TX_DATA_LIST_COUNT, URTW_TX_MAXSIZE,
1511 sc->sc_tx_dma_buf /* no mbufs */);
1515 STAILQ_INIT(&sc->sc_tx_active);
1516 STAILQ_INIT(&sc->sc_tx_inactive);
1517 STAILQ_INIT(&sc->sc_tx_pending);
1519 for (i = 0; i < URTW_TX_DATA_LIST_COUNT; i++)
1520 STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, &sc->sc_tx[i],
1527 urtw_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
1528 const struct ieee80211_bpf_params *params)
1530 struct ieee80211com *ic = ni->ni_ic;
1531 struct urtw_softc *sc = ic->ic_softc;
1532 struct urtw_data *bf;
1534 /* prevent management frames from being sent if we're not ready */
1535 if (!(sc->sc_flags & URTW_RUNNING)) {
1540 bf = urtw_getbuf(sc);
1544 return (ENOBUFS); /* XXX */
1547 if (urtw_tx_start(sc, ni, m, bf, URTW_PRIORITY_LOW) != 0) {
1548 STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
1559 urtw_scan_start(struct ieee80211com *ic)
1562 /* XXX do nothing? */
1566 urtw_scan_end(struct ieee80211com *ic)
1569 /* XXX do nothing? */
1573 urtw_getradiocaps(struct ieee80211com *ic,
1574 int maxchans, int *nchans, struct ieee80211_channel chans[])
1576 uint8_t bands[IEEE80211_MODE_BYTES];
1578 memset(bands, 0, sizeof(bands));
1579 setbit(bands, IEEE80211_MODE_11B);
1580 setbit(bands, IEEE80211_MODE_11G);
1581 ieee80211_add_channels_default_2ghz(chans, maxchans, nchans, bands, 0);
1585 urtw_set_channel(struct ieee80211com *ic)
1587 struct urtw_softc *sc = ic->ic_softc;
1588 uint32_t data, orig;
1592 * if the user set a channel explicitly using ifconfig(8) this function
1593 * can be called earlier than we're expected that in some cases the
1594 * initialization would be failed if setting a channel is called before
1595 * the init have done.
1597 if (!(sc->sc_flags & URTW_RUNNING))
1600 if (sc->sc_curchan != NULL && sc->sc_curchan == ic->ic_curchan)
1606 * during changing th channel we need to temporarily be disable
1609 urtw_read32_m(sc, URTW_TX_CONF, &orig);
1610 data = orig & ~URTW_TX_LOOPBACK_MASK;
1611 urtw_write32_m(sc, URTW_TX_CONF, data | URTW_TX_LOOPBACK_MAC);
1613 error = sc->sc_rf_set_chan(sc, ieee80211_chan2ieee(ic, ic->ic_curchan));
1616 usb_pause_mtx(&sc->sc_mtx, 10);
1617 urtw_write32_m(sc, URTW_TX_CONF, orig);
1619 urtw_write16_m(sc, URTW_ATIM_WND, 2);
1620 urtw_write16_m(sc, URTW_ATIM_TR_ITV, 100);
1621 urtw_write16_m(sc, URTW_BEACON_INTERVAL, 100);
1622 urtw_write16_m(sc, URTW_BEACON_INTERVAL_TIME, 100);
1627 sc->sc_curchan = ic->ic_curchan;
1630 device_printf(sc->sc_dev, "could not change the channel\n");
1634 urtw_update_mcast(struct ieee80211com *ic)
1637 /* XXX do nothing? */
1641 urtw_tx_start(struct urtw_softc *sc, struct ieee80211_node *ni, struct mbuf *m0,
1642 struct urtw_data *data, int prior)
1644 struct ieee80211_frame *wh = mtod(m0, struct ieee80211_frame *);
1645 struct ieee80211_key *k;
1646 const struct ieee80211_txparam *tp = ni->ni_txparms;
1647 struct ieee80211com *ic = &sc->sc_ic;
1648 struct ieee80211vap *vap = ni->ni_vap;
1649 struct usb_xfer *rtl8187b_pipes[URTW_8187B_TXPIPE_MAX] = {
1650 sc->sc_xfer[URTW_8187B_BULK_TX_BE],
1651 sc->sc_xfer[URTW_8187B_BULK_TX_BK],
1652 sc->sc_xfer[URTW_8187B_BULK_TX_VI],
1653 sc->sc_xfer[URTW_8187B_BULK_TX_VO]
1655 struct usb_xfer *xfer;
1656 int dur = 0, rtsdur = 0, rtsenable = 0, ctsenable = 0, rate, type,
1657 pkttime = 0, txdur = 0, isshort = 0, xferlen, ismcast;
1658 uint16_t acktime, rtstime, ctstime;
1662 URTW_ASSERT_LOCKED(sc);
1664 ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
1665 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
1670 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
1671 k = ieee80211_crypto_encap(ni, m0);
1673 device_printf(sc->sc_dev,
1674 "ieee80211_crypto_encap returns NULL.\n");
1675 /* XXX we don't expect the fragmented frames */
1680 /* in case packet header moved, reset pointer */
1681 wh = mtod(m0, struct ieee80211_frame *);
1684 if (ieee80211_radiotap_active_vap(vap)) {
1685 struct urtw_tx_radiotap_header *tap = &sc->sc_txtap;
1687 /* XXX Are variables correct? */
1689 tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
1690 tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
1692 ieee80211_radiotap_tx(vap, m0);
1695 if (type == IEEE80211_FC0_TYPE_MGT ||
1696 type == IEEE80211_FC0_TYPE_CTL ||
1697 (m0->m_flags & M_EAPOL) != 0) {
1698 rate = tp->mgmtrate;
1700 /* for data frames */
1702 rate = tp->mcastrate;
1703 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
1704 rate = tp->ucastrate;
1706 rate = urtw_rtl2rate(sc->sc_currate);
1709 sc->sc_stats.txrates[sc->sc_currate]++;
1712 txdur = pkttime = urtw_compute_txtime(m0->m_pkthdr.len +
1713 IEEE80211_CRC_LEN, rate, 0, 0);
1715 acktime = urtw_compute_txtime(14, 2,0, 0);
1716 if ((m0->m_pkthdr.len + 4) > vap->iv_rtsthreshold) {
1719 rtstime = urtw_compute_txtime(URTW_ACKCTS_LEN, 2, 0, 0);
1720 ctstime = urtw_compute_txtime(14, 2, 0, 0);
1721 pkttime = urtw_compute_txtime(m0->m_pkthdr.len +
1722 IEEE80211_CRC_LEN, rate, 0, isshort);
1723 rtsdur = ctstime + pkttime + acktime +
1724 3 * URTW_ASIFS_TIME;
1725 txdur = rtstime + rtsdur;
1727 rtsenable = ctsenable = rtsdur = 0;
1728 pkttime = urtw_compute_txtime(m0->m_pkthdr.len +
1729 IEEE80211_CRC_LEN, rate, 0, isshort);
1730 txdur = pkttime + URTW_ASIFS_TIME + acktime;
1733 if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG)
1734 dur = urtw_compute_txtime(m0->m_pkthdr.len +
1735 IEEE80211_CRC_LEN, rate, 0, isshort) +
1736 3 * URTW_ASIFS_TIME +
1739 dur = URTW_ASIFS_TIME + acktime;
1741 USETW(wh->i_dur, dur);
1743 xferlen = m0->m_pkthdr.len;
1744 xferlen += (sc->sc_flags & URTW_RTL8187B) ? (4 * 8) : (4 * 3);
1745 if ((0 == xferlen % 64) || (0 == xferlen % 512))
1748 memset(data->buf, 0, URTW_TX_MAXSIZE);
1749 flags = m0->m_pkthdr.len & 0xfff;
1750 flags |= URTW_TX_FLAG_NO_ENC;
1751 if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
1752 (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE) &&
1753 (sc->sc_preamble_mode == URTW_PREAMBLE_MODE_SHORT) &&
1754 (sc->sc_currate != 0))
1755 flags |= URTW_TX_FLAG_SPLCP;
1756 if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG)
1757 flags |= URTW_TX_FLAG_MOREFRAG;
1759 flags |= (sc->sc_currate & 0xf) << URTW_TX_FLAG_TXRATE_SHIFT;
1761 if (sc->sc_flags & URTW_RTL8187B) {
1762 struct urtw_8187b_txhdr *tx;
1764 tx = (struct urtw_8187b_txhdr *)data->buf;
1766 flags |= URTW_TX_FLAG_CTS;
1768 flags |= URTW_TX_FLAG_RTS;
1769 flags |= URTW_RIDX_CCK5 << URTW_TX_FLAG_RTSRATE_SHIFT;
1770 tx->rtsdur = rtsdur;
1772 tx->flag = htole32(flags);
1774 if (type == IEEE80211_FC0_TYPE_MGT &&
1775 (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) ==
1776 IEEE80211_FC0_SUBTYPE_PROBE_RESP)
1779 tx->retry = URTW_TX_MAXRETRY;
1780 m_copydata(m0, 0, m0->m_pkthdr.len, (uint8_t *)(tx + 1));
1782 struct urtw_8187l_txhdr *tx;
1784 tx = (struct urtw_8187l_txhdr *)data->buf;
1786 flags |= URTW_TX_FLAG_RTS;
1787 tx->rtsdur = rtsdur;
1789 flags |= URTW_RIDX_CCK5 << URTW_TX_FLAG_RTSRATE_SHIFT;
1790 tx->flag = htole32(flags);
1791 tx->retry = 3; /* CW minimum */
1792 tx->retry |= 7 << 4; /* CW maximum */
1793 tx->retry |= URTW_TX_MAXRETRY << 8; /* retry limitation */
1794 m_copydata(m0, 0, m0->m_pkthdr.len, (uint8_t *)(tx + 1));
1797 data->buflen = xferlen;
1801 if (sc->sc_flags & URTW_RTL8187B) {
1803 case IEEE80211_FC0_TYPE_CTL:
1804 case IEEE80211_FC0_TYPE_MGT:
1805 xfer = sc->sc_xfer[URTW_8187B_BULK_TX_EP12];
1808 KASSERT(M_WME_GETAC(m0) < URTW_8187B_TXPIPE_MAX,
1809 ("unsupported WME pipe %d", M_WME_GETAC(m0)));
1810 xfer = rtl8187b_pipes[M_WME_GETAC(m0)];
1814 xfer = (prior == URTW_PRIORITY_LOW) ?
1815 sc->sc_xfer[URTW_8187L_BULK_TX_LOW] :
1816 sc->sc_xfer[URTW_8187L_BULK_TX_NORMAL];
1818 STAILQ_INSERT_TAIL(&sc->sc_tx_pending, data, next);
1819 usbd_transfer_start(xfer);
1821 error = urtw_led_ctl(sc, URTW_LED_CTL_TX);
1823 device_printf(sc->sc_dev, "could not control LED (%d)\n",
1829 urtw_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
1831 struct ieee80211com *ic = vap->iv_ic;
1832 struct urtw_softc *sc = ic->ic_softc;
1833 struct urtw_vap *uvp = URTW_VAP(vap);
1834 struct ieee80211_node *ni;
1835 usb_error_t error = 0;
1837 DPRINTF(sc, URTW_DEBUG_STATE, "%s: %s -> %s\n", __func__,
1838 ieee80211_state_name[vap->iv_state],
1839 ieee80211_state_name[nstate]);
1841 sc->sc_state = nstate;
1843 IEEE80211_UNLOCK(ic);
1845 usb_callout_stop(&sc->sc_led_ch);
1846 callout_stop(&sc->sc_watchdog_ch);
1849 case IEEE80211_S_INIT:
1850 case IEEE80211_S_SCAN:
1851 case IEEE80211_S_AUTH:
1852 case IEEE80211_S_ASSOC:
1854 case IEEE80211_S_RUN:
1855 ni = ieee80211_ref_node(vap->iv_bss);
1856 /* setting bssid. */
1857 urtw_write32_m(sc, URTW_BSSID, ((uint32_t *)ni->ni_bssid)[0]);
1858 urtw_write16_m(sc, URTW_BSSID + 4,
1859 ((uint16_t *)ni->ni_bssid)[2]);
1860 urtw_update_msr(sc);
1861 /* XXX maybe the below would be incorrect. */
1862 urtw_write16_m(sc, URTW_ATIM_WND, 2);
1863 urtw_write16_m(sc, URTW_ATIM_TR_ITV, 100);
1864 urtw_write16_m(sc, URTW_BEACON_INTERVAL, 0x64);
1865 urtw_write16_m(sc, URTW_BEACON_INTERVAL_TIME, 100);
1866 error = urtw_led_ctl(sc, URTW_LED_CTL_LINK);
1868 device_printf(sc->sc_dev,
1869 "could not control LED (%d)\n", error);
1870 ieee80211_free_node(ni);
1878 return (uvp->newstate(vap, nstate, arg));
1882 urtw_watchdog(void *arg)
1884 struct urtw_softc *sc = arg;
1886 if (sc->sc_txtimer > 0) {
1887 if (--sc->sc_txtimer == 0) {
1888 device_printf(sc->sc_dev, "device timeout\n");
1889 counter_u64_add(sc->sc_ic.ic_oerrors, 1);
1892 callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc);
1897 urtw_set_multi(void *arg)
1899 /* XXX don't know how to set a device. Lack of docs. */
1903 urtw_set_rate(struct urtw_softc *sc)
1905 int i, basic_rate, min_rr_rate, max_rr_rate;
1909 basic_rate = URTW_RIDX_OFDM24;
1910 min_rr_rate = URTW_RIDX_OFDM6;
1911 max_rr_rate = URTW_RIDX_OFDM24;
1913 urtw_write8_m(sc, URTW_RESP_RATE,
1914 max_rr_rate << URTW_RESP_MAX_RATE_SHIFT |
1915 min_rr_rate << URTW_RESP_MIN_RATE_SHIFT);
1917 urtw_read16_m(sc, URTW_BRSR, &data);
1918 data &= ~URTW_BRSR_MBR_8185;
1920 for (i = 0; i <= basic_rate; i++)
1923 urtw_write16_m(sc, URTW_BRSR, data);
1929 urtw_rtl2rate(uint32_t rate)
1933 for (i = 0; i < nitems(urtw_ratetable); i++) {
1934 if (rate == urtw_ratetable[i].val)
1935 return urtw_ratetable[i].reg;
1942 urtw_update_msr(struct urtw_softc *sc)
1944 struct ieee80211com *ic = &sc->sc_ic;
1948 urtw_read8_m(sc, URTW_MSR, &data);
1949 data &= ~URTW_MSR_LINK_MASK;
1951 if (sc->sc_state == IEEE80211_S_RUN) {
1952 switch (ic->ic_opmode) {
1953 case IEEE80211_M_STA:
1954 case IEEE80211_M_MONITOR:
1955 data |= URTW_MSR_LINK_STA;
1956 if (sc->sc_flags & URTW_RTL8187B)
1957 data |= URTW_MSR_LINK_ENEDCA;
1959 case IEEE80211_M_IBSS:
1960 data |= URTW_MSR_LINK_ADHOC;
1962 case IEEE80211_M_HOSTAP:
1963 data |= URTW_MSR_LINK_HOSTAP;
1966 DPRINTF(sc, URTW_DEBUG_STATE,
1967 "unsupported operation mode 0x%x\n",
1969 error = USB_ERR_INVAL;
1973 data |= URTW_MSR_LINK_NONE;
1975 urtw_write8_m(sc, URTW_MSR, data);
1981 urtw_read8_c(struct urtw_softc *sc, int val, uint8_t *data)
1983 struct usb_device_request req;
1986 URTW_ASSERT_LOCKED(sc);
1988 req.bmRequestType = UT_READ_VENDOR_DEVICE;
1989 req.bRequest = URTW_8187_GETREGS_REQ;
1990 USETW(req.wValue, (val & 0xff) | 0xff00);
1991 USETW(req.wIndex, (val >> 8) & 0x3);
1992 USETW(req.wLength, sizeof(uint8_t));
1994 error = urtw_do_request(sc, &req, data);
1999 urtw_read16_c(struct urtw_softc *sc, int val, uint16_t *data)
2001 struct usb_device_request req;
2004 URTW_ASSERT_LOCKED(sc);
2006 req.bmRequestType = UT_READ_VENDOR_DEVICE;
2007 req.bRequest = URTW_8187_GETREGS_REQ;
2008 USETW(req.wValue, (val & 0xff) | 0xff00);
2009 USETW(req.wIndex, (val >> 8) & 0x3);
2010 USETW(req.wLength, sizeof(uint16_t));
2012 error = urtw_do_request(sc, &req, data);
2017 urtw_read32_c(struct urtw_softc *sc, int val, uint32_t *data)
2019 struct usb_device_request req;
2022 URTW_ASSERT_LOCKED(sc);
2024 req.bmRequestType = UT_READ_VENDOR_DEVICE;
2025 req.bRequest = URTW_8187_GETREGS_REQ;
2026 USETW(req.wValue, (val & 0xff) | 0xff00);
2027 USETW(req.wIndex, (val >> 8) & 0x3);
2028 USETW(req.wLength, sizeof(uint32_t));
2030 error = urtw_do_request(sc, &req, data);
2035 urtw_write8_c(struct urtw_softc *sc, int val, uint8_t data)
2037 struct usb_device_request req;
2039 URTW_ASSERT_LOCKED(sc);
2041 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
2042 req.bRequest = URTW_8187_SETREGS_REQ;
2043 USETW(req.wValue, (val & 0xff) | 0xff00);
2044 USETW(req.wIndex, (val >> 8) & 0x3);
2045 USETW(req.wLength, sizeof(uint8_t));
2047 return (urtw_do_request(sc, &req, &data));
2051 urtw_write16_c(struct urtw_softc *sc, int val, uint16_t data)
2053 struct usb_device_request req;
2055 URTW_ASSERT_LOCKED(sc);
2057 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
2058 req.bRequest = URTW_8187_SETREGS_REQ;
2059 USETW(req.wValue, (val & 0xff) | 0xff00);
2060 USETW(req.wIndex, (val >> 8) & 0x3);
2061 USETW(req.wLength, sizeof(uint16_t));
2063 return (urtw_do_request(sc, &req, &data));
2067 urtw_write32_c(struct urtw_softc *sc, int val, uint32_t data)
2069 struct usb_device_request req;
2071 URTW_ASSERT_LOCKED(sc);
2073 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
2074 req.bRequest = URTW_8187_SETREGS_REQ;
2075 USETW(req.wValue, (val & 0xff) | 0xff00);
2076 USETW(req.wIndex, (val >> 8) & 0x3);
2077 USETW(req.wLength, sizeof(uint32_t));
2079 return (urtw_do_request(sc, &req, &data));
2083 urtw_get_macaddr(struct urtw_softc *sc)
2085 struct ieee80211com *ic = &sc->sc_ic;
2089 error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR, &data);
2092 ic->ic_macaddr[0] = data & 0xff;
2093 ic->ic_macaddr[1] = (data & 0xff00) >> 8;
2094 error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR + 1, &data);
2097 ic->ic_macaddr[2] = data & 0xff;
2098 ic->ic_macaddr[3] = (data & 0xff00) >> 8;
2099 error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR + 2, &data);
2102 ic->ic_macaddr[4] = data & 0xff;
2103 ic->ic_macaddr[5] = (data & 0xff00) >> 8;
2109 urtw_eprom_read32(struct urtw_softc *sc, uint32_t addr, uint32_t *data)
2111 #define URTW_READCMD_LEN 3
2113 int16_t addrstr[8], data16, readcmd[] = { 1, 1, 0 };
2116 /* NB: make sure the buffer is initialized */
2119 /* enable EPROM programming */
2120 urtw_write8_m(sc, URTW_EPROM_CMD, URTW_EPROM_CMD_PROGRAM_MODE);
2121 DELAY(URTW_EPROM_DELAY);
2123 error = urtw_eprom_cs(sc, URTW_EPROM_ENABLE);
2126 error = urtw_eprom_ck(sc);
2129 error = urtw_eprom_sendbits(sc, readcmd, URTW_READCMD_LEN);
2132 if (sc->sc_epromtype == URTW_EEPROM_93C56) {
2134 addrstr[0] = addr & (1 << 7);
2135 addrstr[1] = addr & (1 << 6);
2136 addrstr[2] = addr & (1 << 5);
2137 addrstr[3] = addr & (1 << 4);
2138 addrstr[4] = addr & (1 << 3);
2139 addrstr[5] = addr & (1 << 2);
2140 addrstr[6] = addr & (1 << 1);
2141 addrstr[7] = addr & (1 << 0);
2144 addrstr[0] = addr & (1 << 5);
2145 addrstr[1] = addr & (1 << 4);
2146 addrstr[2] = addr & (1 << 3);
2147 addrstr[3] = addr & (1 << 2);
2148 addrstr[4] = addr & (1 << 1);
2149 addrstr[5] = addr & (1 << 0);
2151 error = urtw_eprom_sendbits(sc, addrstr, addrlen);
2155 error = urtw_eprom_writebit(sc, 0);
2159 for (i = 0; i < 16; i++) {
2160 error = urtw_eprom_ck(sc);
2163 error = urtw_eprom_readbit(sc, &data16);
2167 (*data) |= (data16 << (15 - i));
2170 error = urtw_eprom_cs(sc, URTW_EPROM_DISABLE);
2173 error = urtw_eprom_ck(sc);
2177 /* now disable EPROM programming */
2178 urtw_write8_m(sc, URTW_EPROM_CMD, URTW_EPROM_CMD_NORMAL_MODE);
2181 #undef URTW_READCMD_LEN
2185 urtw_eprom_cs(struct urtw_softc *sc, int able)
2190 urtw_read8_m(sc, URTW_EPROM_CMD, &data);
2191 if (able == URTW_EPROM_ENABLE)
2192 urtw_write8_m(sc, URTW_EPROM_CMD, data | URTW_EPROM_CS);
2194 urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_CS);
2195 DELAY(URTW_EPROM_DELAY);
2201 urtw_eprom_ck(struct urtw_softc *sc)
2207 urtw_read8_m(sc, URTW_EPROM_CMD, &data);
2208 urtw_write8_m(sc, URTW_EPROM_CMD, data | URTW_EPROM_CK);
2209 DELAY(URTW_EPROM_DELAY);
2211 urtw_read8_m(sc, URTW_EPROM_CMD, &data);
2212 urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_CK);
2213 DELAY(URTW_EPROM_DELAY);
2219 urtw_eprom_readbit(struct urtw_softc *sc, int16_t *data)
2224 urtw_read8_m(sc, URTW_EPROM_CMD, &data8);
2225 *data = (data8 & URTW_EPROM_READBIT) ? 1 : 0;
2226 DELAY(URTW_EPROM_DELAY);
2233 urtw_eprom_writebit(struct urtw_softc *sc, int16_t bit)
2238 urtw_read8_m(sc, URTW_EPROM_CMD, &data);
2240 urtw_write8_m(sc, URTW_EPROM_CMD, data | URTW_EPROM_WRITEBIT);
2242 urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_WRITEBIT);
2243 DELAY(URTW_EPROM_DELAY);
2249 urtw_eprom_sendbits(struct urtw_softc *sc, int16_t *buf, int buflen)
2252 usb_error_t error = 0;
2254 for (i = 0; i < buflen; i++) {
2255 error = urtw_eprom_writebit(sc, buf[i]);
2258 error = urtw_eprom_ck(sc);
2268 urtw_get_txpwr(struct urtw_softc *sc)
2274 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW_BASE, &data);
2277 sc->sc_txpwr_cck_base = data & 0xf;
2278 sc->sc_txpwr_ofdm_base = (data >> 4) & 0xf;
2280 for (i = 1, j = 0; i < 6; i += 2, j++) {
2281 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW0 + j, &data);
2284 sc->sc_txpwr_cck[i] = data & 0xf;
2285 sc->sc_txpwr_cck[i + 1] = (data & 0xf00) >> 8;
2286 sc->sc_txpwr_ofdm[i] = (data & 0xf0) >> 4;
2287 sc->sc_txpwr_ofdm[i + 1] = (data & 0xf000) >> 12;
2289 for (i = 1, j = 0; i < 4; i += 2, j++) {
2290 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW1 + j, &data);
2293 sc->sc_txpwr_cck[i + 6] = data & 0xf;
2294 sc->sc_txpwr_cck[i + 6 + 1] = (data & 0xf00) >> 8;
2295 sc->sc_txpwr_ofdm[i + 6] = (data & 0xf0) >> 4;
2296 sc->sc_txpwr_ofdm[i + 6 + 1] = (data & 0xf000) >> 12;
2298 if (sc->sc_flags & URTW_RTL8187B) {
2299 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW2, &data);
2302 sc->sc_txpwr_cck[1 + 6 + 4] = data & 0xf;
2303 sc->sc_txpwr_ofdm[1 + 6 + 4] = (data & 0xf0) >> 4;
2304 error = urtw_eprom_read32(sc, 0x0a, &data);
2307 sc->sc_txpwr_cck[2 + 6 + 4] = data & 0xf;
2308 sc->sc_txpwr_ofdm[2 + 6 + 4] = (data & 0xf0) >> 4;
2309 error = urtw_eprom_read32(sc, 0x1c, &data);
2312 sc->sc_txpwr_cck[3 + 6 + 4] = data & 0xf;
2313 sc->sc_txpwr_cck[3 + 6 + 4 + 1] = (data & 0xf00) >> 8;
2314 sc->sc_txpwr_ofdm[3 + 6 + 4] = (data & 0xf0) >> 4;
2315 sc->sc_txpwr_ofdm[3 + 6 + 4 + 1] = (data & 0xf000) >> 12;
2317 for (i = 1, j = 0; i < 4; i += 2, j++) {
2318 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW2 + j,
2322 sc->sc_txpwr_cck[i + 6 + 4] = data & 0xf;
2323 sc->sc_txpwr_cck[i + 6 + 4 + 1] = (data & 0xf00) >> 8;
2324 sc->sc_txpwr_ofdm[i + 6 + 4] = (data & 0xf0) >> 4;
2325 sc->sc_txpwr_ofdm[i + 6 + 4 + 1] = (data & 0xf000) >> 12;
2334 urtw_get_rfchip(struct urtw_softc *sc)
2341 if (sc->sc_flags & URTW_RTL8187B) {
2342 urtw_read8_m(sc, 0xe1, &data8);
2345 sc->sc_flags |= URTW_RTL8187B_REV_B;
2348 sc->sc_flags |= URTW_RTL8187B_REV_D;
2351 sc->sc_flags |= URTW_RTL8187B_REV_E;
2354 device_printf(sc->sc_dev, "unknown type: %#x\n", data8);
2355 sc->sc_flags |= URTW_RTL8187B_REV_B;
2359 urtw_read32_m(sc, URTW_TX_CONF, &data);
2360 switch (data & URTW_TX_HWMASK) {
2361 case URTW_TX_R8187vD_B:
2362 sc->sc_flags |= URTW_RTL8187B;
2364 case URTW_TX_R8187vD:
2367 device_printf(sc->sc_dev, "unknown RTL8187L type: %#x\n",
2368 data & URTW_TX_HWMASK);
2373 error = urtw_eprom_read32(sc, URTW_EPROM_RFCHIPID, &data);
2376 switch (data & 0xff) {
2377 case URTW_EPROM_RFCHIPID_RTL8225U:
2378 error = urtw_8225_isv2(sc, &ret);
2382 sc->sc_rf_init = urtw_8225_rf_init;
2383 sc->sc_rf_set_sens = urtw_8225_rf_set_sens;
2384 sc->sc_rf_set_chan = urtw_8225_rf_set_chan;
2385 sc->sc_rf_stop = urtw_8225_rf_stop;
2387 sc->sc_rf_init = urtw_8225v2_rf_init;
2388 sc->sc_rf_set_chan = urtw_8225v2_rf_set_chan;
2389 sc->sc_rf_stop = urtw_8225_rf_stop;
2391 sc->sc_max_sens = URTW_8225_RF_MAX_SENS;
2392 sc->sc_sens = URTW_8225_RF_DEF_SENS;
2394 case URTW_EPROM_RFCHIPID_RTL8225Z2:
2395 sc->sc_rf_init = urtw_8225v2b_rf_init;
2396 sc->sc_rf_set_chan = urtw_8225v2b_rf_set_chan;
2397 sc->sc_max_sens = URTW_8225_RF_MAX_SENS;
2398 sc->sc_sens = URTW_8225_RF_DEF_SENS;
2399 sc->sc_rf_stop = urtw_8225_rf_stop;
2402 DPRINTF(sc, URTW_DEBUG_STATE,
2403 "unsupported RF chip %d\n", data & 0xff);
2404 error = USB_ERR_INVAL;
2408 device_printf(sc->sc_dev, "%s rf %s hwrev %s\n",
2409 (sc->sc_flags & URTW_RTL8187B) ? "rtl8187b" : "rtl8187l",
2410 ((data & 0xff) == URTW_EPROM_RFCHIPID_RTL8225U) ? "rtl8225u" :
2412 (sc->sc_flags & URTW_RTL8187B) ? ((data8 == 0) ? "b" :
2413 (data8 == 1) ? "d" : "e") : "none");
2421 urtw_led_init(struct urtw_softc *sc)
2426 urtw_read8_m(sc, URTW_PSR, &sc->sc_psr);
2427 error = urtw_eprom_read32(sc, URTW_EPROM_SWREV, &rev);
2431 switch (rev & URTW_EPROM_CID_MASK) {
2432 case URTW_EPROM_CID_ALPHA0:
2433 sc->sc_strategy = URTW_SW_LED_MODE1;
2435 case URTW_EPROM_CID_SERCOMM_PS:
2436 sc->sc_strategy = URTW_SW_LED_MODE3;
2438 case URTW_EPROM_CID_HW_LED:
2439 sc->sc_strategy = URTW_HW_LED;
2441 case URTW_EPROM_CID_RSVD0:
2442 case URTW_EPROM_CID_RSVD1:
2444 sc->sc_strategy = URTW_SW_LED_MODE0;
2448 sc->sc_gpio_ledpin = URTW_LED_PIN_GPIO0;
2456 urtw_8225_rf_init(struct urtw_softc *sc)
2462 error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
2466 error = urtw_8225_usb_init(sc);
2470 urtw_write32_m(sc, URTW_RF_TIMING, 0x000a8008);
2471 urtw_read16_m(sc, URTW_BRSR, &data); /* XXX ??? */
2472 urtw_write16_m(sc, URTW_BRSR, 0xffff);
2473 urtw_write32_m(sc, URTW_RF_PARA, 0x100044);
2475 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
2478 urtw_write8_m(sc, URTW_CONFIG3, 0x44);
2479 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
2483 error = urtw_8185_rf_pins_enable(sc);
2486 usb_pause_mtx(&sc->sc_mtx, 1000);
2488 for (i = 0; i < nitems(urtw_8225_rf_part1); i++) {
2489 urtw_8225_write(sc, urtw_8225_rf_part1[i].reg,
2490 urtw_8225_rf_part1[i].val);
2491 usb_pause_mtx(&sc->sc_mtx, 1);
2493 usb_pause_mtx(&sc->sc_mtx, 100);
2495 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC1);
2496 usb_pause_mtx(&sc->sc_mtx, 200);
2498 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC2);
2499 usb_pause_mtx(&sc->sc_mtx, 200);
2501 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC3);
2503 for (i = 0; i < 95; i++) {
2504 urtw_8225_write(sc, URTW_8225_ADDR_1_MAGIC, (uint8_t)(i + 1));
2505 urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC, urtw_8225_rxgain[i]);
2509 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC4);
2511 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC5);
2513 for (i = 0; i < 128; i++) {
2514 urtw_8187_write_phy_ofdm(sc, 0xb, urtw_8225_agc[i]);
2515 usb_pause_mtx(&sc->sc_mtx, 1);
2516 urtw_8187_write_phy_ofdm(sc, 0xa, (uint8_t)i + 0x80);
2517 usb_pause_mtx(&sc->sc_mtx, 1);
2520 for (i = 0; i < nitems(urtw_8225_rf_part2); i++) {
2521 urtw_8187_write_phy_ofdm(sc, urtw_8225_rf_part2[i].reg,
2522 urtw_8225_rf_part2[i].val);
2523 usb_pause_mtx(&sc->sc_mtx, 1);
2526 error = urtw_8225_setgain(sc, 4);
2530 for (i = 0; i < nitems(urtw_8225_rf_part3); i++) {
2531 urtw_8187_write_phy_cck(sc, urtw_8225_rf_part3[i].reg,
2532 urtw_8225_rf_part3[i].val);
2533 usb_pause_mtx(&sc->sc_mtx, 1);
2536 urtw_write8_m(sc, URTW_TESTR, 0x0d);
2538 error = urtw_8225_set_txpwrlvl(sc, 1);
2542 urtw_8187_write_phy_cck(sc, 0x10, 0x9b);
2543 usb_pause_mtx(&sc->sc_mtx, 1);
2544 urtw_8187_write_phy_ofdm(sc, 0x26, 0x90);
2545 usb_pause_mtx(&sc->sc_mtx, 1);
2547 /* TX ant A, 0x0 for B */
2548 error = urtw_8185_tx_antenna(sc, 0x3);
2551 urtw_write32_m(sc, URTW_HSSI_PARA, 0x3dc00002);
2553 error = urtw_8225_rf_set_chan(sc, 1);
2559 urtw_8185_rf_pins_enable(struct urtw_softc *sc)
2561 usb_error_t error = 0;
2563 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x1ff7);
2569 urtw_8185_tx_antenna(struct urtw_softc *sc, uint8_t ant)
2573 urtw_write8_m(sc, URTW_TX_ANTENNA, ant);
2574 usb_pause_mtx(&sc->sc_mtx, 1);
2580 urtw_8187_write_phy_ofdm_c(struct urtw_softc *sc, uint8_t addr, uint32_t data)
2584 return urtw_8187_write_phy(sc, addr, data);
2588 urtw_8187_write_phy_cck_c(struct urtw_softc *sc, uint8_t addr, uint32_t data)
2592 return urtw_8187_write_phy(sc, addr, data | 0x10000);
2596 urtw_8187_write_phy(struct urtw_softc *sc, uint8_t addr, uint32_t data)
2601 phyw = ((data << 8) | (addr | 0x80));
2602 urtw_write8_m(sc, URTW_PHY_MAGIC4, ((phyw & 0xff000000) >> 24));
2603 urtw_write8_m(sc, URTW_PHY_MAGIC3, ((phyw & 0x00ff0000) >> 16));
2604 urtw_write8_m(sc, URTW_PHY_MAGIC2, ((phyw & 0x0000ff00) >> 8));
2605 urtw_write8_m(sc, URTW_PHY_MAGIC1, ((phyw & 0x000000ff)));
2606 usb_pause_mtx(&sc->sc_mtx, 1);
2612 urtw_8225_setgain(struct urtw_softc *sc, int16_t gain)
2616 urtw_8187_write_phy_ofdm(sc, 0x0d, urtw_8225_gain[gain * 4]);
2617 urtw_8187_write_phy_ofdm(sc, 0x1b, urtw_8225_gain[gain * 4 + 2]);
2618 urtw_8187_write_phy_ofdm(sc, 0x1d, urtw_8225_gain[gain * 4 + 3]);
2619 urtw_8187_write_phy_ofdm(sc, 0x23, urtw_8225_gain[gain * 4 + 1]);
2625 urtw_8225_usb_init(struct urtw_softc *sc)
2630 urtw_write8_m(sc, URTW_RF_PINS_SELECT + 1, 0);
2631 urtw_write8_m(sc, URTW_GPIO, 0);
2632 error = urtw_read8e(sc, 0x53, &data);
2635 error = urtw_write8e(sc, 0x53, data | (1 << 7));
2638 urtw_write8_m(sc, URTW_RF_PINS_SELECT + 1, 4);
2639 urtw_write8_m(sc, URTW_GPIO, 0x20);
2640 urtw_write8_m(sc, URTW_GP_ENABLE, 0);
2642 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, 0x80);
2643 urtw_write16_m(sc, URTW_RF_PINS_SELECT, 0x80);
2644 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x80);
2646 usb_pause_mtx(&sc->sc_mtx, 500);
2652 urtw_8225_write_c(struct urtw_softc *sc, uint8_t addr, uint16_t data)
2654 uint16_t d80, d82, d84;
2657 urtw_read16_m(sc, URTW_RF_PINS_OUTPUT, &d80);
2658 d80 &= URTW_RF_PINS_MAGIC1;
2659 urtw_read16_m(sc, URTW_RF_PINS_ENABLE, &d82);
2660 urtw_read16_m(sc, URTW_RF_PINS_SELECT, &d84);
2661 d84 &= URTW_RF_PINS_MAGIC2;
2662 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, d82 | URTW_RF_PINS_MAGIC3);
2663 urtw_write16_m(sc, URTW_RF_PINS_SELECT, d84 | URTW_RF_PINS_MAGIC3);
2666 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80 | URTW_BB_HOST_BANG_EN);
2668 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80);
2671 error = urtw_8225_write_s16(sc, addr, 0x8225, &data);
2675 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80 | URTW_BB_HOST_BANG_EN);
2677 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80 | URTW_BB_HOST_BANG_EN);
2678 urtw_write16_m(sc, URTW_RF_PINS_SELECT, d84);
2679 usb_pause_mtx(&sc->sc_mtx, 2);
2685 urtw_8225_write_s16(struct urtw_softc *sc, uint8_t addr, int index,
2690 struct usb_device_request req;
2691 usb_error_t error = 0;
2695 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
2696 req.bRequest = URTW_8187_SETREGS_REQ;
2697 USETW(req.wValue, addr);
2698 USETW(req.wIndex, index);
2699 USETW(req.wLength, sizeof(uint16_t));
2700 buf[0] = (data16 & 0x00ff);
2701 buf[1] = (data16 & 0xff00) >> 8;
2703 error = urtw_do_request(sc, &req, buf);
2709 urtw_8225_rf_set_chan(struct urtw_softc *sc, int chan)
2713 error = urtw_8225_set_txpwrlvl(sc, chan);
2716 urtw_8225_write(sc, URTW_8225_ADDR_7_MAGIC, urtw_8225_channel[chan]);
2717 usb_pause_mtx(&sc->sc_mtx, 10);
2723 urtw_8225_rf_set_sens(struct urtw_softc *sc, int sens)
2727 if (sens < 0 || sens > 6)
2732 URTW_8225_ADDR_C_MAGIC, URTW_8225_ADDR_C_DATA_MAGIC1);
2735 URTW_8225_ADDR_C_MAGIC, URTW_8225_ADDR_C_DATA_MAGIC2);
2738 error = urtw_8225_setgain(sc, sens);
2742 urtw_8187_write_phy_cck(sc, 0x41, urtw_8225_threshold[sens]);
2749 urtw_8225_set_txpwrlvl(struct urtw_softc *sc, int chan)
2752 uint8_t *cck_pwltable;
2753 uint8_t cck_pwrlvl_max, ofdm_pwrlvl_min, ofdm_pwrlvl_max;
2754 uint8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
2755 uint8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
2758 cck_pwrlvl_max = 11;
2759 ofdm_pwrlvl_max = 25; /* 12 -> 25 */
2760 ofdm_pwrlvl_min = 10;
2762 /* CCK power setting */
2763 cck_pwrlvl = (cck_pwrlvl > cck_pwrlvl_max) ? cck_pwrlvl_max : cck_pwrlvl;
2764 idx = cck_pwrlvl % 6;
2765 set = cck_pwrlvl / 6;
2766 cck_pwltable = (chan == 14) ? urtw_8225_txpwr_cck_ch14 :
2767 urtw_8225_txpwr_cck;
2769 urtw_write8_m(sc, URTW_TX_GAIN_CCK,
2770 urtw_8225_tx_gain_cck_ofdm[set] >> 1);
2771 for (i = 0; i < 8; i++) {
2772 urtw_8187_write_phy_cck(sc, 0x44 + i,
2773 cck_pwltable[idx * 8 + i]);
2775 usb_pause_mtx(&sc->sc_mtx, 1);
2777 /* OFDM power setting */
2778 ofdm_pwrlvl = (ofdm_pwrlvl > (ofdm_pwrlvl_max - ofdm_pwrlvl_min)) ?
2779 ofdm_pwrlvl_max : ofdm_pwrlvl + ofdm_pwrlvl_min;
2780 ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
2782 idx = ofdm_pwrlvl % 6;
2783 set = ofdm_pwrlvl / 6;
2785 error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
2788 urtw_8187_write_phy_ofdm(sc, 2, 0x42);
2789 urtw_8187_write_phy_ofdm(sc, 6, 0);
2790 urtw_8187_write_phy_ofdm(sc, 8, 0);
2792 urtw_write8_m(sc, URTW_TX_GAIN_OFDM,
2793 urtw_8225_tx_gain_cck_ofdm[set] >> 1);
2794 urtw_8187_write_phy_ofdm(sc, 0x5, urtw_8225_txpwr_ofdm[idx]);
2795 urtw_8187_write_phy_ofdm(sc, 0x7, urtw_8225_txpwr_ofdm[idx]);
2796 usb_pause_mtx(&sc->sc_mtx, 1);
2803 urtw_8225_rf_stop(struct urtw_softc *sc)
2808 urtw_8225_write(sc, 0x4, 0x1f);
2810 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
2814 urtw_read8_m(sc, URTW_CONFIG3, &data);
2815 urtw_write8_m(sc, URTW_CONFIG3, data | URTW_CONFIG3_ANAPARAM_WRITE);
2816 if (sc->sc_flags & URTW_RTL8187B) {
2817 urtw_write32_m(sc, URTW_ANAPARAM2,
2818 URTW_8187B_8225_ANAPARAM2_OFF);
2819 urtw_write32_m(sc, URTW_ANAPARAM, URTW_8187B_8225_ANAPARAM_OFF);
2820 urtw_write32_m(sc, URTW_ANAPARAM3,
2821 URTW_8187B_8225_ANAPARAM3_OFF);
2823 urtw_write32_m(sc, URTW_ANAPARAM2, URTW_8225_ANAPARAM2_OFF);
2824 urtw_write32_m(sc, URTW_ANAPARAM, URTW_8225_ANAPARAM_OFF);
2827 urtw_write8_m(sc, URTW_CONFIG3, data & ~URTW_CONFIG3_ANAPARAM_WRITE);
2828 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
2837 urtw_8225v2_rf_init(struct urtw_softc *sc)
2844 error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
2848 error = urtw_8225_usb_init(sc);
2852 urtw_write32_m(sc, URTW_RF_TIMING, 0x000a8008);
2853 urtw_read16_m(sc, URTW_BRSR, &data); /* XXX ??? */
2854 urtw_write16_m(sc, URTW_BRSR, 0xffff);
2855 urtw_write32_m(sc, URTW_RF_PARA, 0x100044);
2857 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
2860 urtw_write8_m(sc, URTW_CONFIG3, 0x44);
2861 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
2865 error = urtw_8185_rf_pins_enable(sc);
2869 usb_pause_mtx(&sc->sc_mtx, 500);
2871 for (i = 0; i < nitems(urtw_8225v2_rf_part1); i++) {
2872 urtw_8225_write(sc, urtw_8225v2_rf_part1[i].reg,
2873 urtw_8225v2_rf_part1[i].val);
2875 usb_pause_mtx(&sc->sc_mtx, 50);
2878 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC1);
2880 for (i = 0; i < 95; i++) {
2881 urtw_8225_write(sc, URTW_8225_ADDR_1_MAGIC, (uint8_t)(i + 1));
2882 urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC,
2883 urtw_8225v2_rxgain[i]);
2887 URTW_8225_ADDR_3_MAGIC, URTW_8225_ADDR_3_DATA_MAGIC1);
2889 URTW_8225_ADDR_5_MAGIC, URTW_8225_ADDR_5_DATA_MAGIC1);
2891 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC2);
2893 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC1);
2894 usb_pause_mtx(&sc->sc_mtx, 100);
2896 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC2);
2897 usb_pause_mtx(&sc->sc_mtx, 100);
2899 error = urtw_8225_read(sc, URTW_8225_ADDR_6_MAGIC, &data32);
2902 if (data32 != URTW_8225_ADDR_6_DATA_MAGIC1)
2903 device_printf(sc->sc_dev, "expect 0xe6!! (0x%x)\n", data32);
2904 if (!(data32 & URTW_8225_ADDR_6_DATA_MAGIC2)) {
2906 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC1);
2907 usb_pause_mtx(&sc->sc_mtx, 100);
2909 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC2);
2910 usb_pause_mtx(&sc->sc_mtx, 50);
2911 error = urtw_8225_read(sc, URTW_8225_ADDR_6_MAGIC, &data32);
2914 if (!(data32 & URTW_8225_ADDR_6_DATA_MAGIC2))
2915 device_printf(sc->sc_dev, "RF calibration failed\n");
2917 usb_pause_mtx(&sc->sc_mtx, 100);
2920 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC6);
2921 for (i = 0; i < 128; i++) {
2922 urtw_8187_write_phy_ofdm(sc, 0xb, urtw_8225_agc[i]);
2923 urtw_8187_write_phy_ofdm(sc, 0xa, (uint8_t)i + 0x80);
2926 for (i = 0; i < nitems(urtw_8225v2_rf_part2); i++) {
2927 urtw_8187_write_phy_ofdm(sc, urtw_8225v2_rf_part2[i].reg,
2928 urtw_8225v2_rf_part2[i].val);
2931 error = urtw_8225v2_setgain(sc, 4);
2935 for (i = 0; i < nitems(urtw_8225v2_rf_part3); i++) {
2936 urtw_8187_write_phy_cck(sc, urtw_8225v2_rf_part3[i].reg,
2937 urtw_8225v2_rf_part3[i].val);
2940 urtw_write8_m(sc, URTW_TESTR, 0x0d);
2942 error = urtw_8225v2_set_txpwrlvl(sc, 1);
2946 urtw_8187_write_phy_cck(sc, 0x10, 0x9b);
2947 urtw_8187_write_phy_ofdm(sc, 0x26, 0x90);
2949 /* TX ant A, 0x0 for B */
2950 error = urtw_8185_tx_antenna(sc, 0x3);
2953 urtw_write32_m(sc, URTW_HSSI_PARA, 0x3dc00002);
2955 error = urtw_8225_rf_set_chan(sc, 1);
2961 urtw_8225v2_rf_set_chan(struct urtw_softc *sc, int chan)
2965 error = urtw_8225v2_set_txpwrlvl(sc, chan);
2969 urtw_8225_write(sc, URTW_8225_ADDR_7_MAGIC, urtw_8225_channel[chan]);
2970 usb_pause_mtx(&sc->sc_mtx, 10);
2976 urtw_8225_read(struct urtw_softc *sc, uint8_t addr, uint32_t *data)
2980 uint8_t rlen = 12, wlen = 6;
2981 uint16_t o1, o2, o3, tmp;
2982 uint32_t d2w = ((uint32_t)(addr & 0x1f)) << 27;
2983 uint32_t mask = 0x80000000, value = 0;
2986 urtw_read16_m(sc, URTW_RF_PINS_OUTPUT, &o1);
2987 urtw_read16_m(sc, URTW_RF_PINS_ENABLE, &o2);
2988 urtw_read16_m(sc, URTW_RF_PINS_SELECT, &o3);
2989 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, o2 | URTW_RF_PINS_MAGIC4);
2990 urtw_write16_m(sc, URTW_RF_PINS_SELECT, o3 | URTW_RF_PINS_MAGIC4);
2991 o1 &= ~URTW_RF_PINS_MAGIC4;
2992 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1 | URTW_BB_HOST_BANG_EN);
2994 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1);
2997 for (i = 0; i < (wlen / 2); i++, mask = mask >> 1) {
2998 bit = ((d2w & mask) != 0) ? 1 : 0;
3000 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1);
3002 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
3003 URTW_BB_HOST_BANG_CLK);
3005 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
3006 URTW_BB_HOST_BANG_CLK);
3011 bit = ((d2w & mask) != 0) ? 1 : 0;
3012 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
3013 URTW_BB_HOST_BANG_CLK);
3015 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
3016 URTW_BB_HOST_BANG_CLK);
3018 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1);
3021 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 | URTW_BB_HOST_BANG_RW |
3022 URTW_BB_HOST_BANG_CLK);
3024 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 | URTW_BB_HOST_BANG_RW);
3026 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1 | URTW_BB_HOST_BANG_RW);
3030 for (i = 0; i < rlen; i++, mask = mask >> 1) {
3031 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
3032 o1 | URTW_BB_HOST_BANG_RW);
3034 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
3035 o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK);
3037 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
3038 o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK);
3040 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
3041 o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK);
3044 urtw_read16_m(sc, URTW_RF_PINS_INPUT, &tmp);
3045 value |= ((tmp & URTW_BB_HOST_BANG_CLK) ? mask : 0);
3046 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
3047 o1 | URTW_BB_HOST_BANG_RW);
3051 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1 | URTW_BB_HOST_BANG_EN |
3052 URTW_BB_HOST_BANG_RW);
3055 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, o2);
3056 urtw_write16_m(sc, URTW_RF_PINS_SELECT, o3);
3057 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, URTW_RF_PINS_OUTPUT_MAGIC1);
3067 urtw_8225v2_set_txpwrlvl(struct urtw_softc *sc, int chan)
3070 uint8_t *cck_pwrtable;
3071 uint8_t cck_pwrlvl_max = 15, ofdm_pwrlvl_max = 25, ofdm_pwrlvl_min = 10;
3072 uint8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
3073 uint8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
3076 /* CCK power setting */
3077 cck_pwrlvl = (cck_pwrlvl > cck_pwrlvl_max) ? cck_pwrlvl_max : cck_pwrlvl;
3078 cck_pwrlvl += sc->sc_txpwr_cck_base;
3079 cck_pwrlvl = (cck_pwrlvl > 35) ? 35 : cck_pwrlvl;
3080 cck_pwrtable = (chan == 14) ? urtw_8225v2_txpwr_cck_ch14 :
3081 urtw_8225v2_txpwr_cck;
3083 for (i = 0; i < 8; i++)
3084 urtw_8187_write_phy_cck(sc, 0x44 + i, cck_pwrtable[i]);
3086 urtw_write8_m(sc, URTW_TX_GAIN_CCK,
3087 urtw_8225v2_tx_gain_cck_ofdm[cck_pwrlvl]);
3088 usb_pause_mtx(&sc->sc_mtx, 1);
3090 /* OFDM power setting */
3091 ofdm_pwrlvl = (ofdm_pwrlvl > (ofdm_pwrlvl_max - ofdm_pwrlvl_min)) ?
3092 ofdm_pwrlvl_max : ofdm_pwrlvl + ofdm_pwrlvl_min;
3093 ofdm_pwrlvl += sc->sc_txpwr_ofdm_base;
3094 ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
3096 error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
3100 urtw_8187_write_phy_ofdm(sc, 2, 0x42);
3101 urtw_8187_write_phy_ofdm(sc, 5, 0x0);
3102 urtw_8187_write_phy_ofdm(sc, 6, 0x40);
3103 urtw_8187_write_phy_ofdm(sc, 7, 0x0);
3104 urtw_8187_write_phy_ofdm(sc, 8, 0x40);
3106 urtw_write8_m(sc, URTW_TX_GAIN_OFDM,
3107 urtw_8225v2_tx_gain_cck_ofdm[ofdm_pwrlvl]);
3108 usb_pause_mtx(&sc->sc_mtx, 1);
3114 urtw_8225v2_setgain(struct urtw_softc *sc, int16_t gain)
3120 gainp = urtw_8225v2_gain_bg;
3121 urtw_8187_write_phy_ofdm(sc, 0x0d, gainp[gain * 3]);
3122 usb_pause_mtx(&sc->sc_mtx, 1);
3123 urtw_8187_write_phy_ofdm(sc, 0x1b, gainp[gain * 3 + 1]);
3124 usb_pause_mtx(&sc->sc_mtx, 1);
3125 urtw_8187_write_phy_ofdm(sc, 0x1d, gainp[gain * 3 + 2]);
3126 usb_pause_mtx(&sc->sc_mtx, 1);
3127 urtw_8187_write_phy_ofdm(sc, 0x21, 0x17);
3128 usb_pause_mtx(&sc->sc_mtx, 1);
3134 urtw_8225_isv2(struct urtw_softc *sc, int *ret)
3141 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, URTW_RF_PINS_MAGIC5);
3142 urtw_write16_m(sc, URTW_RF_PINS_SELECT, URTW_RF_PINS_MAGIC5);
3143 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, URTW_RF_PINS_MAGIC5);
3144 usb_pause_mtx(&sc->sc_mtx, 500);
3146 urtw_8225_write(sc, URTW_8225_ADDR_0_MAGIC,
3147 URTW_8225_ADDR_0_DATA_MAGIC1);
3149 error = urtw_8225_read(sc, URTW_8225_ADDR_8_MAGIC, &data);
3152 if (data != URTW_8225_ADDR_8_DATA_MAGIC1)
3155 error = urtw_8225_read(sc, URTW_8225_ADDR_9_MAGIC, &data);
3158 if (data != URTW_8225_ADDR_9_DATA_MAGIC1)
3162 urtw_8225_write(sc, URTW_8225_ADDR_0_MAGIC,
3163 URTW_8225_ADDR_0_DATA_MAGIC2);
3169 urtw_8225v2b_rf_init(struct urtw_softc *sc)
3171 struct ieee80211com *ic = &sc->sc_ic;
3176 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3181 * initialize extra registers on 8187
3183 urtw_write16_m(sc, URTW_BRSR_8187B, 0xfff);
3186 urtw_read8_m(sc, URTW_CW_CONF, &data8);
3187 data8 |= URTW_CW_CONF_PERPACKET_RETRY;
3188 urtw_write8_m(sc, URTW_CW_CONF, data8);
3191 urtw_read8_m(sc, URTW_TX_AGC_CTL, &data8);
3192 data8 |= URTW_TX_AGC_CTL_PERPACKET_GAIN;
3193 urtw_write8_m(sc, URTW_TX_AGC_CTL, data8);
3195 /* Auto Rate Fallback Control */
3196 #define URTW_ARFR 0x1e0
3197 urtw_write16_m(sc, URTW_ARFR, 0xfff);
3198 urtw_read8_m(sc, URTW_RATE_FALLBACK, &data8);
3199 urtw_write8_m(sc, URTW_RATE_FALLBACK,
3200 data8 | URTW_RATE_FALLBACK_ENABLE);
3202 urtw_read8_m(sc, URTW_MSR, &data8);
3203 urtw_write8_m(sc, URTW_MSR, data8 & 0xf3);
3204 urtw_read8_m(sc, URTW_MSR, &data8);
3205 urtw_write8_m(sc, URTW_MSR, data8 | URTW_MSR_LINK_ENEDCA);
3206 urtw_write8_m(sc, URTW_ACM_CONTROL, sc->sc_acmctl);
3208 urtw_write16_m(sc, URTW_ATIM_WND, 2);
3209 urtw_write16_m(sc, URTW_BEACON_INTERVAL, 100);
3210 #define URTW_FEMR_FOR_8187B 0x1d4
3211 urtw_write16_m(sc, URTW_FEMR_FOR_8187B, 0xffff);
3214 urtw_read8_m(sc, URTW_CONFIG1, &data8);
3215 data8 = (data8 & 0x3f) | 0x80;
3216 urtw_write8_m(sc, URTW_CONFIG1, data8);
3218 /* applying MAC address again. */
3219 urtw_write32_m(sc, URTW_MAC0, ((uint32_t *)ic->ic_macaddr)[0]);
3220 urtw_write16_m(sc, URTW_MAC4, ((uint32_t *)ic->ic_macaddr)[1] & 0xffff);
3222 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3226 urtw_write8_m(sc, URTW_WPA_CONFIG, 0);
3231 for (i = 0; i < nitems(urtw_8225v2b_rf_part1); i++)
3232 urtw_write8_m(sc, urtw_8225v2b_rf_part1[i].reg,
3233 urtw_8225v2b_rf_part1[i].val);
3234 urtw_write16_m(sc, URTW_TID_AC_MAP, 0xfa50);
3235 urtw_write16_m(sc, URTW_INT_MIG, 0x0000);
3236 urtw_write32_m(sc, 0x1f0, 0);
3237 urtw_write32_m(sc, 0x1f4, 0);
3238 urtw_write8_m(sc, 0x1f8, 0);
3239 urtw_write32_m(sc, URTW_RF_TIMING, 0x4001);
3241 #define URTW_RFSW_CTRL 0x272
3242 urtw_write16_m(sc, URTW_RFSW_CTRL, 0x569a);
3247 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3250 urtw_read8_m(sc, URTW_CONFIG3, &data8);
3251 urtw_write8_m(sc, URTW_CONFIG3,
3252 data8 | URTW_CONFIG3_ANAPARAM_WRITE);
3254 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3258 /* setup RFE initial timing */
3259 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, 0x0480);
3260 urtw_write16_m(sc, URTW_RF_PINS_SELECT, 0x2488);
3261 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x1fff);
3262 usb_pause_mtx(&sc->sc_mtx, 1100);
3264 for (i = 0; i < nitems(urtw_8225v2b_rf_part0); i++) {
3265 urtw_8225_write(sc, urtw_8225v2b_rf_part0[i].reg,
3266 urtw_8225v2b_rf_part0[i].val);
3267 usb_pause_mtx(&sc->sc_mtx, 1);
3269 urtw_8225_write(sc, 0x00, 0x01b7);
3271 for (i = 0; i < 95; i++) {
3272 urtw_8225_write(sc, URTW_8225_ADDR_1_MAGIC, (uint8_t)(i + 1));
3273 usb_pause_mtx(&sc->sc_mtx, 1);
3274 urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC,
3275 urtw_8225v2b_rxgain[i]);
3276 usb_pause_mtx(&sc->sc_mtx, 1);
3279 urtw_8225_write(sc, URTW_8225_ADDR_3_MAGIC, 0x080);
3280 usb_pause_mtx(&sc->sc_mtx, 1);
3281 urtw_8225_write(sc, URTW_8225_ADDR_5_MAGIC, 0x004);
3282 usb_pause_mtx(&sc->sc_mtx, 1);
3283 urtw_8225_write(sc, URTW_8225_ADDR_0_MAGIC, 0x0b7);
3284 usb_pause_mtx(&sc->sc_mtx, 1);
3285 usb_pause_mtx(&sc->sc_mtx, 3000);
3286 urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC, 0xc4d);
3287 usb_pause_mtx(&sc->sc_mtx, 2000);
3288 urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC, 0x44d);
3289 usb_pause_mtx(&sc->sc_mtx, 1);
3290 urtw_8225_write(sc, URTW_8225_ADDR_0_MAGIC, 0x2bf);
3291 usb_pause_mtx(&sc->sc_mtx, 1);
3293 urtw_write8_m(sc, URTW_TX_GAIN_CCK, 0x03);
3294 urtw_write8_m(sc, URTW_TX_GAIN_OFDM, 0x07);
3295 urtw_write8_m(sc, URTW_TX_ANTENNA, 0x03);
3297 urtw_8187_write_phy_ofdm(sc, 0x80, 0x12);
3298 for (i = 0; i < 128; i++) {
3299 uint32_t addr, data;
3301 data = (urtw_8225z2_agc[i] << 8) | 0x0000008f;
3302 addr = ((i + 0x80) << 8) | 0x0000008e;
3304 urtw_8187_write_phy_ofdm(sc, data & 0x7f, (data >> 8) & 0xff);
3305 urtw_8187_write_phy_ofdm(sc, addr & 0x7f, (addr >> 8) & 0xff);
3306 urtw_8187_write_phy_ofdm(sc, 0x0e, 0x00);
3308 urtw_8187_write_phy_ofdm(sc, 0x80, 0x10);
3310 for (i = 0; i < nitems(urtw_8225v2b_rf_part2); i++)
3311 urtw_8187_write_phy_ofdm(sc, i, urtw_8225v2b_rf_part2[i].val);
3313 urtw_write32_m(sc, URTW_8187B_AC_VO, (7 << 12) | (3 << 8) | 0x1c);
3314 urtw_write32_m(sc, URTW_8187B_AC_VI, (7 << 12) | (3 << 8) | 0x1c);
3315 urtw_write32_m(sc, URTW_8187B_AC_BE, (7 << 12) | (3 << 8) | 0x1c);
3316 urtw_write32_m(sc, URTW_8187B_AC_BK, (7 << 12) | (3 << 8) | 0x1c);
3318 urtw_8187_write_phy_ofdm(sc, 0x97, 0x46);
3319 urtw_8187_write_phy_ofdm(sc, 0xa4, 0xb6);
3320 urtw_8187_write_phy_ofdm(sc, 0x85, 0xfc);
3321 urtw_8187_write_phy_cck(sc, 0xc1, 0x88);
3328 urtw_8225v2b_rf_set_chan(struct urtw_softc *sc, int chan)
3332 error = urtw_8225v2b_set_txpwrlvl(sc, chan);
3336 urtw_8225_write(sc, URTW_8225_ADDR_7_MAGIC, urtw_8225_channel[chan]);
3337 usb_pause_mtx(&sc->sc_mtx, 10);
3343 urtw_8225v2b_set_txpwrlvl(struct urtw_softc *sc, int chan)
3346 uint8_t *cck_pwrtable;
3347 uint8_t cck_pwrlvl_max = 15;
3348 uint8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
3349 uint8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
3352 /* CCK power setting */
3353 cck_pwrlvl = (cck_pwrlvl > cck_pwrlvl_max) ?
3354 ((sc->sc_flags & URTW_RTL8187B_REV_B) ? cck_pwrlvl_max : 22) :
3355 (cck_pwrlvl + ((sc->sc_flags & URTW_RTL8187B_REV_B) ? 0 : 7));
3356 cck_pwrlvl += sc->sc_txpwr_cck_base;
3357 cck_pwrlvl = (cck_pwrlvl > 35) ? 35 : cck_pwrlvl;
3358 cck_pwrtable = (chan == 14) ? urtw_8225v2b_txpwr_cck_ch14 :
3359 urtw_8225v2b_txpwr_cck;
3361 if (sc->sc_flags & URTW_RTL8187B_REV_B)
3362 cck_pwrtable += (cck_pwrlvl <= 6) ? 0 :
3363 ((cck_pwrlvl <= 11) ? 8 : 16);
3365 cck_pwrtable += (cck_pwrlvl <= 5) ? 0 :
3366 ((cck_pwrlvl <= 11) ? 8 : ((cck_pwrlvl <= 17) ? 16 : 24));
3368 for (i = 0; i < 8; i++)
3369 urtw_8187_write_phy_cck(sc, 0x44 + i, cck_pwrtable[i]);
3371 urtw_write8_m(sc, URTW_TX_GAIN_CCK,
3372 urtw_8225v2_tx_gain_cck_ofdm[cck_pwrlvl] << 1);
3373 usb_pause_mtx(&sc->sc_mtx, 1);
3375 /* OFDM power setting */
3376 ofdm_pwrlvl = (ofdm_pwrlvl > 15) ?
3377 ((sc->sc_flags & URTW_RTL8187B_REV_B) ? 17 : 25) :
3378 (ofdm_pwrlvl + ((sc->sc_flags & URTW_RTL8187B_REV_B) ? 2 : 10));
3379 ofdm_pwrlvl += sc->sc_txpwr_ofdm_base;
3380 ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
3382 urtw_write8_m(sc, URTW_TX_GAIN_OFDM,
3383 urtw_8225v2_tx_gain_cck_ofdm[ofdm_pwrlvl] << 1);
3385 if (sc->sc_flags & URTW_RTL8187B_REV_B) {
3386 if (ofdm_pwrlvl <= 11) {
3387 urtw_8187_write_phy_ofdm(sc, 0x87, 0x60);
3388 urtw_8187_write_phy_ofdm(sc, 0x89, 0x60);
3390 urtw_8187_write_phy_ofdm(sc, 0x87, 0x5c);
3391 urtw_8187_write_phy_ofdm(sc, 0x89, 0x5c);
3394 if (ofdm_pwrlvl <= 11) {
3395 urtw_8187_write_phy_ofdm(sc, 0x87, 0x5c);
3396 urtw_8187_write_phy_ofdm(sc, 0x89, 0x5c);
3397 } else if (ofdm_pwrlvl <= 17) {
3398 urtw_8187_write_phy_ofdm(sc, 0x87, 0x54);
3399 urtw_8187_write_phy_ofdm(sc, 0x89, 0x54);
3401 urtw_8187_write_phy_ofdm(sc, 0x87, 0x50);
3402 urtw_8187_write_phy_ofdm(sc, 0x89, 0x50);
3405 usb_pause_mtx(&sc->sc_mtx, 1);
3411 urtw_read8e(struct urtw_softc *sc, int val, uint8_t *data)
3413 struct usb_device_request req;
3416 req.bmRequestType = UT_READ_VENDOR_DEVICE;
3417 req.bRequest = URTW_8187_GETREGS_REQ;
3418 USETW(req.wValue, val | 0xfe00);
3419 USETW(req.wIndex, 0);
3420 USETW(req.wLength, sizeof(uint8_t));
3422 error = urtw_do_request(sc, &req, data);
3427 urtw_write8e(struct urtw_softc *sc, int val, uint8_t data)
3429 struct usb_device_request req;
3431 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
3432 req.bRequest = URTW_8187_SETREGS_REQ;
3433 USETW(req.wValue, val | 0xfe00);
3434 USETW(req.wIndex, 0);
3435 USETW(req.wLength, sizeof(uint8_t));
3437 return (urtw_do_request(sc, &req, &data));
3441 urtw_8180_set_anaparam(struct urtw_softc *sc, uint32_t val)
3446 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3450 urtw_read8_m(sc, URTW_CONFIG3, &data);
3451 urtw_write8_m(sc, URTW_CONFIG3, data | URTW_CONFIG3_ANAPARAM_WRITE);
3452 urtw_write32_m(sc, URTW_ANAPARAM, val);
3453 urtw_read8_m(sc, URTW_CONFIG3, &data);
3454 urtw_write8_m(sc, URTW_CONFIG3, data & ~URTW_CONFIG3_ANAPARAM_WRITE);
3456 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3464 urtw_8185_set_anaparam2(struct urtw_softc *sc, uint32_t val)
3469 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3473 urtw_read8_m(sc, URTW_CONFIG3, &data);
3474 urtw_write8_m(sc, URTW_CONFIG3, data | URTW_CONFIG3_ANAPARAM_WRITE);
3475 urtw_write32_m(sc, URTW_ANAPARAM2, val);
3476 urtw_read8_m(sc, URTW_CONFIG3, &data);
3477 urtw_write8_m(sc, URTW_CONFIG3, data & ~URTW_CONFIG3_ANAPARAM_WRITE);
3479 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3487 urtw_intr_enable(struct urtw_softc *sc)
3491 urtw_write16_m(sc, URTW_INTR_MASK, 0xffff);
3497 urtw_intr_disable(struct urtw_softc *sc)
3501 urtw_write16_m(sc, URTW_INTR_MASK, 0);
3507 urtw_reset(struct urtw_softc *sc)
3512 error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
3515 error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
3519 error = urtw_intr_disable(sc);
3522 usb_pause_mtx(&sc->sc_mtx, 100);
3524 error = urtw_write8e(sc, 0x18, 0x10);
3527 error = urtw_write8e(sc, 0x18, 0x11);
3530 error = urtw_write8e(sc, 0x18, 0x00);
3533 usb_pause_mtx(&sc->sc_mtx, 100);
3535 urtw_read8_m(sc, URTW_CMD, &data);
3536 data = (data & 0x2) | URTW_CMD_RST;
3537 urtw_write8_m(sc, URTW_CMD, data);
3538 usb_pause_mtx(&sc->sc_mtx, 100);
3540 urtw_read8_m(sc, URTW_CMD, &data);
3541 if (data & URTW_CMD_RST) {
3542 device_printf(sc->sc_dev, "reset timeout\n");
3546 error = urtw_set_mode(sc, URTW_EPROM_CMD_LOAD);
3549 usb_pause_mtx(&sc->sc_mtx, 100);
3551 error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
3554 error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
3562 urtw_led_ctl(struct urtw_softc *sc, int mode)
3564 usb_error_t error = 0;
3566 switch (sc->sc_strategy) {
3567 case URTW_SW_LED_MODE0:
3568 error = urtw_led_mode0(sc, mode);
3570 case URTW_SW_LED_MODE1:
3571 error = urtw_led_mode1(sc, mode);
3573 case URTW_SW_LED_MODE2:
3574 error = urtw_led_mode2(sc, mode);
3576 case URTW_SW_LED_MODE3:
3577 error = urtw_led_mode3(sc, mode);
3580 DPRINTF(sc, URTW_DEBUG_STATE,
3581 "unsupported LED mode %d\n", sc->sc_strategy);
3582 error = USB_ERR_INVAL;
3590 urtw_led_mode0(struct urtw_softc *sc, int mode)
3594 case URTW_LED_CTL_POWER_ON:
3595 sc->sc_gpio_ledstate = URTW_LED_POWER_ON_BLINK;
3597 case URTW_LED_CTL_TX:
3598 if (sc->sc_gpio_ledinprogress == 1)
3601 sc->sc_gpio_ledstate = URTW_LED_BLINK_NORMAL;
3602 sc->sc_gpio_blinktime = 2;
3604 case URTW_LED_CTL_LINK:
3605 sc->sc_gpio_ledstate = URTW_LED_ON;
3608 DPRINTF(sc, URTW_DEBUG_STATE,
3609 "unsupported LED mode 0x%x", mode);
3610 return (USB_ERR_INVAL);
3613 switch (sc->sc_gpio_ledstate) {
3615 if (sc->sc_gpio_ledinprogress != 0)
3617 urtw_led_on(sc, URTW_LED_GPIO);
3619 case URTW_LED_BLINK_NORMAL:
3620 if (sc->sc_gpio_ledinprogress != 0)
3622 sc->sc_gpio_ledinprogress = 1;
3623 sc->sc_gpio_blinkstate = (sc->sc_gpio_ledon != 0) ?
3624 URTW_LED_OFF : URTW_LED_ON;
3625 usb_callout_reset(&sc->sc_led_ch, hz, urtw_led_ch, sc);
3627 case URTW_LED_POWER_ON_BLINK:
3628 urtw_led_on(sc, URTW_LED_GPIO);
3629 usb_pause_mtx(&sc->sc_mtx, 100);
3630 urtw_led_off(sc, URTW_LED_GPIO);
3633 DPRINTF(sc, URTW_DEBUG_STATE,
3634 "unknown LED status 0x%x", sc->sc_gpio_ledstate);
3635 return (USB_ERR_INVAL);
3641 urtw_led_mode1(struct urtw_softc *sc, int mode)
3643 return (USB_ERR_INVAL);
3647 urtw_led_mode2(struct urtw_softc *sc, int mode)
3649 return (USB_ERR_INVAL);
3653 urtw_led_mode3(struct urtw_softc *sc, int mode)
3655 return (USB_ERR_INVAL);
3659 urtw_led_on(struct urtw_softc *sc, int type)
3663 if (type == URTW_LED_GPIO) {
3664 switch (sc->sc_gpio_ledpin) {
3665 case URTW_LED_PIN_GPIO0:
3666 urtw_write8_m(sc, URTW_GPIO, 0x01);
3667 urtw_write8_m(sc, URTW_GP_ENABLE, 0x00);
3670 DPRINTF(sc, URTW_DEBUG_STATE,
3671 "unsupported LED PIN type 0x%x",
3672 sc->sc_gpio_ledpin);
3673 error = USB_ERR_INVAL;
3677 DPRINTF(sc, URTW_DEBUG_STATE,
3678 "unsupported LED type 0x%x", type);
3679 error = USB_ERR_INVAL;
3683 sc->sc_gpio_ledon = 1;
3689 urtw_led_off(struct urtw_softc *sc, int type)
3693 if (type == URTW_LED_GPIO) {
3694 switch (sc->sc_gpio_ledpin) {
3695 case URTW_LED_PIN_GPIO0:
3696 urtw_write8_m(sc, URTW_GPIO, URTW_GPIO_DATA_MAGIC1);
3698 URTW_GP_ENABLE, URTW_GP_ENABLE_DATA_MAGIC1);
3701 DPRINTF(sc, URTW_DEBUG_STATE,
3702 "unsupported LED PIN type 0x%x",
3703 sc->sc_gpio_ledpin);
3704 error = USB_ERR_INVAL;
3708 DPRINTF(sc, URTW_DEBUG_STATE,
3709 "unsupported LED type 0x%x", type);
3710 error = USB_ERR_INVAL;
3714 sc->sc_gpio_ledon = 0;
3721 urtw_led_ch(void *arg)
3723 struct urtw_softc *sc = arg;
3724 struct ieee80211com *ic = &sc->sc_ic;
3726 ieee80211_runtask(ic, &sc->sc_led_task);
3730 urtw_ledtask(void *arg, int pending)
3732 struct urtw_softc *sc = arg;
3734 if (sc->sc_strategy != URTW_SW_LED_MODE0) {
3735 DPRINTF(sc, URTW_DEBUG_STATE,
3736 "could not process a LED strategy 0x%x",
3747 urtw_led_blink(struct urtw_softc *sc)
3752 if (sc->sc_gpio_blinkstate == URTW_LED_ON)
3753 error = urtw_led_on(sc, URTW_LED_GPIO);
3755 error = urtw_led_off(sc, URTW_LED_GPIO);
3756 sc->sc_gpio_blinktime--;
3757 if (sc->sc_gpio_blinktime == 0)
3760 if (sc->sc_gpio_ledstate != URTW_LED_BLINK_NORMAL &&
3761 sc->sc_gpio_ledstate != URTW_LED_BLINK_SLOWLY &&
3762 sc->sc_gpio_ledstate != URTW_LED_BLINK_CM3)
3766 if (sc->sc_gpio_ledstate == URTW_LED_ON &&
3767 sc->sc_gpio_ledon == 0)
3768 error = urtw_led_on(sc, URTW_LED_GPIO);
3769 else if (sc->sc_gpio_ledstate == URTW_LED_OFF &&
3770 sc->sc_gpio_ledon == 1)
3771 error = urtw_led_off(sc, URTW_LED_GPIO);
3773 sc->sc_gpio_blinktime = 0;
3774 sc->sc_gpio_ledinprogress = 0;
3778 sc->sc_gpio_blinkstate = (sc->sc_gpio_blinkstate != URTW_LED_ON) ?
3779 URTW_LED_ON : URTW_LED_OFF;
3781 switch (sc->sc_gpio_ledstate) {
3782 case URTW_LED_BLINK_NORMAL:
3783 usb_callout_reset(&sc->sc_led_ch, hz, urtw_led_ch, sc);
3786 DPRINTF(sc, URTW_DEBUG_STATE,
3787 "unknown LED status 0x%x",
3788 sc->sc_gpio_ledstate);
3789 return (USB_ERR_INVAL);
3795 urtw_rx_enable(struct urtw_softc *sc)
3800 usbd_transfer_start((sc->sc_flags & URTW_RTL8187B) ?
3801 sc->sc_xfer[URTW_8187B_BULK_RX] : sc->sc_xfer[URTW_8187L_BULK_RX]);
3803 error = urtw_rx_setconf(sc);
3807 if ((sc->sc_flags & URTW_RTL8187B) == 0) {
3808 urtw_read8_m(sc, URTW_CMD, &data);
3809 urtw_write8_m(sc, URTW_CMD, data | URTW_CMD_RX_ENABLE);
3816 urtw_tx_enable(struct urtw_softc *sc)
3822 if (sc->sc_flags & URTW_RTL8187B) {
3823 urtw_read32_m(sc, URTW_TX_CONF, &data);
3824 data &= ~URTW_TX_LOOPBACK_MASK;
3825 data &= ~(URTW_TX_DPRETRY_MASK | URTW_TX_RTSRETRY_MASK);
3826 data &= ~(URTW_TX_NOCRC | URTW_TX_MXDMA_MASK);
3827 data &= ~URTW_TX_SWPLCPLEN;
3828 data |= URTW_TX_HW_SEQNUM | URTW_TX_DISREQQSIZE |
3829 (7 << 8) | /* short retry limit */
3830 (7 << 0) | /* long retry limit */
3831 (7 << 21); /* MAX TX DMA */
3832 urtw_write32_m(sc, URTW_TX_CONF, data);
3834 urtw_read8_m(sc, URTW_MSR, &data8);
3835 data8 |= URTW_MSR_LINK_ENEDCA;
3836 urtw_write8_m(sc, URTW_MSR, data8);
3840 urtw_read8_m(sc, URTW_CW_CONF, &data8);
3841 data8 &= ~(URTW_CW_CONF_PERPACKET_CW | URTW_CW_CONF_PERPACKET_RETRY);
3842 urtw_write8_m(sc, URTW_CW_CONF, data8);
3844 urtw_read8_m(sc, URTW_TX_AGC_CTL, &data8);
3845 data8 &= ~URTW_TX_AGC_CTL_PERPACKET_GAIN;
3846 data8 &= ~URTW_TX_AGC_CTL_PERPACKET_ANTSEL;
3847 data8 &= ~URTW_TX_AGC_CTL_FEEDBACK_ANT;
3848 urtw_write8_m(sc, URTW_TX_AGC_CTL, data8);
3850 urtw_read32_m(sc, URTW_TX_CONF, &data);
3851 data &= ~URTW_TX_LOOPBACK_MASK;
3852 data |= URTW_TX_LOOPBACK_NONE;
3853 data &= ~(URTW_TX_DPRETRY_MASK | URTW_TX_RTSRETRY_MASK);
3854 data |= sc->sc_tx_retry << URTW_TX_DPRETRY_SHIFT;
3855 data |= sc->sc_rts_retry << URTW_TX_RTSRETRY_SHIFT;
3856 data &= ~(URTW_TX_NOCRC | URTW_TX_MXDMA_MASK);
3857 data |= URTW_TX_MXDMA_2048 | URTW_TX_CWMIN | URTW_TX_DISCW;
3858 data &= ~URTW_TX_SWPLCPLEN;
3859 data |= URTW_TX_NOICV;
3860 urtw_write32_m(sc, URTW_TX_CONF, data);
3862 urtw_read8_m(sc, URTW_CMD, &data8);
3863 urtw_write8_m(sc, URTW_CMD, data8 | URTW_CMD_TX_ENABLE);
3869 urtw_rx_setconf(struct urtw_softc *sc)
3871 struct ieee80211com *ic = &sc->sc_ic;
3875 urtw_read32_m(sc, URTW_RX, &data);
3876 data = data &~ URTW_RX_FILTER_MASK;
3877 if (sc->sc_flags & URTW_RTL8187B) {
3878 data = data | URTW_RX_FILTER_MNG | URTW_RX_FILTER_DATA |
3879 URTW_RX_FILTER_MCAST | URTW_RX_FILTER_BCAST |
3880 URTW_RX_FILTER_NICMAC | URTW_RX_CHECK_BSSID |
3881 URTW_RX_FIFO_THRESHOLD_NONE |
3882 URTW_MAX_RX_DMA_2048 |
3883 URTW_RX_AUTORESETPHY | URTW_RCR_ONLYERLPKT;
3885 data = data | URTW_RX_FILTER_MNG | URTW_RX_FILTER_DATA;
3886 data = data | URTW_RX_FILTER_BCAST | URTW_RX_FILTER_MCAST;
3888 if (ic->ic_opmode == IEEE80211_M_MONITOR) {
3889 data = data | URTW_RX_FILTER_ICVERR;
3890 data = data | URTW_RX_FILTER_PWR;
3892 if (sc->sc_crcmon == 1 && ic->ic_opmode == IEEE80211_M_MONITOR)
3893 data = data | URTW_RX_FILTER_CRCERR;
3895 if (ic->ic_opmode == IEEE80211_M_MONITOR ||
3896 ic->ic_promisc > 0 || ic->ic_allmulti > 0) {
3897 data = data | URTW_RX_FILTER_ALLMAC;
3899 data = data | URTW_RX_FILTER_NICMAC;
3900 data = data | URTW_RX_CHECK_BSSID;
3903 data = data &~ URTW_RX_FIFO_THRESHOLD_MASK;
3904 data = data | URTW_RX_FIFO_THRESHOLD_NONE |
3905 URTW_RX_AUTORESETPHY;
3906 data = data &~ URTW_MAX_RX_DMA_MASK;
3907 data = data | URTW_MAX_RX_DMA_2048 | URTW_RCR_ONLYERLPKT;
3910 urtw_write32_m(sc, URTW_RX, data);
3915 static struct mbuf *
3916 urtw_rxeof(struct usb_xfer *xfer, struct urtw_data *data, int *rssi_p,
3919 int actlen, flen, rssi;
3920 struct ieee80211_frame *wh;
3921 struct mbuf *m, *mnew;
3922 struct urtw_softc *sc = data->sc;
3923 struct ieee80211com *ic = &sc->sc_ic;
3924 uint8_t noise = 0, rate;
3926 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
3928 if (sc->sc_flags & URTW_RTL8187B) {
3929 struct urtw_8187b_rxhdr *rx;
3931 if (actlen < sizeof(*rx) + IEEE80211_ACK_LEN)
3934 rx = (struct urtw_8187b_rxhdr *)(data->buf +
3935 (actlen - (sizeof(struct urtw_8187b_rxhdr))));
3936 flen = le32toh(rx->flag) & 0xfff;
3937 if (flen > actlen - sizeof(*rx))
3940 rate = (le32toh(rx->flag) >> URTW_RX_FLAG_RXRATE_SHIFT) & 0xf;
3942 rssi = rx->rssi & URTW_RX_RSSI_MASK;
3945 struct urtw_8187l_rxhdr *rx;
3947 if (actlen < sizeof(*rx) + IEEE80211_ACK_LEN)
3950 rx = (struct urtw_8187l_rxhdr *)(data->buf +
3951 (actlen - (sizeof(struct urtw_8187l_rxhdr))));
3952 flen = le32toh(rx->flag) & 0xfff;
3953 if (flen > actlen - sizeof(*rx))
3956 rate = (le32toh(rx->flag) >> URTW_RX_FLAG_RXRATE_SHIFT) & 0xf;
3958 rssi = rx->rssi & URTW_RX_8187L_RSSI_MASK;
3962 if (flen < IEEE80211_ACK_LEN)
3965 mnew = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
3971 data->buf = mtod(mnew, uint8_t *);
3974 m->m_pkthdr.len = m->m_len = flen - IEEE80211_CRC_LEN;
3976 if (ieee80211_radiotap_active(ic)) {
3977 struct urtw_rx_radiotap_header *tap = &sc->sc_rxtap;
3979 /* XXX Are variables correct? */
3980 tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
3981 tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
3982 tap->wr_dbm_antsignal = (int8_t)rssi;
3985 wh = mtod(m, struct ieee80211_frame *);
3986 if (IEEE80211_IS_DATA(wh))
3987 sc->sc_currate = (rate > 0) ? rate : sc->sc_currate;
3990 *nf_p = noise; /* XXX correct? */
3995 counter_u64_add(ic->ic_ierrors, 1);
4000 urtw_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
4002 struct urtw_softc *sc = usbd_xfer_softc(xfer);
4003 struct ieee80211com *ic = &sc->sc_ic;
4004 struct ieee80211_node *ni;
4005 struct mbuf *m = NULL;
4006 struct urtw_data *data;
4010 URTW_ASSERT_LOCKED(sc);
4012 switch (USB_GET_STATE(xfer)) {
4013 case USB_ST_TRANSFERRED:
4014 data = STAILQ_FIRST(&sc->sc_rx_active);
4017 STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next);
4018 m = urtw_rxeof(xfer, data, &rssi, &nf);
4019 STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next);
4023 data = STAILQ_FIRST(&sc->sc_rx_inactive);
4025 KASSERT(m == NULL, ("mbuf isn't NULL"));
4028 STAILQ_REMOVE_HEAD(&sc->sc_rx_inactive, next);
4029 STAILQ_INSERT_TAIL(&sc->sc_rx_active, data, next);
4030 usbd_xfer_set_frame_data(xfer, 0, data->buf,
4031 usbd_xfer_max_len(xfer));
4032 usbd_transfer_submit(xfer);
4035 * To avoid LOR we should unlock our private mutex here to call
4036 * ieee80211_input() because here is at the end of a USB
4037 * callback and safe to unlock.
4041 if (m->m_pkthdr.len >=
4042 sizeof(struct ieee80211_frame_min)) {
4043 ni = ieee80211_find_rxnode(ic,
4044 mtod(m, struct ieee80211_frame_min *));
4049 (void) ieee80211_input(ni, m, rssi, nf);
4050 /* node is no longer needed */
4051 ieee80211_free_node(ni);
4053 (void) ieee80211_input_all(ic, m, rssi, nf);
4059 /* needs it to the inactive queue due to a error. */
4060 data = STAILQ_FIRST(&sc->sc_rx_active);
4062 STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next);
4063 STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next);
4065 if (error != USB_ERR_CANCELLED) {
4066 usbd_xfer_set_stall(xfer);
4067 counter_u64_add(ic->ic_ierrors, 1);
4074 #define URTW_STATUS_TYPE_TXCLOSE 1
4075 #define URTW_STATUS_TYPE_BEACON_INTR 0
4078 urtw_txstatus_eof(struct usb_xfer *xfer)
4080 struct urtw_softc *sc = usbd_xfer_softc(xfer);
4081 struct ieee80211com *ic = &sc->sc_ic;
4082 int actlen, type, pktretry, seq;
4085 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
4087 if (actlen != sizeof(uint64_t))
4090 val = le64toh(sc->sc_txstatus);
4091 type = (val >> 30) & 0x3;
4092 if (type == URTW_STATUS_TYPE_TXCLOSE) {
4093 pktretry = val & 0xff;
4094 seq = (val >> 16) & 0xff;
4095 if (pktretry == URTW_TX_MAXRETRY)
4096 counter_u64_add(ic->ic_oerrors, 1);
4097 DPRINTF(sc, URTW_DEBUG_TXSTATUS, "pktretry %d seq %#x\n",
4103 urtw_bulk_tx_status_callback(struct usb_xfer *xfer, usb_error_t error)
4105 struct urtw_softc *sc = usbd_xfer_softc(xfer);
4106 struct ieee80211com *ic = &sc->sc_ic;
4107 void *dma_buf = usbd_xfer_get_frame_buffer(xfer, 0);
4109 URTW_ASSERT_LOCKED(sc);
4111 switch (USB_GET_STATE(xfer)) {
4112 case USB_ST_TRANSFERRED:
4113 urtw_txstatus_eof(xfer);
4117 memcpy(dma_buf, &sc->sc_txstatus, sizeof(uint64_t));
4118 usbd_xfer_set_frame_len(xfer, 0, sizeof(uint64_t));
4119 usbd_transfer_submit(xfer);
4122 if (error != USB_ERR_CANCELLED) {
4123 usbd_xfer_set_stall(xfer);
4124 counter_u64_add(ic->ic_ierrors, 1);
4132 urtw_txeof(struct usb_xfer *xfer, struct urtw_data *data)
4134 struct urtw_softc *sc = usbd_xfer_softc(xfer);
4136 URTW_ASSERT_LOCKED(sc);
4140 ieee80211_tx_complete(data->ni, data->m, 0);
4148 urtw_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error)
4150 struct urtw_softc *sc = usbd_xfer_softc(xfer);
4151 struct urtw_data *data;
4153 URTW_ASSERT_LOCKED(sc);
4155 switch (USB_GET_STATE(xfer)) {
4156 case USB_ST_TRANSFERRED:
4157 data = STAILQ_FIRST(&sc->sc_tx_active);
4160 STAILQ_REMOVE_HEAD(&sc->sc_tx_active, next);
4161 urtw_txeof(xfer, data);
4162 STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data, next);
4166 data = STAILQ_FIRST(&sc->sc_tx_pending);
4168 DPRINTF(sc, URTW_DEBUG_XMIT,
4169 "%s: empty pending queue\n", __func__);
4172 STAILQ_REMOVE_HEAD(&sc->sc_tx_pending, next);
4173 STAILQ_INSERT_TAIL(&sc->sc_tx_active, data, next);
4175 usbd_xfer_set_frame_data(xfer, 0, data->buf, data->buflen);
4176 usbd_transfer_submit(xfer);
4181 data = STAILQ_FIRST(&sc->sc_tx_active);
4184 if (data->ni != NULL) {
4185 if_inc_counter(data->ni->ni_vap->iv_ifp,
4186 IFCOUNTER_OERRORS, 1);
4187 ieee80211_free_node(data->ni);
4190 if (error != USB_ERR_CANCELLED) {
4191 usbd_xfer_set_stall(xfer);
4198 static struct urtw_data *
4199 _urtw_getbuf(struct urtw_softc *sc)
4201 struct urtw_data *bf;
4203 bf = STAILQ_FIRST(&sc->sc_tx_inactive);
4205 STAILQ_REMOVE_HEAD(&sc->sc_tx_inactive, next);
4209 DPRINTF(sc, URTW_DEBUG_XMIT, "%s: %s\n", __func__,
4210 "out of xmit buffers");
4214 static struct urtw_data *
4215 urtw_getbuf(struct urtw_softc *sc)
4217 struct urtw_data *bf;
4219 URTW_ASSERT_LOCKED(sc);
4221 bf = _urtw_getbuf(sc);
4223 DPRINTF(sc, URTW_DEBUG_XMIT, "%s: stop queue\n", __func__);
4228 urtw_isbmode(uint16_t rate)
4231 return ((rate <= 22 && rate != 12 && rate != 18) ||
4232 rate == 44) ? (1) : (0);
4236 urtw_rate2dbps(uint16_t rate)
4256 urtw_compute_txtime(uint16_t framelen, uint16_t rate,
4257 uint8_t ismgt, uint8_t isshort)
4259 uint16_t ceiling, frametime, n_dbps;
4261 if (urtw_isbmode(rate)) {
4262 if (ismgt || !isshort || rate == 2)
4263 frametime = (uint16_t)(144 + 48 +
4264 (framelen * 8 / (rate / 2)));
4266 frametime = (uint16_t)(72 + 24 +
4267 (framelen * 8 / (rate / 2)));
4268 if ((framelen * 8 % (rate / 2)) != 0)
4271 n_dbps = urtw_rate2dbps(rate);
4272 ceiling = (16 + 8 * framelen + 6) / n_dbps
4273 + (((16 + 8 * framelen + 6) % n_dbps) ? 1 : 0);
4274 frametime = (uint16_t)(16 + 4 + 4 * ceiling + 6);
4280 * Callback from the 802.11 layer to update the
4281 * slot time based on the current setting.
4284 urtw_updateslot(struct ieee80211com *ic)
4286 struct urtw_softc *sc = ic->ic_softc;
4288 ieee80211_runtask(ic, &sc->sc_updateslot_task);
4292 urtw_updateslottask(void *arg, int pending)
4294 struct urtw_softc *sc = arg;
4295 struct ieee80211com *ic = &sc->sc_ic;
4299 if ((sc->sc_flags & URTW_RUNNING) == 0) {
4303 if (sc->sc_flags & URTW_RTL8187B) {
4304 urtw_write8_m(sc, URTW_SIFS, 0x22);
4305 if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan))
4306 urtw_write8_m(sc, URTW_SLOT, IEEE80211_DUR_SHSLOT);
4308 urtw_write8_m(sc, URTW_SLOT, IEEE80211_DUR_SLOT);
4309 urtw_write8_m(sc, URTW_8187B_EIFS, 0x5b);
4310 urtw_write8_m(sc, URTW_CARRIER_SCOUNT, 0x5b);
4312 urtw_write8_m(sc, URTW_SIFS, 0x22);
4313 if (sc->sc_state == IEEE80211_S_ASSOC &&
4314 ic->ic_flags & IEEE80211_F_SHSLOT)
4315 urtw_write8_m(sc, URTW_SLOT, IEEE80211_DUR_SHSLOT);
4317 urtw_write8_m(sc, URTW_SLOT, IEEE80211_DUR_SLOT);
4318 if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan)) {
4319 urtw_write8_m(sc, URTW_DIFS, 0x14);
4320 urtw_write8_m(sc, URTW_EIFS, 0x5b - 0x14);
4321 urtw_write8_m(sc, URTW_CW_VAL, 0x73);
4323 urtw_write8_m(sc, URTW_DIFS, 0x24);
4324 urtw_write8_m(sc, URTW_EIFS, 0x5b - 0x24);
4325 urtw_write8_m(sc, URTW_CW_VAL, 0xa5);
4333 urtw_sysctl_node(struct urtw_softc *sc)
4335 #define URTW_SYSCTL_STAT_ADD32(c, h, n, p, d) \
4336 SYSCTL_ADD_UINT(c, h, OID_AUTO, n, CTLFLAG_RD, p, 0, d)
4337 struct sysctl_ctx_list *ctx;
4338 struct sysctl_oid_list *child, *parent;
4339 struct sysctl_oid *tree;
4340 struct urtw_stats *stats = &sc->sc_stats;
4342 ctx = device_get_sysctl_ctx(sc->sc_dev);
4343 child = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->sc_dev));
4345 tree = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "stats", CTLFLAG_RD,
4346 NULL, "URTW statistics");
4347 parent = SYSCTL_CHILDREN(tree);
4349 /* Tx statistics. */
4350 tree = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "tx", CTLFLAG_RD,
4351 NULL, "Tx MAC statistics");
4352 child = SYSCTL_CHILDREN(tree);
4353 URTW_SYSCTL_STAT_ADD32(ctx, child, "1m", &stats->txrates[0],
4355 URTW_SYSCTL_STAT_ADD32(ctx, child, "2m", &stats->txrates[1],
4357 URTW_SYSCTL_STAT_ADD32(ctx, child, "5.5m", &stats->txrates[2],
4359 URTW_SYSCTL_STAT_ADD32(ctx, child, "6m", &stats->txrates[4],
4361 URTW_SYSCTL_STAT_ADD32(ctx, child, "9m", &stats->txrates[5],
4363 URTW_SYSCTL_STAT_ADD32(ctx, child, "11m", &stats->txrates[3],
4365 URTW_SYSCTL_STAT_ADD32(ctx, child, "12m", &stats->txrates[6],
4367 URTW_SYSCTL_STAT_ADD32(ctx, child, "18m", &stats->txrates[7],
4369 URTW_SYSCTL_STAT_ADD32(ctx, child, "24m", &stats->txrates[8],
4371 URTW_SYSCTL_STAT_ADD32(ctx, child, "36m", &stats->txrates[9],
4373 URTW_SYSCTL_STAT_ADD32(ctx, child, "48m", &stats->txrates[10],
4375 URTW_SYSCTL_STAT_ADD32(ctx, child, "54m", &stats->txrates[11],
4377 #undef URTW_SYSCTL_STAT_ADD32
4380 static device_method_t urtw_methods[] = {
4381 DEVMETHOD(device_probe, urtw_match),
4382 DEVMETHOD(device_attach, urtw_attach),
4383 DEVMETHOD(device_detach, urtw_detach),
4386 static driver_t urtw_driver = {
4388 .methods = urtw_methods,
4389 .size = sizeof(struct urtw_softc)
4391 static devclass_t urtw_devclass;
4393 DRIVER_MODULE(urtw, uhub, urtw_driver, urtw_devclass, NULL, 0);
4394 MODULE_DEPEND(urtw, wlan, 1, 1, 1);
4395 MODULE_DEPEND(urtw, usb, 1, 1, 1);
4396 MODULE_VERSION(urtw, 1);
4397 USB_PNP_HOST_INFO(urtw_devs);