Bug Summary

File:dev/usb/if_urtw.c
Warning:line 1957, column 3
Value stored to 'error' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

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