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