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