1/*	$OpenBSD: if_upgt.c,v 1.35 2008/04/16 18:32:15 damien Exp $ */
2/*	$FreeBSD$ */
3
4/*
5 * Copyright (c) 2007 Marcus Glocker <mglocker@openbsd.org>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#include "opt_wlan.h"
21
22#include <sys/param.h>
23#include <sys/systm.h>
24#include <sys/kernel.h>
25#include <sys/endian.h>
26#include <sys/firmware.h>
27#include <sys/linker.h>
28#include <sys/mbuf.h>
29#include <sys/malloc.h>
30#include <sys/module.h>
31#include <sys/socket.h>
32#include <sys/sockio.h>
33#include <sys/sysctl.h>
34
35#include <net/if.h>
36#include <net/if_var.h>
37#include <net/if_arp.h>
38#include <net/ethernet.h>
39#include <net/if_dl.h>
40#include <net/if_media.h>
41#include <net/if_types.h>
42
43#include <sys/bus.h>
44
45#include <net80211/ieee80211_var.h>
46#include <net80211/ieee80211_phy.h>
47#include <net80211/ieee80211_radiotap.h>
48#include <net80211/ieee80211_regdomain.h>
49
50#include <net/bpf.h>
51
52#include <dev/usb/usb.h>
53#include <dev/usb/usbdi.h>
54#include "usbdevs.h"
55
56#include <dev/usb/wlan/if_upgtvar.h>
57
58/*
59 * Driver for the USB PrismGT devices.
60 *
61 * For now just USB 2.0 devices with the GW3887 chipset are supported.
62 * The driver has been written based on the firmware version 2.13.1.0_LM87.
63 *
64 * TODO's:
65 * - MONITOR mode test.
66 * - Add HOSTAP mode.
67 * - Add IBSS mode.
68 * - Support the USB 1.0 devices (NET2280, ISL3880, ISL3886 chipsets).
69 *
70 * Parts of this driver has been influenced by reading the p54u driver
71 * written by Jean-Baptiste Note <jean-baptiste.note@m4x.org> and
72 * Sebastien Bourdeauducq <lekernel@prism54.org>.
73 */
74
75static SYSCTL_NODE(_hw, OID_AUTO, upgt, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
76    "USB PrismGT GW3887 driver parameters");
77
78#ifdef UPGT_DEBUG
79int upgt_debug = 0;
80SYSCTL_INT(_hw_upgt, OID_AUTO, debug, CTLFLAG_RWTUN, &upgt_debug,
81	    0, "control debugging printfs");
82enum {
83	UPGT_DEBUG_XMIT		= 0x00000001,	/* basic xmit operation */
84	UPGT_DEBUG_RECV		= 0x00000002,	/* basic recv operation */
85	UPGT_DEBUG_RESET	= 0x00000004,	/* reset processing */
86	UPGT_DEBUG_INTR		= 0x00000008,	/* INTR */
87	UPGT_DEBUG_TX_PROC	= 0x00000010,	/* tx ISR proc */
88	UPGT_DEBUG_RX_PROC	= 0x00000020,	/* rx ISR proc */
89	UPGT_DEBUG_STATE	= 0x00000040,	/* 802.11 state transitions */
90	UPGT_DEBUG_STAT		= 0x00000080,	/* statistic */
91	UPGT_DEBUG_FW		= 0x00000100,	/* firmware */
92	UPGT_DEBUG_ANY		= 0xffffffff
93};
94#define	DPRINTF(sc, m, fmt, ...) do {				\
95	if (sc->sc_debug & (m))					\
96		printf(fmt, __VA_ARGS__);			\
97} while (0)
98#else
99#define	DPRINTF(sc, m, fmt, ...) do {				\
100	(void) sc;						\
101} while (0)
102#endif
103
104/*
105 * Prototypes.
106 */
107static device_probe_t upgt_match;
108static device_attach_t upgt_attach;
109static device_detach_t upgt_detach;
110static int	upgt_alloc_tx(struct upgt_softc *);
111static int	upgt_alloc_rx(struct upgt_softc *);
112static int	upgt_device_reset(struct upgt_softc *);
113static void	upgt_bulk_tx(struct upgt_softc *, struct upgt_data *);
114static int	upgt_fw_verify(struct upgt_softc *);
115static int	upgt_mem_init(struct upgt_softc *);
116static int	upgt_fw_load(struct upgt_softc *);
117static int	upgt_fw_copy(const uint8_t *, char *, int);
118static uint32_t	upgt_crc32_le(const void *, size_t);
119static struct mbuf *
120		upgt_rxeof(struct usb_xfer *, struct upgt_data *, int *);
121static struct mbuf *
122		upgt_rx(struct upgt_softc *, uint8_t *, int, int *);
123static void	upgt_txeof(struct usb_xfer *, struct upgt_data *);
124static int	upgt_eeprom_read(struct upgt_softc *);
125static int	upgt_eeprom_parse(struct upgt_softc *);
126static void	upgt_eeprom_parse_hwrx(struct upgt_softc *, uint8_t *);
127static void	upgt_eeprom_parse_freq3(struct upgt_softc *, uint8_t *, int);
128static void	upgt_eeprom_parse_freq4(struct upgt_softc *, uint8_t *, int);
129static void	upgt_eeprom_parse_freq6(struct upgt_softc *, uint8_t *, int);
130static uint32_t	upgt_chksum_le(const uint32_t *, size_t);
131static void	upgt_tx_done(struct upgt_softc *, uint8_t *);
132static void	upgt_init(struct upgt_softc *);
133static void	upgt_parent(struct ieee80211com *);
134static int	upgt_transmit(struct ieee80211com *, struct mbuf *);
135static void	upgt_start(struct upgt_softc *);
136static int	upgt_raw_xmit(struct ieee80211_node *, struct mbuf *,
137		    const struct ieee80211_bpf_params *);
138static void	upgt_scan_start(struct ieee80211com *);
139static void	upgt_scan_end(struct ieee80211com *);
140static void	upgt_set_channel(struct ieee80211com *);
141static struct ieee80211vap *upgt_vap_create(struct ieee80211com *,
142		    const char [IFNAMSIZ], int, enum ieee80211_opmode, int,
143		    const uint8_t [IEEE80211_ADDR_LEN],
144		    const uint8_t [IEEE80211_ADDR_LEN]);
145static void	upgt_vap_delete(struct ieee80211vap *);
146static void	upgt_update_mcast(struct ieee80211com *);
147static uint8_t	upgt_rx_rate(struct upgt_softc *, const int);
148static void	upgt_set_multi(void *);
149static void	upgt_stop(struct upgt_softc *);
150static void	upgt_setup_rates(struct ieee80211vap *, struct ieee80211com *);
151static int	upgt_set_macfilter(struct upgt_softc *, uint8_t);
152static int	upgt_newstate(struct ieee80211vap *, enum ieee80211_state, int);
153static void	upgt_set_chan(struct upgt_softc *, struct ieee80211_channel *);
154static void	upgt_set_led(struct upgt_softc *, int);
155static void	upgt_set_led_blink(void *);
156static void	upgt_get_stats(struct upgt_softc *);
157static void	upgt_mem_free(struct upgt_softc *, uint32_t);
158static uint32_t	upgt_mem_alloc(struct upgt_softc *);
159static void	upgt_free_tx(struct upgt_softc *);
160static void	upgt_free_rx(struct upgt_softc *);
161static void	upgt_watchdog(void *);
162static void	upgt_abort_xfers(struct upgt_softc *);
163static void	upgt_abort_xfers_locked(struct upgt_softc *);
164static void	upgt_sysctl_node(struct upgt_softc *);
165static struct upgt_data *
166		upgt_getbuf(struct upgt_softc *);
167static struct upgt_data *
168		upgt_gettxbuf(struct upgt_softc *);
169static int	upgt_tx_start(struct upgt_softc *, struct mbuf *,
170		    struct ieee80211_node *, struct upgt_data *);
171
172static const char *upgt_fwname = "upgt-gw3887";
173
174static const STRUCT_USB_HOST_ID upgt_devs[] = {
175#define	UPGT_DEV(v,p) { USB_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p) }
176	/* version 2 devices */
177	UPGT_DEV(ACCTON,	PRISM_GT),
178	UPGT_DEV(BELKIN,	F5D7050),
179	UPGT_DEV(CISCOLINKSYS,	WUSB54AG),
180	UPGT_DEV(CONCEPTRONIC,	PRISM_GT),
181	UPGT_DEV(DELL,		PRISM_GT_1),
182	UPGT_DEV(DELL,		PRISM_GT_2),
183	UPGT_DEV(FSC,		E5400),
184	UPGT_DEV(GLOBESPAN,	PRISM_GT_1),
185	UPGT_DEV(GLOBESPAN,	PRISM_GT_2),
186	UPGT_DEV(NETGEAR,	WG111V1_2),
187	UPGT_DEV(INTERSIL,	PRISM_GT),
188	UPGT_DEV(SMC,		2862WG),
189	UPGT_DEV(USR,		USR5422),
190	UPGT_DEV(WISTRONNEWEB,	UR045G),
191	UPGT_DEV(XYRATEX,	PRISM_GT_1),
192	UPGT_DEV(XYRATEX,	PRISM_GT_2),
193	UPGT_DEV(ZCOM,		XG703A),
194	UPGT_DEV(ZCOM,		XM142)
195};
196
197static usb_callback_t upgt_bulk_rx_callback;
198static usb_callback_t upgt_bulk_tx_callback;
199
200static const struct usb_config upgt_config[UPGT_N_XFERS] = {
201	[UPGT_BULK_TX] = {
202		.type = UE_BULK,
203		.endpoint = UE_ADDR_ANY,
204		.direction = UE_DIR_OUT,
205		.bufsize = MCLBYTES * UPGT_TX_MAXCOUNT,
206		.flags = {
207			.force_short_xfer = 1,
208			.pipe_bof = 1
209		},
210		.callback = upgt_bulk_tx_callback,
211		.timeout = UPGT_USB_TIMEOUT,	/* ms */
212	},
213	[UPGT_BULK_RX] = {
214		.type = UE_BULK,
215		.endpoint = UE_ADDR_ANY,
216		.direction = UE_DIR_IN,
217		.bufsize = MCLBYTES * UPGT_RX_MAXCOUNT,
218		.flags = {
219			.pipe_bof = 1,
220			.short_xfer_ok = 1
221		},
222		.callback = upgt_bulk_rx_callback,
223	},
224};
225
226static int
227upgt_match(device_t dev)
228{
229	struct usb_attach_arg *uaa = device_get_ivars(dev);
230
231	if (uaa->usb_mode != USB_MODE_HOST)
232		return (ENXIO);
233	if (uaa->info.bConfigIndex != UPGT_CONFIG_INDEX)
234		return (ENXIO);
235	if (uaa->info.bIfaceIndex != UPGT_IFACE_INDEX)
236		return (ENXIO);
237
238	return (usbd_lookup_id_by_uaa(upgt_devs, sizeof(upgt_devs), uaa));
239}
240
241static int
242upgt_attach(device_t dev)
243{
244	struct upgt_softc *sc = device_get_softc(dev);
245	struct ieee80211com *ic = &sc->sc_ic;
246	struct usb_attach_arg *uaa = device_get_ivars(dev);
247	uint8_t bands[IEEE80211_MODE_BYTES];
248	uint8_t iface_index = UPGT_IFACE_INDEX;
249	int error;
250
251	sc->sc_dev = dev;
252	sc->sc_udev = uaa->device;
253#ifdef UPGT_DEBUG
254	sc->sc_debug = upgt_debug;
255#endif
256	device_set_usb_desc(dev);
257
258	mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev), MTX_NETWORK_LOCK,
259	    MTX_DEF);
260	callout_init(&sc->sc_led_ch, 0);
261	callout_init(&sc->sc_watchdog_ch, 0);
262	mbufq_init(&sc->sc_snd, ifqmaxlen);
263
264	error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_xfer,
265	    upgt_config, UPGT_N_XFERS, sc, &sc->sc_mtx);
266	if (error) {
267		device_printf(dev, "could not allocate USB transfers, "
268		    "err=%s\n", usbd_errstr(error));
269		goto fail1;
270	}
271
272	sc->sc_rx_dma_buf = usbd_xfer_get_frame_buffer(
273	    sc->sc_xfer[UPGT_BULK_RX], 0);
274	sc->sc_tx_dma_buf = usbd_xfer_get_frame_buffer(
275	    sc->sc_xfer[UPGT_BULK_TX], 0);
276
277	/* Setup TX and RX buffers */
278	error = upgt_alloc_tx(sc);
279	if (error)
280		goto fail2;
281	error = upgt_alloc_rx(sc);
282	if (error)
283		goto fail3;
284
285	/* Initialize the device.  */
286	error = upgt_device_reset(sc);
287	if (error)
288		goto fail4;
289	/* Verify the firmware.  */
290	error = upgt_fw_verify(sc);
291	if (error)
292		goto fail4;
293	/* Calculate device memory space.  */
294	if (sc->sc_memaddr_frame_start == 0 || sc->sc_memaddr_frame_end == 0) {
295		device_printf(dev,
296		    "could not find memory space addresses on FW\n");
297		error = EIO;
298		goto fail4;
299	}
300	sc->sc_memaddr_frame_end -= UPGT_MEMSIZE_RX + 1;
301	sc->sc_memaddr_rx_start = sc->sc_memaddr_frame_end + 1;
302
303	DPRINTF(sc, UPGT_DEBUG_FW, "memory address frame start=0x%08x\n",
304	    sc->sc_memaddr_frame_start);
305	DPRINTF(sc, UPGT_DEBUG_FW, "memory address frame end=0x%08x\n",
306	    sc->sc_memaddr_frame_end);
307	DPRINTF(sc, UPGT_DEBUG_FW, "memory address rx start=0x%08x\n",
308	    sc->sc_memaddr_rx_start);
309
310	upgt_mem_init(sc);
311
312	/* Load the firmware.  */
313	error = upgt_fw_load(sc);
314	if (error)
315		goto fail4;
316
317	/* Read the whole EEPROM content and parse it.  */
318	error = upgt_eeprom_read(sc);
319	if (error)
320		goto fail4;
321	error = upgt_eeprom_parse(sc);
322	if (error)
323		goto fail4;
324
325	/* all works related with the device have done here. */
326	upgt_abort_xfers(sc);
327
328	ic->ic_softc = sc;
329	ic->ic_name = device_get_nameunit(dev);
330	ic->ic_phytype = IEEE80211_T_OFDM;	/* not only, but not used */
331	ic->ic_opmode = IEEE80211_M_STA;
332	/* set device capabilities */
333	ic->ic_caps =
334		  IEEE80211_C_STA		/* station mode */
335		| IEEE80211_C_MONITOR		/* monitor mode */
336		| IEEE80211_C_SHPREAMBLE	/* short preamble supported */
337	        | IEEE80211_C_SHSLOT		/* short slot time supported */
338		| IEEE80211_C_BGSCAN		/* capable of bg scanning */
339	        | IEEE80211_C_WPA		/* 802.11i */
340		;
341
342	memset(bands, 0, sizeof(bands));
343	setbit(bands, IEEE80211_MODE_11B);
344	setbit(bands, IEEE80211_MODE_11G);
345	ieee80211_init_channels(ic, NULL, bands);
346
347	ieee80211_ifattach(ic);
348	ic->ic_raw_xmit = upgt_raw_xmit;
349	ic->ic_scan_start = upgt_scan_start;
350	ic->ic_scan_end = upgt_scan_end;
351	ic->ic_set_channel = upgt_set_channel;
352	ic->ic_vap_create = upgt_vap_create;
353	ic->ic_vap_delete = upgt_vap_delete;
354	ic->ic_update_mcast = upgt_update_mcast;
355	ic->ic_transmit = upgt_transmit;
356	ic->ic_parent = upgt_parent;
357
358	ieee80211_radiotap_attach(ic,
359	    &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
360		UPGT_TX_RADIOTAP_PRESENT,
361	    &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
362		UPGT_RX_RADIOTAP_PRESENT);
363
364	upgt_sysctl_node(sc);
365
366	if (bootverbose)
367		ieee80211_announce(ic);
368
369	return (0);
370
371fail4:	upgt_free_rx(sc);
372fail3:	upgt_free_tx(sc);
373fail2:	usbd_transfer_unsetup(sc->sc_xfer, UPGT_N_XFERS);
374fail1:	mtx_destroy(&sc->sc_mtx);
375
376	return (error);
377}
378
379static void
380upgt_txeof(struct usb_xfer *xfer, struct upgt_data *data)
381{
382
383	if (data->m) {
384		/* XXX status? */
385		ieee80211_tx_complete(data->ni, data->m, 0);
386		data->m = NULL;
387		data->ni = NULL;
388	}
389}
390
391static void
392upgt_get_stats(struct upgt_softc *sc)
393{
394	struct upgt_data *data_cmd;
395	struct upgt_lmac_mem *mem;
396	struct upgt_lmac_stats *stats;
397
398	data_cmd = upgt_getbuf(sc);
399	if (data_cmd == NULL) {
400		device_printf(sc->sc_dev, "%s: out of buffers.\n", __func__);
401		return;
402	}
403
404	/*
405	 * Transmit the URB containing the CMD data.
406	 */
407	memset(data_cmd->buf, 0, MCLBYTES);
408
409	mem = (struct upgt_lmac_mem *)data_cmd->buf;
410	mem->addr = htole32(sc->sc_memaddr_frame_start +
411	    UPGT_MEMSIZE_FRAME_HEAD);
412
413	stats = (struct upgt_lmac_stats *)(mem + 1);
414
415	stats->header1.flags = 0;
416	stats->header1.type = UPGT_H1_TYPE_CTRL;
417	stats->header1.len = htole16(
418	    sizeof(struct upgt_lmac_stats) - sizeof(struct upgt_lmac_header));
419
420	stats->header2.reqid = htole32(sc->sc_memaddr_frame_start);
421	stats->header2.type = htole16(UPGT_H2_TYPE_STATS);
422	stats->header2.flags = 0;
423
424	data_cmd->buflen = sizeof(*mem) + sizeof(*stats);
425
426	mem->chksum = upgt_chksum_le((uint32_t *)stats,
427	    data_cmd->buflen - sizeof(*mem));
428
429	upgt_bulk_tx(sc, data_cmd);
430}
431
432static void
433upgt_parent(struct ieee80211com *ic)
434{
435	struct upgt_softc *sc = ic->ic_softc;
436	int startall = 0;
437
438	UPGT_LOCK(sc);
439	if (sc->sc_flags & UPGT_FLAG_DETACHED) {
440		UPGT_UNLOCK(sc);
441		return;
442	}
443	if (ic->ic_nrunning > 0) {
444		if (sc->sc_flags & UPGT_FLAG_INITDONE) {
445			if (ic->ic_allmulti > 0 || ic->ic_promisc > 0)
446				upgt_set_multi(sc);
447		} else {
448			upgt_init(sc);
449			startall = 1;
450		}
451	} else if (sc->sc_flags & UPGT_FLAG_INITDONE)
452		upgt_stop(sc);
453	UPGT_UNLOCK(sc);
454	if (startall)
455		ieee80211_start_all(ic);
456}
457
458static void
459upgt_stop(struct upgt_softc *sc)
460{
461
462	UPGT_ASSERT_LOCKED(sc);
463
464	if (sc->sc_flags & UPGT_FLAG_INITDONE)
465		upgt_set_macfilter(sc, IEEE80211_S_INIT);
466	upgt_abort_xfers_locked(sc);
467	/* device down */
468	sc->sc_tx_timer = 0;
469	sc->sc_flags &= ~UPGT_FLAG_INITDONE;
470}
471
472static void
473upgt_set_led(struct upgt_softc *sc, int action)
474{
475	struct upgt_data *data_cmd;
476	struct upgt_lmac_mem *mem;
477	struct upgt_lmac_led *led;
478
479	data_cmd = upgt_getbuf(sc);
480	if (data_cmd == NULL) {
481		device_printf(sc->sc_dev, "%s: out of buffers.\n", __func__);
482		return;
483	}
484
485	/*
486	 * Transmit the URB containing the CMD data.
487	 */
488	memset(data_cmd->buf, 0, MCLBYTES);
489
490	mem = (struct upgt_lmac_mem *)data_cmd->buf;
491	mem->addr = htole32(sc->sc_memaddr_frame_start +
492	    UPGT_MEMSIZE_FRAME_HEAD);
493
494	led = (struct upgt_lmac_led *)(mem + 1);
495
496	led->header1.flags = UPGT_H1_FLAGS_TX_NO_CALLBACK;
497	led->header1.type = UPGT_H1_TYPE_CTRL;
498	led->header1.len = htole16(
499	    sizeof(struct upgt_lmac_led) -
500	    sizeof(struct upgt_lmac_header));
501
502	led->header2.reqid = htole32(sc->sc_memaddr_frame_start);
503	led->header2.type = htole16(UPGT_H2_TYPE_LED);
504	led->header2.flags = 0;
505
506	switch (action) {
507	case UPGT_LED_OFF:
508		led->mode = htole16(UPGT_LED_MODE_SET);
509		led->action_fix = 0;
510		led->action_tmp = htole16(UPGT_LED_ACTION_OFF);
511		led->action_tmp_dur = 0;
512		break;
513	case UPGT_LED_ON:
514		led->mode = htole16(UPGT_LED_MODE_SET);
515		led->action_fix = 0;
516		led->action_tmp = htole16(UPGT_LED_ACTION_ON);
517		led->action_tmp_dur = 0;
518		break;
519	case UPGT_LED_BLINK:
520		if (sc->sc_state != IEEE80211_S_RUN) {
521			STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data_cmd, next);
522			return;
523		}
524		if (sc->sc_led_blink) {
525			/* previous blink was not finished */
526			STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data_cmd, next);
527			return;
528		}
529		led->mode = htole16(UPGT_LED_MODE_SET);
530		led->action_fix = htole16(UPGT_LED_ACTION_OFF);
531		led->action_tmp = htole16(UPGT_LED_ACTION_ON);
532		led->action_tmp_dur = htole16(UPGT_LED_ACTION_TMP_DUR);
533		/* lock blink */
534		sc->sc_led_blink = 1;
535		callout_reset(&sc->sc_led_ch, hz, upgt_set_led_blink, sc);
536		break;
537	default:
538		STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data_cmd, next);
539		return;
540	}
541
542	data_cmd->buflen = sizeof(*mem) + sizeof(*led);
543
544	mem->chksum = upgt_chksum_le((uint32_t *)led,
545	    data_cmd->buflen - sizeof(*mem));
546
547	upgt_bulk_tx(sc, data_cmd);
548}
549
550static void
551upgt_set_led_blink(void *arg)
552{
553	struct upgt_softc *sc = arg;
554
555	/* blink finished, we are ready for a next one */
556	sc->sc_led_blink = 0;
557}
558
559static void
560upgt_init(struct upgt_softc *sc)
561{
562
563	UPGT_ASSERT_LOCKED(sc);
564
565	if (sc->sc_flags & UPGT_FLAG_INITDONE)
566		upgt_stop(sc);
567
568	usbd_transfer_start(sc->sc_xfer[UPGT_BULK_RX]);
569
570	(void)upgt_set_macfilter(sc, IEEE80211_S_SCAN);
571
572	sc->sc_flags |= UPGT_FLAG_INITDONE;
573
574	callout_reset(&sc->sc_watchdog_ch, hz, upgt_watchdog, sc);
575}
576
577static int
578upgt_set_macfilter(struct upgt_softc *sc, uint8_t state)
579{
580	struct ieee80211com *ic = &sc->sc_ic;
581	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
582	struct ieee80211_node *ni;
583	struct upgt_data *data_cmd;
584	struct upgt_lmac_mem *mem;
585	struct upgt_lmac_filter *filter;
586
587	UPGT_ASSERT_LOCKED(sc);
588
589	data_cmd = upgt_getbuf(sc);
590	if (data_cmd == NULL) {
591		device_printf(sc->sc_dev, "out of TX buffers.\n");
592		return (ENOBUFS);
593	}
594
595	/*
596	 * Transmit the URB containing the CMD data.
597	 */
598	memset(data_cmd->buf, 0, MCLBYTES);
599
600	mem = (struct upgt_lmac_mem *)data_cmd->buf;
601	mem->addr = htole32(sc->sc_memaddr_frame_start +
602	    UPGT_MEMSIZE_FRAME_HEAD);
603
604	filter = (struct upgt_lmac_filter *)(mem + 1);
605
606	filter->header1.flags = UPGT_H1_FLAGS_TX_NO_CALLBACK;
607	filter->header1.type = UPGT_H1_TYPE_CTRL;
608	filter->header1.len = htole16(
609	    sizeof(struct upgt_lmac_filter) -
610	    sizeof(struct upgt_lmac_header));
611
612	filter->header2.reqid = htole32(sc->sc_memaddr_frame_start);
613	filter->header2.type = htole16(UPGT_H2_TYPE_MACFILTER);
614	filter->header2.flags = 0;
615
616	switch (state) {
617	case IEEE80211_S_INIT:
618		DPRINTF(sc, UPGT_DEBUG_STATE, "%s: set MAC filter to INIT\n",
619		    __func__);
620		filter->type = htole16(UPGT_FILTER_TYPE_RESET);
621		break;
622	case IEEE80211_S_SCAN:
623		DPRINTF(sc, UPGT_DEBUG_STATE,
624		    "set MAC filter to SCAN (bssid %s)\n",
625		    ether_sprintf(ieee80211broadcastaddr));
626		filter->type = htole16(UPGT_FILTER_TYPE_NONE);
627		IEEE80211_ADDR_COPY(filter->dst,
628		    vap ? vap->iv_myaddr : ic->ic_macaddr);
629		IEEE80211_ADDR_COPY(filter->src, ieee80211broadcastaddr);
630		filter->unknown1 = htole16(UPGT_FILTER_UNKNOWN1);
631		filter->rxaddr = htole32(sc->sc_memaddr_rx_start);
632		filter->unknown2 = htole16(UPGT_FILTER_UNKNOWN2);
633		filter->rxhw = htole32(sc->sc_eeprom_hwrx);
634		filter->unknown3 = htole16(UPGT_FILTER_UNKNOWN3);
635		break;
636	case IEEE80211_S_RUN:
637		ni = ieee80211_ref_node(vap->iv_bss);
638		/* XXX monitor mode isn't tested yet.  */
639		if (vap->iv_opmode == IEEE80211_M_MONITOR) {
640			filter->type = htole16(UPGT_FILTER_TYPE_MONITOR);
641			IEEE80211_ADDR_COPY(filter->dst,
642			    vap ? vap->iv_myaddr : ic->ic_macaddr);
643			IEEE80211_ADDR_COPY(filter->src, ni->ni_bssid);
644			filter->unknown1 = htole16(UPGT_FILTER_MONITOR_UNKNOWN1);
645			filter->rxaddr = htole32(sc->sc_memaddr_rx_start);
646			filter->unknown2 = htole16(UPGT_FILTER_MONITOR_UNKNOWN2);
647			filter->rxhw = htole32(sc->sc_eeprom_hwrx);
648			filter->unknown3 = htole16(UPGT_FILTER_MONITOR_UNKNOWN3);
649		} else {
650			DPRINTF(sc, UPGT_DEBUG_STATE,
651			    "set MAC filter to RUN (bssid %s)\n",
652			    ether_sprintf(ni->ni_bssid));
653			filter->type = htole16(UPGT_FILTER_TYPE_STA);
654			IEEE80211_ADDR_COPY(filter->dst,
655			    vap ? vap->iv_myaddr : ic->ic_macaddr);
656			IEEE80211_ADDR_COPY(filter->src, ni->ni_bssid);
657			filter->unknown1 = htole16(UPGT_FILTER_UNKNOWN1);
658			filter->rxaddr = htole32(sc->sc_memaddr_rx_start);
659			filter->unknown2 = htole16(UPGT_FILTER_UNKNOWN2);
660			filter->rxhw = htole32(sc->sc_eeprom_hwrx);
661			filter->unknown3 = htole16(UPGT_FILTER_UNKNOWN3);
662		}
663		ieee80211_free_node(ni);
664		break;
665	default:
666		device_printf(sc->sc_dev,
667		    "MAC filter does not know that state\n");
668		break;
669	}
670
671	data_cmd->buflen = sizeof(*mem) + sizeof(*filter);
672
673	mem->chksum = upgt_chksum_le((uint32_t *)filter,
674	    data_cmd->buflen - sizeof(*mem));
675
676	upgt_bulk_tx(sc, data_cmd);
677
678	return (0);
679}
680
681static void
682upgt_setup_rates(struct ieee80211vap *vap, struct ieee80211com *ic)
683{
684	struct upgt_softc *sc = ic->ic_softc;
685	const struct ieee80211_txparam *tp;
686
687	/*
688	 * 0x01 = OFMD6   0x10 = DS1
689	 * 0x04 = OFDM9   0x11 = DS2
690	 * 0x06 = OFDM12  0x12 = DS5
691	 * 0x07 = OFDM18  0x13 = DS11
692	 * 0x08 = OFDM24
693	 * 0x09 = OFDM36
694	 * 0x0a = OFDM48
695	 * 0x0b = OFDM54
696	 */
697	const uint8_t rateset_auto_11b[] =
698	    { 0x13, 0x13, 0x12, 0x11, 0x11, 0x10, 0x10, 0x10 };
699	const uint8_t rateset_auto_11g[] =
700	    { 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x04, 0x01 };
701	const uint8_t rateset_fix_11bg[] =
702	    { 0x10, 0x11, 0x12, 0x13, 0x01, 0x04, 0x06, 0x07,
703	      0x08, 0x09, 0x0a, 0x0b };
704
705	tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
706
707	/* XXX */
708	if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE) {
709		/*
710		 * Automatic rate control is done by the device.
711		 * We just pass the rateset from which the device
712		 * will pickup a rate.
713		 */
714		if (ic->ic_curmode == IEEE80211_MODE_11B)
715			memcpy(sc->sc_cur_rateset, rateset_auto_11b,
716			    sizeof(sc->sc_cur_rateset));
717		if (ic->ic_curmode == IEEE80211_MODE_11G ||
718		    ic->ic_curmode == IEEE80211_MODE_AUTO)
719			memcpy(sc->sc_cur_rateset, rateset_auto_11g,
720			    sizeof(sc->sc_cur_rateset));
721	} else {
722		/* set a fixed rate */
723		memset(sc->sc_cur_rateset, rateset_fix_11bg[tp->ucastrate],
724		    sizeof(sc->sc_cur_rateset));
725	}
726}
727
728static void
729upgt_set_multi(void *arg)
730{
731
732	/* XXX don't know how to set a device.  Lack of docs. */
733}
734
735static int
736upgt_transmit(struct ieee80211com *ic, struct mbuf *m)
737{
738	struct upgt_softc *sc = ic->ic_softc;
739	int error;
740
741	UPGT_LOCK(sc);
742	if ((sc->sc_flags & UPGT_FLAG_INITDONE) == 0) {
743		UPGT_UNLOCK(sc);
744		return (ENXIO);
745	}
746	error = mbufq_enqueue(&sc->sc_snd, m);
747	if (error) {
748		UPGT_UNLOCK(sc);
749		return (error);
750	}
751	upgt_start(sc);
752	UPGT_UNLOCK(sc);
753
754	return (0);
755}
756
757static void
758upgt_start(struct upgt_softc *sc)
759{
760	struct upgt_data *data_tx;
761	struct ieee80211_node *ni;
762	struct mbuf *m;
763
764	UPGT_ASSERT_LOCKED(sc);
765
766	if ((sc->sc_flags & UPGT_FLAG_INITDONE) == 0)
767		return;
768
769	while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
770		data_tx = upgt_gettxbuf(sc);
771		if (data_tx == NULL) {
772			mbufq_prepend(&sc->sc_snd, m);
773			break;
774		}
775
776		ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
777		m->m_pkthdr.rcvif = NULL;
778
779		if (upgt_tx_start(sc, m, ni, data_tx) != 0) {
780			if_inc_counter(ni->ni_vap->iv_ifp,
781			    IFCOUNTER_OERRORS, 1);
782			STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, data_tx, next);
783			UPGT_STAT_INC(sc, st_tx_inactive);
784			ieee80211_free_node(ni);
785			continue;
786		}
787		sc->sc_tx_timer = 5;
788	}
789}
790
791static int
792upgt_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
793	const struct ieee80211_bpf_params *params)
794{
795	struct ieee80211com *ic = ni->ni_ic;
796	struct upgt_softc *sc = ic->ic_softc;
797	struct upgt_data *data_tx = NULL;
798
799	UPGT_LOCK(sc);
800	/* prevent management frames from being sent if we're not ready */
801	if (!(sc->sc_flags & UPGT_FLAG_INITDONE)) {
802		m_freem(m);
803		UPGT_UNLOCK(sc);
804		return ENETDOWN;
805	}
806
807	data_tx = upgt_gettxbuf(sc);
808	if (data_tx == NULL) {
809		m_freem(m);
810		UPGT_UNLOCK(sc);
811		return (ENOBUFS);
812	}
813
814	if (upgt_tx_start(sc, m, ni, data_tx) != 0) {
815		STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, data_tx, next);
816		UPGT_STAT_INC(sc, st_tx_inactive);
817		UPGT_UNLOCK(sc);
818		return (EIO);
819	}
820	UPGT_UNLOCK(sc);
821
822	sc->sc_tx_timer = 5;
823	return (0);
824}
825
826static void
827upgt_watchdog(void *arg)
828{
829	struct upgt_softc *sc = arg;
830	struct ieee80211com *ic = &sc->sc_ic;
831
832	if (sc->sc_tx_timer > 0) {
833		if (--sc->sc_tx_timer == 0) {
834			device_printf(sc->sc_dev, "watchdog timeout\n");
835			/* upgt_init(sc); XXX needs a process context ? */
836			counter_u64_add(ic->ic_oerrors, 1);
837			return;
838		}
839		callout_reset(&sc->sc_watchdog_ch, hz, upgt_watchdog, sc);
840	}
841}
842
843static uint32_t
844upgt_mem_alloc(struct upgt_softc *sc)
845{
846	int i;
847
848	for (i = 0; i < sc->sc_memory.pages; i++) {
849		if (sc->sc_memory.page[i].used == 0) {
850			sc->sc_memory.page[i].used = 1;
851			return (sc->sc_memory.page[i].addr);
852		}
853	}
854
855	return (0);
856}
857
858static void
859upgt_scan_start(struct ieee80211com *ic)
860{
861	/* do nothing.  */
862}
863
864static void
865upgt_scan_end(struct ieee80211com *ic)
866{
867	/* do nothing.  */
868}
869
870static void
871upgt_set_channel(struct ieee80211com *ic)
872{
873	struct upgt_softc *sc = ic->ic_softc;
874
875	UPGT_LOCK(sc);
876	upgt_set_chan(sc, ic->ic_curchan);
877	UPGT_UNLOCK(sc);
878}
879
880static void
881upgt_set_chan(struct upgt_softc *sc, struct ieee80211_channel *c)
882{
883	struct ieee80211com *ic = &sc->sc_ic;
884	struct upgt_data *data_cmd;
885	struct upgt_lmac_mem *mem;
886	struct upgt_lmac_channel *chan;
887	int channel;
888
889	UPGT_ASSERT_LOCKED(sc);
890
891	channel = ieee80211_chan2ieee(ic, c);
892	if (channel == 0 || channel == IEEE80211_CHAN_ANY) {
893		/* XXX should NEVER happen */
894		device_printf(sc->sc_dev,
895		    "%s: invalid channel %x\n", __func__, channel);
896		return;
897	}
898
899	DPRINTF(sc, UPGT_DEBUG_STATE, "%s: channel %d\n", __func__, channel);
900
901	data_cmd = upgt_getbuf(sc);
902	if (data_cmd == NULL) {
903		device_printf(sc->sc_dev, "%s: out of buffers.\n", __func__);
904		return;
905	}
906	/*
907	 * Transmit the URB containing the CMD data.
908	 */
909	memset(data_cmd->buf, 0, MCLBYTES);
910
911	mem = (struct upgt_lmac_mem *)data_cmd->buf;
912	mem->addr = htole32(sc->sc_memaddr_frame_start +
913	    UPGT_MEMSIZE_FRAME_HEAD);
914
915	chan = (struct upgt_lmac_channel *)(mem + 1);
916
917	chan->header1.flags = UPGT_H1_FLAGS_TX_NO_CALLBACK;
918	chan->header1.type = UPGT_H1_TYPE_CTRL;
919	chan->header1.len = htole16(
920	    sizeof(struct upgt_lmac_channel) - sizeof(struct upgt_lmac_header));
921
922	chan->header2.reqid = htole32(sc->sc_memaddr_frame_start);
923	chan->header2.type = htole16(UPGT_H2_TYPE_CHANNEL);
924	chan->header2.flags = 0;
925
926	chan->unknown1 = htole16(UPGT_CHANNEL_UNKNOWN1);
927	chan->unknown2 = htole16(UPGT_CHANNEL_UNKNOWN2);
928	chan->freq6 = sc->sc_eeprom_freq6[channel];
929	chan->settings = sc->sc_eeprom_freq6_settings;
930	chan->unknown3 = UPGT_CHANNEL_UNKNOWN3;
931
932	memcpy(chan->freq3_1, &sc->sc_eeprom_freq3[channel].data,
933	    sizeof(chan->freq3_1));
934	memcpy(chan->freq4, &sc->sc_eeprom_freq4[channel],
935	    sizeof(sc->sc_eeprom_freq4[channel]));
936	memcpy(chan->freq3_2, &sc->sc_eeprom_freq3[channel].data,
937	    sizeof(chan->freq3_2));
938
939	data_cmd->buflen = sizeof(*mem) + sizeof(*chan);
940
941	mem->chksum = upgt_chksum_le((uint32_t *)chan,
942	    data_cmd->buflen - sizeof(*mem));
943
944	upgt_bulk_tx(sc, data_cmd);
945}
946
947static struct ieee80211vap *
948upgt_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
949    enum ieee80211_opmode opmode, int flags,
950    const uint8_t bssid[IEEE80211_ADDR_LEN],
951    const uint8_t mac[IEEE80211_ADDR_LEN])
952{
953	struct upgt_vap *uvp;
954	struct ieee80211vap *vap;
955
956	if (!TAILQ_EMPTY(&ic->ic_vaps))		/* only one at a time */
957		return NULL;
958	uvp = malloc(sizeof(struct upgt_vap), M_80211_VAP, M_WAITOK | M_ZERO);
959	vap = &uvp->vap;
960	/* enable s/w bmiss handling for sta mode */
961
962	if (ieee80211_vap_setup(ic, vap, name, unit, opmode,
963	    flags | IEEE80211_CLONE_NOBEACONS, bssid) != 0) {
964		/* out of memory */
965		free(uvp, M_80211_VAP);
966		return (NULL);
967	}
968
969	/* override state transition machine */
970	uvp->newstate = vap->iv_newstate;
971	vap->iv_newstate = upgt_newstate;
972
973	/* setup device rates */
974	upgt_setup_rates(vap, ic);
975
976	/* complete setup */
977	ieee80211_vap_attach(vap, ieee80211_media_change,
978	    ieee80211_media_status, mac);
979	ic->ic_opmode = opmode;
980	return vap;
981}
982
983static int
984upgt_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
985{
986	struct upgt_vap *uvp = UPGT_VAP(vap);
987	struct ieee80211com *ic = vap->iv_ic;
988	struct upgt_softc *sc = ic->ic_softc;
989
990	/* do it in a process context */
991	sc->sc_state = nstate;
992
993	IEEE80211_UNLOCK(ic);
994	UPGT_LOCK(sc);
995	callout_stop(&sc->sc_led_ch);
996	callout_stop(&sc->sc_watchdog_ch);
997
998	switch (nstate) {
999	case IEEE80211_S_INIT:
1000		/* do not accept any frames if the device is down */
1001		(void)upgt_set_macfilter(sc, sc->sc_state);
1002		upgt_set_led(sc, UPGT_LED_OFF);
1003		break;
1004	case IEEE80211_S_SCAN:
1005		upgt_set_chan(sc, ic->ic_curchan);
1006		break;
1007	case IEEE80211_S_AUTH:
1008		upgt_set_chan(sc, ic->ic_curchan);
1009		break;
1010	case IEEE80211_S_ASSOC:
1011		break;
1012	case IEEE80211_S_RUN:
1013		upgt_set_macfilter(sc, sc->sc_state);
1014		upgt_set_led(sc, UPGT_LED_ON);
1015		break;
1016	default:
1017		break;
1018	}
1019	UPGT_UNLOCK(sc);
1020	IEEE80211_LOCK(ic);
1021	return (uvp->newstate(vap, nstate, arg));
1022}
1023
1024static void
1025upgt_vap_delete(struct ieee80211vap *vap)
1026{
1027	struct upgt_vap *uvp = UPGT_VAP(vap);
1028
1029	ieee80211_vap_detach(vap);
1030	free(uvp, M_80211_VAP);
1031}
1032
1033static void
1034upgt_update_mcast(struct ieee80211com *ic)
1035{
1036	struct upgt_softc *sc = ic->ic_softc;
1037
1038	upgt_set_multi(sc);
1039}
1040
1041static int
1042upgt_eeprom_parse(struct upgt_softc *sc)
1043{
1044	struct ieee80211com *ic = &sc->sc_ic;
1045	struct upgt_eeprom_header *eeprom_header;
1046	struct upgt_eeprom_option *eeprom_option;
1047	uint16_t option_len;
1048	uint16_t option_type;
1049	uint16_t preamble_len;
1050	int option_end = 0;
1051
1052	/* calculate eeprom options start offset */
1053	eeprom_header = (struct upgt_eeprom_header *)sc->sc_eeprom;
1054	preamble_len = le16toh(eeprom_header->preamble_len);
1055	eeprom_option = (struct upgt_eeprom_option *)(sc->sc_eeprom +
1056	    (sizeof(struct upgt_eeprom_header) + preamble_len));
1057
1058	while (!option_end) {
1059		/* sanity check */
1060		if (eeprom_option >= (struct upgt_eeprom_option *)
1061		    (sc->sc_eeprom + UPGT_EEPROM_SIZE)) {
1062			return (EINVAL);
1063		}
1064
1065		/* the eeprom option length is stored in words */
1066		option_len =
1067		    (le16toh(eeprom_option->len) - 1) * sizeof(uint16_t);
1068		option_type =
1069		    le16toh(eeprom_option->type);
1070
1071		/* sanity check */
1072		if (option_len == 0 || option_len >= UPGT_EEPROM_SIZE)
1073			return (EINVAL);
1074
1075		switch (option_type) {
1076		case UPGT_EEPROM_TYPE_NAME:
1077			DPRINTF(sc, UPGT_DEBUG_FW,
1078			    "EEPROM name len=%d\n", option_len);
1079			break;
1080		case UPGT_EEPROM_TYPE_SERIAL:
1081			DPRINTF(sc, UPGT_DEBUG_FW,
1082			    "EEPROM serial len=%d\n", option_len);
1083			break;
1084		case UPGT_EEPROM_TYPE_MAC:
1085			DPRINTF(sc, UPGT_DEBUG_FW,
1086			    "EEPROM mac len=%d\n", option_len);
1087
1088			IEEE80211_ADDR_COPY(ic->ic_macaddr,
1089			    eeprom_option->data);
1090			break;
1091		case UPGT_EEPROM_TYPE_HWRX:
1092			DPRINTF(sc, UPGT_DEBUG_FW,
1093			    "EEPROM hwrx len=%d\n", option_len);
1094
1095			upgt_eeprom_parse_hwrx(sc, eeprom_option->data);
1096			break;
1097		case UPGT_EEPROM_TYPE_CHIP:
1098			DPRINTF(sc, UPGT_DEBUG_FW,
1099			    "EEPROM chip len=%d\n", option_len);
1100			break;
1101		case UPGT_EEPROM_TYPE_FREQ3:
1102			DPRINTF(sc, UPGT_DEBUG_FW,
1103			    "EEPROM freq3 len=%d\n", option_len);
1104
1105			upgt_eeprom_parse_freq3(sc, eeprom_option->data,
1106			    option_len);
1107			break;
1108		case UPGT_EEPROM_TYPE_FREQ4:
1109			DPRINTF(sc, UPGT_DEBUG_FW,
1110			    "EEPROM freq4 len=%d\n", option_len);
1111
1112			upgt_eeprom_parse_freq4(sc, eeprom_option->data,
1113			    option_len);
1114			break;
1115		case UPGT_EEPROM_TYPE_FREQ5:
1116			DPRINTF(sc, UPGT_DEBUG_FW,
1117			    "EEPROM freq5 len=%d\n", option_len);
1118			break;
1119		case UPGT_EEPROM_TYPE_FREQ6:
1120			DPRINTF(sc, UPGT_DEBUG_FW,
1121			    "EEPROM freq6 len=%d\n", option_len);
1122
1123			upgt_eeprom_parse_freq6(sc, eeprom_option->data,
1124			    option_len);
1125			break;
1126		case UPGT_EEPROM_TYPE_END:
1127			DPRINTF(sc, UPGT_DEBUG_FW,
1128			    "EEPROM end len=%d\n", option_len);
1129			option_end = 1;
1130			break;
1131		case UPGT_EEPROM_TYPE_OFF:
1132			DPRINTF(sc, UPGT_DEBUG_FW,
1133			    "%s: EEPROM off without end option\n", __func__);
1134			return (EIO);
1135		default:
1136			DPRINTF(sc, UPGT_DEBUG_FW,
1137			    "EEPROM unknown type 0x%04x len=%d\n",
1138			    option_type, option_len);
1139			break;
1140		}
1141
1142		/* jump to next EEPROM option */
1143		eeprom_option = (struct upgt_eeprom_option *)
1144		    (eeprom_option->data + option_len);
1145	}
1146	return (0);
1147}
1148
1149static void
1150upgt_eeprom_parse_freq3(struct upgt_softc *sc, uint8_t *data, int len)
1151{
1152	struct upgt_eeprom_freq3_header *freq3_header;
1153	struct upgt_lmac_freq3 *freq3;
1154	int i;
1155	int elements;
1156	int flags;
1157	unsigned channel;
1158
1159	freq3_header = (struct upgt_eeprom_freq3_header *)data;
1160	freq3 = (struct upgt_lmac_freq3 *)(freq3_header + 1);
1161
1162	flags = freq3_header->flags;
1163	elements = freq3_header->elements;
1164
1165	DPRINTF(sc, UPGT_DEBUG_FW, "flags=0x%02x elements=%d\n",
1166	    flags, elements);
1167
1168	if (elements >= (int)(UPGT_EEPROM_SIZE / sizeof(freq3[0])))
1169		return;
1170
1171	for (i = 0; i < elements; i++) {
1172		channel = ieee80211_mhz2ieee(le16toh(freq3[i].freq), 0);
1173		if (channel >= IEEE80211_CHAN_MAX)
1174			continue;
1175
1176		sc->sc_eeprom_freq3[channel] = freq3[i];
1177
1178		DPRINTF(sc, UPGT_DEBUG_FW, "frequence=%d, channel=%d\n",
1179		    le16toh(sc->sc_eeprom_freq3[channel].freq), channel);
1180	}
1181}
1182
1183void
1184upgt_eeprom_parse_freq4(struct upgt_softc *sc, uint8_t *data, int len)
1185{
1186	struct upgt_eeprom_freq4_header *freq4_header;
1187	struct upgt_eeprom_freq4_1 *freq4_1;
1188	struct upgt_eeprom_freq4_2 *freq4_2;
1189	int i;
1190	int j;
1191	int elements;
1192	int settings;
1193	int flags;
1194	unsigned channel;
1195
1196	freq4_header = (struct upgt_eeprom_freq4_header *)data;
1197	freq4_1 = (struct upgt_eeprom_freq4_1 *)(freq4_header + 1);
1198	flags = freq4_header->flags;
1199	elements = freq4_header->elements;
1200	settings = freq4_header->settings;
1201
1202	/* we need this value later */
1203	sc->sc_eeprom_freq6_settings = freq4_header->settings;
1204
1205	DPRINTF(sc, UPGT_DEBUG_FW, "flags=0x%02x elements=%d settings=%d\n",
1206	    flags, elements, settings);
1207
1208	if (elements >= (int)(UPGT_EEPROM_SIZE / sizeof(freq4_1[0])))
1209		return;
1210
1211	for (i = 0; i < elements; i++) {
1212		channel = ieee80211_mhz2ieee(le16toh(freq4_1[i].freq), 0);
1213		if (channel >= IEEE80211_CHAN_MAX)
1214			continue;
1215
1216		freq4_2 = (struct upgt_eeprom_freq4_2 *)freq4_1[i].data;
1217		for (j = 0; j < settings; j++) {
1218			sc->sc_eeprom_freq4[channel][j].cmd = freq4_2[j];
1219			sc->sc_eeprom_freq4[channel][j].pad = 0;
1220		}
1221
1222		DPRINTF(sc, UPGT_DEBUG_FW, "frequence=%d, channel=%d\n",
1223		    le16toh(freq4_1[i].freq), channel);
1224	}
1225}
1226
1227void
1228upgt_eeprom_parse_freq6(struct upgt_softc *sc, uint8_t *data, int len)
1229{
1230	struct upgt_lmac_freq6 *freq6;
1231	int i;
1232	int elements;
1233	unsigned channel;
1234
1235	freq6 = (struct upgt_lmac_freq6 *)data;
1236	elements = len / sizeof(struct upgt_lmac_freq6);
1237
1238	DPRINTF(sc, UPGT_DEBUG_FW, "elements=%d\n", elements);
1239
1240	if (elements >= (int)(UPGT_EEPROM_SIZE / sizeof(freq6[0])))
1241		return;
1242
1243	for (i = 0; i < elements; i++) {
1244		channel = ieee80211_mhz2ieee(le16toh(freq6[i].freq), 0);
1245		if (channel >= IEEE80211_CHAN_MAX)
1246			continue;
1247
1248		sc->sc_eeprom_freq6[channel] = freq6[i];
1249
1250		DPRINTF(sc, UPGT_DEBUG_FW, "frequence=%d, channel=%d\n",
1251		    le16toh(sc->sc_eeprom_freq6[channel].freq), channel);
1252	}
1253}
1254
1255static void
1256upgt_eeprom_parse_hwrx(struct upgt_softc *sc, uint8_t *data)
1257{
1258	struct upgt_eeprom_option_hwrx *option_hwrx;
1259
1260	option_hwrx = (struct upgt_eeprom_option_hwrx *)data;
1261
1262	sc->sc_eeprom_hwrx = option_hwrx->rxfilter - UPGT_EEPROM_RX_CONST;
1263
1264	DPRINTF(sc, UPGT_DEBUG_FW, "hwrx option value=0x%04x\n",
1265	    sc->sc_eeprom_hwrx);
1266}
1267
1268static int
1269upgt_eeprom_read(struct upgt_softc *sc)
1270{
1271	struct upgt_data *data_cmd;
1272	struct upgt_lmac_mem *mem;
1273	struct upgt_lmac_eeprom	*eeprom;
1274	int block, error, offset;
1275
1276	UPGT_LOCK(sc);
1277	usb_pause_mtx(&sc->sc_mtx, 100);
1278
1279	offset = 0;
1280	block = UPGT_EEPROM_BLOCK_SIZE;
1281	while (offset < UPGT_EEPROM_SIZE) {
1282		DPRINTF(sc, UPGT_DEBUG_FW,
1283		    "request EEPROM block (offset=%d, len=%d)\n", offset, block);
1284
1285		data_cmd = upgt_getbuf(sc);
1286		if (data_cmd == NULL) {
1287			UPGT_UNLOCK(sc);
1288			return (ENOBUFS);
1289		}
1290
1291		/*
1292		 * Transmit the URB containing the CMD data.
1293		 */
1294		memset(data_cmd->buf, 0, MCLBYTES);
1295
1296		mem = (struct upgt_lmac_mem *)data_cmd->buf;
1297		mem->addr = htole32(sc->sc_memaddr_frame_start +
1298		    UPGT_MEMSIZE_FRAME_HEAD);
1299
1300		eeprom = (struct upgt_lmac_eeprom *)(mem + 1);
1301		eeprom->header1.flags = 0;
1302		eeprom->header1.type = UPGT_H1_TYPE_CTRL;
1303		eeprom->header1.len = htole16((
1304		    sizeof(struct upgt_lmac_eeprom) -
1305		    sizeof(struct upgt_lmac_header)) + block);
1306
1307		eeprom->header2.reqid = htole32(sc->sc_memaddr_frame_start);
1308		eeprom->header2.type = htole16(UPGT_H2_TYPE_EEPROM);
1309		eeprom->header2.flags = 0;
1310
1311		eeprom->offset = htole16(offset);
1312		eeprom->len = htole16(block);
1313
1314		data_cmd->buflen = sizeof(*mem) + sizeof(*eeprom) + block;
1315
1316		mem->chksum = upgt_chksum_le((uint32_t *)eeprom,
1317		    data_cmd->buflen - sizeof(*mem));
1318		upgt_bulk_tx(sc, data_cmd);
1319
1320		error = mtx_sleep(sc, &sc->sc_mtx, 0, "eeprom_request", hz);
1321		if (error != 0) {
1322			device_printf(sc->sc_dev,
1323			    "timeout while waiting for EEPROM data\n");
1324			UPGT_UNLOCK(sc);
1325			return (EIO);
1326		}
1327
1328		offset += block;
1329		if (UPGT_EEPROM_SIZE - offset < block)
1330			block = UPGT_EEPROM_SIZE - offset;
1331	}
1332
1333	UPGT_UNLOCK(sc);
1334	return (0);
1335}
1336
1337/*
1338 * When a rx data came in the function returns a mbuf and a rssi values.
1339 */
1340static struct mbuf *
1341upgt_rxeof(struct usb_xfer *xfer, struct upgt_data *data, int *rssi)
1342{
1343	struct mbuf *m = NULL;
1344	struct upgt_softc *sc = usbd_xfer_softc(xfer);
1345	struct upgt_lmac_header *header;
1346	struct upgt_lmac_eeprom *eeprom;
1347	uint8_t h1_type;
1348	uint16_t h2_type;
1349	int actlen, sumlen;
1350
1351	usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL);
1352
1353	UPGT_ASSERT_LOCKED(sc);
1354
1355	if (actlen < 1)
1356		return (NULL);
1357
1358	/* Check only at the very beginning.  */
1359	if (!(sc->sc_flags & UPGT_FLAG_FWLOADED) &&
1360	    (memcmp(data->buf, "OK", 2) == 0)) {
1361		sc->sc_flags |= UPGT_FLAG_FWLOADED;
1362		wakeup_one(sc);
1363		return (NULL);
1364	}
1365
1366	if (actlen < (int)UPGT_RX_MINSZ)
1367		return (NULL);
1368
1369	/*
1370	 * Check what type of frame came in.
1371	 */
1372	header = (struct upgt_lmac_header *)(data->buf + 4);
1373
1374	h1_type = header->header1.type;
1375	h2_type = le16toh(header->header2.type);
1376
1377	if (h1_type == UPGT_H1_TYPE_CTRL && h2_type == UPGT_H2_TYPE_EEPROM) {
1378		eeprom = (struct upgt_lmac_eeprom *)(data->buf + 4);
1379		uint16_t eeprom_offset = le16toh(eeprom->offset);
1380		uint16_t eeprom_len = le16toh(eeprom->len);
1381
1382		DPRINTF(sc, UPGT_DEBUG_FW,
1383		    "received EEPROM block (offset=%d, len=%d)\n",
1384		    eeprom_offset, eeprom_len);
1385
1386		memcpy(sc->sc_eeprom + eeprom_offset,
1387		    data->buf + sizeof(struct upgt_lmac_eeprom) + 4,
1388		    eeprom_len);
1389
1390		/* EEPROM data has arrived in time, wakeup.  */
1391		wakeup(sc);
1392	} else if (h1_type == UPGT_H1_TYPE_CTRL &&
1393	    h2_type == UPGT_H2_TYPE_TX_DONE) {
1394		DPRINTF(sc, UPGT_DEBUG_XMIT, "%s: received 802.11 TX done\n",
1395		    __func__);
1396		upgt_tx_done(sc, data->buf + 4);
1397	} else if (h1_type == UPGT_H1_TYPE_RX_DATA ||
1398	    h1_type == UPGT_H1_TYPE_RX_DATA_MGMT) {
1399		DPRINTF(sc, UPGT_DEBUG_RECV, "%s: received 802.11 RX data\n",
1400		    __func__);
1401		m = upgt_rx(sc, data->buf + 4, le16toh(header->header1.len),
1402		    rssi);
1403	} else if (h1_type == UPGT_H1_TYPE_CTRL &&
1404	    h2_type == UPGT_H2_TYPE_STATS) {
1405		DPRINTF(sc, UPGT_DEBUG_STAT, "%s: received statistic data\n",
1406		    __func__);
1407		/* TODO: what could we do with the statistic data? */
1408	} else {
1409		/* ignore unknown frame types */
1410		DPRINTF(sc, UPGT_DEBUG_INTR,
1411		    "received unknown frame type 0x%02x\n",
1412		    header->header1.type);
1413	}
1414	return (m);
1415}
1416
1417/*
1418 * The firmware awaits a checksum for each frame we send to it.
1419 * The algorithm used therefor is uncommon but somehow similar to CRC32.
1420 */
1421static uint32_t
1422upgt_chksum_le(const uint32_t *buf, size_t size)
1423{
1424	size_t i;
1425	uint32_t crc = 0;
1426
1427	for (i = 0; i < size; i += sizeof(uint32_t)) {
1428		crc = htole32(crc ^ *buf++);
1429		crc = htole32((crc >> 5) ^ (crc << 3));
1430	}
1431
1432	return (crc);
1433}
1434
1435static struct mbuf *
1436upgt_rx(struct upgt_softc *sc, uint8_t *data, int pkglen, int *rssi)
1437{
1438	struct ieee80211com *ic = &sc->sc_ic;
1439	struct upgt_lmac_rx_desc *rxdesc;
1440	struct mbuf *m;
1441
1442	/*
1443	 * don't pass packets to the ieee80211 framework if the driver isn't
1444	 * RUNNING.
1445	 */
1446	if (!(sc->sc_flags & UPGT_FLAG_INITDONE))
1447		return (NULL);
1448
1449	/* access RX packet descriptor */
1450	rxdesc = (struct upgt_lmac_rx_desc *)data;
1451
1452	/* create mbuf which is suitable for strict alignment archs */
1453	KASSERT((pkglen + ETHER_ALIGN) < MCLBYTES,
1454	    ("A current mbuf storage is small (%d)", pkglen + ETHER_ALIGN));
1455	m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
1456	if (m == NULL) {
1457		device_printf(sc->sc_dev, "could not create RX mbuf\n");
1458		return (NULL);
1459	}
1460	m_adj(m, ETHER_ALIGN);
1461	memcpy(mtod(m, char *), rxdesc->data, pkglen);
1462	/* trim FCS */
1463	m->m_len = m->m_pkthdr.len = pkglen - IEEE80211_CRC_LEN;
1464
1465	if (ieee80211_radiotap_active(ic)) {
1466		struct upgt_rx_radiotap_header *tap = &sc->sc_rxtap;
1467
1468		tap->wr_flags = 0;
1469		tap->wr_rate = upgt_rx_rate(sc, rxdesc->rate);
1470		tap->wr_antsignal = rxdesc->rssi;
1471	}
1472
1473	DPRINTF(sc, UPGT_DEBUG_RX_PROC, "%s: RX done\n", __func__);
1474	*rssi = rxdesc->rssi;
1475	return (m);
1476}
1477
1478static uint8_t
1479upgt_rx_rate(struct upgt_softc *sc, const int rate)
1480{
1481	struct ieee80211com *ic = &sc->sc_ic;
1482	static const uint8_t cck_upgt2rate[4] = { 2, 4, 11, 22 };
1483	static const uint8_t ofdm_upgt2rate[12] =
1484	    { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 };
1485
1486	if (ic->ic_curmode == IEEE80211_MODE_11B &&
1487	    !(rate < 0 || rate > 3))
1488		return cck_upgt2rate[rate & 0xf];
1489
1490	if (ic->ic_curmode == IEEE80211_MODE_11G &&
1491	    !(rate < 0 || rate > 11))
1492		return ofdm_upgt2rate[rate & 0xf];
1493
1494	return (0);
1495}
1496
1497static void
1498upgt_tx_done(struct upgt_softc *sc, uint8_t *data)
1499{
1500	struct upgt_lmac_tx_done_desc *desc;
1501	int i, freed = 0;
1502
1503	UPGT_ASSERT_LOCKED(sc);
1504
1505	desc = (struct upgt_lmac_tx_done_desc *)data;
1506
1507	for (i = 0; i < UPGT_TX_MAXCOUNT; i++) {
1508		struct upgt_data *data_tx = &sc->sc_tx_data[i];
1509
1510		if (data_tx->addr == le32toh(desc->header2.reqid)) {
1511			upgt_mem_free(sc, data_tx->addr);
1512			data_tx->ni = NULL;
1513			data_tx->addr = 0;
1514			data_tx->m = NULL;
1515
1516			DPRINTF(sc, UPGT_DEBUG_TX_PROC,
1517			    "TX done: memaddr=0x%08x, status=0x%04x, rssi=%d, ",
1518			    le32toh(desc->header2.reqid),
1519			    le16toh(desc->status), le16toh(desc->rssi));
1520			DPRINTF(sc, UPGT_DEBUG_TX_PROC, "seq=%d\n",
1521			    le16toh(desc->seq));
1522
1523			freed++;
1524		}
1525	}
1526
1527	if (freed != 0) {
1528		UPGT_UNLOCK(sc);
1529		sc->sc_tx_timer = 0;
1530		upgt_start(sc);
1531		UPGT_LOCK(sc);
1532	}
1533}
1534
1535static void
1536upgt_mem_free(struct upgt_softc *sc, uint32_t addr)
1537{
1538	int i;
1539
1540	for (i = 0; i < sc->sc_memory.pages; i++) {
1541		if (sc->sc_memory.page[i].addr == addr) {
1542			sc->sc_memory.page[i].used = 0;
1543			return;
1544		}
1545	}
1546
1547	device_printf(sc->sc_dev,
1548	    "could not free memory address 0x%08x\n", addr);
1549}
1550
1551static int
1552upgt_fw_load(struct upgt_softc *sc)
1553{
1554	const struct firmware *fw;
1555	struct upgt_data *data_cmd;
1556	struct upgt_fw_x2_header *x2;
1557	char start_fwload_cmd[] = { 0x3c, 0x0d };
1558	int error = 0;
1559	size_t offset;
1560	int bsize;
1561	int n;
1562	uint32_t crc32;
1563
1564	fw = firmware_get(upgt_fwname);
1565	if (fw == NULL) {
1566		device_printf(sc->sc_dev, "could not read microcode %s\n",
1567		    upgt_fwname);
1568		return (EIO);
1569	}
1570
1571	UPGT_LOCK(sc);
1572
1573	/* send firmware start load command */
1574	data_cmd = upgt_getbuf(sc);
1575	if (data_cmd == NULL) {
1576		error = ENOBUFS;
1577		goto fail;
1578	}
1579	data_cmd->buflen = sizeof(start_fwload_cmd);
1580	memcpy(data_cmd->buf, start_fwload_cmd, data_cmd->buflen);
1581	upgt_bulk_tx(sc, data_cmd);
1582
1583	/* send X2 header */
1584	data_cmd = upgt_getbuf(sc);
1585	if (data_cmd == NULL) {
1586		error = ENOBUFS;
1587		goto fail;
1588	}
1589	data_cmd->buflen = sizeof(struct upgt_fw_x2_header);
1590	x2 = (struct upgt_fw_x2_header *)data_cmd->buf;
1591	memcpy(x2->signature, UPGT_X2_SIGNATURE, UPGT_X2_SIGNATURE_SIZE);
1592	x2->startaddr = htole32(UPGT_MEMADDR_FIRMWARE_START);
1593	x2->len = htole32(fw->datasize);
1594	x2->crc = upgt_crc32_le((uint8_t *)data_cmd->buf +
1595	    UPGT_X2_SIGNATURE_SIZE,
1596	    sizeof(struct upgt_fw_x2_header) - UPGT_X2_SIGNATURE_SIZE -
1597	    sizeof(uint32_t));
1598	upgt_bulk_tx(sc, data_cmd);
1599
1600	/* download firmware */
1601	for (offset = 0; offset < fw->datasize; offset += bsize) {
1602		if (fw->datasize - offset > UPGT_FW_BLOCK_SIZE)
1603			bsize = UPGT_FW_BLOCK_SIZE;
1604		else
1605			bsize = fw->datasize - offset;
1606
1607		data_cmd = upgt_getbuf(sc);
1608		if (data_cmd == NULL) {
1609			error = ENOBUFS;
1610			goto fail;
1611		}
1612		n = upgt_fw_copy((const uint8_t *)fw->data + offset,
1613		    data_cmd->buf, bsize);
1614		data_cmd->buflen = bsize;
1615		upgt_bulk_tx(sc, data_cmd);
1616
1617		DPRINTF(sc, UPGT_DEBUG_FW, "FW offset=%zu, read=%d, sent=%d\n",
1618		    offset, n, bsize);
1619		bsize = n;
1620	}
1621	DPRINTF(sc, UPGT_DEBUG_FW, "%s: firmware downloaded\n", __func__);
1622
1623	/* load firmware */
1624	data_cmd = upgt_getbuf(sc);
1625	if (data_cmd == NULL) {
1626		error = ENOBUFS;
1627		goto fail;
1628	}
1629	crc32 = upgt_crc32_le(fw->data, fw->datasize);
1630	*((uint32_t *)(data_cmd->buf)    ) = crc32;
1631	*((uint8_t  *)(data_cmd->buf) + 4) = 'g';
1632	*((uint8_t  *)(data_cmd->buf) + 5) = '\r';
1633	data_cmd->buflen = 6;
1634	upgt_bulk_tx(sc, data_cmd);
1635
1636	/* waiting 'OK' response.  */
1637	usbd_transfer_start(sc->sc_xfer[UPGT_BULK_RX]);
1638	error = mtx_sleep(sc, &sc->sc_mtx, 0, "upgtfw", 2 * hz);
1639	if (error != 0) {
1640		device_printf(sc->sc_dev, "firmware load failed\n");
1641		error = EIO;
1642	}
1643
1644	DPRINTF(sc, UPGT_DEBUG_FW, "%s: firmware loaded\n", __func__);
1645fail:
1646	UPGT_UNLOCK(sc);
1647	firmware_put(fw, FIRMWARE_UNLOAD);
1648	return (error);
1649}
1650
1651static uint32_t
1652upgt_crc32_le(const void *buf, size_t size)
1653{
1654	uint32_t crc;
1655
1656	crc = ether_crc32_le(buf, size);
1657
1658	/* apply final XOR value as common for CRC-32 */
1659	crc = htole32(crc ^ 0xffffffffU);
1660
1661	return (crc);
1662}
1663
1664/*
1665 * While copying the version 2 firmware, we need to replace two characters:
1666 *
1667 * 0x7e -> 0x7d 0x5e
1668 * 0x7d -> 0x7d 0x5d
1669 */
1670static int
1671upgt_fw_copy(const uint8_t *src, char *dst, int size)
1672{
1673	int i, j;
1674
1675	for (i = 0, j = 0; i < size && j < size; i++) {
1676		switch (src[i]) {
1677		case 0x7e:
1678			dst[j] = 0x7d;
1679			j++;
1680			dst[j] = 0x5e;
1681			j++;
1682			break;
1683		case 0x7d:
1684			dst[j] = 0x7d;
1685			j++;
1686			dst[j] = 0x5d;
1687			j++;
1688			break;
1689		default:
1690			dst[j] = src[i];
1691			j++;
1692			break;
1693		}
1694	}
1695
1696	return (i);
1697}
1698
1699static int
1700upgt_mem_init(struct upgt_softc *sc)
1701{
1702	int i;
1703
1704	for (i = 0; i < UPGT_MEMORY_MAX_PAGES; i++) {
1705		sc->sc_memory.page[i].used = 0;
1706
1707		if (i == 0) {
1708			/*
1709			 * The first memory page is always reserved for
1710			 * command data.
1711			 */
1712			sc->sc_memory.page[i].addr =
1713			    sc->sc_memaddr_frame_start + MCLBYTES;
1714		} else {
1715			sc->sc_memory.page[i].addr =
1716			    sc->sc_memory.page[i - 1].addr + MCLBYTES;
1717		}
1718
1719		if (sc->sc_memory.page[i].addr + MCLBYTES >=
1720		    sc->sc_memaddr_frame_end)
1721			break;
1722
1723		DPRINTF(sc, UPGT_DEBUG_FW, "memory address page %d=0x%08x\n",
1724		    i, sc->sc_memory.page[i].addr);
1725	}
1726
1727	sc->sc_memory.pages = i;
1728
1729	DPRINTF(sc, UPGT_DEBUG_FW, "memory pages=%d\n", sc->sc_memory.pages);
1730	return (0);
1731}
1732
1733static int
1734upgt_fw_verify(struct upgt_softc *sc)
1735{
1736	const struct firmware *fw;
1737	const struct upgt_fw_bra_option *bra_opt;
1738	const struct upgt_fw_bra_descr *descr;
1739	const uint8_t *p;
1740	const uint32_t *uc;
1741	uint32_t bra_option_type, bra_option_len;
1742	size_t offset;
1743	int bra_end = 0;
1744	int error = 0;
1745
1746	fw = firmware_get(upgt_fwname);
1747	if (fw == NULL) {
1748		device_printf(sc->sc_dev, "could not read microcode %s\n",
1749		    upgt_fwname);
1750		return EIO;
1751	}
1752
1753	/*
1754	 * Seek to beginning of Boot Record Area (BRA).
1755	 */
1756	for (offset = 0; offset < fw->datasize; offset += sizeof(*uc)) {
1757		uc = (const uint32_t *)((const uint8_t *)fw->data + offset);
1758		if (*uc == 0)
1759			break;
1760	}
1761	for (; offset < fw->datasize; offset += sizeof(*uc)) {
1762		uc = (const uint32_t *)((const uint8_t *)fw->data + offset);
1763		if (*uc != 0)
1764			break;
1765	}
1766	if (offset == fw->datasize) {
1767		device_printf(sc->sc_dev,
1768		    "firmware Boot Record Area not found\n");
1769		error = EIO;
1770		goto fail;
1771	}
1772
1773	DPRINTF(sc, UPGT_DEBUG_FW,
1774	    "firmware Boot Record Area found at offset %zu\n", offset);
1775
1776	/*
1777	 * Parse Boot Record Area (BRA) options.
1778	 */
1779	while (offset < fw->datasize && bra_end == 0) {
1780		/* get current BRA option */
1781		p = (const uint8_t *)fw->data + offset;
1782		bra_opt = (const struct upgt_fw_bra_option *)p;
1783		bra_option_type = le32toh(bra_opt->type);
1784		bra_option_len = le32toh(bra_opt->len) * sizeof(*uc);
1785
1786		switch (bra_option_type) {
1787		case UPGT_BRA_TYPE_FW:
1788			DPRINTF(sc, UPGT_DEBUG_FW, "UPGT_BRA_TYPE_FW len=%d\n",
1789			    bra_option_len);
1790
1791			if (bra_option_len != UPGT_BRA_FWTYPE_SIZE) {
1792				device_printf(sc->sc_dev,
1793				    "wrong UPGT_BRA_TYPE_FW len\n");
1794				error = EIO;
1795				goto fail;
1796			}
1797			if (memcmp(UPGT_BRA_FWTYPE_LM86, bra_opt->data,
1798			    bra_option_len) == 0) {
1799				sc->sc_fw_type = UPGT_FWTYPE_LM86;
1800				break;
1801			}
1802			if (memcmp(UPGT_BRA_FWTYPE_LM87, bra_opt->data,
1803			    bra_option_len) == 0) {
1804				sc->sc_fw_type = UPGT_FWTYPE_LM87;
1805				break;
1806			}
1807			device_printf(sc->sc_dev,
1808			    "unsupported firmware type\n");
1809			error = EIO;
1810			goto fail;
1811		case UPGT_BRA_TYPE_VERSION:
1812			DPRINTF(sc, UPGT_DEBUG_FW,
1813			    "UPGT_BRA_TYPE_VERSION len=%d\n", bra_option_len);
1814			break;
1815		case UPGT_BRA_TYPE_DEPIF:
1816			DPRINTF(sc, UPGT_DEBUG_FW,
1817			    "UPGT_BRA_TYPE_DEPIF len=%d\n", bra_option_len);
1818			break;
1819		case UPGT_BRA_TYPE_EXPIF:
1820			DPRINTF(sc, UPGT_DEBUG_FW,
1821			    "UPGT_BRA_TYPE_EXPIF len=%d\n", bra_option_len);
1822			break;
1823		case UPGT_BRA_TYPE_DESCR:
1824			DPRINTF(sc, UPGT_DEBUG_FW,
1825			    "UPGT_BRA_TYPE_DESCR len=%d\n", bra_option_len);
1826
1827			descr = (const struct upgt_fw_bra_descr *)bra_opt->data;
1828
1829			sc->sc_memaddr_frame_start =
1830			    le32toh(descr->memaddr_space_start);
1831			sc->sc_memaddr_frame_end =
1832			    le32toh(descr->memaddr_space_end);
1833
1834			DPRINTF(sc, UPGT_DEBUG_FW,
1835			    "memory address space start=0x%08x\n",
1836			    sc->sc_memaddr_frame_start);
1837			DPRINTF(sc, UPGT_DEBUG_FW,
1838			    "memory address space end=0x%08x\n",
1839			    sc->sc_memaddr_frame_end);
1840			break;
1841		case UPGT_BRA_TYPE_END:
1842			DPRINTF(sc, UPGT_DEBUG_FW, "UPGT_BRA_TYPE_END len=%d\n",
1843			    bra_option_len);
1844			bra_end = 1;
1845			break;
1846		default:
1847			DPRINTF(sc, UPGT_DEBUG_FW, "unknown BRA option len=%d\n",
1848			    bra_option_len);
1849			error = EIO;
1850			goto fail;
1851		}
1852
1853		/* jump to next BRA option */
1854		offset += sizeof(struct upgt_fw_bra_option) + bra_option_len;
1855	}
1856
1857	DPRINTF(sc, UPGT_DEBUG_FW, "%s: firmware verified", __func__);
1858fail:
1859	firmware_put(fw, FIRMWARE_UNLOAD);
1860	return (error);
1861}
1862
1863static void
1864upgt_bulk_tx(struct upgt_softc *sc, struct upgt_data *data)
1865{
1866
1867	UPGT_ASSERT_LOCKED(sc);
1868
1869	STAILQ_INSERT_TAIL(&sc->sc_tx_pending, data, next);
1870	UPGT_STAT_INC(sc, st_tx_pending);
1871	usbd_transfer_start(sc->sc_xfer[UPGT_BULK_TX]);
1872}
1873
1874static int
1875upgt_device_reset(struct upgt_softc *sc)
1876{
1877	struct upgt_data *data;
1878	char init_cmd[] = { 0x7e, 0x7e, 0x7e, 0x7e };
1879
1880	UPGT_LOCK(sc);
1881
1882	data = upgt_getbuf(sc);
1883	if (data == NULL) {
1884		UPGT_UNLOCK(sc);
1885		return (ENOBUFS);
1886	}
1887	memcpy(data->buf, init_cmd, sizeof(init_cmd));
1888	data->buflen = sizeof(init_cmd);
1889	upgt_bulk_tx(sc, data);
1890	usb_pause_mtx(&sc->sc_mtx, 100);
1891
1892	UPGT_UNLOCK(sc);
1893	DPRINTF(sc, UPGT_DEBUG_FW, "%s: device initialized\n", __func__);
1894	return (0);
1895}
1896
1897static int
1898upgt_alloc_tx(struct upgt_softc *sc)
1899{
1900	int i;
1901
1902	STAILQ_INIT(&sc->sc_tx_active);
1903	STAILQ_INIT(&sc->sc_tx_inactive);
1904	STAILQ_INIT(&sc->sc_tx_pending);
1905
1906	for (i = 0; i < UPGT_TX_MAXCOUNT; i++) {
1907		struct upgt_data *data = &sc->sc_tx_data[i];
1908		data->buf = ((uint8_t *)sc->sc_tx_dma_buf) + (i * MCLBYTES);
1909		STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data, next);
1910		UPGT_STAT_INC(sc, st_tx_inactive);
1911	}
1912
1913	return (0);
1914}
1915
1916static int
1917upgt_alloc_rx(struct upgt_softc *sc)
1918{
1919	int i;
1920
1921	STAILQ_INIT(&sc->sc_rx_active);
1922	STAILQ_INIT(&sc->sc_rx_inactive);
1923
1924	for (i = 0; i < UPGT_RX_MAXCOUNT; i++) {
1925		struct upgt_data *data = &sc->sc_rx_data[i];
1926		data->buf = ((uint8_t *)sc->sc_rx_dma_buf) + (i * MCLBYTES);
1927		STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next);
1928	}
1929	return (0);
1930}
1931
1932static int
1933upgt_detach(device_t dev)
1934{
1935	struct upgt_softc *sc = device_get_softc(dev);
1936	struct ieee80211com *ic = &sc->sc_ic;
1937	unsigned int x;
1938
1939	/*
1940	 * Prevent further allocations from RX/TX/CMD
1941	 * data lists and ioctls
1942	 */
1943	UPGT_LOCK(sc);
1944	sc->sc_flags |= UPGT_FLAG_DETACHED;
1945
1946	STAILQ_INIT(&sc->sc_tx_active);
1947	STAILQ_INIT(&sc->sc_tx_inactive);
1948	STAILQ_INIT(&sc->sc_tx_pending);
1949
1950	STAILQ_INIT(&sc->sc_rx_active);
1951	STAILQ_INIT(&sc->sc_rx_inactive);
1952
1953	upgt_stop(sc);
1954	UPGT_UNLOCK(sc);
1955
1956	callout_drain(&sc->sc_led_ch);
1957	callout_drain(&sc->sc_watchdog_ch);
1958
1959	/* drain USB transfers */
1960	for (x = 0; x != UPGT_N_XFERS; x++)
1961		usbd_transfer_drain(sc->sc_xfer[x]);
1962
1963	/* free data buffers */
1964	UPGT_LOCK(sc);
1965	upgt_free_rx(sc);
1966	upgt_free_tx(sc);
1967	UPGT_UNLOCK(sc);
1968
1969	/* free USB transfers and some data buffers */
1970	usbd_transfer_unsetup(sc->sc_xfer, UPGT_N_XFERS);
1971
1972	ieee80211_ifdetach(ic);
1973	mbufq_drain(&sc->sc_snd);
1974	mtx_destroy(&sc->sc_mtx);
1975
1976	return (0);
1977}
1978
1979static void
1980upgt_free_rx(struct upgt_softc *sc)
1981{
1982	int i;
1983
1984	for (i = 0; i < UPGT_RX_MAXCOUNT; i++) {
1985		struct upgt_data *data = &sc->sc_rx_data[i];
1986
1987		data->buf = NULL;
1988		data->ni = NULL;
1989	}
1990}
1991
1992static void
1993upgt_free_tx(struct upgt_softc *sc)
1994{
1995	int i;
1996
1997	for (i = 0; i < UPGT_TX_MAXCOUNT; i++) {
1998		struct upgt_data *data = &sc->sc_tx_data[i];
1999
2000		if (data->ni != NULL)
2001			ieee80211_free_node(data->ni);
2002
2003		data->buf = NULL;
2004		data->ni = NULL;
2005	}
2006}
2007
2008static void
2009upgt_abort_xfers_locked(struct upgt_softc *sc)
2010{
2011	int i;
2012
2013	UPGT_ASSERT_LOCKED(sc);
2014	/* abort any pending transfers */
2015	for (i = 0; i < UPGT_N_XFERS; i++)
2016		usbd_transfer_stop(sc->sc_xfer[i]);
2017}
2018
2019static void
2020upgt_abort_xfers(struct upgt_softc *sc)
2021{
2022
2023	UPGT_LOCK(sc);
2024	upgt_abort_xfers_locked(sc);
2025	UPGT_UNLOCK(sc);
2026}
2027
2028#define	UPGT_SYSCTL_STAT_ADD32(c, h, n, p, d)	\
2029	    SYSCTL_ADD_UINT(c, h, OID_AUTO, n, CTLFLAG_RD, p, 0, d)
2030
2031static void
2032upgt_sysctl_node(struct upgt_softc *sc)
2033{
2034	struct sysctl_ctx_list *ctx;
2035	struct sysctl_oid_list *child;
2036	struct sysctl_oid *tree;
2037	struct upgt_stat *stats;
2038
2039	stats = &sc->sc_stat;
2040	ctx = device_get_sysctl_ctx(sc->sc_dev);
2041	child = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->sc_dev));
2042
2043	tree = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "stats",
2044	    CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "UPGT statistics");
2045	child = SYSCTL_CHILDREN(tree);
2046	UPGT_SYSCTL_STAT_ADD32(ctx, child, "tx_active",
2047	    &stats->st_tx_active, "Active numbers in TX queue");
2048	UPGT_SYSCTL_STAT_ADD32(ctx, child, "tx_inactive",
2049	    &stats->st_tx_inactive, "Inactive numbers in TX queue");
2050	UPGT_SYSCTL_STAT_ADD32(ctx, child, "tx_pending",
2051	    &stats->st_tx_pending, "Pending numbers in TX queue");
2052}
2053
2054#undef UPGT_SYSCTL_STAT_ADD32
2055
2056static struct upgt_data *
2057_upgt_getbuf(struct upgt_softc *sc)
2058{
2059	struct upgt_data *bf;
2060
2061	bf = STAILQ_FIRST(&sc->sc_tx_inactive);
2062	if (bf != NULL) {
2063		STAILQ_REMOVE_HEAD(&sc->sc_tx_inactive, next);
2064		UPGT_STAT_DEC(sc, st_tx_inactive);
2065	} else
2066		bf = NULL;
2067	if (bf == NULL)
2068		DPRINTF(sc, UPGT_DEBUG_XMIT, "%s: %s\n", __func__,
2069		    "out of xmit buffers");
2070	return (bf);
2071}
2072
2073static struct upgt_data *
2074upgt_getbuf(struct upgt_softc *sc)
2075{
2076	struct upgt_data *bf;
2077
2078	UPGT_ASSERT_LOCKED(sc);
2079
2080	bf = _upgt_getbuf(sc);
2081	if (bf == NULL)
2082		DPRINTF(sc, UPGT_DEBUG_XMIT, "%s: stop queue\n", __func__);
2083
2084	return (bf);
2085}
2086
2087static struct upgt_data *
2088upgt_gettxbuf(struct upgt_softc *sc)
2089{
2090	struct upgt_data *bf;
2091
2092	UPGT_ASSERT_LOCKED(sc);
2093
2094	bf = upgt_getbuf(sc);
2095	if (bf == NULL)
2096		return (NULL);
2097
2098	bf->addr = upgt_mem_alloc(sc);
2099	if (bf->addr == 0) {
2100		DPRINTF(sc, UPGT_DEBUG_XMIT, "%s: no free prism memory!\n",
2101		    __func__);
2102		STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
2103		UPGT_STAT_INC(sc, st_tx_inactive);
2104		return (NULL);
2105	}
2106	return (bf);
2107}
2108
2109static int
2110upgt_tx_start(struct upgt_softc *sc, struct mbuf *m, struct ieee80211_node *ni,
2111    struct upgt_data *data)
2112{
2113	struct ieee80211vap *vap = ni->ni_vap;
2114	int error = 0, len;
2115	struct ieee80211_frame *wh;
2116	struct ieee80211_key *k;
2117	struct upgt_lmac_mem *mem;
2118	struct upgt_lmac_tx_desc *txdesc;
2119
2120	UPGT_ASSERT_LOCKED(sc);
2121
2122	upgt_set_led(sc, UPGT_LED_BLINK);
2123
2124	/*
2125	 * Software crypto.
2126	 */
2127	wh = mtod(m, struct ieee80211_frame *);
2128	if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
2129		k = ieee80211_crypto_encap(ni, m);
2130		if (k == NULL) {
2131			device_printf(sc->sc_dev,
2132			    "ieee80211_crypto_encap returns NULL.\n");
2133			error = EIO;
2134			goto done;
2135		}
2136
2137		/* in case packet header moved, reset pointer */
2138		wh = mtod(m, struct ieee80211_frame *);
2139	}
2140
2141	/* Transmit the URB containing the TX data.  */
2142	memset(data->buf, 0, MCLBYTES);
2143	mem = (struct upgt_lmac_mem *)data->buf;
2144	mem->addr = htole32(data->addr);
2145	txdesc = (struct upgt_lmac_tx_desc *)(mem + 1);
2146
2147	if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
2148	    IEEE80211_FC0_TYPE_MGT) {
2149		/* mgmt frames  */
2150		txdesc->header1.flags = UPGT_H1_FLAGS_TX_MGMT;
2151		/* always send mgmt frames at lowest rate (DS1) */
2152		memset(txdesc->rates, 0x10, sizeof(txdesc->rates));
2153	} else {
2154		/* data frames  */
2155		txdesc->header1.flags = UPGT_H1_FLAGS_TX_DATA;
2156		memcpy(txdesc->rates, sc->sc_cur_rateset, sizeof(txdesc->rates));
2157	}
2158	txdesc->header1.type = UPGT_H1_TYPE_TX_DATA;
2159	txdesc->header1.len = htole16(m->m_pkthdr.len);
2160	txdesc->header2.reqid = htole32(data->addr);
2161	txdesc->header2.type = htole16(UPGT_H2_TYPE_TX_ACK_YES);
2162	txdesc->header2.flags = htole16(UPGT_H2_FLAGS_TX_ACK_YES);
2163	txdesc->type = htole32(UPGT_TX_DESC_TYPE_DATA);
2164	txdesc->pad3[0] = UPGT_TX_DESC_PAD3_SIZE;
2165
2166	if (ieee80211_radiotap_active_vap(vap)) {
2167		struct upgt_tx_radiotap_header *tap = &sc->sc_txtap;
2168
2169		tap->wt_flags = 0;
2170		tap->wt_rate = 0;	/* XXX where to get from? */
2171
2172		ieee80211_radiotap_tx(vap, m);
2173	}
2174
2175	/* copy frame below our TX descriptor header */
2176	m_copydata(m, 0, m->m_pkthdr.len,
2177	    data->buf + (sizeof(*mem) + sizeof(*txdesc)));
2178	/* calculate frame size */
2179	len = sizeof(*mem) + sizeof(*txdesc) + m->m_pkthdr.len;
2180	/* we need to align the frame to a 4 byte boundary */
2181	len = (len + 3) & ~3;
2182	/* calculate frame checksum */
2183	mem->chksum = upgt_chksum_le((uint32_t *)txdesc, len - sizeof(*mem));
2184	data->ni = ni;
2185	data->m = m;
2186	data->buflen = len;
2187
2188	DPRINTF(sc, UPGT_DEBUG_XMIT, "%s: TX start data sending (%d bytes)\n",
2189	    __func__, len);
2190	KASSERT(len <= MCLBYTES, ("mbuf is small for saving data"));
2191
2192	upgt_bulk_tx(sc, data);
2193done:
2194	/*
2195	 * If we don't regulary read the device statistics, the RX queue
2196	 * will stall.  It's strange, but it works, so we keep reading
2197	 * the statistics here.  *shrug*
2198	 */
2199	if (!(vap->iv_ifp->if_get_counter(vap->iv_ifp, IFCOUNTER_OPACKETS) %
2200	    UPGT_TX_STAT_INTERVAL))
2201		upgt_get_stats(sc);
2202
2203	return (error);
2204}
2205
2206static void
2207upgt_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
2208{
2209	struct upgt_softc *sc = usbd_xfer_softc(xfer);
2210	struct ieee80211com *ic = &sc->sc_ic;
2211	struct ieee80211_frame *wh;
2212	struct ieee80211_node *ni;
2213	struct epoch_tracker et;
2214	struct mbuf *m = NULL;
2215	struct upgt_data *data;
2216	int8_t nf;
2217	int rssi = -1;
2218
2219	UPGT_ASSERT_LOCKED(sc);
2220
2221	switch (USB_GET_STATE(xfer)) {
2222	case USB_ST_TRANSFERRED:
2223		data = STAILQ_FIRST(&sc->sc_rx_active);
2224		if (data == NULL)
2225			goto setup;
2226		STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next);
2227		m = upgt_rxeof(xfer, data, &rssi);
2228		STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next);
2229		/* FALLTHROUGH */
2230	case USB_ST_SETUP:
2231setup:
2232		data = STAILQ_FIRST(&sc->sc_rx_inactive);
2233		if (data == NULL)
2234			return;
2235		STAILQ_REMOVE_HEAD(&sc->sc_rx_inactive, next);
2236		STAILQ_INSERT_TAIL(&sc->sc_rx_active, data, next);
2237		usbd_xfer_set_frame_data(xfer, 0, data->buf, MCLBYTES);
2238		usbd_transfer_submit(xfer);
2239
2240		/*
2241		 * To avoid LOR we should unlock our private mutex here to call
2242		 * ieee80211_input() because here is at the end of a USB
2243		 * callback and safe to unlock.
2244		 */
2245		UPGT_UNLOCK(sc);
2246		if (m != NULL) {
2247			wh = mtod(m, struct ieee80211_frame *);
2248			ni = ieee80211_find_rxnode(ic,
2249			    (struct ieee80211_frame_min *)wh);
2250			nf = -95;	/* XXX */
2251			NET_EPOCH_ENTER(et);
2252			if (ni != NULL) {
2253				(void) ieee80211_input(ni, m, rssi, nf);
2254				/* node is no longer needed */
2255				ieee80211_free_node(ni);
2256			} else
2257				(void) ieee80211_input_all(ic, m, rssi, nf);
2258			NET_EPOCH_EXIT(et);
2259			m = NULL;
2260		}
2261		UPGT_LOCK(sc);
2262		upgt_start(sc);
2263		break;
2264	default:
2265		/* needs it to the inactive queue due to a error.  */
2266		data = STAILQ_FIRST(&sc->sc_rx_active);
2267		if (data != NULL) {
2268			STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next);
2269			STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next);
2270		}
2271		if (error != USB_ERR_CANCELLED) {
2272			usbd_xfer_set_stall(xfer);
2273			counter_u64_add(ic->ic_ierrors, 1);
2274			goto setup;
2275		}
2276		break;
2277	}
2278}
2279
2280static void
2281upgt_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error)
2282{
2283	struct upgt_softc *sc = usbd_xfer_softc(xfer);
2284	struct upgt_data *data;
2285
2286	UPGT_ASSERT_LOCKED(sc);
2287	switch (USB_GET_STATE(xfer)) {
2288	case USB_ST_TRANSFERRED:
2289		data = STAILQ_FIRST(&sc->sc_tx_active);
2290		if (data == NULL)
2291			goto setup;
2292		STAILQ_REMOVE_HEAD(&sc->sc_tx_active, next);
2293		UPGT_STAT_DEC(sc, st_tx_active);
2294		upgt_txeof(xfer, data);
2295		STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data, next);
2296		UPGT_STAT_INC(sc, st_tx_inactive);
2297		/* FALLTHROUGH */
2298	case USB_ST_SETUP:
2299setup:
2300		data = STAILQ_FIRST(&sc->sc_tx_pending);
2301		if (data == NULL) {
2302			DPRINTF(sc, UPGT_DEBUG_XMIT, "%s: empty pending queue\n",
2303			    __func__);
2304			return;
2305		}
2306		STAILQ_REMOVE_HEAD(&sc->sc_tx_pending, next);
2307		UPGT_STAT_DEC(sc, st_tx_pending);
2308		STAILQ_INSERT_TAIL(&sc->sc_tx_active, data, next);
2309		UPGT_STAT_INC(sc, st_tx_active);
2310
2311		usbd_xfer_set_frame_data(xfer, 0, data->buf, data->buflen);
2312		usbd_transfer_submit(xfer);
2313		upgt_start(sc);
2314		break;
2315	default:
2316		data = STAILQ_FIRST(&sc->sc_tx_active);
2317		if (data == NULL)
2318			goto setup;
2319		if (data->ni != NULL) {
2320			if_inc_counter(data->ni->ni_vap->iv_ifp,
2321			    IFCOUNTER_OERRORS, 1);
2322			ieee80211_free_node(data->ni);
2323			data->ni = NULL;
2324		}
2325		if (error != USB_ERR_CANCELLED) {
2326			usbd_xfer_set_stall(xfer);
2327			goto setup;
2328		}
2329		break;
2330	}
2331}
2332
2333static device_method_t upgt_methods[] = {
2334        /* Device interface */
2335        DEVMETHOD(device_probe, upgt_match),
2336        DEVMETHOD(device_attach, upgt_attach),
2337        DEVMETHOD(device_detach, upgt_detach),
2338	DEVMETHOD_END
2339};
2340
2341static driver_t upgt_driver = {
2342	.name = "upgt",
2343	.methods = upgt_methods,
2344	.size = sizeof(struct upgt_softc)
2345};
2346
2347static devclass_t upgt_devclass;
2348
2349DRIVER_MODULE(if_upgt, uhub, upgt_driver, upgt_devclass, NULL, 0);
2350MODULE_VERSION(if_upgt, 1);
2351MODULE_DEPEND(if_upgt, usb, 1, 1, 1);
2352MODULE_DEPEND(if_upgt, wlan, 1, 1, 1);
2353MODULE_DEPEND(if_upgt, upgtfw_fw, 1, 1, 1);
2354USB_PNP_HOST_INFO(upgt_devs);
2355