2 * Copyright (c) 2008 Weongyo Jeong <weongyo@FreeBSD.org>
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 #include <sys/cdefs.h>
18 __FBSDID("$FreeBSD$");
22 #include <sys/param.h>
23 #include <sys/sockio.h>
24 #include <sys/sysctl.h>
26 #include <sys/mutex.h>
28 #include <sys/kernel.h>
29 #include <sys/socket.h>
30 #include <sys/systm.h>
31 #include <sys/malloc.h>
32 #include <sys/module.h>
34 #include <sys/endian.h>
37 #include <machine/bus.h>
38 #include <machine/resource.h>
42 #include <net/if_var.h>
43 #include <net/if_arp.h>
44 #include <net/ethernet.h>
45 #include <net/if_dl.h>
46 #include <net/if_media.h>
47 #include <net/if_types.h>
50 #include <netinet/in.h>
51 #include <netinet/in_systm.h>
52 #include <netinet/in_var.h>
53 #include <netinet/if_ether.h>
54 #include <netinet/ip.h>
57 #include <net80211/ieee80211_var.h>
58 #include <net80211/ieee80211_regdomain.h>
59 #include <net80211/ieee80211_radiotap.h>
61 #include <dev/usb/usb.h>
62 #include <dev/usb/usbdi.h>
65 #include <dev/usb/wlan/if_urtwreg.h>
66 #include <dev/usb/wlan/if_urtwvar.h>
68 /* copy some rate indices from if_rtwn_ridx.h */
69 #define URTW_RIDX_CCK5 2
70 #define URTW_RIDX_CCK11 3
71 #define URTW_RIDX_OFDM6 4
72 #define URTW_RIDX_OFDM24 8
74 static SYSCTL_NODE(_hw_usb, OID_AUTO, urtw, CTLFLAG_RW, 0, "USB Realtek 8187L");
77 SYSCTL_INT(_hw_usb_urtw, OID_AUTO, debug, CTLFLAG_RWTUN, &urtw_debug, 0,
78 "control debugging printfs");
80 URTW_DEBUG_XMIT = 0x00000001, /* basic xmit operation */
81 URTW_DEBUG_RECV = 0x00000002, /* basic recv operation */
82 URTW_DEBUG_RESET = 0x00000004, /* reset processing */
83 URTW_DEBUG_TX_PROC = 0x00000008, /* tx ISR proc */
84 URTW_DEBUG_RX_PROC = 0x00000010, /* rx ISR proc */
85 URTW_DEBUG_STATE = 0x00000020, /* 802.11 state transitions */
86 URTW_DEBUG_STAT = 0x00000040, /* statistic */
87 URTW_DEBUG_INIT = 0x00000080, /* initialization of dev */
88 URTW_DEBUG_TXSTATUS = 0x00000100, /* tx status */
89 URTW_DEBUG_ANY = 0xffffffff
91 #define DPRINTF(sc, m, fmt, ...) do { \
92 if (sc->sc_debug & (m)) \
93 printf(fmt, __VA_ARGS__); \
96 #define DPRINTF(sc, m, fmt, ...) do { \
100 static int urtw_preamble_mode = URTW_PREAMBLE_MODE_LONG;
101 SYSCTL_INT(_hw_usb_urtw, OID_AUTO, preamble_mode, CTLFLAG_RWTUN,
102 &urtw_preamble_mode, 0, "set the preable mode (long or short)");
104 /* recognized device vendors/products */
105 #define urtw_lookup(v, p) \
106 ((const struct urtw_type *)usb_lookup(urtw_devs, v, p))
107 #define URTW_DEV_B(v,p) \
108 { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, URTW_REV_RTL8187B) }
109 #define URTW_DEV_L(v,p) \
110 { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, URTW_REV_RTL8187L) }
111 #define URTW_REV_RTL8187B 0
112 #define URTW_REV_RTL8187L 1
113 static const STRUCT_USB_HOST_ID urtw_devs[] = {
114 URTW_DEV_B(NETGEAR, WG111V3),
115 URTW_DEV_B(REALTEK, RTL8187B_0),
116 URTW_DEV_B(REALTEK, RTL8187B_1),
117 URTW_DEV_B(REALTEK, RTL8187B_2),
118 URTW_DEV_B(SITECOMEU, WL168V4),
119 URTW_DEV_L(ASUS, P5B_WIFI),
120 URTW_DEV_L(BELKIN, F5D7050E),
121 URTW_DEV_L(LINKSYS4, WUSB54GCV2),
122 URTW_DEV_L(NETGEAR, WG111V2),
123 URTW_DEV_L(REALTEK, RTL8187),
124 URTW_DEV_L(SITECOMEU, WL168V1),
125 URTW_DEV_L(SURECOM, EP9001G2A),
126 { USB_VPI(USB_VENDOR_OVISLINK, 0x8187, URTW_REV_RTL8187L) },
127 { USB_VPI(USB_VENDOR_DICKSMITH, 0x9401, URTW_REV_RTL8187L) },
128 { USB_VPI(USB_VENDOR_HP, 0xca02, URTW_REV_RTL8187L) },
129 { USB_VPI(USB_VENDOR_LOGITEC, 0x010c, URTW_REV_RTL8187L) },
130 { USB_VPI(USB_VENDOR_NETGEAR, 0x6100, URTW_REV_RTL8187L) },
131 { USB_VPI(USB_VENDOR_SPHAIRON, 0x0150, URTW_REV_RTL8187L) },
132 { USB_VPI(USB_VENDOR_QCOM, 0x6232, URTW_REV_RTL8187L) },
137 #define urtw_read8_m(sc, val, data) do { \
138 error = urtw_read8_c(sc, val, data); \
142 #define urtw_write8_m(sc, val, data) do { \
143 error = urtw_write8_c(sc, val, data); \
147 #define urtw_read16_m(sc, val, data) do { \
148 error = urtw_read16_c(sc, val, data); \
152 #define urtw_write16_m(sc, val, data) do { \
153 error = urtw_write16_c(sc, val, data); \
157 #define urtw_read32_m(sc, val, data) do { \
158 error = urtw_read32_c(sc, val, data); \
162 #define urtw_write32_m(sc, val, data) do { \
163 error = urtw_write32_c(sc, val, data); \
167 #define urtw_8187_write_phy_ofdm(sc, val, data) do { \
168 error = urtw_8187_write_phy_ofdm_c(sc, val, data); \
172 #define urtw_8187_write_phy_cck(sc, val, data) do { \
173 error = urtw_8187_write_phy_cck_c(sc, val, data); \
177 #define urtw_8225_write(sc, val, data) do { \
178 error = urtw_8225_write_c(sc, val, data); \
188 static uint8_t urtw_8225_agc[] = {
189 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9d, 0x9c, 0x9b,
190 0x9a, 0x99, 0x98, 0x97, 0x96, 0x95, 0x94, 0x93, 0x92, 0x91, 0x90,
191 0x8f, 0x8e, 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86, 0x85,
192 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a,
193 0x39, 0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f,
194 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24,
195 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19,
196 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e,
197 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03,
198 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
199 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
200 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
203 static uint8_t urtw_8225z2_agc[] = {
204 0x5e, 0x5e, 0x5e, 0x5e, 0x5d, 0x5b, 0x59, 0x57, 0x55, 0x53, 0x51,
205 0x4f, 0x4d, 0x4b, 0x49, 0x47, 0x45, 0x43, 0x41, 0x3f, 0x3d, 0x3b,
206 0x39, 0x37, 0x35, 0x33, 0x31, 0x2f, 0x2d, 0x2b, 0x29, 0x27, 0x25,
207 0x23, 0x21, 0x1f, 0x1d, 0x1b, 0x19, 0x17, 0x15, 0x13, 0x11, 0x0f,
208 0x0d, 0x0b, 0x09, 0x07, 0x05, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01,
209 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x19, 0x19,
210 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x20, 0x21, 0x22, 0x23,
211 0x24, 0x25, 0x26, 0x26, 0x27, 0x27, 0x28, 0x28, 0x29, 0x2a, 0x2a,
212 0x2a, 0x2b, 0x2b, 0x2b, 0x2c, 0x2c, 0x2c, 0x2d, 0x2d, 0x2d, 0x2d,
213 0x2e, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x2f, 0x30, 0x30, 0x31, 0x31,
214 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
215 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31
218 static const uint8_t urtw_chan_2ghz[] =
219 { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };
221 static uint32_t urtw_8225_channel[] = {
222 0x0000, /* dummy channel 0 */
239 static uint8_t urtw_8225_gain[] = {
240 0x23, 0x88, 0x7c, 0xa5, /* -82dbm */
241 0x23, 0x88, 0x7c, 0xb5, /* -82dbm */
242 0x23, 0x88, 0x7c, 0xc5, /* -82dbm */
243 0x33, 0x80, 0x79, 0xc5, /* -78dbm */
244 0x43, 0x78, 0x76, 0xc5, /* -74dbm */
245 0x53, 0x60, 0x73, 0xc5, /* -70dbm */
246 0x63, 0x58, 0x70, 0xc5, /* -66dbm */
249 static struct urtw_pair urtw_8225_rf_part1[] = {
250 { 0x00, 0x0067 }, { 0x01, 0x0fe0 }, { 0x02, 0x044d }, { 0x03, 0x0441 },
251 { 0x04, 0x0486 }, { 0x05, 0x0bc0 }, { 0x06, 0x0ae6 }, { 0x07, 0x082a },
252 { 0x08, 0x001f }, { 0x09, 0x0334 }, { 0x0a, 0x0fd4 }, { 0x0b, 0x0391 },
253 { 0x0c, 0x0050 }, { 0x0d, 0x06db }, { 0x0e, 0x0029 }, { 0x0f, 0x0914 },
256 static struct urtw_pair urtw_8225_rf_part2[] = {
257 { 0x00, 0x01 }, { 0x01, 0x02 }, { 0x02, 0x42 }, { 0x03, 0x00 },
258 { 0x04, 0x00 }, { 0x05, 0x00 }, { 0x06, 0x40 }, { 0x07, 0x00 },
259 { 0x08, 0x40 }, { 0x09, 0xfe }, { 0x0a, 0x09 }, { 0x0b, 0x80 },
260 { 0x0c, 0x01 }, { 0x0e, 0xd3 }, { 0x0f, 0x38 }, { 0x10, 0x84 },
261 { 0x11, 0x06 }, { 0x12, 0x20 }, { 0x13, 0x20 }, { 0x14, 0x00 },
262 { 0x15, 0x40 }, { 0x16, 0x00 }, { 0x17, 0x40 }, { 0x18, 0xef },
263 { 0x19, 0x19 }, { 0x1a, 0x20 }, { 0x1b, 0x76 }, { 0x1c, 0x04 },
264 { 0x1e, 0x95 }, { 0x1f, 0x75 }, { 0x20, 0x1f }, { 0x21, 0x27 },
265 { 0x22, 0x16 }, { 0x24, 0x46 }, { 0x25, 0x20 }, { 0x26, 0x90 },
269 static struct urtw_pair urtw_8225_rf_part3[] = {
270 { 0x00, 0x98 }, { 0x03, 0x20 }, { 0x04, 0x7e }, { 0x05, 0x12 },
271 { 0x06, 0xfc }, { 0x07, 0x78 }, { 0x08, 0x2e }, { 0x10, 0x9b },
272 { 0x11, 0x88 }, { 0x12, 0x47 }, { 0x13, 0xd0 }, { 0x19, 0x00 },
273 { 0x1a, 0xa0 }, { 0x1b, 0x08 }, { 0x40, 0x86 }, { 0x41, 0x8d },
274 { 0x42, 0x15 }, { 0x43, 0x18 }, { 0x44, 0x1f }, { 0x45, 0x1e },
275 { 0x46, 0x1a }, { 0x47, 0x15 }, { 0x48, 0x10 }, { 0x49, 0x0a },
276 { 0x4a, 0x05 }, { 0x4b, 0x02 }, { 0x4c, 0x05 }
279 static uint16_t urtw_8225_rxgain[] = {
280 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
281 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
282 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
283 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
284 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
285 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
286 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
287 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
288 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
289 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
290 0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3,
291 0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb
294 static uint8_t urtw_8225_threshold[] = {
295 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd,
298 static uint8_t urtw_8225_tx_gain_cck_ofdm[] = {
299 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e
302 static uint8_t urtw_8225_txpwr_cck[] = {
303 0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02,
304 0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02,
305 0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02,
306 0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02,
307 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03,
308 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03
311 static uint8_t urtw_8225_txpwr_cck_ch14[] = {
312 0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00,
313 0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00,
314 0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00,
315 0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00,
316 0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00,
317 0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00
320 static uint8_t urtw_8225_txpwr_ofdm[]={
321 0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4
324 static uint8_t urtw_8225v2_gain_bg[]={
325 0x23, 0x15, 0xa5, /* -82-1dbm */
326 0x23, 0x15, 0xb5, /* -82-2dbm */
327 0x23, 0x15, 0xc5, /* -82-3dbm */
328 0x33, 0x15, 0xc5, /* -78dbm */
329 0x43, 0x15, 0xc5, /* -74dbm */
330 0x53, 0x15, 0xc5, /* -70dbm */
331 0x63, 0x15, 0xc5, /* -66dbm */
334 static struct urtw_pair urtw_8225v2_rf_part1[] = {
335 { 0x00, 0x02bf }, { 0x01, 0x0ee0 }, { 0x02, 0x044d }, { 0x03, 0x0441 },
336 { 0x04, 0x08c3 }, { 0x05, 0x0c72 }, { 0x06, 0x00e6 }, { 0x07, 0x082a },
337 { 0x08, 0x003f }, { 0x09, 0x0335 }, { 0x0a, 0x09d4 }, { 0x0b, 0x07bb },
338 { 0x0c, 0x0850 }, { 0x0d, 0x0cdf }, { 0x0e, 0x002b }, { 0x0f, 0x0114 }
341 static struct urtw_pair urtw_8225v2b_rf_part0[] = {
342 { 0x00, 0x00b7 }, { 0x01, 0x0ee0 }, { 0x02, 0x044d }, { 0x03, 0x0441 },
343 { 0x04, 0x08c3 }, { 0x05, 0x0c72 }, { 0x06, 0x00e6 }, { 0x07, 0x082a },
344 { 0x08, 0x003f }, { 0x09, 0x0335 }, { 0x0a, 0x09d4 }, { 0x0b, 0x07bb },
345 { 0x0c, 0x0850 }, { 0x0d, 0x0cdf }, { 0x0e, 0x002b }, { 0x0f, 0x0114 }
348 static struct urtw_pair urtw_8225v2b_rf_part1[] = {
349 {0x0f0, 0x32}, {0x0f1, 0x32}, {0x0f2, 0x00},
350 {0x0f3, 0x00}, {0x0f4, 0x32}, {0x0f5, 0x43},
351 {0x0f6, 0x00}, {0x0f7, 0x00}, {0x0f8, 0x46},
352 {0x0f9, 0xa4}, {0x0fa, 0x00}, {0x0fb, 0x00},
353 {0x0fc, 0x96}, {0x0fd, 0xa4}, {0x0fe, 0x00},
354 {0x0ff, 0x00}, {0x158, 0x4b}, {0x159, 0x00},
355 {0x15a, 0x4b}, {0x15b, 0x00}, {0x160, 0x4b},
356 {0x161, 0x09}, {0x162, 0x4b}, {0x163, 0x09},
357 {0x1ce, 0x0f}, {0x1cf, 0x00}, {0x1e0, 0xff},
358 {0x1e1, 0x0f}, {0x1e2, 0x00}, {0x1f0, 0x4e},
359 {0x1f1, 0x01}, {0x1f2, 0x02}, {0x1f3, 0x03},
360 {0x1f4, 0x04}, {0x1f5, 0x05}, {0x1f6, 0x06},
361 {0x1f7, 0x07}, {0x1f8, 0x08}, {0x24e, 0x00},
362 {0x20c, 0x04}, {0x221, 0x61}, {0x222, 0x68},
363 {0x223, 0x6f}, {0x224, 0x76}, {0x225, 0x7d},
364 {0x226, 0x84}, {0x227, 0x8d}, {0x24d, 0x08},
365 {0x250, 0x05}, {0x251, 0xf5}, {0x252, 0x04},
366 {0x253, 0xa0}, {0x254, 0x1f}, {0x255, 0x23},
367 {0x256, 0x45}, {0x257, 0x67}, {0x258, 0x08},
368 {0x259, 0x08}, {0x25a, 0x08}, {0x25b, 0x08},
369 {0x260, 0x08}, {0x261, 0x08}, {0x262, 0x08},
370 {0x263, 0x08}, {0x264, 0xcf}, {0x272, 0x56},
371 {0x273, 0x9a}, {0x034, 0xf0}, {0x035, 0x0f},
372 {0x05b, 0x40}, {0x084, 0x88}, {0x085, 0x24},
373 {0x088, 0x54}, {0x08b, 0xb8}, {0x08c, 0x07},
374 {0x08d, 0x00}, {0x094, 0x1b}, {0x095, 0x12},
375 {0x096, 0x00}, {0x097, 0x06}, {0x09d, 0x1a},
376 {0x09f, 0x10}, {0x0b4, 0x22}, {0x0be, 0x80},
377 {0x0db, 0x00}, {0x0ee, 0x00}, {0x091, 0x03},
378 {0x24c, 0x00}, {0x39f, 0x00}, {0x08c, 0x01},
379 {0x08d, 0x10}, {0x08e, 0x08}, {0x08f, 0x00}
382 static struct urtw_pair urtw_8225v2_rf_part2[] = {
383 { 0x00, 0x01 }, { 0x01, 0x02 }, { 0x02, 0x42 }, { 0x03, 0x00 },
384 { 0x04, 0x00 }, { 0x05, 0x00 }, { 0x06, 0x40 }, { 0x07, 0x00 },
385 { 0x08, 0x40 }, { 0x09, 0xfe }, { 0x0a, 0x08 }, { 0x0b, 0x80 },
386 { 0x0c, 0x01 }, { 0x0d, 0x43 }, { 0x0e, 0xd3 }, { 0x0f, 0x38 },
387 { 0x10, 0x84 }, { 0x11, 0x07 }, { 0x12, 0x20 }, { 0x13, 0x20 },
388 { 0x14, 0x00 }, { 0x15, 0x40 }, { 0x16, 0x00 }, { 0x17, 0x40 },
389 { 0x18, 0xef }, { 0x19, 0x19 }, { 0x1a, 0x20 }, { 0x1b, 0x15 },
390 { 0x1c, 0x04 }, { 0x1d, 0xc5 }, { 0x1e, 0x95 }, { 0x1f, 0x75 },
391 { 0x20, 0x1f }, { 0x21, 0x17 }, { 0x22, 0x16 }, { 0x23, 0x80 },
392 { 0x24, 0x46 }, { 0x25, 0x00 }, { 0x26, 0x90 }, { 0x27, 0x88 }
395 static struct urtw_pair urtw_8225v2b_rf_part2[] = {
396 { 0x00, 0x10 }, { 0x01, 0x0d }, { 0x02, 0x01 }, { 0x03, 0x00 },
397 { 0x04, 0x14 }, { 0x05, 0xfb }, { 0x06, 0xfb }, { 0x07, 0x60 },
398 { 0x08, 0x00 }, { 0x09, 0x60 }, { 0x0a, 0x00 }, { 0x0b, 0x00 },
399 { 0x0c, 0x00 }, { 0x0d, 0x5c }, { 0x0e, 0x00 }, { 0x0f, 0x00 },
400 { 0x10, 0x40 }, { 0x11, 0x00 }, { 0x12, 0x40 }, { 0x13, 0x00 },
401 { 0x14, 0x00 }, { 0x15, 0x00 }, { 0x16, 0xa8 }, { 0x17, 0x26 },
402 { 0x18, 0x32 }, { 0x19, 0x33 }, { 0x1a, 0x07 }, { 0x1b, 0xa5 },
403 { 0x1c, 0x6f }, { 0x1d, 0x55 }, { 0x1e, 0xc8 }, { 0x1f, 0xb3 },
404 { 0x20, 0x0a }, { 0x21, 0xe1 }, { 0x22, 0x2C }, { 0x23, 0x8a },
405 { 0x24, 0x86 }, { 0x25, 0x83 }, { 0x26, 0x34 }, { 0x27, 0x0f },
406 { 0x28, 0x4f }, { 0x29, 0x24 }, { 0x2a, 0x6f }, { 0x2b, 0xc2 },
407 { 0x2c, 0x6b }, { 0x2d, 0x40 }, { 0x2e, 0x80 }, { 0x2f, 0x00 },
408 { 0x30, 0xc0 }, { 0x31, 0xc1 }, { 0x32, 0x58 }, { 0x33, 0xf1 },
409 { 0x34, 0x00 }, { 0x35, 0xe4 }, { 0x36, 0x90 }, { 0x37, 0x3e },
410 { 0x38, 0x6d }, { 0x39, 0x3c }, { 0x3a, 0xfb }, { 0x3b, 0x07 }
413 static struct urtw_pair urtw_8225v2_rf_part3[] = {
414 { 0x00, 0x98 }, { 0x03, 0x20 }, { 0x04, 0x7e }, { 0x05, 0x12 },
415 { 0x06, 0xfc }, { 0x07, 0x78 }, { 0x08, 0x2e }, { 0x09, 0x11 },
416 { 0x0a, 0x17 }, { 0x0b, 0x11 }, { 0x10, 0x9b }, { 0x11, 0x88 },
417 { 0x12, 0x47 }, { 0x13, 0xd0 }, { 0x19, 0x00 }, { 0x1a, 0xa0 },
418 { 0x1b, 0x08 }, { 0x1d, 0x00 }, { 0x40, 0x86 }, { 0x41, 0x9d },
419 { 0x42, 0x15 }, { 0x43, 0x18 }, { 0x44, 0x36 }, { 0x45, 0x35 },
420 { 0x46, 0x2e }, { 0x47, 0x25 }, { 0x48, 0x1c }, { 0x49, 0x12 },
421 { 0x4a, 0x09 }, { 0x4b, 0x04 }, { 0x4c, 0x05 }
424 static uint16_t urtw_8225v2_rxgain[] = {
425 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0008, 0x0009,
426 0x000a, 0x000b, 0x0102, 0x0103, 0x0104, 0x0105, 0x0140, 0x0141,
427 0x0142, 0x0143, 0x0144, 0x0145, 0x0180, 0x0181, 0x0182, 0x0183,
428 0x0184, 0x0185, 0x0188, 0x0189, 0x018a, 0x018b, 0x0243, 0x0244,
429 0x0245, 0x0280, 0x0281, 0x0282, 0x0283, 0x0284, 0x0285, 0x0288,
430 0x0289, 0x028a, 0x028b, 0x028c, 0x0342, 0x0343, 0x0344, 0x0345,
431 0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x0388, 0x0389,
432 0x038a, 0x038b, 0x038c, 0x038d, 0x0390, 0x0391, 0x0392, 0x0393,
433 0x0394, 0x0395, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d,
434 0x03a0, 0x03a1, 0x03a2, 0x03a3, 0x03a4, 0x03a5, 0x03a8, 0x03a9,
435 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
436 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
439 static uint16_t urtw_8225v2b_rxgain[] = {
440 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
441 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
442 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
443 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
444 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
445 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
446 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
447 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
448 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
449 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
450 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
451 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
454 static uint8_t urtw_8225v2_tx_gain_cck_ofdm[] = {
455 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
456 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
457 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
458 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
459 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
460 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
463 static uint8_t urtw_8225v2_txpwr_cck[] = {
464 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04
467 static uint8_t urtw_8225v2_txpwr_cck_ch14[] = {
468 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00
471 static uint8_t urtw_8225v2b_txpwr_cck[] = {
472 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04,
473 0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03,
474 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03,
475 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03
478 static uint8_t urtw_8225v2b_txpwr_cck_ch14[] = {
479 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00,
480 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
481 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
482 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00
485 static struct urtw_pair urtw_ratetable[] = {
486 { 2, 0 }, { 4, 1 }, { 11, 2 }, { 12, 4 }, { 18, 5 },
487 { 22, 3 }, { 24, 6 }, { 36, 7 }, { 48, 8 }, { 72, 9 },
488 { 96, 10 }, { 108, 11 }
492 static const uint8_t urtw_8187b_reg_table[][3] = {
493 { 0xf0, 0x32, 0 }, { 0xf1, 0x32, 0 }, { 0xf2, 0x00, 0 },
494 { 0xf3, 0x00, 0 }, { 0xf4, 0x32, 0 }, { 0xf5, 0x43, 0 },
495 { 0xf6, 0x00, 0 }, { 0xf7, 0x00, 0 }, { 0xf8, 0x46, 0 },
496 { 0xf9, 0xa4, 0 }, { 0xfa, 0x00, 0 }, { 0xfb, 0x00, 0 },
497 { 0xfc, 0x96, 0 }, { 0xfd, 0xa4, 0 }, { 0xfe, 0x00, 0 },
498 { 0xff, 0x00, 0 }, { 0x58, 0x4b, 1 }, { 0x59, 0x00, 1 },
499 { 0x5a, 0x4b, 1 }, { 0x5b, 0x00, 1 }, { 0x60, 0x4b, 1 },
500 { 0x61, 0x09, 1 }, { 0x62, 0x4b, 1 }, { 0x63, 0x09, 1 },
501 { 0xce, 0x0f, 1 }, { 0xcf, 0x00, 1 }, { 0xe0, 0xff, 1 },
502 { 0xe1, 0x0f, 1 }, { 0xe2, 0x00, 1 }, { 0xf0, 0x4e, 1 },
503 { 0xf1, 0x01, 1 }, { 0xf2, 0x02, 1 }, { 0xf3, 0x03, 1 },
504 { 0xf4, 0x04, 1 }, { 0xf5, 0x05, 1 }, { 0xf6, 0x06, 1 },
505 { 0xf7, 0x07, 1 }, { 0xf8, 0x08, 1 }, { 0x4e, 0x00, 2 },
506 { 0x0c, 0x04, 2 }, { 0x21, 0x61, 2 }, { 0x22, 0x68, 2 },
507 { 0x23, 0x6f, 2 }, { 0x24, 0x76, 2 }, { 0x25, 0x7d, 2 },
508 { 0x26, 0x84, 2 }, { 0x27, 0x8d, 2 }, { 0x4d, 0x08, 2 },
509 { 0x50, 0x05, 2 }, { 0x51, 0xf5, 2 }, { 0x52, 0x04, 2 },
510 { 0x53, 0xa0, 2 }, { 0x54, 0x1f, 2 }, { 0x55, 0x23, 2 },
511 { 0x56, 0x45, 2 }, { 0x57, 0x67, 2 }, { 0x58, 0x08, 2 },
512 { 0x59, 0x08, 2 }, { 0x5a, 0x08, 2 }, { 0x5b, 0x08, 2 },
513 { 0x60, 0x08, 2 }, { 0x61, 0x08, 2 }, { 0x62, 0x08, 2 },
514 { 0x63, 0x08, 2 }, { 0x64, 0xcf, 2 }, { 0x72, 0x56, 2 },
515 { 0x73, 0x9a, 2 }, { 0x34, 0xf0, 0 }, { 0x35, 0x0f, 0 },
516 { 0x5b, 0x40, 0 }, { 0x84, 0x88, 0 }, { 0x85, 0x24, 0 },
517 { 0x88, 0x54, 0 }, { 0x8b, 0xb8, 0 }, { 0x8c, 0x07, 0 },
518 { 0x8d, 0x00, 0 }, { 0x94, 0x1b, 0 }, { 0x95, 0x12, 0 },
519 { 0x96, 0x00, 0 }, { 0x97, 0x06, 0 }, { 0x9d, 0x1a, 0 },
520 { 0x9f, 0x10, 0 }, { 0xb4, 0x22, 0 }, { 0xbe, 0x80, 0 },
521 { 0xdb, 0x00, 0 }, { 0xee, 0x00, 0 }, { 0x91, 0x03, 0 },
522 { 0x4c, 0x00, 2 }, { 0x9f, 0x00, 3 }, { 0x8c, 0x01, 0 },
523 { 0x8d, 0x10, 0 }, { 0x8e, 0x08, 0 }, { 0x8f, 0x00, 0 }
527 static usb_callback_t urtw_bulk_rx_callback;
528 static usb_callback_t urtw_bulk_tx_callback;
529 static usb_callback_t urtw_bulk_tx_status_callback;
531 static const struct usb_config urtw_8187b_usbconfig[URTW_8187B_N_XFERS] = {
532 [URTW_8187B_BULK_RX] = {
535 .direction = UE_DIR_IN,
542 .callback = urtw_bulk_rx_callback
544 [URTW_8187B_BULK_TX_STATUS] = {
547 .direction = UE_DIR_IN,
548 .bufsize = sizeof(uint64_t),
553 .callback = urtw_bulk_tx_status_callback
555 [URTW_8187B_BULK_TX_BE] = {
557 .endpoint = URTW_8187B_TXPIPE_BE,
558 .direction = UE_DIR_OUT,
559 .bufsize = URTW_TX_MAXSIZE * URTW_TX_DATA_LIST_COUNT,
561 .force_short_xfer = 1,
564 .callback = urtw_bulk_tx_callback,
565 .timeout = URTW_DATA_TIMEOUT
567 [URTW_8187B_BULK_TX_BK] = {
569 .endpoint = URTW_8187B_TXPIPE_BK,
570 .direction = UE_DIR_OUT,
571 .bufsize = URTW_TX_MAXSIZE,
574 .force_short_xfer = 1,
577 .callback = urtw_bulk_tx_callback,
578 .timeout = URTW_DATA_TIMEOUT
580 [URTW_8187B_BULK_TX_VI] = {
582 .endpoint = URTW_8187B_TXPIPE_VI,
583 .direction = UE_DIR_OUT,
584 .bufsize = URTW_TX_MAXSIZE,
587 .force_short_xfer = 1,
590 .callback = urtw_bulk_tx_callback,
591 .timeout = URTW_DATA_TIMEOUT
593 [URTW_8187B_BULK_TX_VO] = {
595 .endpoint = URTW_8187B_TXPIPE_VO,
596 .direction = UE_DIR_OUT,
597 .bufsize = URTW_TX_MAXSIZE,
600 .force_short_xfer = 1,
603 .callback = urtw_bulk_tx_callback,
604 .timeout = URTW_DATA_TIMEOUT
606 [URTW_8187B_BULK_TX_EP12] = {
609 .direction = UE_DIR_OUT,
610 .bufsize = URTW_TX_MAXSIZE,
613 .force_short_xfer = 1,
616 .callback = urtw_bulk_tx_callback,
617 .timeout = URTW_DATA_TIMEOUT
621 static const struct usb_config urtw_8187l_usbconfig[URTW_8187L_N_XFERS] = {
622 [URTW_8187L_BULK_RX] = {
625 .direction = UE_DIR_IN,
632 .callback = urtw_bulk_rx_callback
634 [URTW_8187L_BULK_TX_LOW] = {
637 .direction = UE_DIR_OUT,
638 .bufsize = URTW_TX_MAXSIZE * URTW_TX_DATA_LIST_COUNT,
640 .force_short_xfer = 1,
643 .callback = urtw_bulk_tx_callback,
644 .timeout = URTW_DATA_TIMEOUT
646 [URTW_8187L_BULK_TX_NORMAL] = {
649 .direction = UE_DIR_OUT,
650 .bufsize = URTW_TX_MAXSIZE,
653 .force_short_xfer = 1,
656 .callback = urtw_bulk_tx_callback,
657 .timeout = URTW_DATA_TIMEOUT
661 static struct ieee80211vap *urtw_vap_create(struct ieee80211com *,
662 const char [IFNAMSIZ], int, enum ieee80211_opmode,
663 int, const uint8_t [IEEE80211_ADDR_LEN],
664 const uint8_t [IEEE80211_ADDR_LEN]);
665 static void urtw_vap_delete(struct ieee80211vap *);
666 static void urtw_init(struct urtw_softc *);
667 static void urtw_stop(struct urtw_softc *);
668 static void urtw_parent(struct ieee80211com *);
669 static int urtw_transmit(struct ieee80211com *, struct mbuf *);
670 static void urtw_start(struct urtw_softc *);
671 static int urtw_alloc_rx_data_list(struct urtw_softc *);
672 static int urtw_alloc_tx_data_list(struct urtw_softc *);
673 static int urtw_raw_xmit(struct ieee80211_node *, struct mbuf *,
674 const struct ieee80211_bpf_params *);
675 static void urtw_scan_start(struct ieee80211com *);
676 static void urtw_scan_end(struct ieee80211com *);
677 static void urtw_getradiocaps(struct ieee80211com *, int, int *,
678 struct ieee80211_channel[]);
679 static void urtw_set_channel(struct ieee80211com *);
680 static void urtw_update_mcast(struct ieee80211com *);
681 static int urtw_tx_start(struct urtw_softc *,
682 struct ieee80211_node *, struct mbuf *,
683 struct urtw_data *, int);
684 static int urtw_newstate(struct ieee80211vap *,
685 enum ieee80211_state, int);
686 static void urtw_led_ch(void *);
687 static void urtw_ledtask(void *, int);
688 static void urtw_watchdog(void *);
689 static void urtw_set_multi(void *);
690 static int urtw_isbmode(uint16_t);
691 static uint16_t urtw_rtl2rate(uint32_t);
692 static usb_error_t urtw_set_rate(struct urtw_softc *);
693 static usb_error_t urtw_update_msr(struct urtw_softc *);
694 static usb_error_t urtw_read8_c(struct urtw_softc *, int, uint8_t *);
695 static usb_error_t urtw_read16_c(struct urtw_softc *, int, uint16_t *);
696 static usb_error_t urtw_read32_c(struct urtw_softc *, int, uint32_t *);
697 static usb_error_t urtw_write8_c(struct urtw_softc *, int, uint8_t);
698 static usb_error_t urtw_write16_c(struct urtw_softc *, int, uint16_t);
699 static usb_error_t urtw_write32_c(struct urtw_softc *, int, uint32_t);
700 static usb_error_t urtw_eprom_cs(struct urtw_softc *, int);
701 static usb_error_t urtw_eprom_ck(struct urtw_softc *);
702 static usb_error_t urtw_eprom_sendbits(struct urtw_softc *, int16_t *,
704 static usb_error_t urtw_eprom_read32(struct urtw_softc *, uint32_t,
706 static usb_error_t urtw_eprom_readbit(struct urtw_softc *, int16_t *);
707 static usb_error_t urtw_eprom_writebit(struct urtw_softc *, int16_t);
708 static usb_error_t urtw_get_macaddr(struct urtw_softc *);
709 static usb_error_t urtw_get_txpwr(struct urtw_softc *);
710 static usb_error_t urtw_get_rfchip(struct urtw_softc *);
711 static usb_error_t urtw_led_init(struct urtw_softc *);
712 static usb_error_t urtw_8185_rf_pins_enable(struct urtw_softc *);
713 static usb_error_t urtw_8185_tx_antenna(struct urtw_softc *, uint8_t);
714 static usb_error_t urtw_8187_write_phy(struct urtw_softc *, uint8_t,
716 static usb_error_t urtw_8187_write_phy_ofdm_c(struct urtw_softc *,
718 static usb_error_t urtw_8187_write_phy_cck_c(struct urtw_softc *, uint8_t,
720 static usb_error_t urtw_8225_setgain(struct urtw_softc *, int16_t);
721 static usb_error_t urtw_8225_usb_init(struct urtw_softc *);
722 static usb_error_t urtw_8225_write_c(struct urtw_softc *, uint8_t,
724 static usb_error_t urtw_8225_write_s16(struct urtw_softc *, uint8_t, int,
726 static usb_error_t urtw_8225_read(struct urtw_softc *, uint8_t,
728 static usb_error_t urtw_8225_rf_init(struct urtw_softc *);
729 static usb_error_t urtw_8225_rf_set_chan(struct urtw_softc *, int);
730 static usb_error_t urtw_8225_rf_set_sens(struct urtw_softc *, int);
731 static usb_error_t urtw_8225_set_txpwrlvl(struct urtw_softc *, int);
732 static usb_error_t urtw_8225_rf_stop(struct urtw_softc *);
733 static usb_error_t urtw_8225v2_rf_init(struct urtw_softc *);
734 static usb_error_t urtw_8225v2_rf_set_chan(struct urtw_softc *, int);
735 static usb_error_t urtw_8225v2_set_txpwrlvl(struct urtw_softc *, int);
736 static usb_error_t urtw_8225v2_setgain(struct urtw_softc *, int16_t);
737 static usb_error_t urtw_8225_isv2(struct urtw_softc *, int *);
738 static usb_error_t urtw_8225v2b_rf_init(struct urtw_softc *);
739 static usb_error_t urtw_8225v2b_rf_set_chan(struct urtw_softc *, int);
740 static usb_error_t urtw_read8e(struct urtw_softc *, int, uint8_t *);
741 static usb_error_t urtw_write8e(struct urtw_softc *, int, uint8_t);
742 static usb_error_t urtw_8180_set_anaparam(struct urtw_softc *, uint32_t);
743 static usb_error_t urtw_8185_set_anaparam2(struct urtw_softc *, uint32_t);
744 static usb_error_t urtw_intr_enable(struct urtw_softc *);
745 static usb_error_t urtw_intr_disable(struct urtw_softc *);
746 static usb_error_t urtw_reset(struct urtw_softc *);
747 static usb_error_t urtw_led_on(struct urtw_softc *, int);
748 static usb_error_t urtw_led_ctl(struct urtw_softc *, int);
749 static usb_error_t urtw_led_blink(struct urtw_softc *);
750 static usb_error_t urtw_led_mode0(struct urtw_softc *, int);
751 static usb_error_t urtw_led_mode1(struct urtw_softc *, int);
752 static usb_error_t urtw_led_mode2(struct urtw_softc *, int);
753 static usb_error_t urtw_led_mode3(struct urtw_softc *, int);
754 static usb_error_t urtw_rx_setconf(struct urtw_softc *);
755 static usb_error_t urtw_rx_enable(struct urtw_softc *);
756 static usb_error_t urtw_tx_enable(struct urtw_softc *sc);
757 static void urtw_free_tx_data_list(struct urtw_softc *);
758 static void urtw_free_rx_data_list(struct urtw_softc *);
759 static void urtw_free_data_list(struct urtw_softc *,
760 struct urtw_data data[], int, int);
761 static usb_error_t urtw_adapter_start(struct urtw_softc *);
762 static usb_error_t urtw_adapter_start_b(struct urtw_softc *);
763 static usb_error_t urtw_set_mode(struct urtw_softc *, uint32_t);
764 static usb_error_t urtw_8187b_cmd_reset(struct urtw_softc *);
765 static usb_error_t urtw_do_request(struct urtw_softc *,
766 struct usb_device_request *, void *);
767 static usb_error_t urtw_8225v2b_set_txpwrlvl(struct urtw_softc *, int);
768 static usb_error_t urtw_led_off(struct urtw_softc *, int);
769 static void urtw_abort_xfers(struct urtw_softc *);
770 static struct urtw_data *
771 urtw_getbuf(struct urtw_softc *sc);
772 static int urtw_compute_txtime(uint16_t, uint16_t, uint8_t,
774 static void urtw_updateslot(struct ieee80211com *);
775 static void urtw_updateslottask(void *, int);
776 static void urtw_sysctl_node(struct urtw_softc *);
779 urtw_match(device_t dev)
781 struct usb_attach_arg *uaa = device_get_ivars(dev);
783 if (uaa->usb_mode != USB_MODE_HOST)
785 if (uaa->info.bConfigIndex != URTW_CONFIG_INDEX)
787 if (uaa->info.bIfaceIndex != URTW_IFACE_INDEX)
790 return (usbd_lookup_id_by_uaa(urtw_devs, sizeof(urtw_devs), uaa));
794 urtw_attach(device_t dev)
796 const struct usb_config *setup_start;
798 struct urtw_softc *sc = device_get_softc(dev);
799 struct usb_attach_arg *uaa = device_get_ivars(dev);
800 struct ieee80211com *ic = &sc->sc_ic;
801 uint8_t iface_index = URTW_IFACE_INDEX; /* XXX */
806 device_set_usb_desc(dev);
809 sc->sc_udev = uaa->device;
810 if (USB_GET_DRIVER_INFO(uaa) == URTW_REV_RTL8187B)
811 sc->sc_flags |= URTW_RTL8187B;
813 sc->sc_debug = urtw_debug;
816 mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev), MTX_NETWORK_LOCK,
818 usb_callout_init_mtx(&sc->sc_led_ch, &sc->sc_mtx, 0);
819 TASK_INIT(&sc->sc_led_task, 0, urtw_ledtask, sc);
820 TASK_INIT(&sc->sc_updateslot_task, 0, urtw_updateslottask, sc);
821 callout_init(&sc->sc_watchdog_ch, 0);
822 mbufq_init(&sc->sc_snd, ifqmaxlen);
824 if (sc->sc_flags & URTW_RTL8187B) {
825 setup_start = urtw_8187b_usbconfig;
826 n_setup = URTW_8187B_N_XFERS;
828 setup_start = urtw_8187l_usbconfig;
829 n_setup = URTW_8187L_N_XFERS;
832 error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_xfer,
833 setup_start, n_setup, sc, &sc->sc_mtx);
835 device_printf(dev, "could not allocate USB transfers, "
836 "err=%s\n", usbd_errstr(error));
841 if (sc->sc_flags & URTW_RTL8187B) {
843 usbd_xfer_get_frame_buffer(sc->sc_xfer[
844 URTW_8187B_BULK_TX_BE], 0);
847 usbd_xfer_get_frame_buffer(sc->sc_xfer[
848 URTW_8187L_BULK_TX_LOW], 0);
853 urtw_read32_m(sc, URTW_RX, &data);
854 sc->sc_epromtype = (data & URTW_RX_9356SEL) ? URTW_EEPROM_93C56 :
857 error = urtw_get_rfchip(sc);
860 error = urtw_get_macaddr(sc);
863 error = urtw_get_txpwr(sc);
866 error = urtw_led_init(sc);
872 sc->sc_rts_retry = URTW_DEFAULT_RTS_RETRY;
873 sc->sc_tx_retry = URTW_DEFAULT_TX_RETRY;
874 sc->sc_currate = URTW_RIDX_CCK11;
875 sc->sc_preamble_mode = urtw_preamble_mode;
878 ic->ic_name = device_get_nameunit(dev);
879 ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
880 ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
882 /* set device capabilities */
884 IEEE80211_C_STA | /* station mode */
885 IEEE80211_C_MONITOR | /* monitor mode supported */
886 IEEE80211_C_TXPMGT | /* tx power management */
887 IEEE80211_C_SHPREAMBLE | /* short preamble supported */
888 IEEE80211_C_SHSLOT | /* short slot time supported */
889 IEEE80211_C_BGSCAN | /* capable of bg scanning */
890 IEEE80211_C_WPA; /* 802.11i */
892 /* XXX TODO: setup regdomain if URTW_EPROM_CHANPLAN_BY_HW bit is set.*/
894 urtw_getradiocaps(ic, IEEE80211_CHAN_MAX, &ic->ic_nchans,
897 ieee80211_ifattach(ic);
898 ic->ic_raw_xmit = urtw_raw_xmit;
899 ic->ic_scan_start = urtw_scan_start;
900 ic->ic_scan_end = urtw_scan_end;
901 ic->ic_getradiocaps = urtw_getradiocaps;
902 ic->ic_set_channel = urtw_set_channel;
903 ic->ic_updateslot = urtw_updateslot;
904 ic->ic_vap_create = urtw_vap_create;
905 ic->ic_vap_delete = urtw_vap_delete;
906 ic->ic_update_mcast = urtw_update_mcast;
907 ic->ic_parent = urtw_parent;
908 ic->ic_transmit = urtw_transmit;
910 ieee80211_radiotap_attach(ic,
911 &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
912 URTW_TX_RADIOTAP_PRESENT,
913 &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
914 URTW_RX_RADIOTAP_PRESENT);
916 urtw_sysctl_node(sc);
919 ieee80211_announce(ic);
924 usbd_transfer_unsetup(sc->sc_xfer, (sc->sc_flags & URTW_RTL8187B) ?
925 URTW_8187B_N_XFERS : URTW_8187L_N_XFERS);
931 urtw_detach(device_t dev)
933 struct urtw_softc *sc = device_get_softc(dev);
934 struct ieee80211com *ic = &sc->sc_ic;
936 unsigned int n_xfers;
938 /* Prevent further ioctls */
940 sc->sc_flags |= URTW_DETACHED;
944 ieee80211_draintask(ic, &sc->sc_updateslot_task);
945 ieee80211_draintask(ic, &sc->sc_led_task);
947 usb_callout_drain(&sc->sc_led_ch);
948 callout_drain(&sc->sc_watchdog_ch);
950 n_xfers = (sc->sc_flags & URTW_RTL8187B) ?
951 URTW_8187B_N_XFERS : URTW_8187L_N_XFERS;
953 /* prevent further allocations from RX/TX data lists */
955 STAILQ_INIT(&sc->sc_tx_active);
956 STAILQ_INIT(&sc->sc_tx_inactive);
957 STAILQ_INIT(&sc->sc_tx_pending);
959 STAILQ_INIT(&sc->sc_rx_active);
960 STAILQ_INIT(&sc->sc_rx_inactive);
963 /* drain USB transfers */
964 for (x = 0; x != n_xfers; x++)
965 usbd_transfer_drain(sc->sc_xfer[x]);
967 /* free data buffers */
969 urtw_free_tx_data_list(sc);
970 urtw_free_rx_data_list(sc);
973 /* free USB transfers and some data buffers */
974 usbd_transfer_unsetup(sc->sc_xfer, n_xfers);
976 ieee80211_ifdetach(ic);
977 mbufq_drain(&sc->sc_snd);
978 mtx_destroy(&sc->sc_mtx);
983 urtw_free_tx_data_list(struct urtw_softc *sc)
985 urtw_free_data_list(sc, sc->sc_tx, URTW_TX_DATA_LIST_COUNT, 0);
989 urtw_free_rx_data_list(struct urtw_softc *sc)
991 urtw_free_data_list(sc, sc->sc_rx, URTW_RX_DATA_LIST_COUNT, 1);
995 urtw_free_data_list(struct urtw_softc *sc, struct urtw_data data[], int ndata,
1000 for (i = 0; i < ndata; i++) {
1001 struct urtw_data *dp = &data[i];
1003 if (fillmbuf == 1) {
1004 if (dp->m != NULL) {
1012 if (dp->ni != NULL) {
1013 ieee80211_free_node(dp->ni);
1019 static struct ieee80211vap *
1020 urtw_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
1021 enum ieee80211_opmode opmode, int flags,
1022 const uint8_t bssid[IEEE80211_ADDR_LEN],
1023 const uint8_t mac[IEEE80211_ADDR_LEN])
1025 struct urtw_vap *uvp;
1026 struct ieee80211vap *vap;
1028 if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
1030 uvp = malloc(sizeof(struct urtw_vap), M_80211_VAP, M_WAITOK | M_ZERO);
1032 /* enable s/w bmiss handling for sta mode */
1034 if (ieee80211_vap_setup(ic, vap, name, unit, opmode,
1035 flags | IEEE80211_CLONE_NOBEACONS, bssid) != 0) {
1037 free(uvp, M_80211_VAP);
1041 /* override state transition machine */
1042 uvp->newstate = vap->iv_newstate;
1043 vap->iv_newstate = urtw_newstate;
1045 /* complete setup */
1046 ieee80211_vap_attach(vap, ieee80211_media_change,
1047 ieee80211_media_status, mac);
1048 ic->ic_opmode = opmode;
1053 urtw_vap_delete(struct ieee80211vap *vap)
1055 struct urtw_vap *uvp = URTW_VAP(vap);
1057 ieee80211_vap_detach(vap);
1058 free(uvp, M_80211_VAP);
1062 urtw_init(struct urtw_softc *sc)
1067 URTW_ASSERT_LOCKED(sc);
1069 if (sc->sc_flags & URTW_RUNNING)
1072 error = (sc->sc_flags & URTW_RTL8187B) ? urtw_adapter_start_b(sc) :
1073 urtw_adapter_start(sc);
1077 /* reset softc variables */
1080 if (!(sc->sc_flags & URTW_INIT_ONCE)) {
1081 ret = urtw_alloc_rx_data_list(sc);
1084 ret = urtw_alloc_tx_data_list(sc);
1087 sc->sc_flags |= URTW_INIT_ONCE;
1090 error = urtw_rx_enable(sc);
1093 error = urtw_tx_enable(sc);
1097 if (sc->sc_flags & URTW_RTL8187B)
1098 usbd_transfer_start(sc->sc_xfer[URTW_8187B_BULK_TX_STATUS]);
1100 sc->sc_flags |= URTW_RUNNING;
1102 callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc);
1108 urtw_adapter_start_b(struct urtw_softc *sc)
1113 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
1117 urtw_read8_m(sc, URTW_CONFIG3, &data8);
1118 urtw_write8_m(sc, URTW_CONFIG3,
1119 data8 | URTW_CONFIG3_ANAPARAM_WRITE | URTW_CONFIG3_GNT_SELECT);
1120 urtw_write32_m(sc, URTW_ANAPARAM2, URTW_8187B_8225_ANAPARAM2_ON);
1121 urtw_write32_m(sc, URTW_ANAPARAM, URTW_8187B_8225_ANAPARAM_ON);
1122 urtw_write8_m(sc, URTW_ANAPARAM3, URTW_8187B_8225_ANAPARAM3_ON);
1124 urtw_write8_m(sc, 0x61, 0x10);
1125 urtw_read8_m(sc, 0x62, &data8);
1126 urtw_write8_m(sc, 0x62, data8 & ~(1 << 5));
1127 urtw_write8_m(sc, 0x62, data8 | (1 << 5));
1129 urtw_read8_m(sc, URTW_CONFIG3, &data8);
1130 data8 &= ~URTW_CONFIG3_ANAPARAM_WRITE;
1131 urtw_write8_m(sc, URTW_CONFIG3, data8);
1133 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
1137 error = urtw_8187b_cmd_reset(sc);
1141 error = sc->sc_rf_init(sc);
1144 urtw_write8_m(sc, URTW_CMD, URTW_CMD_RX_ENABLE | URTW_CMD_TX_ENABLE);
1146 /* fix RTL8187B RX stall */
1147 error = urtw_intr_enable(sc);
1151 error = urtw_write8e(sc, 0x41, 0xf4);
1154 error = urtw_write8e(sc, 0x40, 0x00);
1157 error = urtw_write8e(sc, 0x42, 0x00);
1160 error = urtw_write8e(sc, 0x42, 0x01);
1163 error = urtw_write8e(sc, 0x40, 0x0f);
1166 error = urtw_write8e(sc, 0x42, 0x00);
1169 error = urtw_write8e(sc, 0x42, 0x01);
1173 urtw_read8_m(sc, 0xdb, &data8);
1174 urtw_write8_m(sc, 0xdb, data8 | (1 << 2));
1175 urtw_write16_m(sc, 0x372, 0x59fa);
1176 urtw_write16_m(sc, 0x374, 0x59d2);
1177 urtw_write16_m(sc, 0x376, 0x59d2);
1178 urtw_write16_m(sc, 0x378, 0x19fa);
1179 urtw_write16_m(sc, 0x37a, 0x19fa);
1180 urtw_write16_m(sc, 0x37c, 0x00d0);
1181 urtw_write8_m(sc, 0x61, 0);
1183 urtw_write8_m(sc, 0x180, 0x0f);
1184 urtw_write8_m(sc, 0x183, 0x03);
1185 urtw_write8_m(sc, 0xda, 0x10);
1186 urtw_write8_m(sc, 0x24d, 0x08);
1187 urtw_write32_m(sc, URTW_HSSI_PARA, 0x0600321b);
1189 urtw_write16_m(sc, 0x1ec, 0x800); /* RX MAX SIZE */
1195 urtw_adapter_start(struct urtw_softc *sc)
1197 struct ieee80211com *ic = &sc->sc_ic;
1200 error = urtw_reset(sc);
1204 urtw_write8_m(sc, URTW_ADDR_MAGIC1, 0);
1205 urtw_write8_m(sc, URTW_GPIO, 0);
1208 urtw_write8_m(sc, URTW_ADDR_MAGIC1, 4);
1209 error = urtw_led_ctl(sc, URTW_LED_CTL_POWER_ON);
1213 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
1216 /* applying MAC address again. */
1217 urtw_write32_m(sc, URTW_MAC0, ((uint32_t *)ic->ic_macaddr)[0]);
1218 urtw_write16_m(sc, URTW_MAC4, ((uint32_t *)ic->ic_macaddr)[1] & 0xffff);
1219 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
1223 error = urtw_update_msr(sc);
1227 urtw_write32_m(sc, URTW_INT_TIMEOUT, 0);
1228 urtw_write8_m(sc, URTW_WPA_CONFIG, 0);
1229 urtw_write8_m(sc, URTW_RATE_FALLBACK, URTW_RATE_FALLBACK_ENABLE | 0x1);
1230 error = urtw_set_rate(sc);
1234 error = sc->sc_rf_init(sc);
1237 if (sc->sc_rf_set_sens != NULL)
1238 sc->sc_rf_set_sens(sc, sc->sc_sens);
1240 /* XXX correct? to call write16 */
1241 urtw_write16_m(sc, URTW_PSR, 1);
1242 urtw_write16_m(sc, URTW_ADDR_MAGIC2, 0x10);
1243 urtw_write8_m(sc, URTW_TALLY_SEL, 0x80);
1244 urtw_write8_m(sc, URTW_ADDR_MAGIC3, 0x60);
1245 /* XXX correct? to call write16 */
1246 urtw_write16_m(sc, URTW_PSR, 0);
1247 urtw_write8_m(sc, URTW_ADDR_MAGIC1, 4);
1249 error = urtw_intr_enable(sc);
1258 urtw_set_mode(struct urtw_softc *sc, uint32_t mode)
1263 urtw_read8_m(sc, URTW_EPROM_CMD, &data);
1264 data = (data & ~URTW_EPROM_CMD_MASK) | (mode << URTW_EPROM_CMD_SHIFT);
1265 data = data & ~(URTW_EPROM_CS | URTW_EPROM_CK);
1266 urtw_write8_m(sc, URTW_EPROM_CMD, data);
1272 urtw_8187b_cmd_reset(struct urtw_softc *sc)
1278 /* XXX the code can be duplicate with urtw_reset(). */
1279 urtw_read8_m(sc, URTW_CMD, &data8);
1280 data8 = (data8 & 0x2) | URTW_CMD_RST;
1281 urtw_write8_m(sc, URTW_CMD, data8);
1283 for (i = 0; i < 20; i++) {
1284 usb_pause_mtx(&sc->sc_mtx, 2);
1285 urtw_read8_m(sc, URTW_CMD, &data8);
1286 if (!(data8 & URTW_CMD_RST))
1290 device_printf(sc->sc_dev, "reset timeout\n");
1298 urtw_do_request(struct urtw_softc *sc,
1299 struct usb_device_request *req, void *data)
1304 URTW_ASSERT_LOCKED(sc);
1307 err = usbd_do_request_flags(sc->sc_udev, &sc->sc_mtx,
1308 req, data, 0, NULL, 250 /* ms */);
1312 DPRINTF(sc, URTW_DEBUG_INIT,
1313 "Control request failed, %s (retrying)\n",
1315 usb_pause_mtx(&sc->sc_mtx, hz / 100);
1321 urtw_stop(struct urtw_softc *sc)
1326 URTW_ASSERT_LOCKED(sc);
1328 sc->sc_flags &= ~URTW_RUNNING;
1330 error = urtw_intr_disable(sc);
1333 urtw_read8_m(sc, URTW_CMD, &data8);
1334 data8 &= ~(URTW_CMD_RX_ENABLE | URTW_CMD_TX_ENABLE);
1335 urtw_write8_m(sc, URTW_CMD, data8);
1337 error = sc->sc_rf_stop(sc);
1341 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
1344 urtw_read8_m(sc, URTW_CONFIG4, &data8);
1345 urtw_write8_m(sc, URTW_CONFIG4, data8 | URTW_CONFIG4_VCOOFF);
1346 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
1351 device_printf(sc->sc_dev, "failed to stop (%s)\n",
1352 usbd_errstr(error));
1354 usb_callout_stop(&sc->sc_led_ch);
1355 callout_stop(&sc->sc_watchdog_ch);
1357 urtw_abort_xfers(sc);
1361 urtw_abort_xfers(struct urtw_softc *sc)
1365 URTW_ASSERT_LOCKED(sc);
1367 max = (sc->sc_flags & URTW_RTL8187B) ? URTW_8187B_N_XFERS :
1370 /* abort any pending transfers */
1371 for (i = 0; i < max; i++)
1372 usbd_transfer_stop(sc->sc_xfer[i]);
1376 urtw_parent(struct ieee80211com *ic)
1378 struct urtw_softc *sc = ic->ic_softc;
1382 if (sc->sc_flags & URTW_DETACHED) {
1387 if (ic->ic_nrunning > 0) {
1388 if (sc->sc_flags & URTW_RUNNING) {
1389 if (ic->ic_promisc > 0 || ic->ic_allmulti > 0)
1395 } else if (sc->sc_flags & URTW_RUNNING)
1399 ieee80211_start_all(ic);
1403 urtw_transmit(struct ieee80211com *ic, struct mbuf *m)
1405 struct urtw_softc *sc = ic->ic_softc;
1409 if ((sc->sc_flags & URTW_RUNNING) == 0) {
1413 error = mbufq_enqueue(&sc->sc_snd, m);
1425 urtw_start(struct urtw_softc *sc)
1427 struct urtw_data *bf;
1428 struct ieee80211_node *ni;
1431 URTW_ASSERT_LOCKED(sc);
1433 if ((sc->sc_flags & URTW_RUNNING) == 0)
1436 while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
1437 bf = urtw_getbuf(sc);
1439 mbufq_prepend(&sc->sc_snd, m);
1443 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
1444 m->m_pkthdr.rcvif = NULL;
1446 if (urtw_tx_start(sc, ni, m, bf, URTW_PRIORITY_NORMAL) != 0) {
1447 if_inc_counter(ni->ni_vap->iv_ifp,
1448 IFCOUNTER_OERRORS, 1);
1449 STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
1450 ieee80211_free_node(ni);
1455 callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc);
1460 urtw_alloc_data_list(struct urtw_softc *sc, struct urtw_data data[],
1461 int ndata, int maxsz, void *dma_buf)
1465 for (i = 0; i < ndata; i++) {
1466 struct urtw_data *dp = &data[i];
1469 if (dma_buf == NULL) {
1470 dp->m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
1471 if (dp->m == NULL) {
1472 device_printf(sc->sc_dev,
1473 "could not allocate rx mbuf\n");
1477 dp->buf = mtod(dp->m, uint8_t *);
1480 dp->buf = ((uint8_t *)dma_buf) +
1487 fail: urtw_free_data_list(sc, data, ndata, 1);
1492 urtw_alloc_rx_data_list(struct urtw_softc *sc)
1496 error = urtw_alloc_data_list(sc,
1497 sc->sc_rx, URTW_RX_DATA_LIST_COUNT,
1498 MCLBYTES, NULL /* 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,
1518 sc->sc_tx_dma_buf /* no mbufs */);
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 urtw_softc *sc = ic->ic_softc;
1539 struct urtw_data *bf;
1541 /* prevent management frames from being sent if we're not ready */
1542 if (!(sc->sc_flags & URTW_RUNNING)) {
1547 bf = urtw_getbuf(sc);
1551 return (ENOBUFS); /* XXX */
1554 if (urtw_tx_start(sc, ni, m, bf, URTW_PRIORITY_LOW) != 0) {
1555 STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
1566 urtw_scan_start(struct ieee80211com *ic)
1569 /* XXX do nothing? */
1573 urtw_scan_end(struct ieee80211com *ic)
1576 /* XXX do nothing? */
1580 urtw_getradiocaps(struct ieee80211com *ic,
1581 int maxchans, int *nchans, struct ieee80211_channel chans[])
1583 uint8_t bands[IEEE80211_MODE_BYTES];
1585 memset(bands, 0, sizeof(bands));
1586 setbit(bands, IEEE80211_MODE_11B);
1587 setbit(bands, IEEE80211_MODE_11G);
1588 ieee80211_add_channel_list_2ghz(chans, maxchans, nchans,
1589 urtw_chan_2ghz, nitems(urtw_chan_2ghz), bands, 0);
1593 urtw_set_channel(struct ieee80211com *ic)
1595 struct urtw_softc *sc = ic->ic_softc;
1596 uint32_t data, orig;
1600 * if the user set a channel explicitly using ifconfig(8) this function
1601 * can be called earlier than we're expected that in some cases the
1602 * initialization would be failed if setting a channel is called before
1603 * the init have done.
1605 if (!(sc->sc_flags & URTW_RUNNING))
1608 if (sc->sc_curchan != NULL && sc->sc_curchan == ic->ic_curchan)
1614 * during changing th channel we need to temporarily be disable
1617 urtw_read32_m(sc, URTW_TX_CONF, &orig);
1618 data = orig & ~URTW_TX_LOOPBACK_MASK;
1619 urtw_write32_m(sc, URTW_TX_CONF, data | URTW_TX_LOOPBACK_MAC);
1621 error = sc->sc_rf_set_chan(sc, ieee80211_chan2ieee(ic, ic->ic_curchan));
1624 usb_pause_mtx(&sc->sc_mtx, 10);
1625 urtw_write32_m(sc, URTW_TX_CONF, orig);
1627 urtw_write16_m(sc, URTW_ATIM_WND, 2);
1628 urtw_write16_m(sc, URTW_ATIM_TR_ITV, 100);
1629 urtw_write16_m(sc, URTW_BEACON_INTERVAL, 100);
1630 urtw_write16_m(sc, URTW_BEACON_INTERVAL_TIME, 100);
1635 sc->sc_curchan = ic->ic_curchan;
1638 device_printf(sc->sc_dev, "could not change the channel\n");
1642 urtw_update_mcast(struct ieee80211com *ic)
1645 /* XXX do nothing? */
1649 urtw_tx_start(struct urtw_softc *sc, struct ieee80211_node *ni, struct mbuf *m0,
1650 struct urtw_data *data, int prior)
1652 struct ieee80211_frame *wh = mtod(m0, struct ieee80211_frame *);
1653 struct ieee80211_key *k;
1654 const struct ieee80211_txparam *tp = ni->ni_txparms;
1655 struct ieee80211com *ic = &sc->sc_ic;
1656 struct ieee80211vap *vap = ni->ni_vap;
1657 struct usb_xfer *rtl8187b_pipes[URTW_8187B_TXPIPE_MAX] = {
1658 sc->sc_xfer[URTW_8187B_BULK_TX_BE],
1659 sc->sc_xfer[URTW_8187B_BULK_TX_BK],
1660 sc->sc_xfer[URTW_8187B_BULK_TX_VI],
1661 sc->sc_xfer[URTW_8187B_BULK_TX_VO]
1663 struct usb_xfer *xfer;
1664 int dur = 0, rtsdur = 0, rtsenable = 0, ctsenable = 0, rate, type,
1665 pkttime = 0, txdur = 0, isshort = 0, xferlen, ismcast;
1666 uint16_t acktime, rtstime, ctstime;
1670 URTW_ASSERT_LOCKED(sc);
1672 ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
1673 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
1678 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
1679 k = ieee80211_crypto_encap(ni, m0);
1681 device_printf(sc->sc_dev,
1682 "ieee80211_crypto_encap returns NULL.\n");
1683 /* XXX we don't expect the fragmented frames */
1688 /* in case packet header moved, reset pointer */
1689 wh = mtod(m0, struct ieee80211_frame *);
1692 if (ieee80211_radiotap_active_vap(vap)) {
1693 struct urtw_tx_radiotap_header *tap = &sc->sc_txtap;
1695 /* XXX Are variables correct? */
1697 tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
1698 tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
1700 ieee80211_radiotap_tx(vap, m0);
1703 if (type == IEEE80211_FC0_TYPE_MGT ||
1704 type == IEEE80211_FC0_TYPE_CTL ||
1705 (m0->m_flags & M_EAPOL) != 0) {
1706 rate = tp->mgmtrate;
1708 /* for data frames */
1710 rate = tp->mcastrate;
1711 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
1712 rate = tp->ucastrate;
1714 rate = urtw_rtl2rate(sc->sc_currate);
1717 sc->sc_stats.txrates[sc->sc_currate]++;
1720 txdur = pkttime = urtw_compute_txtime(m0->m_pkthdr.len +
1721 IEEE80211_CRC_LEN, rate, 0, 0);
1723 acktime = urtw_compute_txtime(14, 2,0, 0);
1724 if ((m0->m_pkthdr.len + 4) > vap->iv_rtsthreshold) {
1727 rtstime = urtw_compute_txtime(URTW_ACKCTS_LEN, 2, 0, 0);
1728 ctstime = urtw_compute_txtime(14, 2, 0, 0);
1729 pkttime = urtw_compute_txtime(m0->m_pkthdr.len +
1730 IEEE80211_CRC_LEN, rate, 0, isshort);
1731 rtsdur = ctstime + pkttime + acktime +
1732 3 * URTW_ASIFS_TIME;
1733 txdur = rtstime + rtsdur;
1735 rtsenable = ctsenable = rtsdur = 0;
1736 pkttime = urtw_compute_txtime(m0->m_pkthdr.len +
1737 IEEE80211_CRC_LEN, rate, 0, isshort);
1738 txdur = pkttime + URTW_ASIFS_TIME + acktime;
1741 if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG)
1742 dur = urtw_compute_txtime(m0->m_pkthdr.len +
1743 IEEE80211_CRC_LEN, rate, 0, isshort) +
1744 3 * URTW_ASIFS_TIME +
1747 dur = URTW_ASIFS_TIME + acktime;
1749 USETW(wh->i_dur, dur);
1751 xferlen = m0->m_pkthdr.len;
1752 xferlen += (sc->sc_flags & URTW_RTL8187B) ? (4 * 8) : (4 * 3);
1753 if ((0 == xferlen % 64) || (0 == xferlen % 512))
1756 memset(data->buf, 0, URTW_TX_MAXSIZE);
1757 flags = m0->m_pkthdr.len & 0xfff;
1758 flags |= URTW_TX_FLAG_NO_ENC;
1759 if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
1760 (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE) &&
1761 (sc->sc_preamble_mode == URTW_PREAMBLE_MODE_SHORT) &&
1762 (sc->sc_currate != 0))
1763 flags |= URTW_TX_FLAG_SPLCP;
1764 if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG)
1765 flags |= URTW_TX_FLAG_MOREFRAG;
1767 flags |= (sc->sc_currate & 0xf) << URTW_TX_FLAG_TXRATE_SHIFT;
1769 if (sc->sc_flags & URTW_RTL8187B) {
1770 struct urtw_8187b_txhdr *tx;
1772 tx = (struct urtw_8187b_txhdr *)data->buf;
1774 flags |= URTW_TX_FLAG_CTS;
1776 flags |= URTW_TX_FLAG_RTS;
1777 flags |= URTW_RIDX_CCK5 << URTW_TX_FLAG_RTSRATE_SHIFT;
1778 tx->rtsdur = rtsdur;
1780 tx->flag = htole32(flags);
1782 if (type == IEEE80211_FC0_TYPE_MGT &&
1783 (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) ==
1784 IEEE80211_FC0_SUBTYPE_PROBE_RESP)
1787 tx->retry = URTW_TX_MAXRETRY;
1788 m_copydata(m0, 0, m0->m_pkthdr.len, (uint8_t *)(tx + 1));
1790 struct urtw_8187l_txhdr *tx;
1792 tx = (struct urtw_8187l_txhdr *)data->buf;
1794 flags |= URTW_TX_FLAG_RTS;
1795 tx->rtsdur = rtsdur;
1797 flags |= URTW_RIDX_CCK5 << URTW_TX_FLAG_RTSRATE_SHIFT;
1798 tx->flag = htole32(flags);
1799 tx->retry = 3; /* CW minimum */
1800 tx->retry |= 7 << 4; /* CW maximum */
1801 tx->retry |= URTW_TX_MAXRETRY << 8; /* retry limitation */
1802 m_copydata(m0, 0, m0->m_pkthdr.len, (uint8_t *)(tx + 1));
1805 data->buflen = xferlen;
1809 if (sc->sc_flags & URTW_RTL8187B) {
1811 case IEEE80211_FC0_TYPE_CTL:
1812 case IEEE80211_FC0_TYPE_MGT:
1813 xfer = sc->sc_xfer[URTW_8187B_BULK_TX_EP12];
1816 KASSERT(M_WME_GETAC(m0) < URTW_8187B_TXPIPE_MAX,
1817 ("unsupported WME pipe %d", M_WME_GETAC(m0)));
1818 xfer = rtl8187b_pipes[M_WME_GETAC(m0)];
1822 xfer = (prior == URTW_PRIORITY_LOW) ?
1823 sc->sc_xfer[URTW_8187L_BULK_TX_LOW] :
1824 sc->sc_xfer[URTW_8187L_BULK_TX_NORMAL];
1826 STAILQ_INSERT_TAIL(&sc->sc_tx_pending, data, next);
1827 usbd_transfer_start(xfer);
1829 error = urtw_led_ctl(sc, URTW_LED_CTL_TX);
1831 device_printf(sc->sc_dev, "could not control LED (%d)\n",
1837 urtw_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
1839 struct ieee80211com *ic = vap->iv_ic;
1840 struct urtw_softc *sc = ic->ic_softc;
1841 struct urtw_vap *uvp = URTW_VAP(vap);
1842 struct ieee80211_node *ni;
1843 usb_error_t error = 0;
1845 DPRINTF(sc, URTW_DEBUG_STATE, "%s: %s -> %s\n", __func__,
1846 ieee80211_state_name[vap->iv_state],
1847 ieee80211_state_name[nstate]);
1849 sc->sc_state = nstate;
1851 IEEE80211_UNLOCK(ic);
1853 usb_callout_stop(&sc->sc_led_ch);
1854 callout_stop(&sc->sc_watchdog_ch);
1857 case IEEE80211_S_INIT:
1858 case IEEE80211_S_SCAN:
1859 case IEEE80211_S_AUTH:
1860 case IEEE80211_S_ASSOC:
1862 case IEEE80211_S_RUN:
1863 ni = ieee80211_ref_node(vap->iv_bss);
1864 /* setting bssid. */
1865 urtw_write32_m(sc, URTW_BSSID, ((uint32_t *)ni->ni_bssid)[0]);
1866 urtw_write16_m(sc, URTW_BSSID + 4,
1867 ((uint16_t *)ni->ni_bssid)[2]);
1868 urtw_update_msr(sc);
1869 /* XXX maybe the below would be incorrect. */
1870 urtw_write16_m(sc, URTW_ATIM_WND, 2);
1871 urtw_write16_m(sc, URTW_ATIM_TR_ITV, 100);
1872 urtw_write16_m(sc, URTW_BEACON_INTERVAL, 0x64);
1873 urtw_write16_m(sc, URTW_BEACON_INTERVAL_TIME, 100);
1874 error = urtw_led_ctl(sc, URTW_LED_CTL_LINK);
1876 device_printf(sc->sc_dev,
1877 "could not control LED (%d)\n", error);
1878 ieee80211_free_node(ni);
1886 return (uvp->newstate(vap, nstate, arg));
1890 urtw_watchdog(void *arg)
1892 struct urtw_softc *sc = arg;
1894 if (sc->sc_txtimer > 0) {
1895 if (--sc->sc_txtimer == 0) {
1896 device_printf(sc->sc_dev, "device timeout\n");
1897 counter_u64_add(sc->sc_ic.ic_oerrors, 1);
1900 callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc);
1905 urtw_set_multi(void *arg)
1907 /* XXX don't know how to set a device. Lack of docs. */
1911 urtw_set_rate(struct urtw_softc *sc)
1913 int i, basic_rate, min_rr_rate, max_rr_rate;
1917 basic_rate = URTW_RIDX_OFDM24;
1918 min_rr_rate = URTW_RIDX_OFDM6;
1919 max_rr_rate = URTW_RIDX_OFDM24;
1921 urtw_write8_m(sc, URTW_RESP_RATE,
1922 max_rr_rate << URTW_RESP_MAX_RATE_SHIFT |
1923 min_rr_rate << URTW_RESP_MIN_RATE_SHIFT);
1925 urtw_read16_m(sc, URTW_BRSR, &data);
1926 data &= ~URTW_BRSR_MBR_8185;
1928 for (i = 0; i <= basic_rate; i++)
1931 urtw_write16_m(sc, URTW_BRSR, data);
1937 urtw_rtl2rate(uint32_t rate)
1941 for (i = 0; i < nitems(urtw_ratetable); i++) {
1942 if (rate == urtw_ratetable[i].val)
1943 return urtw_ratetable[i].reg;
1950 urtw_update_msr(struct urtw_softc *sc)
1952 struct ieee80211com *ic = &sc->sc_ic;
1956 urtw_read8_m(sc, URTW_MSR, &data);
1957 data &= ~URTW_MSR_LINK_MASK;
1959 if (sc->sc_state == IEEE80211_S_RUN) {
1960 switch (ic->ic_opmode) {
1961 case IEEE80211_M_STA:
1962 case IEEE80211_M_MONITOR:
1963 data |= URTW_MSR_LINK_STA;
1964 if (sc->sc_flags & URTW_RTL8187B)
1965 data |= URTW_MSR_LINK_ENEDCA;
1967 case IEEE80211_M_IBSS:
1968 data |= URTW_MSR_LINK_ADHOC;
1970 case IEEE80211_M_HOSTAP:
1971 data |= URTW_MSR_LINK_HOSTAP;
1974 DPRINTF(sc, URTW_DEBUG_STATE,
1975 "unsupported operation mode 0x%x\n",
1977 error = USB_ERR_INVAL;
1981 data |= URTW_MSR_LINK_NONE;
1983 urtw_write8_m(sc, URTW_MSR, data);
1989 urtw_read8_c(struct urtw_softc *sc, int val, uint8_t *data)
1991 struct usb_device_request req;
1994 URTW_ASSERT_LOCKED(sc);
1996 req.bmRequestType = UT_READ_VENDOR_DEVICE;
1997 req.bRequest = URTW_8187_GETREGS_REQ;
1998 USETW(req.wValue, (val & 0xff) | 0xff00);
1999 USETW(req.wIndex, (val >> 8) & 0x3);
2000 USETW(req.wLength, sizeof(uint8_t));
2002 error = urtw_do_request(sc, &req, data);
2007 urtw_read16_c(struct urtw_softc *sc, int val, uint16_t *data)
2009 struct usb_device_request req;
2012 URTW_ASSERT_LOCKED(sc);
2014 req.bmRequestType = UT_READ_VENDOR_DEVICE;
2015 req.bRequest = URTW_8187_GETREGS_REQ;
2016 USETW(req.wValue, (val & 0xff) | 0xff00);
2017 USETW(req.wIndex, (val >> 8) & 0x3);
2018 USETW(req.wLength, sizeof(uint16_t));
2020 error = urtw_do_request(sc, &req, data);
2025 urtw_read32_c(struct urtw_softc *sc, int val, uint32_t *data)
2027 struct usb_device_request req;
2030 URTW_ASSERT_LOCKED(sc);
2032 req.bmRequestType = UT_READ_VENDOR_DEVICE;
2033 req.bRequest = URTW_8187_GETREGS_REQ;
2034 USETW(req.wValue, (val & 0xff) | 0xff00);
2035 USETW(req.wIndex, (val >> 8) & 0x3);
2036 USETW(req.wLength, sizeof(uint32_t));
2038 error = urtw_do_request(sc, &req, data);
2043 urtw_write8_c(struct urtw_softc *sc, int val, uint8_t data)
2045 struct usb_device_request req;
2047 URTW_ASSERT_LOCKED(sc);
2049 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
2050 req.bRequest = URTW_8187_SETREGS_REQ;
2051 USETW(req.wValue, (val & 0xff) | 0xff00);
2052 USETW(req.wIndex, (val >> 8) & 0x3);
2053 USETW(req.wLength, sizeof(uint8_t));
2055 return (urtw_do_request(sc, &req, &data));
2059 urtw_write16_c(struct urtw_softc *sc, int val, uint16_t data)
2061 struct usb_device_request req;
2063 URTW_ASSERT_LOCKED(sc);
2065 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
2066 req.bRequest = URTW_8187_SETREGS_REQ;
2067 USETW(req.wValue, (val & 0xff) | 0xff00);
2068 USETW(req.wIndex, (val >> 8) & 0x3);
2069 USETW(req.wLength, sizeof(uint16_t));
2071 return (urtw_do_request(sc, &req, &data));
2075 urtw_write32_c(struct urtw_softc *sc, int val, uint32_t data)
2077 struct usb_device_request req;
2079 URTW_ASSERT_LOCKED(sc);
2081 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
2082 req.bRequest = URTW_8187_SETREGS_REQ;
2083 USETW(req.wValue, (val & 0xff) | 0xff00);
2084 USETW(req.wIndex, (val >> 8) & 0x3);
2085 USETW(req.wLength, sizeof(uint32_t));
2087 return (urtw_do_request(sc, &req, &data));
2091 urtw_get_macaddr(struct urtw_softc *sc)
2093 struct ieee80211com *ic = &sc->sc_ic;
2097 error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR, &data);
2100 ic->ic_macaddr[0] = data & 0xff;
2101 ic->ic_macaddr[1] = (data & 0xff00) >> 8;
2102 error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR + 1, &data);
2105 ic->ic_macaddr[2] = data & 0xff;
2106 ic->ic_macaddr[3] = (data & 0xff00) >> 8;
2107 error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR + 2, &data);
2110 ic->ic_macaddr[4] = data & 0xff;
2111 ic->ic_macaddr[5] = (data & 0xff00) >> 8;
2117 urtw_eprom_read32(struct urtw_softc *sc, uint32_t addr, uint32_t *data)
2119 #define URTW_READCMD_LEN 3
2121 int16_t addrstr[8], data16, readcmd[] = { 1, 1, 0 };
2124 /* NB: make sure the buffer is initialized */
2127 /* enable EPROM programming */
2128 urtw_write8_m(sc, URTW_EPROM_CMD, URTW_EPROM_CMD_PROGRAM_MODE);
2129 DELAY(URTW_EPROM_DELAY);
2131 error = urtw_eprom_cs(sc, URTW_EPROM_ENABLE);
2134 error = urtw_eprom_ck(sc);
2137 error = urtw_eprom_sendbits(sc, readcmd, URTW_READCMD_LEN);
2140 if (sc->sc_epromtype == URTW_EEPROM_93C56) {
2142 addrstr[0] = addr & (1 << 7);
2143 addrstr[1] = addr & (1 << 6);
2144 addrstr[2] = addr & (1 << 5);
2145 addrstr[3] = addr & (1 << 4);
2146 addrstr[4] = addr & (1 << 3);
2147 addrstr[5] = addr & (1 << 2);
2148 addrstr[6] = addr & (1 << 1);
2149 addrstr[7] = addr & (1 << 0);
2152 addrstr[0] = addr & (1 << 5);
2153 addrstr[1] = addr & (1 << 4);
2154 addrstr[2] = addr & (1 << 3);
2155 addrstr[3] = addr & (1 << 2);
2156 addrstr[4] = addr & (1 << 1);
2157 addrstr[5] = addr & (1 << 0);
2159 error = urtw_eprom_sendbits(sc, addrstr, addrlen);
2163 error = urtw_eprom_writebit(sc, 0);
2167 for (i = 0; i < 16; i++) {
2168 error = urtw_eprom_ck(sc);
2171 error = urtw_eprom_readbit(sc, &data16);
2175 (*data) |= (data16 << (15 - i));
2178 error = urtw_eprom_cs(sc, URTW_EPROM_DISABLE);
2181 error = urtw_eprom_ck(sc);
2185 /* now disable EPROM programming */
2186 urtw_write8_m(sc, URTW_EPROM_CMD, URTW_EPROM_CMD_NORMAL_MODE);
2189 #undef URTW_READCMD_LEN
2193 urtw_eprom_cs(struct urtw_softc *sc, int able)
2198 urtw_read8_m(sc, URTW_EPROM_CMD, &data);
2199 if (able == URTW_EPROM_ENABLE)
2200 urtw_write8_m(sc, URTW_EPROM_CMD, data | URTW_EPROM_CS);
2202 urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_CS);
2203 DELAY(URTW_EPROM_DELAY);
2209 urtw_eprom_ck(struct urtw_softc *sc)
2215 urtw_read8_m(sc, URTW_EPROM_CMD, &data);
2216 urtw_write8_m(sc, URTW_EPROM_CMD, data | URTW_EPROM_CK);
2217 DELAY(URTW_EPROM_DELAY);
2219 urtw_read8_m(sc, URTW_EPROM_CMD, &data);
2220 urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_CK);
2221 DELAY(URTW_EPROM_DELAY);
2227 urtw_eprom_readbit(struct urtw_softc *sc, int16_t *data)
2232 urtw_read8_m(sc, URTW_EPROM_CMD, &data8);
2233 *data = (data8 & URTW_EPROM_READBIT) ? 1 : 0;
2234 DELAY(URTW_EPROM_DELAY);
2241 urtw_eprom_writebit(struct urtw_softc *sc, int16_t bit)
2246 urtw_read8_m(sc, URTW_EPROM_CMD, &data);
2248 urtw_write8_m(sc, URTW_EPROM_CMD, data | URTW_EPROM_WRITEBIT);
2250 urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_WRITEBIT);
2251 DELAY(URTW_EPROM_DELAY);
2257 urtw_eprom_sendbits(struct urtw_softc *sc, int16_t *buf, int buflen)
2260 usb_error_t error = 0;
2262 for (i = 0; i < buflen; i++) {
2263 error = urtw_eprom_writebit(sc, buf[i]);
2266 error = urtw_eprom_ck(sc);
2276 urtw_get_txpwr(struct urtw_softc *sc)
2282 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW_BASE, &data);
2285 sc->sc_txpwr_cck_base = data & 0xf;
2286 sc->sc_txpwr_ofdm_base = (data >> 4) & 0xf;
2288 for (i = 1, j = 0; i < 6; i += 2, j++) {
2289 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW0 + j, &data);
2292 sc->sc_txpwr_cck[i] = data & 0xf;
2293 sc->sc_txpwr_cck[i + 1] = (data & 0xf00) >> 8;
2294 sc->sc_txpwr_ofdm[i] = (data & 0xf0) >> 4;
2295 sc->sc_txpwr_ofdm[i + 1] = (data & 0xf000) >> 12;
2297 for (i = 1, j = 0; i < 4; i += 2, j++) {
2298 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW1 + j, &data);
2301 sc->sc_txpwr_cck[i + 6] = data & 0xf;
2302 sc->sc_txpwr_cck[i + 6 + 1] = (data & 0xf00) >> 8;
2303 sc->sc_txpwr_ofdm[i + 6] = (data & 0xf0) >> 4;
2304 sc->sc_txpwr_ofdm[i + 6 + 1] = (data & 0xf000) >> 12;
2306 if (sc->sc_flags & URTW_RTL8187B) {
2307 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW2, &data);
2310 sc->sc_txpwr_cck[1 + 6 + 4] = data & 0xf;
2311 sc->sc_txpwr_ofdm[1 + 6 + 4] = (data & 0xf0) >> 4;
2312 error = urtw_eprom_read32(sc, 0x0a, &data);
2315 sc->sc_txpwr_cck[2 + 6 + 4] = data & 0xf;
2316 sc->sc_txpwr_ofdm[2 + 6 + 4] = (data & 0xf0) >> 4;
2317 error = urtw_eprom_read32(sc, 0x1c, &data);
2320 sc->sc_txpwr_cck[3 + 6 + 4] = data & 0xf;
2321 sc->sc_txpwr_cck[3 + 6 + 4 + 1] = (data & 0xf00) >> 8;
2322 sc->sc_txpwr_ofdm[3 + 6 + 4] = (data & 0xf0) >> 4;
2323 sc->sc_txpwr_ofdm[3 + 6 + 4 + 1] = (data & 0xf000) >> 12;
2325 for (i = 1, j = 0; i < 4; i += 2, j++) {
2326 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW2 + j,
2330 sc->sc_txpwr_cck[i + 6 + 4] = data & 0xf;
2331 sc->sc_txpwr_cck[i + 6 + 4 + 1] = (data & 0xf00) >> 8;
2332 sc->sc_txpwr_ofdm[i + 6 + 4] = (data & 0xf0) >> 4;
2333 sc->sc_txpwr_ofdm[i + 6 + 4 + 1] = (data & 0xf000) >> 12;
2342 urtw_get_rfchip(struct urtw_softc *sc)
2349 if (sc->sc_flags & URTW_RTL8187B) {
2350 urtw_read8_m(sc, 0xe1, &data8);
2353 sc->sc_flags |= URTW_RTL8187B_REV_B;
2356 sc->sc_flags |= URTW_RTL8187B_REV_D;
2359 sc->sc_flags |= URTW_RTL8187B_REV_E;
2362 device_printf(sc->sc_dev, "unknown type: %#x\n", data8);
2363 sc->sc_flags |= URTW_RTL8187B_REV_B;
2367 urtw_read32_m(sc, URTW_TX_CONF, &data);
2368 switch (data & URTW_TX_HWMASK) {
2369 case URTW_TX_R8187vD_B:
2370 sc->sc_flags |= URTW_RTL8187B;
2372 case URTW_TX_R8187vD:
2375 device_printf(sc->sc_dev, "unknown RTL8187L type: %#x\n",
2376 data & URTW_TX_HWMASK);
2381 error = urtw_eprom_read32(sc, URTW_EPROM_RFCHIPID, &data);
2384 switch (data & 0xff) {
2385 case URTW_EPROM_RFCHIPID_RTL8225U:
2386 error = urtw_8225_isv2(sc, &ret);
2390 sc->sc_rf_init = urtw_8225_rf_init;
2391 sc->sc_rf_set_sens = urtw_8225_rf_set_sens;
2392 sc->sc_rf_set_chan = urtw_8225_rf_set_chan;
2393 sc->sc_rf_stop = urtw_8225_rf_stop;
2395 sc->sc_rf_init = urtw_8225v2_rf_init;
2396 sc->sc_rf_set_chan = urtw_8225v2_rf_set_chan;
2397 sc->sc_rf_stop = urtw_8225_rf_stop;
2399 sc->sc_max_sens = URTW_8225_RF_MAX_SENS;
2400 sc->sc_sens = URTW_8225_RF_DEF_SENS;
2402 case URTW_EPROM_RFCHIPID_RTL8225Z2:
2403 sc->sc_rf_init = urtw_8225v2b_rf_init;
2404 sc->sc_rf_set_chan = urtw_8225v2b_rf_set_chan;
2405 sc->sc_max_sens = URTW_8225_RF_MAX_SENS;
2406 sc->sc_sens = URTW_8225_RF_DEF_SENS;
2407 sc->sc_rf_stop = urtw_8225_rf_stop;
2410 DPRINTF(sc, URTW_DEBUG_STATE,
2411 "unsupported RF chip %d\n", data & 0xff);
2412 error = USB_ERR_INVAL;
2416 device_printf(sc->sc_dev, "%s rf %s hwrev %s\n",
2417 (sc->sc_flags & URTW_RTL8187B) ? "rtl8187b" : "rtl8187l",
2418 ((data & 0xff) == URTW_EPROM_RFCHIPID_RTL8225U) ? "rtl8225u" :
2420 (sc->sc_flags & URTW_RTL8187B) ? ((data8 == 0) ? "b" :
2421 (data8 == 1) ? "d" : "e") : "none");
2429 urtw_led_init(struct urtw_softc *sc)
2434 urtw_read8_m(sc, URTW_PSR, &sc->sc_psr);
2435 error = urtw_eprom_read32(sc, URTW_EPROM_SWREV, &rev);
2439 switch (rev & URTW_EPROM_CID_MASK) {
2440 case URTW_EPROM_CID_ALPHA0:
2441 sc->sc_strategy = URTW_SW_LED_MODE1;
2443 case URTW_EPROM_CID_SERCOMM_PS:
2444 sc->sc_strategy = URTW_SW_LED_MODE3;
2446 case URTW_EPROM_CID_HW_LED:
2447 sc->sc_strategy = URTW_HW_LED;
2449 case URTW_EPROM_CID_RSVD0:
2450 case URTW_EPROM_CID_RSVD1:
2452 sc->sc_strategy = URTW_SW_LED_MODE0;
2456 sc->sc_gpio_ledpin = URTW_LED_PIN_GPIO0;
2464 urtw_8225_rf_init(struct urtw_softc *sc)
2470 error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
2474 error = urtw_8225_usb_init(sc);
2478 urtw_write32_m(sc, URTW_RF_TIMING, 0x000a8008);
2479 urtw_read16_m(sc, URTW_BRSR, &data); /* XXX ??? */
2480 urtw_write16_m(sc, URTW_BRSR, 0xffff);
2481 urtw_write32_m(sc, URTW_RF_PARA, 0x100044);
2483 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
2486 urtw_write8_m(sc, URTW_CONFIG3, 0x44);
2487 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
2491 error = urtw_8185_rf_pins_enable(sc);
2494 usb_pause_mtx(&sc->sc_mtx, 1000);
2496 for (i = 0; i < nitems(urtw_8225_rf_part1); i++) {
2497 urtw_8225_write(sc, urtw_8225_rf_part1[i].reg,
2498 urtw_8225_rf_part1[i].val);
2499 usb_pause_mtx(&sc->sc_mtx, 1);
2501 usb_pause_mtx(&sc->sc_mtx, 100);
2503 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC1);
2504 usb_pause_mtx(&sc->sc_mtx, 200);
2506 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC2);
2507 usb_pause_mtx(&sc->sc_mtx, 200);
2509 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC3);
2511 for (i = 0; i < 95; i++) {
2512 urtw_8225_write(sc, URTW_8225_ADDR_1_MAGIC, (uint8_t)(i + 1));
2513 urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC, urtw_8225_rxgain[i]);
2517 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC4);
2519 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC5);
2521 for (i = 0; i < 128; i++) {
2522 urtw_8187_write_phy_ofdm(sc, 0xb, urtw_8225_agc[i]);
2523 usb_pause_mtx(&sc->sc_mtx, 1);
2524 urtw_8187_write_phy_ofdm(sc, 0xa, (uint8_t)i + 0x80);
2525 usb_pause_mtx(&sc->sc_mtx, 1);
2528 for (i = 0; i < nitems(urtw_8225_rf_part2); i++) {
2529 urtw_8187_write_phy_ofdm(sc, urtw_8225_rf_part2[i].reg,
2530 urtw_8225_rf_part2[i].val);
2531 usb_pause_mtx(&sc->sc_mtx, 1);
2534 error = urtw_8225_setgain(sc, 4);
2538 for (i = 0; i < nitems(urtw_8225_rf_part3); i++) {
2539 urtw_8187_write_phy_cck(sc, urtw_8225_rf_part3[i].reg,
2540 urtw_8225_rf_part3[i].val);
2541 usb_pause_mtx(&sc->sc_mtx, 1);
2544 urtw_write8_m(sc, URTW_TESTR, 0x0d);
2546 error = urtw_8225_set_txpwrlvl(sc, 1);
2550 urtw_8187_write_phy_cck(sc, 0x10, 0x9b);
2551 usb_pause_mtx(&sc->sc_mtx, 1);
2552 urtw_8187_write_phy_ofdm(sc, 0x26, 0x90);
2553 usb_pause_mtx(&sc->sc_mtx, 1);
2555 /* TX ant A, 0x0 for B */
2556 error = urtw_8185_tx_antenna(sc, 0x3);
2559 urtw_write32_m(sc, URTW_HSSI_PARA, 0x3dc00002);
2561 error = urtw_8225_rf_set_chan(sc, 1);
2567 urtw_8185_rf_pins_enable(struct urtw_softc *sc)
2569 usb_error_t error = 0;
2571 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x1ff7);
2577 urtw_8185_tx_antenna(struct urtw_softc *sc, uint8_t ant)
2581 urtw_write8_m(sc, URTW_TX_ANTENNA, ant);
2582 usb_pause_mtx(&sc->sc_mtx, 1);
2588 urtw_8187_write_phy_ofdm_c(struct urtw_softc *sc, uint8_t addr, uint32_t data)
2592 return urtw_8187_write_phy(sc, addr, data);
2596 urtw_8187_write_phy_cck_c(struct urtw_softc *sc, uint8_t addr, uint32_t data)
2600 return urtw_8187_write_phy(sc, addr, data | 0x10000);
2604 urtw_8187_write_phy(struct urtw_softc *sc, uint8_t addr, uint32_t data)
2609 phyw = ((data << 8) | (addr | 0x80));
2610 urtw_write8_m(sc, URTW_PHY_MAGIC4, ((phyw & 0xff000000) >> 24));
2611 urtw_write8_m(sc, URTW_PHY_MAGIC3, ((phyw & 0x00ff0000) >> 16));
2612 urtw_write8_m(sc, URTW_PHY_MAGIC2, ((phyw & 0x0000ff00) >> 8));
2613 urtw_write8_m(sc, URTW_PHY_MAGIC1, ((phyw & 0x000000ff)));
2614 usb_pause_mtx(&sc->sc_mtx, 1);
2620 urtw_8225_setgain(struct urtw_softc *sc, int16_t gain)
2624 urtw_8187_write_phy_ofdm(sc, 0x0d, urtw_8225_gain[gain * 4]);
2625 urtw_8187_write_phy_ofdm(sc, 0x1b, urtw_8225_gain[gain * 4 + 2]);
2626 urtw_8187_write_phy_ofdm(sc, 0x1d, urtw_8225_gain[gain * 4 + 3]);
2627 urtw_8187_write_phy_ofdm(sc, 0x23, urtw_8225_gain[gain * 4 + 1]);
2633 urtw_8225_usb_init(struct urtw_softc *sc)
2638 urtw_write8_m(sc, URTW_RF_PINS_SELECT + 1, 0);
2639 urtw_write8_m(sc, URTW_GPIO, 0);
2640 error = urtw_read8e(sc, 0x53, &data);
2643 error = urtw_write8e(sc, 0x53, data | (1 << 7));
2646 urtw_write8_m(sc, URTW_RF_PINS_SELECT + 1, 4);
2647 urtw_write8_m(sc, URTW_GPIO, 0x20);
2648 urtw_write8_m(sc, URTW_GP_ENABLE, 0);
2650 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, 0x80);
2651 urtw_write16_m(sc, URTW_RF_PINS_SELECT, 0x80);
2652 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x80);
2654 usb_pause_mtx(&sc->sc_mtx, 500);
2660 urtw_8225_write_c(struct urtw_softc *sc, uint8_t addr, uint16_t data)
2662 uint16_t d80, d82, d84;
2665 urtw_read16_m(sc, URTW_RF_PINS_OUTPUT, &d80);
2666 d80 &= URTW_RF_PINS_MAGIC1;
2667 urtw_read16_m(sc, URTW_RF_PINS_ENABLE, &d82);
2668 urtw_read16_m(sc, URTW_RF_PINS_SELECT, &d84);
2669 d84 &= URTW_RF_PINS_MAGIC2;
2670 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, d82 | URTW_RF_PINS_MAGIC3);
2671 urtw_write16_m(sc, URTW_RF_PINS_SELECT, d84 | URTW_RF_PINS_MAGIC3);
2674 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80 | URTW_BB_HOST_BANG_EN);
2676 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80);
2679 error = urtw_8225_write_s16(sc, addr, 0x8225, &data);
2683 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80 | URTW_BB_HOST_BANG_EN);
2685 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80 | URTW_BB_HOST_BANG_EN);
2686 urtw_write16_m(sc, URTW_RF_PINS_SELECT, d84);
2687 usb_pause_mtx(&sc->sc_mtx, 2);
2693 urtw_8225_write_s16(struct urtw_softc *sc, uint8_t addr, int index,
2698 struct usb_device_request req;
2699 usb_error_t error = 0;
2703 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
2704 req.bRequest = URTW_8187_SETREGS_REQ;
2705 USETW(req.wValue, addr);
2706 USETW(req.wIndex, index);
2707 USETW(req.wLength, sizeof(uint16_t));
2708 buf[0] = (data16 & 0x00ff);
2709 buf[1] = (data16 & 0xff00) >> 8;
2711 error = urtw_do_request(sc, &req, buf);
2717 urtw_8225_rf_set_chan(struct urtw_softc *sc, int chan)
2721 error = urtw_8225_set_txpwrlvl(sc, chan);
2724 urtw_8225_write(sc, URTW_8225_ADDR_7_MAGIC, urtw_8225_channel[chan]);
2725 usb_pause_mtx(&sc->sc_mtx, 10);
2731 urtw_8225_rf_set_sens(struct urtw_softc *sc, int sens)
2735 if (sens < 0 || sens > 6)
2740 URTW_8225_ADDR_C_MAGIC, URTW_8225_ADDR_C_DATA_MAGIC1);
2743 URTW_8225_ADDR_C_MAGIC, URTW_8225_ADDR_C_DATA_MAGIC2);
2746 error = urtw_8225_setgain(sc, sens);
2750 urtw_8187_write_phy_cck(sc, 0x41, urtw_8225_threshold[sens]);
2757 urtw_8225_set_txpwrlvl(struct urtw_softc *sc, int chan)
2760 uint8_t *cck_pwltable;
2761 uint8_t cck_pwrlvl_max, ofdm_pwrlvl_min, ofdm_pwrlvl_max;
2762 uint8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
2763 uint8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
2766 cck_pwrlvl_max = 11;
2767 ofdm_pwrlvl_max = 25; /* 12 -> 25 */
2768 ofdm_pwrlvl_min = 10;
2770 /* CCK power setting */
2771 cck_pwrlvl = (cck_pwrlvl > cck_pwrlvl_max) ? cck_pwrlvl_max : cck_pwrlvl;
2772 idx = cck_pwrlvl % 6;
2773 set = cck_pwrlvl / 6;
2774 cck_pwltable = (chan == 14) ? urtw_8225_txpwr_cck_ch14 :
2775 urtw_8225_txpwr_cck;
2777 urtw_write8_m(sc, URTW_TX_GAIN_CCK,
2778 urtw_8225_tx_gain_cck_ofdm[set] >> 1);
2779 for (i = 0; i < 8; i++) {
2780 urtw_8187_write_phy_cck(sc, 0x44 + i,
2781 cck_pwltable[idx * 8 + i]);
2783 usb_pause_mtx(&sc->sc_mtx, 1);
2785 /* OFDM power setting */
2786 ofdm_pwrlvl = (ofdm_pwrlvl > (ofdm_pwrlvl_max - ofdm_pwrlvl_min)) ?
2787 ofdm_pwrlvl_max : ofdm_pwrlvl + ofdm_pwrlvl_min;
2788 ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
2790 idx = ofdm_pwrlvl % 6;
2791 set = ofdm_pwrlvl / 6;
2793 error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
2796 urtw_8187_write_phy_ofdm(sc, 2, 0x42);
2797 urtw_8187_write_phy_ofdm(sc, 6, 0);
2798 urtw_8187_write_phy_ofdm(sc, 8, 0);
2800 urtw_write8_m(sc, URTW_TX_GAIN_OFDM,
2801 urtw_8225_tx_gain_cck_ofdm[set] >> 1);
2802 urtw_8187_write_phy_ofdm(sc, 0x5, urtw_8225_txpwr_ofdm[idx]);
2803 urtw_8187_write_phy_ofdm(sc, 0x7, urtw_8225_txpwr_ofdm[idx]);
2804 usb_pause_mtx(&sc->sc_mtx, 1);
2811 urtw_8225_rf_stop(struct urtw_softc *sc)
2816 urtw_8225_write(sc, 0x4, 0x1f);
2818 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
2822 urtw_read8_m(sc, URTW_CONFIG3, &data);
2823 urtw_write8_m(sc, URTW_CONFIG3, data | URTW_CONFIG3_ANAPARAM_WRITE);
2824 if (sc->sc_flags & URTW_RTL8187B) {
2825 urtw_write32_m(sc, URTW_ANAPARAM2,
2826 URTW_8187B_8225_ANAPARAM2_OFF);
2827 urtw_write32_m(sc, URTW_ANAPARAM, URTW_8187B_8225_ANAPARAM_OFF);
2828 urtw_write32_m(sc, URTW_ANAPARAM3,
2829 URTW_8187B_8225_ANAPARAM3_OFF);
2831 urtw_write32_m(sc, URTW_ANAPARAM2, URTW_8225_ANAPARAM2_OFF);
2832 urtw_write32_m(sc, URTW_ANAPARAM, URTW_8225_ANAPARAM_OFF);
2835 urtw_write8_m(sc, URTW_CONFIG3, data & ~URTW_CONFIG3_ANAPARAM_WRITE);
2836 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
2845 urtw_8225v2_rf_init(struct urtw_softc *sc)
2852 error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
2856 error = urtw_8225_usb_init(sc);
2860 urtw_write32_m(sc, URTW_RF_TIMING, 0x000a8008);
2861 urtw_read16_m(sc, URTW_BRSR, &data); /* XXX ??? */
2862 urtw_write16_m(sc, URTW_BRSR, 0xffff);
2863 urtw_write32_m(sc, URTW_RF_PARA, 0x100044);
2865 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
2868 urtw_write8_m(sc, URTW_CONFIG3, 0x44);
2869 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
2873 error = urtw_8185_rf_pins_enable(sc);
2877 usb_pause_mtx(&sc->sc_mtx, 500);
2879 for (i = 0; i < nitems(urtw_8225v2_rf_part1); i++) {
2880 urtw_8225_write(sc, urtw_8225v2_rf_part1[i].reg,
2881 urtw_8225v2_rf_part1[i].val);
2883 usb_pause_mtx(&sc->sc_mtx, 50);
2886 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC1);
2888 for (i = 0; i < 95; i++) {
2889 urtw_8225_write(sc, URTW_8225_ADDR_1_MAGIC, (uint8_t)(i + 1));
2890 urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC,
2891 urtw_8225v2_rxgain[i]);
2895 URTW_8225_ADDR_3_MAGIC, URTW_8225_ADDR_3_DATA_MAGIC1);
2897 URTW_8225_ADDR_5_MAGIC, URTW_8225_ADDR_5_DATA_MAGIC1);
2899 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC2);
2901 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC1);
2902 usb_pause_mtx(&sc->sc_mtx, 100);
2904 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC2);
2905 usb_pause_mtx(&sc->sc_mtx, 100);
2907 error = urtw_8225_read(sc, URTW_8225_ADDR_6_MAGIC, &data32);
2910 if (data32 != URTW_8225_ADDR_6_DATA_MAGIC1)
2911 device_printf(sc->sc_dev, "expect 0xe6!! (0x%x)\n", data32);
2912 if (!(data32 & URTW_8225_ADDR_6_DATA_MAGIC2)) {
2914 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC1);
2915 usb_pause_mtx(&sc->sc_mtx, 100);
2917 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC2);
2918 usb_pause_mtx(&sc->sc_mtx, 50);
2919 error = urtw_8225_read(sc, URTW_8225_ADDR_6_MAGIC, &data32);
2922 if (!(data32 & URTW_8225_ADDR_6_DATA_MAGIC2))
2923 device_printf(sc->sc_dev, "RF calibration failed\n");
2925 usb_pause_mtx(&sc->sc_mtx, 100);
2928 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC6);
2929 for (i = 0; i < 128; i++) {
2930 urtw_8187_write_phy_ofdm(sc, 0xb, urtw_8225_agc[i]);
2931 urtw_8187_write_phy_ofdm(sc, 0xa, (uint8_t)i + 0x80);
2934 for (i = 0; i < nitems(urtw_8225v2_rf_part2); i++) {
2935 urtw_8187_write_phy_ofdm(sc, urtw_8225v2_rf_part2[i].reg,
2936 urtw_8225v2_rf_part2[i].val);
2939 error = urtw_8225v2_setgain(sc, 4);
2943 for (i = 0; i < nitems(urtw_8225v2_rf_part3); i++) {
2944 urtw_8187_write_phy_cck(sc, urtw_8225v2_rf_part3[i].reg,
2945 urtw_8225v2_rf_part3[i].val);
2948 urtw_write8_m(sc, URTW_TESTR, 0x0d);
2950 error = urtw_8225v2_set_txpwrlvl(sc, 1);
2954 urtw_8187_write_phy_cck(sc, 0x10, 0x9b);
2955 urtw_8187_write_phy_ofdm(sc, 0x26, 0x90);
2957 /* TX ant A, 0x0 for B */
2958 error = urtw_8185_tx_antenna(sc, 0x3);
2961 urtw_write32_m(sc, URTW_HSSI_PARA, 0x3dc00002);
2963 error = urtw_8225_rf_set_chan(sc, 1);
2969 urtw_8225v2_rf_set_chan(struct urtw_softc *sc, int chan)
2973 error = urtw_8225v2_set_txpwrlvl(sc, chan);
2977 urtw_8225_write(sc, URTW_8225_ADDR_7_MAGIC, urtw_8225_channel[chan]);
2978 usb_pause_mtx(&sc->sc_mtx, 10);
2984 urtw_8225_read(struct urtw_softc *sc, uint8_t addr, uint32_t *data)
2988 uint8_t rlen = 12, wlen = 6;
2989 uint16_t o1, o2, o3, tmp;
2990 uint32_t d2w = ((uint32_t)(addr & 0x1f)) << 27;
2991 uint32_t mask = 0x80000000, value = 0;
2994 urtw_read16_m(sc, URTW_RF_PINS_OUTPUT, &o1);
2995 urtw_read16_m(sc, URTW_RF_PINS_ENABLE, &o2);
2996 urtw_read16_m(sc, URTW_RF_PINS_SELECT, &o3);
2997 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, o2 | URTW_RF_PINS_MAGIC4);
2998 urtw_write16_m(sc, URTW_RF_PINS_SELECT, o3 | URTW_RF_PINS_MAGIC4);
2999 o1 &= ~URTW_RF_PINS_MAGIC4;
3000 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1 | URTW_BB_HOST_BANG_EN);
3002 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1);
3005 for (i = 0; i < (wlen / 2); i++, mask = mask >> 1) {
3006 bit = ((d2w & mask) != 0) ? 1 : 0;
3008 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1);
3010 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
3011 URTW_BB_HOST_BANG_CLK);
3013 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
3014 URTW_BB_HOST_BANG_CLK);
3019 bit = ((d2w & mask) != 0) ? 1 : 0;
3020 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
3021 URTW_BB_HOST_BANG_CLK);
3023 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
3024 URTW_BB_HOST_BANG_CLK);
3026 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1);
3029 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 | URTW_BB_HOST_BANG_RW |
3030 URTW_BB_HOST_BANG_CLK);
3032 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 | URTW_BB_HOST_BANG_RW);
3034 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1 | URTW_BB_HOST_BANG_RW);
3038 for (i = 0; i < rlen; i++, mask = mask >> 1) {
3039 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
3040 o1 | URTW_BB_HOST_BANG_RW);
3042 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
3043 o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK);
3045 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
3046 o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK);
3048 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
3049 o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK);
3052 urtw_read16_m(sc, URTW_RF_PINS_INPUT, &tmp);
3053 value |= ((tmp & URTW_BB_HOST_BANG_CLK) ? mask : 0);
3054 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
3055 o1 | URTW_BB_HOST_BANG_RW);
3059 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1 | URTW_BB_HOST_BANG_EN |
3060 URTW_BB_HOST_BANG_RW);
3063 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, o2);
3064 urtw_write16_m(sc, URTW_RF_PINS_SELECT, o3);
3065 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, URTW_RF_PINS_OUTPUT_MAGIC1);
3075 urtw_8225v2_set_txpwrlvl(struct urtw_softc *sc, int chan)
3078 uint8_t *cck_pwrtable;
3079 uint8_t cck_pwrlvl_max = 15, ofdm_pwrlvl_max = 25, ofdm_pwrlvl_min = 10;
3080 uint8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
3081 uint8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
3084 /* CCK power setting */
3085 cck_pwrlvl = (cck_pwrlvl > cck_pwrlvl_max) ? cck_pwrlvl_max : cck_pwrlvl;
3086 cck_pwrlvl += sc->sc_txpwr_cck_base;
3087 cck_pwrlvl = (cck_pwrlvl > 35) ? 35 : cck_pwrlvl;
3088 cck_pwrtable = (chan == 14) ? urtw_8225v2_txpwr_cck_ch14 :
3089 urtw_8225v2_txpwr_cck;
3091 for (i = 0; i < 8; i++)
3092 urtw_8187_write_phy_cck(sc, 0x44 + i, cck_pwrtable[i]);
3094 urtw_write8_m(sc, URTW_TX_GAIN_CCK,
3095 urtw_8225v2_tx_gain_cck_ofdm[cck_pwrlvl]);
3096 usb_pause_mtx(&sc->sc_mtx, 1);
3098 /* OFDM power setting */
3099 ofdm_pwrlvl = (ofdm_pwrlvl > (ofdm_pwrlvl_max - ofdm_pwrlvl_min)) ?
3100 ofdm_pwrlvl_max : ofdm_pwrlvl + ofdm_pwrlvl_min;
3101 ofdm_pwrlvl += sc->sc_txpwr_ofdm_base;
3102 ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
3104 error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
3108 urtw_8187_write_phy_ofdm(sc, 2, 0x42);
3109 urtw_8187_write_phy_ofdm(sc, 5, 0x0);
3110 urtw_8187_write_phy_ofdm(sc, 6, 0x40);
3111 urtw_8187_write_phy_ofdm(sc, 7, 0x0);
3112 urtw_8187_write_phy_ofdm(sc, 8, 0x40);
3114 urtw_write8_m(sc, URTW_TX_GAIN_OFDM,
3115 urtw_8225v2_tx_gain_cck_ofdm[ofdm_pwrlvl]);
3116 usb_pause_mtx(&sc->sc_mtx, 1);
3122 urtw_8225v2_setgain(struct urtw_softc *sc, int16_t gain)
3128 gainp = urtw_8225v2_gain_bg;
3129 urtw_8187_write_phy_ofdm(sc, 0x0d, gainp[gain * 3]);
3130 usb_pause_mtx(&sc->sc_mtx, 1);
3131 urtw_8187_write_phy_ofdm(sc, 0x1b, gainp[gain * 3 + 1]);
3132 usb_pause_mtx(&sc->sc_mtx, 1);
3133 urtw_8187_write_phy_ofdm(sc, 0x1d, gainp[gain * 3 + 2]);
3134 usb_pause_mtx(&sc->sc_mtx, 1);
3135 urtw_8187_write_phy_ofdm(sc, 0x21, 0x17);
3136 usb_pause_mtx(&sc->sc_mtx, 1);
3142 urtw_8225_isv2(struct urtw_softc *sc, int *ret)
3149 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, URTW_RF_PINS_MAGIC5);
3150 urtw_write16_m(sc, URTW_RF_PINS_SELECT, URTW_RF_PINS_MAGIC5);
3151 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, URTW_RF_PINS_MAGIC5);
3152 usb_pause_mtx(&sc->sc_mtx, 500);
3154 urtw_8225_write(sc, URTW_8225_ADDR_0_MAGIC,
3155 URTW_8225_ADDR_0_DATA_MAGIC1);
3157 error = urtw_8225_read(sc, URTW_8225_ADDR_8_MAGIC, &data);
3160 if (data != URTW_8225_ADDR_8_DATA_MAGIC1)
3163 error = urtw_8225_read(sc, URTW_8225_ADDR_9_MAGIC, &data);
3166 if (data != URTW_8225_ADDR_9_DATA_MAGIC1)
3170 urtw_8225_write(sc, URTW_8225_ADDR_0_MAGIC,
3171 URTW_8225_ADDR_0_DATA_MAGIC2);
3177 urtw_8225v2b_rf_init(struct urtw_softc *sc)
3179 struct ieee80211com *ic = &sc->sc_ic;
3184 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3189 * initialize extra registers on 8187
3191 urtw_write16_m(sc, URTW_BRSR_8187B, 0xfff);
3194 urtw_read8_m(sc, URTW_CW_CONF, &data8);
3195 data8 |= URTW_CW_CONF_PERPACKET_RETRY;
3196 urtw_write8_m(sc, URTW_CW_CONF, data8);
3199 urtw_read8_m(sc, URTW_TX_AGC_CTL, &data8);
3200 data8 |= URTW_TX_AGC_CTL_PERPACKET_GAIN;
3201 urtw_write8_m(sc, URTW_TX_AGC_CTL, data8);
3203 /* Auto Rate Fallback Control */
3204 #define URTW_ARFR 0x1e0
3205 urtw_write16_m(sc, URTW_ARFR, 0xfff);
3206 urtw_read8_m(sc, URTW_RATE_FALLBACK, &data8);
3207 urtw_write8_m(sc, URTW_RATE_FALLBACK,
3208 data8 | URTW_RATE_FALLBACK_ENABLE);
3210 urtw_read8_m(sc, URTW_MSR, &data8);
3211 urtw_write8_m(sc, URTW_MSR, data8 & 0xf3);
3212 urtw_read8_m(sc, URTW_MSR, &data8);
3213 urtw_write8_m(sc, URTW_MSR, data8 | URTW_MSR_LINK_ENEDCA);
3214 urtw_write8_m(sc, URTW_ACM_CONTROL, sc->sc_acmctl);
3216 urtw_write16_m(sc, URTW_ATIM_WND, 2);
3217 urtw_write16_m(sc, URTW_BEACON_INTERVAL, 100);
3218 #define URTW_FEMR_FOR_8187B 0x1d4
3219 urtw_write16_m(sc, URTW_FEMR_FOR_8187B, 0xffff);
3222 urtw_read8_m(sc, URTW_CONFIG1, &data8);
3223 data8 = (data8 & 0x3f) | 0x80;
3224 urtw_write8_m(sc, URTW_CONFIG1, data8);
3226 /* applying MAC address again. */
3227 urtw_write32_m(sc, URTW_MAC0, ((uint32_t *)ic->ic_macaddr)[0]);
3228 urtw_write16_m(sc, URTW_MAC4, ((uint32_t *)ic->ic_macaddr)[1] & 0xffff);
3230 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3234 urtw_write8_m(sc, URTW_WPA_CONFIG, 0);
3239 for (i = 0; i < nitems(urtw_8225v2b_rf_part1); i++)
3240 urtw_write8_m(sc, urtw_8225v2b_rf_part1[i].reg,
3241 urtw_8225v2b_rf_part1[i].val);
3242 urtw_write16_m(sc, URTW_TID_AC_MAP, 0xfa50);
3243 urtw_write16_m(sc, URTW_INT_MIG, 0x0000);
3244 urtw_write32_m(sc, 0x1f0, 0);
3245 urtw_write32_m(sc, 0x1f4, 0);
3246 urtw_write8_m(sc, 0x1f8, 0);
3247 urtw_write32_m(sc, URTW_RF_TIMING, 0x4001);
3249 #define URTW_RFSW_CTRL 0x272
3250 urtw_write16_m(sc, URTW_RFSW_CTRL, 0x569a);
3255 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3258 urtw_read8_m(sc, URTW_CONFIG3, &data8);
3259 urtw_write8_m(sc, URTW_CONFIG3,
3260 data8 | URTW_CONFIG3_ANAPARAM_WRITE);
3262 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3266 /* setup RFE initial timing */
3267 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, 0x0480);
3268 urtw_write16_m(sc, URTW_RF_PINS_SELECT, 0x2488);
3269 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x1fff);
3270 usb_pause_mtx(&sc->sc_mtx, 1100);
3272 for (i = 0; i < nitems(urtw_8225v2b_rf_part0); i++) {
3273 urtw_8225_write(sc, urtw_8225v2b_rf_part0[i].reg,
3274 urtw_8225v2b_rf_part0[i].val);
3275 usb_pause_mtx(&sc->sc_mtx, 1);
3277 urtw_8225_write(sc, 0x00, 0x01b7);
3279 for (i = 0; i < 95; i++) {
3280 urtw_8225_write(sc, URTW_8225_ADDR_1_MAGIC, (uint8_t)(i + 1));
3281 usb_pause_mtx(&sc->sc_mtx, 1);
3282 urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC,
3283 urtw_8225v2b_rxgain[i]);
3284 usb_pause_mtx(&sc->sc_mtx, 1);
3287 urtw_8225_write(sc, URTW_8225_ADDR_3_MAGIC, 0x080);
3288 usb_pause_mtx(&sc->sc_mtx, 1);
3289 urtw_8225_write(sc, URTW_8225_ADDR_5_MAGIC, 0x004);
3290 usb_pause_mtx(&sc->sc_mtx, 1);
3291 urtw_8225_write(sc, URTW_8225_ADDR_0_MAGIC, 0x0b7);
3292 usb_pause_mtx(&sc->sc_mtx, 1);
3293 usb_pause_mtx(&sc->sc_mtx, 3000);
3294 urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC, 0xc4d);
3295 usb_pause_mtx(&sc->sc_mtx, 2000);
3296 urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC, 0x44d);
3297 usb_pause_mtx(&sc->sc_mtx, 1);
3298 urtw_8225_write(sc, URTW_8225_ADDR_0_MAGIC, 0x2bf);
3299 usb_pause_mtx(&sc->sc_mtx, 1);
3301 urtw_write8_m(sc, URTW_TX_GAIN_CCK, 0x03);
3302 urtw_write8_m(sc, URTW_TX_GAIN_OFDM, 0x07);
3303 urtw_write8_m(sc, URTW_TX_ANTENNA, 0x03);
3305 urtw_8187_write_phy_ofdm(sc, 0x80, 0x12);
3306 for (i = 0; i < 128; i++) {
3307 uint32_t addr, data;
3309 data = (urtw_8225z2_agc[i] << 8) | 0x0000008f;
3310 addr = ((i + 0x80) << 8) | 0x0000008e;
3312 urtw_8187_write_phy_ofdm(sc, data & 0x7f, (data >> 8) & 0xff);
3313 urtw_8187_write_phy_ofdm(sc, addr & 0x7f, (addr >> 8) & 0xff);
3314 urtw_8187_write_phy_ofdm(sc, 0x0e, 0x00);
3316 urtw_8187_write_phy_ofdm(sc, 0x80, 0x10);
3318 for (i = 0; i < nitems(urtw_8225v2b_rf_part2); i++)
3319 urtw_8187_write_phy_ofdm(sc, i, urtw_8225v2b_rf_part2[i].val);
3321 urtw_write32_m(sc, URTW_8187B_AC_VO, (7 << 12) | (3 << 8) | 0x1c);
3322 urtw_write32_m(sc, URTW_8187B_AC_VI, (7 << 12) | (3 << 8) | 0x1c);
3323 urtw_write32_m(sc, URTW_8187B_AC_BE, (7 << 12) | (3 << 8) | 0x1c);
3324 urtw_write32_m(sc, URTW_8187B_AC_BK, (7 << 12) | (3 << 8) | 0x1c);
3326 urtw_8187_write_phy_ofdm(sc, 0x97, 0x46);
3327 urtw_8187_write_phy_ofdm(sc, 0xa4, 0xb6);
3328 urtw_8187_write_phy_ofdm(sc, 0x85, 0xfc);
3329 urtw_8187_write_phy_cck(sc, 0xc1, 0x88);
3336 urtw_8225v2b_rf_set_chan(struct urtw_softc *sc, int chan)
3340 error = urtw_8225v2b_set_txpwrlvl(sc, chan);
3344 urtw_8225_write(sc, URTW_8225_ADDR_7_MAGIC, urtw_8225_channel[chan]);
3345 usb_pause_mtx(&sc->sc_mtx, 10);
3351 urtw_8225v2b_set_txpwrlvl(struct urtw_softc *sc, int chan)
3354 uint8_t *cck_pwrtable;
3355 uint8_t cck_pwrlvl_max = 15;
3356 uint8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
3357 uint8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
3360 /* CCK power setting */
3361 cck_pwrlvl = (cck_pwrlvl > cck_pwrlvl_max) ?
3362 ((sc->sc_flags & URTW_RTL8187B_REV_B) ? cck_pwrlvl_max : 22) :
3363 (cck_pwrlvl + ((sc->sc_flags & URTW_RTL8187B_REV_B) ? 0 : 7));
3364 cck_pwrlvl += sc->sc_txpwr_cck_base;
3365 cck_pwrlvl = (cck_pwrlvl > 35) ? 35 : cck_pwrlvl;
3366 cck_pwrtable = (chan == 14) ? urtw_8225v2b_txpwr_cck_ch14 :
3367 urtw_8225v2b_txpwr_cck;
3369 if (sc->sc_flags & URTW_RTL8187B_REV_B)
3370 cck_pwrtable += (cck_pwrlvl <= 6) ? 0 :
3371 ((cck_pwrlvl <= 11) ? 8 : 16);
3373 cck_pwrtable += (cck_pwrlvl <= 5) ? 0 :
3374 ((cck_pwrlvl <= 11) ? 8 : ((cck_pwrlvl <= 17) ? 16 : 24));
3376 for (i = 0; i < 8; i++)
3377 urtw_8187_write_phy_cck(sc, 0x44 + i, cck_pwrtable[i]);
3379 urtw_write8_m(sc, URTW_TX_GAIN_CCK,
3380 urtw_8225v2_tx_gain_cck_ofdm[cck_pwrlvl] << 1);
3381 usb_pause_mtx(&sc->sc_mtx, 1);
3383 /* OFDM power setting */
3384 ofdm_pwrlvl = (ofdm_pwrlvl > 15) ?
3385 ((sc->sc_flags & URTW_RTL8187B_REV_B) ? 17 : 25) :
3386 (ofdm_pwrlvl + ((sc->sc_flags & URTW_RTL8187B_REV_B) ? 2 : 10));
3387 ofdm_pwrlvl += sc->sc_txpwr_ofdm_base;
3388 ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
3390 urtw_write8_m(sc, URTW_TX_GAIN_OFDM,
3391 urtw_8225v2_tx_gain_cck_ofdm[ofdm_pwrlvl] << 1);
3393 if (sc->sc_flags & URTW_RTL8187B_REV_B) {
3394 if (ofdm_pwrlvl <= 11) {
3395 urtw_8187_write_phy_ofdm(sc, 0x87, 0x60);
3396 urtw_8187_write_phy_ofdm(sc, 0x89, 0x60);
3398 urtw_8187_write_phy_ofdm(sc, 0x87, 0x5c);
3399 urtw_8187_write_phy_ofdm(sc, 0x89, 0x5c);
3402 if (ofdm_pwrlvl <= 11) {
3403 urtw_8187_write_phy_ofdm(sc, 0x87, 0x5c);
3404 urtw_8187_write_phy_ofdm(sc, 0x89, 0x5c);
3405 } else if (ofdm_pwrlvl <= 17) {
3406 urtw_8187_write_phy_ofdm(sc, 0x87, 0x54);
3407 urtw_8187_write_phy_ofdm(sc, 0x89, 0x54);
3409 urtw_8187_write_phy_ofdm(sc, 0x87, 0x50);
3410 urtw_8187_write_phy_ofdm(sc, 0x89, 0x50);
3413 usb_pause_mtx(&sc->sc_mtx, 1);
3419 urtw_read8e(struct urtw_softc *sc, int val, uint8_t *data)
3421 struct usb_device_request req;
3424 req.bmRequestType = UT_READ_VENDOR_DEVICE;
3425 req.bRequest = URTW_8187_GETREGS_REQ;
3426 USETW(req.wValue, val | 0xfe00);
3427 USETW(req.wIndex, 0);
3428 USETW(req.wLength, sizeof(uint8_t));
3430 error = urtw_do_request(sc, &req, data);
3435 urtw_write8e(struct urtw_softc *sc, int val, uint8_t data)
3437 struct usb_device_request req;
3439 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
3440 req.bRequest = URTW_8187_SETREGS_REQ;
3441 USETW(req.wValue, val | 0xfe00);
3442 USETW(req.wIndex, 0);
3443 USETW(req.wLength, sizeof(uint8_t));
3445 return (urtw_do_request(sc, &req, &data));
3449 urtw_8180_set_anaparam(struct urtw_softc *sc, uint32_t val)
3454 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3458 urtw_read8_m(sc, URTW_CONFIG3, &data);
3459 urtw_write8_m(sc, URTW_CONFIG3, data | URTW_CONFIG3_ANAPARAM_WRITE);
3460 urtw_write32_m(sc, URTW_ANAPARAM, val);
3461 urtw_read8_m(sc, URTW_CONFIG3, &data);
3462 urtw_write8_m(sc, URTW_CONFIG3, data & ~URTW_CONFIG3_ANAPARAM_WRITE);
3464 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3472 urtw_8185_set_anaparam2(struct urtw_softc *sc, uint32_t val)
3477 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3481 urtw_read8_m(sc, URTW_CONFIG3, &data);
3482 urtw_write8_m(sc, URTW_CONFIG3, data | URTW_CONFIG3_ANAPARAM_WRITE);
3483 urtw_write32_m(sc, URTW_ANAPARAM2, val);
3484 urtw_read8_m(sc, URTW_CONFIG3, &data);
3485 urtw_write8_m(sc, URTW_CONFIG3, data & ~URTW_CONFIG3_ANAPARAM_WRITE);
3487 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3495 urtw_intr_enable(struct urtw_softc *sc)
3499 urtw_write16_m(sc, URTW_INTR_MASK, 0xffff);
3505 urtw_intr_disable(struct urtw_softc *sc)
3509 urtw_write16_m(sc, URTW_INTR_MASK, 0);
3515 urtw_reset(struct urtw_softc *sc)
3520 error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
3523 error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
3527 error = urtw_intr_disable(sc);
3530 usb_pause_mtx(&sc->sc_mtx, 100);
3532 error = urtw_write8e(sc, 0x18, 0x10);
3535 error = urtw_write8e(sc, 0x18, 0x11);
3538 error = urtw_write8e(sc, 0x18, 0x00);
3541 usb_pause_mtx(&sc->sc_mtx, 100);
3543 urtw_read8_m(sc, URTW_CMD, &data);
3544 data = (data & 0x2) | URTW_CMD_RST;
3545 urtw_write8_m(sc, URTW_CMD, data);
3546 usb_pause_mtx(&sc->sc_mtx, 100);
3548 urtw_read8_m(sc, URTW_CMD, &data);
3549 if (data & URTW_CMD_RST) {
3550 device_printf(sc->sc_dev, "reset timeout\n");
3554 error = urtw_set_mode(sc, URTW_EPROM_CMD_LOAD);
3557 usb_pause_mtx(&sc->sc_mtx, 100);
3559 error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
3562 error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
3570 urtw_led_ctl(struct urtw_softc *sc, int mode)
3572 usb_error_t error = 0;
3574 switch (sc->sc_strategy) {
3575 case URTW_SW_LED_MODE0:
3576 error = urtw_led_mode0(sc, mode);
3578 case URTW_SW_LED_MODE1:
3579 error = urtw_led_mode1(sc, mode);
3581 case URTW_SW_LED_MODE2:
3582 error = urtw_led_mode2(sc, mode);
3584 case URTW_SW_LED_MODE3:
3585 error = urtw_led_mode3(sc, mode);
3588 DPRINTF(sc, URTW_DEBUG_STATE,
3589 "unsupported LED mode %d\n", sc->sc_strategy);
3590 error = USB_ERR_INVAL;
3598 urtw_led_mode0(struct urtw_softc *sc, int mode)
3602 case URTW_LED_CTL_POWER_ON:
3603 sc->sc_gpio_ledstate = URTW_LED_POWER_ON_BLINK;
3605 case URTW_LED_CTL_TX:
3606 if (sc->sc_gpio_ledinprogress == 1)
3609 sc->sc_gpio_ledstate = URTW_LED_BLINK_NORMAL;
3610 sc->sc_gpio_blinktime = 2;
3612 case URTW_LED_CTL_LINK:
3613 sc->sc_gpio_ledstate = URTW_LED_ON;
3616 DPRINTF(sc, URTW_DEBUG_STATE,
3617 "unsupported LED mode 0x%x", mode);
3618 return (USB_ERR_INVAL);
3621 switch (sc->sc_gpio_ledstate) {
3623 if (sc->sc_gpio_ledinprogress != 0)
3625 urtw_led_on(sc, URTW_LED_GPIO);
3627 case URTW_LED_BLINK_NORMAL:
3628 if (sc->sc_gpio_ledinprogress != 0)
3630 sc->sc_gpio_ledinprogress = 1;
3631 sc->sc_gpio_blinkstate = (sc->sc_gpio_ledon != 0) ?
3632 URTW_LED_OFF : URTW_LED_ON;
3633 usb_callout_reset(&sc->sc_led_ch, hz, urtw_led_ch, sc);
3635 case URTW_LED_POWER_ON_BLINK:
3636 urtw_led_on(sc, URTW_LED_GPIO);
3637 usb_pause_mtx(&sc->sc_mtx, 100);
3638 urtw_led_off(sc, URTW_LED_GPIO);
3641 DPRINTF(sc, URTW_DEBUG_STATE,
3642 "unknown LED status 0x%x", sc->sc_gpio_ledstate);
3643 return (USB_ERR_INVAL);
3649 urtw_led_mode1(struct urtw_softc *sc, int mode)
3651 return (USB_ERR_INVAL);
3655 urtw_led_mode2(struct urtw_softc *sc, int mode)
3657 return (USB_ERR_INVAL);
3661 urtw_led_mode3(struct urtw_softc *sc, int mode)
3663 return (USB_ERR_INVAL);
3667 urtw_led_on(struct urtw_softc *sc, int type)
3671 if (type == URTW_LED_GPIO) {
3672 switch (sc->sc_gpio_ledpin) {
3673 case URTW_LED_PIN_GPIO0:
3674 urtw_write8_m(sc, URTW_GPIO, 0x01);
3675 urtw_write8_m(sc, URTW_GP_ENABLE, 0x00);
3678 DPRINTF(sc, URTW_DEBUG_STATE,
3679 "unsupported LED PIN type 0x%x",
3680 sc->sc_gpio_ledpin);
3681 error = USB_ERR_INVAL;
3685 DPRINTF(sc, URTW_DEBUG_STATE,
3686 "unsupported LED type 0x%x", type);
3687 error = USB_ERR_INVAL;
3691 sc->sc_gpio_ledon = 1;
3697 urtw_led_off(struct urtw_softc *sc, int type)
3701 if (type == URTW_LED_GPIO) {
3702 switch (sc->sc_gpio_ledpin) {
3703 case URTW_LED_PIN_GPIO0:
3704 urtw_write8_m(sc, URTW_GPIO, URTW_GPIO_DATA_MAGIC1);
3706 URTW_GP_ENABLE, URTW_GP_ENABLE_DATA_MAGIC1);
3709 DPRINTF(sc, URTW_DEBUG_STATE,
3710 "unsupported LED PIN type 0x%x",
3711 sc->sc_gpio_ledpin);
3712 error = USB_ERR_INVAL;
3716 DPRINTF(sc, URTW_DEBUG_STATE,
3717 "unsupported LED type 0x%x", type);
3718 error = USB_ERR_INVAL;
3722 sc->sc_gpio_ledon = 0;
3729 urtw_led_ch(void *arg)
3731 struct urtw_softc *sc = arg;
3732 struct ieee80211com *ic = &sc->sc_ic;
3734 ieee80211_runtask(ic, &sc->sc_led_task);
3738 urtw_ledtask(void *arg, int pending)
3740 struct urtw_softc *sc = arg;
3742 if (sc->sc_strategy != URTW_SW_LED_MODE0) {
3743 DPRINTF(sc, URTW_DEBUG_STATE,
3744 "could not process a LED strategy 0x%x",
3755 urtw_led_blink(struct urtw_softc *sc)
3760 if (sc->sc_gpio_blinkstate == URTW_LED_ON)
3761 error = urtw_led_on(sc, URTW_LED_GPIO);
3763 error = urtw_led_off(sc, URTW_LED_GPIO);
3764 sc->sc_gpio_blinktime--;
3765 if (sc->sc_gpio_blinktime == 0)
3768 if (sc->sc_gpio_ledstate != URTW_LED_BLINK_NORMAL &&
3769 sc->sc_gpio_ledstate != URTW_LED_BLINK_SLOWLY &&
3770 sc->sc_gpio_ledstate != URTW_LED_BLINK_CM3)
3774 if (sc->sc_gpio_ledstate == URTW_LED_ON &&
3775 sc->sc_gpio_ledon == 0)
3776 error = urtw_led_on(sc, URTW_LED_GPIO);
3777 else if (sc->sc_gpio_ledstate == URTW_LED_OFF &&
3778 sc->sc_gpio_ledon == 1)
3779 error = urtw_led_off(sc, URTW_LED_GPIO);
3781 sc->sc_gpio_blinktime = 0;
3782 sc->sc_gpio_ledinprogress = 0;
3786 sc->sc_gpio_blinkstate = (sc->sc_gpio_blinkstate != URTW_LED_ON) ?
3787 URTW_LED_ON : URTW_LED_OFF;
3789 switch (sc->sc_gpio_ledstate) {
3790 case URTW_LED_BLINK_NORMAL:
3791 usb_callout_reset(&sc->sc_led_ch, hz, urtw_led_ch, sc);
3794 DPRINTF(sc, URTW_DEBUG_STATE,
3795 "unknown LED status 0x%x",
3796 sc->sc_gpio_ledstate);
3797 return (USB_ERR_INVAL);
3803 urtw_rx_enable(struct urtw_softc *sc)
3808 usbd_transfer_start((sc->sc_flags & URTW_RTL8187B) ?
3809 sc->sc_xfer[URTW_8187B_BULK_RX] : sc->sc_xfer[URTW_8187L_BULK_RX]);
3811 error = urtw_rx_setconf(sc);
3815 if ((sc->sc_flags & URTW_RTL8187B) == 0) {
3816 urtw_read8_m(sc, URTW_CMD, &data);
3817 urtw_write8_m(sc, URTW_CMD, data | URTW_CMD_RX_ENABLE);
3824 urtw_tx_enable(struct urtw_softc *sc)
3830 if (sc->sc_flags & URTW_RTL8187B) {
3831 urtw_read32_m(sc, URTW_TX_CONF, &data);
3832 data &= ~URTW_TX_LOOPBACK_MASK;
3833 data &= ~(URTW_TX_DPRETRY_MASK | URTW_TX_RTSRETRY_MASK);
3834 data &= ~(URTW_TX_NOCRC | URTW_TX_MXDMA_MASK);
3835 data &= ~URTW_TX_SWPLCPLEN;
3836 data |= URTW_TX_HW_SEQNUM | URTW_TX_DISREQQSIZE |
3837 (7 << 8) | /* short retry limit */
3838 (7 << 0) | /* long retry limit */
3839 (7 << 21); /* MAX TX DMA */
3840 urtw_write32_m(sc, URTW_TX_CONF, data);
3842 urtw_read8_m(sc, URTW_MSR, &data8);
3843 data8 |= URTW_MSR_LINK_ENEDCA;
3844 urtw_write8_m(sc, URTW_MSR, data8);
3848 urtw_read8_m(sc, URTW_CW_CONF, &data8);
3849 data8 &= ~(URTW_CW_CONF_PERPACKET_CW | URTW_CW_CONF_PERPACKET_RETRY);
3850 urtw_write8_m(sc, URTW_CW_CONF, data8);
3852 urtw_read8_m(sc, URTW_TX_AGC_CTL, &data8);
3853 data8 &= ~URTW_TX_AGC_CTL_PERPACKET_GAIN;
3854 data8 &= ~URTW_TX_AGC_CTL_PERPACKET_ANTSEL;
3855 data8 &= ~URTW_TX_AGC_CTL_FEEDBACK_ANT;
3856 urtw_write8_m(sc, URTW_TX_AGC_CTL, data8);
3858 urtw_read32_m(sc, URTW_TX_CONF, &data);
3859 data &= ~URTW_TX_LOOPBACK_MASK;
3860 data |= URTW_TX_LOOPBACK_NONE;
3861 data &= ~(URTW_TX_DPRETRY_MASK | URTW_TX_RTSRETRY_MASK);
3862 data |= sc->sc_tx_retry << URTW_TX_DPRETRY_SHIFT;
3863 data |= sc->sc_rts_retry << URTW_TX_RTSRETRY_SHIFT;
3864 data &= ~(URTW_TX_NOCRC | URTW_TX_MXDMA_MASK);
3865 data |= URTW_TX_MXDMA_2048 | URTW_TX_CWMIN | URTW_TX_DISCW;
3866 data &= ~URTW_TX_SWPLCPLEN;
3867 data |= URTW_TX_NOICV;
3868 urtw_write32_m(sc, URTW_TX_CONF, data);
3870 urtw_read8_m(sc, URTW_CMD, &data8);
3871 urtw_write8_m(sc, URTW_CMD, data8 | URTW_CMD_TX_ENABLE);
3877 urtw_rx_setconf(struct urtw_softc *sc)
3879 struct ieee80211com *ic = &sc->sc_ic;
3883 urtw_read32_m(sc, URTW_RX, &data);
3884 data = data &~ URTW_RX_FILTER_MASK;
3885 if (sc->sc_flags & URTW_RTL8187B) {
3886 data = data | URTW_RX_FILTER_MNG | URTW_RX_FILTER_DATA |
3887 URTW_RX_FILTER_MCAST | URTW_RX_FILTER_BCAST |
3888 URTW_RX_FILTER_NICMAC | URTW_RX_CHECK_BSSID |
3889 URTW_RX_FIFO_THRESHOLD_NONE |
3890 URTW_MAX_RX_DMA_2048 |
3891 URTW_RX_AUTORESETPHY | URTW_RCR_ONLYERLPKT;
3893 data = data | URTW_RX_FILTER_MNG | URTW_RX_FILTER_DATA;
3894 data = data | URTW_RX_FILTER_BCAST | URTW_RX_FILTER_MCAST;
3896 if (ic->ic_opmode == IEEE80211_M_MONITOR) {
3897 data = data | URTW_RX_FILTER_ICVERR;
3898 data = data | URTW_RX_FILTER_PWR;
3900 if (sc->sc_crcmon == 1 && ic->ic_opmode == IEEE80211_M_MONITOR)
3901 data = data | URTW_RX_FILTER_CRCERR;
3903 if (ic->ic_opmode == IEEE80211_M_MONITOR ||
3904 ic->ic_promisc > 0 || ic->ic_allmulti > 0) {
3905 data = data | URTW_RX_FILTER_ALLMAC;
3907 data = data | URTW_RX_FILTER_NICMAC;
3908 data = data | URTW_RX_CHECK_BSSID;
3911 data = data &~ URTW_RX_FIFO_THRESHOLD_MASK;
3912 data = data | URTW_RX_FIFO_THRESHOLD_NONE |
3913 URTW_RX_AUTORESETPHY;
3914 data = data &~ URTW_MAX_RX_DMA_MASK;
3915 data = data | URTW_MAX_RX_DMA_2048 | URTW_RCR_ONLYERLPKT;
3918 urtw_write32_m(sc, URTW_RX, data);
3923 static struct mbuf *
3924 urtw_rxeof(struct usb_xfer *xfer, struct urtw_data *data, int *rssi_p,
3927 int actlen, flen, rssi;
3928 struct ieee80211_frame *wh;
3929 struct mbuf *m, *mnew;
3930 struct urtw_softc *sc = data->sc;
3931 struct ieee80211com *ic = &sc->sc_ic;
3932 uint8_t noise = 0, rate;
3934 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
3936 if (actlen < (int)URTW_MIN_RXBUFSZ) {
3937 counter_u64_add(ic->ic_ierrors, 1);
3941 if (sc->sc_flags & URTW_RTL8187B) {
3942 struct urtw_8187b_rxhdr *rx;
3944 rx = (struct urtw_8187b_rxhdr *)(data->buf +
3945 (actlen - (sizeof(struct urtw_8187b_rxhdr))));
3946 flen = le32toh(rx->flag) & 0xfff;
3947 if (flen > actlen) {
3948 counter_u64_add(ic->ic_ierrors, 1);
3951 rate = (le32toh(rx->flag) >> URTW_RX_FLAG_RXRATE_SHIFT) & 0xf;
3953 rssi = rx->rssi & URTW_RX_RSSI_MASK;
3956 struct urtw_8187l_rxhdr *rx;
3958 rx = (struct urtw_8187l_rxhdr *)(data->buf +
3959 (actlen - (sizeof(struct urtw_8187l_rxhdr))));
3960 flen = le32toh(rx->flag) & 0xfff;
3961 if (flen > actlen) {
3962 counter_u64_add(ic->ic_ierrors, 1);
3966 rate = (le32toh(rx->flag) >> URTW_RX_FLAG_RXRATE_SHIFT) & 0xf;
3968 rssi = rx->rssi & URTW_RX_8187L_RSSI_MASK;
3972 mnew = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
3974 counter_u64_add(ic->ic_ierrors, 1);
3980 data->buf = mtod(mnew, uint8_t *);
3983 m->m_pkthdr.len = m->m_len = flen - IEEE80211_CRC_LEN;
3985 if (ieee80211_radiotap_active(ic)) {
3986 struct urtw_rx_radiotap_header *tap = &sc->sc_rxtap;
3988 /* XXX Are variables correct? */
3989 tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
3990 tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
3991 tap->wr_dbm_antsignal = (int8_t)rssi;
3994 wh = mtod(m, struct ieee80211_frame *);
3995 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_DATA)
3996 sc->sc_currate = (rate > 0) ? rate : sc->sc_currate;
3999 *nf_p = noise; /* XXX correct? */
4005 urtw_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
4007 struct urtw_softc *sc = usbd_xfer_softc(xfer);
4008 struct ieee80211com *ic = &sc->sc_ic;
4009 struct ieee80211_frame *wh;
4010 struct ieee80211_node *ni;
4011 struct mbuf *m = NULL;
4012 struct urtw_data *data;
4016 URTW_ASSERT_LOCKED(sc);
4018 switch (USB_GET_STATE(xfer)) {
4019 case USB_ST_TRANSFERRED:
4020 data = STAILQ_FIRST(&sc->sc_rx_active);
4023 STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next);
4024 m = urtw_rxeof(xfer, data, &rssi, &nf);
4025 STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next);
4029 data = STAILQ_FIRST(&sc->sc_rx_inactive);
4031 KASSERT(m == NULL, ("mbuf isn't NULL"));
4034 STAILQ_REMOVE_HEAD(&sc->sc_rx_inactive, next);
4035 STAILQ_INSERT_TAIL(&sc->sc_rx_active, data, next);
4036 usbd_xfer_set_frame_data(xfer, 0, data->buf,
4037 usbd_xfer_max_len(xfer));
4038 usbd_transfer_submit(xfer);
4041 * To avoid LOR we should unlock our private mutex here to call
4042 * ieee80211_input() because here is at the end of a USB
4043 * callback and safe to unlock.
4047 wh = mtod(m, struct ieee80211_frame *);
4048 ni = ieee80211_find_rxnode(ic,
4049 (struct ieee80211_frame_min *)wh);
4051 (void) ieee80211_input(ni, m, rssi, nf);
4052 /* node is no longer needed */
4053 ieee80211_free_node(ni);
4055 (void) ieee80211_input_all(ic, m, rssi, nf);
4061 /* needs it to the inactive queue due to a error. */
4062 data = STAILQ_FIRST(&sc->sc_rx_active);
4064 STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next);
4065 STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next);
4067 if (error != USB_ERR_CANCELLED) {
4068 usbd_xfer_set_stall(xfer);
4069 counter_u64_add(ic->ic_ierrors, 1);
4076 #define URTW_STATUS_TYPE_TXCLOSE 1
4077 #define URTW_STATUS_TYPE_BEACON_INTR 0
4080 urtw_txstatus_eof(struct usb_xfer *xfer)
4082 struct urtw_softc *sc = usbd_xfer_softc(xfer);
4083 struct ieee80211com *ic = &sc->sc_ic;
4084 int actlen, type, pktretry, seq;
4087 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
4089 if (actlen != sizeof(uint64_t))
4092 val = le64toh(sc->sc_txstatus);
4093 type = (val >> 30) & 0x3;
4094 if (type == URTW_STATUS_TYPE_TXCLOSE) {
4095 pktretry = val & 0xff;
4096 seq = (val >> 16) & 0xff;
4097 if (pktretry == URTW_TX_MAXRETRY)
4098 counter_u64_add(ic->ic_oerrors, 1);
4099 DPRINTF(sc, URTW_DEBUG_TXSTATUS, "pktretry %d seq %#x\n",
4105 urtw_bulk_tx_status_callback(struct usb_xfer *xfer, usb_error_t error)
4107 struct urtw_softc *sc = usbd_xfer_softc(xfer);
4108 struct ieee80211com *ic = &sc->sc_ic;
4109 void *dma_buf = usbd_xfer_get_frame_buffer(xfer, 0);
4111 URTW_ASSERT_LOCKED(sc);
4113 switch (USB_GET_STATE(xfer)) {
4114 case USB_ST_TRANSFERRED:
4115 urtw_txstatus_eof(xfer);
4119 memcpy(dma_buf, &sc->sc_txstatus, sizeof(uint64_t));
4120 usbd_xfer_set_frame_len(xfer, 0, sizeof(uint64_t));
4121 usbd_transfer_submit(xfer);
4124 if (error != USB_ERR_CANCELLED) {
4125 usbd_xfer_set_stall(xfer);
4126 counter_u64_add(ic->ic_ierrors, 1);
4134 urtw_txeof(struct usb_xfer *xfer, struct urtw_data *data)
4136 struct urtw_softc *sc = usbd_xfer_softc(xfer);
4138 URTW_ASSERT_LOCKED(sc);
4142 ieee80211_tx_complete(data->ni, data->m, 0);
4150 urtw_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error)
4152 struct urtw_softc *sc = usbd_xfer_softc(xfer);
4153 struct urtw_data *data;
4155 URTW_ASSERT_LOCKED(sc);
4157 switch (USB_GET_STATE(xfer)) {
4158 case USB_ST_TRANSFERRED:
4159 data = STAILQ_FIRST(&sc->sc_tx_active);
4162 STAILQ_REMOVE_HEAD(&sc->sc_tx_active, next);
4163 urtw_txeof(xfer, data);
4164 STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data, next);
4168 data = STAILQ_FIRST(&sc->sc_tx_pending);
4170 DPRINTF(sc, URTW_DEBUG_XMIT,
4171 "%s: empty pending queue\n", __func__);
4174 STAILQ_REMOVE_HEAD(&sc->sc_tx_pending, next);
4175 STAILQ_INSERT_TAIL(&sc->sc_tx_active, data, next);
4177 usbd_xfer_set_frame_data(xfer, 0, data->buf, data->buflen);
4178 usbd_transfer_submit(xfer);
4183 data = STAILQ_FIRST(&sc->sc_tx_active);
4186 if (data->ni != NULL) {
4187 if_inc_counter(data->ni->ni_vap->iv_ifp,
4188 IFCOUNTER_OERRORS, 1);
4189 ieee80211_free_node(data->ni);
4192 if (error != USB_ERR_CANCELLED) {
4193 usbd_xfer_set_stall(xfer);
4200 static struct urtw_data *
4201 _urtw_getbuf(struct urtw_softc *sc)
4203 struct urtw_data *bf;
4205 bf = STAILQ_FIRST(&sc->sc_tx_inactive);
4207 STAILQ_REMOVE_HEAD(&sc->sc_tx_inactive, next);
4211 DPRINTF(sc, URTW_DEBUG_XMIT, "%s: %s\n", __func__,
4212 "out of xmit buffers");
4216 static struct urtw_data *
4217 urtw_getbuf(struct urtw_softc *sc)
4219 struct urtw_data *bf;
4221 URTW_ASSERT_LOCKED(sc);
4223 bf = _urtw_getbuf(sc);
4225 DPRINTF(sc, URTW_DEBUG_XMIT, "%s: stop queue\n", __func__);
4230 urtw_isbmode(uint16_t rate)
4233 return ((rate <= 22 && rate != 12 && rate != 18) ||
4234 rate == 44) ? (1) : (0);
4238 urtw_rate2dbps(uint16_t rate)
4258 urtw_compute_txtime(uint16_t framelen, uint16_t rate,
4259 uint8_t ismgt, uint8_t isshort)
4261 uint16_t ceiling, frametime, n_dbps;
4263 if (urtw_isbmode(rate)) {
4264 if (ismgt || !isshort || rate == 2)
4265 frametime = (uint16_t)(144 + 48 +
4266 (framelen * 8 / (rate / 2)));
4268 frametime = (uint16_t)(72 + 24 +
4269 (framelen * 8 / (rate / 2)));
4270 if ((framelen * 8 % (rate / 2)) != 0)
4273 n_dbps = urtw_rate2dbps(rate);
4274 ceiling = (16 + 8 * framelen + 6) / n_dbps
4275 + (((16 + 8 * framelen + 6) % n_dbps) ? 1 : 0);
4276 frametime = (uint16_t)(16 + 4 + 4 * ceiling + 6);
4282 * Callback from the 802.11 layer to update the
4283 * slot time based on the current setting.
4286 urtw_updateslot(struct ieee80211com *ic)
4288 struct urtw_softc *sc = ic->ic_softc;
4290 ieee80211_runtask(ic, &sc->sc_updateslot_task);
4294 urtw_updateslottask(void *arg, int pending)
4296 struct urtw_softc *sc = arg;
4297 struct ieee80211com *ic = &sc->sc_ic;
4301 if ((sc->sc_flags & URTW_RUNNING) == 0) {
4305 if (sc->sc_flags & URTW_RTL8187B) {
4306 urtw_write8_m(sc, URTW_SIFS, 0x22);
4307 if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan))
4308 urtw_write8_m(sc, URTW_SLOT, IEEE80211_DUR_SHSLOT);
4310 urtw_write8_m(sc, URTW_SLOT, IEEE80211_DUR_SLOT);
4311 urtw_write8_m(sc, URTW_8187B_EIFS, 0x5b);
4312 urtw_write8_m(sc, URTW_CARRIER_SCOUNT, 0x5b);
4314 urtw_write8_m(sc, URTW_SIFS, 0x22);
4315 if (sc->sc_state == IEEE80211_S_ASSOC &&
4316 ic->ic_flags & IEEE80211_F_SHSLOT)
4317 urtw_write8_m(sc, URTW_SLOT, IEEE80211_DUR_SHSLOT);
4319 urtw_write8_m(sc, URTW_SLOT, IEEE80211_DUR_SLOT);
4320 if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan)) {
4321 urtw_write8_m(sc, URTW_DIFS, 0x14);
4322 urtw_write8_m(sc, URTW_EIFS, 0x5b - 0x14);
4323 urtw_write8_m(sc, URTW_CW_VAL, 0x73);
4325 urtw_write8_m(sc, URTW_DIFS, 0x24);
4326 urtw_write8_m(sc, URTW_EIFS, 0x5b - 0x24);
4327 urtw_write8_m(sc, URTW_CW_VAL, 0xa5);
4335 urtw_sysctl_node(struct urtw_softc *sc)
4337 #define URTW_SYSCTL_STAT_ADD32(c, h, n, p, d) \
4338 SYSCTL_ADD_UINT(c, h, OID_AUTO, n, CTLFLAG_RD, p, 0, d)
4339 struct sysctl_ctx_list *ctx;
4340 struct sysctl_oid_list *child, *parent;
4341 struct sysctl_oid *tree;
4342 struct urtw_stats *stats = &sc->sc_stats;
4344 ctx = device_get_sysctl_ctx(sc->sc_dev);
4345 child = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->sc_dev));
4347 tree = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "stats", CTLFLAG_RD,
4348 NULL, "URTW statistics");
4349 parent = SYSCTL_CHILDREN(tree);
4351 /* Tx statistics. */
4352 tree = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "tx", CTLFLAG_RD,
4353 NULL, "Tx MAC statistics");
4354 child = SYSCTL_CHILDREN(tree);
4355 URTW_SYSCTL_STAT_ADD32(ctx, child, "1m", &stats->txrates[0],
4357 URTW_SYSCTL_STAT_ADD32(ctx, child, "2m", &stats->txrates[1],
4359 URTW_SYSCTL_STAT_ADD32(ctx, child, "5.5m", &stats->txrates[2],
4361 URTW_SYSCTL_STAT_ADD32(ctx, child, "6m", &stats->txrates[4],
4363 URTW_SYSCTL_STAT_ADD32(ctx, child, "9m", &stats->txrates[5],
4365 URTW_SYSCTL_STAT_ADD32(ctx, child, "11m", &stats->txrates[3],
4367 URTW_SYSCTL_STAT_ADD32(ctx, child, "12m", &stats->txrates[6],
4369 URTW_SYSCTL_STAT_ADD32(ctx, child, "18m", &stats->txrates[7],
4371 URTW_SYSCTL_STAT_ADD32(ctx, child, "24m", &stats->txrates[8],
4373 URTW_SYSCTL_STAT_ADD32(ctx, child, "36m", &stats->txrates[9],
4375 URTW_SYSCTL_STAT_ADD32(ctx, child, "48m", &stats->txrates[10],
4377 URTW_SYSCTL_STAT_ADD32(ctx, child, "54m", &stats->txrates[11],
4379 #undef URTW_SYSCTL_STAT_ADD32
4382 static device_method_t urtw_methods[] = {
4383 DEVMETHOD(device_probe, urtw_match),
4384 DEVMETHOD(device_attach, urtw_attach),
4385 DEVMETHOD(device_detach, urtw_detach),
4388 static driver_t urtw_driver = {
4390 .methods = urtw_methods,
4391 .size = sizeof(struct urtw_softc)
4393 static devclass_t urtw_devclass;
4395 DRIVER_MODULE(urtw, uhub, urtw_driver, urtw_devclass, NULL, 0);
4396 MODULE_DEPEND(urtw, wlan, 1, 1, 1);
4397 MODULE_DEPEND(urtw, usb, 1, 1, 1);
4398 MODULE_VERSION(urtw, 1);
4399 USB_PNP_HOST_INFO(urtw_devs);