Bug Summary

File:dev/usb/if_atu.c
Warning:line 1980, column 4
Value stored to 'wh' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name if_atu.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -ffreestanding -mcmodel=kernel -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -target-feature -sse2 -target-feature -sse -target-feature -3dnow -target-feature -mmx -target-feature +save-args -disable-red-zone -no-implicit-float -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -nostdsysteminc -nobuiltininc -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/sys -I /usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -I /usr/src/sys/arch -I /usr/src/sys/dev/pci/drm/include -I /usr/src/sys/dev/pci/drm/include/uapi -I /usr/src/sys/dev/pci/drm/amd/include/asic_reg -I /usr/src/sys/dev/pci/drm/amd/include -I /usr/src/sys/dev/pci/drm/amd/amdgpu -I /usr/src/sys/dev/pci/drm/amd/display -I /usr/src/sys/dev/pci/drm/amd/display/include -I /usr/src/sys/dev/pci/drm/amd/display/dc -I /usr/src/sys/dev/pci/drm/amd/display/amdgpu_dm -I /usr/src/sys/dev/pci/drm/amd/pm/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu11 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu12 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/hwmgr -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/smumgr -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc/hw -I /usr/src/sys/dev/pci/drm/amd/display/dc/clk_mgr -I /usr/src/sys/dev/pci/drm/amd/display/modules/inc -I /usr/src/sys/dev/pci/drm/amd/display/modules/hdcp -I /usr/src/sys/dev/pci/drm/amd/display/dmub/inc -I /usr/src/sys/dev/pci/drm/i915 -D DDB -D DIAGNOSTIC -D KTRACE -D ACCOUNTING -D KMEMSTATS -D PTRACE -D POOL_DEBUG -D CRYPTO -D SYSVMSG -D SYSVSEM -D SYSVSHM -D UVM_SWAP_ENCRYPT -D FFS -D FFS2 -D FFS_SOFTUPDATES -D UFS_DIRHASH -D QUOTA -D EXT2FS -D MFS -D NFSCLIENT -D NFSSERVER -D CD9660 -D UDF -D MSDOSFS -D FIFO -D FUSE -D SOCKET_SPLICE -D TCP_ECN -D TCP_SIGNATURE -D INET6 -D IPSEC -D PPP_BSDCOMP -D PPP_DEFLATE -D PIPEX -D MROUTING -D MPLS -D BOOT_CONFIG -D USER_PCICONF -D APERTURE -D MTRR -D NTFS -D HIBERNATE -D PCIVERBOSE -D USBVERBOSE -D WSDISPLAY_COMPAT_USL -D WSDISPLAY_COMPAT_RAWKBD -D WSDISPLAY_DEFAULTSCREENS=6 -D X86EMU -D ONEWIREVERBOSE -D MULTIPROCESSOR -D MAXUSERS=80 -D _KERNEL -D CONFIG_DRM_AMD_DC_DCN3_0 -O2 -Wno-pointer-sign -Wno-address-of-packed-member -Wno-constant-conversion -Wno-unused-but-set-variable -Wno-gnu-folding-constant -fdebug-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -o /usr/obj/sys/arch/amd64/compile/GENERIC.MP/scan-build/2022-01-12-131800-47421-1 -x c /usr/src/sys/dev/usb/if_atu.c
1/* $OpenBSD: if_atu.c,v 1.133 2022/01/09 05:43:00 jsg Exp $ */
2/*
3 * Copyright (c) 2003, 2004
4 * Daan Vreeken <Danovitsch@Vitsch.net>. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by Daan Vreeken.
17 * 4. Neither the name of the author nor the names of any co-contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY Daan Vreeken AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL Daan Vreeken OR THE VOICES IN HIS HEAD
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34/*
35 * Atmel AT76c503 / AT76c503a / AT76c505 / AT76c505a USB WLAN driver
36 * version 0.5 - 2004-08-03
37 *
38 * Originally written by Daan Vreeken <Danovitsch @ Vitsch . net>
39 * http://vitsch.net/bsd/atuwi
40 *
41 * Contributed to by :
42 * Chris Whitehouse, Alistair Phillips, Peter Pilka, Martijn van Buul,
43 * Suihong Liang, Arjan van Leeuwen, Stuart Walsh
44 *
45 * Ported to OpenBSD by Theo de Raadt and David Gwynne.
46 */
47
48#include "bpfilter.h"
49
50#include <sys/param.h>
51#include <sys/sockio.h>
52#include <sys/mbuf.h>
53#include <sys/kernel.h>
54#include <sys/socket.h>
55#include <sys/systm.h>
56#include <sys/timeout.h>
57#include <sys/queue.h>
58#include <sys/device.h>
59
60#include <machine/bus.h>
61
62#include <dev/usb/usb.h>
63#include <dev/usb/usbdi.h>
64#include <dev/usb/usbdi_util.h>
65#include <dev/usb/usbdivar.h>
66
67#include <dev/usb/usbdevs.h>
68
69#if NBPFILTER1 > 0
70#include <net/bpf.h>
71#endif
72
73#include <net/if.h>
74#include <net/if_media.h>
75
76#include <netinet/in.h>
77#include <netinet/if_ether.h>
78
79#include <net80211/ieee80211_var.h>
80#include <net80211/ieee80211_radiotap.h>
81
82#include <dev/usb/if_atureg.h>
83
84#ifdef ATU_DEBUG
85#define DPRINTF(x) do { if (atudebug) printf x; } while (0)
86#define DPRINTFN(n,x) do { if (atudebug>(n)) printf x; } while (0)
87int atudebug = 1;
88#else
89#define DPRINTF(x)
90#define DPRINTFN(n,x)
91#endif
92
93int atu_match(struct device *, void *, void *);
94void atu_attach(struct device *, struct device *, void *);
95int atu_detach(struct device *, int);
96
97struct cfdriver atu_cd = {
98 NULL((void *)0), "atu", DV_IFNET
99};
100
101const struct cfattach atu_ca = {
102 sizeof(struct atu_softc), atu_match, atu_attach, atu_detach
103};
104
105/*
106 * Various supported device vendors/products/radio type.
107 */
108struct atu_type atu_devs[] = {
109 { USB_VENDOR_3COM0x0506, USB_PRODUCT_3COM_3CRSHEW6960x0a01,
110 RadioRFMD, ATU_NO_QUIRK0x0000 },
111 { USB_VENDOR_ABOCOM0x07b8, USB_PRODUCT_ABOCOM_BWU6130xb000,
112 RadioRFMD, ATU_NO_QUIRK0x0000 },
113 { USB_VENDOR_ACCTON0x083a, USB_PRODUCT_ACCTON_2664W0x3501,
114 AT76C503_rfmd_acc, ATU_NO_QUIRK0x0000 },
115 { USB_VENDOR_ACERP0x04a5, USB_PRODUCT_ACERP_AWL3000x9000,
116 RadioIntersil, ATU_NO_QUIRK0x0000 },
117 { USB_VENDOR_ACERP0x04a5, USB_PRODUCT_ACERP_AWL4000x9001,
118 RadioRFMD, ATU_NO_QUIRK0x0000 },
119 { USB_VENDOR_ACTIONTEC0x1668, USB_PRODUCT_ACTIONTEC_802UAT10x7605,
120 RadioRFMD, ATU_NO_QUIRK0x0000 },
121 { USB_VENDOR_ADDTRON0x05dd, USB_PRODUCT_ADDTRON_AWU1200xff31,
122 RadioIntersil, ATU_NO_QUIRK0x0000 },
123 { USB_VENDOR_AINCOMM0x12fd, USB_PRODUCT_AINCOMM_AWU2000B0x1001,
124 RadioRFMD2958, ATU_NO_QUIRK0x0000 },
125 { USB_VENDOR_ASKEY0x069a, USB_PRODUCT_ASKEY_VOYAGER10100x0821,
126 RadioIntersil, ATU_NO_QUIRK0x0000 },
127 { USB_VENDOR_ASKEY0x069a, USB_PRODUCT_ASKEY_WLL013I0x0320,
128 RadioIntersil, ATU_NO_QUIRK0x0000 },
129 { USB_VENDOR_ASKEY0x069a, USB_PRODUCT_ASKEY_WLL0130x0321,
130 RadioRFMD, ATU_NO_QUIRK0x0000 },
131 { USB_VENDOR_ATMEL0x03eb, USB_PRODUCT_ATMEL_AT76C503I10x7603,
132 RadioIntersil, ATU_NO_QUIRK0x0000 },
133 { USB_VENDOR_ATMEL0x03eb, USB_PRODUCT_ATMEL_AT76C503I20x7604,
134 AT76C503_i3863, ATU_NO_QUIRK0x0000 },
135 { USB_VENDOR_ATMEL0x03eb, USB_PRODUCT_ATMEL_AT76C503RFMD0x7605,
136 RadioRFMD, ATU_NO_QUIRK0x0000 },
137 { USB_VENDOR_ATMEL0x03eb, USB_PRODUCT_ATMEL_AT76C505RFMD0x7606,
138 AT76C505_rfmd, ATU_NO_QUIRK0x0000 },
139 { USB_VENDOR_ATMEL0x03eb, USB_PRODUCT_ATMEL_AT76C505RFMD29580x7613,
140 RadioRFMD2958, ATU_NO_QUIRK0x0000 },
141 { USB_VENDOR_ATMEL0x03eb, USB_PRODUCT_ATMEL_AT76C505A0x7614, /* SMC2662 V.4 */
142 RadioRFMD2958_SMC, ATU_QUIRK_NO_REMAP0x0001 | ATU_QUIRK_FW_DELAY0x0002 },
143 { USB_VENDOR_ATMEL0x03eb, USB_PRODUCT_ATMEL_AT76C505AS0x7617, /* quirk? */
144 RadioRFMD2958_SMC, ATU_QUIRK_NO_REMAP0x0001 | ATU_QUIRK_FW_DELAY0x0002 },
145 { USB_VENDOR_ATMEL0x03eb, USB_PRODUCT_ATMEL_WN2100x4102,
146 RadioRFMD, ATU_NO_QUIRK0x0000 },
147 { USB_VENDOR_BELKIN0x050d, USB_PRODUCT_BELKIN_F5D60500x0050,
148 RadioRFMD, ATU_NO_QUIRK0x0000 },
149 { USB_VENDOR_CONCEPTRONIC0x0d8e, USB_PRODUCT_CONCEPTRONIC_C11U0x7100,
150 RadioIntersil, ATU_NO_QUIRK0x0000 },
151 { USB_VENDOR_CONCEPTRONIC0x0d8e, USB_PRODUCT_CONCEPTRONIC_WL2100x7110,
152 RadioIntersil, ATU_NO_QUIRK0x0000 },
153 { USB_VENDOR_COMPAQ0x049f, USB_PRODUCT_COMPAQ_IPAQWLAN0x0032,
154 RadioRFMD, ATU_NO_QUIRK0x0000 },
155 { USB_VENDOR_COREGA0x07aa, USB_PRODUCT_COREGA_WLUSB_11_STICK0x7613,
156 RadioRFMD2958, ATU_NO_QUIRK0x0000 },
157 { USB_VENDOR_DICKSMITH0x1371, USB_PRODUCT_DICKSMITH_CHUSB611G0x0013,
158 RadioRFMD2958, ATU_NO_QUIRK0x0000 },
159 { USB_VENDOR_DICKSMITH0x1371, USB_PRODUCT_DICKSMITH_WL200U0x0002,
160 RadioRFMD, ATU_NO_QUIRK0x0000 },
161 { USB_VENDOR_DICKSMITH0x1371, USB_PRODUCT_DICKSMITH_WL240U0x0014,
162 RadioRFMD2958, ATU_NO_QUIRK0x0000 },
163 { USB_VENDOR_DICKSMITH0x1371, USB_PRODUCT_DICKSMITH_XH11530x5743,
164 RadioRFMD, ATU_NO_QUIRK0x0000 },
165 { USB_VENDOR_DLINK0x2001, USB_PRODUCT_DLINK_DWL120E0x3200,
166 RadioRFMD, ATU_NO_QUIRK0x0000 },
167 { USB_VENDOR_GIGABYTE0x1044, USB_PRODUCT_GIGABYTE_GNWLBM1010x8003,
168 RadioRFMD, ATU_NO_QUIRK0x0000 },
169 { USB_VENDOR_GIGASET0x1690, USB_PRODUCT_GIGASET_WLAN0x0701, /* quirk? */
170 RadioRFMD2958_SMC, ATU_QUIRK_NO_REMAP0x0001 | ATU_QUIRK_FW_DELAY0x0002 },
171 { USB_VENDOR_HP0x03f0, USB_PRODUCT_HP_HN210W0x011c,
172 RadioIntersil, ATU_NO_QUIRK0x0000 },
173 { USB_VENDOR_INTEL0x8086, USB_PRODUCT_INTEL_AP3100x0200,
174 RadioIntersil, ATU_NO_QUIRK0x0000 },
175 { USB_VENDOR_IODATA0x04bb, USB_PRODUCT_IODATA_USBWNB11A0x0919,
176 RadioIntersil, ATU_NO_QUIRK0x0000 },
177 { USB_VENDOR_LEXAR0x05dc, USB_PRODUCT_LEXAR_2662WAR0xa002,
178 RadioRFMD, ATU_NO_QUIRK0x0000 },
179 { USB_VENDOR_LINKSYS0x066b, USB_PRODUCT_LINKSYS_WUSB110x2211,
180 RadioIntersil, ATU_NO_QUIRK0x0000 },
181 { USB_VENDOR_LINKSYS20x077b, USB_PRODUCT_LINKSYS2_NWU11B0x2219,
182 RadioRFMD, ATU_NO_QUIRK0x0000 },
183 { USB_VENDOR_LINKSYS30x1915, USB_PRODUCT_LINKSYS3_WUSB11V280x2233,
184 RadioRFMD2958, ATU_NO_QUIRK0x0000 },
185 { USB_VENDOR_MSI0x0db0, USB_PRODUCT_MSI_WLAN0x1020,
186 RadioRFMD2958, ATU_NO_QUIRK0x0000 },
187 { USB_VENDOR_NETGEAR20x0864, USB_PRODUCT_NETGEAR2_MA1010x4100,
188 RadioIntersil, ATU_NO_QUIRK0x0000 },
189 { USB_VENDOR_NETGEAR20x0864, USB_PRODUCT_NETGEAR2_MA101B0x4102,
190 RadioRFMD, ATU_NO_QUIRK0x0000 },
191 { USB_VENDOR_OQO0x1557, USB_PRODUCT_OQO_WIFI010x0002,
192 RadioRFMD2958_SMC, ATU_QUIRK_NO_REMAP0x0001 | ATU_QUIRK_FW_DELAY0x0002 },
193 { USB_VENDOR_PLANEX20x2019, USB_PRODUCT_PLANEX2_GW_US11S0x3220,
194 RadioRFMD, ATU_NO_QUIRK0x0000 },
195 { USB_VENDOR_SAMSUNG0x055d, USB_PRODUCT_SAMSUNG_SWL2100W0xa000,
196 AT76C503_i3863, ATU_NO_QUIRK0x0000 },
197 { USB_VENDOR_SIEMENS20x0681, USB_PRODUCT_SIEMENS2_WLL0130x001b,
198 RadioRFMD, ATU_NO_QUIRK0x0000 },
199 { USB_VENDOR_SMC30x0d5c, USB_PRODUCT_SMC3_2662WV10xa001,
200 RadioIntersil, ATU_NO_QUIRK0x0000 },
201 { USB_VENDOR_SMC30x0d5c, USB_PRODUCT_SMC3_2662WV20xa002,
202 AT76C503_rfmd_acc, ATU_NO_QUIRK0x0000 },
203 { USB_VENDOR_TEKRAM0x0b3b, USB_PRODUCT_TEKRAM_U300C0x1612,
204 RadioIntersil, ATU_NO_QUIRK0x0000 },
205 { USB_VENDOR_ZCOM0x0cde, USB_PRODUCT_ZCOM_M4Y7500x0001,
206 RadioIntersil, ATU_NO_QUIRK0x0000 },
207};
208
209struct atu_radfirm {
210 enum atu_radio_type atur_type;
211 char *atur_internal;
212 char *atur_external;
213 u_int8_t max_rssi;
214} atu_radfirm[] = {
215 { RadioRFMD, "atu-rfmd-int", "atu-rfmd-ext", 0 },
216 { RadioRFMD2958, "atu-rfmd2958-int", "atu-rfmd2958-ext", 81 },
217 { RadioRFMD2958_SMC, "atu-rfmd2958smc-int", "atu-rfmd2958smc-ext", 0 },
218 { RadioIntersil, "atu-intersil-int", "atu-intersil-ext", 0 },
219 {
220 AT76C503_i3863,
221 "atu-at76c503-i3863-int",
222 "atu-at76c503-i3863-ext",
223 0
224 },
225 {
226 AT76C503_rfmd_acc,
227 "atu-at76c503-rfmd-acc-int",
228 "atu-at76c503-rfmd-acc-ext",
229 0
230 },
231 {
232 AT76C505_rfmd,
233 "atu-at76c505-rfmd-int",
234 "atu-at76c505-rfmd-ext",
235 0
236 }
237};
238
239int atu_newbuf(struct atu_softc *, struct atu_chain *, struct mbuf *);
240void atu_rxeof(struct usbd_xfer *, void *, usbd_status);
241void atu_txeof(struct usbd_xfer *, void *, usbd_status);
242void atu_start(struct ifnet *);
243int atu_ioctl(struct ifnet *, u_long, caddr_t);
244int atu_init(struct ifnet *);
245void atu_stop(struct ifnet *, int);
246void atu_watchdog(struct ifnet *);
247usbd_status atu_usb_request(struct atu_softc *sc, u_int8_t type,
248 u_int8_t request, u_int16_t value, u_int16_t index,
249 u_int16_t length, u_int8_t *data);
250int atu_send_command(struct atu_softc *sc, u_int8_t *command, int size);
251int atu_get_cmd_status(struct atu_softc *sc, u_int8_t cmd,
252 u_int8_t *status);
253int atu_wait_completion(struct atu_softc *sc, u_int8_t cmd,
254 u_int8_t *status);
255int atu_send_mib(struct atu_softc *sc, u_int8_t type,
256 u_int8_t size, u_int8_t index, void *data);
257int atu_get_mib(struct atu_softc *sc, u_int8_t type,
258 u_int8_t size, u_int8_t index, u_int8_t *buf);
259#if 0
260int atu_start_ibss(struct atu_softc *sc);
261#endif
262int atu_start_scan(struct atu_softc *sc);
263int atu_switch_radio(struct atu_softc *sc, int state);
264int atu_initial_config(struct atu_softc *sc);
265int atu_join(struct atu_softc *sc, struct ieee80211_node *node);
266int8_t atu_get_dfu_state(struct atu_softc *sc);
267u_int8_t atu_get_opmode(struct atu_softc *sc, u_int8_t *mode);
268void atu_internal_firmware(struct device *);
269void atu_external_firmware(struct device *);
270int atu_get_card_config(struct atu_softc *sc);
271int atu_media_change(struct ifnet *ifp);
272void atu_media_status(struct ifnet *ifp, struct ifmediareq *req);
273int atu_tx_list_init(struct atu_softc *);
274int atu_rx_list_init(struct atu_softc *);
275void atu_xfer_list_free(struct atu_softc *sc, struct atu_chain *ch,
276 int listlen);
277
278void atu_task(void *);
279int atu_newstate(struct ieee80211com *, enum ieee80211_state, int);
280int atu_tx_start(struct atu_softc *, struct ieee80211_node *,
281 struct atu_chain *, struct mbuf *);
282void atu_complete_attach(struct atu_softc *);
283u_int8_t atu_calculate_padding(int);
284
285usbd_status
286atu_usb_request(struct atu_softc *sc, u_int8_t type,
287 u_int8_t request, u_int16_t value, u_int16_t index, u_int16_t length,
288 u_int8_t *data)
289{
290 usb_device_request_t req;
291 struct usbd_xfer *xfer;
292 usbd_status err;
293 int total_len = 0, s;
294
295 req.bmRequestType = type;
296 req.bRequest = request;
297 USETW(req.wValue, value)(*(u_int16_t *)(req.wValue) = (value));
298 USETW(req.wIndex, index)(*(u_int16_t *)(req.wIndex) = (index));
299 USETW(req.wLength, length)(*(u_int16_t *)(req.wLength) = (length));
300
301#ifdef ATU_DEBUG
302 if (atudebug) {
303 if ((data == NULL((void *)0)) || (type & UT_READ0x80)) {
304 DPRINTFN(20, ("%s: req=%02x val=%02x ind=%02x "
305 "len=%02x\n", sc->atu_dev.dv_xname, request,
306 value, index, length));
307 } else {
308 DPRINTFN(20, ("%s: req=%02x val=%02x ind=%02x "
309 "len=%02x [%8D]\n", sc->atu_dev.dv_xname,
310 request, value, index, length, data, " "));
311 }
312 }
313#endif /* ATU_DEBUG */
314
315 s = splnet()splraise(0x7);
316
317 xfer = usbd_alloc_xfer(sc->atu_udev);
318 usbd_setup_default_xfer(xfer, sc->atu_udev, 0, 500000, &req, data,
319 length, USBD_SHORT_XFER_OK0x04 | USBD_SYNCHRONOUS0x02, 0);
320
321 err = usbd_transfer(xfer);
322
323 usbd_get_xfer_status(xfer, NULL((void *)0), NULL((void *)0), &total_len, NULL((void *)0));
324
325#ifdef ATU_DEBUG
326 if (atudebug) {
327 if (type & UT_READ0x80) {
328 DPRINTFN(20, ("%s: transferred 0x%x bytes in\n",
329 sc->atu_dev.dv_xname, total_len));
330 DPRINTFN(20, ("%s: dump [%10D]\n",
331 sc->atu_dev.dv_xname, data, " "));
332 } else {
333 if (total_len != length)
334 DPRINTF(("%s: ARG! wrote only %x bytes\n",
335 sc->atu_dev.dv_xname, total_len));
336 }
337 }
338#endif /* ATU_DEBUG */
339
340 usbd_free_xfer(xfer);
341
342 splx(s)spllower(s);
343 return(err);
344}
345
346int
347atu_send_command(struct atu_softc *sc, u_int8_t *command, int size)
348{
349 return atu_usb_request(sc, UT_WRITE_VENDOR_DEVICE(0x00 | 0x40 | 0x00), 0x0e, 0x0000,
350 0x0000, size, command);
351}
352
353int
354atu_get_cmd_status(struct atu_softc *sc, u_int8_t cmd, u_int8_t *status)
355{
356 /*
357 * all other drivers (including Windoze) request 40 bytes of status
358 * and get a short-xfer of just 6 bytes. we can save 34 bytes of
359 * buffer if we just request those 6 bytes in the first place :)
360 */
361 /*
362 return atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x22, cmd,
363 0x0000, 40, status);
364 */
365 return atu_usb_request(sc, UT_READ_VENDOR_INTERFACE(0x80 | 0x40 | 0x01), 0x22, cmd,
366 0x0000, 6, status);
367}
368
369int
370atu_wait_completion(struct atu_softc *sc, u_int8_t cmd, u_int8_t *status)
371{
372 int idle_count = 0, err;
373 u_int8_t statusreq[6];
374
375 DPRINTFN(15, ("%s: wait-completion: cmd=%02x\n",
376 sc->atu_dev.dv_xname, cmd));
377
378 while (1) {
379 err = atu_get_cmd_status(sc, cmd, statusreq);
380 if (err)
381 return err;
382
383#ifdef ATU_DEBUG
384 if (atudebug) {
385 DPRINTFN(20, ("%s: status=%s cmd=%02x\n",
386 sc->atu_dev.dv_xname,
387 ether_sprintf(statusreq), cmd));
388 }
389#endif /* ATU_DEBUG */
390
391 /*
392 * during normal operations waiting on STATUS_IDLE
393 * will never happen more than once
394 */
395 if ((statusreq[5] == STATUS_IDLE0x00) && (idle_count++ > 20)) {
396 DPRINTF(("%s: AAARRGGG!!! FIX ME!\n",
397 sc->atu_dev.dv_xname));
398 return 0;
399 }
400
401 if ((statusreq[5] != STATUS_IN_PROGRESS0x08) &&
402 (statusreq[5] != STATUS_IDLE0x00)) {
403 if (status != NULL((void *)0))
404 *status = statusreq[5];
405 return 0;
406 }
407 usbd_delay_ms(sc->atu_udev, 25);
408 }
409}
410
411int
412atu_send_mib(struct atu_softc *sc, u_int8_t type, u_int8_t size,
413 u_int8_t index, void *data)
414{
415 int err;
416 struct atu_cmd_set_mib request;
417
418 /*
419 * We don't construct a MIB packet first and then memcpy it into an
420 * Atmel-command-packet, we just construct it the right way at once :)
421 */
422
423 memset(&request, 0, sizeof(request))__builtin_memset((&request), (0), (sizeof(request)));
424
425 request.AtCmd = CMD_SET_MIB0x01;
426 USETW(request.AtSize, size + 4)(*(u_int16_t *)(request.AtSize) = (size + 4));
427
428 request.MIBType = type;
429 request.MIBSize = size;
430 request.MIBIndex = index;
431 request.MIBReserved = 0;
432
433 /*
434 * For 1 and 2 byte requests we assume a direct value,
435 * everything bigger than 2 bytes we assume a pointer to the data
436 */
437 switch (size) {
438 case 0:
439 break;
440 case 1:
441 request.data[0]=(long)data & 0x000000ff;
442 break;
443 case 2:
444 request.data[0]=(long)data & 0x000000ff;
445 request.data[1]=(long)data >> 8;
446 break;
447 default:
448 memcpy(request.data, data, size)__builtin_memcpy((request.data), (data), (size));
449 break;
450 }
451
452 err = atu_usb_request(sc, UT_WRITE_VENDOR_DEVICE(0x00 | 0x40 | 0x00), 0x0e, 0x0000,
453 0x0000, size+8, (uByte *)&request);
454 if (err)
455 return (err);
456
457 DPRINTFN(15, ("%s: sendmib : waitcompletion...\n",
458 sc->atu_dev.dv_xname));
459 return atu_wait_completion(sc, CMD_SET_MIB0x01, NULL((void *)0));
460}
461
462int
463atu_get_mib(struct atu_softc *sc, u_int8_t type, u_int8_t size,
464 u_int8_t index, u_int8_t *buf)
465{
466
467 /* linux/at76c503.c - 478 */
468 return atu_usb_request(sc, UT_READ_VENDOR_INTERFACE(0x80 | 0x40 | 0x01), 0x033,
469 type << 8, index, size, buf);
470}
471
472#if 0
473int
474atu_start_ibss(struct atu_softc *sc)
475{
476 int err;
477 struct atu_cmd_start_ibss Request;
478
479 Request.Cmd = CMD_START_IBSS0x05;
480 Request.Reserved = 0;
481 Request.Size = sizeof(Request) - 4;
482
483 memset(Request.BSSID, 0x00, sizeof(Request.BSSID))__builtin_memset((Request.BSSID), (0x00), (sizeof(Request.BSSID
)))
;
484 memset(Request.SSID, 0x00, sizeof(Request.SSID))__builtin_memset((Request.SSID), (0x00), (sizeof(Request.SSID
)))
;
485 memcpy(Request.SSID, sc->atu_ssid, sc->atu_ssidlen)__builtin_memcpy((Request.SSID), (sc->atu_ssid), (sc->atu_ssidlen
))
;
486 Request.SSIDSize = sc->atu_ssidlen;
487 if (sc->atu_desired_channel != IEEE80211_CHAN_ANY0xffff)
488 Request.Channel = (u_int8_t)sc->atu_desired_channel;
489 else
490 Request.Channel = ATU_DEFAULT_CHANNEL10;
491 Request.BSSType = AD_HOC_MODE1;
492 memset(Request.Res, 0x00, sizeof(Request.Res))__builtin_memset((Request.Res), (0x00), (sizeof(Request.Res))
)
;
493
494 /* Write config to adapter */
495 err = atu_send_command(sc, (u_int8_t *)&Request, sizeof(Request));
496 if (err) {
497 DPRINTF(("%s: start ibss failed!\n",
498 sc->atu_dev.dv_xname));
499 return err;
500 }
501
502 /* Wait for the adapter to do its thing */
503 err = atu_wait_completion(sc, CMD_START_IBSS0x05, NULL((void *)0));
504 if (err) {
505 DPRINTF(("%s: error waiting for start_ibss\n",
506 sc->atu_dev.dv_xname));
507 return err;
508 }
509
510 /* Get the current BSSID */
511 err = atu_get_mib(sc, MIB_MAC_MGMT__CURRENT_BSSID0x05, 6, 14, sc->atu_bssid);
512 if (err) {
513 DPRINTF(("%s: could not get BSSID!\n",
514 sc->atu_dev.dv_xname));
515 return err;
516 }
517
518 DPRINTF(("%s: started a new IBSS (BSSID=%s)\n",
519 sc->atu_dev.dv_xname, ether_sprintf(sc->atu_bssid)));
520 return 0;
521}
522#endif
523
524int
525atu_start_scan(struct atu_softc *sc)
526{
527 struct ieee80211com *ic = &sc->sc_ic;
528 struct atu_cmd_do_scan Scan;
529 usbd_status err;
530 int Cnt;
531
532 memset(&Scan, 0, sizeof(Scan))__builtin_memset((&Scan), (0), (sizeof(Scan)));
533
534 Scan.Cmd = CMD_START_SCAN0x03;
535 Scan.Reserved = 0;
536 USETW(Scan.Size, sizeof(Scan) - 4)(*(u_int16_t *)(Scan.Size) = (sizeof(Scan) - 4));
537
538 /* use the broadcast BSSID (in active scan) */
539 for (Cnt=0; Cnt<6; Cnt++)
540 Scan.BSSID[Cnt] = 0xff;
541
542 memcpy(Scan.SSID, ic->ic_des_essid, ic->ic_des_esslen)__builtin_memcpy((Scan.SSID), (ic->ic_des_essid), (ic->
ic_des_esslen))
;
543 Scan.SSID_Len = ic->ic_des_esslen;
544
545 /* default values for scan */
546 Scan.ScanType = ATU_SCAN_ACTIVE0x00;
547 if (sc->atu_desired_channel != IEEE80211_CHAN_ANY0xffff)
548 Scan.Channel = (u_int8_t)sc->atu_desired_channel;
549 else
550 Scan.Channel = sc->atu_channel;
551
552 /* we like scans to be quick :) */
553 /* the time we wait before sending probe's */
554 USETW(Scan.ProbeDelay, 0)(*(u_int16_t *)(Scan.ProbeDelay) = (0));
555 /* the time we stay on one channel */
556 USETW(Scan.MinChannelTime, 100)(*(u_int16_t *)(Scan.MinChannelTime) = (100));
557 USETW(Scan.MaxChannelTime, 200)(*(u_int16_t *)(Scan.MaxChannelTime) = (200));
558 /* whether or not we scan all channels */
559 Scan.InternationalScan = 0xc1;
560
561#ifdef ATU_DEBUG
562 if (atudebug) {
563 DPRINTFN(20, ("%s: scan cmd len=%02x\n",
564 sc->atu_dev.dv_xname, sizeof(Scan)));
565 DPRINTFN(20, ("%s: scan cmd: %52D\n", sc->atu_dev.dv_xname,
566 (u_int8_t *)&Scan, " "));
567 }
568#endif /* ATU_DEBUG */
569
570 /* Write config to adapter */
571 err = atu_send_command(sc, (u_int8_t *)&Scan, sizeof(Scan));
572 if (err)
573 return err;
574
575 /*
576 * We don't wait for the command to finish... the mgmt-thread will do
577 * that for us
578 */
579 /*
580 err = atu_wait_completion(sc, CMD_START_SCAN, NULL);
581 if (err)
582 return err;
583 */
584 return 0;
585}
586
587int
588atu_switch_radio(struct atu_softc *sc, int state)
589{
590 usbd_status err;
591 struct atu_cmd CmdRadio;
592
593 if (sc->atu_radio == RadioIntersil) {
594 /*
595 * Intersil doesn't seem to need/support switching the radio
596 * on/off
597 */
598 return 0;
599 }
600
601 memset(&CmdRadio, 0, sizeof(CmdRadio))__builtin_memset((&CmdRadio), (0), (sizeof(CmdRadio)));
602 CmdRadio.Cmd = CMD_RADIO_ON0x06;
603
604 if (sc->atu_radio_on != state) {
605 if (state == 0)
606 CmdRadio.Cmd = CMD_RADIO_OFF0x07;
607
608 err = atu_send_command(sc, (u_int8_t *)&CmdRadio,
609 sizeof(CmdRadio));
610 if (err)
611 return err;
612
613 err = atu_wait_completion(sc, CmdRadio.Cmd, NULL((void *)0));
614 if (err)
615 return err;
616
617 DPRINTFN(10, ("%s: radio turned %s\n",
618 sc->atu_dev.dv_xname, state ? "on" : "off"));
619 sc->atu_radio_on = state;
620 }
621 return 0;
622}
623
624int
625atu_initial_config(struct atu_softc *sc)
626{
627 struct ieee80211com *ic = &sc->sc_ic;
628 u_int32_t i;
629 usbd_status err;
630/* u_int8_t rates[4] = {0x82, 0x84, 0x8B, 0x96};*/
631 u_int8_t rates[4] = {0x82, 0x04, 0x0B, 0x16};
632 struct atu_cmd_card_config cmd;
633 u_int8_t reg_domain;
634
635 DPRINTFN(10, ("%s: sending mac-addr\n", sc->atu_dev.dv_xname));
636 err = atu_send_mib(sc, MIB_MAC_ADDR__ADDR0x02, 6, 0, ic->ic_myaddr);
637 if (err) {
638 DPRINTF(("%s: error setting mac-addr\n",
639 sc->atu_dev.dv_xname));
640 return err;
641 }
642
643 /*
644 DPRINTF(("%s: sending reg-domain\n", sc->atu_dev.dv_xname));
645 err = atu_send_mib(sc, MIB_PHY__REG_DOMAIN, NR(0x30));
646 if (err) {
647 DPRINTF(("%s: error setting mac-addr\n",
648 sc->atu_dev.dv_xname));
649 return err;
650 }
651 */
652
653 memset(&cmd, 0, sizeof(cmd))__builtin_memset((&cmd), (0), (sizeof(cmd)));
654 cmd.Cmd = CMD_STARTUP0x0b;
655 cmd.Reserved = 0;
656 USETW(cmd.Size, sizeof(cmd) - 4)(*(u_int16_t *)(cmd.Size) = (sizeof(cmd) - 4));
657
658 if (sc->atu_desired_channel != IEEE80211_CHAN_ANY0xffff)
659 cmd.Channel = (u_int8_t)sc->atu_desired_channel;
660 else
661 cmd.Channel = sc->atu_channel;
662 cmd.AutoRateFallback = 1;
663 memcpy(cmd.BasicRateSet, rates, 4)__builtin_memcpy((cmd.BasicRateSet), (rates), (4));
664
665 /* ShortRetryLimit should be 7 according to 802.11 spec */
666 cmd.ShortRetryLimit = 7;
667 USETW(cmd.RTS_Threshold, 2347)(*(u_int16_t *)(cmd.RTS_Threshold) = (2347));
668 USETW(cmd.FragThreshold, 2346)(*(u_int16_t *)(cmd.FragThreshold) = (2346));
669
670 /* Doesn't seem to work, but we'll set it to 1 anyway */
671 cmd.PromiscuousMode = 1;
672
673 /* this goes into the beacon we transmit */
674 cmd.PrivacyInvoked = (ic->ic_flags & IEEE80211_F_WEPON0x00000100) ? 1 : 0;
675
676 cmd.ExcludeUnencrypted = 0;
677 switch (ic->ic_nw_keys[ic->ic_wep_txkeyic_def_txkey].k_cipher) {
678 case IEEE80211_CIPHER_WEP40:
679 cmd.EncryptionType = ATU_WEP_40BITS1;
680 break;
681 case IEEE80211_CIPHER_WEP104:
682 cmd.EncryptionType = ATU_WEP_104BITS2;
683 break;
684 default:
685 cmd.EncryptionType = ATU_WEP_OFF0;
686 break;
687 }
688
689 cmd.WEP_DefaultKeyID = ic->ic_wep_txkeyic_def_txkey;
690 for (i = 0; i < IEEE80211_WEP_NKID4; i++) {
691 memcpy(cmd.WEP_DefaultKey[i], ic->ic_nw_keys[i].k_key,__builtin_memcpy((cmd.WEP_DefaultKey[i]), (ic->ic_nw_keys[
i].k_key), (ic->ic_nw_keys[i].k_len))
692 ic->ic_nw_keys[i].k_len)__builtin_memcpy((cmd.WEP_DefaultKey[i]), (ic->ic_nw_keys[
i].k_key), (ic->ic_nw_keys[i].k_len))
;
693 }
694
695 /* Setting the SSID here doesn't seem to do anything */
696 memcpy(cmd.SSID, ic->ic_des_essid, ic->ic_des_esslen)__builtin_memcpy((cmd.SSID), (ic->ic_des_essid), (ic->ic_des_esslen
))
;
697 cmd.SSID_Len = ic->ic_des_esslen;
698
699 cmd.ShortPreamble = 0;
700 USETW(cmd.BeaconPeriod, 100)(*(u_int16_t *)(cmd.BeaconPeriod) = (100));
701 /* cmd.BeaconPeriod = 65535; */
702
703 /*
704 * TODO:
705 * read reg domain MIB_PHY @ 0x17 (1 byte), (reply = 0x30)
706 * we should do something useful with this info. right now it's just
707 * ignored
708 */
709 err = atu_get_mib(sc, MIB_PHY__REG_DOMAIN0x07, 1, 23, &reg_domain);
710 if (err) {
711 DPRINTF(("%s: could not get regdomain!\n",
712 sc->atu_dev.dv_xname));
713 } else {
714 DPRINTF(("%s: we're in reg domain 0x%x according to the "
715 "adapter\n", sc->atu_dev.dv_xname, reg_domain));
716 }
717
718#ifdef ATU_DEBUG
719 if (atudebug) {
720 DPRINTFN(20, ("%s: configlen=%02x\n", sc->atu_dev.dv_xname,
721 sizeof(cmd)));
722 DPRINTFN(20, ("%s: configdata= %108D\n",
723 sc->atu_dev.dv_xname, (u_int8_t *)&cmd, " "));
724 }
725#endif /* ATU_DEBUG */
726
727 /* Windoze : driver says exclude-unencrypted=1 & encr-type=1 */
728
729 err = atu_send_command(sc, (u_int8_t *)&cmd, sizeof(cmd));
730 if (err)
731 return err;
732 err = atu_wait_completion(sc, CMD_STARTUP0x0b, NULL((void *)0));
733 if (err)
734 return err;
735
736 /* Turn on radio now */
737 err = atu_switch_radio(sc, 1);
738 if (err)
739 return err;
740
741 /* preamble type = short */
742 err = atu_send_mib(sc, MIB_LOCAL__PREAMBLE0x01, 1, 9, NR(PREAMBLE_SHORT)(void *)((long)1));
743 if (err)
744 return err;
745
746 /* frag = 1536 */
747 err = atu_send_mib(sc, MIB_MAC__FRAG0x03, 2, 8, NR(2346)(void *)((long)2346));
748 if (err)
749 return err;
750
751 /* rts = 1536 */
752 err = atu_send_mib(sc, MIB_MAC__RTS0x03, 2, 10, NR(2347)(void *)((long)2347));
753 if (err)
754 return err;
755
756 /* auto rate fallback = 1 */
757 err = atu_send_mib(sc, MIB_LOCAL__AUTO_RATE_FALLBACK0x01, 1, 3, NR(1)(void *)((long)1));
758 if (err)
759 return err;
760
761 /* power mode = full on, no power saving */
762 err = atu_send_mib(sc, MIB_MAC_MGMT__POWER_MODE0x05, 1, 53,
763 NR(POWER_MODE_ACTIVE)(void *)((long)1));
764 if (err)
765 return err;
766
767 DPRINTFN(10, ("%s: completed initial config\n",
768 sc->atu_dev.dv_xname));
769 return 0;
770}
771
772int
773atu_join(struct atu_softc *sc, struct ieee80211_node *node)
774{
775 struct atu_cmd_join join;
776 u_int8_t status;
777 usbd_status err;
778
779 memset(&join, 0, sizeof(join))__builtin_memset((&join), (0), (sizeof(join)));
780
781 join.Cmd = CMD_JOIN0x04;
782 join.Reserved = 0x00;
783 USETW(join.Size, sizeof(join) - 4)(*(u_int16_t *)(join.Size) = (sizeof(join) - 4));
784
785 DPRINTFN(15, ("%s: pre-join sc->atu_bssid=%s\n",
786 sc->atu_dev.dv_xname, ether_sprintf(sc->atu_bssid)));
787 DPRINTFN(15, ("%s: mode=%d\n", sc->atu_dev.dv_xname,
788 sc->atu_mode));
789 memcpy(join.bssid, node->ni_bssid, IEEE80211_ADDR_LEN)__builtin_memcpy((join.bssid), (node->ni_bssid), (6));
790 memcpy(join.essid, node->ni_essid, node->ni_esslen)__builtin_memcpy((join.essid), (node->ni_essid), (node->
ni_esslen))
;
791 join.essid_size = node->ni_esslen;
792 if (node->ni_capinfo & IEEE80211_CAPINFO_IBSS0x0002)
793 join.bss_type = AD_HOC_MODE1;
794 else
795 join.bss_type = INFRASTRUCTURE_MODE2;
796 join.channel = ieee80211_chan2ieee(&sc->sc_ic, node->ni_chan);
797
798 USETW(join.timeout, ATU_JOIN_TIMEOUT)(*(u_int16_t *)(join.timeout) = (2000));
799 join.reserved = 0x00;
800
801 DPRINTFN(10, ("%s: trying to join BSSID=%s\n",
802 sc->atu_dev.dv_xname, ether_sprintf(join.bssid)));
803 err = atu_send_command(sc, (u_int8_t *)&join, sizeof(join));
804 if (err) {
805 DPRINTF(("%s: ERROR trying to join IBSS\n",
806 sc->atu_dev.dv_xname));
807 return err;
808 }
809 err = atu_wait_completion(sc, CMD_JOIN0x04, &status);
810 if (err) {
811 DPRINTF(("%s: error joining BSS!\n",
812 sc->atu_dev.dv_xname));
813 return err;
814 }
815 if (status != STATUS_COMPLETE0x01) {
816 DPRINTF(("%s: error joining... [status=%02x]\n",
817 sc->atu_dev.dv_xname, status));
818 return status;
819 } else {
820 DPRINTFN(10, ("%s: joined BSS\n", sc->atu_dev.dv_xname));
821 }
822 return err;
823}
824
825/*
826 * Get the state of the DFU unit
827 */
828int8_t
829atu_get_dfu_state(struct atu_softc *sc)
830{
831 u_int8_t state;
832
833 if (atu_usb_request(sc, DFU_GETSTATE(0x80 | 0x20 | 0x01), 0x05, 0, 0, 1, &state))
834 return -1;
835 return state;
836}
837
838/*
839 * Get MAC opmode
840 */
841u_int8_t
842atu_get_opmode(struct atu_softc *sc, u_int8_t *mode)
843{
844
845 return atu_usb_request(sc, UT_READ_VENDOR_INTERFACE(0x80 | 0x40 | 0x01), 0x33, 0x0001,
846 0x0000, 1, mode);
847}
848
849/*
850 * Upload the internal firmware into the device
851 */
852void
853atu_internal_firmware(struct device *self)
854{
855 struct atu_softc *sc = (struct atu_softc *)self;
856 u_char state, *ptr = NULL((void *)0), *firm = NULL((void *)0), status[6];
857 int block_size, block = 0, err, i;
858 size_t firm_len, bytes_left = 0;
859 char *name = "unknown-device";
860
861 /*
862 * Uploading firmware is done with the DFU (Device Firmware Upgrade)
863 * interface. See "Universal Serial Bus - Device Class Specification
864 * for Device Firmware Upgrade" pdf for details of the protocol.
865 * Maybe this could be moved to a separate 'firmware driver' once more
866 * device drivers need it... For now we'll just do it here.
867 *
868 * Just for your information, the Atmel's DFU descriptor looks like
869 * this:
870 *
871 * 07 size
872 * 21 type
873 * 01 capabilities : only firmware download, need reset
874 * after download
875 * 13 05 detach timeout : max 1299ms between DFU_DETACH and
876 * reset
877 * 00 04 max bytes of firmware per transaction : 1024
878 */
879
880 /* Choose the right firmware for the device */
881 for (i = 0; i < nitems(atu_radfirm)(sizeof((atu_radfirm)) / sizeof((atu_radfirm)[0])); i++)
882 if (sc->atu_radio == atu_radfirm[i].atur_type)
883 name = atu_radfirm[i].atur_internal;
884
885 DPRINTF(("%s: loading firmware %s...\n",
886 sc->atu_dev.dv_xname, name));
887 err = loadfirmware(name, &firm, &firm_len);
888 if (err != 0) {
889 printf("%s: %s loadfirmware error %d\n",
890 sc->atu_dev.dv_xname, name, err);
891 goto fail;
892 }
893
894 ptr = firm;
895 bytes_left = firm_len;
896 state = atu_get_dfu_state(sc);
897
898 while (block >= 0 && state > 0) {
899 switch (state) {
900 case DFUState_DnLoadSync3:
901 /* get DFU status */
902 err = atu_usb_request(sc, DFU_GETSTATUS(0x80 | 0x20 | 0x01), 0x03, 0, 0 , 6,
903 status);
904 if (err) {
905 DPRINTF(("%s: dfu_getstatus failed!\n",
906 sc->atu_dev.dv_xname));
907 free(firm, M_DEVBUF2, firm_len);
908 goto fail;
909 }
910 /* success means state => DnLoadIdle */
911 state = DFUState_DnLoadIdle5;
912 continue;
913 break;
914
915 case DFUState_DFUIdle2:
916 case DFUState_DnLoadIdle5:
917 if (bytes_left>=DFU_MaxBlockSize1024)
918 block_size = DFU_MaxBlockSize1024;
919 else
920 block_size = bytes_left;
921 DPRINTFN(15, ("%s: firmware block %d\n",
922 sc->atu_dev.dv_xname, block));
923
924 err = atu_usb_request(sc, DFU_DNLOAD(0x00 | 0x20 | 0x01), 0x01, block++, 0,
925 block_size, ptr);
926 if (err) {
927 DPRINTF(("%s: dfu_dnload failed\n",
928 sc->atu_dev.dv_xname));
929 free(firm, M_DEVBUF2, firm_len);
930 goto fail;
931 }
932
933 ptr += block_size;
934 bytes_left -= block_size;
935 if (block_size == 0)
936 block = -1;
937 break;
938
939 default:
940 DPRINTFN(20, ("%s: sleeping for a while\n",
941 sc->atu_dev.dv_xname));
942 usbd_delay_ms(sc->atu_udev, 100);
943 break;
944 }
945
946 state = atu_get_dfu_state(sc);
947 }
948 free(firm, M_DEVBUF2, firm_len);
949
950 if (state != DFUState_ManifestSync6) {
951 DPRINTF(("%s: state != manifestsync... eek!\n",
952 sc->atu_dev.dv_xname));
953 }
954
955 err = atu_usb_request(sc, DFU_GETSTATUS(0x80 | 0x20 | 0x01), 0x03, 0, 0, 6, status);
956 if (err) {
957 DPRINTF(("%s: dfu_getstatus failed!\n",
958 sc->atu_dev.dv_xname));
959 goto fail;
960 }
961
962 DPRINTFN(15, ("%s: sending remap\n", sc->atu_dev.dv_xname));
963 err = atu_usb_request(sc, DFU_REMAP(0x00 | 0x40 | 0x01), 0x0a, 0, 0, 0, NULL((void *)0));
964 if ((err) && (!ISSET(sc->atu_quirk, ATU_QUIRK_NO_REMAP)((sc->atu_quirk) & (0x0001)))) {
965 DPRINTF(("%s: remap failed!\n", sc->atu_dev.dv_xname));
966 goto fail;
967 }
968
969 /* after a lot of trying and measuring I found out the device needs
970 * about 56 milliseconds after sending the remap command before
971 * it's ready to communicate again. So we'll wait just a little bit
972 * longer than that to be sure...
973 */
974 usbd_delay_ms(sc->atu_udev, 56+100);
975
976 printf("%s: reattaching after firmware upload\n",
977 sc->atu_dev.dv_xname);
978 usb_needs_reattach(sc->atu_udev);
979
980fail:
981 usbd_deactivate(sc->atu_udev);
982}
983
984void
985atu_external_firmware(struct device *self)
986{
987 struct atu_softc *sc = (struct atu_softc *)self;
988 u_char *ptr = NULL((void *)0), *firm = NULL((void *)0);
989 int block_size, block = 0, err, i;
990 size_t firm_len, bytes_left = 0;
991 char *name = "unknown-device";
992
993 for (i = 0; i < nitems(atu_radfirm)(sizeof((atu_radfirm)) / sizeof((atu_radfirm)[0])); i++)
994 if (sc->atu_radio == atu_radfirm[i].atur_type)
995 name = atu_radfirm[i].atur_external;
996
997 DPRINTF(("%s: loading external firmware %s\n",
998 sc->atu_dev.dv_xname, name));
999 err = loadfirmware(name, &firm, &firm_len);
1000 if (err != 0) {
1001 printf("%s: %s loadfirmware error %d\n",
1002 sc->atu_dev.dv_xname, name, err);
1003 return;
1004 }
1005 ptr = firm;
1006 bytes_left = firm_len;
1007
1008 while (bytes_left) {
1009 if (bytes_left > 1024)
1010 block_size = 1024;
1011 else
1012 block_size = bytes_left;
1013
1014 DPRINTFN(15, ("%s: block:%d size:%d\n",
1015 sc->atu_dev.dv_xname, block, block_size));
1016 err = atu_usb_request(sc, UT_WRITE_VENDOR_DEVICE(0x00 | 0x40 | 0x00), 0x0e,
1017 0x0802, block, block_size, ptr);
1018 if (err) {
1019 DPRINTF(("%s: could not load external firmware "
1020 "block\n", sc->atu_dev.dv_xname));
1021 free(firm, M_DEVBUF2, firm_len);
1022 return;
1023 }
1024
1025 ptr += block_size;
1026 block++;
1027 bytes_left -= block_size;
1028 }
1029 free(firm, M_DEVBUF2, firm_len);
1030
1031 err = atu_usb_request(sc, UT_WRITE_VENDOR_DEVICE(0x00 | 0x40 | 0x00), 0x0e, 0x0802,
1032 block, 0, NULL((void *)0));
1033 if (err) {
1034 DPRINTF(("%s: could not load last zero-length firmware "
1035 "block\n", sc->atu_dev.dv_xname));
1036 return;
1037 }
1038
1039 /*
1040 * The SMC2662w V.4 seems to require some time to do its thing with
1041 * the external firmware... 20 ms isn't enough, but 21 ms works 100
1042 * times out of 100 tries. We'll wait a bit longer just to be sure
1043 */
1044 if (sc->atu_quirk & ATU_QUIRK_FW_DELAY0x0002)
1045 usbd_delay_ms(sc->atu_udev, 21 + 100);
1046
1047 DPRINTFN(10, ("%s: external firmware upload done\n",
1048 sc->atu_dev.dv_xname));
1049 /* complete configuration after the firmwares have been uploaded */
1050 atu_complete_attach(sc);
1051}
1052
1053int
1054atu_get_card_config(struct atu_softc *sc)
1055{
1056 struct ieee80211com *ic = &sc->sc_ic;
1057 struct atu_rfmd_conf rfmd_conf;
1058 struct atu_intersil_conf intersil_conf;
1059 int err;
1060
1061 switch (sc->atu_radio) {
1062
1063 case RadioRFMD:
1064 case RadioRFMD2958:
1065 case RadioRFMD2958_SMC:
1066 case AT76C503_rfmd_acc:
1067 case AT76C505_rfmd:
1068 err = atu_usb_request(sc, UT_READ_VENDOR_INTERFACE(0x80 | 0x40 | 0x01), 0x33,
1069 0x0a02, 0x0000, sizeof(rfmd_conf),
1070 (u_int8_t *)&rfmd_conf);
1071 if (err) {
1072 DPRINTF(("%s: could not get rfmd config!\n",
1073 sc->atu_dev.dv_xname));
1074 return err;
1075 }
1076 memcpy(ic->ic_myaddr, rfmd_conf.MACAddr, IEEE80211_ADDR_LEN)__builtin_memcpy((ic->ic_myaddr), (rfmd_conf.MACAddr), (6)
)
;
1077 break;
1078
1079 case RadioIntersil:
1080 case AT76C503_i3863:
1081 err = atu_usb_request(sc, UT_READ_VENDOR_INTERFACE(0x80 | 0x40 | 0x01), 0x33,
1082 0x0902, 0x0000, sizeof(intersil_conf),
1083 (u_int8_t *)&intersil_conf);
1084 if (err) {
1085 DPRINTF(("%s: could not get intersil config!\n",
1086 sc->atu_dev.dv_xname));
1087 return err;
1088 }
1089 memcpy(ic->ic_myaddr, intersil_conf.MACAddr,__builtin_memcpy((ic->ic_myaddr), (intersil_conf.MACAddr),
(6))
1090 IEEE80211_ADDR_LEN)__builtin_memcpy((ic->ic_myaddr), (intersil_conf.MACAddr),
(6))
;
1091 break;
1092 }
1093 return 0;
1094}
1095
1096/*
1097 * Probe for an AT76c503 chip.
1098 */
1099int
1100atu_match(struct device *parent, void *match, void *aux)
1101{
1102 struct usb_attach_arg *uaa = aux;
1103 int i;
1104
1105 if (uaa->iface == NULL((void *)0) || uaa->configno != ATU_CONFIG_NO1)
1106 return(UMATCH_NONE0);
1107
1108 for (i = 0; i < nitems(atu_devs)(sizeof((atu_devs)) / sizeof((atu_devs)[0])); i++) {
1109 struct atu_type *t = &atu_devs[i];
1110
1111 if (uaa->vendor == t->atu_vid &&
1112 uaa->product == t->atu_pid) {
1113 return(UMATCH_VENDOR_PRODUCT13);
1114 }
1115 }
1116 return(UMATCH_NONE0);
1117}
1118
1119int
1120atu_media_change(struct ifnet *ifp)
1121{
1122#ifdef ATU_DEBUG
1123 struct atu_softc *sc = ifp->if_softc;
1124#endif /* ATU_DEBUG */
1125 int err;
1126
1127 DPRINTFN(10, ("%s: atu_media_change\n", sc->atu_dev.dv_xname));
1128
1129 err = ieee80211_media_change(ifp);
1130 if (err == ENETRESET52) {
1131 if ((ifp->if_flags & (IFF_RUNNING0x40|IFF_UP0x1)) ==
1132 (IFF_RUNNING0x40|IFF_UP0x1))
1133 atu_init(ifp);
1134 err = 0;
1135 }
1136
1137 return (err);
1138}
1139
1140void
1141atu_media_status(struct ifnet *ifp, struct ifmediareq *req)
1142{
1143#ifdef ATU_DEBUG
1144 struct atu_softc *sc = ifp->if_softc;
1145#endif /* ATU_DEBUG */
1146
1147 DPRINTFN(10, ("%s: atu_media_status\n", sc->atu_dev.dv_xname));
1148
1149 ieee80211_media_status(ifp, req);
1150}
1151
1152void
1153atu_task(void *arg)
1154{
1155 struct atu_softc *sc = (struct atu_softc *)arg;
1156 struct ieee80211com *ic = &sc->sc_ic;
1157 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
1158 usbd_status err;
1159 int s;
1160
1161 DPRINTFN(10, ("%s: atu_task\n", sc->atu_dev.dv_xname));
1162
1163 if (usbd_is_dying(sc->atu_udev))
1164 return;
1165
1166 switch (sc->sc_cmd) {
1167 case ATU_C_SCAN1:
1168
1169 err = atu_start_scan(sc);
1170 if (err) {
1171 DPRINTFN(1, ("%s: atu_init: couldn't start scan!\n",
1172 sc->atu_dev.dv_xname));
1173 return;
1174 }
1175
1176 err = atu_wait_completion(sc, CMD_START_SCAN0x03, NULL((void *)0));
1177 if (err) {
1178 DPRINTF(("%s: atu_init: error waiting for scan\n",
1179 sc->atu_dev.dv_xname));
1180 return;
1181 }
1182
1183 DPRINTF(("%s: ==========================> END OF SCAN!\n",
1184 sc->atu_dev.dv_xname));
1185
1186 s = splnet()splraise(0x7);
1187 /* ieee80211_next_scan(ifp); */
1188 ieee80211_end_scan(ifp);
1189 splx(s)spllower(s);
1190
1191 DPRINTF(("%s: ----------------------======> END OF SCAN2!\n",
1192 sc->atu_dev.dv_xname));
1193 break;
1194
1195 case ATU_C_JOIN2:
1196 atu_join(sc, ic->ic_bss);
1197 }
1198}
1199
1200int
1201atu_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
1202{
1203 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
1204 struct atu_softc *sc = ifp->if_softc;
1205 enum ieee80211_state ostate = ic->ic_state;
1206
1207 switch (nstate) {
1208 case IEEE80211_S_SCAN:
1209 memcpy(ic->ic_chan_scan, ic->ic_chan_active,__builtin_memcpy((ic->ic_chan_scan), (ic->ic_chan_active
), (sizeof(ic->ic_chan_active)))
1210 sizeof(ic->ic_chan_active))__builtin_memcpy((ic->ic_chan_scan), (ic->ic_chan_active
), (sizeof(ic->ic_chan_active)))
;
1211 ieee80211_node_cleanup(ic, ic->ic_bss);
1212
1213 /* tell the event thread that we want a scan */
1214 sc->sc_cmd = ATU_C_SCAN1;
1215 usb_add_task(sc->atu_udev, &sc->sc_task);
1216
1217 /* handle this ourselves */
1218 if (ifp->if_flags & IFF_DEBUG0x4)
1219 printf("%s: %s -> %s\n", ifp->if_xname,
1220 ieee80211_state_name[ic->ic_state],
1221 ieee80211_state_name[nstate]);
1222 ieee80211_set_link_state(ic, LINK_STATE_DOWN2);
1223 ic->ic_state = nstate;
1224 return (0);
1225
1226 case IEEE80211_S_AUTH:
1227 case IEEE80211_S_RUN:
1228 if (ostate == IEEE80211_S_SCAN) {
1229 sc->sc_cmd = ATU_C_JOIN2;
1230 usb_add_task(sc->atu_udev, &sc->sc_task);
1231 }
1232 break;
1233 default:
1234 /* nothing to do */
1235 break;
1236 }
1237
1238 return (*sc->sc_newstate)(ic, nstate, arg);
1239}
1240
1241/*
1242 * Attach the interface. Allocate softc structures, do
1243 * setup and ethernet/BPF attach.
1244 */
1245void
1246atu_attach(struct device *parent, struct device *self, void *aux)
1247{
1248 struct atu_softc *sc = (struct atu_softc *)self;
1249 struct usb_attach_arg *uaa = aux;
1250 usbd_status err;
1251 struct usbd_device *dev = uaa->device;
1252 u_int8_t mode, channel;
1253 int i;
1254
1255 sc->atu_unit = self->dv_unit;
1256 sc->atu_udev = dev;
1257
1258 err = usbd_device2interface_handle(dev, ATU_IFACE_IDX0, &sc->atu_iface);
1259 if (err) {
1260 printf("%s: getting interface handle failed\n",
1261 sc->atu_dev.dv_xname);
1262 goto fail;
1263 }
1264
1265 /*
1266 * look up the radio_type for the device
1267 * basically does the same as USB_MATCH
1268 */
1269 for (i = 0; i < nitems(atu_devs)(sizeof((atu_devs)) / sizeof((atu_devs)[0])); i++) {
1270 struct atu_type *t = &atu_devs[i];
1271
1272 if (uaa->vendor == t->atu_vid &&
1273 uaa->product == t->atu_pid) {
1274 sc->atu_radio = t->atu_radio;
1275 sc->atu_quirk = t->atu_quirk;
1276 }
1277 }
1278
1279 /*
1280 * Check in the interface descriptor if we're in DFU mode
1281 * If we're in DFU mode, we upload the external firmware
1282 * If we're not, the PC must have rebooted without power-cycling
1283 * the device. I've tried this out, a reboot only requires the
1284 * external firmware to be reloaded :)
1285 *
1286 * Hmm. The at76c505a doesn't report a DFU descriptor when it's
1287 * in DFU mode... Let's just try to get the opmode
1288 */
1289 err = atu_get_opmode(sc, &mode);
1290 DPRINTFN(20, ("%s: opmode: %d\n", sc->atu_dev.dv_xname, mode));
1291 if (err || (mode != MODE_NETCARD0x01 && mode != MODE_NOFLASHNETCARD0x04)) {
1292 DPRINTF(("%s: starting internal firmware download\n",
1293 sc->atu_dev.dv_xname));
1294
1295 config_mountroot(self, atu_internal_firmware);
1296 /*
1297 * atu_internal_firmware will cause a reset of the device
1298 * so we don't want to do any more configuration after this
1299 * point.
1300 */
1301 return;
1302 }
1303
1304 uaa->iface = sc->atu_iface;
1305
1306 if (mode != MODE_NETCARD0x01) {
1307 DPRINTFN(15, ("%s: device needs external firmware\n",
1308 sc->atu_dev.dv_xname));
1309
1310 if (mode != MODE_NOFLASHNETCARD0x04) {
1311 DPRINTF(("%s: EEK! unexpected opmode=%d\n",
1312 sc->atu_dev.dv_xname, mode));
1313 }
1314
1315 /*
1316 * There is no difference in opmode before and after external
1317 * firmware upload with the SMC2662 V.4 . So instead we'll try
1318 * to read the channel number. If we succeed, external
1319 * firmwaremust have been already uploaded...
1320 */
1321 if (sc->atu_radio != RadioIntersil) {
1322 err = atu_get_mib(sc, MIB_PHY__CHANNEL0x07, 1, 20, &channel);
1323 if (!err) {
1324 DPRINTF(("%s: external firmware has already"
1325 " been downloaded\n",
1326 sc->atu_dev.dv_xname));
1327 atu_complete_attach(sc);
1328 return;
1329 }
1330 }
1331
1332 config_mountroot(self, atu_external_firmware);
1333
1334 /*
1335 * atu_external_firmware will call atu_complete_attach after
1336 * it's finished so we can just return.
1337 */
1338 } else {
1339 /* all the firmwares are in place, so complete the attach */
1340 atu_complete_attach(sc);
1341 }
1342fail:
1343 usbd_deactivate(sc->atu_udev);
1344}
1345
1346void
1347atu_complete_attach(struct atu_softc *sc)
1348{
1349 struct ieee80211com *ic = &sc->sc_ic;
1350 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
1351 usb_interface_descriptor_t *id;
1352 usb_endpoint_descriptor_t *ed;
1353 usbd_status err;
1354 int i;
1355#ifdef ATU_DEBUG
1356 struct atu_fw fw;
1357#endif
1358
1359 id = usbd_get_interface_descriptor(sc->atu_iface);
1360
1361 /* Find endpoints. */
1362 for (i = 0; i < id->bNumEndpoints; i++) {
1363 ed = usbd_interface2endpoint_descriptor(sc->atu_iface, i);
1364 if (!ed) {
1365 DPRINTF(("%s: num_endp:%d\n", sc->atu_dev.dv_xname,
1366 sc->atu_iface->idesc->bNumEndpoints));
1367 DPRINTF(("%s: couldn't get ep %d\n",
1368 sc->atu_dev.dv_xname, i));
1369 goto fail;
1370 }
1371 if (UE_GET_DIR(ed->bEndpointAddress)((ed->bEndpointAddress) & 0x80) == UE_DIR_IN0x80 &&
1372 UE_GET_XFERTYPE(ed->bmAttributes)((ed->bmAttributes) & 0x03) == UE_BULK0x02) {
1373 sc->atu_ed[ATU_ENDPT_RX0x0] = ed->bEndpointAddress;
1374 } else if (UE_GET_DIR(ed->bEndpointAddress)((ed->bEndpointAddress) & 0x80) == UE_DIR_OUT0x00 &&
1375 UE_GET_XFERTYPE(ed->bmAttributes)((ed->bmAttributes) & 0x03) == UE_BULK0x02) {
1376 sc->atu_ed[ATU_ENDPT_TX0x1] = ed->bEndpointAddress;
1377 }
1378 }
1379
1380 /* read device config & get MAC address */
1381 err = atu_get_card_config(sc);
1382 if (err) {
1383 printf("%s: could not get card cfg!\n",
1384 sc->atu_dev.dv_xname);
1385 goto fail;
1386 }
1387
1388#ifdef ATU_DEBUG
1389 /* DEBUG : try to get firmware version */
1390 err = atu_get_mib(sc, MIB_FW_VERSION0x08, sizeof(fw), 0,
1391 (u_int8_t *)&fw);
1392 if (!err) {
1393 DPRINTFN(15, ("%s: firmware: maj:%d min:%d patch:%d "
1394 "build:%d\n", sc->atu_dev.dv_xname, fw.major, fw.minor,
1395 fw.patch, fw.build));
1396 } else {
1397 DPRINTF(("%s: get firmware version failed\n",
1398 sc->atu_dev.dv_xname));
1399 }
1400#endif /* ATU_DEBUG */
1401
1402 /* Show the world our MAC address */
1403 printf("%s: address %s\n", sc->atu_dev.dv_xname,
1404 ether_sprintf(ic->ic_myaddr));
1405
1406 sc->atu_cdata.atu_tx_inuse = 0;
1407
1408 bzero(sc->atu_bssid, ETHER_ADDR_LEN)__builtin_bzero((sc->atu_bssid), (6));
1409 sc->atu_channel = ATU_DEFAULT_CHANNEL10;
1410 sc->atu_desired_channel = IEEE80211_CHAN_ANY0xffff;
1411 sc->atu_mode = INFRASTRUCTURE_MODE2;
1412
1413 ic->ic_softcic_ac.ac_if.if_softc = sc;
1414 ic->ic_phytype = IEEE80211_T_DS;
1415 ic->ic_opmode = IEEE80211_M_STA;
1416 ic->ic_state = IEEE80211_S_INIT;
1417 ic->ic_caps = IEEE80211_C_IBSS0x00000002 | IEEE80211_C_WEP0x00000001 | IEEE80211_C_SCANALL0x00000400;
1418 ic->ic_max_rssi = atu_radfirm[sc->atu_radio].max_rssi;
1419
1420 ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
1421
1422 for (i = 1; i <= 14; i++) {
1423 ic->ic_channels[i].ic_flags = IEEE80211_CHAN_B(0x0080 | 0x0020) |
1424 IEEE80211_CHAN_PASSIVE0x0200;
1425 ic->ic_channels[i].ic_freq = ieee80211_ieee2mhz(i,
1426 ic->ic_channels[i].ic_flags);
1427 }
1428
1429 ic->ic_ibss_chan = &ic->ic_channels[0];
1430
1431 ifp->if_softc = sc;
1432 memcpy(ifp->if_xname, sc->atu_dev.dv_xname, IFNAMSIZ)__builtin_memcpy((ifp->if_xname), (sc->atu_dev.dv_xname
), (16))
;
1433 ifp->if_flags = IFF_BROADCAST0x2 | IFF_SIMPLEX0x800 | IFF_MULTICAST0x8000;
1434 ifp->if_start = atu_start;
1435 ifp->if_ioctl = atu_ioctl;
1436 ifp->if_watchdog = atu_watchdog;
1437 ifp->if_mtuif_data.ifi_mtu = ATU_DEFAULT_MTU1500;
1438
1439 /* Call MI attach routine. */
1440 if_attach(ifp);
1441 ieee80211_ifattach(ifp);
1442
1443 sc->sc_newstate = ic->ic_newstate;
1444 ic->ic_newstate = atu_newstate;
1445
1446 /* setup ifmedia interface */
1447 ieee80211_media_init(ifp, atu_media_change, atu_media_status);
1448
1449 usb_init_task(&sc->sc_task, atu_task, sc, USB_TASK_TYPE_GENERIC)((&sc->sc_task)->fun = (atu_task), (&sc->sc_task
)->arg = (sc), (&sc->sc_task)->type = (0), (&
sc->sc_task)->state = 0x0)
;
1450
1451#if NBPFILTER1 > 0
1452 bpfattach(&sc->sc_radiobpf, &sc->sc_ic.ic_ific_ac.ac_if, DLT_IEEE802_11_RADIO127,
1453 sizeof(struct ieee80211_frame) + 64);
1454
1455 bzero(&sc->sc_rxtapu, sizeof(sc->sc_rxtapu))__builtin_bzero((&sc->sc_rxtapu), (sizeof(sc->sc_rxtapu
)))
;
1456 sc->sc_rxtapsc_rxtapu.tap.rr_ihdr.it_len = sizeof(sc->sc_rxtapu);
1457 sc->sc_rxtapsc_rxtapu.tap.rr_ihdr.it_present = htole32(ATU_RX_RADIOTAP_PRESENT)((__uint32_t)(((1 << IEEE80211_RADIOTAP_TSFT) | (1 <<
IEEE80211_RADIOTAP_FLAGS) | (1 << IEEE80211_RADIOTAP_RATE
) | (1 << IEEE80211_RADIOTAP_CHANNEL) | (1 << IEEE80211_RADIOTAP_LOCK_QUALITY
) | (1 << IEEE80211_RADIOTAP_RSSI) | 0)))
;
1458
1459 bzero(&sc->sc_txtapu, sizeof(sc->sc_txtapu))__builtin_bzero((&sc->sc_txtapu), (sizeof(sc->sc_txtapu
)))
;
1460 sc->sc_txtapsc_txtapu.tap.rt_ihdr.it_len = sizeof(sc->sc_txtapu);
1461 sc->sc_txtapsc_txtapu.tap.rt_ihdr.it_present = htole32(ATU_TX_RADIOTAP_PRESENT)((__uint32_t)(((1 << IEEE80211_RADIOTAP_FLAGS) | (1 <<
IEEE80211_RADIOTAP_RATE) | (1 << IEEE80211_RADIOTAP_CHANNEL
) | 0)))
;
1462#endif
1463
1464fail:
1465 usbd_deactivate(sc->atu_udev);
1466}
1467
1468int
1469atu_detach(struct device *self, int flags)
1470{
1471 struct atu_softc *sc = (struct atu_softc *)self;
1472 struct ifnet *ifp = &sc->sc_ic.ic_ific_ac.ac_if;
1473
1474 DPRINTFN(10, ("%s: atu_detach\n", sc->atu_dev.dv_xname));
1475
1476 if (ifp->if_flags & IFF_RUNNING0x40)
1477 atu_stop(ifp, 1);
1478
1479 usb_rem_task(sc->atu_udev, &sc->sc_task);
1480
1481 if (sc->atu_ep[ATU_ENDPT_TX0x1] != NULL((void *)0))
1482 usbd_abort_pipe(sc->atu_ep[ATU_ENDPT_TX0x1]);
1483 if (sc->atu_ep[ATU_ENDPT_RX0x0] != NULL((void *)0))
1484 usbd_abort_pipe(sc->atu_ep[ATU_ENDPT_RX0x0]);
1485
1486 if (ifp->if_softc != NULL((void *)0)) {
1487 ieee80211_ifdetach(ifp);
1488 if_detach(ifp);
1489 }
1490
1491 return(0);
1492}
1493
1494/*
1495 * Initialize an RX descriptor and attach an MBUF cluster.
1496 */
1497int
1498atu_newbuf(struct atu_softc *sc, struct atu_chain *c, struct mbuf *m)
1499{
1500 struct mbuf *m_new = NULL((void *)0);
1501
1502 if (m == NULL((void *)0)) {
1503 MGETHDR(m_new, M_DONTWAIT, MT_DATA)m_new = m_gethdr((0x0002), (1));
1504 if (m_new == NULL((void *)0)) {
1505 DPRINTF(("%s: no memory for rx list\n",
1506 sc->atu_dev.dv_xname));
1507 return(ENOBUFS55);
1508 }
1509
1510 MCLGET(m_new, M_DONTWAIT)(void) m_clget((m_new), (0x0002), (1 << 11));
1511 if (!(m_new->m_flagsm_hdr.mh_flags & M_EXT0x0001)) {
1512 DPRINTF(("%s: no memory for rx list\n",
1513 sc->atu_dev.dv_xname));
1514 m_freem(m_new);
1515 return(ENOBUFS55);
1516 }
1517 m_new->m_lenm_hdr.mh_len = m_new->m_pkthdrM_dat.MH.MH_pkthdr.len = MCLBYTES(1 << 11);
1518 } else {
1519 m_new = m;
1520 m_new->m_lenm_hdr.mh_len = m_new->m_pkthdrM_dat.MH.MH_pkthdr.len = MCLBYTES(1 << 11);
1521 m_new->m_datam_hdr.mh_data = m_new->m_extM_dat.MH.MH_dat.MH_ext.ext_buf;
1522 }
1523 c->atu_mbuf = m_new;
1524 return(0);
1525}
1526
1527int
1528atu_rx_list_init(struct atu_softc *sc)
1529{
1530 struct atu_cdata *cd = &sc->atu_cdata;
1531 struct atu_chain *c;
1532 int i;
1533
1534 DPRINTFN(15, ("%s: atu_rx_list_init: enter\n",
1535 sc->atu_dev.dv_xname));
1536
1537 for (i = 0; i < ATU_RX_LIST_CNT1; i++) {
1538 c = &cd->atu_rx_chain[i];
1539 c->atu_sc = sc;
1540 c->atu_idx = i;
1541 if (c->atu_xfer == NULL((void *)0)) {
1542 c->atu_xfer = usbd_alloc_xfer(sc->atu_udev);
1543 if (c->atu_xfer == NULL((void *)0))
1544 return (ENOBUFS55);
1545 c->atu_buf = usbd_alloc_buffer(c->atu_xfer,
1546 ATU_RX_BUFSZ(sizeof(struct atu_rx_hdr) + sizeof(struct ieee80211_frame_addr4
) + 2312 + 4)
);
1547 if (c->atu_buf == NULL((void *)0)) /* XXX free xfer */
1548 return (ENOBUFS55);
1549 if (atu_newbuf(sc, c, NULL((void *)0)) == ENOBUFS55) /* XXX free? */
1550 return(ENOBUFS55);
1551 }
1552 }
1553 return (0);
1554}
1555
1556int
1557atu_tx_list_init(struct atu_softc *sc)
1558{
1559 struct atu_cdata *cd = &sc->atu_cdata;
1560 struct atu_chain *c;
1561 int i;
1562
1563 DPRINTFN(15, ("%s: atu_tx_list_init\n",
1564 sc->atu_dev.dv_xname));
1565
1566 SLIST_INIT(&cd->atu_tx_free){ ((&cd->atu_tx_free)->slh_first) = ((void *)0); };
1567 sc->atu_cdata.atu_tx_inuse = 0;
1568
1569 for (i = 0; i < ATU_TX_LIST_CNT8; i++) {
1570 c = &cd->atu_tx_chain[i];
1571 c->atu_sc = sc;
1572 c->atu_idx = i;
1573 if (c->atu_xfer == NULL((void *)0)) {
1574 c->atu_xfer = usbd_alloc_xfer(sc->atu_udev);
1575 if (c->atu_xfer == NULL((void *)0))
1576 return(ENOBUFS55);
1577 c->atu_mbuf = NULL((void *)0);
1578 c->atu_buf = usbd_alloc_buffer(c->atu_xfer,
1579 ATU_TX_BUFSZ(sizeof(struct atu_tx_hdr) + sizeof(struct ieee80211_frame_addr4
) + 2312)
);
1580 if (c->atu_buf == NULL((void *)0))
1581 return(ENOBUFS55); /* XXX free xfer */
1582 SLIST_INSERT_HEAD(&cd->atu_tx_free, c, atu_list)do { (c)->atu_list.sle_next = (&cd->atu_tx_free)->
slh_first; (&cd->atu_tx_free)->slh_first = (c); } while
(0)
;
1583 }
1584 }
1585 return(0);
1586}
1587
1588void
1589atu_xfer_list_free(struct atu_softc *sc, struct atu_chain *ch,
1590 int listlen)
1591{
1592 int i;
1593
1594 /* Free resources. */
1595 for (i = 0; i < listlen; i++) {
1596 if (ch[i].atu_buf != NULL((void *)0))
1597 ch[i].atu_buf = NULL((void *)0);
1598 if (ch[i].atu_mbuf != NULL((void *)0)) {
1599 m_freem(ch[i].atu_mbuf);
1600 ch[i].atu_mbuf = NULL((void *)0);
1601 }
1602 if (ch[i].atu_xfer != NULL((void *)0)) {
1603 usbd_free_xfer(ch[i].atu_xfer);
1604 ch[i].atu_xfer = NULL((void *)0);
1605 }
1606 }
1607}
1608
1609/*
1610 * A frame has been uploaded: pass the resulting mbuf chain up to
1611 * the higher level protocols.
1612 */
1613void
1614atu_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
1615{
1616 struct atu_chain *c = (struct atu_chain *)priv;
1617 struct atu_softc *sc = c->atu_sc;
1618 struct ieee80211com *ic = &sc->sc_ic;
1619 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
1620 struct atu_rx_hdr *h;
1621 struct ieee80211_frame *wh;
1622 struct ieee80211_rxinfo rxi;
1623 struct ieee80211_node *ni;
1624 struct mbuf *m;
1625 u_int32_t len;
1626 int s;
1627
1628 DPRINTFN(25, ("%s: atu_rxeof\n", sc->atu_dev.dv_xname));
1629
1630 if (usbd_is_dying(sc->atu_udev))
1631 return;
1632
1633 if ((ifp->if_flags & (IFF_RUNNING0x40|IFF_UP0x1)) != (IFF_RUNNING0x40|IFF_UP0x1))
1634 goto done;
1635
1636 if (status != USBD_NORMAL_COMPLETION) {
1637 DPRINTF(("%s: status != USBD_NORMAL_COMPLETION\n",
1638 sc->atu_dev.dv_xname));
1639 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
1640 return;
1641 }
1642#if 0
1643 if (status == USBD_IOERROR) {
1644 DPRINTF(("%s: rx: EEK! lost device?\n",
1645 sc->atu_dev.dv_xname));
1646
1647 /*
1648 * My experience with USBD_IOERROR is that trying to
1649 * restart the transfer will always fail and we'll
1650 * keep on looping restarting transfers until someone
1651 * pulls the plug of the device.
1652 * So we don't restart the transfer, but just let it
1653 * die... If someone knows of a situation where we can
1654 * recover from USBD_IOERROR, let me know.
1655 */
1656 splx(s)spllower(s);
1657 return;
1658 }
1659#endif /* 0 */
1660
1661 if (usbd_ratecheck(&sc->atu_rx_notice)) {
1662 DPRINTF(("%s: usb error on rx: %s\n",
1663 sc->atu_dev.dv_xname, usbd_errstr(status)));
1664 }
1665 if (status == USBD_STALLED)
1666 usbd_clear_endpoint_stall_async(
1667 sc->atu_ep[ATU_ENDPT_RX0x0]);
1668 goto done;
1669 }
1670
1671 usbd_get_xfer_status(xfer, NULL((void *)0), NULL((void *)0), &len, NULL((void *)0));
1672
1673 if (len < ATU_RX_HDRLENsizeof(struct atu_rx_hdr)) {
1674 DPRINTF(("%s: atu_rxeof: too short\n",
1675 sc->atu_dev.dv_xname));
1676 ic->ic_stats.is_rx_tooshort++;
1677 ifp->if_ierrorsif_data.ifi_ierrors++;
1678 goto done;
1679 }
1680
1681 h = (struct atu_rx_hdr *)c->atu_buf;
1682 len = UGETW(h->length)(*(u_int16_t *)(h->length));
1683 if (len < IEEE80211_MIN_LEN(sizeof(struct ieee80211_frame_min) + 4)) {
1684 ic->ic_stats.is_rx_tooshort++;
1685 ifp->if_ierrorsif_data.ifi_ierrors++;
1686 goto done;
1687 }
1688 if (len > ATU_RX_BUFSZ(sizeof(struct atu_rx_hdr) + sizeof(struct ieee80211_frame_addr4
) + 2312 + 4)
) {
1689 ifp->if_ierrorsif_data.ifi_ierrors++;
1690 goto done;
1691 }
1692 len -= IEEE80211_CRC_LEN4;
1693
1694 m = c->atu_mbuf;
1695 memcpy(mtod(m, char *), c->atu_buf + ATU_RX_HDRLEN, len)__builtin_memcpy((((char *)((m)->m_hdr.mh_data))), (c->
atu_buf + sizeof(struct atu_rx_hdr)), (len))
;
1696 m->m_pkthdrM_dat.MH.MH_pkthdr.len = m->m_lenm_hdr.mh_len = len;
1697
1698 wh = mtod(m, struct ieee80211_frame *)((struct ieee80211_frame *)((m)->m_hdr.mh_data));
1699 ni = ieee80211_find_rxnode(ic, wh);
1700
1701 s = splnet()splraise(0x7);
1702
1703 if (atu_newbuf(sc, c, NULL((void *)0)) == ENOBUFS55) {
1704 ifp->if_ierrorsif_data.ifi_ierrors++;
1705 goto done1; /* XXX if we can't allocate, why restart it? */
1706 }
1707
1708#if NBPFILTER1 > 0
1709 if (sc->sc_radiobpf != NULL((void *)0)) {
1710 struct mbuf mb;
1711 struct atu_rx_radiotap_header *rr = &sc->sc_rxtapsc_rxtapu.tap;
1712
1713 rr->rr_flags = 0;
1714 rr->rr_chan_freq =
1715 htole16(ic->ic_bss->ni_chan->ic_freq)((__uint16_t)(ic->ic_bss->ni_chan->ic_freq));
1716 rr->rr_chan_flags =
1717 htole16(ic->ic_bss->ni_chan->ic_flags)((__uint16_t)(ic->ic_bss->ni_chan->ic_flags));
1718 rr->rr_rssi = h->rssi;
1719 rr->rr_max_rssi = ic->ic_max_rssi;
1720
1721 mb.m_datam_hdr.mh_data = (caddr_t)rr;
1722 mb.m_lenm_hdr.mh_len = sizeof(sc->sc_txtapu);
1723 mb.m_nextm_hdr.mh_next = m;
1724 mb.m_nextpktm_hdr.mh_nextpkt = NULL((void *)0);
1725 mb.m_typem_hdr.mh_type = 0;
1726 mb.m_flagsm_hdr.mh_flags = 0;
1727 bpf_mtap(sc->sc_radiobpf, &mb, BPF_DIRECTION_IN(1 << 0));
1728 }
1729#endif /* NBPFILTER > 0 */
1730
1731 rxi.rxi_flags = 0;
1732 if (wh->i_fc[1] & IEEE80211_FC1_WEP0x40) {
1733 /*
1734 * WEP is decrypted by hardware. Clear WEP bit
1735 * header for ieee80211_input().
1736 */
1737 wh->i_fc[1] &= ~IEEE80211_FC1_WEP0x40;
1738 rxi.rxi_flags |= IEEE80211_RXI_HWDEC0x00000001;
1739 }
1740
1741 rxi.rxi_rssi = h->rssi;
1742 rxi.rxi_tstamp = UGETDW(h->rx_time)(*(u_int32_t *)(h->rx_time));
1743 ieee80211_input(ifp, m, ni, &rxi);
1744
1745done1:
1746 ieee80211_release_node(ic, ni);
1747 splx(s)spllower(s);
1748done:
1749 /* Setup new transfer. */
1750 usbd_setup_xfer(c->atu_xfer, sc->atu_ep[ATU_ENDPT_RX0x0], c, c->atu_buf,
1751 ATU_RX_BUFSZ(sizeof(struct atu_rx_hdr) + sizeof(struct ieee80211_frame_addr4
) + 2312 + 4)
, USBD_SHORT_XFER_OK0x04 | USBD_NO_COPY0x01, USBD_NO_TIMEOUT0,
1752 atu_rxeof);
1753 usbd_transfer(c->atu_xfer);
1754}
1755
1756/*
1757 * A frame was downloaded to the chip. It's safe for us to clean up
1758 * the list buffers.
1759 */
1760void
1761atu_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
1762{
1763 struct atu_chain *c = (struct atu_chain *)priv;
1764 struct atu_softc *sc = c->atu_sc;
1765 struct ifnet *ifp = &sc->sc_ic.ic_ific_ac.ac_if;
1766 usbd_status err;
1767 int s;
1768
1769 DPRINTFN(25, ("%s: atu_txeof status=%d\n", sc->atu_dev.dv_xname,
1770 status));
1771
1772 if (c->atu_mbuf != NULL((void *)0)) {
1773 m_freem(c->atu_mbuf);
1774 c->atu_mbuf = NULL((void *)0);
1775 }
1776
1777 if (status != USBD_NORMAL_COMPLETION) {
1778 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
1779 return;
1780
1781 DPRINTF(("%s: usb error on tx: %s\n", sc->atu_dev.dv_xname,
1782 usbd_errstr(status)));
1783 if (status == USBD_STALLED)
1784 usbd_clear_endpoint_stall_async(sc->atu_ep[ATU_ENDPT_TX0x1]);
1785 return;
1786 }
1787
1788 usbd_get_xfer_status(c->atu_xfer, NULL((void *)0), NULL((void *)0), NULL((void *)0), &err);
1789
1790 if (err)
1791 ifp->if_oerrorsif_data.ifi_oerrors++;
1792
1793 s = splnet()splraise(0x7);
1794 SLIST_INSERT_HEAD(&sc->atu_cdata.atu_tx_free, c, atu_list)do { (c)->atu_list.sle_next = (&sc->atu_cdata.atu_tx_free
)->slh_first; (&sc->atu_cdata.atu_tx_free)->slh_first
= (c); } while (0)
;
1795 sc->atu_cdata.atu_tx_inuse--;
1796 if (sc->atu_cdata.atu_tx_inuse == 0)
1797 ifp->if_timer = 0;
1798 ifq_clr_oactive(&ifp->if_snd);
1799 splx(s)spllower(s);
1800
1801 atu_start(ifp);
1802}
1803
1804u_int8_t
1805atu_calculate_padding(int size)
1806{
1807 size %= 64;
1808
1809 if (size < 50)
1810 return (50 - size);
1811 if (size >=61)
1812 return (64 + 50 - size);
1813 return (0);
1814}
1815
1816int
1817atu_tx_start(struct atu_softc *sc, struct ieee80211_node *ni,
1818 struct atu_chain *c, struct mbuf *m)
1819{
1820 int len;
1821 struct atu_tx_hdr *h;
1822 usbd_status err;
1823 u_int8_t pad;
1824#if NBPFILTER1 > 0
1825 struct ieee80211com *ic = &sc->sc_ic;
1826#endif
1827
1828 DPRINTFN(25, ("%s: atu_tx_start\n", sc->atu_dev.dv_xname));
1829
1830 /* Don't try to send when we're shutting down the driver */
1831 if (usbd_is_dying(sc->atu_udev)) {
1832 m_freem(m);
1833 return(EIO5);
1834 }
1835
1836#if NBPFILTER1 > 0
1837 if (sc->sc_radiobpf != NULL((void *)0)) {
1838 struct mbuf mb;
1839 struct atu_tx_radiotap_header *rt = &sc->sc_txtapsc_txtapu.tap;
1840
1841 rt->rt_flags = 0;
1842 rt->rt_chan_freq =
1843 htole16(ic->ic_bss->ni_chan->ic_freq)((__uint16_t)(ic->ic_bss->ni_chan->ic_freq));
1844 rt->rt_chan_flags =
1845 htole16(ic->ic_bss->ni_chan->ic_flags)((__uint16_t)(ic->ic_bss->ni_chan->ic_flags));
1846
1847 mb.m_datam_hdr.mh_data = (caddr_t)rt;
1848 mb.m_lenm_hdr.mh_len = sizeof(sc->sc_txtapu);
1849 mb.m_nextm_hdr.mh_next = m;
1850 mb.m_nextpktm_hdr.mh_nextpkt = NULL((void *)0);
1851 mb.m_typem_hdr.mh_type = 0;
1852 mb.m_flagsm_hdr.mh_flags = 0;
1853 bpf_mtap(sc->sc_radiobpf, &mb, BPF_DIRECTION_OUT(1 << 1));
1854 }
1855#endif
1856
1857 /*
1858 * Copy the mbuf data into a contiguous buffer, leaving
1859 * enough room for the atmel headers
1860 */
1861 len = m->m_pkthdrM_dat.MH.MH_pkthdr.len;
1862
1863 m_copydata(m, 0, m->m_pkthdrM_dat.MH.MH_pkthdr.len, c->atu_buf + ATU_TX_HDRLENsizeof(struct atu_tx_hdr));
1864
1865 h = (struct atu_tx_hdr *)c->atu_buf;
1866 memset(h, 0, ATU_TX_HDRLEN)__builtin_memset((h), (0), (sizeof(struct atu_tx_hdr)));
1867 USETW(h->length, len)(*(u_int16_t *)(h->length) = (len));
1868 h->tx_rate = 4; /* XXX rate = auto */
1869 len += ATU_TX_HDRLENsizeof(struct atu_tx_hdr);
1870
1871 pad = atu_calculate_padding(len);
1872 len += pad;
1873 h->padding = pad;
1874
1875 c->atu_length = len;
1876 c->atu_mbuf = m;
1877
1878 usbd_setup_xfer(c->atu_xfer, sc->atu_ep[ATU_ENDPT_TX0x1],
1879 c, c->atu_buf, c->atu_length, USBD_NO_COPY0x01, ATU_TX_TIMEOUT10000,
1880 atu_txeof);
1881
1882 /* Let's get this thing into the air! */
1883 c->atu_in_xfer = 1;
1884 err = usbd_transfer(c->atu_xfer);
1885 if (err != USBD_IN_PROGRESS) {
1886 DPRINTFN(25, ("%s: atu_tx_start: err=%d\n",
1887 sc->atu_dev.dv_xname, err));
1888 c->atu_mbuf = NULL((void *)0);
1889 m_freem(m);
1890 return(EIO5);
1891 }
1892
1893 return (0);
1894}
1895
1896void
1897atu_start(struct ifnet *ifp)
1898{
1899 struct atu_softc *sc = ifp->if_softc;
1900 struct ieee80211com *ic = &sc->sc_ic;
1901 struct atu_cdata *cd = &sc->atu_cdata;
1902 struct ieee80211_node *ni;
1903 struct ieee80211_frame *wh;
1904 struct atu_chain *c;
1905 struct mbuf *m = NULL((void *)0);
1906 int s;
1907
1908 DPRINTFN(25, ("%s: atu_start: enter\n", sc->atu_dev.dv_xname));
1909
1910 if ((ifp->if_flags & (IFF_RUNNING0x40|IFF_UP0x1)) != (IFF_RUNNING0x40|IFF_UP0x1)) {
1911 DPRINTFN(30, ("%s: atu_start: not running or up\n",
1912 sc->atu_dev.dv_xname));
1913 return;
1914 }
1915
1916 if (ifq_is_oactive(&ifp->if_snd)) {
1917 DPRINTFN(30, ("%s: atu_start: oactive\n",
1918 sc->atu_dev.dv_xname));
1919 return;
1920 }
1921
1922 for (;;) {
1923 /* grab a TX buffer */
1924 s = splnet()splraise(0x7);
1925 c = SLIST_FIRST(&cd->atu_tx_free)((&cd->atu_tx_free)->slh_first);
1926 if (c != NULL((void *)0)) {
1927 SLIST_REMOVE_HEAD(&cd->atu_tx_free, atu_list)do { (&cd->atu_tx_free)->slh_first = (&cd->atu_tx_free
)->slh_first->atu_list.sle_next; } while (0)
;
1928 cd->atu_tx_inuse++;
1929 if (cd->atu_tx_inuse == ATU_TX_LIST_CNT8)
1930 ifq_set_oactive(&ifp->if_snd);
1931 }
1932 splx(s)spllower(s);
1933 if (c == NULL((void *)0)) {
1934 DPRINTFN(10, ("%s: out of tx xfers\n",
1935 sc->atu_dev.dv_xname));
1936 ifq_set_oactive(&ifp->if_snd);
1937 break;
1938 }
1939
1940 /*
1941 * Poll the management queue for frames, it has priority over
1942 * normal data frames.
1943 */
1944 m = mq_dequeue(&ic->ic_mgtq);
1945 if (m == NULL((void *)0)) {
1946 DPRINTFN(10, ("%s: atu_start: data packet\n",
1947 sc->atu_dev.dv_xname));
1948 if (ic->ic_state != IEEE80211_S_RUN) {
1949 DPRINTFN(25, ("%s: no data till running\n",
1950 sc->atu_dev.dv_xname));
1951 /* put the xfer back on the list */
1952 s = splnet()splraise(0x7);
1953 SLIST_INSERT_HEAD(&cd->atu_tx_free, c,do { (c)->atu_list.sle_next = (&cd->atu_tx_free)->
slh_first; (&cd->atu_tx_free)->slh_first = (c); } while
(0)
1954 atu_list)do { (c)->atu_list.sle_next = (&cd->atu_tx_free)->
slh_first; (&cd->atu_tx_free)->slh_first = (c); } while
(0)
;
1955 cd->atu_tx_inuse--;
1956 splx(s)spllower(s);
1957 break;
1958 }
1959
1960 m = ifq_dequeue(&ifp->if_snd);
1961 if (m == NULL((void *)0)) {
1962 DPRINTFN(25, ("%s: nothing to send\n",
1963 sc->atu_dev.dv_xname));
1964 s = splnet()splraise(0x7);
1965 SLIST_INSERT_HEAD(&cd->atu_tx_free, c,do { (c)->atu_list.sle_next = (&cd->atu_tx_free)->
slh_first; (&cd->atu_tx_free)->slh_first = (c); } while
(0)
1966 atu_list)do { (c)->atu_list.sle_next = (&cd->atu_tx_free)->
slh_first; (&cd->atu_tx_free)->slh_first = (c); } while
(0)
;
1967 cd->atu_tx_inuse--;
1968 splx(s)spllower(s);
1969 break;
1970 }
1971
1972#if NBPFILTER1 > 0
1973 if (ifp->if_bpf)
1974 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT(1 << 1));
1975#endif
1976
1977 m = ieee80211_encap(ifp, m, &ni);
1978 if (m == NULL((void *)0))
1979 goto bad;
1980 wh = mtod(m, struct ieee80211_frame *)((struct ieee80211_frame *)((m)->m_hdr.mh_data));
Value stored to 'wh' is never read
1981
1982#if NBPFILTER1 > 0
1983 if (ic->ic_rawbpf != NULL((void *)0))
1984 bpf_mtap(ic->ic_rawbpf, m, BPF_DIRECTION_OUT(1 << 1));
1985#endif
1986 } else {
1987 DPRINTFN(25, ("%s: atu_start: mgmt packet\n",
1988 sc->atu_dev.dv_xname));
1989
1990 ni = m->m_pkthdrM_dat.MH.MH_pkthdr.ph_cookie;
1991
1992 wh = mtod(m, struct ieee80211_frame *)((struct ieee80211_frame *)((m)->m_hdr.mh_data));
1993 /* sc->sc_stats.ast_tx_mgmt++; */
1994 }
1995
1996 if (atu_tx_start(sc, ni, c, m)) {
1997bad:
1998 s = splnet()splraise(0x7);
1999 SLIST_INSERT_HEAD(&cd->atu_tx_free, c,do { (c)->atu_list.sle_next = (&cd->atu_tx_free)->
slh_first; (&cd->atu_tx_free)->slh_first = (c); } while
(0)
2000 atu_list)do { (c)->atu_list.sle_next = (&cd->atu_tx_free)->
slh_first; (&cd->atu_tx_free)->slh_first = (c); } while
(0)
;
2001 cd->atu_tx_inuse--;
2002 splx(s)spllower(s);
2003 /* ifp_if_oerrors++; */
2004 if (ni != NULL((void *)0))
2005 ieee80211_release_node(ic, ni);
2006 continue;
2007 }
2008 ifp->if_timer = 5;
2009 }
2010}
2011
2012int
2013atu_init(struct ifnet *ifp)
2014{
2015 struct atu_softc *sc = ifp->if_softc;
2016 struct ieee80211com *ic = &sc->sc_ic;
2017 struct atu_chain *c;
2018 usbd_status err;
2019 int i, s;
2020
2021 s = splnet()splraise(0x7);
2022
2023 DPRINTFN(10, ("%s: atu_init\n", sc->atu_dev.dv_xname));
2024
2025 if (ifp->if_flags & IFF_RUNNING0x40) {
2026 splx(s)spllower(s);
2027 return(0);
2028 }
2029
2030 /* Init TX ring */
2031 if (atu_tx_list_init(sc))
2032 printf("%s: tx list init failed\n", sc->atu_dev.dv_xname);
2033
2034 /* Init RX ring */
2035 if (atu_rx_list_init(sc))
2036 printf("%s: rx list init failed\n", sc->atu_dev.dv_xname);
2037
2038 /* Load the multicast filter. */
2039 /*atu_setmulti(sc); */
2040
2041 /* Open RX and TX pipes. */
2042 err = usbd_open_pipe(sc->atu_iface, sc->atu_ed[ATU_ENDPT_RX0x0],
2043 USBD_EXCLUSIVE_USE0x01, &sc->atu_ep[ATU_ENDPT_RX0x0]);
2044 if (err) {
2045 DPRINTF(("%s: open rx pipe failed: %s\n",
2046 sc->atu_dev.dv_xname, usbd_errstr(err)));
2047 splx(s)spllower(s);
2048 return(EIO5);
2049 }
2050
2051 err = usbd_open_pipe(sc->atu_iface, sc->atu_ed[ATU_ENDPT_TX0x1],
2052 USBD_EXCLUSIVE_USE0x01, &sc->atu_ep[ATU_ENDPT_TX0x1]);
2053 if (err) {
2054 DPRINTF(("%s: open tx pipe failed: %s\n",
2055 sc->atu_dev.dv_xname, usbd_errstr(err)));
2056 splx(s)spllower(s);
2057 return(EIO5);
2058 }
2059
2060 /* Start up the receive pipe. */
2061 for (i = 0; i < ATU_RX_LIST_CNT1; i++) {
2062 c = &sc->atu_cdata.atu_rx_chain[i];
2063
2064 usbd_setup_xfer(c->atu_xfer, sc->atu_ep[ATU_ENDPT_RX0x0], c,
2065 c->atu_buf, ATU_RX_BUFSZ(sizeof(struct atu_rx_hdr) + sizeof(struct ieee80211_frame_addr4
) + 2312 + 4)
, USBD_SHORT_XFER_OK0x04 | USBD_NO_COPY0x01,
2066 USBD_NO_TIMEOUT0, atu_rxeof);
2067 usbd_transfer(c->atu_xfer);
2068 }
2069
2070 DPRINTFN(10, ("%s: starting up using MAC=%s\n",
2071 sc->atu_dev.dv_xname, ether_sprintf(ic->ic_myaddr)));
2072
2073 /* Do initial setup */
2074 err = atu_initial_config(sc);
2075 if (err) {
2076 DPRINTF(("%s: initial config failed!\n",
2077 sc->atu_dev.dv_xname));
2078 splx(s)spllower(s);
2079 return(EIO5);
2080 }
2081 DPRINTFN(10, ("%s: initialised transceiver\n",
2082 sc->atu_dev.dv_xname));
2083
2084 /* sc->atu_rxfilt = ATU_RXFILT_UNICAST|ATU_RXFILT_BROADCAST; */
2085
2086 /* If we want promiscuous mode, set the allframes bit. */
2087 /*
2088 if (ifp->if_flags & IFF_PROMISC)
2089 sc->atu_rxfilt |= ATU_RXFILT_PROMISC;
2090 */
2091
2092 ifp->if_flags |= IFF_RUNNING0x40;
2093 ifq_clr_oactive(&ifp->if_snd);
2094 splx(s)spllower(s);
2095
2096 /* XXX the following HAS to be replaced */
2097 s = splnet()splraise(0x7);
2098 err = ieee80211_new_state(ic, IEEE80211_S_SCAN, -1)(((ic)->ic_newstate)((ic), (IEEE80211_S_SCAN), (-1)));
2099 if (err)
2100 DPRINTFN(1, ("%s: atu_init: error calling "
2101 "ieee80211_net_state", sc->atu_dev.dv_xname));
2102 splx(s)spllower(s);
2103
2104 return 0;
2105}
2106
2107int
2108atu_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
2109{
2110 struct atu_softc *sc = ifp->if_softc;
2111 int err = 0, s;
2112
2113 s = splnet()splraise(0x7);
2114 switch (command) {
2115 case SIOCSIFADDR((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((12)))
:
2116 DPRINTFN(15, ("%s: SIOCSIFADDR\n", sc->atu_dev.dv_xname));
2117
2118 ifp->if_flags |= IFF_UP0x1;
2119 atu_init(ifp);
2120 break;
2121
2122 case SIOCSIFFLAGS((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((16)))
:
2123 DPRINTFN(15, ("%s: SIOCSIFFLAGS\n", sc->atu_dev.dv_xname));
2124
2125 if (ifp->if_flags & IFF_UP0x1) {
2126 if (ifp->if_flags & IFF_RUNNING0x40 &&
2127 ifp->if_flags & IFF_PROMISC0x100 &&
2128 !(sc->atu_if_flags & IFF_PROMISC0x100)) {
2129/* enable promisc */
2130#if 0
2131 sc->atu_rxfilt |= ATU_RXFILT_PROMISC;
2132 atu_setword(sc, ATU_CMD_SET_PKT_FILTER,
2133 sc->atu_rxfilt);
2134#endif
2135 } else if (ifp->if_flags & IFF_RUNNING0x40 &&
2136 !(ifp->if_flags & IFF_PROMISC0x100) &&
2137 sc->atu_if_flags & IFF_PROMISC0x100) {
2138/* disable promisc */
2139#if 0
2140 sc->atu_rxfilt &= ~ATU_RXFILT_PROMISC;
2141 atu_setword(sc, ATU_CMD_SET_PKT_FILTER,
2142 sc->atu_rxfilt);
2143#endif
2144 } else if (!(ifp->if_flags & IFF_RUNNING0x40))
2145 atu_init(ifp);
2146
2147 DPRINTFN(15, ("%s: ioctl calling atu_init()\n",
2148 sc->atu_dev.dv_xname));
2149 atu_init(ifp);
2150 err = atu_switch_radio(sc, 1);
2151 } else {
2152 if (ifp->if_flags & IFF_RUNNING0x40)
2153 atu_stop(ifp, 0);
2154 err = atu_switch_radio(sc, 0);
2155 }
2156 sc->atu_if_flags = ifp->if_flags;
2157 err = 0;
2158 break;
2159
2160 case SIOCADDMULTI((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((49)))
:
2161 DPRINTFN(15, ("%s: SIOCADDMULTI\n", sc->atu_dev.dv_xname));
2162 /* TODO: implement */
2163 err = 0;
2164 break;
2165
2166 case SIOCDELMULTI((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((50)))
:
2167 DPRINTFN(15, ("%s: SIOCDELMULTI\n", sc->atu_dev.dv_xname));
2168 /* TODO: implement */
2169 err = 0;
2170 break;
2171
2172 default:
2173 DPRINTFN(15, ("%s: ieee80211_ioctl (%lu)\n",
2174 sc->atu_dev.dv_xname, command));
2175 err = ieee80211_ioctl(ifp, command, data);
2176 break;
2177 }
2178
2179 if (err == ENETRESET52) {
2180 if ((ifp->if_flags & (IFF_RUNNING0x40|IFF_UP0x1)) ==
2181 (IFF_RUNNING0x40|IFF_UP0x1)) {
2182 DPRINTF(("%s: atu_ioctl(): netreset\n",
2183 sc->atu_dev.dv_xname));
2184 atu_init(ifp);
2185 }
2186 err = 0;
2187 }
2188
2189 splx(s)spllower(s);
2190 return (err);
2191}
2192
2193void
2194atu_watchdog(struct ifnet *ifp)
2195{
2196 struct atu_softc *sc = ifp->if_softc;
2197 struct atu_chain *c;
2198 usbd_status stat;
2199 int cnt, s;
2200
2201 DPRINTF(("%s: atu_watchdog\n", sc->atu_dev.dv_xname));
2202
2203 ifp->if_timer = 0;
2204
2205 if ((ifp->if_flags & (IFF_RUNNING0x40|IFF_UP0x1)) != (IFF_RUNNING0x40|IFF_UP0x1))
2206 return;
2207
2208 if (usbd_is_dying(sc->atu_udev))
2209 return;
2210
2211 sc = ifp->if_softc;
2212 s = splnet()splraise(0x7);
2213 ifp->if_oerrorsif_data.ifi_oerrors++;
2214 DPRINTF(("%s: watchdog timeout\n", sc->atu_dev.dv_xname));
2215
2216 /*
2217 * TODO:
2218 * we should change this since we have multiple TX transfers...
2219 */
2220 for (cnt = 0; cnt < ATU_TX_LIST_CNT8; cnt++) {
2221 c = &sc->atu_cdata.atu_tx_chain[cnt];
2222 if (c->atu_in_xfer) {
2223 usbd_get_xfer_status(c->atu_xfer, NULL((void *)0), NULL((void *)0), NULL((void *)0),
2224 &stat);
2225 atu_txeof(c->atu_xfer, c, stat);
2226 }
2227 }
2228
2229 if (!ifq_empty(&ifp->if_snd)(((&ifp->if_snd)->ifq_len) == 0))
2230 atu_start(ifp);
2231 splx(s)spllower(s);
2232
2233 ieee80211_watchdog(ifp);
2234}
2235
2236/*
2237 * Stop the adapter and free any mbufs allocated to the
2238 * RX and TX lists.
2239 */
2240void
2241atu_stop(struct ifnet *ifp, int disable)
2242{
2243 struct atu_softc *sc = ifp->if_softc;
2244 struct atu_cdata *cd;
2245 usbd_status err;
2246 int s;
2247
2248 s = splnet()splraise(0x7);
2249 ifp->if_flags &= ~IFF_RUNNING0x40;
2250 ifq_clr_oactive(&ifp->if_snd);
2251 ifp->if_timer = 0;
2252
2253 /* Stop transfers. */
2254 if (sc->atu_ep[ATU_ENDPT_RX0x0] != NULL((void *)0)) {
2255 err = usbd_close_pipe(sc->atu_ep[ATU_ENDPT_RX0x0]);
2256 if (err) {
2257 DPRINTF(("%s: close rx pipe failed: %s\n",
2258 sc->atu_dev.dv_xname, usbd_errstr(err)));
2259 }
2260 sc->atu_ep[ATU_ENDPT_RX0x0] = NULL((void *)0);
2261 }
2262
2263 if (sc->atu_ep[ATU_ENDPT_TX0x1] != NULL((void *)0)) {
2264 err = usbd_close_pipe(sc->atu_ep[ATU_ENDPT_TX0x1]);
2265 if (err) {
2266 DPRINTF(("%s: close tx pipe failed: %s\n",
2267 sc->atu_dev.dv_xname, usbd_errstr(err)));
2268 }
2269 sc->atu_ep[ATU_ENDPT_TX0x1] = NULL((void *)0);
2270 }
2271
2272 /* Free RX/TX/MGMT list resources. */
2273 cd = &sc->atu_cdata;
2274 atu_xfer_list_free(sc, cd->atu_rx_chain, ATU_RX_LIST_CNT1);
2275 atu_xfer_list_free(sc, cd->atu_tx_chain, ATU_TX_LIST_CNT8);
2276
2277 /* Let's be nice and turn off the radio before we leave */
2278 atu_switch_radio(sc, 0);
2279
2280 splx(s)spllower(s);
2281}