Bug Summary

File:dev/usb/if_upgt.c
Warning:line 1070, column 2
Value stored to 'flags' 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_upgt.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_upgt.c
1/* $OpenBSD: if_upgt.c,v 1.88 2022/01/09 05:43:00 jsg Exp $ */
2
3/*
4 * Copyright (c) 2007 Marcus Glocker <mglocker@openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include "bpfilter.h"
20
21#include <sys/param.h>
22#include <sys/sockio.h>
23#include <sys/mbuf.h>
24#include <sys/kernel.h>
25#include <sys/socket.h>
26#include <sys/systm.h>
27#include <sys/timeout.h>
28#include <sys/conf.h>
29#include <sys/device.h>
30#include <sys/endian.h>
31
32#include <machine/intr.h>
33
34#if NBPFILTER1 > 0
35#include <net/bpf.h>
36#endif
37#include <net/if.h>
38#include <net/if_dl.h>
39#include <net/if_media.h>
40
41#include <netinet/in.h>
42#include <netinet/if_ether.h>
43
44#include <net80211/ieee80211_var.h>
45#include <net80211/ieee80211_radiotap.h>
46
47#include <dev/usb/usb.h>
48#include <dev/usb/usbdi.h>
49#include <dev/usb/usbdi_util.h>
50#include <dev/usb/usbdevs.h>
51
52#include <dev/usb/if_upgtvar.h>
53
54/*
55 * Driver for the USB PrismGT devices.
56 *
57 * For now just USB 2.0 devices with the GW3887 chipset are supported.
58 * The driver has been written based on the firmware version 2.13.1.0_LM87.
59 *
60 * TODO's:
61 * - Fix MONITOR mode (MAC filter).
62 * - Add HOSTAP mode.
63 * - Add IBSS mode.
64 * - Support the USB 1.0 devices (NET2280, ISL3880, ISL3886 chipsets).
65 *
66 * Parts of this driver has been influenced by reading the p54u driver
67 * written by Jean-Baptiste Note <jean-baptiste.note@m4x.org> and
68 * Sebastien Bourdeauducq <lekernel@prism54.org>.
69 */
70
71#ifdef UPGT_DEBUG
72int upgt_debug = 2;
73#define DPRINTF(l, x...) do { if ((l) <= upgt_debug) printf(x); } while (0)
74#else
75#define DPRINTF(l, x...)
76#endif
77
78/*
79 * Prototypes.
80 */
81int upgt_match(struct device *, void *, void *);
82void upgt_attach(struct device *, struct device *, void *);
83void upgt_attach_hook(struct device *);
84int upgt_detach(struct device *, int);
85
86int upgt_device_type(struct upgt_softc *, uint16_t, uint16_t);
87int upgt_device_init(struct upgt_softc *);
88int upgt_mem_init(struct upgt_softc *);
89uint32_t upgt_mem_alloc(struct upgt_softc *);
90void upgt_mem_free(struct upgt_softc *, uint32_t);
91int upgt_fw_alloc(struct upgt_softc *);
92void upgt_fw_free(struct upgt_softc *);
93int upgt_fw_verify(struct upgt_softc *);
94int upgt_fw_load(struct upgt_softc *);
95int upgt_fw_copy(char *, char *, int);
96int upgt_eeprom_read(struct upgt_softc *);
97int upgt_eeprom_parse(struct upgt_softc *);
98void upgt_eeprom_parse_hwrx(struct upgt_softc *, uint8_t *);
99void upgt_eeprom_parse_freq3(struct upgt_softc *, uint8_t *, int);
100void upgt_eeprom_parse_freq4(struct upgt_softc *, uint8_t *, int);
101void upgt_eeprom_parse_freq6(struct upgt_softc *, uint8_t *, int);
102
103int upgt_ioctl(struct ifnet *, u_long, caddr_t);
104int upgt_init(struct ifnet *);
105void upgt_stop(struct upgt_softc *);
106int upgt_media_change(struct ifnet *);
107void upgt_newassoc(struct ieee80211com *, struct ieee80211_node *,
108 int);
109int upgt_newstate(struct ieee80211com *, enum ieee80211_state, int);
110void upgt_newstate_task(void *);
111void upgt_next_scan(void *);
112void upgt_start(struct ifnet *);
113void upgt_watchdog(struct ifnet *);
114void upgt_tx_task(void *);
115void upgt_tx_done(struct upgt_softc *, uint8_t *);
116void upgt_rx_cb(struct usbd_xfer *, void *, usbd_status);
117void upgt_rx(struct upgt_softc *, uint8_t *, int);
118void upgt_setup_rates(struct upgt_softc *);
119uint8_t upgt_rx_rate(struct upgt_softc *, const int);
120int upgt_set_macfilter(struct upgt_softc *, uint8_t state);
121int upgt_set_channel(struct upgt_softc *, unsigned);
122void upgt_set_led(struct upgt_softc *, int);
123void upgt_set_led_blink(void *);
124int upgt_get_stats(struct upgt_softc *);
125
126int upgt_alloc_tx(struct upgt_softc *);
127int upgt_alloc_rx(struct upgt_softc *);
128int upgt_alloc_cmd(struct upgt_softc *);
129void upgt_free_tx(struct upgt_softc *);
130void upgt_free_rx(struct upgt_softc *);
131void upgt_free_cmd(struct upgt_softc *);
132int upgt_bulk_xmit(struct upgt_softc *, struct upgt_data *,
133 struct usbd_pipe *, uint32_t *, int);
134
135void upgt_hexdump(void *, int);
136uint32_t upgt_crc32_le(const void *, size_t);
137uint32_t upgt_chksum_le(const uint32_t *, size_t);
138
139struct cfdriver upgt_cd = {
140 NULL((void *)0), "upgt", DV_IFNET
141};
142
143const struct cfattach upgt_ca = {
144 sizeof(struct upgt_softc), upgt_match, upgt_attach, upgt_detach
145};
146
147static const struct usb_devno upgt_devs_1[] = {
148 /* version 1 devices */
149 { USB_VENDOR_ALCATELT0x06b9, USB_PRODUCT_ALCATELT_ST120G0x0120 }
150};
151
152static const struct usb_devno upgt_devs_2[] = {
153 /* version 2 devices */
154 { USB_VENDOR_ACCTON0x083a, USB_PRODUCT_ACCTON_PRISM_GT0x4521 },
155 { USB_VENDOR_ALCATELT0x06b9, USB_PRODUCT_ALCATELT_ST121G0x0121 },
156 { USB_VENDOR_BELKIN0x050d, USB_PRODUCT_BELKIN_F5D70500x7050 },
157 { USB_VENDOR_CISCOLINKSYS0x13b1, USB_PRODUCT_CISCOLINKSYS_WUSB54AG0x000c },
158 { USB_VENDOR_CISCOLINKSYS0x13b1, USB_PRODUCT_CISCOLINKSYS_WUSB54GV20x000a },
159 { USB_VENDOR_CONCEPTRONIC0x0d8e, USB_PRODUCT_CONCEPTRONIC_PRISM_GT0x3762 },
160 { USB_VENDOR_DELL0x413c, USB_PRODUCT_DELL_PRISM_GT_10x8102 },
161 { USB_VENDOR_DELL0x413c, USB_PRODUCT_DELL_PRISM_GT_20x8104 },
162 { USB_VENDOR_DLINK0x2001, USB_PRODUCT_DLINK_DWLG122A20x3704 },
163 { USB_VENDOR_FSC0x0bf8, USB_PRODUCT_FSC_E54000x1009 },
164 { USB_VENDOR_GLOBESPAN0x0915, USB_PRODUCT_GLOBESPAN_PRISM_GT_10x2000 },
165 { USB_VENDOR_GLOBESPAN0x0915, USB_PRODUCT_GLOBESPAN_PRISM_GT_20x2002 },
166 { USB_VENDOR_INTERSIL0x09aa, USB_PRODUCT_INTERSIL_PRISM_GT0x1000 },
167 { USB_VENDOR_PHEENET0x124a, USB_PRODUCT_PHEENET_GWU5130x4025 },
168 { USB_VENDOR_PHILIPS0x0471, USB_PRODUCT_PHILIPS_CPWUA0540x1230 },
169 { USB_VENDOR_SMC0x0707, USB_PRODUCT_SMC_2862WG0xee13 },
170 { USB_VENDOR_USR0x0baf, USB_PRODUCT_USR_USR54220x0118 },
171 { USB_VENDOR_WISTRONNEWEB0x1435, USB_PRODUCT_WISTRONNEWEB_UR045G0x0427 },
172 { USB_VENDOR_XYRATEX0x0572, USB_PRODUCT_XYRATEX_PRISM_GT_10x2000 },
173 { USB_VENDOR_XYRATEX0x0572, USB_PRODUCT_XYRATEX_PRISM_GT_20x2002 },
174 { USB_VENDOR_ZCOM0x0cde, USB_PRODUCT_ZCOM_MD409000x0006 },
175 { USB_VENDOR_ZCOM0x0cde, USB_PRODUCT_ZCOM_XG703A0x0008 }
176};
177
178int
179upgt_match(struct device *parent, void *match, void *aux)
180{
181 struct usb_attach_arg *uaa = aux;
182
183 if (uaa->iface == NULL((void *)0) || uaa->configno != UPGT_CONFIG_NO1)
184 return (UMATCH_NONE0);
185
186 if (usb_lookup(upgt_devs_1, uaa->vendor, uaa->product)usbd_match_device((const struct usb_devno *)(upgt_devs_1), sizeof
(upgt_devs_1) / sizeof ((upgt_devs_1)[0]), sizeof ((upgt_devs_1
)[0]), (uaa->vendor), (uaa->product))
!= NULL((void *)0))
187 return (UMATCH_VENDOR_PRODUCT13);
188
189 if (usb_lookup(upgt_devs_2, uaa->vendor, uaa->product)usbd_match_device((const struct usb_devno *)(upgt_devs_2), sizeof
(upgt_devs_2) / sizeof ((upgt_devs_2)[0]), sizeof ((upgt_devs_2
)[0]), (uaa->vendor), (uaa->product))
!= NULL((void *)0))
190 return (UMATCH_VENDOR_PRODUCT13);
191
192 return (UMATCH_NONE0);
193}
194
195void
196upgt_attach(struct device *parent, struct device *self, void *aux)
197{
198 struct upgt_softc *sc = (struct upgt_softc *)self;
199 struct usb_attach_arg *uaa = aux;
200 usb_interface_descriptor_t *id;
201 usb_endpoint_descriptor_t *ed;
202 usbd_status error;
203 int i;
204
205 /*
206 * Attach USB device.
207 */
208 sc->sc_udev = uaa->device;
209
210 /* check device type */
211 if (upgt_device_type(sc, uaa->vendor, uaa->product) != 0)
212 return;
213
214 /* get the first interface handle */
215 error = usbd_device2interface_handle(sc->sc_udev, UPGT_IFACE_INDEX0,
216 &sc->sc_iface);
217 if (error != 0) {
218 printf("%s: could not get interface handle!\n",
219 sc->sc_dev.dv_xname);
220 return;
221 }
222
223 /* find endpoints */
224 id = usbd_get_interface_descriptor(sc->sc_iface);
225 sc->sc_rx_no = sc->sc_tx_no = -1;
226 for (i = 0; i < id->bNumEndpoints; i++) {
227 ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
228 if (ed == NULL((void *)0)) {
229 printf("%s: no endpoint descriptor for iface %d!\n",
230 sc->sc_dev.dv_xname, i);
231 return;
232 }
233
234 if (UE_GET_DIR(ed->bEndpointAddress)((ed->bEndpointAddress) & 0x80) == UE_DIR_OUT0x00 &&
235 UE_GET_XFERTYPE(ed->bmAttributes)((ed->bmAttributes) & 0x03) == UE_BULK0x02)
236 sc->sc_tx_no = ed->bEndpointAddress;
237 if (UE_GET_DIR(ed->bEndpointAddress)((ed->bEndpointAddress) & 0x80) == UE_DIR_IN0x80 &&
238 UE_GET_XFERTYPE(ed->bmAttributes)((ed->bmAttributes) & 0x03) == UE_BULK0x02)
239 sc->sc_rx_no = ed->bEndpointAddress;
240
241 /*
242 * 0x01 TX pipe
243 * 0x81 RX pipe
244 *
245 * Deprecated scheme (not used with fw version >2.5.6.x):
246 * 0x02 TX MGMT pipe
247 * 0x82 TX MGMT pipe
248 */
249 if (sc->sc_tx_no != -1 && sc->sc_rx_no != -1)
250 break;
251 }
252 if (sc->sc_rx_no == -1 || sc->sc_tx_no == -1) {
253 printf("%s: missing endpoint!\n", sc->sc_dev.dv_xname);
254 return;
255 }
256
257 /* setup tasks and timeouts */
258 usb_init_task(&sc->sc_task_newstate, upgt_newstate_task, sc,((&sc->sc_task_newstate)->fun = (upgt_newstate_task
), (&sc->sc_task_newstate)->arg = (sc), (&sc->
sc_task_newstate)->type = (0), (&sc->sc_task_newstate
)->state = 0x0)
259 USB_TASK_TYPE_GENERIC)((&sc->sc_task_newstate)->fun = (upgt_newstate_task
), (&sc->sc_task_newstate)->arg = (sc), (&sc->
sc_task_newstate)->type = (0), (&sc->sc_task_newstate
)->state = 0x0)
;
260 usb_init_task(&sc->sc_task_tx, upgt_tx_task, sc, USB_TASK_TYPE_GENERIC)((&sc->sc_task_tx)->fun = (upgt_tx_task), (&sc->
sc_task_tx)->arg = (sc), (&sc->sc_task_tx)->type
= (0), (&sc->sc_task_tx)->state = 0x0)
;
261 timeout_set(&sc->scan_to, upgt_next_scan, sc);
262 timeout_set(&sc->led_to, upgt_set_led_blink, sc);
263
264 /*
265 * Open TX and RX USB bulk pipes.
266 */
267 error = usbd_open_pipe(sc->sc_iface, sc->sc_tx_no, USBD_EXCLUSIVE_USE0x01,
268 &sc->sc_tx_pipeh);
269 if (error != 0) {
270 printf("%s: could not open TX pipe: %s!\n",
271 sc->sc_dev.dv_xname, usbd_errstr(error));
272 goto fail;
273 }
274 error = usbd_open_pipe(sc->sc_iface, sc->sc_rx_no, USBD_EXCLUSIVE_USE0x01,
275 &sc->sc_rx_pipeh);
276 if (error != 0) {
277 printf("%s: could not open RX pipe: %s!\n",
278 sc->sc_dev.dv_xname, usbd_errstr(error));
279 goto fail;
280 }
281
282 /*
283 * Allocate TX, RX, and CMD xfers.
284 */
285 if (upgt_alloc_tx(sc) != 0)
286 goto fail;
287 if (upgt_alloc_rx(sc) != 0)
288 goto fail;
289 if (upgt_alloc_cmd(sc) != 0)
290 goto fail;
291
292 /*
293 * We need the firmware loaded to complete the attach.
294 */
295 config_mountroot(self, upgt_attach_hook);
296
297 return;
298fail:
299 printf("%s: %s failed!\n", sc->sc_dev.dv_xname, __func__);
300}
301
302void
303upgt_attach_hook(struct device *self)
304{
305 struct upgt_softc *sc = (struct upgt_softc *)self;
306 struct ieee80211com *ic = &sc->sc_ic;
307 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
308 usbd_status error;
309 int i;
310
311 /*
312 * Load firmware file into memory.
313 */
314 if (upgt_fw_alloc(sc) != 0)
315 goto fail;
316
317 /*
318 * Initialize the device.
319 */
320 if (upgt_device_init(sc) != 0)
321 goto fail;
322
323 /*
324 * Verify the firmware.
325 */
326 if (upgt_fw_verify(sc) != 0)
327 goto fail;
328
329 /*
330 * Calculate device memory space.
331 */
332 if (sc->sc_memaddr_frame_start == 0 || sc->sc_memaddr_frame_end == 0) {
333 printf("%s: could not find memory space addresses on FW!\n",
334 sc->sc_dev.dv_xname);
335 goto fail;
336 }
337 sc->sc_memaddr_frame_end -= UPGT_MEMSIZE_RX0x3500 + 1;
338 sc->sc_memaddr_rx_start = sc->sc_memaddr_frame_end + 1;
339
340 DPRINTF(1, "%s: memory address frame start=0x%08x\n",
341 sc->sc_dev.dv_xname, sc->sc_memaddr_frame_start);
342 DPRINTF(1, "%s: memory address frame end=0x%08x\n",
343 sc->sc_dev.dv_xname, sc->sc_memaddr_frame_end);
344 DPRINTF(1, "%s: memory address rx start=0x%08x\n",
345 sc->sc_dev.dv_xname, sc->sc_memaddr_rx_start);
346
347 upgt_mem_init(sc);
348
349 /*
350 * Load the firmware.
351 */
352 if (upgt_fw_load(sc) != 0)
353 goto fail;
354
355 /*
356 * Startup the RX pipe.
357 */
358 struct upgt_data *data_rx = &sc->rx_data;
359
360 usbd_setup_xfer(data_rx->xfer, sc->sc_rx_pipeh, data_rx, data_rx->buf,
361 MCLBYTES(1 << 11), USBD_SHORT_XFER_OK0x04, USBD_NO_TIMEOUT0, upgt_rx_cb);
362 error = usbd_transfer(data_rx->xfer);
363 if (error != 0 && error != USBD_IN_PROGRESS) {
364 printf("%s: could not queue RX transfer!\n",
365 sc->sc_dev.dv_xname);
366 goto fail;
367 }
368 usbd_delay_ms(sc->sc_udev, 100);
369
370 /*
371 * Read the whole EEPROM content and parse it.
372 */
373 if (upgt_eeprom_read(sc) != 0)
374 goto fail;
375 if (upgt_eeprom_parse(sc) != 0)
376 goto fail;
377
378 /*
379 * Setup the 802.11 device.
380 */
381 ic->ic_phytype = IEEE80211_T_OFDM;
382 ic->ic_opmode = IEEE80211_M_STA;
383 ic->ic_state = IEEE80211_S_INIT;
384 ic->ic_caps =
385 IEEE80211_C_MONITOR0x00000200 |
386 IEEE80211_C_SHPREAMBLE0x00000100 |
387 IEEE80211_C_SHSLOT0x00000080 |
388 IEEE80211_C_WEP0x00000001 |
389 IEEE80211_C_RSN0x00001000;
390
391 ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
392 ic->ic_sup_rates[IEEE80211_MODE_11G] = ieee80211_std_rateset_11g;
393
394 for (i = 1; i <= 14; i++) {
395 ic->ic_channels[i].ic_freq =
396 ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ0x0080);
397 ic->ic_channels[i].ic_flags =
398 IEEE80211_CHAN_CCK0x0020 | IEEE80211_CHAN_OFDM0x0040 |
399 IEEE80211_CHAN_DYN0x0400 | IEEE80211_CHAN_2GHZ0x0080;
400 }
401
402 ifp->if_softc = sc;
403 ifp->if_flags = IFF_BROADCAST0x2 | IFF_SIMPLEX0x800 | IFF_MULTICAST0x8000;
404 ifp->if_ioctl = upgt_ioctl;
405 ifp->if_start = upgt_start;
406 ifp->if_watchdog = upgt_watchdog;
407 memcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ)__builtin_memcpy((ifp->if_xname), (sc->sc_dev.dv_xname)
, (16))
;
408
409 if_attach(ifp);
410 ieee80211_ifattach(ifp);
411 ic->ic_newassoc = upgt_newassoc;
412
413 sc->sc_newstate = ic->ic_newstate;
414 ic->ic_newstate = upgt_newstate;
415 ieee80211_media_init(ifp, upgt_media_change, ieee80211_media_status);
416
417#if NBPFILTER1 > 0
418 bpfattach(&sc->sc_drvbpf, ifp, DLT_IEEE802_11_RADIO127,
419 sizeof(struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN64);
420
421 sc->sc_rxtap_len = sizeof(sc->sc_rxtapu);
422 sc->sc_rxtapsc_rxtapu.th.wr_ihdr.it_len = htole16(sc->sc_rxtap_len)((__uint16_t)(sc->sc_rxtap_len));
423 sc->sc_rxtapsc_rxtapu.th.wr_ihdr.it_present = htole32(UPGT_RX_RADIOTAP_PRESENT)((__uint32_t)(((1 << IEEE80211_RADIOTAP_FLAGS) | (1 <<
IEEE80211_RADIOTAP_RATE) | (1 << IEEE80211_RADIOTAP_CHANNEL
) | (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL))))
;
424
425 sc->sc_txtap_len = sizeof(sc->sc_txtapu);
426 sc->sc_txtapsc_txtapu.th.wt_ihdr.it_len = htole16(sc->sc_txtap_len)((__uint16_t)(sc->sc_txtap_len));
427 sc->sc_txtapsc_txtapu.th.wt_ihdr.it_present = htole32(UPGT_TX_RADIOTAP_PRESENT)((__uint32_t)(((1 << IEEE80211_RADIOTAP_FLAGS) | (1 <<
IEEE80211_RADIOTAP_RATE) | (1 << IEEE80211_RADIOTAP_CHANNEL
))))
;
428#endif
429
430 printf("%s: address %s\n",
431 sc->sc_dev.dv_xname, ether_sprintf(ic->ic_myaddr));
432
433 return;
434fail:
435 printf("%s: %s failed!\n", sc->sc_dev.dv_xname, __func__);
436}
437
438int
439upgt_detach(struct device *self, int flags)
440{
441 struct upgt_softc *sc = (struct upgt_softc *)self;
442 struct ifnet *ifp = &sc->sc_ic.ic_ific_ac.ac_if;
443 int s;
444
445 DPRINTF(1, "%s: %s\n", sc->sc_dev.dv_xname, __func__);
446
447 s = splusb()splraise(0x5);
448
449 /* abort and close TX / RX pipes */
450 if (sc->sc_tx_pipeh != NULL((void *)0))
451 usbd_close_pipe(sc->sc_tx_pipeh);
452 if (sc->sc_rx_pipeh != NULL((void *)0))
453 usbd_close_pipe(sc->sc_rx_pipeh);
454
455 /* remove tasks and timeouts */
456 usb_rem_task(sc->sc_udev, &sc->sc_task_newstate);
457 usb_rem_task(sc->sc_udev, &sc->sc_task_tx);
458 if (timeout_initialized(&sc->scan_to)((&sc->scan_to)->to_flags & 0x04))
459 timeout_del(&sc->scan_to);
460 if (timeout_initialized(&sc->led_to)((&sc->led_to)->to_flags & 0x04))
461 timeout_del(&sc->led_to);
462
463 /* free xfers */
464 upgt_free_tx(sc);
465 upgt_free_rx(sc);
466 upgt_free_cmd(sc);
467
468 /* free firmware */
469 upgt_fw_free(sc);
470
471 if (ifp->if_softc != NULL((void *)0)) {
472 /* detach interface */
473 ieee80211_ifdetach(ifp);
474 if_detach(ifp);
475 }
476
477 splx(s)spllower(s);
478
479 return (0);
480}
481
482int
483upgt_device_type(struct upgt_softc *sc, uint16_t vendor, uint16_t product)
484{
485 if (usb_lookup(upgt_devs_1, vendor, product)usbd_match_device((const struct usb_devno *)(upgt_devs_1), sizeof
(upgt_devs_1) / sizeof ((upgt_devs_1)[0]), sizeof ((upgt_devs_1
)[0]), (vendor), (product))
!= NULL((void *)0)) {
486 sc->sc_device_type = 1;
487 /* XXX */
488 printf("%s: version 1 devices not supported yet!\n",
489 sc->sc_dev.dv_xname);
490 return (1);
491 } else {
492 sc->sc_device_type = 2;
493 }
494
495 return (0);
496}
497
498int
499upgt_device_init(struct upgt_softc *sc)
500{
501 struct upgt_data *data_cmd = &sc->cmd_data;
502 char init_cmd[] = { 0x7e, 0x7e, 0x7e, 0x7e };
503 int len;
504
505 len = sizeof(init_cmd);
506 bcopy(init_cmd, data_cmd->buf, len);
507 if (upgt_bulk_xmit(sc, data_cmd, sc->sc_tx_pipeh, &len, 0) != 0) {
508 printf("%s: could not send device init string!\n",
509 sc->sc_dev.dv_xname);
510 return (EIO5);
511 }
512 usbd_delay_ms(sc->sc_udev, 100);
513
514 DPRINTF(1, "%s: device initialized\n", sc->sc_dev.dv_xname);
515
516 return (0);
517}
518
519int
520upgt_mem_init(struct upgt_softc *sc)
521{
522 int i;
523
524 for (i = 0; i < UPGT_MEMORY_MAX_PAGES8; i++) {
525 sc->sc_memory.page[i].used = 0;
526
527 if (i == 0) {
528 /*
529 * The first memory page is always reserved for
530 * command data.
531 */
532 sc->sc_memory.page[i].addr =
533 sc->sc_memaddr_frame_start + MCLBYTES(1 << 11);
534 } else {
535 sc->sc_memory.page[i].addr =
536 sc->sc_memory.page[i - 1].addr + MCLBYTES(1 << 11);
537 }
538
539 if (sc->sc_memory.page[i].addr + MCLBYTES(1 << 11) >=
540 sc->sc_memaddr_frame_end)
541 break;
542
543 DPRINTF(2, "%s: memory address page %d=0x%08x\n",
544 sc->sc_dev.dv_xname, i, sc->sc_memory.page[i].addr);
545 }
546
547 sc->sc_memory.pages = i;
548
549 DPRINTF(2, "%s: memory pages=%d\n",
550 sc->sc_dev.dv_xname, sc->sc_memory.pages);
551
552 return (0);
553}
554
555uint32_t
556upgt_mem_alloc(struct upgt_softc *sc)
557{
558 int i;
559
560 for (i = 0; i < sc->sc_memory.pages; i++) {
561 if (sc->sc_memory.page[i].used == 0) {
562 sc->sc_memory.page[i].used = 1;
563 return (sc->sc_memory.page[i].addr);
564 }
565 }
566
567 return (0);
568}
569
570void
571upgt_mem_free(struct upgt_softc *sc, uint32_t addr)
572{
573 int i;
574
575 for (i = 0; i < sc->sc_memory.pages; i++) {
576 if (sc->sc_memory.page[i].addr == addr) {
577 sc->sc_memory.page[i].used = 0;
578 return;
579 }
580 }
581
582 printf("%s: could not free memory address 0x%08x!\n",
583 sc->sc_dev.dv_xname, addr);
584}
585
586
587int
588upgt_fw_alloc(struct upgt_softc *sc)
589{
590 const char *name = "upgt-gw3887";
591 int error;
592
593 if (sc->sc_fw == NULL((void *)0)) {
594 error = loadfirmware(name, &sc->sc_fw, &sc->sc_fw_size);
595 if (error != 0) {
596 printf("%s: error %d, could not read firmware %s!\n",
597 sc->sc_dev.dv_xname, error, name);
598 return (EIO5);
599 }
600 }
601
602 DPRINTF(1, "%s: firmware %s allocated\n", sc->sc_dev.dv_xname, name);
603
604 return (0);
605}
606
607void
608upgt_fw_free(struct upgt_softc *sc)
609{
610 if (sc->sc_fw != NULL((void *)0)) {
611 free(sc->sc_fw, M_DEVBUF2, sc->sc_fw_size);
612 sc->sc_fw = NULL((void *)0);
613 DPRINTF(1, "%s: firmware freed\n", sc->sc_dev.dv_xname);
614 }
615}
616
617int
618upgt_fw_verify(struct upgt_softc *sc)
619{
620 struct upgt_fw_bra_option *bra_option;
621 uint32_t bra_option_type, bra_option_len;
622 uint32_t *uc;
623 int offset, bra_end = 0;
624
625 /*
626 * Seek to beginning of Boot Record Area (BRA).
627 */
628 for (offset = 0; offset < sc->sc_fw_size; offset += sizeof(*uc)) {
629 uc = (uint32_t *)(sc->sc_fw + offset);
630 if (*uc == 0)
631 break;
632 }
633 for (; offset < sc->sc_fw_size; offset += sizeof(*uc)) {
634 uc = (uint32_t *)(sc->sc_fw + offset);
635 if (*uc != 0)
636 break;
637 }
638 if (offset == sc->sc_fw_size) {
639 printf("%s: firmware Boot Record Area not found!\n",
640 sc->sc_dev.dv_xname);
641 return (EIO5);
642 }
643 DPRINTF(1, "%s: firmware Boot Record Area found at offset %d\n",
644 sc->sc_dev.dv_xname, offset);
645
646 /*
647 * Parse Boot Record Area (BRA) options.
648 */
649 while (offset < sc->sc_fw_size && bra_end == 0) {
650 /* get current BRA option */
651 bra_option = (struct upgt_fw_bra_option *)(sc->sc_fw + offset);
652 bra_option_type = letoh32(bra_option->type)((__uint32_t)(bra_option->type));
653 bra_option_len = letoh32(bra_option->len)((__uint32_t)(bra_option->len)) * sizeof(*uc);
654
655 switch (bra_option_type) {
656 case UPGT_BRA_TYPE_FW0x80000001:
657 DPRINTF(1, "%s: UPGT_BRA_TYPE_FW len=%d\n",
658 sc->sc_dev.dv_xname, bra_option_len);
659
660 if (bra_option_len != UPGT_BRA_FWTYPE_SIZE4) {
661 printf("%s: wrong UPGT_BRA_TYPE_FW len!\n",
662 sc->sc_dev.dv_xname);
663 return (EIO5);
664 }
665 if (memcmp(UPGT_BRA_FWTYPE_LM86, bra_option->data,__builtin_memcmp(("LM86"), (bra_option->data), (bra_option_len
))
666 bra_option_len)__builtin_memcmp(("LM86"), (bra_option->data), (bra_option_len
))
== 0) {
667 sc->sc_fw_type = UPGT_FWTYPE_LM86;
668 break;
669 }
670 if (memcmp(UPGT_BRA_FWTYPE_LM87, bra_option->data,__builtin_memcmp(("LM87"), (bra_option->data), (bra_option_len
))
671 bra_option_len)__builtin_memcmp(("LM87"), (bra_option->data), (bra_option_len
))
== 0) {
672 sc->sc_fw_type = UPGT_FWTYPE_LM87;
673 break;
674 }
675 if (memcmp(UPGT_BRA_FWTYPE_FMAC, bra_option->data,__builtin_memcmp(("FMAC"), (bra_option->data), (bra_option_len
))
676 bra_option_len)__builtin_memcmp(("FMAC"), (bra_option->data), (bra_option_len
))
== 0) {
677 sc->sc_fw_type = UPGT_FWTYPE_FMAC;
678 break;
679 }
680 printf("%s: unsupported firmware type!\n",
681 sc->sc_dev.dv_xname);
682 return (EIO5);
683 case UPGT_BRA_TYPE_VERSION0x80000002:
684 DPRINTF(1, "%s: UPGT_BRA_TYPE_VERSION len=%d\n",
685 sc->sc_dev.dv_xname, bra_option_len);
686 break;
687 case UPGT_BRA_TYPE_DEPIF0x80000003:
688 DPRINTF(1, "%s: UPGT_BRA_TYPE_DEPIF len=%d\n",
689 sc->sc_dev.dv_xname, bra_option_len);
690 break;
691 case UPGT_BRA_TYPE_EXPIF0x80000004:
692 DPRINTF(1, "%s: UPGT_BRA_TYPE_EXPIF len=%d\n",
693 sc->sc_dev.dv_xname, bra_option_len);
694 break;
695 case UPGT_BRA_TYPE_DESCR0x80000101:
696 DPRINTF(1, "%s: UPGT_BRA_TYPE_DESCR len=%d\n",
697 sc->sc_dev.dv_xname, bra_option_len);
698
699 struct upgt_fw_bra_descr *descr =
700 (struct upgt_fw_bra_descr *)bra_option->data;
701
702 sc->sc_memaddr_frame_start =
703 letoh32(descr->memaddr_space_start)((__uint32_t)(descr->memaddr_space_start));
704 sc->sc_memaddr_frame_end =
705 letoh32(descr->memaddr_space_end)((__uint32_t)(descr->memaddr_space_end));
706
707 DPRINTF(2, "%s: memory address space start=0x%08x\n",
708 sc->sc_dev.dv_xname, sc->sc_memaddr_frame_start);
709 DPRINTF(2, "%s: memory address space end=0x%08x\n",
710 sc->sc_dev.dv_xname, sc->sc_memaddr_frame_end);
711 break;
712 case UPGT_BRA_TYPE_END0xff0000ff:
713 DPRINTF(1, "%s: UPGT_BRA_TYPE_END len=%d\n",
714 sc->sc_dev.dv_xname, bra_option_len);
715 bra_end = 1;
716 break;
717 default:
718 DPRINTF(1, "%s: unknown BRA option len=%d\n",
719 sc->sc_dev.dv_xname, bra_option_len);
720 return (EIO5);
721 }
722
723 /* jump to next BRA option */
724 offset += sizeof(struct upgt_fw_bra_option) + bra_option_len;
725 }
726
727 DPRINTF(1, "%s: firmware verified\n", sc->sc_dev.dv_xname);
728
729 return (0);
730}
731
732int
733upgt_fw_load(struct upgt_softc *sc)
734{
735 struct upgt_data *data_cmd = &sc->cmd_data;
736 struct upgt_data *data_rx = &sc->rx_data;
737 char start_fwload_cmd[] = { 0x3c, 0x0d };
738 int offset, bsize, n, i, len;
739 uint32_t crc32;
740
741 /* send firmware start load command */
742 len = sizeof(start_fwload_cmd);
743 bcopy(start_fwload_cmd, data_cmd->buf, len);
744 if (upgt_bulk_xmit(sc, data_cmd, sc->sc_tx_pipeh, &len, 0) != 0) {
745 printf("%s: could not send start_firmware_load command!\n",
746 sc->sc_dev.dv_xname);
747 return (EIO5);
748 }
749
750 /* send X2 header */
751 len = sizeof(struct upgt_fw_x2_header);
752 struct upgt_fw_x2_header *x2 = data_cmd->buf;
753 bcopy(UPGT_X2_SIGNATURE"x2 ", x2->signature, UPGT_X2_SIGNATURE_SIZE4);
754 x2->startaddr = htole32(UPGT_MEMADDR_FIRMWARE_START)((__uint32_t)(0x00020000));
755 x2->len = htole32(sc->sc_fw_size)((__uint32_t)(sc->sc_fw_size));
756 x2->crc = upgt_crc32_le(data_cmd->buf + UPGT_X2_SIGNATURE_SIZE4,
757 sizeof(struct upgt_fw_x2_header) - UPGT_X2_SIGNATURE_SIZE4 -
758 sizeof(uint32_t));
759 if (upgt_bulk_xmit(sc, data_cmd, sc->sc_tx_pipeh, &len, 0) != 0) {
760 printf("%s: could not send firmware X2 header!\n",
761 sc->sc_dev.dv_xname);
762 return (EIO5);
763 }
764
765 /* download firmware */
766 for (offset = 0; offset < sc->sc_fw_size; offset += bsize) {
767 if (sc->sc_fw_size - offset > UPGT_FW_BLOCK_SIZE512)
768 bsize = UPGT_FW_BLOCK_SIZE512;
769 else
770 bsize = sc->sc_fw_size - offset;
771
772 n = upgt_fw_copy(sc->sc_fw + offset, data_cmd->buf, bsize);
773
774 DPRINTF(1, "%s: FW offset=%d, read=%d, sent=%d\n",
775 sc->sc_dev.dv_xname, offset, n, bsize);
776
777 if (upgt_bulk_xmit(sc, data_cmd, sc->sc_tx_pipeh, &bsize, 0)
778 != 0) {
779 printf("%s: error while downloading firmware block!\n",
780 sc->sc_dev.dv_xname);
781 return (EIO5);
782 }
783
784 bsize = n;
785 }
786 DPRINTF(1, "%s: firmware downloaded\n", sc->sc_dev.dv_xname);
787
788 /* load firmware */
789 crc32 = upgt_crc32_le(sc->sc_fw, sc->sc_fw_size);
790 *((uint32_t *)(data_cmd->buf) ) = crc32;
791 *((uint8_t *)(data_cmd->buf) + 4) = 'g';
792 *((uint8_t *)(data_cmd->buf) + 5) = '\r';
793 len = 6;
794 if (upgt_bulk_xmit(sc, data_cmd, sc->sc_tx_pipeh, &len, 0) != 0) {
795 printf("%s: could not send load_firmware command!\n",
796 sc->sc_dev.dv_xname);
797 return (EIO5);
798 }
799
800 for (i = 0; i < UPGT_FIRMWARE_TIMEOUT10; i++) {
801 len = UPGT_FW_BLOCK_SIZE512;
802 bzero(data_rx->buf, MCLBYTES)__builtin_bzero((data_rx->buf), ((1 << 11)));
803 if (upgt_bulk_xmit(sc, data_rx, sc->sc_rx_pipeh, &len,
804 USBD_SHORT_XFER_OK0x04) != 0) {
805 printf("%s: could not read firmware response!\n",
806 sc->sc_dev.dv_xname);
807 return (EIO5);
808 }
809
810 if (memcmp(data_rx->buf, "OK", 2)__builtin_memcmp((data_rx->buf), ("OK"), (2)) == 0)
811 break; /* firmware load was successful */
812 }
813 if (i == UPGT_FIRMWARE_TIMEOUT10) {
814 printf("%s: firmware load failed!\n", sc->sc_dev.dv_xname);
815 return (EIO5);
816 }
817 DPRINTF(1, "%s: firmware loaded\n", sc->sc_dev.dv_xname);
818
819 return (0);
820}
821
822/*
823 * While copying the version 2 firmware, we need to replace two characters:
824 *
825 * 0x7e -> 0x7d 0x5e
826 * 0x7d -> 0x7d 0x5d
827 */
828int
829upgt_fw_copy(char *src, char *dst, int size)
830{
831 int i, j;
832
833 for (i = 0, j = 0; i < size && j < size; i++) {
834 switch (src[i]) {
835 case 0x7e:
836 dst[j] = 0x7d;
837 j++;
838 dst[j] = 0x5e;
839 j++;
840 break;
841 case 0x7d:
842 dst[j] = 0x7d;
843 j++;
844 dst[j] = 0x5d;
845 j++;
846 break;
847 default:
848 dst[j] = src[i];
849 j++;
850 break;
851 }
852 }
853
854 return (i);
855}
856
857int
858upgt_eeprom_read(struct upgt_softc *sc)
859{
860 struct upgt_data *data_cmd = &sc->cmd_data;
861 struct upgt_lmac_mem *mem;
862 struct upgt_lmac_eeprom *eeprom;
863 int offset, block, len;
864
865 offset = 0;
866 block = UPGT_EEPROM_BLOCK_SIZE1020;
867 while (offset < UPGT_EEPROM_SIZE8192) {
868 DPRINTF(1, "%s: request EEPROM block (offset=%d, len=%d)\n",
869 sc->sc_dev.dv_xname, offset, block);
870
871 /*
872 * Transmit the URB containing the CMD data.
873 */
874 bzero(data_cmd->buf, MCLBYTES)__builtin_bzero((data_cmd->buf), ((1 << 11)));
875
876 mem = (struct upgt_lmac_mem *)data_cmd->buf;
877 mem->addr = htole32(sc->sc_memaddr_frame_start +((__uint32_t)(sc->sc_memaddr_frame_start + 0x0070))
878 UPGT_MEMSIZE_FRAME_HEAD)((__uint32_t)(sc->sc_memaddr_frame_start + 0x0070));
879
880 eeprom = (struct upgt_lmac_eeprom *)(mem + 1);
881 eeprom->header1.flags = 0;
882 eeprom->header1.type = UPGT_H1_TYPE_CTRL0x80;
883 eeprom->header1.len = htole16((((__uint16_t)(( sizeof(struct upgt_lmac_eeprom) - sizeof(struct
upgt_lmac_header)) + block))
884 sizeof(struct upgt_lmac_eeprom) -((__uint16_t)(( sizeof(struct upgt_lmac_eeprom) - sizeof(struct
upgt_lmac_header)) + block))
885 sizeof(struct upgt_lmac_header)) + block)((__uint16_t)(( sizeof(struct upgt_lmac_eeprom) - sizeof(struct
upgt_lmac_header)) + block))
;
886
887 eeprom->header2.reqid = htole32(sc->sc_memaddr_frame_start)((__uint32_t)(sc->sc_memaddr_frame_start));
888 eeprom->header2.type = htole16(UPGT_H2_TYPE_EEPROM)((__uint16_t)(0x000c));
889 eeprom->header2.flags = 0;
890
891 eeprom->offset = htole16(offset)((__uint16_t)(offset));
892 eeprom->len = htole16(block)((__uint16_t)(block));
893
894 len = sizeof(*mem) + sizeof(*eeprom) + block;
895
896 mem->chksum = upgt_chksum_le((uint32_t *)eeprom,
897 len - sizeof(*mem));
898
899 if (upgt_bulk_xmit(sc, data_cmd, sc->sc_tx_pipeh, &len,
900 USBD_FORCE_SHORT_XFER0x08) != 0) {
901 printf("%s: could not transmit EEPROM data URB!\n",
902 sc->sc_dev.dv_xname);
903 return (EIO5);
904 }
905 if (tsleep_nsec(sc, 0, "eeprom_request",
906 MSEC_TO_NSEC(UPGT_USB_TIMEOUT1000))) {
907 printf("%s: timeout while waiting for EEPROM data!\n",
908 sc->sc_dev.dv_xname);
909 return (EIO5);
910 }
911
912 offset += block;
913 if (UPGT_EEPROM_SIZE8192 - offset < block)
914 block = UPGT_EEPROM_SIZE8192 - offset;
915 }
916
917 return (0);
918}
919
920int
921upgt_eeprom_parse(struct upgt_softc *sc)
922{
923 struct ieee80211com *ic = &sc->sc_ic;
924 struct upgt_eeprom_header *eeprom_header;
925 struct upgt_eeprom_option *eeprom_option;
926 uint16_t option_len;
927 uint16_t option_type;
928 uint16_t preamble_len;
929 int option_end = 0;
930
931 /* calculate eeprom options start offset */
932 eeprom_header = (struct upgt_eeprom_header *)sc->sc_eeprom;
933 preamble_len = letoh16(eeprom_header->preamble_len)((__uint16_t)(eeprom_header->preamble_len));
934 eeprom_option = (struct upgt_eeprom_option *)(sc->sc_eeprom +
935 (sizeof(struct upgt_eeprom_header) + preamble_len));
936
937 while (!option_end) {
938 /* the eeprom option length is stored in words */
939 option_len =
940 (letoh16(eeprom_option->len)((__uint16_t)(eeprom_option->len)) - 1) * sizeof(uint16_t);
941 option_type =
942 letoh16(eeprom_option->type)((__uint16_t)(eeprom_option->type));
943
944 switch (option_type) {
945 case UPGT_EEPROM_TYPE_NAME0x0001:
946 DPRINTF(1, "%s: EEPROM name len=%d\n",
947 sc->sc_dev.dv_xname, option_len);
948 break;
949 case UPGT_EEPROM_TYPE_SERIAL0x0003:
950 DPRINTF(1, "%s: EEPROM serial len=%d\n",
951 sc->sc_dev.dv_xname, option_len);
952 break;
953 case UPGT_EEPROM_TYPE_MAC0x0101:
954 DPRINTF(1, "%s: EEPROM mac len=%d\n",
955 sc->sc_dev.dv_xname, option_len);
956
957 IEEE80211_ADDR_COPY(ic->ic_myaddr, eeprom_option->data)__builtin_memcpy((ic->ic_myaddr), (eeprom_option->data)
, (6))
;
958 break;
959 case UPGT_EEPROM_TYPE_HWRX0x1001:
960 DPRINTF(1, "%s: EEPROM hwrx len=%d\n",
961 sc->sc_dev.dv_xname, option_len);
962
963 upgt_eeprom_parse_hwrx(sc, eeprom_option->data);
964 break;
965 case UPGT_EEPROM_TYPE_CHIP0x1002:
966 DPRINTF(1, "%s: EEPROM chip len=%d\n",
967 sc->sc_dev.dv_xname, option_len);
968 break;
969 case UPGT_EEPROM_TYPE_FREQ30x1903:
970 DPRINTF(1, "%s: EEPROM freq3 len=%d\n",
971 sc->sc_dev.dv_xname, option_len);
972
973 upgt_eeprom_parse_freq3(sc, eeprom_option->data,
974 option_len);
975 break;
976 case UPGT_EEPROM_TYPE_FREQ40x1904:
977 DPRINTF(1, "%s: EEPROM freq4 len=%d\n",
978 sc->sc_dev.dv_xname, option_len);
979
980 upgt_eeprom_parse_freq4(sc, eeprom_option->data,
981 option_len);
982 break;
983 case UPGT_EEPROM_TYPE_FREQ50x1905:
984 DPRINTF(1, "%s: EEPROM freq5 len=%d\n",
985 sc->sc_dev.dv_xname, option_len);
986 break;
987 case UPGT_EEPROM_TYPE_FREQ60x1906:
988 DPRINTF(1, "%s: EEPROM freq6 len=%d\n",
989 sc->sc_dev.dv_xname, option_len);
990
991 upgt_eeprom_parse_freq6(sc, eeprom_option->data,
992 option_len);
993 break;
994 case UPGT_EEPROM_TYPE_END0x0000:
995 DPRINTF(1, "%s: EEPROM end len=%d\n",
996 sc->sc_dev.dv_xname, option_len);
997 option_end = 1;
998 break;
999 case UPGT_EEPROM_TYPE_OFF0xffff:
1000 DPRINTF(1, "%s: EEPROM off without end option!\n",
1001 sc->sc_dev.dv_xname);
1002 return (EIO5);
1003 default:
1004 DPRINTF(1, "%s: EEPROM unknown type 0x%04x len=%d\n",
1005 sc->sc_dev.dv_xname, option_type, option_len);
1006 break;
1007 }
1008
1009 /* jump to next EEPROM option */
1010 eeprom_option = (struct upgt_eeprom_option *)
1011 (eeprom_option->data + option_len);
1012 }
1013
1014 return (0);
1015}
1016
1017void
1018upgt_eeprom_parse_hwrx(struct upgt_softc *sc, uint8_t *data)
1019{
1020 struct upgt_eeprom_option_hwrx *option_hwrx;
1021
1022 option_hwrx = (struct upgt_eeprom_option_hwrx *)data;
1023
1024 sc->sc_eeprom_hwrx = option_hwrx->rxfilter - UPGT_EEPROM_RX_CONST0x88;
1025
1026 DPRINTF(2, "%s: hwrx option value=0x%04x\n",
1027 sc->sc_dev.dv_xname, sc->sc_eeprom_hwrx);
1028}
1029
1030void
1031upgt_eeprom_parse_freq3(struct upgt_softc *sc, uint8_t *data, int len)
1032{
1033 struct upgt_eeprom_freq3_header *freq3_header;
1034 struct upgt_lmac_freq3 *freq3;
1035 int i, elements, flags;
1036 unsigned channel;
1037
1038 freq3_header = (struct upgt_eeprom_freq3_header *)data;
1039 freq3 = (struct upgt_lmac_freq3 *)(freq3_header + 1);
1040
1041 flags = freq3_header->flags;
1042 elements = freq3_header->elements;
1043
1044 DPRINTF(2, "%s: flags=0x%02x\n", sc->sc_dev.dv_xname, flags);
1045 DPRINTF(2, "%s: elements=%d\n", sc->sc_dev.dv_xname, elements);
1046
1047 for (i = 0; i < elements; i++) {
1048 channel = ieee80211_mhz2ieee(letoh16(freq3[i].freq)((__uint16_t)(freq3[i].freq)), 0);
1049
1050 sc->sc_eeprom_freq3[channel] = freq3[i];
1051
1052 DPRINTF(2, "%s: frequency=%d, channel=%d\n",
1053 sc->sc_dev.dv_xname,
1054 letoh16(sc->sc_eeprom_freq3[channel].freq), channel);
1055 }
1056}
1057
1058void
1059upgt_eeprom_parse_freq4(struct upgt_softc *sc, uint8_t *data, int len)
1060{
1061 struct upgt_eeprom_freq4_header *freq4_header;
1062 struct upgt_eeprom_freq4_1 *freq4_1;
1063 struct upgt_eeprom_freq4_2 *freq4_2;
1064 int i, j, elements, settings, flags;
1065 unsigned channel;
1066
1067 freq4_header = (struct upgt_eeprom_freq4_header *)data;
1068 freq4_1 = (struct upgt_eeprom_freq4_1 *)(freq4_header + 1);
1069
1070 flags = freq4_header->flags;
Value stored to 'flags' is never read
1071 elements = freq4_header->elements;
1072 settings = freq4_header->settings;
1073
1074 /* we need this value later */
1075 sc->sc_eeprom_freq6_settings = freq4_header->settings;
1076
1077 DPRINTF(2, "%s: flags=0x%02x\n", sc->sc_dev.dv_xname, flags);
1078 DPRINTF(2, "%s: elements=%d\n", sc->sc_dev.dv_xname, elements);
1079 DPRINTF(2, "%s: settings=%d\n", sc->sc_dev.dv_xname, settings);
1080
1081 for (i = 0; i < elements; i++) {
1082 channel = ieee80211_mhz2ieee(letoh16(freq4_1[i].freq)((__uint16_t)(freq4_1[i].freq)), 0);
1083
1084 freq4_2 = (struct upgt_eeprom_freq4_2 *)freq4_1[i].data;
1085
1086 for (j = 0; j < settings; j++) {
1087 sc->sc_eeprom_freq4[channel][j].cmd = freq4_2[j];
1088 sc->sc_eeprom_freq4[channel][j].pad = 0;
1089 }
1090
1091 DPRINTF(2, "%s: frequency=%d, channel=%d\n",
1092 sc->sc_dev.dv_xname,
1093 letoh16(freq4_1[i].freq), channel);
1094 }
1095}
1096
1097void
1098upgt_eeprom_parse_freq6(struct upgt_softc *sc, uint8_t *data, int len)
1099{
1100 struct upgt_lmac_freq6 *freq6;
1101 int i, elements;
1102 unsigned channel;
1103
1104 freq6 = (struct upgt_lmac_freq6 *)data;
1105
1106 elements = len / sizeof(struct upgt_lmac_freq6);
1107
1108 DPRINTF(2, "%s: elements=%d\n", sc->sc_dev.dv_xname, elements);
1109
1110 for (i = 0; i < elements; i++) {
1111 channel = ieee80211_mhz2ieee(letoh16(freq6[i].freq)((__uint16_t)(freq6[i].freq)), 0);
1112
1113 sc->sc_eeprom_freq6[channel] = freq6[i];
1114
1115 DPRINTF(2, "%s: frequency=%d, channel=%d\n",
1116 sc->sc_dev.dv_xname,
1117 letoh16(sc->sc_eeprom_freq6[channel].freq), channel);
1118 }
1119}
1120
1121int
1122upgt_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1123{
1124 struct upgt_softc *sc = ifp->if_softc;
1125 struct ieee80211com *ic = &sc->sc_ic;
1126 int s, error = 0;
1127 uint8_t chan;
1128
1129 s = splnet()splraise(0x7);
1130
1131 switch (cmd) {
1132 case SIOCSIFADDR((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((12)))
:
1133 ifp->if_flags |= IFF_UP0x1;
1134 /* FALLTHROUGH */
1135 case SIOCSIFFLAGS((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((16)))
:
1136 if (ifp->if_flags & IFF_UP0x1) {
1137 if ((ifp->if_flags & IFF_RUNNING0x40) == 0)
1138 upgt_init(ifp);
1139 } else {
1140 if (ifp->if_flags & IFF_RUNNING0x40)
1141 upgt_stop(sc);
1142 }
1143 break;
1144 case SIOCS80211CHANNEL((unsigned long)0x80000000 | ((sizeof(struct ieee80211chanreq
) & 0x1fff) << 16) | ((('i')) << 8) | ((238))
)
:
1145 /* allow fast channel switching in monitor mode */
1146 error = ieee80211_ioctl(ifp, cmd, data);
1147 if (error == ENETRESET52 &&
1148 ic->ic_opmode == IEEE80211_M_MONITOR) {
1149 if ((ifp->if_flags & (IFF_UP0x1 | IFF_RUNNING0x40)) ==
1150 (IFF_UP0x1 | IFF_RUNNING0x40)) {
1151 ic->ic_bss->ni_chan = ic->ic_ibss_chan;
1152 chan = ieee80211_chan2ieee(ic,
1153 ic->ic_bss->ni_chan);
1154 upgt_set_channel(sc, chan);
1155 }
1156 error = 0;
1157 }
1158 break;
1159 default:
1160 error = ieee80211_ioctl(ifp, cmd, data);
1161 break;
1162 }
1163
1164 if (error == ENETRESET52) {
1165 if (ifp->if_flags & (IFF_UP0x1 | IFF_RUNNING0x40))
1166 upgt_init(ifp);
1167 error = 0;
1168 }
1169
1170 splx(s)spllower(s);
1171
1172 return (error);
1173}
1174
1175int
1176upgt_init(struct ifnet *ifp)
1177{
1178 struct upgt_softc *sc = ifp->if_softc;
1179 struct ieee80211com *ic = &sc->sc_ic;
1180
1181 DPRINTF(1, "%s: %s\n", sc->sc_dev.dv_xname, __func__);
1182
1183 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))
;
1184
1185 /* select default channel */
1186 ic->ic_bss->ni_chan = ic->ic_ibss_chan;
1187 sc->sc_cur_chan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
1188
1189 /* setup device rates */
1190 upgt_setup_rates(sc);
1191
1192 ifp->if_flags |= IFF_RUNNING0x40;
1193 ifq_clr_oactive(&ifp->if_snd);
1194
1195 upgt_set_macfilter(sc, IEEE80211_S_SCAN);
1196
1197 if (ic->ic_opmode == IEEE80211_M_MONITOR) {
1198 upgt_set_channel(sc, sc->sc_cur_chan);
1199 ieee80211_new_state(ic, IEEE80211_S_RUN, -1)(((ic)->ic_newstate)((ic), (IEEE80211_S_RUN), (-1)));
1200 } else
1201 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1)(((ic)->ic_newstate)((ic), (IEEE80211_S_SCAN), (-1)));
1202
1203 return (0);
1204}
1205
1206void
1207upgt_stop(struct upgt_softc *sc)
1208{
1209 struct ieee80211com *ic = &sc->sc_ic;
1210 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
1211
1212 DPRINTF(1, "%s: %s\n", sc->sc_dev.dv_xname, __func__);
1213
1214 /* device down */
1215 ifp->if_timer = 0;
1216 ifp->if_flags &= ~IFF_RUNNING0x40;
1217 ifq_clr_oactive(&ifp->if_snd);
1218
1219 upgt_set_led(sc, UPGT_LED_OFF0);
1220
1221 /* change device back to initial state */
1222 ieee80211_new_state(ic, IEEE80211_S_INIT, -1)(((ic)->ic_newstate)((ic), (IEEE80211_S_INIT), (-1)));
1223}
1224
1225int
1226upgt_media_change(struct ifnet *ifp)
1227{
1228 struct upgt_softc *sc = ifp->if_softc;
1229 int error;
1230
1231 DPRINTF(1, "%s: %s\n", sc->sc_dev.dv_xname, __func__);
1232
1233 if ((error = ieee80211_media_change(ifp)) != ENETRESET52)
1234 return (error);
1235
1236 if (ifp->if_flags & (IFF_UP0x1 | IFF_RUNNING0x40)) {
1237 /* give pending USB transfers a chance to finish */
1238 usbd_delay_ms(sc->sc_udev, 100);
1239 upgt_init(ifp);
1240 }
1241
1242 return (error);
1243}
1244
1245void
1246upgt_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni, int isnew)
1247{
1248 ni->ni_txrate = 0;
1249}
1250
1251int
1252upgt_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
1253{
1254 struct upgt_softc *sc = ic->ic_ific_ac.ac_if.if_softc;
1255
1256 usb_rem_task(sc->sc_udev, &sc->sc_task_newstate);
1257 timeout_del(&sc->scan_to);
1258
1259 /* do it in a process context */
1260 sc->sc_state = nstate;
1261 sc->sc_arg = arg;
1262 usb_add_task(sc->sc_udev, &sc->sc_task_newstate);
1263
1264 return (0);
1265}
1266
1267void
1268upgt_newstate_task(void *arg)
1269{
1270 struct upgt_softc *sc = arg;
1271 struct ieee80211com *ic = &sc->sc_ic;
1272 struct ieee80211_node *ni;
1273 unsigned channel;
1274
1275 switch (sc->sc_state) {
1276 case IEEE80211_S_INIT:
1277 DPRINTF(1, "%s: newstate is IEEE80211_S_INIT\n",
1278 sc->sc_dev.dv_xname);
1279
1280 /* do not accept any frames if the device is down */
1281 upgt_set_macfilter(sc, IEEE80211_S_INIT);
1282 upgt_set_led(sc, UPGT_LED_OFF0);
1283 break;
1284 case IEEE80211_S_SCAN:
1285 DPRINTF(1, "%s: newstate is IEEE80211_S_SCAN\n",
1286 sc->sc_dev.dv_xname);
1287
1288 channel = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
1289 upgt_set_channel(sc, channel);
1290 timeout_add_msec(&sc->scan_to, 200);
1291 break;
1292 case IEEE80211_S_AUTH:
1293 DPRINTF(1, "%s: newstate is IEEE80211_S_AUTH\n",
1294 sc->sc_dev.dv_xname);
1295
1296 channel = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
1297 upgt_set_channel(sc, channel);
1298 break;
1299 case IEEE80211_S_ASSOC:
1300 DPRINTF(1, "%s: newstate is IEEE80211_S_ASSOC\n",
1301 sc->sc_dev.dv_xname);
1302 break;
1303 case IEEE80211_S_RUN:
1304 DPRINTF(1, "%s: newstate is IEEE80211_S_RUN\n",
1305 sc->sc_dev.dv_xname);
1306
1307 ni = ic->ic_bss;
1308
1309 /*
1310 * TX rate control is done by the firmware.
1311 * Report the maximum rate which is available therefore.
1312 */
1313 ni->ni_txrate = ni->ni_rates.rs_nrates - 1;
1314
1315 if (ic->ic_opmode != IEEE80211_M_MONITOR)
1316 upgt_set_macfilter(sc, IEEE80211_S_RUN);
1317 upgt_set_led(sc, UPGT_LED_ON1);
1318 break;
1319 }
1320
1321 sc->sc_newstate(ic, sc->sc_state, sc->sc_arg);
1322}
1323
1324void
1325upgt_next_scan(void *arg)
1326{
1327 struct upgt_softc *sc = arg;
1328 struct ieee80211com *ic = &sc->sc_ic;
1329 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
1330
1331 DPRINTF(2, "%s: %s\n", sc->sc_dev.dv_xname, __func__);
1332
1333 if (ic->ic_state == IEEE80211_S_SCAN)
1334 ieee80211_next_scan(ifp);
1335}
1336
1337void
1338upgt_start(struct ifnet *ifp)
1339{
1340 struct upgt_softc *sc = ifp->if_softc;
1341 struct ieee80211com *ic = &sc->sc_ic;
1342 struct ieee80211_node *ni;
1343 struct mbuf *m;
1344 int i;
1345
1346 /* don't transmit packets if interface is busy or down */
1347 if (!(ifp->if_flags & IFF_RUNNING0x40) || ifq_is_oactive(&ifp->if_snd))
1348 return;
1349
1350 DPRINTF(2, "%s: %s\n", sc->sc_dev.dv_xname, __func__);
1351
1352 for (i = 0; i < UPGT_TX_COUNT6; i++) {
1353 struct upgt_data *data_tx = &sc->tx_data[i];
1354
1355 m = mq_dequeue(&ic->ic_mgtq);
1356 if (m != NULL((void *)0)) {
1357 /* management frame */
1358 ni = m->m_pkthdrM_dat.MH.MH_pkthdr.ph_cookie;
1359#if NBPFILTER1 > 0
1360 if (ic->ic_rawbpf != NULL((void *)0))
1361 bpf_mtap(ic->ic_rawbpf, m, BPF_DIRECTION_OUT(1 << 1));
1362#endif
1363 if ((data_tx->addr = upgt_mem_alloc(sc)) == 0) {
1364 printf("%s: no free prism memory!\n",
1365 sc->sc_dev.dv_xname);
1366 return;
1367 }
1368 data_tx->ni = ni;
1369 data_tx->m = m;
1370 sc->tx_queued++;
1371 } else {
1372 /* data frame */
1373 if (ic->ic_state != IEEE80211_S_RUN)
1374 break;
1375
1376 m = ifq_dequeue(&ifp->if_snd);
1377 if (m == NULL((void *)0))
1378 break;
1379
1380#if NBPFILTER1 > 0
1381 if (ifp->if_bpf != NULL((void *)0))
1382 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT(1 << 1));
1383#endif
1384 m = ieee80211_encap(ifp, m, &ni);
1385 if (m == NULL((void *)0))
1386 continue;
1387#if NBPFILTER1 > 0
1388 if (ic->ic_rawbpf != NULL((void *)0))
1389 bpf_mtap(ic->ic_rawbpf, m, BPF_DIRECTION_OUT(1 << 1));
1390#endif
1391 if ((data_tx->addr = upgt_mem_alloc(sc)) == 0) {
1392 printf("%s: no free prism memory!\n",
1393 sc->sc_dev.dv_xname);
1394 return;
1395 }
1396 data_tx->ni = ni;
1397 data_tx->m = m;
1398 sc->tx_queued++;
1399 }
1400 }
1401
1402 if (sc->tx_queued > 0) {
1403 DPRINTF(2, "%s: tx_queued=%d\n",
1404 sc->sc_dev.dv_xname, sc->tx_queued);
1405 /* process the TX queue in process context */
1406 ifp->if_timer = 5;
1407 ifq_set_oactive(&ifp->if_snd);
1408 usb_rem_task(sc->sc_udev, &sc->sc_task_tx);
1409 usb_add_task(sc->sc_udev, &sc->sc_task_tx);
1410 }
1411}
1412
1413void
1414upgt_watchdog(struct ifnet *ifp)
1415{
1416 struct upgt_softc *sc = ifp->if_softc;
1417 struct ieee80211com *ic = &sc->sc_ic;
1418
1419 if (ic->ic_state == IEEE80211_S_INIT)
1420 return;
1421
1422 printf("%s: watchdog timeout!\n", sc->sc_dev.dv_xname);
1423
1424 /* TODO: what shall we do on TX timeout? */
1425
1426 ieee80211_watchdog(ifp);
1427}
1428
1429void
1430upgt_tx_task(void *arg)
1431{
1432 struct upgt_softc *sc = arg;
1433 struct ieee80211com *ic = &sc->sc_ic;
1434 struct ieee80211_frame *wh;
1435 struct ieee80211_key *k;
1436 struct upgt_lmac_mem *mem;
1437 struct upgt_lmac_tx_desc *txdesc;
1438 struct mbuf *m;
1439 uint32_t addr;
1440 int len, i, s;
1441 usbd_status error;
1442
1443 s = splusb()splraise(0x5);
1444
1445 upgt_set_led(sc, UPGT_LED_BLINK2);
1446
1447 for (i = 0; i < UPGT_TX_COUNT6; i++) {
1448 struct upgt_data *data_tx = &sc->tx_data[i];
1449
1450 if (data_tx->m == NULL((void *)0)) {
1451 DPRINTF(2, "%s: %d: m is NULL\n",
1452 sc->sc_dev.dv_xname, i);
1453 continue;
1454 }
1455
1456 m = data_tx->m;
1457 addr = data_tx->addr + UPGT_MEMSIZE_FRAME_HEAD0x0070;
1458
1459 /*
1460 * Software crypto.
1461 */
1462 wh = mtod(m, struct ieee80211_frame *)((struct ieee80211_frame *)((m)->m_hdr.mh_data));
1463
1464 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED0x40) {
1465 k = ieee80211_get_txkey(ic, wh, ic->ic_bss);
1466
1467 if ((m = ieee80211_encrypt(ic, m, k)) == NULL((void *)0)) {
1468 splx(s)spllower(s);
1469 return;
1470 }
1471
1472 /* in case packet header moved, reset pointer */
1473 wh = mtod(m, struct ieee80211_frame *)((struct ieee80211_frame *)((m)->m_hdr.mh_data));
1474 }
1475
1476 /*
1477 * Transmit the URB containing the TX data.
1478 */
1479 bzero(data_tx->buf, MCLBYTES)__builtin_bzero((data_tx->buf), ((1 << 11)));
1480
1481 mem = (struct upgt_lmac_mem *)data_tx->buf;
1482 mem->addr = htole32(addr)((__uint32_t)(addr));
1483
1484 txdesc = (struct upgt_lmac_tx_desc *)(mem + 1);
1485
1486 /* XXX differ between data and mgmt frames? */
1487 txdesc->header1.flags = UPGT_H1_FLAGS_TX_DATA0x10;
1488 txdesc->header1.type = UPGT_H1_TYPE_TX_DATA0x40;
1489 txdesc->header1.len = htole16(m->m_pkthdr.len)((__uint16_t)(m->M_dat.MH.MH_pkthdr.len));
1490
1491 txdesc->header2.reqid = htole32(data_tx->addr)((__uint32_t)(data_tx->addr));
1492 txdesc->header2.type = htole16(UPGT_H2_TYPE_TX_ACK_YES)((__uint16_t)(0x0001));
1493 txdesc->header2.flags = htole16(UPGT_H2_FLAGS_TX_ACK_YES)((__uint16_t)(0x0707));
1494
1495 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK0x0c) ==
1496 IEEE80211_FC0_TYPE_MGT0x00) {
1497 /* always send mgmt frames at lowest rate (DS1) */
1498 memset(txdesc->rates, 0x10, sizeof(txdesc->rates))__builtin_memset((txdesc->rates), (0x10), (sizeof(txdesc->
rates)))
;
1499 } else {
1500 bcopy(sc->sc_cur_rateset, txdesc->rates,
1501 sizeof(txdesc->rates));
1502 }
1503 txdesc->type = htole32(UPGT_TX_DESC_TYPE_DATA)((__uint32_t)(0x00000004));
1504 txdesc->pad3[0] = UPGT_TX_DESC_PAD3_SIZE2;
1505
1506#if NBPFILTER1 > 0
1507 if (sc->sc_drvbpf != NULL((void *)0)) {
1508 struct mbuf mb;
1509 struct upgt_tx_radiotap_header *tap = &sc->sc_txtapsc_txtapu.th;
1510
1511 tap->wt_flags = 0;
1512 tap->wt_rate = 0; /* TODO: where to get from? */
1513 tap->wt_chan_freq =
1514 htole16(ic->ic_bss->ni_chan->ic_freq)((__uint16_t)(ic->ic_bss->ni_chan->ic_freq));
1515 tap->wt_chan_flags =
1516 htole16(ic->ic_bss->ni_chan->ic_flags)((__uint16_t)(ic->ic_bss->ni_chan->ic_flags));
1517
1518 mb.m_datam_hdr.mh_data = (caddr_t)tap;
1519 mb.m_lenm_hdr.mh_len = sc->sc_txtap_len;
1520 mb.m_nextm_hdr.mh_next = m;
1521 mb.m_nextpktm_hdr.mh_nextpkt = NULL((void *)0);
1522 mb.m_typem_hdr.mh_type = 0;
1523 mb.m_flagsm_hdr.mh_flags = 0;
1524 bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_OUT(1 << 1));
1525 }
1526#endif
1527 /* copy frame below our TX descriptor header */
1528 m_copydata(m, 0, m->m_pkthdrM_dat.MH.MH_pkthdr.len,
1529 data_tx->buf + (sizeof(*mem) + sizeof(*txdesc)));
1530
1531 /* calculate frame size */
1532 len = sizeof(*mem) + sizeof(*txdesc) + m->m_pkthdrM_dat.MH.MH_pkthdr.len;
1533
1534 /* we need to align the frame to a 4 byte boundary */
1535 len = (len + 3) & ~3;
1536
1537 /* calculate frame checksum */
1538 mem->chksum = upgt_chksum_le((uint32_t *)txdesc,
1539 len - sizeof(*mem));
1540
1541 /* we do not need the mbuf anymore */
1542 m_freem(m);
1543 data_tx->m = NULL((void *)0);
1544
1545 DPRINTF(2, "%s: TX start data sending\n", sc->sc_dev.dv_xname);
1546
1547 usbd_setup_xfer(data_tx->xfer, sc->sc_tx_pipeh, data_tx,
1548 data_tx->buf, len, USBD_FORCE_SHORT_XFER0x08 | USBD_NO_COPY0x01,
1549 UPGT_USB_TIMEOUT1000, NULL((void *)0));
1550 error = usbd_transfer(data_tx->xfer);
1551 if (error != 0 && error != USBD_IN_PROGRESS) {
1552 printf("%s: could not transmit TX data URB!\n",
1553 sc->sc_dev.dv_xname);
1554 splx(s)spllower(s);
1555 return;
1556 }
1557
1558 DPRINTF(2, "%s: TX sent (%d bytes)\n",
1559 sc->sc_dev.dv_xname, len);
1560 }
1561
1562 /*
1563 * If we don't regularly read the device statistics, the RX queue
1564 * will stall. It's strange, but it works, so we keep reading
1565 * the statistics here. *shrug*
1566 */
1567 upgt_get_stats(sc);
1568
1569 splx(s)spllower(s);
1570}
1571
1572void
1573upgt_tx_done(struct upgt_softc *sc, uint8_t *data)
1574{
1575 struct ieee80211com *ic = &sc->sc_ic;
1576 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
1577 struct upgt_lmac_tx_done_desc *desc;
1578 int i, s;
1579
1580 s = splnet()splraise(0x7);
1581
1582 desc = (struct upgt_lmac_tx_done_desc *)data;
1583
1584 for (i = 0; i < UPGT_TX_COUNT6; i++) {
1585 struct upgt_data *data_tx = &sc->tx_data[i];
1586
1587 if (data_tx->addr == letoh32(desc->header2.reqid)((__uint32_t)(desc->header2.reqid))) {
1588 upgt_mem_free(sc, data_tx->addr);
1589 ieee80211_release_node(ic, data_tx->ni);
1590 data_tx->ni = NULL((void *)0);
1591 data_tx->addr = 0;
1592
1593 sc->tx_queued--;
1594
1595 DPRINTF(2, "%s: TX done: ", sc->sc_dev.dv_xname);
1596 DPRINTF(2, "memaddr=0x%08x, status=0x%04x, rssi=%d, ",
1597 letoh32(desc->header2.reqid),
1598 letoh16(desc->status),
1599 letoh16(desc->rssi));
1600 DPRINTF(2, "seq=%d\n", letoh16(desc->seq));
1601 break;
1602 }
1603 }
1604
1605 if (sc->tx_queued == 0) {
1606 /* TX queued was processed, continue */
1607 ifp->if_timer = 0;
1608 ifq_clr_oactive(&ifp->if_snd);
1609 upgt_start(ifp);
1610 }
1611
1612 splx(s)spllower(s);
1613}
1614
1615void
1616upgt_rx_cb(struct usbd_xfer *xfer, void *priv, usbd_status status)
1617{
1618 struct upgt_data *data_rx = priv;
1619 struct upgt_softc *sc = data_rx->sc;
1620 int len;
1621 struct upgt_lmac_header *header;
1622 struct upgt_lmac_eeprom *eeprom;
1623 uint8_t h1_type;
1624 uint16_t h2_type;
1625
1626 DPRINTF(3, "%s: %s\n", sc->sc_dev.dv_xname, __func__);
1627
1628 if (status != USBD_NORMAL_COMPLETION) {
1629 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
1630 return;
1631 if (status == USBD_STALLED)
1632 usbd_clear_endpoint_stall_async(sc->sc_rx_pipeh);
1633 goto skip;
1634 }
1635 usbd_get_xfer_status(xfer, NULL((void *)0), NULL((void *)0), &len, NULL((void *)0));
1636
1637 /*
1638 * Check what type of frame came in.
1639 */
1640 header = (struct upgt_lmac_header *)(data_rx->buf + 4);
1641
1642 h1_type = header->header1.type;
1643 h2_type = letoh16(header->header2.type)((__uint16_t)(header->header2.type));
1644
1645 if (h1_type == UPGT_H1_TYPE_CTRL0x80 &&
1646 h2_type == UPGT_H2_TYPE_EEPROM0x000c) {
1647 eeprom = (struct upgt_lmac_eeprom *)(data_rx->buf + 4);
1648 uint16_t eeprom_offset = letoh16(eeprom->offset)((__uint16_t)(eeprom->offset));
1649 uint16_t eeprom_len = letoh16(eeprom->len)((__uint16_t)(eeprom->len));
1650
1651 DPRINTF(2, "%s: received EEPROM block (offset=%d, len=%d)\n",
1652 sc->sc_dev.dv_xname, eeprom_offset, eeprom_len);
1653
1654 bcopy(data_rx->buf + sizeof(struct upgt_lmac_eeprom) + 4,
1655 sc->sc_eeprom + eeprom_offset, eeprom_len);
1656
1657 /* EEPROM data has arrived in time, wakeup tsleep() */
1658 wakeup(sc);
1659 } else
1660 if (h1_type == UPGT_H1_TYPE_CTRL0x80 &&
1661 h2_type == UPGT_H2_TYPE_TX_DONE0x0008) {
1662 DPRINTF(2, "%s: received 802.11 TX done\n",
1663 sc->sc_dev.dv_xname);
1664
1665 upgt_tx_done(sc, data_rx->buf + 4);
1666 } else
1667 if (h1_type == UPGT_H1_TYPE_RX_DATA0x00 ||
1668 h1_type == UPGT_H1_TYPE_RX_DATA_MGMT0x04) {
1669 DPRINTF(3, "%s: received 802.11 RX data\n",
1670 sc->sc_dev.dv_xname);
1671
1672 upgt_rx(sc, data_rx->buf + 4, letoh16(header->header1.len)((__uint16_t)(header->header1.len)));
1673 } else
1674 if (h1_type == UPGT_H1_TYPE_CTRL0x80 &&
1675 h2_type == UPGT_H2_TYPE_STATS0x000a) {
1676 DPRINTF(2, "%s: received statistic data\n",
1677 sc->sc_dev.dv_xname);
1678
1679 /* TODO: what could we do with the statistic data? */
1680 } else {
1681 /* ignore unknown frame types */
1682 DPRINTF(1, "%s: received unknown frame type 0x%02x\n",
1683 sc->sc_dev.dv_xname, header->header1.type);
1684 }
1685
1686skip: /* setup new transfer */
1687 usbd_setup_xfer(xfer, sc->sc_rx_pipeh, data_rx, data_rx->buf, MCLBYTES(1 << 11),
1688 USBD_SHORT_XFER_OK0x04, USBD_NO_TIMEOUT0, upgt_rx_cb);
1689 (void)usbd_transfer(xfer);
1690}
1691
1692void
1693upgt_rx(struct upgt_softc *sc, uint8_t *data, int pkglen)
1694{
1695 struct ieee80211com *ic = &sc->sc_ic;
1696 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
1697 struct upgt_lmac_rx_desc *rxdesc;
1698 struct ieee80211_frame *wh;
1699 struct ieee80211_rxinfo rxi;
1700 struct ieee80211_node *ni;
1701 struct mbuf *m;
1702 int s;
1703
1704 /* access RX packet descriptor */
1705 rxdesc = (struct upgt_lmac_rx_desc *)data;
1706
1707 /* create mbuf which is suitable for strict alignment archs */
1708 m = m_devget(rxdesc->data, pkglen, ETHER_ALIGN2);
1709 if (m == NULL((void *)0)) {
1710 DPRINTF(1, "%s: could not create RX mbuf!\n", sc->sc_dev.dv_xname);
1711 ifp->if_ierrorsif_data.ifi_ierrors++;
1712 return;
1713 }
1714
1715 s = splnet()splraise(0x7);
1716
1717#if NBPFILTER1 > 0
1718 if (sc->sc_drvbpf != NULL((void *)0)) {
1719 struct mbuf mb;
1720 struct upgt_rx_radiotap_header *tap = &sc->sc_rxtapsc_rxtapu.th;
1721
1722 tap->wr_flags = IEEE80211_RADIOTAP_F_FCS0x10;
1723 tap->wr_rate = upgt_rx_rate(sc, rxdesc->rate);
1724 tap->wr_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq)((__uint16_t)(ic->ic_bss->ni_chan->ic_freq));
1725 tap->wr_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags)((__uint16_t)(ic->ic_bss->ni_chan->ic_flags));
1726 tap->wr_antsignal = rxdesc->rssi;
1727
1728 mb.m_datam_hdr.mh_data = (caddr_t)tap;
1729 mb.m_lenm_hdr.mh_len = sc->sc_rxtap_len;
1730 mb.m_nextm_hdr.mh_next = m;
1731 mb.m_nextpktm_hdr.mh_nextpkt = NULL((void *)0);
1732 mb.m_typem_hdr.mh_type = 0;
1733 mb.m_flagsm_hdr.mh_flags = 0;
1734 bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_IN(1 << 0));
1735 }
1736#endif
1737 /* trim FCS */
1738 m_adj(m, -IEEE80211_CRC_LEN4);
1739
1740 wh = mtod(m, struct ieee80211_frame *)((struct ieee80211_frame *)((m)->m_hdr.mh_data));
1741 ni = ieee80211_find_rxnode(ic, wh);
1742
1743 /* push the frame up to the 802.11 stack */
1744 rxi.rxi_flags = 0;
1745 rxi.rxi_rssi = rxdesc->rssi;
1746 rxi.rxi_tstamp = 0; /* unused */
1747 ieee80211_input(ifp, m, ni, &rxi);
1748
1749 /* node is no longer needed */
1750 ieee80211_release_node(ic, ni);
1751
1752 splx(s)spllower(s);
1753
1754 DPRINTF(3, "%s: RX done\n", sc->sc_dev.dv_xname);
1755}
1756
1757void
1758upgt_setup_rates(struct upgt_softc *sc)
1759{
1760 struct ieee80211com *ic = &sc->sc_ic;
1761
1762 /*
1763 * 0x01 = OFMD6 0x10 = DS1
1764 * 0x04 = OFDM9 0x11 = DS2
1765 * 0x06 = OFDM12 0x12 = DS5
1766 * 0x07 = OFDM18 0x13 = DS11
1767 * 0x08 = OFDM24
1768 * 0x09 = OFDM36
1769 * 0x0a = OFDM48
1770 * 0x0b = OFDM54
1771 */
1772 const uint8_t rateset_auto_11b[] =
1773 { 0x13, 0x13, 0x12, 0x11, 0x11, 0x10, 0x10, 0x10 };
1774 const uint8_t rateset_auto_11g[] =
1775 { 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x04, 0x01 };
1776 const uint8_t rateset_fix_11bg[] =
1777 { 0x10, 0x11, 0x12, 0x13, 0x01, 0x04, 0x06, 0x07,
1778 0x08, 0x09, 0x0a, 0x0b };
1779
1780 if (ic->ic_fixed_rate == -1) {
1781 /*
1782 * Automatic rate control is done by the device.
1783 * We just pass the rateset from which the device
1784 * will pickup a rate.
1785 */
1786 if (ic->ic_curmode == IEEE80211_MODE_11B)
1787 bcopy(rateset_auto_11b, sc->sc_cur_rateset,
1788 sizeof(sc->sc_cur_rateset));
1789 if (ic->ic_curmode == IEEE80211_MODE_11G ||
1790 ic->ic_curmode == IEEE80211_MODE_AUTO)
1791 bcopy(rateset_auto_11g, sc->sc_cur_rateset,
1792 sizeof(sc->sc_cur_rateset));
1793 } else {
1794 /* set a fixed rate */
1795 memset(sc->sc_cur_rateset, rateset_fix_11bg[ic->ic_fixed_rate],__builtin_memset((sc->sc_cur_rateset), (rateset_fix_11bg[ic
->ic_fixed_rate]), (sizeof(sc->sc_cur_rateset)))
1796 sizeof(sc->sc_cur_rateset))__builtin_memset((sc->sc_cur_rateset), (rateset_fix_11bg[ic
->ic_fixed_rate]), (sizeof(sc->sc_cur_rateset)))
;
1797 }
1798}
1799
1800uint8_t
1801upgt_rx_rate(struct upgt_softc *sc, const int rate)
1802{
1803 struct ieee80211com *ic = &sc->sc_ic;
1804
1805 if (ic->ic_curmode == IEEE80211_MODE_11B) {
1806 if (rate < 0 || rate > 3)
1807 /* invalid rate */
1808 return (0);
1809
1810 switch (rate) {
1811 case 0:
1812 return (2);
1813 case 1:
1814 return (4);
1815 case 2:
1816 return (11);
1817 case 3:
1818 return (22);
1819 default:
1820 return (0);
1821 }
1822 }
1823
1824 if (ic->ic_curmode == IEEE80211_MODE_11G) {
1825 if (rate < 0 || rate > 11)
1826 /* invalid rate */
1827 return (0);
1828
1829 switch (rate) {
1830 case 0:
1831 return (2);
1832 case 1:
1833 return (4);
1834 case 2:
1835 return (11);
1836 case 3:
1837 return (22);
1838 case 4:
1839 return (12);
1840 case 5:
1841 return (18);
1842 case 6:
1843 return (24);
1844 case 7:
1845 return (36);
1846 case 8:
1847 return (48);
1848 case 9:
1849 return (72);
1850 case 10:
1851 return (96);
1852 case 11:
1853 return (108);
1854 default:
1855 return (0);
1856 }
1857 }
1858
1859 return (0);
1860}
1861
1862int
1863upgt_set_macfilter(struct upgt_softc *sc, uint8_t state)
1864{
1865 struct ieee80211com *ic = &sc->sc_ic;
1866 struct ieee80211_node *ni = ic->ic_bss;
1867 struct upgt_data *data_cmd = &sc->cmd_data;
1868 struct upgt_lmac_mem *mem;
1869 struct upgt_lmac_filter *filter;
1870 int len;
1871 uint8_t broadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
1872
1873 /*
1874 * Transmit the URB containing the CMD data.
1875 */
1876 bzero(data_cmd->buf, MCLBYTES)__builtin_bzero((data_cmd->buf), ((1 << 11)));
1877
1878 mem = (struct upgt_lmac_mem *)data_cmd->buf;
1879 mem->addr = htole32(sc->sc_memaddr_frame_start +((__uint32_t)(sc->sc_memaddr_frame_start + 0x0070))
1880 UPGT_MEMSIZE_FRAME_HEAD)((__uint32_t)(sc->sc_memaddr_frame_start + 0x0070));
1881
1882 filter = (struct upgt_lmac_filter *)(mem + 1);
1883
1884 filter->header1.flags = UPGT_H1_FLAGS_TX_NO_CALLBACK0x01;
1885 filter->header1.type = UPGT_H1_TYPE_CTRL0x80;
1886 filter->header1.len = htole16(((__uint16_t)(sizeof(struct upgt_lmac_filter) - sizeof(struct
upgt_lmac_header)))
1887 sizeof(struct upgt_lmac_filter) -((__uint16_t)(sizeof(struct upgt_lmac_filter) - sizeof(struct
upgt_lmac_header)))
1888 sizeof(struct upgt_lmac_header))((__uint16_t)(sizeof(struct upgt_lmac_filter) - sizeof(struct
upgt_lmac_header)))
;
1889
1890 filter->header2.reqid = htole32(sc->sc_memaddr_frame_start)((__uint32_t)(sc->sc_memaddr_frame_start));
1891 filter->header2.type = htole16(UPGT_H2_TYPE_MACFILTER)((__uint16_t)(0x0000));
1892 filter->header2.flags = 0;
1893
1894 switch (state) {
1895 case IEEE80211_S_INIT:
1896 DPRINTF(1, "%s: set MAC filter to INIT\n",
1897 sc->sc_dev.dv_xname);
1898
1899 filter->type = htole16(UPGT_FILTER_TYPE_RESET)((__uint16_t)(0x0020));
1900 break;
1901 case IEEE80211_S_SCAN:
1902 DPRINTF(1, "%s: set MAC filter to SCAN (bssid %s)\n",
1903 sc->sc_dev.dv_xname, ether_sprintf(broadcast));
1904
1905 filter->type = htole16(UPGT_FILTER_TYPE_NONE)((__uint16_t)(0x0000));
1906 IEEE80211_ADDR_COPY(filter->dst, ic->ic_myaddr)__builtin_memcpy((filter->dst), (ic->ic_myaddr), (6));
1907 IEEE80211_ADDR_COPY(filter->src, broadcast)__builtin_memcpy((filter->src), (broadcast), (6));
1908 filter->unknown1 = htole16(UPGT_FILTER_UNKNOWN1)((__uint16_t)(0x0002));
1909 filter->rxaddr = htole32(sc->sc_memaddr_rx_start)((__uint32_t)(sc->sc_memaddr_rx_start));
1910 filter->unknown2 = htole16(UPGT_FILTER_UNKNOWN2)((__uint16_t)(0x0ca8));
1911 filter->rxhw = htole32(sc->sc_eeprom_hwrx)((__uint32_t)(sc->sc_eeprom_hwrx));
1912 filter->unknown3 = htole16(UPGT_FILTER_UNKNOWN3)((__uint16_t)(0xffff));
1913 break;
1914 case IEEE80211_S_RUN:
1915 DPRINTF(1, "%s: set MAC filter to RUN (bssid %s)\n",
1916 sc->sc_dev.dv_xname, ether_sprintf(ni->ni_bssid));
1917
1918 filter->type = htole16(UPGT_FILTER_TYPE_STA)((__uint16_t)(0x0001));
1919 IEEE80211_ADDR_COPY(filter->dst, ic->ic_myaddr)__builtin_memcpy((filter->dst), (ic->ic_myaddr), (6));
1920 IEEE80211_ADDR_COPY(filter->src, ni->ni_bssid)__builtin_memcpy((filter->src), (ni->ni_bssid), (6));
1921 filter->unknown1 = htole16(UPGT_FILTER_UNKNOWN1)((__uint16_t)(0x0002));
1922 filter->rxaddr = htole32(sc->sc_memaddr_rx_start)((__uint32_t)(sc->sc_memaddr_rx_start));
1923 filter->unknown2 = htole16(UPGT_FILTER_UNKNOWN2)((__uint16_t)(0x0ca8));
1924 filter->rxhw = htole32(sc->sc_eeprom_hwrx)((__uint32_t)(sc->sc_eeprom_hwrx));
1925 filter->unknown3 = htole16(UPGT_FILTER_UNKNOWN3)((__uint16_t)(0xffff));
1926 break;
1927 default:
1928 printf("%s: MAC filter does not know that state!\n",
1929 sc->sc_dev.dv_xname);
1930 break;
1931 }
1932
1933 len = sizeof(*mem) + sizeof(*filter);
1934
1935 mem->chksum = upgt_chksum_le((uint32_t *)filter,
1936 len - sizeof(*mem));
1937
1938 if (upgt_bulk_xmit(sc, data_cmd, sc->sc_tx_pipeh, &len, 0) != 0) {
1939 printf("%s: could not transmit macfilter CMD data URB!\n",
1940 sc->sc_dev.dv_xname);
1941 return (EIO5);
1942 }
1943
1944 return (0);
1945}
1946
1947int
1948upgt_set_channel(struct upgt_softc *sc, unsigned channel)
1949{
1950 struct upgt_data *data_cmd = &sc->cmd_data;
1951 struct upgt_lmac_mem *mem;
1952 struct upgt_lmac_channel *chan;
1953 int len;
1954
1955 DPRINTF(1, "%s: %s: %d\n", sc->sc_dev.dv_xname, __func__, channel);
1956
1957 /*
1958 * Transmit the URB containing the CMD data.
1959 */
1960 bzero(data_cmd->buf, MCLBYTES)__builtin_bzero((data_cmd->buf), ((1 << 11)));
1961
1962 mem = (struct upgt_lmac_mem *)data_cmd->buf;
1963 mem->addr = htole32(sc->sc_memaddr_frame_start +((__uint32_t)(sc->sc_memaddr_frame_start + 0x0070))
1964 UPGT_MEMSIZE_FRAME_HEAD)((__uint32_t)(sc->sc_memaddr_frame_start + 0x0070));
1965
1966 chan = (struct upgt_lmac_channel *)(mem + 1);
1967
1968 chan->header1.flags = UPGT_H1_FLAGS_TX_NO_CALLBACK0x01;
1969 chan->header1.type = UPGT_H1_TYPE_CTRL0x80;
1970 chan->header1.len = htole16(((__uint16_t)(sizeof(struct upgt_lmac_channel) - sizeof(struct
upgt_lmac_header)))
1971 sizeof(struct upgt_lmac_channel) -((__uint16_t)(sizeof(struct upgt_lmac_channel) - sizeof(struct
upgt_lmac_header)))
1972 sizeof(struct upgt_lmac_header))((__uint16_t)(sizeof(struct upgt_lmac_channel) - sizeof(struct
upgt_lmac_header)))
;
1973
1974 chan->header2.reqid = htole32(sc->sc_memaddr_frame_start)((__uint32_t)(sc->sc_memaddr_frame_start));
1975 chan->header2.type = htole16(UPGT_H2_TYPE_CHANNEL)((__uint16_t)(0x0001));
1976 chan->header2.flags = 0;
1977
1978 chan->unknown1 = htole16(UPGT_CHANNEL_UNKNOWN1)((__uint16_t)(0x0001));
1979 chan->unknown2 = htole16(UPGT_CHANNEL_UNKNOWN2)((__uint16_t)(0x0000));
1980 chan->freq6 = sc->sc_eeprom_freq6[channel];
1981 chan->settings = sc->sc_eeprom_freq6_settings;
1982 chan->unknown3 = UPGT_CHANNEL_UNKNOWN30x48;
1983
1984 bcopy(&sc->sc_eeprom_freq3[channel].data, chan->freq3_1,
1985 sizeof(chan->freq3_1));
1986
1987 bcopy(&sc->sc_eeprom_freq4[channel], chan->freq4,
1988 sizeof(sc->sc_eeprom_freq4[channel]));
1989
1990 bcopy(&sc->sc_eeprom_freq3[channel].data, chan->freq3_2,
1991 sizeof(chan->freq3_2));
1992
1993 len = sizeof(*mem) + sizeof(*chan);
1994
1995 mem->chksum = upgt_chksum_le((uint32_t *)chan,
1996 len - sizeof(*mem));
1997
1998 if (upgt_bulk_xmit(sc, data_cmd, sc->sc_tx_pipeh, &len, 0) != 0) {
1999 printf("%s: could not transmit channel CMD data URB!\n",
2000 sc->sc_dev.dv_xname);
2001 return (EIO5);
2002 }
2003
2004 return (0);
2005}
2006
2007void
2008upgt_set_led(struct upgt_softc *sc, int action)
2009{
2010 struct ieee80211com *ic = &sc->sc_ic;
2011 struct upgt_data *data_cmd = &sc->cmd_data;
2012 struct upgt_lmac_mem *mem;
2013 struct upgt_lmac_led *led;
2014 int len;
2015
2016 /*
2017 * Transmit the URB containing the CMD data.
2018 */
2019 bzero(data_cmd->buf, MCLBYTES)__builtin_bzero((data_cmd->buf), ((1 << 11)));
2020
2021 mem = (struct upgt_lmac_mem *)data_cmd->buf;
2022 mem->addr = htole32(sc->sc_memaddr_frame_start +((__uint32_t)(sc->sc_memaddr_frame_start + 0x0070))
2023 UPGT_MEMSIZE_FRAME_HEAD)((__uint32_t)(sc->sc_memaddr_frame_start + 0x0070));
2024
2025 led = (struct upgt_lmac_led *)(mem + 1);
2026
2027 led->header1.flags = UPGT_H1_FLAGS_TX_NO_CALLBACK0x01;
2028 led->header1.type = UPGT_H1_TYPE_CTRL0x80;
2029 led->header1.len = htole16(((__uint16_t)(sizeof(struct upgt_lmac_led) - sizeof(struct upgt_lmac_header
)))
2030 sizeof(struct upgt_lmac_led) -((__uint16_t)(sizeof(struct upgt_lmac_led) - sizeof(struct upgt_lmac_header
)))
2031 sizeof(struct upgt_lmac_header))((__uint16_t)(sizeof(struct upgt_lmac_led) - sizeof(struct upgt_lmac_header
)))
;
2032
2033 led->header2.reqid = htole32(sc->sc_memaddr_frame_start)((__uint32_t)(sc->sc_memaddr_frame_start));
2034 led->header2.type = htole16(UPGT_H2_TYPE_LED)((__uint16_t)(0x000d));
2035 led->header2.flags = 0;
2036
2037 switch (action) {
2038 case UPGT_LED_OFF0:
2039 led->mode = htole16(UPGT_LED_MODE_SET)((__uint16_t)(0x0003));
2040 led->action_fix = 0;
2041 led->action_tmp = htole16(UPGT_LED_ACTION_OFF)((__uint16_t)(0x0002));
2042 led->action_tmp_dur = 0;
2043 break;
2044 case UPGT_LED_ON1:
2045 led->mode = htole16(UPGT_LED_MODE_SET)((__uint16_t)(0x0003));
2046 led->action_fix = 0;
2047 led->action_tmp = htole16(UPGT_LED_ACTION_ON)((__uint16_t)(0x0003));
2048 led->action_tmp_dur = 0;
2049 break;
2050 case UPGT_LED_BLINK2:
2051 if (ic->ic_state != IEEE80211_S_RUN)
2052 return;
2053 if (sc->sc_led_blink)
2054 /* previous blink was not finished */
2055 return;
2056 led->mode = htole16(UPGT_LED_MODE_SET)((__uint16_t)(0x0003));
2057 led->action_fix = htole16(UPGT_LED_ACTION_OFF)((__uint16_t)(0x0002));
2058 led->action_tmp = htole16(UPGT_LED_ACTION_ON)((__uint16_t)(0x0003));
2059 led->action_tmp_dur = htole16(UPGT_LED_ACTION_TMP_DUR)((__uint16_t)(100));
2060 /* lock blink */
2061 sc->sc_led_blink = 1;
2062 timeout_add_msec(&sc->led_to, UPGT_LED_ACTION_TMP_DUR100);
2063 break;
2064 default:
2065 return;
2066 }
2067
2068 len = sizeof(*mem) + sizeof(*led);
2069
2070 mem->chksum = upgt_chksum_le((uint32_t *)led,
2071 len - sizeof(*mem));
2072
2073 if (upgt_bulk_xmit(sc, data_cmd, sc->sc_tx_pipeh, &len, 0) != 0) {
2074 printf("%s: could not transmit led CMD URB!\n",
2075 sc->sc_dev.dv_xname);
2076 }
2077}
2078
2079void
2080upgt_set_led_blink(void *arg)
2081{
2082 struct upgt_softc *sc = arg;
2083
2084 /* blink finished, we are ready for a next one */
2085 sc->sc_led_blink = 0;
2086 timeout_del(&sc->led_to);
2087}
2088
2089int
2090upgt_get_stats(struct upgt_softc *sc)
2091{
2092 struct upgt_data *data_cmd = &sc->cmd_data;
2093 struct upgt_lmac_mem *mem;
2094 struct upgt_lmac_stats *stats;
2095 int len;
2096
2097 /*
2098 * Transmit the URB containing the CMD data.
2099 */
2100 bzero(data_cmd->buf, MCLBYTES)__builtin_bzero((data_cmd->buf), ((1 << 11)));
2101
2102 mem = (struct upgt_lmac_mem *)data_cmd->buf;
2103 mem->addr = htole32(sc->sc_memaddr_frame_start +((__uint32_t)(sc->sc_memaddr_frame_start + 0x0070))
2104 UPGT_MEMSIZE_FRAME_HEAD)((__uint32_t)(sc->sc_memaddr_frame_start + 0x0070));
2105
2106 stats = (struct upgt_lmac_stats *)(mem + 1);
2107
2108 stats->header1.flags = 0;
2109 stats->header1.type = UPGT_H1_TYPE_CTRL0x80;
2110 stats->header1.len = htole16(((__uint16_t)(sizeof(struct upgt_lmac_stats) - sizeof(struct upgt_lmac_header
)))
2111 sizeof(struct upgt_lmac_stats) -((__uint16_t)(sizeof(struct upgt_lmac_stats) - sizeof(struct upgt_lmac_header
)))
2112 sizeof(struct upgt_lmac_header))((__uint16_t)(sizeof(struct upgt_lmac_stats) - sizeof(struct upgt_lmac_header
)))
;
2113
2114 stats->header2.reqid = htole32(sc->sc_memaddr_frame_start)((__uint32_t)(sc->sc_memaddr_frame_start));
2115 stats->header2.type = htole16(UPGT_H2_TYPE_STATS)((__uint16_t)(0x000a));
2116 stats->header2.flags = 0;
2117
2118 len = sizeof(*mem) + sizeof(*stats);
2119
2120 mem->chksum = upgt_chksum_le((uint32_t *)stats,
2121 len - sizeof(*mem));
2122
2123 if (upgt_bulk_xmit(sc, data_cmd, sc->sc_tx_pipeh, &len, 0) != 0) {
2124 printf("%s: could not transmit statistics CMD data URB!\n",
2125 sc->sc_dev.dv_xname);
2126 return (EIO5);
2127 }
2128
2129 return (0);
2130
2131}
2132
2133int
2134upgt_alloc_tx(struct upgt_softc *sc)
2135{
2136 int i;
2137
2138 sc->tx_queued = 0;
2139
2140 for (i = 0; i < UPGT_TX_COUNT6; i++) {
2141 struct upgt_data *data_tx = &sc->tx_data[i];
2142
2143 data_tx->sc = sc;
2144
2145 data_tx->xfer = usbd_alloc_xfer(sc->sc_udev);
2146 if (data_tx->xfer == NULL((void *)0)) {
2147 printf("%s: could not allocate TX xfer!\n",
2148 sc->sc_dev.dv_xname);
2149 return (ENOMEM12);
2150 }
2151
2152 data_tx->buf = usbd_alloc_buffer(data_tx->xfer, MCLBYTES(1 << 11));
2153 if (data_tx->buf == NULL((void *)0)) {
2154 printf("%s: could not allocate TX buffer!\n",
2155 sc->sc_dev.dv_xname);
2156 return (ENOMEM12);
2157 }
2158
2159 bzero(data_tx->buf, MCLBYTES)__builtin_bzero((data_tx->buf), ((1 << 11)));
2160 }
2161
2162 return (0);
2163}
2164
2165int
2166upgt_alloc_rx(struct upgt_softc *sc)
2167{
2168 struct upgt_data *data_rx = &sc->rx_data;
2169
2170 data_rx->sc = sc;
2171
2172 data_rx->xfer = usbd_alloc_xfer(sc->sc_udev);
2173 if (data_rx->xfer == NULL((void *)0)) {
2174 printf("%s: could not allocate RX xfer!\n",
2175 sc->sc_dev.dv_xname);
2176 return (ENOMEM12);
2177 }
2178
2179 data_rx->buf = usbd_alloc_buffer(data_rx->xfer, MCLBYTES(1 << 11));
2180 if (data_rx->buf == NULL((void *)0)) {
2181 printf("%s: could not allocate RX buffer!\n",
2182 sc->sc_dev.dv_xname);
2183 return (ENOMEM12);
2184 }
2185
2186 bzero(data_rx->buf, MCLBYTES)__builtin_bzero((data_rx->buf), ((1 << 11)));
2187
2188 return (0);
2189}
2190
2191int
2192upgt_alloc_cmd(struct upgt_softc *sc)
2193{
2194 struct upgt_data *data_cmd = &sc->cmd_data;
2195
2196 data_cmd->sc = sc;
2197
2198 data_cmd->xfer = usbd_alloc_xfer(sc->sc_udev);
2199 if (data_cmd->xfer == NULL((void *)0)) {
2200 printf("%s: could not allocate RX xfer!\n",
2201 sc->sc_dev.dv_xname);
2202 return (ENOMEM12);
2203 }
2204
2205 data_cmd->buf = usbd_alloc_buffer(data_cmd->xfer, MCLBYTES(1 << 11));
2206 if (data_cmd->buf == NULL((void *)0)) {
2207 printf("%s: could not allocate RX buffer!\n",
2208 sc->sc_dev.dv_xname);
2209 return (ENOMEM12);
2210 }
2211
2212 bzero(data_cmd->buf, MCLBYTES)__builtin_bzero((data_cmd->buf), ((1 << 11)));
2213
2214 return (0);
2215}
2216
2217void
2218upgt_free_tx(struct upgt_softc *sc)
2219{
2220 int i;
2221
2222 for (i = 0; i < UPGT_TX_COUNT6; i++) {
2223 struct upgt_data *data_tx = &sc->tx_data[i];
2224
2225 if (data_tx->xfer != NULL((void *)0)) {
2226 usbd_free_xfer(data_tx->xfer);
2227 data_tx->xfer = NULL((void *)0);
2228 }
2229
2230 data_tx->ni = NULL((void *)0);
2231 }
2232}
2233
2234void
2235upgt_free_rx(struct upgt_softc *sc)
2236{
2237 struct upgt_data *data_rx = &sc->rx_data;
2238
2239 if (data_rx->xfer != NULL((void *)0)) {
2240 usbd_free_xfer(data_rx->xfer);
2241 data_rx->xfer = NULL((void *)0);
2242 }
2243
2244 data_rx->ni = NULL((void *)0);
2245}
2246
2247void
2248upgt_free_cmd(struct upgt_softc *sc)
2249{
2250 struct upgt_data *data_cmd = &sc->cmd_data;
2251
2252 if (data_cmd->xfer != NULL((void *)0)) {
2253 usbd_free_xfer(data_cmd->xfer);
2254 data_cmd->xfer = NULL((void *)0);
2255 }
2256}
2257
2258int
2259upgt_bulk_xmit(struct upgt_softc *sc, struct upgt_data *data,
2260 struct usbd_pipe *pipeh, uint32_t *size, int flags)
2261{
2262 usbd_status status;
2263
2264 usbd_setup_xfer(data->xfer, pipeh, 0, data->buf, *size,
2265 USBD_NO_COPY0x01 | USBD_SYNCHRONOUS0x02 | flags, UPGT_USB_TIMEOUT1000, NULL((void *)0));
2266 status = usbd_transfer(data->xfer);
2267 if (status != USBD_NORMAL_COMPLETION) {
2268 printf("%s: %s: error %s!\n",
2269 sc->sc_dev.dv_xname, __func__, usbd_errstr(status));
2270 return (EIO5);
2271 }
2272
2273 return (0);
2274}
2275
2276void
2277upgt_hexdump(void *buf, int len)
2278{
2279 int i;
2280
2281 for (i = 0; i < len; i++) {
2282 if (i % 16 == 0)
2283 printf("%s%5i:", i ? "\n" : "", i);
2284 if (i % 4 == 0)
2285 printf(" ");
2286 printf("%02x", (int)*((u_char *)buf + i));
2287 }
2288 printf("\n");
2289}
2290
2291uint32_t
2292upgt_crc32_le(const void *buf, size_t size)
2293{
2294 uint32_t crc;
2295
2296 crc = ether_crc32_le(buf, size);
2297
2298 /* apply final XOR value as common for CRC-32 */
2299 crc = htole32(crc ^ 0xffffffffU)((__uint32_t)(crc ^ 0xffffffffU));
2300
2301 return (crc);
2302}
2303
2304/*
2305 * The firmware awaits a checksum for each frame we send to it.
2306 * The algorithm used therefor is uncommon but somehow similar to CRC32.
2307 */
2308uint32_t
2309upgt_chksum_le(const uint32_t *buf, size_t size)
2310{
2311 int i;
2312 uint32_t crc = 0;
2313
2314 for (i = 0; i < size; i += sizeof(uint32_t)) {
2315 crc = htole32(crc ^ *buf++)((__uint32_t)(crc ^ *buf++));
2316 crc = htole32((crc >> 5) ^ (crc << 3))((__uint32_t)((crc >> 5) ^ (crc << 3)));
2317 }
2318
2319 return (crc);
2320}