Bug Summary

File:dev/usb/if_urtw.c
Warning:line 3157, column 2
Value stored to 'nf' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name if_urtw.c -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 -ffp-contract=on -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 -target-feature +retpoline-external-thunk -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/llvm16/lib/clang/16 -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/legacy-dpm -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc -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/swsmu/smu13 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/inc -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/pm/swsmu/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc/pmfw_if -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 SUSPEND -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 -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 -fcf-protection=branch -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 /home/ben/Projects/scan/2024-01-11-110808-61670-1 -x c /usr/src/sys/dev/usb/if_urtw.c
1/* $OpenBSD: if_urtw.c,v 1.72 2022/04/21 21:03:03 stsp 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(0x2);
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);
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(0x4);
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(0x4);
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(0x4);
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(0x4);
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;
Value stored to 'nf' is never read
3158
3159 /* send the frame to the 802.11 layer */
3160 memset(&rxi, 0, sizeof(rxi))__builtin_memset((&rxi), (0), (sizeof(rxi)));
3161 rxi.rxi_rssi = rssi;
3162 ieee80211_input(ifp, m, ni, &rxi);
3163
3164 /* node is no longer needed */
3165 ieee80211_release_node(ic, ni);
3166
3167 splx(s)spllower(s);
3168
3169skip: /* setup a new transfer */
3170 usbd_setup_xfer(xfer, sc->sc_rxpipe, data, data->buf, MCLBYTES(1 << 11),
3171 USBD_SHORT_XFER_OK0x04, USBD_NO_TIMEOUT0, urtw_rxeof);
3172 (void)usbd_transfer(xfer);
3173}
3174
3175usbd_status
3176urtw_8225v2_setgain(struct urtw_softc *sc, int16_t gain)
3177{
3178 uint8_t *gainp;
3179 usbd_status error;
3180
3181 /* XXX for A? */
3182 gainp = urtw_8225v2_gain_bg;
3183 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)
;
3184 usbd_delay_ms(sc->sc_udev, 1);
3185 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)
;
3186 usbd_delay_ms(sc->sc_udev, 1);
3187 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)
;
3188 usbd_delay_ms(sc->sc_udev, 1);
3189 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)
;
3190 usbd_delay_ms(sc->sc_udev, 1);
3191fail:
3192 return (error);
3193}
3194
3195usbd_status
3196urtw_8225v2_set_txpwrlvl(struct urtw_softc *sc, int chan)
3197{
3198 int i;
3199 uint8_t *cck_pwrtable;
3200 uint8_t cck_pwrlvl_max = 15, ofdm_pwrlvl_max = 25, ofdm_pwrlvl_min = 10;
3201 uint8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
3202 uint8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
3203 usbd_status error;
3204
3205 /* CCK power setting */
3206 cck_pwrlvl = (cck_pwrlvl > cck_pwrlvl_max) ? cck_pwrlvl_max : cck_pwrlvl;
3207 cck_pwrlvl += sc->sc_txpwr_cck_base;
3208 cck_pwrlvl = (cck_pwrlvl > 35) ? 35 : cck_pwrlvl;
3209 cck_pwrtable = (chan == 14) ? urtw_8225v2_txpwr_cck_ch14 :
3210 urtw_8225v2_txpwr_cck;
3211
3212 for (i = 0; i < 8; i++) {
3213 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)
;
3214 }
3215 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)
3216 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)
;
3217 usbd_delay_ms(sc->sc_udev, 1);
3218
3219 /* OFDM power setting */
3220 ofdm_pwrlvl = (ofdm_pwrlvl > (ofdm_pwrlvl_max - ofdm_pwrlvl_min)) ?
3221 ofdm_pwrlvl_max : ofdm_pwrlvl + ofdm_pwrlvl_min;
3222 ofdm_pwrlvl += sc->sc_txpwr_ofdm_base;
3223 ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
3224
3225 error = urtw_8185_set_anaparam2(sc, URTW_8187_8225_ANAPARAM2_ON(0x860c7312));
3226 if (error)
3227 goto fail;
3228
3229 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)
;
3230 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)
;
3231 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)
;
3232 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)
;
3233 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)
;
3234
3235 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)
3236 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)
;
3237 usbd_delay_ms(sc->sc_udev, 1);
3238fail:
3239 return (error);
3240}
3241
3242usbd_status
3243urtw_8225v2_rf_init(struct urtw_rf *rf)
3244{
3245 struct urtw_softc *sc = rf->rf_sc;
3246 int i;
3247 uint16_t data;
3248 uint32_t data32;
3249 usbd_status error;
3250
3251 error = urtw_8180_set_anaparam(sc, URTW_8187_8225_ANAPARAM_ON(0xa0000a59));
3252 if (error)
3253 goto fail;
3254
3255 error = urtw_8225_usb_init(sc);
3256 if (error)
3257 goto fail;
3258
3259 urtw_write32_m(sc, URTW_RF_TIMING, 0x000a8008)do { error = urtw_write32_c(sc, 0x008c, 0x000a8008, 0); if (error
!= 0) goto fail; } while (0)
;
3260 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 ??? */
3261 urtw_write16_m(sc, URTW_8187_BRSR, 0xffff)do { error = urtw_write16_c(sc, 0x002c, 0xffff, 0); if (error
!= 0) goto fail; } while (0)
;
3262 urtw_write32_m(sc, URTW_RF_PARA, 0x100044)do { error = urtw_write32_c(sc, 0x0088, 0x100044, 0); if (error
!= 0) goto fail; } while (0)
;
3263
3264 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG(0x3));
3265 if (error)
3266 goto fail;
3267 urtw_write8_m(sc, URTW_CONFIG3, 0x44)do { error = urtw_write8_c(sc, 0x0059, 0x44, 0); if (error !=
0) goto fail; } while (0)
;
3268 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL(0x0));
3269 if (error)
3270 goto fail;
3271
3272 error = urtw_8185_rf_pins_enable(sc);
3273 if (error)
3274 goto fail;
3275
3276 usbd_delay_ms(sc->sc_udev, 1000);
3277
3278 for (i = 0; i < nitems(urtw_8225v2_rf_part1)(sizeof((urtw_8225v2_rf_part1)) / sizeof((urtw_8225v2_rf_part1
)[0]))
; i++) {
3279 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)
3280 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)
;
3281 usbd_delay_ms(sc->sc_udev, 1);
3282 }
3283 usbd_delay_ms(sc->sc_udev, 50);
3284
3285 urtw_8225_write(sc, 0x0, 0x1b7)do { error = urtw_8225_write_c(sc, 0x0, 0x1b7); if (error != 0
) goto fail; } while (0)
;
3286
3287 for (i = 0; i < nitems(urtw_8225v2_rxgain)(sizeof((urtw_8225v2_rxgain)) / sizeof((urtw_8225v2_rxgain)[0
]))
; i++) {
3288 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)
;
3289 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)
;
3290 }
3291
3292 urtw_8225_write(sc, 0x3, 0x2)do { error = urtw_8225_write_c(sc, 0x3, 0x2); if (error != 0)
goto fail; } while (0)
;
3293 urtw_8225_write(sc, 0x5, 0x4)do { error = urtw_8225_write_c(sc, 0x5, 0x4); if (error != 0)
goto fail; } while (0)
;
3294 urtw_8225_write(sc, 0x0, 0xb7)do { error = urtw_8225_write_c(sc, 0x0, 0xb7); if (error != 0
) goto fail; } while (0)
;
3295 urtw_8225_write(sc, 0x2, 0xc4d)do { error = urtw_8225_write_c(sc, 0x2, 0xc4d); if (error != 0
) goto fail; } while (0)
;
3296 usbd_delay_ms(sc->sc_udev, 100);
3297 urtw_8225_write(sc, 0x2, 0x44d)do { error = urtw_8225_write_c(sc, 0x2, 0x44d); if (error != 0
) goto fail; } while (0)
;
3298 usbd_delay_ms(sc->sc_udev, 100);
3299
3300 error = urtw_8225_read(sc, 0x6, &data32);
3301 if (error != 0)
3302 goto fail;
3303 if (data32 != 0xe6)
3304 printf("%s: expect 0xe6!! (0x%x)\n", sc->sc_dev.dv_xname,
3305 data32);
3306 if (!(data32 & 0x80)) {
3307 urtw_8225_write(sc, 0x02, 0x0c4d)do { error = urtw_8225_write_c(sc, 0x02, 0x0c4d); if (error !=
0) goto fail; } while (0)
;
3308 usbd_delay_ms(sc->sc_udev, 200);
3309 urtw_8225_write(sc, 0x02, 0x044d)do { error = urtw_8225_write_c(sc, 0x02, 0x044d); if (error !=
0) goto fail; } while (0)
;
3310 usbd_delay_ms(sc->sc_udev, 100);
3311 error = urtw_8225_read(sc, 0x6, &data32);
3312 if (error != 0)
3313 goto fail;
3314 if (!(data32 & 0x80))
3315 printf("%s: RF calibration failed\n",
3316 sc->sc_dev.dv_xname);
3317 }
3318 usbd_delay_ms(sc->sc_udev, 100);
3319
3320 urtw_8225_write(sc, 0x0, 0x2bf)do { error = urtw_8225_write_c(sc, 0x0, 0x2bf); if (error != 0
) goto fail; } while (0)
;
3321 for (i = 0; i < nitems(urtw_8225_agc)(sizeof((urtw_8225_agc)) / sizeof((urtw_8225_agc)[0])); i++) {
3322 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)
;
3323 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)
;
3324 }
3325
3326 for (i = 0; i < nitems(urtw_8225v2_rf_part2)(sizeof((urtw_8225v2_rf_part2)) / sizeof((urtw_8225v2_rf_part2
)[0]))
; i++) {
3327 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)
3328 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)
;
3329 }
3330
3331 error = urtw_8225v2_setgain(sc, 4);
3332 if (error)
3333 goto fail;
3334
3335 for (i = 0; i < nitems(urtw_8225v2_rf_part3)(sizeof((urtw_8225v2_rf_part3)) / sizeof((urtw_8225v2_rf_part3
)[0]))
; i++) {
3336 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)
3337 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)
;
3338 }
3339
3340 urtw_write8_m(sc, 0x5b, 0x0d)do { error = urtw_write8_c(sc, 0x5b, 0x0d, 0); if (error != 0
) goto fail; } while (0)
;
3341
3342 error = urtw_8225v2_set_txpwrlvl(sc, 1);
3343 if (error)
3344 goto fail;
3345
3346 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)
;
3347 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)
;
3348
3349 /* TX ant A, 0x0 for B */
3350 error = urtw_8185_tx_antenna(sc, 0x3);
3351 if (error)
3352 goto fail;
3353 urtw_write32_m(sc, 0x94, 0x3dc00002)do { error = urtw_write32_c(sc, 0x94, 0x3dc00002, 0); if (error
!= 0) goto fail; } while (0)
;
3354
3355 error = urtw_8225_rf_set_chan(rf, 1);
3356fail:
3357 return (error);
3358}
3359
3360usbd_status
3361urtw_8225v2_rf_set_chan(struct urtw_rf *rf, int chan)
3362{
3363 struct urtw_softc *sc = rf->rf_sc;
3364 struct ieee80211com *ic = &sc->sc_ic;
3365 struct ieee80211_channel *c = ic->ic_ibss_chan;
3366 usbd_status error;
3367
3368 error = urtw_8225v2_set_txpwrlvl(sc, chan);
3369 if (error)
3370 goto fail;
3371
3372 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)
;
3373 usbd_delay_ms(sc->sc_udev, 10);
3374
3375 urtw_write8_m(sc, URTW_SIFS, 0x22)do { error = urtw_write8_c(sc, 0x00b4, 0x22, 0); if (error !=
0) goto fail; } while (0)
;
3376
3377 if(sc->sc_state == IEEE80211_S_ASSOC &&
3378 ic->ic_flags & IEEE80211_F_SHSLOT0x00020000)
3379 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)
;
3380 else
3381 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)
;
3382
3383 if (IEEE80211_IS_CHAN_G(c)(((c)->ic_flags & (0x0080 | 0x0400)) == (0x0080 | 0x0400
))
) {
3384 urtw_write8_m(sc, URTW_DIFS, 0x14)do { error = urtw_write8_c(sc, 0x00b5, 0x14, 0); if (error !=
0) goto fail; } while (0)
;
3385 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)
;
3386 urtw_write8_m(sc, URTW_CW_VAL, 0x73)do { error = urtw_write8_c(sc, 0x00bd, 0x73, 0); if (error !=
0) goto fail; } while (0)
;
3387 } else {
3388 urtw_write8_m(sc, URTW_DIFS, 0x24)do { error = urtw_write8_c(sc, 0x00b5, 0x24, 0); if (error !=
0) goto fail; } while (0)
;
3389 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)
;
3390 urtw_write8_m(sc, URTW_CW_VAL, 0xa5)do { error = urtw_write8_c(sc, 0x00bd, 0xa5, 0); if (error !=
0) goto fail; } while (0)
;
3391 }
3392
3393fail:
3394 return (error);
3395}
3396
3397void
3398urtw_set_chan(struct urtw_softc *sc, struct ieee80211_channel *c)
3399{
3400 struct urtw_rf *rf = &sc->sc_rf;
3401 struct ieee80211com *ic = &sc->sc_ic;
3402 usbd_status error = 0;
3403 uint32_t data;
3404 u_int chan;
3405
3406 chan = ieee80211_chan2ieee(ic, c);
3407 if (chan == 0 || chan == IEEE80211_CHAN_ANY0xffff)
3408 return;
3409 /*
3410 * During changing the channel we need to temporary disable
3411 * TX.
3412 */
3413 urtw_read32_m(sc, URTW_TX_CONF, &data)do { error = urtw_read32_c(sc, 0x0040, &data, 0); if (error
!= 0) goto fail; } while (0)
;
3414 data &= ~URTW_TX_LOOPBACK_MASK(0x60000);
3415 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)
;
3416 error = rf->set_chan(rf, chan);
3417 if (error != 0) {
3418 printf("%s could not change the channel\n",
3419 sc->sc_dev.dv_xname);
3420 return;
3421 }
3422 usbd_delay_ms(sc->sc_udev, 10);
3423 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)
;
3424
3425fail: return;
3426
3427}
3428
3429void
3430urtw_next_scan(void *arg)
3431{
3432 struct urtw_softc *sc = arg;
3433 struct ieee80211com *ic = &sc->sc_ic;
3434 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
3435
3436 if (usbd_is_dying(sc->sc_udev))
3437 return;
3438
3439 usbd_ref_incr(sc->sc_udev);
3440
3441 if (ic->ic_state == IEEE80211_S_SCAN)
3442 ieee80211_next_scan(ifp);
3443
3444 usbd_ref_decr(sc->sc_udev);
3445}
3446
3447void
3448urtw_task(void *arg)
3449{
3450 struct urtw_softc *sc = arg;
3451 struct ieee80211com *ic = &sc->sc_ic;
3452 struct ieee80211_node *ni;
3453 enum ieee80211_state ostate;
3454 usbd_status error = 0;
3455
3456 if (usbd_is_dying(sc->sc_udev))
3457 return;
3458
3459 ostate = ic->ic_state;
3460
3461 switch (sc->sc_state) {
3462 case IEEE80211_S_INIT:
3463 if (ostate == IEEE80211_S_RUN) {
3464 /* turn link LED off */
3465 (void)urtw_led_off(sc, URTW_LED_GPIO1);
3466 }
3467 break;
3468
3469 case IEEE80211_S_SCAN:
3470 urtw_set_chan(sc, ic->ic_bss->ni_chan);
3471 if (!usbd_is_dying(sc->sc_udev))
3472 timeout_add_msec(&sc->scan_to, 200);
3473 break;
3474
3475 case IEEE80211_S_AUTH:
3476 case IEEE80211_S_ASSOC:
3477 urtw_set_chan(sc, ic->ic_bss->ni_chan);
3478 break;
3479
3480 case IEEE80211_S_RUN:
3481 ni = ic->ic_bss;
3482
3483 /* setting bssid. */
3484 error = urtw_set_bssid(sc, ni->ni_bssid);
3485 if (error != 0)
3486 goto fail;
3487 urtw_update_msr(sc);
3488 /* XXX maybe the below would be incorrect. */
3489 urtw_write16_m(sc, URTW_ATIM_WND, 2)do { error = urtw_write16_c(sc, 0x0072, 2, 0); if (error != 0
) goto fail; } while (0)
;
3490 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)
;
3491 urtw_write16_m(sc, URTW_BEACON_INTERVAL, 0x64)do { error = urtw_write16_c(sc, 0x0070, 0x64, 0); if (error !=
0) goto fail; } while (0)
;
3492 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)
;
3493 error = urtw_led_ctl(sc, URTW_LED_CTL_LINK2);
3494 if (error != 0)
3495 printf("%s: could not control LED (%d)\n",
3496 sc->sc_dev.dv_xname, error);
3497 break;
3498 }
3499
3500 sc->sc_newstate(ic, sc->sc_state, sc->sc_arg);
3501
3502fail:
3503 if (error != 0)
3504 DPRINTF(("%s: error duing processing RUN state.",
3505 sc->sc_dev.dv_xname));
3506}
3507
3508usbd_status
3509urtw_8187b_update_wmm(struct urtw_softc *sc)
3510{
3511 struct ieee80211com *ic = &sc->sc_ic;
3512 struct ieee80211_channel *c = ic->ic_ibss_chan;
3513 uint32_t data;
3514 uint8_t aifs, sifs, slot, ecwmin, ecwmax;
3515 usbd_status error;
3516
3517 sifs = 0xa;
3518 if (IEEE80211_IS_CHAN_G(c)(((c)->ic_flags & (0x0080 | 0x0400)) == (0x0080 | 0x0400
))
)
3519 slot = 0x9;
3520 else
3521 slot = 0x14;
3522
3523 aifs = (2 * slot) + sifs;
3524 ecwmin = 3;
3525 ecwmax = 7;
3526
3527 data = ((uint32_t)aifs << 0) | /* AIFS, offset 0 */
3528 ((uint32_t)ecwmin << 8) | /* ECW minimum, offset 8 */
3529 ((uint32_t)ecwmax << 12); /* ECW maximum, offset 16 */
3530
3531 urtw_write32_m(sc, URTW_AC_VO, data)do { error = urtw_write32_c(sc, 0x00f0, data, 0); if (error !=
0) goto fail; } while (0)
;
3532 urtw_write32_m(sc, URTW_AC_VI, data)do { error = urtw_write32_c(sc, 0x00f4, data, 0); if (error !=
0) goto fail; } while (0)
;
3533 urtw_write32_m(sc, URTW_AC_BE, data)do { error = urtw_write32_c(sc, 0x00f8, data, 0); if (error !=
0) goto fail; } while (0)
;
3534 urtw_write32_m(sc, URTW_AC_BK, data)do { error = urtw_write32_c(sc, 0x00fc, data, 0); if (error !=
0) goto fail; } while (0)
;
3535
3536fail:
3537 return (error);
3538}
3539
3540usbd_status
3541urtw_8187b_reset(struct urtw_softc *sc)
3542{
3543 uint8_t data;
3544 usbd_status error;
3545
3546 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG(0x3));
3547 if (error)
3548 goto fail;
3549
3550 urtw_read8_m(sc, URTW_CONFIG3, &data)do { error = urtw_read8_c(sc, 0x0059, &data, 0); if (error
!= 0) goto fail; } while (0)
;
3551 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)
3552 URTW_CONFIG3_GNT_SELECT)do { error = urtw_write8_c(sc, 0x0059, data | (0x40) | (0x80)
, 0); if (error != 0) goto fail; } while (0)
;
3553
3554 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)
;
3555 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)
;
3556 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)
;
3557
3558 urtw_write8_m(sc, 0x61, 0x10)do { error = urtw_write8_c(sc, 0x61, 0x10, 0); if (error != 0
) goto fail; } while (0)
;
3559 urtw_read8_m(sc, 0x62, &data)do { error = urtw_read8_c(sc, 0x62, &data, 0); if (error !=
0) goto fail; } while (0)
;
3560 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)
;
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
3563 urtw_read8_m(sc, URTW_CONFIG3, &data)do { error = urtw_read8_c(sc, 0x0059, &data, 0); if (error
!= 0) goto fail; } while (0)
;
3564 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)
;
3565
3566 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL(0x0));
3567 if (error)
3568 goto fail;
3569
3570 urtw_read8_m(sc, URTW_CMD, &data)do { error = urtw_read8_c(sc, 0x0037, &data, 0); if (error
!= 0) goto fail; } while (0)
;
3571 data = (data & 2) | URTW_CMD_RST(0x10);
3572 urtw_write8_m(sc, URTW_CMD, data)do { error = urtw_write8_c(sc, 0x0037, data, 0); if (error !=
0) goto fail; } while (0)
;
3573 usbd_delay_ms(sc->sc_udev, 100);
3574
3575 urtw_read8_m(sc, URTW_CMD, &data)do { error = urtw_read8_c(sc, 0x0037, &data, 0); if (error
!= 0) goto fail; } while (0)
;
3576 if (data & URTW_CMD_RST(0x10)) {
3577 printf("%s: reset timeout\n", sc->sc_dev.dv_xname);
3578 goto fail;
3579 }
3580
3581fail:
3582 return (error);
3583}
3584
3585int
3586urtw_8187b_init(struct ifnet *ifp)
3587{
3588 struct urtw_softc *sc = ifp->if_softc;
3589 struct urtw_rf *rf = &sc->sc_rf;
3590 struct ieee80211com *ic = &sc->sc_ic;
3591 uint8_t data;
3592 usbd_status error;
3593
3594 urtw_stop(ifp, 0);
3595
3596 error = urtw_8187b_update_wmm(sc);
3597 if (error != 0)
3598 goto fail;
3599 error = urtw_8187b_reset(sc);
3600 if (error)
3601 goto fail;
3602
3603 /* Applying MAC address again. */
3604 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG(0x3));
3605 if (error)
3606 goto fail;
3607 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))
;
3608 error = urtw_set_macaddr(sc, ic->ic_myaddr);
3609 if (error)
3610 goto fail;
3611 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL(0x0));
3612 if (error)
3613 goto fail;
3614
3615 error = urtw_update_msr(sc);
3616 if (error)
3617 goto fail;
3618
3619 error = rf->init(rf);
3620 if (error != 0)
3621 goto fail;
3622
3623 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)
3624 URTW_CMD_RX_ENABLE)do { error = urtw_write8_c(sc, 0x0037, (0x4) | (0x8), 0); if (
error != 0) goto fail; } while (0)
;
3625 error = urtw_intr_enable(sc);
3626 if (error != 0)
3627 goto fail;
3628
3629 error = urtw_write8e(sc, 0x41, 0xf4);
3630 if (error != 0)
3631 goto fail;
3632 error = urtw_write8e(sc, 0x40, 0x00);
3633 if (error != 0)
3634 goto fail;
3635 error = urtw_write8e(sc, 0x42, 0x00);
3636 if (error != 0)
3637 goto fail;
3638 error = urtw_write8e(sc, 0x42, 0x01);
3639 if (error != 0)
3640 goto fail;
3641 error = urtw_write8e(sc, 0x40, 0x0f);
3642 if (error != 0)
3643 goto fail;
3644 error = urtw_write8e(sc, 0x42, 0x00);
3645 if (error != 0)
3646 goto fail;
3647 error = urtw_write8e(sc, 0x42, 0x01);
3648 if (error != 0)
3649 goto fail;
3650
3651 urtw_read8_m(sc, 0xdb, &data)do { error = urtw_read8_c(sc, 0xdb, &data, 0); if (error !=
0) goto fail; } while (0)
;
3652 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)
;
3653 urtw_write16_idx_m(sc, 0x72, 0x59fa, 3)do { error = urtw_write16_c(sc, 0x72, 0x59fa, 3); if (error !=
0) goto fail; } while (0)
;
3654 urtw_write16_idx_m(sc, 0x74, 0x59d2, 3)do { error = urtw_write16_c(sc, 0x74, 0x59d2, 3); if (error !=
0) goto fail; } while (0)
;
3655 urtw_write16_idx_m(sc, 0x76, 0x59d2, 3)do { error = urtw_write16_c(sc, 0x76, 0x59d2, 3); if (error !=
0) goto fail; } while (0)
;
3656 urtw_write16_idx_m(sc, 0x78, 0x19fa, 3)do { error = urtw_write16_c(sc, 0x78, 0x19fa, 3); if (error !=
0) goto fail; } while (0)
;
3657 urtw_write16_idx_m(sc, 0x7a, 0x19fa, 3)do { error = urtw_write16_c(sc, 0x7a, 0x19fa, 3); if (error !=
0) goto fail; } while (0)
;
3658 urtw_write16_idx_m(sc, 0x7c, 0x00d0, 3)do { error = urtw_write16_c(sc, 0x7c, 0x00d0, 3); if (error !=
0) goto fail; } while (0)
;
3659 urtw_write8_m(sc, 0x61, 0)do { error = urtw_write8_c(sc, 0x61, 0, 0); if (error != 0) goto
fail; } while (0)
;
3660 urtw_write8_idx_m(sc, 0x80, 0x0f, 1)do { error = urtw_write8_c(sc, 0x80, 0x0f, 1); if (error != 0
) goto fail; } while (0)
;
3661 urtw_write8_idx_m(sc, 0x83, 0x03, 1)do { error = urtw_write8_c(sc, 0x83, 0x03, 1); if (error != 0
) goto fail; } while (0)
;
3662 urtw_write8_m(sc, 0xda, 0x10)do { error = urtw_write8_c(sc, 0xda, 0x10, 0); if (error != 0
) goto fail; } while (0)
;
3663 urtw_write8_idx_m(sc, 0x4d, 0x08, 2)do { error = urtw_write8_c(sc, 0x4d, 0x08, 2); if (error != 0
) goto fail; } while (0)
;
3664
3665 urtw_write32_m(sc, URTW_HSSI_PARA, 0x0600321b)do { error = urtw_write32_c(sc, 0x0094, 0x0600321b, 0); if (error
!= 0) goto fail; } while (0)
;
3666
3667 urtw_write16_idx_m(sc, 0xec, 0x0800, 1)do { error = urtw_write16_c(sc, 0xec, 0x0800, 1); if (error !=
0) goto fail; } while (0)
;
3668
3669 urtw_write8_m(sc, URTW_ACM_CONTROL, 0)do { error = urtw_write8_c(sc, 0x00bf, 0, 0); if (error != 0)
goto fail; } while (0)
;
3670
3671 /* Reset softc variables. */
3672 sc->sc_txidx = sc->sc_tx_low_queued = sc->sc_tx_normal_queued = 0;
3673 sc->sc_txtimer = 0;
3674
3675 if (!(sc->sc_flags & URTW_INIT_ONCE(1 << 1))) {
3676 error = urtw_open_pipes(sc);
3677 if (error != 0)
3678 goto fail;
3679 error = urtw_alloc_rx_data_list(sc);
3680 if (error != 0)
3681 goto fail;
3682 error = urtw_alloc_tx_data_list(sc);
3683 if (error != 0)
3684 goto fail;
3685 sc->sc_flags |= URTW_INIT_ONCE(1 << 1);
3686 }
3687
3688 error = urtw_rx_enable(sc);
3689 if (error != 0)
3690 goto fail;
3691 error = urtw_tx_enable(sc);
3692 if (error != 0)
3693 goto fail;
3694
3695 ifp->if_flags |= IFF_RUNNING0x40;
3696 ifq_clr_oactive(&ifp->if_snd);
3697
3698 ifp->if_timer = 1;
3699
3700 if (ic->ic_opmode == IEEE80211_M_MONITOR)
3701 ieee80211_new_state(ic, IEEE80211_S_RUN, -1)(((ic)->ic_newstate)((ic), (IEEE80211_S_RUN), (-1)));
3702 else
3703 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1)(((ic)->ic_newstate)((ic), (IEEE80211_S_SCAN), (-1)));
3704
3705fail:
3706 return (error);
3707}
3708
3709usbd_status
3710urtw_8225v2_b_config_mac(struct urtw_softc *sc)
3711{
3712 int i;
3713 usbd_status error;
3714
3715 for (i = 0; i < nitems(urtw_8187b_regtbl)(sizeof((urtw_8187b_regtbl)) / sizeof((urtw_8187b_regtbl)[0])
)
; i++) {
3716 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)
3717 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)
;
3718 }
3719
3720 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)
;
3721 urtw_write16_m(sc, URTW_INT_MIG, 0)do { error = urtw_write16_c(sc, 0x00e2, 0, 0); if (error != 0
) goto fail; } while (0)
;
3722
3723 urtw_write32_idx_m(sc, 0xf0, 0, 1)do { error = urtw_write32_c(sc, 0xf0, 0, 1); if (error != 0) goto
fail; } while (0)
;
3724 urtw_write32_idx_m(sc, 0xf4, 0, 1)do { error = urtw_write32_c(sc, 0xf4, 0, 1); if (error != 0) goto
fail; } while (0)
;
3725 urtw_write8_idx_m(sc, 0xf8, 0, 1)do { error = urtw_write8_c(sc, 0xf8, 0, 1); if (error != 0) goto
fail; } while (0)
;
3726
3727 urtw_write32_m(sc, URTW_RF_TIMING, 0x00004001)do { error = urtw_write32_c(sc, 0x008c, 0x00004001, 0); if (error
!= 0) goto fail; } while (0)
;
3728
3729fail:
3730 return (error);
3731}
3732
3733usbd_status
3734urtw_8225v2_b_init_rfe(struct urtw_softc *sc)
3735{
3736 usbd_status error;
3737
3738 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)
;
3739 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)
;
3740 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)
;
3741 usbd_delay_ms(sc->sc_udev, 100);
3742
3743fail:
3744 return (error);
3745}
3746
3747usbd_status
3748urtw_8225v2_b_update_chan(struct urtw_softc *sc)
3749{
3750 struct ieee80211com *ic = &sc->sc_ic;
3751 struct ieee80211_channel *c = ic->ic_ibss_chan;
3752 uint8_t aifs, difs, eifs, sifs, slot;
3753 usbd_status error;
3754
3755 urtw_write8_m(sc, URTW_SIFS, 0x22)do { error = urtw_write8_c(sc, 0x00b4, 0x22, 0); if (error !=
0) goto fail; } while (0)
;
3756
3757 sifs = 0xa;
3758 if (IEEE80211_IS_CHAN_G(c)(((c)->ic_flags & (0x0080 | 0x0400)) == (0x0080 | 0x0400
))
) {
3759 slot = 0x9;
3760 difs = 0x1c;
3761 eifs = 0x5b;
3762 } else {
3763 slot = 0x14;
3764 difs = 0x32;
3765 eifs = 0x5b;
3766 }
3767 aifs = (2 * slot) + sifs;
3768
3769 urtw_write8_m(sc, URTW_SLOT, slot)do { error = urtw_write8_c(sc, 0x00b6, slot, 0); if (error !=
0) goto fail; } while (0)
;
3770
3771 urtw_write8_m(sc, URTW_AC_VO, aifs)do { error = urtw_write8_c(sc, 0x00f0, aifs, 0); if (error !=
0) goto fail; } while (0)
;
3772 urtw_write8_m(sc, URTW_AC_VI, aifs)do { error = urtw_write8_c(sc, 0x00f4, aifs, 0); if (error !=
0) goto fail; } while (0)
;
3773 urtw_write8_m(sc, URTW_AC_BE, aifs)do { error = urtw_write8_c(sc, 0x00f8, aifs, 0); if (error !=
0) goto fail; } while (0)
;
3774 urtw_write8_m(sc, URTW_AC_BK, aifs)do { error = urtw_write8_c(sc, 0x00fc, aifs, 0); if (error !=
0) goto fail; } while (0)
;
3775
3776 urtw_write8_m(sc, URTW_DIFS, difs)do { error = urtw_write8_c(sc, 0x00b5, difs, 0); if (error !=
0) goto fail; } while (0)
;
3777 urtw_write8_m(sc, URTW_8187B_EIFS, eifs)do { error = urtw_write8_c(sc, 0x002d, eifs, 0); if (error !=
0) goto fail; } while (0)
;
3778
3779fail:
3780 return (error);
3781}
3782
3783usbd_status
3784urtw_8225v2_b_rf_init(struct urtw_rf *rf)
3785{
3786 struct urtw_softc *sc = rf->rf_sc;
3787 int i;
3788 uint8_t data;
3789 usbd_status error;
3790
3791 /* Set up ACK rate, retry limit, TX AGC, TX antenna. */
3792 urtw_write16_m(sc, URTW_8187B_BRSR, 0x0fff)do { error = urtw_write16_c(sc, 0x0034, 0x0fff, 0); if (error
!= 0) goto fail; } while (0)
;
3793 urtw_read8_m(sc, URTW_CW_CONF, &data)do { error = urtw_read8_c(sc, 0x00bc, &data, 0); if (error
!= 0) goto fail; } while (0)
;
3794 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)
3795 URTW_CW_CONF_PERPACKET_RETRY)do { error = urtw_write8_c(sc, 0x00bc, data | (0x2), 0); if (
error != 0) goto fail; } while (0)
;
3796 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)
;
3797 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)
3798 URTW_TX_AGC_CTL_PERPACKET_GAIN |do { error = urtw_write8_c(sc, 0x009c, data | (0x1) | (0x2), 0
); if (error != 0) goto fail; } while (0)
3799 URTW_TX_AGC_CTL_PERPACKET_ANTSEL)do { error = urtw_write8_c(sc, 0x009c, data | (0x1) | (0x2), 0
); if (error != 0) goto fail; } while (0)
;
3800
3801 /* Auto rate fallback control. */
3802 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 */
3803 urtw_read8_m(sc, URTW_RATE_FALLBACK, &data)do { error = urtw_read8_c(sc, 0x00be, &data, 0); if (error
!= 0) goto fail; } while (0)
;
3804 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)
3805 URTW_RATE_FALLBACK_ENABLE)do { error = urtw_write8_c(sc, 0x00be, data | (0x80), 0); if (
error != 0) goto fail; } while (0)
;
3806
3807 urtw_write16_m(sc, URTW_BEACON_INTERVAL, 100)do { error = urtw_write16_c(sc, 0x0070, 100, 0); if (error !=
0) goto fail; } while (0)
;
3808 urtw_write16_m(sc, URTW_ATIM_WND, 2)do { error = urtw_write16_c(sc, 0x0072, 2, 0); if (error != 0
) goto fail; } while (0)
;
3809 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)
;
3810
3811 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG(0x3));
3812 if (error)
3813 goto fail;
3814 urtw_read8_m(sc, URTW_CONFIG1, &data)do { error = urtw_read8_c(sc, 0x0052, &data, 0); if (error
!= 0) goto fail; } while (0)
;
3815 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)
;
3816 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL(0x0));
3817 if (error)
3818 goto fail;
3819
3820 urtw_write8_m(sc, URTW_WPA_CONFIG, 0)do { error = urtw_write8_c(sc, 0x00b0, 0, 0); if (error != 0)
goto fail; } while (0)
;
3821 urtw_8225v2_b_config_mac(sc);
3822 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)
;
3823
3824 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG(0x3));
3825 if (error)
3826 goto fail;
3827 urtw_read8_m(sc, URTW_CONFIG3, &data)do { error = urtw_read8_c(sc, 0x0059, &data, 0); if (error
!= 0) goto fail; } while (0)
;
3828 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)
;
3829 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL(0x0));
3830 if (error)
3831 goto fail;
3832
3833 urtw_8225v2_b_init_rfe(sc);
3834
3835 for (i = 0; i < nitems(urtw_8225v2_b_rf)(sizeof((urtw_8225v2_b_rf)) / sizeof((urtw_8225v2_b_rf)[0])); i++) {
3836 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)
3837 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)
;
3838 }
3839
3840 for (i = 0; i < nitems(urtw_8225v2_rxgain)(sizeof((urtw_8225v2_rxgain)) / sizeof((urtw_8225v2_rxgain)[0
]))
; i++) {
3841 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)
;
3842 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)
;
3843 }
3844
3845 urtw_8225_write(sc, 0x03, 0x080)do { error = urtw_8225_write_c(sc, 0x03, 0x080); if (error !=
0) goto fail; } while (0)
;
3846 urtw_8225_write(sc, 0x05, 0x004)do { error = urtw_8225_write_c(sc, 0x05, 0x004); if (error !=
0) goto fail; } while (0)
;
3847 urtw_8225_write(sc, 0x00, 0x0b7)do { error = urtw_8225_write_c(sc, 0x00, 0x0b7); if (error !=
0) goto fail; } while (0)
;
3848 urtw_8225_write(sc, 0x02, 0xc4d)do { error = urtw_8225_write_c(sc, 0x02, 0xc4d); if (error !=
0) goto fail; } while (0)
;
3849 urtw_8225_write(sc, 0x02, 0x44d)do { error = urtw_8225_write_c(sc, 0x02, 0x44d); if (error !=
0) goto fail; } while (0)
;
3850 urtw_8225_write(sc, 0x00, 0x2bf)do { error = urtw_8225_write_c(sc, 0x00, 0x2bf); if (error !=
0) goto fail; } while (0)
;
3851
3852 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)
;
3853 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)
;
3854 urtw_write8_m(sc, URTW_TX_ANTENNA, 0x03)do { error = urtw_write8_c(sc, 0x009f, 0x03, 0); if (error !=
0) goto fail; } while (0)
;
3855
3856 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)
;
3857 for (i = 0; i < nitems(urtw_8225v2_agc)(sizeof((urtw_8225v2_agc)) / sizeof((urtw_8225v2_agc)[0])); i++) {
3858 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)
;
3859 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)
;
3860 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)
;
3861 }
3862 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)
;
3863
3864 for (i = 0; i < nitems(urtw_8225v2_ofdm)(sizeof((urtw_8225v2_ofdm)) / sizeof((urtw_8225v2_ofdm)[0])); i++)
3865 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)
;
3866
3867 urtw_8225v2_b_update_chan(sc);
3868
3869 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)
;
3870 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)
;
3871 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)
;
3872 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)
;
3873
3874 error = urtw_8225v2_b_rf_set_chan(rf, 1);
3875fail:
3876 return (error);
3877}
3878
3879usbd_status
3880urtw_8225v2_b_rf_set_chan(struct urtw_rf *rf, int chan)
3881{
3882 struct urtw_softc *sc = rf->rf_sc;
3883 usbd_status error;
3884
3885 error = urtw_8225v2_b_set_txpwrlvl(sc, chan);
3886 if (error)
3887 goto fail;
3888
3889 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)
;
3890 /*
3891 * Delay removed from 8185 to 8187.
3892 * usbd_delay_ms(sc->sc_udev, 10);
3893 */
3894
3895 urtw_write16_m(sc, URTW_AC_VO, 0x5114)do { error = urtw_write16_c(sc, 0x00f0, 0x5114, 0); if (error
!= 0) goto fail; } while (0)
;
3896 urtw_write16_m(sc, URTW_AC_VI, 0x5114)do { error = urtw_write16_c(sc, 0x00f4, 0x5114, 0); if (error
!= 0) goto fail; } while (0)
;
3897 urtw_write16_m(sc, URTW_AC_BE, 0x5114)do { error = urtw_write16_c(sc, 0x00f8, 0x5114, 0); if (error
!= 0) goto fail; } while (0)
;
3898 urtw_write16_m(sc, URTW_AC_BK, 0x5114)do { error = urtw_write16_c(sc, 0x00fc, 0x5114, 0); if (error
!= 0) goto fail; } while (0)
;
3899
3900fail:
3901 return (error);
3902}
3903
3904usbd_status
3905urtw_8225v2_b_set_txpwrlvl(struct urtw_softc *sc, int chan)
3906{
3907 int i;
3908 uint8_t *cck_pwrtable;
3909 uint8_t cck_pwrlvl_min, cck_pwrlvl_max, ofdm_pwrlvl_min,
3910 ofdm_pwrlvl_max;
3911 int8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
3912 int8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
3913 usbd_status error;
3914
3915 if (sc->sc_hwrev & URTW_HWREV_8187B_B0x10) {
3916 cck_pwrlvl_min = 0;
3917 cck_pwrlvl_max = 15;
3918 ofdm_pwrlvl_min = 2;
3919 ofdm_pwrlvl_max = 17;
3920 } else {
3921 cck_pwrlvl_min = 7;
3922 cck_pwrlvl_max = 22;
3923 ofdm_pwrlvl_min = 10;
3924 ofdm_pwrlvl_max = 25;
3925 }
3926
3927 /* CCK power setting */
3928 cck_pwrlvl = (cck_pwrlvl > (cck_pwrlvl_max - cck_pwrlvl_min)) ?
3929 cck_pwrlvl_max : (cck_pwrlvl + cck_pwrlvl_min);
3930
3931 cck_pwrlvl += sc->sc_txpwr_cck_base;
3932 cck_pwrlvl = (cck_pwrlvl > 35) ? 35 : cck_pwrlvl;
3933 cck_pwrlvl = (cck_pwrlvl < 0) ? 0 : cck_pwrlvl;
3934
3935 cck_pwrtable = (chan == 14) ? urtw_8225v2_txpwr_cck_ch14 :
3936 urtw_8225v2_txpwr_cck;
3937
3938 if (sc->sc_hwrev & URTW_HWREV_8187B_B0x10) {
3939 if (cck_pwrlvl <= 6)
3940 ; /* do nothing */
3941 else if (cck_pwrlvl <= 11)
3942 cck_pwrtable += 8;
3943 else
3944 cck_pwrtable += 16;
3945 } else {
3946 if (cck_pwrlvl <= 5)
3947 ; /* do nothing */
3948 else if (cck_pwrlvl <= 11)
3949 cck_pwrtable += 8;
3950 else if (cck_pwrlvl <= 17)
3951 cck_pwrtable += 16;
3952 else
3953 cck_pwrtable += 24;
3954 }
3955
3956 for (i = 0; i < 8; i++) {
3957 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)
;
3958 }
3959
3960 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)
3961 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)
;
3962 /*
3963 * Delay removed from 8185 to 8187.
3964 * usbd_delay_ms(sc->sc_udev, 1);
3965 */
3966
3967 /* OFDM power setting */
3968 ofdm_pwrlvl = (ofdm_pwrlvl > (ofdm_pwrlvl_max - ofdm_pwrlvl_min)) ?
3969 ofdm_pwrlvl_max : ofdm_pwrlvl + ofdm_pwrlvl_min;
3970
3971 ofdm_pwrlvl += sc->sc_txpwr_ofdm_base;
3972 ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
3973 ofdm_pwrlvl = (ofdm_pwrlvl < 0) ? 0 : ofdm_pwrlvl;
3974
3975 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)
3976 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)
;
3977
3978 if (sc->sc_hwrev & URTW_HWREV_8187B_B0x10) {
3979 if (ofdm_pwrlvl <= 11) {
3980 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)
;
3981 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)
;
3982 } else {
3983 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)
;
3984 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)
;
3985 }
3986 } else {
3987 if (ofdm_pwrlvl <= 11) {
3988 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)
;
3989 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)
;
3990 } else if (ofdm_pwrlvl <= 17) {
3991 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)
;
3992 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)
;
3993 } else {
3994 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)
;
3995 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)
;
3996 }
3997 }
3998
3999 /*
4000 * Delay removed from 8185 to 8187.
4001 * usbd_delay_ms(sc->sc_udev, 1);
4002 */
4003fail:
4004 return (error);
4005}
4006
4007int
4008urtw_set_bssid(struct urtw_softc *sc, const uint8_t *bssid)
4009{
4010 int error;
4011
4012 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)
4013 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)
;
4014 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)
4015 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)
;
4016
4017 return 0;
4018
4019fail:
4020 return error;
4021}
4022
4023int
4024urtw_set_macaddr(struct urtw_softc *sc, const uint8_t *addr)
4025{
4026 int error;
4027
4028 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)
4029 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)
;
4030 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)
4031 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)
;
4032
4033 return 0;
4034
4035fail:
4036 return error;
4037}