1/* $NetBSD: if_urtw.c,v 1.11 2016/07/14 04:00:46 msaitoh Exp $ */
2/* $OpenBSD: if_urtw.c,v 1.39 2011/07/03 15:47:17 matthew Exp $ */
3
4/*-
5 * Copyright (c) 2009 Martynas Venckus <martynas@openbsd.org>
6 * Copyright (c) 2008 Weongyo Jeong <weongyo@FreeBSD.org>
7 *
8 * Permission to use, copy, modify, and distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 */
20
21#include <sys/cdefs.h>
22__KERNEL_RCSID(0, "$NetBSD: if_urtw.c,v 1.11 2016/07/14 04:00:46 msaitoh Exp $");
23
24#include <sys/param.h>
25#include <sys/sockio.h>
26#include <sys/proc.h>
27#include <sys/mbuf.h>
28#include <sys/kernel.h>
29#include <sys/socket.h>
30#include <sys/systm.h>
31#include <sys/callout.h>
32#include <sys/conf.h>
33#include <sys/device.h>
34#include <sys/module.h>
35#include <sys/bus.h>
36
37#include <machine/endian.h>
38#include <net/bpf.h>
39#include <net/if.h>
40#include <net/if_arp.h>
41#include <net/if_dl.h>
42#include <net/if_ether.h>
43#include <net/if_media.h>
44#include <net/if_types.h>
45
46#include <netinet/in.h>
47#include <netinet/in_systm.h>
48#include <netinet/in_var.h>
49#include <netinet/if_inarp.h>
50#include <netinet/ip.h>
51
52#include <net80211/ieee80211_var.h>
53#include <net80211/ieee80211_radiotap.h>
54
55#include <dev/usb/usb.h>
56#include <dev/usb/usbdi.h>
57#include <dev/usb/usbdi_util.h>
58#include <dev/usb/usbdivar.h>
59#include <dev/usb/usbdevs.h>
60
61#include "if_urtwreg.h"
62
63#ifdef URTW_DEBUG
64#define DPRINTF(x) do { if (urtw_debug) printf x; } while (0)
65#define DPRINTFN(n, x) do { if (urtw_debug >= (n)) printf x; } while (0)
66int urtw_debug = 0;
67#else
68#define DPRINTF(x)
69#define DPRINTFN(n, x)
70#endif
71
72/*
73 * Recognized device vendors/products.
74 */
75static const struct urtw_type {
76 struct usb_devno dev;
77 uint8_t rev;
78} urtw_devs[] = {
79#define URTW_DEV_RTL8187(v, p) \
80 { { USB_VENDOR_##v, USB_PRODUCT_##v##_##p }, URTW_HWREV_8187 }
81#define URTW_DEV_RTL8187B(v, p) \
82 { { USB_VENDOR_##v, USB_PRODUCT_##v##_##p }, URTW_HWREV_8187B }
83 /* Realtek RTL8187 devices. */
84 URTW_DEV_RTL8187(ASUSTEK, P5B_WIFI),
85 URTW_DEV_RTL8187(DICKSMITH, RTL8187),
86 URTW_DEV_RTL8187(LINKSYS4, WUSB54GC_2),
87 URTW_DEV_RTL8187(LOGITEC, RTL8187),
88 URTW_DEV_RTL8187(NETGEAR, WG111V2),
89 URTW_DEV_RTL8187(REALTEK, RTL8187),
90 URTW_DEV_RTL8187(SITECOMEU, WL168V1),
91 URTW_DEV_RTL8187(SPHAIRON, RTL8187),
92 URTW_DEV_RTL8187(SURECOM, EP9001G2A),
93 /* Realtek RTL8187B devices. */
94 URTW_DEV_RTL8187B(BELKIN, F5D7050E),
95 URTW_DEV_RTL8187B(NETGEAR, WG111V3),
96 URTW_DEV_RTL8187B(REALTEK, RTL8187B_0),
97 URTW_DEV_RTL8187B(REALTEK, RTL8187B_1),
98 URTW_DEV_RTL8187B(REALTEK, RTL8187B_2),
99 URTW_DEV_RTL8187B(SITECOMEU, WL168V4)
100#undef URTW_DEV_RTL8187
101#undef URTW_DEV_RTL8187B
102};
103#define urtw_lookup(v, p) \
104 ((const struct urtw_type *)usb_lookup(urtw_devs, v, p))
105
106/*
107 * Helper read/write macros.
108 */
109#define urtw_read8_m(sc, val, data) do { \
110 error = urtw_read8_c(sc, val, data, 0); \
111 if (error != 0) \
112 goto fail; \
113} while (0)
114#define urtw_read8_idx_m(sc, val, data, idx) do { \
115 error = urtw_read8_c(sc, val, data, idx); \
116 if (error != 0) \
117 goto fail; \
118} while (0)
119#define urtw_write8_m(sc, val, data) do { \
120 error = urtw_write8_c(sc, val, data, 0); \
121 if (error != 0) \
122 goto fail; \
123} while (0)
124#define urtw_write8_idx_m(sc, val, data, idx) do { \
125 error = urtw_write8_c(sc, val, data, idx); \
126 if (error != 0) \
127 goto fail; \
128} while (0)
129#define urtw_read16_m(sc, val, data) do { \
130 error = urtw_read16_c(sc, val, data, 0); \
131 if (error != 0) \
132 goto fail; \
133} while (0)
134#define urtw_read16_idx_m(sc, val, data, idx) do { \
135 error = urtw_read16_c(sc, val, data, idx); \
136 if (error != 0) \
137 goto fail; \
138} while (0)
139#define urtw_write16_m(sc, val, data) do { \
140 error = urtw_write16_c(sc, val, data, 0); \
141 if (error != 0) \
142 goto fail; \
143} while (0)
144#define urtw_write16_idx_m(sc, val, data, idx) do { \
145 error = urtw_write16_c(sc, val, data, idx); \
146 if (error != 0) \
147 goto fail; \
148} while (0)
149#define urtw_read32_m(sc, val, data) do { \
150 error = urtw_read32_c(sc, val, data, 0); \
151 if (error != 0) \
152 goto fail; \
153} while (0)
154#define urtw_read32_idx_m(sc, val, data, idx) do { \
155 error = urtw_read32_c(sc, val, data, idx); \
156 if (error != 0) \
157 goto fail; \
158} while (0)
159#define urtw_write32_m(sc, val, data) do { \
160 error = urtw_write32_c(sc, val, data, 0); \
161 if (error != 0) \
162 goto fail; \
163} while (0)
164#define urtw_write32_idx_m(sc, val, data, idx) do { \
165 error = urtw_write32_c(sc, val, data, idx); \
166 if (error != 0) \
167 goto fail; \
168} while (0)
169#define urtw_8187_write_phy_ofdm(sc, val, data) do { \
170 error = urtw_8187_write_phy_ofdm_c(sc, val, data); \
171 if (error != 0) \
172 goto fail; \
173} while (0)
174#define urtw_8187_write_phy_cck(sc, val, data) do { \
175 error = urtw_8187_write_phy_cck_c(sc, val, data); \
176 if (error != 0) \
177 goto fail; \
178} while (0)
179#define urtw_8225_write(sc, val, data) do { \
180 error = urtw_8225_write_c(sc, val, data); \
181 if (error != 0) \
182 goto fail; \
183} while (0)
184
185struct urtw_pair {
186 uint32_t reg;
187 uint32_t val;
188};
189
190struct urtw_pair_idx {
191 uint8_t reg;
192 uint8_t val;
193 uint8_t idx;
194};
195
196static struct urtw_pair_idx urtw_8187b_regtbl[] = {
197 { 0xf0, 0x32, 0 }, { 0xf1, 0x32, 0 }, { 0xf2, 0x00, 0 },
198 { 0xf3, 0x00, 0 }, { 0xf4, 0x32, 0 }, { 0xf5, 0x43, 0 },
199 { 0xf6, 0x00, 0 }, { 0xf7, 0x00, 0 }, { 0xf8, 0x46, 0 },
200 { 0xf9, 0xa4, 0 }, { 0xfa, 0x00, 0 }, { 0xfb, 0x00, 0 },
201 { 0xfc, 0x96, 0 }, { 0xfd, 0xa4, 0 }, { 0xfe, 0x00, 0 },
202 { 0xff, 0x00, 0 },
203
204 { 0x58, 0x4b, 1 }, { 0x59, 0x00, 1 }, { 0x5a, 0x4b, 1 },
205 { 0x5b, 0x00, 1 }, { 0x60, 0x4b, 1 }, { 0x61, 0x09, 1 },
206 { 0x62, 0x4b, 1 }, { 0x63, 0x09, 1 }, { 0xce, 0x0f, 1 },
207 { 0xcf, 0x00, 1 }, { 0xe0, 0xff, 1 }, { 0xe1, 0x0f, 1 },
208 { 0xe2, 0x00, 1 }, { 0xf0, 0x4e, 1 }, { 0xf1, 0x01, 1 },
209 { 0xf2, 0x02, 1 }, { 0xf3, 0x03, 1 }, { 0xf4, 0x04, 1 },
210 { 0xf5, 0x05, 1 }, { 0xf6, 0x06, 1 }, { 0xf7, 0x07, 1 },
211 { 0xf8, 0x08, 1 },
212
213 { 0x4e, 0x00, 2 }, { 0x0c, 0x04, 2 }, { 0x21, 0x61, 2 },
214 { 0x22, 0x68, 2 }, { 0x23, 0x6f, 2 }, { 0x24, 0x76, 2 },
215 { 0x25, 0x7d, 2 }, { 0x26, 0x84, 2 }, { 0x27, 0x8d, 2 },
216 { 0x4d, 0x08, 2 }, { 0x50, 0x05, 2 }, { 0x51, 0xf5, 2 },
217 { 0x52, 0x04, 2 }, { 0x53, 0xa0, 2 }, { 0x54, 0x1f, 2 },
218 { 0x55, 0x23, 2 }, { 0x56, 0x45, 2 }, { 0x57, 0x67, 2 },
219 { 0x58, 0x08, 2 }, { 0x59, 0x08, 2 }, { 0x5a, 0x08, 2 },
220 { 0x5b, 0x08, 2 }, { 0x60, 0x08, 2 }, { 0x61, 0x08, 2 },
221 { 0x62, 0x08, 2 }, { 0x63, 0x08, 2 }, { 0x64, 0xcf, 2 },
222 { 0x72, 0x56, 2 }, { 0x73, 0x9a, 2 },
223
224 { 0x34, 0xf0, 0 }, { 0x35, 0x0f, 0 }, { 0x5b, 0x40, 0 },
225 { 0x84, 0x88, 0 }, { 0x85, 0x24, 0 }, { 0x88, 0x54, 0 },
226 { 0x8b, 0xb8, 0 }, { 0x8c, 0x07, 0 }, { 0x8d, 0x00, 0 },
227 { 0x94, 0x1b, 0 }, { 0x95, 0x12, 0 }, { 0x96, 0x00, 0 },
228 { 0x97, 0x06, 0 }, { 0x9d, 0x1a, 0 }, { 0x9f, 0x10, 0 },
229 { 0xb4, 0x22, 0 }, { 0xbe, 0x80, 0 }, { 0xdb, 0x00, 0 },
230 { 0xee, 0x00, 0 }, { 0x91, 0x03, 0 },
231
232 { 0x4c, 0x00, 2 }, { 0x9f, 0x00, 3 }, { 0x8c, 0x01, 0 },
233 { 0x8d, 0x10, 0 }, { 0x8e, 0x08, 0 }, { 0x8f, 0x00, 0 }
234};
235
236static uint8_t urtw_8225_agc[] = {
237 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9d, 0x9c, 0x9b,
238 0x9a, 0x99, 0x98, 0x97, 0x96, 0x95, 0x94, 0x93, 0x92, 0x91, 0x90,
239 0x8f, 0x8e, 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86, 0x85,
240 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a,
241 0x39, 0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f,
242 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24,
243 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19,
244 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e,
245 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03,
246 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
247 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
248 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
249};
250
251static uint32_t urtw_8225_channel[] = {
252 0x0000, /* dummy channel 0 */
253 0x085c, /* 1 */
254 0x08dc, /* 2 */
255 0x095c, /* 3 */
256 0x09dc, /* 4 */
257 0x0a5c, /* 5 */
258 0x0adc, /* 6 */
259 0x0b5c, /* 7 */
260 0x0bdc, /* 8 */
261 0x0c5c, /* 9 */
262 0x0cdc, /* 10 */
263 0x0d5c, /* 11 */
264 0x0ddc, /* 12 */
265 0x0e5c, /* 13 */
266 0x0f72, /* 14 */
267};
268
269static uint8_t urtw_8225_gain[] = {
270 0x23, 0x88, 0x7c, 0xa5, /* -82dbm */
271 0x23, 0x88, 0x7c, 0xb5, /* -82dbm */
272 0x23, 0x88, 0x7c, 0xc5, /* -82dbm */
273 0x33, 0x80, 0x79, 0xc5, /* -78dbm */
274 0x43, 0x78, 0x76, 0xc5, /* -74dbm */
275 0x53, 0x60, 0x73, 0xc5, /* -70dbm */
276 0x63, 0x58, 0x70, 0xc5, /* -66dbm */
277};
278
279static struct urtw_pair urtw_8225_rf_part1[] = {
280 { 0x00, 0x0067 }, { 0x01, 0x0fe0 }, { 0x02, 0x044d }, { 0x03, 0x0441 },
281 { 0x04, 0x0486 }, { 0x05, 0x0bc0 }, { 0x06, 0x0ae6 }, { 0x07, 0x082a },
282 { 0x08, 0x001f }, { 0x09, 0x0334 }, { 0x0a, 0x0fd4 }, { 0x0b, 0x0391 },
283 { 0x0c, 0x0050 }, { 0x0d, 0x06db }, { 0x0e, 0x0029 }, { 0x0f, 0x0914 }
284};
285
286static struct urtw_pair urtw_8225_rf_part2[] = {
287 { 0x00, 0x01 }, { 0x01, 0x02 }, { 0x02, 0x42 }, { 0x03, 0x00 },
288 { 0x04, 0x00 }, { 0x05, 0x00 }, { 0x06, 0x40 }, { 0x07, 0x00 },
289 { 0x08, 0x40 }, { 0x09, 0xfe }, { 0x0a, 0x09 }, { 0x0b, 0x80 },
290 { 0x0c, 0x01 }, { 0x0e, 0xd3 }, { 0x0f, 0x38 }, { 0x10, 0x84 },
291 { 0x11, 0x06 }, { 0x12, 0x20 }, { 0x13, 0x20 }, { 0x14, 0x00 },
292 { 0x15, 0x40 }, { 0x16, 0x00 }, { 0x17, 0x40 }, { 0x18, 0xef },
293 { 0x19, 0x19 }, { 0x1a, 0x20 }, { 0x1b, 0x76 }, { 0x1c, 0x04 },
294 { 0x1e, 0x95 }, { 0x1f, 0x75 }, { 0x20, 0x1f }, { 0x21, 0x27 },
295 { 0x22, 0x16 }, { 0x24, 0x46 }, { 0x25, 0x20 }, { 0x26, 0x90 },
296 { 0x27, 0x88 }
297};
298
299static struct urtw_pair urtw_8225_rf_part3[] = {
300 { 0x00, 0x98 }, { 0x03, 0x20 }, { 0x04, 0x7e }, { 0x05, 0x12 },
301 { 0x06, 0xfc }, { 0x07, 0x78 }, { 0x08, 0x2e }, { 0x10, 0x9b },
302 { 0x11, 0x88 }, { 0x12, 0x47 }, { 0x13, 0xd0 }, { 0x19, 0x00 },
303 { 0x1a, 0xa0 }, { 0x1b, 0x08 }, { 0x40, 0x86 }, { 0x41, 0x8d },
304 { 0x42, 0x15 }, { 0x43, 0x18 }, { 0x44, 0x1f }, { 0x45, 0x1e },
305 { 0x46, 0x1a }, { 0x47, 0x15 }, { 0x48, 0x10 }, { 0x49, 0x0a },
306 { 0x4a, 0x05 }, { 0x4b, 0x02 }, { 0x4c, 0x05 }
307};
308
309static uint16_t urtw_8225_rxgain[] = {
310 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
311 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
312 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
313 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
314 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
315 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
316 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
317 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
318 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
319 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
320 0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3,
321 0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb
322};
323
324static uint8_t urtw_8225_threshold[] = {
325 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd
326};
327
328static uint8_t urtw_8225_tx_gain_cck_ofdm[] = {
329 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e
330};
331
332static uint8_t urtw_8225_txpwr_cck[] = {
333 0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02,
334 0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02,
335 0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02,
336 0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02,
337 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03,
338 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03
339};
340
341static uint8_t urtw_8225_txpwr_cck_ch14[] = {
342 0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00,
343 0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00,
344 0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00,
345 0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00,
346 0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00,
347 0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00
348};
349
350static uint8_t urtw_8225_txpwr_ofdm[] = {
351 0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4
352};
353
354static uint8_t urtw_8225v2_agc[] = {
355 0x5e, 0x5e, 0x5e, 0x5e, 0x5d, 0x5b, 0x59, 0x57,
356 0x55, 0x53, 0x51, 0x4f, 0x4d, 0x4b, 0x49, 0x47,
357 0x45, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x39, 0x37,
358 0x35, 0x33, 0x31, 0x2f, 0x2d, 0x2b, 0x29, 0x27,
359 0x25, 0x23, 0x21, 0x1f, 0x1d, 0x1b, 0x19, 0x17,
360 0x15, 0x13, 0x11, 0x0f, 0x0d, 0x0b, 0x09, 0x07,
361 0x05, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
362 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
363 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
364 0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,
365 0x26, 0x27, 0x27, 0x28, 0x28, 0x29, 0x2a, 0x2a,
366 0x2a, 0x2b, 0x2b, 0x2b, 0x2c, 0x2c, 0x2c, 0x2d,
367 0x2d, 0x2d, 0x2d, 0x2e, 0x2e, 0x2e, 0x2e, 0x2f,
368 0x2f, 0x2f, 0x30, 0x30, 0x31, 0x31, 0x31, 0x31,
369 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
370 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31
371};
372
373static uint8_t urtw_8225v2_ofdm[] = {
374 0x10, 0x0d, 0x01, 0x00, 0x14, 0xfb, 0xfb, 0x60,
375 0x00, 0x60, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00,
376 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0xa8, 0x26,
377 0x32, 0x33, 0x07, 0xa5, 0x6f, 0x55, 0xc8, 0xb3,
378 0x0a, 0xe1, 0x2c, 0x8a, 0x86, 0x83, 0x34, 0x0f,
379 0x4f, 0x24, 0x6f, 0xc2, 0x6b, 0x40, 0x80, 0x00,
380 0xc0, 0xc1, 0x58, 0xf1, 0x00, 0xe4, 0x90, 0x3e,
381 0x6d, 0x3c, 0xfb, 0x07
382};
383
384static uint8_t urtw_8225v2_gain_bg[] = {
385 0x23, 0x15, 0xa5, /* -82-1dbm */
386 0x23, 0x15, 0xb5, /* -82-2dbm */
387 0x23, 0x15, 0xc5, /* -82-3dbm */
388 0x33, 0x15, 0xc5, /* -78dbm */
389 0x43, 0x15, 0xc5, /* -74dbm */
390 0x53, 0x15, 0xc5, /* -70dbm */
391 0x63, 0x15, 0xc5, /* -66dbm */
392};
393
394static struct urtw_pair urtw_8225v2_rf_part1[] = {
395 { 0x00, 0x02bf }, { 0x01, 0x0ee0 }, { 0x02, 0x044d }, { 0x03, 0x0441 },
396 { 0x04, 0x08c3 }, { 0x05, 0x0c72 }, { 0x06, 0x00e6 }, { 0x07, 0x082a },
397 { 0x08, 0x003f }, { 0x09, 0x0335 }, { 0x0a, 0x09d4 }, { 0x0b, 0x07bb },
398 { 0x0c, 0x0850 }, { 0x0d, 0x0cdf }, { 0x0e, 0x002b }, { 0x0f, 0x0114 }
399};
400
401static struct urtw_pair urtw_8225v2_rf_part2[] = {
402 { 0x00, 0x01 }, { 0x01, 0x02 }, { 0x02, 0x42 }, { 0x03, 0x00 },
403 { 0x04, 0x00 }, { 0x05, 0x00 }, { 0x06, 0x40 }, { 0x07, 0x00 },
404 { 0x08, 0x40 }, { 0x09, 0xfe }, { 0x0a, 0x08 }, { 0x0b, 0x80 },
405 { 0x0c, 0x01 }, { 0x0d, 0x43 }, { 0x0e, 0xd3 }, { 0x0f, 0x38 },
406 { 0x10, 0x84 }, { 0x11, 0x07 }, { 0x12, 0x20 }, { 0x13, 0x20 },
407 { 0x14, 0x00 }, { 0x15, 0x40 }, { 0x16, 0x00 }, { 0x17, 0x40 },
408 { 0x18, 0xef }, { 0x19, 0x19 }, { 0x1a, 0x20 }, { 0x1b, 0x15 },
409 { 0x1c, 0x04 }, { 0x1d, 0xc5 }, { 0x1e, 0x95 }, { 0x1f, 0x75 },
410 { 0x20, 0x1f }, { 0x21, 0x17 }, { 0x22, 0x16 }, { 0x23, 0x80 },
411 { 0x24, 0x46 }, { 0x25, 0x00 }, { 0x26, 0x90 }, { 0x27, 0x88 }
412};
413
414static struct urtw_pair urtw_8225v2_rf_part3[] = {
415 { 0x00, 0x98 }, { 0x03, 0x20 }, { 0x04, 0x7e }, { 0x05, 0x12 },
416 { 0x06, 0xfc }, { 0x07, 0x78 }, { 0x08, 0x2e }, { 0x09, 0x11 },
417 { 0x0a, 0x17 }, { 0x0b, 0x11 }, { 0x10, 0x9b }, { 0x11, 0x88 },
418 { 0x12, 0x47 }, { 0x13, 0xd0 }, { 0x19, 0x00 }, { 0x1a, 0xa0 },
419 { 0x1b, 0x08 }, { 0x1d, 0x00 }, { 0x40, 0x86 }, { 0x41, 0x9d },
420 { 0x42, 0x15 }, { 0x43, 0x18 }, { 0x44, 0x36 }, { 0x45, 0x35 },
421 { 0x46, 0x2e }, { 0x47, 0x25 }, { 0x48, 0x1c }, { 0x49, 0x12 },
422 { 0x4a, 0x09 }, { 0x4b, 0x04 }, { 0x4c, 0x05 }
423};
424
425static uint16_t urtw_8225v2_rxgain[] = {
426 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
427 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
428 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
429 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
430 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
431 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
432 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
433 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
434 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
435 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
436 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
437 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
438};
439
440static uint8_t urtw_8225v2_tx_gain_cck_ofdm[] = {
441 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
442 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
443 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
444 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
445 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
446 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23
447};
448
449static uint8_t urtw_8225v2_txpwr_cck[] = {
450 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04,
451 0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03,
452 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03,
453 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03
454};
455
456static uint8_t urtw_8225v2_txpwr_cck_ch14[] = {
457 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00,
458 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
459 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
460 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00
461};
462
463static struct urtw_pair urtw_8225v2_b_rf[] = {
464 { 0x00, 0x00b7 }, { 0x01, 0x0ee0 }, { 0x02, 0x044d }, { 0x03, 0x0441 },
465 { 0x04, 0x08c3 }, { 0x05, 0x0c72 }, { 0x06, 0x00e6 }, { 0x07, 0x082a },
466 { 0x08, 0x003f }, { 0x09, 0x0335 }, { 0x0a, 0x09d4 }, { 0x0b, 0x07bb },
467 { 0x0c, 0x0850 }, { 0x0d, 0x0cdf }, { 0x0e, 0x002b }, { 0x0f, 0x0114 },
468 { 0x00, 0x01b7 }
469};
470
471static struct urtw_pair urtw_ratetable[] = {
472 { 2, 0 }, { 4, 1 }, { 11, 2 }, { 12, 4 }, { 18, 5 },
473 { 22, 3 }, { 24, 6 }, { 36, 7 }, { 48, 8 }, { 72, 9 },
474 { 96, 10 }, { 108, 11 }
475};
476
477int urtw_init(struct ifnet *);
478void urtw_stop(struct ifnet *, int);
479int urtw_ioctl(struct ifnet *, u_long, void *);
480void urtw_start(struct ifnet *);
481int urtw_alloc_rx_data_list(struct urtw_softc *);
482void urtw_free_rx_data_list(struct urtw_softc *);
483int urtw_alloc_tx_data_list(struct urtw_softc *);
484void urtw_free_tx_data_list(struct urtw_softc *);
485void urtw_rxeof(struct usbd_xfer *, void *,
486 usbd_status);
487int urtw_tx_start(struct urtw_softc *,
488 struct ieee80211_node *, struct mbuf *, int);
489void urtw_txeof_low(struct usbd_xfer *, void *,
490 usbd_status);
491void urtw_txeof_normal(struct usbd_xfer *, void *,
492 usbd_status);
493void urtw_next_scan(void *);
494void urtw_task(void *);
495void urtw_ledusbtask(void *);
496void urtw_ledtask(void *);
497int urtw_media_change(struct ifnet *);
498int urtw_newstate(struct ieee80211com *, enum ieee80211_state, int);
499void urtw_watchdog(struct ifnet *);
500void urtw_set_chan(struct urtw_softc *, struct ieee80211_channel *);
501int urtw_isbmode(uint16_t);
502uint16_t urtw_rate2rtl(int);
503uint16_t urtw_rtl2rate(int);
504usbd_status urtw_set_rate(struct urtw_softc *);
505usbd_status urtw_update_msr(struct urtw_softc *);
506usbd_status urtw_read8_c(struct urtw_softc *, int, uint8_t *, uint8_t);
507usbd_status urtw_read16_c(struct urtw_softc *, int, uint16_t *, uint8_t);
508usbd_status urtw_read32_c(struct urtw_softc *, int, uint32_t *, uint8_t);
509usbd_status urtw_write8_c(struct urtw_softc *, int, uint8_t, uint8_t);
510usbd_status urtw_write16_c(struct urtw_softc *, int, uint16_t, uint8_t);
511usbd_status urtw_write32_c(struct urtw_softc *, int, uint32_t, uint8_t);
512usbd_status urtw_eprom_cs(struct urtw_softc *, int);
513usbd_status urtw_eprom_ck(struct urtw_softc *);
514usbd_status urtw_eprom_sendbits(struct urtw_softc *, int16_t *,
515 int);
516usbd_status urtw_eprom_read32(struct urtw_softc *, uint32_t,
517 uint32_t *);
518usbd_status urtw_eprom_readbit(struct urtw_softc *, int16_t *);
519usbd_status urtw_eprom_writebit(struct urtw_softc *, int16_t);
520usbd_status urtw_get_macaddr(struct urtw_softc *);
521usbd_status urtw_get_txpwr(struct urtw_softc *);
522usbd_status urtw_get_rfchip(struct urtw_softc *);
523usbd_status urtw_led_init(struct urtw_softc *);
524usbd_status urtw_8185_rf_pins_enable(struct urtw_softc *);
525usbd_status urtw_8185_tx_antenna(struct urtw_softc *, uint8_t);
526usbd_status urtw_8187_write_phy(struct urtw_softc *, uint8_t, uint32_t);
527usbd_status urtw_8187_write_phy_ofdm_c(struct urtw_softc *, uint8_t,
528 uint32_t);
529usbd_status urtw_8187_write_phy_cck_c(struct urtw_softc *, uint8_t,
530 uint32_t);
531usbd_status urtw_8225_setgain(struct urtw_softc *, int16_t);
532usbd_status urtw_8225_usb_init(struct urtw_softc *);
533usbd_status urtw_8225_write_c(struct urtw_softc *, uint8_t, uint16_t);
534usbd_status urtw_8225_write_s16(struct urtw_softc *, uint8_t, int,
535 uint16_t);
536usbd_status urtw_8225_read(struct urtw_softc *, uint8_t, uint32_t *);
537usbd_status urtw_8225_rf_init(struct urtw_rf *);
538usbd_status urtw_8225_rf_set_chan(struct urtw_rf *, int);
539usbd_status urtw_8225_rf_set_sens(struct urtw_rf *);
540usbd_status urtw_8225_set_txpwrlvl(struct urtw_softc *, int);
541usbd_status urtw_8225v2_rf_init(struct urtw_rf *);
542usbd_status urtw_8225v2_rf_set_chan(struct urtw_rf *, int);
543usbd_status urtw_8225v2_set_txpwrlvl(struct urtw_softc *, int);
544usbd_status urtw_8225v2_setgain(struct urtw_softc *, int16_t);
545usbd_status urtw_8225_isv2(struct urtw_softc *, int *);
546usbd_status urtw_read8e(struct urtw_softc *, int, uint8_t *);
547usbd_status urtw_write8e(struct urtw_softc *, int, uint8_t);
548usbd_status urtw_8180_set_anaparam(struct urtw_softc *, uint32_t);
549usbd_status urtw_8185_set_anaparam2(struct urtw_softc *, uint32_t);
550usbd_status urtw_open_pipes(struct urtw_softc *);
551usbd_status urtw_close_pipes(struct urtw_softc *);
552usbd_status urtw_intr_enable(struct urtw_softc *);
553usbd_status urtw_intr_disable(struct urtw_softc *);
554usbd_status urtw_reset(struct urtw_softc *);
555usbd_status urtw_led_on(struct urtw_softc *, int);
556usbd_status urtw_led_ctl(struct urtw_softc *, int);
557usbd_status urtw_led_blink(struct urtw_softc *);
558usbd_status urtw_led_mode0(struct urtw_softc *, int);
559usbd_status urtw_led_mode1(struct urtw_softc *, int);
560usbd_status urtw_led_mode2(struct urtw_softc *, int);
561usbd_status urtw_led_mode3(struct urtw_softc *, int);
562usbd_status urtw_rx_setconf(struct urtw_softc *);
563usbd_status urtw_rx_enable(struct urtw_softc *);
564usbd_status urtw_tx_enable(struct urtw_softc *);
565usbd_status urtw_8187b_update_wmm(struct urtw_softc *);
566usbd_status urtw_8187b_reset(struct urtw_softc *);
567int urtw_8187b_init(struct ifnet *);
568usbd_status urtw_8225v2_b_config_mac(struct urtw_softc *);
569usbd_status urtw_8225v2_b_init_rfe(struct urtw_softc *);
570usbd_status urtw_8225v2_b_update_chan(struct urtw_softc *);
571usbd_status urtw_8225v2_b_rf_init(struct urtw_rf *);
572usbd_status urtw_8225v2_b_rf_set_chan(struct urtw_rf *, int);
573usbd_status urtw_8225v2_b_set_txpwrlvl(struct urtw_softc *, int);
574int urtw_set_bssid(struct urtw_softc *, const uint8_t *);
575int urtw_set_macaddr(struct urtw_softc *, const uint8_t *);
576
577int urtw_match(device_t, cfdata_t, void *);
578void urtw_attach(device_t, device_t, void *);
579int urtw_detach(device_t, int);
580int urtw_activate(device_t, enum devact);
581
582CFATTACH_DECL_NEW(urtw, sizeof(struct urtw_softc),
583 urtw_match,
584 urtw_attach,
585 urtw_detach,
586 urtw_activate
587);
588
589int
590urtw_match(device_t parent, cfdata_t match, void *aux)
591{
592 struct usb_attach_arg *uaa = aux;
593
594 return urtw_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ?
595 UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
596}
597
598void
599urtw_attach(device_t parent, device_t self, void *aux)
600{
601 struct urtw_softc *sc = device_private(self);
602 struct usb_attach_arg *uaa = aux;
603 struct ieee80211com *ic = &sc->sc_ic;
604 struct ifnet *ifp = &sc->sc_if;
605 usbd_status error;
606 uint8_t data8;
607 uint32_t data;
608 int i;
609
610 sc->sc_dev = self;
611 sc->sc_udev = uaa->uaa_device;
612 sc->sc_hwrev = urtw_lookup(uaa->uaa_vendor, uaa->uaa_product)->rev;
613
614 aprint_naive("\n");
615 aprint_normal(": ");
616
617 if (sc->sc_hwrev & URTW_HWREV_8187) {
618 urtw_read32_m(sc, URTW_TX_CONF, &data);
619 data &= URTW_TX_HWREV_MASK;
620 switch (data) {
621 case URTW_TX_HWREV_8187_D:
622 sc->sc_hwrev |= URTW_HWREV_8187_D;
623 aprint_normal("RTL8187 rev D");
624 break;
625 case URTW_TX_HWREV_8187B_D:
626 /*
627 * Detect Realtek RTL8187B devices that use
628 * USB IDs of RTL8187.
629 */
630 sc->sc_hwrev = URTW_HWREV_8187B | URTW_HWREV_8187B_B;
631 aprint_normal("RTL8187B rev B (early)");
632 break;
633 default:
634 sc->sc_hwrev |= URTW_HWREV_8187_B;
635 aprint_normal("RTL8187 rev 0x%02x", data >> 25);
636 break;
637 }
638 } else {
639 /* RTL8187B hwrev register. */
640 urtw_read8_m(sc, URTW_8187B_HWREV, &data8);
641 switch (data8) {
642 case URTW_8187B_HWREV_8187B_B:
643 sc->sc_hwrev |= URTW_HWREV_8187B_B;
644 aprint_normal("RTL8187B rev B");
645 break;
646 case URTW_8187B_HWREV_8187B_D:
647 sc->sc_hwrev |= URTW_HWREV_8187B_D;
648 aprint_normal("RTL8187B rev D");
649 break;
650 case URTW_8187B_HWREV_8187B_E:
651 sc->sc_hwrev |= URTW_HWREV_8187B_E;
652 aprint_normal("RTL8187B rev E");
653 break;
654 default:
655 sc->sc_hwrev |= URTW_HWREV_8187B_B;
656 aprint_normal("RTL8187B rev 0x%02x", data8);
657 break;
658 }
659 }
660
661 urtw_read32_m(sc, URTW_RX, &data);
662 sc->sc_epromtype = (data & URTW_RX_9356SEL) ? URTW_EEPROM_93C56 :
663 URTW_EEPROM_93C46;
664
665 error = urtw_get_rfchip(sc);
666 if (error != 0)
667 goto fail;
668 error = urtw_get_macaddr(sc);
669 if (error != 0)
670 goto fail;
671 error = urtw_get_txpwr(sc);
672 if (error != 0)
673 goto fail;
674 error = urtw_led_init(sc); /* XXX incompleted */
675 if (error != 0)
676 goto fail;
677
678 sc->sc_rts_retry = URTW_DEFAULT_RTS_RETRY;
679 sc->sc_tx_retry = URTW_DEFAULT_TX_RETRY;
680 sc->sc_currate = 3;
681 /* XXX for what? */
682 sc->sc_preamble_mode = 2;
683
684 usb_init_task(&sc->sc_task, urtw_task, sc, 0);
685 usb_init_task(&sc->sc_ledtask, urtw_ledusbtask, sc, 0);
686 callout_init(&sc->scan_to, 0);
687 callout_setfunc(&sc->scan_to, urtw_next_scan, sc);
688 callout_init(&sc->sc_led_ch, 0);
689 callout_setfunc(&sc->sc_led_ch, urtw_ledtask, sc);
690
691 ic->ic_ifp = ifp;
692 ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
693 ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
694 ic->ic_state = IEEE80211_S_INIT;
695
696 /* set device capabilities */
697 ic->ic_caps =
698 IEEE80211_C_MONITOR | /* monitor mode supported */
699 IEEE80211_C_TXPMGT | /* tx power management */
700 IEEE80211_C_SHPREAMBLE | /* short preamble supported */
701 IEEE80211_C_SHSLOT | /* short slot time supported */
702 IEEE80211_C_WEP | /* s/w WEP */
703 IEEE80211_C_WPA; /* WPA/RSN */
704
705 /* set supported .11b and .11g rates */
706 ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
707 ic->ic_sup_rates[IEEE80211_MODE_11G] = ieee80211_std_rateset_11g;
708
709 /* set supported .11b and .11g channels (1 through 14) */
710 for (i = 1; i <= 14; i++) {
711 ic->ic_channels[i].ic_freq =
712 ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
713 ic->ic_channels[i].ic_flags =
714 IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM |
715 IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ;
716 }
717
718 ifp->if_softc = sc;
719 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
720 if (sc->sc_hwrev & URTW_HWREV_8187) {
721 ifp->if_init = urtw_init;
722 } else {
723 ifp->if_init = urtw_8187b_init;
724 }
725 ifp->if_ioctl = urtw_ioctl;
726 ifp->if_start = urtw_start;
727 ifp->if_watchdog = urtw_watchdog;
728 IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
729 IFQ_SET_READY(&ifp->if_snd);
730 memcpy(ifp->if_xname, device_xname(self), IFNAMSIZ);
731
732 if_attach(ifp);
733 ieee80211_ifattach(ic);
734
735 /* override state transition machine */
736 sc->sc_newstate = ic->ic_newstate;
737 ic->ic_newstate = urtw_newstate;
738 ieee80211_media_init(ic, urtw_media_change, ieee80211_media_status);
739
740 bpf_attach2(ifp, DLT_IEEE802_11_RADIO,
741 sizeof(struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN,
742 &sc->sc_drvbpf);
743
744 sc->sc_rxtap_len = sizeof(sc->sc_rxtapu);
745 sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
746 sc->sc_rxtap.wr_ihdr.it_present = htole32(URTW_RX_RADIOTAP_PRESENT);
747
748 sc->sc_txtap_len = sizeof(sc->sc_txtapu);
749 sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
750 sc->sc_txtap.wt_ihdr.it_present = htole32(URTW_TX_RADIOTAP_PRESENT);
751
752 aprint_normal(", address %s\n", ether_sprintf(ic->ic_myaddr));
753
754 ieee80211_announce(ic);
755
756 return;
757fail:
758 aprint_error(": %s failed!\n", __func__);
759 sc->sc_dying = true;
760}
761
762int
763urtw_detach(device_t self, int flags)
764{
765 struct urtw_softc *sc = device_private(self);
766 struct ifnet *ifp = &sc->sc_if;
767 int s;
768
769 s = splusb();
770
771 sc->sc_dying = true;
772
773 callout_destroy(&sc->scan_to);
774 callout_destroy(&sc->sc_led_ch);
775
776 usb_rem_task(sc->sc_udev, &sc->sc_task);
777 usb_rem_task(sc->sc_udev, &sc->sc_ledtask);
778
779 if (ifp->if_softc != NULL) {
780 bpf_detach(ifp);
781 ieee80211_ifdetach(&sc->sc_ic); /* free all nodes */
782 if_detach(ifp);
783 }
784
785 /* abort and free xfers */
786 urtw_free_tx_data_list(sc);
787 urtw_free_rx_data_list(sc);
788 urtw_close_pipes(sc);
789
790 splx(s);
791
792 return 0;
793}
794
795int
796urtw_activate(device_t self, enum devact act)
797{
798 struct urtw_softc *sc = device_private(self);
799
800 switch (act) {
801 case DVACT_DEACTIVATE:
802 sc->sc_dying = true;
803 break;
804 }
805
806 return 0;
807}
808
809usbd_status
810urtw_close_pipes(struct urtw_softc *sc)
811{
812 usbd_status error = 0;
813
814 if (sc->sc_rxpipe != NULL) {
815 error = usbd_close_pipe(sc->sc_rxpipe);
816 if (error != 0)
817 goto fail;
818 sc->sc_rxpipe = NULL;
819 }
820 if (sc->sc_txpipe_low != NULL) {
821 error = usbd_close_pipe(sc->sc_txpipe_low);
822 if (error != 0)
823 goto fail;
824 sc->sc_txpipe_low = NULL;
825 }
826 if (sc->sc_txpipe_normal != NULL) {
827 error = usbd_close_pipe(sc->sc_txpipe_normal);
828 if (error != 0)
829 goto fail;
830 sc->sc_txpipe_normal = NULL;
831 }
832fail:
833 return error;
834}
835
836usbd_status
837urtw_open_pipes(struct urtw_softc *sc)
838{
839 usbd_status error;
840
841 /*
842 * NB: there is no way to distinguish each pipes so we need to hardcode
843 * pipe numbers
844 */
845
846 /* tx pipe - low priority packets */
847 if (sc->sc_hwrev & URTW_HWREV_8187)
848 error = usbd_open_pipe(sc->sc_iface, 0x2,
849 USBD_EXCLUSIVE_USE, &sc->sc_txpipe_low);
850 else
851 error = usbd_open_pipe(sc->sc_iface, 0x6,
852 USBD_EXCLUSIVE_USE, &sc->sc_txpipe_low);
853 if (error != 0) {
854 printf("%s: could not open Tx low pipe: %s\n",
855 device_xname(sc->sc_dev), usbd_errstr(error));
856 goto fail;
857 }
858 /* tx pipe - normal priority packets */
859 if (sc->sc_hwrev & URTW_HWREV_8187)
860 error = usbd_open_pipe(sc->sc_iface, 0x3,
861 USBD_EXCLUSIVE_USE, &sc->sc_txpipe_normal);
862 else
863 error = usbd_open_pipe(sc->sc_iface, 0x7,
864 USBD_EXCLUSIVE_USE, &sc->sc_txpipe_normal);
865 if (error != 0) {
866 printf("%s: could not open Tx normal pipe: %s\n",
867 device_xname(sc->sc_dev), usbd_errstr(error));
868 goto fail;
869 }
870 /* rx pipe */
871 if (sc->sc_hwrev & URTW_HWREV_8187)
872 error = usbd_open_pipe(sc->sc_iface, 0x81,
873 USBD_EXCLUSIVE_USE, &sc->sc_rxpipe);
874 else
875 error = usbd_open_pipe(sc->sc_iface, 0x83,
876 USBD_EXCLUSIVE_USE, &sc->sc_rxpipe);
877 if (error != 0) {
878 printf("%s: could not open Rx pipe: %s\n",
879 device_xname(sc->sc_dev), usbd_errstr(error));
880 goto fail;
881 }
882
883 return 0;
884fail:
885 (void)urtw_close_pipes(sc);
886 return error;
887}
888
889int
890urtw_alloc_rx_data_list(struct urtw_softc *sc)
891{
892 int i, error;
893
894 for (i = 0; i < URTW_RX_DATA_LIST_COUNT; i++) {
895 struct urtw_rx_data *data = &sc->sc_rx_data[i];
896
897 data->sc = sc;
898
899 error = usbd_create_xfer(sc->sc_rxpipe, MCLBYTES,
900 USBD_SHORT_XFER_OK, 0, &data->xfer);
901 if (error) {
902
903 printf("%s: could not allocate rx xfer\n",
904 device_xname(sc->sc_dev));
905 error = ENOMEM;
906 goto fail;
907 }
908
909 MGETHDR(data->m, M_DONTWAIT, MT_DATA);
910 if (data->m == NULL) {
911 printf("%s: could not allocate rx mbuf\n",
912 device_xname(sc->sc_dev));
913 error = ENOMEM;
914 goto fail;
915 }
916 MCLGET(data->m, M_DONTWAIT);
917 if (!(data->m->m_flags & M_EXT)) {
918 printf("%s: could not allocate rx mbuf cluster\n",
919 device_xname(sc->sc_dev));
920 error = ENOMEM;
921 goto fail;
922 }
923 data->buf = mtod(data->m, uint8_t *);
924 }
925
926 return 0;
927
928fail:
929 urtw_free_rx_data_list(sc);
930 return error;
931}
932
933void
934urtw_free_rx_data_list(struct urtw_softc *sc)
935{
936 int i;
937
938 /* Make sure no transfers are pending. */
939 if (sc->sc_rxpipe != NULL)
940 usbd_abort_pipe(sc->sc_rxpipe);
941
942 for (i = 0; i < URTW_RX_DATA_LIST_COUNT; i++) {
943 struct urtw_rx_data *data = &sc->sc_rx_data[i];
944
945 if (data->xfer != NULL) {
946 usbd_destroy_xfer(data->xfer);
947 data->xfer = NULL;
948 }
949 if (data->m != NULL) {
950 m_freem(data->m);
951 data->m = NULL;
952 }
953 }
954}
955
956int
957urtw_alloc_tx_data_list(struct urtw_softc *sc)
958{
959 int i, error;
960
961 for (size_t j = 0; j < URTW_PRIORITY_MAX; j++) {
962 for (i = 0; i < URTW_TX_DATA_LIST_COUNT; i++) {
963 struct urtw_tx_data *data = &sc->sc_tx_data[j][i];
964
965 data->sc = sc;
966 data->ni = NULL;
967
968 error = usbd_create_xfer((j == URTW_PRIORITY_LOW) ?
969 sc->sc_txpipe_low : sc->sc_txpipe_normal,
970 URTW_TX_MAXSIZE, USBD_FORCE_SHORT_XFER, 0,
971 &data->xfer);
972 if (error) {
973 printf("%s: could not allocate tx xfer\n",
974 device_xname(sc->sc_dev));
975 goto fail;
976 }
977
978 data->buf = usbd_get_buffer(data->xfer);
979
980 if (((unsigned long)data->buf) % 4)
981 printf("%s: warn: unaligned buffer %p\n",
982 device_xname(sc->sc_dev), data->buf);
983 }
984 }
985
986 return 0;
987
988fail:
989 urtw_free_tx_data_list(sc);
990 return error;
991}
992
993void
994urtw_free_tx_data_list(struct urtw_softc *sc)
995{
996 int i;
997
998 /* Make sure no transfers are pending. */
999 if (sc->sc_txpipe_low != NULL)
1000 usbd_abort_pipe(sc->sc_txpipe_low);
1001 if (sc->sc_txpipe_normal != NULL)
1002 usbd_abort_pipe(sc->sc_txpipe_normal);
1003
1004 for (size_t j = 0; j < URTW_PRIORITY_MAX; j++) {
1005 for (i = 0; i < URTW_TX_DATA_LIST_COUNT; i++) {
1006 struct urtw_tx_data *data = &sc->sc_tx_data[j][i];
1007
1008 if (data->xfer != NULL) {
1009 usbd_destroy_xfer(data->xfer);
1010 data->xfer = NULL;
1011 }
1012 if (data->ni != NULL) {
1013 ieee80211_free_node(data->ni);
1014 data->ni = NULL;
1015 }
1016 }
1017 }
1018}
1019
1020int
1021urtw_media_change(struct ifnet *ifp)
1022{
1023 int error;
1024
1025 error = ieee80211_media_change(ifp);
1026 if (error != ENETRESET)
1027 return error;
1028
1029 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
1030 (IFF_UP | IFF_RUNNING))
1031 ifp->if_init(ifp);
1032
1033 return 0;
1034}
1035
1036int
1037urtw_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
1038{
1039 struct urtw_softc *sc = ic->ic_ifp->if_softc;
1040
1041 usb_rem_task(sc->sc_udev, &sc->sc_task);
1042 callout_stop(&sc->scan_to);
1043
1044 /* do it in a process context */
1045 sc->sc_state = nstate;
1046 sc->sc_arg = arg;
1047 usb_add_task(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER);
1048
1049 return 0;
1050}
1051
1052usbd_status
1053urtw_led_init(struct urtw_softc *sc)
1054{
1055 uint32_t rev;
1056 usbd_status error;
1057
1058 urtw_read8_m(sc, URTW_PSR, &sc->sc_psr);
1059 error = urtw_eprom_read32(sc, URTW_EPROM_SWREV, &rev);
1060 if (error != 0)
1061 goto fail;
1062
1063 switch (rev & URTW_EPROM_CID_MASK) {
1064 case URTW_EPROM_CID_ALPHA0:
1065 sc->sc_strategy = URTW_SW_LED_MODE1;
1066 break;
1067 case URTW_EPROM_CID_SERCOMM_PS:
1068 sc->sc_strategy = URTW_SW_LED_MODE3;
1069 break;
1070 case URTW_EPROM_CID_HW_LED:
1071 sc->sc_strategy = URTW_HW_LED;
1072 break;
1073 case URTW_EPROM_CID_RSVD0:
1074 case URTW_EPROM_CID_RSVD1:
1075 default:
1076 sc->sc_strategy = URTW_SW_LED_MODE0;
1077 break;
1078 }
1079
1080 sc->sc_gpio_ledpin = URTW_LED_PIN_GPIO0;
1081
1082fail:
1083 return error;
1084}
1085
1086usbd_status
1087urtw_8225_write_s16(struct urtw_softc *sc, uint8_t addr, int index,
1088 uint16_t data)
1089{
1090 usb_device_request_t req;
1091
1092 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
1093 req.bRequest = URTW_8187_SETREGS_REQ;
1094 USETW(req.wValue, addr);
1095 USETW(req.wIndex, index);
1096 USETW(req.wLength, sizeof(uint16_t));
1097
1098 return usbd_do_request(sc->sc_udev, &req, &data);
1099}
1100
1101usbd_status
1102urtw_8225_read(struct urtw_softc *sc, uint8_t addr, uint32_t *data)
1103{
1104 int i;
1105 int16_t bit;
1106 uint8_t rlen = 12, wlen = 6;
1107 uint16_t o1, o2, o3, tmp;
1108 uint32_t d2w = ((uint32_t)(addr & 0x1f)) << 27;
1109 uint32_t mask = 0x80000000, value = 0;
1110 usbd_status error;
1111
1112 urtw_read16_m(sc, URTW_RF_PINS_OUTPUT, &o1);
1113 urtw_read16_m(sc, URTW_RF_PINS_ENABLE, &o2);
1114 urtw_read16_m(sc, URTW_RF_PINS_SELECT, &o3);
1115 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, o2 | 0xf);
1116 urtw_write16_m(sc, URTW_RF_PINS_SELECT, o3 | 0xf);
1117 o1 &= ~0xf;
1118 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1 | URTW_BB_HOST_BANG_EN);
1119 DELAY(5);
1120 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1);
1121 DELAY(5);
1122
1123 for (i = 0; i < (wlen / 2); i++, mask = mask >> 1) {
1124 bit = ((d2w & mask) != 0) ? 1 : 0;
1125
1126 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1);
1127 DELAY(2);
1128 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
1129 URTW_BB_HOST_BANG_CLK);
1130 DELAY(2);
1131 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
1132 URTW_BB_HOST_BANG_CLK);
1133 DELAY(2);
1134 mask = mask >> 1;
1135 if (i == 2)
1136 break;
1137 bit = ((d2w & mask) != 0) ? 1 : 0;
1138 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
1139 URTW_BB_HOST_BANG_CLK);
1140 DELAY(2);
1141 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
1142 URTW_BB_HOST_BANG_CLK);
1143 DELAY(2);
1144 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1);
1145 DELAY(1);
1146 }
1147 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 | URTW_BB_HOST_BANG_RW |
1148 URTW_BB_HOST_BANG_CLK);
1149 DELAY(2);
1150 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 | URTW_BB_HOST_BANG_RW);
1151 DELAY(2);
1152 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1 | URTW_BB_HOST_BANG_RW);
1153 DELAY(2);
1154
1155 mask = 0x800;
1156 for (i = 0; i < rlen; i++, mask = mask >> 1) {
1157 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
1158 o1 | URTW_BB_HOST_BANG_RW);
1159 DELAY(2);
1160 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
1161 o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK);
1162 DELAY(2);
1163 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
1164 o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK);
1165 DELAY(2);
1166 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
1167 o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK);
1168 DELAY(2);
1169
1170 urtw_read16_m(sc, URTW_RF_PINS_INPUT, &tmp);
1171 value |= ((tmp & URTW_BB_HOST_BANG_CLK) ? mask : 0);
1172 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
1173 o1 | URTW_BB_HOST_BANG_RW);
1174 DELAY(2);
1175 }
1176
1177 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1 | URTW_BB_HOST_BANG_EN |
1178 URTW_BB_HOST_BANG_RW);
1179 DELAY(2);
1180
1181 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, o2);
1182 urtw_write16_m(sc, URTW_RF_PINS_SELECT, o3);
1183 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, 0x3a0);
1184
1185 if (data != NULL)
1186 *data = value;
1187fail:
1188 return error;
1189}
1190
1191usbd_status
1192urtw_8225_write_c(struct urtw_softc *sc, uint8_t addr, uint16_t data)
1193{
1194 uint16_t d80, d82, d84;
1195 usbd_status error;
1196
1197 urtw_read16_m(sc, URTW_RF_PINS_OUTPUT, &d80);
1198 d80 &= 0xfff3;
1199 urtw_read16_m(sc, URTW_RF_PINS_ENABLE, &d82);
1200 urtw_read16_m(sc, URTW_RF_PINS_SELECT, &d84);
1201 d84 &= 0xfff0;
1202 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, d82 | 0x0007);
1203 urtw_write16_m(sc, URTW_RF_PINS_SELECT, d84 | 0x0007);
1204 DELAY(10);
1205
1206 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80 | URTW_BB_HOST_BANG_EN);
1207 DELAY(2);
1208 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80);
1209 DELAY(10);
1210
1211 error = urtw_8225_write_s16(sc, addr, 0x8225, data);
1212 if (error != 0)
1213 goto fail;
1214
1215 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80 | URTW_BB_HOST_BANG_EN);
1216 DELAY(10);
1217 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80 | URTW_BB_HOST_BANG_EN);
1218 urtw_write16_m(sc, URTW_RF_PINS_SELECT, d84);
1219 usbd_delay_ms(sc->sc_udev, 2);
1220fail:
1221 return error;
1222}
1223
1224usbd_status
1225urtw_8225_isv2(struct urtw_softc *sc, int *ret)
1226{
1227 uint32_t data;
1228 usbd_status error;
1229
1230 *ret = 1;
1231
1232 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, 0x0080);
1233 urtw_write16_m(sc, URTW_RF_PINS_SELECT, 0x0080);
1234 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x0080);
1235 usbd_delay_ms(sc->sc_udev, 500);
1236
1237 urtw_8225_write(sc, 0x0, 0x1b7);
1238
1239 error = urtw_8225_read(sc, 0x8, &data);
1240 if (error != 0)
1241 goto fail;
1242 if (data != 0x588)
1243 *ret = 0;
1244 else {
1245 error = urtw_8225_read(sc, 0x9, &data);
1246 if (error != 0)
1247 goto fail;
1248 if (data != 0x700)
1249 *ret = 0;
1250 }
1251
1252 urtw_8225_write(sc, 0x0, 0xb7);
1253fail:
1254 return error;
1255}
1256
1257usbd_status
1258urtw_get_rfchip(struct urtw_softc *sc)
1259{
1260 struct urtw_rf *rf = &sc->sc_rf;
1261 int ret;
1262 uint32_t data;
1263 usbd_status error;
1264
1265 rf->rf_sc = sc;
1266
1267 if (sc->sc_hwrev & URTW_HWREV_8187) {
1268 error = urtw_eprom_read32(sc, URTW_EPROM_RFCHIPID, &data);
1269 if (error != 0)
1270 panic("unsupported RF chip");
1271 /* NOTREACHED */
1272 switch (data & 0xff) {
1273 case URTW_EPROM_RFCHIPID_RTL8225U:
1274 error = urtw_8225_isv2(sc, &ret);
1275 if (error != 0)
1276 goto fail;
1277 if (ret == 0) {
1278 rf->init = urtw_8225_rf_init;
1279 rf->set_chan = urtw_8225_rf_set_chan;
1280 rf->set_sens = urtw_8225_rf_set_sens;
1281 printf(", RFv1");
1282 } else {
1283 rf->init = urtw_8225v2_rf_init;
1284 rf->set_chan = urtw_8225v2_rf_set_chan;
1285 rf->set_sens = NULL;
1286 printf(", RFv2");
1287 }
1288 break;
1289 default:
1290 goto fail;
1291 }
1292 } else {
1293 rf->init = urtw_8225v2_b_rf_init;
1294 rf->set_chan = urtw_8225v2_b_rf_set_chan;
1295 rf->set_sens = NULL;
1296 }
1297
1298 rf->max_sens = URTW_8225_RF_MAX_SENS;
1299 rf->sens = URTW_8225_RF_DEF_SENS;
1300
1301 return 0;
1302
1303fail:
1304 panic("unsupported RF chip %d", data & 0xff);
1305 /* NOTREACHED */
1306}
1307
1308usbd_status
1309urtw_get_txpwr(struct urtw_softc *sc)
1310{
1311 int i, j;
1312 uint32_t data;
1313 usbd_status error;
1314
1315 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW_BASE, &data);
1316 if (error != 0)
1317 goto fail;
1318 sc->sc_txpwr_cck_base = data & 0xf;
1319 sc->sc_txpwr_ofdm_base = (data >> 4) & 0xf;
1320
1321 for (i = 1, j = 0; i < 6; i += 2, j++) {
1322 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW0 + j, &data);
1323 if (error != 0)
1324 goto fail;
1325 sc->sc_txpwr_cck[i] = data & 0xf;
1326 sc->sc_txpwr_cck[i + 1] = (data & 0xf00) >> 8;
1327 sc->sc_txpwr_ofdm[i] = (data & 0xf0) >> 4;
1328 sc->sc_txpwr_ofdm[i + 1] = (data & 0xf000) >> 12;
1329 }
1330 for (i = 1, j = 0; i < 4; i += 2, j++) {
1331 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW1 + j, &data);
1332 if (error != 0)
1333 goto fail;
1334 sc->sc_txpwr_cck[i + 6] = data & 0xf;
1335 sc->sc_txpwr_cck[i + 6 + 1] = (data & 0xf00) >> 8;
1336 sc->sc_txpwr_ofdm[i + 6] = (data & 0xf0) >> 4;
1337 sc->sc_txpwr_ofdm[i + 6 + 1] = (data & 0xf000) >> 12;
1338 }
1339 if (sc->sc_hwrev & URTW_HWREV_8187) {
1340 for (i = 1, j = 0; i < 4; i += 2, j++) {
1341 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW2 + j,
1342 &data);
1343 if (error != 0)
1344 goto fail;
1345 sc->sc_txpwr_cck[i + 6 + 4] = data & 0xf;
1346 sc->sc_txpwr_cck[i + 6 + 4 + 1] = (data & 0xf00) >> 8;
1347 sc->sc_txpwr_ofdm[i + 6 + 4] = (data & 0xf0) >> 4;
1348 sc->sc_txpwr_ofdm[i + 6 + 4 + 1] =
1349 (data & 0xf000) >> 12;
1350 }
1351 } else {
1352 /* Channel 11. */
1353 error = urtw_eprom_read32(sc, 0x1b, &data);
1354 if (error != 0)
1355 goto fail;
1356 sc->sc_txpwr_cck[11] = data & 0xf;
1357 sc->sc_txpwr_ofdm[11] = (data & 0xf0) >> 4;
1358
1359 /* Channel 12. */
1360 error = urtw_eprom_read32(sc, 0xa, &data);
1361 if (error != 0)
1362 goto fail;
1363 sc->sc_txpwr_cck[12] = data & 0xf;
1364 sc->sc_txpwr_ofdm[12] = (data & 0xf0) >> 4;
1365
1366 /* Channel 13, 14. */
1367 error = urtw_eprom_read32(sc, 0x1c, &data);
1368 if (error != 0)
1369 goto fail;
1370 sc->sc_txpwr_cck[13] = data & 0xf;
1371 sc->sc_txpwr_ofdm[13] = (data & 0xf0) >> 4;
1372 sc->sc_txpwr_cck[14] = (data & 0xf00) >> 8;
1373 sc->sc_txpwr_ofdm[14] = (data & 0xf000) >> 12;
1374 }
1375fail:
1376 return error;
1377}
1378
1379usbd_status
1380urtw_get_macaddr(struct urtw_softc *sc)
1381{
1382 struct ieee80211com *ic = &sc->sc_ic;
1383 usbd_status error;
1384 uint32_t data;
1385
1386 error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR, &data);
1387 if (error != 0)
1388 goto fail;
1389 ic->ic_myaddr[0] = data & 0xff;
1390 ic->ic_myaddr[1] = (data & 0xff00) >> 8;
1391 error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR + 1, &data);
1392 if (error != 0)
1393 goto fail;
1394 ic->ic_myaddr[2] = data & 0xff;
1395 ic->ic_myaddr[3] = (data & 0xff00) >> 8;
1396 error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR + 2, &data);
1397 if (error != 0)
1398 goto fail;
1399 ic->ic_myaddr[4] = data & 0xff;
1400 ic->ic_myaddr[5] = (data & 0xff00) >> 8;
1401fail:
1402 return error;
1403}
1404
1405usbd_status
1406urtw_eprom_read32(struct urtw_softc *sc, uint32_t addr, uint32_t *data)
1407{
1408#define URTW_READCMD_LEN 3
1409 int addrlen, i;
1410 int16_t addrstr[8], data16, readcmd[] = { 1, 1, 0 };
1411 usbd_status error;
1412
1413 /* NB: make sure the buffer is initialized */
1414 *data = 0;
1415
1416 /* enable EPROM programming */
1417 urtw_write8_m(sc, URTW_EPROM_CMD, URTW_EPROM_CMD_PROGRAM_MODE);
1418 DELAY(URTW_EPROM_DELAY);
1419
1420 error = urtw_eprom_cs(sc, URTW_EPROM_ENABLE);
1421 if (error != 0)
1422 goto fail;
1423 error = urtw_eprom_ck(sc);
1424 if (error != 0)
1425 goto fail;
1426 error = urtw_eprom_sendbits(sc, readcmd, URTW_READCMD_LEN);
1427 if (error != 0)
1428 goto fail;
1429 if (sc->sc_epromtype == URTW_EEPROM_93C56) {
1430 addrlen = 8;
1431 addrstr[0] = addr & (1 << 7);
1432 addrstr[1] = addr & (1 << 6);
1433 addrstr[2] = addr & (1 << 5);
1434 addrstr[3] = addr & (1 << 4);
1435 addrstr[4] = addr & (1 << 3);
1436 addrstr[5] = addr & (1 << 2);
1437 addrstr[6] = addr & (1 << 1);
1438 addrstr[7] = addr & (1 << 0);
1439 } else {
1440 addrlen=6;
1441 addrstr[0] = addr & (1 << 5);
1442 addrstr[1] = addr & (1 << 4);
1443 addrstr[2] = addr & (1 << 3);
1444 addrstr[3] = addr & (1 << 2);
1445 addrstr[4] = addr & (1 << 1);
1446 addrstr[5] = addr & (1 << 0);
1447 }
1448 error = urtw_eprom_sendbits(sc, addrstr, addrlen);
1449 if (error != 0)
1450 goto fail;
1451
1452 error = urtw_eprom_writebit(sc, 0);
1453 if (error != 0)
1454 goto fail;
1455
1456 for (i = 0; i < 16; i++) {
1457 error = urtw_eprom_ck(sc);
1458 if (error != 0)
1459 goto fail;
1460 error = urtw_eprom_readbit(sc, &data16);
1461 if (error != 0)
1462 goto fail;
1463
1464 (*data) |= (data16 << (15 - i));
1465 }
1466
1467 error = urtw_eprom_cs(sc, URTW_EPROM_DISABLE);
1468 if (error != 0)
1469 goto fail;
1470 error = urtw_eprom_ck(sc);
1471 if (error != 0)
1472 goto fail;
1473
1474 /* now disable EPROM programming */
1475 urtw_write8_m(sc, URTW_EPROM_CMD, URTW_EPROM_CMD_NORMAL_MODE);
1476fail:
1477 return error;
1478#undef URTW_READCMD_LEN
1479}
1480
1481usbd_status
1482urtw_eprom_readbit(struct urtw_softc *sc, int16_t *data)
1483{
1484 uint8_t data8;
1485 usbd_status error;
1486
1487 urtw_read8_m(sc, URTW_EPROM_CMD, &data8);
1488 *data = (data8 & URTW_EPROM_READBIT) ? 1 : 0;
1489 DELAY(URTW_EPROM_DELAY);
1490
1491fail:
1492 return error;
1493}
1494
1495usbd_status
1496urtw_eprom_sendbits(struct urtw_softc *sc, int16_t *buf, int buflen)
1497{
1498 int i = 0;
1499 usbd_status error = 0;
1500
1501 for (i = 0; i < buflen; i++) {
1502 error = urtw_eprom_writebit(sc, buf[i]);
1503 if (error != 0)
1504 goto fail;
1505 error = urtw_eprom_ck(sc);
1506 if (error != 0)
1507 goto fail;
1508 }
1509fail:
1510 return error;
1511}
1512
1513usbd_status
1514urtw_eprom_writebit(struct urtw_softc *sc, int16_t bit)
1515{
1516 uint8_t data;
1517 usbd_status error;
1518
1519 urtw_read8_m(sc, URTW_EPROM_CMD, &data);
1520 if (bit != 0)
1521 urtw_write8_m(sc, URTW_EPROM_CMD, data | URTW_EPROM_WRITEBIT);
1522 else
1523 urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_WRITEBIT);
1524 DELAY(URTW_EPROM_DELAY);
1525fail:
1526 return error;
1527}
1528
1529usbd_status
1530urtw_eprom_ck(struct urtw_softc *sc)
1531{
1532 uint8_t data;
1533 usbd_status error;
1534
1535 /* masking */
1536 urtw_read8_m(sc, URTW_EPROM_CMD, &data);
1537 urtw_write8_m(sc, URTW_EPROM_CMD, data | URTW_EPROM_CK);
1538 DELAY(URTW_EPROM_DELAY);
1539 /* unmasking */
1540 urtw_read8_m(sc, URTW_EPROM_CMD, &data);
1541 urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_CK);
1542 DELAY(URTW_EPROM_DELAY);
1543fail:
1544 return error;
1545}
1546
1547usbd_status
1548urtw_eprom_cs(struct urtw_softc *sc, int able)
1549{
1550 uint8_t data;
1551 usbd_status error;
1552
1553 urtw_read8_m(sc, URTW_EPROM_CMD, &data);
1554 if (able == URTW_EPROM_ENABLE)
1555 urtw_write8_m(sc, URTW_EPROM_CMD, data | URTW_EPROM_CS);
1556 else
1557 urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_CS);
1558 DELAY(URTW_EPROM_DELAY);
1559fail:
1560 return error;
1561}
1562
1563usbd_status
1564urtw_read8_c(struct urtw_softc *sc, int val, uint8_t *data, uint8_t idx)
1565{
1566 usb_device_request_t req;
1567 usbd_status error;
1568
1569 req.bmRequestType = UT_READ_VENDOR_DEVICE;
1570 req.bRequest = URTW_8187_GETREGS_REQ;
1571 USETW(req.wValue, val | 0xff00);
1572 USETW(req.wIndex, idx & 0x03);
1573 USETW(req.wLength, sizeof(uint8_t));
1574
1575 error = usbd_do_request(sc->sc_udev, &req, data);
1576 return error;
1577}
1578
1579usbd_status
1580urtw_read8e(struct urtw_softc *sc, int val, uint8_t *data)
1581{
1582 usb_device_request_t req;
1583 usbd_status error;
1584
1585 req.bmRequestType = UT_READ_VENDOR_DEVICE;
1586 req.bRequest = URTW_8187_GETREGS_REQ;
1587 USETW(req.wValue, val | 0xfe00);
1588 USETW(req.wIndex, 0);
1589 USETW(req.wLength, sizeof(uint8_t));
1590
1591 error = usbd_do_request(sc->sc_udev, &req, data);
1592 return error;
1593}
1594
1595usbd_status
1596urtw_read16_c(struct urtw_softc *sc, int val, uint16_t *data, uint8_t idx)
1597{
1598 usb_device_request_t req;
1599 usbd_status error;
1600
1601 req.bmRequestType = UT_READ_VENDOR_DEVICE;
1602 req.bRequest = URTW_8187_GETREGS_REQ;
1603 USETW(req.wValue, val | 0xff00);
1604 USETW(req.wIndex, idx & 0x03);
1605 USETW(req.wLength, sizeof(uint16_t));
1606
1607 error = usbd_do_request(sc->sc_udev, &req, data);
1608 return error;
1609}
1610
1611usbd_status
1612urtw_read32_c(struct urtw_softc *sc, int val, uint32_t *data, uint8_t idx)
1613{
1614 usb_device_request_t req;
1615 usbd_status error;
1616
1617 req.bmRequestType = UT_READ_VENDOR_DEVICE;
1618 req.bRequest = URTW_8187_GETREGS_REQ;
1619 USETW(req.wValue, val | 0xff00);
1620 USETW(req.wIndex, idx & 0x03);
1621 USETW(req.wLength, sizeof(uint32_t));
1622
1623 error = usbd_do_request(sc->sc_udev, &req, data);
1624 return error;
1625}
1626
1627usbd_status
1628urtw_write8_c(struct urtw_softc *sc, int val, uint8_t data, uint8_t idx)
1629{
1630 usb_device_request_t req;
1631
1632 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
1633 req.bRequest = URTW_8187_SETREGS_REQ;
1634 USETW(req.wValue, val | 0xff00);
1635 USETW(req.wIndex, idx & 0x03);
1636 USETW(req.wLength, sizeof(uint8_t));
1637
1638 return usbd_do_request(sc->sc_udev, &req, &data);
1639}
1640
1641usbd_status
1642urtw_write8e(struct urtw_softc *sc, int val, uint8_t data)
1643{
1644 usb_device_request_t req;
1645
1646 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
1647 req.bRequest = URTW_8187_SETREGS_REQ;
1648 USETW(req.wValue, val | 0xfe00);
1649 USETW(req.wIndex, 0);
1650 USETW(req.wLength, sizeof(uint8_t));
1651
1652 return usbd_do_request(sc->sc_udev, &req, &data);
1653}
1654
1655usbd_status
1656urtw_write16_c(struct urtw_softc *sc, int val, uint16_t data, uint8_t idx)
1657{
1658 usb_device_request_t req;
1659
1660 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
1661 req.bRequest = URTW_8187_SETREGS_REQ;
1662 USETW(req.wValue, val | 0xff00);
1663 USETW(req.wIndex, idx & 0x03);
1664 USETW(req.wLength, sizeof(uint16_t));
1665
1666 return usbd_do_request(sc->sc_udev, &req, &data);
1667}
1668
1669usbd_status
1670urtw_write32_c(struct urtw_softc *sc, int val, uint32_t data, uint8_t idx)
1671{
1672 usb_device_request_t req;
1673
1674 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
1675 req.bRequest = URTW_8187_SETREGS_REQ;
1676 USETW(req.wValue, val | 0xff00);
1677 USETW(req.wIndex, idx & 0x03);
1678 USETW(req.wLength, sizeof(uint32_t));
1679
1680 return usbd_do_request(sc->sc_udev, &req, &data);
1681}
1682
1683static usbd_status
1684urtw_set_mode(struct urtw_softc *sc, uint32_t mode)
1685{
1686 uint8_t data;
1687 usbd_status error;
1688
1689 urtw_read8_m(sc, URTW_EPROM_CMD, &data);
1690 data = (data & ~URTW_EPROM_CMD_MASK) | (mode << URTW_EPROM_CMD_SHIFT);
1691 data = data & ~(URTW_EPROM_CS | URTW_EPROM_CK);
1692 urtw_write8_m(sc, URTW_EPROM_CMD, data);
1693fail:
1694 return error;
1695}
1696
1697usbd_status
1698urtw_8180_set_anaparam(struct urtw_softc *sc, uint32_t val)
1699{
1700 uint8_t data;
1701 usbd_status error;
1702
1703 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
1704 if (error)
1705 goto fail;
1706
1707 urtw_read8_m(sc, URTW_CONFIG3, &data);
1708 urtw_write8_m(sc, URTW_CONFIG3, data | URTW_CONFIG3_ANAPARAM_WRITE);
1709 urtw_write32_m(sc, URTW_ANAPARAM, val);
1710 urtw_read8_m(sc, URTW_CONFIG3, &data);
1711 urtw_write8_m(sc, URTW_CONFIG3, data & ~URTW_CONFIG3_ANAPARAM_WRITE);
1712
1713 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
1714 if (error)
1715 goto fail;
1716fail:
1717 return error;
1718}
1719
1720usbd_status
1721urtw_8185_set_anaparam2(struct urtw_softc *sc, uint32_t val)
1722{
1723 uint8_t data;
1724 usbd_status error;
1725
1726 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
1727 if (error)
1728 goto fail;
1729
1730 urtw_read8_m(sc, URTW_CONFIG3, &data);
1731 urtw_write8_m(sc, URTW_CONFIG3, data | URTW_CONFIG3_ANAPARAM_WRITE);
1732 urtw_write32_m(sc, URTW_ANAPARAM2, val);
1733 urtw_read8_m(sc, URTW_CONFIG3, &data);
1734 urtw_write8_m(sc, URTW_CONFIG3, data & ~URTW_CONFIG3_ANAPARAM_WRITE);
1735
1736 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
1737 if (error)
1738 goto fail;
1739fail:
1740 return error;
1741}
1742
1743usbd_status
1744urtw_intr_disable(struct urtw_softc *sc)
1745{
1746 usbd_status error;
1747
1748 urtw_write16_m(sc, URTW_INTR_MASK, 0);
1749
1750fail:
1751 return error;
1752}
1753
1754usbd_status
1755urtw_reset(struct urtw_softc *sc)
1756{
1757 uint8_t data;
1758 usbd_status error;
1759
1760 error = urtw_8180_set_anaparam(sc, URTW_8187_8225_ANAPARAM_ON);
1761 if (error)
1762 goto fail;
1763 error = urtw_8185_set_anaparam2(sc, URTW_8187_8225_ANAPARAM2_ON);
1764 if (error)
1765 goto fail;
1766
1767 error = urtw_intr_disable(sc);
1768 if (error)
1769 goto fail;
1770 usbd_delay_ms(sc->sc_udev, 100);
1771
1772 error = urtw_write8e(sc, 0x18, 0x10);
1773 if (error != 0)
1774 goto fail;
1775 error = urtw_write8e(sc, 0x18, 0x11);
1776 if (error != 0)
1777 goto fail;
1778 error = urtw_write8e(sc, 0x18, 0x00);
1779 if (error != 0)
1780 goto fail;
1781 usbd_delay_ms(sc->sc_udev, 100);
1782
1783 urtw_read8_m(sc, URTW_CMD, &data);
1784 data = (data & 2) | URTW_CMD_RST;
1785 urtw_write8_m(sc, URTW_CMD, data);
1786 usbd_delay_ms(sc->sc_udev, 100);
1787
1788 urtw_read8_m(sc, URTW_CMD, &data);
1789 if (data & URTW_CMD_RST) {
1790 printf("%s: reset timeout\n", device_xname(sc->sc_dev));
1791 goto fail;
1792 }
1793
1794 error = urtw_set_mode(sc, URTW_EPROM_CMD_LOAD);
1795 if (error)
1796 goto fail;
1797 usbd_delay_ms(sc->sc_udev, 100);
1798
1799 error = urtw_8180_set_anaparam(sc, URTW_8187_8225_ANAPARAM_ON);
1800 if (error)
1801 goto fail;
1802 error = urtw_8185_set_anaparam2(sc, URTW_8187_8225_ANAPARAM2_ON);
1803 if (error)
1804 goto fail;
1805fail:
1806 return error;
1807}
1808
1809usbd_status
1810urtw_led_on(struct urtw_softc *sc, int type)
1811{
1812 usbd_status error;
1813
1814 if (type == URTW_LED_GPIO) {
1815 switch (sc->sc_gpio_ledpin) {
1816 case URTW_LED_PIN_GPIO0:
1817 urtw_write8_m(sc, URTW_GPIO, 0x01);
1818 urtw_write8_m(sc, URTW_GP_ENABLE, 0x00);
1819 break;
1820 default:
1821 panic("unsupported LED PIN type 0x%x",
1822 sc->sc_gpio_ledpin);
1823 /* NOTREACHED */
1824 }
1825 } else {
1826 panic("unsupported LED type 0x%x", type);
1827 /* NOTREACHED */
1828 }
1829
1830 sc->sc_gpio_ledon = 1;
1831fail:
1832 return error;
1833}
1834
1835static usbd_status
1836urtw_led_off(struct urtw_softc *sc, int type)
1837{
1838 usbd_status error;
1839
1840 if (type == URTW_LED_GPIO) {
1841 switch (sc->sc_gpio_ledpin) {
1842 case URTW_LED_PIN_GPIO0:
1843 urtw_write8_m(sc, URTW_GPIO, 0x01);
1844 urtw_write8_m(sc, URTW_GP_ENABLE, 0x01);
1845 break;
1846 default:
1847 panic("unsupported LED PIN type 0x%x",
1848 sc->sc_gpio_ledpin);
1849 /* NOTREACHED */
1850 }
1851 } else {
1852 panic("unsupported LED type 0x%x", type);
1853 /* NOTREACHED */
1854 }
1855
1856 sc->sc_gpio_ledon = 0;
1857
1858fail:
1859 return error;
1860}
1861
1862usbd_status
1863urtw_led_mode0(struct urtw_softc *sc, int mode)
1864{
1865 switch (mode) {
1866 case URTW_LED_CTL_POWER_ON:
1867 sc->sc_gpio_ledstate = URTW_LED_POWER_ON_BLINK;
1868 break;
1869 case URTW_LED_CTL_TX:
1870 if (sc->sc_gpio_ledinprogress == 1)
1871 return 0;
1872
1873 sc->sc_gpio_ledstate = URTW_LED_BLINK_NORMAL;
1874 sc->sc_gpio_blinktime = 2;
1875 break;
1876 case URTW_LED_CTL_LINK:
1877 sc->sc_gpio_ledstate = URTW_LED_ON;
1878 break;
1879 default:
1880 panic("unsupported LED mode 0x%x", mode);
1881 /* NOTREACHED */
1882 }
1883
1884 switch (sc->sc_gpio_ledstate) {
1885 case URTW_LED_ON:
1886 if (sc->sc_gpio_ledinprogress != 0)
1887 break;
1888 urtw_led_on(sc, URTW_LED_GPIO);
1889 break;
1890 case URTW_LED_BLINK_NORMAL:
1891 if (sc->sc_gpio_ledinprogress != 0)
1892 break;
1893 sc->sc_gpio_ledinprogress = 1;
1894 sc->sc_gpio_blinkstate = (sc->sc_gpio_ledon != 0) ?
1895 URTW_LED_OFF : URTW_LED_ON;
1896 if (!sc->sc_dying)
1897 callout_schedule(&sc->sc_led_ch, mstohz(100));
1898 break;
1899 case URTW_LED_POWER_ON_BLINK:
1900 urtw_led_on(sc, URTW_LED_GPIO);
1901 usbd_delay_ms(sc->sc_udev, 100);
1902 urtw_led_off(sc, URTW_LED_GPIO);
1903 break;
1904 default:
1905 panic("unknown LED status 0x%x", sc->sc_gpio_ledstate);
1906 /* NOTREACHED */
1907 }
1908 return 0;
1909}
1910
1911usbd_status
1912urtw_led_mode1(struct urtw_softc *sc, int mode)
1913{
1914 return USBD_INVAL;
1915}
1916
1917usbd_status
1918urtw_led_mode2(struct urtw_softc *sc, int mode)
1919{
1920 return USBD_INVAL;
1921}
1922
1923usbd_status
1924urtw_led_mode3(struct urtw_softc *sc, int mode)
1925{
1926 return USBD_INVAL;
1927}
1928
1929void
1930urtw_ledusbtask(void *arg)
1931{
1932 struct urtw_softc *sc = arg;
1933
1934 if (sc->sc_strategy != URTW_SW_LED_MODE0)
1935 panic("could not process a LED strategy 0x%x", sc->sc_strategy);
1936
1937 urtw_led_blink(sc);
1938}
1939
1940void
1941urtw_ledtask(void *arg)
1942{
1943 struct urtw_softc *sc = arg;
1944
1945 /*
1946 * NB: to change a status of the led we need at least a sleep so we
1947 * can't do it here
1948 */
1949 usb_add_task(sc->sc_udev, &sc->sc_ledtask, USB_TASKQ_DRIVER);
1950}
1951
1952usbd_status
1953urtw_led_ctl(struct urtw_softc *sc, int mode)
1954{
1955 usbd_status error = 0;
1956
1957 switch (sc->sc_strategy) {
1958 case URTW_SW_LED_MODE0:
1959 error = urtw_led_mode0(sc, mode);
1960 break;
1961 case URTW_SW_LED_MODE1:
1962 error = urtw_led_mode1(sc, mode);
1963 break;
1964 case URTW_SW_LED_MODE2:
1965 error = urtw_led_mode2(sc, mode);
1966 break;
1967 case URTW_SW_LED_MODE3:
1968 error = urtw_led_mode3(sc, mode);
1969 break;
1970 default:
1971 panic("unsupported LED mode %d", sc->sc_strategy);
1972 /* NOTREACHED */
1973 }
1974
1975 return error;
1976}
1977
1978usbd_status
1979urtw_led_blink(struct urtw_softc *sc)
1980{
1981 uint8_t ing = 0;
1982
1983 if (sc->sc_gpio_blinkstate == URTW_LED_ON)
1984 (void)urtw_led_on(sc, URTW_LED_GPIO);
1985 else
1986 (void)urtw_led_off(sc, URTW_LED_GPIO);
1987 sc->sc_gpio_blinktime--;
1988 if (sc->sc_gpio_blinktime == 0)
1989 ing = 1;
1990 else {
1991 if (sc->sc_gpio_ledstate != URTW_LED_BLINK_NORMAL &&
1992 sc->sc_gpio_ledstate != URTW_LED_BLINK_SLOWLY &&
1993 sc->sc_gpio_ledstate != URTW_LED_BLINK_CM3)
1994 ing = 1;
1995 }
1996 if (ing == 1) {
1997 if (sc->sc_gpio_ledstate == URTW_LED_ON &&
1998 sc->sc_gpio_ledon == 0)
1999 (void)urtw_led_on(sc, URTW_LED_GPIO);
2000 else if (sc->sc_gpio_ledstate == URTW_LED_OFF &&
2001 sc->sc_gpio_ledon == 1)
2002 (void)urtw_led_off(sc, URTW_LED_GPIO);
2003
2004 sc->sc_gpio_blinktime = 0;
2005 sc->sc_gpio_ledinprogress = 0;
2006 return 0;
2007 }
2008
2009 sc->sc_gpio_blinkstate = (sc->sc_gpio_blinkstate != URTW_LED_ON) ?
2010 URTW_LED_ON : URTW_LED_OFF;
2011
2012 switch (sc->sc_gpio_ledstate) {
2013 case URTW_LED_BLINK_NORMAL:
2014 if (!sc->sc_dying)
2015 callout_schedule(&sc->sc_led_ch, mstohz(100));
2016 break;
2017 default:
2018 panic("unknown LED status 0x%x", sc->sc_gpio_ledstate);
2019 /* NOTREACHED */
2020 }
2021 return 0;
2022}
2023
2024usbd_status
2025urtw_update_msr(struct urtw_softc *sc)
2026{
2027 struct ieee80211com *ic = &sc->sc_ic;
2028 uint8_t data;
2029 usbd_status error;
2030
2031 urtw_read8_m(sc, URTW_MSR, &data);
2032 data &= ~URTW_MSR_LINK_MASK;
2033
2034 /* Should always be set. */
2035 if (sc->sc_hwrev & URTW_HWREV_8187B)
2036 data |= URTW_MSR_LINK_ENEDCA;
2037
2038 if (sc->sc_state == IEEE80211_S_RUN) {
2039 switch (ic->ic_opmode) {
2040 case IEEE80211_M_STA:
2041 case IEEE80211_M_MONITOR:
2042 data |= URTW_MSR_LINK_STA;
2043 break;
2044 default:
2045 panic("unsupported operation mode 0x%x",
2046 ic->ic_opmode);
2047 /* NOTREACHED */
2048 }
2049 } else
2050 data |= URTW_MSR_LINK_NONE;
2051
2052 urtw_write8_m(sc, URTW_MSR, data);
2053fail:
2054 return error;
2055}
2056
2057uint16_t
2058urtw_rate2rtl(int rate)
2059{
2060 unsigned int i;
2061
2062 for (i = 0; i < __arraycount(urtw_ratetable); i++) {
2063 if (rate == urtw_ratetable[i].reg)
2064 return urtw_ratetable[i].val;
2065 }
2066
2067 return 3;
2068}
2069
2070uint16_t
2071urtw_rtl2rate(int rate)
2072{
2073 unsigned int i;
2074
2075 for (i = 0; i < __arraycount(urtw_ratetable); i++) {
2076 if (rate == urtw_ratetable[i].val)
2077 return urtw_ratetable[i].reg;
2078 }
2079
2080 return 0;
2081}
2082
2083usbd_status
2084urtw_set_rate(struct urtw_softc *sc)
2085{
2086 int i, basic_rate, min_rr_rate, max_rr_rate;
2087 uint16_t data;
2088 usbd_status error;
2089
2090 basic_rate = urtw_rate2rtl(48);
2091 min_rr_rate = urtw_rate2rtl(12);
2092 max_rr_rate = urtw_rate2rtl(48);
2093
2094 urtw_write8_m(sc, URTW_RESP_RATE,
2095 max_rr_rate << URTW_RESP_MAX_RATE_SHIFT |
2096 min_rr_rate << URTW_RESP_MIN_RATE_SHIFT);
2097
2098 urtw_read16_m(sc, URTW_8187_BRSR, &data);
2099 data &= ~URTW_BRSR_MBR_8185;
2100
2101 for (i = 0; i <= basic_rate; i++)
2102 data |= (1 << i);
2103
2104 urtw_write16_m(sc, URTW_8187_BRSR, data);
2105fail:
2106 return error;
2107}
2108
2109usbd_status
2110urtw_intr_enable(struct urtw_softc *sc)
2111{
2112 usbd_status error;
2113
2114 urtw_write16_m(sc, URTW_INTR_MASK, 0xffff);
2115fail:
2116 return error;
2117}
2118
2119usbd_status
2120urtw_rx_setconf(struct urtw_softc *sc)
2121{
2122 struct ifnet *ifp = sc->sc_ic.ic_ifp;
2123 struct ieee80211com *ic = &sc->sc_ic;
2124 uint32_t data;
2125 usbd_status error;
2126
2127 urtw_read32_m(sc, URTW_RX, &data);
2128 data = data &~ URTW_RX_FILTER_MASK;
2129#if 0
2130 data = data | URTW_RX_FILTER_CTL;
2131#endif
2132 data = data | URTW_RX_FILTER_MNG | URTW_RX_FILTER_DATA;
2133 data = data | URTW_RX_FILTER_BCAST | URTW_RX_FILTER_MCAST;
2134
2135 if (ic->ic_opmode == IEEE80211_M_MONITOR) {
2136 data = data | URTW_RX_FILTER_ICVERR;
2137 data = data | URTW_RX_FILTER_PWR;
2138 }
2139 if (sc->sc_crcmon == 1 && ic->ic_opmode == IEEE80211_M_MONITOR)
2140 data = data | URTW_RX_FILTER_CRCERR;
2141
2142 if (ic->ic_opmode == IEEE80211_M_MONITOR ||
2143 (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC))) {
2144 data = data | URTW_RX_FILTER_ALLMAC;
2145 } else {
2146 data = data | URTW_RX_FILTER_NICMAC;
2147 data = data | URTW_RX_CHECK_BSSID;
2148 }
2149
2150 data = data &~ URTW_RX_FIFO_THRESHOLD_MASK;
2151 data = data | URTW_RX_FIFO_THRESHOLD_NONE | URTW_RX_AUTORESETPHY;
2152 data = data &~ URTW_MAX_RX_DMA_MASK;
2153 data = data | URTW_MAX_RX_DMA_2048 | URTW_RCR_ONLYERLPKT;
2154
2155 urtw_write32_m(sc, URTW_RX, data);
2156fail:
2157 return error;
2158}
2159
2160usbd_status
2161urtw_rx_enable(struct urtw_softc *sc)
2162{
2163 int i;
2164 struct urtw_rx_data *rx_data;
2165 uint8_t data;
2166 usbd_status error;
2167
2168 /*
2169 * Start up the receive pipe.
2170 */
2171 for (i = 0; i < URTW_RX_DATA_LIST_COUNT; i++) {
2172 rx_data = &sc->sc_rx_data[i];
2173
2174 usbd_setup_xfer(rx_data->xfer, rx_data, rx_data->buf, MCLBYTES,
2175 USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, urtw_rxeof);
2176 error = usbd_transfer(rx_data->xfer);
2177 if (error != USBD_IN_PROGRESS && error != 0) {
2178 printf("%s: could not queue Rx transfer\n",
2179 device_xname(sc->sc_dev));
2180 goto fail;
2181 }
2182 }
2183
2184 error = urtw_rx_setconf(sc);
2185 if (error != 0)
2186 goto fail;
2187
2188 urtw_read8_m(sc, URTW_CMD, &data);
2189 urtw_write8_m(sc, URTW_CMD, data | URTW_CMD_RX_ENABLE);
2190fail:
2191 return error;
2192}
2193
2194usbd_status
2195urtw_tx_enable(struct urtw_softc *sc)
2196{
2197 uint8_t data8;
2198 uint32_t data;
2199 usbd_status error;
2200
2201 if (sc->sc_hwrev & URTW_HWREV_8187) {
2202 urtw_read8_m(sc, URTW_CW_CONF, &data8);
2203 data8 &= ~(URTW_CW_CONF_PERPACKET_CW |
2204 URTW_CW_CONF_PERPACKET_RETRY);
2205 urtw_write8_m(sc, URTW_CW_CONF, data8);
2206
2207 urtw_read8_m(sc, URTW_TX_AGC_CTL, &data8);
2208 data8 &= ~URTW_TX_AGC_CTL_PERPACKET_GAIN;
2209 data8 &= ~URTW_TX_AGC_CTL_PERPACKET_ANTSEL;
2210 data8 &= ~URTW_TX_AGC_CTL_FEEDBACK_ANT;
2211 urtw_write8_m(sc, URTW_TX_AGC_CTL, data8);
2212
2213 urtw_read32_m(sc, URTW_TX_CONF, &data);
2214 data &= ~URTW_TX_LOOPBACK_MASK;
2215 data |= URTW_TX_LOOPBACK_NONE;
2216 data &= ~(URTW_TX_DPRETRY_MASK | URTW_TX_RTSRETRY_MASK);
2217 data |= sc->sc_tx_retry << URTW_TX_DPRETRY_SHIFT;
2218 data |= sc->sc_rts_retry << URTW_TX_RTSRETRY_SHIFT;
2219 data &= ~(URTW_TX_NOCRC | URTW_TX_MXDMA_MASK);
2220 data |= URTW_TX_MXDMA_2048 | URTW_TX_CWMIN | URTW_TX_DISCW;
2221 data &= ~URTW_TX_SWPLCPLEN;
2222 data |= URTW_TX_NOICV;
2223 urtw_write32_m(sc, URTW_TX_CONF, data);
2224 } else {
2225 data = URTW_TX_DURPROCMODE | URTW_TX_DISREQQSIZE |
2226 URTW_TX_MXDMA_2048 | URTW_TX_SHORTRETRY |
2227 URTW_TX_LONGRETRY;
2228 urtw_write32_m(sc, URTW_TX_CONF, data);
2229 }
2230
2231 urtw_read8_m(sc, URTW_CMD, &data8);
2232 urtw_write8_m(sc, URTW_CMD, data8 | URTW_CMD_TX_ENABLE);
2233fail:
2234 return error;
2235}
2236
2237int
2238urtw_init(struct ifnet *ifp)
2239{
2240 struct urtw_softc *sc = ifp->if_softc;
2241 struct urtw_rf *rf = &sc->sc_rf;
2242 struct ieee80211com *ic = &sc->sc_ic;
2243 usbd_status error;
2244
2245 urtw_stop(ifp, 0);
2246
2247 error = urtw_reset(sc);
2248 if (error)
2249 goto fail;
2250
2251 urtw_write8_m(sc, 0x85, 0);
2252 urtw_write8_m(sc, URTW_GPIO, 0);
2253
2254 /* for led */
2255 urtw_write8_m(sc, 0x85, 4);
2256 error = urtw_led_ctl(sc, URTW_LED_CTL_POWER_ON);
2257 if (error != 0)
2258 goto fail;
2259
2260 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
2261 if (error)
2262 goto fail;
2263
2264 /* applying MAC address again. */
2265 IEEE80211_ADDR_COPY(ic->ic_myaddr, CLLADDR(ifp->if_sadl));
2266 error = urtw_set_macaddr(sc, ic->ic_myaddr);
2267 if (error)
2268 goto fail;
2269 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
2270 if (error)
2271 goto fail;
2272
2273 error = urtw_update_msr(sc);
2274 if (error)
2275 goto fail;
2276
2277 urtw_write32_m(sc, URTW_INT_TIMEOUT, 0);
2278 urtw_write8_m(sc, URTW_WPA_CONFIG, 0);
2279 urtw_write8_m(sc, URTW_RATE_FALLBACK, 0x81);
2280 error = urtw_set_rate(sc);
2281 if (error != 0)
2282 goto fail;
2283
2284 error = rf->init(rf);
2285 if (error != 0)
2286 goto fail;
2287 if (rf->set_sens != NULL)
2288 rf->set_sens(rf);
2289
2290 urtw_write16_m(sc, 0x5e, 1);
2291 urtw_write16_m(sc, 0xfe, 0x10);
2292 urtw_write8_m(sc, URTW_TALLY_SEL, 0x80);
2293 urtw_write8_m(sc, 0xff, 0x60);
2294 urtw_write16_m(sc, 0x5e, 0);
2295 urtw_write8_m(sc, 0x85, 4);
2296
2297 error = urtw_intr_enable(sc);
2298 if (error != 0)
2299 goto fail;
2300
2301 /* reset softc variables */
2302 for (size_t j = 0; j < URTW_PRIORITY_MAX; j++) {
2303 sc->sc_txidx[j] = sc->sc_tx_queued[j] = 0;
2304 }
2305 sc->sc_txtimer = 0;
2306
2307 if (!(sc->sc_flags & URTW_INIT_ONCE)) {
2308 error = usbd_set_config_no(sc->sc_udev, URTW_CONFIG_NO, 0);
2309 if (error != 0) {
2310 aprint_error_dev(sc->sc_dev, "failed to set configuration"
2311 ", err=%s\n", usbd_errstr(error));
2312 goto fail;
2313 }
2314 /* get the first interface handle */
2315 error = usbd_device2interface_handle(sc->sc_udev,
2316 URTW_IFACE_INDEX, &sc->sc_iface);
2317 if (error != 0) {
2318 printf("%s: could not get interface handle\n",
2319 device_xname(sc->sc_dev));
2320 goto fail;
2321 }
2322 error = urtw_open_pipes(sc);
2323 if (error != 0)
2324 goto fail;
2325 error = urtw_alloc_rx_data_list(sc);
2326 if (error != 0)
2327 goto fail;
2328 error = urtw_alloc_tx_data_list(sc);
2329 if (error != 0)
2330 goto fail;
2331 sc->sc_flags |= URTW_INIT_ONCE;
2332 }
2333
2334 error = urtw_rx_enable(sc);
2335 if (error != 0)
2336 goto fail;
2337 error = urtw_tx_enable(sc);
2338 if (error != 0)
2339 goto fail;
2340
2341 ifp->if_flags &= ~IFF_OACTIVE;
2342 ifp->if_flags |= IFF_RUNNING;
2343
2344 if (ic->ic_opmode == IEEE80211_M_MONITOR)
2345 ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
2346 else
2347 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
2348
2349 return 0;
2350fail:
2351 return error;
2352}
2353
2354int
2355urtw_ioctl(struct ifnet *ifp, u_long cmd, void *data)
2356{
2357#define IS_RUNNING(ifp) \
2358 (((ifp)->if_flags & IFF_UP) && ((ifp)->if_flags & IFF_RUNNING))
2359
2360 struct urtw_softc *sc = ifp->if_softc;
2361 struct ieee80211com *ic = &sc->sc_ic;
2362 int s, error = 0;
2363
2364 if (sc->sc_dying)
2365 return ENXIO;
2366
2367 s = splnet();
2368
2369 switch (cmd) {
2370 case SIOCSIFFLAGS:
2371 if ((error = ifioctl_common(ifp, cmd, data)) != 0)
2372 break;
2373 switch (ifp->if_flags & (IFF_UP|IFF_RUNNING)) {
2374 case IFF_UP|IFF_RUNNING:
2375 break;
2376 case IFF_UP:
2377 ifp->if_init(ifp);
2378 break;
2379 case IFF_RUNNING:
2380 urtw_stop(ifp, 1);
2381 break;
2382 case 0:
2383 break;
2384 }
2385 break;
2386
2387 case SIOCADDMULTI:
2388 case SIOCDELMULTI:
2389 if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET)
2390 error = 0;
2391 break;
2392
2393 default:
2394 error = ieee80211_ioctl(ic, cmd, data);
2395 break;
2396 }
2397
2398 if (error == ENETRESET) {
2399 if (IS_RUNNING(ifp) &&
2400 (ic->ic_roaming != IEEE80211_ROAMING_MANUAL))
2401 ifp->if_init(ifp);
2402 error = 0;
2403 }
2404
2405 splx(s);
2406
2407 return error;
2408#undef IS_RUNNING
2409}
2410
2411void
2412urtw_start(struct ifnet *ifp)
2413{
2414 struct urtw_softc *sc = ifp->if_softc;
2415 struct ieee80211com *ic = &sc->sc_ic;
2416 struct ieee80211_node *ni;
2417 struct ether_header *eh;
2418 struct mbuf *m0;
2419
2420 /*
2421 * net80211 may still try to send management frames even if the
2422 * IFF_RUNNING flag is not set...
2423 */
2424 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
2425 return;
2426
2427 for (;;) {
2428 IF_POLL(&ic->ic_mgtq, m0);
2429 if (m0 != NULL) {
2430
2431 if (sc->sc_tx_queued[URTW_PRIORITY_NORMAL] >=
2432 URTW_TX_DATA_LIST_COUNT) {
2433 ifp->if_flags |= IFF_OACTIVE;
2434 break;
2435 }
2436 IF_DEQUEUE(&ic->ic_mgtq, m0);
2437 ni = M_GETCTX(m0, struct ieee80211_node *);
2438 M_CLEARCTX(m0);
2439 bpf_mtap3(ic->ic_rawbpf, m0);
2440 if (urtw_tx_start(sc, ni, m0, URTW_PRIORITY_NORMAL)
2441 != 0)
2442 break;
2443 } else {
2444 if (ic->ic_state != IEEE80211_S_RUN)
2445 break;
2446 IFQ_POLL(&ifp->if_snd, m0);
2447 if (m0 == NULL)
2448 break;
2449 if (sc->sc_tx_queued[URTW_PRIORITY_NORMAL] >=
2450 URTW_TX_DATA_LIST_COUNT) {
2451 ifp->if_flags |= IFF_OACTIVE;
2452 break;
2453 }
2454 IFQ_DEQUEUE(&ifp->if_snd, m0);
2455 if (m0->m_len < sizeof(struct ether_header) &&
2456 !(m0 = m_pullup(m0, sizeof(struct ether_header))))
2457 continue;
2458
2459 eh = mtod(m0, struct ether_header *);
2460 ni = ieee80211_find_txnode(ic, eh->ether_dhost);
2461 if (ni == NULL) {
2462 m_freem(m0);
2463 continue;
2464 }
2465 bpf_mtap(ifp, m0);
2466 m0 = ieee80211_encap(ic, m0, ni);
2467 if (m0 == NULL) {
2468 ieee80211_free_node(ni);
2469 continue;
2470 }
2471 bpf_mtap3(ic->ic_rawbpf, m0);
2472 if (urtw_tx_start(sc, ni, m0, URTW_PRIORITY_NORMAL)
2473 != 0) {
2474 ieee80211_free_node(ni);
2475 ifp->if_oerrors++;
2476 break;
2477 }
2478 }
2479 sc->sc_txtimer = 5;
2480 ifp->if_timer = 1;
2481 }
2482}
2483
2484void
2485urtw_watchdog(struct ifnet *ifp)
2486{
2487 struct urtw_softc *sc = ifp->if_softc;
2488
2489 ifp->if_timer = 0;
2490
2491 if (sc->sc_txtimer > 0) {
2492 if (--sc->sc_txtimer == 0) {
2493 printf("%s: device timeout\n", device_xname(sc->sc_dev));
2494 ifp->if_oerrors++;
2495 return;
2496 }
2497 ifp->if_timer = 1;
2498 }
2499
2500 ieee80211_watchdog(&sc->sc_ic);
2501}
2502
2503void
2504urtw_txeof_low(struct usbd_xfer *xfer, void *priv,
2505 usbd_status status)
2506{
2507 struct urtw_tx_data *data = priv;
2508 struct urtw_softc *sc = data->sc;
2509 struct ieee80211com *ic = &sc->sc_ic;
2510 struct ifnet *ifp = ic->ic_ifp;
2511 int s;
2512
2513 if (status != USBD_NORMAL_COMPLETION) {
2514 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
2515 return;
2516
2517 printf("%s: could not transmit buffer: %s\n",
2518 device_xname(sc->sc_dev), usbd_errstr(status));
2519
2520 if (status == USBD_STALLED)
2521 usbd_clear_endpoint_stall_async(sc->sc_txpipe_low);
2522
2523 ifp->if_oerrors++;
2524 return;
2525 }
2526
2527 s = splnet();
2528
2529 ieee80211_free_node(data->ni);
2530 data->ni = NULL;
2531
2532 sc->sc_txtimer = 0;
2533 ifp->if_opackets++;
2534
2535 sc->sc_tx_queued[URTW_PRIORITY_LOW]--;
2536 ifp->if_flags &= ~IFF_OACTIVE;
2537 urtw_start(ifp);
2538
2539 splx(s);
2540}
2541
2542void
2543urtw_txeof_normal(struct usbd_xfer *xfer, void *priv,
2544 usbd_status status)
2545{
2546 struct urtw_tx_data *data = priv;
2547 struct urtw_softc *sc = data->sc;
2548 struct ieee80211com *ic = &sc->sc_ic;
2549 struct ifnet *ifp = ic->ic_ifp;
2550 int s;
2551
2552 if (status != USBD_NORMAL_COMPLETION) {
2553 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
2554 return;
2555
2556 printf("%s: could not transmit buffer: %s\n",
2557 device_xname(sc->sc_dev), usbd_errstr(status));
2558
2559 if (status == USBD_STALLED)
2560 usbd_clear_endpoint_stall_async(sc->sc_txpipe_normal);
2561
2562 ifp->if_oerrors++;
2563 return;
2564 }
2565
2566 s = splnet();
2567
2568 ieee80211_free_node(data->ni);
2569 data->ni = NULL;
2570
2571 sc->sc_txtimer = 0;
2572 ifp->if_opackets++;
2573
2574 sc->sc_tx_queued[URTW_PRIORITY_NORMAL]--;
2575 ifp->if_flags &= ~IFF_OACTIVE;
2576 urtw_start(ifp);
2577
2578 splx(s);
2579}
2580
2581int
2582urtw_tx_start(struct urtw_softc *sc, struct ieee80211_node *ni, struct mbuf *m0,
2583 int prior)
2584{
2585 struct ieee80211com *ic = &sc->sc_ic;
2586 struct urtw_tx_data *data;
2587 struct ieee80211_frame *wh;
2588 struct ieee80211_key *k;
2589 usbd_status error;
2590 int xferlen;
2591
2592 wh = mtod(m0, struct ieee80211_frame *);
2593
2594 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
2595 k = ieee80211_crypto_encap(ic, ni, m0);
2596 if (k == NULL) {
2597 m_freem(m0);
2598 return ENOBUFS;
2599 }
2600 /* packet header may have moved, reset our local pointer */
2601 wh = mtod(m0, struct ieee80211_frame *);
2602 }
2603
2604 if (sc->sc_drvbpf != NULL) {
2605 struct urtw_tx_radiotap_header *tap = &sc->sc_txtap;
2606
2607 tap->wt_flags = 0;
2608 tap->wt_rate = 0;
2609 tap->wt_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq);
2610 tap->wt_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags);
2611
2612 bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0);
2613 }
2614
2615 if (sc->sc_hwrev & URTW_HWREV_8187)
2616 xferlen = m0->m_pkthdr.len + 4 * 3;
2617 else
2618 xferlen = m0->m_pkthdr.len + 4 * 8;
2619
2620 if ((0 == xferlen % 64) || (0 == xferlen % 512))
2621 xferlen += 1;
2622
2623 data = &sc->sc_tx_data[prior][sc->sc_txidx[prior]];
2624 sc->sc_txidx[prior] =
2625 (sc->sc_txidx[prior] + 1) % URTW_TX_DATA_LIST_COUNT;
2626
2627 memset(data->buf, 0, URTW_TX_MAXSIZE);
2628 data->buf[0] = m0->m_pkthdr.len & 0xff;
2629 data->buf[1] = (m0->m_pkthdr.len & 0x0f00) >> 8;
2630 data->buf[1] |= (1 << 7);
2631
2632 /* XXX sc_preamble_mode is always 2. */
2633 if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
2634 (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE) &&
2635 (sc->sc_preamble_mode == 1) && (sc->sc_currate != 0))
2636 data->buf[2] |= 1;
2637 if ((m0->m_pkthdr.len > ic->ic_rtsthreshold) &&
2638 prior == URTW_PRIORITY_LOW)
2639 panic("TODO tx.");
2640 if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG)
2641 data->buf[2] |= (1 << 1);
2642 /* RTS rate - 10 means we use a basic rate. */
2643 data->buf[2] |= (urtw_rate2rtl(2) << 3);
2644 /*
2645 * XXX currently TX rate control depends on the rate value of
2646 * RX descriptor because I don't know how to we can control TX rate
2647 * in more smart way. Please fix me you find a thing.
2648 */
2649 data->buf[3] = sc->sc_currate;
2650 if (prior == URTW_PRIORITY_NORMAL) {
2651 if (IEEE80211_IS_MULTICAST(wh->i_addr1))
2652 data->buf[3] = urtw_rate2rtl(ni->ni_rates.rs_rates[0]);
2653 else if (ic->ic_fixed_rate != -1)
2654 data->buf[3] = urtw_rate2rtl(ic->ic_fixed_rate);
2655 }
2656
2657 if (sc->sc_hwrev & URTW_HWREV_8187) {
2658 data->buf[8] = 3; /* CW minimum */
2659 data->buf[8] |= (7 << 4); /* CW maximum */
2660 data->buf[9] |= 11; /* retry limitation */
2661 m_copydata(m0, 0, m0->m_pkthdr.len, (uint8_t *)&data->buf[12]);
2662 } else {
2663 data->buf[21] |= 11; /* retry limitation */
2664 m_copydata(m0, 0, m0->m_pkthdr.len, (uint8_t *)&data->buf[32]);
2665 }
2666
2667 data->ni = ni;
2668
2669 /* mbuf is no longer needed. */
2670 m_freem(m0);
2671
2672 usbd_setup_xfer(data->xfer, data, data->buf, xferlen,
2673 USBD_FORCE_SHORT_XFER, URTW_DATA_TIMEOUT,
2674 (prior == URTW_PRIORITY_LOW) ? urtw_txeof_low : urtw_txeof_normal);
2675 error = usbd_transfer(data->xfer);
2676 if (error != USBD_IN_PROGRESS && error != USBD_NORMAL_COMPLETION) {
2677 printf("%s: could not send frame: %s\n",
2678 device_xname(sc->sc_dev), usbd_errstr(error));
2679 return EIO;
2680 }
2681
2682 error = urtw_led_ctl(sc, URTW_LED_CTL_TX);
2683 if (error != 0)
2684 printf("%s: could not control LED (%d)\n",
2685 device_xname(sc->sc_dev), error);
2686
2687 sc->sc_tx_queued[prior]++;
2688
2689 return 0;
2690}
2691
2692usbd_status
2693urtw_8225_usb_init(struct urtw_softc *sc)
2694{
2695 uint8_t data;
2696 usbd_status error;
2697
2698 urtw_write8_m(sc, URTW_RF_PINS_SELECT + 1, 0);
2699 urtw_write8_m(sc, URTW_GPIO, 0);
2700 error = urtw_read8e(sc, 0x53, &data);
2701 if (error)
2702 goto fail;
2703 error = urtw_write8e(sc, 0x53, data | (1 << 7));
2704 if (error)
2705 goto fail;
2706 urtw_write8_m(sc, URTW_RF_PINS_SELECT + 1, 4);
2707 urtw_write8_m(sc, URTW_GPIO, 0x20);
2708 urtw_write8_m(sc, URTW_GP_ENABLE, 0);
2709
2710 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, 0x80);
2711 urtw_write16_m(sc, URTW_RF_PINS_SELECT, 0x80);
2712 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x80);
2713
2714 usbd_delay_ms(sc->sc_udev, 500);
2715fail:
2716 return error;
2717}
2718
2719usbd_status
2720urtw_8185_rf_pins_enable(struct urtw_softc *sc)
2721{
2722 usbd_status error = 0;
2723
2724 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x1ff7);
2725fail:
2726 return error;
2727}
2728
2729usbd_status
2730urtw_8187_write_phy(struct urtw_softc *sc, uint8_t addr, uint32_t data)
2731{
2732 uint32_t phyw;
2733 usbd_status error;
2734
2735 phyw = ((data << 8) | (addr | 0x80));
2736 urtw_write8_m(sc, 0x7f, ((phyw & 0xff000000) >> 24));
2737 urtw_write8_m(sc, 0x7e, ((phyw & 0x00ff0000) >> 16));
2738 urtw_write8_m(sc, 0x7d, ((phyw & 0x0000ff00) >> 8));
2739 urtw_write8_m(sc, 0x7c, ((phyw & 0x000000ff)));
2740 /*
2741 * Delay removed from 8185 to 8187.
2742 * usbd_delay_ms(sc->sc_udev, 1);
2743 */
2744fail:
2745 return error;
2746}
2747
2748usbd_status
2749urtw_8187_write_phy_ofdm_c(struct urtw_softc *sc, uint8_t addr, uint32_t data)
2750{
2751 data = data & 0xff;
2752 return urtw_8187_write_phy(sc, addr, data);
2753}
2754
2755usbd_status
2756urtw_8187_write_phy_cck_c(struct urtw_softc *sc, uint8_t addr, uint32_t data)
2757{
2758 data = data & 0xff;
2759 return urtw_8187_write_phy(sc, addr, data | 0x10000);
2760}
2761
2762usbd_status
2763urtw_8225_setgain(struct urtw_softc *sc, int16_t gain)
2764{
2765 usbd_status error;
2766
2767 urtw_8187_write_phy_ofdm(sc, 0x0d, urtw_8225_gain[gain * 4]);
2768 urtw_8187_write_phy_ofdm(sc, 0x1b, urtw_8225_gain[gain * 4 + 2]);
2769 urtw_8187_write_phy_ofdm(sc, 0x1d, urtw_8225_gain[gain * 4 + 3]);
2770 urtw_8187_write_phy_ofdm(sc, 0x23, urtw_8225_gain[gain * 4 + 1]);
2771fail:
2772 return error;
2773}
2774
2775usbd_status
2776urtw_8225_set_txpwrlvl(struct urtw_softc *sc, int chan)
2777{
2778 int i, idx, set;
2779 uint8_t *cck_pwltable;
2780 uint8_t cck_pwrlvl_max, ofdm_pwrlvl_min, ofdm_pwrlvl_max;
2781 uint8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
2782 uint8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
2783 usbd_status error;
2784
2785 cck_pwrlvl_max = 11;
2786 ofdm_pwrlvl_max = 25; /* 12 -> 25 */
2787 ofdm_pwrlvl_min = 10;
2788
2789 /* CCK power setting */
2790 cck_pwrlvl = (cck_pwrlvl > cck_pwrlvl_max) ? cck_pwrlvl_max : cck_pwrlvl;
2791 idx = cck_pwrlvl % 6;
2792 set = cck_pwrlvl / 6;
2793 cck_pwltable = (chan == 14) ? urtw_8225_txpwr_cck_ch14 :
2794 urtw_8225_txpwr_cck;
2795
2796 urtw_write8_m(sc, URTW_TX_GAIN_CCK,
2797 urtw_8225_tx_gain_cck_ofdm[set] >> 1);
2798 for (i = 0; i < 8; i++) {
2799 urtw_8187_write_phy_cck(sc, 0x44 + i,
2800 cck_pwltable[idx * 8 + i]);
2801 }
2802 usbd_delay_ms(sc->sc_udev, 1);
2803
2804 /* OFDM power setting */
2805 ofdm_pwrlvl = (ofdm_pwrlvl > (ofdm_pwrlvl_max - ofdm_pwrlvl_min)) ?
2806 ofdm_pwrlvl_max : ofdm_pwrlvl + ofdm_pwrlvl_min;
2807 ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
2808
2809 idx = ofdm_pwrlvl % 6;
2810 set = ofdm_pwrlvl / 6;
2811
2812 error = urtw_8185_set_anaparam2(sc, URTW_8187_8225_ANAPARAM2_ON);
2813 if (error)
2814 goto fail;
2815 urtw_8187_write_phy_ofdm(sc, 2, 0x42);
2816 urtw_8187_write_phy_ofdm(sc, 6, 0);
2817 urtw_8187_write_phy_ofdm(sc, 8, 0);
2818
2819 urtw_write8_m(sc, URTW_TX_GAIN_OFDM,
2820 urtw_8225_tx_gain_cck_ofdm[set] >> 1);
2821 urtw_8187_write_phy_ofdm(sc, 0x5, urtw_8225_txpwr_ofdm[idx]);
2822 urtw_8187_write_phy_ofdm(sc, 0x7, urtw_8225_txpwr_ofdm[idx]);
2823 usbd_delay_ms(sc->sc_udev, 1);
2824fail:
2825 return error;
2826}
2827
2828usbd_status
2829urtw_8185_tx_antenna(struct urtw_softc *sc, uint8_t ant)
2830{
2831 usbd_status error;
2832
2833 urtw_write8_m(sc, URTW_TX_ANTENNA, ant);
2834 usbd_delay_ms(sc->sc_udev, 1);
2835fail:
2836 return error;
2837}
2838
2839usbd_status
2840urtw_8225_rf_init(struct urtw_rf *rf)
2841{
2842 struct urtw_softc *sc = rf->rf_sc;
2843 unsigned int i;
2844 uint16_t data;
2845 usbd_status error;
2846
2847 error = urtw_8180_set_anaparam(sc, URTW_8187_8225_ANAPARAM_ON);
2848 if (error)
2849 goto fail;
2850
2851 error = urtw_8225_usb_init(sc);
2852 if (error)
2853 goto fail;
2854
2855 urtw_write32_m(sc, URTW_RF_TIMING, 0x000a8008);
2856 urtw_read16_m(sc, URTW_8187_BRSR, &data); /* XXX ??? */
2857 urtw_write16_m(sc, URTW_8187_BRSR, 0xffff);
2858 urtw_write32_m(sc, URTW_RF_PARA, 0x100044);
2859
2860 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
2861 if (error)
2862 goto fail;
2863 urtw_write8_m(sc, URTW_CONFIG3, 0x44);
2864 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
2865 if (error)
2866 goto fail;
2867
2868 error = urtw_8185_rf_pins_enable(sc);
2869 if (error)
2870 goto fail;
2871
2872 usbd_delay_ms(sc->sc_udev, 500);
2873
2874 for (i = 0; i < __arraycount(urtw_8225_rf_part1); i++) {
2875 urtw_8225_write(sc, urtw_8225_rf_part1[i].reg,
2876 urtw_8225_rf_part1[i].val);
2877 }
2878 usbd_delay_ms(sc->sc_udev, 50);
2879 urtw_8225_write(sc, 0x2, 0xc4d);
2880 usbd_delay_ms(sc->sc_udev, 200);
2881 urtw_8225_write(sc, 0x2, 0x44d);
2882 usbd_delay_ms(sc->sc_udev, 200);
2883 urtw_8225_write(sc, 0x0, 0x127);
2884
2885 for (i = 0; i < __arraycount(urtw_8225_rxgain); i++) {
2886 urtw_8225_write(sc, 0x1, (uint8_t)(i + 1));
2887 urtw_8225_write(sc, 0x2, urtw_8225_rxgain[i]);
2888 }
2889
2890 urtw_8225_write(sc, 0x0, 0x27);
2891 urtw_8225_write(sc, 0x0, 0x22f);
2892
2893 for (i = 0; i < __arraycount(urtw_8225_agc); i++) {
2894 urtw_8187_write_phy_ofdm(sc, 0xb, urtw_8225_agc[i]);
2895 urtw_8187_write_phy_ofdm(sc, 0xa, (uint8_t)i + 0x80);
2896 }
2897
2898 for (i = 0; i < __arraycount(urtw_8225_rf_part2); i++) {
2899 urtw_8187_write_phy_ofdm(sc, urtw_8225_rf_part2[i].reg,
2900 urtw_8225_rf_part2[i].val);
2901 usbd_delay_ms(sc->sc_udev, 1);
2902 }
2903
2904 error = urtw_8225_setgain(sc, 4);
2905 if (error)
2906 goto fail;
2907
2908 for (i = 0; i < __arraycount(urtw_8225_rf_part3); i++) {
2909 urtw_8187_write_phy_cck(sc, urtw_8225_rf_part3[i].reg,
2910 urtw_8225_rf_part3[i].val);
2911 usbd_delay_ms(sc->sc_udev, 1);
2912 }
2913
2914 urtw_write8_m(sc, 0x5b, 0x0d);
2915
2916 error = urtw_8225_set_txpwrlvl(sc, 1);
2917 if (error)
2918 goto fail;
2919
2920 urtw_8187_write_phy_cck(sc, 0x10, 0x9b);
2921 usbd_delay_ms(sc->sc_udev, 1);
2922 urtw_8187_write_phy_ofdm(sc, 0x26, 0x90);
2923 usbd_delay_ms(sc->sc_udev, 1);
2924
2925 /* TX ant A, 0x0 for B */
2926 error = urtw_8185_tx_antenna(sc, 0x3);
2927 if (error)
2928 goto fail;
2929 urtw_write32_m(sc, 0x94, 0x3dc00002);
2930
2931 error = urtw_8225_rf_set_chan(rf, 1);
2932fail:
2933 return error;
2934}
2935
2936usbd_status
2937urtw_8225_rf_set_chan(struct urtw_rf *rf, int chan)
2938{
2939 struct urtw_softc *sc = rf->rf_sc;
2940 struct ieee80211com *ic = &sc->sc_ic;
2941 struct ieee80211_channel *c = ic->ic_ibss_chan;
2942 usbd_status error;
2943
2944 error = urtw_8225_set_txpwrlvl(sc, chan);
2945 if (error)
2946 goto fail;
2947 urtw_8225_write(sc, 0x7, urtw_8225_channel[chan]);
2948 usbd_delay_ms(sc->sc_udev, 10);
2949
2950 urtw_write8_m(sc, URTW_SIFS, 0x22);
2951
2952 if (sc->sc_state == IEEE80211_S_ASSOC &&
2953 ic->ic_flags & IEEE80211_F_SHSLOT)
2954 urtw_write8_m(sc, URTW_SLOT, 0x9);
2955 else
2956 urtw_write8_m(sc, URTW_SLOT, 0x14);
2957
2958 if (IEEE80211_IS_CHAN_G(c)) {
2959 urtw_write8_m(sc, URTW_DIFS, 0x14);
2960 urtw_write8_m(sc, URTW_8187_EIFS, 0x5b - 0x14);
2961 urtw_write8_m(sc, URTW_CW_VAL, 0x73);
2962 } else {
2963 urtw_write8_m(sc, URTW_DIFS, 0x24);
2964 urtw_write8_m(sc, URTW_8187_EIFS, 0x5b - 0x24);
2965 urtw_write8_m(sc, URTW_CW_VAL, 0xa5);
2966 }
2967
2968fail:
2969 return error;
2970}
2971
2972usbd_status
2973urtw_8225_rf_set_sens(struct urtw_rf *rf)
2974{
2975 struct urtw_softc *sc = rf->rf_sc;
2976 usbd_status error;
2977
2978 if (rf->sens > 6)
2979 return -1;
2980
2981 if (rf->sens > 4)
2982 urtw_8225_write(sc, 0x0c, 0x850);
2983 else
2984 urtw_8225_write(sc, 0x0c, 0x50);
2985
2986 rf->sens = 6 - rf->sens;
2987 error = urtw_8225_setgain(sc, rf->sens);
2988 if (error)
2989 goto fail;
2990
2991 urtw_8187_write_phy_cck(sc, 0x41, urtw_8225_threshold[rf->sens]);
2992
2993fail:
2994 return error;
2995}
2996
2997void
2998urtw_stop(struct ifnet *ifp, int disable)
2999{
3000 struct urtw_softc *sc = ifp->if_softc;
3001 struct ieee80211com *ic = &sc->sc_ic;
3002 uint8_t data;
3003 usbd_status error;
3004
3005 ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
3006
3007 sc->sc_txtimer = 0;
3008 ifp->if_timer = 0;
3009 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
3010
3011 callout_stop(&sc->scan_to);
3012 callout_stop(&sc->sc_led_ch);
3013
3014 urtw_intr_disable(sc);
3015 urtw_read8_m(sc, URTW_CMD, &data);
3016 data &= ~URTW_CMD_TX_ENABLE;
3017 data &= ~URTW_CMD_RX_ENABLE;
3018 urtw_write8_m(sc, URTW_CMD, data);
3019
3020 if (sc->sc_rxpipe != NULL)
3021 usbd_abort_pipe(sc->sc_rxpipe);
3022 if (sc->sc_txpipe_low != NULL)
3023 usbd_abort_pipe(sc->sc_txpipe_low);
3024 if (sc->sc_txpipe_normal != NULL)
3025 usbd_abort_pipe(sc->sc_txpipe_normal);
3026
3027fail:
3028 return;
3029}
3030
3031int
3032urtw_isbmode(uint16_t rate)
3033{
3034 rate = urtw_rtl2rate(rate);
3035
3036 return ((rate <= 22 && rate != 12 && rate != 18) ||
3037 rate == 44) ? 1 : 0;
3038}
3039
3040void
3041urtw_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
3042{
3043 struct urtw_rx_data *data = priv;
3044 struct urtw_softc *sc = data->sc;
3045 struct ieee80211com *ic = &sc->sc_ic;
3046 struct ifnet *ifp = ic->ic_ifp;
3047 struct ieee80211_frame *wh;
3048 struct ieee80211_node *ni;
3049 struct mbuf *m, *mnew;
3050 uint8_t *desc, quality, rate;
3051 int actlen, flen, len, rssi, s;
3052
3053 if (status != USBD_NORMAL_COMPLETION) {
3054 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
3055 return;
3056
3057 if (status == USBD_STALLED)
3058 usbd_clear_endpoint_stall_async(sc->sc_rxpipe);
3059 ifp->if_ierrors++;
3060 goto skip;
3061 }
3062
3063 usbd_get_xfer_status(xfer, NULL, NULL, &actlen, NULL);
3064 if (actlen < URTW_MIN_RXBUFSZ) {
3065 ifp->if_ierrors++;
3066 goto skip;
3067 }
3068
3069 if (sc->sc_hwrev & URTW_HWREV_8187)
3070 /* 4 dword and 4 byte CRC */
3071 len = actlen - (4 * 4);
3072 else
3073 /* 5 dword and 4 byte CRC */
3074 len = actlen - (4 * 5);
3075
3076 desc = data->buf + len;
3077 flen = ((desc[1] & 0x0f) << 8) + (desc[0] & 0xff);
3078 if (flen > actlen) {
3079 ifp->if_ierrors++;
3080 goto skip;
3081 }
3082
3083 rate = (desc[2] & 0xf0) >> 4;
3084 if (sc->sc_hwrev & URTW_HWREV_8187) {
3085 quality = desc[4] & 0xff;
3086 rssi = (desc[6] & 0xfe) >> 1;
3087
3088 /* XXX correct? */
3089 if (!urtw_isbmode(rate)) {
3090 rssi = (rssi > 90) ? 90 : ((rssi < 25) ? 25 : rssi);
3091 rssi = ((90 - rssi) * 100) / 65;
3092 } else {
3093 rssi = (rssi > 90) ? 95 : ((rssi < 30) ? 30 : rssi);
3094 rssi = ((95 - rssi) * 100) / 65;
3095 }
3096 } else {
3097 quality = desc[12];
3098 rssi = 14 - desc[14] / 2;
3099 }
3100
3101 MGETHDR(mnew, M_DONTWAIT, MT_DATA);
3102 if (mnew == NULL) {
3103 printf("%s: could not allocate rx mbuf\n",
3104 device_xname(sc->sc_dev));
3105 ifp->if_ierrors++;
3106 goto skip;
3107 }
3108 MCLGET(mnew, M_DONTWAIT);
3109 if (!(mnew->m_flags & M_EXT)) {
3110 printf("%s: could not allocate rx mbuf cluster\n",
3111 device_xname(sc->sc_dev));
3112 m_freem(mnew);
3113 ifp->if_ierrors++;
3114 goto skip;
3115 }
3116
3117 m = data->m;
3118 data->m = mnew;
3119 data->buf = mtod(mnew, uint8_t *);
3120
3121 /* finalize mbuf */
3122 m_set_rcvif(m, ifp);
3123 m->m_pkthdr.len = m->m_len = flen - 4;
3124
3125 s = splnet();
3126
3127 if (sc->sc_drvbpf != NULL) {
3128 struct urtw_rx_radiotap_header *tap = &sc->sc_rxtap;
3129
3130 /* XXX Are variables correct? */
3131 tap->wr_chan_freq = htole16(ic->ic_ibss_chan->ic_freq);
3132 tap->wr_chan_flags = htole16(ic->ic_ibss_chan->ic_flags);
3133 tap->wr_dbm_antsignal = (int8_t)rssi;
3134
3135 bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m);
3136 }
3137 wh = mtod(m, struct ieee80211_frame *);
3138 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_DATA)
3139 sc->sc_currate = (rate > 0) ? rate : sc->sc_currate;
3140 ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh);
3141
3142 /* XXX correct? */
3143 if (!urtw_isbmode(rate)) {
3144 if (quality > 127)
3145 quality = 0;
3146 else if (quality < 27)
3147 quality = 100;
3148 else
3149 quality = 127 - quality;
3150 } else
3151 quality = (quality > 64) ? 0 : ((64 - quality) * 100) / 64;
3152
3153 /* send the frame to the 802.11 layer */
3154 ieee80211_input(ic, m, ni, rssi, 0);
3155
3156 /* node is no longer needed */
3157 ieee80211_free_node(ni);
3158
3159 splx(s);
3160
3161skip: /* setup a new transfer */
3162 usbd_setup_xfer(xfer, data, data->buf, MCLBYTES,
3163 USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, urtw_rxeof);
3164 (void)usbd_transfer(xfer);
3165}
3166
3167usbd_status
3168urtw_8225v2_setgain(struct urtw_softc *sc, int16_t gain)
3169{
3170 uint8_t *gainp;
3171 usbd_status error;
3172
3173 /* XXX for A? */
3174 gainp = urtw_8225v2_gain_bg;
3175 urtw_8187_write_phy_ofdm(sc, 0x0d, gainp[gain * 3]);
3176 usbd_delay_ms(sc->sc_udev, 1);
3177 urtw_8187_write_phy_ofdm(sc, 0x1b, gainp[gain * 3 + 1]);
3178 usbd_delay_ms(sc->sc_udev, 1);
3179 urtw_8187_write_phy_ofdm(sc, 0x1d, gainp[gain * 3 + 2]);
3180 usbd_delay_ms(sc->sc_udev, 1);
3181 urtw_8187_write_phy_ofdm(sc, 0x21, 0x17);
3182 usbd_delay_ms(sc->sc_udev, 1);
3183fail:
3184 return error;
3185}
3186
3187usbd_status
3188urtw_8225v2_set_txpwrlvl(struct urtw_softc *sc, int chan)
3189{
3190 int i;
3191 uint8_t *cck_pwrtable;
3192 uint8_t cck_pwrlvl_max = 15, ofdm_pwrlvl_max = 25, ofdm_pwrlvl_min = 10;
3193 uint8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
3194 uint8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
3195 usbd_status error;
3196
3197 /* CCK power setting */
3198 cck_pwrlvl = (cck_pwrlvl > cck_pwrlvl_max) ? cck_pwrlvl_max : cck_pwrlvl;
3199 cck_pwrlvl += sc->sc_txpwr_cck_base;
3200 cck_pwrlvl = (cck_pwrlvl > 35) ? 35 : cck_pwrlvl;
3201 cck_pwrtable = (chan == 14) ? urtw_8225v2_txpwr_cck_ch14 :
3202 urtw_8225v2_txpwr_cck;
3203
3204 for (i = 0; i < 8; i++) {
3205 urtw_8187_write_phy_cck(sc, 0x44 + i, cck_pwrtable[i]);
3206 }
3207 urtw_write8_m(sc, URTW_TX_GAIN_CCK,
3208 urtw_8225v2_tx_gain_cck_ofdm[cck_pwrlvl]);
3209 usbd_delay_ms(sc->sc_udev, 1);
3210
3211 /* OFDM power setting */
3212 ofdm_pwrlvl = (ofdm_pwrlvl > (ofdm_pwrlvl_max - ofdm_pwrlvl_min)) ?
3213 ofdm_pwrlvl_max : ofdm_pwrlvl + ofdm_pwrlvl_min;
3214 ofdm_pwrlvl += sc->sc_txpwr_ofdm_base;
3215 ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
3216
3217 error = urtw_8185_set_anaparam2(sc, URTW_8187_8225_ANAPARAM2_ON);
3218 if (error)
3219 goto fail;
3220
3221 urtw_8187_write_phy_ofdm(sc, 2, 0x42);
3222 urtw_8187_write_phy_ofdm(sc, 5, 0x0);
3223 urtw_8187_write_phy_ofdm(sc, 6, 0x40);
3224 urtw_8187_write_phy_ofdm(sc, 7, 0x0);
3225 urtw_8187_write_phy_ofdm(sc, 8, 0x40);
3226
3227 urtw_write8_m(sc, URTW_TX_GAIN_OFDM,
3228 urtw_8225v2_tx_gain_cck_ofdm[ofdm_pwrlvl]);
3229 usbd_delay_ms(sc->sc_udev, 1);
3230fail:
3231 return error;
3232}
3233
3234usbd_status
3235urtw_8225v2_rf_init(struct urtw_rf *rf)
3236{
3237 struct urtw_softc *sc = rf->rf_sc;
3238 int i;
3239 uint16_t data;
3240 uint32_t data32;
3241 usbd_status error;
3242
3243 error = urtw_8180_set_anaparam(sc, URTW_8187_8225_ANAPARAM_ON);
3244 if (error)
3245 goto fail;
3246
3247 error = urtw_8225_usb_init(sc);
3248 if (error)
3249 goto fail;
3250
3251 urtw_write32_m(sc, URTW_RF_TIMING, 0x000a8008);
3252 urtw_read16_m(sc, URTW_8187_BRSR, &data); /* XXX ??? */
3253 urtw_write16_m(sc, URTW_8187_BRSR, 0xffff);
3254 urtw_write32_m(sc, URTW_RF_PARA, 0x100044);
3255
3256 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3257 if (error)
3258 goto fail;
3259 urtw_write8_m(sc, URTW_CONFIG3, 0x44);
3260 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3261 if (error)
3262 goto fail;
3263
3264 error = urtw_8185_rf_pins_enable(sc);
3265 if (error)
3266 goto fail;
3267
3268 usbd_delay_ms(sc->sc_udev, 1000);
3269
3270 for (i = 0; i < __arraycount(urtw_8225v2_rf_part1); i++) {
3271 urtw_8225_write(sc, urtw_8225v2_rf_part1[i].reg,
3272 urtw_8225v2_rf_part1[i].val);
3273 usbd_delay_ms(sc->sc_udev, 1);
3274 }
3275 usbd_delay_ms(sc->sc_udev, 50);
3276
3277 urtw_8225_write(sc, 0x0, 0x1b7);
3278
3279 for (i = 0; i < __arraycount(urtw_8225v2_rxgain); i++) {
3280 urtw_8225_write(sc, 0x1, (uint8_t)(i + 1));
3281 urtw_8225_write(sc, 0x2, urtw_8225v2_rxgain[i]);
3282 }
3283
3284 urtw_8225_write(sc, 0x3, 0x2);
3285 urtw_8225_write(sc, 0x5, 0x4);
3286 urtw_8225_write(sc, 0x0, 0xb7);
3287 urtw_8225_write(sc, 0x2, 0xc4d);
3288 usbd_delay_ms(sc->sc_udev, 100);
3289 urtw_8225_write(sc, 0x2, 0x44d);
3290 usbd_delay_ms(sc->sc_udev, 100);
3291
3292 error = urtw_8225_read(sc, 0x6, &data32);
3293 if (error != 0)
3294 goto fail;
3295 if (data32 != 0xe6)
3296 printf("%s: expect 0xe6!! (0x%x)\n", device_xname(sc->sc_dev),
3297 data32);
3298 if (!(data32 & 0x80)) {
3299 urtw_8225_write(sc, 0x02, 0x0c4d);
3300 usbd_delay_ms(sc->sc_udev, 200);
3301 urtw_8225_write(sc, 0x02, 0x044d);
3302 usbd_delay_ms(sc->sc_udev, 100);
3303 error = urtw_8225_read(sc, 0x6, &data32);
3304 if (error != 0)
3305 goto fail;
3306 if (!(data32 & 0x80))
3307 printf("%s: RF calibration failed\n",
3308 device_xname(sc->sc_dev));
3309 }
3310 usbd_delay_ms(sc->sc_udev, 100);
3311
3312 urtw_8225_write(sc, 0x0, 0x2bf);
3313 for (i = 0; i < __arraycount(urtw_8225_agc); i++) {
3314 urtw_8187_write_phy_ofdm(sc, 0xb, urtw_8225_agc[i]);
3315 urtw_8187_write_phy_ofdm(sc, 0xa, (uint8_t)i + 0x80);
3316 }
3317
3318 for (i = 0; i < __arraycount(urtw_8225v2_rf_part2); i++) {
3319 urtw_8187_write_phy_ofdm(sc, urtw_8225v2_rf_part2[i].reg,
3320 urtw_8225v2_rf_part2[i].val);
3321 }
3322
3323 error = urtw_8225v2_setgain(sc, 4);
3324 if (error)
3325 goto fail;
3326
3327 for (i = 0; i < __arraycount(urtw_8225v2_rf_part3); i++) {
3328 urtw_8187_write_phy_cck(sc, urtw_8225v2_rf_part3[i].reg,
3329 urtw_8225v2_rf_part3[i].val);
3330 }
3331
3332 urtw_write8_m(sc, 0x5b, 0x0d);
3333
3334 error = urtw_8225v2_set_txpwrlvl(sc, 1);
3335 if (error)
3336 goto fail;
3337
3338 urtw_8187_write_phy_cck(sc, 0x10, 0x9b);
3339 urtw_8187_write_phy_ofdm(sc, 0x26, 0x90);
3340
3341 /* TX ant A, 0x0 for B */
3342 error = urtw_8185_tx_antenna(sc, 0x3);
3343 if (error)
3344 goto fail;
3345 urtw_write32_m(sc, 0x94, 0x3dc00002);
3346
3347 error = urtw_8225_rf_set_chan(rf, 1);
3348fail:
3349 return error;
3350}
3351
3352usbd_status
3353urtw_8225v2_rf_set_chan(struct urtw_rf *rf, int chan)
3354{
3355 struct urtw_softc *sc = rf->rf_sc;
3356 struct ieee80211com *ic = &sc->sc_ic;
3357 struct ieee80211_channel *c = ic->ic_ibss_chan;
3358 usbd_status error;
3359
3360 error = urtw_8225v2_set_txpwrlvl(sc, chan);
3361 if (error)
3362 goto fail;
3363
3364 urtw_8225_write(sc, 0x7, urtw_8225_channel[chan]);
3365 usbd_delay_ms(sc->sc_udev, 10);
3366
3367 urtw_write8_m(sc, URTW_SIFS, 0x22);
3368
3369 if(sc->sc_state == IEEE80211_S_ASSOC &&
3370 ic->ic_flags & IEEE80211_F_SHSLOT)
3371 urtw_write8_m(sc, URTW_SLOT, 0x9);
3372 else
3373 urtw_write8_m(sc, URTW_SLOT, 0x14);
3374
3375 if (IEEE80211_IS_CHAN_G(c)) {
3376 urtw_write8_m(sc, URTW_DIFS, 0x14);
3377 urtw_write8_m(sc, URTW_8187_EIFS, 0x5b - 0x14);
3378 urtw_write8_m(sc, URTW_CW_VAL, 0x73);
3379 } else {
3380 urtw_write8_m(sc, URTW_DIFS, 0x24);
3381 urtw_write8_m(sc, URTW_8187_EIFS, 0x5b - 0x24);
3382 urtw_write8_m(sc, URTW_CW_VAL, 0xa5);
3383 }
3384
3385fail:
3386 return error;
3387}
3388
3389void
3390urtw_set_chan(struct urtw_softc *sc, struct ieee80211_channel *c)
3391{
3392 struct urtw_rf *rf = &sc->sc_rf;
3393 struct ieee80211com *ic = &sc->sc_ic;
3394 usbd_status error = 0;
3395 uint32_t data;
3396 u_int chan;
3397
3398 chan = ieee80211_chan2ieee(ic, c);
3399 if (chan == 0 || chan == IEEE80211_CHAN_ANY)
3400 return;
3401 /*
3402 * During changing the channel we need to temporary disable
3403 * TX.
3404 */
3405 urtw_read32_m(sc, URTW_TX_CONF, &data);
3406 data &= ~URTW_TX_LOOPBACK_MASK;
3407 urtw_write32_m(sc, URTW_TX_CONF, data | URTW_TX_LOOPBACK_MAC);
3408 error = rf->set_chan(rf, chan);
3409 if (error != 0) {
3410 printf("%s could not change the channel\n",
3411 device_xname(sc->sc_dev));
3412 return;
3413 }
3414 usbd_delay_ms(sc->sc_udev, 10);
3415 urtw_write32_m(sc, URTW_TX_CONF, data | URTW_TX_LOOPBACK_NONE);
3416
3417fail: return;
3418
3419}
3420
3421void
3422urtw_next_scan(void *arg)
3423{
3424 struct urtw_softc *sc = arg;
3425 struct ieee80211com *ic = &sc->sc_ic;
3426 int s;
3427
3428 if (sc->sc_dying)
3429 return;
3430
3431 s = splnet();
3432 if (ic->ic_state == IEEE80211_S_SCAN)
3433 ieee80211_next_scan(ic);
3434 splx(s);
3435}
3436
3437void
3438urtw_task(void *arg)
3439{
3440 struct urtw_softc *sc = arg;
3441 struct ieee80211com *ic = &sc->sc_ic;
3442 struct ieee80211_node *ni;
3443 enum ieee80211_state ostate;
3444 usbd_status error = 0;
3445
3446 if (sc->sc_dying)
3447 return;
3448
3449 ostate = ic->ic_state;
3450
3451 switch (sc->sc_state) {
3452 case IEEE80211_S_INIT:
3453 if (ostate == IEEE80211_S_RUN) {
3454 /* turn link LED off */
3455 (void)urtw_led_off(sc, URTW_LED_GPIO);
3456 }
3457 break;
3458
3459 case IEEE80211_S_SCAN:
3460 urtw_set_chan(sc, ic->ic_curchan);
3461 if (!sc->sc_dying)
3462 callout_schedule(&sc->scan_to, mstohz(200));
3463 break;
3464
3465 case IEEE80211_S_AUTH:
3466 case IEEE80211_S_ASSOC:
3467 urtw_set_chan(sc, ic->ic_curchan);
3468 break;
3469
3470 case IEEE80211_S_RUN:
3471 ni = ic->ic_bss;
3472
3473 urtw_set_chan(sc, ic->ic_curchan);
3474
3475 /* setting bssid. */
3476 error = urtw_set_bssid(sc, ni->ni_bssid);
3477 if (error != 0)
3478 goto fail;
3479 urtw_update_msr(sc);
3480 /* XXX maybe the below would be incorrect. */
3481 urtw_write16_m(sc, URTW_ATIM_WND, 2);
3482 urtw_write16_m(sc, URTW_ATIM_TR_ITV, 100);
3483 urtw_write16_m(sc, URTW_BEACON_INTERVAL, 0x64);
3484 urtw_write16_m(sc, URTW_BEACON_INTERVAL_TIME, 0x3ff);
3485 error = urtw_led_ctl(sc, URTW_LED_CTL_LINK);
3486 if (error != 0)
3487 printf("%s: could not control LED (%d)\n",
3488 device_xname(sc->sc_dev), error);
3489 break;
3490 }
3491
3492 sc->sc_newstate(ic, sc->sc_state, sc->sc_arg);
3493
3494fail:
3495 if (error != 0) {
3496 DPRINTF(("%s: error duing processing RUN state.",
3497 device_xname(sc->sc_dev)));
3498 }
3499}
3500
3501usbd_status
3502urtw_8187b_update_wmm(struct urtw_softc *sc)
3503{
3504 struct ieee80211com *ic = &sc->sc_ic;
3505 struct ieee80211_channel *c = ic->ic_ibss_chan;
3506 uint32_t data;
3507 uint8_t aifs, sifs, slot, ecwmin, ecwmax;
3508 usbd_status error;
3509
3510 sifs = 0xa;
3511 if (IEEE80211_IS_CHAN_G(c))
3512 slot = 0x9;
3513 else
3514 slot = 0x14;
3515
3516 aifs = (2 * slot) + sifs;
3517 ecwmin = 3;
3518 ecwmax = 7;
3519
3520 data = ((uint32_t)aifs << 0) | /* AIFS, offset 0 */
3521 ((uint32_t)ecwmin << 8) | /* ECW minimum, offset 8 */
3522 ((uint32_t)ecwmax << 12); /* ECW maximum, offset 16 */
3523
3524 urtw_write32_m(sc, URTW_AC_VO, data);
3525 urtw_write32_m(sc, URTW_AC_VI, data);
3526 urtw_write32_m(sc, URTW_AC_BE, data);
3527 urtw_write32_m(sc, URTW_AC_BK, data);
3528
3529fail:
3530 return error;
3531}
3532
3533usbd_status
3534urtw_8187b_reset(struct urtw_softc *sc)
3535{
3536 uint8_t data;
3537 usbd_status error;
3538
3539 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3540 if (error)
3541 goto fail;
3542
3543 urtw_read8_m(sc, URTW_CONFIG3, &data);
3544 urtw_write8_m(sc, URTW_CONFIG3, data | URTW_CONFIG3_ANAPARAM_WRITE |
3545 URTW_CONFIG3_GNT_SELECT);
3546
3547 urtw_write32_m(sc, URTW_ANAPARAM2, URTW_8187B_8225_ANAPARAM2_ON);
3548 urtw_write32_m(sc, URTW_ANAPARAM, URTW_8187B_8225_ANAPARAM_ON);
3549 urtw_write8_m(sc, URTW_ANAPARAM3, URTW_8187B_8225_ANAPARAM3_ON);
3550
3551 urtw_write8_m(sc, 0x61, 0x10);
3552 urtw_read8_m(sc, 0x62, &data);
3553 urtw_write8_m(sc, 0x62, data & ~(1 << 5));
3554 urtw_write8_m(sc, 0x62, data | (1 << 5));
3555
3556 urtw_read8_m(sc, URTW_CONFIG3, &data);
3557 urtw_write8_m(sc, URTW_CONFIG3, data & ~URTW_CONFIG3_ANAPARAM_WRITE);
3558
3559 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3560 if (error)
3561 goto fail;
3562
3563 urtw_read8_m(sc, URTW_CMD, &data);
3564 data = (data & 2) | URTW_CMD_RST;
3565 urtw_write8_m(sc, URTW_CMD, data);
3566 usbd_delay_ms(sc->sc_udev, 100);
3567
3568 urtw_read8_m(sc, URTW_CMD, &data);
3569 if (data & URTW_CMD_RST) {
3570 printf("%s: reset timeout\n", device_xname(sc->sc_dev));
3571 goto fail;
3572 }
3573
3574fail:
3575 return error;
3576}
3577
3578int
3579urtw_8187b_init(struct ifnet *ifp)
3580{
3581 struct urtw_softc *sc = ifp->if_softc;
3582 struct urtw_rf *rf = &sc->sc_rf;
3583 struct ieee80211com *ic = &sc->sc_ic;
3584 uint8_t data;
3585 usbd_status error;
3586
3587 urtw_stop(ifp, 0);
3588
3589 error = urtw_8187b_update_wmm(sc);
3590 if (error != 0)
3591 goto fail;
3592 error = urtw_8187b_reset(sc);
3593 if (error)
3594 goto fail;
3595
3596 /* Applying MAC address again. */
3597 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3598 if (error)
3599 goto fail;
3600 IEEE80211_ADDR_COPY(ic->ic_myaddr, CLLADDR(ifp->if_sadl));
3601 error = urtw_set_macaddr(sc, ic->ic_myaddr);
3602 if (error)
3603 goto fail;
3604 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3605 if (error)
3606 goto fail;
3607
3608 error = urtw_update_msr(sc);
3609 if (error)
3610 goto fail;
3611
3612 error = rf->init(rf);
3613 if (error != 0)
3614 goto fail;
3615
3616 urtw_write8_m(sc, URTW_CMD, URTW_CMD_TX_ENABLE |
3617 URTW_CMD_RX_ENABLE);
3618 error = urtw_intr_enable(sc);
3619 if (error != 0)
3620 goto fail;
3621
3622 error = urtw_write8e(sc, 0x41, 0xf4);
3623 if (error != 0)
3624 goto fail;
3625 error = urtw_write8e(sc, 0x40, 0x00);
3626 if (error != 0)
3627 goto fail;
3628 error = urtw_write8e(sc, 0x42, 0x00);
3629 if (error != 0)
3630 goto fail;
3631 error = urtw_write8e(sc, 0x42, 0x01);
3632 if (error != 0)
3633 goto fail;
3634 error = urtw_write8e(sc, 0x40, 0x0f);
3635 if (error != 0)
3636 goto fail;
3637 error = urtw_write8e(sc, 0x42, 0x00);
3638 if (error != 0)
3639 goto fail;
3640 error = urtw_write8e(sc, 0x42, 0x01);
3641 if (error != 0)
3642 goto fail;
3643
3644 urtw_read8_m(sc, 0xdb, &data);
3645 urtw_write8_m(sc, 0xdb, data | (1 << 2));
3646 urtw_write16_idx_m(sc, 0x72, 0x59fa, 3);
3647 urtw_write16_idx_m(sc, 0x74, 0x59d2, 3);
3648 urtw_write16_idx_m(sc, 0x76, 0x59d2, 3);
3649 urtw_write16_idx_m(sc, 0x78, 0x19fa, 3);
3650 urtw_write16_idx_m(sc, 0x7a, 0x19fa, 3);
3651 urtw_write16_idx_m(sc, 0x7c, 0x00d0, 3);
3652 urtw_write8_m(sc, 0x61, 0);
3653 urtw_write8_idx_m(sc, 0x80, 0x0f, 1);
3654 urtw_write8_idx_m(sc, 0x83, 0x03, 1);
3655 urtw_write8_m(sc, 0xda, 0x10);
3656 urtw_write8_idx_m(sc, 0x4d, 0x08, 2);
3657
3658 urtw_write32_m(sc, URTW_HSSI_PARA, 0x0600321b);
3659
3660 urtw_write16_idx_m(sc, 0xec, 0x0800, 1);
3661
3662 urtw_write8_m(sc, URTW_ACM_CONTROL, 0);
3663
3664 /* Reset softc variables. */
3665 for (size_t j = 0; j < URTW_PRIORITY_MAX; j++) {
3666 sc->sc_txidx[j] = sc->sc_tx_queued[j] = 0;
3667 }
3668 sc->sc_txtimer = 0;
3669
3670 if (!(sc->sc_flags & URTW_INIT_ONCE)) {
3671 error = usbd_set_config_no(sc->sc_udev, URTW_CONFIG_NO, 0);
3672 if (error != 0) {
3673 aprint_error_dev(sc->sc_dev, "failed to set configuration"
3674 ", err=%s\n", usbd_errstr(error));
3675
3676 goto fail;
3677 }
3678 /* Get the first interface handle. */
3679 error = usbd_device2interface_handle(sc->sc_udev,
3680 URTW_IFACE_INDEX, &sc->sc_iface);
3681 if (error != 0) {
3682 printf("%s: could not get interface handle\n",
3683 device_xname(sc->sc_dev));
3684 goto fail;
3685 }
3686 error = urtw_open_pipes(sc);
3687 if (error != 0)
3688 goto fail;
3689 error = urtw_alloc_rx_data_list(sc);
3690 if (error != 0)
3691 goto fail;
3692 error = urtw_alloc_tx_data_list(sc);
3693 if (error != 0)
3694 goto fail;
3695 sc->sc_flags |= URTW_INIT_ONCE;
3696 }
3697
3698 error = urtw_rx_enable(sc);
3699 if (error != 0)
3700 goto fail;
3701 error = urtw_tx_enable(sc);
3702 if (error != 0)
3703 goto fail;
3704
3705 ifp->if_flags &= ~IFF_OACTIVE;
3706 ifp->if_flags |= IFF_RUNNING;
3707
3708 if (ic->ic_opmode == IEEE80211_M_MONITOR)
3709 ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
3710 else
3711 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
3712
3713fail:
3714 return error;
3715}
3716
3717usbd_status
3718urtw_8225v2_b_config_mac(struct urtw_softc *sc)
3719{
3720 int i;
3721 usbd_status error;
3722
3723 for (i = 0; i < __arraycount(urtw_8187b_regtbl); i++) {
3724 urtw_write8_idx_m(sc, urtw_8187b_regtbl[i].reg,
3725 urtw_8187b_regtbl[i].val, urtw_8187b_regtbl[i].idx);
3726 }
3727
3728 urtw_write16_m(sc, URTW_TID_AC_MAP, 0xfa50);
3729 urtw_write16_m(sc, URTW_INT_MIG, 0);
3730
3731 urtw_write32_idx_m(sc, 0xf0, 0, 1);
3732 urtw_write32_idx_m(sc, 0xf4, 0, 1);
3733 urtw_write8_idx_m(sc, 0xf8, 0, 1);
3734
3735 urtw_write32_m(sc, URTW_RF_TIMING, 0x00004001);
3736
3737fail:
3738 return error;
3739}
3740
3741usbd_status
3742urtw_8225v2_b_init_rfe(struct urtw_softc *sc)
3743{
3744 usbd_status error;
3745
3746 urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, 0x0480);
3747 urtw_write16_m(sc, URTW_RF_PINS_SELECT, 0x2488);
3748 urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x1fff);
3749 usbd_delay_ms(sc->sc_udev, 100);
3750
3751fail:
3752 return error;
3753}
3754
3755usbd_status
3756urtw_8225v2_b_update_chan(struct urtw_softc *sc)
3757{
3758 struct ieee80211com *ic = &sc->sc_ic;
3759 struct ieee80211_channel *c = ic->ic_ibss_chan;
3760 uint8_t aifs, difs, eifs, sifs, slot;
3761 usbd_status error;
3762
3763 urtw_write8_m(sc, URTW_SIFS, 0x22);
3764
3765 sifs = 0xa;
3766 if (IEEE80211_IS_CHAN_G(c)) {
3767 slot = 0x9;
3768 difs = 0x1c;
3769 eifs = 0x5b;
3770 } else {
3771 slot = 0x14;
3772 difs = 0x32;
3773 eifs = 0x5b;
3774 }
3775 aifs = (2 * slot) + sifs;
3776
3777 urtw_write8_m(sc, URTW_SLOT, slot);
3778
3779 urtw_write8_m(sc, URTW_AC_VO, aifs);
3780 urtw_write8_m(sc, URTW_AC_VI, aifs);
3781 urtw_write8_m(sc, URTW_AC_BE, aifs);
3782 urtw_write8_m(sc, URTW_AC_BK, aifs);
3783
3784 urtw_write8_m(sc, URTW_DIFS, difs);
3785 urtw_write8_m(sc, URTW_8187B_EIFS, eifs);
3786
3787fail:
3788 return error;
3789}
3790
3791usbd_status
3792urtw_8225v2_b_rf_init(struct urtw_rf *rf)
3793{
3794 struct urtw_softc *sc = rf->rf_sc;
3795 unsigned int i;
3796 uint8_t data;
3797 usbd_status error;
3798
3799 /* Set up ACK rate, retry limit, TX AGC, TX antenna. */
3800 urtw_write16_m(sc, URTW_8187B_BRSR, 0x0fff);
3801 urtw_read8_m(sc, URTW_CW_CONF, &data);
3802 urtw_write8_m(sc, URTW_CW_CONF, data |
3803 URTW_CW_CONF_PERPACKET_RETRY);
3804 urtw_read8_m(sc, URTW_TX_AGC_CTL, &data);
3805 urtw_write8_m(sc, URTW_TX_AGC_CTL, data |
3806 URTW_TX_AGC_CTL_PERPACKET_GAIN |
3807 URTW_TX_AGC_CTL_PERPACKET_ANTSEL);
3808
3809 /* Auto rate fallback control. */
3810 urtw_write16_idx_m(sc, URTW_ARFR, 0x0fff, 1); /* 1M ~ 54M */
3811 urtw_read8_m(sc, URTW_RATE_FALLBACK, &data);
3812 urtw_write8_m(sc, URTW_RATE_FALLBACK, data |
3813 URTW_RATE_FALLBACK_ENABLE);
3814
3815 urtw_write16_m(sc, URTW_BEACON_INTERVAL, 100);
3816 urtw_write16_m(sc, URTW_ATIM_WND, 2);
3817 urtw_write16_idx_m(sc, URTW_FEMR, 0xffff, 1);
3818
3819 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3820 if (error)
3821 goto fail;
3822 urtw_read8_m(sc, URTW_CONFIG1, &data);
3823 urtw_write8_m(sc, URTW_CONFIG1, (data & 0x3f) | 0x80);
3824 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3825 if (error)
3826 goto fail;
3827
3828 urtw_write8_m(sc, URTW_WPA_CONFIG, 0);
3829 urtw_8225v2_b_config_mac(sc);
3830 urtw_write16_idx_m(sc, URTW_RFSW_CTRL, 0x569a, 2);
3831
3832 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3833 if (error)
3834 goto fail;
3835 urtw_read8_m(sc, URTW_CONFIG3, &data);
3836 urtw_write8_m(sc, URTW_CONFIG3, data | URTW_CONFIG3_ANAPARAM_WRITE);
3837 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3838 if (error)
3839 goto fail;
3840
3841 urtw_8225v2_b_init_rfe(sc);
3842
3843 for (i = 0; i < __arraycount(urtw_8225v2_b_rf); i++) {
3844 urtw_8225_write(sc, urtw_8225v2_b_rf[i].reg,
3845 urtw_8225v2_b_rf[i].val);
3846 }
3847
3848 for (i = 0; i < __arraycount(urtw_8225v2_rxgain); i++) {
3849 urtw_8225_write(sc, 0x1, (uint8_t)(i + 1));
3850 urtw_8225_write(sc, 0x2, urtw_8225v2_rxgain[i]);
3851 }
3852
3853 urtw_8225_write(sc, 0x03, 0x080);
3854 urtw_8225_write(sc, 0x05, 0x004);
3855 urtw_8225_write(sc, 0x00, 0x0b7);
3856 urtw_8225_write(sc, 0x02, 0xc4d);
3857 urtw_8225_write(sc, 0x02, 0x44d);
3858 urtw_8225_write(sc, 0x00, 0x2bf);
3859
3860 urtw_write8_m(sc, URTW_TX_GAIN_CCK, 0x03);
3861 urtw_write8_m(sc, URTW_TX_GAIN_OFDM, 0x07);
3862 urtw_write8_m(sc, URTW_TX_ANTENNA, 0x03);
3863
3864 urtw_8187_write_phy_ofdm(sc, 0x80, 0x12);
3865 for (i = 0; i < __arraycount(urtw_8225v2_agc); i++) {
3866 urtw_8187_write_phy_ofdm(sc, 0x0f, urtw_8225v2_agc[i]);
3867 urtw_8187_write_phy_ofdm(sc, 0x0e, (uint8_t)i + 0x80);
3868 urtw_8187_write_phy_ofdm(sc, 0x0e, 0);
3869 }
3870 urtw_8187_write_phy_ofdm(sc, 0x80, 0x10);
3871
3872 for (i = 0; i < __arraycount(urtw_8225v2_ofdm); i++)
3873 urtw_8187_write_phy_ofdm(sc, i, urtw_8225v2_ofdm[i]);
3874
3875 urtw_8225v2_b_update_chan(sc);
3876
3877 urtw_8187_write_phy_ofdm(sc, 0x97, 0x46);
3878 urtw_8187_write_phy_ofdm(sc, 0xa4, 0xb6);
3879 urtw_8187_write_phy_ofdm(sc, 0x85, 0xfc);
3880 urtw_8187_write_phy_cck(sc, 0xc1, 0x88);
3881
3882 error = urtw_8225v2_b_rf_set_chan(rf, 1);
3883fail:
3884 return error;
3885}
3886
3887usbd_status
3888urtw_8225v2_b_rf_set_chan(struct urtw_rf *rf, int chan)
3889{
3890 struct urtw_softc *sc = rf->rf_sc;
3891 usbd_status error;
3892
3893 error = urtw_8225v2_b_set_txpwrlvl(sc, chan);
3894 if (error)
3895 goto fail;
3896
3897 urtw_8225_write(sc, 0x7, urtw_8225_channel[chan]);
3898 /*
3899 * Delay removed from 8185 to 8187.
3900 * usbd_delay_ms(sc->sc_udev, 10);
3901 */
3902
3903 urtw_write16_m(sc, URTW_AC_VO, 0x5114);
3904 urtw_write16_m(sc, URTW_AC_VI, 0x5114);
3905 urtw_write16_m(sc, URTW_AC_BE, 0x5114);
3906 urtw_write16_m(sc, URTW_AC_BK, 0x5114);
3907
3908fail:
3909 return error;
3910}
3911
3912usbd_status
3913urtw_8225v2_b_set_txpwrlvl(struct urtw_softc *sc, int chan)
3914{
3915 int i;
3916 uint8_t *cck_pwrtable;
3917 uint8_t cck_pwrlvl_min, cck_pwrlvl_max, ofdm_pwrlvl_min,
3918 ofdm_pwrlvl_max;
3919 int8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
3920 int8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
3921 usbd_status error;
3922
3923 if (sc->sc_hwrev & URTW_HWREV_8187B_B) {
3924 cck_pwrlvl_min = 0;
3925 cck_pwrlvl_max = 15;
3926 ofdm_pwrlvl_min = 2;
3927 ofdm_pwrlvl_max = 17;
3928 } else {
3929 cck_pwrlvl_min = 7;
3930 cck_pwrlvl_max = 22;
3931 ofdm_pwrlvl_min = 10;
3932 ofdm_pwrlvl_max = 25;
3933 }
3934
3935 /* CCK power setting */
3936 cck_pwrlvl = (cck_pwrlvl > (cck_pwrlvl_max - cck_pwrlvl_min)) ?
3937 cck_pwrlvl_max : (cck_pwrlvl + cck_pwrlvl_min);
3938
3939 cck_pwrlvl += sc->sc_txpwr_cck_base;
3940 cck_pwrlvl = (cck_pwrlvl > 35) ? 35 : cck_pwrlvl;
3941 cck_pwrlvl = (cck_pwrlvl < 0) ? 0 : cck_pwrlvl;
3942
3943 cck_pwrtable = (chan == 14) ? urtw_8225v2_txpwr_cck_ch14 :
3944 urtw_8225v2_txpwr_cck;
3945
3946 if (sc->sc_hwrev & URTW_HWREV_8187B_B) {
3947 if (cck_pwrlvl <= 6)
3948 ; /* do nothing */
3949 else if (cck_pwrlvl <= 11)
3950 cck_pwrtable += 8;
3951 else
3952 cck_pwrtable += 16;
3953 } else {
3954 if (cck_pwrlvl <= 5)
3955 ; /* do nothing */
3956 else if (cck_pwrlvl <= 11)
3957 cck_pwrtable += 8;
3958 else if (cck_pwrlvl <= 17)
3959 cck_pwrtable += 16;
3960 else
3961 cck_pwrtable += 24;
3962 }
3963
3964 for (i = 0; i < 8; i++) {
3965 urtw_8187_write_phy_cck(sc, 0x44 + i, cck_pwrtable[i]);
3966 }
3967
3968 urtw_write8_m(sc, URTW_TX_GAIN_CCK,
3969 urtw_8225v2_tx_gain_cck_ofdm[cck_pwrlvl] << 1);
3970 /*
3971 * Delay removed from 8185 to 8187.
3972 * usbd_delay_ms(sc->sc_udev, 1);
3973 */
3974
3975 /* OFDM power setting */
3976 ofdm_pwrlvl = (ofdm_pwrlvl > (ofdm_pwrlvl_max - ofdm_pwrlvl_min)) ?
3977 ofdm_pwrlvl_max : ofdm_pwrlvl + ofdm_pwrlvl_min;
3978
3979 ofdm_pwrlvl += sc->sc_txpwr_ofdm_base;
3980 ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
3981 ofdm_pwrlvl = (ofdm_pwrlvl < 0) ? 0 : ofdm_pwrlvl;
3982
3983 urtw_write8_m(sc, URTW_TX_GAIN_OFDM,
3984 urtw_8225v2_tx_gain_cck_ofdm[ofdm_pwrlvl] << 1);
3985
3986 if (sc->sc_hwrev & URTW_HWREV_8187B_B) {
3987 if (ofdm_pwrlvl <= 11) {
3988 urtw_8187_write_phy_ofdm(sc, 0x87, 0x60);
3989 urtw_8187_write_phy_ofdm(sc, 0x89, 0x60);
3990 } else {
3991 urtw_8187_write_phy_ofdm(sc, 0x87, 0x5c);
3992 urtw_8187_write_phy_ofdm(sc, 0x89, 0x5c);
3993 }
3994 } else {
3995 if (ofdm_pwrlvl <= 11) {
3996 urtw_8187_write_phy_ofdm(sc, 0x87, 0x5c);
3997 urtw_8187_write_phy_ofdm(sc, 0x89, 0x5c);
3998 } else if (ofdm_pwrlvl <= 17) {
3999 urtw_8187_write_phy_ofdm(sc, 0x87, 0x54);
4000 urtw_8187_write_phy_ofdm(sc, 0x89, 0x54);
4001 } else {
4002 urtw_8187_write_phy_ofdm(sc, 0x87, 0x50);
4003 urtw_8187_write_phy_ofdm(sc, 0x89, 0x50);
4004 }
4005 }
4006
4007 /*
4008 * Delay removed from 8185 to 8187.
4009 * usbd_delay_ms(sc->sc_udev, 1);
4010 */
4011fail:
4012 return error;
4013}
4014
4015int
4016urtw_set_bssid(struct urtw_softc *sc, const uint8_t *bssid)
4017{
4018 int error;
4019
4020 urtw_write32_m(sc, URTW_BSSID,
4021 bssid[0] | bssid[1] << 8 | bssid[2] << 16 | bssid[3] << 24);
4022 urtw_write16_m(sc, URTW_BSSID + 4,
4023 bssid[4] | bssid[5] << 8);
4024
4025 return 0;
4026
4027fail:
4028 return error;
4029}
4030
4031int
4032urtw_set_macaddr(struct urtw_softc *sc, const uint8_t *addr)
4033{
4034 int error;
4035
4036 urtw_write32_m(sc, URTW_MAC0,
4037 addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24);
4038 urtw_write16_m(sc, URTW_MAC4,
4039 addr[4] | addr[5] << 8);
4040
4041 return 0;
4042
4043fail:
4044 return error;
4045}
4046
4047MODULE(MODULE_CLASS_DRIVER, if_urtw, "bpf");
4048
4049#ifdef _MODULE
4050#include "ioconf.c"
4051#endif
4052
4053static int
4054if_urtw_modcmd(modcmd_t cmd, void *aux)
4055{
4056 int error = 0;
4057
4058 switch (cmd) {
4059 case MODULE_CMD_INIT:
4060#ifdef _MODULE
4061 error = config_init_component(cfdriver_ioconf_urtw,
4062 cfattach_ioconf_urtw, cfdata_ioconf_urtw);
4063#endif
4064 return error;
4065 case MODULE_CMD_FINI:
4066#ifdef _MODULE
4067 error = config_fini_component(cfdriver_ioconf_urtw,
4068 cfattach_ioconf_urtw, cfdata_ioconf_urtw);
4069#endif
4070 return error;
4071 default:
4072 return ENOTTY;
4073 }
4074}
4075