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