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