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