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