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$");
19 #include <sys/param.h>
20 #include <sys/sockio.h>
21 #include <sys/sysctl.h>
23 #include <sys/mutex.h>
25 #include <sys/kernel.h>
26 #include <sys/socket.h>
27 #include <sys/systm.h>
28 #include <sys/malloc.h>
29 #include <sys/module.h>
31 #include <sys/endian.h>
34 #include <machine/bus.h>
35 #include <machine/resource.h>
39 #include <net/if_var.h>
40 #include <net/if_arp.h>
41 #include <net/ethernet.h>
42 #include <net/if_dl.h>
43 #include <net/if_media.h>
44 #include <net/if_types.h>
47 #include <netinet/in.h>
48 #include <netinet/in_systm.h>
49 #include <netinet/in_var.h>
50 #include <netinet/if_ether.h>
51 #include <netinet/ip.h>
54 #include <net80211/ieee80211_var.h>
55 #include <net80211/ieee80211_regdomain.h>
56 #include <net80211/ieee80211_radiotap.h>
58 #include <dev/usb/usb.h>
59 #include <dev/usb/usbdi.h>
62 #include <dev/usb/wlan/if_urtwreg.h>
63 #include <dev/usb/wlan/if_urtwvar.h>
65 static SYSCTL_NODE(_hw_usb, OID_AUTO, urtw, CTLFLAG_RW, 0, "USB Realtek 8187L");
68 SYSCTL_INT(_hw_usb_urtw, OID_AUTO, debug, CTLFLAG_RWTUN, &urtw_debug, 0,
69 "control debugging printfs");
71 URTW_DEBUG_XMIT = 0x00000001, /* basic xmit operation */
72 URTW_DEBUG_RECV = 0x00000002, /* basic recv operation */
73 URTW_DEBUG_RESET = 0x00000004, /* reset processing */
74 URTW_DEBUG_TX_PROC = 0x00000008, /* tx ISR proc */
75 URTW_DEBUG_RX_PROC = 0x00000010, /* rx ISR proc */
76 URTW_DEBUG_STATE = 0x00000020, /* 802.11 state transitions */
77 URTW_DEBUG_STAT = 0x00000040, /* statistic */
78 URTW_DEBUG_INIT = 0x00000080, /* initialization of dev */
79 URTW_DEBUG_TXSTATUS = 0x00000100, /* tx status */
80 URTW_DEBUG_ANY = 0xffffffff
82 #define DPRINTF(sc, m, fmt, ...) do { \
83 if (sc->sc_debug & (m)) \
84 printf(fmt, __VA_ARGS__); \
87 #define DPRINTF(sc, m, fmt, ...) do { \
91 static int urtw_preamble_mode = URTW_PREAMBLE_MODE_LONG;
92 SYSCTL_INT(_hw_usb_urtw, OID_AUTO, preamble_mode, CTLFLAG_RWTUN,
93 &urtw_preamble_mode, 0, "set the preable mode (long or short)");
95 /* recognized device vendors/products */
96 #define urtw_lookup(v, p) \
97 ((const struct urtw_type *)usb_lookup(urtw_devs, v, p))
98 #define URTW_DEV_B(v,p) \
99 { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, URTW_REV_RTL8187B) }
100 #define URTW_DEV_L(v,p) \
101 { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, URTW_REV_RTL8187L) }
102 #define URTW_REV_RTL8187B 0
103 #define URTW_REV_RTL8187L 1
104 static const STRUCT_USB_HOST_ID urtw_devs[] = {
105 URTW_DEV_B(NETGEAR, WG111V3),
106 URTW_DEV_B(REALTEK, RTL8187B_0),
107 URTW_DEV_B(REALTEK, RTL8187B_1),
108 URTW_DEV_B(REALTEK, RTL8187B_2),
109 URTW_DEV_B(SITECOMEU, WL168V4),
110 URTW_DEV_L(ASUS, P5B_WIFI),
111 URTW_DEV_L(BELKIN, F5D7050E),
112 URTW_DEV_L(LINKSYS4, WUSB54GCV2),
113 URTW_DEV_L(NETGEAR, WG111V2),
114 URTW_DEV_L(REALTEK, RTL8187),
115 URTW_DEV_L(SITECOMEU, WL168V1),
116 URTW_DEV_L(SURECOM, EP9001G2A),
117 { USB_VPI(USB_VENDOR_OVISLINK, 0x8187, URTW_REV_RTL8187L) },
118 { USB_VPI(USB_VENDOR_DICKSMITH, 0x9401, URTW_REV_RTL8187L) },
119 { USB_VPI(USB_VENDOR_HP, 0xca02, URTW_REV_RTL8187L) },
120 { USB_VPI(USB_VENDOR_LOGITEC, 0x010c, URTW_REV_RTL8187L) },
121 { USB_VPI(USB_VENDOR_NETGEAR, 0x6100, URTW_REV_RTL8187L) },
122 { USB_VPI(USB_VENDOR_SPHAIRON, 0x0150, URTW_REV_RTL8187L) },
123 { USB_VPI(USB_VENDOR_QCOM, 0x6232, URTW_REV_RTL8187L) },
128 #define urtw_read8_m(sc, val, data) do { \
129 error = urtw_read8_c(sc, val, data); \
133 #define urtw_write8_m(sc, val, data) do { \
134 error = urtw_write8_c(sc, val, data); \
138 #define urtw_read16_m(sc, val, data) do { \
139 error = urtw_read16_c(sc, val, data); \
143 #define urtw_write16_m(sc, val, data) do { \
144 error = urtw_write16_c(sc, val, data); \
148 #define urtw_read32_m(sc, val, data) do { \
149 error = urtw_read32_c(sc, val, data); \
153 #define urtw_write32_m(sc, val, data) do { \
154 error = urtw_write32_c(sc, val, data); \
158 #define urtw_8187_write_phy_ofdm(sc, val, data) do { \
159 error = urtw_8187_write_phy_ofdm_c(sc, val, data); \
163 #define urtw_8187_write_phy_cck(sc, val, data) do { \
164 error = urtw_8187_write_phy_cck_c(sc, val, data); \
168 #define urtw_8225_write(sc, val, data) do { \
169 error = urtw_8225_write_c(sc, val, data); \
179 static uint8_t urtw_8225_agc[] = {
180 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9d, 0x9c, 0x9b,
181 0x9a, 0x99, 0x98, 0x97, 0x96, 0x95, 0x94, 0x93, 0x92, 0x91, 0x90,
182 0x8f, 0x8e, 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86, 0x85,
183 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a,
184 0x39, 0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f,
185 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24,
186 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19,
187 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e,
188 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03,
189 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
190 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
191 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
194 static uint8_t urtw_8225z2_agc[] = {
195 0x5e, 0x5e, 0x5e, 0x5e, 0x5d, 0x5b, 0x59, 0x57, 0x55, 0x53, 0x51,
196 0x4f, 0x4d, 0x4b, 0x49, 0x47, 0x45, 0x43, 0x41, 0x3f, 0x3d, 0x3b,
197 0x39, 0x37, 0x35, 0x33, 0x31, 0x2f, 0x2d, 0x2b, 0x29, 0x27, 0x25,
198 0x23, 0x21, 0x1f, 0x1d, 0x1b, 0x19, 0x17, 0x15, 0x13, 0x11, 0x0f,
199 0x0d, 0x0b, 0x09, 0x07, 0x05, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01,
200 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x19, 0x19,
201 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x20, 0x21, 0x22, 0x23,
202 0x24, 0x25, 0x26, 0x26, 0x27, 0x27, 0x28, 0x28, 0x29, 0x2a, 0x2a,
203 0x2a, 0x2b, 0x2b, 0x2b, 0x2c, 0x2c, 0x2c, 0x2d, 0x2d, 0x2d, 0x2d,
204 0x2e, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x2f, 0x30, 0x30, 0x31, 0x31,
205 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
206 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31
209 static const uint8_t urtw_chan_2ghz[] =
210 { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };
212 static uint32_t urtw_8225_channel[] = {
213 0x0000, /* dummy channel 0 */
230 static uint8_t urtw_8225_gain[] = {
231 0x23, 0x88, 0x7c, 0xa5, /* -82dbm */
232 0x23, 0x88, 0x7c, 0xb5, /* -82dbm */
233 0x23, 0x88, 0x7c, 0xc5, /* -82dbm */
234 0x33, 0x80, 0x79, 0xc5, /* -78dbm */
235 0x43, 0x78, 0x76, 0xc5, /* -74dbm */
236 0x53, 0x60, 0x73, 0xc5, /* -70dbm */
237 0x63, 0x58, 0x70, 0xc5, /* -66dbm */
240 static struct urtw_pair urtw_8225_rf_part1[] = {
241 { 0x00, 0x0067 }, { 0x01, 0x0fe0 }, { 0x02, 0x044d }, { 0x03, 0x0441 },
242 { 0x04, 0x0486 }, { 0x05, 0x0bc0 }, { 0x06, 0x0ae6 }, { 0x07, 0x082a },
243 { 0x08, 0x001f }, { 0x09, 0x0334 }, { 0x0a, 0x0fd4 }, { 0x0b, 0x0391 },
244 { 0x0c, 0x0050 }, { 0x0d, 0x06db }, { 0x0e, 0x0029 }, { 0x0f, 0x0914 },
247 static struct urtw_pair urtw_8225_rf_part2[] = {
248 { 0x00, 0x01 }, { 0x01, 0x02 }, { 0x02, 0x42 }, { 0x03, 0x00 },
249 { 0x04, 0x00 }, { 0x05, 0x00 }, { 0x06, 0x40 }, { 0x07, 0x00 },
250 { 0x08, 0x40 }, { 0x09, 0xfe }, { 0x0a, 0x09 }, { 0x0b, 0x80 },
251 { 0x0c, 0x01 }, { 0x0e, 0xd3 }, { 0x0f, 0x38 }, { 0x10, 0x84 },
252 { 0x11, 0x06 }, { 0x12, 0x20 }, { 0x13, 0x20 }, { 0x14, 0x00 },
253 { 0x15, 0x40 }, { 0x16, 0x00 }, { 0x17, 0x40 }, { 0x18, 0xef },
254 { 0x19, 0x19 }, { 0x1a, 0x20 }, { 0x1b, 0x76 }, { 0x1c, 0x04 },
255 { 0x1e, 0x95 }, { 0x1f, 0x75 }, { 0x20, 0x1f }, { 0x21, 0x27 },
256 { 0x22, 0x16 }, { 0x24, 0x46 }, { 0x25, 0x20 }, { 0x26, 0x90 },
260 static struct urtw_pair urtw_8225_rf_part3[] = {
261 { 0x00, 0x98 }, { 0x03, 0x20 }, { 0x04, 0x7e }, { 0x05, 0x12 },
262 { 0x06, 0xfc }, { 0x07, 0x78 }, { 0x08, 0x2e }, { 0x10, 0x9b },
263 { 0x11, 0x88 }, { 0x12, 0x47 }, { 0x13, 0xd0 }, { 0x19, 0x00 },
264 { 0x1a, 0xa0 }, { 0x1b, 0x08 }, { 0x40, 0x86 }, { 0x41, 0x8d },
265 { 0x42, 0x15 }, { 0x43, 0x18 }, { 0x44, 0x1f }, { 0x45, 0x1e },
266 { 0x46, 0x1a }, { 0x47, 0x15 }, { 0x48, 0x10 }, { 0x49, 0x0a },
267 { 0x4a, 0x05 }, { 0x4b, 0x02 }, { 0x4c, 0x05 }
270 static uint16_t urtw_8225_rxgain[] = {
271 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
272 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
273 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
274 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
275 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
276 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
277 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
278 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
279 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
280 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
281 0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3,
282 0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb
285 static uint8_t urtw_8225_threshold[] = {
286 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd,
289 static uint8_t urtw_8225_tx_gain_cck_ofdm[] = {
290 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e
293 static uint8_t urtw_8225_txpwr_cck[] = {
294 0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02,
295 0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02,
296 0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02,
297 0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02,
298 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03,
299 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03
302 static uint8_t urtw_8225_txpwr_cck_ch14[] = {
303 0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00,
304 0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00,
305 0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00,
306 0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00,
307 0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00,
308 0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00
311 static uint8_t urtw_8225_txpwr_ofdm[]={
312 0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4
315 static uint8_t urtw_8225v2_gain_bg[]={
316 0x23, 0x15, 0xa5, /* -82-1dbm */
317 0x23, 0x15, 0xb5, /* -82-2dbm */
318 0x23, 0x15, 0xc5, /* -82-3dbm */
319 0x33, 0x15, 0xc5, /* -78dbm */
320 0x43, 0x15, 0xc5, /* -74dbm */
321 0x53, 0x15, 0xc5, /* -70dbm */
322 0x63, 0x15, 0xc5, /* -66dbm */
325 static struct urtw_pair urtw_8225v2_rf_part1[] = {
326 { 0x00, 0x02bf }, { 0x01, 0x0ee0 }, { 0x02, 0x044d }, { 0x03, 0x0441 },
327 { 0x04, 0x08c3 }, { 0x05, 0x0c72 }, { 0x06, 0x00e6 }, { 0x07, 0x082a },
328 { 0x08, 0x003f }, { 0x09, 0x0335 }, { 0x0a, 0x09d4 }, { 0x0b, 0x07bb },
329 { 0x0c, 0x0850 }, { 0x0d, 0x0cdf }, { 0x0e, 0x002b }, { 0x0f, 0x0114 }
332 static struct urtw_pair urtw_8225v2b_rf_part0[] = {
333 { 0x00, 0x00b7 }, { 0x01, 0x0ee0 }, { 0x02, 0x044d }, { 0x03, 0x0441 },
334 { 0x04, 0x08c3 }, { 0x05, 0x0c72 }, { 0x06, 0x00e6 }, { 0x07, 0x082a },
335 { 0x08, 0x003f }, { 0x09, 0x0335 }, { 0x0a, 0x09d4 }, { 0x0b, 0x07bb },
336 { 0x0c, 0x0850 }, { 0x0d, 0x0cdf }, { 0x0e, 0x002b }, { 0x0f, 0x0114 }
339 static struct urtw_pair urtw_8225v2b_rf_part1[] = {
340 {0x0f0, 0x32}, {0x0f1, 0x32}, {0x0f2, 0x00},
341 {0x0f3, 0x00}, {0x0f4, 0x32}, {0x0f5, 0x43},
342 {0x0f6, 0x00}, {0x0f7, 0x00}, {0x0f8, 0x46},
343 {0x0f9, 0xa4}, {0x0fa, 0x00}, {0x0fb, 0x00},
344 {0x0fc, 0x96}, {0x0fd, 0xa4}, {0x0fe, 0x00},
345 {0x0ff, 0x00}, {0x158, 0x4b}, {0x159, 0x00},
346 {0x15a, 0x4b}, {0x15b, 0x00}, {0x160, 0x4b},
347 {0x161, 0x09}, {0x162, 0x4b}, {0x163, 0x09},
348 {0x1ce, 0x0f}, {0x1cf, 0x00}, {0x1e0, 0xff},
349 {0x1e1, 0x0f}, {0x1e2, 0x00}, {0x1f0, 0x4e},
350 {0x1f1, 0x01}, {0x1f2, 0x02}, {0x1f3, 0x03},
351 {0x1f4, 0x04}, {0x1f5, 0x05}, {0x1f6, 0x06},
352 {0x1f7, 0x07}, {0x1f8, 0x08}, {0x24e, 0x00},
353 {0x20c, 0x04}, {0x221, 0x61}, {0x222, 0x68},
354 {0x223, 0x6f}, {0x224, 0x76}, {0x225, 0x7d},
355 {0x226, 0x84}, {0x227, 0x8d}, {0x24d, 0x08},
356 {0x250, 0x05}, {0x251, 0xf5}, {0x252, 0x04},
357 {0x253, 0xa0}, {0x254, 0x1f}, {0x255, 0x23},
358 {0x256, 0x45}, {0x257, 0x67}, {0x258, 0x08},
359 {0x259, 0x08}, {0x25a, 0x08}, {0x25b, 0x08},
360 {0x260, 0x08}, {0x261, 0x08}, {0x262, 0x08},
361 {0x263, 0x08}, {0x264, 0xcf}, {0x272, 0x56},
362 {0x273, 0x9a}, {0x034, 0xf0}, {0x035, 0x0f},
363 {0x05b, 0x40}, {0x084, 0x88}, {0x085, 0x24},
364 {0x088, 0x54}, {0x08b, 0xb8}, {0x08c, 0x07},
365 {0x08d, 0x00}, {0x094, 0x1b}, {0x095, 0x12},
366 {0x096, 0x00}, {0x097, 0x06}, {0x09d, 0x1a},
367 {0x09f, 0x10}, {0x0b4, 0x22}, {0x0be, 0x80},
368 {0x0db, 0x00}, {0x0ee, 0x00}, {0x091, 0x03},
369 {0x24c, 0x00}, {0x39f, 0x00}, {0x08c, 0x01},
370 {0x08d, 0x10}, {0x08e, 0x08}, {0x08f, 0x00}
373 static struct urtw_pair urtw_8225v2_rf_part2[] = {
374 { 0x00, 0x01 }, { 0x01, 0x02 }, { 0x02, 0x42 }, { 0x03, 0x00 },
375 { 0x04, 0x00 }, { 0x05, 0x00 }, { 0x06, 0x40 }, { 0x07, 0x00 },
376 { 0x08, 0x40 }, { 0x09, 0xfe }, { 0x0a, 0x08 }, { 0x0b, 0x80 },
377 { 0x0c, 0x01 }, { 0x0d, 0x43 }, { 0x0e, 0xd3 }, { 0x0f, 0x38 },
378 { 0x10, 0x84 }, { 0x11, 0x07 }, { 0x12, 0x20 }, { 0x13, 0x20 },
379 { 0x14, 0x00 }, { 0x15, 0x40 }, { 0x16, 0x00 }, { 0x17, 0x40 },
380 { 0x18, 0xef }, { 0x19, 0x19 }, { 0x1a, 0x20 }, { 0x1b, 0x15 },
381 { 0x1c, 0x04 }, { 0x1d, 0xc5 }, { 0x1e, 0x95 }, { 0x1f, 0x75 },
382 { 0x20, 0x1f }, { 0x21, 0x17 }, { 0x22, 0x16 }, { 0x23, 0x80 },
383 { 0x24, 0x46 }, { 0x25, 0x00 }, { 0x26, 0x90 }, { 0x27, 0x88 }
386 static struct urtw_pair urtw_8225v2b_rf_part2[] = {
387 { 0x00, 0x10 }, { 0x01, 0x0d }, { 0x02, 0x01 }, { 0x03, 0x00 },
388 { 0x04, 0x14 }, { 0x05, 0xfb }, { 0x06, 0xfb }, { 0x07, 0x60 },
389 { 0x08, 0x00 }, { 0x09, 0x60 }, { 0x0a, 0x00 }, { 0x0b, 0x00 },
390 { 0x0c, 0x00 }, { 0x0d, 0x5c }, { 0x0e, 0x00 }, { 0x0f, 0x00 },
391 { 0x10, 0x40 }, { 0x11, 0x00 }, { 0x12, 0x40 }, { 0x13, 0x00 },
392 { 0x14, 0x00 }, { 0x15, 0x00 }, { 0x16, 0xa8 }, { 0x17, 0x26 },
393 { 0x18, 0x32 }, { 0x19, 0x33 }, { 0x1a, 0x07 }, { 0x1b, 0xa5 },
394 { 0x1c, 0x6f }, { 0x1d, 0x55 }, { 0x1e, 0xc8 }, { 0x1f, 0xb3 },
395 { 0x20, 0x0a }, { 0x21, 0xe1 }, { 0x22, 0x2C }, { 0x23, 0x8a },
396 { 0x24, 0x86 }, { 0x25, 0x83 }, { 0x26, 0x34 }, { 0x27, 0x0f },
397 { 0x28, 0x4f }, { 0x29, 0x24 }, { 0x2a, 0x6f }, { 0x2b, 0xc2 },
398 { 0x2c, 0x6b }, { 0x2d, 0x40 }, { 0x2e, 0x80 }, { 0x2f, 0x00 },
399 { 0x30, 0xc0 }, { 0x31, 0xc1 }, { 0x32, 0x58 }, { 0x33, 0xf1 },
400 { 0x34, 0x00 }, { 0x35, 0xe4 }, { 0x36, 0x90 }, { 0x37, 0x3e },
401 { 0x38, 0x6d }, { 0x39, 0x3c }, { 0x3a, 0xfb }, { 0x3b, 0x07 }
404 static struct urtw_pair urtw_8225v2_rf_part3[] = {
405 { 0x00, 0x98 }, { 0x03, 0x20 }, { 0x04, 0x7e }, { 0x05, 0x12 },
406 { 0x06, 0xfc }, { 0x07, 0x78 }, { 0x08, 0x2e }, { 0x09, 0x11 },
407 { 0x0a, 0x17 }, { 0x0b, 0x11 }, { 0x10, 0x9b }, { 0x11, 0x88 },
408 { 0x12, 0x47 }, { 0x13, 0xd0 }, { 0x19, 0x00 }, { 0x1a, 0xa0 },
409 { 0x1b, 0x08 }, { 0x1d, 0x00 }, { 0x40, 0x86 }, { 0x41, 0x9d },
410 { 0x42, 0x15 }, { 0x43, 0x18 }, { 0x44, 0x36 }, { 0x45, 0x35 },
411 { 0x46, 0x2e }, { 0x47, 0x25 }, { 0x48, 0x1c }, { 0x49, 0x12 },
412 { 0x4a, 0x09 }, { 0x4b, 0x04 }, { 0x4c, 0x05 }
415 static uint16_t urtw_8225v2_rxgain[] = {
416 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0008, 0x0009,
417 0x000a, 0x000b, 0x0102, 0x0103, 0x0104, 0x0105, 0x0140, 0x0141,
418 0x0142, 0x0143, 0x0144, 0x0145, 0x0180, 0x0181, 0x0182, 0x0183,
419 0x0184, 0x0185, 0x0188, 0x0189, 0x018a, 0x018b, 0x0243, 0x0244,
420 0x0245, 0x0280, 0x0281, 0x0282, 0x0283, 0x0284, 0x0285, 0x0288,
421 0x0289, 0x028a, 0x028b, 0x028c, 0x0342, 0x0343, 0x0344, 0x0345,
422 0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x0388, 0x0389,
423 0x038a, 0x038b, 0x038c, 0x038d, 0x0390, 0x0391, 0x0392, 0x0393,
424 0x0394, 0x0395, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d,
425 0x03a0, 0x03a1, 0x03a2, 0x03a3, 0x03a4, 0x03a5, 0x03a8, 0x03a9,
426 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
427 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
430 static uint16_t urtw_8225v2b_rxgain[] = {
431 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
432 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
433 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
434 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
435 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
436 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
437 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
438 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
439 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
440 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
441 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
442 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
445 static uint8_t urtw_8225v2_tx_gain_cck_ofdm[] = {
446 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
447 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
448 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
449 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
450 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
451 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
454 static uint8_t urtw_8225v2_txpwr_cck[] = {
455 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04
458 static uint8_t urtw_8225v2_txpwr_cck_ch14[] = {
459 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00
462 static uint8_t urtw_8225v2b_txpwr_cck[] = {
463 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04,
464 0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03,
465 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03,
466 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03
469 static uint8_t urtw_8225v2b_txpwr_cck_ch14[] = {
470 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00,
471 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
472 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
473 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00
476 static struct urtw_pair urtw_ratetable[] = {
477 { 2, 0 }, { 4, 1 }, { 11, 2 }, { 12, 4 }, { 18, 5 },
478 { 22, 3 }, { 24, 6 }, { 36, 7 }, { 48, 8 }, { 72, 9 },
479 { 96, 10 }, { 108, 11 }
483 static const uint8_t urtw_8187b_reg_table[][3] = {
484 { 0xf0, 0x32, 0 }, { 0xf1, 0x32, 0 }, { 0xf2, 0x00, 0 },
485 { 0xf3, 0x00, 0 }, { 0xf4, 0x32, 0 }, { 0xf5, 0x43, 0 },
486 { 0xf6, 0x00, 0 }, { 0xf7, 0x00, 0 }, { 0xf8, 0x46, 0 },
487 { 0xf9, 0xa4, 0 }, { 0xfa, 0x00, 0 }, { 0xfb, 0x00, 0 },
488 { 0xfc, 0x96, 0 }, { 0xfd, 0xa4, 0 }, { 0xfe, 0x00, 0 },
489 { 0xff, 0x00, 0 }, { 0x58, 0x4b, 1 }, { 0x59, 0x00, 1 },
490 { 0x5a, 0x4b, 1 }, { 0x5b, 0x00, 1 }, { 0x60, 0x4b, 1 },
491 { 0x61, 0x09, 1 }, { 0x62, 0x4b, 1 }, { 0x63, 0x09, 1 },
492 { 0xce, 0x0f, 1 }, { 0xcf, 0x00, 1 }, { 0xe0, 0xff, 1 },
493 { 0xe1, 0x0f, 1 }, { 0xe2, 0x00, 1 }, { 0xf0, 0x4e, 1 },
494 { 0xf1, 0x01, 1 }, { 0xf2, 0x02, 1 }, { 0xf3, 0x03, 1 },
495 { 0xf4, 0x04, 1 }, { 0xf5, 0x05, 1 }, { 0xf6, 0x06, 1 },
496 { 0xf7, 0x07, 1 }, { 0xf8, 0x08, 1 }, { 0x4e, 0x00, 2 },
497 { 0x0c, 0x04, 2 }, { 0x21, 0x61, 2 }, { 0x22, 0x68, 2 },
498 { 0x23, 0x6f, 2 }, { 0x24, 0x76, 2 }, { 0x25, 0x7d, 2 },
499 { 0x26, 0x84, 2 }, { 0x27, 0x8d, 2 }, { 0x4d, 0x08, 2 },
500 { 0x50, 0x05, 2 }, { 0x51, 0xf5, 2 }, { 0x52, 0x04, 2 },
501 { 0x53, 0xa0, 2 }, { 0x54, 0x1f, 2 }, { 0x55, 0x23, 2 },
502 { 0x56, 0x45, 2 }, { 0x57, 0x67, 2 }, { 0x58, 0x08, 2 },
503 { 0x59, 0x08, 2 }, { 0x5a, 0x08, 2 }, { 0x5b, 0x08, 2 },
504 { 0x60, 0x08, 2 }, { 0x61, 0x08, 2 }, { 0x62, 0x08, 2 },
505 { 0x63, 0x08, 2 }, { 0x64, 0xcf, 2 }, { 0x72, 0x56, 2 },
506 { 0x73, 0x9a, 2 }, { 0x34, 0xf0, 0 }, { 0x35, 0x0f, 0 },
507 { 0x5b, 0x40, 0 }, { 0x84, 0x88, 0 }, { 0x85, 0x24, 0 },
508 { 0x88, 0x54, 0 }, { 0x8b, 0xb8, 0 }, { 0x8c, 0x07, 0 },
509 { 0x8d, 0x00, 0 }, { 0x94, 0x1b, 0 }, { 0x95, 0x12, 0 },
510 { 0x96, 0x00, 0 }, { 0x97, 0x06, 0 }, { 0x9d, 0x1a, 0 },
511 { 0x9f, 0x10, 0 }, { 0xb4, 0x22, 0 }, { 0xbe, 0x80, 0 },
512 { 0xdb, 0x00, 0 }, { 0xee, 0x00, 0 }, { 0x91, 0x03, 0 },
513 { 0x4c, 0x00, 2 }, { 0x9f, 0x00, 3 }, { 0x8c, 0x01, 0 },
514 { 0x8d, 0x10, 0 }, { 0x8e, 0x08, 0 }, { 0x8f, 0x00, 0 }
518 static usb_callback_t urtw_bulk_rx_callback;
519 static usb_callback_t urtw_bulk_tx_callback;
520 static usb_callback_t urtw_bulk_tx_status_callback;
522 static const struct usb_config urtw_8187b_usbconfig[URTW_8187B_N_XFERS] = {
523 [URTW_8187B_BULK_RX] = {
526 .direction = UE_DIR_IN,
533 .callback = urtw_bulk_rx_callback
535 [URTW_8187B_BULK_TX_STATUS] = {
538 .direction = UE_DIR_IN,
539 .bufsize = sizeof(uint64_t),
544 .callback = urtw_bulk_tx_status_callback
546 [URTW_8187B_BULK_TX_BE] = {
548 .endpoint = URTW_8187B_TXPIPE_BE,
549 .direction = UE_DIR_OUT,
550 .bufsize = URTW_TX_MAXSIZE * URTW_TX_DATA_LIST_COUNT,
552 .force_short_xfer = 1,
555 .callback = urtw_bulk_tx_callback,
556 .timeout = URTW_DATA_TIMEOUT
558 [URTW_8187B_BULK_TX_BK] = {
560 .endpoint = URTW_8187B_TXPIPE_BK,
561 .direction = UE_DIR_OUT,
562 .bufsize = URTW_TX_MAXSIZE,
565 .force_short_xfer = 1,
568 .callback = urtw_bulk_tx_callback,
569 .timeout = URTW_DATA_TIMEOUT
571 [URTW_8187B_BULK_TX_VI] = {
573 .endpoint = URTW_8187B_TXPIPE_VI,
574 .direction = UE_DIR_OUT,
575 .bufsize = URTW_TX_MAXSIZE,
578 .force_short_xfer = 1,
581 .callback = urtw_bulk_tx_callback,
582 .timeout = URTW_DATA_TIMEOUT
584 [URTW_8187B_BULK_TX_VO] = {
586 .endpoint = URTW_8187B_TXPIPE_VO,
587 .direction = UE_DIR_OUT,
588 .bufsize = URTW_TX_MAXSIZE,
591 .force_short_xfer = 1,
594 .callback = urtw_bulk_tx_callback,
595 .timeout = URTW_DATA_TIMEOUT
597 [URTW_8187B_BULK_TX_EP12] = {
600 .direction = UE_DIR_OUT,
601 .bufsize = URTW_TX_MAXSIZE,
604 .force_short_xfer = 1,
607 .callback = urtw_bulk_tx_callback,
608 .timeout = URTW_DATA_TIMEOUT
612 static const struct usb_config urtw_8187l_usbconfig[URTW_8187L_N_XFERS] = {
613 [URTW_8187L_BULK_RX] = {
616 .direction = UE_DIR_IN,
623 .callback = urtw_bulk_rx_callback
625 [URTW_8187L_BULK_TX_LOW] = {
628 .direction = UE_DIR_OUT,
629 .bufsize = URTW_TX_MAXSIZE * URTW_TX_DATA_LIST_COUNT,
631 .force_short_xfer = 1,
634 .callback = urtw_bulk_tx_callback,
635 .timeout = URTW_DATA_TIMEOUT
637 [URTW_8187L_BULK_TX_NORMAL] = {
640 .direction = UE_DIR_OUT,
641 .bufsize = URTW_TX_MAXSIZE,
644 .force_short_xfer = 1,
647 .callback = urtw_bulk_tx_callback,
648 .timeout = URTW_DATA_TIMEOUT
652 static struct ieee80211vap *urtw_vap_create(struct ieee80211com *,
653 const char [IFNAMSIZ], int, enum ieee80211_opmode,
654 int, const uint8_t [IEEE80211_ADDR_LEN],
655 const uint8_t [IEEE80211_ADDR_LEN]);
656 static void urtw_vap_delete(struct ieee80211vap *);
657 static void urtw_init(struct urtw_softc *);
658 static void urtw_stop(struct urtw_softc *);
659 static void urtw_parent(struct ieee80211com *);
660 static int urtw_transmit(struct ieee80211com *, struct mbuf *);
661 static void urtw_start(struct urtw_softc *);
662 static int urtw_alloc_rx_data_list(struct urtw_softc *);
663 static int urtw_alloc_tx_data_list(struct urtw_softc *);
664 static int urtw_raw_xmit(struct ieee80211_node *, struct mbuf *,
665 const struct ieee80211_bpf_params *);
666 static void urtw_scan_start(struct ieee80211com *);
667 static void urtw_scan_end(struct ieee80211com *);
668 static void urtw_getradiocaps(struct ieee80211com *, int, int *,
669 struct ieee80211_channel[]);
670 static void urtw_set_channel(struct ieee80211com *);
671 static void urtw_update_mcast(struct ieee80211com *);
672 static int urtw_tx_start(struct urtw_softc *,
673 struct ieee80211_node *, struct mbuf *,
674 struct urtw_data *, int);
675 static int urtw_newstate(struct ieee80211vap *,
676 enum ieee80211_state, int);
677 static void urtw_led_ch(void *);
678 static void urtw_ledtask(void *, int);
679 static void urtw_watchdog(void *);
680 static void urtw_set_multi(void *);
681 static int urtw_isbmode(uint16_t);
682 static uint16_t urtw_rate2rtl(uint32_t);
683 static uint16_t urtw_rtl2rate(uint32_t);
684 static usb_error_t urtw_set_rate(struct urtw_softc *);
685 static usb_error_t urtw_update_msr(struct urtw_softc *);
686 static usb_error_t urtw_read8_c(struct urtw_softc *, int, uint8_t *);
687 static usb_error_t urtw_read16_c(struct urtw_softc *, int, uint16_t *);
688 static usb_error_t urtw_read32_c(struct urtw_softc *, int, uint32_t *);
689 static usb_error_t urtw_write8_c(struct urtw_softc *, int, uint8_t);
690 static usb_error_t urtw_write16_c(struct urtw_softc *, int, uint16_t);
691 static usb_error_t urtw_write32_c(struct urtw_softc *, int, uint32_t);
692 static usb_error_t urtw_eprom_cs(struct urtw_softc *, int);
693 static usb_error_t urtw_eprom_ck(struct urtw_softc *);
694 static usb_error_t urtw_eprom_sendbits(struct urtw_softc *, int16_t *,
696 static usb_error_t urtw_eprom_read32(struct urtw_softc *, uint32_t,
698 static usb_error_t urtw_eprom_readbit(struct urtw_softc *, int16_t *);
699 static usb_error_t urtw_eprom_writebit(struct urtw_softc *, int16_t);
700 static usb_error_t urtw_get_macaddr(struct urtw_softc *);
701 static usb_error_t urtw_get_txpwr(struct urtw_softc *);
702 static usb_error_t urtw_get_rfchip(struct urtw_softc *);
703 static usb_error_t urtw_led_init(struct urtw_softc *);
704 static usb_error_t urtw_8185_rf_pins_enable(struct urtw_softc *);
705 static usb_error_t urtw_8185_tx_antenna(struct urtw_softc *, uint8_t);
706 static usb_error_t urtw_8187_write_phy(struct urtw_softc *, uint8_t,
708 static usb_error_t urtw_8187_write_phy_ofdm_c(struct urtw_softc *,
710 static usb_error_t urtw_8187_write_phy_cck_c(struct urtw_softc *, uint8_t,
712 static usb_error_t urtw_8225_setgain(struct urtw_softc *, int16_t);
713 static usb_error_t urtw_8225_usb_init(struct urtw_softc *);
714 static usb_error_t urtw_8225_write_c(struct urtw_softc *, uint8_t,
716 static usb_error_t urtw_8225_write_s16(struct urtw_softc *, uint8_t, int,
718 static usb_error_t urtw_8225_read(struct urtw_softc *, uint8_t,
720 static usb_error_t urtw_8225_rf_init(struct urtw_softc *);
721 static usb_error_t urtw_8225_rf_set_chan(struct urtw_softc *, int);
722 static usb_error_t urtw_8225_rf_set_sens(struct urtw_softc *, int);
723 static usb_error_t urtw_8225_set_txpwrlvl(struct urtw_softc *, int);
724 static usb_error_t urtw_8225_rf_stop(struct urtw_softc *);
725 static usb_error_t urtw_8225v2_rf_init(struct urtw_softc *);
726 static usb_error_t urtw_8225v2_rf_set_chan(struct urtw_softc *, int);
727 static usb_error_t urtw_8225v2_set_txpwrlvl(struct urtw_softc *, int);
728 static usb_error_t urtw_8225v2_setgain(struct urtw_softc *, int16_t);
729 static usb_error_t urtw_8225_isv2(struct urtw_softc *, int *);
730 static usb_error_t urtw_8225v2b_rf_init(struct urtw_softc *);
731 static usb_error_t urtw_8225v2b_rf_set_chan(struct urtw_softc *, int);
732 static usb_error_t urtw_read8e(struct urtw_softc *, int, uint8_t *);
733 static usb_error_t urtw_write8e(struct urtw_softc *, int, uint8_t);
734 static usb_error_t urtw_8180_set_anaparam(struct urtw_softc *, uint32_t);
735 static usb_error_t urtw_8185_set_anaparam2(struct urtw_softc *, uint32_t);
736 static usb_error_t urtw_intr_enable(struct urtw_softc *);
737 static usb_error_t urtw_intr_disable(struct urtw_softc *);
738 static usb_error_t urtw_reset(struct urtw_softc *);
739 static usb_error_t urtw_led_on(struct urtw_softc *, int);
740 static usb_error_t urtw_led_ctl(struct urtw_softc *, int);
741 static usb_error_t urtw_led_blink(struct urtw_softc *);
742 static usb_error_t urtw_led_mode0(struct urtw_softc *, int);
743 static usb_error_t urtw_led_mode1(struct urtw_softc *, int);
744 static usb_error_t urtw_led_mode2(struct urtw_softc *, int);
745 static usb_error_t urtw_led_mode3(struct urtw_softc *, int);
746 static usb_error_t urtw_rx_setconf(struct urtw_softc *);
747 static usb_error_t urtw_rx_enable(struct urtw_softc *);
748 static usb_error_t urtw_tx_enable(struct urtw_softc *sc);
749 static void urtw_free_tx_data_list(struct urtw_softc *);
750 static void urtw_free_rx_data_list(struct urtw_softc *);
751 static void urtw_free_data_list(struct urtw_softc *,
752 struct urtw_data data[], int, int);
753 static usb_error_t urtw_adapter_start(struct urtw_softc *);
754 static usb_error_t urtw_adapter_start_b(struct urtw_softc *);
755 static usb_error_t urtw_set_mode(struct urtw_softc *, uint32_t);
756 static usb_error_t urtw_8187b_cmd_reset(struct urtw_softc *);
757 static usb_error_t urtw_do_request(struct urtw_softc *,
758 struct usb_device_request *, void *);
759 static usb_error_t urtw_8225v2b_set_txpwrlvl(struct urtw_softc *, int);
760 static usb_error_t urtw_led_off(struct urtw_softc *, int);
761 static void urtw_abort_xfers(struct urtw_softc *);
762 static struct urtw_data *
763 urtw_getbuf(struct urtw_softc *sc);
764 static int urtw_compute_txtime(uint16_t, uint16_t, uint8_t,
766 static void urtw_updateslot(struct ieee80211com *);
767 static void urtw_updateslottask(void *, int);
768 static void urtw_sysctl_node(struct urtw_softc *);
771 urtw_match(device_t dev)
773 struct usb_attach_arg *uaa = device_get_ivars(dev);
775 if (uaa->usb_mode != USB_MODE_HOST)
777 if (uaa->info.bConfigIndex != URTW_CONFIG_INDEX)
779 if (uaa->info.bIfaceIndex != URTW_IFACE_INDEX)
782 return (usbd_lookup_id_by_uaa(urtw_devs, sizeof(urtw_devs), uaa));
786 urtw_attach(device_t dev)
788 const struct usb_config *setup_start;
790 struct urtw_softc *sc = device_get_softc(dev);
791 struct usb_attach_arg *uaa = device_get_ivars(dev);
792 struct ieee80211com *ic = &sc->sc_ic;
793 uint8_t iface_index = URTW_IFACE_INDEX; /* XXX */
798 device_set_usb_desc(dev);
801 sc->sc_udev = uaa->device;
802 if (USB_GET_DRIVER_INFO(uaa) == URTW_REV_RTL8187B)
803 sc->sc_flags |= URTW_RTL8187B;
805 sc->sc_debug = urtw_debug;
808 mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev), MTX_NETWORK_LOCK,
810 usb_callout_init_mtx(&sc->sc_led_ch, &sc->sc_mtx, 0);
811 TASK_INIT(&sc->sc_led_task, 0, urtw_ledtask, sc);
812 TASK_INIT(&sc->sc_updateslot_task, 0, urtw_updateslottask, sc);
813 callout_init(&sc->sc_watchdog_ch, 0);
814 mbufq_init(&sc->sc_snd, ifqmaxlen);
816 if (sc->sc_flags & URTW_RTL8187B) {
817 setup_start = urtw_8187b_usbconfig;
818 n_setup = URTW_8187B_N_XFERS;
820 setup_start = urtw_8187l_usbconfig;
821 n_setup = URTW_8187L_N_XFERS;
824 error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_xfer,
825 setup_start, n_setup, sc, &sc->sc_mtx);
827 device_printf(dev, "could not allocate USB transfers, "
828 "err=%s\n", usbd_errstr(error));
833 if (sc->sc_flags & URTW_RTL8187B) {
835 usbd_xfer_get_frame_buffer(sc->sc_xfer[
836 URTW_8187B_BULK_TX_BE], 0);
839 usbd_xfer_get_frame_buffer(sc->sc_xfer[
840 URTW_8187L_BULK_TX_LOW], 0);
845 urtw_read32_m(sc, URTW_RX, &data);
846 sc->sc_epromtype = (data & URTW_RX_9356SEL) ? URTW_EEPROM_93C56 :
849 error = urtw_get_rfchip(sc);
852 error = urtw_get_macaddr(sc);
855 error = urtw_get_txpwr(sc);
858 error = urtw_led_init(sc);
864 sc->sc_rts_retry = URTW_DEFAULT_RTS_RETRY;
865 sc->sc_tx_retry = URTW_DEFAULT_TX_RETRY;
867 sc->sc_preamble_mode = urtw_preamble_mode;
870 ic->ic_name = device_get_nameunit(dev);
871 ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
872 ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
874 /* set device capabilities */
876 IEEE80211_C_STA | /* station mode */
877 IEEE80211_C_MONITOR | /* monitor mode supported */
878 IEEE80211_C_TXPMGT | /* tx power management */
879 IEEE80211_C_SHPREAMBLE | /* short preamble supported */
880 IEEE80211_C_SHSLOT | /* short slot time supported */
881 IEEE80211_C_BGSCAN | /* capable of bg scanning */
882 IEEE80211_C_WPA; /* 802.11i */
884 /* XXX TODO: setup regdomain if URTW_EPROM_CHANPLAN_BY_HW bit is set.*/
886 urtw_getradiocaps(ic, IEEE80211_CHAN_MAX, &ic->ic_nchans,
889 ieee80211_ifattach(ic);
890 ic->ic_raw_xmit = urtw_raw_xmit;
891 ic->ic_scan_start = urtw_scan_start;
892 ic->ic_scan_end = urtw_scan_end;
893 ic->ic_getradiocaps = urtw_getradiocaps;
894 ic->ic_set_channel = urtw_set_channel;
895 ic->ic_updateslot = urtw_updateslot;
896 ic->ic_vap_create = urtw_vap_create;
897 ic->ic_vap_delete = urtw_vap_delete;
898 ic->ic_update_mcast = urtw_update_mcast;
899 ic->ic_parent = urtw_parent;
900 ic->ic_transmit = urtw_transmit;
902 ieee80211_radiotap_attach(ic,
903 &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
904 URTW_TX_RADIOTAP_PRESENT,
905 &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
906 URTW_RX_RADIOTAP_PRESENT);
908 urtw_sysctl_node(sc);
911 ieee80211_announce(ic);
916 usbd_transfer_unsetup(sc->sc_xfer, (sc->sc_flags & URTW_RTL8187B) ?
917 URTW_8187B_N_XFERS : URTW_8187L_N_XFERS);
923 urtw_detach(device_t dev)
925 struct urtw_softc *sc = device_get_softc(dev);
926 struct ieee80211com *ic = &sc->sc_ic;
928 unsigned int n_xfers;
930 /* Prevent further ioctls */
932 sc->sc_flags |= URTW_DETACHED;
936 ieee80211_draintask(ic, &sc->sc_updateslot_task);
937 ieee80211_draintask(ic, &sc->sc_led_task);
939 usb_callout_drain(&sc->sc_led_ch);
940 callout_drain(&sc->sc_watchdog_ch);
942 n_xfers = (sc->sc_flags & URTW_RTL8187B) ?
943 URTW_8187B_N_XFERS : URTW_8187L_N_XFERS;
945 /* prevent further allocations from RX/TX data lists */
947 STAILQ_INIT(&sc->sc_tx_active);
948 STAILQ_INIT(&sc->sc_tx_inactive);
949 STAILQ_INIT(&sc->sc_tx_pending);
951 STAILQ_INIT(&sc->sc_rx_active);
952 STAILQ_INIT(&sc->sc_rx_inactive);
955 /* drain USB transfers */
956 for (x = 0; x != n_xfers; x++)
957 usbd_transfer_drain(sc->sc_xfer[x]);
959 /* free data buffers */
961 urtw_free_tx_data_list(sc);
962 urtw_free_rx_data_list(sc);
965 /* free USB transfers and some data buffers */
966 usbd_transfer_unsetup(sc->sc_xfer, n_xfers);
968 ieee80211_ifdetach(ic);
969 mbufq_drain(&sc->sc_snd);
970 mtx_destroy(&sc->sc_mtx);
975 urtw_free_tx_data_list(struct urtw_softc *sc)
977 urtw_free_data_list(sc, sc->sc_tx, URTW_TX_DATA_LIST_COUNT, 0);
981 urtw_free_rx_data_list(struct urtw_softc *sc)
983 urtw_free_data_list(sc, sc->sc_rx, URTW_RX_DATA_LIST_COUNT, 1);
987 urtw_free_data_list(struct urtw_softc *sc, struct urtw_data data[], int ndata,
992 for (i = 0; i < ndata; i++) {
993 struct urtw_data *dp = &data[i];
1004 if (dp->ni != NULL) {
1005 ieee80211_free_node(dp->ni);
1011 static struct ieee80211vap *
1012 urtw_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
1013 enum ieee80211_opmode opmode, int flags,
1014 const uint8_t bssid[IEEE80211_ADDR_LEN],
1015 const uint8_t mac[IEEE80211_ADDR_LEN])
1017 struct urtw_vap *uvp;
1018 struct ieee80211vap *vap;
1020 if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
1022 uvp = malloc(sizeof(struct urtw_vap), M_80211_VAP, M_WAITOK | M_ZERO);
1024 /* enable s/w bmiss handling for sta mode */
1026 if (ieee80211_vap_setup(ic, vap, name, unit, opmode,
1027 flags | IEEE80211_CLONE_NOBEACONS, bssid) != 0) {
1029 free(uvp, M_80211_VAP);
1033 /* override state transition machine */
1034 uvp->newstate = vap->iv_newstate;
1035 vap->iv_newstate = urtw_newstate;
1037 /* complete setup */
1038 ieee80211_vap_attach(vap, ieee80211_media_change,
1039 ieee80211_media_status, mac);
1040 ic->ic_opmode = opmode;
1045 urtw_vap_delete(struct ieee80211vap *vap)
1047 struct urtw_vap *uvp = URTW_VAP(vap);
1049 ieee80211_vap_detach(vap);
1050 free(uvp, M_80211_VAP);
1054 urtw_init(struct urtw_softc *sc)
1059 URTW_ASSERT_LOCKED(sc);
1061 if (sc->sc_flags & URTW_RUNNING)
1064 error = (sc->sc_flags & URTW_RTL8187B) ? urtw_adapter_start_b(sc) :
1065 urtw_adapter_start(sc);
1069 /* reset softc variables */
1072 if (!(sc->sc_flags & URTW_INIT_ONCE)) {
1073 ret = urtw_alloc_rx_data_list(sc);
1076 ret = urtw_alloc_tx_data_list(sc);
1079 sc->sc_flags |= URTW_INIT_ONCE;
1082 error = urtw_rx_enable(sc);
1085 error = urtw_tx_enable(sc);
1089 if (sc->sc_flags & URTW_RTL8187B)
1090 usbd_transfer_start(sc->sc_xfer[URTW_8187B_BULK_TX_STATUS]);
1092 sc->sc_flags |= URTW_RUNNING;
1094 callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc);
1100 urtw_adapter_start_b(struct urtw_softc *sc)
1105 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
1109 urtw_read8_m(sc, URTW_CONFIG3, &data8);
1110 urtw_write8_m(sc, URTW_CONFIG3,
1111 data8 | URTW_CONFIG3_ANAPARAM_WRITE | URTW_CONFIG3_GNT_SELECT);
1112 urtw_write32_m(sc, URTW_ANAPARAM2, URTW_8187B_8225_ANAPARAM2_ON);
1113 urtw_write32_m(sc, URTW_ANAPARAM, URTW_8187B_8225_ANAPARAM_ON);
1114 urtw_write8_m(sc, URTW_ANAPARAM3, URTW_8187B_8225_ANAPARAM3_ON);
1116 urtw_write8_m(sc, 0x61, 0x10);
1117 urtw_read8_m(sc, 0x62, &data8);
1118 urtw_write8_m(sc, 0x62, data8 & ~(1 << 5));
1119 urtw_write8_m(sc, 0x62, data8 | (1 << 5));
1121 urtw_read8_m(sc, URTW_CONFIG3, &data8);
1122 data8 &= ~URTW_CONFIG3_ANAPARAM_WRITE;
1123 urtw_write8_m(sc, URTW_CONFIG3, data8);
1125 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
1129 error = urtw_8187b_cmd_reset(sc);
1133 error = sc->sc_rf_init(sc);
1136 urtw_write8_m(sc, URTW_CMD, URTW_CMD_RX_ENABLE | URTW_CMD_TX_ENABLE);
1138 /* fix RTL8187B RX stall */
1139 error = urtw_intr_enable(sc);
1143 error = urtw_write8e(sc, 0x41, 0xf4);
1146 error = urtw_write8e(sc, 0x40, 0x00);
1149 error = urtw_write8e(sc, 0x42, 0x00);
1152 error = urtw_write8e(sc, 0x42, 0x01);
1155 error = urtw_write8e(sc, 0x40, 0x0f);
1158 error = urtw_write8e(sc, 0x42, 0x00);
1161 error = urtw_write8e(sc, 0x42, 0x01);
1165 urtw_read8_m(sc, 0xdb, &data8);
1166 urtw_write8_m(sc, 0xdb, data8 | (1 << 2));
1167 urtw_write16_m(sc, 0x372, 0x59fa);
1168 urtw_write16_m(sc, 0x374, 0x59d2);
1169 urtw_write16_m(sc, 0x376, 0x59d2);
1170 urtw_write16_m(sc, 0x378, 0x19fa);
1171 urtw_write16_m(sc, 0x37a, 0x19fa);
1172 urtw_write16_m(sc, 0x37c, 0x00d0);
1173 urtw_write8_m(sc, 0x61, 0);
1175 urtw_write8_m(sc, 0x180, 0x0f);
1176 urtw_write8_m(sc, 0x183, 0x03);
1177 urtw_write8_m(sc, 0xda, 0x10);
1178 urtw_write8_m(sc, 0x24d, 0x08);
1179 urtw_write32_m(sc, URTW_HSSI_PARA, 0x0600321b);
1181 urtw_write16_m(sc, 0x1ec, 0x800); /* RX MAX SIZE */
1187 urtw_adapter_start(struct urtw_softc *sc)
1189 struct ieee80211com *ic = &sc->sc_ic;
1192 error = urtw_reset(sc);
1196 urtw_write8_m(sc, URTW_ADDR_MAGIC1, 0);
1197 urtw_write8_m(sc, URTW_GPIO, 0);
1200 urtw_write8_m(sc, URTW_ADDR_MAGIC1, 4);
1201 error = urtw_led_ctl(sc, URTW_LED_CTL_POWER_ON);
1205 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
1208 /* applying MAC address again. */
1209 urtw_write32_m(sc, URTW_MAC0, ((uint32_t *)ic->ic_macaddr)[0]);
1210 urtw_write16_m(sc, URTW_MAC4, ((uint32_t *)ic->ic_macaddr)[1] & 0xffff);
1211 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
1215 error = urtw_update_msr(sc);
1219 urtw_write32_m(sc, URTW_INT_TIMEOUT, 0);
1220 urtw_write8_m(sc, URTW_WPA_CONFIG, 0);
1221 urtw_write8_m(sc, URTW_RATE_FALLBACK, URTW_RATE_FALLBACK_ENABLE | 0x1);
1222 error = urtw_set_rate(sc);
1226 error = sc->sc_rf_init(sc);
1229 if (sc->sc_rf_set_sens != NULL)
1230 sc->sc_rf_set_sens(sc, sc->sc_sens);
1232 /* XXX correct? to call write16 */
1233 urtw_write16_m(sc, URTW_PSR, 1);
1234 urtw_write16_m(sc, URTW_ADDR_MAGIC2, 0x10);
1235 urtw_write8_m(sc, URTW_TALLY_SEL, 0x80);
1236 urtw_write8_m(sc, URTW_ADDR_MAGIC3, 0x60);
1237 /* XXX correct? to call write16 */
1238 urtw_write16_m(sc, URTW_PSR, 0);
1239 urtw_write8_m(sc, URTW_ADDR_MAGIC1, 4);
1241 error = urtw_intr_enable(sc);
1250 urtw_set_mode(struct urtw_softc *sc, uint32_t mode)
1255 urtw_read8_m(sc, URTW_EPROM_CMD, &data);
1256 data = (data & ~URTW_EPROM_CMD_MASK) | (mode << URTW_EPROM_CMD_SHIFT);
1257 data = data & ~(URTW_EPROM_CS | URTW_EPROM_CK);
1258 urtw_write8_m(sc, URTW_EPROM_CMD, data);
1264 urtw_8187b_cmd_reset(struct urtw_softc *sc)
1270 /* XXX the code can be duplicate with urtw_reset(). */
1271 urtw_read8_m(sc, URTW_CMD, &data8);
1272 data8 = (data8 & 0x2) | URTW_CMD_RST;
1273 urtw_write8_m(sc, URTW_CMD, data8);
1275 for (i = 0; i < 20; i++) {
1276 usb_pause_mtx(&sc->sc_mtx, 2);
1277 urtw_read8_m(sc, URTW_CMD, &data8);
1278 if (!(data8 & URTW_CMD_RST))
1282 device_printf(sc->sc_dev, "reset timeout\n");
1290 urtw_do_request(struct urtw_softc *sc,
1291 struct usb_device_request *req, void *data)
1296 URTW_ASSERT_LOCKED(sc);
1299 err = usbd_do_request_flags(sc->sc_udev, &sc->sc_mtx,
1300 req, data, 0, NULL, 250 /* ms */);
1304 DPRINTF(sc, URTW_DEBUG_INIT,
1305 "Control request failed, %s (retrying)\n",
1307 usb_pause_mtx(&sc->sc_mtx, hz / 100);
1313 urtw_stop(struct urtw_softc *sc)
1318 URTW_ASSERT_LOCKED(sc);
1320 sc->sc_flags &= ~URTW_RUNNING;
1322 error = urtw_intr_disable(sc);
1325 urtw_read8_m(sc, URTW_CMD, &data8);
1326 data8 &= ~(URTW_CMD_RX_ENABLE | URTW_CMD_TX_ENABLE);
1327 urtw_write8_m(sc, URTW_CMD, data8);
1329 error = sc->sc_rf_stop(sc);
1333 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
1336 urtw_read8_m(sc, URTW_CONFIG4, &data8);
1337 urtw_write8_m(sc, URTW_CONFIG4, data8 | URTW_CONFIG4_VCOOFF);
1338 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
1343 device_printf(sc->sc_dev, "failed to stop (%s)\n",
1344 usbd_errstr(error));
1346 usb_callout_stop(&sc->sc_led_ch);
1347 callout_stop(&sc->sc_watchdog_ch);
1349 urtw_abort_xfers(sc);
1353 urtw_abort_xfers(struct urtw_softc *sc)
1357 URTW_ASSERT_LOCKED(sc);
1359 max = (sc->sc_flags & URTW_RTL8187B) ? URTW_8187B_N_XFERS :
1362 /* abort any pending transfers */
1363 for (i = 0; i < max; i++)
1364 usbd_transfer_stop(sc->sc_xfer[i]);
1368 urtw_parent(struct ieee80211com *ic)
1370 struct urtw_softc *sc = ic->ic_softc;
1374 if (sc->sc_flags & URTW_DETACHED) {
1379 if (ic->ic_nrunning > 0) {
1380 if (sc->sc_flags & URTW_RUNNING) {
1381 if (ic->ic_promisc > 0 || ic->ic_allmulti > 0)
1387 } else if (sc->sc_flags & URTW_RUNNING)
1391 ieee80211_start_all(ic);
1395 urtw_transmit(struct ieee80211com *ic, struct mbuf *m)
1397 struct urtw_softc *sc = ic->ic_softc;
1401 if ((sc->sc_flags & URTW_RUNNING) == 0) {
1405 error = mbufq_enqueue(&sc->sc_snd, m);
1417 urtw_start(struct urtw_softc *sc)
1419 struct urtw_data *bf;
1420 struct ieee80211_node *ni;
1423 URTW_ASSERT_LOCKED(sc);
1425 if ((sc->sc_flags & URTW_RUNNING) == 0)
1428 while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
1429 bf = urtw_getbuf(sc);
1431 mbufq_prepend(&sc->sc_snd, m);
1435 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
1436 m->m_pkthdr.rcvif = NULL;
1438 if (urtw_tx_start(sc, ni, m, bf, URTW_PRIORITY_NORMAL) != 0) {
1439 if_inc_counter(ni->ni_vap->iv_ifp,
1440 IFCOUNTER_OERRORS, 1);
1441 STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
1442 ieee80211_free_node(ni);
1447 callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc);
1452 urtw_alloc_data_list(struct urtw_softc *sc, struct urtw_data data[],
1453 int ndata, int maxsz, void *dma_buf)
1457 for (i = 0; i < ndata; i++) {
1458 struct urtw_data *dp = &data[i];
1461 if (dma_buf == NULL) {
1462 dp->m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
1463 if (dp->m == NULL) {
1464 device_printf(sc->sc_dev,
1465 "could not allocate rx mbuf\n");
1469 dp->buf = mtod(dp->m, uint8_t *);
1472 dp->buf = ((uint8_t *)dma_buf) +
1479 fail: urtw_free_data_list(sc, data, ndata, 1);
1484 urtw_alloc_rx_data_list(struct urtw_softc *sc)
1488 error = urtw_alloc_data_list(sc,
1489 sc->sc_rx, URTW_RX_DATA_LIST_COUNT,
1490 MCLBYTES, NULL /* mbufs */);
1494 STAILQ_INIT(&sc->sc_rx_active);
1495 STAILQ_INIT(&sc->sc_rx_inactive);
1497 for (i = 0; i < URTW_RX_DATA_LIST_COUNT; i++)
1498 STAILQ_INSERT_HEAD(&sc->sc_rx_inactive, &sc->sc_rx[i], next);
1504 urtw_alloc_tx_data_list(struct urtw_softc *sc)
1508 error = urtw_alloc_data_list(sc,
1509 sc->sc_tx, URTW_TX_DATA_LIST_COUNT, URTW_TX_MAXSIZE,
1510 sc->sc_tx_dma_buf /* no mbufs */);
1514 STAILQ_INIT(&sc->sc_tx_active);
1515 STAILQ_INIT(&sc->sc_tx_inactive);
1516 STAILQ_INIT(&sc->sc_tx_pending);
1518 for (i = 0; i < URTW_TX_DATA_LIST_COUNT; i++)
1519 STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, &sc->sc_tx[i],
1526 urtw_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
1527 const struct ieee80211_bpf_params *params)
1529 struct ieee80211com *ic = ni->ni_ic;
1530 struct urtw_softc *sc = ic->ic_softc;
1531 struct urtw_data *bf;
1533 /* prevent management frames from being sent if we're not ready */
1534 if (!(sc->sc_flags & URTW_RUNNING)) {
1539 bf = urtw_getbuf(sc);
1543 return (ENOBUFS); /* XXX */
1546 if (urtw_tx_start(sc, ni, m, bf, URTW_PRIORITY_LOW) != 0) {
1547 STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
1558 urtw_scan_start(struct ieee80211com *ic)
1561 /* XXX do nothing? */
1565 urtw_scan_end(struct ieee80211com *ic)
1568 /* XXX do nothing? */
1572 urtw_getradiocaps(struct ieee80211com *ic,
1573 int maxchans, int *nchans, struct ieee80211_channel chans[])
1575 uint8_t bands[IEEE80211_MODE_BYTES];
1577 memset(bands, 0, sizeof(bands));
1578 setbit(bands, IEEE80211_MODE_11B);
1579 setbit(bands, IEEE80211_MODE_11G);
1580 ieee80211_add_channel_list_2ghz(chans, maxchans, nchans,
1581 urtw_chan_2ghz, nitems(urtw_chan_2ghz), 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,
1657 pkttime = 0, txdur = 0, isshort = 0, xferlen;
1658 uint16_t acktime, rtstime, ctstime;
1662 URTW_ASSERT_LOCKED(sc);
1667 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
1668 k = ieee80211_crypto_encap(ni, m0);
1670 device_printf(sc->sc_dev,
1671 "ieee80211_crypto_encap returns NULL.\n");
1672 /* XXX we don't expect the fragmented frames */
1677 /* in case packet header moved, reset pointer */
1678 wh = mtod(m0, struct ieee80211_frame *);
1681 if (ieee80211_radiotap_active_vap(vap)) {
1682 struct urtw_tx_radiotap_header *tap = &sc->sc_txtap;
1684 /* XXX Are variables correct? */
1686 tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
1687 tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
1689 ieee80211_radiotap_tx(vap, m0);
1692 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_MGT ||
1693 (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL ||
1694 (m0->m_flags & M_EAPOL) != 0) {
1695 rate = tp->mgmtrate;
1697 /* for data frames */
1698 if (IEEE80211_IS_MULTICAST(wh->i_addr1))
1699 rate = tp->mcastrate;
1700 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
1701 rate = tp->ucastrate;
1703 rate = urtw_rtl2rate(sc->sc_currate);
1706 sc->sc_stats.txrates[sc->sc_currate]++;
1708 if (IEEE80211_IS_MULTICAST(wh->i_addr1))
1709 txdur = pkttime = urtw_compute_txtime(m0->m_pkthdr.len +
1710 IEEE80211_CRC_LEN, rate, 0, 0);
1712 acktime = urtw_compute_txtime(14, 2,0, 0);
1713 if ((m0->m_pkthdr.len + 4) > vap->iv_rtsthreshold) {
1716 rtstime = urtw_compute_txtime(URTW_ACKCTS_LEN, 2, 0, 0);
1717 ctstime = urtw_compute_txtime(14, 2, 0, 0);
1718 pkttime = urtw_compute_txtime(m0->m_pkthdr.len +
1719 IEEE80211_CRC_LEN, rate, 0, isshort);
1720 rtsdur = ctstime + pkttime + acktime +
1721 3 * URTW_ASIFS_TIME;
1722 txdur = rtstime + rtsdur;
1724 rtsenable = ctsenable = rtsdur = 0;
1725 pkttime = urtw_compute_txtime(m0->m_pkthdr.len +
1726 IEEE80211_CRC_LEN, rate, 0, isshort);
1727 txdur = pkttime + URTW_ASIFS_TIME + acktime;
1730 if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG)
1731 dur = urtw_compute_txtime(m0->m_pkthdr.len +
1732 IEEE80211_CRC_LEN, rate, 0, isshort) +
1733 3 * URTW_ASIFS_TIME +
1736 dur = URTW_ASIFS_TIME + acktime;
1738 USETW(wh->i_dur, dur);
1740 xferlen = m0->m_pkthdr.len;
1741 xferlen += (sc->sc_flags & URTW_RTL8187B) ? (4 * 8) : (4 * 3);
1742 if ((0 == xferlen % 64) || (0 == xferlen % 512))
1745 memset(data->buf, 0, URTW_TX_MAXSIZE);
1746 flags = m0->m_pkthdr.len & 0xfff;
1747 flags |= URTW_TX_FLAG_NO_ENC;
1748 if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
1749 (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE) &&
1750 (sc->sc_preamble_mode == URTW_PREAMBLE_MODE_SHORT) &&
1751 (sc->sc_currate != 0))
1752 flags |= URTW_TX_FLAG_SPLCP;
1753 if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG)
1754 flags |= URTW_TX_FLAG_MOREFRAG;
1756 flags |= (sc->sc_currate & 0xf) << URTW_TX_FLAG_TXRATE_SHIFT;
1758 if (sc->sc_flags & URTW_RTL8187B) {
1759 struct urtw_8187b_txhdr *tx;
1761 tx = (struct urtw_8187b_txhdr *)data->buf;
1763 flags |= URTW_TX_FLAG_CTS;
1765 flags |= URTW_TX_FLAG_RTS;
1766 flags |= (urtw_rate2rtl(11) & 0xf) <<
1767 URTW_TX_FLAG_RTSRATE_SHIFT;
1768 tx->rtsdur = rtsdur;
1770 tx->flag = htole32(flags);
1772 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
1773 IEEE80211_FC0_TYPE_MGT &&
1774 (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) ==
1775 IEEE80211_FC0_SUBTYPE_PROBE_RESP)
1778 tx->retry = URTW_TX_MAXRETRY;
1779 m_copydata(m0, 0, m0->m_pkthdr.len, (uint8_t *)(tx + 1));
1781 struct urtw_8187l_txhdr *tx;
1783 tx = (struct urtw_8187l_txhdr *)data->buf;
1785 flags |= URTW_TX_FLAG_RTS;
1786 tx->rtsdur = rtsdur;
1788 flags |= (urtw_rate2rtl(11) & 0xf) << URTW_TX_FLAG_RTSRATE_SHIFT;
1789 tx->flag = htole32(flags);
1790 tx->retry = 3; /* CW minimum */
1791 tx->retry |= 7 << 4; /* CW maximum */
1792 tx->retry |= URTW_TX_MAXRETRY << 8; /* retry limitation */
1793 m_copydata(m0, 0, m0->m_pkthdr.len, (uint8_t *)(tx + 1));
1796 data->buflen = xferlen;
1800 if (sc->sc_flags & URTW_RTL8187B) {
1801 switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) {
1802 case IEEE80211_FC0_TYPE_CTL:
1803 case IEEE80211_FC0_TYPE_MGT:
1804 xfer = sc->sc_xfer[URTW_8187B_BULK_TX_EP12];
1807 KASSERT(M_WME_GETAC(m0) < URTW_8187B_TXPIPE_MAX,
1808 ("unsupported WME pipe %d", M_WME_GETAC(m0)));
1809 xfer = rtl8187b_pipes[M_WME_GETAC(m0)];
1813 xfer = (prior == URTW_PRIORITY_LOW) ?
1814 sc->sc_xfer[URTW_8187L_BULK_TX_LOW] :
1815 sc->sc_xfer[URTW_8187L_BULK_TX_NORMAL];
1817 STAILQ_INSERT_TAIL(&sc->sc_tx_pending, data, next);
1818 usbd_transfer_start(xfer);
1820 error = urtw_led_ctl(sc, URTW_LED_CTL_TX);
1822 device_printf(sc->sc_dev, "could not control LED (%d)\n",
1828 urtw_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
1830 struct ieee80211com *ic = vap->iv_ic;
1831 struct urtw_softc *sc = ic->ic_softc;
1832 struct urtw_vap *uvp = URTW_VAP(vap);
1833 struct ieee80211_node *ni;
1834 usb_error_t error = 0;
1836 DPRINTF(sc, URTW_DEBUG_STATE, "%s: %s -> %s\n", __func__,
1837 ieee80211_state_name[vap->iv_state],
1838 ieee80211_state_name[nstate]);
1840 sc->sc_state = nstate;
1842 IEEE80211_UNLOCK(ic);
1844 usb_callout_stop(&sc->sc_led_ch);
1845 callout_stop(&sc->sc_watchdog_ch);
1848 case IEEE80211_S_INIT:
1849 case IEEE80211_S_SCAN:
1850 case IEEE80211_S_AUTH:
1851 case IEEE80211_S_ASSOC:
1853 case IEEE80211_S_RUN:
1854 ni = ieee80211_ref_node(vap->iv_bss);
1855 /* setting bssid. */
1856 urtw_write32_m(sc, URTW_BSSID, ((uint32_t *)ni->ni_bssid)[0]);
1857 urtw_write16_m(sc, URTW_BSSID + 4,
1858 ((uint16_t *)ni->ni_bssid)[2]);
1859 urtw_update_msr(sc);
1860 /* XXX maybe the below would be incorrect. */
1861 urtw_write16_m(sc, URTW_ATIM_WND, 2);
1862 urtw_write16_m(sc, URTW_ATIM_TR_ITV, 100);
1863 urtw_write16_m(sc, URTW_BEACON_INTERVAL, 0x64);
1864 urtw_write16_m(sc, URTW_BEACON_INTERVAL_TIME, 100);
1865 error = urtw_led_ctl(sc, URTW_LED_CTL_LINK);
1867 device_printf(sc->sc_dev,
1868 "could not control LED (%d)\n", error);
1869 ieee80211_free_node(ni);
1877 return (uvp->newstate(vap, nstate, arg));
1881 urtw_watchdog(void *arg)
1883 struct urtw_softc *sc = arg;
1885 if (sc->sc_txtimer > 0) {
1886 if (--sc->sc_txtimer == 0) {
1887 device_printf(sc->sc_dev, "device timeout\n");
1888 counter_u64_add(sc->sc_ic.ic_oerrors, 1);
1891 callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc);
1896 urtw_set_multi(void *arg)
1898 /* XXX don't know how to set a device. Lack of docs. */
1902 urtw_set_rate(struct urtw_softc *sc)
1904 int i, basic_rate, min_rr_rate, max_rr_rate;
1908 basic_rate = urtw_rate2rtl(48);
1909 min_rr_rate = urtw_rate2rtl(12);
1910 max_rr_rate = urtw_rate2rtl(48);
1912 urtw_write8_m(sc, URTW_RESP_RATE,
1913 max_rr_rate << URTW_RESP_MAX_RATE_SHIFT |
1914 min_rr_rate << URTW_RESP_MIN_RATE_SHIFT);
1916 urtw_read16_m(sc, URTW_BRSR, &data);
1917 data &= ~URTW_BRSR_MBR_8185;
1919 for (i = 0; i <= basic_rate; i++)
1922 urtw_write16_m(sc, URTW_BRSR, data);
1928 urtw_rate2rtl(uint32_t rate)
1932 for (i = 0; i < nitems(urtw_ratetable); i++) {
1933 if (rate == urtw_ratetable[i].reg)
1934 return urtw_ratetable[i].val;
1941 urtw_rtl2rate(uint32_t rate)
1945 for (i = 0; i < nitems(urtw_ratetable); i++) {
1946 if (rate == urtw_ratetable[i].val)
1947 return urtw_ratetable[i].reg;
1954 urtw_update_msr(struct urtw_softc *sc)
1956 struct ieee80211com *ic = &sc->sc_ic;
1960 urtw_read8_m(sc, URTW_MSR, &data);
1961 data &= ~URTW_MSR_LINK_MASK;
1963 if (sc->sc_state == IEEE80211_S_RUN) {
1964 switch (ic->ic_opmode) {
1965 case IEEE80211_M_STA:
1966 case IEEE80211_M_MONITOR:
1967 data |= URTW_MSR_LINK_STA;
1968 if (sc->sc_flags & URTW_RTL8187B)
1969 data |= URTW_MSR_LINK_ENEDCA;
1971 case IEEE80211_M_IBSS:
1972 data |= URTW_MSR_LINK_ADHOC;
1974 case IEEE80211_M_HOSTAP:
1975 data |= URTW_MSR_LINK_HOSTAP;
1978 DPRINTF(sc, URTW_DEBUG_STATE,
1979 "unsupported operation mode 0x%x\n",
1981 error = USB_ERR_INVAL;
1985 data |= URTW_MSR_LINK_NONE;
1987 urtw_write8_m(sc, URTW_MSR, data);
1993 urtw_read8_c(struct urtw_softc *sc, int val, uint8_t *data)
1995 struct usb_device_request req;
1998 URTW_ASSERT_LOCKED(sc);
2000 req.bmRequestType = UT_READ_VENDOR_DEVICE;
2001 req.bRequest = URTW_8187_GETREGS_REQ;
2002 USETW(req.wValue, (val & 0xff) | 0xff00);
2003 USETW(req.wIndex, (val >> 8) & 0x3);
2004 USETW(req.wLength, sizeof(uint8_t));
2006 error = urtw_do_request(sc, &req, data);
2011 urtw_read16_c(struct urtw_softc *sc, int val, uint16_t *data)
2013 struct usb_device_request req;
2016 URTW_ASSERT_LOCKED(sc);
2018 req.bmRequestType = UT_READ_VENDOR_DEVICE;
2019 req.bRequest = URTW_8187_GETREGS_REQ;
2020 USETW(req.wValue, (val & 0xff) | 0xff00);
2021 USETW(req.wIndex, (val >> 8) & 0x3);
2022 USETW(req.wLength, sizeof(uint16_t));
2024 error = urtw_do_request(sc, &req, data);
2029 urtw_read32_c(struct urtw_softc *sc, int val, uint32_t *data)
2031 struct usb_device_request req;
2034 URTW_ASSERT_LOCKED(sc);
2036 req.bmRequestType = UT_READ_VENDOR_DEVICE;
2037 req.bRequest = URTW_8187_GETREGS_REQ;
2038 USETW(req.wValue, (val & 0xff) | 0xff00);
2039 USETW(req.wIndex, (val >> 8) & 0x3);
2040 USETW(req.wLength, sizeof(uint32_t));
2042 error = urtw_do_request(sc, &req, data);
2047 urtw_write8_c(struct urtw_softc *sc, int val, uint8_t data)
2049 struct usb_device_request req;
2051 URTW_ASSERT_LOCKED(sc);
2053 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
2054 req.bRequest = URTW_8187_SETREGS_REQ;
2055 USETW(req.wValue, (val & 0xff) | 0xff00);
2056 USETW(req.wIndex, (val >> 8) & 0x3);
2057 USETW(req.wLength, sizeof(uint8_t));
2059 return (urtw_do_request(sc, &req, &data));
2063 urtw_write16_c(struct urtw_softc *sc, int val, uint16_t data)
2065 struct usb_device_request req;
2067 URTW_ASSERT_LOCKED(sc);
2069 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
2070 req.bRequest = URTW_8187_SETREGS_REQ;
2071 USETW(req.wValue, (val & 0xff) | 0xff00);
2072 USETW(req.wIndex, (val >> 8) & 0x3);
2073 USETW(req.wLength, sizeof(uint16_t));
2075 return (urtw_do_request(sc, &req, &data));
2079 urtw_write32_c(struct urtw_softc *sc, int val, uint32_t data)
2081 struct usb_device_request req;
2083 URTW_ASSERT_LOCKED(sc);
2085 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
2086 req.bRequest = URTW_8187_SETREGS_REQ;
2087 USETW(req.wValue, (val & 0xff) | 0xff00);
2088 USETW(req.wIndex, (val >> 8) & 0x3);
2089 USETW(req.wLength, sizeof(uint32_t));
2091 return (urtw_do_request(sc, &req, &data));
2095 urtw_get_macaddr(struct urtw_softc *sc)
2097 struct ieee80211com *ic = &sc->sc_ic;
2101 error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR, &data);
2104 ic->ic_macaddr[0] = data & 0xff;
2105 ic->ic_macaddr[1] = (data & 0xff00) >> 8;
2106 error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR + 1, &data);
2109 ic->ic_macaddr[2] = data & 0xff;
2110 ic->ic_macaddr[3] = (data & 0xff00) >> 8;
2111 error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR + 2, &data);
2114 ic->ic_macaddr[4] = data & 0xff;
2115 ic->ic_macaddr[5] = (data & 0xff00) >> 8;
2121 urtw_eprom_read32(struct urtw_softc *sc, uint32_t addr, uint32_t *data)
2123 #define URTW_READCMD_LEN 3
2125 int16_t addrstr[8], data16, readcmd[] = { 1, 1, 0 };
2128 /* NB: make sure the buffer is initialized */
2131 /* enable EPROM programming */
2132 urtw_write8_m(sc, URTW_EPROM_CMD, URTW_EPROM_CMD_PROGRAM_MODE);
2133 DELAY(URTW_EPROM_DELAY);
2135 error = urtw_eprom_cs(sc, URTW_EPROM_ENABLE);
2138 error = urtw_eprom_ck(sc);
2141 error = urtw_eprom_sendbits(sc, readcmd, URTW_READCMD_LEN);
2144 if (sc->sc_epromtype == URTW_EEPROM_93C56) {
2146 addrstr[0] = addr & (1 << 7);
2147 addrstr[1] = addr & (1 << 6);
2148 addrstr[2] = addr & (1 << 5);
2149 addrstr[3] = addr & (1 << 4);
2150 addrstr[4] = addr & (1 << 3);
2151 addrstr[5] = addr & (1 << 2);
2152 addrstr[6] = addr & (1 << 1);
2153 addrstr[7] = addr & (1 << 0);
2156 addrstr[0] = addr & (1 << 5);
2157 addrstr[1] = addr & (1 << 4);
2158 addrstr[2] = addr & (1 << 3);
2159 addrstr[3] = addr & (1 << 2);
2160 addrstr[4] = addr & (1 << 1);
2161 addrstr[5] = addr & (1 << 0);
2163 error = urtw_eprom_sendbits(sc, addrstr, addrlen);
2167 error = urtw_eprom_writebit(sc, 0);
2171 for (i = 0; i < 16; i++) {
2172 error = urtw_eprom_ck(sc);
2175 error = urtw_eprom_readbit(sc, &data16);
2179 (*data) |= (data16 << (15 - i));
2182 error = urtw_eprom_cs(sc, URTW_EPROM_DISABLE);
2185 error = urtw_eprom_ck(sc);
2189 /* now disable EPROM programming */
2190 urtw_write8_m(sc, URTW_EPROM_CMD, URTW_EPROM_CMD_NORMAL_MODE);
2193 #undef URTW_READCMD_LEN
2197 urtw_eprom_cs(struct urtw_softc *sc, int able)
2202 urtw_read8_m(sc, URTW_EPROM_CMD, &data);
2203 if (able == URTW_EPROM_ENABLE)
2204 urtw_write8_m(sc, URTW_EPROM_CMD, data | URTW_EPROM_CS);
2206 urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_CS);
2207 DELAY(URTW_EPROM_DELAY);
2213 urtw_eprom_ck(struct urtw_softc *sc)
2219 urtw_read8_m(sc, URTW_EPROM_CMD, &data);
2220 urtw_write8_m(sc, URTW_EPROM_CMD, data | URTW_EPROM_CK);
2221 DELAY(URTW_EPROM_DELAY);
2223 urtw_read8_m(sc, URTW_EPROM_CMD, &data);
2224 urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_CK);
2225 DELAY(URTW_EPROM_DELAY);
2231 urtw_eprom_readbit(struct urtw_softc *sc, int16_t *data)
2236 urtw_read8_m(sc, URTW_EPROM_CMD, &data8);
2237 *data = (data8 & URTW_EPROM_READBIT) ? 1 : 0;
2238 DELAY(URTW_EPROM_DELAY);
2245 urtw_eprom_writebit(struct urtw_softc *sc, int16_t bit)
2250 urtw_read8_m(sc, URTW_EPROM_CMD, &data);
2252 urtw_write8_m(sc, URTW_EPROM_CMD, data | URTW_EPROM_WRITEBIT);
2254 urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_WRITEBIT);
2255 DELAY(URTW_EPROM_DELAY);
2261 urtw_eprom_sendbits(struct urtw_softc *sc, int16_t *buf, int buflen)
2264 usb_error_t error = 0;
2266 for (i = 0; i < buflen; i++) {
2267 error = urtw_eprom_writebit(sc, buf[i]);
2270 error = urtw_eprom_ck(sc);
2280 urtw_get_txpwr(struct urtw_softc *sc)
2286 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW_BASE, &data);
2289 sc->sc_txpwr_cck_base = data & 0xf;
2290 sc->sc_txpwr_ofdm_base = (data >> 4) & 0xf;
2292 for (i = 1, j = 0; i < 6; i += 2, j++) {
2293 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW0 + j, &data);
2296 sc->sc_txpwr_cck[i] = data & 0xf;
2297 sc->sc_txpwr_cck[i + 1] = (data & 0xf00) >> 8;
2298 sc->sc_txpwr_ofdm[i] = (data & 0xf0) >> 4;
2299 sc->sc_txpwr_ofdm[i + 1] = (data & 0xf000) >> 12;
2301 for (i = 1, j = 0; i < 4; i += 2, j++) {
2302 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW1 + j, &data);
2305 sc->sc_txpwr_cck[i + 6] = data & 0xf;
2306 sc->sc_txpwr_cck[i + 6 + 1] = (data & 0xf00) >> 8;
2307 sc->sc_txpwr_ofdm[i + 6] = (data & 0xf0) >> 4;
2308 sc->sc_txpwr_ofdm[i + 6 + 1] = (data & 0xf000) >> 12;
2310 if (sc->sc_flags & URTW_RTL8187B) {
2311 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW2, &data);
2314 sc->sc_txpwr_cck[1 + 6 + 4] = data & 0xf;
2315 sc->sc_txpwr_ofdm[1 + 6 + 4] = (data & 0xf0) >> 4;
2316 error = urtw_eprom_read32(sc, 0x0a, &data);
2319 sc->sc_txpwr_cck[2 + 6 + 4] = data & 0xf;
2320 sc->sc_txpwr_ofdm[2 + 6 + 4] = (data & 0xf0) >> 4;
2321 error = urtw_eprom_read32(sc, 0x1c, &data);
2324 sc->sc_txpwr_cck[3 + 6 + 4] = data & 0xf;
2325 sc->sc_txpwr_cck[3 + 6 + 4 + 1] = (data & 0xf00) >> 8;
2326 sc->sc_txpwr_ofdm[3 + 6 + 4] = (data & 0xf0) >> 4;
2327 sc->sc_txpwr_ofdm[3 + 6 + 4 + 1] = (data & 0xf000) >> 12;
2329 for (i = 1, j = 0; i < 4; i += 2, j++) {
2330 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW2 + j,
2334 sc->sc_txpwr_cck[i + 6 + 4] = data & 0xf;
2335 sc->sc_txpwr_cck[i + 6 + 4 + 1] = (data & 0xf00) >> 8;
2336 sc->sc_txpwr_ofdm[i + 6 + 4] = (data & 0xf0) >> 4;
2337 sc->sc_txpwr_ofdm[i + 6 + 4 + 1] = (data & 0xf000) >> 12;
2346 urtw_get_rfchip(struct urtw_softc *sc)
2353 if (sc->sc_flags & URTW_RTL8187B) {
2354 urtw_read8_m(sc, 0xe1, &data8);
2357 sc->sc_flags |= URTW_RTL8187B_REV_B;
2360 sc->sc_flags |= URTW_RTL8187B_REV_D;
2363 sc->sc_flags |= URTW_RTL8187B_REV_E;
2366 device_printf(sc->sc_dev, "unknown type: %#x\n", data8);
2367 sc->sc_flags |= URTW_RTL8187B_REV_B;
2371 urtw_read32_m(sc, URTW_TX_CONF, &data);
2372 switch (data & URTW_TX_HWMASK) {
2373 case URTW_TX_R8187vD_B:
2374 sc->sc_flags |= URTW_RTL8187B;
2376 case URTW_TX_R8187vD:
2379 device_printf(sc->sc_dev, "unknown RTL8187L type: %#x\n",
2380 data & URTW_TX_HWMASK);
2385 error = urtw_eprom_read32(sc, URTW_EPROM_RFCHIPID, &data);
2388 switch (data & 0xff) {
2389 case URTW_EPROM_RFCHIPID_RTL8225U:
2390 error = urtw_8225_isv2(sc, &ret);
2394 sc->sc_rf_init = urtw_8225_rf_init;
2395 sc->sc_rf_set_sens = urtw_8225_rf_set_sens;
2396 sc->sc_rf_set_chan = urtw_8225_rf_set_chan;
2397 sc->sc_rf_stop = urtw_8225_rf_stop;
2399 sc->sc_rf_init = urtw_8225v2_rf_init;
2400 sc->sc_rf_set_chan = urtw_8225v2_rf_set_chan;
2401 sc->sc_rf_stop = urtw_8225_rf_stop;
2403 sc->sc_max_sens = URTW_8225_RF_MAX_SENS;
2404 sc->sc_sens = URTW_8225_RF_DEF_SENS;
2406 case URTW_EPROM_RFCHIPID_RTL8225Z2:
2407 sc->sc_rf_init = urtw_8225v2b_rf_init;
2408 sc->sc_rf_set_chan = urtw_8225v2b_rf_set_chan;
2409 sc->sc_max_sens = URTW_8225_RF_MAX_SENS;
2410 sc->sc_sens = URTW_8225_RF_DEF_SENS;
2411 sc->sc_rf_stop = urtw_8225_rf_stop;
2414 DPRINTF(sc, URTW_DEBUG_STATE,
2415 "unsupported RF chip %d\n", data & 0xff);
2416 error = USB_ERR_INVAL;
2420 device_printf(sc->sc_dev, "%s rf %s hwrev %s\n",
2421 (sc->sc_flags & URTW_RTL8187B) ? "rtl8187b" : "rtl8187l",
2422 ((data & 0xff) == URTW_EPROM_RFCHIPID_RTL8225U) ? "rtl8225u" :
2424 (sc->sc_flags & URTW_RTL8187B) ? ((data8 == 0) ? "b" :
2425 (data8 == 1) ? "d" : "e") : "none");
2433 urtw_led_init(struct urtw_softc *sc)
2438 urtw_read8_m(sc, URTW_PSR, &sc->sc_psr);
2439 error = urtw_eprom_read32(sc, URTW_EPROM_SWREV, &rev);
2443 switch (rev & URTW_EPROM_CID_MASK) {
2444 case URTW_EPROM_CID_ALPHA0:
2445 sc->sc_strategy = URTW_SW_LED_MODE1;
2447 case URTW_EPROM_CID_SERCOMM_PS:
2448 sc->sc_strategy = URTW_SW_LED_MODE3;
2450 case URTW_EPROM_CID_HW_LED:
2451 sc->sc_strategy = URTW_HW_LED;
2453 case URTW_EPROM_CID_RSVD0:
2454 case URTW_EPROM_CID_RSVD1:
2456 sc->sc_strategy = URTW_SW_LED_MODE0;
2460 sc->sc_gpio_ledpin = URTW_LED_PIN_GPIO0;
2468 urtw_8225_rf_init(struct urtw_softc *sc)
2474 error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
2478 error = urtw_8225_usb_init(sc);
2482 urtw_write32_m(sc, URTW_RF_TIMING, 0x000a8008);
2483 urtw_read16_m(sc, URTW_BRSR, &data); /* XXX ??? */
2484 urtw_write16_m(sc, URTW_BRSR, 0xffff);
2485 urtw_write32_m(sc, URTW_RF_PARA, 0x100044);
2487 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
2490 urtw_write8_m(sc, URTW_CONFIG3, 0x44);
2491 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
2495 error = urtw_8185_rf_pins_enable(sc);
2498 usb_pause_mtx(&sc->sc_mtx, 1000);
2500 for (i = 0; i < nitems(urtw_8225_rf_part1); i++) {
2501 urtw_8225_write(sc, urtw_8225_rf_part1[i].reg,
2502 urtw_8225_rf_part1[i].val);
2503 usb_pause_mtx(&sc->sc_mtx, 1);
2505 usb_pause_mtx(&sc->sc_mtx, 100);
2507 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC1);
2508 usb_pause_mtx(&sc->sc_mtx, 200);
2510 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC2);
2511 usb_pause_mtx(&sc->sc_mtx, 200);
2513 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC3);
2515 for (i = 0; i < 95; i++) {
2516 urtw_8225_write(sc, URTW_8225_ADDR_1_MAGIC, (uint8_t)(i + 1));
2517 urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC, urtw_8225_rxgain[i]);
2521 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC4);
2523 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC5);
2525 for (i = 0; i < 128; i++) {
2526 urtw_8187_write_phy_ofdm(sc, 0xb, urtw_8225_agc[i]);
2527 usb_pause_mtx(&sc->sc_mtx, 1);
2528 urtw_8187_write_phy_ofdm(sc, 0xa, (uint8_t)i + 0x80);
2529 usb_pause_mtx(&sc->sc_mtx, 1);
2532 for (i = 0; i < nitems(urtw_8225_rf_part2); i++) {
2533 urtw_8187_write_phy_ofdm(sc, urtw_8225_rf_part2[i].reg,
2534 urtw_8225_rf_part2[i].val);
2535 usb_pause_mtx(&sc->sc_mtx, 1);
2538 error = urtw_8225_setgain(sc, 4);
2542 for (i = 0; i < nitems(urtw_8225_rf_part3); i++) {
2543 urtw_8187_write_phy_cck(sc, urtw_8225_rf_part3[i].reg,
2544 urtw_8225_rf_part3[i].val);
2545 usb_pause_mtx(&sc->sc_mtx, 1);
2548 urtw_write8_m(sc, URTW_TESTR, 0x0d);
2550 error = urtw_8225_set_txpwrlvl(sc, 1);
2554 urtw_8187_write_phy_cck(sc, 0x10, 0x9b);
2555 usb_pause_mtx(&sc->sc_mtx, 1);
2556 urtw_8187_write_phy_ofdm(sc, 0x26, 0x90);
2557 usb_pause_mtx(&sc->sc_mtx, 1);
2559 /* TX ant A, 0x0 for B */
2560 error = urtw_8185_tx_antenna(sc, 0x3);
2563 urtw_write32_m(sc, URTW_HSSI_PARA, 0x3dc00002);
2565 error = urtw_8225_rf_set_chan(sc, 1);
2571 urtw_8185_rf_pins_enable(struct urtw_softc *sc)
2573 usb_error_t error = 0;
2575 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x1ff7);
2581 urtw_8185_tx_antenna(struct urtw_softc *sc, uint8_t ant)
2585 urtw_write8_m(sc, URTW_TX_ANTENNA, ant);
2586 usb_pause_mtx(&sc->sc_mtx, 1);
2592 urtw_8187_write_phy_ofdm_c(struct urtw_softc *sc, uint8_t addr, uint32_t data)
2596 return urtw_8187_write_phy(sc, addr, data);
2600 urtw_8187_write_phy_cck_c(struct urtw_softc *sc, uint8_t addr, uint32_t data)
2604 return urtw_8187_write_phy(sc, addr, data | 0x10000);
2608 urtw_8187_write_phy(struct urtw_softc *sc, uint8_t addr, uint32_t data)
2613 phyw = ((data << 8) | (addr | 0x80));
2614 urtw_write8_m(sc, URTW_PHY_MAGIC4, ((phyw & 0xff000000) >> 24));
2615 urtw_write8_m(sc, URTW_PHY_MAGIC3, ((phyw & 0x00ff0000) >> 16));
2616 urtw_write8_m(sc, URTW_PHY_MAGIC2, ((phyw & 0x0000ff00) >> 8));
2617 urtw_write8_m(sc, URTW_PHY_MAGIC1, ((phyw & 0x000000ff)));
2618 usb_pause_mtx(&sc->sc_mtx, 1);
2624 urtw_8225_setgain(struct urtw_softc *sc, int16_t gain)
2628 urtw_8187_write_phy_ofdm(sc, 0x0d, urtw_8225_gain[gain * 4]);
2629 urtw_8187_write_phy_ofdm(sc, 0x1b, urtw_8225_gain[gain * 4 + 2]);
2630 urtw_8187_write_phy_ofdm(sc, 0x1d, urtw_8225_gain[gain * 4 + 3]);
2631 urtw_8187_write_phy_ofdm(sc, 0x23, urtw_8225_gain[gain * 4 + 1]);
2637 urtw_8225_usb_init(struct urtw_softc *sc)
2642 urtw_write8_m(sc, URTW_RF_PINS_SELECT + 1, 0);
2643 urtw_write8_m(sc, URTW_GPIO, 0);
2644 error = urtw_read8e(sc, 0x53, &data);
2647 error = urtw_write8e(sc, 0x53, data | (1 << 7));
2650 urtw_write8_m(sc, URTW_RF_PINS_SELECT + 1, 4);
2651 urtw_write8_m(sc, URTW_GPIO, 0x20);
2652 urtw_write8_m(sc, URTW_GP_ENABLE, 0);
2654 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, 0x80);
2655 urtw_write16_m(sc, URTW_RF_PINS_SELECT, 0x80);
2656 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x80);
2658 usb_pause_mtx(&sc->sc_mtx, 500);
2664 urtw_8225_write_c(struct urtw_softc *sc, uint8_t addr, uint16_t data)
2666 uint16_t d80, d82, d84;
2669 urtw_read16_m(sc, URTW_RF_PINS_OUTPUT, &d80);
2670 d80 &= URTW_RF_PINS_MAGIC1;
2671 urtw_read16_m(sc, URTW_RF_PINS_ENABLE, &d82);
2672 urtw_read16_m(sc, URTW_RF_PINS_SELECT, &d84);
2673 d84 &= URTW_RF_PINS_MAGIC2;
2674 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, d82 | URTW_RF_PINS_MAGIC3);
2675 urtw_write16_m(sc, URTW_RF_PINS_SELECT, d84 | URTW_RF_PINS_MAGIC3);
2678 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80 | URTW_BB_HOST_BANG_EN);
2680 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80);
2683 error = urtw_8225_write_s16(sc, addr, 0x8225, &data);
2687 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80 | URTW_BB_HOST_BANG_EN);
2689 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80 | URTW_BB_HOST_BANG_EN);
2690 urtw_write16_m(sc, URTW_RF_PINS_SELECT, d84);
2691 usb_pause_mtx(&sc->sc_mtx, 2);
2697 urtw_8225_write_s16(struct urtw_softc *sc, uint8_t addr, int index,
2702 struct usb_device_request req;
2703 usb_error_t error = 0;
2707 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
2708 req.bRequest = URTW_8187_SETREGS_REQ;
2709 USETW(req.wValue, addr);
2710 USETW(req.wIndex, index);
2711 USETW(req.wLength, sizeof(uint16_t));
2712 buf[0] = (data16 & 0x00ff);
2713 buf[1] = (data16 & 0xff00) >> 8;
2715 error = urtw_do_request(sc, &req, buf);
2721 urtw_8225_rf_set_chan(struct urtw_softc *sc, int chan)
2725 error = urtw_8225_set_txpwrlvl(sc, chan);
2728 urtw_8225_write(sc, URTW_8225_ADDR_7_MAGIC, urtw_8225_channel[chan]);
2729 usb_pause_mtx(&sc->sc_mtx, 10);
2735 urtw_8225_rf_set_sens(struct urtw_softc *sc, int sens)
2739 if (sens < 0 || sens > 6)
2744 URTW_8225_ADDR_C_MAGIC, URTW_8225_ADDR_C_DATA_MAGIC1);
2747 URTW_8225_ADDR_C_MAGIC, URTW_8225_ADDR_C_DATA_MAGIC2);
2750 error = urtw_8225_setgain(sc, sens);
2754 urtw_8187_write_phy_cck(sc, 0x41, urtw_8225_threshold[sens]);
2761 urtw_8225_set_txpwrlvl(struct urtw_softc *sc, int chan)
2764 uint8_t *cck_pwltable;
2765 uint8_t cck_pwrlvl_max, ofdm_pwrlvl_min, ofdm_pwrlvl_max;
2766 uint8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
2767 uint8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
2770 cck_pwrlvl_max = 11;
2771 ofdm_pwrlvl_max = 25; /* 12 -> 25 */
2772 ofdm_pwrlvl_min = 10;
2774 /* CCK power setting */
2775 cck_pwrlvl = (cck_pwrlvl > cck_pwrlvl_max) ? cck_pwrlvl_max : cck_pwrlvl;
2776 idx = cck_pwrlvl % 6;
2777 set = cck_pwrlvl / 6;
2778 cck_pwltable = (chan == 14) ? urtw_8225_txpwr_cck_ch14 :
2779 urtw_8225_txpwr_cck;
2781 urtw_write8_m(sc, URTW_TX_GAIN_CCK,
2782 urtw_8225_tx_gain_cck_ofdm[set] >> 1);
2783 for (i = 0; i < 8; i++) {
2784 urtw_8187_write_phy_cck(sc, 0x44 + i,
2785 cck_pwltable[idx * 8 + i]);
2787 usb_pause_mtx(&sc->sc_mtx, 1);
2789 /* OFDM power setting */
2790 ofdm_pwrlvl = (ofdm_pwrlvl > (ofdm_pwrlvl_max - ofdm_pwrlvl_min)) ?
2791 ofdm_pwrlvl_max : ofdm_pwrlvl + ofdm_pwrlvl_min;
2792 ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
2794 idx = ofdm_pwrlvl % 6;
2795 set = ofdm_pwrlvl / 6;
2797 error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
2800 urtw_8187_write_phy_ofdm(sc, 2, 0x42);
2801 urtw_8187_write_phy_ofdm(sc, 6, 0);
2802 urtw_8187_write_phy_ofdm(sc, 8, 0);
2804 urtw_write8_m(sc, URTW_TX_GAIN_OFDM,
2805 urtw_8225_tx_gain_cck_ofdm[set] >> 1);
2806 urtw_8187_write_phy_ofdm(sc, 0x5, urtw_8225_txpwr_ofdm[idx]);
2807 urtw_8187_write_phy_ofdm(sc, 0x7, urtw_8225_txpwr_ofdm[idx]);
2808 usb_pause_mtx(&sc->sc_mtx, 1);
2815 urtw_8225_rf_stop(struct urtw_softc *sc)
2820 urtw_8225_write(sc, 0x4, 0x1f);
2822 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
2826 urtw_read8_m(sc, URTW_CONFIG3, &data);
2827 urtw_write8_m(sc, URTW_CONFIG3, data | URTW_CONFIG3_ANAPARAM_WRITE);
2828 if (sc->sc_flags & URTW_RTL8187B) {
2829 urtw_write32_m(sc, URTW_ANAPARAM2,
2830 URTW_8187B_8225_ANAPARAM2_OFF);
2831 urtw_write32_m(sc, URTW_ANAPARAM, URTW_8187B_8225_ANAPARAM_OFF);
2832 urtw_write32_m(sc, URTW_ANAPARAM3,
2833 URTW_8187B_8225_ANAPARAM3_OFF);
2835 urtw_write32_m(sc, URTW_ANAPARAM2, URTW_8225_ANAPARAM2_OFF);
2836 urtw_write32_m(sc, URTW_ANAPARAM, URTW_8225_ANAPARAM_OFF);
2839 urtw_write8_m(sc, URTW_CONFIG3, data & ~URTW_CONFIG3_ANAPARAM_WRITE);
2840 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
2849 urtw_8225v2_rf_init(struct urtw_softc *sc)
2856 error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
2860 error = urtw_8225_usb_init(sc);
2864 urtw_write32_m(sc, URTW_RF_TIMING, 0x000a8008);
2865 urtw_read16_m(sc, URTW_BRSR, &data); /* XXX ??? */
2866 urtw_write16_m(sc, URTW_BRSR, 0xffff);
2867 urtw_write32_m(sc, URTW_RF_PARA, 0x100044);
2869 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
2872 urtw_write8_m(sc, URTW_CONFIG3, 0x44);
2873 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
2877 error = urtw_8185_rf_pins_enable(sc);
2881 usb_pause_mtx(&sc->sc_mtx, 500);
2883 for (i = 0; i < nitems(urtw_8225v2_rf_part1); i++) {
2884 urtw_8225_write(sc, urtw_8225v2_rf_part1[i].reg,
2885 urtw_8225v2_rf_part1[i].val);
2887 usb_pause_mtx(&sc->sc_mtx, 50);
2890 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC1);
2892 for (i = 0; i < 95; i++) {
2893 urtw_8225_write(sc, URTW_8225_ADDR_1_MAGIC, (uint8_t)(i + 1));
2894 urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC,
2895 urtw_8225v2_rxgain[i]);
2899 URTW_8225_ADDR_3_MAGIC, URTW_8225_ADDR_3_DATA_MAGIC1);
2901 URTW_8225_ADDR_5_MAGIC, URTW_8225_ADDR_5_DATA_MAGIC1);
2903 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC2);
2905 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC1);
2906 usb_pause_mtx(&sc->sc_mtx, 100);
2908 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC2);
2909 usb_pause_mtx(&sc->sc_mtx, 100);
2911 error = urtw_8225_read(sc, URTW_8225_ADDR_6_MAGIC, &data32);
2914 if (data32 != URTW_8225_ADDR_6_DATA_MAGIC1)
2915 device_printf(sc->sc_dev, "expect 0xe6!! (0x%x)\n", data32);
2916 if (!(data32 & URTW_8225_ADDR_6_DATA_MAGIC2)) {
2918 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC1);
2919 usb_pause_mtx(&sc->sc_mtx, 100);
2921 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC2);
2922 usb_pause_mtx(&sc->sc_mtx, 50);
2923 error = urtw_8225_read(sc, URTW_8225_ADDR_6_MAGIC, &data32);
2926 if (!(data32 & URTW_8225_ADDR_6_DATA_MAGIC2))
2927 device_printf(sc->sc_dev, "RF calibration failed\n");
2929 usb_pause_mtx(&sc->sc_mtx, 100);
2932 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC6);
2933 for (i = 0; i < 128; i++) {
2934 urtw_8187_write_phy_ofdm(sc, 0xb, urtw_8225_agc[i]);
2935 urtw_8187_write_phy_ofdm(sc, 0xa, (uint8_t)i + 0x80);
2938 for (i = 0; i < nitems(urtw_8225v2_rf_part2); i++) {
2939 urtw_8187_write_phy_ofdm(sc, urtw_8225v2_rf_part2[i].reg,
2940 urtw_8225v2_rf_part2[i].val);
2943 error = urtw_8225v2_setgain(sc, 4);
2947 for (i = 0; i < nitems(urtw_8225v2_rf_part3); i++) {
2948 urtw_8187_write_phy_cck(sc, urtw_8225v2_rf_part3[i].reg,
2949 urtw_8225v2_rf_part3[i].val);
2952 urtw_write8_m(sc, URTW_TESTR, 0x0d);
2954 error = urtw_8225v2_set_txpwrlvl(sc, 1);
2958 urtw_8187_write_phy_cck(sc, 0x10, 0x9b);
2959 urtw_8187_write_phy_ofdm(sc, 0x26, 0x90);
2961 /* TX ant A, 0x0 for B */
2962 error = urtw_8185_tx_antenna(sc, 0x3);
2965 urtw_write32_m(sc, URTW_HSSI_PARA, 0x3dc00002);
2967 error = urtw_8225_rf_set_chan(sc, 1);
2973 urtw_8225v2_rf_set_chan(struct urtw_softc *sc, int chan)
2977 error = urtw_8225v2_set_txpwrlvl(sc, chan);
2981 urtw_8225_write(sc, URTW_8225_ADDR_7_MAGIC, urtw_8225_channel[chan]);
2982 usb_pause_mtx(&sc->sc_mtx, 10);
2988 urtw_8225_read(struct urtw_softc *sc, uint8_t addr, uint32_t *data)
2992 uint8_t rlen = 12, wlen = 6;
2993 uint16_t o1, o2, o3, tmp;
2994 uint32_t d2w = ((uint32_t)(addr & 0x1f)) << 27;
2995 uint32_t mask = 0x80000000, value = 0;
2998 urtw_read16_m(sc, URTW_RF_PINS_OUTPUT, &o1);
2999 urtw_read16_m(sc, URTW_RF_PINS_ENABLE, &o2);
3000 urtw_read16_m(sc, URTW_RF_PINS_SELECT, &o3);
3001 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, o2 | URTW_RF_PINS_MAGIC4);
3002 urtw_write16_m(sc, URTW_RF_PINS_SELECT, o3 | URTW_RF_PINS_MAGIC4);
3003 o1 &= ~URTW_RF_PINS_MAGIC4;
3004 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1 | URTW_BB_HOST_BANG_EN);
3006 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1);
3009 for (i = 0; i < (wlen / 2); i++, mask = mask >> 1) {
3010 bit = ((d2w & mask) != 0) ? 1 : 0;
3012 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1);
3014 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
3015 URTW_BB_HOST_BANG_CLK);
3017 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
3018 URTW_BB_HOST_BANG_CLK);
3023 bit = ((d2w & mask) != 0) ? 1 : 0;
3024 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
3025 URTW_BB_HOST_BANG_CLK);
3027 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
3028 URTW_BB_HOST_BANG_CLK);
3030 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1);
3033 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 | URTW_BB_HOST_BANG_RW |
3034 URTW_BB_HOST_BANG_CLK);
3036 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 | URTW_BB_HOST_BANG_RW);
3038 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1 | URTW_BB_HOST_BANG_RW);
3042 for (i = 0; i < rlen; i++, mask = mask >> 1) {
3043 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
3044 o1 | URTW_BB_HOST_BANG_RW);
3046 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
3047 o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK);
3049 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
3050 o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK);
3052 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
3053 o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK);
3056 urtw_read16_m(sc, URTW_RF_PINS_INPUT, &tmp);
3057 value |= ((tmp & URTW_BB_HOST_BANG_CLK) ? mask : 0);
3058 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
3059 o1 | URTW_BB_HOST_BANG_RW);
3063 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1 | URTW_BB_HOST_BANG_EN |
3064 URTW_BB_HOST_BANG_RW);
3067 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, o2);
3068 urtw_write16_m(sc, URTW_RF_PINS_SELECT, o3);
3069 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, URTW_RF_PINS_OUTPUT_MAGIC1);
3079 urtw_8225v2_set_txpwrlvl(struct urtw_softc *sc, int chan)
3082 uint8_t *cck_pwrtable;
3083 uint8_t cck_pwrlvl_max = 15, ofdm_pwrlvl_max = 25, ofdm_pwrlvl_min = 10;
3084 uint8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
3085 uint8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
3088 /* CCK power setting */
3089 cck_pwrlvl = (cck_pwrlvl > cck_pwrlvl_max) ? cck_pwrlvl_max : cck_pwrlvl;
3090 cck_pwrlvl += sc->sc_txpwr_cck_base;
3091 cck_pwrlvl = (cck_pwrlvl > 35) ? 35 : cck_pwrlvl;
3092 cck_pwrtable = (chan == 14) ? urtw_8225v2_txpwr_cck_ch14 :
3093 urtw_8225v2_txpwr_cck;
3095 for (i = 0; i < 8; i++)
3096 urtw_8187_write_phy_cck(sc, 0x44 + i, cck_pwrtable[i]);
3098 urtw_write8_m(sc, URTW_TX_GAIN_CCK,
3099 urtw_8225v2_tx_gain_cck_ofdm[cck_pwrlvl]);
3100 usb_pause_mtx(&sc->sc_mtx, 1);
3102 /* OFDM power setting */
3103 ofdm_pwrlvl = (ofdm_pwrlvl > (ofdm_pwrlvl_max - ofdm_pwrlvl_min)) ?
3104 ofdm_pwrlvl_max : ofdm_pwrlvl + ofdm_pwrlvl_min;
3105 ofdm_pwrlvl += sc->sc_txpwr_ofdm_base;
3106 ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
3108 error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
3112 urtw_8187_write_phy_ofdm(sc, 2, 0x42);
3113 urtw_8187_write_phy_ofdm(sc, 5, 0x0);
3114 urtw_8187_write_phy_ofdm(sc, 6, 0x40);
3115 urtw_8187_write_phy_ofdm(sc, 7, 0x0);
3116 urtw_8187_write_phy_ofdm(sc, 8, 0x40);
3118 urtw_write8_m(sc, URTW_TX_GAIN_OFDM,
3119 urtw_8225v2_tx_gain_cck_ofdm[ofdm_pwrlvl]);
3120 usb_pause_mtx(&sc->sc_mtx, 1);
3126 urtw_8225v2_setgain(struct urtw_softc *sc, int16_t gain)
3132 gainp = urtw_8225v2_gain_bg;
3133 urtw_8187_write_phy_ofdm(sc, 0x0d, gainp[gain * 3]);
3134 usb_pause_mtx(&sc->sc_mtx, 1);
3135 urtw_8187_write_phy_ofdm(sc, 0x1b, gainp[gain * 3 + 1]);
3136 usb_pause_mtx(&sc->sc_mtx, 1);
3137 urtw_8187_write_phy_ofdm(sc, 0x1d, gainp[gain * 3 + 2]);
3138 usb_pause_mtx(&sc->sc_mtx, 1);
3139 urtw_8187_write_phy_ofdm(sc, 0x21, 0x17);
3140 usb_pause_mtx(&sc->sc_mtx, 1);
3146 urtw_8225_isv2(struct urtw_softc *sc, int *ret)
3153 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, URTW_RF_PINS_MAGIC5);
3154 urtw_write16_m(sc, URTW_RF_PINS_SELECT, URTW_RF_PINS_MAGIC5);
3155 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, URTW_RF_PINS_MAGIC5);
3156 usb_pause_mtx(&sc->sc_mtx, 500);
3158 urtw_8225_write(sc, URTW_8225_ADDR_0_MAGIC,
3159 URTW_8225_ADDR_0_DATA_MAGIC1);
3161 error = urtw_8225_read(sc, URTW_8225_ADDR_8_MAGIC, &data);
3164 if (data != URTW_8225_ADDR_8_DATA_MAGIC1)
3167 error = urtw_8225_read(sc, URTW_8225_ADDR_9_MAGIC, &data);
3170 if (data != URTW_8225_ADDR_9_DATA_MAGIC1)
3174 urtw_8225_write(sc, URTW_8225_ADDR_0_MAGIC,
3175 URTW_8225_ADDR_0_DATA_MAGIC2);
3181 urtw_8225v2b_rf_init(struct urtw_softc *sc)
3183 struct ieee80211com *ic = &sc->sc_ic;
3188 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3193 * initialize extra registers on 8187
3195 urtw_write16_m(sc, URTW_BRSR_8187B, 0xfff);
3198 urtw_read8_m(sc, URTW_CW_CONF, &data8);
3199 data8 |= URTW_CW_CONF_PERPACKET_RETRY;
3200 urtw_write8_m(sc, URTW_CW_CONF, data8);
3203 urtw_read8_m(sc, URTW_TX_AGC_CTL, &data8);
3204 data8 |= URTW_TX_AGC_CTL_PERPACKET_GAIN;
3205 urtw_write8_m(sc, URTW_TX_AGC_CTL, data8);
3207 /* Auto Rate Fallback Control */
3208 #define URTW_ARFR 0x1e0
3209 urtw_write16_m(sc, URTW_ARFR, 0xfff);
3210 urtw_read8_m(sc, URTW_RATE_FALLBACK, &data8);
3211 urtw_write8_m(sc, URTW_RATE_FALLBACK,
3212 data8 | URTW_RATE_FALLBACK_ENABLE);
3214 urtw_read8_m(sc, URTW_MSR, &data8);
3215 urtw_write8_m(sc, URTW_MSR, data8 & 0xf3);
3216 urtw_read8_m(sc, URTW_MSR, &data8);
3217 urtw_write8_m(sc, URTW_MSR, data8 | URTW_MSR_LINK_ENEDCA);
3218 urtw_write8_m(sc, URTW_ACM_CONTROL, sc->sc_acmctl);
3220 urtw_write16_m(sc, URTW_ATIM_WND, 2);
3221 urtw_write16_m(sc, URTW_BEACON_INTERVAL, 100);
3222 #define URTW_FEMR_FOR_8187B 0x1d4
3223 urtw_write16_m(sc, URTW_FEMR_FOR_8187B, 0xffff);
3226 urtw_read8_m(sc, URTW_CONFIG1, &data8);
3227 data8 = (data8 & 0x3f) | 0x80;
3228 urtw_write8_m(sc, URTW_CONFIG1, data8);
3230 /* applying MAC address again. */
3231 urtw_write32_m(sc, URTW_MAC0, ((uint32_t *)ic->ic_macaddr)[0]);
3232 urtw_write16_m(sc, URTW_MAC4, ((uint32_t *)ic->ic_macaddr)[1] & 0xffff);
3234 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3238 urtw_write8_m(sc, URTW_WPA_CONFIG, 0);
3243 for (i = 0; i < nitems(urtw_8225v2b_rf_part1); i++)
3244 urtw_write8_m(sc, urtw_8225v2b_rf_part1[i].reg,
3245 urtw_8225v2b_rf_part1[i].val);
3246 urtw_write16_m(sc, URTW_TID_AC_MAP, 0xfa50);
3247 urtw_write16_m(sc, URTW_INT_MIG, 0x0000);
3248 urtw_write32_m(sc, 0x1f0, 0);
3249 urtw_write32_m(sc, 0x1f4, 0);
3250 urtw_write8_m(sc, 0x1f8, 0);
3251 urtw_write32_m(sc, URTW_RF_TIMING, 0x4001);
3253 #define URTW_RFSW_CTRL 0x272
3254 urtw_write16_m(sc, URTW_RFSW_CTRL, 0x569a);
3259 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3262 urtw_read8_m(sc, URTW_CONFIG3, &data8);
3263 urtw_write8_m(sc, URTW_CONFIG3,
3264 data8 | URTW_CONFIG3_ANAPARAM_WRITE);
3266 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3270 /* setup RFE initial timing */
3271 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, 0x0480);
3272 urtw_write16_m(sc, URTW_RF_PINS_SELECT, 0x2488);
3273 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x1fff);
3274 usb_pause_mtx(&sc->sc_mtx, 1100);
3276 for (i = 0; i < nitems(urtw_8225v2b_rf_part0); i++) {
3277 urtw_8225_write(sc, urtw_8225v2b_rf_part0[i].reg,
3278 urtw_8225v2b_rf_part0[i].val);
3279 usb_pause_mtx(&sc->sc_mtx, 1);
3281 urtw_8225_write(sc, 0x00, 0x01b7);
3283 for (i = 0; i < 95; i++) {
3284 urtw_8225_write(sc, URTW_8225_ADDR_1_MAGIC, (uint8_t)(i + 1));
3285 usb_pause_mtx(&sc->sc_mtx, 1);
3286 urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC,
3287 urtw_8225v2b_rxgain[i]);
3288 usb_pause_mtx(&sc->sc_mtx, 1);
3291 urtw_8225_write(sc, URTW_8225_ADDR_3_MAGIC, 0x080);
3292 usb_pause_mtx(&sc->sc_mtx, 1);
3293 urtw_8225_write(sc, URTW_8225_ADDR_5_MAGIC, 0x004);
3294 usb_pause_mtx(&sc->sc_mtx, 1);
3295 urtw_8225_write(sc, URTW_8225_ADDR_0_MAGIC, 0x0b7);
3296 usb_pause_mtx(&sc->sc_mtx, 1);
3297 usb_pause_mtx(&sc->sc_mtx, 3000);
3298 urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC, 0xc4d);
3299 usb_pause_mtx(&sc->sc_mtx, 2000);
3300 urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC, 0x44d);
3301 usb_pause_mtx(&sc->sc_mtx, 1);
3302 urtw_8225_write(sc, URTW_8225_ADDR_0_MAGIC, 0x2bf);
3303 usb_pause_mtx(&sc->sc_mtx, 1);
3305 urtw_write8_m(sc, URTW_TX_GAIN_CCK, 0x03);
3306 urtw_write8_m(sc, URTW_TX_GAIN_OFDM, 0x07);
3307 urtw_write8_m(sc, URTW_TX_ANTENNA, 0x03);
3309 urtw_8187_write_phy_ofdm(sc, 0x80, 0x12);
3310 for (i = 0; i < 128; i++) {
3311 uint32_t addr, data;
3313 data = (urtw_8225z2_agc[i] << 8) | 0x0000008f;
3314 addr = ((i + 0x80) << 8) | 0x0000008e;
3316 urtw_8187_write_phy_ofdm(sc, data & 0x7f, (data >> 8) & 0xff);
3317 urtw_8187_write_phy_ofdm(sc, addr & 0x7f, (addr >> 8) & 0xff);
3318 urtw_8187_write_phy_ofdm(sc, 0x0e, 0x00);
3320 urtw_8187_write_phy_ofdm(sc, 0x80, 0x10);
3322 for (i = 0; i < nitems(urtw_8225v2b_rf_part2); i++)
3323 urtw_8187_write_phy_ofdm(sc, i, urtw_8225v2b_rf_part2[i].val);
3325 urtw_write32_m(sc, URTW_8187B_AC_VO, (7 << 12) | (3 << 8) | 0x1c);
3326 urtw_write32_m(sc, URTW_8187B_AC_VI, (7 << 12) | (3 << 8) | 0x1c);
3327 urtw_write32_m(sc, URTW_8187B_AC_BE, (7 << 12) | (3 << 8) | 0x1c);
3328 urtw_write32_m(sc, URTW_8187B_AC_BK, (7 << 12) | (3 << 8) | 0x1c);
3330 urtw_8187_write_phy_ofdm(sc, 0x97, 0x46);
3331 urtw_8187_write_phy_ofdm(sc, 0xa4, 0xb6);
3332 urtw_8187_write_phy_ofdm(sc, 0x85, 0xfc);
3333 urtw_8187_write_phy_cck(sc, 0xc1, 0x88);
3340 urtw_8225v2b_rf_set_chan(struct urtw_softc *sc, int chan)
3344 error = urtw_8225v2b_set_txpwrlvl(sc, chan);
3348 urtw_8225_write(sc, URTW_8225_ADDR_7_MAGIC, urtw_8225_channel[chan]);
3349 usb_pause_mtx(&sc->sc_mtx, 10);
3355 urtw_8225v2b_set_txpwrlvl(struct urtw_softc *sc, int chan)
3358 uint8_t *cck_pwrtable;
3359 uint8_t cck_pwrlvl_max = 15;
3360 uint8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
3361 uint8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
3364 /* CCK power setting */
3365 cck_pwrlvl = (cck_pwrlvl > cck_pwrlvl_max) ?
3366 ((sc->sc_flags & URTW_RTL8187B_REV_B) ? cck_pwrlvl_max : 22) :
3367 (cck_pwrlvl + ((sc->sc_flags & URTW_RTL8187B_REV_B) ? 0 : 7));
3368 cck_pwrlvl += sc->sc_txpwr_cck_base;
3369 cck_pwrlvl = (cck_pwrlvl > 35) ? 35 : cck_pwrlvl;
3370 cck_pwrtable = (chan == 14) ? urtw_8225v2b_txpwr_cck_ch14 :
3371 urtw_8225v2b_txpwr_cck;
3373 if (sc->sc_flags & URTW_RTL8187B_REV_B)
3374 cck_pwrtable += (cck_pwrlvl <= 6) ? 0 :
3375 ((cck_pwrlvl <= 11) ? 8 : 16);
3377 cck_pwrtable += (cck_pwrlvl <= 5) ? 0 :
3378 ((cck_pwrlvl <= 11) ? 8 : ((cck_pwrlvl <= 17) ? 16 : 24));
3380 for (i = 0; i < 8; i++)
3381 urtw_8187_write_phy_cck(sc, 0x44 + i, cck_pwrtable[i]);
3383 urtw_write8_m(sc, URTW_TX_GAIN_CCK,
3384 urtw_8225v2_tx_gain_cck_ofdm[cck_pwrlvl] << 1);
3385 usb_pause_mtx(&sc->sc_mtx, 1);
3387 /* OFDM power setting */
3388 ofdm_pwrlvl = (ofdm_pwrlvl > 15) ?
3389 ((sc->sc_flags & URTW_RTL8187B_REV_B) ? 17 : 25) :
3390 (ofdm_pwrlvl + ((sc->sc_flags & URTW_RTL8187B_REV_B) ? 2 : 10));
3391 ofdm_pwrlvl += sc->sc_txpwr_ofdm_base;
3392 ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
3394 urtw_write8_m(sc, URTW_TX_GAIN_OFDM,
3395 urtw_8225v2_tx_gain_cck_ofdm[ofdm_pwrlvl] << 1);
3397 if (sc->sc_flags & URTW_RTL8187B_REV_B) {
3398 if (ofdm_pwrlvl <= 11) {
3399 urtw_8187_write_phy_ofdm(sc, 0x87, 0x60);
3400 urtw_8187_write_phy_ofdm(sc, 0x89, 0x60);
3402 urtw_8187_write_phy_ofdm(sc, 0x87, 0x5c);
3403 urtw_8187_write_phy_ofdm(sc, 0x89, 0x5c);
3406 if (ofdm_pwrlvl <= 11) {
3407 urtw_8187_write_phy_ofdm(sc, 0x87, 0x5c);
3408 urtw_8187_write_phy_ofdm(sc, 0x89, 0x5c);
3409 } else if (ofdm_pwrlvl <= 17) {
3410 urtw_8187_write_phy_ofdm(sc, 0x87, 0x54);
3411 urtw_8187_write_phy_ofdm(sc, 0x89, 0x54);
3413 urtw_8187_write_phy_ofdm(sc, 0x87, 0x50);
3414 urtw_8187_write_phy_ofdm(sc, 0x89, 0x50);
3417 usb_pause_mtx(&sc->sc_mtx, 1);
3423 urtw_read8e(struct urtw_softc *sc, int val, uint8_t *data)
3425 struct usb_device_request req;
3428 req.bmRequestType = UT_READ_VENDOR_DEVICE;
3429 req.bRequest = URTW_8187_GETREGS_REQ;
3430 USETW(req.wValue, val | 0xfe00);
3431 USETW(req.wIndex, 0);
3432 USETW(req.wLength, sizeof(uint8_t));
3434 error = urtw_do_request(sc, &req, data);
3439 urtw_write8e(struct urtw_softc *sc, int val, uint8_t data)
3441 struct usb_device_request req;
3443 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
3444 req.bRequest = URTW_8187_SETREGS_REQ;
3445 USETW(req.wValue, val | 0xfe00);
3446 USETW(req.wIndex, 0);
3447 USETW(req.wLength, sizeof(uint8_t));
3449 return (urtw_do_request(sc, &req, &data));
3453 urtw_8180_set_anaparam(struct urtw_softc *sc, uint32_t val)
3458 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3462 urtw_read8_m(sc, URTW_CONFIG3, &data);
3463 urtw_write8_m(sc, URTW_CONFIG3, data | URTW_CONFIG3_ANAPARAM_WRITE);
3464 urtw_write32_m(sc, URTW_ANAPARAM, val);
3465 urtw_read8_m(sc, URTW_CONFIG3, &data);
3466 urtw_write8_m(sc, URTW_CONFIG3, data & ~URTW_CONFIG3_ANAPARAM_WRITE);
3468 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3476 urtw_8185_set_anaparam2(struct urtw_softc *sc, uint32_t val)
3481 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3485 urtw_read8_m(sc, URTW_CONFIG3, &data);
3486 urtw_write8_m(sc, URTW_CONFIG3, data | URTW_CONFIG3_ANAPARAM_WRITE);
3487 urtw_write32_m(sc, URTW_ANAPARAM2, val);
3488 urtw_read8_m(sc, URTW_CONFIG3, &data);
3489 urtw_write8_m(sc, URTW_CONFIG3, data & ~URTW_CONFIG3_ANAPARAM_WRITE);
3491 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3499 urtw_intr_enable(struct urtw_softc *sc)
3503 urtw_write16_m(sc, URTW_INTR_MASK, 0xffff);
3509 urtw_intr_disable(struct urtw_softc *sc)
3513 urtw_write16_m(sc, URTW_INTR_MASK, 0);
3519 urtw_reset(struct urtw_softc *sc)
3524 error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
3527 error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
3531 error = urtw_intr_disable(sc);
3534 usb_pause_mtx(&sc->sc_mtx, 100);
3536 error = urtw_write8e(sc, 0x18, 0x10);
3539 error = urtw_write8e(sc, 0x18, 0x11);
3542 error = urtw_write8e(sc, 0x18, 0x00);
3545 usb_pause_mtx(&sc->sc_mtx, 100);
3547 urtw_read8_m(sc, URTW_CMD, &data);
3548 data = (data & 0x2) | URTW_CMD_RST;
3549 urtw_write8_m(sc, URTW_CMD, data);
3550 usb_pause_mtx(&sc->sc_mtx, 100);
3552 urtw_read8_m(sc, URTW_CMD, &data);
3553 if (data & URTW_CMD_RST) {
3554 device_printf(sc->sc_dev, "reset timeout\n");
3558 error = urtw_set_mode(sc, URTW_EPROM_CMD_LOAD);
3561 usb_pause_mtx(&sc->sc_mtx, 100);
3563 error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
3566 error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
3574 urtw_led_ctl(struct urtw_softc *sc, int mode)
3576 usb_error_t error = 0;
3578 switch (sc->sc_strategy) {
3579 case URTW_SW_LED_MODE0:
3580 error = urtw_led_mode0(sc, mode);
3582 case URTW_SW_LED_MODE1:
3583 error = urtw_led_mode1(sc, mode);
3585 case URTW_SW_LED_MODE2:
3586 error = urtw_led_mode2(sc, mode);
3588 case URTW_SW_LED_MODE3:
3589 error = urtw_led_mode3(sc, mode);
3592 DPRINTF(sc, URTW_DEBUG_STATE,
3593 "unsupported LED mode %d\n", sc->sc_strategy);
3594 error = USB_ERR_INVAL;
3602 urtw_led_mode0(struct urtw_softc *sc, int mode)
3606 case URTW_LED_CTL_POWER_ON:
3607 sc->sc_gpio_ledstate = URTW_LED_POWER_ON_BLINK;
3609 case URTW_LED_CTL_TX:
3610 if (sc->sc_gpio_ledinprogress == 1)
3613 sc->sc_gpio_ledstate = URTW_LED_BLINK_NORMAL;
3614 sc->sc_gpio_blinktime = 2;
3616 case URTW_LED_CTL_LINK:
3617 sc->sc_gpio_ledstate = URTW_LED_ON;
3620 DPRINTF(sc, URTW_DEBUG_STATE,
3621 "unsupported LED mode 0x%x", mode);
3622 return (USB_ERR_INVAL);
3625 switch (sc->sc_gpio_ledstate) {
3627 if (sc->sc_gpio_ledinprogress != 0)
3629 urtw_led_on(sc, URTW_LED_GPIO);
3631 case URTW_LED_BLINK_NORMAL:
3632 if (sc->sc_gpio_ledinprogress != 0)
3634 sc->sc_gpio_ledinprogress = 1;
3635 sc->sc_gpio_blinkstate = (sc->sc_gpio_ledon != 0) ?
3636 URTW_LED_OFF : URTW_LED_ON;
3637 usb_callout_reset(&sc->sc_led_ch, hz, urtw_led_ch, sc);
3639 case URTW_LED_POWER_ON_BLINK:
3640 urtw_led_on(sc, URTW_LED_GPIO);
3641 usb_pause_mtx(&sc->sc_mtx, 100);
3642 urtw_led_off(sc, URTW_LED_GPIO);
3645 DPRINTF(sc, URTW_DEBUG_STATE,
3646 "unknown LED status 0x%x", sc->sc_gpio_ledstate);
3647 return (USB_ERR_INVAL);
3653 urtw_led_mode1(struct urtw_softc *sc, int mode)
3655 return (USB_ERR_INVAL);
3659 urtw_led_mode2(struct urtw_softc *sc, int mode)
3661 return (USB_ERR_INVAL);
3665 urtw_led_mode3(struct urtw_softc *sc, int mode)
3667 return (USB_ERR_INVAL);
3671 urtw_led_on(struct urtw_softc *sc, int type)
3675 if (type == URTW_LED_GPIO) {
3676 switch (sc->sc_gpio_ledpin) {
3677 case URTW_LED_PIN_GPIO0:
3678 urtw_write8_m(sc, URTW_GPIO, 0x01);
3679 urtw_write8_m(sc, URTW_GP_ENABLE, 0x00);
3682 DPRINTF(sc, URTW_DEBUG_STATE,
3683 "unsupported LED PIN type 0x%x",
3684 sc->sc_gpio_ledpin);
3685 error = USB_ERR_INVAL;
3689 DPRINTF(sc, URTW_DEBUG_STATE,
3690 "unsupported LED type 0x%x", type);
3691 error = USB_ERR_INVAL;
3695 sc->sc_gpio_ledon = 1;
3701 urtw_led_off(struct urtw_softc *sc, int type)
3705 if (type == URTW_LED_GPIO) {
3706 switch (sc->sc_gpio_ledpin) {
3707 case URTW_LED_PIN_GPIO0:
3708 urtw_write8_m(sc, URTW_GPIO, URTW_GPIO_DATA_MAGIC1);
3710 URTW_GP_ENABLE, URTW_GP_ENABLE_DATA_MAGIC1);
3713 DPRINTF(sc, URTW_DEBUG_STATE,
3714 "unsupported LED PIN type 0x%x",
3715 sc->sc_gpio_ledpin);
3716 error = USB_ERR_INVAL;
3720 DPRINTF(sc, URTW_DEBUG_STATE,
3721 "unsupported LED type 0x%x", type);
3722 error = USB_ERR_INVAL;
3726 sc->sc_gpio_ledon = 0;
3733 urtw_led_ch(void *arg)
3735 struct urtw_softc *sc = arg;
3736 struct ieee80211com *ic = &sc->sc_ic;
3738 ieee80211_runtask(ic, &sc->sc_led_task);
3742 urtw_ledtask(void *arg, int pending)
3744 struct urtw_softc *sc = arg;
3746 if (sc->sc_strategy != URTW_SW_LED_MODE0) {
3747 DPRINTF(sc, URTW_DEBUG_STATE,
3748 "could not process a LED strategy 0x%x",
3759 urtw_led_blink(struct urtw_softc *sc)
3764 if (sc->sc_gpio_blinkstate == URTW_LED_ON)
3765 error = urtw_led_on(sc, URTW_LED_GPIO);
3767 error = urtw_led_off(sc, URTW_LED_GPIO);
3768 sc->sc_gpio_blinktime--;
3769 if (sc->sc_gpio_blinktime == 0)
3772 if (sc->sc_gpio_ledstate != URTW_LED_BLINK_NORMAL &&
3773 sc->sc_gpio_ledstate != URTW_LED_BLINK_SLOWLY &&
3774 sc->sc_gpio_ledstate != URTW_LED_BLINK_CM3)
3778 if (sc->sc_gpio_ledstate == URTW_LED_ON &&
3779 sc->sc_gpio_ledon == 0)
3780 error = urtw_led_on(sc, URTW_LED_GPIO);
3781 else if (sc->sc_gpio_ledstate == URTW_LED_OFF &&
3782 sc->sc_gpio_ledon == 1)
3783 error = urtw_led_off(sc, URTW_LED_GPIO);
3785 sc->sc_gpio_blinktime = 0;
3786 sc->sc_gpio_ledinprogress = 0;
3790 sc->sc_gpio_blinkstate = (sc->sc_gpio_blinkstate != URTW_LED_ON) ?
3791 URTW_LED_ON : URTW_LED_OFF;
3793 switch (sc->sc_gpio_ledstate) {
3794 case URTW_LED_BLINK_NORMAL:
3795 usb_callout_reset(&sc->sc_led_ch, hz, urtw_led_ch, sc);
3798 DPRINTF(sc, URTW_DEBUG_STATE,
3799 "unknown LED status 0x%x",
3800 sc->sc_gpio_ledstate);
3801 return (USB_ERR_INVAL);
3807 urtw_rx_enable(struct urtw_softc *sc)
3812 usbd_transfer_start((sc->sc_flags & URTW_RTL8187B) ?
3813 sc->sc_xfer[URTW_8187B_BULK_RX] : sc->sc_xfer[URTW_8187L_BULK_RX]);
3815 error = urtw_rx_setconf(sc);
3819 if ((sc->sc_flags & URTW_RTL8187B) == 0) {
3820 urtw_read8_m(sc, URTW_CMD, &data);
3821 urtw_write8_m(sc, URTW_CMD, data | URTW_CMD_RX_ENABLE);
3828 urtw_tx_enable(struct urtw_softc *sc)
3834 if (sc->sc_flags & URTW_RTL8187B) {
3835 urtw_read32_m(sc, URTW_TX_CONF, &data);
3836 data &= ~URTW_TX_LOOPBACK_MASK;
3837 data &= ~(URTW_TX_DPRETRY_MASK | URTW_TX_RTSRETRY_MASK);
3838 data &= ~(URTW_TX_NOCRC | URTW_TX_MXDMA_MASK);
3839 data &= ~URTW_TX_SWPLCPLEN;
3840 data |= URTW_TX_HW_SEQNUM | URTW_TX_DISREQQSIZE |
3841 (7 << 8) | /* short retry limit */
3842 (7 << 0) | /* long retry limit */
3843 (7 << 21); /* MAX TX DMA */
3844 urtw_write32_m(sc, URTW_TX_CONF, data);
3846 urtw_read8_m(sc, URTW_MSR, &data8);
3847 data8 |= URTW_MSR_LINK_ENEDCA;
3848 urtw_write8_m(sc, URTW_MSR, data8);
3852 urtw_read8_m(sc, URTW_CW_CONF, &data8);
3853 data8 &= ~(URTW_CW_CONF_PERPACKET_CW | URTW_CW_CONF_PERPACKET_RETRY);
3854 urtw_write8_m(sc, URTW_CW_CONF, data8);
3856 urtw_read8_m(sc, URTW_TX_AGC_CTL, &data8);
3857 data8 &= ~URTW_TX_AGC_CTL_PERPACKET_GAIN;
3858 data8 &= ~URTW_TX_AGC_CTL_PERPACKET_ANTSEL;
3859 data8 &= ~URTW_TX_AGC_CTL_FEEDBACK_ANT;
3860 urtw_write8_m(sc, URTW_TX_AGC_CTL, data8);
3862 urtw_read32_m(sc, URTW_TX_CONF, &data);
3863 data &= ~URTW_TX_LOOPBACK_MASK;
3864 data |= URTW_TX_LOOPBACK_NONE;
3865 data &= ~(URTW_TX_DPRETRY_MASK | URTW_TX_RTSRETRY_MASK);
3866 data |= sc->sc_tx_retry << URTW_TX_DPRETRY_SHIFT;
3867 data |= sc->sc_rts_retry << URTW_TX_RTSRETRY_SHIFT;
3868 data &= ~(URTW_TX_NOCRC | URTW_TX_MXDMA_MASK);
3869 data |= URTW_TX_MXDMA_2048 | URTW_TX_CWMIN | URTW_TX_DISCW;
3870 data &= ~URTW_TX_SWPLCPLEN;
3871 data |= URTW_TX_NOICV;
3872 urtw_write32_m(sc, URTW_TX_CONF, data);
3874 urtw_read8_m(sc, URTW_CMD, &data8);
3875 urtw_write8_m(sc, URTW_CMD, data8 | URTW_CMD_TX_ENABLE);
3881 urtw_rx_setconf(struct urtw_softc *sc)
3883 struct ieee80211com *ic = &sc->sc_ic;
3887 urtw_read32_m(sc, URTW_RX, &data);
3888 data = data &~ URTW_RX_FILTER_MASK;
3889 if (sc->sc_flags & URTW_RTL8187B) {
3890 data = data | URTW_RX_FILTER_MNG | URTW_RX_FILTER_DATA |
3891 URTW_RX_FILTER_MCAST | URTW_RX_FILTER_BCAST |
3892 URTW_RX_FILTER_NICMAC | URTW_RX_CHECK_BSSID |
3893 URTW_RX_FIFO_THRESHOLD_NONE |
3894 URTW_MAX_RX_DMA_2048 |
3895 URTW_RX_AUTORESETPHY | URTW_RCR_ONLYERLPKT;
3897 data = data | URTW_RX_FILTER_MNG | URTW_RX_FILTER_DATA;
3898 data = data | URTW_RX_FILTER_BCAST | URTW_RX_FILTER_MCAST;
3900 if (ic->ic_opmode == IEEE80211_M_MONITOR) {
3901 data = data | URTW_RX_FILTER_ICVERR;
3902 data = data | URTW_RX_FILTER_PWR;
3904 if (sc->sc_crcmon == 1 && ic->ic_opmode == IEEE80211_M_MONITOR)
3905 data = data | URTW_RX_FILTER_CRCERR;
3907 if (ic->ic_opmode == IEEE80211_M_MONITOR ||
3908 ic->ic_promisc > 0 || ic->ic_allmulti > 0) {
3909 data = data | URTW_RX_FILTER_ALLMAC;
3911 data = data | URTW_RX_FILTER_NICMAC;
3912 data = data | URTW_RX_CHECK_BSSID;
3915 data = data &~ URTW_RX_FIFO_THRESHOLD_MASK;
3916 data = data | URTW_RX_FIFO_THRESHOLD_NONE |
3917 URTW_RX_AUTORESETPHY;
3918 data = data &~ URTW_MAX_RX_DMA_MASK;
3919 data = data | URTW_MAX_RX_DMA_2048 | URTW_RCR_ONLYERLPKT;
3922 urtw_write32_m(sc, URTW_RX, data);
3927 static struct mbuf *
3928 urtw_rxeof(struct usb_xfer *xfer, struct urtw_data *data, int *rssi_p,
3931 int actlen, flen, rssi;
3932 struct ieee80211_frame *wh;
3933 struct mbuf *m, *mnew;
3934 struct urtw_softc *sc = data->sc;
3935 struct ieee80211com *ic = &sc->sc_ic;
3936 uint8_t noise = 0, rate;
3938 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
3940 if (actlen < (int)URTW_MIN_RXBUFSZ) {
3941 counter_u64_add(ic->ic_ierrors, 1);
3945 if (sc->sc_flags & URTW_RTL8187B) {
3946 struct urtw_8187b_rxhdr *rx;
3948 rx = (struct urtw_8187b_rxhdr *)(data->buf +
3949 (actlen - (sizeof(struct urtw_8187b_rxhdr))));
3950 flen = le32toh(rx->flag) & 0xfff;
3951 if (flen > actlen) {
3952 counter_u64_add(ic->ic_ierrors, 1);
3955 rate = (le32toh(rx->flag) >> URTW_RX_FLAG_RXRATE_SHIFT) & 0xf;
3957 rssi = rx->rssi & URTW_RX_RSSI_MASK;
3960 struct urtw_8187l_rxhdr *rx;
3962 rx = (struct urtw_8187l_rxhdr *)(data->buf +
3963 (actlen - (sizeof(struct urtw_8187l_rxhdr))));
3964 flen = le32toh(rx->flag) & 0xfff;
3965 if (flen > actlen) {
3966 counter_u64_add(ic->ic_ierrors, 1);
3970 rate = (le32toh(rx->flag) >> URTW_RX_FLAG_RXRATE_SHIFT) & 0xf;
3972 rssi = rx->rssi & URTW_RX_8187L_RSSI_MASK;
3976 mnew = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
3978 counter_u64_add(ic->ic_ierrors, 1);
3984 data->buf = mtod(mnew, uint8_t *);
3987 m->m_pkthdr.len = m->m_len = flen - IEEE80211_CRC_LEN;
3989 if (ieee80211_radiotap_active(ic)) {
3990 struct urtw_rx_radiotap_header *tap = &sc->sc_rxtap;
3992 /* XXX Are variables correct? */
3993 tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
3994 tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
3995 tap->wr_dbm_antsignal = (int8_t)rssi;
3998 wh = mtod(m, struct ieee80211_frame *);
3999 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_DATA)
4000 sc->sc_currate = (rate > 0) ? rate : sc->sc_currate;
4003 *nf_p = noise; /* XXX correct? */
4009 urtw_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
4011 struct urtw_softc *sc = usbd_xfer_softc(xfer);
4012 struct ieee80211com *ic = &sc->sc_ic;
4013 struct ieee80211_frame *wh;
4014 struct ieee80211_node *ni;
4015 struct mbuf *m = NULL;
4016 struct urtw_data *data;
4020 URTW_ASSERT_LOCKED(sc);
4022 switch (USB_GET_STATE(xfer)) {
4023 case USB_ST_TRANSFERRED:
4024 data = STAILQ_FIRST(&sc->sc_rx_active);
4027 STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next);
4028 m = urtw_rxeof(xfer, data, &rssi, &nf);
4029 STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next);
4033 data = STAILQ_FIRST(&sc->sc_rx_inactive);
4035 KASSERT(m == NULL, ("mbuf isn't NULL"));
4038 STAILQ_REMOVE_HEAD(&sc->sc_rx_inactive, next);
4039 STAILQ_INSERT_TAIL(&sc->sc_rx_active, data, next);
4040 usbd_xfer_set_frame_data(xfer, 0, data->buf,
4041 usbd_xfer_max_len(xfer));
4042 usbd_transfer_submit(xfer);
4045 * To avoid LOR we should unlock our private mutex here to call
4046 * ieee80211_input() because here is at the end of a USB
4047 * callback and safe to unlock.
4051 wh = mtod(m, struct ieee80211_frame *);
4052 ni = ieee80211_find_rxnode(ic,
4053 (struct ieee80211_frame_min *)wh);
4055 (void) ieee80211_input(ni, m, rssi, nf);
4056 /* node is no longer needed */
4057 ieee80211_free_node(ni);
4059 (void) ieee80211_input_all(ic, m, rssi, nf);
4065 /* needs it to the inactive queue due to a error. */
4066 data = STAILQ_FIRST(&sc->sc_rx_active);
4068 STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next);
4069 STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next);
4071 if (error != USB_ERR_CANCELLED) {
4072 usbd_xfer_set_stall(xfer);
4073 counter_u64_add(ic->ic_ierrors, 1);
4080 #define URTW_STATUS_TYPE_TXCLOSE 1
4081 #define URTW_STATUS_TYPE_BEACON_INTR 0
4084 urtw_txstatus_eof(struct usb_xfer *xfer)
4086 struct urtw_softc *sc = usbd_xfer_softc(xfer);
4087 struct ieee80211com *ic = &sc->sc_ic;
4088 int actlen, type, pktretry, seq;
4091 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
4093 if (actlen != sizeof(uint64_t))
4096 val = le64toh(sc->sc_txstatus);
4097 type = (val >> 30) & 0x3;
4098 if (type == URTW_STATUS_TYPE_TXCLOSE) {
4099 pktretry = val & 0xff;
4100 seq = (val >> 16) & 0xff;
4101 if (pktretry == URTW_TX_MAXRETRY)
4102 counter_u64_add(ic->ic_oerrors, 1);
4103 DPRINTF(sc, URTW_DEBUG_TXSTATUS, "pktretry %d seq %#x\n",
4109 urtw_bulk_tx_status_callback(struct usb_xfer *xfer, usb_error_t error)
4111 struct urtw_softc *sc = usbd_xfer_softc(xfer);
4112 struct ieee80211com *ic = &sc->sc_ic;
4113 void *dma_buf = usbd_xfer_get_frame_buffer(xfer, 0);
4115 URTW_ASSERT_LOCKED(sc);
4117 switch (USB_GET_STATE(xfer)) {
4118 case USB_ST_TRANSFERRED:
4119 urtw_txstatus_eof(xfer);
4123 memcpy(dma_buf, &sc->sc_txstatus, sizeof(uint64_t));
4124 usbd_xfer_set_frame_len(xfer, 0, sizeof(uint64_t));
4125 usbd_transfer_submit(xfer);
4128 if (error != USB_ERR_CANCELLED) {
4129 usbd_xfer_set_stall(xfer);
4130 counter_u64_add(ic->ic_ierrors, 1);
4138 urtw_txeof(struct usb_xfer *xfer, struct urtw_data *data)
4140 struct urtw_softc *sc = usbd_xfer_softc(xfer);
4142 URTW_ASSERT_LOCKED(sc);
4146 ieee80211_tx_complete(data->ni, data->m, 0);
4154 urtw_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error)
4156 struct urtw_softc *sc = usbd_xfer_softc(xfer);
4157 struct urtw_data *data;
4159 URTW_ASSERT_LOCKED(sc);
4161 switch (USB_GET_STATE(xfer)) {
4162 case USB_ST_TRANSFERRED:
4163 data = STAILQ_FIRST(&sc->sc_tx_active);
4166 STAILQ_REMOVE_HEAD(&sc->sc_tx_active, next);
4167 urtw_txeof(xfer, data);
4168 STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data, next);
4172 data = STAILQ_FIRST(&sc->sc_tx_pending);
4174 DPRINTF(sc, URTW_DEBUG_XMIT,
4175 "%s: empty pending queue\n", __func__);
4178 STAILQ_REMOVE_HEAD(&sc->sc_tx_pending, next);
4179 STAILQ_INSERT_TAIL(&sc->sc_tx_active, data, next);
4181 usbd_xfer_set_frame_data(xfer, 0, data->buf, data->buflen);
4182 usbd_transfer_submit(xfer);
4187 data = STAILQ_FIRST(&sc->sc_tx_active);
4190 if (data->ni != NULL) {
4191 if_inc_counter(data->ni->ni_vap->iv_ifp,
4192 IFCOUNTER_OERRORS, 1);
4193 ieee80211_free_node(data->ni);
4196 if (error != USB_ERR_CANCELLED) {
4197 usbd_xfer_set_stall(xfer);
4204 static struct urtw_data *
4205 _urtw_getbuf(struct urtw_softc *sc)
4207 struct urtw_data *bf;
4209 bf = STAILQ_FIRST(&sc->sc_tx_inactive);
4211 STAILQ_REMOVE_HEAD(&sc->sc_tx_inactive, next);
4215 DPRINTF(sc, URTW_DEBUG_XMIT, "%s: %s\n", __func__,
4216 "out of xmit buffers");
4220 static struct urtw_data *
4221 urtw_getbuf(struct urtw_softc *sc)
4223 struct urtw_data *bf;
4225 URTW_ASSERT_LOCKED(sc);
4227 bf = _urtw_getbuf(sc);
4229 DPRINTF(sc, URTW_DEBUG_XMIT, "%s: stop queue\n", __func__);
4234 urtw_isbmode(uint16_t rate)
4237 return ((rate <= 22 && rate != 12 && rate != 18) ||
4238 rate == 44) ? (1) : (0);
4242 urtw_rate2dbps(uint16_t rate)
4262 urtw_compute_txtime(uint16_t framelen, uint16_t rate,
4263 uint8_t ismgt, uint8_t isshort)
4265 uint16_t ceiling, frametime, n_dbps;
4267 if (urtw_isbmode(rate)) {
4268 if (ismgt || !isshort || rate == 2)
4269 frametime = (uint16_t)(144 + 48 +
4270 (framelen * 8 / (rate / 2)));
4272 frametime = (uint16_t)(72 + 24 +
4273 (framelen * 8 / (rate / 2)));
4274 if ((framelen * 8 % (rate / 2)) != 0)
4277 n_dbps = urtw_rate2dbps(rate);
4278 ceiling = (16 + 8 * framelen + 6) / n_dbps
4279 + (((16 + 8 * framelen + 6) % n_dbps) ? 1 : 0);
4280 frametime = (uint16_t)(16 + 4 + 4 * ceiling + 6);
4286 * Callback from the 802.11 layer to update the
4287 * slot time based on the current setting.
4290 urtw_updateslot(struct ieee80211com *ic)
4292 struct urtw_softc *sc = ic->ic_softc;
4294 ieee80211_runtask(ic, &sc->sc_updateslot_task);
4298 urtw_updateslottask(void *arg, int pending)
4300 struct urtw_softc *sc = arg;
4301 struct ieee80211com *ic = &sc->sc_ic;
4305 if ((sc->sc_flags & URTW_RUNNING) == 0) {
4309 if (sc->sc_flags & URTW_RTL8187B) {
4310 urtw_write8_m(sc, URTW_SIFS, 0x22);
4311 if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan))
4312 urtw_write8_m(sc, URTW_SLOT, IEEE80211_DUR_SHSLOT);
4314 urtw_write8_m(sc, URTW_SLOT, IEEE80211_DUR_SLOT);
4315 urtw_write8_m(sc, URTW_8187B_EIFS, 0x5b);
4316 urtw_write8_m(sc, URTW_CARRIER_SCOUNT, 0x5b);
4318 urtw_write8_m(sc, URTW_SIFS, 0x22);
4319 if (sc->sc_state == IEEE80211_S_ASSOC &&
4320 ic->ic_flags & IEEE80211_F_SHSLOT)
4321 urtw_write8_m(sc, URTW_SLOT, IEEE80211_DUR_SHSLOT);
4323 urtw_write8_m(sc, URTW_SLOT, IEEE80211_DUR_SLOT);
4324 if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan)) {
4325 urtw_write8_m(sc, URTW_DIFS, 0x14);
4326 urtw_write8_m(sc, URTW_EIFS, 0x5b - 0x14);
4327 urtw_write8_m(sc, URTW_CW_VAL, 0x73);
4329 urtw_write8_m(sc, URTW_DIFS, 0x24);
4330 urtw_write8_m(sc, URTW_EIFS, 0x5b - 0x24);
4331 urtw_write8_m(sc, URTW_CW_VAL, 0xa5);
4339 urtw_sysctl_node(struct urtw_softc *sc)
4341 #define URTW_SYSCTL_STAT_ADD32(c, h, n, p, d) \
4342 SYSCTL_ADD_UINT(c, h, OID_AUTO, n, CTLFLAG_RD, p, 0, d)
4343 struct sysctl_ctx_list *ctx;
4344 struct sysctl_oid_list *child, *parent;
4345 struct sysctl_oid *tree;
4346 struct urtw_stats *stats = &sc->sc_stats;
4348 ctx = device_get_sysctl_ctx(sc->sc_dev);
4349 child = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->sc_dev));
4351 tree = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "stats", CTLFLAG_RD,
4352 NULL, "URTW statistics");
4353 parent = SYSCTL_CHILDREN(tree);
4355 /* Tx statistics. */
4356 tree = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "tx", CTLFLAG_RD,
4357 NULL, "Tx MAC statistics");
4358 child = SYSCTL_CHILDREN(tree);
4359 URTW_SYSCTL_STAT_ADD32(ctx, child, "1m", &stats->txrates[0],
4361 URTW_SYSCTL_STAT_ADD32(ctx, child, "2m", &stats->txrates[1],
4363 URTW_SYSCTL_STAT_ADD32(ctx, child, "5.5m", &stats->txrates[2],
4365 URTW_SYSCTL_STAT_ADD32(ctx, child, "6m", &stats->txrates[4],
4367 URTW_SYSCTL_STAT_ADD32(ctx, child, "9m", &stats->txrates[5],
4369 URTW_SYSCTL_STAT_ADD32(ctx, child, "11m", &stats->txrates[3],
4371 URTW_SYSCTL_STAT_ADD32(ctx, child, "12m", &stats->txrates[6],
4373 URTW_SYSCTL_STAT_ADD32(ctx, child, "18m", &stats->txrates[7],
4375 URTW_SYSCTL_STAT_ADD32(ctx, child, "24m", &stats->txrates[8],
4377 URTW_SYSCTL_STAT_ADD32(ctx, child, "36m", &stats->txrates[9],
4379 URTW_SYSCTL_STAT_ADD32(ctx, child, "48m", &stats->txrates[10],
4381 URTW_SYSCTL_STAT_ADD32(ctx, child, "54m", &stats->txrates[11],
4383 #undef URTW_SYSCTL_STAT_ADD32
4386 static device_method_t urtw_methods[] = {
4387 DEVMETHOD(device_probe, urtw_match),
4388 DEVMETHOD(device_attach, urtw_attach),
4389 DEVMETHOD(device_detach, urtw_detach),
4392 static driver_t urtw_driver = {
4394 .methods = urtw_methods,
4395 .size = sizeof(struct urtw_softc)
4397 static devclass_t urtw_devclass;
4399 DRIVER_MODULE(urtw, uhub, urtw_driver, urtw_devclass, NULL, 0);
4400 MODULE_DEPEND(urtw, wlan, 1, 1, 1);
4401 MODULE_DEPEND(urtw, usb, 1, 1, 1);
4402 MODULE_VERSION(urtw, 1);
4403 USB_PNP_HOST_INFO(urtw_devs);