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