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