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 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_device_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(0x1b75, 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 name[IFNAMSIZ], int unit, int opmode,
653 int flags, const uint8_t bssid[IEEE80211_ADDR_LEN],
654 const uint8_t mac[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 ifnet *);
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 ifnet *);
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);
876 ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
877 ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
879 /* set device capabilities */
881 IEEE80211_C_STA | /* station mode */
882 IEEE80211_C_MONITOR | /* monitor mode supported */
883 IEEE80211_C_TXPMGT | /* tx power management */
884 IEEE80211_C_SHPREAMBLE | /* short preamble supported */
885 IEEE80211_C_SHSLOT | /* short slot time supported */
886 IEEE80211_C_BGSCAN | /* capable of bg scanning */
887 IEEE80211_C_WPA; /* 802.11i */
890 setbit(&bands, IEEE80211_MODE_11B);
891 setbit(&bands, IEEE80211_MODE_11G);
892 ieee80211_init_channels(ic, NULL, &bands);
894 ieee80211_ifattach(ic, sc->sc_bssid);
895 ic->ic_raw_xmit = urtw_raw_xmit;
896 ic->ic_scan_start = urtw_scan_start;
897 ic->ic_scan_end = urtw_scan_end;
898 ic->ic_set_channel = urtw_set_channel;
899 ic->ic_updateslot = urtw_updateslot;
900 ic->ic_vap_create = urtw_vap_create;
901 ic->ic_vap_delete = urtw_vap_delete;
902 ic->ic_update_mcast = urtw_update_mcast;
904 ieee80211_radiotap_attach(ic,
905 &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
906 URTW_TX_RADIOTAP_PRESENT,
907 &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
908 URTW_RX_RADIOTAP_PRESENT);
910 urtw_sysctl_node(sc);
913 ieee80211_announce(ic);
916 fail: URTW_UNLOCK(sc);
917 fail1: usbd_transfer_unsetup(sc->sc_xfer, (sc->sc_flags & URTW_RTL8187B) ?
918 URTW_8187B_N_XFERS : URTW_8187L_N_XFERS);
924 urtw_detach(device_t dev)
926 struct urtw_softc *sc = device_get_softc(dev);
927 struct ifnet *ifp = sc->sc_ifp;
928 struct ieee80211com *ic = ifp->if_l2com;
930 if (!device_is_attached(dev))
934 ieee80211_draintask(ic, &sc->sc_updateslot_task);
935 ieee80211_draintask(ic, &sc->sc_led_task);
937 usb_callout_drain(&sc->sc_led_ch);
938 callout_drain(&sc->sc_watchdog_ch);
940 usbd_transfer_unsetup(sc->sc_xfer, (sc->sc_flags & URTW_RTL8187B) ?
941 URTW_8187B_N_XFERS : URTW_8187L_N_XFERS);
942 ieee80211_ifdetach(ic);
944 urtw_free_tx_data_list(sc);
945 urtw_free_rx_data_list(sc);
948 mtx_destroy(&sc->sc_mtx);
954 urtw_free_tx_data_list(struct urtw_softc *sc)
957 urtw_free_data_list(sc, sc->sc_tx, URTW_TX_DATA_LIST_COUNT, 0);
961 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,
997 const char name[IFNAMSIZ], int unit, int 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_NOWAIT | 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)
1095 #define N(a) (sizeof(a) / sizeof((a)[0]))
1099 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
1103 urtw_read8_m(sc, URTW_CONFIG3, &data8);
1104 urtw_write8_m(sc, URTW_CONFIG3,
1105 data8 | URTW_CONFIG3_ANAPARAM_WRITE | URTW_CONFIG3_GNT_SELECT);
1106 urtw_write32_m(sc, URTW_ANAPARAM2, URTW_8187B_8225_ANAPARAM2_ON);
1107 urtw_write32_m(sc, URTW_ANAPARAM, URTW_8187B_8225_ANAPARAM_ON);
1108 urtw_write8_m(sc, URTW_ANAPARAM3, URTW_8187B_8225_ANAPARAM3_ON);
1110 urtw_write8_m(sc, 0x61, 0x10);
1111 urtw_read8_m(sc, 0x62, &data8);
1112 urtw_write8_m(sc, 0x62, data8 & ~(1 << 5));
1113 urtw_write8_m(sc, 0x62, data8 | (1 << 5));
1115 urtw_read8_m(sc, URTW_CONFIG3, &data8);
1116 data8 &= ~URTW_CONFIG3_ANAPARAM_WRITE;
1117 urtw_write8_m(sc, URTW_CONFIG3, data8);
1119 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
1123 error = urtw_8187b_cmd_reset(sc);
1127 error = sc->sc_rf_init(sc);
1130 urtw_write8_m(sc, URTW_CMD, URTW_CMD_RX_ENABLE | URTW_CMD_TX_ENABLE);
1132 /* fix RTL8187B RX stall */
1133 error = urtw_intr_enable(sc);
1137 error = urtw_write8e(sc, 0x41, 0xf4);
1140 error = urtw_write8e(sc, 0x40, 0x00);
1143 error = urtw_write8e(sc, 0x42, 0x00);
1146 error = urtw_write8e(sc, 0x42, 0x01);
1149 error = urtw_write8e(sc, 0x40, 0x0f);
1152 error = urtw_write8e(sc, 0x42, 0x00);
1155 error = urtw_write8e(sc, 0x42, 0x01);
1159 urtw_read8_m(sc, 0xdb, &data8);
1160 urtw_write8_m(sc, 0xdb, data8 | (1 << 2));
1161 urtw_write16_m(sc, 0x372, 0x59fa);
1162 urtw_write16_m(sc, 0x374, 0x59d2);
1163 urtw_write16_m(sc, 0x376, 0x59d2);
1164 urtw_write16_m(sc, 0x378, 0x19fa);
1165 urtw_write16_m(sc, 0x37a, 0x19fa);
1166 urtw_write16_m(sc, 0x37c, 0x00d0);
1167 urtw_write8_m(sc, 0x61, 0);
1169 urtw_write8_m(sc, 0x180, 0x0f);
1170 urtw_write8_m(sc, 0x183, 0x03);
1171 urtw_write8_m(sc, 0xda, 0x10);
1172 urtw_write8_m(sc, 0x24d, 0x08);
1173 urtw_write32_m(sc, URTW_HSSI_PARA, 0x0600321b);
1175 urtw_write16_m(sc, 0x1ec, 0x800); /* RX MAX SIZE */
1182 urtw_adapter_start(struct urtw_softc *sc)
1186 error = urtw_reset(sc);
1190 urtw_write8_m(sc, URTW_ADDR_MAGIC1, 0);
1191 urtw_write8_m(sc, URTW_GPIO, 0);
1194 urtw_write8_m(sc, URTW_ADDR_MAGIC1, 4);
1195 error = urtw_led_ctl(sc, URTW_LED_CTL_POWER_ON);
1199 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
1202 /* applying MAC address again. */
1203 urtw_write32_m(sc, URTW_MAC0, ((uint32_t *)sc->sc_bssid)[0]);
1204 urtw_write16_m(sc, URTW_MAC4, ((uint32_t *)sc->sc_bssid)[1] & 0xffff);
1205 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
1209 error = urtw_update_msr(sc);
1213 urtw_write32_m(sc, URTW_INT_TIMEOUT, 0);
1214 urtw_write8_m(sc, URTW_WPA_CONFIG, 0);
1215 urtw_write8_m(sc, URTW_RATE_FALLBACK, URTW_RATE_FALLBACK_ENABLE | 0x1);
1216 error = urtw_set_rate(sc);
1220 error = sc->sc_rf_init(sc);
1223 if (sc->sc_rf_set_sens != NULL)
1224 sc->sc_rf_set_sens(sc, sc->sc_sens);
1226 /* XXX correct? to call write16 */
1227 urtw_write16_m(sc, URTW_PSR, 1);
1228 urtw_write16_m(sc, URTW_ADDR_MAGIC2, 0x10);
1229 urtw_write8_m(sc, URTW_TALLY_SEL, 0x80);
1230 urtw_write8_m(sc, URTW_ADDR_MAGIC3, 0x60);
1231 /* XXX correct? to call write16 */
1232 urtw_write16_m(sc, URTW_PSR, 0);
1233 urtw_write8_m(sc, URTW_ADDR_MAGIC1, 4);
1235 error = urtw_intr_enable(sc);
1244 urtw_set_mode(struct urtw_softc *sc, uint32_t mode)
1249 urtw_read8_m(sc, URTW_EPROM_CMD, &data);
1250 data = (data & ~URTW_EPROM_CMD_MASK) | (mode << URTW_EPROM_CMD_SHIFT);
1251 data = data & ~(URTW_EPROM_CS | URTW_EPROM_CK);
1252 urtw_write8_m(sc, URTW_EPROM_CMD, data);
1258 urtw_8187b_cmd_reset(struct urtw_softc *sc)
1264 /* XXX the code can be duplicate with urtw_reset(). */
1265 urtw_read8_m(sc, URTW_CMD, &data8);
1266 data8 = (data8 & 0x2) | URTW_CMD_RST;
1267 urtw_write8_m(sc, URTW_CMD, data8);
1269 for (i = 0; i < 20; i++) {
1270 usb_pause_mtx(&sc->sc_mtx, 2);
1271 urtw_read8_m(sc, URTW_CMD, &data8);
1272 if (!(data8 & URTW_CMD_RST))
1276 device_printf(sc->sc_dev, "reset timeout\n");
1284 urtw_do_request(struct urtw_softc *sc,
1285 struct usb_device_request *req, void *data)
1290 URTW_ASSERT_LOCKED(sc);
1293 err = usbd_do_request_flags(sc->sc_udev, &sc->sc_mtx,
1294 req, data, 0, NULL, 250 /* ms */);
1298 DPRINTF(sc, URTW_DEBUG_INIT,
1299 "Control request failed, %s (retrying)\n",
1301 usb_pause_mtx(&sc->sc_mtx, hz / 100);
1307 urtw_stop_locked(struct ifnet *ifp, int disable)
1309 struct urtw_softc *sc = ifp->if_softc;
1314 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
1316 error = urtw_intr_disable(sc);
1319 urtw_read8_m(sc, URTW_CMD, &data8);
1320 data8 &= ~(URTW_CMD_RX_ENABLE | URTW_CMD_TX_ENABLE);
1321 urtw_write8_m(sc, URTW_CMD, data8);
1323 error = sc->sc_rf_stop(sc);
1327 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
1330 urtw_read8_m(sc, URTW_CONFIG4, &data8);
1331 urtw_write8_m(sc, URTW_CONFIG4, data8 | URTW_CONFIG4_VCOOFF);
1332 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
1337 device_printf(sc->sc_dev, "failed to stop (%s)\n",
1338 usbd_errstr(error));
1340 usb_callout_stop(&sc->sc_led_ch);
1341 callout_stop(&sc->sc_watchdog_ch);
1343 urtw_abort_xfers(sc);
1347 urtw_stop(struct ifnet *ifp, int disable)
1349 struct urtw_softc *sc = ifp->if_softc;
1352 urtw_stop_locked(ifp, disable);
1357 urtw_abort_xfers(struct urtw_softc *sc)
1361 URTW_ASSERT_LOCKED(sc);
1363 max = (sc->sc_flags & URTW_RTL8187B) ? URTW_8187B_N_XFERS :
1366 /* abort any pending transfers */
1367 for (i = 0; i < max; i++)
1368 usbd_transfer_stop(sc->sc_xfer[i]);
1372 urtw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1374 struct urtw_softc *sc = ifp->if_softc;
1375 struct ieee80211com *ic = ifp->if_l2com;
1376 struct ifreq *ifr = (struct ifreq *) data;
1377 int error = 0, startall = 0;
1381 if (ifp->if_flags & IFF_UP) {
1382 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
1383 if ((ifp->if_flags ^ sc->sc_if_flags) &
1384 (IFF_ALLMULTI | IFF_PROMISC))
1387 urtw_init(ifp->if_softc);
1391 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1394 sc->sc_if_flags = ifp->if_flags;
1396 ieee80211_start_all(ic);
1399 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
1402 error = ether_ioctl(ifp, cmd, data);
1413 urtw_start(struct ifnet *ifp)
1415 struct urtw_data *bf;
1416 struct urtw_softc *sc = ifp->if_softc;
1417 struct ieee80211_node *ni;
1420 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
1425 IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
1428 bf = urtw_getbuf(sc);
1430 IFQ_DRV_PREPEND(&ifp->if_snd, m);
1434 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
1435 m->m_pkthdr.rcvif = NULL;
1437 if (urtw_tx_start(sc, ni, m, bf, URTW_PRIORITY_NORMAL) != 0) {
1439 STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
1440 ieee80211_free_node(ni);
1445 callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc);
1451 urtw_alloc_data_list(struct urtw_softc *sc, struct urtw_data data[],
1452 int ndata, int maxsz, int fillmbuf)
1456 for (i = 0; i < ndata; i++) {
1457 struct urtw_data *dp = &data[i];
1461 dp->m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
1462 if (dp->m == NULL) {
1463 device_printf(sc->sc_dev,
1464 "could not allocate rx mbuf\n");
1468 dp->buf = mtod(dp->m, uint8_t *);
1471 dp->buf = malloc(maxsz, M_USBDEV, M_NOWAIT);
1472 if (dp->buf == NULL) {
1473 device_printf(sc->sc_dev,
1474 "could not allocate buffer\n");
1478 if (((unsigned long)dp->buf) % 4)
1479 device_printf(sc->sc_dev,
1480 "warn: unaligned buffer %p\n", dp->buf);
1487 fail: urtw_free_data_list(sc, data, ndata, fillmbuf);
1492 urtw_alloc_rx_data_list(struct urtw_softc *sc)
1496 error = urtw_alloc_data_list(sc,
1497 sc->sc_rx, URTW_RX_DATA_LIST_COUNT, MCLBYTES, 1 /* mbufs */);
1501 STAILQ_INIT(&sc->sc_rx_active);
1502 STAILQ_INIT(&sc->sc_rx_inactive);
1504 for (i = 0; i < URTW_RX_DATA_LIST_COUNT; i++)
1505 STAILQ_INSERT_HEAD(&sc->sc_rx_inactive, &sc->sc_rx[i], next);
1511 urtw_alloc_tx_data_list(struct urtw_softc *sc)
1515 error = urtw_alloc_data_list(sc,
1516 sc->sc_tx, URTW_TX_DATA_LIST_COUNT, URTW_TX_MAXSIZE,
1521 STAILQ_INIT(&sc->sc_tx_active);
1522 STAILQ_INIT(&sc->sc_tx_inactive);
1523 STAILQ_INIT(&sc->sc_tx_pending);
1525 for (i = 0; i < URTW_TX_DATA_LIST_COUNT; i++)
1526 STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, &sc->sc_tx[i],
1533 urtw_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
1534 const struct ieee80211_bpf_params *params)
1536 struct ieee80211com *ic = ni->ni_ic;
1537 struct ifnet *ifp = ic->ic_ifp;
1538 struct urtw_data *bf;
1539 struct urtw_softc *sc = ifp->if_softc;
1541 /* prevent management frames from being sent if we're not ready */
1542 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
1544 ieee80211_free_node(ni);
1548 bf = urtw_getbuf(sc);
1550 ieee80211_free_node(ni);
1553 return (ENOBUFS); /* XXX */
1557 if (urtw_tx_start(sc, ni, m, bf, URTW_PRIORITY_LOW) != 0) {
1558 ieee80211_free_node(ni);
1560 STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
1571 urtw_scan_start(struct ieee80211com *ic)
1574 /* XXX do nothing? */
1578 urtw_scan_end(struct ieee80211com *ic)
1581 /* XXX do nothing? */
1585 urtw_set_channel(struct ieee80211com *ic)
1587 struct urtw_softc *sc = ic->ic_ifp->if_softc;
1588 struct ifnet *ifp = sc->sc_ifp;
1589 uint32_t data, orig;
1593 * if the user set a channel explicitly using ifconfig(8) this function
1594 * can be called earlier than we're expected that in some cases the
1595 * initialization would be failed if setting a channel is called before
1596 * the init have done.
1598 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
1601 if (sc->sc_curchan != NULL && sc->sc_curchan == ic->ic_curchan)
1607 * during changing th channel we need to temporarily be disable
1610 urtw_read32_m(sc, URTW_TX_CONF, &orig);
1611 data = orig & ~URTW_TX_LOOPBACK_MASK;
1612 urtw_write32_m(sc, URTW_TX_CONF, data | URTW_TX_LOOPBACK_MAC);
1614 error = sc->sc_rf_set_chan(sc, ieee80211_chan2ieee(ic, ic->ic_curchan));
1617 usb_pause_mtx(&sc->sc_mtx, 10);
1618 urtw_write32_m(sc, URTW_TX_CONF, orig);
1620 urtw_write16_m(sc, URTW_ATIM_WND, 2);
1621 urtw_write16_m(sc, URTW_ATIM_TR_ITV, 100);
1622 urtw_write16_m(sc, URTW_BEACON_INTERVAL, 100);
1623 urtw_write16_m(sc, URTW_BEACON_INTERVAL_TIME, 100);
1628 sc->sc_curchan = ic->ic_curchan;
1631 device_printf(sc->sc_dev, "could not change the channel\n");
1635 urtw_update_mcast(struct ifnet *ifp)
1638 /* XXX do nothing? */
1642 urtw_tx_start(struct urtw_softc *sc, struct ieee80211_node *ni, struct mbuf *m0,
1643 struct urtw_data *data, int prior)
1645 struct ifnet *ifp = sc->sc_ifp;
1646 struct ieee80211_frame *wh = mtod(m0, struct ieee80211_frame *);
1647 struct ieee80211_key *k;
1648 const struct ieee80211_txparam *tp;
1649 struct ieee80211com *ic = ifp->if_l2com;
1650 struct ieee80211vap *vap = ni->ni_vap;
1651 struct usb_xfer *rtl8187b_pipes[URTW_8187B_TXPIPE_MAX] = {
1652 sc->sc_xfer[URTW_8187B_BULK_TX_BE],
1653 sc->sc_xfer[URTW_8187B_BULK_TX_BK],
1654 sc->sc_xfer[URTW_8187B_BULK_TX_VI],
1655 sc->sc_xfer[URTW_8187B_BULK_TX_VO]
1657 struct usb_xfer *xfer;
1658 int dur = 0, rtsdur = 0, rtsenable = 0, ctsenable = 0, rate,
1659 pkttime = 0, txdur = 0, isshort = 0, xferlen;
1660 uint16_t acktime, rtstime, ctstime;
1664 URTW_ASSERT_LOCKED(sc);
1669 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
1670 k = ieee80211_crypto_encap(ni, m0);
1672 device_printf(sc->sc_dev,
1673 "ieee80211_crypto_encap returns NULL.\n");
1674 /* XXX we don't expect the fragmented frames */
1679 /* in case packet header moved, reset pointer */
1680 wh = mtod(m0, struct ieee80211_frame *);
1683 if (ieee80211_radiotap_active_vap(vap)) {
1684 struct urtw_tx_radiotap_header *tap = &sc->sc_txtap;
1686 /* XXX Are variables correct? */
1688 tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
1689 tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
1691 ieee80211_radiotap_tx(vap, m0);
1694 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_MGT ||
1695 (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL) {
1696 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
1697 rate = tp->mgmtrate;
1699 tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)];
1700 /* for data frames */
1701 if (IEEE80211_IS_MULTICAST(wh->i_addr1))
1702 rate = tp->mcastrate;
1703 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
1704 rate = tp->ucastrate;
1706 rate = urtw_rtl2rate(sc->sc_currate);
1709 sc->sc_stats.txrates[sc->sc_currate]++;
1711 if (IEEE80211_IS_MULTICAST(wh->i_addr1))
1712 txdur = pkttime = urtw_compute_txtime(m0->m_pkthdr.len +
1713 IEEE80211_CRC_LEN, rate, 0, 0);
1715 acktime = urtw_compute_txtime(14, 2,0, 0);
1716 if ((m0->m_pkthdr.len + 4) > vap->iv_rtsthreshold) {
1719 rtstime = urtw_compute_txtime(URTW_ACKCTS_LEN, 2, 0, 0);
1720 ctstime = urtw_compute_txtime(14, 2, 0, 0);
1721 pkttime = urtw_compute_txtime(m0->m_pkthdr.len +
1722 IEEE80211_CRC_LEN, rate, 0, isshort);
1723 rtsdur = ctstime + pkttime + acktime +
1724 3 * URTW_ASIFS_TIME;
1725 txdur = rtstime + rtsdur;
1727 rtsenable = ctsenable = rtsdur = 0;
1728 pkttime = urtw_compute_txtime(m0->m_pkthdr.len +
1729 IEEE80211_CRC_LEN, rate, 0, isshort);
1730 txdur = pkttime + URTW_ASIFS_TIME + acktime;
1733 if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG)
1734 dur = urtw_compute_txtime(m0->m_pkthdr.len +
1735 IEEE80211_CRC_LEN, rate, 0, isshort) +
1736 3 * URTW_ASIFS_TIME +
1739 dur = URTW_ASIFS_TIME + acktime;
1741 *(uint16_t *)wh->i_dur = htole16(dur);
1743 xferlen = m0->m_pkthdr.len;
1744 xferlen += (sc->sc_flags & URTW_RTL8187B) ? (4 * 8) : (4 * 3);
1745 if ((0 == xferlen % 64) || (0 == xferlen % 512))
1748 bzero(data->buf, URTW_TX_MAXSIZE);
1749 flags = m0->m_pkthdr.len & 0xfff;
1750 flags |= URTW_TX_FLAG_NO_ENC;
1751 if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
1752 (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE) &&
1753 (sc->sc_preamble_mode == URTW_PREAMBLE_MODE_SHORT) &&
1754 (sc->sc_currate != 0))
1755 flags |= URTW_TX_FLAG_SPLCP;
1756 if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG)
1757 flags |= URTW_TX_FLAG_MOREFRAG;
1759 flags |= (sc->sc_currate & 0xf) << URTW_TX_FLAG_TXRATE_SHIFT;
1761 if (sc->sc_flags & URTW_RTL8187B) {
1762 struct urtw_8187b_txhdr *tx;
1764 tx = (struct urtw_8187b_txhdr *)data->buf;
1766 flags |= URTW_TX_FLAG_CTS;
1768 flags |= URTW_TX_FLAG_RTS;
1769 flags |= (urtw_rate2rtl(11) & 0xf) <<
1770 URTW_TX_FLAG_RTSRATE_SHIFT;
1771 tx->rtsdur = rtsdur;
1773 tx->flag = htole32(flags);
1775 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
1776 IEEE80211_FC0_TYPE_MGT &&
1777 (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) ==
1778 IEEE80211_FC0_SUBTYPE_PROBE_RESP)
1781 tx->retry = URTW_TX_MAXRETRY;
1782 m_copydata(m0, 0, m0->m_pkthdr.len, (uint8_t *)(tx + 1));
1784 struct urtw_8187l_txhdr *tx;
1786 tx = (struct urtw_8187l_txhdr *)data->buf;
1788 flags |= URTW_TX_FLAG_RTS;
1789 tx->rtsdur = rtsdur;
1791 flags |= (urtw_rate2rtl(11) & 0xf) << URTW_TX_FLAG_RTSRATE_SHIFT;
1792 tx->flag = htole32(flags);
1793 tx->retry = 3; /* CW minimum */
1794 tx->retry = 7 << 4; /* CW maximum */
1795 tx->retry = URTW_TX_MAXRETRY << 8; /* retry limitation */
1796 m_copydata(m0, 0, m0->m_pkthdr.len, (uint8_t *)(tx + 1));
1799 data->buflen = xferlen;
1803 if (sc->sc_flags & URTW_RTL8187B) {
1804 switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) {
1805 case IEEE80211_FC0_TYPE_CTL:
1806 case IEEE80211_FC0_TYPE_MGT:
1807 xfer = sc->sc_xfer[URTW_8187B_BULK_TX_EP12];
1810 KASSERT(M_WME_GETAC(m0) < URTW_8187B_TXPIPE_MAX,
1811 ("unsupported WME pipe %d", M_WME_GETAC(m0)));
1812 xfer = rtl8187b_pipes[M_WME_GETAC(m0)];
1816 xfer = (prior == URTW_PRIORITY_LOW) ?
1817 sc->sc_xfer[URTW_8187L_BULK_TX_LOW] :
1818 sc->sc_xfer[URTW_8187L_BULK_TX_NORMAL];
1820 STAILQ_INSERT_TAIL(&sc->sc_tx_pending, data, next);
1821 usbd_transfer_start(xfer);
1823 error = urtw_led_ctl(sc, URTW_LED_CTL_TX);
1825 device_printf(sc->sc_dev, "could not control LED (%d)\n",
1831 urtw_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
1833 struct ieee80211_node *ni = vap->iv_bss;
1834 struct ieee80211com *ic = vap->iv_ic;
1835 struct urtw_softc *sc = ic->ic_ifp->if_softc;
1836 struct urtw_vap *uvp = URTW_VAP(vap);
1837 usb_error_t error = 0;
1839 DPRINTF(sc, URTW_DEBUG_STATE, "%s: %s -> %s\n", __func__,
1840 ieee80211_state_name[vap->iv_state],
1841 ieee80211_state_name[nstate]);
1843 sc->sc_state = nstate;
1845 IEEE80211_UNLOCK(ic);
1847 usb_callout_stop(&sc->sc_led_ch);
1848 callout_stop(&sc->sc_watchdog_ch);
1851 case IEEE80211_S_INIT:
1852 case IEEE80211_S_SCAN:
1853 case IEEE80211_S_AUTH:
1854 case IEEE80211_S_ASSOC:
1856 case IEEE80211_S_RUN:
1857 /* setting bssid. */
1858 urtw_write32_m(sc, URTW_BSSID, ((uint32_t *)ni->ni_bssid)[0]);
1859 urtw_write16_m(sc, URTW_BSSID + 4,
1860 ((uint16_t *)ni->ni_bssid)[2]);
1861 urtw_update_msr(sc);
1862 /* XXX maybe the below would be incorrect. */
1863 urtw_write16_m(sc, URTW_ATIM_WND, 2);
1864 urtw_write16_m(sc, URTW_ATIM_TR_ITV, 100);
1865 urtw_write16_m(sc, URTW_BEACON_INTERVAL, 0x64);
1866 urtw_write16_m(sc, URTW_BEACON_INTERVAL_TIME, 100);
1867 error = urtw_led_ctl(sc, URTW_LED_CTL_LINK);
1869 device_printf(sc->sc_dev,
1870 "could not control LED (%d)\n", error);
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)
1942 #define N(a) (sizeof(a) / sizeof((a)[0]))
1945 for (i = 0; i < N(urtw_ratetable); i++) {
1946 if (rate == urtw_ratetable[i].reg)
1947 return urtw_ratetable[i].val;
1955 urtw_rtl2rate(int rate)
1957 #define N(a) (sizeof(a) / sizeof((a)[0]))
1960 for (i = 0; i < N(urtw_ratetable); i++) {
1961 if (rate == urtw_ratetable[i].val)
1962 return urtw_ratetable[i].reg;
1970 urtw_update_msr(struct urtw_softc *sc)
1972 struct ifnet *ifp = sc->sc_ifp;
1973 struct ieee80211com *ic = ifp->if_l2com;
1977 urtw_read8_m(sc, URTW_MSR, &data);
1978 data &= ~URTW_MSR_LINK_MASK;
1980 if (sc->sc_state == IEEE80211_S_RUN) {
1981 switch (ic->ic_opmode) {
1982 case IEEE80211_M_STA:
1983 case IEEE80211_M_MONITOR:
1984 data |= URTW_MSR_LINK_STA;
1985 if (sc->sc_flags & URTW_RTL8187B)
1986 data |= URTW_MSR_LINK_ENEDCA;
1988 case IEEE80211_M_IBSS:
1989 data |= URTW_MSR_LINK_ADHOC;
1991 case IEEE80211_M_HOSTAP:
1992 data |= URTW_MSR_LINK_HOSTAP;
1995 panic("unsupported operation mode 0x%x\n",
2000 data |= URTW_MSR_LINK_NONE;
2002 urtw_write8_m(sc, URTW_MSR, data);
2008 urtw_read8_c(struct urtw_softc *sc, int val, uint8_t *data)
2010 struct usb_device_request req;
2013 URTW_ASSERT_LOCKED(sc);
2015 req.bmRequestType = UT_READ_VENDOR_DEVICE;
2016 req.bRequest = URTW_8187_GETREGS_REQ;
2017 USETW(req.wValue, (val & 0xff) | 0xff00);
2018 USETW(req.wIndex, (val >> 8) & 0x3);
2019 USETW(req.wLength, sizeof(uint8_t));
2021 error = urtw_do_request(sc, &req, data);
2026 urtw_read16_c(struct urtw_softc *sc, int val, uint16_t *data)
2028 struct usb_device_request req;
2031 URTW_ASSERT_LOCKED(sc);
2033 req.bmRequestType = UT_READ_VENDOR_DEVICE;
2034 req.bRequest = URTW_8187_GETREGS_REQ;
2035 USETW(req.wValue, (val & 0xff) | 0xff00);
2036 USETW(req.wIndex, (val >> 8) & 0x3);
2037 USETW(req.wLength, sizeof(uint16_t));
2039 error = urtw_do_request(sc, &req, data);
2044 urtw_read32_c(struct urtw_softc *sc, int val, uint32_t *data)
2046 struct usb_device_request req;
2049 URTW_ASSERT_LOCKED(sc);
2051 req.bmRequestType = UT_READ_VENDOR_DEVICE;
2052 req.bRequest = URTW_8187_GETREGS_REQ;
2053 USETW(req.wValue, (val & 0xff) | 0xff00);
2054 USETW(req.wIndex, (val >> 8) & 0x3);
2055 USETW(req.wLength, sizeof(uint32_t));
2057 error = urtw_do_request(sc, &req, data);
2062 urtw_write8_c(struct urtw_softc *sc, int val, uint8_t data)
2064 struct usb_device_request req;
2066 URTW_ASSERT_LOCKED(sc);
2068 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
2069 req.bRequest = URTW_8187_SETREGS_REQ;
2070 USETW(req.wValue, (val & 0xff) | 0xff00);
2071 USETW(req.wIndex, (val >> 8) & 0x3);
2072 USETW(req.wLength, sizeof(uint8_t));
2074 return (urtw_do_request(sc, &req, &data));
2078 urtw_write16_c(struct urtw_softc *sc, int val, uint16_t data)
2080 struct usb_device_request req;
2082 URTW_ASSERT_LOCKED(sc);
2084 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
2085 req.bRequest = URTW_8187_SETREGS_REQ;
2086 USETW(req.wValue, (val & 0xff) | 0xff00);
2087 USETW(req.wIndex, (val >> 8) & 0x3);
2088 USETW(req.wLength, sizeof(uint16_t));
2090 return (urtw_do_request(sc, &req, &data));
2094 urtw_write32_c(struct urtw_softc *sc, int val, uint32_t data)
2096 struct usb_device_request req;
2098 URTW_ASSERT_LOCKED(sc);
2100 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
2101 req.bRequest = URTW_8187_SETREGS_REQ;
2102 USETW(req.wValue, (val & 0xff) | 0xff00);
2103 USETW(req.wIndex, (val >> 8) & 0x3);
2104 USETW(req.wLength, sizeof(uint32_t));
2106 return (urtw_do_request(sc, &req, &data));
2110 urtw_get_macaddr(struct urtw_softc *sc)
2115 error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR, &data);
2118 sc->sc_bssid[0] = data & 0xff;
2119 sc->sc_bssid[1] = (data & 0xff00) >> 8;
2120 error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR + 1, &data);
2123 sc->sc_bssid[2] = data & 0xff;
2124 sc->sc_bssid[3] = (data & 0xff00) >> 8;
2125 error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR + 2, &data);
2128 sc->sc_bssid[4] = data & 0xff;
2129 sc->sc_bssid[5] = (data & 0xff00) >> 8;
2135 urtw_eprom_read32(struct urtw_softc *sc, uint32_t addr, uint32_t *data)
2137 #define URTW_READCMD_LEN 3
2139 int16_t addrstr[8], data16, readcmd[] = { 1, 1, 0 };
2142 /* NB: make sure the buffer is initialized */
2145 /* enable EPROM programming */
2146 urtw_write8_m(sc, URTW_EPROM_CMD, URTW_EPROM_CMD_PROGRAM_MODE);
2147 DELAY(URTW_EPROM_DELAY);
2149 error = urtw_eprom_cs(sc, URTW_EPROM_ENABLE);
2152 error = urtw_eprom_ck(sc);
2155 error = urtw_eprom_sendbits(sc, readcmd, URTW_READCMD_LEN);
2158 if (sc->sc_epromtype == URTW_EEPROM_93C56) {
2160 addrstr[0] = addr & (1 << 7);
2161 addrstr[1] = addr & (1 << 6);
2162 addrstr[2] = addr & (1 << 5);
2163 addrstr[3] = addr & (1 << 4);
2164 addrstr[4] = addr & (1 << 3);
2165 addrstr[5] = addr & (1 << 2);
2166 addrstr[6] = addr & (1 << 1);
2167 addrstr[7] = addr & (1 << 0);
2170 addrstr[0] = addr & (1 << 5);
2171 addrstr[1] = addr & (1 << 4);
2172 addrstr[2] = addr & (1 << 3);
2173 addrstr[3] = addr & (1 << 2);
2174 addrstr[4] = addr & (1 << 1);
2175 addrstr[5] = addr & (1 << 0);
2177 error = urtw_eprom_sendbits(sc, addrstr, addrlen);
2181 error = urtw_eprom_writebit(sc, 0);
2185 for (i = 0; i < 16; i++) {
2186 error = urtw_eprom_ck(sc);
2189 error = urtw_eprom_readbit(sc, &data16);
2193 (*data) |= (data16 << (15 - i));
2196 error = urtw_eprom_cs(sc, URTW_EPROM_DISABLE);
2199 error = urtw_eprom_ck(sc);
2203 /* now disable EPROM programming */
2204 urtw_write8_m(sc, URTW_EPROM_CMD, URTW_EPROM_CMD_NORMAL_MODE);
2207 #undef URTW_READCMD_LEN
2211 urtw_eprom_cs(struct urtw_softc *sc, int able)
2216 urtw_read8_m(sc, URTW_EPROM_CMD, &data);
2217 if (able == URTW_EPROM_ENABLE)
2218 urtw_write8_m(sc, URTW_EPROM_CMD, data | URTW_EPROM_CS);
2220 urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_CS);
2221 DELAY(URTW_EPROM_DELAY);
2227 urtw_eprom_ck(struct urtw_softc *sc)
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);
2237 urtw_read8_m(sc, URTW_EPROM_CMD, &data);
2238 urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_CK);
2239 DELAY(URTW_EPROM_DELAY);
2245 urtw_eprom_readbit(struct urtw_softc *sc, int16_t *data)
2250 urtw_read8_m(sc, URTW_EPROM_CMD, &data8);
2251 *data = (data8 & URTW_EPROM_READBIT) ? 1 : 0;
2252 DELAY(URTW_EPROM_DELAY);
2259 urtw_eprom_writebit(struct urtw_softc *sc, int16_t bit)
2264 urtw_read8_m(sc, URTW_EPROM_CMD, &data);
2266 urtw_write8_m(sc, URTW_EPROM_CMD, data | URTW_EPROM_WRITEBIT);
2268 urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_WRITEBIT);
2269 DELAY(URTW_EPROM_DELAY);
2275 urtw_eprom_sendbits(struct urtw_softc *sc, int16_t *buf, int buflen)
2278 usb_error_t error = 0;
2280 for (i = 0; i < buflen; i++) {
2281 error = urtw_eprom_writebit(sc, buf[i]);
2284 error = urtw_eprom_ck(sc);
2294 urtw_get_txpwr(struct urtw_softc *sc)
2300 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW_BASE, &data);
2303 sc->sc_txpwr_cck_base = data & 0xf;
2304 sc->sc_txpwr_ofdm_base = (data >> 4) & 0xf;
2306 for (i = 1, j = 0; i < 6; i += 2, j++) {
2307 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW0 + j, &data);
2310 sc->sc_txpwr_cck[i] = data & 0xf;
2311 sc->sc_txpwr_cck[i + 1] = (data & 0xf00) >> 8;
2312 sc->sc_txpwr_ofdm[i] = (data & 0xf0) >> 4;
2313 sc->sc_txpwr_ofdm[i + 1] = (data & 0xf000) >> 12;
2315 for (i = 1, j = 0; i < 4; i += 2, j++) {
2316 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW1 + j, &data);
2319 sc->sc_txpwr_cck[i + 6] = data & 0xf;
2320 sc->sc_txpwr_cck[i + 6 + 1] = (data & 0xf00) >> 8;
2321 sc->sc_txpwr_ofdm[i + 6] = (data & 0xf0) >> 4;
2322 sc->sc_txpwr_ofdm[i + 6 + 1] = (data & 0xf000) >> 12;
2324 if (sc->sc_flags & URTW_RTL8187B) {
2325 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW2, &data);
2328 sc->sc_txpwr_cck[1 + 6 + 4] = data & 0xf;
2329 sc->sc_txpwr_ofdm[1 + 6 + 4] = (data & 0xf0) >> 4;
2330 error = urtw_eprom_read32(sc, 0x0a, &data);
2333 sc->sc_txpwr_cck[2 + 6 + 4] = data & 0xf;
2334 sc->sc_txpwr_ofdm[2 + 6 + 4] = (data & 0xf0) >> 4;
2335 error = urtw_eprom_read32(sc, 0x1c, &data);
2338 sc->sc_txpwr_cck[3 + 6 + 4] = data & 0xf;
2339 sc->sc_txpwr_cck[3 + 6 + 4 + 1] = (data & 0xf00) >> 8;
2340 sc->sc_txpwr_ofdm[3 + 6 + 4] = (data & 0xf0) >> 4;
2341 sc->sc_txpwr_ofdm[3 + 6 + 4 + 1] = (data & 0xf000) >> 12;
2343 for (i = 1, j = 0; i < 4; i += 2, j++) {
2344 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW2 + j,
2348 sc->sc_txpwr_cck[i + 6 + 4] = data & 0xf;
2349 sc->sc_txpwr_cck[i + 6 + 4 + 1] = (data & 0xf00) >> 8;
2350 sc->sc_txpwr_ofdm[i + 6 + 4] = (data & 0xf0) >> 4;
2351 sc->sc_txpwr_ofdm[i + 6 + 4 + 1] = (data & 0xf000) >> 12;
2360 urtw_get_rfchip(struct urtw_softc *sc)
2367 if (sc->sc_flags & URTW_RTL8187B) {
2368 urtw_read8_m(sc, 0xe1, &data8);
2371 sc->sc_flags |= URTW_RTL8187B_REV_B;
2374 sc->sc_flags |= URTW_RTL8187B_REV_D;
2377 sc->sc_flags |= URTW_RTL8187B_REV_E;
2380 device_printf(sc->sc_dev, "unknown type: %#x\n", data8);
2381 sc->sc_flags |= URTW_RTL8187B_REV_B;
2385 urtw_read32_m(sc, URTW_TX_CONF, &data);
2386 switch (data & URTW_TX_HWMASK) {
2387 case URTW_TX_R8187vD_B:
2388 sc->sc_flags |= URTW_RTL8187B;
2390 case URTW_TX_R8187vD:
2393 device_printf(sc->sc_dev, "unknown RTL8187L type: %#x\n",
2394 data & URTW_TX_HWMASK);
2399 error = urtw_eprom_read32(sc, URTW_EPROM_RFCHIPID, &data);
2402 switch (data & 0xff) {
2403 case URTW_EPROM_RFCHIPID_RTL8225U:
2404 error = urtw_8225_isv2(sc, &ret);
2408 sc->sc_rf_init = urtw_8225_rf_init;
2409 sc->sc_rf_set_sens = urtw_8225_rf_set_sens;
2410 sc->sc_rf_set_chan = urtw_8225_rf_set_chan;
2411 sc->sc_rf_stop = urtw_8225_rf_stop;
2413 sc->sc_rf_init = urtw_8225v2_rf_init;
2414 sc->sc_rf_set_chan = urtw_8225v2_rf_set_chan;
2415 sc->sc_rf_stop = urtw_8225_rf_stop;
2417 sc->sc_max_sens = URTW_8225_RF_MAX_SENS;
2418 sc->sc_sens = URTW_8225_RF_DEF_SENS;
2420 case URTW_EPROM_RFCHIPID_RTL8225Z2:
2421 sc->sc_rf_init = urtw_8225v2b_rf_init;
2422 sc->sc_rf_set_chan = urtw_8225v2b_rf_set_chan;
2423 sc->sc_max_sens = URTW_8225_RF_MAX_SENS;
2424 sc->sc_sens = URTW_8225_RF_DEF_SENS;
2425 sc->sc_rf_stop = urtw_8225_rf_stop;
2428 panic("unsupported RF chip %d\n", data & 0xff);
2432 device_printf(sc->sc_dev, "%s rf %s hwrev %s\n",
2433 (sc->sc_flags & URTW_RTL8187B) ? "rtl8187b" : "rtl8187l",
2434 ((data & 0xff) == URTW_EPROM_RFCHIPID_RTL8225U) ? "rtl8225u" :
2436 (sc->sc_flags & URTW_RTL8187B) ? ((data8 == 0) ? "b" :
2437 (data8 == 1) ? "d" : "e") : "none");
2445 urtw_led_init(struct urtw_softc *sc)
2450 urtw_read8_m(sc, URTW_PSR, &sc->sc_psr);
2451 error = urtw_eprom_read32(sc, URTW_EPROM_SWREV, &rev);
2455 switch (rev & URTW_EPROM_CID_MASK) {
2456 case URTW_EPROM_CID_ALPHA0:
2457 sc->sc_strategy = URTW_SW_LED_MODE1;
2459 case URTW_EPROM_CID_SERCOMM_PS:
2460 sc->sc_strategy = URTW_SW_LED_MODE3;
2462 case URTW_EPROM_CID_HW_LED:
2463 sc->sc_strategy = URTW_HW_LED;
2465 case URTW_EPROM_CID_RSVD0:
2466 case URTW_EPROM_CID_RSVD1:
2468 sc->sc_strategy = URTW_SW_LED_MODE0;
2472 sc->sc_gpio_ledpin = URTW_LED_PIN_GPIO0;
2480 urtw_8225_rf_init(struct urtw_softc *sc)
2482 #define N(a) (sizeof(a) / sizeof((a)[0]))
2487 error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
2491 error = urtw_8225_usb_init(sc);
2495 urtw_write32_m(sc, URTW_RF_TIMING, 0x000a8008);
2496 urtw_read16_m(sc, URTW_BRSR, &data); /* XXX ??? */
2497 urtw_write16_m(sc, URTW_BRSR, 0xffff);
2498 urtw_write32_m(sc, URTW_RF_PARA, 0x100044);
2500 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
2503 urtw_write8_m(sc, URTW_CONFIG3, 0x44);
2504 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
2508 error = urtw_8185_rf_pins_enable(sc);
2511 usb_pause_mtx(&sc->sc_mtx, 1000);
2513 for (i = 0; i < N(urtw_8225_rf_part1); i++) {
2514 urtw_8225_write(sc, urtw_8225_rf_part1[i].reg,
2515 urtw_8225_rf_part1[i].val);
2516 usb_pause_mtx(&sc->sc_mtx, 1);
2518 usb_pause_mtx(&sc->sc_mtx, 100);
2520 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC1);
2521 usb_pause_mtx(&sc->sc_mtx, 200);
2523 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC2);
2524 usb_pause_mtx(&sc->sc_mtx, 200);
2526 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC3);
2528 for (i = 0; i < 95; i++) {
2529 urtw_8225_write(sc, URTW_8225_ADDR_1_MAGIC, (uint8_t)(i + 1));
2530 urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC, urtw_8225_rxgain[i]);
2534 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC4);
2536 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC5);
2538 for (i = 0; i < 128; i++) {
2539 urtw_8187_write_phy_ofdm(sc, 0xb, urtw_8225_agc[i]);
2540 usb_pause_mtx(&sc->sc_mtx, 1);
2541 urtw_8187_write_phy_ofdm(sc, 0xa, (uint8_t)i + 0x80);
2542 usb_pause_mtx(&sc->sc_mtx, 1);
2545 for (i = 0; i < N(urtw_8225_rf_part2); i++) {
2546 urtw_8187_write_phy_ofdm(sc, urtw_8225_rf_part2[i].reg,
2547 urtw_8225_rf_part2[i].val);
2548 usb_pause_mtx(&sc->sc_mtx, 1);
2551 error = urtw_8225_setgain(sc, 4);
2555 for (i = 0; i < N(urtw_8225_rf_part3); i++) {
2556 urtw_8187_write_phy_cck(sc, urtw_8225_rf_part3[i].reg,
2557 urtw_8225_rf_part3[i].val);
2558 usb_pause_mtx(&sc->sc_mtx, 1);
2561 urtw_write8_m(sc, URTW_TESTR, 0x0d);
2563 error = urtw_8225_set_txpwrlvl(sc, 1);
2567 urtw_8187_write_phy_cck(sc, 0x10, 0x9b);
2568 usb_pause_mtx(&sc->sc_mtx, 1);
2569 urtw_8187_write_phy_ofdm(sc, 0x26, 0x90);
2570 usb_pause_mtx(&sc->sc_mtx, 1);
2572 /* TX ant A, 0x0 for B */
2573 error = urtw_8185_tx_antenna(sc, 0x3);
2576 urtw_write32_m(sc, URTW_HSSI_PARA, 0x3dc00002);
2578 error = urtw_8225_rf_set_chan(sc, 1);
2585 urtw_8185_rf_pins_enable(struct urtw_softc *sc)
2587 usb_error_t error = 0;
2589 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x1ff7);
2595 urtw_8185_tx_antenna(struct urtw_softc *sc, uint8_t ant)
2599 urtw_write8_m(sc, URTW_TX_ANTENNA, ant);
2600 usb_pause_mtx(&sc->sc_mtx, 1);
2606 urtw_8187_write_phy_ofdm_c(struct urtw_softc *sc, uint8_t addr, uint32_t data)
2610 return urtw_8187_write_phy(sc, addr, data);
2614 urtw_8187_write_phy_cck_c(struct urtw_softc *sc, uint8_t addr, uint32_t data)
2618 return urtw_8187_write_phy(sc, addr, data | 0x10000);
2622 urtw_8187_write_phy(struct urtw_softc *sc, uint8_t addr, uint32_t data)
2627 phyw = ((data << 8) | (addr | 0x80));
2628 urtw_write8_m(sc, URTW_PHY_MAGIC4, ((phyw & 0xff000000) >> 24));
2629 urtw_write8_m(sc, URTW_PHY_MAGIC3, ((phyw & 0x00ff0000) >> 16));
2630 urtw_write8_m(sc, URTW_PHY_MAGIC2, ((phyw & 0x0000ff00) >> 8));
2631 urtw_write8_m(sc, URTW_PHY_MAGIC1, ((phyw & 0x000000ff)));
2632 usb_pause_mtx(&sc->sc_mtx, 1);
2638 urtw_8225_setgain(struct urtw_softc *sc, int16_t gain)
2642 urtw_8187_write_phy_ofdm(sc, 0x0d, urtw_8225_gain[gain * 4]);
2643 urtw_8187_write_phy_ofdm(sc, 0x1b, urtw_8225_gain[gain * 4 + 2]);
2644 urtw_8187_write_phy_ofdm(sc, 0x1d, urtw_8225_gain[gain * 4 + 3]);
2645 urtw_8187_write_phy_ofdm(sc, 0x23, urtw_8225_gain[gain * 4 + 1]);
2651 urtw_8225_usb_init(struct urtw_softc *sc)
2656 urtw_write8_m(sc, URTW_RF_PINS_SELECT + 1, 0);
2657 urtw_write8_m(sc, URTW_GPIO, 0);
2658 error = urtw_read8e(sc, 0x53, &data);
2661 error = urtw_write8e(sc, 0x53, data | (1 << 7));
2664 urtw_write8_m(sc, URTW_RF_PINS_SELECT + 1, 4);
2665 urtw_write8_m(sc, URTW_GPIO, 0x20);
2666 urtw_write8_m(sc, URTW_GP_ENABLE, 0);
2668 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, 0x80);
2669 urtw_write16_m(sc, URTW_RF_PINS_SELECT, 0x80);
2670 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x80);
2672 usb_pause_mtx(&sc->sc_mtx, 500);
2678 urtw_8225_write_c(struct urtw_softc *sc, uint8_t addr, uint16_t data)
2680 uint16_t d80, d82, d84;
2683 urtw_read16_m(sc, URTW_RF_PINS_OUTPUT, &d80);
2684 d80 &= URTW_RF_PINS_MAGIC1;
2685 urtw_read16_m(sc, URTW_RF_PINS_ENABLE, &d82);
2686 urtw_read16_m(sc, URTW_RF_PINS_SELECT, &d84);
2687 d84 &= URTW_RF_PINS_MAGIC2;
2688 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, d82 | URTW_RF_PINS_MAGIC3);
2689 urtw_write16_m(sc, URTW_RF_PINS_SELECT, d84 | URTW_RF_PINS_MAGIC3);
2692 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80 | URTW_BB_HOST_BANG_EN);
2694 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80);
2697 error = urtw_8225_write_s16(sc, addr, 0x8225, &data);
2701 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80 | URTW_BB_HOST_BANG_EN);
2703 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80 | URTW_BB_HOST_BANG_EN);
2704 urtw_write16_m(sc, URTW_RF_PINS_SELECT, d84);
2705 usb_pause_mtx(&sc->sc_mtx, 2);
2710 /* XXX why we should allocalte memory buffer instead of using memory stack? */
2712 urtw_8225_write_s16(struct urtw_softc *sc, uint8_t addr, int index,
2717 struct usb_device_request *req;
2718 usb_error_t error = 0;
2721 req = (usb_device_request_t *)malloc(sizeof(usb_device_request_t),
2722 M_80211_VAP, M_NOWAIT | M_ZERO);
2724 device_printf(sc->sc_dev, "could not allocate a memory\n");
2727 buf = (uint8_t *)malloc(2, M_80211_VAP, M_NOWAIT | M_ZERO);
2729 device_printf(sc->sc_dev, "could not allocate a memory\n");
2733 req->bmRequestType = UT_WRITE_VENDOR_DEVICE;
2734 req->bRequest = URTW_8187_SETREGS_REQ;
2735 USETW(req->wValue, addr);
2736 USETW(req->wIndex, index);
2737 USETW(req->wLength, sizeof(uint16_t));
2738 buf[0] = (data16 & 0x00ff);
2739 buf[1] = (data16 & 0xff00) >> 8;
2741 error = urtw_do_request(sc, req, buf);
2743 free(buf, M_80211_VAP);
2744 fail1: free(req, M_80211_VAP);
2745 fail0: return (error);
2749 urtw_8225_rf_set_chan(struct urtw_softc *sc, int chan)
2753 error = urtw_8225_set_txpwrlvl(sc, chan);
2756 urtw_8225_write(sc, URTW_8225_ADDR_7_MAGIC, urtw_8225_channel[chan]);
2757 usb_pause_mtx(&sc->sc_mtx, 10);
2763 urtw_8225_rf_set_sens(struct urtw_softc *sc, int sens)
2767 if (sens < 0 || sens > 6)
2772 URTW_8225_ADDR_C_MAGIC, URTW_8225_ADDR_C_DATA_MAGIC1);
2775 URTW_8225_ADDR_C_MAGIC, URTW_8225_ADDR_C_DATA_MAGIC2);
2778 error = urtw_8225_setgain(sc, sens);
2782 urtw_8187_write_phy_cck(sc, 0x41, urtw_8225_threshold[sens]);
2789 urtw_8225_set_txpwrlvl(struct urtw_softc *sc, int chan)
2792 uint8_t *cck_pwltable;
2793 uint8_t cck_pwrlvl_max, ofdm_pwrlvl_min, ofdm_pwrlvl_max;
2794 uint8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
2795 uint8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
2798 cck_pwrlvl_max = 11;
2799 ofdm_pwrlvl_max = 25; /* 12 -> 25 */
2800 ofdm_pwrlvl_min = 10;
2802 /* CCK power setting */
2803 cck_pwrlvl = (cck_pwrlvl > cck_pwrlvl_max) ? cck_pwrlvl_max : cck_pwrlvl;
2804 idx = cck_pwrlvl % 6;
2805 set = cck_pwrlvl / 6;
2806 cck_pwltable = (chan == 14) ? urtw_8225_txpwr_cck_ch14 :
2807 urtw_8225_txpwr_cck;
2809 urtw_write8_m(sc, URTW_TX_GAIN_CCK,
2810 urtw_8225_tx_gain_cck_ofdm[set] >> 1);
2811 for (i = 0; i < 8; i++) {
2812 urtw_8187_write_phy_cck(sc, 0x44 + i,
2813 cck_pwltable[idx * 8 + i]);
2815 usb_pause_mtx(&sc->sc_mtx, 1);
2817 /* OFDM power setting */
2818 ofdm_pwrlvl = (ofdm_pwrlvl > (ofdm_pwrlvl_max - ofdm_pwrlvl_min)) ?
2819 ofdm_pwrlvl_max : ofdm_pwrlvl + ofdm_pwrlvl_min;
2820 ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
2822 idx = ofdm_pwrlvl % 6;
2823 set = ofdm_pwrlvl / 6;
2825 error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
2828 urtw_8187_write_phy_ofdm(sc, 2, 0x42);
2829 urtw_8187_write_phy_ofdm(sc, 6, 0);
2830 urtw_8187_write_phy_ofdm(sc, 8, 0);
2832 urtw_write8_m(sc, URTW_TX_GAIN_OFDM,
2833 urtw_8225_tx_gain_cck_ofdm[set] >> 1);
2834 urtw_8187_write_phy_ofdm(sc, 0x5, urtw_8225_txpwr_ofdm[idx]);
2835 urtw_8187_write_phy_ofdm(sc, 0x7, urtw_8225_txpwr_ofdm[idx]);
2836 usb_pause_mtx(&sc->sc_mtx, 1);
2843 urtw_8225_rf_stop(struct urtw_softc *sc)
2848 urtw_8225_write(sc, 0x4, 0x1f);
2850 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
2854 urtw_read8_m(sc, URTW_CONFIG3, &data);
2855 urtw_write8_m(sc, URTW_CONFIG3, data | URTW_CONFIG3_ANAPARAM_WRITE);
2856 if (sc->sc_flags & URTW_RTL8187B) {
2857 urtw_write32_m(sc, URTW_ANAPARAM2,
2858 URTW_8187B_8225_ANAPARAM2_OFF);
2859 urtw_write32_m(sc, URTW_ANAPARAM, URTW_8187B_8225_ANAPARAM_OFF);
2860 urtw_write32_m(sc, URTW_ANAPARAM3,
2861 URTW_8187B_8225_ANAPARAM3_OFF);
2863 urtw_write32_m(sc, URTW_ANAPARAM2, URTW_8225_ANAPARAM2_OFF);
2864 urtw_write32_m(sc, URTW_ANAPARAM, URTW_8225_ANAPARAM_OFF);
2867 urtw_write8_m(sc, URTW_CONFIG3, data & ~URTW_CONFIG3_ANAPARAM_WRITE);
2868 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
2877 urtw_8225v2_rf_init(struct urtw_softc *sc)
2879 #define N(a) (sizeof(a) / sizeof((a)[0]))
2885 error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
2889 error = urtw_8225_usb_init(sc);
2893 urtw_write32_m(sc, URTW_RF_TIMING, 0x000a8008);
2894 urtw_read16_m(sc, URTW_BRSR, &data); /* XXX ??? */
2895 urtw_write16_m(sc, URTW_BRSR, 0xffff);
2896 urtw_write32_m(sc, URTW_RF_PARA, 0x100044);
2898 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
2901 urtw_write8_m(sc, URTW_CONFIG3, 0x44);
2902 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
2906 error = urtw_8185_rf_pins_enable(sc);
2910 usb_pause_mtx(&sc->sc_mtx, 500);
2912 for (i = 0; i < N(urtw_8225v2_rf_part1); i++) {
2913 urtw_8225_write(sc, urtw_8225v2_rf_part1[i].reg,
2914 urtw_8225v2_rf_part1[i].val);
2916 usb_pause_mtx(&sc->sc_mtx, 50);
2919 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC1);
2921 for (i = 0; i < 95; i++) {
2922 urtw_8225_write(sc, URTW_8225_ADDR_1_MAGIC, (uint8_t)(i + 1));
2923 urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC,
2924 urtw_8225v2_rxgain[i]);
2928 URTW_8225_ADDR_3_MAGIC, URTW_8225_ADDR_3_DATA_MAGIC1);
2930 URTW_8225_ADDR_5_MAGIC, URTW_8225_ADDR_5_DATA_MAGIC1);
2932 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC2);
2934 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC1);
2935 usb_pause_mtx(&sc->sc_mtx, 100);
2937 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC2);
2938 usb_pause_mtx(&sc->sc_mtx, 100);
2940 error = urtw_8225_read(sc, URTW_8225_ADDR_6_MAGIC, &data32);
2943 if (data32 != URTW_8225_ADDR_6_DATA_MAGIC1)
2944 device_printf(sc->sc_dev, "expect 0xe6!! (0x%x)\n", data32);
2945 if (!(data32 & URTW_8225_ADDR_6_DATA_MAGIC2)) {
2947 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC1);
2948 usb_pause_mtx(&sc->sc_mtx, 100);
2950 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC2);
2951 usb_pause_mtx(&sc->sc_mtx, 50);
2952 error = urtw_8225_read(sc, URTW_8225_ADDR_6_MAGIC, &data32);
2955 if (!(data32 & URTW_8225_ADDR_6_DATA_MAGIC2))
2956 device_printf(sc->sc_dev, "RF calibration failed\n");
2958 usb_pause_mtx(&sc->sc_mtx, 100);
2961 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC6);
2962 for (i = 0; i < 128; i++) {
2963 urtw_8187_write_phy_ofdm(sc, 0xb, urtw_8225_agc[i]);
2964 urtw_8187_write_phy_ofdm(sc, 0xa, (uint8_t)i + 0x80);
2967 for (i = 0; i < N(urtw_8225v2_rf_part2); i++) {
2968 urtw_8187_write_phy_ofdm(sc, urtw_8225v2_rf_part2[i].reg,
2969 urtw_8225v2_rf_part2[i].val);
2972 error = urtw_8225v2_setgain(sc, 4);
2976 for (i = 0; i < N(urtw_8225v2_rf_part3); i++) {
2977 urtw_8187_write_phy_cck(sc, urtw_8225v2_rf_part3[i].reg,
2978 urtw_8225v2_rf_part3[i].val);
2981 urtw_write8_m(sc, URTW_TESTR, 0x0d);
2983 error = urtw_8225v2_set_txpwrlvl(sc, 1);
2987 urtw_8187_write_phy_cck(sc, 0x10, 0x9b);
2988 urtw_8187_write_phy_ofdm(sc, 0x26, 0x90);
2990 /* TX ant A, 0x0 for B */
2991 error = urtw_8185_tx_antenna(sc, 0x3);
2994 urtw_write32_m(sc, URTW_HSSI_PARA, 0x3dc00002);
2996 error = urtw_8225_rf_set_chan(sc, 1);
3003 urtw_8225v2_rf_set_chan(struct urtw_softc *sc, int chan)
3007 error = urtw_8225v2_set_txpwrlvl(sc, chan);
3011 urtw_8225_write(sc, URTW_8225_ADDR_7_MAGIC, urtw_8225_channel[chan]);
3012 usb_pause_mtx(&sc->sc_mtx, 10);
3018 urtw_8225_read(struct urtw_softc *sc, uint8_t addr, uint32_t *data)
3022 uint8_t rlen = 12, wlen = 6;
3023 uint16_t o1, o2, o3, tmp;
3024 uint32_t d2w = ((uint32_t)(addr & 0x1f)) << 27;
3025 uint32_t mask = 0x80000000, value = 0;
3028 urtw_read16_m(sc, URTW_RF_PINS_OUTPUT, &o1);
3029 urtw_read16_m(sc, URTW_RF_PINS_ENABLE, &o2);
3030 urtw_read16_m(sc, URTW_RF_PINS_SELECT, &o3);
3031 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, o2 | URTW_RF_PINS_MAGIC4);
3032 urtw_write16_m(sc, URTW_RF_PINS_SELECT, o3 | URTW_RF_PINS_MAGIC4);
3033 o1 &= ~URTW_RF_PINS_MAGIC4;
3034 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1 | URTW_BB_HOST_BANG_EN);
3036 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1);
3039 for (i = 0; i < (wlen / 2); i++, mask = mask >> 1) {
3040 bit = ((d2w & mask) != 0) ? 1 : 0;
3042 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1);
3044 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
3045 URTW_BB_HOST_BANG_CLK);
3047 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
3048 URTW_BB_HOST_BANG_CLK);
3053 bit = ((d2w & mask) != 0) ? 1 : 0;
3054 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
3055 URTW_BB_HOST_BANG_CLK);
3057 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
3058 URTW_BB_HOST_BANG_CLK);
3060 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1);
3063 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 | URTW_BB_HOST_BANG_RW |
3064 URTW_BB_HOST_BANG_CLK);
3066 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 | URTW_BB_HOST_BANG_RW);
3068 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1 | URTW_BB_HOST_BANG_RW);
3072 for (i = 0; i < rlen; i++, mask = mask >> 1) {
3073 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
3074 o1 | URTW_BB_HOST_BANG_RW);
3076 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
3077 o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK);
3079 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
3080 o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK);
3082 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
3083 o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK);
3086 urtw_read16_m(sc, URTW_RF_PINS_INPUT, &tmp);
3087 value |= ((tmp & URTW_BB_HOST_BANG_CLK) ? mask : 0);
3088 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
3089 o1 | URTW_BB_HOST_BANG_RW);
3093 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1 | URTW_BB_HOST_BANG_EN |
3094 URTW_BB_HOST_BANG_RW);
3097 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, o2);
3098 urtw_write16_m(sc, URTW_RF_PINS_SELECT, o3);
3099 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, URTW_RF_PINS_OUTPUT_MAGIC1);
3109 urtw_8225v2_set_txpwrlvl(struct urtw_softc *sc, int chan)
3112 uint8_t *cck_pwrtable;
3113 uint8_t cck_pwrlvl_max = 15, ofdm_pwrlvl_max = 25, ofdm_pwrlvl_min = 10;
3114 uint8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
3115 uint8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
3118 /* CCK power setting */
3119 cck_pwrlvl = (cck_pwrlvl > cck_pwrlvl_max) ? cck_pwrlvl_max : cck_pwrlvl;
3120 cck_pwrlvl += sc->sc_txpwr_cck_base;
3121 cck_pwrlvl = (cck_pwrlvl > 35) ? 35 : cck_pwrlvl;
3122 cck_pwrtable = (chan == 14) ? urtw_8225v2_txpwr_cck_ch14 :
3123 urtw_8225v2_txpwr_cck;
3125 for (i = 0; i < 8; i++)
3126 urtw_8187_write_phy_cck(sc, 0x44 + i, cck_pwrtable[i]);
3128 urtw_write8_m(sc, URTW_TX_GAIN_CCK,
3129 urtw_8225v2_tx_gain_cck_ofdm[cck_pwrlvl]);
3130 usb_pause_mtx(&sc->sc_mtx, 1);
3132 /* OFDM power setting */
3133 ofdm_pwrlvl = (ofdm_pwrlvl > (ofdm_pwrlvl_max - ofdm_pwrlvl_min)) ?
3134 ofdm_pwrlvl_max : ofdm_pwrlvl + ofdm_pwrlvl_min;
3135 ofdm_pwrlvl += sc->sc_txpwr_ofdm_base;
3136 ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
3138 error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
3142 urtw_8187_write_phy_ofdm(sc, 2, 0x42);
3143 urtw_8187_write_phy_ofdm(sc, 5, 0x0);
3144 urtw_8187_write_phy_ofdm(sc, 6, 0x40);
3145 urtw_8187_write_phy_ofdm(sc, 7, 0x0);
3146 urtw_8187_write_phy_ofdm(sc, 8, 0x40);
3148 urtw_write8_m(sc, URTW_TX_GAIN_OFDM,
3149 urtw_8225v2_tx_gain_cck_ofdm[ofdm_pwrlvl]);
3150 usb_pause_mtx(&sc->sc_mtx, 1);
3156 urtw_8225v2_setgain(struct urtw_softc *sc, int16_t gain)
3162 gainp = urtw_8225v2_gain_bg;
3163 urtw_8187_write_phy_ofdm(sc, 0x0d, gainp[gain * 3]);
3164 usb_pause_mtx(&sc->sc_mtx, 1);
3165 urtw_8187_write_phy_ofdm(sc, 0x1b, gainp[gain * 3 + 1]);
3166 usb_pause_mtx(&sc->sc_mtx, 1);
3167 urtw_8187_write_phy_ofdm(sc, 0x1d, gainp[gain * 3 + 2]);
3168 usb_pause_mtx(&sc->sc_mtx, 1);
3169 urtw_8187_write_phy_ofdm(sc, 0x21, 0x17);
3170 usb_pause_mtx(&sc->sc_mtx, 1);
3176 urtw_8225_isv2(struct urtw_softc *sc, int *ret)
3183 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, URTW_RF_PINS_MAGIC5);
3184 urtw_write16_m(sc, URTW_RF_PINS_SELECT, URTW_RF_PINS_MAGIC5);
3185 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, URTW_RF_PINS_MAGIC5);
3186 usb_pause_mtx(&sc->sc_mtx, 500);
3188 urtw_8225_write(sc, URTW_8225_ADDR_0_MAGIC,
3189 URTW_8225_ADDR_0_DATA_MAGIC1);
3191 error = urtw_8225_read(sc, URTW_8225_ADDR_8_MAGIC, &data);
3194 if (data != URTW_8225_ADDR_8_DATA_MAGIC1)
3197 error = urtw_8225_read(sc, URTW_8225_ADDR_9_MAGIC, &data);
3200 if (data != URTW_8225_ADDR_9_DATA_MAGIC1)
3204 urtw_8225_write(sc, URTW_8225_ADDR_0_MAGIC,
3205 URTW_8225_ADDR_0_DATA_MAGIC2);
3211 urtw_8225v2b_rf_init(struct urtw_softc *sc)
3213 #define N(a) (sizeof(a) / sizeof((a)[0]))
3218 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3223 * initialize extra registers on 8187
3225 urtw_write16_m(sc, URTW_BRSR_8187B, 0xfff);
3228 urtw_read8_m(sc, URTW_CW_CONF, &data8);
3229 data8 |= URTW_CW_CONF_PERPACKET_RETRY;
3230 urtw_write8_m(sc, URTW_CW_CONF, data8);
3233 urtw_read8_m(sc, URTW_TX_AGC_CTL, &data8);
3234 data8 |= URTW_TX_AGC_CTL_PERPACKET_GAIN;
3235 urtw_write8_m(sc, URTW_TX_AGC_CTL, data8);
3237 /* Auto Rate Fallback Control */
3238 #define URTW_ARFR 0x1e0
3239 urtw_write16_m(sc, URTW_ARFR, 0xfff);
3240 urtw_read8_m(sc, URTW_RATE_FALLBACK, &data8);
3241 urtw_write8_m(sc, URTW_RATE_FALLBACK,
3242 data8 | URTW_RATE_FALLBACK_ENABLE);
3244 urtw_read8_m(sc, URTW_MSR, &data8);
3245 urtw_write8_m(sc, URTW_MSR, data8 & 0xf3);
3246 urtw_read8_m(sc, URTW_MSR, &data8);
3247 urtw_write8_m(sc, URTW_MSR, data8 | URTW_MSR_LINK_ENEDCA);
3248 urtw_write8_m(sc, URTW_ACM_CONTROL, sc->sc_acmctl);
3250 urtw_write16_m(sc, URTW_ATIM_WND, 2);
3251 urtw_write16_m(sc, URTW_BEACON_INTERVAL, 100);
3252 #define URTW_FEMR_FOR_8187B 0x1d4
3253 urtw_write16_m(sc, URTW_FEMR_FOR_8187B, 0xffff);
3256 urtw_read8_m(sc, URTW_CONFIG1, &data8);
3257 data8 = (data8 & 0x3f) | 0x80;
3258 urtw_write8_m(sc, URTW_CONFIG1, data8);
3260 /* applying MAC address again. */
3261 urtw_write32_m(sc, URTW_MAC0, ((uint32_t *)sc->sc_bssid)[0]);
3262 urtw_write16_m(sc, URTW_MAC4, ((uint32_t *)sc->sc_bssid)[1] & 0xffff);
3264 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3268 urtw_write8_m(sc, URTW_WPA_CONFIG, 0);
3273 for (i = 0; i < N(urtw_8225v2b_rf_part1); i++)
3274 urtw_write8_m(sc, urtw_8225v2b_rf_part1[i].reg,
3275 urtw_8225v2b_rf_part1[i].val);
3276 urtw_write16_m(sc, URTW_TID_AC_MAP, 0xfa50);
3277 urtw_write16_m(sc, URTW_INT_MIG, 0x0000);
3278 urtw_write32_m(sc, 0x1f0, 0);
3279 urtw_write32_m(sc, 0x1f4, 0);
3280 urtw_write8_m(sc, 0x1f8, 0);
3281 urtw_write32_m(sc, URTW_RF_TIMING, 0x4001);
3283 #define URTW_RFSW_CTRL 0x272
3284 urtw_write16_m(sc, URTW_RFSW_CTRL, 0x569a);
3289 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3292 urtw_read8_m(sc, URTW_CONFIG3, &data8);
3293 urtw_write8_m(sc, URTW_CONFIG3,
3294 data8 | URTW_CONFIG3_ANAPARAM_WRITE);
3296 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3300 /* setup RFE initial timing */
3301 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, 0x0480);
3302 urtw_write16_m(sc, URTW_RF_PINS_SELECT, 0x2488);
3303 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x1fff);
3304 usb_pause_mtx(&sc->sc_mtx, 1100);
3306 for (i = 0; i < N(urtw_8225v2b_rf_part0); i++) {
3307 urtw_8225_write(sc, urtw_8225v2b_rf_part0[i].reg,
3308 urtw_8225v2b_rf_part0[i].val);
3309 usb_pause_mtx(&sc->sc_mtx, 1);
3311 urtw_8225_write(sc, 0x00, 0x01b7);
3313 for (i = 0; i < 95; i++) {
3314 urtw_8225_write(sc, URTW_8225_ADDR_1_MAGIC, (uint8_t)(i + 1));
3315 usb_pause_mtx(&sc->sc_mtx, 1);
3316 urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC,
3317 urtw_8225v2b_rxgain[i]);
3318 usb_pause_mtx(&sc->sc_mtx, 1);
3321 urtw_8225_write(sc, URTW_8225_ADDR_3_MAGIC, 0x080);
3322 usb_pause_mtx(&sc->sc_mtx, 1);
3323 urtw_8225_write(sc, URTW_8225_ADDR_5_MAGIC, 0x004);
3324 usb_pause_mtx(&sc->sc_mtx, 1);
3325 urtw_8225_write(sc, URTW_8225_ADDR_0_MAGIC, 0x0b7);
3326 usb_pause_mtx(&sc->sc_mtx, 1);
3327 usb_pause_mtx(&sc->sc_mtx, 3000);
3328 urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC, 0xc4d);
3329 usb_pause_mtx(&sc->sc_mtx, 2000);
3330 urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC, 0x44d);
3331 usb_pause_mtx(&sc->sc_mtx, 1);
3332 urtw_8225_write(sc, URTW_8225_ADDR_0_MAGIC, 0x2bf);
3333 usb_pause_mtx(&sc->sc_mtx, 1);
3335 urtw_write8_m(sc, URTW_TX_GAIN_CCK, 0x03);
3336 urtw_write8_m(sc, URTW_TX_GAIN_OFDM, 0x07);
3337 urtw_write8_m(sc, URTW_TX_ANTENNA, 0x03);
3339 urtw_8187_write_phy_ofdm(sc, 0x80, 0x12);
3340 for (i = 0; i < 128; i++) {
3341 uint32_t addr, data;
3343 data = (urtw_8225z2_agc[i] << 8) | 0x0000008f;
3344 addr = ((i + 0x80) << 8) | 0x0000008e;
3346 urtw_8187_write_phy_ofdm(sc, data & 0x7f, (data >> 8) & 0xff);
3347 urtw_8187_write_phy_ofdm(sc, addr & 0x7f, (addr >> 8) & 0xff);
3348 urtw_8187_write_phy_ofdm(sc, 0x0e, 0x00);
3350 urtw_8187_write_phy_ofdm(sc, 0x80, 0x10);
3352 for (i = 0; i < N(urtw_8225v2b_rf_part2); i++)
3353 urtw_8187_write_phy_ofdm(sc, i, urtw_8225v2b_rf_part2[i].val);
3355 urtw_write32_m(sc, URTW_8187B_AC_VO, (7 << 12) | (3 << 8) | 0x1c);
3356 urtw_write32_m(sc, URTW_8187B_AC_VI, (7 << 12) | (3 << 8) | 0x1c);
3357 urtw_write32_m(sc, URTW_8187B_AC_BE, (7 << 12) | (3 << 8) | 0x1c);
3358 urtw_write32_m(sc, URTW_8187B_AC_BK, (7 << 12) | (3 << 8) | 0x1c);
3360 urtw_8187_write_phy_ofdm(sc, 0x97, 0x46);
3361 urtw_8187_write_phy_ofdm(sc, 0xa4, 0xb6);
3362 urtw_8187_write_phy_ofdm(sc, 0x85, 0xfc);
3363 urtw_8187_write_phy_cck(sc, 0xc1, 0x88);
3371 urtw_8225v2b_rf_set_chan(struct urtw_softc *sc, int chan)
3375 error = urtw_8225v2b_set_txpwrlvl(sc, chan);
3379 urtw_8225_write(sc, URTW_8225_ADDR_7_MAGIC, urtw_8225_channel[chan]);
3380 usb_pause_mtx(&sc->sc_mtx, 10);
3386 urtw_8225v2b_set_txpwrlvl(struct urtw_softc *sc, int chan)
3389 uint8_t *cck_pwrtable;
3390 uint8_t cck_pwrlvl_max = 15;
3391 uint8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
3392 uint8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
3395 /* CCK power setting */
3396 cck_pwrlvl = (cck_pwrlvl > cck_pwrlvl_max) ?
3397 ((sc->sc_flags & URTW_RTL8187B_REV_B) ? cck_pwrlvl_max : 22) :
3398 (cck_pwrlvl + ((sc->sc_flags & URTW_RTL8187B_REV_B) ? 0 : 7));
3399 cck_pwrlvl += sc->sc_txpwr_cck_base;
3400 cck_pwrlvl = (cck_pwrlvl > 35) ? 35 : cck_pwrlvl;
3401 cck_pwrtable = (chan == 14) ? urtw_8225v2b_txpwr_cck_ch14 :
3402 urtw_8225v2b_txpwr_cck;
3404 if (sc->sc_flags & URTW_RTL8187B_REV_B)
3405 cck_pwrtable += (cck_pwrlvl <= 6) ? 0 :
3406 ((cck_pwrlvl <= 11) ? 8 : 16);
3408 cck_pwrtable += (cck_pwrlvl <= 5) ? 0 :
3409 ((cck_pwrlvl <= 11) ? 8 : ((cck_pwrlvl <= 17) ? 16 : 24));
3411 for (i = 0; i < 8; i++)
3412 urtw_8187_write_phy_cck(sc, 0x44 + i, cck_pwrtable[i]);
3414 urtw_write8_m(sc, URTW_TX_GAIN_CCK,
3415 urtw_8225v2_tx_gain_cck_ofdm[cck_pwrlvl] << 1);
3416 usb_pause_mtx(&sc->sc_mtx, 1);
3418 /* OFDM power setting */
3419 ofdm_pwrlvl = (ofdm_pwrlvl > 15) ?
3420 ((sc->sc_flags & URTW_RTL8187B_REV_B) ? 17 : 25) :
3421 (ofdm_pwrlvl + ((sc->sc_flags & URTW_RTL8187B_REV_B) ? 2 : 10));
3422 ofdm_pwrlvl += sc->sc_txpwr_ofdm_base;
3423 ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
3425 urtw_write8_m(sc, URTW_TX_GAIN_OFDM,
3426 urtw_8225v2_tx_gain_cck_ofdm[ofdm_pwrlvl] << 1);
3428 if (sc->sc_flags & URTW_RTL8187B_REV_B) {
3429 if (ofdm_pwrlvl <= 11) {
3430 urtw_8187_write_phy_ofdm(sc, 0x87, 0x60);
3431 urtw_8187_write_phy_ofdm(sc, 0x89, 0x60);
3433 urtw_8187_write_phy_ofdm(sc, 0x87, 0x5c);
3434 urtw_8187_write_phy_ofdm(sc, 0x89, 0x5c);
3437 if (ofdm_pwrlvl <= 11) {
3438 urtw_8187_write_phy_ofdm(sc, 0x87, 0x5c);
3439 urtw_8187_write_phy_ofdm(sc, 0x89, 0x5c);
3440 } else if (ofdm_pwrlvl <= 17) {
3441 urtw_8187_write_phy_ofdm(sc, 0x87, 0x54);
3442 urtw_8187_write_phy_ofdm(sc, 0x89, 0x54);
3444 urtw_8187_write_phy_ofdm(sc, 0x87, 0x50);
3445 urtw_8187_write_phy_ofdm(sc, 0x89, 0x50);
3448 usb_pause_mtx(&sc->sc_mtx, 1);
3454 urtw_read8e(struct urtw_softc *sc, int val, uint8_t *data)
3456 struct usb_device_request req;
3459 req.bmRequestType = UT_READ_VENDOR_DEVICE;
3460 req.bRequest = URTW_8187_GETREGS_REQ;
3461 USETW(req.wValue, val | 0xfe00);
3462 USETW(req.wIndex, 0);
3463 USETW(req.wLength, sizeof(uint8_t));
3465 error = urtw_do_request(sc, &req, data);
3470 urtw_write8e(struct urtw_softc *sc, int val, uint8_t data)
3472 struct usb_device_request req;
3474 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
3475 req.bRequest = URTW_8187_SETREGS_REQ;
3476 USETW(req.wValue, val | 0xfe00);
3477 USETW(req.wIndex, 0);
3478 USETW(req.wLength, sizeof(uint8_t));
3480 return (urtw_do_request(sc, &req, &data));
3484 urtw_8180_set_anaparam(struct urtw_softc *sc, uint32_t val)
3489 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3493 urtw_read8_m(sc, URTW_CONFIG3, &data);
3494 urtw_write8_m(sc, URTW_CONFIG3, data | URTW_CONFIG3_ANAPARAM_WRITE);
3495 urtw_write32_m(sc, URTW_ANAPARAM, val);
3496 urtw_read8_m(sc, URTW_CONFIG3, &data);
3497 urtw_write8_m(sc, URTW_CONFIG3, data & ~URTW_CONFIG3_ANAPARAM_WRITE);
3499 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3507 urtw_8185_set_anaparam2(struct urtw_softc *sc, uint32_t val)
3512 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3516 urtw_read8_m(sc, URTW_CONFIG3, &data);
3517 urtw_write8_m(sc, URTW_CONFIG3, data | URTW_CONFIG3_ANAPARAM_WRITE);
3518 urtw_write32_m(sc, URTW_ANAPARAM2, val);
3519 urtw_read8_m(sc, URTW_CONFIG3, &data);
3520 urtw_write8_m(sc, URTW_CONFIG3, data & ~URTW_CONFIG3_ANAPARAM_WRITE);
3522 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3530 urtw_intr_enable(struct urtw_softc *sc)
3534 urtw_write16_m(sc, URTW_INTR_MASK, 0xffff);
3540 urtw_intr_disable(struct urtw_softc *sc)
3544 urtw_write16_m(sc, URTW_INTR_MASK, 0);
3550 urtw_reset(struct urtw_softc *sc)
3555 error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
3558 error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
3562 error = urtw_intr_disable(sc);
3565 usb_pause_mtx(&sc->sc_mtx, 100);
3567 error = urtw_write8e(sc, 0x18, 0x10);
3570 error = urtw_write8e(sc, 0x18, 0x11);
3573 error = urtw_write8e(sc, 0x18, 0x00);
3576 usb_pause_mtx(&sc->sc_mtx, 100);
3578 urtw_read8_m(sc, URTW_CMD, &data);
3579 data = (data & 0x2) | URTW_CMD_RST;
3580 urtw_write8_m(sc, URTW_CMD, data);
3581 usb_pause_mtx(&sc->sc_mtx, 100);
3583 urtw_read8_m(sc, URTW_CMD, &data);
3584 if (data & URTW_CMD_RST) {
3585 device_printf(sc->sc_dev, "reset timeout\n");
3589 error = urtw_set_mode(sc, URTW_EPROM_CMD_LOAD);
3592 usb_pause_mtx(&sc->sc_mtx, 100);
3594 error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
3597 error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
3605 urtw_led_ctl(struct urtw_softc *sc, int mode)
3607 usb_error_t error = 0;
3609 switch (sc->sc_strategy) {
3610 case URTW_SW_LED_MODE0:
3611 error = urtw_led_mode0(sc, mode);
3613 case URTW_SW_LED_MODE1:
3614 error = urtw_led_mode1(sc, mode);
3616 case URTW_SW_LED_MODE2:
3617 error = urtw_led_mode2(sc, mode);
3619 case URTW_SW_LED_MODE3:
3620 error = urtw_led_mode3(sc, mode);
3623 panic("unsupported LED mode %d\n", sc->sc_strategy);
3631 urtw_led_mode0(struct urtw_softc *sc, int mode)
3635 case URTW_LED_CTL_POWER_ON:
3636 sc->sc_gpio_ledstate = URTW_LED_POWER_ON_BLINK;
3638 case URTW_LED_CTL_TX:
3639 if (sc->sc_gpio_ledinprogress == 1)
3642 sc->sc_gpio_ledstate = URTW_LED_BLINK_NORMAL;
3643 sc->sc_gpio_blinktime = 2;
3645 case URTW_LED_CTL_LINK:
3646 sc->sc_gpio_ledstate = URTW_LED_ON;
3649 panic("unsupported LED mode 0x%x", mode);
3653 switch (sc->sc_gpio_ledstate) {
3655 if (sc->sc_gpio_ledinprogress != 0)
3657 urtw_led_on(sc, URTW_LED_GPIO);
3659 case URTW_LED_BLINK_NORMAL:
3660 if (sc->sc_gpio_ledinprogress != 0)
3662 sc->sc_gpio_ledinprogress = 1;
3663 sc->sc_gpio_blinkstate = (sc->sc_gpio_ledon != 0) ?
3664 URTW_LED_OFF : URTW_LED_ON;
3665 usb_callout_reset(&sc->sc_led_ch, hz, urtw_led_ch, sc);
3667 case URTW_LED_POWER_ON_BLINK:
3668 urtw_led_on(sc, URTW_LED_GPIO);
3669 usb_pause_mtx(&sc->sc_mtx, 100);
3670 urtw_led_off(sc, URTW_LED_GPIO);
3673 panic("unknown LED status 0x%x", sc->sc_gpio_ledstate);
3680 urtw_led_mode1(struct urtw_softc *sc, int mode)
3683 return (USB_ERR_INVAL);
3687 urtw_led_mode2(struct urtw_softc *sc, int mode)
3690 return (USB_ERR_INVAL);
3694 urtw_led_mode3(struct urtw_softc *sc, int mode)
3697 return (USB_ERR_INVAL);
3701 urtw_led_on(struct urtw_softc *sc, int type)
3705 if (type == URTW_LED_GPIO) {
3706 switch (sc->sc_gpio_ledpin) {
3707 case URTW_LED_PIN_GPIO0:
3708 urtw_write8_m(sc, URTW_GPIO, 0x01);
3709 urtw_write8_m(sc, URTW_GP_ENABLE, 0x00);
3712 panic("unsupported LED PIN type 0x%x",
3713 sc->sc_gpio_ledpin);
3717 panic("unsupported LED type 0x%x", type);
3721 sc->sc_gpio_ledon = 1;
3727 urtw_led_off(struct urtw_softc *sc, int type)
3731 if (type == URTW_LED_GPIO) {
3732 switch (sc->sc_gpio_ledpin) {
3733 case URTW_LED_PIN_GPIO0:
3734 urtw_write8_m(sc, URTW_GPIO, URTW_GPIO_DATA_MAGIC1);
3736 URTW_GP_ENABLE, URTW_GP_ENABLE_DATA_MAGIC1);
3739 panic("unsupported LED PIN type 0x%x",
3740 sc->sc_gpio_ledpin);
3744 panic("unsupported LED type 0x%x", type);
3748 sc->sc_gpio_ledon = 0;
3755 urtw_led_ch(void *arg)
3757 struct urtw_softc *sc = arg;
3758 struct ifnet *ifp = sc->sc_ifp;
3759 struct ieee80211com *ic = ifp->if_l2com;
3761 ieee80211_runtask(ic, &sc->sc_led_task);
3765 urtw_ledtask(void *arg, int pending)
3767 struct urtw_softc *sc = arg;
3769 if (sc->sc_strategy != URTW_SW_LED_MODE0)
3770 panic("could not process a LED strategy 0x%x", sc->sc_strategy);
3778 urtw_led_blink(struct urtw_softc *sc)
3783 if (sc->sc_gpio_blinkstate == URTW_LED_ON)
3784 error = urtw_led_on(sc, URTW_LED_GPIO);
3786 error = urtw_led_off(sc, URTW_LED_GPIO);
3787 sc->sc_gpio_blinktime--;
3788 if (sc->sc_gpio_blinktime == 0)
3791 if (sc->sc_gpio_ledstate != URTW_LED_BLINK_NORMAL &&
3792 sc->sc_gpio_ledstate != URTW_LED_BLINK_SLOWLY &&
3793 sc->sc_gpio_ledstate != URTW_LED_BLINK_CM3)
3797 if (sc->sc_gpio_ledstate == URTW_LED_ON &&
3798 sc->sc_gpio_ledon == 0)
3799 error = urtw_led_on(sc, URTW_LED_GPIO);
3800 else if (sc->sc_gpio_ledstate == URTW_LED_OFF &&
3801 sc->sc_gpio_ledon == 1)
3802 error = urtw_led_off(sc, URTW_LED_GPIO);
3804 sc->sc_gpio_blinktime = 0;
3805 sc->sc_gpio_ledinprogress = 0;
3809 sc->sc_gpio_blinkstate = (sc->sc_gpio_blinkstate != URTW_LED_ON) ?
3810 URTW_LED_ON : URTW_LED_OFF;
3812 switch (sc->sc_gpio_ledstate) {
3813 case URTW_LED_BLINK_NORMAL:
3814 usb_callout_reset(&sc->sc_led_ch, hz, urtw_led_ch, sc);
3817 panic("unknown LED status 0x%x", sc->sc_gpio_ledstate);
3824 urtw_rx_enable(struct urtw_softc *sc)
3829 usbd_transfer_start((sc->sc_flags & URTW_RTL8187B) ?
3830 sc->sc_xfer[URTW_8187B_BULK_RX] : sc->sc_xfer[URTW_8187L_BULK_RX]);
3832 error = urtw_rx_setconf(sc);
3836 if ((sc->sc_flags & URTW_RTL8187B) == 0) {
3837 urtw_read8_m(sc, URTW_CMD, &data);
3838 urtw_write8_m(sc, URTW_CMD, data | URTW_CMD_RX_ENABLE);
3845 urtw_tx_enable(struct urtw_softc *sc)
3851 if (sc->sc_flags & URTW_RTL8187B) {
3852 urtw_read32_m(sc, URTW_TX_CONF, &data);
3853 data &= ~URTW_TX_LOOPBACK_MASK;
3854 data &= ~(URTW_TX_DPRETRY_MASK | URTW_TX_RTSRETRY_MASK);
3855 data &= ~(URTW_TX_NOCRC | URTW_TX_MXDMA_MASK);
3856 data &= ~URTW_TX_SWPLCPLEN;
3857 data |= URTW_TX_HW_SEQNUM | URTW_TX_DISREQQSIZE |
3858 (7 << 8) | /* short retry limit */
3859 (7 << 0) | /* long retry limit */
3860 (7 << 21); /* MAX TX DMA */
3861 urtw_write32_m(sc, URTW_TX_CONF, data);
3863 urtw_read8_m(sc, URTW_MSR, &data8);
3864 data8 |= URTW_MSR_LINK_ENEDCA;
3865 urtw_write8_m(sc, URTW_MSR, data8);
3869 urtw_read8_m(sc, URTW_CW_CONF, &data8);
3870 data8 &= ~(URTW_CW_CONF_PERPACKET_CW | URTW_CW_CONF_PERPACKET_RETRY);
3871 urtw_write8_m(sc, URTW_CW_CONF, data8);
3873 urtw_read8_m(sc, URTW_TX_AGC_CTL, &data8);
3874 data8 &= ~URTW_TX_AGC_CTL_PERPACKET_GAIN;
3875 data8 &= ~URTW_TX_AGC_CTL_PERPACKET_ANTSEL;
3876 data8 &= ~URTW_TX_AGC_CTL_FEEDBACK_ANT;
3877 urtw_write8_m(sc, URTW_TX_AGC_CTL, data8);
3879 urtw_read32_m(sc, URTW_TX_CONF, &data);
3880 data &= ~URTW_TX_LOOPBACK_MASK;
3881 data |= URTW_TX_LOOPBACK_NONE;
3882 data &= ~(URTW_TX_DPRETRY_MASK | URTW_TX_RTSRETRY_MASK);
3883 data |= sc->sc_tx_retry << URTW_TX_DPRETRY_SHIFT;
3884 data |= sc->sc_rts_retry << URTW_TX_RTSRETRY_SHIFT;
3885 data &= ~(URTW_TX_NOCRC | URTW_TX_MXDMA_MASK);
3886 data |= URTW_TX_MXDMA_2048 | URTW_TX_CWMIN | URTW_TX_DISCW;
3887 data &= ~URTW_TX_SWPLCPLEN;
3888 data |= URTW_TX_NOICV;
3889 urtw_write32_m(sc, URTW_TX_CONF, data);
3891 urtw_read8_m(sc, URTW_CMD, &data8);
3892 urtw_write8_m(sc, URTW_CMD, data8 | URTW_CMD_TX_ENABLE);
3898 urtw_rx_setconf(struct urtw_softc *sc)
3900 struct ifnet *ifp = sc->sc_ifp;
3901 struct ieee80211com *ic = ifp->if_l2com;
3905 urtw_read32_m(sc, URTW_RX, &data);
3906 data = data &~ URTW_RX_FILTER_MASK;
3907 if (sc->sc_flags & URTW_RTL8187B) {
3908 data = data | URTW_RX_FILTER_MNG | URTW_RX_FILTER_DATA |
3909 URTW_RX_FILTER_MCAST | URTW_RX_FILTER_BCAST |
3910 URTW_RX_FILTER_NICMAC | URTW_RX_CHECK_BSSID |
3911 URTW_RX_FIFO_THRESHOLD_NONE |
3912 URTW_MAX_RX_DMA_2048 |
3913 URTW_RX_AUTORESETPHY | URTW_RCR_ONLYERLPKT;
3915 data = data | URTW_RX_FILTER_MNG | URTW_RX_FILTER_DATA;
3916 data = data | URTW_RX_FILTER_BCAST | URTW_RX_FILTER_MCAST;
3918 if (ic->ic_opmode == IEEE80211_M_MONITOR) {
3919 data = data | URTW_RX_FILTER_ICVERR;
3920 data = data | URTW_RX_FILTER_PWR;
3922 if (sc->sc_crcmon == 1 && ic->ic_opmode == IEEE80211_M_MONITOR)
3923 data = data | URTW_RX_FILTER_CRCERR;
3925 if (ic->ic_opmode == IEEE80211_M_MONITOR ||
3926 (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC))) {
3927 data = data | URTW_RX_FILTER_ALLMAC;
3929 data = data | URTW_RX_FILTER_NICMAC;
3930 data = data | URTW_RX_CHECK_BSSID;
3933 data = data &~ URTW_RX_FIFO_THRESHOLD_MASK;
3934 data = data | URTW_RX_FIFO_THRESHOLD_NONE |
3935 URTW_RX_AUTORESETPHY;
3936 data = data &~ URTW_MAX_RX_DMA_MASK;
3937 data = data | URTW_MAX_RX_DMA_2048 | URTW_RCR_ONLYERLPKT;
3940 urtw_write32_m(sc, URTW_RX, data);
3945 static struct mbuf *
3946 urtw_rxeof(struct usb_xfer *xfer, struct urtw_data *data, int *rssi_p,
3949 int actlen, flen, rssi;
3950 struct ieee80211_frame *wh;
3951 struct mbuf *m, *mnew;
3952 struct urtw_softc *sc = data->sc;
3953 struct ifnet *ifp = sc->sc_ifp;
3954 struct ieee80211com *ic = ifp->if_l2com;
3955 uint8_t noise = 0, rate;
3957 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
3959 if (actlen < URTW_MIN_RXBUFSZ) {
3964 if (sc->sc_flags & URTW_RTL8187B) {
3965 struct urtw_8187b_rxhdr *rx;
3967 rx = (struct urtw_8187b_rxhdr *)(data->buf +
3968 (actlen - (sizeof(struct urtw_8187b_rxhdr))));
3969 flen = le32toh(rx->flag) & 0xfff;
3970 if (flen > actlen) {
3974 rate = (le32toh(rx->flag) >> URTW_RX_FLAG_RXRATE_SHIFT) & 0xf;
3976 rssi = rx->rssi & URTW_RX_RSSI_MASK;
3979 struct urtw_8187l_rxhdr *rx;
3981 rx = (struct urtw_8187l_rxhdr *)(data->buf +
3982 (actlen - (sizeof(struct urtw_8187l_rxhdr))));
3983 flen = le32toh(rx->flag) & 0xfff;
3984 if (flen > actlen) {
3989 rate = (le32toh(rx->flag) >> URTW_RX_FLAG_RXRATE_SHIFT) & 0xf;
3991 rssi = rx->rssi & URTW_RX_8187L_RSSI_MASK;
3995 mnew = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
4003 data->buf = mtod(mnew, uint8_t *);
4006 m->m_pkthdr.rcvif = ifp;
4007 m->m_pkthdr.len = m->m_len = flen - IEEE80211_CRC_LEN;
4009 if (ieee80211_radiotap_active(ic)) {
4010 struct urtw_rx_radiotap_header *tap = &sc->sc_rxtap;
4012 /* XXX Are variables correct? */
4013 tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
4014 tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
4015 tap->wr_dbm_antsignal = (int8_t)rssi;
4018 wh = mtod(m, struct ieee80211_frame *);
4019 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_DATA)
4020 sc->sc_currate = (rate > 0) ? rate : sc->sc_currate;
4023 *nf_p = noise; /* XXX correct? */
4029 urtw_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
4031 struct urtw_softc *sc = usbd_xfer_softc(xfer);
4032 struct ifnet *ifp = sc->sc_ifp;
4033 struct ieee80211com *ic = ifp->if_l2com;
4034 struct ieee80211_frame *wh;
4035 struct ieee80211_node *ni;
4036 struct mbuf *m = NULL;
4037 struct urtw_data *data;
4041 URTW_ASSERT_LOCKED(sc);
4043 switch (USB_GET_STATE(xfer)) {
4044 case USB_ST_TRANSFERRED:
4045 data = STAILQ_FIRST(&sc->sc_rx_active);
4048 STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next);
4049 m = urtw_rxeof(xfer, data, &rssi, &nf);
4050 STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next);
4054 data = STAILQ_FIRST(&sc->sc_rx_inactive);
4056 KASSERT(m == NULL, ("mbuf isn't NULL"));
4059 STAILQ_REMOVE_HEAD(&sc->sc_rx_inactive, next);
4060 STAILQ_INSERT_TAIL(&sc->sc_rx_active, data, next);
4061 usbd_xfer_set_frame_data(xfer, 0, data->buf,
4062 usbd_xfer_max_len(xfer));
4063 usbd_transfer_submit(xfer);
4066 * To avoid LOR we should unlock our private mutex here to call
4067 * ieee80211_input() because here is at the end of a USB
4068 * callback and safe to unlock.
4072 wh = mtod(m, struct ieee80211_frame *);
4073 ni = ieee80211_find_rxnode(ic,
4074 (struct ieee80211_frame_min *)wh);
4076 (void) ieee80211_input(ni, m, rssi, nf);
4077 /* node is no longer needed */
4078 ieee80211_free_node(ni);
4080 (void) ieee80211_input_all(ic, m, rssi, nf);
4086 /* needs it to the inactive queue due to a error. */
4087 data = STAILQ_FIRST(&sc->sc_rx_active);
4089 STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next);
4090 STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next);
4092 if (error != USB_ERR_CANCELLED) {
4093 usbd_xfer_set_stall(xfer);
4101 #define URTW_STATUS_TYPE_TXCLOSE 1
4102 #define URTW_STATUS_TYPE_BEACON_INTR 0
4105 urtw_txstatus_eof(struct usb_xfer *xfer)
4107 struct urtw_softc *sc = usbd_xfer_softc(xfer);
4108 struct ifnet *ifp = sc->sc_ifp;
4109 int actlen, type, pktretry, seq;
4112 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
4114 if (actlen != sizeof(uint64_t))
4117 val = le64toh(sc->sc_txstatus);
4118 type = (val >> 30) & 0x3;
4119 if (type == URTW_STATUS_TYPE_TXCLOSE) {
4120 pktretry = val & 0xff;
4121 seq = (val >> 16) & 0xff;
4122 if (pktretry == URTW_TX_MAXRETRY)
4124 DPRINTF(sc, URTW_DEBUG_TXSTATUS, "pktretry %d seq %#x\n",
4130 urtw_bulk_tx_status_callback(struct usb_xfer *xfer, usb_error_t error)
4132 struct urtw_softc *sc = usbd_xfer_softc(xfer);
4133 struct ifnet *ifp = sc->sc_ifp;
4135 URTW_ASSERT_LOCKED(sc);
4137 switch (USB_GET_STATE(xfer)) {
4138 case USB_ST_TRANSFERRED:
4139 urtw_txstatus_eof(xfer);
4143 usbd_xfer_set_frame_data(xfer, 0, &sc->sc_txstatus,
4145 usbd_transfer_submit(xfer);
4148 if (error != USB_ERR_CANCELLED) {
4149 usbd_xfer_set_stall(xfer);
4158 urtw_txeof(struct usb_xfer *xfer, struct urtw_data *data)
4160 struct urtw_softc *sc = usbd_xfer_softc(xfer);
4161 struct ifnet *ifp = sc->sc_ifp;
4164 URTW_ASSERT_LOCKED(sc);
4167 * Do any tx complete callback. Note this must be done before releasing
4168 * the node reference.
4172 if (m->m_flags & M_TXCB) {
4174 ieee80211_process_callback(data->ni, m, 0);
4180 ieee80211_free_node(data->ni);
4185 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
4189 urtw_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error)
4191 struct urtw_softc *sc = usbd_xfer_softc(xfer);
4192 struct ifnet *ifp = sc->sc_ifp;
4193 struct urtw_data *data;
4195 URTW_ASSERT_LOCKED(sc);
4197 switch (USB_GET_STATE(xfer)) {
4198 case USB_ST_TRANSFERRED:
4199 data = STAILQ_FIRST(&sc->sc_tx_active);
4202 STAILQ_REMOVE_HEAD(&sc->sc_tx_active, next);
4203 urtw_txeof(xfer, data);
4204 STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data, next);
4208 data = STAILQ_FIRST(&sc->sc_tx_pending);
4210 DPRINTF(sc, URTW_DEBUG_XMIT,
4211 "%s: empty pending queue\n", __func__);
4214 STAILQ_REMOVE_HEAD(&sc->sc_tx_pending, next);
4215 STAILQ_INSERT_TAIL(&sc->sc_tx_active, data, next);
4217 usbd_xfer_set_frame_data(xfer, 0, data->buf, data->buflen);
4218 usbd_transfer_submit(xfer);
4225 data = STAILQ_FIRST(&sc->sc_tx_active);
4228 if (data->ni != NULL) {
4229 ieee80211_free_node(data->ni);
4233 if (error != USB_ERR_CANCELLED) {
4234 usbd_xfer_set_stall(xfer);
4241 static struct urtw_data *
4242 _urtw_getbuf(struct urtw_softc *sc)
4244 struct urtw_data *bf;
4246 bf = STAILQ_FIRST(&sc->sc_tx_inactive);
4248 STAILQ_REMOVE_HEAD(&sc->sc_tx_inactive, next);
4252 DPRINTF(sc, URTW_DEBUG_XMIT, "%s: %s\n", __func__,
4253 "out of xmit buffers");
4257 static struct urtw_data *
4258 urtw_getbuf(struct urtw_softc *sc)
4260 struct urtw_data *bf;
4262 URTW_ASSERT_LOCKED(sc);
4264 bf = _urtw_getbuf(sc);
4266 struct ifnet *ifp = sc->sc_ifp;
4268 DPRINTF(sc, URTW_DEBUG_XMIT, "%s: stop queue\n", __func__);
4269 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
4275 urtw_isbmode(uint16_t rate)
4278 return ((rate <= 22 && rate != 12 && rate != 18) ||
4279 rate == 44) ? (1) : (0);
4283 urtw_rate2dbps(uint16_t rate)
4303 urtw_compute_txtime(uint16_t framelen, uint16_t rate,
4304 uint8_t ismgt, uint8_t isshort)
4306 uint16_t ceiling, frametime, n_dbps;
4308 if (urtw_isbmode(rate)) {
4309 if (ismgt || !isshort || rate == 2)
4310 frametime = (uint16_t)(144 + 48 +
4311 (framelen * 8 / (rate / 2)));
4313 frametime = (uint16_t)(72 + 24 +
4314 (framelen * 8 / (rate / 2)));
4315 if ((framelen * 8 % (rate / 2)) != 0)
4318 n_dbps = urtw_rate2dbps(rate);
4319 ceiling = (16 + 8 * framelen + 6) / n_dbps
4320 + (((16 + 8 * framelen + 6) % n_dbps) ? 1 : 0);
4321 frametime = (uint16_t)(16 + 4 + 4 * ceiling + 6);
4327 * Callback from the 802.11 layer to update the
4328 * slot time based on the current setting.
4331 urtw_updateslot(struct ifnet *ifp)
4333 struct urtw_softc *sc = ifp->if_softc;
4334 struct ieee80211com *ic = ifp->if_l2com;
4336 ieee80211_runtask(ic, &sc->sc_updateslot_task);
4340 urtw_updateslottask(void *arg, int pending)
4342 struct urtw_softc *sc = arg;
4343 struct ifnet *ifp = sc->sc_ifp;
4344 struct ieee80211com *ic = ifp->if_l2com;
4347 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
4351 if (sc->sc_flags & URTW_RTL8187B) {
4352 urtw_write8_m(sc, URTW_SIFS, 0x22);
4353 if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan))
4354 urtw_write8_m(sc, URTW_SLOT, 0x9);
4356 urtw_write8_m(sc, URTW_SLOT, 0x14);
4357 urtw_write8_m(sc, URTW_8187B_EIFS, 0x5b);
4358 urtw_write8_m(sc, URTW_CARRIER_SCOUNT, 0x5b);
4360 urtw_write8_m(sc, URTW_SIFS, 0x22);
4361 if (sc->sc_state == IEEE80211_S_ASSOC &&
4362 ic->ic_flags & IEEE80211_F_SHSLOT)
4363 urtw_write8_m(sc, URTW_SLOT, 0x9);
4365 urtw_write8_m(sc, URTW_SLOT, 0x14);
4366 if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan)) {
4367 urtw_write8_m(sc, URTW_DIFS, 0x14);
4368 urtw_write8_m(sc, URTW_EIFS, 0x5b - 0x14);
4369 urtw_write8_m(sc, URTW_CW_VAL, 0x73);
4371 urtw_write8_m(sc, URTW_DIFS, 0x24);
4372 urtw_write8_m(sc, URTW_EIFS, 0x5b - 0x24);
4373 urtw_write8_m(sc, URTW_CW_VAL, 0xa5);
4381 urtw_sysctl_node(struct urtw_softc *sc)
4383 #define URTW_SYSCTL_STAT_ADD32(c, h, n, p, d) \
4384 SYSCTL_ADD_UINT(c, h, OID_AUTO, n, CTLFLAG_RD, p, 0, d)
4385 struct sysctl_ctx_list *ctx;
4386 struct sysctl_oid_list *child, *parent;
4387 struct sysctl_oid *tree;
4388 struct urtw_stats *stats = &sc->sc_stats;
4390 ctx = device_get_sysctl_ctx(sc->sc_dev);
4391 child = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->sc_dev));
4393 tree = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "stats", CTLFLAG_RD,
4394 NULL, "URTW statistics");
4395 parent = SYSCTL_CHILDREN(tree);
4397 /* Tx statistics. */
4398 tree = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "tx", CTLFLAG_RD,
4399 NULL, "Tx MAC statistics");
4400 child = SYSCTL_CHILDREN(tree);
4401 URTW_SYSCTL_STAT_ADD32(ctx, child, "1m", &stats->txrates[0],
4403 URTW_SYSCTL_STAT_ADD32(ctx, child, "2m", &stats->txrates[1],
4405 URTW_SYSCTL_STAT_ADD32(ctx, child, "5.5m", &stats->txrates[2],
4407 URTW_SYSCTL_STAT_ADD32(ctx, child, "6m", &stats->txrates[4],
4409 URTW_SYSCTL_STAT_ADD32(ctx, child, "9m", &stats->txrates[5],
4411 URTW_SYSCTL_STAT_ADD32(ctx, child, "11m", &stats->txrates[3],
4413 URTW_SYSCTL_STAT_ADD32(ctx, child, "12m", &stats->txrates[6],
4415 URTW_SYSCTL_STAT_ADD32(ctx, child, "18m", &stats->txrates[7],
4417 URTW_SYSCTL_STAT_ADD32(ctx, child, "24m", &stats->txrates[8],
4419 URTW_SYSCTL_STAT_ADD32(ctx, child, "36m", &stats->txrates[9],
4421 URTW_SYSCTL_STAT_ADD32(ctx, child, "48m", &stats->txrates[10],
4423 URTW_SYSCTL_STAT_ADD32(ctx, child, "54m", &stats->txrates[11],
4425 #undef URTW_SYSCTL_STAT_ADD32
4428 static device_method_t urtw_methods[] = {
4429 DEVMETHOD(device_probe, urtw_match),
4430 DEVMETHOD(device_attach, urtw_attach),
4431 DEVMETHOD(device_detach, urtw_detach),
4434 static driver_t urtw_driver = {
4437 sizeof(struct urtw_softc)
4439 static devclass_t urtw_devclass;
4441 DRIVER_MODULE(urtw, uhub, urtw_driver, urtw_devclass, NULL, 0);
4442 MODULE_DEPEND(urtw, wlan, 1, 1, 1);
4443 MODULE_DEPEND(urtw, usb, 1, 1, 1);
4444 MODULE_VERSION(urtw, 1);