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