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_arp.h>
40 #include <net/ethernet.h>
41 #include <net/if_dl.h>
42 #include <net/if_media.h>
43 #include <net/if_types.h>
46 #include <netinet/in.h>
47 #include <netinet/in_systm.h>
48 #include <netinet/in_var.h>
49 #include <netinet/if_ether.h>
50 #include <netinet/ip.h>
53 #include <net80211/ieee80211_var.h>
54 #include <net80211/ieee80211_regdomain.h>
55 #include <net80211/ieee80211_radiotap.h>
57 #include <dev/usb/usb.h>
58 #include <dev/usb/usbdi.h>
61 #include <dev/usb/wlan/if_urtwreg.h>
62 #include <dev/usb/wlan/if_urtwvar.h>
64 static SYSCTL_NODE(_hw_usb, OID_AUTO, urtw, CTLFLAG_RW, 0, "USB Realtek 8187L");
67 SYSCTL_INT(_hw_usb_urtw, OID_AUTO, debug, CTLFLAG_RW, &urtw_debug, 0,
68 "control debugging printfs");
69 TUNABLE_INT("hw.usb.urtw.debug", &urtw_debug);
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_RW,
93 &urtw_preamble_mode, 0, "set the preable mode (long or short)");
94 TUNABLE_INT("hw.usb.urtw.preamble_mode", &urtw_preamble_mode);
96 /* recognized device vendors/products */
97 #define urtw_lookup(v, p) \
98 ((const struct urtw_type *)usb_lookup(urtw_devs, v, p))
99 #define URTW_DEV_B(v,p) \
100 { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, URTW_REV_RTL8187B) }
101 #define URTW_DEV_L(v,p) \
102 { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, URTW_REV_RTL8187L) }
103 #define URTW_REV_RTL8187B 0
104 #define URTW_REV_RTL8187L 1
105 static const STRUCT_USB_HOST_ID urtw_devs[] = {
106 URTW_DEV_B(NETGEAR, WG111V3),
107 URTW_DEV_B(REALTEK, RTL8187B_0),
108 URTW_DEV_B(REALTEK, RTL8187B_1),
109 URTW_DEV_B(REALTEK, RTL8187B_2),
110 URTW_DEV_B(SITECOMEU, WL168V4),
111 URTW_DEV_L(ASUS, P5B_WIFI),
112 URTW_DEV_L(BELKIN, F5D7050E),
113 URTW_DEV_L(LINKSYS4, WUSB54GCV2),
114 URTW_DEV_L(NETGEAR, WG111V2),
115 URTW_DEV_L(REALTEK, RTL8187),
116 URTW_DEV_L(SITECOMEU, WL168V1),
117 URTW_DEV_L(SURECOM, EP9001G2A),
118 { USB_VPI(USB_VENDOR_OVISLINK, 0x8187, URTW_REV_RTL8187L) },
119 { USB_VPI(USB_VENDOR_DICKSMITH, 0x9401, URTW_REV_RTL8187L) },
120 { USB_VPI(USB_VENDOR_HP, 0xca02, URTW_REV_RTL8187L) },
121 { USB_VPI(USB_VENDOR_LOGITEC, 0x010c, URTW_REV_RTL8187L) },
122 { USB_VPI(USB_VENDOR_NETGEAR, 0x6100, URTW_REV_RTL8187L) },
123 { USB_VPI(USB_VENDOR_SPHAIRON, 0x0150, URTW_REV_RTL8187L) },
124 { USB_VPI(USB_VENDOR_QCOM, 0x6232, URTW_REV_RTL8187L) },
129 #define urtw_read8_m(sc, val, data) do { \
130 error = urtw_read8_c(sc, val, data); \
134 #define urtw_write8_m(sc, val, data) do { \
135 error = urtw_write8_c(sc, val, data); \
139 #define urtw_read16_m(sc, val, data) do { \
140 error = urtw_read16_c(sc, val, data); \
144 #define urtw_write16_m(sc, val, data) do { \
145 error = urtw_write16_c(sc, val, data); \
149 #define urtw_read32_m(sc, val, data) do { \
150 error = urtw_read32_c(sc, val, data); \
154 #define urtw_write32_m(sc, val, data) do { \
155 error = urtw_write32_c(sc, val, data); \
159 #define urtw_8187_write_phy_ofdm(sc, val, data) do { \
160 error = urtw_8187_write_phy_ofdm_c(sc, val, data); \
164 #define urtw_8187_write_phy_cck(sc, val, data) do { \
165 error = urtw_8187_write_phy_cck_c(sc, val, data); \
169 #define urtw_8225_write(sc, val, data) do { \
170 error = urtw_8225_write_c(sc, val, data); \
180 static uint8_t urtw_8225_agc[] = {
181 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9d, 0x9c, 0x9b,
182 0x9a, 0x99, 0x98, 0x97, 0x96, 0x95, 0x94, 0x93, 0x92, 0x91, 0x90,
183 0x8f, 0x8e, 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86, 0x85,
184 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a,
185 0x39, 0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f,
186 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24,
187 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19,
188 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e,
189 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03,
190 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
191 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
192 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
195 static uint8_t urtw_8225z2_agc[] = {
196 0x5e, 0x5e, 0x5e, 0x5e, 0x5d, 0x5b, 0x59, 0x57, 0x55, 0x53, 0x51,
197 0x4f, 0x4d, 0x4b, 0x49, 0x47, 0x45, 0x43, 0x41, 0x3f, 0x3d, 0x3b,
198 0x39, 0x37, 0x35, 0x33, 0x31, 0x2f, 0x2d, 0x2b, 0x29, 0x27, 0x25,
199 0x23, 0x21, 0x1f, 0x1d, 0x1b, 0x19, 0x17, 0x15, 0x13, 0x11, 0x0f,
200 0x0d, 0x0b, 0x09, 0x07, 0x05, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01,
201 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x19, 0x19,
202 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x20, 0x21, 0x22, 0x23,
203 0x24, 0x25, 0x26, 0x26, 0x27, 0x27, 0x28, 0x28, 0x29, 0x2a, 0x2a,
204 0x2a, 0x2b, 0x2b, 0x2b, 0x2c, 0x2c, 0x2c, 0x2d, 0x2d, 0x2d, 0x2d,
205 0x2e, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x2f, 0x30, 0x30, 0x31, 0x31,
206 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
207 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31
210 static uint32_t urtw_8225_channel[] = {
211 0x0000, /* dummy channel 0 */
228 static uint8_t urtw_8225_gain[] = {
229 0x23, 0x88, 0x7c, 0xa5, /* -82dbm */
230 0x23, 0x88, 0x7c, 0xb5, /* -82dbm */
231 0x23, 0x88, 0x7c, 0xc5, /* -82dbm */
232 0x33, 0x80, 0x79, 0xc5, /* -78dbm */
233 0x43, 0x78, 0x76, 0xc5, /* -74dbm */
234 0x53, 0x60, 0x73, 0xc5, /* -70dbm */
235 0x63, 0x58, 0x70, 0xc5, /* -66dbm */
238 static struct urtw_pair urtw_8225_rf_part1[] = {
239 { 0x00, 0x0067 }, { 0x01, 0x0fe0 }, { 0x02, 0x044d }, { 0x03, 0x0441 },
240 { 0x04, 0x0486 }, { 0x05, 0x0bc0 }, { 0x06, 0x0ae6 }, { 0x07, 0x082a },
241 { 0x08, 0x001f }, { 0x09, 0x0334 }, { 0x0a, 0x0fd4 }, { 0x0b, 0x0391 },
242 { 0x0c, 0x0050 }, { 0x0d, 0x06db }, { 0x0e, 0x0029 }, { 0x0f, 0x0914 },
245 static struct urtw_pair urtw_8225_rf_part2[] = {
246 { 0x00, 0x01 }, { 0x01, 0x02 }, { 0x02, 0x42 }, { 0x03, 0x00 },
247 { 0x04, 0x00 }, { 0x05, 0x00 }, { 0x06, 0x40 }, { 0x07, 0x00 },
248 { 0x08, 0x40 }, { 0x09, 0xfe }, { 0x0a, 0x09 }, { 0x0b, 0x80 },
249 { 0x0c, 0x01 }, { 0x0e, 0xd3 }, { 0x0f, 0x38 }, { 0x10, 0x84 },
250 { 0x11, 0x06 }, { 0x12, 0x20 }, { 0x13, 0x20 }, { 0x14, 0x00 },
251 { 0x15, 0x40 }, { 0x16, 0x00 }, { 0x17, 0x40 }, { 0x18, 0xef },
252 { 0x19, 0x19 }, { 0x1a, 0x20 }, { 0x1b, 0x76 }, { 0x1c, 0x04 },
253 { 0x1e, 0x95 }, { 0x1f, 0x75 }, { 0x20, 0x1f }, { 0x21, 0x27 },
254 { 0x22, 0x16 }, { 0x24, 0x46 }, { 0x25, 0x20 }, { 0x26, 0x90 },
258 static struct urtw_pair urtw_8225_rf_part3[] = {
259 { 0x00, 0x98 }, { 0x03, 0x20 }, { 0x04, 0x7e }, { 0x05, 0x12 },
260 { 0x06, 0xfc }, { 0x07, 0x78 }, { 0x08, 0x2e }, { 0x10, 0x9b },
261 { 0x11, 0x88 }, { 0x12, 0x47 }, { 0x13, 0xd0 }, { 0x19, 0x00 },
262 { 0x1a, 0xa0 }, { 0x1b, 0x08 }, { 0x40, 0x86 }, { 0x41, 0x8d },
263 { 0x42, 0x15 }, { 0x43, 0x18 }, { 0x44, 0x1f }, { 0x45, 0x1e },
264 { 0x46, 0x1a }, { 0x47, 0x15 }, { 0x48, 0x10 }, { 0x49, 0x0a },
265 { 0x4a, 0x05 }, { 0x4b, 0x02 }, { 0x4c, 0x05 }
268 static uint16_t urtw_8225_rxgain[] = {
269 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
270 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
271 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
272 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
273 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
274 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
275 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
276 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
277 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
278 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
279 0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3,
280 0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb
283 static uint8_t urtw_8225_threshold[] = {
284 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd,
287 static uint8_t urtw_8225_tx_gain_cck_ofdm[] = {
288 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e
291 static uint8_t urtw_8225_txpwr_cck[] = {
292 0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02,
293 0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02,
294 0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02,
295 0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02,
296 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03,
297 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03
300 static uint8_t urtw_8225_txpwr_cck_ch14[] = {
301 0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00,
302 0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00,
303 0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00,
304 0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00,
305 0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00,
306 0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00
309 static uint8_t urtw_8225_txpwr_ofdm[]={
310 0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4
313 static uint8_t urtw_8225v2_gain_bg[]={
314 0x23, 0x15, 0xa5, /* -82-1dbm */
315 0x23, 0x15, 0xb5, /* -82-2dbm */
316 0x23, 0x15, 0xc5, /* -82-3dbm */
317 0x33, 0x15, 0xc5, /* -78dbm */
318 0x43, 0x15, 0xc5, /* -74dbm */
319 0x53, 0x15, 0xc5, /* -70dbm */
320 0x63, 0x15, 0xc5, /* -66dbm */
323 static struct urtw_pair urtw_8225v2_rf_part1[] = {
324 { 0x00, 0x02bf }, { 0x01, 0x0ee0 }, { 0x02, 0x044d }, { 0x03, 0x0441 },
325 { 0x04, 0x08c3 }, { 0x05, 0x0c72 }, { 0x06, 0x00e6 }, { 0x07, 0x082a },
326 { 0x08, 0x003f }, { 0x09, 0x0335 }, { 0x0a, 0x09d4 }, { 0x0b, 0x07bb },
327 { 0x0c, 0x0850 }, { 0x0d, 0x0cdf }, { 0x0e, 0x002b }, { 0x0f, 0x0114 }
330 static struct urtw_pair urtw_8225v2b_rf_part0[] = {
331 { 0x00, 0x00b7 }, { 0x01, 0x0ee0 }, { 0x02, 0x044d }, { 0x03, 0x0441 },
332 { 0x04, 0x08c3 }, { 0x05, 0x0c72 }, { 0x06, 0x00e6 }, { 0x07, 0x082a },
333 { 0x08, 0x003f }, { 0x09, 0x0335 }, { 0x0a, 0x09d4 }, { 0x0b, 0x07bb },
334 { 0x0c, 0x0850 }, { 0x0d, 0x0cdf }, { 0x0e, 0x002b }, { 0x0f, 0x0114 }
337 static struct urtw_pair urtw_8225v2b_rf_part1[] = {
338 {0x0f0, 0x32}, {0x0f1, 0x32}, {0x0f2, 0x00},
339 {0x0f3, 0x00}, {0x0f4, 0x32}, {0x0f5, 0x43},
340 {0x0f6, 0x00}, {0x0f7, 0x00}, {0x0f8, 0x46},
341 {0x0f9, 0xa4}, {0x0fa, 0x00}, {0x0fb, 0x00},
342 {0x0fc, 0x96}, {0x0fd, 0xa4}, {0x0fe, 0x00},
343 {0x0ff, 0x00}, {0x158, 0x4b}, {0x159, 0x00},
344 {0x15a, 0x4b}, {0x15b, 0x00}, {0x160, 0x4b},
345 {0x161, 0x09}, {0x162, 0x4b}, {0x163, 0x09},
346 {0x1ce, 0x0f}, {0x1cf, 0x00}, {0x1e0, 0xff},
347 {0x1e1, 0x0f}, {0x1e2, 0x00}, {0x1f0, 0x4e},
348 {0x1f1, 0x01}, {0x1f2, 0x02}, {0x1f3, 0x03},
349 {0x1f4, 0x04}, {0x1f5, 0x05}, {0x1f6, 0x06},
350 {0x1f7, 0x07}, {0x1f8, 0x08}, {0x24e, 0x00},
351 {0x20c, 0x04}, {0x221, 0x61}, {0x222, 0x68},
352 {0x223, 0x6f}, {0x224, 0x76}, {0x225, 0x7d},
353 {0x226, 0x84}, {0x227, 0x8d}, {0x24d, 0x08},
354 {0x250, 0x05}, {0x251, 0xf5}, {0x252, 0x04},
355 {0x253, 0xa0}, {0x254, 0x1f}, {0x255, 0x23},
356 {0x256, 0x45}, {0x257, 0x67}, {0x258, 0x08},
357 {0x259, 0x08}, {0x25a, 0x08}, {0x25b, 0x08},
358 {0x260, 0x08}, {0x261, 0x08}, {0x262, 0x08},
359 {0x263, 0x08}, {0x264, 0xcf}, {0x272, 0x56},
360 {0x273, 0x9a}, {0x034, 0xf0}, {0x035, 0x0f},
361 {0x05b, 0x40}, {0x084, 0x88}, {0x085, 0x24},
362 {0x088, 0x54}, {0x08b, 0xb8}, {0x08c, 0x07},
363 {0x08d, 0x00}, {0x094, 0x1b}, {0x095, 0x12},
364 {0x096, 0x00}, {0x097, 0x06}, {0x09d, 0x1a},
365 {0x09f, 0x10}, {0x0b4, 0x22}, {0x0be, 0x80},
366 {0x0db, 0x00}, {0x0ee, 0x00}, {0x091, 0x03},
367 {0x24c, 0x00}, {0x39f, 0x00}, {0x08c, 0x01},
368 {0x08d, 0x10}, {0x08e, 0x08}, {0x08f, 0x00}
371 static struct urtw_pair urtw_8225v2_rf_part2[] = {
372 { 0x00, 0x01 }, { 0x01, 0x02 }, { 0x02, 0x42 }, { 0x03, 0x00 },
373 { 0x04, 0x00 }, { 0x05, 0x00 }, { 0x06, 0x40 }, { 0x07, 0x00 },
374 { 0x08, 0x40 }, { 0x09, 0xfe }, { 0x0a, 0x08 }, { 0x0b, 0x80 },
375 { 0x0c, 0x01 }, { 0x0d, 0x43 }, { 0x0e, 0xd3 }, { 0x0f, 0x38 },
376 { 0x10, 0x84 }, { 0x11, 0x07 }, { 0x12, 0x20 }, { 0x13, 0x20 },
377 { 0x14, 0x00 }, { 0x15, 0x40 }, { 0x16, 0x00 }, { 0x17, 0x40 },
378 { 0x18, 0xef }, { 0x19, 0x19 }, { 0x1a, 0x20 }, { 0x1b, 0x15 },
379 { 0x1c, 0x04 }, { 0x1d, 0xc5 }, { 0x1e, 0x95 }, { 0x1f, 0x75 },
380 { 0x20, 0x1f }, { 0x21, 0x17 }, { 0x22, 0x16 }, { 0x23, 0x80 },
381 { 0x24, 0x46 }, { 0x25, 0x00 }, { 0x26, 0x90 }, { 0x27, 0x88 }
384 static struct urtw_pair urtw_8225v2b_rf_part2[] = {
385 { 0x00, 0x10 }, { 0x01, 0x0d }, { 0x02, 0x01 }, { 0x03, 0x00 },
386 { 0x04, 0x14 }, { 0x05, 0xfb }, { 0x06, 0xfb }, { 0x07, 0x60 },
387 { 0x08, 0x00 }, { 0x09, 0x60 }, { 0x0a, 0x00 }, { 0x0b, 0x00 },
388 { 0x0c, 0x00 }, { 0x0d, 0x5c }, { 0x0e, 0x00 }, { 0x0f, 0x00 },
389 { 0x10, 0x40 }, { 0x11, 0x00 }, { 0x12, 0x40 }, { 0x13, 0x00 },
390 { 0x14, 0x00 }, { 0x15, 0x00 }, { 0x16, 0xa8 }, { 0x17, 0x26 },
391 { 0x18, 0x32 }, { 0x19, 0x33 }, { 0x1a, 0x07 }, { 0x1b, 0xa5 },
392 { 0x1c, 0x6f }, { 0x1d, 0x55 }, { 0x1e, 0xc8 }, { 0x1f, 0xb3 },
393 { 0x20, 0x0a }, { 0x21, 0xe1 }, { 0x22, 0x2C }, { 0x23, 0x8a },
394 { 0x24, 0x86 }, { 0x25, 0x83 }, { 0x26, 0x34 }, { 0x27, 0x0f },
395 { 0x28, 0x4f }, { 0x29, 0x24 }, { 0x2a, 0x6f }, { 0x2b, 0xc2 },
396 { 0x2c, 0x6b }, { 0x2d, 0x40 }, { 0x2e, 0x80 }, { 0x2f, 0x00 },
397 { 0x30, 0xc0 }, { 0x31, 0xc1 }, { 0x32, 0x58 }, { 0x33, 0xf1 },
398 { 0x34, 0x00 }, { 0x35, 0xe4 }, { 0x36, 0x90 }, { 0x37, 0x3e },
399 { 0x38, 0x6d }, { 0x39, 0x3c }, { 0x3a, 0xfb }, { 0x3b, 0x07 }
402 static struct urtw_pair urtw_8225v2_rf_part3[] = {
403 { 0x00, 0x98 }, { 0x03, 0x20 }, { 0x04, 0x7e }, { 0x05, 0x12 },
404 { 0x06, 0xfc }, { 0x07, 0x78 }, { 0x08, 0x2e }, { 0x09, 0x11 },
405 { 0x0a, 0x17 }, { 0x0b, 0x11 }, { 0x10, 0x9b }, { 0x11, 0x88 },
406 { 0x12, 0x47 }, { 0x13, 0xd0 }, { 0x19, 0x00 }, { 0x1a, 0xa0 },
407 { 0x1b, 0x08 }, { 0x1d, 0x00 }, { 0x40, 0x86 }, { 0x41, 0x9d },
408 { 0x42, 0x15 }, { 0x43, 0x18 }, { 0x44, 0x36 }, { 0x45, 0x35 },
409 { 0x46, 0x2e }, { 0x47, 0x25 }, { 0x48, 0x1c }, { 0x49, 0x12 },
410 { 0x4a, 0x09 }, { 0x4b, 0x04 }, { 0x4c, 0x05 }
413 static uint16_t urtw_8225v2_rxgain[] = {
414 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0008, 0x0009,
415 0x000a, 0x000b, 0x0102, 0x0103, 0x0104, 0x0105, 0x0140, 0x0141,
416 0x0142, 0x0143, 0x0144, 0x0145, 0x0180, 0x0181, 0x0182, 0x0183,
417 0x0184, 0x0185, 0x0188, 0x0189, 0x018a, 0x018b, 0x0243, 0x0244,
418 0x0245, 0x0280, 0x0281, 0x0282, 0x0283, 0x0284, 0x0285, 0x0288,
419 0x0289, 0x028a, 0x028b, 0x028c, 0x0342, 0x0343, 0x0344, 0x0345,
420 0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x0388, 0x0389,
421 0x038a, 0x038b, 0x038c, 0x038d, 0x0390, 0x0391, 0x0392, 0x0393,
422 0x0394, 0x0395, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d,
423 0x03a0, 0x03a1, 0x03a2, 0x03a3, 0x03a4, 0x03a5, 0x03a8, 0x03a9,
424 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
425 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
428 static uint16_t urtw_8225v2b_rxgain[] = {
429 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
430 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
431 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
432 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
433 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
434 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
435 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
436 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
437 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
438 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
439 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
440 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
443 static uint8_t urtw_8225v2_tx_gain_cck_ofdm[] = {
444 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
445 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
446 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
447 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
448 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
449 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
452 static uint8_t urtw_8225v2_txpwr_cck[] = {
453 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04
456 static uint8_t urtw_8225v2_txpwr_cck_ch14[] = {
457 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00
460 static uint8_t urtw_8225v2b_txpwr_cck[] = {
461 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04,
462 0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03,
463 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03,
464 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03
467 static uint8_t urtw_8225v2b_txpwr_cck_ch14[] = {
468 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00,
469 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
470 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
471 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00
474 static struct urtw_pair urtw_ratetable[] = {
475 { 2, 0 }, { 4, 1 }, { 11, 2 }, { 12, 4 }, { 18, 5 },
476 { 22, 3 }, { 24, 6 }, { 36, 7 }, { 48, 8 }, { 72, 9 },
477 { 96, 10 }, { 108, 11 }
480 static const uint8_t urtw_8187b_reg_table[][3] = {
481 { 0xf0, 0x32, 0 }, { 0xf1, 0x32, 0 }, { 0xf2, 0x00, 0 },
482 { 0xf3, 0x00, 0 }, { 0xf4, 0x32, 0 }, { 0xf5, 0x43, 0 },
483 { 0xf6, 0x00, 0 }, { 0xf7, 0x00, 0 }, { 0xf8, 0x46, 0 },
484 { 0xf9, 0xa4, 0 }, { 0xfa, 0x00, 0 }, { 0xfb, 0x00, 0 },
485 { 0xfc, 0x96, 0 }, { 0xfd, 0xa4, 0 }, { 0xfe, 0x00, 0 },
486 { 0xff, 0x00, 0 }, { 0x58, 0x4b, 1 }, { 0x59, 0x00, 1 },
487 { 0x5a, 0x4b, 1 }, { 0x5b, 0x00, 1 }, { 0x60, 0x4b, 1 },
488 { 0x61, 0x09, 1 }, { 0x62, 0x4b, 1 }, { 0x63, 0x09, 1 },
489 { 0xce, 0x0f, 1 }, { 0xcf, 0x00, 1 }, { 0xe0, 0xff, 1 },
490 { 0xe1, 0x0f, 1 }, { 0xe2, 0x00, 1 }, { 0xf0, 0x4e, 1 },
491 { 0xf1, 0x01, 1 }, { 0xf2, 0x02, 1 }, { 0xf3, 0x03, 1 },
492 { 0xf4, 0x04, 1 }, { 0xf5, 0x05, 1 }, { 0xf6, 0x06, 1 },
493 { 0xf7, 0x07, 1 }, { 0xf8, 0x08, 1 }, { 0x4e, 0x00, 2 },
494 { 0x0c, 0x04, 2 }, { 0x21, 0x61, 2 }, { 0x22, 0x68, 2 },
495 { 0x23, 0x6f, 2 }, { 0x24, 0x76, 2 }, { 0x25, 0x7d, 2 },
496 { 0x26, 0x84, 2 }, { 0x27, 0x8d, 2 }, { 0x4d, 0x08, 2 },
497 { 0x50, 0x05, 2 }, { 0x51, 0xf5, 2 }, { 0x52, 0x04, 2 },
498 { 0x53, 0xa0, 2 }, { 0x54, 0x1f, 2 }, { 0x55, 0x23, 2 },
499 { 0x56, 0x45, 2 }, { 0x57, 0x67, 2 }, { 0x58, 0x08, 2 },
500 { 0x59, 0x08, 2 }, { 0x5a, 0x08, 2 }, { 0x5b, 0x08, 2 },
501 { 0x60, 0x08, 2 }, { 0x61, 0x08, 2 }, { 0x62, 0x08, 2 },
502 { 0x63, 0x08, 2 }, { 0x64, 0xcf, 2 }, { 0x72, 0x56, 2 },
503 { 0x73, 0x9a, 2 }, { 0x34, 0xf0, 0 }, { 0x35, 0x0f, 0 },
504 { 0x5b, 0x40, 0 }, { 0x84, 0x88, 0 }, { 0x85, 0x24, 0 },
505 { 0x88, 0x54, 0 }, { 0x8b, 0xb8, 0 }, { 0x8c, 0x07, 0 },
506 { 0x8d, 0x00, 0 }, { 0x94, 0x1b, 0 }, { 0x95, 0x12, 0 },
507 { 0x96, 0x00, 0 }, { 0x97, 0x06, 0 }, { 0x9d, 0x1a, 0 },
508 { 0x9f, 0x10, 0 }, { 0xb4, 0x22, 0 }, { 0xbe, 0x80, 0 },
509 { 0xdb, 0x00, 0 }, { 0xee, 0x00, 0 }, { 0x91, 0x03, 0 },
510 { 0x4c, 0x00, 2 }, { 0x9f, 0x00, 3 }, { 0x8c, 0x01, 0 },
511 { 0x8d, 0x10, 0 }, { 0x8e, 0x08, 0 }, { 0x8f, 0x00, 0 }
514 static usb_callback_t urtw_bulk_rx_callback;
515 static usb_callback_t urtw_bulk_tx_callback;
516 static usb_callback_t urtw_bulk_tx_status_callback;
518 static const struct usb_config urtw_8187b_usbconfig[URTW_8187B_N_XFERS] = {
519 [URTW_8187B_BULK_RX] = {
522 .direction = UE_DIR_IN,
529 .callback = urtw_bulk_rx_callback
531 [URTW_8187B_BULK_TX_STATUS] = {
534 .direction = UE_DIR_IN,
541 .callback = urtw_bulk_tx_status_callback
543 [URTW_8187B_BULK_TX_BE] = {
545 .endpoint = URTW_8187B_TXPIPE_BE,
546 .direction = UE_DIR_OUT,
547 .bufsize = URTW_TX_MAXSIZE,
550 .force_short_xfer = 1,
553 .callback = urtw_bulk_tx_callback,
554 .timeout = URTW_DATA_TIMEOUT
556 [URTW_8187B_BULK_TX_BK] = {
558 .endpoint = URTW_8187B_TXPIPE_BK,
559 .direction = UE_DIR_OUT,
560 .bufsize = URTW_TX_MAXSIZE,
563 .force_short_xfer = 1,
566 .callback = urtw_bulk_tx_callback,
567 .timeout = URTW_DATA_TIMEOUT
569 [URTW_8187B_BULK_TX_VI] = {
571 .endpoint = URTW_8187B_TXPIPE_VI,
572 .direction = UE_DIR_OUT,
573 .bufsize = URTW_TX_MAXSIZE,
576 .force_short_xfer = 1,
579 .callback = urtw_bulk_tx_callback,
580 .timeout = URTW_DATA_TIMEOUT
582 [URTW_8187B_BULK_TX_VO] = {
584 .endpoint = URTW_8187B_TXPIPE_VO,
585 .direction = UE_DIR_OUT,
586 .bufsize = URTW_TX_MAXSIZE,
589 .force_short_xfer = 1,
592 .callback = urtw_bulk_tx_callback,
593 .timeout = URTW_DATA_TIMEOUT
595 [URTW_8187B_BULK_TX_EP12] = {
598 .direction = UE_DIR_OUT,
599 .bufsize = URTW_TX_MAXSIZE,
602 .force_short_xfer = 1,
605 .callback = urtw_bulk_tx_callback,
606 .timeout = URTW_DATA_TIMEOUT
610 static const struct usb_config urtw_8187l_usbconfig[URTW_8187L_N_XFERS] = {
611 [URTW_8187L_BULK_RX] = {
614 .direction = UE_DIR_IN,
621 .callback = urtw_bulk_rx_callback
623 [URTW_8187L_BULK_TX_LOW] = {
626 .direction = UE_DIR_OUT,
627 .bufsize = URTW_TX_MAXSIZE,
630 .force_short_xfer = 1,
633 .callback = urtw_bulk_tx_callback,
634 .timeout = URTW_DATA_TIMEOUT
636 [URTW_8187L_BULK_TX_NORMAL] = {
639 .direction = UE_DIR_OUT,
640 .bufsize = URTW_TX_MAXSIZE,
643 .force_short_xfer = 1,
646 .callback = urtw_bulk_tx_callback,
647 .timeout = URTW_DATA_TIMEOUT
651 static struct ieee80211vap *urtw_vap_create(struct ieee80211com *,
652 const char [IFNAMSIZ], int, enum ieee80211_opmode,
653 int, const uint8_t [IEEE80211_ADDR_LEN],
654 const uint8_t [IEEE80211_ADDR_LEN]);
655 static void urtw_vap_delete(struct ieee80211vap *);
656 static void urtw_init(void *);
657 static void urtw_stop(struct ifnet *, int);
658 static void urtw_stop_locked(struct ifnet *, int);
659 static int urtw_ioctl(struct ifnet *, u_long, caddr_t);
660 static void urtw_start(struct ifnet *);
661 static int urtw_alloc_rx_data_list(struct urtw_softc *);
662 static int urtw_alloc_tx_data_list(struct urtw_softc *);
663 static int urtw_raw_xmit(struct ieee80211_node *, struct mbuf *,
664 const struct ieee80211_bpf_params *);
665 static void urtw_scan_start(struct ieee80211com *);
666 static void urtw_scan_end(struct ieee80211com *);
667 static void urtw_set_channel(struct ieee80211com *);
668 static void urtw_update_mcast(struct ieee80211com *);
669 static int urtw_tx_start(struct urtw_softc *,
670 struct ieee80211_node *, struct mbuf *,
671 struct urtw_data *, int);
672 static int urtw_newstate(struct ieee80211vap *,
673 enum ieee80211_state, int);
674 static void urtw_led_ch(void *);
675 static void urtw_ledtask(void *, int);
676 static void urtw_watchdog(void *);
677 static void urtw_set_multi(void *);
678 static int urtw_isbmode(uint16_t);
679 static uint16_t urtw_rate2rtl(int);
680 static uint16_t urtw_rtl2rate(int);
681 static usb_error_t urtw_set_rate(struct urtw_softc *);
682 static usb_error_t urtw_update_msr(struct urtw_softc *);
683 static usb_error_t urtw_read8_c(struct urtw_softc *, int, uint8_t *);
684 static usb_error_t urtw_read16_c(struct urtw_softc *, int, uint16_t *);
685 static usb_error_t urtw_read32_c(struct urtw_softc *, int, uint32_t *);
686 static usb_error_t urtw_write8_c(struct urtw_softc *, int, uint8_t);
687 static usb_error_t urtw_write16_c(struct urtw_softc *, int, uint16_t);
688 static usb_error_t urtw_write32_c(struct urtw_softc *, int, uint32_t);
689 static usb_error_t urtw_eprom_cs(struct urtw_softc *, int);
690 static usb_error_t urtw_eprom_ck(struct urtw_softc *);
691 static usb_error_t urtw_eprom_sendbits(struct urtw_softc *, int16_t *,
693 static usb_error_t urtw_eprom_read32(struct urtw_softc *, uint32_t,
695 static usb_error_t urtw_eprom_readbit(struct urtw_softc *, int16_t *);
696 static usb_error_t urtw_eprom_writebit(struct urtw_softc *, int16_t);
697 static usb_error_t urtw_get_macaddr(struct urtw_softc *);
698 static usb_error_t urtw_get_txpwr(struct urtw_softc *);
699 static usb_error_t urtw_get_rfchip(struct urtw_softc *);
700 static usb_error_t urtw_led_init(struct urtw_softc *);
701 static usb_error_t urtw_8185_rf_pins_enable(struct urtw_softc *);
702 static usb_error_t urtw_8185_tx_antenna(struct urtw_softc *, uint8_t);
703 static usb_error_t urtw_8187_write_phy(struct urtw_softc *, uint8_t,
705 static usb_error_t urtw_8187_write_phy_ofdm_c(struct urtw_softc *,
707 static usb_error_t urtw_8187_write_phy_cck_c(struct urtw_softc *, uint8_t,
709 static usb_error_t urtw_8225_setgain(struct urtw_softc *, int16_t);
710 static usb_error_t urtw_8225_usb_init(struct urtw_softc *);
711 static usb_error_t urtw_8225_write_c(struct urtw_softc *, uint8_t,
713 static usb_error_t urtw_8225_write_s16(struct urtw_softc *, uint8_t, int,
715 static usb_error_t urtw_8225_read(struct urtw_softc *, uint8_t,
717 static usb_error_t urtw_8225_rf_init(struct urtw_softc *);
718 static usb_error_t urtw_8225_rf_set_chan(struct urtw_softc *, int);
719 static usb_error_t urtw_8225_rf_set_sens(struct urtw_softc *, int);
720 static usb_error_t urtw_8225_set_txpwrlvl(struct urtw_softc *, int);
721 static usb_error_t urtw_8225_rf_stop(struct urtw_softc *);
722 static usb_error_t urtw_8225v2_rf_init(struct urtw_softc *);
723 static usb_error_t urtw_8225v2_rf_set_chan(struct urtw_softc *, int);
724 static usb_error_t urtw_8225v2_set_txpwrlvl(struct urtw_softc *, int);
725 static usb_error_t urtw_8225v2_setgain(struct urtw_softc *, int16_t);
726 static usb_error_t urtw_8225_isv2(struct urtw_softc *, int *);
727 static usb_error_t urtw_8225v2b_rf_init(struct urtw_softc *);
728 static usb_error_t urtw_8225v2b_rf_set_chan(struct urtw_softc *, int);
729 static usb_error_t urtw_read8e(struct urtw_softc *, int, uint8_t *);
730 static usb_error_t urtw_write8e(struct urtw_softc *, int, uint8_t);
731 static usb_error_t urtw_8180_set_anaparam(struct urtw_softc *, uint32_t);
732 static usb_error_t urtw_8185_set_anaparam2(struct urtw_softc *, uint32_t);
733 static usb_error_t urtw_intr_enable(struct urtw_softc *);
734 static usb_error_t urtw_intr_disable(struct urtw_softc *);
735 static usb_error_t urtw_reset(struct urtw_softc *);
736 static usb_error_t urtw_led_on(struct urtw_softc *, int);
737 static usb_error_t urtw_led_ctl(struct urtw_softc *, int);
738 static usb_error_t urtw_led_blink(struct urtw_softc *);
739 static usb_error_t urtw_led_mode0(struct urtw_softc *, int);
740 static usb_error_t urtw_led_mode1(struct urtw_softc *, int);
741 static usb_error_t urtw_led_mode2(struct urtw_softc *, int);
742 static usb_error_t urtw_led_mode3(struct urtw_softc *, int);
743 static usb_error_t urtw_rx_setconf(struct urtw_softc *);
744 static usb_error_t urtw_rx_enable(struct urtw_softc *);
745 static usb_error_t urtw_tx_enable(struct urtw_softc *sc);
746 static void urtw_free_tx_data_list(struct urtw_softc *);
747 static void urtw_free_rx_data_list(struct urtw_softc *);
748 static void urtw_free_data_list(struct urtw_softc *,
749 struct urtw_data data[], int, int);
750 static usb_error_t urtw_adapter_start(struct urtw_softc *);
751 static usb_error_t urtw_adapter_start_b(struct urtw_softc *);
752 static usb_error_t urtw_set_mode(struct urtw_softc *, uint32_t);
753 static usb_error_t urtw_8187b_cmd_reset(struct urtw_softc *);
754 static usb_error_t urtw_do_request(struct urtw_softc *,
755 struct usb_device_request *, void *);
756 static usb_error_t urtw_8225v2b_set_txpwrlvl(struct urtw_softc *, int);
757 static usb_error_t urtw_led_off(struct urtw_softc *, int);
758 static void urtw_abort_xfers(struct urtw_softc *);
759 static struct urtw_data *
760 urtw_getbuf(struct urtw_softc *sc);
761 static int urtw_compute_txtime(uint16_t, uint16_t, uint8_t,
763 static void urtw_updateslot(struct ieee80211com *);
764 static void urtw_updateslottask(void *, int);
765 static void urtw_sysctl_node(struct urtw_softc *);
768 urtw_match(device_t dev)
770 struct usb_attach_arg *uaa = device_get_ivars(dev);
772 if (uaa->usb_mode != USB_MODE_HOST)
774 if (uaa->info.bConfigIndex != URTW_CONFIG_INDEX)
776 if (uaa->info.bIfaceIndex != URTW_IFACE_INDEX)
779 return (usbd_lookup_id_by_uaa(urtw_devs, sizeof(urtw_devs), uaa));
783 urtw_attach(device_t dev)
785 const struct usb_config *setup_start;
787 struct urtw_softc *sc = device_get_softc(dev);
788 struct usb_attach_arg *uaa = device_get_ivars(dev);
789 struct ieee80211com *ic;
791 uint8_t bands, iface_index = URTW_IFACE_INDEX; /* XXX */
796 device_set_usb_desc(dev);
799 sc->sc_udev = uaa->device;
800 if (USB_GET_DRIVER_INFO(uaa) == URTW_REV_RTL8187B)
801 sc->sc_flags |= URTW_RTL8187B;
803 sc->sc_debug = urtw_debug;
806 mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev), MTX_NETWORK_LOCK,
808 usb_callout_init_mtx(&sc->sc_led_ch, &sc->sc_mtx, 0);
809 TASK_INIT(&sc->sc_led_task, 0, urtw_ledtask, sc);
810 TASK_INIT(&sc->sc_updateslot_task, 0, urtw_updateslottask, sc);
811 callout_init(&sc->sc_watchdog_ch, 0);
813 if (sc->sc_flags & URTW_RTL8187B) {
814 setup_start = urtw_8187b_usbconfig;
815 n_setup = URTW_8187B_N_XFERS;
817 setup_start = urtw_8187l_usbconfig;
818 n_setup = URTW_8187L_N_XFERS;
821 error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_xfer,
822 setup_start, n_setup, sc, &sc->sc_mtx);
824 device_printf(dev, "could not allocate USB transfers, "
825 "err=%s\n", usbd_errstr(error));
832 urtw_read32_m(sc, URTW_RX, &data);
833 sc->sc_epromtype = (data & URTW_RX_9356SEL) ? URTW_EEPROM_93C56 :
836 error = urtw_get_rfchip(sc);
839 error = urtw_get_macaddr(sc);
842 error = urtw_get_txpwr(sc);
845 error = urtw_led_init(sc);
851 sc->sc_rts_retry = URTW_DEFAULT_RTS_RETRY;
852 sc->sc_tx_retry = URTW_DEFAULT_TX_RETRY;
854 sc->sc_preamble_mode = urtw_preamble_mode;
856 ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
858 device_printf(sc->sc_dev, "can not allocate ifnet\n");
864 if_initname(ifp, "urtw", device_get_unit(sc->sc_dev));
865 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
866 ifp->if_init = urtw_init;
867 ifp->if_ioctl = urtw_ioctl;
868 ifp->if_start = urtw_start;
869 /* XXX URTW_TX_DATA_LIST_COUNT */
870 IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
871 ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
872 IFQ_SET_READY(&ifp->if_snd);
877 ic->ic_name = device_get_nameunit(dev);
878 ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
879 ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
881 /* set device capabilities */
883 IEEE80211_C_STA | /* station mode */
884 IEEE80211_C_MONITOR | /* monitor mode supported */
885 IEEE80211_C_TXPMGT | /* tx power management */
886 IEEE80211_C_SHPREAMBLE | /* short preamble supported */
887 IEEE80211_C_SHSLOT | /* short slot time supported */
888 IEEE80211_C_BGSCAN | /* capable of bg scanning */
889 IEEE80211_C_WPA; /* 802.11i */
892 setbit(&bands, IEEE80211_MODE_11B);
893 setbit(&bands, IEEE80211_MODE_11G);
894 ieee80211_init_channels(ic, NULL, &bands);
896 ieee80211_ifattach(ic, sc->sc_bssid);
897 ic->ic_raw_xmit = urtw_raw_xmit;
898 ic->ic_scan_start = urtw_scan_start;
899 ic->ic_scan_end = urtw_scan_end;
900 ic->ic_set_channel = urtw_set_channel;
901 ic->ic_updateslot = urtw_updateslot;
902 ic->ic_vap_create = urtw_vap_create;
903 ic->ic_vap_delete = urtw_vap_delete;
904 ic->ic_update_mcast = urtw_update_mcast;
906 ieee80211_radiotap_attach(ic,
907 &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
908 URTW_TX_RADIOTAP_PRESENT,
909 &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
910 URTW_RX_RADIOTAP_PRESENT);
912 urtw_sysctl_node(sc);
915 ieee80211_announce(ic);
918 fail: URTW_UNLOCK(sc);
919 fail1: usbd_transfer_unsetup(sc->sc_xfer, (sc->sc_flags & URTW_RTL8187B) ?
920 URTW_8187B_N_XFERS : URTW_8187L_N_XFERS);
926 urtw_detach(device_t dev)
928 struct urtw_softc *sc = device_get_softc(dev);
929 struct ifnet *ifp = sc->sc_ifp;
930 struct ieee80211com *ic = ifp->if_l2com;
932 if (!device_is_attached(dev))
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 usbd_transfer_unsetup(sc->sc_xfer, (sc->sc_flags & URTW_RTL8187B) ?
943 URTW_8187B_N_XFERS : URTW_8187L_N_XFERS);
944 ieee80211_ifdetach(ic);
946 urtw_free_tx_data_list(sc);
947 urtw_free_rx_data_list(sc);
950 mtx_destroy(&sc->sc_mtx);
956 urtw_free_tx_data_list(struct urtw_softc *sc)
958 urtw_free_data_list(sc, sc->sc_tx, URTW_TX_DATA_LIST_COUNT, 0);
962 urtw_free_rx_data_list(struct urtw_softc *sc)
964 urtw_free_data_list(sc, sc->sc_rx, URTW_RX_DATA_LIST_COUNT, 1);
968 urtw_free_data_list(struct urtw_softc *sc, struct urtw_data data[], int ndata,
973 for (i = 0; i < ndata; i++) {
974 struct urtw_data *dp = &data[i];
983 if (dp->buf != NULL) {
984 free(dp->buf, M_USBDEV);
988 if (dp->ni != NULL) {
989 ieee80211_free_node(dp->ni);
995 static struct ieee80211vap *
996 urtw_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
997 enum ieee80211_opmode opmode, int flags,
998 const uint8_t bssid[IEEE80211_ADDR_LEN],
999 const uint8_t mac[IEEE80211_ADDR_LEN])
1001 struct urtw_vap *uvp;
1002 struct ieee80211vap *vap;
1004 if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
1006 uvp = (struct urtw_vap *) malloc(sizeof(struct urtw_vap),
1007 M_80211_VAP, M_WAITOK | M_ZERO);
1011 /* enable s/w bmiss handling for sta mode */
1012 ieee80211_vap_setup(ic, vap, name, unit, opmode,
1013 flags | IEEE80211_CLONE_NOBEACONS, bssid, mac);
1015 /* override state transition machine */
1016 uvp->newstate = vap->iv_newstate;
1017 vap->iv_newstate = urtw_newstate;
1019 /* complete setup */
1020 ieee80211_vap_attach(vap, ieee80211_media_change,
1021 ieee80211_media_status);
1022 ic->ic_opmode = opmode;
1027 urtw_vap_delete(struct ieee80211vap *vap)
1029 struct urtw_vap *uvp = URTW_VAP(vap);
1031 ieee80211_vap_detach(vap);
1032 free(uvp, M_80211_VAP);
1036 urtw_init_locked(void *arg)
1039 struct urtw_softc *sc = arg;
1040 struct ifnet *ifp = sc->sc_ifp;
1043 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1044 urtw_stop_locked(ifp, 0);
1046 error = (sc->sc_flags & URTW_RTL8187B) ? urtw_adapter_start_b(sc) :
1047 urtw_adapter_start(sc);
1051 /* reset softc variables */
1054 if (!(sc->sc_flags & URTW_INIT_ONCE)) {
1055 ret = urtw_alloc_rx_data_list(sc);
1058 ret = urtw_alloc_tx_data_list(sc);
1061 sc->sc_flags |= URTW_INIT_ONCE;
1064 error = urtw_rx_enable(sc);
1067 error = urtw_tx_enable(sc);
1071 if (sc->sc_flags & URTW_RTL8187B)
1072 usbd_transfer_start(sc->sc_xfer[URTW_8187B_BULK_TX_STATUS]);
1074 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
1075 ifp->if_drv_flags |= IFF_DRV_RUNNING;
1077 callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc);
1083 urtw_init(void *arg)
1085 struct urtw_softc *sc = arg;
1088 urtw_init_locked(arg);
1093 urtw_adapter_start_b(struct urtw_softc *sc)
1098 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
1102 urtw_read8_m(sc, URTW_CONFIG3, &data8);
1103 urtw_write8_m(sc, URTW_CONFIG3,
1104 data8 | URTW_CONFIG3_ANAPARAM_WRITE | URTW_CONFIG3_GNT_SELECT);
1105 urtw_write32_m(sc, URTW_ANAPARAM2, URTW_8187B_8225_ANAPARAM2_ON);
1106 urtw_write32_m(sc, URTW_ANAPARAM, URTW_8187B_8225_ANAPARAM_ON);
1107 urtw_write8_m(sc, URTW_ANAPARAM3, URTW_8187B_8225_ANAPARAM3_ON);
1109 urtw_write8_m(sc, 0x61, 0x10);
1110 urtw_read8_m(sc, 0x62, &data8);
1111 urtw_write8_m(sc, 0x62, data8 & ~(1 << 5));
1112 urtw_write8_m(sc, 0x62, data8 | (1 << 5));
1114 urtw_read8_m(sc, URTW_CONFIG3, &data8);
1115 data8 &= ~URTW_CONFIG3_ANAPARAM_WRITE;
1116 urtw_write8_m(sc, URTW_CONFIG3, data8);
1118 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
1122 error = urtw_8187b_cmd_reset(sc);
1126 error = sc->sc_rf_init(sc);
1129 urtw_write8_m(sc, URTW_CMD, URTW_CMD_RX_ENABLE | URTW_CMD_TX_ENABLE);
1131 /* fix RTL8187B RX stall */
1132 error = urtw_intr_enable(sc);
1136 error = urtw_write8e(sc, 0x41, 0xf4);
1139 error = urtw_write8e(sc, 0x40, 0x00);
1142 error = urtw_write8e(sc, 0x42, 0x00);
1145 error = urtw_write8e(sc, 0x42, 0x01);
1148 error = urtw_write8e(sc, 0x40, 0x0f);
1151 error = urtw_write8e(sc, 0x42, 0x00);
1154 error = urtw_write8e(sc, 0x42, 0x01);
1158 urtw_read8_m(sc, 0xdb, &data8);
1159 urtw_write8_m(sc, 0xdb, data8 | (1 << 2));
1160 urtw_write16_m(sc, 0x372, 0x59fa);
1161 urtw_write16_m(sc, 0x374, 0x59d2);
1162 urtw_write16_m(sc, 0x376, 0x59d2);
1163 urtw_write16_m(sc, 0x378, 0x19fa);
1164 urtw_write16_m(sc, 0x37a, 0x19fa);
1165 urtw_write16_m(sc, 0x37c, 0x00d0);
1166 urtw_write8_m(sc, 0x61, 0);
1168 urtw_write8_m(sc, 0x180, 0x0f);
1169 urtw_write8_m(sc, 0x183, 0x03);
1170 urtw_write8_m(sc, 0xda, 0x10);
1171 urtw_write8_m(sc, 0x24d, 0x08);
1172 urtw_write32_m(sc, URTW_HSSI_PARA, 0x0600321b);
1174 urtw_write16_m(sc, 0x1ec, 0x800); /* RX MAX SIZE */
1180 urtw_adapter_start(struct urtw_softc *sc)
1184 error = urtw_reset(sc);
1188 urtw_write8_m(sc, URTW_ADDR_MAGIC1, 0);
1189 urtw_write8_m(sc, URTW_GPIO, 0);
1192 urtw_write8_m(sc, URTW_ADDR_MAGIC1, 4);
1193 error = urtw_led_ctl(sc, URTW_LED_CTL_POWER_ON);
1197 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
1200 /* applying MAC address again. */
1201 urtw_write32_m(sc, URTW_MAC0, ((uint32_t *)sc->sc_bssid)[0]);
1202 urtw_write16_m(sc, URTW_MAC4, ((uint32_t *)sc->sc_bssid)[1] & 0xffff);
1203 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
1207 error = urtw_update_msr(sc);
1211 urtw_write32_m(sc, URTW_INT_TIMEOUT, 0);
1212 urtw_write8_m(sc, URTW_WPA_CONFIG, 0);
1213 urtw_write8_m(sc, URTW_RATE_FALLBACK, URTW_RATE_FALLBACK_ENABLE | 0x1);
1214 error = urtw_set_rate(sc);
1218 error = sc->sc_rf_init(sc);
1221 if (sc->sc_rf_set_sens != NULL)
1222 sc->sc_rf_set_sens(sc, sc->sc_sens);
1224 /* XXX correct? to call write16 */
1225 urtw_write16_m(sc, URTW_PSR, 1);
1226 urtw_write16_m(sc, URTW_ADDR_MAGIC2, 0x10);
1227 urtw_write8_m(sc, URTW_TALLY_SEL, 0x80);
1228 urtw_write8_m(sc, URTW_ADDR_MAGIC3, 0x60);
1229 /* XXX correct? to call write16 */
1230 urtw_write16_m(sc, URTW_PSR, 0);
1231 urtw_write8_m(sc, URTW_ADDR_MAGIC1, 4);
1233 error = urtw_intr_enable(sc);
1242 urtw_set_mode(struct urtw_softc *sc, uint32_t mode)
1247 urtw_read8_m(sc, URTW_EPROM_CMD, &data);
1248 data = (data & ~URTW_EPROM_CMD_MASK) | (mode << URTW_EPROM_CMD_SHIFT);
1249 data = data & ~(URTW_EPROM_CS | URTW_EPROM_CK);
1250 urtw_write8_m(sc, URTW_EPROM_CMD, data);
1256 urtw_8187b_cmd_reset(struct urtw_softc *sc)
1262 /* XXX the code can be duplicate with urtw_reset(). */
1263 urtw_read8_m(sc, URTW_CMD, &data8);
1264 data8 = (data8 & 0x2) | URTW_CMD_RST;
1265 urtw_write8_m(sc, URTW_CMD, data8);
1267 for (i = 0; i < 20; i++) {
1268 usb_pause_mtx(&sc->sc_mtx, 2);
1269 urtw_read8_m(sc, URTW_CMD, &data8);
1270 if (!(data8 & URTW_CMD_RST))
1274 device_printf(sc->sc_dev, "reset timeout\n");
1282 urtw_do_request(struct urtw_softc *sc,
1283 struct usb_device_request *req, void *data)
1288 URTW_ASSERT_LOCKED(sc);
1291 err = usbd_do_request_flags(sc->sc_udev, &sc->sc_mtx,
1292 req, data, 0, NULL, 250 /* ms */);
1296 DPRINTF(sc, URTW_DEBUG_INIT,
1297 "Control request failed, %s (retrying)\n",
1299 usb_pause_mtx(&sc->sc_mtx, hz / 100);
1305 urtw_stop_locked(struct ifnet *ifp, int disable)
1307 struct urtw_softc *sc = ifp->if_softc;
1312 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
1314 error = urtw_intr_disable(sc);
1317 urtw_read8_m(sc, URTW_CMD, &data8);
1318 data8 &= ~(URTW_CMD_RX_ENABLE | URTW_CMD_TX_ENABLE);
1319 urtw_write8_m(sc, URTW_CMD, data8);
1321 error = sc->sc_rf_stop(sc);
1325 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
1328 urtw_read8_m(sc, URTW_CONFIG4, &data8);
1329 urtw_write8_m(sc, URTW_CONFIG4, data8 | URTW_CONFIG4_VCOOFF);
1330 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
1335 device_printf(sc->sc_dev, "failed to stop (%s)\n",
1336 usbd_errstr(error));
1338 usb_callout_stop(&sc->sc_led_ch);
1339 callout_stop(&sc->sc_watchdog_ch);
1341 urtw_abort_xfers(sc);
1345 urtw_stop(struct ifnet *ifp, int disable)
1347 struct urtw_softc *sc = ifp->if_softc;
1350 urtw_stop_locked(ifp, disable);
1355 urtw_abort_xfers(struct urtw_softc *sc)
1359 URTW_ASSERT_LOCKED(sc);
1361 max = (sc->sc_flags & URTW_RTL8187B) ? URTW_8187B_N_XFERS :
1364 /* abort any pending transfers */
1365 for (i = 0; i < max; i++)
1366 usbd_transfer_stop(sc->sc_xfer[i]);
1370 urtw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1372 struct urtw_softc *sc = ifp->if_softc;
1373 struct ieee80211com *ic = ifp->if_l2com;
1374 struct ifreq *ifr = (struct ifreq *) data;
1375 int error = 0, startall = 0;
1379 if (ifp->if_flags & IFF_UP) {
1380 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
1381 if ((ifp->if_flags ^ sc->sc_if_flags) &
1382 (IFF_ALLMULTI | IFF_PROMISC))
1385 urtw_init(ifp->if_softc);
1389 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1392 sc->sc_if_flags = ifp->if_flags;
1394 ieee80211_start_all(ic);
1397 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
1400 error = ether_ioctl(ifp, cmd, data);
1411 urtw_start(struct ifnet *ifp)
1413 struct urtw_data *bf;
1414 struct urtw_softc *sc = ifp->if_softc;
1415 struct ieee80211_node *ni;
1418 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
1423 IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
1426 bf = urtw_getbuf(sc);
1428 IFQ_DRV_PREPEND(&ifp->if_snd, m);
1432 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
1433 m->m_pkthdr.rcvif = NULL;
1435 if (urtw_tx_start(sc, ni, m, bf, URTW_PRIORITY_NORMAL) != 0) {
1437 STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
1438 ieee80211_free_node(ni);
1443 callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc);
1449 urtw_alloc_data_list(struct urtw_softc *sc, struct urtw_data data[],
1450 int ndata, int maxsz, int fillmbuf)
1454 for (i = 0; i < ndata; i++) {
1455 struct urtw_data *dp = &data[i];
1459 dp->m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
1460 if (dp->m == NULL) {
1461 device_printf(sc->sc_dev,
1462 "could not allocate rx mbuf\n");
1466 dp->buf = mtod(dp->m, uint8_t *);
1469 dp->buf = malloc(maxsz, M_USBDEV, M_WAITOK);
1470 if (dp->buf == NULL) {
1471 device_printf(sc->sc_dev,
1472 "could not allocate buffer\n");
1476 if (((unsigned long)dp->buf) % 4)
1477 device_printf(sc->sc_dev,
1478 "warn: unaligned buffer %p\n", dp->buf);
1485 fail: urtw_free_data_list(sc, data, ndata, fillmbuf);
1490 urtw_alloc_rx_data_list(struct urtw_softc *sc)
1494 error = urtw_alloc_data_list(sc,
1495 sc->sc_rx, URTW_RX_DATA_LIST_COUNT, MCLBYTES, 1 /* mbufs */);
1499 STAILQ_INIT(&sc->sc_rx_active);
1500 STAILQ_INIT(&sc->sc_rx_inactive);
1502 for (i = 0; i < URTW_RX_DATA_LIST_COUNT; i++)
1503 STAILQ_INSERT_HEAD(&sc->sc_rx_inactive, &sc->sc_rx[i], next);
1509 urtw_alloc_tx_data_list(struct urtw_softc *sc)
1513 error = urtw_alloc_data_list(sc,
1514 sc->sc_tx, URTW_TX_DATA_LIST_COUNT, URTW_TX_MAXSIZE,
1519 STAILQ_INIT(&sc->sc_tx_active);
1520 STAILQ_INIT(&sc->sc_tx_inactive);
1521 STAILQ_INIT(&sc->sc_tx_pending);
1523 for (i = 0; i < URTW_TX_DATA_LIST_COUNT; i++)
1524 STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, &sc->sc_tx[i],
1531 urtw_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
1532 const struct ieee80211_bpf_params *params)
1534 struct ieee80211com *ic = ni->ni_ic;
1535 struct ifnet *ifp = ic->ic_ifp;
1536 struct urtw_data *bf;
1537 struct urtw_softc *sc = ifp->if_softc;
1539 /* prevent management frames from being sent if we're not ready */
1540 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
1542 ieee80211_free_node(ni);
1546 bf = urtw_getbuf(sc);
1548 ieee80211_free_node(ni);
1551 return (ENOBUFS); /* XXX */
1555 if (urtw_tx_start(sc, ni, m, bf, URTW_PRIORITY_LOW) != 0) {
1556 ieee80211_free_node(ni);
1558 STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
1569 urtw_scan_start(struct ieee80211com *ic)
1572 /* XXX do nothing? */
1576 urtw_scan_end(struct ieee80211com *ic)
1579 /* XXX do nothing? */
1583 urtw_set_channel(struct ieee80211com *ic)
1585 struct urtw_softc *sc = ic->ic_ifp->if_softc;
1586 struct ifnet *ifp = sc->sc_ifp;
1587 uint32_t data, orig;
1591 * if the user set a channel explicitly using ifconfig(8) this function
1592 * can be called earlier than we're expected that in some cases the
1593 * initialization would be failed if setting a channel is called before
1594 * the init have done.
1596 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
1599 if (sc->sc_curchan != NULL && sc->sc_curchan == ic->ic_curchan)
1605 * during changing th channel we need to temporarily be disable
1608 urtw_read32_m(sc, URTW_TX_CONF, &orig);
1609 data = orig & ~URTW_TX_LOOPBACK_MASK;
1610 urtw_write32_m(sc, URTW_TX_CONF, data | URTW_TX_LOOPBACK_MAC);
1612 error = sc->sc_rf_set_chan(sc, ieee80211_chan2ieee(ic, ic->ic_curchan));
1615 usb_pause_mtx(&sc->sc_mtx, 10);
1616 urtw_write32_m(sc, URTW_TX_CONF, orig);
1618 urtw_write16_m(sc, URTW_ATIM_WND, 2);
1619 urtw_write16_m(sc, URTW_ATIM_TR_ITV, 100);
1620 urtw_write16_m(sc, URTW_BEACON_INTERVAL, 100);
1621 urtw_write16_m(sc, URTW_BEACON_INTERVAL_TIME, 100);
1626 sc->sc_curchan = ic->ic_curchan;
1629 device_printf(sc->sc_dev, "could not change the channel\n");
1633 urtw_update_mcast(struct ieee80211com *ic)
1636 /* XXX do nothing? */
1640 urtw_tx_start(struct urtw_softc *sc, struct ieee80211_node *ni, struct mbuf *m0,
1641 struct urtw_data *data, int prior)
1643 struct ifnet *ifp = sc->sc_ifp;
1644 struct ieee80211_frame *wh = mtod(m0, struct ieee80211_frame *);
1645 struct ieee80211_key *k;
1646 const struct ieee80211_txparam *tp;
1647 struct ieee80211com *ic = ifp->if_l2com;
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 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
1695 rate = tp->mgmtrate;
1697 tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)];
1698 /* for data frames */
1699 if (IEEE80211_IS_MULTICAST(wh->i_addr1))
1700 rate = tp->mcastrate;
1701 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
1702 rate = tp->ucastrate;
1704 rate = urtw_rtl2rate(sc->sc_currate);
1707 sc->sc_stats.txrates[sc->sc_currate]++;
1709 if (IEEE80211_IS_MULTICAST(wh->i_addr1))
1710 txdur = pkttime = urtw_compute_txtime(m0->m_pkthdr.len +
1711 IEEE80211_CRC_LEN, rate, 0, 0);
1713 acktime = urtw_compute_txtime(14, 2,0, 0);
1714 if ((m0->m_pkthdr.len + 4) > vap->iv_rtsthreshold) {
1717 rtstime = urtw_compute_txtime(URTW_ACKCTS_LEN, 2, 0, 0);
1718 ctstime = urtw_compute_txtime(14, 2, 0, 0);
1719 pkttime = urtw_compute_txtime(m0->m_pkthdr.len +
1720 IEEE80211_CRC_LEN, rate, 0, isshort);
1721 rtsdur = ctstime + pkttime + acktime +
1722 3 * URTW_ASIFS_TIME;
1723 txdur = rtstime + rtsdur;
1725 rtsenable = ctsenable = rtsdur = 0;
1726 pkttime = urtw_compute_txtime(m0->m_pkthdr.len +
1727 IEEE80211_CRC_LEN, rate, 0, isshort);
1728 txdur = pkttime + URTW_ASIFS_TIME + acktime;
1731 if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG)
1732 dur = urtw_compute_txtime(m0->m_pkthdr.len +
1733 IEEE80211_CRC_LEN, rate, 0, isshort) +
1734 3 * URTW_ASIFS_TIME +
1737 dur = URTW_ASIFS_TIME + acktime;
1739 *(uint16_t *)wh->i_dur = htole16(dur);
1741 xferlen = m0->m_pkthdr.len;
1742 xferlen += (sc->sc_flags & URTW_RTL8187B) ? (4 * 8) : (4 * 3);
1743 if ((0 == xferlen % 64) || (0 == xferlen % 512))
1746 memset(data->buf, 0, URTW_TX_MAXSIZE);
1747 flags = m0->m_pkthdr.len & 0xfff;
1748 flags |= URTW_TX_FLAG_NO_ENC;
1749 if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
1750 (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE) &&
1751 (sc->sc_preamble_mode == URTW_PREAMBLE_MODE_SHORT) &&
1752 (sc->sc_currate != 0))
1753 flags |= URTW_TX_FLAG_SPLCP;
1754 if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG)
1755 flags |= URTW_TX_FLAG_MOREFRAG;
1757 flags |= (sc->sc_currate & 0xf) << URTW_TX_FLAG_TXRATE_SHIFT;
1759 if (sc->sc_flags & URTW_RTL8187B) {
1760 struct urtw_8187b_txhdr *tx;
1762 tx = (struct urtw_8187b_txhdr *)data->buf;
1764 flags |= URTW_TX_FLAG_CTS;
1766 flags |= URTW_TX_FLAG_RTS;
1767 flags |= (urtw_rate2rtl(11) & 0xf) <<
1768 URTW_TX_FLAG_RTSRATE_SHIFT;
1769 tx->rtsdur = rtsdur;
1771 tx->flag = htole32(flags);
1773 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
1774 IEEE80211_FC0_TYPE_MGT &&
1775 (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) ==
1776 IEEE80211_FC0_SUBTYPE_PROBE_RESP)
1779 tx->retry = URTW_TX_MAXRETRY;
1780 m_copydata(m0, 0, m0->m_pkthdr.len, (uint8_t *)(tx + 1));
1782 struct urtw_8187l_txhdr *tx;
1784 tx = (struct urtw_8187l_txhdr *)data->buf;
1786 flags |= URTW_TX_FLAG_RTS;
1787 tx->rtsdur = rtsdur;
1789 flags |= (urtw_rate2rtl(11) & 0xf) << URTW_TX_FLAG_RTSRATE_SHIFT;
1790 tx->flag = htole32(flags);
1791 tx->retry = 3; /* CW minimum */
1792 tx->retry |= 7 << 4; /* CW maximum */
1793 tx->retry |= URTW_TX_MAXRETRY << 8; /* retry limitation */
1794 m_copydata(m0, 0, m0->m_pkthdr.len, (uint8_t *)(tx + 1));
1797 data->buflen = xferlen;
1801 if (sc->sc_flags & URTW_RTL8187B) {
1802 switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) {
1803 case IEEE80211_FC0_TYPE_CTL:
1804 case IEEE80211_FC0_TYPE_MGT:
1805 xfer = sc->sc_xfer[URTW_8187B_BULK_TX_EP12];
1808 KASSERT(M_WME_GETAC(m0) < URTW_8187B_TXPIPE_MAX,
1809 ("unsupported WME pipe %d", M_WME_GETAC(m0)));
1810 xfer = rtl8187b_pipes[M_WME_GETAC(m0)];
1814 xfer = (prior == URTW_PRIORITY_LOW) ?
1815 sc->sc_xfer[URTW_8187L_BULK_TX_LOW] :
1816 sc->sc_xfer[URTW_8187L_BULK_TX_NORMAL];
1818 STAILQ_INSERT_TAIL(&sc->sc_tx_pending, data, next);
1819 usbd_transfer_start(xfer);
1821 error = urtw_led_ctl(sc, URTW_LED_CTL_TX);
1823 device_printf(sc->sc_dev, "could not control LED (%d)\n",
1829 urtw_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
1831 struct ieee80211com *ic = vap->iv_ic;
1832 struct urtw_softc *sc = ic->ic_ifp->if_softc;
1833 struct urtw_vap *uvp = URTW_VAP(vap);
1834 struct ieee80211_node *ni;
1835 usb_error_t error = 0;
1837 DPRINTF(sc, URTW_DEBUG_STATE, "%s: %s -> %s\n", __func__,
1838 ieee80211_state_name[vap->iv_state],
1839 ieee80211_state_name[nstate]);
1841 sc->sc_state = nstate;
1843 IEEE80211_UNLOCK(ic);
1845 usb_callout_stop(&sc->sc_led_ch);
1846 callout_stop(&sc->sc_watchdog_ch);
1849 case IEEE80211_S_INIT:
1850 case IEEE80211_S_SCAN:
1851 case IEEE80211_S_AUTH:
1852 case IEEE80211_S_ASSOC:
1854 case IEEE80211_S_RUN:
1855 ni = ieee80211_ref_node(vap->iv_bss);
1856 /* setting bssid. */
1857 urtw_write32_m(sc, URTW_BSSID, ((uint32_t *)ni->ni_bssid)[0]);
1858 urtw_write16_m(sc, URTW_BSSID + 4,
1859 ((uint16_t *)ni->ni_bssid)[2]);
1860 urtw_update_msr(sc);
1861 /* XXX maybe the below would be incorrect. */
1862 urtw_write16_m(sc, URTW_ATIM_WND, 2);
1863 urtw_write16_m(sc, URTW_ATIM_TR_ITV, 100);
1864 urtw_write16_m(sc, URTW_BEACON_INTERVAL, 0x64);
1865 urtw_write16_m(sc, URTW_BEACON_INTERVAL_TIME, 100);
1866 error = urtw_led_ctl(sc, URTW_LED_CTL_LINK);
1868 device_printf(sc->sc_dev,
1869 "could not control LED (%d)\n", error);
1870 ieee80211_free_node(ni);
1878 return (uvp->newstate(vap, nstate, arg));
1882 urtw_watchdog(void *arg)
1884 struct urtw_softc *sc = arg;
1885 struct ifnet *ifp = sc->sc_ifp;
1887 if (sc->sc_txtimer > 0) {
1888 if (--sc->sc_txtimer == 0) {
1889 device_printf(sc->sc_dev, "device timeout\n");
1893 callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc);
1898 urtw_set_multi(void *arg)
1900 struct urtw_softc *sc = arg;
1901 struct ifnet *ifp = sc->sc_ifp;
1903 if (!(ifp->if_flags & IFF_UP))
1907 * XXX don't know how to set a device. Lack of docs. Just try to set
1908 * IFF_ALLMULTI flag here.
1910 ifp->if_flags |= IFF_ALLMULTI;
1914 urtw_set_rate(struct urtw_softc *sc)
1916 int i, basic_rate, min_rr_rate, max_rr_rate;
1920 basic_rate = urtw_rate2rtl(48);
1921 min_rr_rate = urtw_rate2rtl(12);
1922 max_rr_rate = urtw_rate2rtl(48);
1924 urtw_write8_m(sc, URTW_RESP_RATE,
1925 max_rr_rate << URTW_RESP_MAX_RATE_SHIFT |
1926 min_rr_rate << URTW_RESP_MIN_RATE_SHIFT);
1928 urtw_read16_m(sc, URTW_BRSR, &data);
1929 data &= ~URTW_BRSR_MBR_8185;
1931 for (i = 0; i <= basic_rate; i++)
1934 urtw_write16_m(sc, URTW_BRSR, data);
1940 urtw_rate2rtl(int rate)
1944 for (i = 0; i < nitems(urtw_ratetable); i++) {
1945 if (rate == urtw_ratetable[i].reg)
1946 return urtw_ratetable[i].val;
1953 urtw_rtl2rate(int rate)
1957 for (i = 0; i < nitems(urtw_ratetable); i++) {
1958 if (rate == urtw_ratetable[i].val)
1959 return urtw_ratetable[i].reg;
1966 urtw_update_msr(struct urtw_softc *sc)
1968 struct ifnet *ifp = sc->sc_ifp;
1969 struct ieee80211com *ic = ifp->if_l2com;
1973 urtw_read8_m(sc, URTW_MSR, &data);
1974 data &= ~URTW_MSR_LINK_MASK;
1976 if (sc->sc_state == IEEE80211_S_RUN) {
1977 switch (ic->ic_opmode) {
1978 case IEEE80211_M_STA:
1979 case IEEE80211_M_MONITOR:
1980 data |= URTW_MSR_LINK_STA;
1981 if (sc->sc_flags & URTW_RTL8187B)
1982 data |= URTW_MSR_LINK_ENEDCA;
1984 case IEEE80211_M_IBSS:
1985 data |= URTW_MSR_LINK_ADHOC;
1987 case IEEE80211_M_HOSTAP:
1988 data |= URTW_MSR_LINK_HOSTAP;
1991 panic("unsupported operation mode 0x%x\n",
1996 data |= URTW_MSR_LINK_NONE;
1998 urtw_write8_m(sc, URTW_MSR, data);
2004 urtw_read8_c(struct urtw_softc *sc, int val, uint8_t *data)
2006 struct usb_device_request req;
2009 URTW_ASSERT_LOCKED(sc);
2011 req.bmRequestType = UT_READ_VENDOR_DEVICE;
2012 req.bRequest = URTW_8187_GETREGS_REQ;
2013 USETW(req.wValue, (val & 0xff) | 0xff00);
2014 USETW(req.wIndex, (val >> 8) & 0x3);
2015 USETW(req.wLength, sizeof(uint8_t));
2017 error = urtw_do_request(sc, &req, data);
2022 urtw_read16_c(struct urtw_softc *sc, int val, uint16_t *data)
2024 struct usb_device_request req;
2027 URTW_ASSERT_LOCKED(sc);
2029 req.bmRequestType = UT_READ_VENDOR_DEVICE;
2030 req.bRequest = URTW_8187_GETREGS_REQ;
2031 USETW(req.wValue, (val & 0xff) | 0xff00);
2032 USETW(req.wIndex, (val >> 8) & 0x3);
2033 USETW(req.wLength, sizeof(uint16_t));
2035 error = urtw_do_request(sc, &req, data);
2040 urtw_read32_c(struct urtw_softc *sc, int val, uint32_t *data)
2042 struct usb_device_request req;
2045 URTW_ASSERT_LOCKED(sc);
2047 req.bmRequestType = UT_READ_VENDOR_DEVICE;
2048 req.bRequest = URTW_8187_GETREGS_REQ;
2049 USETW(req.wValue, (val & 0xff) | 0xff00);
2050 USETW(req.wIndex, (val >> 8) & 0x3);
2051 USETW(req.wLength, sizeof(uint32_t));
2053 error = urtw_do_request(sc, &req, data);
2058 urtw_write8_c(struct urtw_softc *sc, int val, uint8_t data)
2060 struct usb_device_request req;
2062 URTW_ASSERT_LOCKED(sc);
2064 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
2065 req.bRequest = URTW_8187_SETREGS_REQ;
2066 USETW(req.wValue, (val & 0xff) | 0xff00);
2067 USETW(req.wIndex, (val >> 8) & 0x3);
2068 USETW(req.wLength, sizeof(uint8_t));
2070 return (urtw_do_request(sc, &req, &data));
2074 urtw_write16_c(struct urtw_softc *sc, int val, uint16_t data)
2076 struct usb_device_request req;
2078 URTW_ASSERT_LOCKED(sc);
2080 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
2081 req.bRequest = URTW_8187_SETREGS_REQ;
2082 USETW(req.wValue, (val & 0xff) | 0xff00);
2083 USETW(req.wIndex, (val >> 8) & 0x3);
2084 USETW(req.wLength, sizeof(uint16_t));
2086 return (urtw_do_request(sc, &req, &data));
2090 urtw_write32_c(struct urtw_softc *sc, int val, uint32_t data)
2092 struct usb_device_request req;
2094 URTW_ASSERT_LOCKED(sc);
2096 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
2097 req.bRequest = URTW_8187_SETREGS_REQ;
2098 USETW(req.wValue, (val & 0xff) | 0xff00);
2099 USETW(req.wIndex, (val >> 8) & 0x3);
2100 USETW(req.wLength, sizeof(uint32_t));
2102 return (urtw_do_request(sc, &req, &data));
2106 urtw_get_macaddr(struct urtw_softc *sc)
2111 error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR, &data);
2114 sc->sc_bssid[0] = data & 0xff;
2115 sc->sc_bssid[1] = (data & 0xff00) >> 8;
2116 error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR + 1, &data);
2119 sc->sc_bssid[2] = data & 0xff;
2120 sc->sc_bssid[3] = (data & 0xff00) >> 8;
2121 error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR + 2, &data);
2124 sc->sc_bssid[4] = data & 0xff;
2125 sc->sc_bssid[5] = (data & 0xff00) >> 8;
2131 urtw_eprom_read32(struct urtw_softc *sc, uint32_t addr, uint32_t *data)
2133 #define URTW_READCMD_LEN 3
2135 int16_t addrstr[8], data16, readcmd[] = { 1, 1, 0 };
2138 /* NB: make sure the buffer is initialized */
2141 /* enable EPROM programming */
2142 urtw_write8_m(sc, URTW_EPROM_CMD, URTW_EPROM_CMD_PROGRAM_MODE);
2143 DELAY(URTW_EPROM_DELAY);
2145 error = urtw_eprom_cs(sc, URTW_EPROM_ENABLE);
2148 error = urtw_eprom_ck(sc);
2151 error = urtw_eprom_sendbits(sc, readcmd, URTW_READCMD_LEN);
2154 if (sc->sc_epromtype == URTW_EEPROM_93C56) {
2156 addrstr[0] = addr & (1 << 7);
2157 addrstr[1] = addr & (1 << 6);
2158 addrstr[2] = addr & (1 << 5);
2159 addrstr[3] = addr & (1 << 4);
2160 addrstr[4] = addr & (1 << 3);
2161 addrstr[5] = addr & (1 << 2);
2162 addrstr[6] = addr & (1 << 1);
2163 addrstr[7] = addr & (1 << 0);
2166 addrstr[0] = addr & (1 << 5);
2167 addrstr[1] = addr & (1 << 4);
2168 addrstr[2] = addr & (1 << 3);
2169 addrstr[3] = addr & (1 << 2);
2170 addrstr[4] = addr & (1 << 1);
2171 addrstr[5] = addr & (1 << 0);
2173 error = urtw_eprom_sendbits(sc, addrstr, addrlen);
2177 error = urtw_eprom_writebit(sc, 0);
2181 for (i = 0; i < 16; i++) {
2182 error = urtw_eprom_ck(sc);
2185 error = urtw_eprom_readbit(sc, &data16);
2189 (*data) |= (data16 << (15 - i));
2192 error = urtw_eprom_cs(sc, URTW_EPROM_DISABLE);
2195 error = urtw_eprom_ck(sc);
2199 /* now disable EPROM programming */
2200 urtw_write8_m(sc, URTW_EPROM_CMD, URTW_EPROM_CMD_NORMAL_MODE);
2203 #undef URTW_READCMD_LEN
2207 urtw_eprom_cs(struct urtw_softc *sc, int able)
2212 urtw_read8_m(sc, URTW_EPROM_CMD, &data);
2213 if (able == URTW_EPROM_ENABLE)
2214 urtw_write8_m(sc, URTW_EPROM_CMD, data | URTW_EPROM_CS);
2216 urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_CS);
2217 DELAY(URTW_EPROM_DELAY);
2223 urtw_eprom_ck(struct urtw_softc *sc)
2229 urtw_read8_m(sc, URTW_EPROM_CMD, &data);
2230 urtw_write8_m(sc, URTW_EPROM_CMD, data | URTW_EPROM_CK);
2231 DELAY(URTW_EPROM_DELAY);
2233 urtw_read8_m(sc, URTW_EPROM_CMD, &data);
2234 urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_CK);
2235 DELAY(URTW_EPROM_DELAY);
2241 urtw_eprom_readbit(struct urtw_softc *sc, int16_t *data)
2246 urtw_read8_m(sc, URTW_EPROM_CMD, &data8);
2247 *data = (data8 & URTW_EPROM_READBIT) ? 1 : 0;
2248 DELAY(URTW_EPROM_DELAY);
2255 urtw_eprom_writebit(struct urtw_softc *sc, int16_t bit)
2260 urtw_read8_m(sc, URTW_EPROM_CMD, &data);
2262 urtw_write8_m(sc, URTW_EPROM_CMD, data | URTW_EPROM_WRITEBIT);
2264 urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_WRITEBIT);
2265 DELAY(URTW_EPROM_DELAY);
2271 urtw_eprom_sendbits(struct urtw_softc *sc, int16_t *buf, int buflen)
2274 usb_error_t error = 0;
2276 for (i = 0; i < buflen; i++) {
2277 error = urtw_eprom_writebit(sc, buf[i]);
2280 error = urtw_eprom_ck(sc);
2290 urtw_get_txpwr(struct urtw_softc *sc)
2296 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW_BASE, &data);
2299 sc->sc_txpwr_cck_base = data & 0xf;
2300 sc->sc_txpwr_ofdm_base = (data >> 4) & 0xf;
2302 for (i = 1, j = 0; i < 6; i += 2, j++) {
2303 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW0 + j, &data);
2306 sc->sc_txpwr_cck[i] = data & 0xf;
2307 sc->sc_txpwr_cck[i + 1] = (data & 0xf00) >> 8;
2308 sc->sc_txpwr_ofdm[i] = (data & 0xf0) >> 4;
2309 sc->sc_txpwr_ofdm[i + 1] = (data & 0xf000) >> 12;
2311 for (i = 1, j = 0; i < 4; i += 2, j++) {
2312 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW1 + j, &data);
2315 sc->sc_txpwr_cck[i + 6] = data & 0xf;
2316 sc->sc_txpwr_cck[i + 6 + 1] = (data & 0xf00) >> 8;
2317 sc->sc_txpwr_ofdm[i + 6] = (data & 0xf0) >> 4;
2318 sc->sc_txpwr_ofdm[i + 6 + 1] = (data & 0xf000) >> 12;
2320 if (sc->sc_flags & URTW_RTL8187B) {
2321 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW2, &data);
2324 sc->sc_txpwr_cck[1 + 6 + 4] = data & 0xf;
2325 sc->sc_txpwr_ofdm[1 + 6 + 4] = (data & 0xf0) >> 4;
2326 error = urtw_eprom_read32(sc, 0x0a, &data);
2329 sc->sc_txpwr_cck[2 + 6 + 4] = data & 0xf;
2330 sc->sc_txpwr_ofdm[2 + 6 + 4] = (data & 0xf0) >> 4;
2331 error = urtw_eprom_read32(sc, 0x1c, &data);
2334 sc->sc_txpwr_cck[3 + 6 + 4] = data & 0xf;
2335 sc->sc_txpwr_cck[3 + 6 + 4 + 1] = (data & 0xf00) >> 8;
2336 sc->sc_txpwr_ofdm[3 + 6 + 4] = (data & 0xf0) >> 4;
2337 sc->sc_txpwr_ofdm[3 + 6 + 4 + 1] = (data & 0xf000) >> 12;
2339 for (i = 1, j = 0; i < 4; i += 2, j++) {
2340 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW2 + j,
2344 sc->sc_txpwr_cck[i + 6 + 4] = data & 0xf;
2345 sc->sc_txpwr_cck[i + 6 + 4 + 1] = (data & 0xf00) >> 8;
2346 sc->sc_txpwr_ofdm[i + 6 + 4] = (data & 0xf0) >> 4;
2347 sc->sc_txpwr_ofdm[i + 6 + 4 + 1] = (data & 0xf000) >> 12;
2356 urtw_get_rfchip(struct urtw_softc *sc)
2363 if (sc->sc_flags & URTW_RTL8187B) {
2364 urtw_read8_m(sc, 0xe1, &data8);
2367 sc->sc_flags |= URTW_RTL8187B_REV_B;
2370 sc->sc_flags |= URTW_RTL8187B_REV_D;
2373 sc->sc_flags |= URTW_RTL8187B_REV_E;
2376 device_printf(sc->sc_dev, "unknown type: %#x\n", data8);
2377 sc->sc_flags |= URTW_RTL8187B_REV_B;
2381 urtw_read32_m(sc, URTW_TX_CONF, &data);
2382 switch (data & URTW_TX_HWMASK) {
2383 case URTW_TX_R8187vD_B:
2384 sc->sc_flags |= URTW_RTL8187B;
2386 case URTW_TX_R8187vD:
2389 device_printf(sc->sc_dev, "unknown RTL8187L type: %#x\n",
2390 data & URTW_TX_HWMASK);
2395 error = urtw_eprom_read32(sc, URTW_EPROM_RFCHIPID, &data);
2398 switch (data & 0xff) {
2399 case URTW_EPROM_RFCHIPID_RTL8225U:
2400 error = urtw_8225_isv2(sc, &ret);
2404 sc->sc_rf_init = urtw_8225_rf_init;
2405 sc->sc_rf_set_sens = urtw_8225_rf_set_sens;
2406 sc->sc_rf_set_chan = urtw_8225_rf_set_chan;
2407 sc->sc_rf_stop = urtw_8225_rf_stop;
2409 sc->sc_rf_init = urtw_8225v2_rf_init;
2410 sc->sc_rf_set_chan = urtw_8225v2_rf_set_chan;
2411 sc->sc_rf_stop = urtw_8225_rf_stop;
2413 sc->sc_max_sens = URTW_8225_RF_MAX_SENS;
2414 sc->sc_sens = URTW_8225_RF_DEF_SENS;
2416 case URTW_EPROM_RFCHIPID_RTL8225Z2:
2417 sc->sc_rf_init = urtw_8225v2b_rf_init;
2418 sc->sc_rf_set_chan = urtw_8225v2b_rf_set_chan;
2419 sc->sc_max_sens = URTW_8225_RF_MAX_SENS;
2420 sc->sc_sens = URTW_8225_RF_DEF_SENS;
2421 sc->sc_rf_stop = urtw_8225_rf_stop;
2424 panic("unsupported RF chip %d\n", data & 0xff);
2428 device_printf(sc->sc_dev, "%s rf %s hwrev %s\n",
2429 (sc->sc_flags & URTW_RTL8187B) ? "rtl8187b" : "rtl8187l",
2430 ((data & 0xff) == URTW_EPROM_RFCHIPID_RTL8225U) ? "rtl8225u" :
2432 (sc->sc_flags & URTW_RTL8187B) ? ((data8 == 0) ? "b" :
2433 (data8 == 1) ? "d" : "e") : "none");
2441 urtw_led_init(struct urtw_softc *sc)
2446 urtw_read8_m(sc, URTW_PSR, &sc->sc_psr);
2447 error = urtw_eprom_read32(sc, URTW_EPROM_SWREV, &rev);
2451 switch (rev & URTW_EPROM_CID_MASK) {
2452 case URTW_EPROM_CID_ALPHA0:
2453 sc->sc_strategy = URTW_SW_LED_MODE1;
2455 case URTW_EPROM_CID_SERCOMM_PS:
2456 sc->sc_strategy = URTW_SW_LED_MODE3;
2458 case URTW_EPROM_CID_HW_LED:
2459 sc->sc_strategy = URTW_HW_LED;
2461 case URTW_EPROM_CID_RSVD0:
2462 case URTW_EPROM_CID_RSVD1:
2464 sc->sc_strategy = URTW_SW_LED_MODE0;
2468 sc->sc_gpio_ledpin = URTW_LED_PIN_GPIO0;
2476 urtw_8225_rf_init(struct urtw_softc *sc)
2482 error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
2486 error = urtw_8225_usb_init(sc);
2490 urtw_write32_m(sc, URTW_RF_TIMING, 0x000a8008);
2491 urtw_read16_m(sc, URTW_BRSR, &data); /* XXX ??? */
2492 urtw_write16_m(sc, URTW_BRSR, 0xffff);
2493 urtw_write32_m(sc, URTW_RF_PARA, 0x100044);
2495 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
2498 urtw_write8_m(sc, URTW_CONFIG3, 0x44);
2499 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
2503 error = urtw_8185_rf_pins_enable(sc);
2506 usb_pause_mtx(&sc->sc_mtx, 1000);
2508 for (i = 0; i < nitems(urtw_8225_rf_part1); i++) {
2509 urtw_8225_write(sc, urtw_8225_rf_part1[i].reg,
2510 urtw_8225_rf_part1[i].val);
2511 usb_pause_mtx(&sc->sc_mtx, 1);
2513 usb_pause_mtx(&sc->sc_mtx, 100);
2515 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC1);
2516 usb_pause_mtx(&sc->sc_mtx, 200);
2518 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC2);
2519 usb_pause_mtx(&sc->sc_mtx, 200);
2521 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC3);
2523 for (i = 0; i < 95; i++) {
2524 urtw_8225_write(sc, URTW_8225_ADDR_1_MAGIC, (uint8_t)(i + 1));
2525 urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC, urtw_8225_rxgain[i]);
2529 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC4);
2531 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC5);
2533 for (i = 0; i < 128; i++) {
2534 urtw_8187_write_phy_ofdm(sc, 0xb, urtw_8225_agc[i]);
2535 usb_pause_mtx(&sc->sc_mtx, 1);
2536 urtw_8187_write_phy_ofdm(sc, 0xa, (uint8_t)i + 0x80);
2537 usb_pause_mtx(&sc->sc_mtx, 1);
2540 for (i = 0; i < nitems(urtw_8225_rf_part2); i++) {
2541 urtw_8187_write_phy_ofdm(sc, urtw_8225_rf_part2[i].reg,
2542 urtw_8225_rf_part2[i].val);
2543 usb_pause_mtx(&sc->sc_mtx, 1);
2546 error = urtw_8225_setgain(sc, 4);
2550 for (i = 0; i < nitems(urtw_8225_rf_part3); i++) {
2551 urtw_8187_write_phy_cck(sc, urtw_8225_rf_part3[i].reg,
2552 urtw_8225_rf_part3[i].val);
2553 usb_pause_mtx(&sc->sc_mtx, 1);
2556 urtw_write8_m(sc, URTW_TESTR, 0x0d);
2558 error = urtw_8225_set_txpwrlvl(sc, 1);
2562 urtw_8187_write_phy_cck(sc, 0x10, 0x9b);
2563 usb_pause_mtx(&sc->sc_mtx, 1);
2564 urtw_8187_write_phy_ofdm(sc, 0x26, 0x90);
2565 usb_pause_mtx(&sc->sc_mtx, 1);
2567 /* TX ant A, 0x0 for B */
2568 error = urtw_8185_tx_antenna(sc, 0x3);
2571 urtw_write32_m(sc, URTW_HSSI_PARA, 0x3dc00002);
2573 error = urtw_8225_rf_set_chan(sc, 1);
2579 urtw_8185_rf_pins_enable(struct urtw_softc *sc)
2581 usb_error_t error = 0;
2583 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x1ff7);
2589 urtw_8185_tx_antenna(struct urtw_softc *sc, uint8_t ant)
2593 urtw_write8_m(sc, URTW_TX_ANTENNA, ant);
2594 usb_pause_mtx(&sc->sc_mtx, 1);
2600 urtw_8187_write_phy_ofdm_c(struct urtw_softc *sc, uint8_t addr, uint32_t data)
2604 return urtw_8187_write_phy(sc, addr, data);
2608 urtw_8187_write_phy_cck_c(struct urtw_softc *sc, uint8_t addr, uint32_t data)
2612 return urtw_8187_write_phy(sc, addr, data | 0x10000);
2616 urtw_8187_write_phy(struct urtw_softc *sc, uint8_t addr, uint32_t data)
2621 phyw = ((data << 8) | (addr | 0x80));
2622 urtw_write8_m(sc, URTW_PHY_MAGIC4, ((phyw & 0xff000000) >> 24));
2623 urtw_write8_m(sc, URTW_PHY_MAGIC3, ((phyw & 0x00ff0000) >> 16));
2624 urtw_write8_m(sc, URTW_PHY_MAGIC2, ((phyw & 0x0000ff00) >> 8));
2625 urtw_write8_m(sc, URTW_PHY_MAGIC1, ((phyw & 0x000000ff)));
2626 usb_pause_mtx(&sc->sc_mtx, 1);
2632 urtw_8225_setgain(struct urtw_softc *sc, int16_t gain)
2636 urtw_8187_write_phy_ofdm(sc, 0x0d, urtw_8225_gain[gain * 4]);
2637 urtw_8187_write_phy_ofdm(sc, 0x1b, urtw_8225_gain[gain * 4 + 2]);
2638 urtw_8187_write_phy_ofdm(sc, 0x1d, urtw_8225_gain[gain * 4 + 3]);
2639 urtw_8187_write_phy_ofdm(sc, 0x23, urtw_8225_gain[gain * 4 + 1]);
2645 urtw_8225_usb_init(struct urtw_softc *sc)
2650 urtw_write8_m(sc, URTW_RF_PINS_SELECT + 1, 0);
2651 urtw_write8_m(sc, URTW_GPIO, 0);
2652 error = urtw_read8e(sc, 0x53, &data);
2655 error = urtw_write8e(sc, 0x53, data | (1 << 7));
2658 urtw_write8_m(sc, URTW_RF_PINS_SELECT + 1, 4);
2659 urtw_write8_m(sc, URTW_GPIO, 0x20);
2660 urtw_write8_m(sc, URTW_GP_ENABLE, 0);
2662 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, 0x80);
2663 urtw_write16_m(sc, URTW_RF_PINS_SELECT, 0x80);
2664 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x80);
2666 usb_pause_mtx(&sc->sc_mtx, 500);
2672 urtw_8225_write_c(struct urtw_softc *sc, uint8_t addr, uint16_t data)
2674 uint16_t d80, d82, d84;
2677 urtw_read16_m(sc, URTW_RF_PINS_OUTPUT, &d80);
2678 d80 &= URTW_RF_PINS_MAGIC1;
2679 urtw_read16_m(sc, URTW_RF_PINS_ENABLE, &d82);
2680 urtw_read16_m(sc, URTW_RF_PINS_SELECT, &d84);
2681 d84 &= URTW_RF_PINS_MAGIC2;
2682 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, d82 | URTW_RF_PINS_MAGIC3);
2683 urtw_write16_m(sc, URTW_RF_PINS_SELECT, d84 | URTW_RF_PINS_MAGIC3);
2686 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80 | URTW_BB_HOST_BANG_EN);
2688 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80);
2691 error = urtw_8225_write_s16(sc, addr, 0x8225, &data);
2695 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80 | URTW_BB_HOST_BANG_EN);
2697 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80 | URTW_BB_HOST_BANG_EN);
2698 urtw_write16_m(sc, URTW_RF_PINS_SELECT, d84);
2699 usb_pause_mtx(&sc->sc_mtx, 2);
2704 /* XXX why we should allocalte memory buffer instead of using memory stack? */
2706 urtw_8225_write_s16(struct urtw_softc *sc, uint8_t addr, int index,
2711 struct usb_device_request *req;
2712 usb_error_t error = 0;
2715 req = (usb_device_request_t *)malloc(sizeof(usb_device_request_t),
2716 M_80211_VAP, M_WAITOK | M_ZERO);
2718 device_printf(sc->sc_dev, "could not allocate a memory\n");
2721 buf = (uint8_t *)malloc(2, M_80211_VAP, M_WAITOK | M_ZERO);
2723 device_printf(sc->sc_dev, "could not allocate a memory\n");
2727 req->bmRequestType = UT_WRITE_VENDOR_DEVICE;
2728 req->bRequest = URTW_8187_SETREGS_REQ;
2729 USETW(req->wValue, addr);
2730 USETW(req->wIndex, index);
2731 USETW(req->wLength, sizeof(uint16_t));
2732 buf[0] = (data16 & 0x00ff);
2733 buf[1] = (data16 & 0xff00) >> 8;
2735 error = urtw_do_request(sc, req, buf);
2737 free(buf, M_80211_VAP);
2738 fail1: free(req, M_80211_VAP);
2739 fail0: return (error);
2743 urtw_8225_rf_set_chan(struct urtw_softc *sc, int chan)
2747 error = urtw_8225_set_txpwrlvl(sc, chan);
2750 urtw_8225_write(sc, URTW_8225_ADDR_7_MAGIC, urtw_8225_channel[chan]);
2751 usb_pause_mtx(&sc->sc_mtx, 10);
2757 urtw_8225_rf_set_sens(struct urtw_softc *sc, int sens)
2761 if (sens < 0 || sens > 6)
2766 URTW_8225_ADDR_C_MAGIC, URTW_8225_ADDR_C_DATA_MAGIC1);
2769 URTW_8225_ADDR_C_MAGIC, URTW_8225_ADDR_C_DATA_MAGIC2);
2772 error = urtw_8225_setgain(sc, sens);
2776 urtw_8187_write_phy_cck(sc, 0x41, urtw_8225_threshold[sens]);
2783 urtw_8225_set_txpwrlvl(struct urtw_softc *sc, int chan)
2786 uint8_t *cck_pwltable;
2787 uint8_t cck_pwrlvl_max, ofdm_pwrlvl_min, ofdm_pwrlvl_max;
2788 uint8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
2789 uint8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
2792 cck_pwrlvl_max = 11;
2793 ofdm_pwrlvl_max = 25; /* 12 -> 25 */
2794 ofdm_pwrlvl_min = 10;
2796 /* CCK power setting */
2797 cck_pwrlvl = (cck_pwrlvl > cck_pwrlvl_max) ? cck_pwrlvl_max : cck_pwrlvl;
2798 idx = cck_pwrlvl % 6;
2799 set = cck_pwrlvl / 6;
2800 cck_pwltable = (chan == 14) ? urtw_8225_txpwr_cck_ch14 :
2801 urtw_8225_txpwr_cck;
2803 urtw_write8_m(sc, URTW_TX_GAIN_CCK,
2804 urtw_8225_tx_gain_cck_ofdm[set] >> 1);
2805 for (i = 0; i < 8; i++) {
2806 urtw_8187_write_phy_cck(sc, 0x44 + i,
2807 cck_pwltable[idx * 8 + i]);
2809 usb_pause_mtx(&sc->sc_mtx, 1);
2811 /* OFDM power setting */
2812 ofdm_pwrlvl = (ofdm_pwrlvl > (ofdm_pwrlvl_max - ofdm_pwrlvl_min)) ?
2813 ofdm_pwrlvl_max : ofdm_pwrlvl + ofdm_pwrlvl_min;
2814 ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
2816 idx = ofdm_pwrlvl % 6;
2817 set = ofdm_pwrlvl / 6;
2819 error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
2822 urtw_8187_write_phy_ofdm(sc, 2, 0x42);
2823 urtw_8187_write_phy_ofdm(sc, 6, 0);
2824 urtw_8187_write_phy_ofdm(sc, 8, 0);
2826 urtw_write8_m(sc, URTW_TX_GAIN_OFDM,
2827 urtw_8225_tx_gain_cck_ofdm[set] >> 1);
2828 urtw_8187_write_phy_ofdm(sc, 0x5, urtw_8225_txpwr_ofdm[idx]);
2829 urtw_8187_write_phy_ofdm(sc, 0x7, urtw_8225_txpwr_ofdm[idx]);
2830 usb_pause_mtx(&sc->sc_mtx, 1);
2837 urtw_8225_rf_stop(struct urtw_softc *sc)
2842 urtw_8225_write(sc, 0x4, 0x1f);
2844 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
2848 urtw_read8_m(sc, URTW_CONFIG3, &data);
2849 urtw_write8_m(sc, URTW_CONFIG3, data | URTW_CONFIG3_ANAPARAM_WRITE);
2850 if (sc->sc_flags & URTW_RTL8187B) {
2851 urtw_write32_m(sc, URTW_ANAPARAM2,
2852 URTW_8187B_8225_ANAPARAM2_OFF);
2853 urtw_write32_m(sc, URTW_ANAPARAM, URTW_8187B_8225_ANAPARAM_OFF);
2854 urtw_write32_m(sc, URTW_ANAPARAM3,
2855 URTW_8187B_8225_ANAPARAM3_OFF);
2857 urtw_write32_m(sc, URTW_ANAPARAM2, URTW_8225_ANAPARAM2_OFF);
2858 urtw_write32_m(sc, URTW_ANAPARAM, URTW_8225_ANAPARAM_OFF);
2861 urtw_write8_m(sc, URTW_CONFIG3, data & ~URTW_CONFIG3_ANAPARAM_WRITE);
2862 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
2871 urtw_8225v2_rf_init(struct urtw_softc *sc)
2878 error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
2882 error = urtw_8225_usb_init(sc);
2886 urtw_write32_m(sc, URTW_RF_TIMING, 0x000a8008);
2887 urtw_read16_m(sc, URTW_BRSR, &data); /* XXX ??? */
2888 urtw_write16_m(sc, URTW_BRSR, 0xffff);
2889 urtw_write32_m(sc, URTW_RF_PARA, 0x100044);
2891 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
2894 urtw_write8_m(sc, URTW_CONFIG3, 0x44);
2895 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
2899 error = urtw_8185_rf_pins_enable(sc);
2903 usb_pause_mtx(&sc->sc_mtx, 500);
2905 for (i = 0; i < nitems(urtw_8225v2_rf_part1); i++) {
2906 urtw_8225_write(sc, urtw_8225v2_rf_part1[i].reg,
2907 urtw_8225v2_rf_part1[i].val);
2909 usb_pause_mtx(&sc->sc_mtx, 50);
2912 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC1);
2914 for (i = 0; i < 95; i++) {
2915 urtw_8225_write(sc, URTW_8225_ADDR_1_MAGIC, (uint8_t)(i + 1));
2916 urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC,
2917 urtw_8225v2_rxgain[i]);
2921 URTW_8225_ADDR_3_MAGIC, URTW_8225_ADDR_3_DATA_MAGIC1);
2923 URTW_8225_ADDR_5_MAGIC, URTW_8225_ADDR_5_DATA_MAGIC1);
2925 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC2);
2927 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC1);
2928 usb_pause_mtx(&sc->sc_mtx, 100);
2930 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC2);
2931 usb_pause_mtx(&sc->sc_mtx, 100);
2933 error = urtw_8225_read(sc, URTW_8225_ADDR_6_MAGIC, &data32);
2936 if (data32 != URTW_8225_ADDR_6_DATA_MAGIC1)
2937 device_printf(sc->sc_dev, "expect 0xe6!! (0x%x)\n", data32);
2938 if (!(data32 & URTW_8225_ADDR_6_DATA_MAGIC2)) {
2940 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC1);
2941 usb_pause_mtx(&sc->sc_mtx, 100);
2943 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC2);
2944 usb_pause_mtx(&sc->sc_mtx, 50);
2945 error = urtw_8225_read(sc, URTW_8225_ADDR_6_MAGIC, &data32);
2948 if (!(data32 & URTW_8225_ADDR_6_DATA_MAGIC2))
2949 device_printf(sc->sc_dev, "RF calibration failed\n");
2951 usb_pause_mtx(&sc->sc_mtx, 100);
2954 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC6);
2955 for (i = 0; i < 128; i++) {
2956 urtw_8187_write_phy_ofdm(sc, 0xb, urtw_8225_agc[i]);
2957 urtw_8187_write_phy_ofdm(sc, 0xa, (uint8_t)i + 0x80);
2960 for (i = 0; i < nitems(urtw_8225v2_rf_part2); i++) {
2961 urtw_8187_write_phy_ofdm(sc, urtw_8225v2_rf_part2[i].reg,
2962 urtw_8225v2_rf_part2[i].val);
2965 error = urtw_8225v2_setgain(sc, 4);
2969 for (i = 0; i < nitems(urtw_8225v2_rf_part3); i++) {
2970 urtw_8187_write_phy_cck(sc, urtw_8225v2_rf_part3[i].reg,
2971 urtw_8225v2_rf_part3[i].val);
2974 urtw_write8_m(sc, URTW_TESTR, 0x0d);
2976 error = urtw_8225v2_set_txpwrlvl(sc, 1);
2980 urtw_8187_write_phy_cck(sc, 0x10, 0x9b);
2981 urtw_8187_write_phy_ofdm(sc, 0x26, 0x90);
2983 /* TX ant A, 0x0 for B */
2984 error = urtw_8185_tx_antenna(sc, 0x3);
2987 urtw_write32_m(sc, URTW_HSSI_PARA, 0x3dc00002);
2989 error = urtw_8225_rf_set_chan(sc, 1);
2995 urtw_8225v2_rf_set_chan(struct urtw_softc *sc, int chan)
2999 error = urtw_8225v2_set_txpwrlvl(sc, chan);
3003 urtw_8225_write(sc, URTW_8225_ADDR_7_MAGIC, urtw_8225_channel[chan]);
3004 usb_pause_mtx(&sc->sc_mtx, 10);
3010 urtw_8225_read(struct urtw_softc *sc, uint8_t addr, uint32_t *data)
3014 uint8_t rlen = 12, wlen = 6;
3015 uint16_t o1, o2, o3, tmp;
3016 uint32_t d2w = ((uint32_t)(addr & 0x1f)) << 27;
3017 uint32_t mask = 0x80000000, value = 0;
3020 urtw_read16_m(sc, URTW_RF_PINS_OUTPUT, &o1);
3021 urtw_read16_m(sc, URTW_RF_PINS_ENABLE, &o2);
3022 urtw_read16_m(sc, URTW_RF_PINS_SELECT, &o3);
3023 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, o2 | URTW_RF_PINS_MAGIC4);
3024 urtw_write16_m(sc, URTW_RF_PINS_SELECT, o3 | URTW_RF_PINS_MAGIC4);
3025 o1 &= ~URTW_RF_PINS_MAGIC4;
3026 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1 | URTW_BB_HOST_BANG_EN);
3028 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1);
3031 for (i = 0; i < (wlen / 2); i++, mask = mask >> 1) {
3032 bit = ((d2w & mask) != 0) ? 1 : 0;
3034 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1);
3036 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
3037 URTW_BB_HOST_BANG_CLK);
3039 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
3040 URTW_BB_HOST_BANG_CLK);
3045 bit = ((d2w & mask) != 0) ? 1 : 0;
3046 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
3047 URTW_BB_HOST_BANG_CLK);
3049 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
3050 URTW_BB_HOST_BANG_CLK);
3052 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1);
3055 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 | URTW_BB_HOST_BANG_RW |
3056 URTW_BB_HOST_BANG_CLK);
3058 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 | URTW_BB_HOST_BANG_RW);
3060 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1 | URTW_BB_HOST_BANG_RW);
3064 for (i = 0; i < rlen; i++, mask = mask >> 1) {
3065 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
3066 o1 | URTW_BB_HOST_BANG_RW);
3068 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
3069 o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK);
3071 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
3072 o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK);
3074 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
3075 o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK);
3078 urtw_read16_m(sc, URTW_RF_PINS_INPUT, &tmp);
3079 value |= ((tmp & URTW_BB_HOST_BANG_CLK) ? mask : 0);
3080 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
3081 o1 | URTW_BB_HOST_BANG_RW);
3085 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1 | URTW_BB_HOST_BANG_EN |
3086 URTW_BB_HOST_BANG_RW);
3089 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, o2);
3090 urtw_write16_m(sc, URTW_RF_PINS_SELECT, o3);
3091 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, URTW_RF_PINS_OUTPUT_MAGIC1);
3101 urtw_8225v2_set_txpwrlvl(struct urtw_softc *sc, int chan)
3104 uint8_t *cck_pwrtable;
3105 uint8_t cck_pwrlvl_max = 15, ofdm_pwrlvl_max = 25, ofdm_pwrlvl_min = 10;
3106 uint8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
3107 uint8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
3110 /* CCK power setting */
3111 cck_pwrlvl = (cck_pwrlvl > cck_pwrlvl_max) ? cck_pwrlvl_max : cck_pwrlvl;
3112 cck_pwrlvl += sc->sc_txpwr_cck_base;
3113 cck_pwrlvl = (cck_pwrlvl > 35) ? 35 : cck_pwrlvl;
3114 cck_pwrtable = (chan == 14) ? urtw_8225v2_txpwr_cck_ch14 :
3115 urtw_8225v2_txpwr_cck;
3117 for (i = 0; i < 8; i++)
3118 urtw_8187_write_phy_cck(sc, 0x44 + i, cck_pwrtable[i]);
3120 urtw_write8_m(sc, URTW_TX_GAIN_CCK,
3121 urtw_8225v2_tx_gain_cck_ofdm[cck_pwrlvl]);
3122 usb_pause_mtx(&sc->sc_mtx, 1);
3124 /* OFDM power setting */
3125 ofdm_pwrlvl = (ofdm_pwrlvl > (ofdm_pwrlvl_max - ofdm_pwrlvl_min)) ?
3126 ofdm_pwrlvl_max : ofdm_pwrlvl + ofdm_pwrlvl_min;
3127 ofdm_pwrlvl += sc->sc_txpwr_ofdm_base;
3128 ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
3130 error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
3134 urtw_8187_write_phy_ofdm(sc, 2, 0x42);
3135 urtw_8187_write_phy_ofdm(sc, 5, 0x0);
3136 urtw_8187_write_phy_ofdm(sc, 6, 0x40);
3137 urtw_8187_write_phy_ofdm(sc, 7, 0x0);
3138 urtw_8187_write_phy_ofdm(sc, 8, 0x40);
3140 urtw_write8_m(sc, URTW_TX_GAIN_OFDM,
3141 urtw_8225v2_tx_gain_cck_ofdm[ofdm_pwrlvl]);
3142 usb_pause_mtx(&sc->sc_mtx, 1);
3148 urtw_8225v2_setgain(struct urtw_softc *sc, int16_t gain)
3154 gainp = urtw_8225v2_gain_bg;
3155 urtw_8187_write_phy_ofdm(sc, 0x0d, gainp[gain * 3]);
3156 usb_pause_mtx(&sc->sc_mtx, 1);
3157 urtw_8187_write_phy_ofdm(sc, 0x1b, gainp[gain * 3 + 1]);
3158 usb_pause_mtx(&sc->sc_mtx, 1);
3159 urtw_8187_write_phy_ofdm(sc, 0x1d, gainp[gain * 3 + 2]);
3160 usb_pause_mtx(&sc->sc_mtx, 1);
3161 urtw_8187_write_phy_ofdm(sc, 0x21, 0x17);
3162 usb_pause_mtx(&sc->sc_mtx, 1);
3168 urtw_8225_isv2(struct urtw_softc *sc, int *ret)
3175 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, URTW_RF_PINS_MAGIC5);
3176 urtw_write16_m(sc, URTW_RF_PINS_SELECT, URTW_RF_PINS_MAGIC5);
3177 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, URTW_RF_PINS_MAGIC5);
3178 usb_pause_mtx(&sc->sc_mtx, 500);
3180 urtw_8225_write(sc, URTW_8225_ADDR_0_MAGIC,
3181 URTW_8225_ADDR_0_DATA_MAGIC1);
3183 error = urtw_8225_read(sc, URTW_8225_ADDR_8_MAGIC, &data);
3186 if (data != URTW_8225_ADDR_8_DATA_MAGIC1)
3189 error = urtw_8225_read(sc, URTW_8225_ADDR_9_MAGIC, &data);
3192 if (data != URTW_8225_ADDR_9_DATA_MAGIC1)
3196 urtw_8225_write(sc, URTW_8225_ADDR_0_MAGIC,
3197 URTW_8225_ADDR_0_DATA_MAGIC2);
3203 urtw_8225v2b_rf_init(struct urtw_softc *sc)
3209 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3214 * initialize extra registers on 8187
3216 urtw_write16_m(sc, URTW_BRSR_8187B, 0xfff);
3219 urtw_read8_m(sc, URTW_CW_CONF, &data8);
3220 data8 |= URTW_CW_CONF_PERPACKET_RETRY;
3221 urtw_write8_m(sc, URTW_CW_CONF, data8);
3224 urtw_read8_m(sc, URTW_TX_AGC_CTL, &data8);
3225 data8 |= URTW_TX_AGC_CTL_PERPACKET_GAIN;
3226 urtw_write8_m(sc, URTW_TX_AGC_CTL, data8);
3228 /* Auto Rate Fallback Control */
3229 #define URTW_ARFR 0x1e0
3230 urtw_write16_m(sc, URTW_ARFR, 0xfff);
3231 urtw_read8_m(sc, URTW_RATE_FALLBACK, &data8);
3232 urtw_write8_m(sc, URTW_RATE_FALLBACK,
3233 data8 | URTW_RATE_FALLBACK_ENABLE);
3235 urtw_read8_m(sc, URTW_MSR, &data8);
3236 urtw_write8_m(sc, URTW_MSR, data8 & 0xf3);
3237 urtw_read8_m(sc, URTW_MSR, &data8);
3238 urtw_write8_m(sc, URTW_MSR, data8 | URTW_MSR_LINK_ENEDCA);
3239 urtw_write8_m(sc, URTW_ACM_CONTROL, sc->sc_acmctl);
3241 urtw_write16_m(sc, URTW_ATIM_WND, 2);
3242 urtw_write16_m(sc, URTW_BEACON_INTERVAL, 100);
3243 #define URTW_FEMR_FOR_8187B 0x1d4
3244 urtw_write16_m(sc, URTW_FEMR_FOR_8187B, 0xffff);
3247 urtw_read8_m(sc, URTW_CONFIG1, &data8);
3248 data8 = (data8 & 0x3f) | 0x80;
3249 urtw_write8_m(sc, URTW_CONFIG1, data8);
3251 /* applying MAC address again. */
3252 urtw_write32_m(sc, URTW_MAC0, ((uint32_t *)sc->sc_bssid)[0]);
3253 urtw_write16_m(sc, URTW_MAC4, ((uint32_t *)sc->sc_bssid)[1] & 0xffff);
3255 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3259 urtw_write8_m(sc, URTW_WPA_CONFIG, 0);
3264 for (i = 0; i < nitems(urtw_8225v2b_rf_part1); i++)
3265 urtw_write8_m(sc, urtw_8225v2b_rf_part1[i].reg,
3266 urtw_8225v2b_rf_part1[i].val);
3267 urtw_write16_m(sc, URTW_TID_AC_MAP, 0xfa50);
3268 urtw_write16_m(sc, URTW_INT_MIG, 0x0000);
3269 urtw_write32_m(sc, 0x1f0, 0);
3270 urtw_write32_m(sc, 0x1f4, 0);
3271 urtw_write8_m(sc, 0x1f8, 0);
3272 urtw_write32_m(sc, URTW_RF_TIMING, 0x4001);
3274 #define URTW_RFSW_CTRL 0x272
3275 urtw_write16_m(sc, URTW_RFSW_CTRL, 0x569a);
3280 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3283 urtw_read8_m(sc, URTW_CONFIG3, &data8);
3284 urtw_write8_m(sc, URTW_CONFIG3,
3285 data8 | URTW_CONFIG3_ANAPARAM_WRITE);
3287 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3291 /* setup RFE initial timing */
3292 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, 0x0480);
3293 urtw_write16_m(sc, URTW_RF_PINS_SELECT, 0x2488);
3294 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x1fff);
3295 usb_pause_mtx(&sc->sc_mtx, 1100);
3297 for (i = 0; i < nitems(urtw_8225v2b_rf_part0); i++) {
3298 urtw_8225_write(sc, urtw_8225v2b_rf_part0[i].reg,
3299 urtw_8225v2b_rf_part0[i].val);
3300 usb_pause_mtx(&sc->sc_mtx, 1);
3302 urtw_8225_write(sc, 0x00, 0x01b7);
3304 for (i = 0; i < 95; i++) {
3305 urtw_8225_write(sc, URTW_8225_ADDR_1_MAGIC, (uint8_t)(i + 1));
3306 usb_pause_mtx(&sc->sc_mtx, 1);
3307 urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC,
3308 urtw_8225v2b_rxgain[i]);
3309 usb_pause_mtx(&sc->sc_mtx, 1);
3312 urtw_8225_write(sc, URTW_8225_ADDR_3_MAGIC, 0x080);
3313 usb_pause_mtx(&sc->sc_mtx, 1);
3314 urtw_8225_write(sc, URTW_8225_ADDR_5_MAGIC, 0x004);
3315 usb_pause_mtx(&sc->sc_mtx, 1);
3316 urtw_8225_write(sc, URTW_8225_ADDR_0_MAGIC, 0x0b7);
3317 usb_pause_mtx(&sc->sc_mtx, 1);
3318 usb_pause_mtx(&sc->sc_mtx, 3000);
3319 urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC, 0xc4d);
3320 usb_pause_mtx(&sc->sc_mtx, 2000);
3321 urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC, 0x44d);
3322 usb_pause_mtx(&sc->sc_mtx, 1);
3323 urtw_8225_write(sc, URTW_8225_ADDR_0_MAGIC, 0x2bf);
3324 usb_pause_mtx(&sc->sc_mtx, 1);
3326 urtw_write8_m(sc, URTW_TX_GAIN_CCK, 0x03);
3327 urtw_write8_m(sc, URTW_TX_GAIN_OFDM, 0x07);
3328 urtw_write8_m(sc, URTW_TX_ANTENNA, 0x03);
3330 urtw_8187_write_phy_ofdm(sc, 0x80, 0x12);
3331 for (i = 0; i < 128; i++) {
3332 uint32_t addr, data;
3334 data = (urtw_8225z2_agc[i] << 8) | 0x0000008f;
3335 addr = ((i + 0x80) << 8) | 0x0000008e;
3337 urtw_8187_write_phy_ofdm(sc, data & 0x7f, (data >> 8) & 0xff);
3338 urtw_8187_write_phy_ofdm(sc, addr & 0x7f, (addr >> 8) & 0xff);
3339 urtw_8187_write_phy_ofdm(sc, 0x0e, 0x00);
3341 urtw_8187_write_phy_ofdm(sc, 0x80, 0x10);
3343 for (i = 0; i < nitems(urtw_8225v2b_rf_part2); i++)
3344 urtw_8187_write_phy_ofdm(sc, i, urtw_8225v2b_rf_part2[i].val);
3346 urtw_write32_m(sc, URTW_8187B_AC_VO, (7 << 12) | (3 << 8) | 0x1c);
3347 urtw_write32_m(sc, URTW_8187B_AC_VI, (7 << 12) | (3 << 8) | 0x1c);
3348 urtw_write32_m(sc, URTW_8187B_AC_BE, (7 << 12) | (3 << 8) | 0x1c);
3349 urtw_write32_m(sc, URTW_8187B_AC_BK, (7 << 12) | (3 << 8) | 0x1c);
3351 urtw_8187_write_phy_ofdm(sc, 0x97, 0x46);
3352 urtw_8187_write_phy_ofdm(sc, 0xa4, 0xb6);
3353 urtw_8187_write_phy_ofdm(sc, 0x85, 0xfc);
3354 urtw_8187_write_phy_cck(sc, 0xc1, 0x88);
3361 urtw_8225v2b_rf_set_chan(struct urtw_softc *sc, int chan)
3365 error = urtw_8225v2b_set_txpwrlvl(sc, chan);
3369 urtw_8225_write(sc, URTW_8225_ADDR_7_MAGIC, urtw_8225_channel[chan]);
3370 usb_pause_mtx(&sc->sc_mtx, 10);
3376 urtw_8225v2b_set_txpwrlvl(struct urtw_softc *sc, int chan)
3379 uint8_t *cck_pwrtable;
3380 uint8_t cck_pwrlvl_max = 15;
3381 uint8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
3382 uint8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
3385 /* CCK power setting */
3386 cck_pwrlvl = (cck_pwrlvl > cck_pwrlvl_max) ?
3387 ((sc->sc_flags & URTW_RTL8187B_REV_B) ? cck_pwrlvl_max : 22) :
3388 (cck_pwrlvl + ((sc->sc_flags & URTW_RTL8187B_REV_B) ? 0 : 7));
3389 cck_pwrlvl += sc->sc_txpwr_cck_base;
3390 cck_pwrlvl = (cck_pwrlvl > 35) ? 35 : cck_pwrlvl;
3391 cck_pwrtable = (chan == 14) ? urtw_8225v2b_txpwr_cck_ch14 :
3392 urtw_8225v2b_txpwr_cck;
3394 if (sc->sc_flags & URTW_RTL8187B_REV_B)
3395 cck_pwrtable += (cck_pwrlvl <= 6) ? 0 :
3396 ((cck_pwrlvl <= 11) ? 8 : 16);
3398 cck_pwrtable += (cck_pwrlvl <= 5) ? 0 :
3399 ((cck_pwrlvl <= 11) ? 8 : ((cck_pwrlvl <= 17) ? 16 : 24));
3401 for (i = 0; i < 8; i++)
3402 urtw_8187_write_phy_cck(sc, 0x44 + i, cck_pwrtable[i]);
3404 urtw_write8_m(sc, URTW_TX_GAIN_CCK,
3405 urtw_8225v2_tx_gain_cck_ofdm[cck_pwrlvl] << 1);
3406 usb_pause_mtx(&sc->sc_mtx, 1);
3408 /* OFDM power setting */
3409 ofdm_pwrlvl = (ofdm_pwrlvl > 15) ?
3410 ((sc->sc_flags & URTW_RTL8187B_REV_B) ? 17 : 25) :
3411 (ofdm_pwrlvl + ((sc->sc_flags & URTW_RTL8187B_REV_B) ? 2 : 10));
3412 ofdm_pwrlvl += sc->sc_txpwr_ofdm_base;
3413 ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
3415 urtw_write8_m(sc, URTW_TX_GAIN_OFDM,
3416 urtw_8225v2_tx_gain_cck_ofdm[ofdm_pwrlvl] << 1);
3418 if (sc->sc_flags & URTW_RTL8187B_REV_B) {
3419 if (ofdm_pwrlvl <= 11) {
3420 urtw_8187_write_phy_ofdm(sc, 0x87, 0x60);
3421 urtw_8187_write_phy_ofdm(sc, 0x89, 0x60);
3423 urtw_8187_write_phy_ofdm(sc, 0x87, 0x5c);
3424 urtw_8187_write_phy_ofdm(sc, 0x89, 0x5c);
3427 if (ofdm_pwrlvl <= 11) {
3428 urtw_8187_write_phy_ofdm(sc, 0x87, 0x5c);
3429 urtw_8187_write_phy_ofdm(sc, 0x89, 0x5c);
3430 } else if (ofdm_pwrlvl <= 17) {
3431 urtw_8187_write_phy_ofdm(sc, 0x87, 0x54);
3432 urtw_8187_write_phy_ofdm(sc, 0x89, 0x54);
3434 urtw_8187_write_phy_ofdm(sc, 0x87, 0x50);
3435 urtw_8187_write_phy_ofdm(sc, 0x89, 0x50);
3438 usb_pause_mtx(&sc->sc_mtx, 1);
3444 urtw_read8e(struct urtw_softc *sc, int val, uint8_t *data)
3446 struct usb_device_request req;
3449 req.bmRequestType = UT_READ_VENDOR_DEVICE;
3450 req.bRequest = URTW_8187_GETREGS_REQ;
3451 USETW(req.wValue, val | 0xfe00);
3452 USETW(req.wIndex, 0);
3453 USETW(req.wLength, sizeof(uint8_t));
3455 error = urtw_do_request(sc, &req, data);
3460 urtw_write8e(struct urtw_softc *sc, int val, uint8_t data)
3462 struct usb_device_request req;
3464 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
3465 req.bRequest = URTW_8187_SETREGS_REQ;
3466 USETW(req.wValue, val | 0xfe00);
3467 USETW(req.wIndex, 0);
3468 USETW(req.wLength, sizeof(uint8_t));
3470 return (urtw_do_request(sc, &req, &data));
3474 urtw_8180_set_anaparam(struct urtw_softc *sc, uint32_t val)
3479 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3483 urtw_read8_m(sc, URTW_CONFIG3, &data);
3484 urtw_write8_m(sc, URTW_CONFIG3, data | URTW_CONFIG3_ANAPARAM_WRITE);
3485 urtw_write32_m(sc, URTW_ANAPARAM, val);
3486 urtw_read8_m(sc, URTW_CONFIG3, &data);
3487 urtw_write8_m(sc, URTW_CONFIG3, data & ~URTW_CONFIG3_ANAPARAM_WRITE);
3489 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3497 urtw_8185_set_anaparam2(struct urtw_softc *sc, uint32_t val)
3502 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3506 urtw_read8_m(sc, URTW_CONFIG3, &data);
3507 urtw_write8_m(sc, URTW_CONFIG3, data | URTW_CONFIG3_ANAPARAM_WRITE);
3508 urtw_write32_m(sc, URTW_ANAPARAM2, val);
3509 urtw_read8_m(sc, URTW_CONFIG3, &data);
3510 urtw_write8_m(sc, URTW_CONFIG3, data & ~URTW_CONFIG3_ANAPARAM_WRITE);
3512 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3520 urtw_intr_enable(struct urtw_softc *sc)
3524 urtw_write16_m(sc, URTW_INTR_MASK, 0xffff);
3530 urtw_intr_disable(struct urtw_softc *sc)
3534 urtw_write16_m(sc, URTW_INTR_MASK, 0);
3540 urtw_reset(struct urtw_softc *sc)
3545 error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
3548 error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
3552 error = urtw_intr_disable(sc);
3555 usb_pause_mtx(&sc->sc_mtx, 100);
3557 error = urtw_write8e(sc, 0x18, 0x10);
3560 error = urtw_write8e(sc, 0x18, 0x11);
3563 error = urtw_write8e(sc, 0x18, 0x00);
3566 usb_pause_mtx(&sc->sc_mtx, 100);
3568 urtw_read8_m(sc, URTW_CMD, &data);
3569 data = (data & 0x2) | URTW_CMD_RST;
3570 urtw_write8_m(sc, URTW_CMD, data);
3571 usb_pause_mtx(&sc->sc_mtx, 100);
3573 urtw_read8_m(sc, URTW_CMD, &data);
3574 if (data & URTW_CMD_RST) {
3575 device_printf(sc->sc_dev, "reset timeout\n");
3579 error = urtw_set_mode(sc, URTW_EPROM_CMD_LOAD);
3582 usb_pause_mtx(&sc->sc_mtx, 100);
3584 error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
3587 error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
3595 urtw_led_ctl(struct urtw_softc *sc, int mode)
3597 usb_error_t error = 0;
3599 switch (sc->sc_strategy) {
3600 case URTW_SW_LED_MODE0:
3601 error = urtw_led_mode0(sc, mode);
3603 case URTW_SW_LED_MODE1:
3604 error = urtw_led_mode1(sc, mode);
3606 case URTW_SW_LED_MODE2:
3607 error = urtw_led_mode2(sc, mode);
3609 case URTW_SW_LED_MODE3:
3610 error = urtw_led_mode3(sc, mode);
3613 panic("unsupported LED mode %d\n", sc->sc_strategy);
3621 urtw_led_mode0(struct urtw_softc *sc, int mode)
3625 case URTW_LED_CTL_POWER_ON:
3626 sc->sc_gpio_ledstate = URTW_LED_POWER_ON_BLINK;
3628 case URTW_LED_CTL_TX:
3629 if (sc->sc_gpio_ledinprogress == 1)
3632 sc->sc_gpio_ledstate = URTW_LED_BLINK_NORMAL;
3633 sc->sc_gpio_blinktime = 2;
3635 case URTW_LED_CTL_LINK:
3636 sc->sc_gpio_ledstate = URTW_LED_ON;
3639 panic("unsupported LED mode 0x%x", mode);
3643 switch (sc->sc_gpio_ledstate) {
3645 if (sc->sc_gpio_ledinprogress != 0)
3647 urtw_led_on(sc, URTW_LED_GPIO);
3649 case URTW_LED_BLINK_NORMAL:
3650 if (sc->sc_gpio_ledinprogress != 0)
3652 sc->sc_gpio_ledinprogress = 1;
3653 sc->sc_gpio_blinkstate = (sc->sc_gpio_ledon != 0) ?
3654 URTW_LED_OFF : URTW_LED_ON;
3655 usb_callout_reset(&sc->sc_led_ch, hz, urtw_led_ch, sc);
3657 case URTW_LED_POWER_ON_BLINK:
3658 urtw_led_on(sc, URTW_LED_GPIO);
3659 usb_pause_mtx(&sc->sc_mtx, 100);
3660 urtw_led_off(sc, URTW_LED_GPIO);
3663 panic("unknown LED status 0x%x", sc->sc_gpio_ledstate);
3670 urtw_led_mode1(struct urtw_softc *sc, int mode)
3672 return (USB_ERR_INVAL);
3676 urtw_led_mode2(struct urtw_softc *sc, int mode)
3678 return (USB_ERR_INVAL);
3682 urtw_led_mode3(struct urtw_softc *sc, int mode)
3684 return (USB_ERR_INVAL);
3688 urtw_led_on(struct urtw_softc *sc, int type)
3692 if (type == URTW_LED_GPIO) {
3693 switch (sc->sc_gpio_ledpin) {
3694 case URTW_LED_PIN_GPIO0:
3695 urtw_write8_m(sc, URTW_GPIO, 0x01);
3696 urtw_write8_m(sc, URTW_GP_ENABLE, 0x00);
3699 panic("unsupported LED PIN type 0x%x",
3700 sc->sc_gpio_ledpin);
3704 panic("unsupported LED type 0x%x", type);
3708 sc->sc_gpio_ledon = 1;
3714 urtw_led_off(struct urtw_softc *sc, int type)
3718 if (type == URTW_LED_GPIO) {
3719 switch (sc->sc_gpio_ledpin) {
3720 case URTW_LED_PIN_GPIO0:
3721 urtw_write8_m(sc, URTW_GPIO, URTW_GPIO_DATA_MAGIC1);
3723 URTW_GP_ENABLE, URTW_GP_ENABLE_DATA_MAGIC1);
3726 panic("unsupported LED PIN type 0x%x",
3727 sc->sc_gpio_ledpin);
3731 panic("unsupported LED type 0x%x", type);
3735 sc->sc_gpio_ledon = 0;
3742 urtw_led_ch(void *arg)
3744 struct urtw_softc *sc = arg;
3745 struct ifnet *ifp = sc->sc_ifp;
3746 struct ieee80211com *ic = ifp->if_l2com;
3748 ieee80211_runtask(ic, &sc->sc_led_task);
3752 urtw_ledtask(void *arg, int pending)
3754 struct urtw_softc *sc = arg;
3756 if (sc->sc_strategy != URTW_SW_LED_MODE0)
3757 panic("could not process a LED strategy 0x%x", sc->sc_strategy);
3765 urtw_led_blink(struct urtw_softc *sc)
3770 if (sc->sc_gpio_blinkstate == URTW_LED_ON)
3771 error = urtw_led_on(sc, URTW_LED_GPIO);
3773 error = urtw_led_off(sc, URTW_LED_GPIO);
3774 sc->sc_gpio_blinktime--;
3775 if (sc->sc_gpio_blinktime == 0)
3778 if (sc->sc_gpio_ledstate != URTW_LED_BLINK_NORMAL &&
3779 sc->sc_gpio_ledstate != URTW_LED_BLINK_SLOWLY &&
3780 sc->sc_gpio_ledstate != URTW_LED_BLINK_CM3)
3784 if (sc->sc_gpio_ledstate == URTW_LED_ON &&
3785 sc->sc_gpio_ledon == 0)
3786 error = urtw_led_on(sc, URTW_LED_GPIO);
3787 else if (sc->sc_gpio_ledstate == URTW_LED_OFF &&
3788 sc->sc_gpio_ledon == 1)
3789 error = urtw_led_off(sc, URTW_LED_GPIO);
3791 sc->sc_gpio_blinktime = 0;
3792 sc->sc_gpio_ledinprogress = 0;
3796 sc->sc_gpio_blinkstate = (sc->sc_gpio_blinkstate != URTW_LED_ON) ?
3797 URTW_LED_ON : URTW_LED_OFF;
3799 switch (sc->sc_gpio_ledstate) {
3800 case URTW_LED_BLINK_NORMAL:
3801 usb_callout_reset(&sc->sc_led_ch, hz, urtw_led_ch, sc);
3804 panic("unknown LED status 0x%x", sc->sc_gpio_ledstate);
3811 urtw_rx_enable(struct urtw_softc *sc)
3816 usbd_transfer_start((sc->sc_flags & URTW_RTL8187B) ?
3817 sc->sc_xfer[URTW_8187B_BULK_RX] : sc->sc_xfer[URTW_8187L_BULK_RX]);
3819 error = urtw_rx_setconf(sc);
3823 if ((sc->sc_flags & URTW_RTL8187B) == 0) {
3824 urtw_read8_m(sc, URTW_CMD, &data);
3825 urtw_write8_m(sc, URTW_CMD, data | URTW_CMD_RX_ENABLE);
3832 urtw_tx_enable(struct urtw_softc *sc)
3838 if (sc->sc_flags & URTW_RTL8187B) {
3839 urtw_read32_m(sc, URTW_TX_CONF, &data);
3840 data &= ~URTW_TX_LOOPBACK_MASK;
3841 data &= ~(URTW_TX_DPRETRY_MASK | URTW_TX_RTSRETRY_MASK);
3842 data &= ~(URTW_TX_NOCRC | URTW_TX_MXDMA_MASK);
3843 data &= ~URTW_TX_SWPLCPLEN;
3844 data |= URTW_TX_HW_SEQNUM | URTW_TX_DISREQQSIZE |
3845 (7 << 8) | /* short retry limit */
3846 (7 << 0) | /* long retry limit */
3847 (7 << 21); /* MAX TX DMA */
3848 urtw_write32_m(sc, URTW_TX_CONF, data);
3850 urtw_read8_m(sc, URTW_MSR, &data8);
3851 data8 |= URTW_MSR_LINK_ENEDCA;
3852 urtw_write8_m(sc, URTW_MSR, data8);
3856 urtw_read8_m(sc, URTW_CW_CONF, &data8);
3857 data8 &= ~(URTW_CW_CONF_PERPACKET_CW | URTW_CW_CONF_PERPACKET_RETRY);
3858 urtw_write8_m(sc, URTW_CW_CONF, data8);
3860 urtw_read8_m(sc, URTW_TX_AGC_CTL, &data8);
3861 data8 &= ~URTW_TX_AGC_CTL_PERPACKET_GAIN;
3862 data8 &= ~URTW_TX_AGC_CTL_PERPACKET_ANTSEL;
3863 data8 &= ~URTW_TX_AGC_CTL_FEEDBACK_ANT;
3864 urtw_write8_m(sc, URTW_TX_AGC_CTL, data8);
3866 urtw_read32_m(sc, URTW_TX_CONF, &data);
3867 data &= ~URTW_TX_LOOPBACK_MASK;
3868 data |= URTW_TX_LOOPBACK_NONE;
3869 data &= ~(URTW_TX_DPRETRY_MASK | URTW_TX_RTSRETRY_MASK);
3870 data |= sc->sc_tx_retry << URTW_TX_DPRETRY_SHIFT;
3871 data |= sc->sc_rts_retry << URTW_TX_RTSRETRY_SHIFT;
3872 data &= ~(URTW_TX_NOCRC | URTW_TX_MXDMA_MASK);
3873 data |= URTW_TX_MXDMA_2048 | URTW_TX_CWMIN | URTW_TX_DISCW;
3874 data &= ~URTW_TX_SWPLCPLEN;
3875 data |= URTW_TX_NOICV;
3876 urtw_write32_m(sc, URTW_TX_CONF, data);
3878 urtw_read8_m(sc, URTW_CMD, &data8);
3879 urtw_write8_m(sc, URTW_CMD, data8 | URTW_CMD_TX_ENABLE);
3885 urtw_rx_setconf(struct urtw_softc *sc)
3887 struct ifnet *ifp = sc->sc_ifp;
3888 struct ieee80211com *ic = ifp->if_l2com;
3892 urtw_read32_m(sc, URTW_RX, &data);
3893 data = data &~ URTW_RX_FILTER_MASK;
3894 if (sc->sc_flags & URTW_RTL8187B) {
3895 data = data | URTW_RX_FILTER_MNG | URTW_RX_FILTER_DATA |
3896 URTW_RX_FILTER_MCAST | URTW_RX_FILTER_BCAST |
3897 URTW_RX_FILTER_NICMAC | URTW_RX_CHECK_BSSID |
3898 URTW_RX_FIFO_THRESHOLD_NONE |
3899 URTW_MAX_RX_DMA_2048 |
3900 URTW_RX_AUTORESETPHY | URTW_RCR_ONLYERLPKT;
3902 data = data | URTW_RX_FILTER_MNG | URTW_RX_FILTER_DATA;
3903 data = data | URTW_RX_FILTER_BCAST | URTW_RX_FILTER_MCAST;
3905 if (ic->ic_opmode == IEEE80211_M_MONITOR) {
3906 data = data | URTW_RX_FILTER_ICVERR;
3907 data = data | URTW_RX_FILTER_PWR;
3909 if (sc->sc_crcmon == 1 && ic->ic_opmode == IEEE80211_M_MONITOR)
3910 data = data | URTW_RX_FILTER_CRCERR;
3912 if (ic->ic_opmode == IEEE80211_M_MONITOR ||
3913 (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC))) {
3914 data = data | URTW_RX_FILTER_ALLMAC;
3916 data = data | URTW_RX_FILTER_NICMAC;
3917 data = data | URTW_RX_CHECK_BSSID;
3920 data = data &~ URTW_RX_FIFO_THRESHOLD_MASK;
3921 data = data | URTW_RX_FIFO_THRESHOLD_NONE |
3922 URTW_RX_AUTORESETPHY;
3923 data = data &~ URTW_MAX_RX_DMA_MASK;
3924 data = data | URTW_MAX_RX_DMA_2048 | URTW_RCR_ONLYERLPKT;
3927 urtw_write32_m(sc, URTW_RX, data);
3932 static struct mbuf *
3933 urtw_rxeof(struct usb_xfer *xfer, struct urtw_data *data, int *rssi_p,
3936 int actlen, flen, rssi;
3937 struct ieee80211_frame *wh;
3938 struct mbuf *m, *mnew;
3939 struct urtw_softc *sc = data->sc;
3940 struct ifnet *ifp = sc->sc_ifp;
3941 struct ieee80211com *ic = ifp->if_l2com;
3942 uint8_t noise = 0, rate;
3944 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
3946 if (actlen < URTW_MIN_RXBUFSZ) {
3951 if (sc->sc_flags & URTW_RTL8187B) {
3952 struct urtw_8187b_rxhdr *rx;
3954 rx = (struct urtw_8187b_rxhdr *)(data->buf +
3955 (actlen - (sizeof(struct urtw_8187b_rxhdr))));
3956 flen = le32toh(rx->flag) & 0xfff;
3957 if (flen > actlen) {
3961 rate = (le32toh(rx->flag) >> URTW_RX_FLAG_RXRATE_SHIFT) & 0xf;
3963 rssi = rx->rssi & URTW_RX_RSSI_MASK;
3966 struct urtw_8187l_rxhdr *rx;
3968 rx = (struct urtw_8187l_rxhdr *)(data->buf +
3969 (actlen - (sizeof(struct urtw_8187l_rxhdr))));
3970 flen = le32toh(rx->flag) & 0xfff;
3971 if (flen > actlen) {
3976 rate = (le32toh(rx->flag) >> URTW_RX_FLAG_RXRATE_SHIFT) & 0xf;
3978 rssi = rx->rssi & URTW_RX_8187L_RSSI_MASK;
3982 mnew = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
3990 data->buf = mtod(mnew, uint8_t *);
3993 m->m_pkthdr.rcvif = ifp;
3994 m->m_pkthdr.len = m->m_len = flen - IEEE80211_CRC_LEN;
3996 if (ieee80211_radiotap_active(ic)) {
3997 struct urtw_rx_radiotap_header *tap = &sc->sc_rxtap;
3999 /* XXX Are variables correct? */
4000 tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
4001 tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
4002 tap->wr_dbm_antsignal = (int8_t)rssi;
4005 wh = mtod(m, struct ieee80211_frame *);
4006 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_DATA)
4007 sc->sc_currate = (rate > 0) ? rate : sc->sc_currate;
4010 *nf_p = noise; /* XXX correct? */
4016 urtw_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
4018 struct urtw_softc *sc = usbd_xfer_softc(xfer);
4019 struct ifnet *ifp = sc->sc_ifp;
4020 struct ieee80211com *ic = ifp->if_l2com;
4021 struct ieee80211_frame *wh;
4022 struct ieee80211_node *ni;
4023 struct mbuf *m = NULL;
4024 struct urtw_data *data;
4028 URTW_ASSERT_LOCKED(sc);
4030 switch (USB_GET_STATE(xfer)) {
4031 case USB_ST_TRANSFERRED:
4032 data = STAILQ_FIRST(&sc->sc_rx_active);
4035 STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next);
4036 m = urtw_rxeof(xfer, data, &rssi, &nf);
4037 STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next);
4041 data = STAILQ_FIRST(&sc->sc_rx_inactive);
4043 KASSERT(m == NULL, ("mbuf isn't NULL"));
4046 STAILQ_REMOVE_HEAD(&sc->sc_rx_inactive, next);
4047 STAILQ_INSERT_TAIL(&sc->sc_rx_active, data, next);
4048 usbd_xfer_set_frame_data(xfer, 0, data->buf,
4049 usbd_xfer_max_len(xfer));
4050 usbd_transfer_submit(xfer);
4053 * To avoid LOR we should unlock our private mutex here to call
4054 * ieee80211_input() because here is at the end of a USB
4055 * callback and safe to unlock.
4059 wh = mtod(m, struct ieee80211_frame *);
4060 ni = ieee80211_find_rxnode(ic,
4061 (struct ieee80211_frame_min *)wh);
4063 (void) ieee80211_input(ni, m, rssi, nf);
4064 /* node is no longer needed */
4065 ieee80211_free_node(ni);
4067 (void) ieee80211_input_all(ic, m, rssi, nf);
4073 /* needs it to the inactive queue due to a error. */
4074 data = STAILQ_FIRST(&sc->sc_rx_active);
4076 STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next);
4077 STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next);
4079 if (error != USB_ERR_CANCELLED) {
4080 usbd_xfer_set_stall(xfer);
4088 #define URTW_STATUS_TYPE_TXCLOSE 1
4089 #define URTW_STATUS_TYPE_BEACON_INTR 0
4092 urtw_txstatus_eof(struct usb_xfer *xfer)
4094 struct urtw_softc *sc = usbd_xfer_softc(xfer);
4095 struct ifnet *ifp = sc->sc_ifp;
4096 int actlen, type, pktretry, seq;
4099 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
4101 if (actlen != sizeof(uint64_t))
4104 val = le64toh(sc->sc_txstatus);
4105 type = (val >> 30) & 0x3;
4106 if (type == URTW_STATUS_TYPE_TXCLOSE) {
4107 pktretry = val & 0xff;
4108 seq = (val >> 16) & 0xff;
4109 if (pktretry == URTW_TX_MAXRETRY)
4111 DPRINTF(sc, URTW_DEBUG_TXSTATUS, "pktretry %d seq %#x\n",
4117 urtw_bulk_tx_status_callback(struct usb_xfer *xfer, usb_error_t error)
4119 struct urtw_softc *sc = usbd_xfer_softc(xfer);
4120 struct ifnet *ifp = sc->sc_ifp;
4122 URTW_ASSERT_LOCKED(sc);
4124 switch (USB_GET_STATE(xfer)) {
4125 case USB_ST_TRANSFERRED:
4126 urtw_txstatus_eof(xfer);
4130 usbd_xfer_set_frame_data(xfer, 0, &sc->sc_txstatus,
4132 usbd_transfer_submit(xfer);
4135 if (error != USB_ERR_CANCELLED) {
4136 usbd_xfer_set_stall(xfer);
4145 urtw_txeof(struct usb_xfer *xfer, struct urtw_data *data)
4147 struct urtw_softc *sc = usbd_xfer_softc(xfer);
4148 struct ifnet *ifp = sc->sc_ifp;
4151 URTW_ASSERT_LOCKED(sc);
4154 * Do any tx complete callback. Note this must be done before releasing
4155 * the node reference.
4159 if (m->m_flags & M_TXCB) {
4161 ieee80211_process_callback(data->ni, m, 0);
4167 ieee80211_free_node(data->ni);
4172 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
4176 urtw_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error)
4178 struct urtw_softc *sc = usbd_xfer_softc(xfer);
4179 struct ifnet *ifp = sc->sc_ifp;
4180 struct urtw_data *data;
4182 URTW_ASSERT_LOCKED(sc);
4184 switch (USB_GET_STATE(xfer)) {
4185 case USB_ST_TRANSFERRED:
4186 data = STAILQ_FIRST(&sc->sc_tx_active);
4189 STAILQ_REMOVE_HEAD(&sc->sc_tx_active, next);
4190 urtw_txeof(xfer, data);
4191 STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data, next);
4195 data = STAILQ_FIRST(&sc->sc_tx_pending);
4197 DPRINTF(sc, URTW_DEBUG_XMIT,
4198 "%s: empty pending queue\n", __func__);
4201 STAILQ_REMOVE_HEAD(&sc->sc_tx_pending, next);
4202 STAILQ_INSERT_TAIL(&sc->sc_tx_active, data, next);
4204 usbd_xfer_set_frame_data(xfer, 0, data->buf, data->buflen);
4205 usbd_transfer_submit(xfer);
4212 data = STAILQ_FIRST(&sc->sc_tx_active);
4215 if (data->ni != NULL) {
4216 ieee80211_free_node(data->ni);
4220 if (error != USB_ERR_CANCELLED) {
4221 usbd_xfer_set_stall(xfer);
4228 static struct urtw_data *
4229 _urtw_getbuf(struct urtw_softc *sc)
4231 struct urtw_data *bf;
4233 bf = STAILQ_FIRST(&sc->sc_tx_inactive);
4235 STAILQ_REMOVE_HEAD(&sc->sc_tx_inactive, next);
4239 DPRINTF(sc, URTW_DEBUG_XMIT, "%s: %s\n", __func__,
4240 "out of xmit buffers");
4244 static struct urtw_data *
4245 urtw_getbuf(struct urtw_softc *sc)
4247 struct urtw_data *bf;
4249 URTW_ASSERT_LOCKED(sc);
4251 bf = _urtw_getbuf(sc);
4253 struct ifnet *ifp = sc->sc_ifp;
4255 DPRINTF(sc, URTW_DEBUG_XMIT, "%s: stop queue\n", __func__);
4256 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
4262 urtw_isbmode(uint16_t rate)
4265 return ((rate <= 22 && rate != 12 && rate != 18) ||
4266 rate == 44) ? (1) : (0);
4270 urtw_rate2dbps(uint16_t rate)
4290 urtw_compute_txtime(uint16_t framelen, uint16_t rate,
4291 uint8_t ismgt, uint8_t isshort)
4293 uint16_t ceiling, frametime, n_dbps;
4295 if (urtw_isbmode(rate)) {
4296 if (ismgt || !isshort || rate == 2)
4297 frametime = (uint16_t)(144 + 48 +
4298 (framelen * 8 / (rate / 2)));
4300 frametime = (uint16_t)(72 + 24 +
4301 (framelen * 8 / (rate / 2)));
4302 if ((framelen * 8 % (rate / 2)) != 0)
4305 n_dbps = urtw_rate2dbps(rate);
4306 ceiling = (16 + 8 * framelen + 6) / n_dbps
4307 + (((16 + 8 * framelen + 6) % n_dbps) ? 1 : 0);
4308 frametime = (uint16_t)(16 + 4 + 4 * ceiling + 6);
4314 * Callback from the 802.11 layer to update the
4315 * slot time based on the current setting.
4318 urtw_updateslot(struct ieee80211com *ic)
4320 struct urtw_softc *sc = ic->ic_softc;
4322 ieee80211_runtask(ic, &sc->sc_updateslot_task);
4326 urtw_updateslottask(void *arg, int pending)
4328 struct urtw_softc *sc = arg;
4329 struct ifnet *ifp = sc->sc_ifp;
4330 struct ieee80211com *ic = ifp->if_l2com;
4333 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
4337 if (sc->sc_flags & URTW_RTL8187B) {
4338 urtw_write8_m(sc, URTW_SIFS, 0x22);
4339 if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan))
4340 urtw_write8_m(sc, URTW_SLOT, 0x9);
4342 urtw_write8_m(sc, URTW_SLOT, 0x14);
4343 urtw_write8_m(sc, URTW_8187B_EIFS, 0x5b);
4344 urtw_write8_m(sc, URTW_CARRIER_SCOUNT, 0x5b);
4346 urtw_write8_m(sc, URTW_SIFS, 0x22);
4347 if (sc->sc_state == IEEE80211_S_ASSOC &&
4348 ic->ic_flags & IEEE80211_F_SHSLOT)
4349 urtw_write8_m(sc, URTW_SLOT, 0x9);
4351 urtw_write8_m(sc, URTW_SLOT, 0x14);
4352 if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan)) {
4353 urtw_write8_m(sc, URTW_DIFS, 0x14);
4354 urtw_write8_m(sc, URTW_EIFS, 0x5b - 0x14);
4355 urtw_write8_m(sc, URTW_CW_VAL, 0x73);
4357 urtw_write8_m(sc, URTW_DIFS, 0x24);
4358 urtw_write8_m(sc, URTW_EIFS, 0x5b - 0x24);
4359 urtw_write8_m(sc, URTW_CW_VAL, 0xa5);
4367 urtw_sysctl_node(struct urtw_softc *sc)
4369 #define URTW_SYSCTL_STAT_ADD32(c, h, n, p, d) \
4370 SYSCTL_ADD_UINT(c, h, OID_AUTO, n, CTLFLAG_RD, p, 0, d)
4371 struct sysctl_ctx_list *ctx;
4372 struct sysctl_oid_list *child, *parent;
4373 struct sysctl_oid *tree;
4374 struct urtw_stats *stats = &sc->sc_stats;
4376 ctx = device_get_sysctl_ctx(sc->sc_dev);
4377 child = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->sc_dev));
4379 tree = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "stats", CTLFLAG_RD,
4380 NULL, "URTW statistics");
4381 parent = SYSCTL_CHILDREN(tree);
4383 /* Tx statistics. */
4384 tree = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "tx", CTLFLAG_RD,
4385 NULL, "Tx MAC statistics");
4386 child = SYSCTL_CHILDREN(tree);
4387 URTW_SYSCTL_STAT_ADD32(ctx, child, "1m", &stats->txrates[0],
4389 URTW_SYSCTL_STAT_ADD32(ctx, child, "2m", &stats->txrates[1],
4391 URTW_SYSCTL_STAT_ADD32(ctx, child, "5.5m", &stats->txrates[2],
4393 URTW_SYSCTL_STAT_ADD32(ctx, child, "6m", &stats->txrates[4],
4395 URTW_SYSCTL_STAT_ADD32(ctx, child, "9m", &stats->txrates[5],
4397 URTW_SYSCTL_STAT_ADD32(ctx, child, "11m", &stats->txrates[3],
4399 URTW_SYSCTL_STAT_ADD32(ctx, child, "12m", &stats->txrates[6],
4401 URTW_SYSCTL_STAT_ADD32(ctx, child, "18m", &stats->txrates[7],
4403 URTW_SYSCTL_STAT_ADD32(ctx, child, "24m", &stats->txrates[8],
4405 URTW_SYSCTL_STAT_ADD32(ctx, child, "36m", &stats->txrates[9],
4407 URTW_SYSCTL_STAT_ADD32(ctx, child, "48m", &stats->txrates[10],
4409 URTW_SYSCTL_STAT_ADD32(ctx, child, "54m", &stats->txrates[11],
4411 #undef URTW_SYSCTL_STAT_ADD32
4414 static device_method_t urtw_methods[] = {
4415 DEVMETHOD(device_probe, urtw_match),
4416 DEVMETHOD(device_attach, urtw_attach),
4417 DEVMETHOD(device_detach, urtw_detach),
4420 static driver_t urtw_driver = {
4423 sizeof(struct urtw_softc)
4425 static devclass_t urtw_devclass;
4427 DRIVER_MODULE(urtw, uhub, urtw_driver, urtw_devclass, NULL, NULL);
4428 MODULE_DEPEND(urtw, wlan, 1, 1, 1);
4429 MODULE_DEPEND(urtw, usb, 1, 1, 1);
4430 MODULE_VERSION(urtw, 1);