if_zyd.c revision 286416
1/*	$OpenBSD: if_zyd.c,v 1.52 2007/02/11 00:08:04 jsg Exp $	*/
2/*	$NetBSD: if_zyd.c,v 1.7 2007/06/21 04:04:29 kiyohara Exp $	*/
3/*	$FreeBSD: head/sys/dev/usb/wlan/if_zyd.c 286416 2015-08-07 16:23:16Z glebius $	*/
4
5/*-
6 * Copyright (c) 2006 by Damien Bergamini <damien.bergamini@free.fr>
7 * Copyright (c) 2006 by Florian Stoehr <ich@florian-stoehr.de>
8 *
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 */
21
22#include <sys/cdefs.h>
23__FBSDID("$FreeBSD: head/sys/dev/usb/wlan/if_zyd.c 286416 2015-08-07 16:23:16Z glebius $");
24
25/*
26 * ZyDAS ZD1211/ZD1211B USB WLAN driver.
27 */
28
29#include <sys/param.h>
30#include <sys/sockio.h>
31#include <sys/sysctl.h>
32#include <sys/lock.h>
33#include <sys/mutex.h>
34#include <sys/condvar.h>
35#include <sys/mbuf.h>
36#include <sys/kernel.h>
37#include <sys/socket.h>
38#include <sys/systm.h>
39#include <sys/malloc.h>
40#include <sys/module.h>
41#include <sys/bus.h>
42#include <sys/endian.h>
43#include <sys/kdb.h>
44
45#include <machine/bus.h>
46#include <machine/resource.h>
47#include <sys/rman.h>
48
49#include <net/bpf.h>
50#include <net/if.h>
51#include <net/if_var.h>
52#include <net/if_arp.h>
53#include <net/ethernet.h>
54#include <net/if_dl.h>
55#include <net/if_media.h>
56#include <net/if_types.h>
57
58#ifdef INET
59#include <netinet/in.h>
60#include <netinet/in_systm.h>
61#include <netinet/in_var.h>
62#include <netinet/if_ether.h>
63#include <netinet/ip.h>
64#endif
65
66#include <net80211/ieee80211_var.h>
67#include <net80211/ieee80211_regdomain.h>
68#include <net80211/ieee80211_radiotap.h>
69#include <net80211/ieee80211_ratectl.h>
70
71#include <dev/usb/usb.h>
72#include <dev/usb/usbdi.h>
73#include <dev/usb/usbdi_util.h>
74#include "usbdevs.h"
75
76#include <dev/usb/wlan/if_zydreg.h>
77#include <dev/usb/wlan/if_zydfw.h>
78
79#ifdef USB_DEBUG
80static int zyd_debug = 0;
81
82static SYSCTL_NODE(_hw_usb, OID_AUTO, zyd, CTLFLAG_RW, 0, "USB zyd");
83SYSCTL_INT(_hw_usb_zyd, OID_AUTO, debug, CTLFLAG_RWTUN, &zyd_debug, 0,
84    "zyd debug level");
85
86enum {
87	ZYD_DEBUG_XMIT		= 0x00000001,	/* basic xmit operation */
88	ZYD_DEBUG_RECV		= 0x00000002,	/* basic recv operation */
89	ZYD_DEBUG_RESET		= 0x00000004,	/* reset processing */
90	ZYD_DEBUG_INIT		= 0x00000008,	/* device init */
91	ZYD_DEBUG_TX_PROC	= 0x00000010,	/* tx ISR proc */
92	ZYD_DEBUG_RX_PROC	= 0x00000020,	/* rx ISR proc */
93	ZYD_DEBUG_STATE		= 0x00000040,	/* 802.11 state transitions */
94	ZYD_DEBUG_STAT		= 0x00000080,	/* statistic */
95	ZYD_DEBUG_FW		= 0x00000100,	/* firmware */
96	ZYD_DEBUG_CMD		= 0x00000200,	/* fw commands */
97	ZYD_DEBUG_ANY		= 0xffffffff
98};
99#define	DPRINTF(sc, m, fmt, ...) do {				\
100	if (zyd_debug & (m))					\
101		printf("%s: " fmt, __func__, ## __VA_ARGS__);	\
102} while (0)
103#else
104#define	DPRINTF(sc, m, fmt, ...) do {				\
105	(void) sc;						\
106} while (0)
107#endif
108
109#define	zyd_do_request(sc,req,data) \
110    usbd_do_request_flags((sc)->sc_udev, &(sc)->sc_mtx, req, data, 0, NULL, 5000)
111
112static device_probe_t zyd_match;
113static device_attach_t zyd_attach;
114static device_detach_t zyd_detach;
115
116static usb_callback_t zyd_intr_read_callback;
117static usb_callback_t zyd_intr_write_callback;
118static usb_callback_t zyd_bulk_read_callback;
119static usb_callback_t zyd_bulk_write_callback;
120
121static struct ieee80211vap *zyd_vap_create(struct ieee80211com *,
122		    const char [IFNAMSIZ], int, enum ieee80211_opmode, int,
123		    const uint8_t [IEEE80211_ADDR_LEN],
124		    const uint8_t [IEEE80211_ADDR_LEN]);
125static void	zyd_vap_delete(struct ieee80211vap *);
126static void	zyd_tx_free(struct zyd_tx_data *, int);
127static void	zyd_setup_tx_list(struct zyd_softc *);
128static void	zyd_unsetup_tx_list(struct zyd_softc *);
129static int	zyd_newstate(struct ieee80211vap *, enum ieee80211_state, int);
130static int	zyd_cmd(struct zyd_softc *, uint16_t, const void *, int,
131		    void *, int, int);
132static int	zyd_read16(struct zyd_softc *, uint16_t, uint16_t *);
133static int	zyd_read32(struct zyd_softc *, uint16_t, uint32_t *);
134static int	zyd_write16(struct zyd_softc *, uint16_t, uint16_t);
135static int	zyd_write32(struct zyd_softc *, uint16_t, uint32_t);
136static int	zyd_rfwrite(struct zyd_softc *, uint32_t);
137static int	zyd_lock_phy(struct zyd_softc *);
138static int	zyd_unlock_phy(struct zyd_softc *);
139static int	zyd_rf_attach(struct zyd_softc *, uint8_t);
140static const char *zyd_rf_name(uint8_t);
141static int	zyd_hw_init(struct zyd_softc *);
142static int	zyd_read_pod(struct zyd_softc *);
143static int	zyd_read_eeprom(struct zyd_softc *);
144static int	zyd_get_macaddr(struct zyd_softc *);
145static int	zyd_set_macaddr(struct zyd_softc *, const uint8_t *);
146static int	zyd_set_bssid(struct zyd_softc *, const uint8_t *);
147static int	zyd_switch_radio(struct zyd_softc *, int);
148static int	zyd_set_led(struct zyd_softc *, int, int);
149static void	zyd_set_multi(struct zyd_softc *);
150static void	zyd_update_mcast(struct ieee80211com *);
151static int	zyd_set_rxfilter(struct zyd_softc *);
152static void	zyd_set_chan(struct zyd_softc *, struct ieee80211_channel *);
153static int	zyd_set_beacon_interval(struct zyd_softc *, int);
154static void	zyd_rx_data(struct usb_xfer *, int, uint16_t);
155static int	zyd_tx_start(struct zyd_softc *, struct mbuf *,
156		    struct ieee80211_node *);
157static int	zyd_transmit(struct ieee80211com *, struct mbuf *);
158static void	zyd_start(struct zyd_softc *);
159static int	zyd_raw_xmit(struct ieee80211_node *, struct mbuf *,
160		    const struct ieee80211_bpf_params *);
161static void	zyd_parent(struct ieee80211com *);
162static void	zyd_init_locked(struct zyd_softc *);
163static void	zyd_stop(struct zyd_softc *);
164static int	zyd_loadfirmware(struct zyd_softc *);
165static void	zyd_scan_start(struct ieee80211com *);
166static void	zyd_scan_end(struct ieee80211com *);
167static void	zyd_set_channel(struct ieee80211com *);
168static int	zyd_rfmd_init(struct zyd_rf *);
169static int	zyd_rfmd_switch_radio(struct zyd_rf *, int);
170static int	zyd_rfmd_set_channel(struct zyd_rf *, uint8_t);
171static int	zyd_al2230_init(struct zyd_rf *);
172static int	zyd_al2230_switch_radio(struct zyd_rf *, int);
173static int	zyd_al2230_set_channel(struct zyd_rf *, uint8_t);
174static int	zyd_al2230_set_channel_b(struct zyd_rf *, uint8_t);
175static int	zyd_al2230_init_b(struct zyd_rf *);
176static int	zyd_al7230B_init(struct zyd_rf *);
177static int	zyd_al7230B_switch_radio(struct zyd_rf *, int);
178static int	zyd_al7230B_set_channel(struct zyd_rf *, uint8_t);
179static int	zyd_al2210_init(struct zyd_rf *);
180static int	zyd_al2210_switch_radio(struct zyd_rf *, int);
181static int	zyd_al2210_set_channel(struct zyd_rf *, uint8_t);
182static int	zyd_gct_init(struct zyd_rf *);
183static int	zyd_gct_switch_radio(struct zyd_rf *, int);
184static int	zyd_gct_set_channel(struct zyd_rf *, uint8_t);
185static int	zyd_gct_mode(struct zyd_rf *);
186static int	zyd_gct_set_channel_synth(struct zyd_rf *, int, int);
187static int	zyd_gct_write(struct zyd_rf *, uint16_t);
188static int	zyd_gct_txgain(struct zyd_rf *, uint8_t);
189static int	zyd_maxim2_init(struct zyd_rf *);
190static int	zyd_maxim2_switch_radio(struct zyd_rf *, int);
191static int	zyd_maxim2_set_channel(struct zyd_rf *, uint8_t);
192
193static const struct zyd_phy_pair zyd_def_phy[] = ZYD_DEF_PHY;
194static const struct zyd_phy_pair zyd_def_phyB[] = ZYD_DEF_PHYB;
195
196/* various supported device vendors/products */
197#define ZYD_ZD1211	0
198#define ZYD_ZD1211B	1
199
200#define	ZYD_ZD1211_DEV(v,p)	\
201	{ USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, ZYD_ZD1211) }
202#define	ZYD_ZD1211B_DEV(v,p)	\
203	{ USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, ZYD_ZD1211B) }
204static const STRUCT_USB_HOST_ID zyd_devs[] = {
205	/* ZYD_ZD1211 */
206	ZYD_ZD1211_DEV(3COM2, 3CRUSB10075),
207	ZYD_ZD1211_DEV(ABOCOM, WL54),
208	ZYD_ZD1211_DEV(ASUS, WL159G),
209	ZYD_ZD1211_DEV(CYBERTAN, TG54USB),
210	ZYD_ZD1211_DEV(DRAYTEK, VIGOR550),
211	ZYD_ZD1211_DEV(PLANEX2, GWUS54GD),
212	ZYD_ZD1211_DEV(PLANEX2, GWUS54GZL),
213	ZYD_ZD1211_DEV(PLANEX3, GWUS54GZ),
214	ZYD_ZD1211_DEV(PLANEX3, GWUS54MINI),
215	ZYD_ZD1211_DEV(SAGEM, XG760A),
216	ZYD_ZD1211_DEV(SENAO, NUB8301),
217	ZYD_ZD1211_DEV(SITECOMEU, WL113),
218	ZYD_ZD1211_DEV(SWEEX, ZD1211),
219	ZYD_ZD1211_DEV(TEKRAM, QUICKWLAN),
220	ZYD_ZD1211_DEV(TEKRAM, ZD1211_1),
221	ZYD_ZD1211_DEV(TEKRAM, ZD1211_2),
222	ZYD_ZD1211_DEV(TWINMOS, G240),
223	ZYD_ZD1211_DEV(UMEDIA, ALL0298V2),
224	ZYD_ZD1211_DEV(UMEDIA, TEW429UB_A),
225	ZYD_ZD1211_DEV(UMEDIA, TEW429UB),
226	ZYD_ZD1211_DEV(WISTRONNEWEB, UR055G),
227	ZYD_ZD1211_DEV(ZCOM, ZD1211),
228	ZYD_ZD1211_DEV(ZYDAS, ZD1211),
229	ZYD_ZD1211_DEV(ZYXEL, AG225H),
230	ZYD_ZD1211_DEV(ZYXEL, ZYAIRG220),
231	ZYD_ZD1211_DEV(ZYXEL, G200V2),
232	/* ZYD_ZD1211B */
233	ZYD_ZD1211B_DEV(ACCTON, SMCWUSBG_NF),
234	ZYD_ZD1211B_DEV(ACCTON, SMCWUSBG),
235	ZYD_ZD1211B_DEV(ACCTON, ZD1211B),
236	ZYD_ZD1211B_DEV(ASUS, A9T_WIFI),
237	ZYD_ZD1211B_DEV(BELKIN, F5D7050_V4000),
238	ZYD_ZD1211B_DEV(BELKIN, ZD1211B),
239	ZYD_ZD1211B_DEV(CISCOLINKSYS, WUSBF54G),
240	ZYD_ZD1211B_DEV(FIBERLINE, WL430U),
241	ZYD_ZD1211B_DEV(MELCO, KG54L),
242	ZYD_ZD1211B_DEV(PHILIPS, SNU5600),
243	ZYD_ZD1211B_DEV(PLANEX2, GW_US54GXS),
244	ZYD_ZD1211B_DEV(SAGEM, XG76NA),
245	ZYD_ZD1211B_DEV(SITECOMEU, ZD1211B),
246	ZYD_ZD1211B_DEV(UMEDIA, TEW429UBC1),
247	ZYD_ZD1211B_DEV(USR, USR5423),
248	ZYD_ZD1211B_DEV(VTECH, ZD1211B),
249	ZYD_ZD1211B_DEV(ZCOM, ZD1211B),
250	ZYD_ZD1211B_DEV(ZYDAS, ZD1211B),
251	ZYD_ZD1211B_DEV(ZYXEL, M202),
252	ZYD_ZD1211B_DEV(ZYXEL, G202),
253	ZYD_ZD1211B_DEV(ZYXEL, G220V2)
254};
255
256static const struct usb_config zyd_config[ZYD_N_TRANSFER] = {
257	[ZYD_BULK_WR] = {
258		.type = UE_BULK,
259		.endpoint = UE_ADDR_ANY,
260		.direction = UE_DIR_OUT,
261		.bufsize = ZYD_MAX_TXBUFSZ,
262		.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
263		.callback = zyd_bulk_write_callback,
264		.ep_index = 0,
265		.timeout = 10000,	/* 10 seconds */
266	},
267	[ZYD_BULK_RD] = {
268		.type = UE_BULK,
269		.endpoint = UE_ADDR_ANY,
270		.direction = UE_DIR_IN,
271		.bufsize = ZYX_MAX_RXBUFSZ,
272		.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
273		.callback = zyd_bulk_read_callback,
274		.ep_index = 0,
275	},
276	[ZYD_INTR_WR] = {
277		.type = UE_BULK_INTR,
278		.endpoint = UE_ADDR_ANY,
279		.direction = UE_DIR_OUT,
280		.bufsize = sizeof(struct zyd_cmd),
281		.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
282		.callback = zyd_intr_write_callback,
283		.timeout = 1000,	/* 1 second */
284		.ep_index = 1,
285	},
286	[ZYD_INTR_RD] = {
287		.type = UE_INTERRUPT,
288		.endpoint = UE_ADDR_ANY,
289		.direction = UE_DIR_IN,
290		.bufsize = sizeof(struct zyd_cmd),
291		.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
292		.callback = zyd_intr_read_callback,
293	},
294};
295#define zyd_read16_m(sc, val, data)	do {				\
296	error = zyd_read16(sc, val, data);				\
297	if (error != 0)							\
298		goto fail;						\
299} while (0)
300#define zyd_write16_m(sc, val, data)	do {				\
301	error = zyd_write16(sc, val, data);				\
302	if (error != 0)							\
303		goto fail;						\
304} while (0)
305#define zyd_read32_m(sc, val, data)	do {				\
306	error = zyd_read32(sc, val, data);				\
307	if (error != 0)							\
308		goto fail;						\
309} while (0)
310#define zyd_write32_m(sc, val, data)	do {				\
311	error = zyd_write32(sc, val, data);				\
312	if (error != 0)							\
313		goto fail;						\
314} while (0)
315
316static int
317zyd_match(device_t dev)
318{
319	struct usb_attach_arg *uaa = device_get_ivars(dev);
320
321	if (uaa->usb_mode != USB_MODE_HOST)
322		return (ENXIO);
323	if (uaa->info.bConfigIndex != ZYD_CONFIG_INDEX)
324		return (ENXIO);
325	if (uaa->info.bIfaceIndex != ZYD_IFACE_INDEX)
326		return (ENXIO);
327
328	return (usbd_lookup_id_by_uaa(zyd_devs, sizeof(zyd_devs), uaa));
329}
330
331static int
332zyd_attach(device_t dev)
333{
334	struct usb_attach_arg *uaa = device_get_ivars(dev);
335	struct zyd_softc *sc = device_get_softc(dev);
336	struct ieee80211com *ic = &sc->sc_ic;
337	uint8_t iface_index, bands;
338	int error;
339
340	if (uaa->info.bcdDevice < 0x4330) {
341		device_printf(dev, "device version mismatch: 0x%X "
342		    "(only >= 43.30 supported)\n",
343		    uaa->info.bcdDevice);
344		return (EINVAL);
345	}
346
347	device_set_usb_desc(dev);
348	sc->sc_dev = dev;
349	sc->sc_udev = uaa->device;
350	sc->sc_macrev = USB_GET_DRIVER_INFO(uaa);
351
352	mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev),
353	    MTX_NETWORK_LOCK, MTX_DEF);
354	STAILQ_INIT(&sc->sc_rqh);
355	mbufq_init(&sc->sc_snd, ifqmaxlen);
356
357	iface_index = ZYD_IFACE_INDEX;
358	error = usbd_transfer_setup(uaa->device,
359	    &iface_index, sc->sc_xfer, zyd_config,
360	    ZYD_N_TRANSFER, sc, &sc->sc_mtx);
361	if (error) {
362		device_printf(dev, "could not allocate USB transfers, "
363		    "err=%s\n", usbd_errstr(error));
364		goto detach;
365	}
366
367	ZYD_LOCK(sc);
368	if ((error = zyd_get_macaddr(sc)) != 0) {
369		device_printf(sc->sc_dev, "could not read EEPROM\n");
370		ZYD_UNLOCK(sc);
371		goto detach;
372	}
373	ZYD_UNLOCK(sc);
374
375	ic->ic_softc = sc;
376	ic->ic_name = device_get_nameunit(dev);
377	ic->ic_phytype = IEEE80211_T_OFDM;	/* not only, but not used */
378	ic->ic_opmode = IEEE80211_M_STA;
379
380	/* set device capabilities */
381	ic->ic_caps =
382		  IEEE80211_C_STA		/* station mode */
383		| IEEE80211_C_MONITOR		/* monitor mode */
384		| IEEE80211_C_SHPREAMBLE	/* short preamble supported */
385	        | IEEE80211_C_SHSLOT		/* short slot time supported */
386		| IEEE80211_C_BGSCAN		/* capable of bg scanning */
387	        | IEEE80211_C_WPA		/* 802.11i */
388		;
389
390	bands = 0;
391	setbit(&bands, IEEE80211_MODE_11B);
392	setbit(&bands, IEEE80211_MODE_11G);
393	ieee80211_init_channels(ic, NULL, &bands);
394
395	ieee80211_ifattach(ic);
396	ic->ic_raw_xmit = zyd_raw_xmit;
397	ic->ic_scan_start = zyd_scan_start;
398	ic->ic_scan_end = zyd_scan_end;
399	ic->ic_set_channel = zyd_set_channel;
400	ic->ic_vap_create = zyd_vap_create;
401	ic->ic_vap_delete = zyd_vap_delete;
402	ic->ic_update_mcast = zyd_update_mcast;
403	ic->ic_update_promisc = zyd_update_mcast;
404	ic->ic_parent = zyd_parent;
405	ic->ic_transmit = zyd_transmit;
406
407	ieee80211_radiotap_attach(ic,
408	    &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
409		ZYD_TX_RADIOTAP_PRESENT,
410	    &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
411		ZYD_RX_RADIOTAP_PRESENT);
412
413	if (bootverbose)
414		ieee80211_announce(ic);
415
416	return (0);
417
418detach:
419	zyd_detach(dev);
420	return (ENXIO);			/* failure */
421}
422
423static int
424zyd_detach(device_t dev)
425{
426	struct zyd_softc *sc = device_get_softc(dev);
427	struct ieee80211com *ic = &sc->sc_ic;
428	unsigned int x;
429
430	/*
431	 * Prevent further allocations from RX/TX data
432	 * lists and ioctls:
433	 */
434	ZYD_LOCK(sc);
435	sc->sc_flags |= ZYD_FLAG_DETACHED;
436	STAILQ_INIT(&sc->tx_q);
437	STAILQ_INIT(&sc->tx_free);
438	ZYD_UNLOCK(sc);
439
440	/* drain USB transfers */
441	for (x = 0; x != ZYD_N_TRANSFER; x++)
442		usbd_transfer_drain(sc->sc_xfer[x]);
443
444	/* free TX list, if any */
445	ZYD_LOCK(sc);
446	zyd_unsetup_tx_list(sc);
447	ZYD_UNLOCK(sc);
448
449	/* free USB transfers and some data buffers */
450	usbd_transfer_unsetup(sc->sc_xfer, ZYD_N_TRANSFER);
451
452	if (ic->ic_softc == sc)
453		ieee80211_ifdetach(ic);
454	mbufq_drain(&sc->sc_snd);
455	mtx_destroy(&sc->sc_mtx);
456
457	return (0);
458}
459
460static struct ieee80211vap *
461zyd_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
462    enum ieee80211_opmode opmode, int flags,
463    const uint8_t bssid[IEEE80211_ADDR_LEN],
464    const uint8_t mac[IEEE80211_ADDR_LEN])
465{
466	struct zyd_vap *zvp;
467	struct ieee80211vap *vap;
468
469	if (!TAILQ_EMPTY(&ic->ic_vaps))		/* only one at a time */
470		return (NULL);
471	zvp = malloc(sizeof(struct zyd_vap), M_80211_VAP, M_WAITOK | M_ZERO);
472	vap = &zvp->vap;
473
474	/* enable s/w bmiss handling for sta mode */
475	if (ieee80211_vap_setup(ic, vap, name, unit, opmode,
476	    flags | IEEE80211_CLONE_NOBEACONS, bssid) != 0) {
477		/* out of memory */
478		free(zvp, M_80211_VAP);
479		return (NULL);
480	}
481
482	/* override state transition machine */
483	zvp->newstate = vap->iv_newstate;
484	vap->iv_newstate = zyd_newstate;
485
486	ieee80211_ratectl_init(vap);
487	ieee80211_ratectl_setinterval(vap, 1000 /* 1 sec */);
488
489	/* complete setup */
490	ieee80211_vap_attach(vap, ieee80211_media_change,
491	    ieee80211_media_status, mac);
492	ic->ic_opmode = opmode;
493	return (vap);
494}
495
496static void
497zyd_vap_delete(struct ieee80211vap *vap)
498{
499	struct zyd_vap *zvp = ZYD_VAP(vap);
500
501	ieee80211_ratectl_deinit(vap);
502	ieee80211_vap_detach(vap);
503	free(zvp, M_80211_VAP);
504}
505
506static void
507zyd_tx_free(struct zyd_tx_data *data, int txerr)
508{
509	struct zyd_softc *sc = data->sc;
510
511	if (data->m != NULL) {
512		ieee80211_tx_complete(data->ni, data->m, txerr);
513		data->m = NULL;
514		data->ni = NULL;
515	}
516	STAILQ_INSERT_TAIL(&sc->tx_free, data, next);
517	sc->tx_nfree++;
518}
519
520static void
521zyd_setup_tx_list(struct zyd_softc *sc)
522{
523	struct zyd_tx_data *data;
524	int i;
525
526	sc->tx_nfree = 0;
527	STAILQ_INIT(&sc->tx_q);
528	STAILQ_INIT(&sc->tx_free);
529
530	for (i = 0; i < ZYD_TX_LIST_CNT; i++) {
531		data = &sc->tx_data[i];
532
533		data->sc = sc;
534		STAILQ_INSERT_TAIL(&sc->tx_free, data, next);
535		sc->tx_nfree++;
536	}
537}
538
539static void
540zyd_unsetup_tx_list(struct zyd_softc *sc)
541{
542	struct zyd_tx_data *data;
543	int i;
544
545	/* make sure any subsequent use of the queues will fail */
546	sc->tx_nfree = 0;
547	STAILQ_INIT(&sc->tx_q);
548	STAILQ_INIT(&sc->tx_free);
549
550	/* free up all node references and mbufs */
551	for (i = 0; i < ZYD_TX_LIST_CNT; i++) {
552		data = &sc->tx_data[i];
553
554		if (data->m != NULL) {
555			m_freem(data->m);
556			data->m = NULL;
557		}
558		if (data->ni != NULL) {
559			ieee80211_free_node(data->ni);
560			data->ni = NULL;
561		}
562	}
563}
564
565static int
566zyd_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
567{
568	struct zyd_vap *zvp = ZYD_VAP(vap);
569	struct ieee80211com *ic = vap->iv_ic;
570	struct zyd_softc *sc = ic->ic_softc;
571	int error;
572
573	DPRINTF(sc, ZYD_DEBUG_STATE, "%s: %s -> %s\n", __func__,
574	    ieee80211_state_name[vap->iv_state],
575	    ieee80211_state_name[nstate]);
576
577	IEEE80211_UNLOCK(ic);
578	ZYD_LOCK(sc);
579	switch (nstate) {
580	case IEEE80211_S_AUTH:
581		zyd_set_chan(sc, ic->ic_curchan);
582		break;
583	case IEEE80211_S_RUN:
584		if (vap->iv_opmode == IEEE80211_M_MONITOR)
585			break;
586
587		/* turn link LED on */
588		error = zyd_set_led(sc, ZYD_LED1, 1);
589		if (error != 0)
590			break;
591
592		/* make data LED blink upon Tx */
593		zyd_write32_m(sc, sc->sc_fwbase + ZYD_FW_LINK_STATUS, 1);
594
595		IEEE80211_ADDR_COPY(ic->ic_macaddr, vap->iv_bss->ni_bssid);
596		zyd_set_bssid(sc, ic->ic_macaddr);
597		break;
598	default:
599		break;
600	}
601fail:
602	ZYD_UNLOCK(sc);
603	IEEE80211_LOCK(ic);
604	return (zvp->newstate(vap, nstate, arg));
605}
606
607/*
608 * Callback handler for interrupt transfer
609 */
610static void
611zyd_intr_read_callback(struct usb_xfer *xfer, usb_error_t error)
612{
613	struct zyd_softc *sc = usbd_xfer_softc(xfer);
614	struct ieee80211com *ic = &sc->sc_ic;
615	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
616	struct ieee80211_node *ni;
617	struct zyd_cmd *cmd = &sc->sc_ibuf;
618	struct usb_page_cache *pc;
619	int datalen;
620	int actlen;
621
622	usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
623
624	switch (USB_GET_STATE(xfer)) {
625	case USB_ST_TRANSFERRED:
626		pc = usbd_xfer_get_frame(xfer, 0);
627		usbd_copy_out(pc, 0, cmd, sizeof(*cmd));
628
629		switch (le16toh(cmd->code)) {
630		case ZYD_NOTIF_RETRYSTATUS:
631		{
632			struct zyd_notif_retry *retry =
633			    (struct zyd_notif_retry *)cmd->data;
634
635			DPRINTF(sc, ZYD_DEBUG_TX_PROC,
636			    "retry intr: rate=0x%x addr=%s count=%d (0x%x)\n",
637			    le16toh(retry->rate), ether_sprintf(retry->macaddr),
638			    le16toh(retry->count)&0xff, le16toh(retry->count));
639
640			/*
641			 * Find the node to which the packet was sent and
642			 * update its retry statistics.  In BSS mode, this node
643			 * is the AP we're associated to so no lookup is
644			 * actually needed.
645			 */
646			ni = ieee80211_find_txnode(vap, retry->macaddr);
647			if (ni != NULL) {
648				int retrycnt =
649				    (int)(le16toh(retry->count) & 0xff);
650
651				ieee80211_ratectl_tx_complete(vap, ni,
652				    IEEE80211_RATECTL_TX_FAILURE,
653				    &retrycnt, NULL);
654				ieee80211_free_node(ni);
655			}
656			if (le16toh(retry->count) & 0x100)
657				/* too many retries */
658				if_inc_counter(vap->iv_ifp, IFCOUNTER_OERRORS,
659				    1);
660			break;
661		}
662		case ZYD_NOTIF_IORD:
663		{
664			struct zyd_rq *rqp;
665
666			if (le16toh(*(uint16_t *)cmd->data) == ZYD_CR_INTERRUPT)
667				break;	/* HMAC interrupt */
668
669			datalen = actlen - sizeof(cmd->code);
670			datalen -= 2;	/* XXX: padding? */
671
672			STAILQ_FOREACH(rqp, &sc->sc_rqh, rq) {
673				int i;
674				int count;
675
676				if (rqp->olen != datalen)
677					continue;
678				count = rqp->olen / sizeof(struct zyd_pair);
679				for (i = 0; i < count; i++) {
680					if (*(((const uint16_t *)rqp->idata) + i) !=
681					    (((struct zyd_pair *)cmd->data) + i)->reg)
682						break;
683				}
684				if (i != count)
685					continue;
686				/* copy answer into caller-supplied buffer */
687				memcpy(rqp->odata, cmd->data, rqp->olen);
688				DPRINTF(sc, ZYD_DEBUG_CMD,
689				    "command %p complete, data = %*D \n",
690				    rqp, rqp->olen, (char *)rqp->odata, ":");
691				wakeup(rqp);	/* wakeup caller */
692				break;
693			}
694			if (rqp == NULL) {
695				device_printf(sc->sc_dev,
696				    "unexpected IORD notification %*D\n",
697				    datalen, cmd->data, ":");
698			}
699			break;
700		}
701		default:
702			device_printf(sc->sc_dev, "unknown notification %x\n",
703			    le16toh(cmd->code));
704		}
705
706		/* FALLTHROUGH */
707	case USB_ST_SETUP:
708tr_setup:
709		usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
710		usbd_transfer_submit(xfer);
711		break;
712
713	default:			/* Error */
714		DPRINTF(sc, ZYD_DEBUG_CMD, "error = %s\n",
715		    usbd_errstr(error));
716
717		if (error != USB_ERR_CANCELLED) {
718			/* try to clear stall first */
719			usbd_xfer_set_stall(xfer);
720			goto tr_setup;
721		}
722		break;
723	}
724}
725
726static void
727zyd_intr_write_callback(struct usb_xfer *xfer, usb_error_t error)
728{
729	struct zyd_softc *sc = usbd_xfer_softc(xfer);
730	struct zyd_rq *rqp, *cmd;
731	struct usb_page_cache *pc;
732
733	switch (USB_GET_STATE(xfer)) {
734	case USB_ST_TRANSFERRED:
735		cmd = usbd_xfer_get_priv(xfer);
736		DPRINTF(sc, ZYD_DEBUG_CMD, "command %p transferred\n", cmd);
737		STAILQ_FOREACH(rqp, &sc->sc_rqh, rq) {
738			/* Ensure the cached rq pointer is still valid */
739			if (rqp == cmd &&
740			    (rqp->flags & ZYD_CMD_FLAG_READ) == 0)
741				wakeup(rqp);	/* wakeup caller */
742		}
743
744		/* FALLTHROUGH */
745	case USB_ST_SETUP:
746tr_setup:
747		STAILQ_FOREACH(rqp, &sc->sc_rqh, rq) {
748			if (rqp->flags & ZYD_CMD_FLAG_SENT)
749				continue;
750
751			pc = usbd_xfer_get_frame(xfer, 0);
752			usbd_copy_in(pc, 0, rqp->cmd, rqp->ilen);
753
754			usbd_xfer_set_frame_len(xfer, 0, rqp->ilen);
755			usbd_xfer_set_priv(xfer, rqp);
756			rqp->flags |= ZYD_CMD_FLAG_SENT;
757			usbd_transfer_submit(xfer);
758			break;
759		}
760		break;
761
762	default:			/* Error */
763		DPRINTF(sc, ZYD_DEBUG_ANY, "error = %s\n",
764		    usbd_errstr(error));
765
766		if (error != USB_ERR_CANCELLED) {
767			/* try to clear stall first */
768			usbd_xfer_set_stall(xfer);
769			goto tr_setup;
770		}
771		break;
772	}
773}
774
775static int
776zyd_cmd(struct zyd_softc *sc, uint16_t code, const void *idata, int ilen,
777    void *odata, int olen, int flags)
778{
779	struct zyd_cmd cmd;
780	struct zyd_rq rq;
781	int error;
782
783	if (ilen > (int)sizeof(cmd.data))
784		return (EINVAL);
785
786	cmd.code = htole16(code);
787	memcpy(cmd.data, idata, ilen);
788	DPRINTF(sc, ZYD_DEBUG_CMD, "sending cmd %p = %*D\n",
789	    &rq, ilen, idata, ":");
790
791	rq.cmd = &cmd;
792	rq.idata = idata;
793	rq.odata = odata;
794	rq.ilen = sizeof(uint16_t) + ilen;
795	rq.olen = olen;
796	rq.flags = flags;
797	STAILQ_INSERT_TAIL(&sc->sc_rqh, &rq, rq);
798	usbd_transfer_start(sc->sc_xfer[ZYD_INTR_RD]);
799	usbd_transfer_start(sc->sc_xfer[ZYD_INTR_WR]);
800
801	/* wait at most one second for command reply */
802	error = mtx_sleep(&rq, &sc->sc_mtx, 0 , "zydcmd", hz);
803	if (error)
804		device_printf(sc->sc_dev, "command timeout\n");
805	STAILQ_REMOVE(&sc->sc_rqh, &rq, zyd_rq, rq);
806	DPRINTF(sc, ZYD_DEBUG_CMD, "finsihed cmd %p, error = %d \n",
807	    &rq, error);
808
809	return (error);
810}
811
812static int
813zyd_read16(struct zyd_softc *sc, uint16_t reg, uint16_t *val)
814{
815	struct zyd_pair tmp;
816	int error;
817
818	reg = htole16(reg);
819	error = zyd_cmd(sc, ZYD_CMD_IORD, &reg, sizeof(reg), &tmp, sizeof(tmp),
820	    ZYD_CMD_FLAG_READ);
821	if (error == 0)
822		*val = le16toh(tmp.val);
823	return (error);
824}
825
826static int
827zyd_read32(struct zyd_softc *sc, uint16_t reg, uint32_t *val)
828{
829	struct zyd_pair tmp[2];
830	uint16_t regs[2];
831	int error;
832
833	regs[0] = htole16(ZYD_REG32_HI(reg));
834	regs[1] = htole16(ZYD_REG32_LO(reg));
835	error = zyd_cmd(sc, ZYD_CMD_IORD, regs, sizeof(regs), tmp, sizeof(tmp),
836	    ZYD_CMD_FLAG_READ);
837	if (error == 0)
838		*val = le16toh(tmp[0].val) << 16 | le16toh(tmp[1].val);
839	return (error);
840}
841
842static int
843zyd_write16(struct zyd_softc *sc, uint16_t reg, uint16_t val)
844{
845	struct zyd_pair pair;
846
847	pair.reg = htole16(reg);
848	pair.val = htole16(val);
849
850	return zyd_cmd(sc, ZYD_CMD_IOWR, &pair, sizeof(pair), NULL, 0, 0);
851}
852
853static int
854zyd_write32(struct zyd_softc *sc, uint16_t reg, uint32_t val)
855{
856	struct zyd_pair pair[2];
857
858	pair[0].reg = htole16(ZYD_REG32_HI(reg));
859	pair[0].val = htole16(val >> 16);
860	pair[1].reg = htole16(ZYD_REG32_LO(reg));
861	pair[1].val = htole16(val & 0xffff);
862
863	return zyd_cmd(sc, ZYD_CMD_IOWR, pair, sizeof(pair), NULL, 0, 0);
864}
865
866static int
867zyd_rfwrite(struct zyd_softc *sc, uint32_t val)
868{
869	struct zyd_rf *rf = &sc->sc_rf;
870	struct zyd_rfwrite_cmd req;
871	uint16_t cr203;
872	int error, i;
873
874	zyd_read16_m(sc, ZYD_CR203, &cr203);
875	cr203 &= ~(ZYD_RF_IF_LE | ZYD_RF_CLK | ZYD_RF_DATA);
876
877	req.code  = htole16(2);
878	req.width = htole16(rf->width);
879	for (i = 0; i < rf->width; i++) {
880		req.bit[i] = htole16(cr203);
881		if (val & (1 << (rf->width - 1 - i)))
882			req.bit[i] |= htole16(ZYD_RF_DATA);
883	}
884	error = zyd_cmd(sc, ZYD_CMD_RFCFG, &req, 4 + 2 * rf->width, NULL, 0, 0);
885fail:
886	return (error);
887}
888
889static int
890zyd_rfwrite_cr(struct zyd_softc *sc, uint32_t val)
891{
892	int error;
893
894	zyd_write16_m(sc, ZYD_CR244, (val >> 16) & 0xff);
895	zyd_write16_m(sc, ZYD_CR243, (val >>  8) & 0xff);
896	zyd_write16_m(sc, ZYD_CR242, (val >>  0) & 0xff);
897fail:
898	return (error);
899}
900
901static int
902zyd_lock_phy(struct zyd_softc *sc)
903{
904	int error;
905	uint32_t tmp;
906
907	zyd_read32_m(sc, ZYD_MAC_MISC, &tmp);
908	tmp &= ~ZYD_UNLOCK_PHY_REGS;
909	zyd_write32_m(sc, ZYD_MAC_MISC, tmp);
910fail:
911	return (error);
912}
913
914static int
915zyd_unlock_phy(struct zyd_softc *sc)
916{
917	int error;
918	uint32_t tmp;
919
920	zyd_read32_m(sc, ZYD_MAC_MISC, &tmp);
921	tmp |= ZYD_UNLOCK_PHY_REGS;
922	zyd_write32_m(sc, ZYD_MAC_MISC, tmp);
923fail:
924	return (error);
925}
926
927/*
928 * RFMD RF methods.
929 */
930static int
931zyd_rfmd_init(struct zyd_rf *rf)
932{
933#define N(a)	((int)(sizeof(a) / sizeof((a)[0])))
934	struct zyd_softc *sc = rf->rf_sc;
935	static const struct zyd_phy_pair phyini[] = ZYD_RFMD_PHY;
936	static const uint32_t rfini[] = ZYD_RFMD_RF;
937	int i, error;
938
939	/* init RF-dependent PHY registers */
940	for (i = 0; i < N(phyini); i++) {
941		zyd_write16_m(sc, phyini[i].reg, phyini[i].val);
942	}
943
944	/* init RFMD radio */
945	for (i = 0; i < N(rfini); i++) {
946		if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
947			return (error);
948	}
949fail:
950	return (error);
951#undef N
952}
953
954static int
955zyd_rfmd_switch_radio(struct zyd_rf *rf, int on)
956{
957	int error;
958	struct zyd_softc *sc = rf->rf_sc;
959
960	zyd_write16_m(sc, ZYD_CR10, on ? 0x89 : 0x15);
961	zyd_write16_m(sc, ZYD_CR11, on ? 0x00 : 0x81);
962fail:
963	return (error);
964}
965
966static int
967zyd_rfmd_set_channel(struct zyd_rf *rf, uint8_t chan)
968{
969	int error;
970	struct zyd_softc *sc = rf->rf_sc;
971	static const struct {
972		uint32_t	r1, r2;
973	} rfprog[] = ZYD_RFMD_CHANTABLE;
974
975	error = zyd_rfwrite(sc, rfprog[chan - 1].r1);
976	if (error != 0)
977		goto fail;
978	error = zyd_rfwrite(sc, rfprog[chan - 1].r2);
979	if (error != 0)
980		goto fail;
981
982fail:
983	return (error);
984}
985
986/*
987 * AL2230 RF methods.
988 */
989static int
990zyd_al2230_init(struct zyd_rf *rf)
991{
992#define N(a)	((int)(sizeof(a) / sizeof((a)[0])))
993	struct zyd_softc *sc = rf->rf_sc;
994	static const struct zyd_phy_pair phyini[] = ZYD_AL2230_PHY;
995	static const struct zyd_phy_pair phy2230s[] = ZYD_AL2230S_PHY_INIT;
996	static const struct zyd_phy_pair phypll[] = {
997		{ ZYD_CR251, 0x2f }, { ZYD_CR251, 0x3f },
998		{ ZYD_CR138, 0x28 }, { ZYD_CR203, 0x06 }
999	};
1000	static const uint32_t rfini1[] = ZYD_AL2230_RF_PART1;
1001	static const uint32_t rfini2[] = ZYD_AL2230_RF_PART2;
1002	static const uint32_t rfini3[] = ZYD_AL2230_RF_PART3;
1003	int i, error;
1004
1005	/* init RF-dependent PHY registers */
1006	for (i = 0; i < N(phyini); i++)
1007		zyd_write16_m(sc, phyini[i].reg, phyini[i].val);
1008
1009	if (sc->sc_rfrev == ZYD_RF_AL2230S || sc->sc_al2230s != 0) {
1010		for (i = 0; i < N(phy2230s); i++)
1011			zyd_write16_m(sc, phy2230s[i].reg, phy2230s[i].val);
1012	}
1013
1014	/* init AL2230 radio */
1015	for (i = 0; i < N(rfini1); i++) {
1016		error = zyd_rfwrite(sc, rfini1[i]);
1017		if (error != 0)
1018			goto fail;
1019	}
1020
1021	if (sc->sc_rfrev == ZYD_RF_AL2230S || sc->sc_al2230s != 0)
1022		error = zyd_rfwrite(sc, 0x000824);
1023	else
1024		error = zyd_rfwrite(sc, 0x0005a4);
1025	if (error != 0)
1026		goto fail;
1027
1028	for (i = 0; i < N(rfini2); i++) {
1029		error = zyd_rfwrite(sc, rfini2[i]);
1030		if (error != 0)
1031			goto fail;
1032	}
1033
1034	for (i = 0; i < N(phypll); i++)
1035		zyd_write16_m(sc, phypll[i].reg, phypll[i].val);
1036
1037	for (i = 0; i < N(rfini3); i++) {
1038		error = zyd_rfwrite(sc, rfini3[i]);
1039		if (error != 0)
1040			goto fail;
1041	}
1042fail:
1043	return (error);
1044#undef N
1045}
1046
1047static int
1048zyd_al2230_fini(struct zyd_rf *rf)
1049{
1050#define N(a)	((int)(sizeof(a) / sizeof((a)[0])))
1051	int error, i;
1052	struct zyd_softc *sc = rf->rf_sc;
1053	static const struct zyd_phy_pair phy[] = ZYD_AL2230_PHY_FINI_PART1;
1054
1055	for (i = 0; i < N(phy); i++)
1056		zyd_write16_m(sc, phy[i].reg, phy[i].val);
1057
1058	if (sc->sc_newphy != 0)
1059		zyd_write16_m(sc, ZYD_CR9, 0xe1);
1060
1061	zyd_write16_m(sc, ZYD_CR203, 0x6);
1062fail:
1063	return (error);
1064#undef N
1065}
1066
1067static int
1068zyd_al2230_init_b(struct zyd_rf *rf)
1069{
1070#define N(a)	((int)(sizeof(a) / sizeof((a)[0])))
1071	struct zyd_softc *sc = rf->rf_sc;
1072	static const struct zyd_phy_pair phy1[] = ZYD_AL2230_PHY_PART1;
1073	static const struct zyd_phy_pair phy2[] = ZYD_AL2230_PHY_PART2;
1074	static const struct zyd_phy_pair phy3[] = ZYD_AL2230_PHY_PART3;
1075	static const struct zyd_phy_pair phy2230s[] = ZYD_AL2230S_PHY_INIT;
1076	static const struct zyd_phy_pair phyini[] = ZYD_AL2230_PHY_B;
1077	static const uint32_t rfini_part1[] = ZYD_AL2230_RF_B_PART1;
1078	static const uint32_t rfini_part2[] = ZYD_AL2230_RF_B_PART2;
1079	static const uint32_t rfini_part3[] = ZYD_AL2230_RF_B_PART3;
1080	static const uint32_t zyd_al2230_chtable[][3] = ZYD_AL2230_CHANTABLE;
1081	int i, error;
1082
1083	for (i = 0; i < N(phy1); i++)
1084		zyd_write16_m(sc, phy1[i].reg, phy1[i].val);
1085
1086	/* init RF-dependent PHY registers */
1087	for (i = 0; i < N(phyini); i++)
1088		zyd_write16_m(sc, phyini[i].reg, phyini[i].val);
1089
1090	if (sc->sc_rfrev == ZYD_RF_AL2230S || sc->sc_al2230s != 0) {
1091		for (i = 0; i < N(phy2230s); i++)
1092			zyd_write16_m(sc, phy2230s[i].reg, phy2230s[i].val);
1093	}
1094
1095	for (i = 0; i < 3; i++) {
1096		error = zyd_rfwrite_cr(sc, zyd_al2230_chtable[0][i]);
1097		if (error != 0)
1098			return (error);
1099	}
1100
1101	for (i = 0; i < N(rfini_part1); i++) {
1102		error = zyd_rfwrite_cr(sc, rfini_part1[i]);
1103		if (error != 0)
1104			return (error);
1105	}
1106
1107	if (sc->sc_rfrev == ZYD_RF_AL2230S || sc->sc_al2230s != 0)
1108		error = zyd_rfwrite(sc, 0x241000);
1109	else
1110		error = zyd_rfwrite(sc, 0x25a000);
1111	if (error != 0)
1112		goto fail;
1113
1114	for (i = 0; i < N(rfini_part2); i++) {
1115		error = zyd_rfwrite_cr(sc, rfini_part2[i]);
1116		if (error != 0)
1117			return (error);
1118	}
1119
1120	for (i = 0; i < N(phy2); i++)
1121		zyd_write16_m(sc, phy2[i].reg, phy2[i].val);
1122
1123	for (i = 0; i < N(rfini_part3); i++) {
1124		error = zyd_rfwrite_cr(sc, rfini_part3[i]);
1125		if (error != 0)
1126			return (error);
1127	}
1128
1129	for (i = 0; i < N(phy3); i++)
1130		zyd_write16_m(sc, phy3[i].reg, phy3[i].val);
1131
1132	error = zyd_al2230_fini(rf);
1133fail:
1134	return (error);
1135#undef N
1136}
1137
1138static int
1139zyd_al2230_switch_radio(struct zyd_rf *rf, int on)
1140{
1141	struct zyd_softc *sc = rf->rf_sc;
1142	int error, on251 = (sc->sc_macrev == ZYD_ZD1211) ? 0x3f : 0x7f;
1143
1144	zyd_write16_m(sc, ZYD_CR11,  on ? 0x00 : 0x04);
1145	zyd_write16_m(sc, ZYD_CR251, on ? on251 : 0x2f);
1146fail:
1147	return (error);
1148}
1149
1150static int
1151zyd_al2230_set_channel(struct zyd_rf *rf, uint8_t chan)
1152{
1153#define N(a)	((int)(sizeof(a) / sizeof((a)[0])))
1154	int error, i;
1155	struct zyd_softc *sc = rf->rf_sc;
1156	static const struct zyd_phy_pair phy1[] = {
1157		{ ZYD_CR138, 0x28 }, { ZYD_CR203, 0x06 },
1158	};
1159	static const struct {
1160		uint32_t	r1, r2, r3;
1161	} rfprog[] = ZYD_AL2230_CHANTABLE;
1162
1163	error = zyd_rfwrite(sc, rfprog[chan - 1].r1);
1164	if (error != 0)
1165		goto fail;
1166	error = zyd_rfwrite(sc, rfprog[chan - 1].r2);
1167	if (error != 0)
1168		goto fail;
1169	error = zyd_rfwrite(sc, rfprog[chan - 1].r3);
1170	if (error != 0)
1171		goto fail;
1172
1173	for (i = 0; i < N(phy1); i++)
1174		zyd_write16_m(sc, phy1[i].reg, phy1[i].val);
1175fail:
1176	return (error);
1177#undef N
1178}
1179
1180static int
1181zyd_al2230_set_channel_b(struct zyd_rf *rf, uint8_t chan)
1182{
1183#define N(a)	((int)(sizeof(a) / sizeof((a)[0])))
1184	int error, i;
1185	struct zyd_softc *sc = rf->rf_sc;
1186	static const struct zyd_phy_pair phy1[] = ZYD_AL2230_PHY_PART1;
1187	static const struct {
1188		uint32_t	r1, r2, r3;
1189	} rfprog[] = ZYD_AL2230_CHANTABLE_B;
1190
1191	for (i = 0; i < N(phy1); i++)
1192		zyd_write16_m(sc, phy1[i].reg, phy1[i].val);
1193
1194	error = zyd_rfwrite_cr(sc, rfprog[chan - 1].r1);
1195	if (error != 0)
1196		goto fail;
1197	error = zyd_rfwrite_cr(sc, rfprog[chan - 1].r2);
1198	if (error != 0)
1199		goto fail;
1200	error = zyd_rfwrite_cr(sc, rfprog[chan - 1].r3);
1201	if (error != 0)
1202		goto fail;
1203	error = zyd_al2230_fini(rf);
1204fail:
1205	return (error);
1206#undef N
1207}
1208
1209#define	ZYD_AL2230_PHY_BANDEDGE6					\
1210{									\
1211	{ ZYD_CR128, 0x14 }, { ZYD_CR129, 0x12 }, { ZYD_CR130, 0x10 },	\
1212	{ ZYD_CR47,  0x1e }						\
1213}
1214
1215static int
1216zyd_al2230_bandedge6(struct zyd_rf *rf, struct ieee80211_channel *c)
1217{
1218#define N(a)	((int)(sizeof(a) / sizeof((a)[0])))
1219	int error = 0, i;
1220	struct zyd_softc *sc = rf->rf_sc;
1221	struct ieee80211com *ic = &sc->sc_ic;
1222	struct zyd_phy_pair r[] = ZYD_AL2230_PHY_BANDEDGE6;
1223	int chan = ieee80211_chan2ieee(ic, c);
1224
1225	if (chan == 1 || chan == 11)
1226		r[0].val = 0x12;
1227
1228	for (i = 0; i < N(r); i++)
1229		zyd_write16_m(sc, r[i].reg, r[i].val);
1230fail:
1231	return (error);
1232#undef N
1233}
1234
1235/*
1236 * AL7230B RF methods.
1237 */
1238static int
1239zyd_al7230B_init(struct zyd_rf *rf)
1240{
1241#define N(a)	((int)(sizeof(a) / sizeof((a)[0])))
1242	struct zyd_softc *sc = rf->rf_sc;
1243	static const struct zyd_phy_pair phyini_1[] = ZYD_AL7230B_PHY_1;
1244	static const struct zyd_phy_pair phyini_2[] = ZYD_AL7230B_PHY_2;
1245	static const struct zyd_phy_pair phyini_3[] = ZYD_AL7230B_PHY_3;
1246	static const uint32_t rfini_1[] = ZYD_AL7230B_RF_1;
1247	static const uint32_t rfini_2[] = ZYD_AL7230B_RF_2;
1248	int i, error;
1249
1250	/* for AL7230B, PHY and RF need to be initialized in "phases" */
1251
1252	/* init RF-dependent PHY registers, part one */
1253	for (i = 0; i < N(phyini_1); i++)
1254		zyd_write16_m(sc, phyini_1[i].reg, phyini_1[i].val);
1255
1256	/* init AL7230B radio, part one */
1257	for (i = 0; i < N(rfini_1); i++) {
1258		if ((error = zyd_rfwrite(sc, rfini_1[i])) != 0)
1259			return (error);
1260	}
1261	/* init RF-dependent PHY registers, part two */
1262	for (i = 0; i < N(phyini_2); i++)
1263		zyd_write16_m(sc, phyini_2[i].reg, phyini_2[i].val);
1264
1265	/* init AL7230B radio, part two */
1266	for (i = 0; i < N(rfini_2); i++) {
1267		if ((error = zyd_rfwrite(sc, rfini_2[i])) != 0)
1268			return (error);
1269	}
1270	/* init RF-dependent PHY registers, part three */
1271	for (i = 0; i < N(phyini_3); i++)
1272		zyd_write16_m(sc, phyini_3[i].reg, phyini_3[i].val);
1273fail:
1274	return (error);
1275#undef N
1276}
1277
1278static int
1279zyd_al7230B_switch_radio(struct zyd_rf *rf, int on)
1280{
1281	int error;
1282	struct zyd_softc *sc = rf->rf_sc;
1283
1284	zyd_write16_m(sc, ZYD_CR11,  on ? 0x00 : 0x04);
1285	zyd_write16_m(sc, ZYD_CR251, on ? 0x3f : 0x2f);
1286fail:
1287	return (error);
1288}
1289
1290static int
1291zyd_al7230B_set_channel(struct zyd_rf *rf, uint8_t chan)
1292{
1293#define N(a)	((int)(sizeof(a) / sizeof((a)[0])))
1294	struct zyd_softc *sc = rf->rf_sc;
1295	static const struct {
1296		uint32_t	r1, r2;
1297	} rfprog[] = ZYD_AL7230B_CHANTABLE;
1298	static const uint32_t rfsc[] = ZYD_AL7230B_RF_SETCHANNEL;
1299	int i, error;
1300
1301	zyd_write16_m(sc, ZYD_CR240, 0x57);
1302	zyd_write16_m(sc, ZYD_CR251, 0x2f);
1303
1304	for (i = 0; i < N(rfsc); i++) {
1305		if ((error = zyd_rfwrite(sc, rfsc[i])) != 0)
1306			return (error);
1307	}
1308
1309	zyd_write16_m(sc, ZYD_CR128, 0x14);
1310	zyd_write16_m(sc, ZYD_CR129, 0x12);
1311	zyd_write16_m(sc, ZYD_CR130, 0x10);
1312	zyd_write16_m(sc, ZYD_CR38,  0x38);
1313	zyd_write16_m(sc, ZYD_CR136, 0xdf);
1314
1315	error = zyd_rfwrite(sc, rfprog[chan - 1].r1);
1316	if (error != 0)
1317		goto fail;
1318	error = zyd_rfwrite(sc, rfprog[chan - 1].r2);
1319	if (error != 0)
1320		goto fail;
1321	error = zyd_rfwrite(sc, 0x3c9000);
1322	if (error != 0)
1323		goto fail;
1324
1325	zyd_write16_m(sc, ZYD_CR251, 0x3f);
1326	zyd_write16_m(sc, ZYD_CR203, 0x06);
1327	zyd_write16_m(sc, ZYD_CR240, 0x08);
1328fail:
1329	return (error);
1330#undef N
1331}
1332
1333/*
1334 * AL2210 RF methods.
1335 */
1336static int
1337zyd_al2210_init(struct zyd_rf *rf)
1338{
1339#define N(a)	((int)(sizeof(a) / sizeof((a)[0])))
1340	struct zyd_softc *sc = rf->rf_sc;
1341	static const struct zyd_phy_pair phyini[] = ZYD_AL2210_PHY;
1342	static const uint32_t rfini[] = ZYD_AL2210_RF;
1343	uint32_t tmp;
1344	int i, error;
1345
1346	zyd_write32_m(sc, ZYD_CR18, 2);
1347
1348	/* init RF-dependent PHY registers */
1349	for (i = 0; i < N(phyini); i++)
1350		zyd_write16_m(sc, phyini[i].reg, phyini[i].val);
1351
1352	/* init AL2210 radio */
1353	for (i = 0; i < N(rfini); i++) {
1354		if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
1355			return (error);
1356	}
1357	zyd_write16_m(sc, ZYD_CR47, 0x1e);
1358	zyd_read32_m(sc, ZYD_CR_RADIO_PD, &tmp);
1359	zyd_write32_m(sc, ZYD_CR_RADIO_PD, tmp & ~1);
1360	zyd_write32_m(sc, ZYD_CR_RADIO_PD, tmp | 1);
1361	zyd_write32_m(sc, ZYD_CR_RFCFG, 0x05);
1362	zyd_write32_m(sc, ZYD_CR_RFCFG, 0x00);
1363	zyd_write16_m(sc, ZYD_CR47, 0x1e);
1364	zyd_write32_m(sc, ZYD_CR18, 3);
1365fail:
1366	return (error);
1367#undef N
1368}
1369
1370static int
1371zyd_al2210_switch_radio(struct zyd_rf *rf, int on)
1372{
1373	/* vendor driver does nothing for this RF chip */
1374
1375	return (0);
1376}
1377
1378static int
1379zyd_al2210_set_channel(struct zyd_rf *rf, uint8_t chan)
1380{
1381	int error;
1382	struct zyd_softc *sc = rf->rf_sc;
1383	static const uint32_t rfprog[] = ZYD_AL2210_CHANTABLE;
1384	uint32_t tmp;
1385
1386	zyd_write32_m(sc, ZYD_CR18, 2);
1387	zyd_write16_m(sc, ZYD_CR47, 0x1e);
1388	zyd_read32_m(sc, ZYD_CR_RADIO_PD, &tmp);
1389	zyd_write32_m(sc, ZYD_CR_RADIO_PD, tmp & ~1);
1390	zyd_write32_m(sc, ZYD_CR_RADIO_PD, tmp | 1);
1391	zyd_write32_m(sc, ZYD_CR_RFCFG, 0x05);
1392	zyd_write32_m(sc, ZYD_CR_RFCFG, 0x00);
1393	zyd_write16_m(sc, ZYD_CR47, 0x1e);
1394
1395	/* actually set the channel */
1396	error = zyd_rfwrite(sc, rfprog[chan - 1]);
1397	if (error != 0)
1398		goto fail;
1399
1400	zyd_write32_m(sc, ZYD_CR18, 3);
1401fail:
1402	return (error);
1403}
1404
1405/*
1406 * GCT RF methods.
1407 */
1408static int
1409zyd_gct_init(struct zyd_rf *rf)
1410{
1411#define	ZYD_GCT_INTR_REG	0x85c1
1412#define N(a)	((int)(sizeof(a) / sizeof((a)[0])))
1413	struct zyd_softc *sc = rf->rf_sc;
1414	static const struct zyd_phy_pair phyini[] = ZYD_GCT_PHY;
1415	static const uint32_t rfini[] = ZYD_GCT_RF;
1416	static const uint16_t vco[11][7] = ZYD_GCT_VCO;
1417	int i, idx = -1, error;
1418	uint16_t data;
1419
1420	/* init RF-dependent PHY registers */
1421	for (i = 0; i < N(phyini); i++)
1422		zyd_write16_m(sc, phyini[i].reg, phyini[i].val);
1423
1424	/* init cgt radio */
1425	for (i = 0; i < N(rfini); i++) {
1426		if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
1427			return (error);
1428	}
1429
1430	error = zyd_gct_mode(rf);
1431	if (error != 0)
1432		return (error);
1433
1434	for (i = 0; i < (int)(N(vco) - 1); i++) {
1435		error = zyd_gct_set_channel_synth(rf, 1, 0);
1436		if (error != 0)
1437			goto fail;
1438		error = zyd_gct_write(rf, vco[i][0]);
1439		if (error != 0)
1440			goto fail;
1441		zyd_write16_m(sc, ZYD_GCT_INTR_REG, 0xf);
1442		zyd_read16_m(sc, ZYD_GCT_INTR_REG, &data);
1443		if ((data & 0xf) == 0) {
1444			idx = i;
1445			break;
1446		}
1447	}
1448	if (idx == -1) {
1449		error = zyd_gct_set_channel_synth(rf, 1, 1);
1450		if (error != 0)
1451			goto fail;
1452		error = zyd_gct_write(rf, 0x6662);
1453		if (error != 0)
1454			goto fail;
1455	}
1456
1457	rf->idx = idx;
1458	zyd_write16_m(sc, ZYD_CR203, 0x6);
1459fail:
1460	return (error);
1461#undef N
1462#undef ZYD_GCT_INTR_REG
1463}
1464
1465static int
1466zyd_gct_mode(struct zyd_rf *rf)
1467{
1468#define N(a)	((int)(sizeof(a) / sizeof((a)[0])))
1469	struct zyd_softc *sc = rf->rf_sc;
1470	static const uint32_t mode[] = {
1471		0x25f98, 0x25f9a, 0x25f94, 0x27fd4
1472	};
1473	int i, error;
1474
1475	for (i = 0; i < N(mode); i++) {
1476		if ((error = zyd_rfwrite(sc, mode[i])) != 0)
1477			break;
1478	}
1479	return (error);
1480#undef N
1481}
1482
1483static int
1484zyd_gct_set_channel_synth(struct zyd_rf *rf, int chan, int acal)
1485{
1486	int error, idx = chan - 1;
1487	struct zyd_softc *sc = rf->rf_sc;
1488	static uint32_t acal_synth[] = ZYD_GCT_CHANNEL_ACAL;
1489	static uint32_t std_synth[] = ZYD_GCT_CHANNEL_STD;
1490	static uint32_t div_synth[] = ZYD_GCT_CHANNEL_DIV;
1491
1492	error = zyd_rfwrite(sc,
1493	    (acal == 1) ? acal_synth[idx] : std_synth[idx]);
1494	if (error != 0)
1495		return (error);
1496	return zyd_rfwrite(sc, div_synth[idx]);
1497}
1498
1499static int
1500zyd_gct_write(struct zyd_rf *rf, uint16_t value)
1501{
1502	struct zyd_softc *sc = rf->rf_sc;
1503
1504	return zyd_rfwrite(sc, 0x300000 | 0x40000 | value);
1505}
1506
1507static int
1508zyd_gct_switch_radio(struct zyd_rf *rf, int on)
1509{
1510	int error;
1511	struct zyd_softc *sc = rf->rf_sc;
1512
1513	error = zyd_rfwrite(sc, on ? 0x25f94 : 0x25f90);
1514	if (error != 0)
1515		return (error);
1516
1517	zyd_write16_m(sc, ZYD_CR11, on ? 0x00 : 0x04);
1518	zyd_write16_m(sc, ZYD_CR251,
1519	    on ? ((sc->sc_macrev == ZYD_ZD1211B) ? 0x7f : 0x3f) : 0x2f);
1520fail:
1521	return (error);
1522}
1523
1524static int
1525zyd_gct_set_channel(struct zyd_rf *rf, uint8_t chan)
1526{
1527#define N(a)	((int)(sizeof(a) / sizeof((a)[0])))
1528	int error, i;
1529	struct zyd_softc *sc = rf->rf_sc;
1530	static const struct zyd_phy_pair cmd[] = {
1531		{ ZYD_CR80, 0x30 }, { ZYD_CR81, 0x30 }, { ZYD_CR79, 0x58 },
1532		{ ZYD_CR12, 0xf0 }, { ZYD_CR77, 0x1b }, { ZYD_CR78, 0x58 },
1533	};
1534	static const uint16_t vco[11][7] = ZYD_GCT_VCO;
1535
1536	error = zyd_gct_set_channel_synth(rf, chan, 0);
1537	if (error != 0)
1538		goto fail;
1539	error = zyd_gct_write(rf, (rf->idx == -1) ? 0x6662 :
1540	    vco[rf->idx][((chan - 1) / 2)]);
1541	if (error != 0)
1542		goto fail;
1543	error = zyd_gct_mode(rf);
1544	if (error != 0)
1545		return (error);
1546	for (i = 0; i < N(cmd); i++)
1547		zyd_write16_m(sc, cmd[i].reg, cmd[i].val);
1548	error = zyd_gct_txgain(rf, chan);
1549	if (error != 0)
1550		return (error);
1551	zyd_write16_m(sc, ZYD_CR203, 0x6);
1552fail:
1553	return (error);
1554#undef N
1555}
1556
1557static int
1558zyd_gct_txgain(struct zyd_rf *rf, uint8_t chan)
1559{
1560#define N(a)	(sizeof(a) / sizeof((a)[0]))
1561	struct zyd_softc *sc = rf->rf_sc;
1562	static uint32_t txgain[] = ZYD_GCT_TXGAIN;
1563	uint8_t idx = sc->sc_pwrint[chan - 1];
1564
1565	if (idx >= N(txgain)) {
1566		device_printf(sc->sc_dev, "could not set TX gain (%d %#x)\n",
1567		    chan, idx);
1568		return 0;
1569	}
1570
1571	return zyd_rfwrite(sc, 0x700000 | txgain[idx]);
1572#undef N
1573}
1574
1575/*
1576 * Maxim2 RF methods.
1577 */
1578static int
1579zyd_maxim2_init(struct zyd_rf *rf)
1580{
1581#define N(a)	((int)(sizeof(a) / sizeof((a)[0])))
1582	struct zyd_softc *sc = rf->rf_sc;
1583	static const struct zyd_phy_pair phyini[] = ZYD_MAXIM2_PHY;
1584	static const uint32_t rfini[] = ZYD_MAXIM2_RF;
1585	uint16_t tmp;
1586	int i, error;
1587
1588	/* init RF-dependent PHY registers */
1589	for (i = 0; i < N(phyini); i++)
1590		zyd_write16_m(sc, phyini[i].reg, phyini[i].val);
1591
1592	zyd_read16_m(sc, ZYD_CR203, &tmp);
1593	zyd_write16_m(sc, ZYD_CR203, tmp & ~(1 << 4));
1594
1595	/* init maxim2 radio */
1596	for (i = 0; i < N(rfini); i++) {
1597		if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
1598			return (error);
1599	}
1600	zyd_read16_m(sc, ZYD_CR203, &tmp);
1601	zyd_write16_m(sc, ZYD_CR203, tmp | (1 << 4));
1602fail:
1603	return (error);
1604#undef N
1605}
1606
1607static int
1608zyd_maxim2_switch_radio(struct zyd_rf *rf, int on)
1609{
1610
1611	/* vendor driver does nothing for this RF chip */
1612	return (0);
1613}
1614
1615static int
1616zyd_maxim2_set_channel(struct zyd_rf *rf, uint8_t chan)
1617{
1618#define N(a)	((int)(sizeof(a) / sizeof((a)[0])))
1619	struct zyd_softc *sc = rf->rf_sc;
1620	static const struct zyd_phy_pair phyini[] = ZYD_MAXIM2_PHY;
1621	static const uint32_t rfini[] = ZYD_MAXIM2_RF;
1622	static const struct {
1623		uint32_t	r1, r2;
1624	} rfprog[] = ZYD_MAXIM2_CHANTABLE;
1625	uint16_t tmp;
1626	int i, error;
1627
1628	/*
1629	 * Do the same as we do when initializing it, except for the channel
1630	 * values coming from the two channel tables.
1631	 */
1632
1633	/* init RF-dependent PHY registers */
1634	for (i = 0; i < N(phyini); i++)
1635		zyd_write16_m(sc, phyini[i].reg, phyini[i].val);
1636
1637	zyd_read16_m(sc, ZYD_CR203, &tmp);
1638	zyd_write16_m(sc, ZYD_CR203, tmp & ~(1 << 4));
1639
1640	/* first two values taken from the chantables */
1641	error = zyd_rfwrite(sc, rfprog[chan - 1].r1);
1642	if (error != 0)
1643		goto fail;
1644	error = zyd_rfwrite(sc, rfprog[chan - 1].r2);
1645	if (error != 0)
1646		goto fail;
1647
1648	/* init maxim2 radio - skipping the two first values */
1649	for (i = 2; i < N(rfini); i++) {
1650		if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
1651			return (error);
1652	}
1653	zyd_read16_m(sc, ZYD_CR203, &tmp);
1654	zyd_write16_m(sc, ZYD_CR203, tmp | (1 << 4));
1655fail:
1656	return (error);
1657#undef N
1658}
1659
1660static int
1661zyd_rf_attach(struct zyd_softc *sc, uint8_t type)
1662{
1663	struct zyd_rf *rf = &sc->sc_rf;
1664
1665	rf->rf_sc = sc;
1666	rf->update_pwr = 1;
1667
1668	switch (type) {
1669	case ZYD_RF_RFMD:
1670		rf->init         = zyd_rfmd_init;
1671		rf->switch_radio = zyd_rfmd_switch_radio;
1672		rf->set_channel  = zyd_rfmd_set_channel;
1673		rf->width        = 24;	/* 24-bit RF values */
1674		break;
1675	case ZYD_RF_AL2230:
1676	case ZYD_RF_AL2230S:
1677		if (sc->sc_macrev == ZYD_ZD1211B) {
1678			rf->init = zyd_al2230_init_b;
1679			rf->set_channel = zyd_al2230_set_channel_b;
1680		} else {
1681			rf->init = zyd_al2230_init;
1682			rf->set_channel = zyd_al2230_set_channel;
1683		}
1684		rf->switch_radio = zyd_al2230_switch_radio;
1685		rf->bandedge6	 = zyd_al2230_bandedge6;
1686		rf->width        = 24;	/* 24-bit RF values */
1687		break;
1688	case ZYD_RF_AL7230B:
1689		rf->init         = zyd_al7230B_init;
1690		rf->switch_radio = zyd_al7230B_switch_radio;
1691		rf->set_channel  = zyd_al7230B_set_channel;
1692		rf->width        = 24;	/* 24-bit RF values */
1693		break;
1694	case ZYD_RF_AL2210:
1695		rf->init         = zyd_al2210_init;
1696		rf->switch_radio = zyd_al2210_switch_radio;
1697		rf->set_channel  = zyd_al2210_set_channel;
1698		rf->width        = 24;	/* 24-bit RF values */
1699		break;
1700	case ZYD_RF_MAXIM_NEW:
1701	case ZYD_RF_GCT:
1702		rf->init         = zyd_gct_init;
1703		rf->switch_radio = zyd_gct_switch_radio;
1704		rf->set_channel  = zyd_gct_set_channel;
1705		rf->width        = 24;	/* 24-bit RF values */
1706		rf->update_pwr   = 0;
1707		break;
1708	case ZYD_RF_MAXIM_NEW2:
1709		rf->init         = zyd_maxim2_init;
1710		rf->switch_radio = zyd_maxim2_switch_radio;
1711		rf->set_channel  = zyd_maxim2_set_channel;
1712		rf->width        = 18;	/* 18-bit RF values */
1713		break;
1714	default:
1715		device_printf(sc->sc_dev,
1716		    "sorry, radio \"%s\" is not supported yet\n",
1717		    zyd_rf_name(type));
1718		return (EINVAL);
1719	}
1720	return (0);
1721}
1722
1723static const char *
1724zyd_rf_name(uint8_t type)
1725{
1726	static const char * const zyd_rfs[] = {
1727		"unknown", "unknown", "UW2451",   "UCHIP",     "AL2230",
1728		"AL7230B", "THETA",   "AL2210",   "MAXIM_NEW", "GCT",
1729		"AL2230S",  "RALINK",  "INTERSIL", "RFMD",      "MAXIM_NEW2",
1730		"PHILIPS"
1731	};
1732
1733	return zyd_rfs[(type > 15) ? 0 : type];
1734}
1735
1736static int
1737zyd_hw_init(struct zyd_softc *sc)
1738{
1739	int error;
1740	const struct zyd_phy_pair *phyp;
1741	struct zyd_rf *rf = &sc->sc_rf;
1742	uint16_t val;
1743
1744	/* specify that the plug and play is finished */
1745	zyd_write32_m(sc, ZYD_MAC_AFTER_PNP, 1);
1746	zyd_read16_m(sc, ZYD_FIRMWARE_BASE_ADDR, &sc->sc_fwbase);
1747	DPRINTF(sc, ZYD_DEBUG_FW, "firmware base address=0x%04x\n",
1748	    sc->sc_fwbase);
1749
1750	/* retrieve firmware revision number */
1751	zyd_read16_m(sc, sc->sc_fwbase + ZYD_FW_FIRMWARE_REV, &sc->sc_fwrev);
1752	zyd_write32_m(sc, ZYD_CR_GPI_EN, 0);
1753	zyd_write32_m(sc, ZYD_MAC_CONT_WIN_LIMIT, 0x7f043f);
1754	/* set mandatory rates - XXX assumes 802.11b/g */
1755	zyd_write32_m(sc, ZYD_MAC_MAN_RATE, 0x150f);
1756
1757	/* disable interrupts */
1758	zyd_write32_m(sc, ZYD_CR_INTERRUPT, 0);
1759
1760	if ((error = zyd_read_pod(sc)) != 0) {
1761		device_printf(sc->sc_dev, "could not read EEPROM\n");
1762		goto fail;
1763	}
1764
1765	/* PHY init (resetting) */
1766	error = zyd_lock_phy(sc);
1767	if (error != 0)
1768		goto fail;
1769	phyp = (sc->sc_macrev == ZYD_ZD1211B) ? zyd_def_phyB : zyd_def_phy;
1770	for (; phyp->reg != 0; phyp++)
1771		zyd_write16_m(sc, phyp->reg, phyp->val);
1772	if (sc->sc_macrev == ZYD_ZD1211 && sc->sc_fix_cr157 != 0) {
1773		zyd_read16_m(sc, ZYD_EEPROM_PHY_REG, &val);
1774		zyd_write32_m(sc, ZYD_CR157, val >> 8);
1775	}
1776	error = zyd_unlock_phy(sc);
1777	if (error != 0)
1778		goto fail;
1779
1780	/* HMAC init */
1781	zyd_write32_m(sc, ZYD_MAC_ACK_EXT, 0x00000020);
1782	zyd_write32_m(sc, ZYD_CR_ADDA_MBIAS_WT, 0x30000808);
1783	zyd_write32_m(sc, ZYD_MAC_SNIFFER, 0x00000000);
1784	zyd_write32_m(sc, ZYD_MAC_RXFILTER, 0x00000000);
1785	zyd_write32_m(sc, ZYD_MAC_GHTBL, 0x00000000);
1786	zyd_write32_m(sc, ZYD_MAC_GHTBH, 0x80000000);
1787	zyd_write32_m(sc, ZYD_MAC_MISC, 0x000000a4);
1788	zyd_write32_m(sc, ZYD_CR_ADDA_PWR_DWN, 0x0000007f);
1789	zyd_write32_m(sc, ZYD_MAC_BCNCFG, 0x00f00401);
1790	zyd_write32_m(sc, ZYD_MAC_PHY_DELAY2, 0x00000000);
1791	zyd_write32_m(sc, ZYD_MAC_ACK_EXT, 0x00000080);
1792	zyd_write32_m(sc, ZYD_CR_ADDA_PWR_DWN, 0x00000000);
1793	zyd_write32_m(sc, ZYD_MAC_SIFS_ACK_TIME, 0x00000100);
1794	zyd_write32_m(sc, ZYD_CR_RX_PE_DELAY, 0x00000070);
1795	zyd_write32_m(sc, ZYD_CR_PS_CTRL, 0x10000000);
1796	zyd_write32_m(sc, ZYD_MAC_RTSCTSRATE, 0x02030203);
1797	zyd_write32_m(sc, ZYD_MAC_AFTER_PNP, 1);
1798	zyd_write32_m(sc, ZYD_MAC_BACKOFF_PROTECT, 0x00000114);
1799	zyd_write32_m(sc, ZYD_MAC_DIFS_EIFS_SIFS, 0x0a47c032);
1800	zyd_write32_m(sc, ZYD_MAC_CAM_MODE, 0x3);
1801
1802	if (sc->sc_macrev == ZYD_ZD1211) {
1803		zyd_write32_m(sc, ZYD_MAC_RETRY, 0x00000002);
1804		zyd_write32_m(sc, ZYD_MAC_RX_THRESHOLD, 0x000c0640);
1805	} else {
1806		zyd_write32_m(sc, ZYD_MACB_MAX_RETRY, 0x02020202);
1807		zyd_write32_m(sc, ZYD_MACB_TXPWR_CTL4, 0x007f003f);
1808		zyd_write32_m(sc, ZYD_MACB_TXPWR_CTL3, 0x007f003f);
1809		zyd_write32_m(sc, ZYD_MACB_TXPWR_CTL2, 0x003f001f);
1810		zyd_write32_m(sc, ZYD_MACB_TXPWR_CTL1, 0x001f000f);
1811		zyd_write32_m(sc, ZYD_MACB_AIFS_CTL1, 0x00280028);
1812		zyd_write32_m(sc, ZYD_MACB_AIFS_CTL2, 0x008C003C);
1813		zyd_write32_m(sc, ZYD_MACB_TXOP, 0x01800824);
1814		zyd_write32_m(sc, ZYD_MAC_RX_THRESHOLD, 0x000c0eff);
1815	}
1816
1817	/* init beacon interval to 100ms */
1818	if ((error = zyd_set_beacon_interval(sc, 100)) != 0)
1819		goto fail;
1820
1821	if ((error = zyd_rf_attach(sc, sc->sc_rfrev)) != 0) {
1822		device_printf(sc->sc_dev, "could not attach RF, rev 0x%x\n",
1823		    sc->sc_rfrev);
1824		goto fail;
1825	}
1826
1827	/* RF chip init */
1828	error = zyd_lock_phy(sc);
1829	if (error != 0)
1830		goto fail;
1831	error = (*rf->init)(rf);
1832	if (error != 0) {
1833		device_printf(sc->sc_dev,
1834		    "radio initialization failed, error %d\n", error);
1835		goto fail;
1836	}
1837	error = zyd_unlock_phy(sc);
1838	if (error != 0)
1839		goto fail;
1840
1841	if ((error = zyd_read_eeprom(sc)) != 0) {
1842		device_printf(sc->sc_dev, "could not read EEPROM\n");
1843		goto fail;
1844	}
1845
1846fail:	return (error);
1847}
1848
1849static int
1850zyd_read_pod(struct zyd_softc *sc)
1851{
1852	int error;
1853	uint32_t tmp;
1854
1855	zyd_read32_m(sc, ZYD_EEPROM_POD, &tmp);
1856	sc->sc_rfrev     = tmp & 0x0f;
1857	sc->sc_ledtype   = (tmp >>  4) & 0x01;
1858	sc->sc_al2230s   = (tmp >>  7) & 0x01;
1859	sc->sc_cckgain   = (tmp >>  8) & 0x01;
1860	sc->sc_fix_cr157 = (tmp >> 13) & 0x01;
1861	sc->sc_parev     = (tmp >> 16) & 0x0f;
1862	sc->sc_bandedge6 = (tmp >> 21) & 0x01;
1863	sc->sc_newphy    = (tmp >> 31) & 0x01;
1864	sc->sc_txled     = ((tmp & (1 << 24)) && (tmp & (1 << 29))) ? 0 : 1;
1865fail:
1866	return (error);
1867}
1868
1869static int
1870zyd_read_eeprom(struct zyd_softc *sc)
1871{
1872	uint16_t val;
1873	int error, i;
1874
1875	/* read Tx power calibration tables */
1876	for (i = 0; i < 7; i++) {
1877		zyd_read16_m(sc, ZYD_EEPROM_PWR_CAL + i, &val);
1878		sc->sc_pwrcal[i * 2] = val >> 8;
1879		sc->sc_pwrcal[i * 2 + 1] = val & 0xff;
1880		zyd_read16_m(sc, ZYD_EEPROM_PWR_INT + i, &val);
1881		sc->sc_pwrint[i * 2] = val >> 8;
1882		sc->sc_pwrint[i * 2 + 1] = val & 0xff;
1883		zyd_read16_m(sc, ZYD_EEPROM_36M_CAL + i, &val);
1884		sc->sc_ofdm36_cal[i * 2] = val >> 8;
1885		sc->sc_ofdm36_cal[i * 2 + 1] = val & 0xff;
1886		zyd_read16_m(sc, ZYD_EEPROM_48M_CAL + i, &val);
1887		sc->sc_ofdm48_cal[i * 2] = val >> 8;
1888		sc->sc_ofdm48_cal[i * 2 + 1] = val & 0xff;
1889		zyd_read16_m(sc, ZYD_EEPROM_54M_CAL + i, &val);
1890		sc->sc_ofdm54_cal[i * 2] = val >> 8;
1891		sc->sc_ofdm54_cal[i * 2 + 1] = val & 0xff;
1892	}
1893fail:
1894	return (error);
1895}
1896
1897static int
1898zyd_get_macaddr(struct zyd_softc *sc)
1899{
1900	struct usb_device_request req;
1901	usb_error_t error;
1902
1903	req.bmRequestType = UT_READ_VENDOR_DEVICE;
1904	req.bRequest = ZYD_READFWDATAREQ;
1905	USETW(req.wValue, ZYD_EEPROM_MAC_ADDR_P1);
1906	USETW(req.wIndex, 0);
1907	USETW(req.wLength, IEEE80211_ADDR_LEN);
1908
1909	error = zyd_do_request(sc, &req, sc->sc_ic.ic_macaddr);
1910	if (error != 0) {
1911		device_printf(sc->sc_dev, "could not read EEPROM: %s\n",
1912		    usbd_errstr(error));
1913	}
1914
1915	return (error);
1916}
1917
1918static int
1919zyd_set_macaddr(struct zyd_softc *sc, const uint8_t *addr)
1920{
1921	int error;
1922	uint32_t tmp;
1923
1924	tmp = addr[3] << 24 | addr[2] << 16 | addr[1] << 8 | addr[0];
1925	zyd_write32_m(sc, ZYD_MAC_MACADRL, tmp);
1926	tmp = addr[5] << 8 | addr[4];
1927	zyd_write32_m(sc, ZYD_MAC_MACADRH, tmp);
1928fail:
1929	return (error);
1930}
1931
1932static int
1933zyd_set_bssid(struct zyd_softc *sc, const uint8_t *addr)
1934{
1935	int error;
1936	uint32_t tmp;
1937
1938	tmp = addr[3] << 24 | addr[2] << 16 | addr[1] << 8 | addr[0];
1939	zyd_write32_m(sc, ZYD_MAC_BSSADRL, tmp);
1940	tmp = addr[5] << 8 | addr[4];
1941	zyd_write32_m(sc, ZYD_MAC_BSSADRH, tmp);
1942fail:
1943	return (error);
1944}
1945
1946static int
1947zyd_switch_radio(struct zyd_softc *sc, int on)
1948{
1949	struct zyd_rf *rf = &sc->sc_rf;
1950	int error;
1951
1952	error = zyd_lock_phy(sc);
1953	if (error != 0)
1954		goto fail;
1955	error = (*rf->switch_radio)(rf, on);
1956	if (error != 0)
1957		goto fail;
1958	error = zyd_unlock_phy(sc);
1959fail:
1960	return (error);
1961}
1962
1963static int
1964zyd_set_led(struct zyd_softc *sc, int which, int on)
1965{
1966	int error;
1967	uint32_t tmp;
1968
1969	zyd_read32_m(sc, ZYD_MAC_TX_PE_CONTROL, &tmp);
1970	tmp &= ~which;
1971	if (on)
1972		tmp |= which;
1973	zyd_write32_m(sc, ZYD_MAC_TX_PE_CONTROL, tmp);
1974fail:
1975	return (error);
1976}
1977
1978static void
1979zyd_set_multi(struct zyd_softc *sc)
1980{
1981	struct ieee80211com *ic = &sc->sc_ic;
1982	uint32_t low, high;
1983	int error;
1984
1985	if ((sc->sc_flags & ZYD_FLAG_RUNNING) == 0)
1986		return;
1987
1988	low = 0x00000000;
1989	high = 0x80000000;
1990
1991	if (ic->ic_opmode == IEEE80211_M_MONITOR || ic->ic_allmulti > 0 ||
1992	    ic->ic_promisc > 0) {
1993		low = 0xffffffff;
1994		high = 0xffffffff;
1995	} else {
1996		struct ieee80211vap *vap;
1997		struct ifnet *ifp;
1998		struct ifmultiaddr *ifma;
1999		uint8_t v;
2000
2001		TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
2002			ifp = vap->iv_ifp;
2003			if_maddr_rlock(ifp);
2004			TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
2005				if (ifma->ifma_addr->sa_family != AF_LINK)
2006					continue;
2007				v = ((uint8_t *)LLADDR((struct sockaddr_dl *)
2008				    ifma->ifma_addr))[5] >> 2;
2009				if (v < 32)
2010					low |= 1 << v;
2011				else
2012					high |= 1 << (v - 32);
2013			}
2014			if_maddr_runlock(ifp);
2015		}
2016	}
2017
2018	/* reprogram multicast global hash table */
2019	zyd_write32_m(sc, ZYD_MAC_GHTBL, low);
2020	zyd_write32_m(sc, ZYD_MAC_GHTBH, high);
2021fail:
2022	if (error != 0)
2023		device_printf(sc->sc_dev,
2024		    "could not set multicast hash table\n");
2025}
2026
2027static void
2028zyd_update_mcast(struct ieee80211com *ic)
2029{
2030	struct zyd_softc *sc = ic->ic_softc;
2031
2032	ZYD_LOCK(sc);
2033	zyd_set_multi(sc);
2034	ZYD_UNLOCK(sc);
2035}
2036
2037static int
2038zyd_set_rxfilter(struct zyd_softc *sc)
2039{
2040	struct ieee80211com *ic = &sc->sc_ic;
2041	uint32_t rxfilter;
2042
2043	switch (ic->ic_opmode) {
2044	case IEEE80211_M_STA:
2045		rxfilter = ZYD_FILTER_BSS;
2046		break;
2047	case IEEE80211_M_IBSS:
2048	case IEEE80211_M_HOSTAP:
2049		rxfilter = ZYD_FILTER_HOSTAP;
2050		break;
2051	case IEEE80211_M_MONITOR:
2052		rxfilter = ZYD_FILTER_MONITOR;
2053		break;
2054	default:
2055		/* should not get there */
2056		return (EINVAL);
2057	}
2058	return zyd_write32(sc, ZYD_MAC_RXFILTER, rxfilter);
2059}
2060
2061static void
2062zyd_set_chan(struct zyd_softc *sc, struct ieee80211_channel *c)
2063{
2064	int error;
2065	struct ieee80211com *ic = &sc->sc_ic;
2066	struct zyd_rf *rf = &sc->sc_rf;
2067	uint32_t tmp;
2068	int chan;
2069
2070	chan = ieee80211_chan2ieee(ic, c);
2071	if (chan == 0 || chan == IEEE80211_CHAN_ANY) {
2072		/* XXX should NEVER happen */
2073		device_printf(sc->sc_dev,
2074		    "%s: invalid channel %x\n", __func__, chan);
2075		return;
2076	}
2077
2078	error = zyd_lock_phy(sc);
2079	if (error != 0)
2080		goto fail;
2081
2082	error = (*rf->set_channel)(rf, chan);
2083	if (error != 0)
2084		goto fail;
2085
2086	if (rf->update_pwr) {
2087		/* update Tx power */
2088		zyd_write16_m(sc, ZYD_CR31, sc->sc_pwrint[chan - 1]);
2089
2090		if (sc->sc_macrev == ZYD_ZD1211B) {
2091			zyd_write16_m(sc, ZYD_CR67,
2092			    sc->sc_ofdm36_cal[chan - 1]);
2093			zyd_write16_m(sc, ZYD_CR66,
2094			    sc->sc_ofdm48_cal[chan - 1]);
2095			zyd_write16_m(sc, ZYD_CR65,
2096			    sc->sc_ofdm54_cal[chan - 1]);
2097			zyd_write16_m(sc, ZYD_CR68, sc->sc_pwrcal[chan - 1]);
2098			zyd_write16_m(sc, ZYD_CR69, 0x28);
2099			zyd_write16_m(sc, ZYD_CR69, 0x2a);
2100		}
2101	}
2102	if (sc->sc_cckgain) {
2103		/* set CCK baseband gain from EEPROM */
2104		if (zyd_read32(sc, ZYD_EEPROM_PHY_REG, &tmp) == 0)
2105			zyd_write16_m(sc, ZYD_CR47, tmp & 0xff);
2106	}
2107	if (sc->sc_bandedge6 && rf->bandedge6 != NULL) {
2108		error = (*rf->bandedge6)(rf, c);
2109		if (error != 0)
2110			goto fail;
2111	}
2112	zyd_write32_m(sc, ZYD_CR_CONFIG_PHILIPS, 0);
2113
2114	error = zyd_unlock_phy(sc);
2115	if (error != 0)
2116		goto fail;
2117
2118	sc->sc_rxtap.wr_chan_freq = sc->sc_txtap.wt_chan_freq =
2119	    htole16(c->ic_freq);
2120	sc->sc_rxtap.wr_chan_flags = sc->sc_txtap.wt_chan_flags =
2121	    htole16(c->ic_flags);
2122fail:
2123	return;
2124}
2125
2126static int
2127zyd_set_beacon_interval(struct zyd_softc *sc, int bintval)
2128{
2129	int error;
2130	uint32_t val;
2131
2132	zyd_read32_m(sc, ZYD_CR_ATIM_WND_PERIOD, &val);
2133	sc->sc_atim_wnd = val;
2134	zyd_read32_m(sc, ZYD_CR_PRE_TBTT, &val);
2135	sc->sc_pre_tbtt = val;
2136	sc->sc_bcn_int = bintval;
2137
2138	if (sc->sc_bcn_int <= 5)
2139		sc->sc_bcn_int = 5;
2140	if (sc->sc_pre_tbtt < 4 || sc->sc_pre_tbtt >= sc->sc_bcn_int)
2141		sc->sc_pre_tbtt = sc->sc_bcn_int - 1;
2142	if (sc->sc_atim_wnd >= sc->sc_pre_tbtt)
2143		sc->sc_atim_wnd = sc->sc_pre_tbtt - 1;
2144
2145	zyd_write32_m(sc, ZYD_CR_ATIM_WND_PERIOD, sc->sc_atim_wnd);
2146	zyd_write32_m(sc, ZYD_CR_PRE_TBTT, sc->sc_pre_tbtt);
2147	zyd_write32_m(sc, ZYD_CR_BCN_INTERVAL, sc->sc_bcn_int);
2148fail:
2149	return (error);
2150}
2151
2152static void
2153zyd_rx_data(struct usb_xfer *xfer, int offset, uint16_t len)
2154{
2155	struct zyd_softc *sc = usbd_xfer_softc(xfer);
2156	struct ieee80211com *ic = &sc->sc_ic;
2157	struct zyd_plcphdr plcp;
2158	struct zyd_rx_stat stat;
2159	struct usb_page_cache *pc;
2160	struct mbuf *m;
2161	int rlen, rssi;
2162
2163	if (len < ZYD_MIN_FRAGSZ) {
2164		DPRINTF(sc, ZYD_DEBUG_RECV, "%s: frame too short (length=%d)\n",
2165		    device_get_nameunit(sc->sc_dev), len);
2166		counter_u64_add(ic->ic_ierrors, 1);
2167		return;
2168	}
2169	pc = usbd_xfer_get_frame(xfer, 0);
2170	usbd_copy_out(pc, offset, &plcp, sizeof(plcp));
2171	usbd_copy_out(pc, offset + len - sizeof(stat), &stat, sizeof(stat));
2172
2173	if (stat.flags & ZYD_RX_ERROR) {
2174		DPRINTF(sc, ZYD_DEBUG_RECV,
2175		    "%s: RX status indicated error (%x)\n",
2176		    device_get_nameunit(sc->sc_dev), stat.flags);
2177		counter_u64_add(ic->ic_ierrors, 1);
2178		return;
2179	}
2180
2181	/* compute actual frame length */
2182	rlen = len - sizeof(struct zyd_plcphdr) -
2183	    sizeof(struct zyd_rx_stat) - IEEE80211_CRC_LEN;
2184
2185	/* allocate a mbuf to store the frame */
2186	if (rlen > (int)MCLBYTES) {
2187		DPRINTF(sc, ZYD_DEBUG_RECV, "%s: frame too long (length=%d)\n",
2188		    device_get_nameunit(sc->sc_dev), rlen);
2189		counter_u64_add(ic->ic_ierrors, 1);
2190		return;
2191	} else if (rlen > (int)MHLEN)
2192		m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
2193	else
2194		m = m_gethdr(M_NOWAIT, MT_DATA);
2195	if (m == NULL) {
2196		DPRINTF(sc, ZYD_DEBUG_RECV, "%s: could not allocate rx mbuf\n",
2197		    device_get_nameunit(sc->sc_dev));
2198		counter_u64_add(ic->ic_ierrors, 1);
2199		return;
2200	}
2201	m->m_pkthdr.len = m->m_len = rlen;
2202	usbd_copy_out(pc, offset + sizeof(plcp), mtod(m, uint8_t *), rlen);
2203
2204	if (ieee80211_radiotap_active(ic)) {
2205		struct zyd_rx_radiotap_header *tap = &sc->sc_rxtap;
2206
2207		tap->wr_flags = 0;
2208		if (stat.flags & (ZYD_RX_BADCRC16 | ZYD_RX_BADCRC32))
2209			tap->wr_flags |= IEEE80211_RADIOTAP_F_BADFCS;
2210		/* XXX toss, no way to express errors */
2211		if (stat.flags & ZYD_RX_DECRYPTERR)
2212			tap->wr_flags |= IEEE80211_RADIOTAP_F_BADFCS;
2213		tap->wr_rate = ieee80211_plcp2rate(plcp.signal,
2214		    (stat.flags & ZYD_RX_OFDM) ?
2215			IEEE80211_T_OFDM : IEEE80211_T_CCK);
2216		tap->wr_antsignal = stat.rssi + -95;
2217		tap->wr_antnoise = -95;	/* XXX */
2218	}
2219	rssi = (stat.rssi > 63) ? 127 : 2 * stat.rssi;
2220
2221	sc->sc_rx_data[sc->sc_rx_count].rssi = rssi;
2222	sc->sc_rx_data[sc->sc_rx_count].m = m;
2223	sc->sc_rx_count++;
2224}
2225
2226static void
2227zyd_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
2228{
2229	struct zyd_softc *sc = usbd_xfer_softc(xfer);
2230	struct ieee80211com *ic = &sc->sc_ic;
2231	struct ieee80211_node *ni;
2232	struct zyd_rx_desc desc;
2233	struct mbuf *m;
2234	struct usb_page_cache *pc;
2235	uint32_t offset;
2236	uint8_t rssi;
2237	int8_t nf;
2238	int i;
2239	int actlen;
2240
2241	usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
2242
2243	sc->sc_rx_count = 0;
2244	switch (USB_GET_STATE(xfer)) {
2245	case USB_ST_TRANSFERRED:
2246		pc = usbd_xfer_get_frame(xfer, 0);
2247		usbd_copy_out(pc, actlen - sizeof(desc), &desc, sizeof(desc));
2248
2249		offset = 0;
2250		if (UGETW(desc.tag) == ZYD_TAG_MULTIFRAME) {
2251			DPRINTF(sc, ZYD_DEBUG_RECV,
2252			    "%s: received multi-frame transfer\n", __func__);
2253
2254			for (i = 0; i < ZYD_MAX_RXFRAMECNT; i++) {
2255				uint16_t len16 = UGETW(desc.len[i]);
2256
2257				if (len16 == 0 || len16 > actlen)
2258					break;
2259
2260				zyd_rx_data(xfer, offset, len16);
2261
2262				/* next frame is aligned on a 32-bit boundary */
2263				len16 = (len16 + 3) & ~3;
2264				offset += len16;
2265				if (len16 > actlen)
2266					break;
2267				actlen -= len16;
2268			}
2269		} else {
2270			DPRINTF(sc, ZYD_DEBUG_RECV,
2271			    "%s: received single-frame transfer\n", __func__);
2272
2273			zyd_rx_data(xfer, 0, actlen);
2274		}
2275		/* FALLTHROUGH */
2276	case USB_ST_SETUP:
2277tr_setup:
2278		usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
2279		usbd_transfer_submit(xfer);
2280
2281		/*
2282		 * At the end of a USB callback it is always safe to unlock
2283		 * the private mutex of a device! That is why we do the
2284		 * "ieee80211_input" here, and not some lines up!
2285		 */
2286		ZYD_UNLOCK(sc);
2287		for (i = 0; i < sc->sc_rx_count; i++) {
2288			rssi = sc->sc_rx_data[i].rssi;
2289			m = sc->sc_rx_data[i].m;
2290			sc->sc_rx_data[i].m = NULL;
2291
2292			nf = -95;	/* XXX */
2293
2294			ni = ieee80211_find_rxnode(ic,
2295			    mtod(m, struct ieee80211_frame_min *));
2296			if (ni != NULL) {
2297				(void)ieee80211_input(ni, m, rssi, nf);
2298				ieee80211_free_node(ni);
2299			} else
2300				(void)ieee80211_input_all(ic, m, rssi, nf);
2301		}
2302		ZYD_LOCK(sc);
2303		zyd_start(sc);
2304		break;
2305
2306	default:			/* Error */
2307		DPRINTF(sc, ZYD_DEBUG_ANY, "frame error: %s\n", usbd_errstr(error));
2308
2309		if (error != USB_ERR_CANCELLED) {
2310			/* try to clear stall first */
2311			usbd_xfer_set_stall(xfer);
2312			goto tr_setup;
2313		}
2314		break;
2315	}
2316}
2317
2318static uint8_t
2319zyd_plcp_signal(struct zyd_softc *sc, int rate)
2320{
2321	switch (rate) {
2322	/* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
2323	case 12:
2324		return (0xb);
2325	case 18:
2326		return (0xf);
2327	case 24:
2328		return (0xa);
2329	case 36:
2330		return (0xe);
2331	case 48:
2332		return (0x9);
2333	case 72:
2334		return (0xd);
2335	case 96:
2336		return (0x8);
2337	case 108:
2338		return (0xc);
2339	/* CCK rates (NB: not IEEE std, device-specific) */
2340	case 2:
2341		return (0x0);
2342	case 4:
2343		return (0x1);
2344	case 11:
2345		return (0x2);
2346	case 22:
2347		return (0x3);
2348	}
2349
2350	device_printf(sc->sc_dev, "unsupported rate %d\n", rate);
2351	return (0x0);
2352}
2353
2354static void
2355zyd_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error)
2356{
2357	struct zyd_softc *sc = usbd_xfer_softc(xfer);
2358	struct ieee80211vap *vap;
2359	struct zyd_tx_data *data;
2360	struct mbuf *m;
2361	struct usb_page_cache *pc;
2362	int actlen;
2363
2364	usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
2365
2366	switch (USB_GET_STATE(xfer)) {
2367	case USB_ST_TRANSFERRED:
2368		DPRINTF(sc, ZYD_DEBUG_ANY, "transfer complete, %u bytes\n",
2369		    actlen);
2370
2371		/* free resources */
2372		data = usbd_xfer_get_priv(xfer);
2373		zyd_tx_free(data, 0);
2374		usbd_xfer_set_priv(xfer, NULL);
2375
2376		/* FALLTHROUGH */
2377	case USB_ST_SETUP:
2378tr_setup:
2379		data = STAILQ_FIRST(&sc->tx_q);
2380		if (data) {
2381			STAILQ_REMOVE_HEAD(&sc->tx_q, next);
2382			m = data->m;
2383
2384			if (m->m_pkthdr.len > (int)ZYD_MAX_TXBUFSZ) {
2385				DPRINTF(sc, ZYD_DEBUG_ANY, "data overflow, %u bytes\n",
2386				    m->m_pkthdr.len);
2387				m->m_pkthdr.len = ZYD_MAX_TXBUFSZ;
2388			}
2389			pc = usbd_xfer_get_frame(xfer, 0);
2390			usbd_copy_in(pc, 0, &data->desc, ZYD_TX_DESC_SIZE);
2391			usbd_m_copy_in(pc, ZYD_TX_DESC_SIZE, m, 0,
2392			    m->m_pkthdr.len);
2393
2394			vap = data->ni->ni_vap;
2395			if (ieee80211_radiotap_active_vap(vap)) {
2396				struct zyd_tx_radiotap_header *tap = &sc->sc_txtap;
2397
2398				tap->wt_flags = 0;
2399				tap->wt_rate = data->rate;
2400
2401				ieee80211_radiotap_tx(vap, m);
2402			}
2403
2404			usbd_xfer_set_frame_len(xfer, 0, ZYD_TX_DESC_SIZE + m->m_pkthdr.len);
2405			usbd_xfer_set_priv(xfer, data);
2406			usbd_transfer_submit(xfer);
2407		}
2408		zyd_start(sc);
2409		break;
2410
2411	default:			/* Error */
2412		DPRINTF(sc, ZYD_DEBUG_ANY, "transfer error, %s\n",
2413		    usbd_errstr(error));
2414
2415		counter_u64_add(sc->sc_ic.ic_oerrors, 1);
2416		data = usbd_xfer_get_priv(xfer);
2417		usbd_xfer_set_priv(xfer, NULL);
2418		if (data != NULL)
2419			zyd_tx_free(data, error);
2420
2421		if (error != USB_ERR_CANCELLED) {
2422			if (error == USB_ERR_TIMEOUT)
2423				device_printf(sc->sc_dev, "device timeout\n");
2424
2425			/*
2426			 * Try to clear stall first, also if other
2427			 * errors occur, hence clearing stall
2428			 * introduces a 50 ms delay:
2429			 */
2430			usbd_xfer_set_stall(xfer);
2431			goto tr_setup;
2432		}
2433		break;
2434	}
2435}
2436
2437static int
2438zyd_tx_start(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
2439{
2440	struct ieee80211vap *vap = ni->ni_vap;
2441	struct ieee80211com *ic = ni->ni_ic;
2442	struct zyd_tx_desc *desc;
2443	struct zyd_tx_data *data;
2444	struct ieee80211_frame *wh;
2445	const struct ieee80211_txparam *tp;
2446	struct ieee80211_key *k;
2447	int rate, totlen;
2448	static const uint8_t ratediv[] = ZYD_TX_RATEDIV;
2449	uint8_t phy;
2450	uint16_t pktlen;
2451	uint32_t bits;
2452
2453	wh = mtod(m0, struct ieee80211_frame *);
2454	data = STAILQ_FIRST(&sc->tx_free);
2455	STAILQ_REMOVE_HEAD(&sc->tx_free, next);
2456	sc->tx_nfree--;
2457
2458	if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_MGT ||
2459	    (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL) {
2460		tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
2461		rate = tp->mgmtrate;
2462	} else {
2463		tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)];
2464		/* for data frames */
2465		if (IEEE80211_IS_MULTICAST(wh->i_addr1))
2466			rate = tp->mcastrate;
2467		else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
2468			rate = tp->ucastrate;
2469		else {
2470			(void) ieee80211_ratectl_rate(ni, NULL, 0);
2471			rate = ni->ni_txrate;
2472		}
2473	}
2474
2475	if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
2476		k = ieee80211_crypto_encap(ni, m0);
2477		if (k == NULL) {
2478			m_freem(m0);
2479			return (ENOBUFS);
2480		}
2481		/* packet header may have moved, reset our local pointer */
2482		wh = mtod(m0, struct ieee80211_frame *);
2483	}
2484
2485	data->ni = ni;
2486	data->m = m0;
2487	data->rate = rate;
2488
2489	/* fill Tx descriptor */
2490	desc = &data->desc;
2491	phy = zyd_plcp_signal(sc, rate);
2492	desc->phy = phy;
2493	if (ZYD_RATE_IS_OFDM(rate)) {
2494		desc->phy |= ZYD_TX_PHY_OFDM;
2495		if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
2496			desc->phy |= ZYD_TX_PHY_5GHZ;
2497	} else if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
2498		desc->phy |= ZYD_TX_PHY_SHPREAMBLE;
2499
2500	totlen = m0->m_pkthdr.len + IEEE80211_CRC_LEN;
2501	desc->len = htole16(totlen);
2502
2503	desc->flags = ZYD_TX_FLAG_BACKOFF;
2504	if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
2505		/* multicast frames are not sent at OFDM rates in 802.11b/g */
2506		if (totlen > vap->iv_rtsthreshold) {
2507			desc->flags |= ZYD_TX_FLAG_RTS;
2508		} else if (ZYD_RATE_IS_OFDM(rate) &&
2509		    (ic->ic_flags & IEEE80211_F_USEPROT)) {
2510			if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
2511				desc->flags |= ZYD_TX_FLAG_CTS_TO_SELF;
2512			else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
2513				desc->flags |= ZYD_TX_FLAG_RTS;
2514		}
2515	} else
2516		desc->flags |= ZYD_TX_FLAG_MULTICAST;
2517	if ((wh->i_fc[0] &
2518	    (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
2519	    (IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_PS_POLL))
2520		desc->flags |= ZYD_TX_FLAG_TYPE(ZYD_TX_TYPE_PS_POLL);
2521
2522	/* actual transmit length (XXX why +10?) */
2523	pktlen = ZYD_TX_DESC_SIZE + 10;
2524	if (sc->sc_macrev == ZYD_ZD1211)
2525		pktlen += totlen;
2526	desc->pktlen = htole16(pktlen);
2527
2528	bits = (rate == 11) ? (totlen * 16) + 10 :
2529	    ((rate == 22) ? (totlen * 8) + 10 : (totlen * 8));
2530	desc->plcp_length = htole16(bits / ratediv[phy]);
2531	desc->plcp_service = 0;
2532	if (rate == 22 && (bits % 11) > 0 && (bits % 11) <= 3)
2533		desc->plcp_service |= ZYD_PLCP_LENGEXT;
2534	desc->nextlen = 0;
2535
2536	if (ieee80211_radiotap_active_vap(vap)) {
2537		struct zyd_tx_radiotap_header *tap = &sc->sc_txtap;
2538
2539		tap->wt_flags = 0;
2540		tap->wt_rate = rate;
2541
2542		ieee80211_radiotap_tx(vap, m0);
2543	}
2544
2545	DPRINTF(sc, ZYD_DEBUG_XMIT,
2546	    "%s: sending data frame len=%zu rate=%u\n",
2547	    device_get_nameunit(sc->sc_dev), (size_t)m0->m_pkthdr.len,
2548		rate);
2549
2550	STAILQ_INSERT_TAIL(&sc->tx_q, data, next);
2551	usbd_transfer_start(sc->sc_xfer[ZYD_BULK_WR]);
2552
2553	return (0);
2554}
2555
2556static int
2557zyd_transmit(struct ieee80211com *ic, struct mbuf *m)
2558{
2559	struct zyd_softc *sc = ic->ic_softc;
2560	int error;
2561
2562	ZYD_LOCK(sc);
2563	if ((sc->sc_flags & ZYD_FLAG_RUNNING) == 0) {
2564		ZYD_UNLOCK(sc);
2565		return (ENXIO);
2566	}
2567	error = mbufq_enqueue(&sc->sc_snd, m);
2568	if (error) {
2569		ZYD_UNLOCK(sc);
2570		return (error);
2571	}
2572	zyd_start(sc);
2573	ZYD_UNLOCK(sc);
2574
2575	return (0);
2576}
2577
2578static void
2579zyd_start(struct zyd_softc *sc)
2580{
2581	struct ieee80211_node *ni;
2582	struct mbuf *m;
2583
2584	ZYD_LOCK_ASSERT(sc, MA_OWNED);
2585
2586	while (sc->tx_nfree > 0 && (m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
2587		ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
2588		if (zyd_tx_start(sc, m, ni) != 0) {
2589			ieee80211_free_node(ni);
2590			if_inc_counter(ni->ni_vap->iv_ifp,
2591			    IFCOUNTER_OERRORS, 1);
2592			break;
2593		}
2594	}
2595}
2596
2597static int
2598zyd_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
2599	const struct ieee80211_bpf_params *params)
2600{
2601	struct ieee80211com *ic = ni->ni_ic;
2602	struct zyd_softc *sc = ic->ic_softc;
2603
2604	ZYD_LOCK(sc);
2605	/* prevent management frames from being sent if we're not ready */
2606	if (!(sc->sc_flags & ZYD_FLAG_RUNNING)) {
2607		ZYD_UNLOCK(sc);
2608		m_freem(m);
2609		ieee80211_free_node(ni);
2610		return (ENETDOWN);
2611	}
2612	if (sc->tx_nfree == 0) {
2613		ZYD_UNLOCK(sc);
2614		m_freem(m);
2615		ieee80211_free_node(ni);
2616		return (ENOBUFS);		/* XXX */
2617	}
2618
2619	/*
2620	 * Legacy path; interpret frame contents to decide
2621	 * precisely how to send the frame.
2622	 * XXX raw path
2623	 */
2624	if (zyd_tx_start(sc, m, ni) != 0) {
2625		ZYD_UNLOCK(sc);
2626		ieee80211_free_node(ni);
2627		return (EIO);
2628	}
2629	ZYD_UNLOCK(sc);
2630	return (0);
2631}
2632
2633static void
2634zyd_parent(struct ieee80211com *ic)
2635{
2636	struct zyd_softc *sc = ic->ic_softc;
2637	int startall = 0;
2638
2639	ZYD_LOCK(sc);
2640	if (sc->sc_flags & ZYD_FLAG_DETACHED) {
2641		ZYD_UNLOCK(sc);
2642		return;
2643	}
2644	if (ic->ic_nrunning > 0) {
2645		if ((sc->sc_flags & ZYD_FLAG_RUNNING) == 0) {
2646			zyd_init_locked(sc);
2647			startall = 1;
2648		} else
2649			zyd_set_multi(sc);
2650	} else if (sc->sc_flags & ZYD_FLAG_RUNNING)
2651		zyd_stop(sc);
2652	ZYD_UNLOCK(sc);
2653	if (startall)
2654		ieee80211_start_all(ic);
2655}
2656
2657static void
2658zyd_init_locked(struct zyd_softc *sc)
2659{
2660	struct ieee80211com *ic = &sc->sc_ic;
2661	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
2662	struct usb_config_descriptor *cd;
2663	int error;
2664	uint32_t val;
2665
2666	ZYD_LOCK_ASSERT(sc, MA_OWNED);
2667
2668	if (!(sc->sc_flags & ZYD_FLAG_INITONCE)) {
2669		error = zyd_loadfirmware(sc);
2670		if (error != 0) {
2671			device_printf(sc->sc_dev,
2672			    "could not load firmware (error=%d)\n", error);
2673			goto fail;
2674		}
2675
2676		/* reset device */
2677		cd = usbd_get_config_descriptor(sc->sc_udev);
2678		error = usbd_req_set_config(sc->sc_udev, &sc->sc_mtx,
2679		    cd->bConfigurationValue);
2680		if (error)
2681			device_printf(sc->sc_dev, "reset failed, continuing\n");
2682
2683		error = zyd_hw_init(sc);
2684		if (error) {
2685			device_printf(sc->sc_dev,
2686			    "hardware initialization failed\n");
2687			goto fail;
2688		}
2689
2690		device_printf(sc->sc_dev,
2691		    "HMAC ZD1211%s, FW %02x.%02x, RF %s S%x, PA%x LED %x "
2692		    "BE%x NP%x Gain%x F%x\n",
2693		    (sc->sc_macrev == ZYD_ZD1211) ? "": "B",
2694		    sc->sc_fwrev >> 8, sc->sc_fwrev & 0xff,
2695		    zyd_rf_name(sc->sc_rfrev), sc->sc_al2230s, sc->sc_parev,
2696		    sc->sc_ledtype, sc->sc_bandedge6, sc->sc_newphy,
2697		    sc->sc_cckgain, sc->sc_fix_cr157);
2698
2699		/* read regulatory domain (currently unused) */
2700		zyd_read32_m(sc, ZYD_EEPROM_SUBID, &val);
2701		sc->sc_regdomain = val >> 16;
2702		DPRINTF(sc, ZYD_DEBUG_INIT, "regulatory domain %x\n",
2703		    sc->sc_regdomain);
2704
2705		/* we'll do software WEP decryption for now */
2706		DPRINTF(sc, ZYD_DEBUG_INIT, "%s: setting encryption type\n",
2707		    __func__);
2708		zyd_write32_m(sc, ZYD_MAC_ENCRYPTION_TYPE, ZYD_ENC_SNIFFER);
2709
2710		sc->sc_flags |= ZYD_FLAG_INITONCE;
2711	}
2712
2713	if (sc->sc_flags & ZYD_FLAG_RUNNING)
2714		zyd_stop(sc);
2715
2716	DPRINTF(sc, ZYD_DEBUG_INIT, "setting MAC address to %6D\n",
2717	    vap ? vap->iv_myaddr : ic->ic_macaddr, ":");
2718	error = zyd_set_macaddr(sc, vap ? vap->iv_myaddr : ic->ic_macaddr);
2719	if (error != 0)
2720		return;
2721
2722	/* set basic rates */
2723	if (ic->ic_curmode == IEEE80211_MODE_11B)
2724		zyd_write32_m(sc, ZYD_MAC_BAS_RATE, 0x0003);
2725	else if (ic->ic_curmode == IEEE80211_MODE_11A)
2726		zyd_write32_m(sc, ZYD_MAC_BAS_RATE, 0x1500);
2727	else	/* assumes 802.11b/g */
2728		zyd_write32_m(sc, ZYD_MAC_BAS_RATE, 0xff0f);
2729
2730	/* promiscuous mode */
2731	zyd_write32_m(sc, ZYD_MAC_SNIFFER, 0);
2732	/* multicast setup */
2733	zyd_set_multi(sc);
2734	/* set RX filter  */
2735	error = zyd_set_rxfilter(sc);
2736	if (error != 0)
2737		goto fail;
2738
2739	/* switch radio transmitter ON */
2740	error = zyd_switch_radio(sc, 1);
2741	if (error != 0)
2742		goto fail;
2743	/* set default BSS channel */
2744	zyd_set_chan(sc, ic->ic_curchan);
2745
2746	/*
2747	 * Allocate Tx and Rx xfer queues.
2748	 */
2749	zyd_setup_tx_list(sc);
2750
2751	/* enable interrupts */
2752	zyd_write32_m(sc, ZYD_CR_INTERRUPT, ZYD_HWINT_MASK);
2753
2754	sc->sc_flags |= ZYD_FLAG_RUNNING;
2755	usbd_xfer_set_stall(sc->sc_xfer[ZYD_BULK_WR]);
2756	usbd_transfer_start(sc->sc_xfer[ZYD_BULK_RD]);
2757	usbd_transfer_start(sc->sc_xfer[ZYD_INTR_RD]);
2758
2759	return;
2760
2761fail:	zyd_stop(sc);
2762	return;
2763}
2764
2765static void
2766zyd_stop(struct zyd_softc *sc)
2767{
2768	int error;
2769
2770	ZYD_LOCK_ASSERT(sc, MA_OWNED);
2771
2772	sc->sc_flags &= ~ZYD_FLAG_RUNNING;
2773
2774	/*
2775	 * Drain all the transfers, if not already drained:
2776	 */
2777	ZYD_UNLOCK(sc);
2778	usbd_transfer_drain(sc->sc_xfer[ZYD_BULK_WR]);
2779	usbd_transfer_drain(sc->sc_xfer[ZYD_BULK_RD]);
2780	ZYD_LOCK(sc);
2781
2782	zyd_unsetup_tx_list(sc);
2783
2784	/* Stop now if the device was never set up */
2785	if (!(sc->sc_flags & ZYD_FLAG_INITONCE))
2786		return;
2787
2788	/* switch radio transmitter OFF */
2789	error = zyd_switch_radio(sc, 0);
2790	if (error != 0)
2791		goto fail;
2792	/* disable Rx */
2793	zyd_write32_m(sc, ZYD_MAC_RXFILTER, 0);
2794	/* disable interrupts */
2795	zyd_write32_m(sc, ZYD_CR_INTERRUPT, 0);
2796
2797fail:
2798	return;
2799}
2800
2801static int
2802zyd_loadfirmware(struct zyd_softc *sc)
2803{
2804	struct usb_device_request req;
2805	size_t size;
2806	u_char *fw;
2807	uint8_t stat;
2808	uint16_t addr;
2809
2810	if (sc->sc_flags & ZYD_FLAG_FWLOADED)
2811		return (0);
2812
2813	if (sc->sc_macrev == ZYD_ZD1211) {
2814		fw = (u_char *)zd1211_firmware;
2815		size = sizeof(zd1211_firmware);
2816	} else {
2817		fw = (u_char *)zd1211b_firmware;
2818		size = sizeof(zd1211b_firmware);
2819	}
2820
2821	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
2822	req.bRequest = ZYD_DOWNLOADREQ;
2823	USETW(req.wIndex, 0);
2824
2825	addr = ZYD_FIRMWARE_START_ADDR;
2826	while (size > 0) {
2827		/*
2828		 * When the transfer size is 4096 bytes, it is not
2829		 * likely to be able to transfer it.
2830		 * The cause is port or machine or chip?
2831		 */
2832		const int mlen = min(size, 64);
2833
2834		DPRINTF(sc, ZYD_DEBUG_FW,
2835		    "loading firmware block: len=%d, addr=0x%x\n", mlen, addr);
2836
2837		USETW(req.wValue, addr);
2838		USETW(req.wLength, mlen);
2839		if (zyd_do_request(sc, &req, fw) != 0)
2840			return (EIO);
2841
2842		addr += mlen / 2;
2843		fw   += mlen;
2844		size -= mlen;
2845	}
2846
2847	/* check whether the upload succeeded */
2848	req.bmRequestType = UT_READ_VENDOR_DEVICE;
2849	req.bRequest = ZYD_DOWNLOADSTS;
2850	USETW(req.wValue, 0);
2851	USETW(req.wIndex, 0);
2852	USETW(req.wLength, sizeof(stat));
2853	if (zyd_do_request(sc, &req, &stat) != 0)
2854		return (EIO);
2855
2856	sc->sc_flags |= ZYD_FLAG_FWLOADED;
2857
2858	return (stat & 0x80) ? (EIO) : (0);
2859}
2860
2861static void
2862zyd_scan_start(struct ieee80211com *ic)
2863{
2864	struct zyd_softc *sc = ic->ic_softc;
2865
2866	ZYD_LOCK(sc);
2867	/* want broadcast address while scanning */
2868	zyd_set_bssid(sc, ieee80211broadcastaddr);
2869	ZYD_UNLOCK(sc);
2870}
2871
2872static void
2873zyd_scan_end(struct ieee80211com *ic)
2874{
2875	struct zyd_softc *sc = ic->ic_softc;
2876
2877	ZYD_LOCK(sc);
2878	/* restore previous bssid */
2879	zyd_set_bssid(sc, ic->ic_macaddr);
2880	ZYD_UNLOCK(sc);
2881}
2882
2883static void
2884zyd_set_channel(struct ieee80211com *ic)
2885{
2886	struct zyd_softc *sc = ic->ic_softc;
2887
2888	ZYD_LOCK(sc);
2889	zyd_set_chan(sc, ic->ic_curchan);
2890	ZYD_UNLOCK(sc);
2891}
2892
2893static device_method_t zyd_methods[] = {
2894        /* Device interface */
2895        DEVMETHOD(device_probe, zyd_match),
2896        DEVMETHOD(device_attach, zyd_attach),
2897        DEVMETHOD(device_detach, zyd_detach),
2898	DEVMETHOD_END
2899};
2900
2901static driver_t zyd_driver = {
2902	.name = "zyd",
2903	.methods = zyd_methods,
2904	.size = sizeof(struct zyd_softc)
2905};
2906
2907static devclass_t zyd_devclass;
2908
2909DRIVER_MODULE(zyd, uhub, zyd_driver, zyd_devclass, NULL, 0);
2910MODULE_DEPEND(zyd, usb, 1, 1, 1);
2911MODULE_DEPEND(zyd, wlan, 1, 1, 1);
2912MODULE_VERSION(zyd, 1);
2913