Deleted Added
sdiff udiff text old ( 203087 ) new ( 206358 )
full compact
1/*-
2 * Copyright (c) 2008 Weongyo Jeong <weongyo@FreeBSD.org>
3 *
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.
7 *
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.
15 */
16
17#include <sys/cdefs.h>
18__FBSDID("$FreeBSD: head/sys/dev/usb/wlan/if_urtw.c 206358 2010-04-07 15:29:13Z rpaulo $");
19#include <sys/param.h>
20#include <sys/sockio.h>
21#include <sys/sysctl.h>
22#include <sys/lock.h>
23#include <sys/mutex.h>
24#include <sys/mbuf.h>
25#include <sys/kernel.h>
26#include <sys/socket.h>
27#include <sys/systm.h>
28#include <sys/malloc.h>
29#include <sys/module.h>
30#include <sys/bus.h>
31#include <sys/endian.h>
32#include <sys/kdb.h>
33
34#include <machine/bus.h>
35#include <machine/resource.h>
36#include <sys/rman.h>
37
38#include <net/if.h>
39#include <net/if_arp.h>
40#include <net/ethernet.h>
41#include <net/if_dl.h>
42#include <net/if_media.h>
43#include <net/if_types.h>
44
45#ifdef INET
46#include <netinet/in.h>
47#include <netinet/in_systm.h>
48#include <netinet/in_var.h>
49#include <netinet/if_ether.h>
50#include <netinet/ip.h>
51#endif
52
53#include <net80211/ieee80211_var.h>
54#include <net80211/ieee80211_regdomain.h>
55#include <net80211/ieee80211_radiotap.h>
56
57#include <dev/usb/usb.h>
58#include <dev/usb/usbdi.h>
59#include "usbdevs.h"
60
61#include <dev/usb/wlan/if_urtwreg.h>
62#include <dev/usb/wlan/if_urtwvar.h>
63
64SYSCTL_NODE(_hw_usb, OID_AUTO, urtw, CTLFLAG_RW, 0, "USB Realtek 8187L");
65#define URTW_DEBUG
66#ifdef URTW_DEBUG
67int urtw_debug = 0;
68SYSCTL_INT(_hw_usb_urtw, OID_AUTO, debug, CTLFLAG_RW, &urtw_debug, 0,
69 "control debugging printfs");
70TUNABLE_INT("hw.usb.urtw.debug", &urtw_debug);
71enum {
72 URTW_DEBUG_XMIT = 0x00000001, /* basic xmit operation */
73 URTW_DEBUG_RECV = 0x00000002, /* basic recv operation */
74 URTW_DEBUG_RESET = 0x00000004, /* reset processing */
75 URTW_DEBUG_TX_PROC = 0x00000008, /* tx ISR proc */
76 URTW_DEBUG_RX_PROC = 0x00000010, /* rx ISR proc */
77 URTW_DEBUG_STATE = 0x00000020, /* 802.11 state transitions */
78 URTW_DEBUG_STAT = 0x00000040, /* statistic */
79 URTW_DEBUG_INIT = 0x00000080, /* initialization of dev */
80 URTW_DEBUG_TXSTATUS = 0x00000100, /* tx status */
81 URTW_DEBUG_ANY = 0xffffffff
82};
83#define DPRINTF(sc, m, fmt, ...) do { \
84 if (sc->sc_debug & (m)) \
85 printf(fmt, __VA_ARGS__); \
86} while (0)
87#else
88#define DPRINTF(sc, m, fmt, ...) do { \
89 (void) sc; \
90} while (0)
91#endif
92static int urtw_preamble_mode = URTW_PREAMBLE_MODE_LONG;
93SYSCTL_INT(_hw_usb_urtw, OID_AUTO, preamble_mode, CTLFLAG_RW,
94 &urtw_preamble_mode, 0, "set the preable mode (long or short)");
95TUNABLE_INT("hw.usb.urtw.preamble_mode", &urtw_preamble_mode);
96
97/* recognized device vendors/products */
98#define urtw_lookup(v, p) \
99 ((const struct urtw_type *)usb_lookup(urtw_devs, v, p))
100#define URTW_DEV_B(v,p) \
101 { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, URTW_REV_RTL8187B) }
102#define URTW_DEV_L(v,p) \
103 { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, URTW_REV_RTL8187L) }
104#define URTW_REV_RTL8187B 0
105#define URTW_REV_RTL8187L 1
106static const struct usb_device_id urtw_devs[] = {
107 URTW_DEV_B(NETGEAR, WG111V3),
108 URTW_DEV_B(REALTEK, RTL8187B_0),
109 URTW_DEV_B(REALTEK, RTL8187B_1),
110 URTW_DEV_B(REALTEK, RTL8187B_2),
111 URTW_DEV_B(SITECOMEU, WL168V4),
112 URTW_DEV_L(ASUS, P5B_WIFI),
113 URTW_DEV_L(BELKIN, F5D7050E),
114 URTW_DEV_L(LINKSYS4, WUSB54GCV2),
115 URTW_DEV_L(NETGEAR, WG111V2),
116 URTW_DEV_L(REALTEK, RTL8187),
117 URTW_DEV_L(SITECOMEU, WL168V1),
118 URTW_DEV_L(SURECOM, EP9001G2A),
119 { USB_VPI(0x1b75, 0x8187, URTW_REV_RTL8187L) },
120 { USB_VPI(USB_VENDOR_DICKSMITH, 0x9401, URTW_REV_RTL8187L) },
121 { USB_VPI(USB_VENDOR_HP, 0xca02, URTW_REV_RTL8187L) },
122 { USB_VPI(USB_VENDOR_LOGITEC, 0x010c, URTW_REV_RTL8187L) },
123 { USB_VPI(USB_VENDOR_NETGEAR, 0x6100, URTW_REV_RTL8187L) },
124 { USB_VPI(USB_VENDOR_SPHAIRON, 0x0150, URTW_REV_RTL8187L) },
125 { USB_VPI(USB_VENDOR_QCOM, 0x6232, URTW_REV_RTL8187L) },
126#undef URTW_DEV_L
127#undef URTW_DEV_B
128};
129
130#define urtw_read8_m(sc, val, data) do { \
131 error = urtw_read8_c(sc, val, data); \
132 if (error != 0) \
133 goto fail; \
134} while (0)
135#define urtw_write8_m(sc, val, data) do { \
136 error = urtw_write8_c(sc, val, data); \
137 if (error != 0) \
138 goto fail; \
139} while (0)
140#define urtw_read16_m(sc, val, data) do { \
141 error = urtw_read16_c(sc, val, data); \
142 if (error != 0) \
143 goto fail; \
144} while (0)
145#define urtw_write16_m(sc, val, data) do { \
146 error = urtw_write16_c(sc, val, data); \
147 if (error != 0) \
148 goto fail; \
149} while (0)
150#define urtw_read32_m(sc, val, data) do { \
151 error = urtw_read32_c(sc, val, data); \
152 if (error != 0) \
153 goto fail; \
154} while (0)
155#define urtw_write32_m(sc, val, data) do { \
156 error = urtw_write32_c(sc, val, data); \
157 if (error != 0) \
158 goto fail; \
159} while (0)
160#define urtw_8187_write_phy_ofdm(sc, val, data) do { \
161 error = urtw_8187_write_phy_ofdm_c(sc, val, data); \
162 if (error != 0) \
163 goto fail; \
164} while (0)
165#define urtw_8187_write_phy_cck(sc, val, data) do { \
166 error = urtw_8187_write_phy_cck_c(sc, val, data); \
167 if (error != 0) \
168 goto fail; \
169} while (0)
170#define urtw_8225_write(sc, val, data) do { \
171 error = urtw_8225_write_c(sc, val, data); \
172 if (error != 0) \
173 goto fail; \
174} while (0)
175
176struct urtw_pair {
177 uint32_t reg;
178 uint32_t val;
179};
180
181static uint8_t urtw_8225_agc[] = {
182 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9d, 0x9c, 0x9b,
183 0x9a, 0x99, 0x98, 0x97, 0x96, 0x95, 0x94, 0x93, 0x92, 0x91, 0x90,
184 0x8f, 0x8e, 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86, 0x85,
185 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a,
186 0x39, 0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f,
187 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24,
188 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19,
189 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e,
190 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03,
191 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
192 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
193 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
194};
195
196static uint8_t urtw_8225z2_agc[] = {
197 0x5e, 0x5e, 0x5e, 0x5e, 0x5d, 0x5b, 0x59, 0x57, 0x55, 0x53, 0x51,
198 0x4f, 0x4d, 0x4b, 0x49, 0x47, 0x45, 0x43, 0x41, 0x3f, 0x3d, 0x3b,
199 0x39, 0x37, 0x35, 0x33, 0x31, 0x2f, 0x2d, 0x2b, 0x29, 0x27, 0x25,
200 0x23, 0x21, 0x1f, 0x1d, 0x1b, 0x19, 0x17, 0x15, 0x13, 0x11, 0x0f,
201 0x0d, 0x0b, 0x09, 0x07, 0x05, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01,
202 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x19, 0x19,
203 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x20, 0x21, 0x22, 0x23,
204 0x24, 0x25, 0x26, 0x26, 0x27, 0x27, 0x28, 0x28, 0x29, 0x2a, 0x2a,
205 0x2a, 0x2b, 0x2b, 0x2b, 0x2c, 0x2c, 0x2c, 0x2d, 0x2d, 0x2d, 0x2d,
206 0x2e, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x2f, 0x30, 0x30, 0x31, 0x31,
207 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
208 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31
209};
210
211static uint32_t urtw_8225_channel[] = {
212 0x0000, /* dummy channel 0 */
213 0x085c, /* 1 */
214 0x08dc, /* 2 */
215 0x095c, /* 3 */
216 0x09dc, /* 4 */
217 0x0a5c, /* 5 */
218 0x0adc, /* 6 */
219 0x0b5c, /* 7 */
220 0x0bdc, /* 8 */
221 0x0c5c, /* 9 */
222 0x0cdc, /* 10 */
223 0x0d5c, /* 11 */
224 0x0ddc, /* 12 */
225 0x0e5c, /* 13 */
226 0x0f72, /* 14 */
227};
228
229static uint8_t urtw_8225_gain[] = {
230 0x23, 0x88, 0x7c, 0xa5, /* -82dbm */
231 0x23, 0x88, 0x7c, 0xb5, /* -82dbm */
232 0x23, 0x88, 0x7c, 0xc5, /* -82dbm */
233 0x33, 0x80, 0x79, 0xc5, /* -78dbm */
234 0x43, 0x78, 0x76, 0xc5, /* -74dbm */
235 0x53, 0x60, 0x73, 0xc5, /* -70dbm */
236 0x63, 0x58, 0x70, 0xc5, /* -66dbm */
237};
238
239static struct urtw_pair urtw_8225_rf_part1[] = {
240 { 0x00, 0x0067 }, { 0x01, 0x0fe0 }, { 0x02, 0x044d }, { 0x03, 0x0441 },
241 { 0x04, 0x0486 }, { 0x05, 0x0bc0 }, { 0x06, 0x0ae6 }, { 0x07, 0x082a },
242 { 0x08, 0x001f }, { 0x09, 0x0334 }, { 0x0a, 0x0fd4 }, { 0x0b, 0x0391 },
243 { 0x0c, 0x0050 }, { 0x0d, 0x06db }, { 0x0e, 0x0029 }, { 0x0f, 0x0914 },
244};
245
246static struct urtw_pair urtw_8225_rf_part2[] = {
247 { 0x00, 0x01 }, { 0x01, 0x02 }, { 0x02, 0x42 }, { 0x03, 0x00 },
248 { 0x04, 0x00 }, { 0x05, 0x00 }, { 0x06, 0x40 }, { 0x07, 0x00 },
249 { 0x08, 0x40 }, { 0x09, 0xfe }, { 0x0a, 0x09 }, { 0x0b, 0x80 },
250 { 0x0c, 0x01 }, { 0x0e, 0xd3 }, { 0x0f, 0x38 }, { 0x10, 0x84 },
251 { 0x11, 0x06 }, { 0x12, 0x20 }, { 0x13, 0x20 }, { 0x14, 0x00 },
252 { 0x15, 0x40 }, { 0x16, 0x00 }, { 0x17, 0x40 }, { 0x18, 0xef },
253 { 0x19, 0x19 }, { 0x1a, 0x20 }, { 0x1b, 0x76 }, { 0x1c, 0x04 },
254 { 0x1e, 0x95 }, { 0x1f, 0x75 }, { 0x20, 0x1f }, { 0x21, 0x27 },
255 { 0x22, 0x16 }, { 0x24, 0x46 }, { 0x25, 0x20 }, { 0x26, 0x90 },
256 { 0x27, 0x88 }
257};
258
259static struct urtw_pair urtw_8225_rf_part3[] = {
260 { 0x00, 0x98 }, { 0x03, 0x20 }, { 0x04, 0x7e }, { 0x05, 0x12 },
261 { 0x06, 0xfc }, { 0x07, 0x78 }, { 0x08, 0x2e }, { 0x10, 0x9b },
262 { 0x11, 0x88 }, { 0x12, 0x47 }, { 0x13, 0xd0 }, { 0x19, 0x00 },
263 { 0x1a, 0xa0 }, { 0x1b, 0x08 }, { 0x40, 0x86 }, { 0x41, 0x8d },
264 { 0x42, 0x15 }, { 0x43, 0x18 }, { 0x44, 0x1f }, { 0x45, 0x1e },
265 { 0x46, 0x1a }, { 0x47, 0x15 }, { 0x48, 0x10 }, { 0x49, 0x0a },
266 { 0x4a, 0x05 }, { 0x4b, 0x02 }, { 0x4c, 0x05 }
267};
268
269static uint16_t urtw_8225_rxgain[] = {
270 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
271 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
272 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
273 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
274 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
275 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
276 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
277 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
278 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
279 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
280 0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3,
281 0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb
282};
283
284static uint8_t urtw_8225_threshold[] = {
285 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd,
286};
287
288static uint8_t urtw_8225_tx_gain_cck_ofdm[] = {
289 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e
290};
291
292static uint8_t urtw_8225_txpwr_cck[] = {
293 0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02,
294 0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02,
295 0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02,
296 0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02,
297 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03,
298 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03
299};
300
301static uint8_t urtw_8225_txpwr_cck_ch14[] = {
302 0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00,
303 0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00,
304 0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00,
305 0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00,
306 0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00,
307 0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00
308};
309
310static uint8_t urtw_8225_txpwr_ofdm[]={
311 0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4
312};
313
314static uint8_t urtw_8225v2_gain_bg[]={
315 0x23, 0x15, 0xa5, /* -82-1dbm */
316 0x23, 0x15, 0xb5, /* -82-2dbm */
317 0x23, 0x15, 0xc5, /* -82-3dbm */
318 0x33, 0x15, 0xc5, /* -78dbm */
319 0x43, 0x15, 0xc5, /* -74dbm */
320 0x53, 0x15, 0xc5, /* -70dbm */
321 0x63, 0x15, 0xc5, /* -66dbm */
322};
323
324static struct urtw_pair urtw_8225v2_rf_part1[] = {
325 { 0x00, 0x02bf }, { 0x01, 0x0ee0 }, { 0x02, 0x044d }, { 0x03, 0x0441 },
326 { 0x04, 0x08c3 }, { 0x05, 0x0c72 }, { 0x06, 0x00e6 }, { 0x07, 0x082a },
327 { 0x08, 0x003f }, { 0x09, 0x0335 }, { 0x0a, 0x09d4 }, { 0x0b, 0x07bb },
328 { 0x0c, 0x0850 }, { 0x0d, 0x0cdf }, { 0x0e, 0x002b }, { 0x0f, 0x0114 }
329};
330
331static struct urtw_pair urtw_8225v2b_rf_part0[] = {
332 { 0x00, 0x00b7 }, { 0x01, 0x0ee0 }, { 0x02, 0x044d }, { 0x03, 0x0441 },
333 { 0x04, 0x08c3 }, { 0x05, 0x0c72 }, { 0x06, 0x00e6 }, { 0x07, 0x082a },
334 { 0x08, 0x003f }, { 0x09, 0x0335 }, { 0x0a, 0x09d4 }, { 0x0b, 0x07bb },
335 { 0x0c, 0x0850 }, { 0x0d, 0x0cdf }, { 0x0e, 0x002b }, { 0x0f, 0x0114 }
336};
337
338static struct urtw_pair urtw_8225v2b_rf_part1[] = {
339 {0x0f0, 0x32}, {0x0f1, 0x32}, {0x0f2, 0x00},
340 {0x0f3, 0x00}, {0x0f4, 0x32}, {0x0f5, 0x43},
341 {0x0f6, 0x00}, {0x0f7, 0x00}, {0x0f8, 0x46},
342 {0x0f9, 0xa4}, {0x0fa, 0x00}, {0x0fb, 0x00},
343 {0x0fc, 0x96}, {0x0fd, 0xa4}, {0x0fe, 0x00},
344 {0x0ff, 0x00}, {0x158, 0x4b}, {0x159, 0x00},
345 {0x15a, 0x4b}, {0x15b, 0x00}, {0x160, 0x4b},
346 {0x161, 0x09}, {0x162, 0x4b}, {0x163, 0x09},
347 {0x1ce, 0x0f}, {0x1cf, 0x00}, {0x1e0, 0xff},
348 {0x1e1, 0x0f}, {0x1e2, 0x00}, {0x1f0, 0x4e},
349 {0x1f1, 0x01}, {0x1f2, 0x02}, {0x1f3, 0x03},
350 {0x1f4, 0x04}, {0x1f5, 0x05}, {0x1f6, 0x06},
351 {0x1f7, 0x07}, {0x1f8, 0x08}, {0x24e, 0x00},
352 {0x20c, 0x04}, {0x221, 0x61}, {0x222, 0x68},
353 {0x223, 0x6f}, {0x224, 0x76}, {0x225, 0x7d},
354 {0x226, 0x84}, {0x227, 0x8d}, {0x24d, 0x08},
355 {0x250, 0x05}, {0x251, 0xf5}, {0x252, 0x04},
356 {0x253, 0xa0}, {0x254, 0x1f}, {0x255, 0x23},
357 {0x256, 0x45}, {0x257, 0x67}, {0x258, 0x08},
358 {0x259, 0x08}, {0x25a, 0x08}, {0x25b, 0x08},
359 {0x260, 0x08}, {0x261, 0x08}, {0x262, 0x08},
360 {0x263, 0x08}, {0x264, 0xcf}, {0x272, 0x56},
361 {0x273, 0x9a}, {0x034, 0xf0}, {0x035, 0x0f},
362 {0x05b, 0x40}, {0x084, 0x88}, {0x085, 0x24},
363 {0x088, 0x54}, {0x08b, 0xb8}, {0x08c, 0x07},
364 {0x08d, 0x00}, {0x094, 0x1b}, {0x095, 0x12},
365 {0x096, 0x00}, {0x097, 0x06}, {0x09d, 0x1a},
366 {0x09f, 0x10}, {0x0b4, 0x22}, {0x0be, 0x80},
367 {0x0db, 0x00}, {0x0ee, 0x00}, {0x091, 0x03},
368 {0x24c, 0x00}, {0x39f, 0x00}, {0x08c, 0x01},
369 {0x08d, 0x10}, {0x08e, 0x08}, {0x08f, 0x00}
370};
371
372static struct urtw_pair urtw_8225v2_rf_part2[] = {
373 { 0x00, 0x01 }, { 0x01, 0x02 }, { 0x02, 0x42 }, { 0x03, 0x00 },
374 { 0x04, 0x00 }, { 0x05, 0x00 }, { 0x06, 0x40 }, { 0x07, 0x00 },
375 { 0x08, 0x40 }, { 0x09, 0xfe }, { 0x0a, 0x08 }, { 0x0b, 0x80 },
376 { 0x0c, 0x01 }, { 0x0d, 0x43 }, { 0x0e, 0xd3 }, { 0x0f, 0x38 },
377 { 0x10, 0x84 }, { 0x11, 0x07 }, { 0x12, 0x20 }, { 0x13, 0x20 },
378 { 0x14, 0x00 }, { 0x15, 0x40 }, { 0x16, 0x00 }, { 0x17, 0x40 },
379 { 0x18, 0xef }, { 0x19, 0x19 }, { 0x1a, 0x20 }, { 0x1b, 0x15 },
380 { 0x1c, 0x04 }, { 0x1d, 0xc5 }, { 0x1e, 0x95 }, { 0x1f, 0x75 },
381 { 0x20, 0x1f }, { 0x21, 0x17 }, { 0x22, 0x16 }, { 0x23, 0x80 },
382 { 0x24, 0x46 }, { 0x25, 0x00 }, { 0x26, 0x90 }, { 0x27, 0x88 }
383};
384
385static struct urtw_pair urtw_8225v2b_rf_part2[] = {
386 { 0x00, 0x10 }, { 0x01, 0x0d }, { 0x02, 0x01 }, { 0x03, 0x00 },
387 { 0x04, 0x14 }, { 0x05, 0xfb }, { 0x06, 0xfb }, { 0x07, 0x60 },
388 { 0x08, 0x00 }, { 0x09, 0x60 }, { 0x0a, 0x00 }, { 0x0b, 0x00 },
389 { 0x0c, 0x00 }, { 0x0d, 0x5c }, { 0x0e, 0x00 }, { 0x0f, 0x00 },
390 { 0x10, 0x40 }, { 0x11, 0x00 }, { 0x12, 0x40 }, { 0x13, 0x00 },
391 { 0x14, 0x00 }, { 0x15, 0x00 }, { 0x16, 0xa8 }, { 0x17, 0x26 },
392 { 0x18, 0x32 }, { 0x19, 0x33 }, { 0x1a, 0x07 }, { 0x1b, 0xa5 },
393 { 0x1c, 0x6f }, { 0x1d, 0x55 }, { 0x1e, 0xc8 }, { 0x1f, 0xb3 },
394 { 0x20, 0x0a }, { 0x21, 0xe1 }, { 0x22, 0x2C }, { 0x23, 0x8a },
395 { 0x24, 0x86 }, { 0x25, 0x83 }, { 0x26, 0x34 }, { 0x27, 0x0f },
396 { 0x28, 0x4f }, { 0x29, 0x24 }, { 0x2a, 0x6f }, { 0x2b, 0xc2 },
397 { 0x2c, 0x6b }, { 0x2d, 0x40 }, { 0x2e, 0x80 }, { 0x2f, 0x00 },
398 { 0x30, 0xc0 }, { 0x31, 0xc1 }, { 0x32, 0x58 }, { 0x33, 0xf1 },
399 { 0x34, 0x00 }, { 0x35, 0xe4 }, { 0x36, 0x90 }, { 0x37, 0x3e },
400 { 0x38, 0x6d }, { 0x39, 0x3c }, { 0x3a, 0xfb }, { 0x3b, 0x07 }
401};
402
403static struct urtw_pair urtw_8225v2_rf_part3[] = {
404 { 0x00, 0x98 }, { 0x03, 0x20 }, { 0x04, 0x7e }, { 0x05, 0x12 },
405 { 0x06, 0xfc }, { 0x07, 0x78 }, { 0x08, 0x2e }, { 0x09, 0x11 },
406 { 0x0a, 0x17 }, { 0x0b, 0x11 }, { 0x10, 0x9b }, { 0x11, 0x88 },
407 { 0x12, 0x47 }, { 0x13, 0xd0 }, { 0x19, 0x00 }, { 0x1a, 0xa0 },
408 { 0x1b, 0x08 }, { 0x1d, 0x00 }, { 0x40, 0x86 }, { 0x41, 0x9d },
409 { 0x42, 0x15 }, { 0x43, 0x18 }, { 0x44, 0x36 }, { 0x45, 0x35 },
410 { 0x46, 0x2e }, { 0x47, 0x25 }, { 0x48, 0x1c }, { 0x49, 0x12 },
411 { 0x4a, 0x09 }, { 0x4b, 0x04 }, { 0x4c, 0x05 }
412};
413
414static uint16_t urtw_8225v2_rxgain[] = {
415 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0008, 0x0009,
416 0x000a, 0x000b, 0x0102, 0x0103, 0x0104, 0x0105, 0x0140, 0x0141,
417 0x0142, 0x0143, 0x0144, 0x0145, 0x0180, 0x0181, 0x0182, 0x0183,
418 0x0184, 0x0185, 0x0188, 0x0189, 0x018a, 0x018b, 0x0243, 0x0244,
419 0x0245, 0x0280, 0x0281, 0x0282, 0x0283, 0x0284, 0x0285, 0x0288,
420 0x0289, 0x028a, 0x028b, 0x028c, 0x0342, 0x0343, 0x0344, 0x0345,
421 0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x0388, 0x0389,
422 0x038a, 0x038b, 0x038c, 0x038d, 0x0390, 0x0391, 0x0392, 0x0393,
423 0x0394, 0x0395, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d,
424 0x03a0, 0x03a1, 0x03a2, 0x03a3, 0x03a4, 0x03a5, 0x03a8, 0x03a9,
425 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
426 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
427};
428
429static uint16_t urtw_8225v2b_rxgain[] = {
430 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
431 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
432 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
433 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
434 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
435 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
436 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
437 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
438 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
439 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
440 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
441 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
442};
443
444static uint8_t urtw_8225v2_tx_gain_cck_ofdm[] = {
445 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
446 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
447 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
448 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
449 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
450 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
451};
452
453static uint8_t urtw_8225v2_txpwr_cck[] = {
454 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04
455};
456
457static uint8_t urtw_8225v2_txpwr_cck_ch14[] = {
458 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00
459};
460
461static uint8_t urtw_8225v2b_txpwr_cck[] = {
462 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04,
463 0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03,
464 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03,
465 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03
466};
467
468static uint8_t urtw_8225v2b_txpwr_cck_ch14[] = {
469 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00,
470 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
471 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
472 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00
473};
474
475static struct urtw_pair urtw_ratetable[] = {
476 { 2, 0 }, { 4, 1 }, { 11, 2 }, { 12, 4 }, { 18, 5 },
477 { 22, 3 }, { 24, 6 }, { 36, 7 }, { 48, 8 }, { 72, 9 },
478 { 96, 10 }, { 108, 11 }
479};
480
481static const uint8_t urtw_8187b_reg_table[][3] = {
482 { 0xf0, 0x32, 0 }, { 0xf1, 0x32, 0 }, { 0xf2, 0x00, 0 },
483 { 0xf3, 0x00, 0 }, { 0xf4, 0x32, 0 }, { 0xf5, 0x43, 0 },
484 { 0xf6, 0x00, 0 }, { 0xf7, 0x00, 0 }, { 0xf8, 0x46, 0 },
485 { 0xf9, 0xa4, 0 }, { 0xfa, 0x00, 0 }, { 0xfb, 0x00, 0 },
486 { 0xfc, 0x96, 0 }, { 0xfd, 0xa4, 0 }, { 0xfe, 0x00, 0 },
487 { 0xff, 0x00, 0 }, { 0x58, 0x4b, 1 }, { 0x59, 0x00, 1 },
488 { 0x5a, 0x4b, 1 }, { 0x5b, 0x00, 1 }, { 0x60, 0x4b, 1 },
489 { 0x61, 0x09, 1 }, { 0x62, 0x4b, 1 }, { 0x63, 0x09, 1 },
490 { 0xce, 0x0f, 1 }, { 0xcf, 0x00, 1 }, { 0xe0, 0xff, 1 },
491 { 0xe1, 0x0f, 1 }, { 0xe2, 0x00, 1 }, { 0xf0, 0x4e, 1 },
492 { 0xf1, 0x01, 1 }, { 0xf2, 0x02, 1 }, { 0xf3, 0x03, 1 },
493 { 0xf4, 0x04, 1 }, { 0xf5, 0x05, 1 }, { 0xf6, 0x06, 1 },
494 { 0xf7, 0x07, 1 }, { 0xf8, 0x08, 1 }, { 0x4e, 0x00, 2 },
495 { 0x0c, 0x04, 2 }, { 0x21, 0x61, 2 }, { 0x22, 0x68, 2 },
496 { 0x23, 0x6f, 2 }, { 0x24, 0x76, 2 }, { 0x25, 0x7d, 2 },
497 { 0x26, 0x84, 2 }, { 0x27, 0x8d, 2 }, { 0x4d, 0x08, 2 },
498 { 0x50, 0x05, 2 }, { 0x51, 0xf5, 2 }, { 0x52, 0x04, 2 },
499 { 0x53, 0xa0, 2 }, { 0x54, 0x1f, 2 }, { 0x55, 0x23, 2 },
500 { 0x56, 0x45, 2 }, { 0x57, 0x67, 2 }, { 0x58, 0x08, 2 },
501 { 0x59, 0x08, 2 }, { 0x5a, 0x08, 2 }, { 0x5b, 0x08, 2 },
502 { 0x60, 0x08, 2 }, { 0x61, 0x08, 2 }, { 0x62, 0x08, 2 },
503 { 0x63, 0x08, 2 }, { 0x64, 0xcf, 2 }, { 0x72, 0x56, 2 },
504 { 0x73, 0x9a, 2 }, { 0x34, 0xf0, 0 }, { 0x35, 0x0f, 0 },
505 { 0x5b, 0x40, 0 }, { 0x84, 0x88, 0 }, { 0x85, 0x24, 0 },
506 { 0x88, 0x54, 0 }, { 0x8b, 0xb8, 0 }, { 0x8c, 0x07, 0 },
507 { 0x8d, 0x00, 0 }, { 0x94, 0x1b, 0 }, { 0x95, 0x12, 0 },
508 { 0x96, 0x00, 0 }, { 0x97, 0x06, 0 }, { 0x9d, 0x1a, 0 },
509 { 0x9f, 0x10, 0 }, { 0xb4, 0x22, 0 }, { 0xbe, 0x80, 0 },
510 { 0xdb, 0x00, 0 }, { 0xee, 0x00, 0 }, { 0x91, 0x03, 0 },
511 { 0x4c, 0x00, 2 }, { 0x9f, 0x00, 3 }, { 0x8c, 0x01, 0 },
512 { 0x8d, 0x10, 0 }, { 0x8e, 0x08, 0 }, { 0x8f, 0x00, 0 }
513};
514
515static usb_callback_t urtw_bulk_rx_callback;
516static usb_callback_t urtw_bulk_tx_callback;
517static usb_callback_t urtw_bulk_tx_status_callback;
518
519static const struct usb_config urtw_8187b_usbconfig[URTW_8187B_N_XFERS] = {
520 [URTW_8187B_BULK_RX] = {
521 .type = UE_BULK,
522 .endpoint = 0x83,
523 .direction = UE_DIR_IN,
524 .bufsize = MCLBYTES,
525 .flags = {
526 .ext_buffer = 1,
527 .pipe_bof = 1,
528 .short_xfer_ok = 1
529 },
530 .callback = urtw_bulk_rx_callback
531 },
532 [URTW_8187B_BULK_TX_STATUS] = {
533 .type = UE_BULK,
534 .endpoint = 0x89,
535 .direction = UE_DIR_IN,
536 .bufsize = MCLBYTES,
537 .flags = {
538 .ext_buffer = 1,
539 .pipe_bof = 1,
540 .short_xfer_ok = 1
541 },
542 .callback = urtw_bulk_tx_status_callback
543 },
544 [URTW_8187B_BULK_TX_BE] = {
545 .type = UE_BULK,
546 .endpoint = URTW_8187B_TXPIPE_BE,
547 .direction = UE_DIR_OUT,
548 .bufsize = URTW_TX_MAXSIZE,
549 .flags = {
550 .ext_buffer = 1,
551 .force_short_xfer = 1,
552 .pipe_bof = 1,
553 },
554 .callback = urtw_bulk_tx_callback,
555 .timeout = URTW_DATA_TIMEOUT
556 },
557 [URTW_8187B_BULK_TX_BK] = {
558 .type = UE_BULK,
559 .endpoint = URTW_8187B_TXPIPE_BK,
560 .direction = UE_DIR_OUT,
561 .bufsize = URTW_TX_MAXSIZE,
562 .flags = {
563 .ext_buffer = 1,
564 .force_short_xfer = 1,
565 .pipe_bof = 1,
566 },
567 .callback = urtw_bulk_tx_callback,
568 .timeout = URTW_DATA_TIMEOUT
569 },
570 [URTW_8187B_BULK_TX_VI] = {
571 .type = UE_BULK,
572 .endpoint = URTW_8187B_TXPIPE_VI,
573 .direction = UE_DIR_OUT,
574 .bufsize = URTW_TX_MAXSIZE,
575 .flags = {
576 .ext_buffer = 1,
577 .force_short_xfer = 1,
578 .pipe_bof = 1,
579 },
580 .callback = urtw_bulk_tx_callback,
581 .timeout = URTW_DATA_TIMEOUT
582 },
583 [URTW_8187B_BULK_TX_VO] = {
584 .type = UE_BULK,
585 .endpoint = URTW_8187B_TXPIPE_VO,
586 .direction = UE_DIR_OUT,
587 .bufsize = URTW_TX_MAXSIZE,
588 .flags = {
589 .ext_buffer = 1,
590 .force_short_xfer = 1,
591 .pipe_bof = 1,
592 },
593 .callback = urtw_bulk_tx_callback,
594 .timeout = URTW_DATA_TIMEOUT
595 },
596 [URTW_8187B_BULK_TX_EP12] = {
597 .type = UE_BULK,
598 .endpoint = 0xc,
599 .direction = UE_DIR_OUT,
600 .bufsize = URTW_TX_MAXSIZE,
601 .flags = {
602 .ext_buffer = 1,
603 .force_short_xfer = 1,
604 .pipe_bof = 1,
605 },
606 .callback = urtw_bulk_tx_callback,
607 .timeout = URTW_DATA_TIMEOUT
608 }
609};
610
611static const struct usb_config urtw_8187l_usbconfig[URTW_8187L_N_XFERS] = {
612 [URTW_8187L_BULK_RX] = {
613 .type = UE_BULK,
614 .endpoint = 0x81,
615 .direction = UE_DIR_IN,
616 .bufsize = MCLBYTES,
617 .flags = {
618 .ext_buffer = 1,
619 .pipe_bof = 1,
620 .short_xfer_ok = 1
621 },
622 .callback = urtw_bulk_rx_callback
623 },
624 [URTW_8187L_BULK_TX_LOW] = {
625 .type = UE_BULK,
626 .endpoint = 0x2,
627 .direction = UE_DIR_OUT,
628 .bufsize = URTW_TX_MAXSIZE,
629 .flags = {
630 .ext_buffer = 1,
631 .force_short_xfer = 1,
632 .pipe_bof = 1,
633 },
634 .callback = urtw_bulk_tx_callback,
635 .timeout = URTW_DATA_TIMEOUT
636 },
637 [URTW_8187L_BULK_TX_NORMAL] = {
638 .type = UE_BULK,
639 .endpoint = 0x3,
640 .direction = UE_DIR_OUT,
641 .bufsize = URTW_TX_MAXSIZE,
642 .flags = {
643 .ext_buffer = 1,
644 .force_short_xfer = 1,
645 .pipe_bof = 1,
646 },
647 .callback = urtw_bulk_tx_callback,
648 .timeout = URTW_DATA_TIMEOUT
649 },
650};
651
652static struct ieee80211vap *urtw_vap_create(struct ieee80211com *,
653 const char name[IFNAMSIZ], int unit, int opmode,
654 int flags, const uint8_t bssid[IEEE80211_ADDR_LEN],
655 const uint8_t mac[IEEE80211_ADDR_LEN]);
656static void urtw_vap_delete(struct ieee80211vap *);
657static void urtw_init(void *);
658static void urtw_stop(struct ifnet *, int);
659static void urtw_stop_locked(struct ifnet *, int);
660static int urtw_ioctl(struct ifnet *, u_long, caddr_t);
661static void urtw_start(struct ifnet *);
662static int urtw_alloc_rx_data_list(struct urtw_softc *);
663static int urtw_alloc_tx_data_list(struct urtw_softc *);
664static int urtw_raw_xmit(struct ieee80211_node *, struct mbuf *,
665 const struct ieee80211_bpf_params *);
666static void urtw_scan_start(struct ieee80211com *);
667static void urtw_scan_end(struct ieee80211com *);
668static void urtw_set_channel(struct ieee80211com *);
669static void urtw_update_mcast(struct ifnet *);
670static int urtw_tx_start(struct urtw_softc *,
671 struct ieee80211_node *, struct mbuf *,
672 struct urtw_data *, int);
673static int urtw_newstate(struct ieee80211vap *,
674 enum ieee80211_state, int);
675static void urtw_led_ch(void *);
676static void urtw_ledtask(void *, int);
677static void urtw_watchdog(void *);
678static void urtw_set_multi(void *);
679static int urtw_isbmode(uint16_t);
680static uint16_t urtw_rate2rtl(int);
681static uint16_t urtw_rtl2rate(int);
682static usb_error_t urtw_set_rate(struct urtw_softc *);
683static usb_error_t urtw_update_msr(struct urtw_softc *);
684static usb_error_t urtw_read8_c(struct urtw_softc *, int, uint8_t *);
685static usb_error_t urtw_read16_c(struct urtw_softc *, int, uint16_t *);
686static usb_error_t urtw_read32_c(struct urtw_softc *, int, uint32_t *);
687static usb_error_t urtw_write8_c(struct urtw_softc *, int, uint8_t);
688static usb_error_t urtw_write16_c(struct urtw_softc *, int, uint16_t);
689static usb_error_t urtw_write32_c(struct urtw_softc *, int, uint32_t);
690static usb_error_t urtw_eprom_cs(struct urtw_softc *, int);
691static usb_error_t urtw_eprom_ck(struct urtw_softc *);
692static usb_error_t urtw_eprom_sendbits(struct urtw_softc *, int16_t *,
693 int);
694static usb_error_t urtw_eprom_read32(struct urtw_softc *, uint32_t,
695 uint32_t *);
696static usb_error_t urtw_eprom_readbit(struct urtw_softc *, int16_t *);
697static usb_error_t urtw_eprom_writebit(struct urtw_softc *, int16_t);
698static usb_error_t urtw_get_macaddr(struct urtw_softc *);
699static usb_error_t urtw_get_txpwr(struct urtw_softc *);
700static usb_error_t urtw_get_rfchip(struct urtw_softc *);
701static usb_error_t urtw_led_init(struct urtw_softc *);
702static usb_error_t urtw_8185_rf_pins_enable(struct urtw_softc *);
703static usb_error_t urtw_8185_tx_antenna(struct urtw_softc *, uint8_t);
704static usb_error_t urtw_8187_write_phy(struct urtw_softc *, uint8_t,
705 uint32_t);
706static usb_error_t urtw_8187_write_phy_ofdm_c(struct urtw_softc *,
707 uint8_t, uint32_t);
708static usb_error_t urtw_8187_write_phy_cck_c(struct urtw_softc *, uint8_t,
709 uint32_t);
710static usb_error_t urtw_8225_setgain(struct urtw_softc *, int16_t);
711static usb_error_t urtw_8225_usb_init(struct urtw_softc *);
712static usb_error_t urtw_8225_write_c(struct urtw_softc *, uint8_t,
713 uint16_t);
714static usb_error_t urtw_8225_write_s16(struct urtw_softc *, uint8_t, int,
715 uint16_t *);
716static usb_error_t urtw_8225_read(struct urtw_softc *, uint8_t,
717 uint32_t *);
718static usb_error_t urtw_8225_rf_init(struct urtw_softc *);
719static usb_error_t urtw_8225_rf_set_chan(struct urtw_softc *, int);
720static usb_error_t urtw_8225_rf_set_sens(struct urtw_softc *, int);
721static usb_error_t urtw_8225_set_txpwrlvl(struct urtw_softc *, int);
722static usb_error_t urtw_8225_rf_stop(struct urtw_softc *);
723static usb_error_t urtw_8225v2_rf_init(struct urtw_softc *);
724static usb_error_t urtw_8225v2_rf_set_chan(struct urtw_softc *, int);
725static usb_error_t urtw_8225v2_set_txpwrlvl(struct urtw_softc *, int);
726static usb_error_t urtw_8225v2_setgain(struct urtw_softc *, int16_t);
727static usb_error_t urtw_8225_isv2(struct urtw_softc *, int *);
728static usb_error_t urtw_8225v2b_rf_init(struct urtw_softc *);
729static usb_error_t urtw_8225v2b_rf_set_chan(struct urtw_softc *, int);
730static usb_error_t urtw_read8e(struct urtw_softc *, int, uint8_t *);
731static usb_error_t urtw_write8e(struct urtw_softc *, int, uint8_t);
732static usb_error_t urtw_8180_set_anaparam(struct urtw_softc *, uint32_t);
733static usb_error_t urtw_8185_set_anaparam2(struct urtw_softc *, uint32_t);
734static usb_error_t urtw_intr_enable(struct urtw_softc *);
735static usb_error_t urtw_intr_disable(struct urtw_softc *);
736static usb_error_t urtw_reset(struct urtw_softc *);
737static usb_error_t urtw_led_on(struct urtw_softc *, int);
738static usb_error_t urtw_led_ctl(struct urtw_softc *, int);
739static usb_error_t urtw_led_blink(struct urtw_softc *);
740static usb_error_t urtw_led_mode0(struct urtw_softc *, int);
741static usb_error_t urtw_led_mode1(struct urtw_softc *, int);
742static usb_error_t urtw_led_mode2(struct urtw_softc *, int);
743static usb_error_t urtw_led_mode3(struct urtw_softc *, int);
744static usb_error_t urtw_rx_setconf(struct urtw_softc *);
745static usb_error_t urtw_rx_enable(struct urtw_softc *);
746static usb_error_t urtw_tx_enable(struct urtw_softc *sc);
747static void urtw_free_tx_data_list(struct urtw_softc *);
748static void urtw_free_rx_data_list(struct urtw_softc *);
749static void urtw_free_data_list(struct urtw_softc *,
750 struct urtw_data data[], int, int);
751static usb_error_t urtw_adapter_start(struct urtw_softc *);
752static usb_error_t urtw_adapter_start_b(struct urtw_softc *);
753static usb_error_t urtw_set_mode(struct urtw_softc *, uint32_t);
754static usb_error_t urtw_8187b_cmd_reset(struct urtw_softc *);
755static usb_error_t urtw_do_request(struct urtw_softc *,
756 struct usb_device_request *, void *);
757static usb_error_t urtw_8225v2b_set_txpwrlvl(struct urtw_softc *, int);
758static usb_error_t urtw_led_off(struct urtw_softc *, int);
759static void urtw_abort_xfers(struct urtw_softc *);
760static struct urtw_data *
761 urtw_getbuf(struct urtw_softc *sc);
762static int urtw_compute_txtime(uint16_t, uint16_t, uint8_t,
763 uint8_t);
764static void urtw_updateslot(struct ifnet *);
765static void urtw_updateslottask(void *, int);
766static void urtw_sysctl_node(struct urtw_softc *);
767
768static int
769urtw_match(device_t dev)
770{
771 struct usb_attach_arg *uaa = device_get_ivars(dev);
772
773 if (uaa->usb_mode != USB_MODE_HOST)
774 return (ENXIO);
775 if (uaa->info.bConfigIndex != URTW_CONFIG_INDEX)
776 return (ENXIO);
777 if (uaa->info.bIfaceIndex != URTW_IFACE_INDEX)
778 return (ENXIO);
779
780 return (usbd_lookup_id_by_uaa(urtw_devs, sizeof(urtw_devs), uaa));
781}
782
783static int
784urtw_attach(device_t dev)
785{
786 const struct usb_config *setup_start;
787 int ret = ENXIO;
788 struct urtw_softc *sc = device_get_softc(dev);
789 struct usb_attach_arg *uaa = device_get_ivars(dev);
790 struct ieee80211com *ic;
791 struct ifnet *ifp;
792 uint8_t bands, iface_index = URTW_IFACE_INDEX; /* XXX */
793 uint16_t n_setup;
794 uint32_t data;
795 usb_error_t error;
796
797 device_set_usb_desc(dev);
798
799 sc->sc_dev = dev;
800 sc->sc_udev = uaa->device;
801 if (USB_GET_DRIVER_INFO(uaa) == URTW_REV_RTL8187B)
802 sc->sc_flags |= URTW_RTL8187B;
803#ifdef URTW_DEBUG
804 sc->sc_debug = urtw_debug;
805#endif
806
807 mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev), MTX_NETWORK_LOCK,
808 MTX_DEF);
809 usb_callout_init_mtx(&sc->sc_led_ch, &sc->sc_mtx, 0);
810 TASK_INIT(&sc->sc_led_task, 0, urtw_ledtask, sc);
811 TASK_INIT(&sc->sc_updateslot_task, 0, urtw_updateslottask, sc);
812 callout_init(&sc->sc_watchdog_ch, 0);
813
814 if (sc->sc_flags & URTW_RTL8187B) {
815 setup_start = urtw_8187b_usbconfig;
816 n_setup = URTW_8187B_N_XFERS;
817 } else {
818 setup_start = urtw_8187l_usbconfig;
819 n_setup = URTW_8187L_N_XFERS;
820 }
821
822 error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_xfer,
823 setup_start, n_setup, sc, &sc->sc_mtx);
824 if (error) {
825 device_printf(dev, "could not allocate USB transfers, "
826 "err=%s\n", usbd_errstr(error));
827 ret = ENXIO;
828 goto fail0;
829 }
830
831 URTW_LOCK(sc);
832
833 urtw_read32_m(sc, URTW_RX, &data);
834 sc->sc_epromtype = (data & URTW_RX_9356SEL) ? URTW_EEPROM_93C56 :
835 URTW_EEPROM_93C46;
836
837 error = urtw_get_rfchip(sc);
838 if (error != 0)
839 goto fail;
840 error = urtw_get_macaddr(sc);
841 if (error != 0)
842 goto fail;
843 error = urtw_get_txpwr(sc);
844 if (error != 0)
845 goto fail;
846 error = urtw_led_init(sc);
847 if (error != 0)
848 goto fail;
849
850 URTW_UNLOCK(sc);
851
852 sc->sc_rts_retry = URTW_DEFAULT_RTS_RETRY;
853 sc->sc_tx_retry = URTW_DEFAULT_TX_RETRY;
854 sc->sc_currate = 3;
855 sc->sc_preamble_mode = urtw_preamble_mode;
856
857 ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
858 if (ifp == NULL) {
859 device_printf(sc->sc_dev, "can not allocate ifnet\n");
860 ret = ENOMEM;
861 goto fail1;
862 }
863
864 ifp->if_softc = sc;
865 if_initname(ifp, "urtw", device_get_unit(sc->sc_dev));
866 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
867 ifp->if_init = urtw_init;
868 ifp->if_ioctl = urtw_ioctl;
869 ifp->if_start = urtw_start;
870 /* XXX URTW_TX_DATA_LIST_COUNT */
871 IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
872 ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
873 IFQ_SET_READY(&ifp->if_snd);
874
875 ic = ifp->if_l2com;
876 ic->ic_ifp = ifp;
877 ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
878 ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
879
880 /* set device capabilities */
881 ic->ic_caps =
882 IEEE80211_C_STA | /* station mode */
883 IEEE80211_C_MONITOR | /* monitor mode supported */
884 IEEE80211_C_TXPMGT | /* tx power management */
885 IEEE80211_C_SHPREAMBLE | /* short preamble supported */
886 IEEE80211_C_SHSLOT | /* short slot time supported */
887 IEEE80211_C_BGSCAN | /* capable of bg scanning */
888 IEEE80211_C_WPA; /* 802.11i */
889
890 bands = 0;
891 setbit(&bands, IEEE80211_MODE_11B);
892 setbit(&bands, IEEE80211_MODE_11G);
893 ieee80211_init_channels(ic, NULL, &bands);
894
895 ieee80211_ifattach(ic, sc->sc_bssid);
896 ic->ic_raw_xmit = urtw_raw_xmit;
897 ic->ic_scan_start = urtw_scan_start;
898 ic->ic_scan_end = urtw_scan_end;
899 ic->ic_set_channel = urtw_set_channel;
900 ic->ic_updateslot = urtw_updateslot;
901 ic->ic_vap_create = urtw_vap_create;
902 ic->ic_vap_delete = urtw_vap_delete;
903 ic->ic_update_mcast = urtw_update_mcast;
904
905 ieee80211_radiotap_attach(ic,
906 &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
907 URTW_TX_RADIOTAP_PRESENT,
908 &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
909 URTW_RX_RADIOTAP_PRESENT);
910
911 urtw_sysctl_node(sc);
912
913 if (bootverbose)
914 ieee80211_announce(ic);
915 return (0);
916
917fail: URTW_UNLOCK(sc);
918fail1: usbd_transfer_unsetup(sc->sc_xfer, (sc->sc_flags & URTW_RTL8187B) ?
919 URTW_8187B_N_XFERS : URTW_8187L_N_XFERS);
920fail0:
921 return (ret);
922}
923
924static int
925urtw_detach(device_t dev)
926{
927 struct urtw_softc *sc = device_get_softc(dev);
928 struct ifnet *ifp = sc->sc_ifp;
929 struct ieee80211com *ic = ifp->if_l2com;
930
931 if (!device_is_attached(dev))
932 return (0);
933
934 urtw_stop(ifp, 1);
935 ieee80211_draintask(ic, &sc->sc_updateslot_task);
936 ieee80211_draintask(ic, &sc->sc_led_task);
937
938 usb_callout_drain(&sc->sc_led_ch);
939 callout_drain(&sc->sc_watchdog_ch);
940
941 usbd_transfer_unsetup(sc->sc_xfer, (sc->sc_flags & URTW_RTL8187B) ?
942 URTW_8187B_N_XFERS : URTW_8187L_N_XFERS);
943 ieee80211_ifdetach(ic);
944
945 urtw_free_tx_data_list(sc);
946 urtw_free_rx_data_list(sc);
947
948 if_free(ifp);
949 mtx_destroy(&sc->sc_mtx);
950
951 return (0);
952}
953
954static void
955urtw_free_tx_data_list(struct urtw_softc *sc)
956{
957
958 urtw_free_data_list(sc, sc->sc_tx, URTW_TX_DATA_LIST_COUNT, 0);
959}
960
961static void
962urtw_free_rx_data_list(struct urtw_softc *sc)
963{
964
965 urtw_free_data_list(sc, sc->sc_rx, URTW_RX_DATA_LIST_COUNT, 1);
966}
967
968static void
969urtw_free_data_list(struct urtw_softc *sc, struct urtw_data data[], int ndata,
970 int fillmbuf)
971{
972 int i;
973
974 for (i = 0; i < ndata; i++) {
975 struct urtw_data *dp = &data[i];
976
977 if (fillmbuf == 1) {
978 if (dp->m != NULL) {
979 m_freem(dp->m);
980 dp->m = NULL;
981 dp->buf = NULL;
982 }
983 } else {
984 if (dp->buf != NULL) {
985 free(dp->buf, M_USBDEV);
986 dp->buf = NULL;
987 }
988 }
989 if (dp->ni != NULL) {
990 ieee80211_free_node(dp->ni);
991 dp->ni = NULL;
992 }
993 }
994}
995
996static struct ieee80211vap *
997urtw_vap_create(struct ieee80211com *ic,
998 const char name[IFNAMSIZ], int unit, int opmode, int flags,
999 const uint8_t bssid[IEEE80211_ADDR_LEN],
1000 const uint8_t mac[IEEE80211_ADDR_LEN])
1001{
1002 struct urtw_vap *uvp;
1003 struct ieee80211vap *vap;
1004
1005 if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
1006 return (NULL);
1007 uvp = (struct urtw_vap *) malloc(sizeof(struct urtw_vap),
1008 M_80211_VAP, M_NOWAIT | M_ZERO);
1009 if (uvp == NULL)
1010 return (NULL);
1011 vap = &uvp->vap;
1012 /* enable s/w bmiss handling for sta mode */
1013 ieee80211_vap_setup(ic, vap, name, unit, opmode,
1014 flags | IEEE80211_CLONE_NOBEACONS, bssid, mac);
1015
1016 /* override state transition machine */
1017 uvp->newstate = vap->iv_newstate;
1018 vap->iv_newstate = urtw_newstate;
1019
1020 /* complete setup */
1021 ieee80211_vap_attach(vap, ieee80211_media_change,
1022 ieee80211_media_status);
1023 ic->ic_opmode = opmode;
1024 return (vap);
1025}
1026
1027static void
1028urtw_vap_delete(struct ieee80211vap *vap)
1029{
1030 struct urtw_vap *uvp = URTW_VAP(vap);
1031
1032 ieee80211_vap_detach(vap);
1033 free(uvp, M_80211_VAP);
1034}
1035
1036static void
1037urtw_init_locked(void *arg)
1038{
1039 int ret;
1040 struct urtw_softc *sc = arg;
1041 struct ifnet *ifp = sc->sc_ifp;
1042 usb_error_t error;
1043
1044 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1045 urtw_stop_locked(ifp, 0);
1046
1047 error = (sc->sc_flags & URTW_RTL8187B) ? urtw_adapter_start_b(sc) :
1048 urtw_adapter_start(sc);
1049 if (error != 0)
1050 goto fail;
1051
1052 /* reset softc variables */
1053 sc->sc_txtimer = 0;
1054
1055 if (!(sc->sc_flags & URTW_INIT_ONCE)) {
1056 ret = urtw_alloc_rx_data_list(sc);
1057 if (error != 0)
1058 goto fail;
1059 ret = urtw_alloc_tx_data_list(sc);
1060 if (error != 0)
1061 goto fail;
1062 sc->sc_flags |= URTW_INIT_ONCE;
1063 }
1064
1065 error = urtw_rx_enable(sc);
1066 if (error != 0)
1067 goto fail;
1068 error = urtw_tx_enable(sc);
1069 if (error != 0)
1070 goto fail;
1071
1072 if (sc->sc_flags & URTW_RTL8187B)
1073 usbd_transfer_start(sc->sc_xfer[URTW_8187B_BULK_TX_STATUS]);
1074
1075 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
1076 ifp->if_drv_flags |= IFF_DRV_RUNNING;
1077
1078 callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc);
1079fail:
1080 return;
1081}
1082
1083static void
1084urtw_init(void *arg)
1085{
1086 struct urtw_softc *sc = arg;
1087
1088 URTW_LOCK(sc);
1089 urtw_init_locked(arg);
1090 URTW_UNLOCK(sc);
1091}
1092
1093static usb_error_t
1094urtw_adapter_start_b(struct urtw_softc *sc)
1095{
1096#define N(a) (sizeof(a) / sizeof((a)[0]))
1097 uint8_t data8;
1098 usb_error_t error;
1099
1100 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
1101 if (error)
1102 goto fail;
1103
1104 urtw_read8_m(sc, URTW_CONFIG3, &data8);
1105 urtw_write8_m(sc, URTW_CONFIG3,
1106 data8 | URTW_CONFIG3_ANAPARAM_WRITE | URTW_CONFIG3_GNT_SELECT);
1107 urtw_write32_m(sc, URTW_ANAPARAM2, URTW_8187B_8225_ANAPARAM2_ON);
1108 urtw_write32_m(sc, URTW_ANAPARAM, URTW_8187B_8225_ANAPARAM_ON);
1109 urtw_write8_m(sc, URTW_ANAPARAM3, URTW_8187B_8225_ANAPARAM3_ON);
1110
1111 urtw_write8_m(sc, 0x61, 0x10);
1112 urtw_read8_m(sc, 0x62, &data8);
1113 urtw_write8_m(sc, 0x62, data8 & ~(1 << 5));
1114 urtw_write8_m(sc, 0x62, data8 | (1 << 5));
1115
1116 urtw_read8_m(sc, URTW_CONFIG3, &data8);
1117 data8 &= ~URTW_CONFIG3_ANAPARAM_WRITE;
1118 urtw_write8_m(sc, URTW_CONFIG3, data8);
1119
1120 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
1121 if (error)
1122 goto fail;
1123
1124 error = urtw_8187b_cmd_reset(sc);
1125 if (error)
1126 goto fail;
1127
1128 error = sc->sc_rf_init(sc);
1129 if (error != 0)
1130 goto fail;
1131 urtw_write8_m(sc, URTW_CMD, URTW_CMD_RX_ENABLE | URTW_CMD_TX_ENABLE);
1132
1133 /* fix RTL8187B RX stall */
1134 error = urtw_intr_enable(sc);
1135 if (error)
1136 goto fail;
1137
1138 error = urtw_write8e(sc, 0x41, 0xf4);
1139 if (error)
1140 goto fail;
1141 error = urtw_write8e(sc, 0x40, 0x00);
1142 if (error)
1143 goto fail;
1144 error = urtw_write8e(sc, 0x42, 0x00);
1145 if (error)
1146 goto fail;
1147 error = urtw_write8e(sc, 0x42, 0x01);
1148 if (error)
1149 goto fail;
1150 error = urtw_write8e(sc, 0x40, 0x0f);
1151 if (error)
1152 goto fail;
1153 error = urtw_write8e(sc, 0x42, 0x00);
1154 if (error)
1155 goto fail;
1156 error = urtw_write8e(sc, 0x42, 0x01);
1157 if (error)
1158 goto fail;
1159
1160 urtw_read8_m(sc, 0xdb, &data8);
1161 urtw_write8_m(sc, 0xdb, data8 | (1 << 2));
1162 urtw_write16_m(sc, 0x372, 0x59fa);
1163 urtw_write16_m(sc, 0x374, 0x59d2);
1164 urtw_write16_m(sc, 0x376, 0x59d2);
1165 urtw_write16_m(sc, 0x378, 0x19fa);
1166 urtw_write16_m(sc, 0x37a, 0x19fa);
1167 urtw_write16_m(sc, 0x37c, 0x00d0);
1168 urtw_write8_m(sc, 0x61, 0);
1169
1170 urtw_write8_m(sc, 0x180, 0x0f);
1171 urtw_write8_m(sc, 0x183, 0x03);
1172 urtw_write8_m(sc, 0xda, 0x10);
1173 urtw_write8_m(sc, 0x24d, 0x08);
1174 urtw_write32_m(sc, URTW_HSSI_PARA, 0x0600321b);
1175
1176 urtw_write16_m(sc, 0x1ec, 0x800); /* RX MAX SIZE */
1177fail:
1178 return (error);
1179#undef N
1180}
1181
1182static usb_error_t
1183urtw_adapter_start(struct urtw_softc *sc)
1184{
1185 usb_error_t error;
1186
1187 error = urtw_reset(sc);
1188 if (error)
1189 goto fail;
1190
1191 urtw_write8_m(sc, URTW_ADDR_MAGIC1, 0);
1192 urtw_write8_m(sc, URTW_GPIO, 0);
1193
1194 /* for led */
1195 urtw_write8_m(sc, URTW_ADDR_MAGIC1, 4);
1196 error = urtw_led_ctl(sc, URTW_LED_CTL_POWER_ON);
1197 if (error != 0)
1198 goto fail;
1199
1200 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
1201 if (error)
1202 goto fail;
1203 /* applying MAC address again. */
1204 urtw_write32_m(sc, URTW_MAC0, ((uint32_t *)sc->sc_bssid)[0]);
1205 urtw_write16_m(sc, URTW_MAC4, ((uint32_t *)sc->sc_bssid)[1] & 0xffff);
1206 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
1207 if (error)
1208 goto fail;
1209
1210 error = urtw_update_msr(sc);
1211 if (error)
1212 goto fail;
1213
1214 urtw_write32_m(sc, URTW_INT_TIMEOUT, 0);
1215 urtw_write8_m(sc, URTW_WPA_CONFIG, 0);
1216 urtw_write8_m(sc, URTW_RATE_FALLBACK, URTW_RATE_FALLBACK_ENABLE | 0x1);
1217 error = urtw_set_rate(sc);
1218 if (error != 0)
1219 goto fail;
1220
1221 error = sc->sc_rf_init(sc);
1222 if (error != 0)
1223 goto fail;
1224 if (sc->sc_rf_set_sens != NULL)
1225 sc->sc_rf_set_sens(sc, sc->sc_sens);
1226
1227 /* XXX correct? to call write16 */
1228 urtw_write16_m(sc, URTW_PSR, 1);
1229 urtw_write16_m(sc, URTW_ADDR_MAGIC2, 0x10);
1230 urtw_write8_m(sc, URTW_TALLY_SEL, 0x80);
1231 urtw_write8_m(sc, URTW_ADDR_MAGIC3, 0x60);
1232 /* XXX correct? to call write16 */
1233 urtw_write16_m(sc, URTW_PSR, 0);
1234 urtw_write8_m(sc, URTW_ADDR_MAGIC1, 4);
1235
1236 error = urtw_intr_enable(sc);
1237 if (error != 0)
1238 goto fail;
1239
1240fail:
1241 return (error);
1242}
1243
1244static usb_error_t
1245urtw_set_mode(struct urtw_softc *sc, uint32_t mode)
1246{
1247 uint8_t data;
1248 usb_error_t error;
1249
1250 urtw_read8_m(sc, URTW_EPROM_CMD, &data);
1251 data = (data & ~URTW_EPROM_CMD_MASK) | (mode << URTW_EPROM_CMD_SHIFT);
1252 data = data & ~(URTW_EPROM_CS | URTW_EPROM_CK);
1253 urtw_write8_m(sc, URTW_EPROM_CMD, data);
1254fail:
1255 return (error);
1256}
1257
1258static usb_error_t
1259urtw_8187b_cmd_reset(struct urtw_softc *sc)
1260{
1261 int i;
1262 uint8_t data8;
1263 usb_error_t error;
1264
1265 /* XXX the code can be duplicate with urtw_reset(). */
1266 urtw_read8_m(sc, URTW_CMD, &data8);
1267 data8 = (data8 & 0x2) | URTW_CMD_RST;
1268 urtw_write8_m(sc, URTW_CMD, data8);
1269
1270 for (i = 0; i < 20; i++) {
1271 usb_pause_mtx(&sc->sc_mtx, 2);
1272 urtw_read8_m(sc, URTW_CMD, &data8);
1273 if (!(data8 & URTW_CMD_RST))
1274 break;
1275 }
1276 if (i >= 20) {
1277 device_printf(sc->sc_dev, "reset timeout\n");
1278 goto fail;
1279 }
1280fail:
1281 return (error);
1282}
1283
1284static usb_error_t
1285urtw_do_request(struct urtw_softc *sc,
1286 struct usb_device_request *req, void *data)
1287{
1288 usb_error_t err;
1289 int ntries = 10;
1290
1291 URTW_ASSERT_LOCKED(sc);
1292
1293 while (ntries--) {
1294 err = usbd_do_request_flags(sc->sc_udev, &sc->sc_mtx,
1295 req, data, 0, NULL, 250 /* ms */);
1296 if (err == 0)
1297 break;
1298
1299 DPRINTF(sc, URTW_DEBUG_INIT,
1300 "Control request failed, %s (retrying)\n",
1301 usbd_errstr(err));
1302 usb_pause_mtx(&sc->sc_mtx, hz / 100);
1303 }
1304 return (err);
1305}
1306
1307static void
1308urtw_stop_locked(struct ifnet *ifp, int disable)
1309{
1310 struct urtw_softc *sc = ifp->if_softc;
1311 uint8_t data8;
1312 usb_error_t error;
1313
1314 (void)disable;
1315 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
1316
1317 error = urtw_intr_disable(sc);
1318 if (error)
1319 goto fail;
1320 urtw_read8_m(sc, URTW_CMD, &data8);
1321 data8 &= ~(URTW_CMD_RX_ENABLE | URTW_CMD_TX_ENABLE);
1322 urtw_write8_m(sc, URTW_CMD, data8);
1323
1324 error = sc->sc_rf_stop(sc);
1325 if (error != 0)
1326 goto fail;
1327
1328 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
1329 if (error)
1330 goto fail;
1331 urtw_read8_m(sc, URTW_CONFIG4, &data8);
1332 urtw_write8_m(sc, URTW_CONFIG4, data8 | URTW_CONFIG4_VCOOFF);
1333 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
1334 if (error)
1335 goto fail;
1336fail:
1337 if (error)
1338 device_printf(sc->sc_dev, "failed to stop (%s)\n",
1339 usbd_errstr(error));
1340
1341 usb_callout_stop(&sc->sc_led_ch);
1342 callout_stop(&sc->sc_watchdog_ch);
1343
1344 urtw_abort_xfers(sc);
1345}
1346
1347static void
1348urtw_stop(struct ifnet *ifp, int disable)
1349{
1350 struct urtw_softc *sc = ifp->if_softc;
1351
1352 URTW_LOCK(sc);
1353 urtw_stop_locked(ifp, disable);
1354 URTW_UNLOCK(sc);
1355}
1356
1357static void
1358urtw_abort_xfers(struct urtw_softc *sc)
1359{
1360 int i, max;
1361
1362 URTW_ASSERT_LOCKED(sc);
1363
1364 max = (sc->sc_flags & URTW_RTL8187B) ? URTW_8187B_N_XFERS :
1365 URTW_8187L_N_XFERS;
1366
1367 /* abort any pending transfers */
1368 for (i = 0; i < max; i++)
1369 usbd_transfer_stop(sc->sc_xfer[i]);
1370}
1371
1372static int
1373urtw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1374{
1375 struct urtw_softc *sc = ifp->if_softc;
1376 struct ieee80211com *ic = ifp->if_l2com;
1377 struct ifreq *ifr = (struct ifreq *) data;
1378 int error = 0, startall = 0;
1379
1380 switch (cmd) {
1381 case SIOCSIFFLAGS:
1382 if (ifp->if_flags & IFF_UP) {
1383 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
1384 if ((ifp->if_flags ^ sc->sc_if_flags) &
1385 (IFF_ALLMULTI | IFF_PROMISC))
1386 urtw_set_multi(sc);
1387 } else {
1388 urtw_init(ifp->if_softc);
1389 startall = 1;
1390 }
1391 } else {
1392 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1393 urtw_stop(ifp, 1);
1394 }
1395 sc->sc_if_flags = ifp->if_flags;
1396 if (startall)
1397 ieee80211_start_all(ic);
1398 break;
1399 case SIOCGIFMEDIA:
1400 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
1401 break;
1402 case SIOCGIFADDR:
1403 error = ether_ioctl(ifp, cmd, data);
1404 break;
1405 default:
1406 error = EINVAL;
1407 break;
1408 }
1409
1410 return (error);
1411}
1412
1413static void
1414urtw_start(struct ifnet *ifp)
1415{
1416 struct urtw_data *bf;
1417 struct urtw_softc *sc = ifp->if_softc;
1418 struct ieee80211_node *ni;
1419 struct mbuf *m;
1420
1421 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
1422 return;
1423
1424 URTW_LOCK(sc);
1425 for (;;) {
1426 IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
1427 if (m == NULL)
1428 break;
1429 bf = urtw_getbuf(sc);
1430 if (bf == NULL) {
1431 IFQ_DRV_PREPEND(&ifp->if_snd, m);
1432 break;
1433 }
1434
1435 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
1436 m->m_pkthdr.rcvif = NULL;
1437
1438 if (urtw_tx_start(sc, ni, m, bf, URTW_PRIORITY_NORMAL) != 0) {
1439 ifp->if_oerrors++;
1440 STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
1441 ieee80211_free_node(ni);
1442 break;
1443 }
1444
1445 sc->sc_txtimer = 5;
1446 callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc);
1447 }
1448 URTW_UNLOCK(sc);
1449}
1450
1451static int
1452urtw_alloc_data_list(struct urtw_softc *sc, struct urtw_data data[],
1453 int ndata, int maxsz, int fillmbuf)
1454{
1455 int i, error;
1456
1457 for (i = 0; i < ndata; i++) {
1458 struct urtw_data *dp = &data[i];
1459
1460 dp->sc = sc;
1461 if (fillmbuf) {
1462 dp->m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
1463 if (dp->m == NULL) {
1464 device_printf(sc->sc_dev,
1465 "could not allocate rx mbuf\n");
1466 error = ENOMEM;
1467 goto fail;
1468 }
1469 dp->buf = mtod(dp->m, uint8_t *);
1470 } else {
1471 dp->m = NULL;
1472 dp->buf = malloc(maxsz, M_USBDEV, M_NOWAIT);
1473 if (dp->buf == NULL) {
1474 device_printf(sc->sc_dev,
1475 "could not allocate buffer\n");
1476 error = ENOMEM;
1477 goto fail;
1478 }
1479 if (((unsigned long)dp->buf) % 4)
1480 device_printf(sc->sc_dev,
1481 "warn: unaligned buffer %p\n", dp->buf);
1482 }
1483 dp->ni = NULL;
1484 }
1485
1486 return 0;
1487
1488fail: urtw_free_data_list(sc, data, ndata, fillmbuf);
1489 return error;
1490}
1491
1492static int
1493urtw_alloc_rx_data_list(struct urtw_softc *sc)
1494{
1495 int error, i;
1496
1497 error = urtw_alloc_data_list(sc,
1498 sc->sc_rx, URTW_RX_DATA_LIST_COUNT, MCLBYTES, 1 /* mbufs */);
1499 if (error != 0)
1500 return (error);
1501
1502 STAILQ_INIT(&sc->sc_rx_active);
1503 STAILQ_INIT(&sc->sc_rx_inactive);
1504
1505 for (i = 0; i < URTW_RX_DATA_LIST_COUNT; i++)
1506 STAILQ_INSERT_HEAD(&sc->sc_rx_inactive, &sc->sc_rx[i], next);
1507
1508 return (0);
1509}
1510
1511static int
1512urtw_alloc_tx_data_list(struct urtw_softc *sc)
1513{
1514 int error, i;
1515
1516 error = urtw_alloc_data_list(sc,
1517 sc->sc_tx, URTW_TX_DATA_LIST_COUNT, URTW_TX_MAXSIZE,
1518 0 /* no mbufs */);
1519 if (error != 0)
1520 return (error);
1521
1522 STAILQ_INIT(&sc->sc_tx_active);
1523 STAILQ_INIT(&sc->sc_tx_inactive);
1524 STAILQ_INIT(&sc->sc_tx_pending);
1525
1526 for (i = 0; i < URTW_TX_DATA_LIST_COUNT; i++)
1527 STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, &sc->sc_tx[i],
1528 next);
1529
1530 return (0);
1531}
1532
1533static int
1534urtw_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
1535 const struct ieee80211_bpf_params *params)
1536{
1537 struct ieee80211com *ic = ni->ni_ic;
1538 struct ifnet *ifp = ic->ic_ifp;
1539 struct urtw_data *bf;
1540 struct urtw_softc *sc = ifp->if_softc;
1541
1542 /* prevent management frames from being sent if we're not ready */
1543 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
1544 m_freem(m);
1545 ieee80211_free_node(ni);
1546 return ENETDOWN;
1547 }
1548 URTW_LOCK(sc);
1549 bf = urtw_getbuf(sc);
1550 if (bf == NULL) {
1551 ieee80211_free_node(ni);
1552 m_freem(m);
1553 URTW_UNLOCK(sc);
1554 return (ENOBUFS); /* XXX */
1555 }
1556
1557 ifp->if_opackets++;
1558 if (urtw_tx_start(sc, ni, m, bf, URTW_PRIORITY_LOW) != 0) {
1559 ieee80211_free_node(ni);
1560 ifp->if_oerrors++;
1561 STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
1562 URTW_UNLOCK(sc);
1563 return (EIO);
1564 }
1565 URTW_UNLOCK(sc);
1566
1567 sc->sc_txtimer = 5;
1568 return (0);
1569}
1570
1571static void
1572urtw_scan_start(struct ieee80211com *ic)
1573{
1574
1575 /* XXX do nothing? */
1576}
1577
1578static void
1579urtw_scan_end(struct ieee80211com *ic)
1580{
1581
1582 /* XXX do nothing? */
1583}
1584
1585static void
1586urtw_set_channel(struct ieee80211com *ic)
1587{
1588 struct urtw_softc *sc = ic->ic_ifp->if_softc;
1589 struct ifnet *ifp = sc->sc_ifp;
1590 uint32_t data, orig;
1591 usb_error_t error;
1592
1593 /*
1594 * if the user set a channel explicitly using ifconfig(8) this function
1595 * can be called earlier than we're expected that in some cases the
1596 * initialization would be failed if setting a channel is called before
1597 * the init have done.
1598 */
1599 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
1600 return;
1601
1602 if (sc->sc_curchan != NULL && sc->sc_curchan == ic->ic_curchan)
1603 return;
1604
1605 URTW_LOCK(sc);
1606
1607 /*
1608 * during changing th channel we need to temporarily be disable
1609 * TX.
1610 */
1611 urtw_read32_m(sc, URTW_TX_CONF, &orig);
1612 data = orig & ~URTW_TX_LOOPBACK_MASK;
1613 urtw_write32_m(sc, URTW_TX_CONF, data | URTW_TX_LOOPBACK_MAC);
1614
1615 error = sc->sc_rf_set_chan(sc, ieee80211_chan2ieee(ic, ic->ic_curchan));
1616 if (error != 0)
1617 goto fail;
1618 usb_pause_mtx(&sc->sc_mtx, 10);
1619 urtw_write32_m(sc, URTW_TX_CONF, orig);
1620
1621 urtw_write16_m(sc, URTW_ATIM_WND, 2);
1622 urtw_write16_m(sc, URTW_ATIM_TR_ITV, 100);
1623 urtw_write16_m(sc, URTW_BEACON_INTERVAL, 100);
1624 urtw_write16_m(sc, URTW_BEACON_INTERVAL_TIME, 100);
1625
1626fail:
1627 URTW_UNLOCK(sc);
1628
1629 sc->sc_curchan = ic->ic_curchan;
1630
1631 if (error != 0)
1632 device_printf(sc->sc_dev, "could not change the channel\n");
1633}
1634
1635static void
1636urtw_update_mcast(struct ifnet *ifp)
1637{
1638
1639 /* XXX do nothing? */
1640}
1641
1642static int
1643urtw_tx_start(struct urtw_softc *sc, struct ieee80211_node *ni, struct mbuf *m0,
1644 struct urtw_data *data, int prior)
1645{
1646 struct ifnet *ifp = sc->sc_ifp;
1647 struct ieee80211_frame *wh = mtod(m0, struct ieee80211_frame *);
1648 struct ieee80211_key *k;
1649 const struct ieee80211_txparam *tp;
1650 struct ieee80211com *ic = ifp->if_l2com;
1651 struct ieee80211vap *vap = ni->ni_vap;
1652 struct usb_xfer *rtl8187b_pipes[URTW_8187B_TXPIPE_MAX] = {
1653 sc->sc_xfer[URTW_8187B_BULK_TX_BE],
1654 sc->sc_xfer[URTW_8187B_BULK_TX_BK],
1655 sc->sc_xfer[URTW_8187B_BULK_TX_VI],
1656 sc->sc_xfer[URTW_8187B_BULK_TX_VO]
1657 };
1658 struct usb_xfer *xfer;
1659 int dur = 0, rtsdur = 0, rtsenable = 0, ctsenable = 0, rate,
1660 pkttime = 0, txdur = 0, isshort = 0, xferlen;
1661 uint16_t acktime, rtstime, ctstime;
1662 uint32_t flags;
1663 usb_error_t error;
1664
1665 URTW_ASSERT_LOCKED(sc);
1666
1667 /*
1668 * Software crypto.
1669 */
1670 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
1671 k = ieee80211_crypto_encap(ni, m0);
1672 if (k == NULL) {
1673 device_printf(sc->sc_dev,
1674 "ieee80211_crypto_encap returns NULL.\n");
1675 /* XXX we don't expect the fragmented frames */
1676 m_freem(m0);
1677 return (ENOBUFS);
1678 }
1679
1680 /* in case packet header moved, reset pointer */
1681 wh = mtod(m0, struct ieee80211_frame *);
1682 }
1683
1684 if (ieee80211_radiotap_active_vap(vap)) {
1685 struct urtw_tx_radiotap_header *tap = &sc->sc_txtap;
1686
1687 /* XXX Are variables correct? */
1688 tap->wt_flags = 0;
1689 tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
1690 tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
1691
1692 ieee80211_radiotap_tx(vap, m0);
1693 }
1694
1695 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_MGT ||
1696 (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL) {
1697 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
1698 rate = tp->mgmtrate;
1699 } else {
1700 tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)];
1701 /* for data frames */
1702 if (IEEE80211_IS_MULTICAST(wh->i_addr1))
1703 rate = tp->mcastrate;
1704 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
1705 rate = tp->ucastrate;
1706 else
1707 rate = urtw_rtl2rate(sc->sc_currate);
1708 }
1709
1710 sc->sc_stats.txrates[sc->sc_currate]++;
1711
1712 if (IEEE80211_IS_MULTICAST(wh->i_addr1))
1713 txdur = pkttime = urtw_compute_txtime(m0->m_pkthdr.len +
1714 IEEE80211_CRC_LEN, rate, 0, 0);
1715 else {
1716 acktime = urtw_compute_txtime(14, 2,0, 0);
1717 if ((m0->m_pkthdr.len + 4) > vap->iv_rtsthreshold) {
1718 rtsenable = 1;
1719 ctsenable = 0;
1720 rtstime = urtw_compute_txtime(URTW_ACKCTS_LEN, 2, 0, 0);
1721 ctstime = urtw_compute_txtime(14, 2, 0, 0);
1722 pkttime = urtw_compute_txtime(m0->m_pkthdr.len +
1723 IEEE80211_CRC_LEN, rate, 0, isshort);
1724 rtsdur = ctstime + pkttime + acktime +
1725 3 * URTW_ASIFS_TIME;
1726 txdur = rtstime + rtsdur;
1727 } else {
1728 rtsenable = ctsenable = rtsdur = 0;
1729 pkttime = urtw_compute_txtime(m0->m_pkthdr.len +
1730 IEEE80211_CRC_LEN, rate, 0, isshort);
1731 txdur = pkttime + URTW_ASIFS_TIME + acktime;
1732 }
1733
1734 if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG)
1735 dur = urtw_compute_txtime(m0->m_pkthdr.len +
1736 IEEE80211_CRC_LEN, rate, 0, isshort) +
1737 3 * URTW_ASIFS_TIME +
1738 2 * acktime;
1739 else
1740 dur = URTW_ASIFS_TIME + acktime;
1741 }
1742 *(uint16_t *)wh->i_dur = htole16(dur);
1743
1744 xferlen = m0->m_pkthdr.len;
1745 xferlen += (sc->sc_flags & URTW_RTL8187B) ? (4 * 8) : (4 * 3);
1746 if ((0 == xferlen % 64) || (0 == xferlen % 512))
1747 xferlen += 1;
1748
1749 bzero(data->buf, URTW_TX_MAXSIZE);
1750 flags = m0->m_pkthdr.len & 0xfff;
1751 flags |= URTW_TX_FLAG_NO_ENC;
1752 if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
1753 (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE) &&
1754 (sc->sc_preamble_mode == URTW_PREAMBLE_MODE_SHORT) &&
1755 (sc->sc_currate != 0))
1756 flags |= URTW_TX_FLAG_SPLCP;
1757 if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG)
1758 flags |= URTW_TX_FLAG_MOREFRAG;
1759
1760 flags |= (sc->sc_currate & 0xf) << URTW_TX_FLAG_TXRATE_SHIFT;
1761
1762 if (sc->sc_flags & URTW_RTL8187B) {
1763 struct urtw_8187b_txhdr *tx;
1764
1765 tx = (struct urtw_8187b_txhdr *)data->buf;
1766 if (ctsenable)
1767 flags |= URTW_TX_FLAG_CTS;
1768 if (rtsenable) {
1769 flags |= URTW_TX_FLAG_RTS;
1770 flags |= (urtw_rate2rtl(11) & 0xf) <<
1771 URTW_TX_FLAG_RTSRATE_SHIFT;
1772 tx->rtsdur = rtsdur;
1773 }
1774 tx->flag = htole32(flags);
1775 tx->txdur = txdur;
1776 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
1777 IEEE80211_FC0_TYPE_MGT &&
1778 (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) ==
1779 IEEE80211_FC0_SUBTYPE_PROBE_RESP)
1780 tx->retry = 1;
1781 else
1782 tx->retry = URTW_TX_MAXRETRY;
1783 m_copydata(m0, 0, m0->m_pkthdr.len, (uint8_t *)(tx + 1));
1784 } else {
1785 struct urtw_8187l_txhdr *tx;
1786
1787 tx = (struct urtw_8187l_txhdr *)data->buf;
1788 if (rtsenable) {
1789 flags |= URTW_TX_FLAG_RTS;
1790 tx->rtsdur = rtsdur;
1791 }
1792 flags |= (urtw_rate2rtl(11) & 0xf) << URTW_TX_FLAG_RTSRATE_SHIFT;
1793 tx->flag = htole32(flags);
1794 tx->retry = 3; /* CW minimum */
1795 tx->retry = 7 << 4; /* CW maximum */
1796 tx->retry = URTW_TX_MAXRETRY << 8; /* retry limitation */
1797 m_copydata(m0, 0, m0->m_pkthdr.len, (uint8_t *)(tx + 1));
1798 }
1799
1800 data->buflen = xferlen;
1801 data->ni = ni;
1802 data->m = m0;
1803
1804 if (sc->sc_flags & URTW_RTL8187B) {
1805 switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) {
1806 case IEEE80211_FC0_TYPE_CTL:
1807 case IEEE80211_FC0_TYPE_MGT:
1808 xfer = sc->sc_xfer[URTW_8187B_BULK_TX_EP12];
1809 break;
1810 default:
1811 KASSERT(M_WME_GETAC(m0) < URTW_8187B_TXPIPE_MAX,
1812 ("unsupported WME pipe %d", M_WME_GETAC(m0)));
1813 xfer = rtl8187b_pipes[M_WME_GETAC(m0)];
1814 break;
1815 }
1816 } else
1817 xfer = (prior == URTW_PRIORITY_LOW) ?
1818 sc->sc_xfer[URTW_8187L_BULK_TX_LOW] :
1819 sc->sc_xfer[URTW_8187L_BULK_TX_NORMAL];
1820
1821 STAILQ_INSERT_TAIL(&sc->sc_tx_pending, data, next);
1822 usbd_transfer_start(xfer);
1823
1824 error = urtw_led_ctl(sc, URTW_LED_CTL_TX);
1825 if (error != 0)
1826 device_printf(sc->sc_dev, "could not control LED (%d)\n",
1827 error);
1828 return (0);
1829}
1830
1831static int
1832urtw_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
1833{
1834 struct ieee80211_node *ni = vap->iv_bss;
1835 struct ieee80211com *ic = vap->iv_ic;
1836 struct urtw_softc *sc = ic->ic_ifp->if_softc;
1837 struct urtw_vap *uvp = URTW_VAP(vap);
1838 usb_error_t error = 0;
1839
1840 DPRINTF(sc, URTW_DEBUG_STATE, "%s: %s -> %s\n", __func__,
1841 ieee80211_state_name[vap->iv_state],
1842 ieee80211_state_name[nstate]);
1843
1844 sc->sc_state = nstate;
1845
1846 IEEE80211_UNLOCK(ic);
1847 URTW_LOCK(sc);
1848 usb_callout_stop(&sc->sc_led_ch);
1849 callout_stop(&sc->sc_watchdog_ch);
1850
1851 switch (nstate) {
1852 case IEEE80211_S_INIT:
1853 case IEEE80211_S_SCAN:
1854 case IEEE80211_S_AUTH:
1855 case IEEE80211_S_ASSOC:
1856 break;
1857 case IEEE80211_S_RUN:
1858 /* setting bssid. */
1859 urtw_write32_m(sc, URTW_BSSID, ((uint32_t *)ni->ni_bssid)[0]);
1860 urtw_write16_m(sc, URTW_BSSID + 4,
1861 ((uint16_t *)ni->ni_bssid)[2]);
1862 urtw_update_msr(sc);
1863 /* XXX maybe the below would be incorrect. */
1864 urtw_write16_m(sc, URTW_ATIM_WND, 2);
1865 urtw_write16_m(sc, URTW_ATIM_TR_ITV, 100);
1866 urtw_write16_m(sc, URTW_BEACON_INTERVAL, 0x64);
1867 urtw_write16_m(sc, URTW_BEACON_INTERVAL_TIME, 100);
1868 error = urtw_led_ctl(sc, URTW_LED_CTL_LINK);
1869 if (error != 0)
1870 device_printf(sc->sc_dev,
1871 "could not control LED (%d)\n", error);
1872 break;
1873 default:
1874 break;
1875 }
1876fail:
1877 URTW_UNLOCK(sc);
1878 IEEE80211_LOCK(ic);
1879 return (uvp->newstate(vap, nstate, arg));
1880}
1881
1882static void
1883urtw_watchdog(void *arg)
1884{
1885 struct urtw_softc *sc = arg;
1886 struct ifnet *ifp = sc->sc_ifp;
1887
1888 if (sc->sc_txtimer > 0) {
1889 if (--sc->sc_txtimer == 0) {
1890 device_printf(sc->sc_dev, "device timeout\n");
1891 ifp->if_oerrors++;
1892 return;
1893 }
1894 callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc);
1895 }
1896}
1897
1898static void
1899urtw_set_multi(void *arg)
1900{
1901 struct urtw_softc *sc = arg;
1902 struct ifnet *ifp = sc->sc_ifp;
1903
1904 if (!(ifp->if_flags & IFF_UP))
1905 return;
1906
1907 /*
1908 * XXX don't know how to set a device. Lack of docs. Just try to set
1909 * IFF_ALLMULTI flag here.
1910 */
1911 ifp->if_flags |= IFF_ALLMULTI;
1912}
1913
1914static usb_error_t
1915urtw_set_rate(struct urtw_softc *sc)
1916{
1917 int i, basic_rate, min_rr_rate, max_rr_rate;
1918 uint16_t data;
1919 usb_error_t error;
1920
1921 basic_rate = urtw_rate2rtl(48);
1922 min_rr_rate = urtw_rate2rtl(12);
1923 max_rr_rate = urtw_rate2rtl(48);
1924
1925 urtw_write8_m(sc, URTW_RESP_RATE,
1926 max_rr_rate << URTW_RESP_MAX_RATE_SHIFT |
1927 min_rr_rate << URTW_RESP_MIN_RATE_SHIFT);
1928
1929 urtw_read16_m(sc, URTW_BRSR, &data);
1930 data &= ~URTW_BRSR_MBR_8185;
1931
1932 for (i = 0; i <= basic_rate; i++)
1933 data |= (1 << i);
1934
1935 urtw_write16_m(sc, URTW_BRSR, data);
1936fail:
1937 return (error);
1938}
1939
1940static uint16_t
1941urtw_rate2rtl(int rate)
1942{
1943#define N(a) (sizeof(a) / sizeof((a)[0]))
1944 int i;
1945
1946 for (i = 0; i < N(urtw_ratetable); i++) {
1947 if (rate == urtw_ratetable[i].reg)
1948 return urtw_ratetable[i].val;
1949 }
1950
1951 return (3);
1952#undef N
1953}
1954
1955static uint16_t
1956urtw_rtl2rate(int rate)
1957{
1958#define N(a) (sizeof(a) / sizeof((a)[0]))
1959 int i;
1960
1961 for (i = 0; i < N(urtw_ratetable); i++) {
1962 if (rate == urtw_ratetable[i].val)
1963 return urtw_ratetable[i].reg;
1964 }
1965
1966 return (0);
1967#undef N
1968}
1969
1970static usb_error_t
1971urtw_update_msr(struct urtw_softc *sc)
1972{
1973 struct ifnet *ifp = sc->sc_ifp;
1974 struct ieee80211com *ic = ifp->if_l2com;
1975 uint8_t data;
1976 usb_error_t error;
1977
1978 urtw_read8_m(sc, URTW_MSR, &data);
1979 data &= ~URTW_MSR_LINK_MASK;
1980
1981 if (sc->sc_state == IEEE80211_S_RUN) {
1982 switch (ic->ic_opmode) {
1983 case IEEE80211_M_STA:
1984 case IEEE80211_M_MONITOR:
1985 data |= URTW_MSR_LINK_STA;
1986 if (sc->sc_flags & URTW_RTL8187B)
1987 data |= URTW_MSR_LINK_ENEDCA;
1988 break;
1989 case IEEE80211_M_IBSS:
1990 data |= URTW_MSR_LINK_ADHOC;
1991 break;
1992 case IEEE80211_M_HOSTAP:
1993 data |= URTW_MSR_LINK_HOSTAP;
1994 break;
1995 default:
1996 panic("unsupported operation mode 0x%x\n",
1997 ic->ic_opmode);
1998 /* never reach */
1999 }
2000 } else
2001 data |= URTW_MSR_LINK_NONE;
2002
2003 urtw_write8_m(sc, URTW_MSR, data);
2004fail:
2005 return (error);
2006}
2007
2008static usb_error_t
2009urtw_read8_c(struct urtw_softc *sc, int val, uint8_t *data)
2010{
2011 struct usb_device_request req;
2012 usb_error_t error;
2013
2014 URTW_ASSERT_LOCKED(sc);
2015
2016 req.bmRequestType = UT_READ_VENDOR_DEVICE;
2017 req.bRequest = URTW_8187_GETREGS_REQ;
2018 USETW(req.wValue, (val & 0xff) | 0xff00);
2019 USETW(req.wIndex, (val >> 8) & 0x3);
2020 USETW(req.wLength, sizeof(uint8_t));
2021
2022 error = urtw_do_request(sc, &req, data);
2023 return (error);
2024}
2025
2026static usb_error_t
2027urtw_read16_c(struct urtw_softc *sc, int val, uint16_t *data)
2028{
2029 struct usb_device_request req;
2030 usb_error_t error;
2031
2032 URTW_ASSERT_LOCKED(sc);
2033
2034 req.bmRequestType = UT_READ_VENDOR_DEVICE;
2035 req.bRequest = URTW_8187_GETREGS_REQ;
2036 USETW(req.wValue, (val & 0xff) | 0xff00);
2037 USETW(req.wIndex, (val >> 8) & 0x3);
2038 USETW(req.wLength, sizeof(uint16_t));
2039
2040 error = urtw_do_request(sc, &req, data);
2041 return (error);
2042}
2043
2044static usb_error_t
2045urtw_read32_c(struct urtw_softc *sc, int val, uint32_t *data)
2046{
2047 struct usb_device_request req;
2048 usb_error_t error;
2049
2050 URTW_ASSERT_LOCKED(sc);
2051
2052 req.bmRequestType = UT_READ_VENDOR_DEVICE;
2053 req.bRequest = URTW_8187_GETREGS_REQ;
2054 USETW(req.wValue, (val & 0xff) | 0xff00);
2055 USETW(req.wIndex, (val >> 8) & 0x3);
2056 USETW(req.wLength, sizeof(uint32_t));
2057
2058 error = urtw_do_request(sc, &req, data);
2059 return (error);
2060}
2061
2062static usb_error_t
2063urtw_write8_c(struct urtw_softc *sc, int val, uint8_t data)
2064{
2065 struct usb_device_request req;
2066
2067 URTW_ASSERT_LOCKED(sc);
2068
2069 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
2070 req.bRequest = URTW_8187_SETREGS_REQ;
2071 USETW(req.wValue, (val & 0xff) | 0xff00);
2072 USETW(req.wIndex, (val >> 8) & 0x3);
2073 USETW(req.wLength, sizeof(uint8_t));
2074
2075 return (urtw_do_request(sc, &req, &data));
2076}
2077
2078static usb_error_t
2079urtw_write16_c(struct urtw_softc *sc, int val, uint16_t data)
2080{
2081 struct usb_device_request req;
2082
2083 URTW_ASSERT_LOCKED(sc);
2084
2085 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
2086 req.bRequest = URTW_8187_SETREGS_REQ;
2087 USETW(req.wValue, (val & 0xff) | 0xff00);
2088 USETW(req.wIndex, (val >> 8) & 0x3);
2089 USETW(req.wLength, sizeof(uint16_t));
2090
2091 return (urtw_do_request(sc, &req, &data));
2092}
2093
2094static usb_error_t
2095urtw_write32_c(struct urtw_softc *sc, int val, uint32_t data)
2096{
2097 struct usb_device_request req;
2098
2099 URTW_ASSERT_LOCKED(sc);
2100
2101 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
2102 req.bRequest = URTW_8187_SETREGS_REQ;
2103 USETW(req.wValue, (val & 0xff) | 0xff00);
2104 USETW(req.wIndex, (val >> 8) & 0x3);
2105 USETW(req.wLength, sizeof(uint32_t));
2106
2107 return (urtw_do_request(sc, &req, &data));
2108}
2109
2110static usb_error_t
2111urtw_get_macaddr(struct urtw_softc *sc)
2112{
2113 uint32_t data;
2114 usb_error_t error;
2115
2116 error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR, &data);
2117 if (error != 0)
2118 goto fail;
2119 sc->sc_bssid[0] = data & 0xff;
2120 sc->sc_bssid[1] = (data & 0xff00) >> 8;
2121 error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR + 1, &data);
2122 if (error != 0)
2123 goto fail;
2124 sc->sc_bssid[2] = data & 0xff;
2125 sc->sc_bssid[3] = (data & 0xff00) >> 8;
2126 error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR + 2, &data);
2127 if (error != 0)
2128 goto fail;
2129 sc->sc_bssid[4] = data & 0xff;
2130 sc->sc_bssid[5] = (data & 0xff00) >> 8;
2131fail:
2132 return (error);
2133}
2134
2135static usb_error_t
2136urtw_eprom_read32(struct urtw_softc *sc, uint32_t addr, uint32_t *data)
2137{
2138#define URTW_READCMD_LEN 3
2139 int addrlen, i;
2140 int16_t addrstr[8], data16, readcmd[] = { 1, 1, 0 };
2141 usb_error_t error;
2142
2143 /* NB: make sure the buffer is initialized */
2144 *data = 0;
2145
2146 /* enable EPROM programming */
2147 urtw_write8_m(sc, URTW_EPROM_CMD, URTW_EPROM_CMD_PROGRAM_MODE);
2148 DELAY(URTW_EPROM_DELAY);
2149
2150 error = urtw_eprom_cs(sc, URTW_EPROM_ENABLE);
2151 if (error != 0)
2152 goto fail;
2153 error = urtw_eprom_ck(sc);
2154 if (error != 0)
2155 goto fail;
2156 error = urtw_eprom_sendbits(sc, readcmd, URTW_READCMD_LEN);
2157 if (error != 0)
2158 goto fail;
2159 if (sc->sc_epromtype == URTW_EEPROM_93C56) {
2160 addrlen = 8;
2161 addrstr[0] = addr & (1 << 7);
2162 addrstr[1] = addr & (1 << 6);
2163 addrstr[2] = addr & (1 << 5);
2164 addrstr[3] = addr & (1 << 4);
2165 addrstr[4] = addr & (1 << 3);
2166 addrstr[5] = addr & (1 << 2);
2167 addrstr[6] = addr & (1 << 1);
2168 addrstr[7] = addr & (1 << 0);
2169 } else {
2170 addrlen=6;
2171 addrstr[0] = addr & (1 << 5);
2172 addrstr[1] = addr & (1 << 4);
2173 addrstr[2] = addr & (1 << 3);
2174 addrstr[3] = addr & (1 << 2);
2175 addrstr[4] = addr & (1 << 1);
2176 addrstr[5] = addr & (1 << 0);
2177 }
2178 error = urtw_eprom_sendbits(sc, addrstr, addrlen);
2179 if (error != 0)
2180 goto fail;
2181
2182 error = urtw_eprom_writebit(sc, 0);
2183 if (error != 0)
2184 goto fail;
2185
2186 for (i = 0; i < 16; i++) {
2187 error = urtw_eprom_ck(sc);
2188 if (error != 0)
2189 goto fail;
2190 error = urtw_eprom_readbit(sc, &data16);
2191 if (error != 0)
2192 goto fail;
2193
2194 (*data) |= (data16 << (15 - i));
2195 }
2196
2197 error = urtw_eprom_cs(sc, URTW_EPROM_DISABLE);
2198 if (error != 0)
2199 goto fail;
2200 error = urtw_eprom_ck(sc);
2201 if (error != 0)
2202 goto fail;
2203
2204 /* now disable EPROM programming */
2205 urtw_write8_m(sc, URTW_EPROM_CMD, URTW_EPROM_CMD_NORMAL_MODE);
2206fail:
2207 return (error);
2208#undef URTW_READCMD_LEN
2209}
2210
2211static usb_error_t
2212urtw_eprom_cs(struct urtw_softc *sc, int able)
2213{
2214 uint8_t data;
2215 usb_error_t error;
2216
2217 urtw_read8_m(sc, URTW_EPROM_CMD, &data);
2218 if (able == URTW_EPROM_ENABLE)
2219 urtw_write8_m(sc, URTW_EPROM_CMD, data | URTW_EPROM_CS);
2220 else
2221 urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_CS);
2222 DELAY(URTW_EPROM_DELAY);
2223fail:
2224 return (error);
2225}
2226
2227static usb_error_t
2228urtw_eprom_ck(struct urtw_softc *sc)
2229{
2230 uint8_t data;
2231 usb_error_t error;
2232
2233 /* masking */
2234 urtw_read8_m(sc, URTW_EPROM_CMD, &data);
2235 urtw_write8_m(sc, URTW_EPROM_CMD, data | URTW_EPROM_CK);
2236 DELAY(URTW_EPROM_DELAY);
2237 /* unmasking */
2238 urtw_read8_m(sc, URTW_EPROM_CMD, &data);
2239 urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_CK);
2240 DELAY(URTW_EPROM_DELAY);
2241fail:
2242 return (error);
2243}
2244
2245static usb_error_t
2246urtw_eprom_readbit(struct urtw_softc *sc, int16_t *data)
2247{
2248 uint8_t data8;
2249 usb_error_t error;
2250
2251 urtw_read8_m(sc, URTW_EPROM_CMD, &data8);
2252 *data = (data8 & URTW_EPROM_READBIT) ? 1 : 0;
2253 DELAY(URTW_EPROM_DELAY);
2254
2255fail:
2256 return (error);
2257}
2258
2259static usb_error_t
2260urtw_eprom_writebit(struct urtw_softc *sc, int16_t bit)
2261{
2262 uint8_t data;
2263 usb_error_t error;
2264
2265 urtw_read8_m(sc, URTW_EPROM_CMD, &data);
2266 if (bit != 0)
2267 urtw_write8_m(sc, URTW_EPROM_CMD, data | URTW_EPROM_WRITEBIT);
2268 else
2269 urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_WRITEBIT);
2270 DELAY(URTW_EPROM_DELAY);
2271fail:
2272 return (error);
2273}
2274
2275static usb_error_t
2276urtw_eprom_sendbits(struct urtw_softc *sc, int16_t *buf, int buflen)
2277{
2278 int i = 0;
2279 usb_error_t error = 0;
2280
2281 for (i = 0; i < buflen; i++) {
2282 error = urtw_eprom_writebit(sc, buf[i]);
2283 if (error != 0)
2284 goto fail;
2285 error = urtw_eprom_ck(sc);
2286 if (error != 0)
2287 goto fail;
2288 }
2289fail:
2290 return (error);
2291}
2292
2293
2294static usb_error_t
2295urtw_get_txpwr(struct urtw_softc *sc)
2296{
2297 int i, j;
2298 uint32_t data;
2299 usb_error_t error;
2300
2301 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW_BASE, &data);
2302 if (error != 0)
2303 goto fail;
2304 sc->sc_txpwr_cck_base = data & 0xf;
2305 sc->sc_txpwr_ofdm_base = (data >> 4) & 0xf;
2306
2307 for (i = 1, j = 0; i < 6; i += 2, j++) {
2308 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW0 + j, &data);
2309 if (error != 0)
2310 goto fail;
2311 sc->sc_txpwr_cck[i] = data & 0xf;
2312 sc->sc_txpwr_cck[i + 1] = (data & 0xf00) >> 8;
2313 sc->sc_txpwr_ofdm[i] = (data & 0xf0) >> 4;
2314 sc->sc_txpwr_ofdm[i + 1] = (data & 0xf000) >> 12;
2315 }
2316 for (i = 1, j = 0; i < 4; i += 2, j++) {
2317 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW1 + j, &data);
2318 if (error != 0)
2319 goto fail;
2320 sc->sc_txpwr_cck[i + 6] = data & 0xf;
2321 sc->sc_txpwr_cck[i + 6 + 1] = (data & 0xf00) >> 8;
2322 sc->sc_txpwr_ofdm[i + 6] = (data & 0xf0) >> 4;
2323 sc->sc_txpwr_ofdm[i + 6 + 1] = (data & 0xf000) >> 12;
2324 }
2325 if (sc->sc_flags & URTW_RTL8187B) {
2326 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW2, &data);
2327 if (error != 0)
2328 goto fail;
2329 sc->sc_txpwr_cck[1 + 6 + 4] = data & 0xf;
2330 sc->sc_txpwr_ofdm[1 + 6 + 4] = (data & 0xf0) >> 4;
2331 error = urtw_eprom_read32(sc, 0x0a, &data);
2332 if (error != 0)
2333 goto fail;
2334 sc->sc_txpwr_cck[2 + 6 + 4] = data & 0xf;
2335 sc->sc_txpwr_ofdm[2 + 6 + 4] = (data & 0xf0) >> 4;
2336 error = urtw_eprom_read32(sc, 0x1c, &data);
2337 if (error != 0)
2338 goto fail;
2339 sc->sc_txpwr_cck[3 + 6 + 4] = data & 0xf;
2340 sc->sc_txpwr_cck[3 + 6 + 4 + 1] = (data & 0xf00) >> 8;
2341 sc->sc_txpwr_ofdm[3 + 6 + 4] = (data & 0xf0) >> 4;
2342 sc->sc_txpwr_ofdm[3 + 6 + 4 + 1] = (data & 0xf000) >> 12;
2343 } else {
2344 for (i = 1, j = 0; i < 4; i += 2, j++) {
2345 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW2 + j,
2346 &data);
2347 if (error != 0)
2348 goto fail;
2349 sc->sc_txpwr_cck[i + 6 + 4] = data & 0xf;
2350 sc->sc_txpwr_cck[i + 6 + 4 + 1] = (data & 0xf00) >> 8;
2351 sc->sc_txpwr_ofdm[i + 6 + 4] = (data & 0xf0) >> 4;
2352 sc->sc_txpwr_ofdm[i + 6 + 4 + 1] = (data & 0xf000) >> 12;
2353 }
2354 }
2355fail:
2356 return (error);
2357}
2358
2359
2360static usb_error_t
2361urtw_get_rfchip(struct urtw_softc *sc)
2362{
2363 int ret;
2364 uint8_t data8;
2365 uint32_t data;
2366 usb_error_t error;
2367
2368 if (sc->sc_flags & URTW_RTL8187B) {
2369 urtw_read8_m(sc, 0xe1, &data8);
2370 switch (data8) {
2371 case 0:
2372 sc->sc_flags |= URTW_RTL8187B_REV_B;
2373 break;
2374 case 1:
2375 sc->sc_flags |= URTW_RTL8187B_REV_D;
2376 break;
2377 case 2:
2378 sc->sc_flags |= URTW_RTL8187B_REV_E;
2379 break;
2380 default:
2381 device_printf(sc->sc_dev, "unknown type: %#x\n", data8);
2382 sc->sc_flags |= URTW_RTL8187B_REV_B;
2383 break;
2384 }
2385 } else {
2386 urtw_read32_m(sc, URTW_TX_CONF, &data);
2387 switch (data & URTW_TX_HWMASK) {
2388 case URTW_TX_R8187vD_B:
2389 sc->sc_flags |= URTW_RTL8187B;
2390 break;
2391 case URTW_TX_R8187vD:
2392 break;
2393 default:
2394 device_printf(sc->sc_dev, "unknown RTL8187L type: %#x\n",
2395 data & URTW_TX_HWMASK);
2396 break;
2397 }
2398 }
2399
2400 error = urtw_eprom_read32(sc, URTW_EPROM_RFCHIPID, &data);
2401 if (error != 0)
2402 goto fail;
2403 switch (data & 0xff) {
2404 case URTW_EPROM_RFCHIPID_RTL8225U:
2405 error = urtw_8225_isv2(sc, &ret);
2406 if (error != 0)
2407 goto fail;
2408 if (ret == 0) {
2409 sc->sc_rf_init = urtw_8225_rf_init;
2410 sc->sc_rf_set_sens = urtw_8225_rf_set_sens;
2411 sc->sc_rf_set_chan = urtw_8225_rf_set_chan;
2412 sc->sc_rf_stop = urtw_8225_rf_stop;
2413 } else {
2414 sc->sc_rf_init = urtw_8225v2_rf_init;
2415 sc->sc_rf_set_chan = urtw_8225v2_rf_set_chan;
2416 sc->sc_rf_stop = urtw_8225_rf_stop;
2417 }
2418 sc->sc_max_sens = URTW_8225_RF_MAX_SENS;
2419 sc->sc_sens = URTW_8225_RF_DEF_SENS;
2420 break;
2421 case URTW_EPROM_RFCHIPID_RTL8225Z2:
2422 sc->sc_rf_init = urtw_8225v2b_rf_init;
2423 sc->sc_rf_set_chan = urtw_8225v2b_rf_set_chan;
2424 sc->sc_max_sens = URTW_8225_RF_MAX_SENS;
2425 sc->sc_sens = URTW_8225_RF_DEF_SENS;
2426 sc->sc_rf_stop = urtw_8225_rf_stop;
2427 break;
2428 default:
2429 panic("unsupported RF chip %d\n", data & 0xff);
2430 /* never reach */
2431 }
2432
2433 device_printf(sc->sc_dev, "%s rf %s hwrev %s\n",
2434 (sc->sc_flags & URTW_RTL8187B) ? "rtl8187b" : "rtl8187l",
2435 ((data & 0xff) == URTW_EPROM_RFCHIPID_RTL8225U) ? "rtl8225u" :
2436 "rtl8225z2",
2437 (sc->sc_flags & URTW_RTL8187B) ? ((data8 == 0) ? "b" :
2438 (data8 == 1) ? "d" : "e") : "none");
2439
2440fail:
2441 return (error);
2442}
2443
2444
2445static usb_error_t
2446urtw_led_init(struct urtw_softc *sc)
2447{
2448 uint32_t rev;
2449 usb_error_t error;
2450
2451 urtw_read8_m(sc, URTW_PSR, &sc->sc_psr);
2452 error = urtw_eprom_read32(sc, URTW_EPROM_SWREV, &rev);
2453 if (error != 0)
2454 goto fail;
2455
2456 switch (rev & URTW_EPROM_CID_MASK) {
2457 case URTW_EPROM_CID_ALPHA0:
2458 sc->sc_strategy = URTW_SW_LED_MODE1;
2459 break;
2460 case URTW_EPROM_CID_SERCOMM_PS:
2461 sc->sc_strategy = URTW_SW_LED_MODE3;
2462 break;
2463 case URTW_EPROM_CID_HW_LED:
2464 sc->sc_strategy = URTW_HW_LED;
2465 break;
2466 case URTW_EPROM_CID_RSVD0:
2467 case URTW_EPROM_CID_RSVD1:
2468 default:
2469 sc->sc_strategy = URTW_SW_LED_MODE0;
2470 break;
2471 }
2472
2473 sc->sc_gpio_ledpin = URTW_LED_PIN_GPIO0;
2474
2475fail:
2476 return (error);
2477}
2478
2479
2480static usb_error_t
2481urtw_8225_rf_init(struct urtw_softc *sc)
2482{
2483#define N(a) (sizeof(a) / sizeof((a)[0]))
2484 int i;
2485 uint16_t data;
2486 usb_error_t error;
2487
2488 error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
2489 if (error)
2490 goto fail;
2491
2492 error = urtw_8225_usb_init(sc);
2493 if (error)
2494 goto fail;
2495
2496 urtw_write32_m(sc, URTW_RF_TIMING, 0x000a8008);
2497 urtw_read16_m(sc, URTW_BRSR, &data); /* XXX ??? */
2498 urtw_write16_m(sc, URTW_BRSR, 0xffff);
2499 urtw_write32_m(sc, URTW_RF_PARA, 0x100044);
2500
2501 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
2502 if (error)
2503 goto fail;
2504 urtw_write8_m(sc, URTW_CONFIG3, 0x44);
2505 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
2506 if (error)
2507 goto fail;
2508
2509 error = urtw_8185_rf_pins_enable(sc);
2510 if (error)
2511 goto fail;
2512 usb_pause_mtx(&sc->sc_mtx, 1000);
2513
2514 for (i = 0; i < N(urtw_8225_rf_part1); i++) {
2515 urtw_8225_write(sc, urtw_8225_rf_part1[i].reg,
2516 urtw_8225_rf_part1[i].val);
2517 usb_pause_mtx(&sc->sc_mtx, 1);
2518 }
2519 usb_pause_mtx(&sc->sc_mtx, 100);
2520 urtw_8225_write(sc,
2521 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC1);
2522 usb_pause_mtx(&sc->sc_mtx, 200);
2523 urtw_8225_write(sc,
2524 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC2);
2525 usb_pause_mtx(&sc->sc_mtx, 200);
2526 urtw_8225_write(sc,
2527 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC3);
2528
2529 for (i = 0; i < 95; i++) {
2530 urtw_8225_write(sc, URTW_8225_ADDR_1_MAGIC, (uint8_t)(i + 1));
2531 urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC, urtw_8225_rxgain[i]);
2532 }
2533
2534 urtw_8225_write(sc,
2535 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC4);
2536 urtw_8225_write(sc,
2537 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC5);
2538
2539 for (i = 0; i < 128; i++) {
2540 urtw_8187_write_phy_ofdm(sc, 0xb, urtw_8225_agc[i]);
2541 usb_pause_mtx(&sc->sc_mtx, 1);
2542 urtw_8187_write_phy_ofdm(sc, 0xa, (uint8_t)i + 0x80);
2543 usb_pause_mtx(&sc->sc_mtx, 1);
2544 }
2545
2546 for (i = 0; i < N(urtw_8225_rf_part2); i++) {
2547 urtw_8187_write_phy_ofdm(sc, urtw_8225_rf_part2[i].reg,
2548 urtw_8225_rf_part2[i].val);
2549 usb_pause_mtx(&sc->sc_mtx, 1);
2550 }
2551
2552 error = urtw_8225_setgain(sc, 4);
2553 if (error)
2554 goto fail;
2555
2556 for (i = 0; i < N(urtw_8225_rf_part3); i++) {
2557 urtw_8187_write_phy_cck(sc, urtw_8225_rf_part3[i].reg,
2558 urtw_8225_rf_part3[i].val);
2559 usb_pause_mtx(&sc->sc_mtx, 1);
2560 }
2561
2562 urtw_write8_m(sc, URTW_TESTR, 0x0d);
2563
2564 error = urtw_8225_set_txpwrlvl(sc, 1);
2565 if (error)
2566 goto fail;
2567
2568 urtw_8187_write_phy_cck(sc, 0x10, 0x9b);
2569 usb_pause_mtx(&sc->sc_mtx, 1);
2570 urtw_8187_write_phy_ofdm(sc, 0x26, 0x90);
2571 usb_pause_mtx(&sc->sc_mtx, 1);
2572
2573 /* TX ant A, 0x0 for B */
2574 error = urtw_8185_tx_antenna(sc, 0x3);
2575 if (error)
2576 goto fail;
2577 urtw_write32_m(sc, URTW_HSSI_PARA, 0x3dc00002);
2578
2579 error = urtw_8225_rf_set_chan(sc, 1);
2580fail:
2581 return (error);
2582#undef N
2583}
2584
2585static usb_error_t
2586urtw_8185_rf_pins_enable(struct urtw_softc *sc)
2587{
2588 usb_error_t error = 0;
2589
2590 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x1ff7);
2591fail:
2592 return (error);
2593}
2594
2595static usb_error_t
2596urtw_8185_tx_antenna(struct urtw_softc *sc, uint8_t ant)
2597{
2598 usb_error_t error;
2599
2600 urtw_write8_m(sc, URTW_TX_ANTENNA, ant);
2601 usb_pause_mtx(&sc->sc_mtx, 1);
2602fail:
2603 return (error);
2604}
2605
2606static usb_error_t
2607urtw_8187_write_phy_ofdm_c(struct urtw_softc *sc, uint8_t addr, uint32_t data)
2608{
2609
2610 data = data & 0xff;
2611 return urtw_8187_write_phy(sc, addr, data);
2612}
2613
2614static usb_error_t
2615urtw_8187_write_phy_cck_c(struct urtw_softc *sc, uint8_t addr, uint32_t data)
2616{
2617
2618 data = data & 0xff;
2619 return urtw_8187_write_phy(sc, addr, data | 0x10000);
2620}
2621
2622static usb_error_t
2623urtw_8187_write_phy(struct urtw_softc *sc, uint8_t addr, uint32_t data)
2624{
2625 uint32_t phyw;
2626 usb_error_t error;
2627
2628 phyw = ((data << 8) | (addr | 0x80));
2629 urtw_write8_m(sc, URTW_PHY_MAGIC4, ((phyw & 0xff000000) >> 24));
2630 urtw_write8_m(sc, URTW_PHY_MAGIC3, ((phyw & 0x00ff0000) >> 16));
2631 urtw_write8_m(sc, URTW_PHY_MAGIC2, ((phyw & 0x0000ff00) >> 8));
2632 urtw_write8_m(sc, URTW_PHY_MAGIC1, ((phyw & 0x000000ff)));
2633 usb_pause_mtx(&sc->sc_mtx, 1);
2634fail:
2635 return (error);
2636}
2637
2638static usb_error_t
2639urtw_8225_setgain(struct urtw_softc *sc, int16_t gain)
2640{
2641 usb_error_t error;
2642
2643 urtw_8187_write_phy_ofdm(sc, 0x0d, urtw_8225_gain[gain * 4]);
2644 urtw_8187_write_phy_ofdm(sc, 0x1b, urtw_8225_gain[gain * 4 + 2]);
2645 urtw_8187_write_phy_ofdm(sc, 0x1d, urtw_8225_gain[gain * 4 + 3]);
2646 urtw_8187_write_phy_ofdm(sc, 0x23, urtw_8225_gain[gain * 4 + 1]);
2647fail:
2648 return (error);
2649}
2650
2651static usb_error_t
2652urtw_8225_usb_init(struct urtw_softc *sc)
2653{
2654 uint8_t data;
2655 usb_error_t error;
2656
2657 urtw_write8_m(sc, URTW_RF_PINS_SELECT + 1, 0);
2658 urtw_write8_m(sc, URTW_GPIO, 0);
2659 error = urtw_read8e(sc, 0x53, &data);
2660 if (error)
2661 goto fail;
2662 error = urtw_write8e(sc, 0x53, data | (1 << 7));
2663 if (error)
2664 goto fail;
2665 urtw_write8_m(sc, URTW_RF_PINS_SELECT + 1, 4);
2666 urtw_write8_m(sc, URTW_GPIO, 0x20);
2667 urtw_write8_m(sc, URTW_GP_ENABLE, 0);
2668
2669 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, 0x80);
2670 urtw_write16_m(sc, URTW_RF_PINS_SELECT, 0x80);
2671 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x80);
2672
2673 usb_pause_mtx(&sc->sc_mtx, 500);
2674fail:
2675 return (error);
2676}
2677
2678static usb_error_t
2679urtw_8225_write_c(struct urtw_softc *sc, uint8_t addr, uint16_t data)
2680{
2681 uint16_t d80, d82, d84;
2682 usb_error_t error;
2683
2684 urtw_read16_m(sc, URTW_RF_PINS_OUTPUT, &d80);
2685 d80 &= URTW_RF_PINS_MAGIC1;
2686 urtw_read16_m(sc, URTW_RF_PINS_ENABLE, &d82);
2687 urtw_read16_m(sc, URTW_RF_PINS_SELECT, &d84);
2688 d84 &= URTW_RF_PINS_MAGIC2;
2689 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, d82 | URTW_RF_PINS_MAGIC3);
2690 urtw_write16_m(sc, URTW_RF_PINS_SELECT, d84 | URTW_RF_PINS_MAGIC3);
2691 DELAY(10);
2692
2693 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80 | URTW_BB_HOST_BANG_EN);
2694 DELAY(2);
2695 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80);
2696 DELAY(10);
2697
2698 error = urtw_8225_write_s16(sc, addr, 0x8225, &data);
2699 if (error != 0)
2700 goto fail;
2701
2702 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80 | URTW_BB_HOST_BANG_EN);
2703 DELAY(10);
2704 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80 | URTW_BB_HOST_BANG_EN);
2705 urtw_write16_m(sc, URTW_RF_PINS_SELECT, d84);
2706 usb_pause_mtx(&sc->sc_mtx, 2);
2707fail:
2708 return (error);
2709}
2710
2711/* XXX why we should allocalte memory buffer instead of using memory stack? */
2712static usb_error_t
2713urtw_8225_write_s16(struct urtw_softc *sc, uint8_t addr, int index,
2714 uint16_t *data)
2715{
2716 uint8_t *buf;
2717 uint16_t data16;
2718 struct usb_device_request *req;
2719 usb_error_t error = 0;
2720
2721 data16 = *data;
2722 req = (usb_device_request_t *)malloc(sizeof(usb_device_request_t),
2723 M_80211_VAP, M_NOWAIT | M_ZERO);
2724 if (req == NULL) {
2725 device_printf(sc->sc_dev, "could not allocate a memory\n");
2726 goto fail0;
2727 }
2728 buf = (uint8_t *)malloc(2, M_80211_VAP, M_NOWAIT | M_ZERO);
2729 if (req == NULL) {
2730 device_printf(sc->sc_dev, "could not allocate a memory\n");
2731 goto fail1;
2732 }
2733
2734 req->bmRequestType = UT_WRITE_VENDOR_DEVICE;
2735 req->bRequest = URTW_8187_SETREGS_REQ;
2736 USETW(req->wValue, addr);
2737 USETW(req->wIndex, index);
2738 USETW(req->wLength, sizeof(uint16_t));
2739 buf[0] = (data16 & 0x00ff);
2740 buf[1] = (data16 & 0xff00) >> 8;
2741
2742 error = urtw_do_request(sc, req, buf);
2743
2744 free(buf, M_80211_VAP);
2745fail1: free(req, M_80211_VAP);
2746fail0: return (error);
2747}
2748
2749static usb_error_t
2750urtw_8225_rf_set_chan(struct urtw_softc *sc, int chan)
2751{
2752 usb_error_t error;
2753
2754 error = urtw_8225_set_txpwrlvl(sc, chan);
2755 if (error)
2756 goto fail;
2757 urtw_8225_write(sc, URTW_8225_ADDR_7_MAGIC, urtw_8225_channel[chan]);
2758 usb_pause_mtx(&sc->sc_mtx, 10);
2759fail:
2760 return (error);
2761}
2762
2763static usb_error_t
2764urtw_8225_rf_set_sens(struct urtw_softc *sc, int sens)
2765{
2766 usb_error_t error;
2767
2768 if (sens < 0 || sens > 6)
2769 return -1;
2770
2771 if (sens > 4)
2772 urtw_8225_write(sc,
2773 URTW_8225_ADDR_C_MAGIC, URTW_8225_ADDR_C_DATA_MAGIC1);
2774 else
2775 urtw_8225_write(sc,
2776 URTW_8225_ADDR_C_MAGIC, URTW_8225_ADDR_C_DATA_MAGIC2);
2777
2778 sens = 6 - sens;
2779 error = urtw_8225_setgain(sc, sens);
2780 if (error)
2781 goto fail;
2782
2783 urtw_8187_write_phy_cck(sc, 0x41, urtw_8225_threshold[sens]);
2784
2785fail:
2786 return (error);
2787}
2788
2789static usb_error_t
2790urtw_8225_set_txpwrlvl(struct urtw_softc *sc, int chan)
2791{
2792 int i, idx, set;
2793 uint8_t *cck_pwltable;
2794 uint8_t cck_pwrlvl_max, ofdm_pwrlvl_min, ofdm_pwrlvl_max;
2795 uint8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
2796 uint8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
2797 usb_error_t error;
2798
2799 cck_pwrlvl_max = 11;
2800 ofdm_pwrlvl_max = 25; /* 12 -> 25 */
2801 ofdm_pwrlvl_min = 10;
2802
2803 /* CCK power setting */
2804 cck_pwrlvl = (cck_pwrlvl > cck_pwrlvl_max) ? cck_pwrlvl_max : cck_pwrlvl;
2805 idx = cck_pwrlvl % 6;
2806 set = cck_pwrlvl / 6;
2807 cck_pwltable = (chan == 14) ? urtw_8225_txpwr_cck_ch14 :
2808 urtw_8225_txpwr_cck;
2809
2810 urtw_write8_m(sc, URTW_TX_GAIN_CCK,
2811 urtw_8225_tx_gain_cck_ofdm[set] >> 1);
2812 for (i = 0; i < 8; i++) {
2813 urtw_8187_write_phy_cck(sc, 0x44 + i,
2814 cck_pwltable[idx * 8 + i]);
2815 }
2816 usb_pause_mtx(&sc->sc_mtx, 1);
2817
2818 /* OFDM power setting */
2819 ofdm_pwrlvl = (ofdm_pwrlvl > (ofdm_pwrlvl_max - ofdm_pwrlvl_min)) ?
2820 ofdm_pwrlvl_max : ofdm_pwrlvl + ofdm_pwrlvl_min;
2821 ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
2822
2823 idx = ofdm_pwrlvl % 6;
2824 set = ofdm_pwrlvl / 6;
2825
2826 error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
2827 if (error)
2828 goto fail;
2829 urtw_8187_write_phy_ofdm(sc, 2, 0x42);
2830 urtw_8187_write_phy_ofdm(sc, 6, 0);
2831 urtw_8187_write_phy_ofdm(sc, 8, 0);
2832
2833 urtw_write8_m(sc, URTW_TX_GAIN_OFDM,
2834 urtw_8225_tx_gain_cck_ofdm[set] >> 1);
2835 urtw_8187_write_phy_ofdm(sc, 0x5, urtw_8225_txpwr_ofdm[idx]);
2836 urtw_8187_write_phy_ofdm(sc, 0x7, urtw_8225_txpwr_ofdm[idx]);
2837 usb_pause_mtx(&sc->sc_mtx, 1);
2838fail:
2839 return (error);
2840}
2841
2842
2843static usb_error_t
2844urtw_8225_rf_stop(struct urtw_softc *sc)
2845{
2846 uint8_t data;
2847 usb_error_t error;
2848
2849 urtw_8225_write(sc, 0x4, 0x1f);
2850
2851 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
2852 if (error)
2853 goto fail;
2854
2855 urtw_read8_m(sc, URTW_CONFIG3, &data);
2856 urtw_write8_m(sc, URTW_CONFIG3, data | URTW_CONFIG3_ANAPARAM_WRITE);
2857 if (sc->sc_flags & URTW_RTL8187B) {
2858 urtw_write32_m(sc, URTW_ANAPARAM2,
2859 URTW_8187B_8225_ANAPARAM2_OFF);
2860 urtw_write32_m(sc, URTW_ANAPARAM, URTW_8187B_8225_ANAPARAM_OFF);
2861 urtw_write32_m(sc, URTW_ANAPARAM3,
2862 URTW_8187B_8225_ANAPARAM3_OFF);
2863 } else {
2864 urtw_write32_m(sc, URTW_ANAPARAM2, URTW_8225_ANAPARAM2_OFF);
2865 urtw_write32_m(sc, URTW_ANAPARAM, URTW_8225_ANAPARAM_OFF);
2866 }
2867
2868 urtw_write8_m(sc, URTW_CONFIG3, data & ~URTW_CONFIG3_ANAPARAM_WRITE);
2869 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
2870 if (error)
2871 goto fail;
2872
2873fail:
2874 return (error);
2875}
2876
2877static usb_error_t
2878urtw_8225v2_rf_init(struct urtw_softc *sc)
2879{
2880#define N(a) (sizeof(a) / sizeof((a)[0]))
2881 int i;
2882 uint16_t data;
2883 uint32_t data32;
2884 usb_error_t error;
2885
2886 error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
2887 if (error)
2888 goto fail;
2889
2890 error = urtw_8225_usb_init(sc);
2891 if (error)
2892 goto fail;
2893
2894 urtw_write32_m(sc, URTW_RF_TIMING, 0x000a8008);
2895 urtw_read16_m(sc, URTW_BRSR, &data); /* XXX ??? */
2896 urtw_write16_m(sc, URTW_BRSR, 0xffff);
2897 urtw_write32_m(sc, URTW_RF_PARA, 0x100044);
2898
2899 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
2900 if (error)
2901 goto fail;
2902 urtw_write8_m(sc, URTW_CONFIG3, 0x44);
2903 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
2904 if (error)
2905 goto fail;
2906
2907 error = urtw_8185_rf_pins_enable(sc);
2908 if (error)
2909 goto fail;
2910
2911 usb_pause_mtx(&sc->sc_mtx, 500);
2912
2913 for (i = 0; i < N(urtw_8225v2_rf_part1); i++) {
2914 urtw_8225_write(sc, urtw_8225v2_rf_part1[i].reg,
2915 urtw_8225v2_rf_part1[i].val);
2916 }
2917 usb_pause_mtx(&sc->sc_mtx, 50);
2918
2919 urtw_8225_write(sc,
2920 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC1);
2921
2922 for (i = 0; i < 95; i++) {
2923 urtw_8225_write(sc, URTW_8225_ADDR_1_MAGIC, (uint8_t)(i + 1));
2924 urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC,
2925 urtw_8225v2_rxgain[i]);
2926 }
2927
2928 urtw_8225_write(sc,
2929 URTW_8225_ADDR_3_MAGIC, URTW_8225_ADDR_3_DATA_MAGIC1);
2930 urtw_8225_write(sc,
2931 URTW_8225_ADDR_5_MAGIC, URTW_8225_ADDR_5_DATA_MAGIC1);
2932 urtw_8225_write(sc,
2933 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC2);
2934 urtw_8225_write(sc,
2935 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC1);
2936 usb_pause_mtx(&sc->sc_mtx, 100);
2937 urtw_8225_write(sc,
2938 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC2);
2939 usb_pause_mtx(&sc->sc_mtx, 100);
2940
2941 error = urtw_8225_read(sc, URTW_8225_ADDR_6_MAGIC, &data32);
2942 if (error != 0)
2943 goto fail;
2944 if (data32 != URTW_8225_ADDR_6_DATA_MAGIC1)
2945 device_printf(sc->sc_dev, "expect 0xe6!! (0x%x)\n", data32);
2946 if (!(data32 & URTW_8225_ADDR_6_DATA_MAGIC2)) {
2947 urtw_8225_write(sc,
2948 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC1);
2949 usb_pause_mtx(&sc->sc_mtx, 100);
2950 urtw_8225_write(sc,
2951 URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC2);
2952 usb_pause_mtx(&sc->sc_mtx, 50);
2953 error = urtw_8225_read(sc, URTW_8225_ADDR_6_MAGIC, &data32);
2954 if (error != 0)
2955 goto fail;
2956 if (!(data32 & URTW_8225_ADDR_6_DATA_MAGIC2))
2957 device_printf(sc->sc_dev, "RF calibration failed\n");
2958 }
2959 usb_pause_mtx(&sc->sc_mtx, 100);
2960
2961 urtw_8225_write(sc,
2962 URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC6);
2963 for (i = 0; i < 128; i++) {
2964 urtw_8187_write_phy_ofdm(sc, 0xb, urtw_8225_agc[i]);
2965 urtw_8187_write_phy_ofdm(sc, 0xa, (uint8_t)i + 0x80);
2966 }
2967
2968 for (i = 0; i < N(urtw_8225v2_rf_part2); i++) {
2969 urtw_8187_write_phy_ofdm(sc, urtw_8225v2_rf_part2[i].reg,
2970 urtw_8225v2_rf_part2[i].val);
2971 }
2972
2973 error = urtw_8225v2_setgain(sc, 4);
2974 if (error)
2975 goto fail;
2976
2977 for (i = 0; i < N(urtw_8225v2_rf_part3); i++) {
2978 urtw_8187_write_phy_cck(sc, urtw_8225v2_rf_part3[i].reg,
2979 urtw_8225v2_rf_part3[i].val);
2980 }
2981
2982 urtw_write8_m(sc, URTW_TESTR, 0x0d);
2983
2984 error = urtw_8225v2_set_txpwrlvl(sc, 1);
2985 if (error)
2986 goto fail;
2987
2988 urtw_8187_write_phy_cck(sc, 0x10, 0x9b);
2989 urtw_8187_write_phy_ofdm(sc, 0x26, 0x90);
2990
2991 /* TX ant A, 0x0 for B */
2992 error = urtw_8185_tx_antenna(sc, 0x3);
2993 if (error)
2994 goto fail;
2995 urtw_write32_m(sc, URTW_HSSI_PARA, 0x3dc00002);
2996
2997 error = urtw_8225_rf_set_chan(sc, 1);
2998fail:
2999 return (error);
3000#undef N
3001}
3002
3003static usb_error_t
3004urtw_8225v2_rf_set_chan(struct urtw_softc *sc, int chan)
3005{
3006 usb_error_t error;
3007
3008 error = urtw_8225v2_set_txpwrlvl(sc, chan);
3009 if (error)
3010 goto fail;
3011
3012 urtw_8225_write(sc, URTW_8225_ADDR_7_MAGIC, urtw_8225_channel[chan]);
3013 usb_pause_mtx(&sc->sc_mtx, 10);
3014fail:
3015 return (error);
3016}
3017
3018static usb_error_t
3019urtw_8225_read(struct urtw_softc *sc, uint8_t addr, uint32_t *data)
3020{
3021 int i;
3022 int16_t bit;
3023 uint8_t rlen = 12, wlen = 6;
3024 uint16_t o1, o2, o3, tmp;
3025 uint32_t d2w = ((uint32_t)(addr & 0x1f)) << 27;
3026 uint32_t mask = 0x80000000, value = 0;
3027 usb_error_t error;
3028
3029 urtw_read16_m(sc, URTW_RF_PINS_OUTPUT, &o1);
3030 urtw_read16_m(sc, URTW_RF_PINS_ENABLE, &o2);
3031 urtw_read16_m(sc, URTW_RF_PINS_SELECT, &o3);
3032 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, o2 | URTW_RF_PINS_MAGIC4);
3033 urtw_write16_m(sc, URTW_RF_PINS_SELECT, o3 | URTW_RF_PINS_MAGIC4);
3034 o1 &= ~URTW_RF_PINS_MAGIC4;
3035 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1 | URTW_BB_HOST_BANG_EN);
3036 DELAY(5);
3037 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1);
3038 DELAY(5);
3039
3040 for (i = 0; i < (wlen / 2); i++, mask = mask >> 1) {
3041 bit = ((d2w & mask) != 0) ? 1 : 0;
3042
3043 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1);
3044 DELAY(2);
3045 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
3046 URTW_BB_HOST_BANG_CLK);
3047 DELAY(2);
3048 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
3049 URTW_BB_HOST_BANG_CLK);
3050 DELAY(2);
3051 mask = mask >> 1;
3052 if (i == 2)
3053 break;
3054 bit = ((d2w & mask) != 0) ? 1 : 0;
3055 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
3056 URTW_BB_HOST_BANG_CLK);
3057 DELAY(2);
3058 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
3059 URTW_BB_HOST_BANG_CLK);
3060 DELAY(2);
3061 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1);
3062 DELAY(1);
3063 }
3064 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 | URTW_BB_HOST_BANG_RW |
3065 URTW_BB_HOST_BANG_CLK);
3066 DELAY(2);
3067 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 | URTW_BB_HOST_BANG_RW);
3068 DELAY(2);
3069 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1 | URTW_BB_HOST_BANG_RW);
3070 DELAY(2);
3071
3072 mask = 0x800;
3073 for (i = 0; i < rlen; i++, mask = mask >> 1) {
3074 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
3075 o1 | URTW_BB_HOST_BANG_RW);
3076 DELAY(2);
3077 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
3078 o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK);
3079 DELAY(2);
3080 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
3081 o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK);
3082 DELAY(2);
3083 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
3084 o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK);
3085 DELAY(2);
3086
3087 urtw_read16_m(sc, URTW_RF_PINS_INPUT, &tmp);
3088 value |= ((tmp & URTW_BB_HOST_BANG_CLK) ? mask : 0);
3089 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
3090 o1 | URTW_BB_HOST_BANG_RW);
3091 DELAY(2);
3092 }
3093
3094 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1 | URTW_BB_HOST_BANG_EN |
3095 URTW_BB_HOST_BANG_RW);
3096 DELAY(2);
3097
3098 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, o2);
3099 urtw_write16_m(sc, URTW_RF_PINS_SELECT, o3);
3100 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, URTW_RF_PINS_OUTPUT_MAGIC1);
3101
3102 if (data != NULL)
3103 *data = value;
3104fail:
3105 return (error);
3106}
3107
3108
3109static usb_error_t
3110urtw_8225v2_set_txpwrlvl(struct urtw_softc *sc, int chan)
3111{
3112 int i;
3113 uint8_t *cck_pwrtable;
3114 uint8_t cck_pwrlvl_max = 15, ofdm_pwrlvl_max = 25, ofdm_pwrlvl_min = 10;
3115 uint8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
3116 uint8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
3117 usb_error_t error;
3118
3119 /* CCK power setting */
3120 cck_pwrlvl = (cck_pwrlvl > cck_pwrlvl_max) ? cck_pwrlvl_max : cck_pwrlvl;
3121 cck_pwrlvl += sc->sc_txpwr_cck_base;
3122 cck_pwrlvl = (cck_pwrlvl > 35) ? 35 : cck_pwrlvl;
3123 cck_pwrtable = (chan == 14) ? urtw_8225v2_txpwr_cck_ch14 :
3124 urtw_8225v2_txpwr_cck;
3125
3126 for (i = 0; i < 8; i++)
3127 urtw_8187_write_phy_cck(sc, 0x44 + i, cck_pwrtable[i]);
3128
3129 urtw_write8_m(sc, URTW_TX_GAIN_CCK,
3130 urtw_8225v2_tx_gain_cck_ofdm[cck_pwrlvl]);
3131 usb_pause_mtx(&sc->sc_mtx, 1);
3132
3133 /* OFDM power setting */
3134 ofdm_pwrlvl = (ofdm_pwrlvl > (ofdm_pwrlvl_max - ofdm_pwrlvl_min)) ?
3135 ofdm_pwrlvl_max : ofdm_pwrlvl + ofdm_pwrlvl_min;
3136 ofdm_pwrlvl += sc->sc_txpwr_ofdm_base;
3137 ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
3138
3139 error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
3140 if (error)
3141 goto fail;
3142
3143 urtw_8187_write_phy_ofdm(sc, 2, 0x42);
3144 urtw_8187_write_phy_ofdm(sc, 5, 0x0);
3145 urtw_8187_write_phy_ofdm(sc, 6, 0x40);
3146 urtw_8187_write_phy_ofdm(sc, 7, 0x0);
3147 urtw_8187_write_phy_ofdm(sc, 8, 0x40);
3148
3149 urtw_write8_m(sc, URTW_TX_GAIN_OFDM,
3150 urtw_8225v2_tx_gain_cck_ofdm[ofdm_pwrlvl]);
3151 usb_pause_mtx(&sc->sc_mtx, 1);
3152fail:
3153 return (error);
3154}
3155
3156static usb_error_t
3157urtw_8225v2_setgain(struct urtw_softc *sc, int16_t gain)
3158{
3159 uint8_t *gainp;
3160 usb_error_t error;
3161
3162 /* XXX for A? */
3163 gainp = urtw_8225v2_gain_bg;
3164 urtw_8187_write_phy_ofdm(sc, 0x0d, gainp[gain * 3]);
3165 usb_pause_mtx(&sc->sc_mtx, 1);
3166 urtw_8187_write_phy_ofdm(sc, 0x1b, gainp[gain * 3 + 1]);
3167 usb_pause_mtx(&sc->sc_mtx, 1);
3168 urtw_8187_write_phy_ofdm(sc, 0x1d, gainp[gain * 3 + 2]);
3169 usb_pause_mtx(&sc->sc_mtx, 1);
3170 urtw_8187_write_phy_ofdm(sc, 0x21, 0x17);
3171 usb_pause_mtx(&sc->sc_mtx, 1);
3172fail:
3173 return (error);
3174}
3175
3176static usb_error_t
3177urtw_8225_isv2(struct urtw_softc *sc, int *ret)
3178{
3179 uint32_t data;
3180 usb_error_t error;
3181
3182 *ret = 1;
3183
3184 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, URTW_RF_PINS_MAGIC5);
3185 urtw_write16_m(sc, URTW_RF_PINS_SELECT, URTW_RF_PINS_MAGIC5);
3186 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, URTW_RF_PINS_MAGIC5);
3187 usb_pause_mtx(&sc->sc_mtx, 500);
3188
3189 urtw_8225_write(sc, URTW_8225_ADDR_0_MAGIC,
3190 URTW_8225_ADDR_0_DATA_MAGIC1);
3191
3192 error = urtw_8225_read(sc, URTW_8225_ADDR_8_MAGIC, &data);
3193 if (error != 0)
3194 goto fail;
3195 if (data != URTW_8225_ADDR_8_DATA_MAGIC1)
3196 *ret = 0;
3197 else {
3198 error = urtw_8225_read(sc, URTW_8225_ADDR_9_MAGIC, &data);
3199 if (error != 0)
3200 goto fail;
3201 if (data != URTW_8225_ADDR_9_DATA_MAGIC1)
3202 *ret = 0;
3203 }
3204
3205 urtw_8225_write(sc, URTW_8225_ADDR_0_MAGIC,
3206 URTW_8225_ADDR_0_DATA_MAGIC2);
3207fail:
3208 return (error);
3209}
3210
3211static usb_error_t
3212urtw_8225v2b_rf_init(struct urtw_softc *sc)
3213{
3214#define N(a) (sizeof(a) / sizeof((a)[0]))
3215 int i;
3216 uint8_t data8;
3217 usb_error_t error;
3218
3219 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3220 if (error)
3221 goto fail;
3222
3223 /*
3224 * initialize extra registers on 8187
3225 */
3226 urtw_write16_m(sc, URTW_BRSR_8187B, 0xfff);
3227
3228 /* retry limit */
3229 urtw_read8_m(sc, URTW_CW_CONF, &data8);
3230 data8 |= URTW_CW_CONF_PERPACKET_RETRY;
3231 urtw_write8_m(sc, URTW_CW_CONF, data8);
3232
3233 /* TX AGC */
3234 urtw_read8_m(sc, URTW_TX_AGC_CTL, &data8);
3235 data8 |= URTW_TX_AGC_CTL_PERPACKET_GAIN;
3236 urtw_write8_m(sc, URTW_TX_AGC_CTL, data8);
3237
3238 /* Auto Rate Fallback Control */
3239#define URTW_ARFR 0x1e0
3240 urtw_write16_m(sc, URTW_ARFR, 0xfff);
3241 urtw_read8_m(sc, URTW_RATE_FALLBACK, &data8);
3242 urtw_write8_m(sc, URTW_RATE_FALLBACK,
3243 data8 | URTW_RATE_FALLBACK_ENABLE);
3244
3245 urtw_read8_m(sc, URTW_MSR, &data8);
3246 urtw_write8_m(sc, URTW_MSR, data8 & 0xf3);
3247 urtw_read8_m(sc, URTW_MSR, &data8);
3248 urtw_write8_m(sc, URTW_MSR, data8 | URTW_MSR_LINK_ENEDCA);
3249 urtw_write8_m(sc, URTW_ACM_CONTROL, sc->sc_acmctl);
3250
3251 urtw_write16_m(sc, URTW_ATIM_WND, 2);
3252 urtw_write16_m(sc, URTW_BEACON_INTERVAL, 100);
3253#define URTW_FEMR_FOR_8187B 0x1d4
3254 urtw_write16_m(sc, URTW_FEMR_FOR_8187B, 0xffff);
3255
3256 /* led type */
3257 urtw_read8_m(sc, URTW_CONFIG1, &data8);
3258 data8 = (data8 & 0x3f) | 0x80;
3259 urtw_write8_m(sc, URTW_CONFIG1, data8);
3260
3261 /* applying MAC address again. */
3262 urtw_write32_m(sc, URTW_MAC0, ((uint32_t *)sc->sc_bssid)[0]);
3263 urtw_write16_m(sc, URTW_MAC4, ((uint32_t *)sc->sc_bssid)[1] & 0xffff);
3264
3265 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3266 if (error)
3267 goto fail;
3268
3269 urtw_write8_m(sc, URTW_WPA_CONFIG, 0);
3270
3271 /*
3272 * MAC configuration
3273 */
3274 for (i = 0; i < N(urtw_8225v2b_rf_part1); i++)
3275 urtw_write8_m(sc, urtw_8225v2b_rf_part1[i].reg,
3276 urtw_8225v2b_rf_part1[i].val);
3277 urtw_write16_m(sc, URTW_TID_AC_MAP, 0xfa50);
3278 urtw_write16_m(sc, URTW_INT_MIG, 0x0000);
3279 urtw_write32_m(sc, 0x1f0, 0);
3280 urtw_write32_m(sc, 0x1f4, 0);
3281 urtw_write8_m(sc, 0x1f8, 0);
3282 urtw_write32_m(sc, URTW_RF_TIMING, 0x4001);
3283
3284#define URTW_RFSW_CTRL 0x272
3285 urtw_write16_m(sc, URTW_RFSW_CTRL, 0x569a);
3286
3287 /*
3288 * initialize PHY
3289 */
3290 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3291 if (error)
3292 goto fail;
3293 urtw_read8_m(sc, URTW_CONFIG3, &data8);
3294 urtw_write8_m(sc, URTW_CONFIG3,
3295 data8 | URTW_CONFIG3_ANAPARAM_WRITE);
3296
3297 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3298 if (error)
3299 goto fail;
3300
3301 /* setup RFE initial timing */
3302 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, 0x0480);
3303 urtw_write16_m(sc, URTW_RF_PINS_SELECT, 0x2488);
3304 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x1fff);
3305 usb_pause_mtx(&sc->sc_mtx, 1100);
3306
3307 for (i = 0; i < N(urtw_8225v2b_rf_part0); i++) {
3308 urtw_8225_write(sc, urtw_8225v2b_rf_part0[i].reg,
3309 urtw_8225v2b_rf_part0[i].val);
3310 usb_pause_mtx(&sc->sc_mtx, 1);
3311 }
3312 urtw_8225_write(sc, 0x00, 0x01b7);
3313
3314 for (i = 0; i < 95; i++) {
3315 urtw_8225_write(sc, URTW_8225_ADDR_1_MAGIC, (uint8_t)(i + 1));
3316 usb_pause_mtx(&sc->sc_mtx, 1);
3317 urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC,
3318 urtw_8225v2b_rxgain[i]);
3319 usb_pause_mtx(&sc->sc_mtx, 1);
3320 }
3321
3322 urtw_8225_write(sc, URTW_8225_ADDR_3_MAGIC, 0x080);
3323 usb_pause_mtx(&sc->sc_mtx, 1);
3324 urtw_8225_write(sc, URTW_8225_ADDR_5_MAGIC, 0x004);
3325 usb_pause_mtx(&sc->sc_mtx, 1);
3326 urtw_8225_write(sc, URTW_8225_ADDR_0_MAGIC, 0x0b7);
3327 usb_pause_mtx(&sc->sc_mtx, 1);
3328 usb_pause_mtx(&sc->sc_mtx, 3000);
3329 urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC, 0xc4d);
3330 usb_pause_mtx(&sc->sc_mtx, 2000);
3331 urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC, 0x44d);
3332 usb_pause_mtx(&sc->sc_mtx, 1);
3333 urtw_8225_write(sc, URTW_8225_ADDR_0_MAGIC, 0x2bf);
3334 usb_pause_mtx(&sc->sc_mtx, 1);
3335
3336 urtw_write8_m(sc, URTW_TX_GAIN_CCK, 0x03);
3337 urtw_write8_m(sc, URTW_TX_GAIN_OFDM, 0x07);
3338 urtw_write8_m(sc, URTW_TX_ANTENNA, 0x03);
3339
3340 urtw_8187_write_phy_ofdm(sc, 0x80, 0x12);
3341 for (i = 0; i < 128; i++) {
3342 uint32_t addr, data;
3343
3344 data = (urtw_8225z2_agc[i] << 8) | 0x0000008f;
3345 addr = ((i + 0x80) << 8) | 0x0000008e;
3346
3347 urtw_8187_write_phy_ofdm(sc, data & 0x7f, (data >> 8) & 0xff);
3348 urtw_8187_write_phy_ofdm(sc, addr & 0x7f, (addr >> 8) & 0xff);
3349 urtw_8187_write_phy_ofdm(sc, 0x0e, 0x00);
3350 }
3351 urtw_8187_write_phy_ofdm(sc, 0x80, 0x10);
3352
3353 for (i = 0; i < N(urtw_8225v2b_rf_part2); i++)
3354 urtw_8187_write_phy_ofdm(sc, i, urtw_8225v2b_rf_part2[i].val);
3355
3356 urtw_write32_m(sc, URTW_8187B_AC_VO, (7 << 12) | (3 << 8) | 0x1c);
3357 urtw_write32_m(sc, URTW_8187B_AC_VI, (7 << 12) | (3 << 8) | 0x1c);
3358 urtw_write32_m(sc, URTW_8187B_AC_BE, (7 << 12) | (3 << 8) | 0x1c);
3359 urtw_write32_m(sc, URTW_8187B_AC_BK, (7 << 12) | (3 << 8) | 0x1c);
3360
3361 urtw_8187_write_phy_ofdm(sc, 0x97, 0x46);
3362 urtw_8187_write_phy_ofdm(sc, 0xa4, 0xb6);
3363 urtw_8187_write_phy_ofdm(sc, 0x85, 0xfc);
3364 urtw_8187_write_phy_cck(sc, 0xc1, 0x88);
3365
3366fail:
3367 return (error);
3368#undef N
3369}
3370
3371static usb_error_t
3372urtw_8225v2b_rf_set_chan(struct urtw_softc *sc, int chan)
3373{
3374 usb_error_t error;
3375
3376 error = urtw_8225v2b_set_txpwrlvl(sc, chan);
3377 if (error)
3378 goto fail;
3379
3380 urtw_8225_write(sc, URTW_8225_ADDR_7_MAGIC, urtw_8225_channel[chan]);
3381 usb_pause_mtx(&sc->sc_mtx, 10);
3382fail:
3383 return (error);
3384}
3385
3386static usb_error_t
3387urtw_8225v2b_set_txpwrlvl(struct urtw_softc *sc, int chan)
3388{
3389 int i;
3390 uint8_t *cck_pwrtable;
3391 uint8_t cck_pwrlvl_max = 15;
3392 uint8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
3393 uint8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
3394 usb_error_t error;
3395
3396 /* CCK power setting */
3397 cck_pwrlvl = (cck_pwrlvl > cck_pwrlvl_max) ?
3398 ((sc->sc_flags & URTW_RTL8187B_REV_B) ? cck_pwrlvl_max : 22) :
3399 (cck_pwrlvl + ((sc->sc_flags & URTW_RTL8187B_REV_B) ? 0 : 7));
3400 cck_pwrlvl += sc->sc_txpwr_cck_base;
3401 cck_pwrlvl = (cck_pwrlvl > 35) ? 35 : cck_pwrlvl;
3402 cck_pwrtable = (chan == 14) ? urtw_8225v2b_txpwr_cck_ch14 :
3403 urtw_8225v2b_txpwr_cck;
3404
3405 if (sc->sc_flags & URTW_RTL8187B_REV_B)
3406 cck_pwrtable += (cck_pwrlvl <= 6) ? 0 :
3407 ((cck_pwrlvl <= 11) ? 8 : 16);
3408 else
3409 cck_pwrtable += (cck_pwrlvl <= 5) ? 0 :
3410 ((cck_pwrlvl <= 11) ? 8 : ((cck_pwrlvl <= 17) ? 16 : 24));
3411
3412 for (i = 0; i < 8; i++)
3413 urtw_8187_write_phy_cck(sc, 0x44 + i, cck_pwrtable[i]);
3414
3415 urtw_write8_m(sc, URTW_TX_GAIN_CCK,
3416 urtw_8225v2_tx_gain_cck_ofdm[cck_pwrlvl] << 1);
3417 usb_pause_mtx(&sc->sc_mtx, 1);
3418
3419 /* OFDM power setting */
3420 ofdm_pwrlvl = (ofdm_pwrlvl > 15) ?
3421 ((sc->sc_flags & URTW_RTL8187B_REV_B) ? 17 : 25) :
3422 (ofdm_pwrlvl + ((sc->sc_flags & URTW_RTL8187B_REV_B) ? 2 : 10));
3423 ofdm_pwrlvl += sc->sc_txpwr_ofdm_base;
3424 ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
3425
3426 urtw_write8_m(sc, URTW_TX_GAIN_OFDM,
3427 urtw_8225v2_tx_gain_cck_ofdm[ofdm_pwrlvl] << 1);
3428
3429 if (sc->sc_flags & URTW_RTL8187B_REV_B) {
3430 if (ofdm_pwrlvl <= 11) {
3431 urtw_8187_write_phy_ofdm(sc, 0x87, 0x60);
3432 urtw_8187_write_phy_ofdm(sc, 0x89, 0x60);
3433 } else {
3434 urtw_8187_write_phy_ofdm(sc, 0x87, 0x5c);
3435 urtw_8187_write_phy_ofdm(sc, 0x89, 0x5c);
3436 }
3437 } else {
3438 if (ofdm_pwrlvl <= 11) {
3439 urtw_8187_write_phy_ofdm(sc, 0x87, 0x5c);
3440 urtw_8187_write_phy_ofdm(sc, 0x89, 0x5c);
3441 } else if (ofdm_pwrlvl <= 17) {
3442 urtw_8187_write_phy_ofdm(sc, 0x87, 0x54);
3443 urtw_8187_write_phy_ofdm(sc, 0x89, 0x54);
3444 } else {
3445 urtw_8187_write_phy_ofdm(sc, 0x87, 0x50);
3446 urtw_8187_write_phy_ofdm(sc, 0x89, 0x50);
3447 }
3448 }
3449 usb_pause_mtx(&sc->sc_mtx, 1);
3450fail:
3451 return (error);
3452}
3453
3454static usb_error_t
3455urtw_read8e(struct urtw_softc *sc, int val, uint8_t *data)
3456{
3457 struct usb_device_request req;
3458 usb_error_t error;
3459
3460 req.bmRequestType = UT_READ_VENDOR_DEVICE;
3461 req.bRequest = URTW_8187_GETREGS_REQ;
3462 USETW(req.wValue, val | 0xfe00);
3463 USETW(req.wIndex, 0);
3464 USETW(req.wLength, sizeof(uint8_t));
3465
3466 error = urtw_do_request(sc, &req, data);
3467 return (error);
3468}
3469
3470static usb_error_t
3471urtw_write8e(struct urtw_softc *sc, int val, uint8_t data)
3472{
3473 struct usb_device_request req;
3474
3475 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
3476 req.bRequest = URTW_8187_SETREGS_REQ;
3477 USETW(req.wValue, val | 0xfe00);
3478 USETW(req.wIndex, 0);
3479 USETW(req.wLength, sizeof(uint8_t));
3480
3481 return (urtw_do_request(sc, &req, &data));
3482}
3483
3484static usb_error_t
3485urtw_8180_set_anaparam(struct urtw_softc *sc, uint32_t val)
3486{
3487 uint8_t data;
3488 usb_error_t error;
3489
3490 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3491 if (error)
3492 goto fail;
3493
3494 urtw_read8_m(sc, URTW_CONFIG3, &data);
3495 urtw_write8_m(sc, URTW_CONFIG3, data | URTW_CONFIG3_ANAPARAM_WRITE);
3496 urtw_write32_m(sc, URTW_ANAPARAM, val);
3497 urtw_read8_m(sc, URTW_CONFIG3, &data);
3498 urtw_write8_m(sc, URTW_CONFIG3, data & ~URTW_CONFIG3_ANAPARAM_WRITE);
3499
3500 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3501 if (error)
3502 goto fail;
3503fail:
3504 return (error);
3505}
3506
3507static usb_error_t
3508urtw_8185_set_anaparam2(struct urtw_softc *sc, uint32_t val)
3509{
3510 uint8_t data;
3511 usb_error_t error;
3512
3513 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3514 if (error)
3515 goto fail;
3516
3517 urtw_read8_m(sc, URTW_CONFIG3, &data);
3518 urtw_write8_m(sc, URTW_CONFIG3, data | URTW_CONFIG3_ANAPARAM_WRITE);
3519 urtw_write32_m(sc, URTW_ANAPARAM2, val);
3520 urtw_read8_m(sc, URTW_CONFIG3, &data);
3521 urtw_write8_m(sc, URTW_CONFIG3, data & ~URTW_CONFIG3_ANAPARAM_WRITE);
3522
3523 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3524 if (error)
3525 goto fail;
3526fail:
3527 return (error);
3528}
3529
3530static usb_error_t
3531urtw_intr_enable(struct urtw_softc *sc)
3532{
3533 usb_error_t error;
3534
3535 urtw_write16_m(sc, URTW_INTR_MASK, 0xffff);
3536fail:
3537 return (error);
3538}
3539
3540static usb_error_t
3541urtw_intr_disable(struct urtw_softc *sc)
3542{
3543 usb_error_t error;
3544
3545 urtw_write16_m(sc, URTW_INTR_MASK, 0);
3546fail:
3547 return (error);
3548}
3549
3550static usb_error_t
3551urtw_reset(struct urtw_softc *sc)
3552{
3553 uint8_t data;
3554 usb_error_t error;
3555
3556 error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
3557 if (error)
3558 goto fail;
3559 error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
3560 if (error)
3561 goto fail;
3562
3563 error = urtw_intr_disable(sc);
3564 if (error)
3565 goto fail;
3566 usb_pause_mtx(&sc->sc_mtx, 100);
3567
3568 error = urtw_write8e(sc, 0x18, 0x10);
3569 if (error != 0)
3570 goto fail;
3571 error = urtw_write8e(sc, 0x18, 0x11);
3572 if (error != 0)
3573 goto fail;
3574 error = urtw_write8e(sc, 0x18, 0x00);
3575 if (error != 0)
3576 goto fail;
3577 usb_pause_mtx(&sc->sc_mtx, 100);
3578
3579 urtw_read8_m(sc, URTW_CMD, &data);
3580 data = (data & 0x2) | URTW_CMD_RST;
3581 urtw_write8_m(sc, URTW_CMD, data);
3582 usb_pause_mtx(&sc->sc_mtx, 100);
3583
3584 urtw_read8_m(sc, URTW_CMD, &data);
3585 if (data & URTW_CMD_RST) {
3586 device_printf(sc->sc_dev, "reset timeout\n");
3587 goto fail;
3588 }
3589
3590 error = urtw_set_mode(sc, URTW_EPROM_CMD_LOAD);
3591 if (error)
3592 goto fail;
3593 usb_pause_mtx(&sc->sc_mtx, 100);
3594
3595 error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
3596 if (error)
3597 goto fail;
3598 error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
3599 if (error)
3600 goto fail;
3601fail:
3602 return (error);
3603}
3604
3605static usb_error_t
3606urtw_led_ctl(struct urtw_softc *sc, int mode)
3607{
3608 usb_error_t error = 0;
3609
3610 switch (sc->sc_strategy) {
3611 case URTW_SW_LED_MODE0:
3612 error = urtw_led_mode0(sc, mode);
3613 break;
3614 case URTW_SW_LED_MODE1:
3615 error = urtw_led_mode1(sc, mode);
3616 break;
3617 case URTW_SW_LED_MODE2:
3618 error = urtw_led_mode2(sc, mode);
3619 break;
3620 case URTW_SW_LED_MODE3:
3621 error = urtw_led_mode3(sc, mode);
3622 break;
3623 default:
3624 panic("unsupported LED mode %d\n", sc->sc_strategy);
3625 /* never reach */
3626 }
3627
3628 return (error);
3629}
3630
3631static usb_error_t
3632urtw_led_mode0(struct urtw_softc *sc, int mode)
3633{
3634
3635 switch (mode) {
3636 case URTW_LED_CTL_POWER_ON:
3637 sc->sc_gpio_ledstate = URTW_LED_POWER_ON_BLINK;
3638 break;
3639 case URTW_LED_CTL_TX:
3640 if (sc->sc_gpio_ledinprogress == 1)
3641 return (0);
3642
3643 sc->sc_gpio_ledstate = URTW_LED_BLINK_NORMAL;
3644 sc->sc_gpio_blinktime = 2;
3645 break;
3646 case URTW_LED_CTL_LINK:
3647 sc->sc_gpio_ledstate = URTW_LED_ON;
3648 break;
3649 default:
3650 panic("unsupported LED mode 0x%x", mode);
3651 /* never reach */
3652 }
3653
3654 switch (sc->sc_gpio_ledstate) {
3655 case URTW_LED_ON:
3656 if (sc->sc_gpio_ledinprogress != 0)
3657 break;
3658 urtw_led_on(sc, URTW_LED_GPIO);
3659 break;
3660 case URTW_LED_BLINK_NORMAL:
3661 if (sc->sc_gpio_ledinprogress != 0)
3662 break;
3663 sc->sc_gpio_ledinprogress = 1;
3664 sc->sc_gpio_blinkstate = (sc->sc_gpio_ledon != 0) ?
3665 URTW_LED_OFF : URTW_LED_ON;
3666 usb_callout_reset(&sc->sc_led_ch, hz, urtw_led_ch, sc);
3667 break;
3668 case URTW_LED_POWER_ON_BLINK:
3669 urtw_led_on(sc, URTW_LED_GPIO);
3670 usb_pause_mtx(&sc->sc_mtx, 100);
3671 urtw_led_off(sc, URTW_LED_GPIO);
3672 break;
3673 default:
3674 panic("unknown LED status 0x%x", sc->sc_gpio_ledstate);
3675 /* never reach */
3676 }
3677 return (0);
3678}
3679
3680static usb_error_t
3681urtw_led_mode1(struct urtw_softc *sc, int mode)
3682{
3683
3684 return (USB_ERR_INVAL);
3685}
3686
3687static usb_error_t
3688urtw_led_mode2(struct urtw_softc *sc, int mode)
3689{
3690
3691 return (USB_ERR_INVAL);
3692}
3693
3694static usb_error_t
3695urtw_led_mode3(struct urtw_softc *sc, int mode)
3696{
3697
3698 return (USB_ERR_INVAL);
3699}
3700
3701static usb_error_t
3702urtw_led_on(struct urtw_softc *sc, int type)
3703{
3704 usb_error_t error;
3705
3706 if (type == URTW_LED_GPIO) {
3707 switch (sc->sc_gpio_ledpin) {
3708 case URTW_LED_PIN_GPIO0:
3709 urtw_write8_m(sc, URTW_GPIO, 0x01);
3710 urtw_write8_m(sc, URTW_GP_ENABLE, 0x00);
3711 break;
3712 default:
3713 panic("unsupported LED PIN type 0x%x",
3714 sc->sc_gpio_ledpin);
3715 /* never reach */
3716 }
3717 } else {
3718 panic("unsupported LED type 0x%x", type);
3719 /* never reach */
3720 }
3721
3722 sc->sc_gpio_ledon = 1;
3723fail:
3724 return (error);
3725}
3726
3727static usb_error_t
3728urtw_led_off(struct urtw_softc *sc, int type)
3729{
3730 usb_error_t error;
3731
3732 if (type == URTW_LED_GPIO) {
3733 switch (sc->sc_gpio_ledpin) {
3734 case URTW_LED_PIN_GPIO0:
3735 urtw_write8_m(sc, URTW_GPIO, URTW_GPIO_DATA_MAGIC1);
3736 urtw_write8_m(sc,
3737 URTW_GP_ENABLE, URTW_GP_ENABLE_DATA_MAGIC1);
3738 break;
3739 default:
3740 panic("unsupported LED PIN type 0x%x",
3741 sc->sc_gpio_ledpin);
3742 /* never reach */
3743 }
3744 } else {
3745 panic("unsupported LED type 0x%x", type);
3746 /* never reach */
3747 }
3748
3749 sc->sc_gpio_ledon = 0;
3750
3751fail:
3752 return (error);
3753}
3754
3755static void
3756urtw_led_ch(void *arg)
3757{
3758 struct urtw_softc *sc = arg;
3759 struct ifnet *ifp = sc->sc_ifp;
3760 struct ieee80211com *ic = ifp->if_l2com;
3761
3762 ieee80211_runtask(ic, &sc->sc_led_task);
3763}
3764
3765static void
3766urtw_ledtask(void *arg, int pending)
3767{
3768 struct urtw_softc *sc = arg;
3769
3770 if (sc->sc_strategy != URTW_SW_LED_MODE0)
3771 panic("could not process a LED strategy 0x%x", sc->sc_strategy);
3772
3773 URTW_LOCK(sc);
3774 urtw_led_blink(sc);
3775 URTW_UNLOCK(sc);
3776}
3777
3778static usb_error_t
3779urtw_led_blink(struct urtw_softc *sc)
3780{
3781 uint8_t ing = 0;
3782 usb_error_t error;
3783
3784 if (sc->sc_gpio_blinkstate == URTW_LED_ON)
3785 error = urtw_led_on(sc, URTW_LED_GPIO);
3786 else
3787 error = urtw_led_off(sc, URTW_LED_GPIO);
3788 sc->sc_gpio_blinktime--;
3789 if (sc->sc_gpio_blinktime == 0)
3790 ing = 1;
3791 else {
3792 if (sc->sc_gpio_ledstate != URTW_LED_BLINK_NORMAL &&
3793 sc->sc_gpio_ledstate != URTW_LED_BLINK_SLOWLY &&
3794 sc->sc_gpio_ledstate != URTW_LED_BLINK_CM3)
3795 ing = 1;
3796 }
3797 if (ing == 1) {
3798 if (sc->sc_gpio_ledstate == URTW_LED_ON &&
3799 sc->sc_gpio_ledon == 0)
3800 error = urtw_led_on(sc, URTW_LED_GPIO);
3801 else if (sc->sc_gpio_ledstate == URTW_LED_OFF &&
3802 sc->sc_gpio_ledon == 1)
3803 error = urtw_led_off(sc, URTW_LED_GPIO);
3804
3805 sc->sc_gpio_blinktime = 0;
3806 sc->sc_gpio_ledinprogress = 0;
3807 return (0);
3808 }
3809
3810 sc->sc_gpio_blinkstate = (sc->sc_gpio_blinkstate != URTW_LED_ON) ?
3811 URTW_LED_ON : URTW_LED_OFF;
3812
3813 switch (sc->sc_gpio_ledstate) {
3814 case URTW_LED_BLINK_NORMAL:
3815 usb_callout_reset(&sc->sc_led_ch, hz, urtw_led_ch, sc);
3816 break;
3817 default:
3818 panic("unknown LED status 0x%x", sc->sc_gpio_ledstate);
3819 /* never reach */
3820 }
3821 return (0);
3822}
3823
3824static usb_error_t
3825urtw_rx_enable(struct urtw_softc *sc)
3826{
3827 uint8_t data;
3828 usb_error_t error;
3829
3830 usbd_transfer_start((sc->sc_flags & URTW_RTL8187B) ?
3831 sc->sc_xfer[URTW_8187B_BULK_RX] : sc->sc_xfer[URTW_8187L_BULK_RX]);
3832
3833 error = urtw_rx_setconf(sc);
3834 if (error != 0)
3835 goto fail;
3836
3837 if ((sc->sc_flags & URTW_RTL8187B) == 0) {
3838 urtw_read8_m(sc, URTW_CMD, &data);
3839 urtw_write8_m(sc, URTW_CMD, data | URTW_CMD_RX_ENABLE);
3840 }
3841fail:
3842 return (error);
3843}
3844
3845static usb_error_t
3846urtw_tx_enable(struct urtw_softc *sc)
3847{
3848 uint8_t data8;
3849 uint32_t data;
3850 usb_error_t error;
3851
3852 if (sc->sc_flags & URTW_RTL8187B) {
3853 urtw_read32_m(sc, URTW_TX_CONF, &data);
3854 data &= ~URTW_TX_LOOPBACK_MASK;
3855 data &= ~(URTW_TX_DPRETRY_MASK | URTW_TX_RTSRETRY_MASK);
3856 data &= ~(URTW_TX_NOCRC | URTW_TX_MXDMA_MASK);
3857 data &= ~URTW_TX_SWPLCPLEN;
3858 data |= URTW_TX_HW_SEQNUM | URTW_TX_DISREQQSIZE |
3859 (7 << 8) | /* short retry limit */
3860 (7 << 0) | /* long retry limit */
3861 (7 << 21); /* MAX TX DMA */
3862 urtw_write32_m(sc, URTW_TX_CONF, data);
3863
3864 urtw_read8_m(sc, URTW_MSR, &data8);
3865 data8 |= URTW_MSR_LINK_ENEDCA;
3866 urtw_write8_m(sc, URTW_MSR, data8);
3867 return (error);
3868 }
3869
3870 urtw_read8_m(sc, URTW_CW_CONF, &data8);
3871 data8 &= ~(URTW_CW_CONF_PERPACKET_CW | URTW_CW_CONF_PERPACKET_RETRY);
3872 urtw_write8_m(sc, URTW_CW_CONF, data8);
3873
3874 urtw_read8_m(sc, URTW_TX_AGC_CTL, &data8);
3875 data8 &= ~URTW_TX_AGC_CTL_PERPACKET_GAIN;
3876 data8 &= ~URTW_TX_AGC_CTL_PERPACKET_ANTSEL;
3877 data8 &= ~URTW_TX_AGC_CTL_FEEDBACK_ANT;
3878 urtw_write8_m(sc, URTW_TX_AGC_CTL, data8);
3879
3880 urtw_read32_m(sc, URTW_TX_CONF, &data);
3881 data &= ~URTW_TX_LOOPBACK_MASK;
3882 data |= URTW_TX_LOOPBACK_NONE;
3883 data &= ~(URTW_TX_DPRETRY_MASK | URTW_TX_RTSRETRY_MASK);
3884 data |= sc->sc_tx_retry << URTW_TX_DPRETRY_SHIFT;
3885 data |= sc->sc_rts_retry << URTW_TX_RTSRETRY_SHIFT;
3886 data &= ~(URTW_TX_NOCRC | URTW_TX_MXDMA_MASK);
3887 data |= URTW_TX_MXDMA_2048 | URTW_TX_CWMIN | URTW_TX_DISCW;
3888 data &= ~URTW_TX_SWPLCPLEN;
3889 data |= URTW_TX_NOICV;
3890 urtw_write32_m(sc, URTW_TX_CONF, data);
3891
3892 urtw_read8_m(sc, URTW_CMD, &data8);
3893 urtw_write8_m(sc, URTW_CMD, data8 | URTW_CMD_TX_ENABLE);
3894fail:
3895 return (error);
3896}
3897
3898static usb_error_t
3899urtw_rx_setconf(struct urtw_softc *sc)
3900{
3901 struct ifnet *ifp = sc->sc_ifp;
3902 struct ieee80211com *ic = ifp->if_l2com;
3903 uint32_t data;
3904 usb_error_t error;
3905
3906 urtw_read32_m(sc, URTW_RX, &data);
3907 data = data &~ URTW_RX_FILTER_MASK;
3908 if (sc->sc_flags & URTW_RTL8187B) {
3909 data = data | URTW_RX_FILTER_MNG | URTW_RX_FILTER_DATA |
3910 URTW_RX_FILTER_MCAST | URTW_RX_FILTER_BCAST |
3911 URTW_RX_FILTER_NICMAC | URTW_RX_CHECK_BSSID |
3912 URTW_RX_FIFO_THRESHOLD_NONE |
3913 URTW_MAX_RX_DMA_2048 |
3914 URTW_RX_AUTORESETPHY | URTW_RCR_ONLYERLPKT;
3915 } else {
3916 data = data | URTW_RX_FILTER_MNG | URTW_RX_FILTER_DATA;
3917 data = data | URTW_RX_FILTER_BCAST | URTW_RX_FILTER_MCAST;
3918
3919 if (ic->ic_opmode == IEEE80211_M_MONITOR) {
3920 data = data | URTW_RX_FILTER_ICVERR;
3921 data = data | URTW_RX_FILTER_PWR;
3922 }
3923 if (sc->sc_crcmon == 1 && ic->ic_opmode == IEEE80211_M_MONITOR)
3924 data = data | URTW_RX_FILTER_CRCERR;
3925
3926 if (ic->ic_opmode == IEEE80211_M_MONITOR ||
3927 (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC))) {
3928 data = data | URTW_RX_FILTER_ALLMAC;
3929 } else {
3930 data = data | URTW_RX_FILTER_NICMAC;
3931 data = data | URTW_RX_CHECK_BSSID;
3932 }
3933
3934 data = data &~ URTW_RX_FIFO_THRESHOLD_MASK;
3935 data = data | URTW_RX_FIFO_THRESHOLD_NONE |
3936 URTW_RX_AUTORESETPHY;
3937 data = data &~ URTW_MAX_RX_DMA_MASK;
3938 data = data | URTW_MAX_RX_DMA_2048 | URTW_RCR_ONLYERLPKT;
3939 }
3940
3941 urtw_write32_m(sc, URTW_RX, data);
3942fail:
3943 return (error);
3944}
3945
3946static struct mbuf *
3947urtw_rxeof(struct usb_xfer *xfer, struct urtw_data *data, int *rssi_p,
3948 int8_t *nf_p)
3949{
3950 int actlen, flen, rssi;
3951 struct ieee80211_frame *wh;
3952 struct mbuf *m, *mnew;
3953 struct urtw_softc *sc = data->sc;
3954 struct ifnet *ifp = sc->sc_ifp;
3955 struct ieee80211com *ic = ifp->if_l2com;
3956 uint8_t noise = 0, rate;
3957
3958 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
3959
3960 if (actlen < URTW_MIN_RXBUFSZ) {
3961 ifp->if_ierrors++;
3962 return (NULL);
3963 }
3964
3965 if (sc->sc_flags & URTW_RTL8187B) {
3966 struct urtw_8187b_rxhdr *rx;
3967
3968 rx = (struct urtw_8187b_rxhdr *)(data->buf +
3969 (actlen - (sizeof(struct urtw_8187b_rxhdr))));
3970 flen = le32toh(rx->flag) & 0xfff;
3971 if (flen > actlen) {
3972 ifp->if_ierrors++;
3973 return (NULL);
3974 }
3975 rate = (le32toh(rx->flag) >> URTW_RX_FLAG_RXRATE_SHIFT) & 0xf;
3976 /* XXX correct? */
3977 rssi = rx->rssi & URTW_RX_RSSI_MASK;
3978 noise = rx->noise;
3979 } else {
3980 struct urtw_8187l_rxhdr *rx;
3981
3982 rx = (struct urtw_8187l_rxhdr *)(data->buf +
3983 (actlen - (sizeof(struct urtw_8187l_rxhdr))));
3984 flen = le32toh(rx->flag) & 0xfff;
3985 if (flen > actlen) {
3986 ifp->if_ierrors++;
3987 return (NULL);
3988 }
3989
3990 rate = (le32toh(rx->flag) >> URTW_RX_FLAG_RXRATE_SHIFT) & 0xf;
3991 /* XXX correct? */
3992 rssi = rx->rssi & URTW_RX_8187L_RSSI_MASK;
3993 noise = rx->noise;
3994 }
3995
3996 mnew = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
3997 if (mnew == NULL) {
3998 ifp->if_ierrors++;
3999 return (NULL);
4000 }
4001
4002 m = data->m;
4003 data->m = mnew;
4004 data->buf = mtod(mnew, uint8_t *);
4005
4006 /* finalize mbuf */
4007 m->m_pkthdr.rcvif = ifp;
4008 m->m_pkthdr.len = m->m_len = flen - IEEE80211_CRC_LEN;
4009
4010 if (ieee80211_radiotap_active(ic)) {
4011 struct urtw_rx_radiotap_header *tap = &sc->sc_rxtap;
4012
4013 /* XXX Are variables correct? */
4014 tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
4015 tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
4016 tap->wr_dbm_antsignal = (int8_t)rssi;
4017 }
4018
4019 wh = mtod(m, struct ieee80211_frame *);
4020 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_DATA)
4021 sc->sc_currate = (rate > 0) ? rate : sc->sc_currate;
4022
4023 *rssi_p = rssi;
4024 *nf_p = noise; /* XXX correct? */
4025
4026 return (m);
4027}
4028
4029static void
4030urtw_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
4031{
4032 struct urtw_softc *sc = usbd_xfer_softc(xfer);
4033 struct ifnet *ifp = sc->sc_ifp;
4034 struct ieee80211com *ic = ifp->if_l2com;
4035 struct ieee80211_frame *wh;
4036 struct ieee80211_node *ni;
4037 struct mbuf *m = NULL;
4038 struct urtw_data *data;
4039 int8_t nf = -95;
4040 int rssi = 1;
4041
4042 URTW_ASSERT_LOCKED(sc);
4043
4044 switch (USB_GET_STATE(xfer)) {
4045 case USB_ST_TRANSFERRED:
4046 data = STAILQ_FIRST(&sc->sc_rx_active);
4047 if (data == NULL)
4048 goto setup;
4049 STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next);
4050 m = urtw_rxeof(xfer, data, &rssi, &nf);
4051 STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next);
4052 /* FALLTHROUGH */
4053 case USB_ST_SETUP:
4054setup:
4055 data = STAILQ_FIRST(&sc->sc_rx_inactive);
4056 if (data == NULL) {
4057 KASSERT(m == NULL, ("mbuf isn't NULL"));
4058 return;
4059 }
4060 STAILQ_REMOVE_HEAD(&sc->sc_rx_inactive, next);
4061 STAILQ_INSERT_TAIL(&sc->sc_rx_active, data, next);
4062 usbd_xfer_set_frame_data(xfer, 0, data->buf,
4063 usbd_xfer_max_len(xfer));
4064 usbd_transfer_submit(xfer);
4065
4066 /*
4067 * To avoid LOR we should unlock our private mutex here to call
4068 * ieee80211_input() because here is at the end of a USB
4069 * callback and safe to unlock.
4070 */
4071 URTW_UNLOCK(sc);
4072 if (m != NULL) {
4073 wh = mtod(m, struct ieee80211_frame *);
4074 ni = ieee80211_find_rxnode(ic,
4075 (struct ieee80211_frame_min *)wh);
4076 if (ni != NULL) {
4077 (void) ieee80211_input(ni, m, rssi, nf);
4078 /* node is no longer needed */
4079 ieee80211_free_node(ni);
4080 } else
4081 (void) ieee80211_input_all(ic, m, rssi, nf);
4082 m = NULL;
4083 }
4084 URTW_LOCK(sc);
4085 break;
4086 default:
4087 /* needs it to the inactive queue due to a error. */
4088 data = STAILQ_FIRST(&sc->sc_rx_active);
4089 if (data != NULL) {
4090 STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next);
4091 STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next);
4092 }
4093 if (error != USB_ERR_CANCELLED) {
4094 usbd_xfer_set_stall(xfer);
4095 ifp->if_ierrors++;
4096 goto setup;
4097 }
4098 break;
4099 }
4100}
4101
4102#define URTW_STATUS_TYPE_TXCLOSE 1
4103#define URTW_STATUS_TYPE_BEACON_INTR 0
4104
4105static void
4106urtw_txstatus_eof(struct usb_xfer *xfer)
4107{
4108 struct urtw_softc *sc = usbd_xfer_softc(xfer);
4109 struct ifnet *ifp = sc->sc_ifp;
4110 int actlen, type, pktretry, seq;
4111 uint64_t val;
4112
4113 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
4114
4115 if (actlen != sizeof(uint64_t))
4116 return;
4117
4118 val = le64toh(sc->sc_txstatus);
4119 type = (val >> 30) & 0x3;
4120 if (type == URTW_STATUS_TYPE_TXCLOSE) {
4121 pktretry = val & 0xff;
4122 seq = (val >> 16) & 0xff;
4123 if (pktretry == URTW_TX_MAXRETRY)
4124 ifp->if_oerrors++;
4125 DPRINTF(sc, URTW_DEBUG_TXSTATUS, "pktretry %d seq %#x\n",
4126 pktretry, seq);
4127 }
4128}
4129
4130static void
4131urtw_bulk_tx_status_callback(struct usb_xfer *xfer, usb_error_t error)
4132{
4133 struct urtw_softc *sc = usbd_xfer_softc(xfer);
4134 struct ifnet *ifp = sc->sc_ifp;
4135
4136 URTW_ASSERT_LOCKED(sc);
4137
4138 switch (USB_GET_STATE(xfer)) {
4139 case USB_ST_TRANSFERRED:
4140 urtw_txstatus_eof(xfer);
4141 /* FALLTHROUGH */
4142 case USB_ST_SETUP:
4143setup:
4144 usbd_xfer_set_frame_data(xfer, 0, &sc->sc_txstatus,
4145 sizeof(int64_t));
4146 usbd_transfer_submit(xfer);
4147 break;
4148 default:
4149 if (error != USB_ERR_CANCELLED) {
4150 usbd_xfer_set_stall(xfer);
4151 ifp->if_ierrors++;
4152 goto setup;
4153 }
4154 break;
4155 }
4156}
4157
4158static void
4159urtw_txeof(struct usb_xfer *xfer, struct urtw_data *data)
4160{
4161 struct urtw_softc *sc = usbd_xfer_softc(xfer);
4162 struct ifnet *ifp = sc->sc_ifp;
4163 struct mbuf *m;
4164
4165 URTW_ASSERT_LOCKED(sc);
4166
4167 /*
4168 * Do any tx complete callback. Note this must be done before releasing
4169 * the node reference.
4170 */
4171 if (data->m) {
4172 m = data->m;
4173 if (m->m_flags & M_TXCB) {
4174 /* XXX status? */
4175 ieee80211_process_callback(data->ni, m, 0);
4176 }
4177 m_freem(m);
4178 data->m = NULL;
4179 }
4180 if (data->ni) {
4181 ieee80211_free_node(data->ni);
4182 data->ni = NULL;
4183 }
4184 sc->sc_txtimer = 0;
4185 ifp->if_opackets++;
4186 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
4187}
4188
4189static void
4190urtw_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error)
4191{
4192 struct urtw_softc *sc = usbd_xfer_softc(xfer);
4193 struct ifnet *ifp = sc->sc_ifp;
4194 struct urtw_data *data;
4195
4196 URTW_ASSERT_LOCKED(sc);
4197
4198 switch (USB_GET_STATE(xfer)) {
4199 case USB_ST_TRANSFERRED:
4200 data = STAILQ_FIRST(&sc->sc_tx_active);
4201 if (data == NULL)
4202 goto setup;
4203 STAILQ_REMOVE_HEAD(&sc->sc_tx_active, next);
4204 urtw_txeof(xfer, data);
4205 STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data, next);
4206 /* FALLTHROUGH */
4207 case USB_ST_SETUP:
4208setup:
4209 data = STAILQ_FIRST(&sc->sc_tx_pending);
4210 if (data == NULL) {
4211 DPRINTF(sc, URTW_DEBUG_XMIT,
4212 "%s: empty pending queue\n", __func__);
4213 return;
4214 }
4215 STAILQ_REMOVE_HEAD(&sc->sc_tx_pending, next);
4216 STAILQ_INSERT_TAIL(&sc->sc_tx_active, data, next);
4217
4218 usbd_xfer_set_frame_data(xfer, 0, data->buf, data->buflen);
4219 usbd_transfer_submit(xfer);
4220
4221 URTW_UNLOCK(sc);
4222 urtw_start(ifp);
4223 URTW_LOCK(sc);
4224 break;
4225 default:
4226 data = STAILQ_FIRST(&sc->sc_tx_active);
4227 if (data == NULL)
4228 goto setup;
4229 if (data->ni != NULL) {
4230 ieee80211_free_node(data->ni);
4231 data->ni = NULL;
4232 ifp->if_oerrors++;
4233 }
4234 if (error != USB_ERR_CANCELLED) {
4235 usbd_xfer_set_stall(xfer);
4236 goto setup;
4237 }
4238 break;
4239 }
4240}
4241
4242static struct urtw_data *
4243_urtw_getbuf(struct urtw_softc *sc)
4244{
4245 struct urtw_data *bf;
4246
4247 bf = STAILQ_FIRST(&sc->sc_tx_inactive);
4248 if (bf != NULL)
4249 STAILQ_REMOVE_HEAD(&sc->sc_tx_inactive, next);
4250 else
4251 bf = NULL;
4252 if (bf == NULL)
4253 DPRINTF(sc, URTW_DEBUG_XMIT, "%s: %s\n", __func__,
4254 "out of xmit buffers");
4255 return (bf);
4256}
4257
4258static struct urtw_data *
4259urtw_getbuf(struct urtw_softc *sc)
4260{
4261 struct urtw_data *bf;
4262
4263 URTW_ASSERT_LOCKED(sc);
4264
4265 bf = _urtw_getbuf(sc);
4266 if (bf == NULL) {
4267 struct ifnet *ifp = sc->sc_ifp;
4268
4269 DPRINTF(sc, URTW_DEBUG_XMIT, "%s: stop queue\n", __func__);
4270 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
4271 }
4272 return (bf);
4273}
4274
4275static int
4276urtw_isbmode(uint16_t rate)
4277{
4278
4279 return ((rate <= 22 && rate != 12 && rate != 18) ||
4280 rate == 44) ? (1) : (0);
4281}
4282
4283static uint16_t
4284urtw_rate2dbps(uint16_t rate)
4285{
4286
4287 switch(rate) {
4288 case 12:
4289 case 18:
4290 case 24:
4291 case 36:
4292 case 48:
4293 case 72:
4294 case 96:
4295 case 108:
4296 return (rate * 2);
4297 default:
4298 break;
4299 }
4300 return (24);
4301}
4302
4303static int
4304urtw_compute_txtime(uint16_t framelen, uint16_t rate,
4305 uint8_t ismgt, uint8_t isshort)
4306{
4307 uint16_t ceiling, frametime, n_dbps;
4308
4309 if (urtw_isbmode(rate)) {
4310 if (ismgt || !isshort || rate == 2)
4311 frametime = (uint16_t)(144 + 48 +
4312 (framelen * 8 / (rate / 2)));
4313 else
4314 frametime = (uint16_t)(72 + 24 +
4315 (framelen * 8 / (rate / 2)));
4316 if ((framelen * 8 % (rate / 2)) != 0)
4317 frametime++;
4318 } else {
4319 n_dbps = urtw_rate2dbps(rate);
4320 ceiling = (16 + 8 * framelen + 6) / n_dbps
4321 + (((16 + 8 * framelen + 6) % n_dbps) ? 1 : 0);
4322 frametime = (uint16_t)(16 + 4 + 4 * ceiling + 6);
4323 }
4324 return (frametime);
4325}
4326
4327/*
4328 * Callback from the 802.11 layer to update the
4329 * slot time based on the current setting.
4330 */
4331static void
4332urtw_updateslot(struct ifnet *ifp)
4333{
4334 struct urtw_softc *sc = ifp->if_softc;
4335 struct ieee80211com *ic = ifp->if_l2com;
4336
4337 ieee80211_runtask(ic, &sc->sc_updateslot_task);
4338}
4339
4340static void
4341urtw_updateslottask(void *arg, int pending)
4342{
4343 struct urtw_softc *sc = arg;
4344 struct ifnet *ifp = sc->sc_ifp;
4345 struct ieee80211com *ic = ifp->if_l2com;
4346 int error;
4347
4348 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
4349 return;
4350
4351 URTW_LOCK(sc);
4352 if (sc->sc_flags & URTW_RTL8187B) {
4353 urtw_write8_m(sc, URTW_SIFS, 0x22);
4354 if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan))
4355 urtw_write8_m(sc, URTW_SLOT, 0x9);
4356 else
4357 urtw_write8_m(sc, URTW_SLOT, 0x14);
4358 urtw_write8_m(sc, URTW_8187B_EIFS, 0x5b);
4359 urtw_write8_m(sc, URTW_CARRIER_SCOUNT, 0x5b);
4360 } else {
4361 urtw_write8_m(sc, URTW_SIFS, 0x22);
4362 if (sc->sc_state == IEEE80211_S_ASSOC &&
4363 ic->ic_flags & IEEE80211_F_SHSLOT)
4364 urtw_write8_m(sc, URTW_SLOT, 0x9);
4365 else
4366 urtw_write8_m(sc, URTW_SLOT, 0x14);
4367 if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan)) {
4368 urtw_write8_m(sc, URTW_DIFS, 0x14);
4369 urtw_write8_m(sc, URTW_EIFS, 0x5b - 0x14);
4370 urtw_write8_m(sc, URTW_CW_VAL, 0x73);
4371 } else {
4372 urtw_write8_m(sc, URTW_DIFS, 0x24);
4373 urtw_write8_m(sc, URTW_EIFS, 0x5b - 0x24);
4374 urtw_write8_m(sc, URTW_CW_VAL, 0xa5);
4375 }
4376 }
4377fail:
4378 URTW_UNLOCK(sc);
4379}
4380
4381static void
4382urtw_sysctl_node(struct urtw_softc *sc)
4383{
4384#define URTW_SYSCTL_STAT_ADD32(c, h, n, p, d) \
4385 SYSCTL_ADD_UINT(c, h, OID_AUTO, n, CTLFLAG_RD, p, 0, d)
4386 struct sysctl_ctx_list *ctx;
4387 struct sysctl_oid_list *child, *parent;
4388 struct sysctl_oid *tree;
4389 struct urtw_stats *stats = &sc->sc_stats;
4390
4391 ctx = device_get_sysctl_ctx(sc->sc_dev);
4392 child = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->sc_dev));
4393
4394 tree = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "stats", CTLFLAG_RD,
4395 NULL, "URTW statistics");
4396 parent = SYSCTL_CHILDREN(tree);
4397
4398 /* Tx statistics. */
4399 tree = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "tx", CTLFLAG_RD,
4400 NULL, "Tx MAC statistics");
4401 child = SYSCTL_CHILDREN(tree);
4402 URTW_SYSCTL_STAT_ADD32(ctx, child, "1m", &stats->txrates[0],
4403 "1 Mbit/s");
4404 URTW_SYSCTL_STAT_ADD32(ctx, child, "2m", &stats->txrates[1],
4405 "2 Mbit/s");
4406 URTW_SYSCTL_STAT_ADD32(ctx, child, "5.5m", &stats->txrates[2],
4407 "5.5 Mbit/s");
4408 URTW_SYSCTL_STAT_ADD32(ctx, child, "6m", &stats->txrates[4],
4409 "6 Mbit/s");
4410 URTW_SYSCTL_STAT_ADD32(ctx, child, "9m", &stats->txrates[5],
4411 "9 Mbit/s");
4412 URTW_SYSCTL_STAT_ADD32(ctx, child, "11m", &stats->txrates[3],
4413 "11 Mbit/s");
4414 URTW_SYSCTL_STAT_ADD32(ctx, child, "12m", &stats->txrates[6],
4415 "12 Mbit/s");
4416 URTW_SYSCTL_STAT_ADD32(ctx, child, "18m", &stats->txrates[7],
4417 "18 Mbit/s");
4418 URTW_SYSCTL_STAT_ADD32(ctx, child, "24m", &stats->txrates[8],
4419 "24 Mbit/s");
4420 URTW_SYSCTL_STAT_ADD32(ctx, child, "36m", &stats->txrates[9],
4421 "36 Mbit/s");
4422 URTW_SYSCTL_STAT_ADD32(ctx, child, "48m", &stats->txrates[10],
4423 "48 Mbit/s");
4424 URTW_SYSCTL_STAT_ADD32(ctx, child, "54m", &stats->txrates[11],
4425 "54 Mbit/s");
4426#undef URTW_SYSCTL_STAT_ADD32
4427}
4428
4429static device_method_t urtw_methods[] = {
4430 DEVMETHOD(device_probe, urtw_match),
4431 DEVMETHOD(device_attach, urtw_attach),
4432 DEVMETHOD(device_detach, urtw_detach),
4433 { 0, 0 }
4434};
4435static driver_t urtw_driver = {
4436 "urtw",
4437 urtw_methods,
4438 sizeof(struct urtw_softc)
4439};
4440static devclass_t urtw_devclass;
4441
4442DRIVER_MODULE(urtw, uhub, urtw_driver, urtw_devclass, NULL, 0);
4443MODULE_DEPEND(urtw, wlan, 1, 1, 1);
4444MODULE_DEPEND(urtw, usb, 1, 1, 1);