xref: /freebsd/sys/dev/usb/wlan/if_zyd.c (revision a03411e84728e9b267056fd31c7d1d9d1dc1b01e)
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
75 static int zyd_debug = 0;
76 
77 static SYSCTL_NODE(_hw_usb, OID_AUTO, zyd, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
78     "USB zyd");
79 SYSCTL_INT(_hw_usb_zyd, OID_AUTO, debug, CTLFLAG_RWTUN, &zyd_debug, 0,
80     "zyd debug level");
81 
82 enum {
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 
108 static device_probe_t zyd_match;
109 static device_attach_t zyd_attach;
110 static device_detach_t zyd_detach;
111 
112 static usb_callback_t zyd_intr_read_callback;
113 static usb_callback_t zyd_intr_write_callback;
114 static usb_callback_t zyd_bulk_read_callback;
115 static usb_callback_t zyd_bulk_write_callback;
116 
117 static 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]);
121 static void	zyd_vap_delete(struct ieee80211vap *);
122 static void	zyd_tx_free(struct zyd_tx_data *, int);
123 static void	zyd_setup_tx_list(struct zyd_softc *);
124 static void	zyd_unsetup_tx_list(struct zyd_softc *);
125 static int	zyd_newstate(struct ieee80211vap *, enum ieee80211_state, int);
126 static int	zyd_cmd(struct zyd_softc *, uint16_t, const void *, int,
127 		    void *, int, int);
128 static int	zyd_read16(struct zyd_softc *, uint16_t, uint16_t *);
129 static int	zyd_read32(struct zyd_softc *, uint16_t, uint32_t *);
130 static int	zyd_write16(struct zyd_softc *, uint16_t, uint16_t);
131 static int	zyd_write32(struct zyd_softc *, uint16_t, uint32_t);
132 static int	zyd_rfwrite(struct zyd_softc *, uint32_t);
133 static int	zyd_lock_phy(struct zyd_softc *);
134 static int	zyd_unlock_phy(struct zyd_softc *);
135 static int	zyd_rf_attach(struct zyd_softc *, uint8_t);
136 static const char *zyd_rf_name(uint8_t);
137 static int	zyd_hw_init(struct zyd_softc *);
138 static int	zyd_read_pod(struct zyd_softc *);
139 static int	zyd_read_eeprom(struct zyd_softc *);
140 static int	zyd_get_macaddr(struct zyd_softc *);
141 static int	zyd_set_macaddr(struct zyd_softc *, const uint8_t *);
142 static int	zyd_set_bssid(struct zyd_softc *, const uint8_t *);
143 static int	zyd_switch_radio(struct zyd_softc *, int);
144 static int	zyd_set_led(struct zyd_softc *, int, int);
145 static void	zyd_set_multi(struct zyd_softc *);
146 static void	zyd_update_mcast(struct ieee80211com *);
147 static int	zyd_set_rxfilter(struct zyd_softc *);
148 static void	zyd_set_chan(struct zyd_softc *, struct ieee80211_channel *);
149 static int	zyd_set_beacon_interval(struct zyd_softc *, int);
150 static void	zyd_rx_data(struct usb_xfer *, int, uint16_t);
151 static int	zyd_tx_start(struct zyd_softc *, struct mbuf *,
152 		    struct ieee80211_node *);
153 static int	zyd_transmit(struct ieee80211com *, struct mbuf *);
154 static void	zyd_start(struct zyd_softc *);
155 static int	zyd_raw_xmit(struct ieee80211_node *, struct mbuf *,
156 		    const struct ieee80211_bpf_params *);
157 static void	zyd_parent(struct ieee80211com *);
158 static void	zyd_init_locked(struct zyd_softc *);
159 static void	zyd_stop(struct zyd_softc *);
160 static int	zyd_loadfirmware(struct zyd_softc *);
161 static void	zyd_scan_start(struct ieee80211com *);
162 static void	zyd_scan_end(struct ieee80211com *);
163 static void	zyd_getradiocaps(struct ieee80211com *, int, int *,
164 		    struct ieee80211_channel[]);
165 static void	zyd_set_channel(struct ieee80211com *);
166 static int	zyd_rfmd_init(struct zyd_rf *);
167 static int	zyd_rfmd_switch_radio(struct zyd_rf *, int);
168 static int	zyd_rfmd_set_channel(struct zyd_rf *, uint8_t);
169 static int	zyd_al2230_init(struct zyd_rf *);
170 static int	zyd_al2230_switch_radio(struct zyd_rf *, int);
171 static int	zyd_al2230_set_channel(struct zyd_rf *, uint8_t);
172 static int	zyd_al2230_set_channel_b(struct zyd_rf *, uint8_t);
173 static int	zyd_al2230_init_b(struct zyd_rf *);
174 static int	zyd_al7230B_init(struct zyd_rf *);
175 static int	zyd_al7230B_switch_radio(struct zyd_rf *, int);
176 static int	zyd_al7230B_set_channel(struct zyd_rf *, uint8_t);
177 static int	zyd_al2210_init(struct zyd_rf *);
178 static int	zyd_al2210_switch_radio(struct zyd_rf *, int);
179 static int	zyd_al2210_set_channel(struct zyd_rf *, uint8_t);
180 static int	zyd_gct_init(struct zyd_rf *);
181 static int	zyd_gct_switch_radio(struct zyd_rf *, int);
182 static int	zyd_gct_set_channel(struct zyd_rf *, uint8_t);
183 static int	zyd_gct_mode(struct zyd_rf *);
184 static int	zyd_gct_set_channel_synth(struct zyd_rf *, int, int);
185 static int	zyd_gct_write(struct zyd_rf *, uint16_t);
186 static int	zyd_gct_txgain(struct zyd_rf *, uint8_t);
187 static int	zyd_maxim2_init(struct zyd_rf *);
188 static int	zyd_maxim2_switch_radio(struct zyd_rf *, int);
189 static int	zyd_maxim2_set_channel(struct zyd_rf *, uint8_t);
190 
191 static const struct zyd_phy_pair zyd_def_phy[] = ZYD_DEF_PHY;
192 static 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) }
202 static 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 
254 static 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 
314 static int
315 zyd_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 
329 static int
330 zyd_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 
415 detach:
416 	zyd_detach(dev);
417 	return (ENXIO);			/* failure */
418 }
419 
420 static void
421 zyd_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 
435 static int
436 zyd_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 
472 static struct ieee80211vap *
473 zyd_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 
508 static void
509 zyd_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 
518 static void
519 zyd_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 
532 static void
533 zyd_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 
551 static void
552 zyd_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 
577 static int
578 zyd_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 	}
613 fail:
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  */
622 static void
623 zyd_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:
731 tr_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 
749 static void
750 zyd_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:
769 tr_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 
798 static int
799 zyd_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 
835 static int
836 zyd_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 
849 static int
850 zyd_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 
865 static int
866 zyd_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 
876 static int
877 zyd_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 
889 static int
890 zyd_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);
908 fail:
909 	return (error);
910 }
911 
912 static int
913 zyd_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);
920 fail:
921 	return (error);
922 }
923 
924 static int
925 zyd_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);
933 fail:
934 	return (error);
935 }
936 
937 static int
938 zyd_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);
946 fail:
947 	return (error);
948 }
949 
950 /*
951  * RFMD RF methods.
952  */
953 static int
954 zyd_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 	}
971 fail:
972 	return (error);
973 }
974 
975 static int
976 zyd_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);
983 fail:
984 	return (error);
985 }
986 
987 static int
988 zyd_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 
1003 fail:
1004 	return (error);
1005 }
1006 
1007 /*
1008  * AL2230 RF methods.
1009  */
1010 static int
1011 zyd_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 	}
1062 fail:
1063 	return (error);
1064 }
1065 
1066 static int
1067 zyd_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);
1080 fail:
1081 	return (error);
1082 }
1083 
1084 static int
1085 zyd_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);
1149 fail:
1150 	return (error);
1151 }
1152 
1153 static int
1154 zyd_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);
1161 fail:
1162 	return (error);
1163 }
1164 
1165 static int
1166 zyd_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);
1189 fail:
1190 	return (error);
1191 }
1192 
1193 static int
1194 zyd_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);
1216 fail:
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 
1226 static int
1227 zyd_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);
1240 fail:
1241 	return (error);
1242 }
1243 
1244 /*
1245  * AL7230B RF methods.
1246  */
1247 static int
1248 zyd_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);
1281 fail:
1282 	return (error);
1283 }
1284 
1285 static int
1286 zyd_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);
1293 fail:
1294 	return (error);
1295 }
1296 
1297 static int
1298 zyd_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);
1334 fail:
1335 	return (error);
1336 }
1337 
1338 /*
1339  * AL2210 RF methods.
1340  */
1341 static int
1342 zyd_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);
1369 fail:
1370 	return (error);
1371 }
1372 
1373 static int
1374 zyd_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 
1381 static int
1382 zyd_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);
1404 fail:
1405 	return (error);
1406 }
1407 
1408 /*
1409  * GCT RF methods.
1410  */
1411 static int
1412 zyd_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);
1461 fail:
1462 	return (error);
1463 #undef ZYD_GCT_INTR_REG
1464 }
1465 
1466 static int
1467 zyd_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 
1482 static int
1483 zyd_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 
1498 static int
1499 zyd_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 
1506 static int
1507 zyd_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);
1519 fail:
1520 	return (error);
1521 }
1522 
1523 static int
1524 zyd_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);
1550 fail:
1551 	return (error);
1552 }
1553 
1554 static int
1555 zyd_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  */
1573 static int
1574 zyd_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));
1596 fail:
1597 	return (error);
1598 }
1599 
1600 static int
1601 zyd_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 
1608 static int
1609 zyd_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));
1647 fail:
1648 	return (error);
1649 }
1650 
1651 static int
1652 zyd_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 
1714 static const char *
1715 zyd_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 
1727 static int
1728 zyd_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 
1837 fail:	return (error);
1838 }
1839 
1840 static int
1841 zyd_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;
1856 fail:
1857 	return (error);
1858 }
1859 
1860 static int
1861 zyd_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 	}
1884 fail:
1885 	return (error);
1886 }
1887 
1888 static int
1889 zyd_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 
1909 static int
1910 zyd_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);
1919 fail:
1920 	return (error);
1921 }
1922 
1923 static int
1924 zyd_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);
1933 fail:
1934 	return (error);
1935 }
1936 
1937 static int
1938 zyd_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);
1950 fail:
1951 	return (error);
1952 }
1953 
1954 static int
1955 zyd_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);
1965 fail:
1966 	return (error);
1967 }
1968 
1969 static u_int
1970 zyd_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 
1984 static void
1985 zyd_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]);
2011 fail:
2012 	if (error != 0)
2013 		device_printf(sc->sc_dev,
2014 		    "could not set multicast hash table\n");
2015 }
2016 
2017 static void
2018 zyd_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 
2027 static int
2028 zyd_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 
2051 static void
2052 zyd_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);
2112 fail:
2113 	return;
2114 }
2115 
2116 static int
2117 zyd_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);
2138 fail:
2139 	return (error);
2140 }
2141 
2142 static void
2143 zyd_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 
2216 static void
2217 zyd_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:
2267 tr_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 
2308 static uint8_t
2309 zyd_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 
2344 static void
2345 zyd_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:
2368 tr_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 
2427 static int
2428 zyd_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 
2547 static int
2548 zyd_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 
2569 static void
2570 zyd_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 
2589 static int
2590 zyd_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 
2623 static void
2624 zyd_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 
2647 static void
2648 zyd_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 
2751 fail:	zyd_stop(sc);
2752 	return;
2753 }
2754 
2755 static void
2756 zyd_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 
2788 fail:
2789 	return;
2790 }
2791 
2792 static int
2793 zyd_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 
2852 static void
2853 zyd_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 
2863 static void
2864 zyd_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 
2874 static void
2875 zyd_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 
2886 static void
2887 zyd_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 
2896 static 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 
2904 static driver_t zyd_driver = {
2905 	.name = "zyd",
2906 	.methods = zyd_methods,
2907 	.size = sizeof(struct zyd_softc)
2908 };
2909 
2910 DRIVER_MODULE(zyd, uhub, zyd_driver, NULL, NULL);
2911 MODULE_DEPEND(zyd, usb, 1, 1, 1);
2912 MODULE_DEPEND(zyd, wlan, 1, 1, 1);
2913 MODULE_VERSION(zyd, 1);
2914 USB_PNP_HOST_INFO(zyd_devs);
2915