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");
68 SYSCTL_INT(_hw_usb_urtw, OID_AUTO, debug, CTLFLAG_RW, &urtw_debug, 0,
69 "control debugging printfs");
70 TUNABLE_INT("hw.usb.urtw.debug", &urtw_debug);
72 URTW_DEBUG_XMIT = 0x00000001, /* basic xmit operation */
73 URTW_DEBUG_RECV = 0x00000002, /* basic recv operation */
74 URTW_DEBUG_RESET = 0x00000004, /* reset processing */
75 URTW_DEBUG_TX_PROC = 0x00000008, /* tx ISR proc */
76 URTW_DEBUG_RX_PROC = 0x00000010, /* rx ISR proc */
77 URTW_DEBUG_STATE = 0x00000020, /* 802.11 state transitions */
78 URTW_DEBUG_STAT = 0x00000040, /* statistic */
79 URTW_DEBUG_INIT = 0x00000080, /* initialization of dev */
80 URTW_DEBUG_TXSTATUS = 0x00000100, /* tx status */
81 URTW_DEBUG_ANY = 0xffffffff
83 #define DPRINTF(sc, m, fmt, ...) do { \
84 if (sc->sc_debug & (m)) \
85 printf(fmt, __VA_ARGS__); \
88 #define DPRINTF(sc, m, fmt, ...) do { \
92 static int urtw_preamble_mode = URTW_PREAMBLE_MODE_LONG;
93 SYSCTL_INT(_hw_usb_urtw, OID_AUTO, preamble_mode, CTLFLAG_RW,
94 &urtw_preamble_mode, 0, "set the preable mode (long or short)");
95 TUNABLE_INT("hw.usb.urtw.preamble_mode", &urtw_preamble_mode);
97 /* recognized device vendors/products */
98 #define urtw_lookup(v, p) \
99 ((const struct urtw_type *)usb_lookup(urtw_devs, v, p))
100 #define URTW_DEV_B(v,p) \
101 { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, URTW_REV_RTL8187B) }
102 #define URTW_DEV_L(v,p) \
103 { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, URTW_REV_RTL8187L) }
104 #define URTW_REV_RTL8187B 0
105 #define URTW_REV_RTL8187L 1
106 static const struct usb_device_id urtw_devs[] = {
107 URTW_DEV_B(NETGEAR, WG111V3),
108 URTW_DEV_B(REALTEK, RTL8187B_0),
109 URTW_DEV_B(REALTEK, RTL8187B_1),
110 URTW_DEV_B(REALTEK, RTL8187B_2),
111 URTW_DEV_B(SITECOMEU, WL168V4),
112 URTW_DEV_L(ASUS, P5B_WIFI),
113 URTW_DEV_L(BELKIN, F5D7050E),
114 URTW_DEV_L(LINKSYS4, WUSB54GCV2),
115 URTW_DEV_L(NETGEAR, WG111V2),
116 URTW_DEV_L(REALTEK, RTL8187),
117 URTW_DEV_L(SITECOMEU, WL168V1),
118 URTW_DEV_L(SURECOM, EP9001G2A),
119 { USB_VPI(0x1b75, 0x8187, URTW_REV_RTL8187L) },
120 { USB_VPI(USB_VENDOR_DICKSMITH, 0x9401, URTW_REV_RTL8187L) },
121 { USB_VPI(USB_VENDOR_HP, 0xca02, URTW_REV_RTL8187L) },
122 { USB_VPI(USB_VENDOR_LOGITEC, 0x010c, URTW_REV_RTL8187L) },
123 { USB_VPI(USB_VENDOR_NETGEAR, 0x6100, URTW_REV_RTL8187L) },
124 { USB_VPI(USB_VENDOR_SPHAIRON, 0x0150, URTW_REV_RTL8187L) },
125 { USB_VPI(USB_VENDOR_QCOM, 0x6232, URTW_REV_RTL8187L) },
130 #define urtw_read8_m(sc, val, data) do { \
131 error = urtw_read8_c(sc, val, data); \
135 #define urtw_write8_m(sc, val, data) do { \
136 error = urtw_write8_c(sc, val, data); \
140 #define urtw_read16_m(sc, val, data) do { \
141 error = urtw_read16_c(sc, val, data); \
145 #define urtw_write16_m(sc, val, data) do { \
146 error = urtw_write16_c(sc, val, data); \
150 #define urtw_read32_m(sc, val, data) do { \
151 error = urtw_read32_c(sc, val, data); \
155 #define urtw_write32_m(sc, val, data) do { \
156 error = urtw_write32_c(sc, val, data); \
160 #define urtw_8187_write_phy_ofdm(sc, val, data) do { \
161 error = urtw_8187_write_phy_ofdm_c(sc, val, data); \
165 #define urtw_8187_write_phy_cck(sc, val, data) do { \
166 error = urtw_8187_write_phy_cck_c(sc, val, data); \
170 #define urtw_8225_write(sc, val, data) do { \
171 error = urtw_8225_write_c(sc, val, data); \
181 static uint8_t urtw_8225_agc[] = {
182 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9d, 0x9c, 0x9b,
183 0x9a, 0x99, 0x98, 0x97, 0x96, 0x95, 0x94, 0x93, 0x92, 0x91, 0x90,
184 0x8f, 0x8e, 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86, 0x85,
185 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a,
186 0x39, 0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f,
187 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24,
188 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19,
189 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e,
190 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03,
191 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
192 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
193 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
196 static uint8_t urtw_8225z2_agc[] = {
197 0x5e, 0x5e, 0x5e, 0x5e, 0x5d, 0x5b, 0x59, 0x57, 0x55, 0x53, 0x51,
198 0x4f, 0x4d, 0x4b, 0x49, 0x47, 0x45, 0x43, 0x41, 0x3f, 0x3d, 0x3b,
199 0x39, 0x37, 0x35, 0x33, 0x31, 0x2f, 0x2d, 0x2b, 0x29, 0x27, 0x25,
200 0x23, 0x21, 0x1f, 0x1d, 0x1b, 0x19, 0x17, 0x15, 0x13, 0x11, 0x0f,
201 0x0d, 0x0b, 0x09, 0x07, 0x05, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01,
202 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x19, 0x19,
203 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x20, 0x21, 0x22, 0x23,
204 0x24, 0x25, 0x26, 0x26, 0x27, 0x27, 0x28, 0x28, 0x29, 0x2a, 0x2a,
205 0x2a, 0x2b, 0x2b, 0x2b, 0x2c, 0x2c, 0x2c, 0x2d, 0x2d, 0x2d, 0x2d,
206 0x2e, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x2f, 0x30, 0x30, 0x31, 0x31,
207 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
208 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31
211 static uint32_t urtw_8225_channel[] = {
212 0x0000, /* dummy channel 0 */
229 static uint8_t urtw_8225_gain[] = {
230 0x23, 0x88, 0x7c, 0xa5, /* -82dbm */
231 0x23, 0x88, 0x7c, 0xb5, /* -82dbm */
232 0x23, 0x88, 0x7c, 0xc5, /* -82dbm */
233 0x33, 0x80, 0x79, 0xc5, /* -78dbm */
234 0x43, 0x78, 0x76, 0xc5, /* -74dbm */
235 0x53, 0x60, 0x73, 0xc5, /* -70dbm */
236 0x63, 0x58, 0x70, 0xc5, /* -66dbm */
239 static struct urtw_pair urtw_8225_rf_part1[] = {
240 { 0x00, 0x0067 }, { 0x01, 0x0fe0 }, { 0x02, 0x044d }, { 0x03, 0x0441 },
241 { 0x04, 0x0486 }, { 0x05, 0x0bc0 }, { 0x06, 0x0ae6 }, { 0x07, 0x082a },
242 { 0x08, 0x001f }, { 0x09, 0x0334 }, { 0x0a, 0x0fd4 }, { 0x0b, 0x0391 },
243 { 0x0c, 0x0050 }, { 0x0d, 0x06db }, { 0x0e, 0x0029 }, { 0x0f, 0x0914 },
246 static struct urtw_pair urtw_8225_rf_part2[] = {
247 { 0x00, 0x01 }, { 0x01, 0x02 }, { 0x02, 0x42 }, { 0x03, 0x00 },
248 { 0x04, 0x00 }, { 0x05, 0x00 }, { 0x06, 0x40 }, { 0x07, 0x00 },
249 { 0x08, 0x40 }, { 0x09, 0xfe }, { 0x0a, 0x09 }, { 0x0b, 0x80 },
250 { 0x0c, 0x01 }, { 0x0e, 0xd3 }, { 0x0f, 0x38 }, { 0x10, 0x84 },
251 { 0x11, 0x06 }, { 0x12, 0x20 }, { 0x13, 0x20 }, { 0x14, 0x00 },
252 { 0x15, 0x40 }, { 0x16, 0x00 }, { 0x17, 0x40 }, { 0x18, 0xef },
253 { 0x19, 0x19 }, { 0x1a, 0x20 }, { 0x1b, 0x76 }, { 0x1c, 0x04 },
254 { 0x1e, 0x95 }, { 0x1f, 0x75 }, { 0x20, 0x1f }, { 0x21, 0x27 },
255 { 0x22, 0x16 }, { 0x24, 0x46 }, { 0x25, 0x20 }, { 0x26, 0x90 },
259 static struct urtw_pair urtw_8225_rf_part3[] = {
260 { 0x00, 0x98 }, { 0x03, 0x20 }, { 0x04, 0x7e }, { 0x05, 0x12 },
261 { 0x06, 0xfc }, { 0x07, 0x78 }, { 0x08, 0x2e }, { 0x10, 0x9b },
262 { 0x11, 0x88 }, { 0x12, 0x47 }, { 0x13, 0xd0 }, { 0x19, 0x00 },
263 { 0x1a, 0xa0 }, { 0x1b, 0x08 }, { 0x40, 0x86 }, { 0x41, 0x8d },
264 { 0x42, 0x15 }, { 0x43, 0x18 }, { 0x44, 0x1f }, { 0x45, 0x1e },
265 { 0x46, 0x1a }, { 0x47, 0x15 }, { 0x48, 0x10 }, { 0x49, 0x0a },
266 { 0x4a, 0x05 }, { 0x4b, 0x02 }, { 0x4c, 0x05 }
269 static uint16_t urtw_8225_rxgain[] = {
270 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
271 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
272 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
273 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
274 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
275 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
276 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
277 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
278 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
279 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
280 0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3,
281 0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb
284 static uint8_t urtw_8225_threshold[] = {
285 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd,
288 static uint8_t urtw_8225_tx_gain_cck_ofdm[] = {
289 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e
292 static uint8_t urtw_8225_txpwr_cck[] = {
293 0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02,
294 0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02,
295 0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02,
296 0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02,
297 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03,
298 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03
301 static uint8_t urtw_8225_txpwr_cck_ch14[] = {
302 0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00,
303 0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00,
304 0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00,
305 0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00,
306 0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00,
307 0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00
310 static uint8_t urtw_8225_txpwr_ofdm[]={
311 0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4
314 static uint8_t urtw_8225v2_gain_bg[]={
315 0x23, 0x15, 0xa5, /* -82-1dbm */
316 0x23, 0x15, 0xb5, /* -82-2dbm */
317 0x23, 0x15, 0xc5, /* -82-3dbm */
318 0x33, 0x15, 0xc5, /* -78dbm */
319 0x43, 0x15, 0xc5, /* -74dbm */
320 0x53, 0x15, 0xc5, /* -70dbm */
321 0x63, 0x15, 0xc5, /* -66dbm */
324 static struct urtw_pair urtw_8225v2_rf_part1[] = {
325 { 0x00, 0x02bf }, { 0x01, 0x0ee0 }, { 0x02, 0x044d }, { 0x03, 0x0441 },
326 { 0x04, 0x08c3 }, { 0x05, 0x0c72 }, { 0x06, 0x00e6 }, { 0x07, 0x082a },
327 { 0x08, 0x003f }, { 0x09, 0x0335 }, { 0x0a, 0x09d4 }, { 0x0b, 0x07bb },
328 { 0x0c, 0x0850 }, { 0x0d, 0x0cdf }, { 0x0e, 0x002b }, { 0x0f, 0x0114 }
331 static struct urtw_pair urtw_8225v2b_rf_part0[] = {
332 { 0x00, 0x00b7 }, { 0x01, 0x0ee0 }, { 0x02, 0x044d }, { 0x03, 0x0441 },
333 { 0x04, 0x08c3 }, { 0x05, 0x0c72 }, { 0x06, 0x00e6 }, { 0x07, 0x082a },
334 { 0x08, 0x003f }, { 0x09, 0x0335 }, { 0x0a, 0x09d4 }, { 0x0b, 0x07bb },
335 { 0x0c, 0x0850 }, { 0x0d, 0x0cdf }, { 0x0e, 0x002b }, { 0x0f, 0x0114 }
338 static struct urtw_pair urtw_8225v2b_rf_part1[] = {
339 {0x0f0, 0x32}, {0x0f1, 0x32}, {0x0f2, 0x00},
340 {0x0f3, 0x00}, {0x0f4, 0x32}, {0x0f5, 0x43},
341 {0x0f6, 0x00}, {0x0f7, 0x00}, {0x0f8, 0x46},
342 {0x0f9, 0xa4}, {0x0fa, 0x00}, {0x0fb, 0x00},
343 {0x0fc, 0x96}, {0x0fd, 0xa4}, {0x0fe, 0x00},
344 {0x0ff, 0x00}, {0x158, 0x4b}, {0x159, 0x00},
345 {0x15a, 0x4b}, {0x15b, 0x00}, {0x160, 0x4b},
346 {0x161, 0x09}, {0x162, 0x4b}, {0x163, 0x09},
347 {0x1ce, 0x0f}, {0x1cf, 0x00}, {0x1e0, 0xff},
348 {0x1e1, 0x0f}, {0x1e2, 0x00}, {0x1f0, 0x4e},
349 {0x1f1, 0x01}, {0x1f2, 0x02}, {0x1f3, 0x03},
350 {0x1f4, 0x04}, {0x1f5, 0x05}, {0x1f6, 0x06},
351 {0x1f7, 0x07}, {0x1f8, 0x08}, {0x24e, 0x00},
352 {0x20c, 0x04}, {0x221, 0x61}, {0x222, 0x68},
353 {0x223, 0x6f}, {0x224, 0x76}, {0x225, 0x7d},
354 {0x226, 0x84}, {0x227, 0x8d}, {0x24d, 0x08},
355 {0x250, 0x05}, {0x251, 0xf5}, {0x252, 0x04},
356 {0x253, 0xa0}, {0x254, 0x1f}, {0x255, 0x23},
357 {0x256, 0x45}, {0x257, 0x67}, {0x258, 0x08},
358 {0x259, 0x08}, {0x25a, 0x08}, {0x25b, 0x08},
359 {0x260, 0x08}, {0x261, 0x08}, {0x262, 0x08},
360 {0x263, 0x08}, {0x264, 0xcf}, {0x272, 0x56},
361 {0x273, 0x9a}, {0x034, 0xf0}, {0x035, 0x0f},
362 {0x05b, 0x40}, {0x084, 0x88}, {0x085, 0x24},
363 {0x088, 0x54}, {0x08b, 0xb8}, {0x08c, 0x07},
364 {0x08d, 0x00}, {0x094, 0x1b}, {0x095, 0x12},
365 {0x096, 0x00}, {0x097, 0x06}, {0x09d, 0x1a},
366 {0x09f, 0x10}, {0x0b4, 0x22}, {0x0be, 0x80},
367 {0x0db, 0x00}, {0x0ee, 0x00}, {0x091, 0x03},
368 {0x24c, 0x00}, {0x39f, 0x00}, {0x08c, 0x01},
369 {0x08d, 0x10}, {0x08e, 0x08}, {0x08f, 0x00}
372 static struct urtw_pair urtw_8225v2_rf_part2[] = {
373 { 0x00, 0x01 }, { 0x01, 0x02 }, { 0x02, 0x42 }, { 0x03, 0x00 },
374 { 0x04, 0x00 }, { 0x05, 0x00 }, { 0x06, 0x40 }, { 0x07, 0x00 },
375 { 0x08, 0x40 }, { 0x09, 0xfe }, { 0x0a, 0x08 }, { 0x0b, 0x80 },
376 { 0x0c, 0x01 }, { 0x0d, 0x43 }, { 0x0e, 0xd3 }, { 0x0f, 0x38 },
377 { 0x10, 0x84 }, { 0x11, 0x07 }, { 0x12, 0x20 }, { 0x13, 0x20 },
378 { 0x14, 0x00 }, { 0x15, 0x40 }, { 0x16, 0x00 }, { 0x17, 0x40 },
379 { 0x18, 0xef }, { 0x19, 0x19 }, { 0x1a, 0x20 }, { 0x1b, 0x15 },
380 { 0x1c, 0x04 }, { 0x1d, 0xc5 }, { 0x1e, 0x95 }, { 0x1f, 0x75 },
381 { 0x20, 0x1f }, { 0x21, 0x17 }, { 0x22, 0x16 }, { 0x23, 0x80 },
382 { 0x24, 0x46 }, { 0x25, 0x00 }, { 0x26, 0x90 }, { 0x27, 0x88 }
385 static struct urtw_pair urtw_8225v2b_rf_part2[] = {
386 { 0x00, 0x10 }, { 0x01, 0x0d }, { 0x02, 0x01 }, { 0x03, 0x00 },
387 { 0x04, 0x14 }, { 0x05, 0xfb }, { 0x06, 0xfb }, { 0x07, 0x60 },
388 { 0x08, 0x00 }, { 0x09, 0x60 }, { 0x0a, 0x00 }, { 0x0b, 0x00 },
389 { 0x0c, 0x00 }, { 0x0d, 0x5c }, { 0x0e, 0x00 }, { 0x0f, 0x00 },
390 { 0x10, 0x40 }, { 0x11, 0x00 }, { 0x12, 0x40 }, { 0x13, 0x00 },
391 { 0x14, 0x00 }, { 0x15, 0x00 }, { 0x16, 0xa8 }, { 0x17, 0x26 },
392 { 0x18, 0x32 }, { 0x19, 0x33 }, { 0x1a, 0x07 }, { 0x1b, 0xa5 },
393 { 0x1c, 0x6f }, { 0x1d, 0x55 }, { 0x1e, 0xc8 }, { 0x1f, 0xb3 },
394 { 0x20, 0x0a }, { 0x21, 0xe1 }, { 0x22, 0x2C }, { 0x23, 0x8a },
395 { 0x24, 0x86 }, { 0x25, 0x83 }, { 0x26, 0x34 }, { 0x27, 0x0f },
396 { 0x28, 0x4f }, { 0x29, 0x24 }, { 0x2a, 0x6f }, { 0x2b, 0xc2 },
397 { 0x2c, 0x6b }, { 0x2d, 0x40 }, { 0x2e, 0x80 }, { 0x2f, 0x00 },
398 { 0x30, 0xc0 }, { 0x31, 0xc1 }, { 0x32, 0x58 }, { 0x33, 0xf1 },
399 { 0x34, 0x00 }, { 0x35, 0xe4 }, { 0x36, 0x90 }, { 0x37, 0x3e },
400 { 0x38, 0x6d }, { 0x39, 0x3c }, { 0x3a, 0xfb }, { 0x3b, 0x07 }
403 static struct urtw_pair urtw_8225v2_rf_part3[] = {
404 { 0x00, 0x98 }, { 0x03, 0x20 }, { 0x04, 0x7e }, { 0x05, 0x12 },
405 { 0x06, 0xfc }, { 0x07, 0x78 }, { 0x08, 0x2e }, { 0x09, 0x11 },
406 { 0x0a, 0x17 }, { 0x0b, 0x11 }, { 0x10, 0x9b }, { 0x11, 0x88 },
407 { 0x12, 0x47 }, { 0x13, 0xd0 }, { 0x19, 0x00 }, { 0x1a, 0xa0 },
408 { 0x1b, 0x08 }, { 0x1d, 0x00 }, { 0x40, 0x86 }, { 0x41, 0x9d },
409 { 0x42, 0x15 }, { 0x43, 0x18 }, { 0x44, 0x36 }, { 0x45, 0x35 },
410 { 0x46, 0x2e }, { 0x47, 0x25 }, { 0x48, 0x1c }, { 0x49, 0x12 },
411 { 0x4a, 0x09 }, { 0x4b, 0x04 }, { 0x4c, 0x05 }
414 static uint16_t urtw_8225v2_rxgain[] = {
415 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0008, 0x0009,
416 0x000a, 0x000b, 0x0102, 0x0103, 0x0104, 0x0105, 0x0140, 0x0141,
417 0x0142, 0x0143, 0x0144, 0x0145, 0x0180, 0x0181, 0x0182, 0x0183,
418 0x0184, 0x0185, 0x0188, 0x0189, 0x018a, 0x018b, 0x0243, 0x0244,
419 0x0245, 0x0280, 0x0281, 0x0282, 0x0283, 0x0284, 0x0285, 0x0288,
420 0x0289, 0x028a, 0x028b, 0x028c, 0x0342, 0x0343, 0x0344, 0x0345,
421 0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x0388, 0x0389,
422 0x038a, 0x038b, 0x038c, 0x038d, 0x0390, 0x0391, 0x0392, 0x0393,
423 0x0394, 0x0395, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d,
424 0x03a0, 0x03a1, 0x03a2, 0x03a3, 0x03a4, 0x03a5, 0x03a8, 0x03a9,
425 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
426 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
429 static uint16_t urtw_8225v2b_rxgain[] = {
430 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
431 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
432 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
433 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
434 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
435 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
436 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
437 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
438 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
439 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
440 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
441 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
444 static uint8_t urtw_8225v2_tx_gain_cck_ofdm[] = {
445 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
446 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
447 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
448 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
449 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
450 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
453 static uint8_t urtw_8225v2_txpwr_cck[] = {
454 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04
457 static uint8_t urtw_8225v2_txpwr_cck_ch14[] = {
458 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00
461 static uint8_t urtw_8225v2b_txpwr_cck[] = {
462 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04,
463 0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03,
464 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03,
465 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03
468 static uint8_t urtw_8225v2b_txpwr_cck_ch14[] = {
469 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00,
470 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
471 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
472 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00
475 static struct urtw_pair urtw_ratetable[] = {
476 { 2, 0 }, { 4, 1 }, { 11, 2 }, { 12, 4 }, { 18, 5 },
477 { 22, 3 }, { 24, 6 }, { 36, 7 }, { 48, 8 }, { 72, 9 },
478 { 96, 10 }, { 108, 11 }
481 static const uint8_t urtw_8187b_reg_table[][3] = {
482 { 0xf0, 0x32, 0 }, { 0xf1, 0x32, 0 }, { 0xf2, 0x00, 0 },
483 { 0xf3, 0x00, 0 }, { 0xf4, 0x32, 0 }, { 0xf5, 0x43, 0 },
484 { 0xf6, 0x00, 0 }, { 0xf7, 0x00, 0 }, { 0xf8, 0x46, 0 },
485 { 0xf9, 0xa4, 0 }, { 0xfa, 0x00, 0 }, { 0xfb, 0x00, 0 },
486 { 0xfc, 0x96, 0 }, { 0xfd, 0xa4, 0 }, { 0xfe, 0x00, 0 },
487 { 0xff, 0x00, 0 }, { 0x58, 0x4b, 1 }, { 0x59, 0x00, 1 },
488 { 0x5a, 0x4b, 1 }, { 0x5b, 0x00, 1 }, { 0x60, 0x4b, 1 },
489 { 0x61, 0x09, 1 }, { 0x62, 0x4b, 1 }, { 0x63, 0x09, 1 },
490 { 0xce, 0x0f, 1 }, { 0xcf, 0x00, 1 }, { 0xe0, 0xff, 1 },
491 { 0xe1, 0x0f, 1 }, { 0xe2, 0x00, 1 }, { 0xf0, 0x4e, 1 },
492 { 0xf1, 0x01, 1 }, { 0xf2, 0x02, 1 }, { 0xf3, 0x03, 1 },
493 { 0xf4, 0x04, 1 }, { 0xf5, 0x05, 1 }, { 0xf6, 0x06, 1 },
494 { 0xf7, 0x07, 1 }, { 0xf8, 0x08, 1 }, { 0x4e, 0x00, 2 },
495 { 0x0c, 0x04, 2 }, { 0x21, 0x61, 2 }, { 0x22, 0x68, 2 },
496 { 0x23, 0x6f, 2 }, { 0x24, 0x76, 2 }, { 0x25, 0x7d, 2 },
497 { 0x26, 0x84, 2 }, { 0x27, 0x8d, 2 }, { 0x4d, 0x08, 2 },
498 { 0x50, 0x05, 2 }, { 0x51, 0xf5, 2 }, { 0x52, 0x04, 2 },
499 { 0x53, 0xa0, 2 }, { 0x54, 0x1f, 2 }, { 0x55, 0x23, 2 },
500 { 0x56, 0x45, 2 }, { 0x57, 0x67, 2 }, { 0x58, 0x08, 2 },
501 { 0x59, 0x08, 2 }, { 0x5a, 0x08, 2 }, { 0x5b, 0x08, 2 },
502 { 0x60, 0x08, 2 }, { 0x61, 0x08, 2 }, { 0x62, 0x08, 2 },
503 { 0x63, 0x08, 2 }, { 0x64, 0xcf, 2 }, { 0x72, 0x56, 2 },
504 { 0x73, 0x9a, 2 }, { 0x34, 0xf0, 0 }, { 0x35, 0x0f, 0 },
505 { 0x5b, 0x40, 0 }, { 0x84, 0x88, 0 }, { 0x85, 0x24, 0 },
506 { 0x88, 0x54, 0 }, { 0x8b, 0xb8, 0 }, { 0x8c, 0x07, 0 },
507 { 0x8d, 0x00, 0 }, { 0x94, 0x1b, 0 }, { 0x95, 0x12, 0 },
508 { 0x96, 0x00, 0 }, { 0x97, 0x06, 0 }, { 0x9d, 0x1a, 0 },
509 { 0x9f, 0x10, 0 }, { 0xb4, 0x22, 0 }, { 0xbe, 0x80, 0 },
510 { 0xdb, 0x00, 0 }, { 0xee, 0x00, 0 }, { 0x91, 0x03, 0 },
511 { 0x4c, 0x00, 2 }, { 0x9f, 0x00, 3 }, { 0x8c, 0x01, 0 },
512 { 0x8d, 0x10, 0 }, { 0x8e, 0x08, 0 }, { 0x8f, 0x00, 0 }
515 static usb_callback_t urtw_bulk_rx_callback;
516 static usb_callback_t urtw_bulk_tx_callback;
517 static usb_callback_t urtw_bulk_tx_status_callback;
519 static const struct usb_config urtw_8187b_usbconfig[URTW_8187B_N_XFERS] = {
520 [URTW_8187B_BULK_RX] = {
523 .direction = UE_DIR_IN,
530 .callback = urtw_bulk_rx_callback
532 [URTW_8187B_BULK_TX_STATUS] = {
535 .direction = UE_DIR_IN,
542 .callback = urtw_bulk_tx_status_callback
544 [URTW_8187B_BULK_TX_BE] = {
546 .endpoint = URTW_8187B_TXPIPE_BE,
547 .direction = UE_DIR_OUT,
548 .bufsize = URTW_TX_MAXSIZE,
551 .force_short_xfer = 1,
554 .callback = urtw_bulk_tx_callback,
555 .timeout = URTW_DATA_TIMEOUT
557 [URTW_8187B_BULK_TX_BK] = {
559 .endpoint = URTW_8187B_TXPIPE_BK,
560 .direction = UE_DIR_OUT,
561 .bufsize = URTW_TX_MAXSIZE,
564 .force_short_xfer = 1,
567 .callback = urtw_bulk_tx_callback,
568 .timeout = URTW_DATA_TIMEOUT
570 [URTW_8187B_BULK_TX_VI] = {
572 .endpoint = URTW_8187B_TXPIPE_VI,
573 .direction = UE_DIR_OUT,
574 .bufsize = URTW_TX_MAXSIZE,
577 .force_short_xfer = 1,
580 .callback = urtw_bulk_tx_callback,
581 .timeout = URTW_DATA_TIMEOUT
583 [URTW_8187B_BULK_TX_VO] = {
585 .endpoint = URTW_8187B_TXPIPE_VO,
586 .direction = UE_DIR_OUT,
587 .bufsize = URTW_TX_MAXSIZE,
590 .force_short_xfer = 1,
593 .callback = urtw_bulk_tx_callback,
594 .timeout = URTW_DATA_TIMEOUT
596 [URTW_8187B_BULK_TX_EP12] = {
599 .direction = UE_DIR_OUT,
600 .bufsize = URTW_TX_MAXSIZE,
603 .force_short_xfer = 1,
606 .callback = urtw_bulk_tx_callback,
607 .timeout = URTW_DATA_TIMEOUT
611 static const struct usb_config urtw_8187l_usbconfig[URTW_8187L_N_XFERS] = {
612 [URTW_8187L_BULK_RX] = {
615 .direction = UE_DIR_IN,
622 .callback = urtw_bulk_rx_callback
624 [URTW_8187L_BULK_TX_LOW] = {
627 .direction = UE_DIR_OUT,
628 .bufsize = URTW_TX_MAXSIZE,
631 .force_short_xfer = 1,
634 .callback = urtw_bulk_tx_callback,
635 .timeout = URTW_DATA_TIMEOUT
637 [URTW_8187L_BULK_TX_NORMAL] = {
640 .direction = UE_DIR_OUT,
641 .bufsize = URTW_TX_MAXSIZE,
644 .force_short_xfer = 1,
647 .callback = urtw_bulk_tx_callback,
648 .timeout = URTW_DATA_TIMEOUT
652 static struct ieee80211vap *urtw_vap_create(struct ieee80211com *,
653 const char name[IFNAMSIZ], int unit, int opmode,
654 int flags, const uint8_t bssid[IEEE80211_ADDR_LEN],
655 const uint8_t mac[IEEE80211_ADDR_LEN]);
656 static void urtw_vap_delete(struct ieee80211vap *);
657 static void urtw_init(void *);
658 static void urtw_stop(struct ifnet *, int);
659 static void urtw_stop_locked(struct ifnet *, int);
660 static int urtw_ioctl(struct ifnet *, u_long, caddr_t);
661 static void urtw_start(struct ifnet *);
662 static int urtw_alloc_rx_data_list(struct urtw_softc *);
663 static int urtw_alloc_tx_data_list(struct urtw_softc *);
664 static int urtw_raw_xmit(struct ieee80211_node *, struct mbuf *,
665 const struct ieee80211_bpf_params *);
666 static void urtw_scan_start(struct ieee80211com *);
667 static void urtw_scan_end(struct ieee80211com *);
668 static void urtw_set_channel(struct ieee80211com *);
669 static void urtw_update_mcast(struct ifnet *);
670 static int urtw_tx_start(struct urtw_softc *,
671 struct ieee80211_node *, struct mbuf *,
672 struct urtw_data *, int);
673 static int urtw_newstate(struct ieee80211vap *,
674 enum ieee80211_state, int);
675 static void urtw_led_ch(void *);
676 static void urtw_ledtask(void *, int);
677 static void urtw_watchdog(void *);
678 static void urtw_set_multi(void *);
679 static int urtw_isbmode(uint16_t);
680 static uint16_t urtw_rate2rtl(int);
681 static uint16_t urtw_rtl2rate(int);
682 static usb_error_t urtw_set_rate(struct urtw_softc *);
683 static usb_error_t urtw_update_msr(struct urtw_softc *);
684 static usb_error_t urtw_read8_c(struct urtw_softc *, int, uint8_t *);
685 static usb_error_t urtw_read16_c(struct urtw_softc *, int, uint16_t *);
686 static usb_error_t urtw_read32_c(struct urtw_softc *, int, uint32_t *);
687 static usb_error_t urtw_write8_c(struct urtw_softc *, int, uint8_t);
688 static usb_error_t urtw_write16_c(struct urtw_softc *, int, uint16_t);
689 static usb_error_t urtw_write32_c(struct urtw_softc *, int, uint32_t);
690 static usb_error_t urtw_eprom_cs(struct urtw_softc *, int);
691 static usb_error_t urtw_eprom_ck(struct urtw_softc *);
692 static usb_error_t urtw_eprom_sendbits(struct urtw_softc *, int16_t *,
694 static usb_error_t urtw_eprom_read32(struct urtw_softc *, uint32_t,
696 static usb_error_t urtw_eprom_readbit(struct urtw_softc *, int16_t *);
697 static usb_error_t urtw_eprom_writebit(struct urtw_softc *, int16_t);
698 static usb_error_t urtw_get_macaddr(struct urtw_softc *);
699 static usb_error_t urtw_get_txpwr(struct urtw_softc *);
700 static usb_error_t urtw_get_rfchip(struct urtw_softc *);
701 static usb_error_t urtw_led_init(struct urtw_softc *);
702 static usb_error_t urtw_8185_rf_pins_enable(struct urtw_softc *);
703 static usb_error_t urtw_8185_tx_antenna(struct urtw_softc *, uint8_t);
704 static usb_error_t urtw_8187_write_phy(struct urtw_softc *, uint8_t,
706 static usb_error_t urtw_8187_write_phy_ofdm_c(struct urtw_softc *,
708 static usb_error_t urtw_8187_write_phy_cck_c(struct urtw_softc *, uint8_t,
710 static usb_error_t urtw_8225_setgain(struct urtw_softc *, int16_t);
711 static usb_error_t urtw_8225_usb_init(struct urtw_softc *);
712 static usb_error_t urtw_8225_write_c(struct urtw_softc *, uint8_t,
714 static usb_error_t urtw_8225_write_s16(struct urtw_softc *, uint8_t, int,
716 static usb_error_t urtw_8225_read(struct urtw_softc *, uint8_t,
718 static usb_error_t urtw_8225_rf_init(struct urtw_softc *);
719 static usb_error_t urtw_8225_rf_set_chan(struct urtw_softc *, int);
720 static usb_error_t urtw_8225_rf_set_sens(struct urtw_softc *, int);
721 static usb_error_t urtw_8225_set_txpwrlvl(struct urtw_softc *, int);
722 static usb_error_t urtw_8225_rf_stop(struct urtw_softc *);
723 static usb_error_t urtw_8225v2_rf_init(struct urtw_softc *);
724 static usb_error_t urtw_8225v2_rf_set_chan(struct urtw_softc *, int);
725 static usb_error_t urtw_8225v2_set_txpwrlvl(struct urtw_softc *, int);
726 static usb_error_t urtw_8225v2_setgain(struct urtw_softc *, int16_t);
727 static usb_error_t urtw_8225_isv2(struct urtw_softc *, int *);
728 static usb_error_t urtw_8225v2b_rf_init(struct urtw_softc *);
729 static usb_error_t urtw_8225v2b_rf_set_chan(struct urtw_softc *, int);
730 static usb_error_t urtw_read8e(struct urtw_softc *, int, uint8_t *);
731 static usb_error_t urtw_write8e(struct urtw_softc *, int, uint8_t);
732 static usb_error_t urtw_8180_set_anaparam(struct urtw_softc *, uint32_t);
733 static usb_error_t urtw_8185_set_anaparam2(struct urtw_softc *, uint32_t);
734 static usb_error_t urtw_intr_enable(struct urtw_softc *);
735 static usb_error_t urtw_intr_disable(struct urtw_softc *);
736 static usb_error_t urtw_reset(struct urtw_softc *);
737 static usb_error_t urtw_led_on(struct urtw_softc *, int);
738 static usb_error_t urtw_led_ctl(struct urtw_softc *, int);
739 static usb_error_t urtw_led_blink(struct urtw_softc *);
740 static usb_error_t urtw_led_mode0(struct urtw_softc *, int);
741 static usb_error_t urtw_led_mode1(struct urtw_softc *, int);
742 static usb_error_t urtw_led_mode2(struct urtw_softc *, int);
743 static usb_error_t urtw_led_mode3(struct urtw_softc *, int);
744 static usb_error_t urtw_rx_setconf(struct urtw_softc *);
745 static usb_error_t urtw_rx_enable(struct urtw_softc *);
746 static usb_error_t urtw_tx_enable(struct urtw_softc *sc);
747 static void urtw_free_tx_data_list(struct urtw_softc *);
748 static void urtw_free_rx_data_list(struct urtw_softc *);
749 static void urtw_free_data_list(struct urtw_softc *,
750 struct urtw_data data[], int, int);
751 static usb_error_t urtw_adapter_start(struct urtw_softc *);
752 static usb_error_t urtw_adapter_start_b(struct urtw_softc *);
753 static usb_error_t urtw_set_mode(struct urtw_softc *, uint32_t);
754 static usb_error_t urtw_8187b_cmd_reset(struct urtw_softc *);
755 static usb_error_t urtw_do_request(struct urtw_softc *,
756 struct usb_device_request *, void *);
757 static usb_error_t urtw_8225v2b_set_txpwrlvl(struct urtw_softc *, int);
758 static usb_error_t urtw_led_off(struct urtw_softc *, int);
759 static void urtw_abort_xfers(struct urtw_softc *);
760 static struct urtw_data *
761 urtw_getbuf(struct urtw_softc *sc);
762 static int urtw_compute_txtime(uint16_t, uint16_t, uint8_t,
764 static void urtw_updateslot(struct ifnet *);
765 static void urtw_updateslottask(void *, int);
766 static void urtw_sysctl_node(struct urtw_softc *);
769 urtw_match(device_t dev)
771 struct usb_attach_arg *uaa = device_get_ivars(dev);
773 if (uaa->usb_mode != USB_MODE_HOST)
775 if (uaa->info.bConfigIndex != URTW_CONFIG_INDEX)
777 if (uaa->info.bIfaceIndex != URTW_IFACE_INDEX)
780 return (usbd_lookup_id_by_uaa(urtw_devs, sizeof(urtw_devs), uaa));
784 urtw_attach(device_t dev)
786 const struct usb_config *setup_start;
788 struct urtw_softc *sc = device_get_softc(dev);
789 struct usb_attach_arg *uaa = device_get_ivars(dev);
790 struct ieee80211com *ic;
792 uint8_t bands, iface_index = URTW_IFACE_INDEX; /* XXX */
797 device_set_usb_desc(dev);
800 sc->sc_udev = uaa->device;
801 if (USB_GET_DRIVER_INFO(uaa) == URTW_REV_RTL8187B)
802 sc->sc_flags |= URTW_RTL8187B;
804 sc->sc_debug = urtw_debug;
807 mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev), MTX_NETWORK_LOCK,
809 usb_callout_init_mtx(&sc->sc_led_ch, &sc->sc_mtx, 0);
810 TASK_INIT(&sc->sc_led_task, 0, urtw_ledtask, sc);
811 TASK_INIT(&sc->sc_updateslot_task, 0, urtw_updateslottask, sc);
812 callout_init(&sc->sc_watchdog_ch, 0);
814 if (sc->sc_flags & URTW_RTL8187B) {
815 setup_start = urtw_8187b_usbconfig;
816 n_setup = URTW_8187B_N_XFERS;
818 setup_start = urtw_8187l_usbconfig;
819 n_setup = URTW_8187L_N_XFERS;
822 error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_xfer,
823 setup_start, n_setup, sc, &sc->sc_mtx);
825 device_printf(dev, "could not allocate USB transfers, "
826 "err=%s\n", usbd_errstr(error));
833 urtw_read32_m(sc, URTW_RX, &data);
834 sc->sc_epromtype = (data & URTW_RX_9356SEL) ? URTW_EEPROM_93C56 :
837 error = urtw_get_rfchip(sc);
840 error = urtw_get_macaddr(sc);
843 error = urtw_get_txpwr(sc);
846 error = urtw_led_init(sc);
852 sc->sc_rts_retry = URTW_DEFAULT_RTS_RETRY;
853 sc->sc_tx_retry = URTW_DEFAULT_TX_RETRY;
855 sc->sc_preamble_mode = urtw_preamble_mode;
857 ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
859 device_printf(sc->sc_dev, "can not allocate ifnet\n");
865 if_initname(ifp, "urtw", device_get_unit(sc->sc_dev));
866 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
867 ifp->if_init = urtw_init;
868 ifp->if_ioctl = urtw_ioctl;
869 ifp->if_start = urtw_start;
870 /* XXX URTW_TX_DATA_LIST_COUNT */
871 IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
872 ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
873 IFQ_SET_READY(&ifp->if_snd);
877 ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
878 ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
880 /* set device capabilities */
882 IEEE80211_C_STA | /* station mode */
883 IEEE80211_C_MONITOR | /* monitor mode supported */
884 IEEE80211_C_TXPMGT | /* tx power management */
885 IEEE80211_C_SHPREAMBLE | /* short preamble supported */
886 IEEE80211_C_SHSLOT | /* short slot time supported */
887 IEEE80211_C_BGSCAN | /* capable of bg scanning */
888 IEEE80211_C_WPA; /* 802.11i */
891 setbit(&bands, IEEE80211_MODE_11B);
892 setbit(&bands, IEEE80211_MODE_11G);
893 ieee80211_init_channels(ic, NULL, &bands);
895 ieee80211_ifattach(ic, sc->sc_bssid);
896 ic->ic_raw_xmit = urtw_raw_xmit;
897 ic->ic_scan_start = urtw_scan_start;
898 ic->ic_scan_end = urtw_scan_end;
899 ic->ic_set_channel = urtw_set_channel;
900 ic->ic_updateslot = urtw_updateslot;
901 ic->ic_vap_create = urtw_vap_create;
902 ic->ic_vap_delete = urtw_vap_delete;
903 ic->ic_update_mcast = urtw_update_mcast;
905 ieee80211_radiotap_attach(ic,
906 &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
907 URTW_TX_RADIOTAP_PRESENT,
908 &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
909 URTW_RX_RADIOTAP_PRESENT);
911 urtw_sysctl_node(sc);
914 ieee80211_announce(ic);
917 fail: URTW_UNLOCK(sc);
918 fail1: usbd_transfer_unsetup(sc->sc_xfer, (sc->sc_flags & URTW_RTL8187B) ?
919 URTW_8187B_N_XFERS : URTW_8187L_N_XFERS);
925 urtw_detach(device_t dev)
927 struct urtw_softc *sc = device_get_softc(dev);
928 struct ifnet *ifp = sc->sc_ifp;
929 struct ieee80211com *ic = ifp->if_l2com;
931 if (!device_is_attached(dev))
935 ieee80211_draintask(ic, &sc->sc_updateslot_task);
936 ieee80211_draintask(ic, &sc->sc_led_task);
938 usb_callout_drain(&sc->sc_led_ch);
939 callout_drain(&sc->sc_watchdog_ch);
941 usbd_transfer_unsetup(sc->sc_xfer, (sc->sc_flags & URTW_RTL8187B) ?
942 URTW_8187B_N_XFERS : URTW_8187L_N_XFERS);
943 ieee80211_ifdetach(ic);
945 urtw_free_tx_data_list(sc);
946 urtw_free_rx_data_list(sc);
949 mtx_destroy(&sc->sc_mtx);
955 urtw_free_tx_data_list(struct urtw_softc *sc)
958 urtw_free_data_list(sc, sc->sc_tx, URTW_TX_DATA_LIST_COUNT, 0);
962 urtw_free_rx_data_list(struct urtw_softc *sc)
965 urtw_free_data_list(sc, sc->sc_rx, URTW_RX_DATA_LIST_COUNT, 1);
969 urtw_free_data_list(struct urtw_softc *sc, struct urtw_data data[], int ndata,
974 for (i = 0; i < ndata; i++) {
975 struct urtw_data *dp = &data[i];
984 if (dp->buf != NULL) {
985 free(dp->buf, M_USBDEV);
989 if (dp->ni != NULL) {
990 ieee80211_free_node(dp->ni);
996 static struct ieee80211vap *
997 urtw_vap_create(struct ieee80211com *ic,
998 const char name[IFNAMSIZ], int unit, int opmode, int flags,
999 const uint8_t bssid[IEEE80211_ADDR_LEN],
1000 const uint8_t mac[IEEE80211_ADDR_LEN])
1002 struct urtw_vap *uvp;
1003 struct ieee80211vap *vap;
1005 if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
1007 uvp = (struct urtw_vap *) malloc(sizeof(struct urtw_vap),
1008 M_80211_VAP, M_NOWAIT | M_ZERO);
1012 /* enable s/w bmiss handling for sta mode */
1013 ieee80211_vap_setup(ic, vap, name, unit, opmode,
1014 flags | IEEE80211_CLONE_NOBEACONS, bssid, mac);
1016 /* override state transition machine */
1017 uvp->newstate = vap->iv_newstate;
1018 vap->iv_newstate = urtw_newstate;
1020 /* complete setup */
1021 ieee80211_vap_attach(vap, ieee80211_media_change,
1022 ieee80211_media_status);
1023 ic->ic_opmode = opmode;
1028 urtw_vap_delete(struct ieee80211vap *vap)
1030 struct urtw_vap *uvp = URTW_VAP(vap);
1032 ieee80211_vap_detach(vap);
1033 free(uvp, M_80211_VAP);
1037 urtw_init_locked(void *arg)
1040 struct urtw_softc *sc = arg;
1041 struct ifnet *ifp = sc->sc_ifp;
1044 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1045 urtw_stop_locked(ifp, 0);
1047 error = (sc->sc_flags & URTW_RTL8187B) ? urtw_adapter_start_b(sc) :
1048 urtw_adapter_start(sc);
1052 /* reset softc variables */
1055 if (!(sc->sc_flags & URTW_INIT_ONCE)) {
1056 ret = urtw_alloc_rx_data_list(sc);
1059 ret = urtw_alloc_tx_data_list(sc);
1062 sc->sc_flags |= URTW_INIT_ONCE;
1065 error = urtw_rx_enable(sc);
1068 error = urtw_tx_enable(sc);
1072 if (sc->sc_flags & URTW_RTL8187B)
1073 usbd_transfer_start(sc->sc_xfer[URTW_8187B_BULK_TX_STATUS]);
1075 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
1076 ifp->if_drv_flags |= IFF_DRV_RUNNING;
1078 callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc);
1084 urtw_init(void *arg)
1086 struct urtw_softc *sc = arg;
1089 urtw_init_locked(arg);
1094 urtw_adapter_start_b(struct urtw_softc *sc)
1096 #define N(a) (sizeof(a) / sizeof((a)[0]))
1100 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
1104 urtw_read8_m(sc, URTW_CONFIG3, &data8);
1105 urtw_write8_m(sc, URTW_CONFIG3,
1106 data8 | URTW_CONFIG3_ANAPARAM_WRITE | URTW_CONFIG3_GNT_SELECT);
1107 urtw_write32_m(sc, URTW_ANAPARAM2, URTW_8187B_8225_ANAPARAM2_ON);
1108 urtw_write32_m(sc, URTW_ANAPARAM, URTW_8187B_8225_ANAPARAM_ON);
1109 urtw_write8_m(sc, URTW_ANAPARAM3, URTW_8187B_8225_ANAPARAM3_ON);
1111 urtw_write8_m(sc, 0x61, 0x10);
1112 urtw_read8_m(sc, 0x62, &data8);
1113 urtw_write8_m(sc, 0x62, data8 & ~(1 << 5));
1114 urtw_write8_m(sc, 0x62, data8 | (1 << 5));
1116 urtw_read8_m(sc, URTW_CONFIG3, &data8);
1117 data8 &= ~URTW_CONFIG3_ANAPARAM_WRITE;
1118 urtw_write8_m(sc, URTW_CONFIG3, data8);
1120 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
1124 error = urtw_8187b_cmd_reset(sc);
1128 error = sc->sc_rf_init(sc);
1131 urtw_write8_m(sc, URTW_CMD, URTW_CMD_RX_ENABLE | URTW_CMD_TX_ENABLE);
1133 /* fix RTL8187B RX stall */
1134 error = urtw_intr_enable(sc);
1138 error = urtw_write8e(sc, 0x41, 0xf4);
1141 error = urtw_write8e(sc, 0x40, 0x00);
1144 error = urtw_write8e(sc, 0x42, 0x00);
1147 error = urtw_write8e(sc, 0x42, 0x01);
1150 error = urtw_write8e(sc, 0x40, 0x0f);
1153 error = urtw_write8e(sc, 0x42, 0x00);
1156 error = urtw_write8e(sc, 0x42, 0x01);
1160 urtw_read8_m(sc, 0xdb, &data8);
1161 urtw_write8_m(sc, 0xdb, data8 | (1 << 2));
1162 urtw_write16_m(sc, 0x372, 0x59fa);
1163 urtw_write16_m(sc, 0x374, 0x59d2);
1164 urtw_write16_m(sc, 0x376, 0x59d2);
1165 urtw_write16_m(sc, 0x378, 0x19fa);
1166 urtw_write16_m(sc, 0x37a, 0x19fa);
1167 urtw_write16_m(sc, 0x37c, 0x00d0);
1168 urtw_write8_m(sc, 0x61, 0);
1170 urtw_write8_m(sc, 0x180, 0x0f);
1171 urtw_write8_m(sc, 0x183, 0x03);
1172 urtw_write8_m(sc, 0xda, 0x10);
1173 urtw_write8_m(sc, 0x24d, 0x08);
1174 urtw_write32_m(sc, URTW_HSSI_PARA, 0x0600321b);
1176 urtw_write16_m(sc, 0x1ec, 0x800); /* RX MAX SIZE */
1183 urtw_adapter_start(struct urtw_softc *sc)
1187 error = urtw_reset(sc);
1191 urtw_write8_m(sc, URTW_ADDR_MAGIC1, 0);
1192 urtw_write8_m(sc, URTW_GPIO, 0);
1195 urtw_write8_m(sc, URTW_ADDR_MAGIC1, 4);
1196 error = urtw_led_ctl(sc, URTW_LED_CTL_POWER_ON);
1200 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
1203 /* applying MAC address again. */
1204 urtw_write32_m(sc, URTW_MAC0, ((uint32_t *)sc->sc_bssid)[0]);
1205 urtw_write16_m(sc, URTW_MAC4, ((uint32_t *)sc->sc_bssid)[1] & 0xffff);
1206 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
1210 error = urtw_update_msr(sc);
1214 urtw_write32_m(sc, URTW_INT_TIMEOUT, 0);
1215 urtw_write8_m(sc, URTW_WPA_CONFIG, 0);
1216 urtw_write8_m(sc, URTW_RATE_FALLBACK, URTW_RATE_FALLBACK_ENABLE | 0x1);
1217 error = urtw_set_rate(sc);
1221 error = sc->sc_rf_init(sc);
1224 if (sc->sc_rf_set_sens != NULL)
1225 sc->sc_rf_set_sens(sc, sc->sc_sens);
1227 /* XXX correct? to call write16 */
1228 urtw_write16_m(sc, URTW_PSR, 1);
1229 urtw_write16_m(sc, URTW_ADDR_MAGIC2, 0x10);
1230 urtw_write8_m(sc, URTW_TALLY_SEL, 0x80);
1231 urtw_write8_m(sc, URTW_ADDR_MAGIC3, 0x60);
1232 /* XXX correct? to call write16 */
1233 urtw_write16_m(sc, URTW_PSR, 0);
1234 urtw_write8_m(sc, URTW_ADDR_MAGIC1, 4);
1236 error = urtw_intr_enable(sc);
1245 urtw_set_mode(struct urtw_softc *sc, uint32_t mode)
1250 urtw_read8_m(sc, URTW_EPROM_CMD, &data);
1251 data = (data & ~URTW_EPROM_CMD_MASK) | (mode << URTW_EPROM_CMD_SHIFT);
1252 data = data & ~(URTW_EPROM_CS | URTW_EPROM_CK);
1253 urtw_write8_m(sc, URTW_EPROM_CMD, data);
1259 urtw_8187b_cmd_reset(struct urtw_softc *sc)
1265 /* XXX the code can be duplicate with urtw_reset(). */
1266 urtw_read8_m(sc, URTW_CMD, &data8);
1267 data8 = (data8 & 0x2) | URTW_CMD_RST;
1268 urtw_write8_m(sc, URTW_CMD, data8);
1270 for (i = 0; i < 20; i++) {
1271 usb_pause_mtx(&sc->sc_mtx, 2);
1272 urtw_read8_m(sc, URTW_CMD, &data8);
1273 if (!(data8 & URTW_CMD_RST))
1277 device_printf(sc->sc_dev, "reset timeout\n");
1285 urtw_do_request(struct urtw_softc *sc,
1286 struct usb_device_request *req, void *data)
1291 URTW_ASSERT_LOCKED(sc);
1294 err = usbd_do_request_flags(sc->sc_udev, &sc->sc_mtx,
1295 req, data, 0, NULL, 250 /* ms */);
1299 DPRINTF(sc, URTW_DEBUG_INIT,
1300 "Control request failed, %s (retrying)\n",
1302 usb_pause_mtx(&sc->sc_mtx, hz / 100);
1308 urtw_stop_locked(struct ifnet *ifp, int disable)
1310 struct urtw_softc *sc = ifp->if_softc;
1315 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
1317 error = urtw_intr_disable(sc);
1320 urtw_read8_m(sc, URTW_CMD, &data8);
1321 data8 &= ~(URTW_CMD_RX_ENABLE | URTW_CMD_TX_ENABLE);
1322 urtw_write8_m(sc, URTW_CMD, data8);
1324 error = sc->sc_rf_stop(sc);
1328 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
1331 urtw_read8_m(sc, URTW_CONFIG4, &data8);
1332 urtw_write8_m(sc, URTW_CONFIG4, data8 | URTW_CONFIG4_VCOOFF);
1333 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
1338 device_printf(sc->sc_dev, "failed to stop (%s)\n",
1339 usbd_errstr(error));
1341 usb_callout_stop(&sc->sc_led_ch);
1342 callout_stop(&sc->sc_watchdog_ch);
1344 urtw_abort_xfers(sc);
1348 urtw_stop(struct ifnet *ifp, int disable)
1350 struct urtw_softc *sc = ifp->if_softc;
1353 urtw_stop_locked(ifp, disable);
1358 urtw_abort_xfers(struct urtw_softc *sc)
1362 URTW_ASSERT_LOCKED(sc);
1364 max = (sc->sc_flags & URTW_RTL8187B) ? URTW_8187B_N_XFERS :
1367 /* abort any pending transfers */
1368 for (i = 0; i < max; i++)
1369 usbd_transfer_stop(sc->sc_xfer[i]);
1373 urtw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1375 struct urtw_softc *sc = ifp->if_softc;
1376 struct ieee80211com *ic = ifp->if_l2com;
1377 struct ifreq *ifr = (struct ifreq *) data;
1378 int error = 0, startall = 0;
1382 if (ifp->if_flags & IFF_UP) {
1383 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
1384 if ((ifp->if_flags ^ sc->sc_if_flags) &
1385 (IFF_ALLMULTI | IFF_PROMISC))
1388 urtw_init(ifp->if_softc);
1392 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1395 sc->sc_if_flags = ifp->if_flags;
1397 ieee80211_start_all(ic);
1400 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
1403 error = ether_ioctl(ifp, cmd, data);
1414 urtw_start(struct ifnet *ifp)
1416 struct urtw_data *bf;
1417 struct urtw_softc *sc = ifp->if_softc;
1418 struct ieee80211_node *ni;
1421 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
1426 IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
1429 bf = urtw_getbuf(sc);
1431 IFQ_DRV_PREPEND(&ifp->if_snd, m);
1435 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
1436 m->m_pkthdr.rcvif = NULL;
1438 if (urtw_tx_start(sc, ni, m, bf, URTW_PRIORITY_NORMAL) != 0) {
1440 STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
1441 ieee80211_free_node(ni);
1446 callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc);
1452 urtw_alloc_data_list(struct urtw_softc *sc, struct urtw_data data[],
1453 int ndata, int maxsz, int fillmbuf)
1457 for (i = 0; i < ndata; i++) {
1458 struct urtw_data *dp = &data[i];
1462 dp->m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
1463 if (dp->m == NULL) {
1464 device_printf(sc->sc_dev,
1465 "could not allocate rx mbuf\n");
1469 dp->buf = mtod(dp->m, uint8_t *);
1472 dp->buf = malloc(maxsz, M_USBDEV, M_NOWAIT);
1473 if (dp->buf == NULL) {
1474 device_printf(sc->sc_dev,
1475 "could not allocate buffer\n");
1479 if (((unsigned long)dp->buf) % 4)
1480 device_printf(sc->sc_dev,
1481 "warn: unaligned buffer %p\n", dp->buf);
1488 fail: urtw_free_data_list(sc, data, ndata, fillmbuf);
1493 urtw_alloc_rx_data_list(struct urtw_softc *sc)
1497 error = urtw_alloc_data_list(sc,
1498 sc->sc_rx, URTW_RX_DATA_LIST_COUNT, MCLBYTES, 1 /* mbufs */);
1502 STAILQ_INIT(&sc->sc_rx_active);
1503 STAILQ_INIT(&sc->sc_rx_inactive);
1505 for (i = 0; i < URTW_RX_DATA_LIST_COUNT; i++)
1506 STAILQ_INSERT_HEAD(&sc->sc_rx_inactive, &sc->sc_rx[i], next);
1512 urtw_alloc_tx_data_list(struct urtw_softc *sc)
1516 error = urtw_alloc_data_list(sc,
1517 sc->sc_tx, URTW_TX_DATA_LIST_COUNT, URTW_TX_MAXSIZE,
1522 STAILQ_INIT(&sc->sc_tx_active);
1523 STAILQ_INIT(&sc->sc_tx_inactive);
1524 STAILQ_INIT(&sc->sc_tx_pending);
1526 for (i = 0; i < URTW_TX_DATA_LIST_COUNT; i++)
1527 STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, &sc->sc_tx[i],
1534 urtw_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
1535 const struct ieee80211_bpf_params *params)
1537 struct ieee80211com *ic = ni->ni_ic;
1538 struct ifnet *ifp = ic->ic_ifp;
1539 struct urtw_data *bf;
1540 struct urtw_softc *sc = ifp->if_softc;
1542 /* prevent management frames from being sent if we're not ready */
1543 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
1545 ieee80211_free_node(ni);
1549 bf = urtw_getbuf(sc);
1551 ieee80211_free_node(ni);
1554 return (ENOBUFS); /* XXX */
1558 if (urtw_tx_start(sc, ni, m, bf, URTW_PRIORITY_LOW) != 0) {
1559 ieee80211_free_node(ni);
1561 STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
1572 urtw_scan_start(struct ieee80211com *ic)
1575 /* XXX do nothing? */
1579 urtw_scan_end(struct ieee80211com *ic)
1582 /* XXX do nothing? */
1586 urtw_set_channel(struct ieee80211com *ic)
1588 struct urtw_softc *sc = ic->ic_ifp->if_softc;
1589 struct ifnet *ifp = sc->sc_ifp;
1590 uint32_t data, orig;
1594 * if the user set a channel explicitly using ifconfig(8) this function
1595 * can be called earlier than we're expected that in some cases the
1596 * initialization would be failed if setting a channel is called before
1597 * the init have done.
1599 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
1602 if (sc->sc_curchan != NULL && sc->sc_curchan == ic->ic_curchan)
1608 * during changing th channel we need to temporarily be disable
1611 urtw_read32_m(sc, URTW_TX_CONF, &orig);
1612 data = orig & ~URTW_TX_LOOPBACK_MASK;
1613 urtw_write32_m(sc, URTW_TX_CONF, data | URTW_TX_LOOPBACK_MAC);
1615 error = sc->sc_rf_set_chan(sc, ieee80211_chan2ieee(ic, ic->ic_curchan));
1618 usb_pause_mtx(&sc->sc_mtx, 10);
1619 urtw_write32_m(sc, URTW_TX_CONF, orig);
1621 urtw_write16_m(sc, URTW_ATIM_WND, 2);
1622 urtw_write16_m(sc, URTW_ATIM_TR_ITV, 100);
1623 urtw_write16_m(sc, URTW_BEACON_INTERVAL, 100);
1624 urtw_write16_m(sc, URTW_BEACON_INTERVAL_TIME, 100);
1629 sc->sc_curchan = ic->ic_curchan;
1632 device_printf(sc->sc_dev, "could not change the channel\n");
1636 urtw_update_mcast(struct ifnet *ifp)
1639 /* XXX do nothing? */
1643 urtw_tx_start(struct urtw_softc *sc, struct ieee80211_node *ni, struct mbuf *m0,
1644 struct urtw_data *data, int prior)
1646 struct ifnet *ifp = sc->sc_ifp;
1647 struct ieee80211_frame *wh = mtod(m0, struct ieee80211_frame *);
1648 struct ieee80211_key *k;
1649 const struct ieee80211_txparam *tp;
1650 struct ieee80211com *ic = ifp->if_l2com;
1651 struct ieee80211vap *vap = ni->ni_vap;
1652 struct usb_xfer *rtl8187b_pipes[URTW_8187B_TXPIPE_MAX] = {
1653 sc->sc_xfer[URTW_8187B_BULK_TX_BE],
1654 sc->sc_xfer[URTW_8187B_BULK_TX_BK],
1655 sc->sc_xfer[URTW_8187B_BULK_TX_VI],
1656 sc->sc_xfer[URTW_8187B_BULK_TX_VO]
1658 struct usb_xfer *xfer;
1659 int dur = 0, rtsdur = 0, rtsenable = 0, ctsenable = 0, rate,
1660 pkttime = 0, txdur = 0, isshort = 0, xferlen;
1661 uint16_t acktime, rtstime, ctstime;
1665 URTW_ASSERT_LOCKED(sc);
1670 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
1671 k = ieee80211_crypto_encap(ni, m0);
1673 device_printf(sc->sc_dev,
1674 "ieee80211_crypto_encap returns NULL.\n");
1675 /* XXX we don't expect the fragmented frames */
1680 /* in case packet header moved, reset pointer */
1681 wh = mtod(m0, struct ieee80211_frame *);
1684 if (ieee80211_radiotap_active_vap(vap)) {
1685 struct urtw_tx_radiotap_header *tap = &sc->sc_txtap;
1687 /* XXX Are variables correct? */
1689 tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
1690 tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
1692 ieee80211_radiotap_tx(vap, m0);
1695 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_MGT ||
1696 (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL) {
1697 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
1698 rate = tp->mgmtrate;
1700 tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)];
1701 /* for data frames */
1702 if (IEEE80211_IS_MULTICAST(wh->i_addr1))
1703 rate = tp->mcastrate;
1704 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
1705 rate = tp->ucastrate;
1707 rate = urtw_rtl2rate(sc->sc_currate);
1710 sc->sc_stats.txrates[sc->sc_currate]++;
1712 if (IEEE80211_IS_MULTICAST(wh->i_addr1))
1713 txdur = pkttime = urtw_compute_txtime(m0->m_pkthdr.len +
1714 IEEE80211_CRC_LEN, rate, 0, 0);
1716 acktime = urtw_compute_txtime(14, 2,0, 0);
1717 if ((m0->m_pkthdr.len + 4) > vap->iv_rtsthreshold) {
1720 rtstime = urtw_compute_txtime(URTW_ACKCTS_LEN, 2, 0, 0);
1721 ctstime = urtw_compute_txtime(14, 2, 0, 0);
1722 pkttime = urtw_compute_txtime(m0->m_pkthdr.len +
1723 IEEE80211_CRC_LEN, rate, 0, isshort);
1724 rtsdur = ctstime + pkttime + acktime +
1725 3 * URTW_ASIFS_TIME;
1726 txdur = rtstime + rtsdur;
1728 rtsenable = ctsenable = rtsdur = 0;
1729 pkttime = urtw_compute_txtime(m0->m_pkthdr.len +
1730 IEEE80211_CRC_LEN, rate, 0, isshort);
1731 txdur = pkttime + URTW_ASIFS_TIME + acktime;
1734 if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG)
1735 dur = urtw_compute_txtime(m0->m_pkthdr.len +
1736 IEEE80211_CRC_LEN, rate, 0, isshort) +
1737 3 * URTW_ASIFS_TIME +
1740 dur = URTW_ASIFS_TIME + acktime;
1742 *(uint16_t *)wh->i_dur = htole16(dur);
1744 xferlen = m0->m_pkthdr.len;
1745 xferlen += (sc->sc_flags & URTW_RTL8187B) ? (4 * 8) : (4 * 3);
1746 if ((0 == xferlen % 64) || (0 == xferlen % 512))
1749 bzero(data->buf, URTW_TX_MAXSIZE);
1750 flags = m0->m_pkthdr.len & 0xfff;
1751 flags |= URTW_TX_FLAG_NO_ENC;
1752 if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
1753 (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE) &&
1754 (sc->sc_preamble_mode == URTW_PREAMBLE_MODE_SHORT) &&
1755 (sc->sc_currate != 0))
1756 flags |= URTW_TX_FLAG_SPLCP;
1757 if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG)
1758 flags |= URTW_TX_FLAG_MOREFRAG;
1760 flags |= (sc->sc_currate & 0xf) << URTW_TX_FLAG_TXRATE_SHIFT;
1762 if (sc->sc_flags & URTW_RTL8187B) {
1763 struct urtw_8187b_txhdr *tx;
1765 tx = (struct urtw_8187b_txhdr *)data->buf;
1767 flags |= URTW_TX_FLAG_CTS;
1769 flags |= URTW_TX_FLAG_RTS;
1770 flags |= (urtw_rate2rtl(11) & 0xf) <<
1771 URTW_TX_FLAG_RTSRATE_SHIFT;
1772 tx->rtsdur = rtsdur;
1774 tx->flag = htole32(flags);
1776 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
1777 IEEE80211_FC0_TYPE_MGT &&
1778 (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) ==
1779 IEEE80211_FC0_SUBTYPE_PROBE_RESP)
1782 tx->retry = URTW_TX_MAXRETRY;
1783 m_copydata(m0, 0, m0->m_pkthdr.len, (uint8_t *)(tx + 1));
1785 struct urtw_8187l_txhdr *tx;
1787 tx = (struct urtw_8187l_txhdr *)data->buf;
1789 flags |= URTW_TX_FLAG_RTS;
1790 tx->rtsdur = rtsdur;
1792 flags |= (urtw_rate2rtl(11) & 0xf) << URTW_TX_FLAG_RTSRATE_SHIFT;
1793 tx->flag = htole32(flags);
1794 tx->retry = 3; /* CW minimum */
1795 tx->retry = 7 << 4; /* CW maximum */
1796 tx->retry = URTW_TX_MAXRETRY << 8; /* retry limitation */
1797 m_copydata(m0, 0, m0->m_pkthdr.len, (uint8_t *)(tx + 1));
1800 data->buflen = xferlen;
1804 if (sc->sc_flags & URTW_RTL8187B) {
1805 switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) {
1806 case IEEE80211_FC0_TYPE_CTL:
1807 case IEEE80211_FC0_TYPE_MGT:
1808 xfer = sc->sc_xfer[URTW_8187B_BULK_TX_EP12];
1811 KASSERT(M_WME_GETAC(m0) < URTW_8187B_TXPIPE_MAX,
1812 ("unsupported WME pipe %d", M_WME_GETAC(m0)));
1813 xfer = rtl8187b_pipes[M_WME_GETAC(m0)];
1817 xfer = (prior == URTW_PRIORITY_LOW) ?
1818 sc->sc_xfer[URTW_8187L_BULK_TX_LOW] :
1819 sc->sc_xfer[URTW_8187L_BULK_TX_NORMAL];
1821 STAILQ_INSERT_TAIL(&sc->sc_tx_pending, data, next);
1822 usbd_transfer_start(xfer);
1824 error = urtw_led_ctl(sc, URTW_LED_CTL_TX);
1826 device_printf(sc->sc_dev, "could not control LED (%d)\n",
1832 urtw_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
1834 struct ieee80211_node *ni = vap->iv_bss;
1835 struct ieee80211com *ic = vap->iv_ic;
1836 struct urtw_softc *sc = ic->ic_ifp->if_softc;
1837 struct urtw_vap *uvp = URTW_VAP(vap);
1838 usb_error_t error = 0;
1840 DPRINTF(sc, URTW_DEBUG_STATE, "%s: %s -> %s\n", __func__,
1841 ieee80211_state_name[vap->iv_state],
1842 ieee80211_state_name[nstate]);
1844 sc->sc_state = nstate;
1846 IEEE80211_UNLOCK(ic);
1848 usb_callout_stop(&sc->sc_led_ch);
1849 callout_stop(&sc->sc_watchdog_ch);
1852 case IEEE80211_S_INIT:
1853 case IEEE80211_S_SCAN:
1854 case IEEE80211_S_AUTH:
1855 case IEEE80211_S_ASSOC:
1857 case IEEE80211_S_RUN:
1858 /* setting bssid. */
1859 urtw_write32_m(sc, URTW_BSSID, ((uint32_t *)ni->ni_bssid)[0]);
1860 urtw_write16_m(sc, URTW_BSSID + 4,
1861 ((uint16_t *)ni->ni_bssid)[2]);
1862 urtw_update_msr(sc);
1863 /* XXX maybe the below would be incorrect. */
1864 urtw_write16_m(sc, URTW_ATIM_WND, 2);
1865 urtw_write16_m(sc, URTW_ATIM_TR_ITV, 100);
1866 urtw_write16_m(sc, URTW_BEACON_INTERVAL, 0x64);
1867 urtw_write16_m(sc, URTW_BEACON_INTERVAL_TIME, 100);
1868 error = urtw_led_ctl(sc, URTW_LED_CTL_LINK);
1870 device_printf(sc->sc_dev,
1871 "could not control LED (%d)\n", error);
1879 return (uvp->newstate(vap, nstate, arg));
1883 urtw_watchdog(void *arg)
1885 struct urtw_softc *sc = arg;
1886 struct ifnet *ifp = sc->sc_ifp;
1888 if (sc->sc_txtimer > 0) {
1889 if (--sc->sc_txtimer == 0) {
1890 device_printf(sc->sc_dev, "device timeout\n");
1894 callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc);
1899 urtw_set_multi(void *arg)
1901 struct urtw_softc *sc = arg;
1902 struct ifnet *ifp = sc->sc_ifp;
1904 if (!(ifp->if_flags & IFF_UP))
1908 * XXX don't know how to set a device. Lack of docs. Just try to set
1909 * IFF_ALLMULTI flag here.
1911 ifp->if_flags |= IFF_ALLMULTI;
1915 urtw_set_rate(struct urtw_softc *sc)
1917 int i, basic_rate, min_rr_rate, max_rr_rate;
1921 basic_rate = urtw_rate2rtl(48);
1922 min_rr_rate = urtw_rate2rtl(12);
1923 max_rr_rate = urtw_rate2rtl(48);
1925 urtw_write8_m(sc, URTW_RESP_RATE,
1926 max_rr_rate << URTW_RESP_MAX_RATE_SHIFT |
1927 min_rr_rate << URTW_RESP_MIN_RATE_SHIFT);
1929 urtw_read16_m(sc, URTW_BRSR, &data);
1930 data &= ~URTW_BRSR_MBR_8185;
1932 for (i = 0; i <= basic_rate; i++)
1935 urtw_write16_m(sc, URTW_BRSR, data);
1941 urtw_rate2rtl(int rate)
1943 #define N(a) (sizeof(a) / sizeof((a)[0]))
1946 for (i = 0; i < N(urtw_ratetable); i++) {
1947 if (rate == urtw_ratetable[i].reg)
1948 return urtw_ratetable[i].val;
1956 urtw_rtl2rate(int rate)
1958 #define N(a) (sizeof(a) / sizeof((a)[0]))
1961 for (i = 0; i < N(urtw_ratetable); i++) {
1962 if (rate == urtw_ratetable[i].val)
1963 return urtw_ratetable[i].reg;
1971 urtw_update_msr(struct urtw_softc *sc)
1973 struct ifnet *ifp = sc->sc_ifp;
1974 struct ieee80211com *ic = ifp->if_l2com;
1978 urtw_read8_m(sc, URTW_MSR, &data);
1979 data &= ~URTW_MSR_LINK_MASK;
1981 if (sc->sc_state == IEEE80211_S_RUN) {
1982 switch (ic->ic_opmode) {
1983 case IEEE80211_M_STA:
1984 case IEEE80211_M_MONITOR:
1985 data |= URTW_MSR_LINK_STA;
1986 if (sc->sc_flags & URTW_RTL8187B)
1987 data |= URTW_MSR_LINK_ENEDCA;
1989 case IEEE80211_M_IBSS:
1990 data |= URTW_MSR_LINK_ADHOC;
1992 case IEEE80211_M_HOSTAP:
1993 data |= URTW_MSR_LINK_HOSTAP;
1996 panic("unsupported operation mode 0x%x\n",
2001 data |= URTW_MSR_LINK_NONE;
2003 urtw_write8_m(sc, URTW_MSR, data);
2009 urtw_read8_c(struct urtw_softc *sc, int val, uint8_t *data)
2011 struct usb_device_request req;
2014 URTW_ASSERT_LOCKED(sc);
2016 req.bmRequestType = UT_READ_VENDOR_DEVICE;
2017 req.bRequest = URTW_8187_GETREGS_REQ;
2018 USETW(req.wValue, (val & 0xff) | 0xff00);
2019 USETW(req.wIndex, (val >> 8) & 0x3);
2020 USETW(req.wLength, sizeof(uint8_t));
2022 error = urtw_do_request(sc, &req, data);
2027 urtw_read16_c(struct urtw_softc *sc, int val, uint16_t *data)
2029 struct usb_device_request req;
2032 URTW_ASSERT_LOCKED(sc);
2034 req.bmRequestType = UT_READ_VENDOR_DEVICE;
2035 req.bRequest = URTW_8187_GETREGS_REQ;
2036 USETW(req.wValue, (val & 0xff) | 0xff00);
2037 USETW(req.wIndex, (val >> 8) & 0x3);
2038 USETW(req.wLength, sizeof(uint16_t));
2040 error = urtw_do_request(sc, &req, data);
2045 urtw_read32_c(struct urtw_softc *sc, int val, uint32_t *data)
2047 struct usb_device_request req;
2050 URTW_ASSERT_LOCKED(sc);
2052 req.bmRequestType = UT_READ_VENDOR_DEVICE;
2053 req.bRequest = URTW_8187_GETREGS_REQ;
2054 USETW(req.wValue, (val & 0xff) | 0xff00);
2055 USETW(req.wIndex, (val >> 8) & 0x3);
2056 USETW(req.wLength, sizeof(uint32_t));
2058 error = urtw_do_request(sc, &req, data);
2063 urtw_write8_c(struct urtw_softc *sc, int val, uint8_t data)
2065 struct usb_device_request req;
2067 URTW_ASSERT_LOCKED(sc);
2069 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
2070 req.bRequest = URTW_8187_SETREGS_REQ;
2071 USETW(req.wValue, (val & 0xff) | 0xff00);
2072 USETW(req.wIndex, (val >> 8) & 0x3);
2073 USETW(req.wLength, sizeof(uint8_t));
2075 return (urtw_do_request(sc, &req, &data));
2079 urtw_write16_c(struct urtw_softc *sc, int val, uint16_t data)
2081 struct usb_device_request req;
2083 URTW_ASSERT_LOCKED(sc);
2085 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
2086 req.bRequest = URTW_8187_SETREGS_REQ;
2087 USETW(req.wValue, (val & 0xff) | 0xff00);
2088 USETW(req.wIndex, (val >> 8) & 0x3);
2089 USETW(req.wLength, sizeof(uint16_t));
2091 return (urtw_do_request(sc, &req, &data));
2095 urtw_write32_c(struct urtw_softc *sc, int val, uint32_t data)
2097 struct usb_device_request req;
2099 URTW_ASSERT_LOCKED(sc);
2101 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
2102 req.bRequest = URTW_8187_SETREGS_REQ;
2103 USETW(req.wValue, (val & 0xff) | 0xff00);
2104 USETW(req.wIndex, (val >> 8) & 0x3);
2105 USETW(req.wLength, sizeof(uint32_t));
2107 return (urtw_do_request(sc, &req, &data));
2111 urtw_get_macaddr(struct urtw_softc *sc)
2116 error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR, &data);
2119 sc->sc_bssid[0] = data & 0xff;
2120 sc->sc_bssid[1] = (data & 0xff00) >> 8;
2121 error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR + 1, &data);
2124 sc->sc_bssid[2] = data & 0xff;
2125 sc->sc_bssid[3] = (data & 0xff00) >> 8;
2126 error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR + 2, &data);
2129 sc->sc_bssid[4] = data & 0xff;
2130 sc->sc_bssid[5] = (data & 0xff00) >> 8;
2136 urtw_eprom_read32(struct urtw_softc *sc, uint32_t addr, uint32_t *data)
2138 #define URTW_READCMD_LEN 3
2140 int16_t addrstr[8], data16, readcmd[] = { 1, 1, 0 };
2143 /* NB: make sure the buffer is initialized */
2146 /* enable EPROM programming */
2147 urtw_write8_m(sc, URTW_EPROM_CMD, URTW_EPROM_CMD_PROGRAM_MODE);
2148 DELAY(URTW_EPROM_DELAY);
2150 error = urtw_eprom_cs(sc, URTW_EPROM_ENABLE);
2153 error = urtw_eprom_ck(sc);
2156 error = urtw_eprom_sendbits(sc, readcmd, URTW_READCMD_LEN);
2159 if (sc->sc_epromtype == URTW_EEPROM_93C56) {
2161 addrstr[0] = addr & (1 << 7);
2162 addrstr[1] = addr & (1 << 6);
2163 addrstr[2] = addr & (1 << 5);
2164 addrstr[3] = addr & (1 << 4);
2165 addrstr[4] = addr & (1 << 3);
2166 addrstr[5] = addr & (1 << 2);
2167 addrstr[6] = addr & (1 << 1);
2168 addrstr[7] = addr & (1 << 0);
2171 addrstr[0] = addr & (1 << 5);
2172 addrstr[1] = addr & (1 << 4);
2173 addrstr[2] = addr & (1 << 3);
2174 addrstr[3] = addr & (1 << 2);
2175 addrstr[4] = addr & (1 << 1);
2176 addrstr[5] = addr & (1 << 0);
2178 error = urtw_eprom_sendbits(sc, addrstr, addrlen);
2182 error = urtw_eprom_writebit(sc, 0);
2186 for (i = 0; i < 16; i++) {
2187 error = urtw_eprom_ck(sc);
2190 error = urtw_eprom_readbit(sc, &data16);
2194 (*data) |= (data16 << (15 - i));
2197 error = urtw_eprom_cs(sc, URTW_EPROM_DISABLE);
2200 error = urtw_eprom_ck(sc);
2204 /* now disable EPROM programming */
2205 urtw_write8_m(sc, URTW_EPROM_CMD, URTW_EPROM_CMD_NORMAL_MODE);
2208 #undef URTW_READCMD_LEN
2212 urtw_eprom_cs(struct urtw_softc *sc, int able)
2217 urtw_read8_m(sc, URTW_EPROM_CMD, &data);
2218 if (able == URTW_EPROM_ENABLE)
2219 urtw_write8_m(sc, URTW_EPROM_CMD, data | URTW_EPROM_CS);
2221 urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_CS);
2222 DELAY(URTW_EPROM_DELAY);
2228 urtw_eprom_ck(struct urtw_softc *sc)
2234 urtw_read8_m(sc, URTW_EPROM_CMD, &data);
2235 urtw_write8_m(sc, URTW_EPROM_CMD, data | URTW_EPROM_CK);
2236 DELAY(URTW_EPROM_DELAY);
2238 urtw_read8_m(sc, URTW_EPROM_CMD, &data);
2239 urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_CK);
2240 DELAY(URTW_EPROM_DELAY);
2246 urtw_eprom_readbit(struct urtw_softc *sc, int16_t *data)
2251 urtw_read8_m(sc, URTW_EPROM_CMD, &data8);
2252 *data = (data8 & URTW_EPROM_READBIT) ? 1 : 0;
2253 DELAY(URTW_EPROM_DELAY);
2260 urtw_eprom_writebit(struct urtw_softc *sc, int16_t bit)
2265 urtw_read8_m(sc, URTW_EPROM_CMD, &data);
2267 urtw_write8_m(sc, URTW_EPROM_CMD, data | URTW_EPROM_WRITEBIT);
2269 urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_WRITEBIT);
2270 DELAY(URTW_EPROM_DELAY);
2276 urtw_eprom_sendbits(struct urtw_softc *sc, int16_t *buf, int buflen)
2279 usb_error_t error = 0;
2281 for (i = 0; i < buflen; i++) {
2282 error = urtw_eprom_writebit(sc, buf[i]);
2285 error = urtw_eprom_ck(sc);
2295 urtw_get_txpwr(struct urtw_softc *sc)
2301 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW_BASE, &data);
2304 sc->sc_txpwr_cck_base = data & 0xf;
2305 sc->sc_txpwr_ofdm_base = (data >> 4) & 0xf;
2307 for (i = 1, j = 0; i < 6; i += 2, j++) {
2308 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW0 + j, &data);
2311 sc->sc_txpwr_cck[i] = data & 0xf;
2312 sc->sc_txpwr_cck[i + 1] = (data & 0xf00) >> 8;
2313 sc->sc_txpwr_ofdm[i] = (data & 0xf0) >> 4;
2314 sc->sc_txpwr_ofdm[i + 1] = (data & 0xf000) >> 12;
2316 for (i = 1, j = 0; i < 4; i += 2, j++) {
2317 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW1 + j, &data);
2320 sc->sc_txpwr_cck[i + 6] = data & 0xf;
2321 sc->sc_txpwr_cck[i + 6 + 1] = (data & 0xf00) >> 8;
2322 sc->sc_txpwr_ofdm[i + 6] = (data & 0xf0) >> 4;
2323 sc->sc_txpwr_ofdm[i + 6 + 1] = (data & 0xf000) >> 12;
2325 if (sc->sc_flags & URTW_RTL8187B) {
2326 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW2, &data);
2329 sc->sc_txpwr_cck[1 + 6 + 4] = data & 0xf;
2330 sc->sc_txpwr_ofdm[1 + 6 + 4] = (data & 0xf0) >> 4;
2331 error = urtw_eprom_read32(sc, 0x0a, &data);
2334 sc->sc_txpwr_cck[2 + 6 + 4] = data & 0xf;
2335 sc->sc_txpwr_ofdm[2 + 6 + 4] = (data & 0xf0) >> 4;
2336 error = urtw_eprom_read32(sc, 0x1c, &data);
2339 sc->sc_txpwr_cck[3 + 6 + 4] = data & 0xf;
2340 sc->sc_txpwr_cck[3 + 6 + 4 + 1] = (data & 0xf00) >> 8;
2341 sc->sc_txpwr_ofdm[3 + 6 + 4] = (data & 0xf0) >> 4;
2342 sc->sc_txpwr_ofdm[3 + 6 + 4 + 1] = (data & 0xf000) >> 12;
2344 for (i = 1, j = 0; i < 4; i += 2, j++) {
2345 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW2 + j,
2349 sc->sc_txpwr_cck[i + 6 + 4] = data & 0xf;
2350 sc->sc_txpwr_cck[i + 6 + 4 + 1] = (data & 0xf00) >> 8;
2351 sc->sc_txpwr_ofdm[i + 6 + 4] = (data & 0xf0) >> 4;
2352 sc->sc_txpwr_ofdm[i + 6 + 4 + 1] = (data & 0xf000) >> 12;
2361 urtw_get_rfchip(struct urtw_softc *sc)
2368 if (sc->sc_flags & URTW_RTL8187B) {
2369 urtw_read8_m(sc, 0xe1, &data8);
2372 sc->sc_flags |= URTW_RTL8187B_REV_B;
2375 sc->sc_flags |= URTW_RTL8187B_REV_D;
2378 sc->sc_flags |= URTW_RTL8187B_REV_E;
2381 device_printf(sc->sc_dev, "unknown type: %#x\n", data8);
2382 sc->sc_flags |= URTW_RTL8187B_REV_B;
2386 urtw_read32_m(sc, URTW_TX_CONF, &data);
2387 switch (data & URTW_TX_HWMASK) {
2388 case URTW_TX_R8187vD_B:
2389 sc->sc_flags |= URTW_RTL8187B;
2391 case URTW_TX_R8187vD:
2394 device_printf(sc->sc_dev, "unknown RTL8187L type: %#x\n",
2395 data & URTW_TX_HWMASK);
2400 error = urtw_eprom_read32(sc, URTW_EPROM_RFCHIPID, &data);
2403 switch (data & 0xff) {
2404 case URTW_EPROM_RFCHIPID_RTL8225U:
2405 error = urtw_8225_isv2(sc, &ret);
2409 sc->sc_rf_init = urtw_8225_rf_init;
2410 sc->sc_rf_set_sens = urtw_8225_rf_set_sens;
2411 sc->sc_rf_set_chan = urtw_8225_rf_set_chan;
2412 sc->sc_rf_stop = urtw_8225_rf_stop;
2414 sc->sc_rf_init = urtw_8225v2_rf_init;
2415 sc->sc_rf_set_chan = urtw_8225v2_rf_set_chan;
2416 sc->sc_rf_stop = urtw_8225_rf_stop;
2418 sc->sc_max_sens = URTW_8225_RF_MAX_SENS;
2419 sc->sc_sens = URTW_8225_RF_DEF_SENS;
2421 case URTW_EPROM_RFCHIPID_RTL8225Z2:
2422 sc->sc_rf_init = urtw_8225v2b_rf_init;
2423 sc->sc_rf_set_chan = urtw_8225v2b_rf_set_chan;
2424 sc->sc_max_sens = URTW_8225_RF_MAX_SENS;
2425 sc->sc_sens = URTW_8225_RF_DEF_SENS;
2426 sc->sc_rf_stop = urtw_8225_rf_stop;
2429 panic("unsupported RF chip %d\n", data & 0xff);
2433 device_printf(sc->sc_dev, "%s rf %s hwrev %s\n",
2434 (sc->sc_flags & URTW_RTL8187B) ? "rtl8187b" : "rtl8187l",
2435 ((data & 0xff) == URTW_EPROM_RFCHIPID_RTL8225U) ? "rtl8225u" :
2437 (sc->sc_flags & URTW_RTL8187B) ? ((data8 == 0) ? "b" :
2438 (data8 == 1) ? "d" : "e") : "none");
2446 urtw_led_init(struct urtw_softc *sc)
2451 urtw_read8_m(sc, URTW_PSR, &sc->sc_psr);
2452 error = urtw_eprom_read32(sc, URTW_EPROM_SWREV, &rev);
2456 switch (rev & URTW_EPROM_CID_MASK) {
2457 case URTW_EPROM_CID_ALPHA0:
2458 sc->sc_strategy = URTW_SW_LED_MODE1;
2460 case URTW_EPROM_CID_SERCOMM_PS:
2461 sc->sc_strategy = URTW_SW_LED_MODE3;
2463 case URTW_EPROM_CID_HW_LED:
2464 sc->sc_strategy = URTW_HW_LED;
2466 case URTW_EPROM_CID_RSVD0:
2467 case URTW_EPROM_CID_RSVD1:
2469 sc->sc_strategy = URTW_SW_LED_MODE0;
2473 sc->sc_gpio_ledpin = URTW_LED_PIN_GPIO0;
2481 urtw_8225_rf_init(struct urtw_softc *sc)
2483 #define N(a) (sizeof(a) / sizeof((a)[0]))
2488 error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
2492 error = urtw_8225_usb_init(sc);
2496 urtw_write32_m(sc, URTW_RF_TIMING, 0x000a8008);
2497 urtw_read16_m(sc, URTW_BRSR, &data); /* XXX ??? */
2498 urtw_write16_m(sc, URTW_BRSR, 0xffff);
2499 urtw_write32_m(sc, URTW_RF_PARA, 0x100044);
2501 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
2504 urtw_write8_m(sc, URTW_CONFIG3, 0x44);
2505 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
2509 error = urtw_8185_rf_pins_enable(sc);
2512 usb_pause_mtx(&sc->sc_mtx, 1000);
2514 for (i = 0; i < N(urtw_8225_rf_part1); i++) {
2515 urtw_8225_write(sc, urtw_8225_rf_part1[i].reg,
2516 urtw_8225_rf_part1[i].val);
2517 usb_pause_mtx(&sc->sc_mtx, 1);
2519 usb_pause_mtx(&sc->sc_mtx, 100);
2521 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC1);
2522 usb_pause_mtx(&sc->sc_mtx, 200);
2524 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC2);
2525 usb_pause_mtx(&sc->sc_mtx, 200);
2527 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC3);
2529 for (i = 0; i < 95; i++) {
2530 urtw_8225_write(sc, URTW_8225_ADDR_1_MAGIC, (uint8_t)(i + 1));
2531 urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC, urtw_8225_rxgain[i]);
2535 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC4);
2537 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC5);
2539 for (i = 0; i < 128; i++) {
2540 urtw_8187_write_phy_ofdm(sc, 0xb, urtw_8225_agc[i]);
2541 usb_pause_mtx(&sc->sc_mtx, 1);
2542 urtw_8187_write_phy_ofdm(sc, 0xa, (uint8_t)i + 0x80);
2543 usb_pause_mtx(&sc->sc_mtx, 1);
2546 for (i = 0; i < N(urtw_8225_rf_part2); i++) {
2547 urtw_8187_write_phy_ofdm(sc, urtw_8225_rf_part2[i].reg,
2548 urtw_8225_rf_part2[i].val);
2549 usb_pause_mtx(&sc->sc_mtx, 1);
2552 error = urtw_8225_setgain(sc, 4);
2556 for (i = 0; i < N(urtw_8225_rf_part3); i++) {
2557 urtw_8187_write_phy_cck(sc, urtw_8225_rf_part3[i].reg,
2558 urtw_8225_rf_part3[i].val);
2559 usb_pause_mtx(&sc->sc_mtx, 1);
2562 urtw_write8_m(sc, URTW_TESTR, 0x0d);
2564 error = urtw_8225_set_txpwrlvl(sc, 1);
2568 urtw_8187_write_phy_cck(sc, 0x10, 0x9b);
2569 usb_pause_mtx(&sc->sc_mtx, 1);
2570 urtw_8187_write_phy_ofdm(sc, 0x26, 0x90);
2571 usb_pause_mtx(&sc->sc_mtx, 1);
2573 /* TX ant A, 0x0 for B */
2574 error = urtw_8185_tx_antenna(sc, 0x3);
2577 urtw_write32_m(sc, URTW_HSSI_PARA, 0x3dc00002);
2579 error = urtw_8225_rf_set_chan(sc, 1);
2586 urtw_8185_rf_pins_enable(struct urtw_softc *sc)
2588 usb_error_t error = 0;
2590 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x1ff7);
2596 urtw_8185_tx_antenna(struct urtw_softc *sc, uint8_t ant)
2600 urtw_write8_m(sc, URTW_TX_ANTENNA, ant);
2601 usb_pause_mtx(&sc->sc_mtx, 1);
2607 urtw_8187_write_phy_ofdm_c(struct urtw_softc *sc, uint8_t addr, uint32_t data)
2611 return urtw_8187_write_phy(sc, addr, data);
2615 urtw_8187_write_phy_cck_c(struct urtw_softc *sc, uint8_t addr, uint32_t data)
2619 return urtw_8187_write_phy(sc, addr, data | 0x10000);
2623 urtw_8187_write_phy(struct urtw_softc *sc, uint8_t addr, uint32_t data)
2628 phyw = ((data << 8) | (addr | 0x80));
2629 urtw_write8_m(sc, URTW_PHY_MAGIC4, ((phyw & 0xff000000) >> 24));
2630 urtw_write8_m(sc, URTW_PHY_MAGIC3, ((phyw & 0x00ff0000) >> 16));
2631 urtw_write8_m(sc, URTW_PHY_MAGIC2, ((phyw & 0x0000ff00) >> 8));
2632 urtw_write8_m(sc, URTW_PHY_MAGIC1, ((phyw & 0x000000ff)));
2633 usb_pause_mtx(&sc->sc_mtx, 1);
2639 urtw_8225_setgain(struct urtw_softc *sc, int16_t gain)
2643 urtw_8187_write_phy_ofdm(sc, 0x0d, urtw_8225_gain[gain * 4]);
2644 urtw_8187_write_phy_ofdm(sc, 0x1b, urtw_8225_gain[gain * 4 + 2]);
2645 urtw_8187_write_phy_ofdm(sc, 0x1d, urtw_8225_gain[gain * 4 + 3]);
2646 urtw_8187_write_phy_ofdm(sc, 0x23, urtw_8225_gain[gain * 4 + 1]);
2652 urtw_8225_usb_init(struct urtw_softc *sc)
2657 urtw_write8_m(sc, URTW_RF_PINS_SELECT + 1, 0);
2658 urtw_write8_m(sc, URTW_GPIO, 0);
2659 error = urtw_read8e(sc, 0x53, &data);
2662 error = urtw_write8e(sc, 0x53, data | (1 << 7));
2665 urtw_write8_m(sc, URTW_RF_PINS_SELECT + 1, 4);
2666 urtw_write8_m(sc, URTW_GPIO, 0x20);
2667 urtw_write8_m(sc, URTW_GP_ENABLE, 0);
2669 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, 0x80);
2670 urtw_write16_m(sc, URTW_RF_PINS_SELECT, 0x80);
2671 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x80);
2673 usb_pause_mtx(&sc->sc_mtx, 500);
2679 urtw_8225_write_c(struct urtw_softc *sc, uint8_t addr, uint16_t data)
2681 uint16_t d80, d82, d84;
2684 urtw_read16_m(sc, URTW_RF_PINS_OUTPUT, &d80);
2685 d80 &= URTW_RF_PINS_MAGIC1;
2686 urtw_read16_m(sc, URTW_RF_PINS_ENABLE, &d82);
2687 urtw_read16_m(sc, URTW_RF_PINS_SELECT, &d84);
2688 d84 &= URTW_RF_PINS_MAGIC2;
2689 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, d82 | URTW_RF_PINS_MAGIC3);
2690 urtw_write16_m(sc, URTW_RF_PINS_SELECT, d84 | URTW_RF_PINS_MAGIC3);
2693 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80 | URTW_BB_HOST_BANG_EN);
2695 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80);
2698 error = urtw_8225_write_s16(sc, addr, 0x8225, &data);
2702 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80 | URTW_BB_HOST_BANG_EN);
2704 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80 | URTW_BB_HOST_BANG_EN);
2705 urtw_write16_m(sc, URTW_RF_PINS_SELECT, d84);
2706 usb_pause_mtx(&sc->sc_mtx, 2);
2711 /* XXX why we should allocalte memory buffer instead of using memory stack? */
2713 urtw_8225_write_s16(struct urtw_softc *sc, uint8_t addr, int index,
2718 struct usb_device_request *req;
2719 usb_error_t error = 0;
2722 req = (usb_device_request_t *)malloc(sizeof(usb_device_request_t),
2723 M_80211_VAP, M_NOWAIT | M_ZERO);
2725 device_printf(sc->sc_dev, "could not allocate a memory\n");
2728 buf = (uint8_t *)malloc(2, M_80211_VAP, M_NOWAIT | M_ZERO);
2730 device_printf(sc->sc_dev, "could not allocate a memory\n");
2734 req->bmRequestType = UT_WRITE_VENDOR_DEVICE;
2735 req->bRequest = URTW_8187_SETREGS_REQ;
2736 USETW(req->wValue, addr);
2737 USETW(req->wIndex, index);
2738 USETW(req->wLength, sizeof(uint16_t));
2739 buf[0] = (data16 & 0x00ff);
2740 buf[1] = (data16 & 0xff00) >> 8;
2742 error = urtw_do_request(sc, req, buf);
2744 free(buf, M_80211_VAP);
2745 fail1: free(req, M_80211_VAP);
2746 fail0: return (error);
2750 urtw_8225_rf_set_chan(struct urtw_softc *sc, int chan)
2754 error = urtw_8225_set_txpwrlvl(sc, chan);
2757 urtw_8225_write(sc, URTW_8225_ADDR_7_MAGIC, urtw_8225_channel[chan]);
2758 usb_pause_mtx(&sc->sc_mtx, 10);
2764 urtw_8225_rf_set_sens(struct urtw_softc *sc, int sens)
2768 if (sens < 0 || sens > 6)
2773 URTW_8225_ADDR_C_MAGIC, URTW_8225_ADDR_C_DATA_MAGIC1);
2776 URTW_8225_ADDR_C_MAGIC, URTW_8225_ADDR_C_DATA_MAGIC2);
2779 error = urtw_8225_setgain(sc, sens);
2783 urtw_8187_write_phy_cck(sc, 0x41, urtw_8225_threshold[sens]);
2790 urtw_8225_set_txpwrlvl(struct urtw_softc *sc, int chan)
2793 uint8_t *cck_pwltable;
2794 uint8_t cck_pwrlvl_max, ofdm_pwrlvl_min, ofdm_pwrlvl_max;
2795 uint8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
2796 uint8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
2799 cck_pwrlvl_max = 11;
2800 ofdm_pwrlvl_max = 25; /* 12 -> 25 */
2801 ofdm_pwrlvl_min = 10;
2803 /* CCK power setting */
2804 cck_pwrlvl = (cck_pwrlvl > cck_pwrlvl_max) ? cck_pwrlvl_max : cck_pwrlvl;
2805 idx = cck_pwrlvl % 6;
2806 set = cck_pwrlvl / 6;
2807 cck_pwltable = (chan == 14) ? urtw_8225_txpwr_cck_ch14 :
2808 urtw_8225_txpwr_cck;
2810 urtw_write8_m(sc, URTW_TX_GAIN_CCK,
2811 urtw_8225_tx_gain_cck_ofdm[set] >> 1);
2812 for (i = 0; i < 8; i++) {
2813 urtw_8187_write_phy_cck(sc, 0x44 + i,
2814 cck_pwltable[idx * 8 + i]);
2816 usb_pause_mtx(&sc->sc_mtx, 1);
2818 /* OFDM power setting */
2819 ofdm_pwrlvl = (ofdm_pwrlvl > (ofdm_pwrlvl_max - ofdm_pwrlvl_min)) ?
2820 ofdm_pwrlvl_max : ofdm_pwrlvl + ofdm_pwrlvl_min;
2821 ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
2823 idx = ofdm_pwrlvl % 6;
2824 set = ofdm_pwrlvl / 6;
2826 error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
2829 urtw_8187_write_phy_ofdm(sc, 2, 0x42);
2830 urtw_8187_write_phy_ofdm(sc, 6, 0);
2831 urtw_8187_write_phy_ofdm(sc, 8, 0);
2833 urtw_write8_m(sc, URTW_TX_GAIN_OFDM,
2834 urtw_8225_tx_gain_cck_ofdm[set] >> 1);
2835 urtw_8187_write_phy_ofdm(sc, 0x5, urtw_8225_txpwr_ofdm[idx]);
2836 urtw_8187_write_phy_ofdm(sc, 0x7, urtw_8225_txpwr_ofdm[idx]);
2837 usb_pause_mtx(&sc->sc_mtx, 1);
2844 urtw_8225_rf_stop(struct urtw_softc *sc)
2849 urtw_8225_write(sc, 0x4, 0x1f);
2851 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
2855 urtw_read8_m(sc, URTW_CONFIG3, &data);
2856 urtw_write8_m(sc, URTW_CONFIG3, data | URTW_CONFIG3_ANAPARAM_WRITE);
2857 if (sc->sc_flags & URTW_RTL8187B) {
2858 urtw_write32_m(sc, URTW_ANAPARAM2,
2859 URTW_8187B_8225_ANAPARAM2_OFF);
2860 urtw_write32_m(sc, URTW_ANAPARAM, URTW_8187B_8225_ANAPARAM_OFF);
2861 urtw_write32_m(sc, URTW_ANAPARAM3,
2862 URTW_8187B_8225_ANAPARAM3_OFF);
2864 urtw_write32_m(sc, URTW_ANAPARAM2, URTW_8225_ANAPARAM2_OFF);
2865 urtw_write32_m(sc, URTW_ANAPARAM, URTW_8225_ANAPARAM_OFF);
2868 urtw_write8_m(sc, URTW_CONFIG3, data & ~URTW_CONFIG3_ANAPARAM_WRITE);
2869 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
2878 urtw_8225v2_rf_init(struct urtw_softc *sc)
2880 #define N(a) (sizeof(a) / sizeof((a)[0]))
2886 error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
2890 error = urtw_8225_usb_init(sc);
2894 urtw_write32_m(sc, URTW_RF_TIMING, 0x000a8008);
2895 urtw_read16_m(sc, URTW_BRSR, &data); /* XXX ??? */
2896 urtw_write16_m(sc, URTW_BRSR, 0xffff);
2897 urtw_write32_m(sc, URTW_RF_PARA, 0x100044);
2899 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
2902 urtw_write8_m(sc, URTW_CONFIG3, 0x44);
2903 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
2907 error = urtw_8185_rf_pins_enable(sc);
2911 usb_pause_mtx(&sc->sc_mtx, 500);
2913 for (i = 0; i < N(urtw_8225v2_rf_part1); i++) {
2914 urtw_8225_write(sc, urtw_8225v2_rf_part1[i].reg,
2915 urtw_8225v2_rf_part1[i].val);
2917 usb_pause_mtx(&sc->sc_mtx, 50);
2920 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC1);
2922 for (i = 0; i < 95; i++) {
2923 urtw_8225_write(sc, URTW_8225_ADDR_1_MAGIC, (uint8_t)(i + 1));
2924 urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC,
2925 urtw_8225v2_rxgain[i]);
2929 URTW_8225_ADDR_3_MAGIC, URTW_8225_ADDR_3_DATA_MAGIC1);
2931 URTW_8225_ADDR_5_MAGIC, URTW_8225_ADDR_5_DATA_MAGIC1);
2933 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC2);
2935 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC1);
2936 usb_pause_mtx(&sc->sc_mtx, 100);
2938 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC2);
2939 usb_pause_mtx(&sc->sc_mtx, 100);
2941 error = urtw_8225_read(sc, URTW_8225_ADDR_6_MAGIC, &data32);
2944 if (data32 != URTW_8225_ADDR_6_DATA_MAGIC1)
2945 device_printf(sc->sc_dev, "expect 0xe6!! (0x%x)\n", data32);
2946 if (!(data32 & URTW_8225_ADDR_6_DATA_MAGIC2)) {
2948 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC1);
2949 usb_pause_mtx(&sc->sc_mtx, 100);
2951 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC2);
2952 usb_pause_mtx(&sc->sc_mtx, 50);
2953 error = urtw_8225_read(sc, URTW_8225_ADDR_6_MAGIC, &data32);
2956 if (!(data32 & URTW_8225_ADDR_6_DATA_MAGIC2))
2957 device_printf(sc->sc_dev, "RF calibration failed\n");
2959 usb_pause_mtx(&sc->sc_mtx, 100);
2962 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC6);
2963 for (i = 0; i < 128; i++) {
2964 urtw_8187_write_phy_ofdm(sc, 0xb, urtw_8225_agc[i]);
2965 urtw_8187_write_phy_ofdm(sc, 0xa, (uint8_t)i + 0x80);
2968 for (i = 0; i < N(urtw_8225v2_rf_part2); i++) {
2969 urtw_8187_write_phy_ofdm(sc, urtw_8225v2_rf_part2[i].reg,
2970 urtw_8225v2_rf_part2[i].val);
2973 error = urtw_8225v2_setgain(sc, 4);
2977 for (i = 0; i < N(urtw_8225v2_rf_part3); i++) {
2978 urtw_8187_write_phy_cck(sc, urtw_8225v2_rf_part3[i].reg,
2979 urtw_8225v2_rf_part3[i].val);
2982 urtw_write8_m(sc, URTW_TESTR, 0x0d);
2984 error = urtw_8225v2_set_txpwrlvl(sc, 1);
2988 urtw_8187_write_phy_cck(sc, 0x10, 0x9b);
2989 urtw_8187_write_phy_ofdm(sc, 0x26, 0x90);
2991 /* TX ant A, 0x0 for B */
2992 error = urtw_8185_tx_antenna(sc, 0x3);
2995 urtw_write32_m(sc, URTW_HSSI_PARA, 0x3dc00002);
2997 error = urtw_8225_rf_set_chan(sc, 1);
3004 urtw_8225v2_rf_set_chan(struct urtw_softc *sc, int chan)
3008 error = urtw_8225v2_set_txpwrlvl(sc, chan);
3012 urtw_8225_write(sc, URTW_8225_ADDR_7_MAGIC, urtw_8225_channel[chan]);
3013 usb_pause_mtx(&sc->sc_mtx, 10);
3019 urtw_8225_read(struct urtw_softc *sc, uint8_t addr, uint32_t *data)
3023 uint8_t rlen = 12, wlen = 6;
3024 uint16_t o1, o2, o3, tmp;
3025 uint32_t d2w = ((uint32_t)(addr & 0x1f)) << 27;
3026 uint32_t mask = 0x80000000, value = 0;
3029 urtw_read16_m(sc, URTW_RF_PINS_OUTPUT, &o1);
3030 urtw_read16_m(sc, URTW_RF_PINS_ENABLE, &o2);
3031 urtw_read16_m(sc, URTW_RF_PINS_SELECT, &o3);
3032 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, o2 | URTW_RF_PINS_MAGIC4);
3033 urtw_write16_m(sc, URTW_RF_PINS_SELECT, o3 | URTW_RF_PINS_MAGIC4);
3034 o1 &= ~URTW_RF_PINS_MAGIC4;
3035 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1 | URTW_BB_HOST_BANG_EN);
3037 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1);
3040 for (i = 0; i < (wlen / 2); i++, mask = mask >> 1) {
3041 bit = ((d2w & mask) != 0) ? 1 : 0;
3043 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1);
3045 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
3046 URTW_BB_HOST_BANG_CLK);
3048 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
3049 URTW_BB_HOST_BANG_CLK);
3054 bit = ((d2w & mask) != 0) ? 1 : 0;
3055 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
3056 URTW_BB_HOST_BANG_CLK);
3058 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
3059 URTW_BB_HOST_BANG_CLK);
3061 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1);
3064 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 | URTW_BB_HOST_BANG_RW |
3065 URTW_BB_HOST_BANG_CLK);
3067 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 | URTW_BB_HOST_BANG_RW);
3069 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1 | URTW_BB_HOST_BANG_RW);
3073 for (i = 0; i < rlen; i++, mask = mask >> 1) {
3074 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
3075 o1 | URTW_BB_HOST_BANG_RW);
3077 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
3078 o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK);
3080 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
3081 o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK);
3083 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
3084 o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK);
3087 urtw_read16_m(sc, URTW_RF_PINS_INPUT, &tmp);
3088 value |= ((tmp & URTW_BB_HOST_BANG_CLK) ? mask : 0);
3089 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
3090 o1 | URTW_BB_HOST_BANG_RW);
3094 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1 | URTW_BB_HOST_BANG_EN |
3095 URTW_BB_HOST_BANG_RW);
3098 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, o2);
3099 urtw_write16_m(sc, URTW_RF_PINS_SELECT, o3);
3100 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, URTW_RF_PINS_OUTPUT_MAGIC1);
3110 urtw_8225v2_set_txpwrlvl(struct urtw_softc *sc, int chan)
3113 uint8_t *cck_pwrtable;
3114 uint8_t cck_pwrlvl_max = 15, ofdm_pwrlvl_max = 25, ofdm_pwrlvl_min = 10;
3115 uint8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
3116 uint8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
3119 /* CCK power setting */
3120 cck_pwrlvl = (cck_pwrlvl > cck_pwrlvl_max) ? cck_pwrlvl_max : cck_pwrlvl;
3121 cck_pwrlvl += sc->sc_txpwr_cck_base;
3122 cck_pwrlvl = (cck_pwrlvl > 35) ? 35 : cck_pwrlvl;
3123 cck_pwrtable = (chan == 14) ? urtw_8225v2_txpwr_cck_ch14 :
3124 urtw_8225v2_txpwr_cck;
3126 for (i = 0; i < 8; i++)
3127 urtw_8187_write_phy_cck(sc, 0x44 + i, cck_pwrtable[i]);
3129 urtw_write8_m(sc, URTW_TX_GAIN_CCK,
3130 urtw_8225v2_tx_gain_cck_ofdm[cck_pwrlvl]);
3131 usb_pause_mtx(&sc->sc_mtx, 1);
3133 /* OFDM power setting */
3134 ofdm_pwrlvl = (ofdm_pwrlvl > (ofdm_pwrlvl_max - ofdm_pwrlvl_min)) ?
3135 ofdm_pwrlvl_max : ofdm_pwrlvl + ofdm_pwrlvl_min;
3136 ofdm_pwrlvl += sc->sc_txpwr_ofdm_base;
3137 ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
3139 error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
3143 urtw_8187_write_phy_ofdm(sc, 2, 0x42);
3144 urtw_8187_write_phy_ofdm(sc, 5, 0x0);
3145 urtw_8187_write_phy_ofdm(sc, 6, 0x40);
3146 urtw_8187_write_phy_ofdm(sc, 7, 0x0);
3147 urtw_8187_write_phy_ofdm(sc, 8, 0x40);
3149 urtw_write8_m(sc, URTW_TX_GAIN_OFDM,
3150 urtw_8225v2_tx_gain_cck_ofdm[ofdm_pwrlvl]);
3151 usb_pause_mtx(&sc->sc_mtx, 1);
3157 urtw_8225v2_setgain(struct urtw_softc *sc, int16_t gain)
3163 gainp = urtw_8225v2_gain_bg;
3164 urtw_8187_write_phy_ofdm(sc, 0x0d, gainp[gain * 3]);
3165 usb_pause_mtx(&sc->sc_mtx, 1);
3166 urtw_8187_write_phy_ofdm(sc, 0x1b, gainp[gain * 3 + 1]);
3167 usb_pause_mtx(&sc->sc_mtx, 1);
3168 urtw_8187_write_phy_ofdm(sc, 0x1d, gainp[gain * 3 + 2]);
3169 usb_pause_mtx(&sc->sc_mtx, 1);
3170 urtw_8187_write_phy_ofdm(sc, 0x21, 0x17);
3171 usb_pause_mtx(&sc->sc_mtx, 1);
3177 urtw_8225_isv2(struct urtw_softc *sc, int *ret)
3184 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, URTW_RF_PINS_MAGIC5);
3185 urtw_write16_m(sc, URTW_RF_PINS_SELECT, URTW_RF_PINS_MAGIC5);
3186 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, URTW_RF_PINS_MAGIC5);
3187 usb_pause_mtx(&sc->sc_mtx, 500);
3189 urtw_8225_write(sc, URTW_8225_ADDR_0_MAGIC,
3190 URTW_8225_ADDR_0_DATA_MAGIC1);
3192 error = urtw_8225_read(sc, URTW_8225_ADDR_8_MAGIC, &data);
3195 if (data != URTW_8225_ADDR_8_DATA_MAGIC1)
3198 error = urtw_8225_read(sc, URTW_8225_ADDR_9_MAGIC, &data);
3201 if (data != URTW_8225_ADDR_9_DATA_MAGIC1)
3205 urtw_8225_write(sc, URTW_8225_ADDR_0_MAGIC,
3206 URTW_8225_ADDR_0_DATA_MAGIC2);
3212 urtw_8225v2b_rf_init(struct urtw_softc *sc)
3214 #define N(a) (sizeof(a) / sizeof((a)[0]))
3219 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3224 * initialize extra registers on 8187
3226 urtw_write16_m(sc, URTW_BRSR_8187B, 0xfff);
3229 urtw_read8_m(sc, URTW_CW_CONF, &data8);
3230 data8 |= URTW_CW_CONF_PERPACKET_RETRY;
3231 urtw_write8_m(sc, URTW_CW_CONF, data8);
3234 urtw_read8_m(sc, URTW_TX_AGC_CTL, &data8);
3235 data8 |= URTW_TX_AGC_CTL_PERPACKET_GAIN;
3236 urtw_write8_m(sc, URTW_TX_AGC_CTL, data8);
3238 /* Auto Rate Fallback Control */
3239 #define URTW_ARFR 0x1e0
3240 urtw_write16_m(sc, URTW_ARFR, 0xfff);
3241 urtw_read8_m(sc, URTW_RATE_FALLBACK, &data8);
3242 urtw_write8_m(sc, URTW_RATE_FALLBACK,
3243 data8 | URTW_RATE_FALLBACK_ENABLE);
3245 urtw_read8_m(sc, URTW_MSR, &data8);
3246 urtw_write8_m(sc, URTW_MSR, data8 & 0xf3);
3247 urtw_read8_m(sc, URTW_MSR, &data8);
3248 urtw_write8_m(sc, URTW_MSR, data8 | URTW_MSR_LINK_ENEDCA);
3249 urtw_write8_m(sc, URTW_ACM_CONTROL, sc->sc_acmctl);
3251 urtw_write16_m(sc, URTW_ATIM_WND, 2);
3252 urtw_write16_m(sc, URTW_BEACON_INTERVAL, 100);
3253 #define URTW_FEMR_FOR_8187B 0x1d4
3254 urtw_write16_m(sc, URTW_FEMR_FOR_8187B, 0xffff);
3257 urtw_read8_m(sc, URTW_CONFIG1, &data8);
3258 data8 = (data8 & 0x3f) | 0x80;
3259 urtw_write8_m(sc, URTW_CONFIG1, data8);
3261 /* applying MAC address again. */
3262 urtw_write32_m(sc, URTW_MAC0, ((uint32_t *)sc->sc_bssid)[0]);
3263 urtw_write16_m(sc, URTW_MAC4, ((uint32_t *)sc->sc_bssid)[1] & 0xffff);
3265 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3269 urtw_write8_m(sc, URTW_WPA_CONFIG, 0);
3274 for (i = 0; i < N(urtw_8225v2b_rf_part1); i++)
3275 urtw_write8_m(sc, urtw_8225v2b_rf_part1[i].reg,
3276 urtw_8225v2b_rf_part1[i].val);
3277 urtw_write16_m(sc, URTW_TID_AC_MAP, 0xfa50);
3278 urtw_write16_m(sc, URTW_INT_MIG, 0x0000);
3279 urtw_write32_m(sc, 0x1f0, 0);
3280 urtw_write32_m(sc, 0x1f4, 0);
3281 urtw_write8_m(sc, 0x1f8, 0);
3282 urtw_write32_m(sc, URTW_RF_TIMING, 0x4001);
3284 #define URTW_RFSW_CTRL 0x272
3285 urtw_write16_m(sc, URTW_RFSW_CTRL, 0x569a);
3290 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3293 urtw_read8_m(sc, URTW_CONFIG3, &data8);
3294 urtw_write8_m(sc, URTW_CONFIG3,
3295 data8 | URTW_CONFIG3_ANAPARAM_WRITE);
3297 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3301 /* setup RFE initial timing */
3302 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, 0x0480);
3303 urtw_write16_m(sc, URTW_RF_PINS_SELECT, 0x2488);
3304 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x1fff);
3305 usb_pause_mtx(&sc->sc_mtx, 1100);
3307 for (i = 0; i < N(urtw_8225v2b_rf_part0); i++) {
3308 urtw_8225_write(sc, urtw_8225v2b_rf_part0[i].reg,
3309 urtw_8225v2b_rf_part0[i].val);
3310 usb_pause_mtx(&sc->sc_mtx, 1);
3312 urtw_8225_write(sc, 0x00, 0x01b7);
3314 for (i = 0; i < 95; i++) {
3315 urtw_8225_write(sc, URTW_8225_ADDR_1_MAGIC, (uint8_t)(i + 1));
3316 usb_pause_mtx(&sc->sc_mtx, 1);
3317 urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC,
3318 urtw_8225v2b_rxgain[i]);
3319 usb_pause_mtx(&sc->sc_mtx, 1);
3322 urtw_8225_write(sc, URTW_8225_ADDR_3_MAGIC, 0x080);
3323 usb_pause_mtx(&sc->sc_mtx, 1);
3324 urtw_8225_write(sc, URTW_8225_ADDR_5_MAGIC, 0x004);
3325 usb_pause_mtx(&sc->sc_mtx, 1);
3326 urtw_8225_write(sc, URTW_8225_ADDR_0_MAGIC, 0x0b7);
3327 usb_pause_mtx(&sc->sc_mtx, 1);
3328 usb_pause_mtx(&sc->sc_mtx, 3000);
3329 urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC, 0xc4d);
3330 usb_pause_mtx(&sc->sc_mtx, 2000);
3331 urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC, 0x44d);
3332 usb_pause_mtx(&sc->sc_mtx, 1);
3333 urtw_8225_write(sc, URTW_8225_ADDR_0_MAGIC, 0x2bf);
3334 usb_pause_mtx(&sc->sc_mtx, 1);
3336 urtw_write8_m(sc, URTW_TX_GAIN_CCK, 0x03);
3337 urtw_write8_m(sc, URTW_TX_GAIN_OFDM, 0x07);
3338 urtw_write8_m(sc, URTW_TX_ANTENNA, 0x03);
3340 urtw_8187_write_phy_ofdm(sc, 0x80, 0x12);
3341 for (i = 0; i < 128; i++) {
3342 uint32_t addr, data;
3344 data = (urtw_8225z2_agc[i] << 8) | 0x0000008f;
3345 addr = ((i + 0x80) << 8) | 0x0000008e;
3347 urtw_8187_write_phy_ofdm(sc, data & 0x7f, (data >> 8) & 0xff);
3348 urtw_8187_write_phy_ofdm(sc, addr & 0x7f, (addr >> 8) & 0xff);
3349 urtw_8187_write_phy_ofdm(sc, 0x0e, 0x00);
3351 urtw_8187_write_phy_ofdm(sc, 0x80, 0x10);
3353 for (i = 0; i < N(urtw_8225v2b_rf_part2); i++)
3354 urtw_8187_write_phy_ofdm(sc, i, urtw_8225v2b_rf_part2[i].val);
3356 urtw_write32_m(sc, URTW_8187B_AC_VO, (7 << 12) | (3 << 8) | 0x1c);
3357 urtw_write32_m(sc, URTW_8187B_AC_VI, (7 << 12) | (3 << 8) | 0x1c);
3358 urtw_write32_m(sc, URTW_8187B_AC_BE, (7 << 12) | (3 << 8) | 0x1c);
3359 urtw_write32_m(sc, URTW_8187B_AC_BK, (7 << 12) | (3 << 8) | 0x1c);
3361 urtw_8187_write_phy_ofdm(sc, 0x97, 0x46);
3362 urtw_8187_write_phy_ofdm(sc, 0xa4, 0xb6);
3363 urtw_8187_write_phy_ofdm(sc, 0x85, 0xfc);
3364 urtw_8187_write_phy_cck(sc, 0xc1, 0x88);
3372 urtw_8225v2b_rf_set_chan(struct urtw_softc *sc, int chan)
3376 error = urtw_8225v2b_set_txpwrlvl(sc, chan);
3380 urtw_8225_write(sc, URTW_8225_ADDR_7_MAGIC, urtw_8225_channel[chan]);
3381 usb_pause_mtx(&sc->sc_mtx, 10);
3387 urtw_8225v2b_set_txpwrlvl(struct urtw_softc *sc, int chan)
3390 uint8_t *cck_pwrtable;
3391 uint8_t cck_pwrlvl_max = 15;
3392 uint8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
3393 uint8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
3396 /* CCK power setting */
3397 cck_pwrlvl = (cck_pwrlvl > cck_pwrlvl_max) ?
3398 ((sc->sc_flags & URTW_RTL8187B_REV_B) ? cck_pwrlvl_max : 22) :
3399 (cck_pwrlvl + ((sc->sc_flags & URTW_RTL8187B_REV_B) ? 0 : 7));
3400 cck_pwrlvl += sc->sc_txpwr_cck_base;
3401 cck_pwrlvl = (cck_pwrlvl > 35) ? 35 : cck_pwrlvl;
3402 cck_pwrtable = (chan == 14) ? urtw_8225v2b_txpwr_cck_ch14 :
3403 urtw_8225v2b_txpwr_cck;
3405 if (sc->sc_flags & URTW_RTL8187B_REV_B)
3406 cck_pwrtable += (cck_pwrlvl <= 6) ? 0 :
3407 ((cck_pwrlvl <= 11) ? 8 : 16);
3409 cck_pwrtable += (cck_pwrlvl <= 5) ? 0 :
3410 ((cck_pwrlvl <= 11) ? 8 : ((cck_pwrlvl <= 17) ? 16 : 24));
3412 for (i = 0; i < 8; i++)
3413 urtw_8187_write_phy_cck(sc, 0x44 + i, cck_pwrtable[i]);
3415 urtw_write8_m(sc, URTW_TX_GAIN_CCK,
3416 urtw_8225v2_tx_gain_cck_ofdm[cck_pwrlvl] << 1);
3417 usb_pause_mtx(&sc->sc_mtx, 1);
3419 /* OFDM power setting */
3420 ofdm_pwrlvl = (ofdm_pwrlvl > 15) ?
3421 ((sc->sc_flags & URTW_RTL8187B_REV_B) ? 17 : 25) :
3422 (ofdm_pwrlvl + ((sc->sc_flags & URTW_RTL8187B_REV_B) ? 2 : 10));
3423 ofdm_pwrlvl += sc->sc_txpwr_ofdm_base;
3424 ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
3426 urtw_write8_m(sc, URTW_TX_GAIN_OFDM,
3427 urtw_8225v2_tx_gain_cck_ofdm[ofdm_pwrlvl] << 1);
3429 if (sc->sc_flags & URTW_RTL8187B_REV_B) {
3430 if (ofdm_pwrlvl <= 11) {
3431 urtw_8187_write_phy_ofdm(sc, 0x87, 0x60);
3432 urtw_8187_write_phy_ofdm(sc, 0x89, 0x60);
3434 urtw_8187_write_phy_ofdm(sc, 0x87, 0x5c);
3435 urtw_8187_write_phy_ofdm(sc, 0x89, 0x5c);
3438 if (ofdm_pwrlvl <= 11) {
3439 urtw_8187_write_phy_ofdm(sc, 0x87, 0x5c);
3440 urtw_8187_write_phy_ofdm(sc, 0x89, 0x5c);
3441 } else if (ofdm_pwrlvl <= 17) {
3442 urtw_8187_write_phy_ofdm(sc, 0x87, 0x54);
3443 urtw_8187_write_phy_ofdm(sc, 0x89, 0x54);
3445 urtw_8187_write_phy_ofdm(sc, 0x87, 0x50);
3446 urtw_8187_write_phy_ofdm(sc, 0x89, 0x50);
3449 usb_pause_mtx(&sc->sc_mtx, 1);
3455 urtw_read8e(struct urtw_softc *sc, int val, uint8_t *data)
3457 struct usb_device_request req;
3460 req.bmRequestType = UT_READ_VENDOR_DEVICE;
3461 req.bRequest = URTW_8187_GETREGS_REQ;
3462 USETW(req.wValue, val | 0xfe00);
3463 USETW(req.wIndex, 0);
3464 USETW(req.wLength, sizeof(uint8_t));
3466 error = urtw_do_request(sc, &req, data);
3471 urtw_write8e(struct urtw_softc *sc, int val, uint8_t data)
3473 struct usb_device_request req;
3475 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
3476 req.bRequest = URTW_8187_SETREGS_REQ;
3477 USETW(req.wValue, val | 0xfe00);
3478 USETW(req.wIndex, 0);
3479 USETW(req.wLength, sizeof(uint8_t));
3481 return (urtw_do_request(sc, &req, &data));
3485 urtw_8180_set_anaparam(struct urtw_softc *sc, uint32_t val)
3490 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3494 urtw_read8_m(sc, URTW_CONFIG3, &data);
3495 urtw_write8_m(sc, URTW_CONFIG3, data | URTW_CONFIG3_ANAPARAM_WRITE);
3496 urtw_write32_m(sc, URTW_ANAPARAM, val);
3497 urtw_read8_m(sc, URTW_CONFIG3, &data);
3498 urtw_write8_m(sc, URTW_CONFIG3, data & ~URTW_CONFIG3_ANAPARAM_WRITE);
3500 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3508 urtw_8185_set_anaparam2(struct urtw_softc *sc, uint32_t val)
3513 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3517 urtw_read8_m(sc, URTW_CONFIG3, &data);
3518 urtw_write8_m(sc, URTW_CONFIG3, data | URTW_CONFIG3_ANAPARAM_WRITE);
3519 urtw_write32_m(sc, URTW_ANAPARAM2, val);
3520 urtw_read8_m(sc, URTW_CONFIG3, &data);
3521 urtw_write8_m(sc, URTW_CONFIG3, data & ~URTW_CONFIG3_ANAPARAM_WRITE);
3523 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3531 urtw_intr_enable(struct urtw_softc *sc)
3535 urtw_write16_m(sc, URTW_INTR_MASK, 0xffff);
3541 urtw_intr_disable(struct urtw_softc *sc)
3545 urtw_write16_m(sc, URTW_INTR_MASK, 0);
3551 urtw_reset(struct urtw_softc *sc)
3556 error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
3559 error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
3563 error = urtw_intr_disable(sc);
3566 usb_pause_mtx(&sc->sc_mtx, 100);
3568 error = urtw_write8e(sc, 0x18, 0x10);
3571 error = urtw_write8e(sc, 0x18, 0x11);
3574 error = urtw_write8e(sc, 0x18, 0x00);
3577 usb_pause_mtx(&sc->sc_mtx, 100);
3579 urtw_read8_m(sc, URTW_CMD, &data);
3580 data = (data & 0x2) | URTW_CMD_RST;
3581 urtw_write8_m(sc, URTW_CMD, data);
3582 usb_pause_mtx(&sc->sc_mtx, 100);
3584 urtw_read8_m(sc, URTW_CMD, &data);
3585 if (data & URTW_CMD_RST) {
3586 device_printf(sc->sc_dev, "reset timeout\n");
3590 error = urtw_set_mode(sc, URTW_EPROM_CMD_LOAD);
3593 usb_pause_mtx(&sc->sc_mtx, 100);
3595 error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
3598 error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
3606 urtw_led_ctl(struct urtw_softc *sc, int mode)
3608 usb_error_t error = 0;
3610 switch (sc->sc_strategy) {
3611 case URTW_SW_LED_MODE0:
3612 error = urtw_led_mode0(sc, mode);
3614 case URTW_SW_LED_MODE1:
3615 error = urtw_led_mode1(sc, mode);
3617 case URTW_SW_LED_MODE2:
3618 error = urtw_led_mode2(sc, mode);
3620 case URTW_SW_LED_MODE3:
3621 error = urtw_led_mode3(sc, mode);
3624 panic("unsupported LED mode %d\n", sc->sc_strategy);
3632 urtw_led_mode0(struct urtw_softc *sc, int mode)
3636 case URTW_LED_CTL_POWER_ON:
3637 sc->sc_gpio_ledstate = URTW_LED_POWER_ON_BLINK;
3639 case URTW_LED_CTL_TX:
3640 if (sc->sc_gpio_ledinprogress == 1)
3643 sc->sc_gpio_ledstate = URTW_LED_BLINK_NORMAL;
3644 sc->sc_gpio_blinktime = 2;
3646 case URTW_LED_CTL_LINK:
3647 sc->sc_gpio_ledstate = URTW_LED_ON;
3650 panic("unsupported LED mode 0x%x", mode);
3654 switch (sc->sc_gpio_ledstate) {
3656 if (sc->sc_gpio_ledinprogress != 0)
3658 urtw_led_on(sc, URTW_LED_GPIO);
3660 case URTW_LED_BLINK_NORMAL:
3661 if (sc->sc_gpio_ledinprogress != 0)
3663 sc->sc_gpio_ledinprogress = 1;
3664 sc->sc_gpio_blinkstate = (sc->sc_gpio_ledon != 0) ?
3665 URTW_LED_OFF : URTW_LED_ON;
3666 usb_callout_reset(&sc->sc_led_ch, hz, urtw_led_ch, sc);
3668 case URTW_LED_POWER_ON_BLINK:
3669 urtw_led_on(sc, URTW_LED_GPIO);
3670 usb_pause_mtx(&sc->sc_mtx, 100);
3671 urtw_led_off(sc, URTW_LED_GPIO);
3674 panic("unknown LED status 0x%x", sc->sc_gpio_ledstate);
3681 urtw_led_mode1(struct urtw_softc *sc, int mode)
3684 return (USB_ERR_INVAL);
3688 urtw_led_mode2(struct urtw_softc *sc, int mode)
3691 return (USB_ERR_INVAL);
3695 urtw_led_mode3(struct urtw_softc *sc, int mode)
3698 return (USB_ERR_INVAL);
3702 urtw_led_on(struct urtw_softc *sc, int type)
3706 if (type == URTW_LED_GPIO) {
3707 switch (sc->sc_gpio_ledpin) {
3708 case URTW_LED_PIN_GPIO0:
3709 urtw_write8_m(sc, URTW_GPIO, 0x01);
3710 urtw_write8_m(sc, URTW_GP_ENABLE, 0x00);
3713 panic("unsupported LED PIN type 0x%x",
3714 sc->sc_gpio_ledpin);
3718 panic("unsupported LED type 0x%x", type);
3722 sc->sc_gpio_ledon = 1;
3728 urtw_led_off(struct urtw_softc *sc, int type)
3732 if (type == URTW_LED_GPIO) {
3733 switch (sc->sc_gpio_ledpin) {
3734 case URTW_LED_PIN_GPIO0:
3735 urtw_write8_m(sc, URTW_GPIO, URTW_GPIO_DATA_MAGIC1);
3737 URTW_GP_ENABLE, URTW_GP_ENABLE_DATA_MAGIC1);
3740 panic("unsupported LED PIN type 0x%x",
3741 sc->sc_gpio_ledpin);
3745 panic("unsupported LED type 0x%x", type);
3749 sc->sc_gpio_ledon = 0;
3756 urtw_led_ch(void *arg)
3758 struct urtw_softc *sc = arg;
3759 struct ifnet *ifp = sc->sc_ifp;
3760 struct ieee80211com *ic = ifp->if_l2com;
3762 ieee80211_runtask(ic, &sc->sc_led_task);
3766 urtw_ledtask(void *arg, int pending)
3768 struct urtw_softc *sc = arg;
3770 if (sc->sc_strategy != URTW_SW_LED_MODE0)
3771 panic("could not process a LED strategy 0x%x", sc->sc_strategy);
3779 urtw_led_blink(struct urtw_softc *sc)
3784 if (sc->sc_gpio_blinkstate == URTW_LED_ON)
3785 error = urtw_led_on(sc, URTW_LED_GPIO);
3787 error = urtw_led_off(sc, URTW_LED_GPIO);
3788 sc->sc_gpio_blinktime--;
3789 if (sc->sc_gpio_blinktime == 0)
3792 if (sc->sc_gpio_ledstate != URTW_LED_BLINK_NORMAL &&
3793 sc->sc_gpio_ledstate != URTW_LED_BLINK_SLOWLY &&
3794 sc->sc_gpio_ledstate != URTW_LED_BLINK_CM3)
3798 if (sc->sc_gpio_ledstate == URTW_LED_ON &&
3799 sc->sc_gpio_ledon == 0)
3800 error = urtw_led_on(sc, URTW_LED_GPIO);
3801 else if (sc->sc_gpio_ledstate == URTW_LED_OFF &&
3802 sc->sc_gpio_ledon == 1)
3803 error = urtw_led_off(sc, URTW_LED_GPIO);
3805 sc->sc_gpio_blinktime = 0;
3806 sc->sc_gpio_ledinprogress = 0;
3810 sc->sc_gpio_blinkstate = (sc->sc_gpio_blinkstate != URTW_LED_ON) ?
3811 URTW_LED_ON : URTW_LED_OFF;
3813 switch (sc->sc_gpio_ledstate) {
3814 case URTW_LED_BLINK_NORMAL:
3815 usb_callout_reset(&sc->sc_led_ch, hz, urtw_led_ch, sc);
3818 panic("unknown LED status 0x%x", sc->sc_gpio_ledstate);
3825 urtw_rx_enable(struct urtw_softc *sc)
3830 usbd_transfer_start((sc->sc_flags & URTW_RTL8187B) ?
3831 sc->sc_xfer[URTW_8187B_BULK_RX] : sc->sc_xfer[URTW_8187L_BULK_RX]);
3833 error = urtw_rx_setconf(sc);
3837 if ((sc->sc_flags & URTW_RTL8187B) == 0) {
3838 urtw_read8_m(sc, URTW_CMD, &data);
3839 urtw_write8_m(sc, URTW_CMD, data | URTW_CMD_RX_ENABLE);
3846 urtw_tx_enable(struct urtw_softc *sc)
3852 if (sc->sc_flags & URTW_RTL8187B) {
3853 urtw_read32_m(sc, URTW_TX_CONF, &data);
3854 data &= ~URTW_TX_LOOPBACK_MASK;
3855 data &= ~(URTW_TX_DPRETRY_MASK | URTW_TX_RTSRETRY_MASK);
3856 data &= ~(URTW_TX_NOCRC | URTW_TX_MXDMA_MASK);
3857 data &= ~URTW_TX_SWPLCPLEN;
3858 data |= URTW_TX_HW_SEQNUM | URTW_TX_DISREQQSIZE |
3859 (7 << 8) | /* short retry limit */
3860 (7 << 0) | /* long retry limit */
3861 (7 << 21); /* MAX TX DMA */
3862 urtw_write32_m(sc, URTW_TX_CONF, data);
3864 urtw_read8_m(sc, URTW_MSR, &data8);
3865 data8 |= URTW_MSR_LINK_ENEDCA;
3866 urtw_write8_m(sc, URTW_MSR, data8);
3870 urtw_read8_m(sc, URTW_CW_CONF, &data8);
3871 data8 &= ~(URTW_CW_CONF_PERPACKET_CW | URTW_CW_CONF_PERPACKET_RETRY);
3872 urtw_write8_m(sc, URTW_CW_CONF, data8);
3874 urtw_read8_m(sc, URTW_TX_AGC_CTL, &data8);
3875 data8 &= ~URTW_TX_AGC_CTL_PERPACKET_GAIN;
3876 data8 &= ~URTW_TX_AGC_CTL_PERPACKET_ANTSEL;
3877 data8 &= ~URTW_TX_AGC_CTL_FEEDBACK_ANT;
3878 urtw_write8_m(sc, URTW_TX_AGC_CTL, data8);
3880 urtw_read32_m(sc, URTW_TX_CONF, &data);
3881 data &= ~URTW_TX_LOOPBACK_MASK;
3882 data |= URTW_TX_LOOPBACK_NONE;
3883 data &= ~(URTW_TX_DPRETRY_MASK | URTW_TX_RTSRETRY_MASK);
3884 data |= sc->sc_tx_retry << URTW_TX_DPRETRY_SHIFT;
3885 data |= sc->sc_rts_retry << URTW_TX_RTSRETRY_SHIFT;
3886 data &= ~(URTW_TX_NOCRC | URTW_TX_MXDMA_MASK);
3887 data |= URTW_TX_MXDMA_2048 | URTW_TX_CWMIN | URTW_TX_DISCW;
3888 data &= ~URTW_TX_SWPLCPLEN;
3889 data |= URTW_TX_NOICV;
3890 urtw_write32_m(sc, URTW_TX_CONF, data);
3892 urtw_read8_m(sc, URTW_CMD, &data8);
3893 urtw_write8_m(sc, URTW_CMD, data8 | URTW_CMD_TX_ENABLE);
3899 urtw_rx_setconf(struct urtw_softc *sc)
3901 struct ifnet *ifp = sc->sc_ifp;
3902 struct ieee80211com *ic = ifp->if_l2com;
3906 urtw_read32_m(sc, URTW_RX, &data);
3907 data = data &~ URTW_RX_FILTER_MASK;
3908 if (sc->sc_flags & URTW_RTL8187B) {
3909 data = data | URTW_RX_FILTER_MNG | URTW_RX_FILTER_DATA |
3910 URTW_RX_FILTER_MCAST | URTW_RX_FILTER_BCAST |
3911 URTW_RX_FILTER_NICMAC | URTW_RX_CHECK_BSSID |
3912 URTW_RX_FIFO_THRESHOLD_NONE |
3913 URTW_MAX_RX_DMA_2048 |
3914 URTW_RX_AUTORESETPHY | URTW_RCR_ONLYERLPKT;
3916 data = data | URTW_RX_FILTER_MNG | URTW_RX_FILTER_DATA;
3917 data = data | URTW_RX_FILTER_BCAST | URTW_RX_FILTER_MCAST;
3919 if (ic->ic_opmode == IEEE80211_M_MONITOR) {
3920 data = data | URTW_RX_FILTER_ICVERR;
3921 data = data | URTW_RX_FILTER_PWR;
3923 if (sc->sc_crcmon == 1 && ic->ic_opmode == IEEE80211_M_MONITOR)
3924 data = data | URTW_RX_FILTER_CRCERR;
3926 if (ic->ic_opmode == IEEE80211_M_MONITOR ||
3927 (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC))) {
3928 data = data | URTW_RX_FILTER_ALLMAC;
3930 data = data | URTW_RX_FILTER_NICMAC;
3931 data = data | URTW_RX_CHECK_BSSID;
3934 data = data &~ URTW_RX_FIFO_THRESHOLD_MASK;
3935 data = data | URTW_RX_FIFO_THRESHOLD_NONE |
3936 URTW_RX_AUTORESETPHY;
3937 data = data &~ URTW_MAX_RX_DMA_MASK;
3938 data = data | URTW_MAX_RX_DMA_2048 | URTW_RCR_ONLYERLPKT;
3941 urtw_write32_m(sc, URTW_RX, data);
3946 static struct mbuf *
3947 urtw_rxeof(struct usb_xfer *xfer, struct urtw_data *data, int *rssi_p,
3950 int actlen, flen, rssi;
3951 struct ieee80211_frame *wh;
3952 struct mbuf *m, *mnew;
3953 struct urtw_softc *sc = data->sc;
3954 struct ifnet *ifp = sc->sc_ifp;
3955 struct ieee80211com *ic = ifp->if_l2com;
3956 uint8_t noise = 0, rate;
3958 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
3960 if (actlen < URTW_MIN_RXBUFSZ) {
3965 if (sc->sc_flags & URTW_RTL8187B) {
3966 struct urtw_8187b_rxhdr *rx;
3968 rx = (struct urtw_8187b_rxhdr *)(data->buf +
3969 (actlen - (sizeof(struct urtw_8187b_rxhdr))));
3970 flen = le32toh(rx->flag) & 0xfff;
3971 if (flen > actlen) {
3975 rate = (le32toh(rx->flag) >> URTW_RX_FLAG_RXRATE_SHIFT) & 0xf;
3977 rssi = rx->rssi & URTW_RX_RSSI_MASK;
3980 struct urtw_8187l_rxhdr *rx;
3982 rx = (struct urtw_8187l_rxhdr *)(data->buf +
3983 (actlen - (sizeof(struct urtw_8187l_rxhdr))));
3984 flen = le32toh(rx->flag) & 0xfff;
3985 if (flen > actlen) {
3990 rate = (le32toh(rx->flag) >> URTW_RX_FLAG_RXRATE_SHIFT) & 0xf;
3992 rssi = rx->rssi & URTW_RX_8187L_RSSI_MASK;
3996 mnew = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
4004 data->buf = mtod(mnew, uint8_t *);
4007 m->m_pkthdr.rcvif = ifp;
4008 m->m_pkthdr.len = m->m_len = flen - IEEE80211_CRC_LEN;
4010 if (ieee80211_radiotap_active(ic)) {
4011 struct urtw_rx_radiotap_header *tap = &sc->sc_rxtap;
4013 /* XXX Are variables correct? */
4014 tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
4015 tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
4016 tap->wr_dbm_antsignal = (int8_t)rssi;
4019 wh = mtod(m, struct ieee80211_frame *);
4020 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_DATA)
4021 sc->sc_currate = (rate > 0) ? rate : sc->sc_currate;
4024 *nf_p = noise; /* XXX correct? */
4030 urtw_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
4032 struct urtw_softc *sc = usbd_xfer_softc(xfer);
4033 struct ifnet *ifp = sc->sc_ifp;
4034 struct ieee80211com *ic = ifp->if_l2com;
4035 struct ieee80211_frame *wh;
4036 struct ieee80211_node *ni;
4037 struct mbuf *m = NULL;
4038 struct urtw_data *data;
4042 URTW_ASSERT_LOCKED(sc);
4044 switch (USB_GET_STATE(xfer)) {
4045 case USB_ST_TRANSFERRED:
4046 data = STAILQ_FIRST(&sc->sc_rx_active);
4049 STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next);
4050 m = urtw_rxeof(xfer, data, &rssi, &nf);
4051 STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next);
4055 data = STAILQ_FIRST(&sc->sc_rx_inactive);
4057 KASSERT(m == NULL, ("mbuf isn't NULL"));
4060 STAILQ_REMOVE_HEAD(&sc->sc_rx_inactive, next);
4061 STAILQ_INSERT_TAIL(&sc->sc_rx_active, data, next);
4062 usbd_xfer_set_frame_data(xfer, 0, data->buf,
4063 usbd_xfer_max_len(xfer));
4064 usbd_transfer_submit(xfer);
4067 * To avoid LOR we should unlock our private mutex here to call
4068 * ieee80211_input() because here is at the end of a USB
4069 * callback and safe to unlock.
4073 wh = mtod(m, struct ieee80211_frame *);
4074 ni = ieee80211_find_rxnode(ic,
4075 (struct ieee80211_frame_min *)wh);
4077 (void) ieee80211_input(ni, m, rssi, nf);
4078 /* node is no longer needed */
4079 ieee80211_free_node(ni);
4081 (void) ieee80211_input_all(ic, m, rssi, nf);
4087 /* needs it to the inactive queue due to a error. */
4088 data = STAILQ_FIRST(&sc->sc_rx_active);
4090 STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next);
4091 STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next);
4093 if (error != USB_ERR_CANCELLED) {
4094 usbd_xfer_set_stall(xfer);
4102 #define URTW_STATUS_TYPE_TXCLOSE 1
4103 #define URTW_STATUS_TYPE_BEACON_INTR 0
4106 urtw_txstatus_eof(struct usb_xfer *xfer)
4108 struct urtw_softc *sc = usbd_xfer_softc(xfer);
4109 struct ifnet *ifp = sc->sc_ifp;
4110 int actlen, type, pktretry, seq;
4113 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
4115 if (actlen != sizeof(uint64_t))
4118 val = le64toh(sc->sc_txstatus);
4119 type = (val >> 30) & 0x3;
4120 if (type == URTW_STATUS_TYPE_TXCLOSE) {
4121 pktretry = val & 0xff;
4122 seq = (val >> 16) & 0xff;
4123 if (pktretry == URTW_TX_MAXRETRY)
4125 DPRINTF(sc, URTW_DEBUG_TXSTATUS, "pktretry %d seq %#x\n",
4131 urtw_bulk_tx_status_callback(struct usb_xfer *xfer, usb_error_t error)
4133 struct urtw_softc *sc = usbd_xfer_softc(xfer);
4134 struct ifnet *ifp = sc->sc_ifp;
4136 URTW_ASSERT_LOCKED(sc);
4138 switch (USB_GET_STATE(xfer)) {
4139 case USB_ST_TRANSFERRED:
4140 urtw_txstatus_eof(xfer);
4144 usbd_xfer_set_frame_data(xfer, 0, &sc->sc_txstatus,
4146 usbd_transfer_submit(xfer);
4149 if (error != USB_ERR_CANCELLED) {
4150 usbd_xfer_set_stall(xfer);
4159 urtw_txeof(struct usb_xfer *xfer, struct urtw_data *data)
4161 struct urtw_softc *sc = usbd_xfer_softc(xfer);
4162 struct ifnet *ifp = sc->sc_ifp;
4165 URTW_ASSERT_LOCKED(sc);
4168 * Do any tx complete callback. Note this must be done before releasing
4169 * the node reference.
4173 if (m->m_flags & M_TXCB) {
4175 ieee80211_process_callback(data->ni, m, 0);
4181 ieee80211_free_node(data->ni);
4186 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
4190 urtw_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error)
4192 struct urtw_softc *sc = usbd_xfer_softc(xfer);
4193 struct ifnet *ifp = sc->sc_ifp;
4194 struct urtw_data *data;
4196 URTW_ASSERT_LOCKED(sc);
4198 switch (USB_GET_STATE(xfer)) {
4199 case USB_ST_TRANSFERRED:
4200 data = STAILQ_FIRST(&sc->sc_tx_active);
4203 STAILQ_REMOVE_HEAD(&sc->sc_tx_active, next);
4204 urtw_txeof(xfer, data);
4205 STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data, next);
4209 data = STAILQ_FIRST(&sc->sc_tx_pending);
4211 DPRINTF(sc, URTW_DEBUG_XMIT,
4212 "%s: empty pending queue\n", __func__);
4215 STAILQ_REMOVE_HEAD(&sc->sc_tx_pending, next);
4216 STAILQ_INSERT_TAIL(&sc->sc_tx_active, data, next);
4218 usbd_xfer_set_frame_data(xfer, 0, data->buf, data->buflen);
4219 usbd_transfer_submit(xfer);
4226 data = STAILQ_FIRST(&sc->sc_tx_active);
4229 if (data->ni != NULL) {
4230 ieee80211_free_node(data->ni);
4234 if (error != USB_ERR_CANCELLED) {
4235 usbd_xfer_set_stall(xfer);
4242 static struct urtw_data *
4243 _urtw_getbuf(struct urtw_softc *sc)
4245 struct urtw_data *bf;
4247 bf = STAILQ_FIRST(&sc->sc_tx_inactive);
4249 STAILQ_REMOVE_HEAD(&sc->sc_tx_inactive, next);
4253 DPRINTF(sc, URTW_DEBUG_XMIT, "%s: %s\n", __func__,
4254 "out of xmit buffers");
4258 static struct urtw_data *
4259 urtw_getbuf(struct urtw_softc *sc)
4261 struct urtw_data *bf;
4263 URTW_ASSERT_LOCKED(sc);
4265 bf = _urtw_getbuf(sc);
4267 struct ifnet *ifp = sc->sc_ifp;
4269 DPRINTF(sc, URTW_DEBUG_XMIT, "%s: stop queue\n", __func__);
4270 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
4276 urtw_isbmode(uint16_t rate)
4279 return ((rate <= 22 && rate != 12 && rate != 18) ||
4280 rate == 44) ? (1) : (0);
4284 urtw_rate2dbps(uint16_t rate)
4304 urtw_compute_txtime(uint16_t framelen, uint16_t rate,
4305 uint8_t ismgt, uint8_t isshort)
4307 uint16_t ceiling, frametime, n_dbps;
4309 if (urtw_isbmode(rate)) {
4310 if (ismgt || !isshort || rate == 2)
4311 frametime = (uint16_t)(144 + 48 +
4312 (framelen * 8 / (rate / 2)));
4314 frametime = (uint16_t)(72 + 24 +
4315 (framelen * 8 / (rate / 2)));
4316 if ((framelen * 8 % (rate / 2)) != 0)
4319 n_dbps = urtw_rate2dbps(rate);
4320 ceiling = (16 + 8 * framelen + 6) / n_dbps
4321 + (((16 + 8 * framelen + 6) % n_dbps) ? 1 : 0);
4322 frametime = (uint16_t)(16 + 4 + 4 * ceiling + 6);
4328 * Callback from the 802.11 layer to update the
4329 * slot time based on the current setting.
4332 urtw_updateslot(struct ifnet *ifp)
4334 struct urtw_softc *sc = ifp->if_softc;
4335 struct ieee80211com *ic = ifp->if_l2com;
4337 ieee80211_runtask(ic, &sc->sc_updateslot_task);
4341 urtw_updateslottask(void *arg, int pending)
4343 struct urtw_softc *sc = arg;
4344 struct ifnet *ifp = sc->sc_ifp;
4345 struct ieee80211com *ic = ifp->if_l2com;
4348 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
4352 if (sc->sc_flags & URTW_RTL8187B) {
4353 urtw_write8_m(sc, URTW_SIFS, 0x22);
4354 if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan))
4355 urtw_write8_m(sc, URTW_SLOT, 0x9);
4357 urtw_write8_m(sc, URTW_SLOT, 0x14);
4358 urtw_write8_m(sc, URTW_8187B_EIFS, 0x5b);
4359 urtw_write8_m(sc, URTW_CARRIER_SCOUNT, 0x5b);
4361 urtw_write8_m(sc, URTW_SIFS, 0x22);
4362 if (sc->sc_state == IEEE80211_S_ASSOC &&
4363 ic->ic_flags & IEEE80211_F_SHSLOT)
4364 urtw_write8_m(sc, URTW_SLOT, 0x9);
4366 urtw_write8_m(sc, URTW_SLOT, 0x14);
4367 if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan)) {
4368 urtw_write8_m(sc, URTW_DIFS, 0x14);
4369 urtw_write8_m(sc, URTW_EIFS, 0x5b - 0x14);
4370 urtw_write8_m(sc, URTW_CW_VAL, 0x73);
4372 urtw_write8_m(sc, URTW_DIFS, 0x24);
4373 urtw_write8_m(sc, URTW_EIFS, 0x5b - 0x24);
4374 urtw_write8_m(sc, URTW_CW_VAL, 0xa5);
4382 urtw_sysctl_node(struct urtw_softc *sc)
4384 #define URTW_SYSCTL_STAT_ADD32(c, h, n, p, d) \
4385 SYSCTL_ADD_UINT(c, h, OID_AUTO, n, CTLFLAG_RD, p, 0, d)
4386 struct sysctl_ctx_list *ctx;
4387 struct sysctl_oid_list *child, *parent;
4388 struct sysctl_oid *tree;
4389 struct urtw_stats *stats = &sc->sc_stats;
4391 ctx = device_get_sysctl_ctx(sc->sc_dev);
4392 child = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->sc_dev));
4394 tree = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "stats", CTLFLAG_RD,
4395 NULL, "URTW statistics");
4396 parent = SYSCTL_CHILDREN(tree);
4398 /* Tx statistics. */
4399 tree = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "tx", CTLFLAG_RD,
4400 NULL, "Tx MAC statistics");
4401 child = SYSCTL_CHILDREN(tree);
4402 URTW_SYSCTL_STAT_ADD32(ctx, child, "1m", &stats->txrates[0],
4404 URTW_SYSCTL_STAT_ADD32(ctx, child, "2m", &stats->txrates[1],
4406 URTW_SYSCTL_STAT_ADD32(ctx, child, "5.5m", &stats->txrates[2],
4408 URTW_SYSCTL_STAT_ADD32(ctx, child, "6m", &stats->txrates[4],
4410 URTW_SYSCTL_STAT_ADD32(ctx, child, "9m", &stats->txrates[5],
4412 URTW_SYSCTL_STAT_ADD32(ctx, child, "11m", &stats->txrates[3],
4414 URTW_SYSCTL_STAT_ADD32(ctx, child, "12m", &stats->txrates[6],
4416 URTW_SYSCTL_STAT_ADD32(ctx, child, "18m", &stats->txrates[7],
4418 URTW_SYSCTL_STAT_ADD32(ctx, child, "24m", &stats->txrates[8],
4420 URTW_SYSCTL_STAT_ADD32(ctx, child, "36m", &stats->txrates[9],
4422 URTW_SYSCTL_STAT_ADD32(ctx, child, "48m", &stats->txrates[10],
4424 URTW_SYSCTL_STAT_ADD32(ctx, child, "54m", &stats->txrates[11],
4426 #undef URTW_SYSCTL_STAT_ADD32
4429 static device_method_t urtw_methods[] = {
4430 DEVMETHOD(device_probe, urtw_match),
4431 DEVMETHOD(device_attach, urtw_attach),
4432 DEVMETHOD(device_detach, urtw_detach),
4435 static driver_t urtw_driver = {
4438 sizeof(struct urtw_softc)
4440 static devclass_t urtw_devclass;
4442 DRIVER_MODULE(urtw, uhub, urtw_driver, urtw_devclass, NULL, 0);
4443 MODULE_DEPEND(urtw, wlan, 1, 1, 1);
4444 MODULE_DEPEND(urtw, usb, 1, 1, 1);