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