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