1/*	$OpenBSD: if_zyd.c,v 1.52 2007/02/11 00:08:04 jsg Exp $	*/
2/*	$NetBSD: if_zyd.c,v 1.61 2024/02/09 22:08:37 andvar 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/*-
22 * ZyDAS ZD1211/ZD1211B USB WLAN driver.
23 */
24
25#include <sys/cdefs.h>
26__KERNEL_RCSID(0, "$NetBSD: if_zyd.c,v 1.61 2024/02/09 22:08:37 andvar Exp $");
27
28#ifdef _KERNEL_OPT
29#include "opt_usb.h"
30#endif
31
32#include <sys/param.h>
33#include <sys/sockio.h>
34#include <sys/proc.h>
35#include <sys/mbuf.h>
36#include <sys/kernel.h>
37#include <sys/kmem.h>
38#include <sys/socket.h>
39#include <sys/systm.h>
40#include <sys/malloc.h>
41#include <sys/conf.h>
42#include <sys/device.h>
43
44#include <sys/bus.h>
45#include <machine/endian.h>
46
47#include <net/bpf.h>
48#include <net/if.h>
49#include <net/if_arp.h>
50#include <net/if_dl.h>
51#include <net/if_ether.h>
52#include <net/if_media.h>
53#include <net/if_types.h>
54
55#include <netinet/in.h>
56#include <netinet/in_systm.h>
57#include <netinet/in_var.h>
58#include <netinet/ip.h>
59
60#include <net80211/ieee80211_netbsd.h>
61#include <net80211/ieee80211_var.h>
62#include <net80211/ieee80211_amrr.h>
63#include <net80211/ieee80211_radiotap.h>
64
65#include <dev/firmload.h>
66
67#include <dev/usb/usb.h>
68#include <dev/usb/usbdi.h>
69#include <dev/usb/usbdi_util.h>
70#include <dev/usb/usbdevs.h>
71
72#include <dev/usb/if_zydreg.h>
73
74#ifdef ZYD_DEBUG
75#define DPRINTF(x)	do { if (zyddebug > 0) printf x; } while (0)
76#define DPRINTFN(n, x)	do { if (zyddebug > (n)) printf x; } while (0)
77int zyddebug = 0;
78#else
79#define DPRINTF(x)
80#define DPRINTFN(n, x)
81#endif
82
83static const struct zyd_phy_pair zyd_def_phy[] = ZYD_DEF_PHY;
84static const struct zyd_phy_pair zyd_def_phyB[] = ZYD_DEF_PHYB;
85
86/* various supported device vendors/products */
87#define ZYD_ZD1211_DEV(v, p)	\
88	{ { USB_VENDOR_##v, USB_PRODUCT_##v##_##p }, ZYD_ZD1211 }
89#define ZYD_ZD1211B_DEV(v, p)	\
90	{ { USB_VENDOR_##v, USB_PRODUCT_##v##_##p }, ZYD_ZD1211B }
91static const struct zyd_type {
92	struct usb_devno	dev;
93	uint8_t			rev;
94#define ZYD_ZD1211	0
95#define ZYD_ZD1211B	1
96} zyd_devs[] = {
97	ZYD_ZD1211_DEV(3COM2,		3CRUSB10075),
98	ZYD_ZD1211_DEV(ABOCOM,		WL54),
99	ZYD_ZD1211_DEV(ASUSTEK,		WL159G),
100	ZYD_ZD1211_DEV(CYBERTAN,	TG54USB),
101	ZYD_ZD1211_DEV(DRAYTEK,		VIGOR550),
102	ZYD_ZD1211_DEV(PLANEX2,		GWUS54GD),
103	ZYD_ZD1211_DEV(PLANEX2,		GWUS54GZL),
104	ZYD_ZD1211_DEV(PLANEX3,		GWUS54GZ),
105	ZYD_ZD1211_DEV(PLANEX3,		GWUS54MINI),
106	ZYD_ZD1211_DEV(SAGEM,		XG760A),
107	ZYD_ZD1211_DEV(SENAO,		NUB8301),
108	ZYD_ZD1211_DEV(SITECOMEU,	WL113),
109	ZYD_ZD1211_DEV(SWEEX,		ZD1211),
110	ZYD_ZD1211_DEV(TEKRAM,		QUICKWLAN),
111	ZYD_ZD1211_DEV(TEKRAM,		ZD1211_1),
112	ZYD_ZD1211_DEV(TEKRAM,		ZD1211_2),
113	ZYD_ZD1211_DEV(TWINMOS,		G240),
114	ZYD_ZD1211_DEV(UMEDIA,		ALL0298V2),
115	ZYD_ZD1211_DEV(UMEDIA,		TEW429UB_A),
116	ZYD_ZD1211_DEV(UMEDIA,		TEW429UB),
117	ZYD_ZD1211_DEV(WISTRONNEWEB,	UR055G),
118	ZYD_ZD1211_DEV(ZCOM,		ZD1211),
119	ZYD_ZD1211_DEV(ZYDAS,		ZD1211),
120	ZYD_ZD1211_DEV(ZYXEL,		AG225H),
121	ZYD_ZD1211_DEV(ZYXEL,		ZYAIRG220),
122	ZYD_ZD1211_DEV(ZYXEL,		G200V2),
123
124	ZYD_ZD1211B_DEV(ACCTON,		SMCWUSBG),
125	ZYD_ZD1211B_DEV(ACCTON,		WN4501H_LF_IR),
126	ZYD_ZD1211B_DEV(ACCTON,		WUS201),
127	ZYD_ZD1211B_DEV(ACCTON,		ZD1211B),
128	ZYD_ZD1211B_DEV(ASUSTEK,	A9T_WIFI),
129	ZYD_ZD1211B_DEV(BELKIN,		F5D7050C),
130	ZYD_ZD1211B_DEV(BELKIN,		ZD1211B),
131	ZYD_ZD1211B_DEV(BEWAN,		BWIFI_USB54AR),
132	ZYD_ZD1211B_DEV(CISCOLINKSYS,	WUSBF54G),
133	ZYD_ZD1211B_DEV(CYBERTAN,	ZD1211B),
134	ZYD_ZD1211B_DEV(FIBERLINE,	WL430U),
135	ZYD_ZD1211B_DEV(MELCO,		KG54L),
136	ZYD_ZD1211B_DEV(PHILIPS,	SNU5600),
137	ZYD_ZD1211B_DEV(PHILIPS,	SNU5630NS05),
138	ZYD_ZD1211B_DEV(PLANEX2,	GWUS54GXS),
139	ZYD_ZD1211B_DEV(SAGEM,		XG76NA),
140	ZYD_ZD1211B_DEV(SITECOMEU,	WL603),
141	ZYD_ZD1211B_DEV(SITECOMEU,	ZD1211B),
142	ZYD_ZD1211B_DEV(SONY,		IFU_WLM2),
143	ZYD_ZD1211B_DEV(UMEDIA,		TEW429UBC1),
144	ZYD_ZD1211B_DEV(UNKNOWN1,	ZD1211B),
145	ZYD_ZD1211B_DEV(UNKNOWN2,	ZD1211B),
146	ZYD_ZD1211B_DEV(UNKNOWN3,	ZD1211B),
147	ZYD_ZD1211B_DEV(USR,		USR5423),
148	ZYD_ZD1211B_DEV(VTECH,		ZD1211B),
149	ZYD_ZD1211B_DEV(ZCOM,		ZD1211B),
150	ZYD_ZD1211B_DEV(ZYDAS,		ZD1211B),
151	ZYD_ZD1211B_DEV(ZYDAS,		ZD1211B_2),
152	ZYD_ZD1211B_DEV(ZYXEL,		M202),
153	ZYD_ZD1211B_DEV(ZYXEL,		G220V2),
154};
155#define zyd_lookup(v, p)	\
156	((const struct zyd_type *)usb_lookup(zyd_devs, v, p))
157
158static int zyd_match(device_t, cfdata_t, void *);
159static void zyd_attach(device_t, device_t, void *);
160static int zyd_detach(device_t, int);
161static int zyd_activate(device_t, enum devact);
162
163
164CFATTACH_DECL_NEW(zyd, sizeof(struct zyd_softc), zyd_match,
165    zyd_attach, zyd_detach, zyd_activate);
166
167Static void	zyd_attachhook(device_t);
168Static int	zyd_complete_attach(struct zyd_softc *);
169Static int	zyd_open_pipes(struct zyd_softc *);
170Static void	zyd_close_pipes(struct zyd_softc *);
171Static int	zyd_alloc_tx_list(struct zyd_softc *);
172Static void	zyd_free_tx_list(struct zyd_softc *);
173Static int	zyd_alloc_rx_list(struct zyd_softc *);
174Static void	zyd_free_rx_list(struct zyd_softc *);
175Static struct	ieee80211_node *zyd_node_alloc(struct ieee80211_node_table *);
176Static int	zyd_media_change(struct ifnet *);
177Static void	zyd_next_scan(void *);
178Static void	zyd_task(void *);
179Static int	zyd_newstate(struct ieee80211com *, enum ieee80211_state, int);
180Static int	zyd_cmd(struct zyd_softc *, uint16_t, const void *, int,
181		    void *, int, u_int);
182Static int	zyd_read16(struct zyd_softc *, uint16_t, uint16_t *);
183Static int	zyd_read32(struct zyd_softc *, uint16_t, uint32_t *);
184Static int	zyd_write16(struct zyd_softc *, uint16_t, uint16_t);
185Static int	zyd_write32(struct zyd_softc *, uint16_t, uint32_t);
186Static int	zyd_rfwrite(struct zyd_softc *, uint32_t);
187Static void	zyd_lock_phy(struct zyd_softc *);
188Static void	zyd_unlock_phy(struct zyd_softc *);
189Static int	zyd_rfmd_init(struct zyd_rf *);
190Static int	zyd_rfmd_switch_radio(struct zyd_rf *, int);
191Static int	zyd_rfmd_set_channel(struct zyd_rf *, uint8_t);
192Static int	zyd_al2230_init(struct zyd_rf *);
193Static int	zyd_al2230_switch_radio(struct zyd_rf *, int);
194Static int	zyd_al2230_set_channel(struct zyd_rf *, uint8_t);
195Static int	zyd_al2230_init_b(struct zyd_rf *);
196Static int	zyd_al7230B_init(struct zyd_rf *);
197Static int	zyd_al7230B_switch_radio(struct zyd_rf *, int);
198Static int	zyd_al7230B_set_channel(struct zyd_rf *, uint8_t);
199Static int	zyd_al2210_init(struct zyd_rf *);
200Static int	zyd_al2210_switch_radio(struct zyd_rf *, int);
201Static int	zyd_al2210_set_channel(struct zyd_rf *, uint8_t);
202Static int	zyd_gct_init(struct zyd_rf *);
203Static int	zyd_gct_switch_radio(struct zyd_rf *, int);
204Static int	zyd_gct_set_channel(struct zyd_rf *, uint8_t);
205Static int	zyd_maxim_init(struct zyd_rf *);
206Static int	zyd_maxim_switch_radio(struct zyd_rf *, int);
207Static int	zyd_maxim_set_channel(struct zyd_rf *, uint8_t);
208Static int	zyd_maxim2_init(struct zyd_rf *);
209Static int	zyd_maxim2_switch_radio(struct zyd_rf *, int);
210Static int	zyd_maxim2_set_channel(struct zyd_rf *, uint8_t);
211Static int	zyd_rf_attach(struct zyd_softc *, uint8_t);
212Static const char *zyd_rf_name(uint8_t);
213Static int	zyd_hw_init(struct zyd_softc *);
214Static int	zyd_read_eeprom(struct zyd_softc *);
215Static int	zyd_set_macaddr(struct zyd_softc *, const uint8_t *);
216Static int	zyd_set_bssid(struct zyd_softc *, const uint8_t *);
217Static int	zyd_switch_radio(struct zyd_softc *, int);
218Static void	zyd_set_led(struct zyd_softc *, int, int);
219Static int	zyd_set_rxfilter(struct zyd_softc *);
220Static void	zyd_set_chan(struct zyd_softc *, struct ieee80211_channel *);
221Static int	zyd_set_beacon_interval(struct zyd_softc *, int);
222Static uint8_t	zyd_plcp_signal(int);
223Static void	zyd_intr(struct usbd_xfer *, void *, usbd_status);
224Static void	zyd_rx_data(struct zyd_softc *, const uint8_t *, uint16_t);
225Static void	zyd_rxeof(struct usbd_xfer *, void *, usbd_status);
226Static void	zyd_txeof(struct usbd_xfer *, void *, usbd_status);
227Static int	zyd_tx_mgt(struct zyd_softc *, struct mbuf *,
228		    struct ieee80211_node *);
229Static int	zyd_tx_data(struct zyd_softc *, struct mbuf *,
230		    struct ieee80211_node *);
231Static void	zyd_start(struct ifnet *);
232Static void	zyd_watchdog(struct ifnet *);
233Static int	zyd_ioctl(struct ifnet *, u_long, void *);
234Static int	zyd_init(struct ifnet *);
235Static void	zyd_stop(struct ifnet *, int);
236Static int	zyd_loadfirmware(struct zyd_softc *, u_char *, size_t);
237Static void	zyd_iter_func(void *, struct ieee80211_node *);
238Static void	zyd_amrr_timeout(void *);
239Static void	zyd_newassoc(struct ieee80211_node *, int);
240
241static int
242zyd_match(device_t parent, cfdata_t match, void *aux)
243{
244	struct usb_attach_arg *uaa = aux;
245
246	return (zyd_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL) ?
247	    UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
248}
249
250Static void
251zyd_attachhook(device_t self)
252{
253	struct zyd_softc *sc = device_private(self);
254	firmware_handle_t fwh;
255	const char *fwname;
256	u_char *fw;
257	size_t size;
258	int error;
259
260	fwname = (sc->mac_rev == ZYD_ZD1211) ? "zyd-zd1211" : "zyd-zd1211b";
261	if ((error = firmware_open("zyd", fwname, &fwh)) != 0) {
262		aprint_error_dev(sc->sc_dev,
263		    "failed to open firmware %s (error=%d)\n", fwname, error);
264		return;
265	}
266	size = firmware_get_size(fwh);
267	fw = firmware_malloc(size);
268	if (fw == NULL) {
269		aprint_error_dev(sc->sc_dev,
270		    "failed to allocate firmware memory\n");
271		firmware_close(fwh);
272		return;
273	}
274	error = firmware_read(fwh, 0, fw, size);
275	firmware_close(fwh);
276	if (error != 0) {
277		aprint_error_dev(sc->sc_dev,
278		    "failed to read firmware (error %d)\n", error);
279		firmware_free(fw, size);
280		return;
281	}
282
283	error = zyd_loadfirmware(sc, fw, size);
284	if (error != 0) {
285		aprint_error_dev(sc->sc_dev,
286		    "could not load firmware (error=%d)\n", error);
287		firmware_free(fw, size);
288		return;
289	}
290
291	firmware_free(fw, size);
292
293	/* complete the attach process */
294	if ((error = zyd_complete_attach(sc)) == 0)
295		sc->attached = 1;
296	return;
297}
298
299static void
300zyd_attach(device_t parent, device_t self, void *aux)
301{
302	struct zyd_softc *sc = device_private(self);
303	struct usb_attach_arg *uaa = aux;
304	char *devinfop;
305	usb_device_descriptor_t* ddesc;
306	struct ifnet *ifp = &sc->sc_if;
307
308	sc->sc_dev = self;
309	sc->sc_udev = uaa->uaa_device;
310
311	aprint_naive("\n");
312	aprint_normal("\n");
313
314	devinfop = usbd_devinfo_alloc(uaa->uaa_device, 0);
315	aprint_normal_dev(self, "%s\n", devinfop);
316	usbd_devinfo_free(devinfop);
317
318	sc->mac_rev = zyd_lookup(uaa->uaa_vendor, uaa->uaa_product)->rev;
319
320	ddesc = usbd_get_device_descriptor(sc->sc_udev);
321	if (UGETW(ddesc->bcdDevice) < 0x4330) {
322		aprint_error_dev(self, "device version mismatch: %#x "
323		    "(only >= 43.30 supported)\n", UGETW(ddesc->bcdDevice));
324		return;
325	}
326
327	ifp->if_softc = sc;
328	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
329	ifp->if_init = zyd_init;
330	ifp->if_ioctl = zyd_ioctl;
331	ifp->if_start = zyd_start;
332	ifp->if_watchdog = zyd_watchdog;
333	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
334	IFQ_SET_READY(&ifp->if_snd);
335	memcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
336
337	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB);
338	cv_init(&sc->sc_cmdcv, "zydcmd");
339	SIMPLEQ_INIT(&sc->sc_rqh);
340
341	/* defer configuration after file system is ready to load firmware */
342	config_mountroot(self, zyd_attachhook);
343}
344
345Static int
346zyd_complete_attach(struct zyd_softc *sc)
347{
348	struct ieee80211com *ic = &sc->sc_ic;
349	struct ifnet *ifp = &sc->sc_if;
350	usbd_status error;
351	int i;
352
353	usb_init_task(&sc->sc_task, zyd_task, sc, 0);
354	callout_init(&(sc->sc_scan_ch), 0);
355
356	sc->amrr.amrr_min_success_threshold =  1;
357	sc->amrr.amrr_max_success_threshold = 10;
358	callout_init(&sc->sc_amrr_ch, 0);
359
360	error = usbd_set_config_no(sc->sc_udev, ZYD_CONFIG_NO, 1);
361	if (error != 0) {
362		aprint_error_dev(sc->sc_dev, "failed to set configuration"
363		    ", err=%s\n", usbd_errstr(error));
364		goto fail;
365	}
366
367	error = usbd_device2interface_handle(sc->sc_udev, ZYD_IFACE_INDEX,
368	    &sc->sc_iface);
369	if (error != 0) {
370		aprint_error_dev(sc->sc_dev,
371		    "getting interface handle failed\n");
372		goto fail;
373	}
374
375	if ((error = zyd_open_pipes(sc)) != 0) {
376		aprint_error_dev(sc->sc_dev, "could not open pipes\n");
377		goto fail;
378	}
379
380	if ((error = zyd_read_eeprom(sc)) != 0) {
381		aprint_error_dev(sc->sc_dev, "could not read EEPROM\n");
382		goto fail;
383	}
384
385	if ((error = zyd_rf_attach(sc, sc->rf_rev)) != 0) {
386		aprint_error_dev(sc->sc_dev, "could not attach RF\n");
387		goto fail;
388	}
389
390	if ((error = zyd_hw_init(sc)) != 0) {
391		aprint_error_dev(sc->sc_dev,
392		    "hardware initialization failed\n");
393		goto fail;
394	}
395
396	aprint_normal_dev(sc->sc_dev,
397	    "HMAC ZD1211%s, FW %02x.%02x, RF %s, PA %x, address %s\n",
398	    (sc->mac_rev == ZYD_ZD1211) ? "": "B",
399	    sc->fw_rev >> 8, sc->fw_rev & 0xff, zyd_rf_name(sc->rf_rev),
400	    sc->pa_rev, ether_sprintf(ic->ic_myaddr));
401
402	ic->ic_ifp = ifp;
403	ic->ic_phytype = IEEE80211_T_OFDM;	/* not only, but not used */
404	ic->ic_opmode = IEEE80211_M_STA;	/* default to BSS mode */
405	ic->ic_state = IEEE80211_S_INIT;
406
407	/* set device capabilities */
408	ic->ic_caps =
409	    IEEE80211_C_MONITOR |	/* monitor mode supported */
410	    IEEE80211_C_TXPMGT |	/* tx power management */
411	    IEEE80211_C_SHPREAMBLE |	/* short preamble supported */
412	    IEEE80211_C_WEP;		/* s/w WEP */
413
414	/* set supported .11b and .11g rates */
415	ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
416	ic->ic_sup_rates[IEEE80211_MODE_11G] = ieee80211_std_rateset_11g;
417
418	/* set supported .11b and .11g channels (1 through 14) */
419	for (i = 1; i <= 14; i++) {
420		ic->ic_channels[i].ic_freq =
421		    ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
422		ic->ic_channels[i].ic_flags =
423		    IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM |
424		    IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ;
425	}
426
427	if_attach(ifp);
428	ieee80211_ifattach(ic);
429	ic->ic_node_alloc = zyd_node_alloc;
430	ic->ic_newassoc = zyd_newassoc;
431
432	/* override state transition machine */
433	sc->sc_newstate = ic->ic_newstate;
434	ic->ic_newstate = zyd_newstate;
435
436	/* XXX media locking needs revisiting */
437	mutex_init(&sc->sc_media_mtx, MUTEX_DEFAULT, IPL_SOFTUSB);
438	ieee80211_media_init_with_lock(ic,
439	    zyd_media_change, ieee80211_media_status, &sc->sc_media_mtx);
440
441	bpf_attach2(ifp, DLT_IEEE802_11_RADIO,
442	    sizeof(struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN,
443	    &sc->sc_drvbpf);
444
445	sc->sc_rxtap_len = sizeof(sc->sc_rxtapu);
446	sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
447	sc->sc_rxtap.wr_ihdr.it_present = htole32(ZYD_RX_RADIOTAP_PRESENT);
448
449	sc->sc_txtap_len = sizeof(sc->sc_txtapu);
450	sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
451	sc->sc_txtap.wt_ihdr.it_present = htole32(ZYD_TX_RADIOTAP_PRESENT);
452
453	ieee80211_announce(ic);
454
455	usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev);
456
457fail:	return error;
458}
459
460static int
461zyd_detach(device_t self, int flags)
462{
463	struct zyd_softc *sc = device_private(self);
464	struct ieee80211com *ic = &sc->sc_ic;
465	struct ifnet *ifp = &sc->sc_if;
466
467	if (!sc->attached)
468		return 0;
469
470	mutex_enter(&sc->sc_lock);
471
472	zyd_stop(ifp, 1);
473	callout_halt(&sc->sc_scan_ch, NULL);
474	callout_halt(&sc->sc_amrr_ch, NULL);
475	usb_rem_task_wait(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER, NULL);
476
477	/* Abort, etc. done by zyd_stop */
478	zyd_close_pipes(sc);
479
480	sc->attached = 0;
481
482	bpf_detach(ifp);
483	ieee80211_ifdetach(ic);
484	if_detach(ifp);
485
486	mutex_exit(&sc->sc_lock);
487
488	mutex_destroy(&sc->sc_lock);
489	cv_destroy(&sc->sc_cmdcv);
490
491	usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev);
492
493	return 0;
494}
495
496Static int
497zyd_open_pipes(struct zyd_softc *sc)
498{
499	usb_endpoint_descriptor_t *edesc;
500	usbd_status error;
501
502	/* interrupt in */
503	edesc = usbd_get_endpoint_descriptor(sc->sc_iface, 0x83);
504	if (edesc == NULL)
505		return EINVAL;
506
507	sc->ibuf_size = UGETW(edesc->wMaxPacketSize);
508	if (sc->ibuf_size == 0)	/* should not happen */
509		return EINVAL;
510
511	sc->ibuf = kmem_alloc(sc->ibuf_size, KM_SLEEP);
512
513	error = usbd_open_pipe_intr(sc->sc_iface, 0x83, USBD_SHORT_XFER_OK,
514	    &sc->zyd_ep[ZYD_ENDPT_IIN], sc, sc->ibuf, sc->ibuf_size, zyd_intr,
515	    USBD_DEFAULT_INTERVAL);
516	if (error != 0) {
517		printf("%s: open rx intr pipe failed: %s\n",
518		    device_xname(sc->sc_dev), usbd_errstr(error));
519		goto fail;
520	}
521
522	/* interrupt out (not necessarily an interrupt pipe) */
523	error = usbd_open_pipe(sc->sc_iface, 0x04, USBD_EXCLUSIVE_USE,
524	    &sc->zyd_ep[ZYD_ENDPT_IOUT]);
525	if (error != 0) {
526		printf("%s: open tx intr pipe failed: %s\n",
527		    device_xname(sc->sc_dev), usbd_errstr(error));
528		goto fail;
529	}
530
531	/* bulk in */
532	error = usbd_open_pipe(sc->sc_iface, 0x82, USBD_EXCLUSIVE_USE,
533	    &sc->zyd_ep[ZYD_ENDPT_BIN]);
534	if (error != 0) {
535		printf("%s: open rx pipe failed: %s\n",
536		    device_xname(sc->sc_dev), usbd_errstr(error));
537		goto fail;
538	}
539
540	/* bulk out */
541	error = usbd_open_pipe(sc->sc_iface, 0x01, USBD_EXCLUSIVE_USE,
542	    &sc->zyd_ep[ZYD_ENDPT_BOUT]);
543	if (error != 0) {
544		printf("%s: open tx pipe failed: %s\n",
545		    device_xname(sc->sc_dev), usbd_errstr(error));
546		goto fail;
547	}
548
549	return 0;
550
551fail:	zyd_close_pipes(sc);
552	return error;
553}
554
555Static void
556zyd_close_pipes(struct zyd_softc *sc)
557{
558	int i;
559
560	for (i = 0; i < ZYD_ENDPT_CNT; i++) {
561		if (sc->zyd_ep[i] != NULL) {
562			usbd_close_pipe(sc->zyd_ep[i]);
563			sc->zyd_ep[i] = NULL;
564		}
565	}
566	if (sc->ibuf != NULL) {
567		kmem_free(sc->ibuf, sc->ibuf_size);
568		sc->ibuf = NULL;
569	}
570}
571
572Static int
573zyd_alloc_tx_list(struct zyd_softc *sc)
574{
575	int i, error;
576
577	sc->tx_queued = 0;
578
579	for (i = 0; i < ZYD_TX_LIST_CNT; i++) {
580		struct zyd_tx_data *data = &sc->tx_data[i];
581
582		data->sc = sc;	/* backpointer for callbacks */
583
584		error = usbd_create_xfer(sc->zyd_ep[ZYD_ENDPT_BOUT],
585		    ZYD_MAX_TXBUFSZ, USBD_FORCE_SHORT_XFER, 0, &data->xfer);
586		if (error) {
587			printf("%s: could not allocate tx xfer\n",
588			    device_xname(sc->sc_dev));
589			goto fail;
590		}
591		data->buf = usbd_get_buffer(data->xfer);
592
593		/* clear Tx descriptor */
594		memset(data->buf, 0, sizeof(struct zyd_tx_desc));
595	}
596	return 0;
597
598fail:	zyd_free_tx_list(sc);
599	return error;
600}
601
602Static void
603zyd_free_tx_list(struct zyd_softc *sc)
604{
605	int i;
606
607	for (i = 0; i < ZYD_TX_LIST_CNT; i++) {
608		struct zyd_tx_data *data = &sc->tx_data[i];
609
610		if (data->xfer != NULL) {
611			usbd_destroy_xfer(data->xfer);
612			data->xfer = NULL;
613		}
614		if (data->ni != NULL) {
615			ieee80211_free_node(data->ni);
616			data->ni = NULL;
617		}
618	}
619}
620
621Static int
622zyd_alloc_rx_list(struct zyd_softc *sc)
623{
624	int i, error;
625
626	for (i = 0; i < ZYD_RX_LIST_CNT; i++) {
627		struct zyd_rx_data *data = &sc->rx_data[i];
628
629		data->sc = sc;	/* backpointer for callbacks */
630
631		error = usbd_create_xfer(sc->zyd_ep[ZYD_ENDPT_BIN],
632		    ZYX_MAX_RXBUFSZ, 0, 0, &data->xfer);
633		if (error) {
634			printf("%s: could not allocate rx xfer\n",
635			    device_xname(sc->sc_dev));
636			goto fail;
637		}
638		data->buf = usbd_get_buffer(data->xfer);
639	}
640	return 0;
641
642fail:	zyd_free_rx_list(sc);
643	return error;
644}
645
646Static void
647zyd_free_rx_list(struct zyd_softc *sc)
648{
649	int i;
650
651	for (i = 0; i < ZYD_RX_LIST_CNT; i++) {
652		struct zyd_rx_data *data = &sc->rx_data[i];
653
654		if (data->xfer != NULL) {
655			usbd_destroy_xfer(data->xfer);
656			data->xfer = NULL;
657		}
658	}
659}
660
661/* ARGUSED */
662Static struct ieee80211_node *
663zyd_node_alloc(struct ieee80211_node_table *nt __unused)
664{
665	struct zyd_node *zn;
666
667	zn = malloc(sizeof(struct zyd_node), M_80211_NODE, M_NOWAIT | M_ZERO);
668	return zn ? &zn->ni : NULL;
669}
670
671Static int
672zyd_media_change(struct ifnet *ifp)
673{
674	int error;
675
676	error = ieee80211_media_change(ifp);
677	if (error != ENETRESET)
678		return error;
679
680	if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING))
681		zyd_init(ifp);
682
683	return 0;
684}
685
686/*
687 * This function is called periodically (every 200ms) during scanning to
688 * switch from one channel to another.
689 */
690Static void
691zyd_next_scan(void *arg)
692{
693	struct zyd_softc *sc = arg;
694	struct ieee80211com *ic = &sc->sc_ic;
695
696	if (ic->ic_state == IEEE80211_S_SCAN)
697		ieee80211_next_scan(ic);
698}
699
700Static void
701zyd_task(void *arg)
702{
703	struct zyd_softc *sc = arg;
704	struct ieee80211com *ic = &sc->sc_ic;
705	enum ieee80211_state ostate;
706
707	ostate = ic->ic_state;
708
709	switch (sc->sc_state) {
710	case IEEE80211_S_INIT:
711		if (ostate == IEEE80211_S_RUN) {
712			/* turn link LED off */
713			zyd_set_led(sc, ZYD_LED1, 0);
714
715			/* stop data LED from blinking */
716			zyd_write32(sc, sc->fwbase + ZYD_FW_LINK_STATUS, 0);
717		}
718		break;
719
720	case IEEE80211_S_SCAN:
721		zyd_set_chan(sc, ic->ic_curchan);
722		callout_reset(&sc->sc_scan_ch, hz / 5, zyd_next_scan, sc);
723		break;
724
725	case IEEE80211_S_AUTH:
726	case IEEE80211_S_ASSOC:
727		zyd_set_chan(sc, ic->ic_curchan);
728		break;
729
730	case IEEE80211_S_RUN:
731	{
732		struct ieee80211_node *ni = ic->ic_bss;
733
734		zyd_set_chan(sc, ic->ic_curchan);
735
736		if (ic->ic_opmode != IEEE80211_M_MONITOR) {
737			/* turn link LED on */
738			zyd_set_led(sc, ZYD_LED1, 1);
739
740			/* make data LED blink upon Tx */
741			zyd_write32(sc, sc->fwbase + ZYD_FW_LINK_STATUS, 1);
742
743			zyd_set_bssid(sc, ni->ni_bssid);
744		}
745
746		if (ic->ic_opmode == IEEE80211_M_STA) {
747			/* fake a join to init the tx rate */
748			zyd_newassoc(ni, 1);
749		}
750
751		/* start automatic rate control timer */
752		if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE)
753			callout_reset(&sc->sc_amrr_ch, hz, zyd_amrr_timeout, sc);
754
755		break;
756	}
757	}
758
759	sc->sc_newstate(ic, sc->sc_state, -1);
760}
761
762Static int
763zyd_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
764{
765	struct zyd_softc *sc = ic->ic_ifp->if_softc;
766
767	if (!sc->attached)
768		return ENXIO;
769
770	/*
771	 * XXXSMP: This does not wait for the task, if it is in flight,
772	 * to complete.  If this code works at all, it must rely on the
773	 * kernel lock to serialize with the USB task thread.
774	 */
775	usb_rem_task(sc->sc_udev, &sc->sc_task);
776	callout_stop(&sc->sc_scan_ch);
777	callout_stop(&sc->sc_amrr_ch);
778
779	/* do it in a process context */
780	sc->sc_state = nstate;
781	usb_add_task(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER);
782
783	return 0;
784}
785
786Static int
787zyd_cmd(struct zyd_softc *sc, uint16_t code, const void *idata, int ilen,
788    void *odata, int olen, u_int flags)
789{
790	struct usbd_xfer *xfer;
791	struct zyd_cmd cmd;
792	struct rq rq;
793	uint16_t xferflags;
794	int error;
795	usbd_status uerror;
796
797	error = usbd_create_xfer(sc->zyd_ep[ZYD_ENDPT_IOUT],
798	    sizeof(uint16_t) + ilen, USBD_FORCE_SHORT_XFER, 0, &xfer);
799	if (error)
800		return error;
801
802	cmd.code = htole16(code);
803	memcpy(cmd.data, idata, ilen);
804
805	xferflags = USBD_FORCE_SHORT_XFER;
806	if (!(flags & ZYD_CMD_FLAG_READ))
807		xferflags |= USBD_SYNCHRONOUS;
808	else {
809		rq.idata = idata;
810		rq.odata = odata;
811		rq.len = olen / sizeof(struct zyd_pair);
812		mutex_enter(&sc->sc_lock);
813		SIMPLEQ_INSERT_TAIL(&sc->sc_rqh, &rq, rq);
814		mutex_exit(&sc->sc_lock);
815	}
816
817	usbd_setup_xfer(xfer, 0, &cmd, sizeof(uint16_t) + ilen, xferflags,
818	    ZYD_INTR_TIMEOUT, NULL);
819	uerror = usbd_transfer(xfer);
820	if (uerror != USBD_IN_PROGRESS && uerror != 0) {
821		printf("%s: could not send command (error=%s)\n",
822		    device_xname(sc->sc_dev), usbd_errstr(uerror));
823		(void)usbd_destroy_xfer(xfer);
824		return EIO;
825	}
826	if (!(flags & ZYD_CMD_FLAG_READ)) {
827		(void)usbd_destroy_xfer(xfer);
828		return 0;	/* write: don't wait for reply */
829	}
830	/* wait at most one second for command reply */
831	mutex_enter(&sc->sc_lock);
832	error = cv_timedwait_sig(&sc->sc_cmdcv, &sc->sc_lock, hz);
833	if (error == EWOULDBLOCK)
834		printf("%s: zyd_read sleep timeout\n", device_xname(sc->sc_dev));
835	SIMPLEQ_REMOVE(&sc->sc_rqh, &rq, rq, rq);
836	mutex_exit(&sc->sc_lock);
837
838	(void)usbd_destroy_xfer(xfer);
839	return error;
840}
841
842Static int
843zyd_read16(struct zyd_softc *sc, uint16_t reg, uint16_t *val)
844{
845	struct zyd_pair tmp;
846	int error;
847
848	reg = htole16(reg);
849	error = zyd_cmd(sc, ZYD_CMD_IORD, &reg, sizeof(reg), &tmp, sizeof(tmp),
850	    ZYD_CMD_FLAG_READ);
851	if (error == 0)
852		*val = le16toh(tmp.val);
853	else
854		*val = 0;
855	return error;
856}
857
858Static int
859zyd_read32(struct zyd_softc *sc, uint16_t reg, uint32_t *val)
860{
861	struct zyd_pair tmp[2];
862	uint16_t regs[2];
863	int error;
864
865	regs[0] = htole16(ZYD_REG32_HI(reg));
866	regs[1] = htole16(ZYD_REG32_LO(reg));
867	error = zyd_cmd(sc, ZYD_CMD_IORD, regs, sizeof(regs), tmp, sizeof(tmp),
868	    ZYD_CMD_FLAG_READ);
869	if (error == 0)
870		*val = le16toh(tmp[0].val) << 16 | le16toh(tmp[1].val);
871	else
872		*val = 0;
873	return error;
874}
875
876Static int
877zyd_write16(struct zyd_softc *sc, uint16_t reg, uint16_t val)
878{
879	struct zyd_pair pair;
880
881	pair.reg = htole16(reg);
882	pair.val = htole16(val);
883
884	return zyd_cmd(sc, ZYD_CMD_IOWR, &pair, sizeof(pair), NULL, 0, 0);
885}
886
887Static int
888zyd_write32(struct zyd_softc *sc, uint16_t reg, uint32_t val)
889{
890	struct zyd_pair pair[2];
891
892	pair[0].reg = htole16(ZYD_REG32_HI(reg));
893	pair[0].val = htole16(val >> 16);
894	pair[1].reg = htole16(ZYD_REG32_LO(reg));
895	pair[1].val = htole16(val & 0xffff);
896
897	return zyd_cmd(sc, ZYD_CMD_IOWR, pair, sizeof(pair), NULL, 0, 0);
898}
899
900Static int
901zyd_rfwrite(struct zyd_softc *sc, uint32_t val)
902{
903	struct zyd_rf *rf = &sc->sc_rf;
904	struct zyd_rfwrite req;
905	uint16_t cr203;
906	int i;
907
908	(void)zyd_read16(sc, ZYD_CR203, &cr203);
909	cr203 &= ~(ZYD_RF_IF_LE | ZYD_RF_CLK | ZYD_RF_DATA);
910
911	req.code  = htole16(2);
912	req.width = htole16(rf->width);
913	for (i = 0; i < rf->width; i++) {
914		req.bit[i] = htole16(cr203);
915		if (val & (1 << (rf->width - 1 - i)))
916			req.bit[i] |= htole16(ZYD_RF_DATA);
917	}
918	return zyd_cmd(sc, ZYD_CMD_RFCFG, &req, 4 + 2 * rf->width, NULL, 0, 0);
919}
920
921Static void
922zyd_lock_phy(struct zyd_softc *sc)
923{
924	uint32_t tmp;
925
926	(void)zyd_read32(sc, ZYD_MAC_MISC, &tmp);
927	tmp &= ~ZYD_UNLOCK_PHY_REGS;
928	(void)zyd_write32(sc, ZYD_MAC_MISC, tmp);
929}
930
931Static void
932zyd_unlock_phy(struct zyd_softc *sc)
933{
934	uint32_t tmp;
935
936	(void)zyd_read32(sc, ZYD_MAC_MISC, &tmp);
937	tmp |= ZYD_UNLOCK_PHY_REGS;
938	(void)zyd_write32(sc, ZYD_MAC_MISC, tmp);
939}
940
941/*
942 * RFMD RF methods.
943 */
944Static int
945zyd_rfmd_init(struct zyd_rf *rf)
946{
947	struct zyd_softc *sc = rf->rf_sc;
948	static const struct zyd_phy_pair phyini[] = ZYD_RFMD_PHY;
949	static const uint32_t rfini[] = ZYD_RFMD_RF;
950	int error;
951	size_t i;
952
953	/* init RF-dependent PHY registers */
954	for (i = 0; i < __arraycount(phyini); i++) {
955		error = zyd_write16(sc, phyini[i].reg, phyini[i].val);
956		if (error != 0)
957			return error;
958	}
959
960	/* init RFMD radio */
961	for (i = 0; i < __arraycount(rfini); i++) {
962		if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
963			return error;
964	}
965	return 0;
966}
967
968Static int
969zyd_rfmd_switch_radio(struct zyd_rf *rf, int on)
970{
971	struct zyd_softc *sc = rf->rf_sc;
972
973	(void)zyd_write16(sc, ZYD_CR10, on ? 0x89 : 0x15);
974	(void)zyd_write16(sc, ZYD_CR11, on ? 0x00 : 0x81);
975
976	return 0;
977}
978
979Static int
980zyd_rfmd_set_channel(struct zyd_rf *rf, uint8_t chan)
981{
982	struct zyd_softc *sc = rf->rf_sc;
983	static const struct {
984		uint32_t	r1, r2;
985	} rfprog[] = ZYD_RFMD_CHANTABLE;
986
987	(void)zyd_rfwrite(sc, rfprog[chan - 1].r1);
988	(void)zyd_rfwrite(sc, rfprog[chan - 1].r2);
989
990	return 0;
991}
992
993/*
994 * AL2230 RF methods.
995 */
996Static int
997zyd_al2230_init(struct zyd_rf *rf)
998{
999	struct zyd_softc *sc = rf->rf_sc;
1000	static const struct zyd_phy_pair phyini[] = ZYD_AL2230_PHY;
1001	static const struct zyd_phy_pair phy2230s[] = ZYD_AL2230S_PHY_INIT;
1002	static const uint32_t rfini[] = ZYD_AL2230_RF;
1003	int error;
1004	size_t i;
1005
1006	/* init RF-dependent PHY registers */
1007	for (i = 0; i < __arraycount(phyini); i++) {
1008		error = zyd_write16(sc, phyini[i].reg, phyini[i].val);
1009		if (error != 0)
1010			return error;
1011	}
1012
1013	if (sc->rf_rev == ZYD_RF_AL2230S) {
1014		for (i = 0; i < __arraycount(phy2230s); i++) {
1015			error = zyd_write16(sc, phy2230s[i].reg,
1016			    phy2230s[i].val);
1017			if (error != 0)
1018				return error;
1019		}
1020	}
1021
1022	/* init AL2230 radio */
1023	for (i = 0; i < __arraycount(rfini); i++) {
1024		if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
1025			return error;
1026	}
1027	return 0;
1028}
1029
1030Static int
1031zyd_al2230_init_b(struct zyd_rf *rf)
1032{
1033	struct zyd_softc *sc = rf->rf_sc;
1034	static const struct zyd_phy_pair phyini[] = ZYD_AL2230_PHY_B;
1035	static const uint32_t rfini[] = ZYD_AL2230_RF_B;
1036	int error;
1037	size_t i;
1038
1039	/* init RF-dependent PHY registers */
1040	for (i = 0; i < __arraycount(phyini); i++) {
1041		error = zyd_write16(sc, phyini[i].reg, phyini[i].val);
1042		if (error != 0)
1043			return error;
1044	}
1045
1046	/* init AL2230 radio */
1047	for (i = 0; i < __arraycount(rfini); i++) {
1048		if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
1049			return error;
1050	}
1051	return 0;
1052}
1053
1054Static int
1055zyd_al2230_switch_radio(struct zyd_rf *rf, int on)
1056{
1057	struct zyd_softc *sc = rf->rf_sc;
1058	int on251 = (sc->mac_rev == ZYD_ZD1211) ? 0x3f : 0x7f;
1059
1060	(void)zyd_write16(sc, ZYD_CR11,  on ? 0x00 : 0x04);
1061	(void)zyd_write16(sc, ZYD_CR251, on ? on251 : 0x2f);
1062
1063	return 0;
1064}
1065
1066Static int
1067zyd_al2230_set_channel(struct zyd_rf *rf, uint8_t chan)
1068{
1069	struct zyd_softc *sc = rf->rf_sc;
1070	static const struct {
1071		uint32_t	r1, r2, r3;
1072	} rfprog[] = ZYD_AL2230_CHANTABLE;
1073
1074	(void)zyd_rfwrite(sc, rfprog[chan - 1].r1);
1075	(void)zyd_rfwrite(sc, rfprog[chan - 1].r2);
1076	(void)zyd_rfwrite(sc, rfprog[chan - 1].r3);
1077
1078	(void)zyd_write16(sc, ZYD_CR138, 0x28);
1079	(void)zyd_write16(sc, ZYD_CR203, 0x06);
1080
1081	return 0;
1082}
1083
1084/*
1085 * AL7230B RF methods.
1086 */
1087Static int
1088zyd_al7230B_init(struct zyd_rf *rf)
1089{
1090	struct zyd_softc *sc = rf->rf_sc;
1091	static const struct zyd_phy_pair phyini_1[] = ZYD_AL7230B_PHY_1;
1092	static const struct zyd_phy_pair phyini_2[] = ZYD_AL7230B_PHY_2;
1093	static const struct zyd_phy_pair phyini_3[] = ZYD_AL7230B_PHY_3;
1094	static const uint32_t rfini_1[] = ZYD_AL7230B_RF_1;
1095	static const uint32_t rfini_2[] = ZYD_AL7230B_RF_2;
1096	int error;
1097	size_t i;
1098
1099	/* for AL7230B, PHY and RF need to be initialized in "phases" */
1100
1101	/* init RF-dependent PHY registers, part one */
1102	for (i = 0; i < __arraycount(phyini_1); i++) {
1103		error = zyd_write16(sc, phyini_1[i].reg, phyini_1[i].val);
1104		if (error != 0)
1105			return error;
1106	}
1107	/* init AL7230B radio, part one */
1108	for (i = 0; i < __arraycount(rfini_1); i++) {
1109		if ((error = zyd_rfwrite(sc, rfini_1[i])) != 0)
1110			return error;
1111	}
1112	/* init RF-dependent PHY registers, part two */
1113	for (i = 0; i < __arraycount(phyini_2); i++) {
1114		error = zyd_write16(sc, phyini_2[i].reg, phyini_2[i].val);
1115		if (error != 0)
1116			return error;
1117	}
1118	/* init AL7230B radio, part two */
1119	for (i = 0; i < __arraycount(rfini_2); i++) {
1120		if ((error = zyd_rfwrite(sc, rfini_2[i])) != 0)
1121			return error;
1122	}
1123	/* init RF-dependent PHY registers, part three */
1124	for (i = 0; i < __arraycount(phyini_3); i++) {
1125		error = zyd_write16(sc, phyini_3[i].reg, phyini_3[i].val);
1126		if (error != 0)
1127			return error;
1128	}
1129
1130	return 0;
1131}
1132
1133Static int
1134zyd_al7230B_switch_radio(struct zyd_rf *rf, int on)
1135{
1136	struct zyd_softc *sc = rf->rf_sc;
1137
1138	(void)zyd_write16(sc, ZYD_CR11,  on ? 0x00 : 0x04);
1139	(void)zyd_write16(sc, ZYD_CR251, on ? 0x3f : 0x2f);
1140
1141	return 0;
1142}
1143
1144Static int
1145zyd_al7230B_set_channel(struct zyd_rf *rf, uint8_t chan)
1146{
1147	struct zyd_softc *sc = rf->rf_sc;
1148	static const struct {
1149		uint32_t	r1, r2;
1150	} rfprog[] = ZYD_AL7230B_CHANTABLE;
1151	static const uint32_t rfsc[] = ZYD_AL7230B_RF_SETCHANNEL;
1152	int error;
1153	size_t i;
1154
1155	(void)zyd_write16(sc, ZYD_CR240, 0x57);
1156	(void)zyd_write16(sc, ZYD_CR251, 0x2f);
1157
1158	for (i = 0; i < __arraycount(rfsc); i++) {
1159		if ((error = zyd_rfwrite(sc, rfsc[i])) != 0)
1160			return error;
1161	}
1162
1163	(void)zyd_write16(sc, ZYD_CR128, 0x14);
1164	(void)zyd_write16(sc, ZYD_CR129, 0x12);
1165	(void)zyd_write16(sc, ZYD_CR130, 0x10);
1166	(void)zyd_write16(sc, ZYD_CR38,  0x38);
1167	(void)zyd_write16(sc, ZYD_CR136, 0xdf);
1168
1169	(void)zyd_rfwrite(sc, rfprog[chan - 1].r1);
1170	(void)zyd_rfwrite(sc, rfprog[chan - 1].r2);
1171	(void)zyd_rfwrite(sc, 0x3c9000);
1172
1173	(void)zyd_write16(sc, ZYD_CR251, 0x3f);
1174	(void)zyd_write16(sc, ZYD_CR203, 0x06);
1175	(void)zyd_write16(sc, ZYD_CR240, 0x08);
1176
1177	return 0;
1178}
1179
1180/*
1181 * AL2210 RF methods.
1182 */
1183Static int
1184zyd_al2210_init(struct zyd_rf *rf)
1185{
1186	struct zyd_softc *sc = rf->rf_sc;
1187	static const struct zyd_phy_pair phyini[] = ZYD_AL2210_PHY;
1188	static const uint32_t rfini[] = ZYD_AL2210_RF;
1189	uint32_t tmp;
1190	int error;
1191	size_t i;
1192
1193	(void)zyd_write32(sc, ZYD_CR18, 2);
1194
1195	/* init RF-dependent PHY registers */
1196	for (i = 0; i < __arraycount(phyini); i++) {
1197		error = zyd_write16(sc, phyini[i].reg, phyini[i].val);
1198		if (error != 0)
1199			return error;
1200	}
1201	/* init AL2210 radio */
1202	for (i = 0; i < __arraycount(rfini); i++) {
1203		if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
1204			return error;
1205	}
1206	(void)zyd_write16(sc, ZYD_CR47, 0x1e);
1207	(void)zyd_read32(sc, ZYD_CR_RADIO_PD, &tmp);
1208	(void)zyd_write32(sc, ZYD_CR_RADIO_PD, tmp & ~1);
1209	(void)zyd_write32(sc, ZYD_CR_RADIO_PD, tmp | 1);
1210	(void)zyd_write32(sc, ZYD_CR_RFCFG, 0x05);
1211	(void)zyd_write32(sc, ZYD_CR_RFCFG, 0x00);
1212	(void)zyd_write16(sc, ZYD_CR47, 0x1e);
1213	(void)zyd_write32(sc, ZYD_CR18, 3);
1214
1215	return 0;
1216}
1217
1218Static int
1219zyd_al2210_switch_radio(struct zyd_rf *rf, int on)
1220{
1221	/* vendor driver does nothing for this RF chip */
1222
1223	return 0;
1224}
1225
1226Static int
1227zyd_al2210_set_channel(struct zyd_rf *rf, uint8_t chan)
1228{
1229	struct zyd_softc *sc = rf->rf_sc;
1230	static const uint32_t rfprog[] = ZYD_AL2210_CHANTABLE;
1231	uint32_t tmp;
1232
1233	(void)zyd_write32(sc, ZYD_CR18, 2);
1234	(void)zyd_write16(sc, ZYD_CR47, 0x1e);
1235	(void)zyd_read32(sc, ZYD_CR_RADIO_PD, &tmp);
1236	(void)zyd_write32(sc, ZYD_CR_RADIO_PD, tmp & ~1);
1237	(void)zyd_write32(sc, ZYD_CR_RADIO_PD, tmp | 1);
1238	(void)zyd_write32(sc, ZYD_CR_RFCFG, 0x05);
1239
1240	(void)zyd_write32(sc, ZYD_CR_RFCFG, 0x00);
1241	(void)zyd_write16(sc, ZYD_CR47, 0x1e);
1242
1243	/* actually set the channel */
1244	(void)zyd_rfwrite(sc, rfprog[chan - 1]);
1245
1246	(void)zyd_write32(sc, ZYD_CR18, 3);
1247
1248	return 0;
1249}
1250
1251/*
1252 * GCT RF methods.
1253 */
1254Static int
1255zyd_gct_init(struct zyd_rf *rf)
1256{
1257	struct zyd_softc *sc = rf->rf_sc;
1258	static const struct zyd_phy_pair phyini[] = ZYD_GCT_PHY;
1259	static const uint32_t rfini[] = ZYD_GCT_RF;
1260	int error;
1261	size_t i;
1262
1263	/* init RF-dependent PHY registers */
1264	for (i = 0; i < __arraycount(phyini); i++) {
1265		error = zyd_write16(sc, phyini[i].reg, phyini[i].val);
1266		if (error != 0)
1267			return error;
1268	}
1269	/* init cgt radio */
1270	for (i = 0; i < __arraycount(rfini); i++) {
1271		if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
1272			return error;
1273	}
1274	return 0;
1275}
1276
1277Static int
1278zyd_gct_switch_radio(struct zyd_rf *rf, int on)
1279{
1280	/* vendor driver does nothing for this RF chip */
1281
1282	return 0;
1283}
1284
1285Static int
1286zyd_gct_set_channel(struct zyd_rf *rf, uint8_t chan)
1287{
1288	struct zyd_softc *sc = rf->rf_sc;
1289	static const uint32_t rfprog[] = ZYD_GCT_CHANTABLE;
1290
1291	(void)zyd_rfwrite(sc, 0x1c0000);
1292	(void)zyd_rfwrite(sc, rfprog[chan - 1]);
1293	(void)zyd_rfwrite(sc, 0x1c0008);
1294
1295	return 0;
1296}
1297
1298/*
1299 * Maxim RF methods.
1300 */
1301Static int
1302zyd_maxim_init(struct zyd_rf *rf)
1303{
1304	struct zyd_softc *sc = rf->rf_sc;
1305	static const struct zyd_phy_pair phyini[] = ZYD_MAXIM_PHY;
1306	static const uint32_t rfini[] = ZYD_MAXIM_RF;
1307	uint16_t tmp;
1308	int error;
1309	size_t i;
1310
1311	/* init RF-dependent PHY registers */
1312	for (i = 0; i < __arraycount(phyini); i++) {
1313		error = zyd_write16(sc, phyini[i].reg, phyini[i].val);
1314		if (error != 0)
1315			return error;
1316	}
1317	(void)zyd_read16(sc, ZYD_CR203, &tmp);
1318	(void)zyd_write16(sc, ZYD_CR203, tmp & ~(1 << 4));
1319
1320	/* init maxim radio */
1321	for (i = 0; i < __arraycount(rfini); i++) {
1322		if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
1323			return error;
1324	}
1325	(void)zyd_read16(sc, ZYD_CR203, &tmp);
1326	(void)zyd_write16(sc, ZYD_CR203, tmp | (1 << 4));
1327
1328	return 0;
1329}
1330
1331Static int
1332zyd_maxim_switch_radio(struct zyd_rf *rf, int on)
1333{
1334	/* vendor driver does nothing for this RF chip */
1335
1336	return 0;
1337}
1338
1339Static int
1340zyd_maxim_set_channel(struct zyd_rf *rf, uint8_t chan)
1341{
1342	struct zyd_softc *sc = rf->rf_sc;
1343	static const struct zyd_phy_pair phyini[] = ZYD_MAXIM_PHY;
1344	static const uint32_t rfini[] = ZYD_MAXIM_RF;
1345	static const struct {
1346		uint32_t	r1, r2;
1347	} rfprog[] = ZYD_MAXIM_CHANTABLE;
1348	uint16_t tmp;
1349	int error;
1350	size_t i;
1351
1352	/*
1353	 * Do the same as we do when initializing it, except for the channel
1354	 * values coming from the two channel tables.
1355	 */
1356
1357	/* init RF-dependent PHY registers */
1358	for (i = 0; i < __arraycount(phyini); i++) {
1359		error = zyd_write16(sc, phyini[i].reg, phyini[i].val);
1360		if (error != 0)
1361			return error;
1362	}
1363	(void)zyd_read16(sc, ZYD_CR203, &tmp);
1364	(void)zyd_write16(sc, ZYD_CR203, tmp & ~(1 << 4));
1365
1366	/* first two values taken from the chantables */
1367	(void)zyd_rfwrite(sc, rfprog[chan - 1].r1);
1368	(void)zyd_rfwrite(sc, rfprog[chan - 1].r2);
1369
1370	/* init maxim radio - skipping the two first values */
1371	for (i = 2; i < __arraycount(rfini); i++) {
1372		if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
1373			return error;
1374	}
1375	(void)zyd_read16(sc, ZYD_CR203, &tmp);
1376	(void)zyd_write16(sc, ZYD_CR203, tmp | (1 << 4));
1377
1378	return 0;
1379}
1380
1381/*
1382 * Maxim2 RF methods.
1383 */
1384Static int
1385zyd_maxim2_init(struct zyd_rf *rf)
1386{
1387	struct zyd_softc *sc = rf->rf_sc;
1388	static const struct zyd_phy_pair phyini[] = ZYD_MAXIM2_PHY;
1389	static const uint32_t rfini[] = ZYD_MAXIM2_RF;
1390	uint16_t tmp;
1391	int error;
1392	size_t i;
1393
1394	/* init RF-dependent PHY registers */
1395	for (i = 0; i < __arraycount(phyini); i++) {
1396		error = zyd_write16(sc, phyini[i].reg, phyini[i].val);
1397		if (error != 0)
1398			return error;
1399	}
1400	(void)zyd_read16(sc, ZYD_CR203, &tmp);
1401	(void)zyd_write16(sc, ZYD_CR203, tmp & ~(1 << 4));
1402
1403	/* init maxim2 radio */
1404	for (i = 0; i < __arraycount(rfini); i++) {
1405		if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
1406			return error;
1407	}
1408	(void)zyd_read16(sc, ZYD_CR203, &tmp);
1409	(void)zyd_write16(sc, ZYD_CR203, tmp | (1 << 4));
1410
1411	return 0;
1412}
1413
1414Static int
1415zyd_maxim2_switch_radio(struct zyd_rf *rf, int on)
1416{
1417	/* vendor driver does nothing for this RF chip */
1418
1419	return 0;
1420}
1421
1422Static int
1423zyd_maxim2_set_channel(struct zyd_rf *rf, uint8_t chan)
1424{
1425	struct zyd_softc *sc = rf->rf_sc;
1426	static const struct zyd_phy_pair phyini[] = ZYD_MAXIM2_PHY;
1427	static const uint32_t rfini[] = ZYD_MAXIM2_RF;
1428	static const struct {
1429		uint32_t	r1, r2;
1430	} rfprog[] = ZYD_MAXIM2_CHANTABLE;
1431	uint16_t tmp;
1432	int error;
1433	size_t i;
1434
1435	/*
1436	 * Do the same as we do when initializing it, except for the channel
1437	 * values coming from the two channel tables.
1438	 */
1439
1440	/* init RF-dependent PHY registers */
1441	for (i = 0; i < __arraycount(phyini); i++) {
1442		error = zyd_write16(sc, phyini[i].reg, phyini[i].val);
1443		if (error != 0)
1444			return error;
1445	}
1446	(void)zyd_read16(sc, ZYD_CR203, &tmp);
1447	(void)zyd_write16(sc, ZYD_CR203, tmp & ~(1 << 4));
1448
1449	/* first two values taken from the chantables */
1450	(void)zyd_rfwrite(sc, rfprog[chan - 1].r1);
1451	(void)zyd_rfwrite(sc, rfprog[chan - 1].r2);
1452
1453	/* init maxim2 radio - skipping the two first values */
1454	for (i = 2; i < __arraycount(rfini); i++) {
1455		if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
1456			return error;
1457	}
1458	(void)zyd_read16(sc, ZYD_CR203, &tmp);
1459	(void)zyd_write16(sc, ZYD_CR203, tmp | (1 << 4));
1460
1461	return 0;
1462}
1463
1464Static int
1465zyd_rf_attach(struct zyd_softc *sc, uint8_t type)
1466{
1467	struct zyd_rf *rf = &sc->sc_rf;
1468
1469	rf->rf_sc = sc;
1470
1471	switch (type) {
1472	case ZYD_RF_RFMD:
1473		rf->init         = zyd_rfmd_init;
1474		rf->switch_radio = zyd_rfmd_switch_radio;
1475		rf->set_channel  = zyd_rfmd_set_channel;
1476		rf->width        = 24;	/* 24-bit RF values */
1477		break;
1478	case ZYD_RF_AL2230:
1479	case ZYD_RF_AL2230S:
1480		if (sc->mac_rev == ZYD_ZD1211B)
1481			rf->init = zyd_al2230_init_b;
1482		else
1483			rf->init = zyd_al2230_init;
1484		rf->switch_radio = zyd_al2230_switch_radio;
1485		rf->set_channel  = zyd_al2230_set_channel;
1486		rf->width        = 24;	/* 24-bit RF values */
1487		break;
1488	case ZYD_RF_AL7230B:
1489		rf->init         = zyd_al7230B_init;
1490		rf->switch_radio = zyd_al7230B_switch_radio;
1491		rf->set_channel  = zyd_al7230B_set_channel;
1492		rf->width        = 24;	/* 24-bit RF values */
1493		break;
1494	case ZYD_RF_AL2210:
1495		rf->init         = zyd_al2210_init;
1496		rf->switch_radio = zyd_al2210_switch_radio;
1497		rf->set_channel  = zyd_al2210_set_channel;
1498		rf->width        = 24;	/* 24-bit RF values */
1499		break;
1500	case ZYD_RF_GCT:
1501		rf->init         = zyd_gct_init;
1502		rf->switch_radio = zyd_gct_switch_radio;
1503		rf->set_channel  = zyd_gct_set_channel;
1504		rf->width        = 21;	/* 21-bit RF values */
1505		break;
1506	case ZYD_RF_MAXIM_NEW:
1507		rf->init         = zyd_maxim_init;
1508		rf->switch_radio = zyd_maxim_switch_radio;
1509		rf->set_channel  = zyd_maxim_set_channel;
1510		rf->width        = 18;	/* 18-bit RF values */
1511		break;
1512	case ZYD_RF_MAXIM_NEW2:
1513		rf->init         = zyd_maxim2_init;
1514		rf->switch_radio = zyd_maxim2_switch_radio;
1515		rf->set_channel  = zyd_maxim2_set_channel;
1516		rf->width        = 18;	/* 18-bit RF values */
1517		break;
1518	default:
1519		printf("%s: sorry, radio \"%s\" is not supported yet\n",
1520		    device_xname(sc->sc_dev), zyd_rf_name(type));
1521		return EINVAL;
1522	}
1523	return 0;
1524}
1525
1526Static const char *
1527zyd_rf_name(uint8_t type)
1528{
1529	static const char * const zyd_rfs[] = {
1530		"unknown", "unknown", "UW2451",   "UCHIP",     "AL2230",
1531		"AL7230B", "THETA",   "AL2210",   "MAXIM_NEW", "GCT",
1532		"AL2230S", "RALINK",  "INTERSIL", "RFMD",      "MAXIM_NEW2",
1533		"PHILIPS"
1534	};
1535
1536	return zyd_rfs[(type > 15) ? 0 : type];
1537}
1538
1539Static int
1540zyd_hw_init(struct zyd_softc *sc)
1541{
1542	struct zyd_rf *rf = &sc->sc_rf;
1543	const struct zyd_phy_pair *phyp;
1544	int error;
1545
1546	/* specify that the plug and play is finished */
1547	(void)zyd_write32(sc, ZYD_MAC_AFTER_PNP, 1);
1548
1549	(void)zyd_read16(sc, ZYD_FIRMWARE_BASE_ADDR, &sc->fwbase);
1550	DPRINTF(("firmware base address=0x%04x\n", sc->fwbase));
1551
1552	/* retrieve firmware revision number */
1553	(void)zyd_read16(sc, sc->fwbase + ZYD_FW_FIRMWARE_REV, &sc->fw_rev);
1554
1555	(void)zyd_write32(sc, ZYD_CR_GPI_EN, 0);
1556	(void)zyd_write32(sc, ZYD_MAC_CONT_WIN_LIMIT, 0x7f043f);
1557
1558	/* disable interrupts */
1559	(void)zyd_write32(sc, ZYD_CR_INTERRUPT, 0);
1560
1561	/* PHY init */
1562	zyd_lock_phy(sc);
1563	phyp = (sc->mac_rev == ZYD_ZD1211B) ? zyd_def_phyB : zyd_def_phy;
1564	for (; phyp->reg != 0; phyp++) {
1565		if ((error = zyd_write16(sc, phyp->reg, phyp->val)) != 0)
1566			goto fail;
1567	}
1568	zyd_unlock_phy(sc);
1569
1570	/* HMAC init */
1571	zyd_write32(sc, ZYD_MAC_ACK_EXT, 0x00000020);
1572	zyd_write32(sc, ZYD_CR_ADDA_MBIAS_WT, 0x30000808);
1573
1574	if (sc->mac_rev == ZYD_ZD1211) {
1575		zyd_write32(sc, ZYD_MAC_RETRY, 0x00000002);
1576	} else {
1577		zyd_write32(sc, ZYD_MAC_RETRY, 0x02020202);
1578		zyd_write32(sc, ZYD_MACB_TXPWR_CTL4, 0x007f003f);
1579		zyd_write32(sc, ZYD_MACB_TXPWR_CTL3, 0x007f003f);
1580		zyd_write32(sc, ZYD_MACB_TXPWR_CTL2, 0x003f001f);
1581		zyd_write32(sc, ZYD_MACB_TXPWR_CTL1, 0x001f000f);
1582		zyd_write32(sc, ZYD_MACB_AIFS_CTL1, 0x00280028);
1583		zyd_write32(sc, ZYD_MACB_AIFS_CTL2, 0x008C003C);
1584		zyd_write32(sc, ZYD_MACB_TXOP, 0x01800824);
1585	}
1586
1587	zyd_write32(sc, ZYD_MAC_SNIFFER, 0x00000000);
1588	zyd_write32(sc, ZYD_MAC_RXFILTER, 0x00000000);
1589	zyd_write32(sc, ZYD_MAC_GHTBL, 0x00000000);
1590	zyd_write32(sc, ZYD_MAC_GHTBH, 0x80000000);
1591	zyd_write32(sc, ZYD_MAC_MISC, 0x000000a4);
1592	zyd_write32(sc, ZYD_CR_ADDA_PWR_DWN, 0x0000007f);
1593	zyd_write32(sc, ZYD_MAC_BCNCFG, 0x00f00401);
1594	zyd_write32(sc, ZYD_MAC_PHY_DELAY2, 0x00000000);
1595	zyd_write32(sc, ZYD_MAC_ACK_EXT, 0x00000080);
1596	zyd_write32(sc, ZYD_CR_ADDA_PWR_DWN, 0x00000000);
1597	zyd_write32(sc, ZYD_MAC_SIFS_ACK_TIME, 0x00000100);
1598	zyd_write32(sc, ZYD_MAC_DIFS_EIFS_SIFS, 0x0547c032);
1599	zyd_write32(sc, ZYD_CR_RX_PE_DELAY, 0x00000070);
1600	zyd_write32(sc, ZYD_CR_PS_CTRL, 0x10000000);
1601	zyd_write32(sc, ZYD_MAC_RTSCTSRATE, 0x02030203);
1602	zyd_write32(sc, ZYD_MAC_RX_THRESHOLD, 0x000c0640);
1603	zyd_write32(sc, ZYD_MAC_BACKOFF_PROTECT, 0x00000114);
1604
1605	/* RF chip init */
1606	zyd_lock_phy(sc);
1607	error = (*rf->init)(rf);
1608	zyd_unlock_phy(sc);
1609	if (error != 0) {
1610		printf("%s: radio initialization failed\n",
1611		    device_xname(sc->sc_dev));
1612		goto fail;
1613	}
1614
1615	/* init beacon interval to 100ms */
1616	if ((error = zyd_set_beacon_interval(sc, 100)) != 0)
1617		goto fail;
1618
1619fail:	return error;
1620}
1621
1622Static int
1623zyd_read_eeprom(struct zyd_softc *sc)
1624{
1625	struct ieee80211com *ic = &sc->sc_ic;
1626	uint32_t tmp;
1627	uint16_t val;
1628	int i;
1629
1630	/* read MAC address */
1631	(void)zyd_read32(sc, ZYD_EEPROM_MAC_ADDR_P1, &tmp);
1632	ic->ic_myaddr[0] = tmp & 0xff;
1633	ic->ic_myaddr[1] = tmp >>  8;
1634	ic->ic_myaddr[2] = tmp >> 16;
1635	ic->ic_myaddr[3] = tmp >> 24;
1636	(void)zyd_read32(sc, ZYD_EEPROM_MAC_ADDR_P2, &tmp);
1637	ic->ic_myaddr[4] = tmp & 0xff;
1638	ic->ic_myaddr[5] = tmp >>  8;
1639
1640	(void)zyd_read32(sc, ZYD_EEPROM_POD, &tmp);
1641	sc->rf_rev = tmp & 0x0f;
1642	sc->pa_rev = (tmp >> 16) & 0x0f;
1643
1644	/* read regulatory domain (currently unused) */
1645	(void)zyd_read32(sc, ZYD_EEPROM_SUBID, &tmp);
1646	sc->regdomain = tmp >> 16;
1647	DPRINTF(("regulatory domain %x\n", sc->regdomain));
1648
1649	/* read Tx power calibration tables */
1650	for (i = 0; i < 7; i++) {
1651		(void)zyd_read16(sc, ZYD_EEPROM_PWR_CAL + i, &val);
1652		sc->pwr_cal[i * 2] = val >> 8;
1653		sc->pwr_cal[i * 2 + 1] = val & 0xff;
1654
1655		(void)zyd_read16(sc, ZYD_EEPROM_PWR_INT + i, &val);
1656		sc->pwr_int[i * 2] = val >> 8;
1657		sc->pwr_int[i * 2 + 1] = val & 0xff;
1658
1659		(void)zyd_read16(sc, ZYD_EEPROM_36M_CAL + i, &val);
1660		sc->ofdm36_cal[i * 2] = val >> 8;
1661		sc->ofdm36_cal[i * 2 + 1] = val & 0xff;
1662
1663		(void)zyd_read16(sc, ZYD_EEPROM_48M_CAL + i, &val);
1664		sc->ofdm48_cal[i * 2] = val >> 8;
1665		sc->ofdm48_cal[i * 2 + 1] = val & 0xff;
1666
1667		(void)zyd_read16(sc, ZYD_EEPROM_54M_CAL + i, &val);
1668		sc->ofdm54_cal[i * 2] = val >> 8;
1669		sc->ofdm54_cal[i * 2 + 1] = val & 0xff;
1670	}
1671	return 0;
1672}
1673
1674Static int
1675zyd_set_macaddr(struct zyd_softc *sc, const uint8_t *addr)
1676{
1677	uint32_t tmp;
1678
1679	tmp = addr[3] << 24 | addr[2] << 16 | addr[1] << 8 | addr[0];
1680	(void)zyd_write32(sc, ZYD_MAC_MACADRL, tmp);
1681
1682	tmp = addr[5] << 8 | addr[4];
1683	(void)zyd_write32(sc, ZYD_MAC_MACADRH, tmp);
1684
1685	return 0;
1686}
1687
1688Static int
1689zyd_set_bssid(struct zyd_softc *sc, const uint8_t *addr)
1690{
1691	uint32_t tmp;
1692
1693	tmp = addr[3] << 24 | addr[2] << 16 | addr[1] << 8 | addr[0];
1694	(void)zyd_write32(sc, ZYD_MAC_BSSADRL, tmp);
1695
1696	tmp = addr[5] << 8 | addr[4];
1697	(void)zyd_write32(sc, ZYD_MAC_BSSADRH, tmp);
1698
1699	return 0;
1700}
1701
1702Static int
1703zyd_switch_radio(struct zyd_softc *sc, int on)
1704{
1705	struct zyd_rf *rf = &sc->sc_rf;
1706	int error;
1707
1708	zyd_lock_phy(sc);
1709	error = (*rf->switch_radio)(rf, on);
1710	zyd_unlock_phy(sc);
1711
1712	return error;
1713}
1714
1715Static void
1716zyd_set_led(struct zyd_softc *sc, int which, int on)
1717{
1718	uint32_t tmp;
1719
1720	(void)zyd_read32(sc, ZYD_MAC_TX_PE_CONTROL, &tmp);
1721	tmp &= ~which;
1722	if (on)
1723		tmp |= which;
1724	(void)zyd_write32(sc, ZYD_MAC_TX_PE_CONTROL, tmp);
1725}
1726
1727Static int
1728zyd_set_rxfilter(struct zyd_softc *sc)
1729{
1730	uint32_t rxfilter;
1731
1732	switch (sc->sc_ic.ic_opmode) {
1733	case IEEE80211_M_STA:
1734		rxfilter = ZYD_FILTER_BSS;
1735		break;
1736	case IEEE80211_M_IBSS:
1737	case IEEE80211_M_HOSTAP:
1738		rxfilter = ZYD_FILTER_HOSTAP;
1739		break;
1740	case IEEE80211_M_MONITOR:
1741		rxfilter = ZYD_FILTER_MONITOR;
1742		break;
1743	default:
1744		/* should not get there */
1745		return EINVAL;
1746	}
1747	return zyd_write32(sc, ZYD_MAC_RXFILTER, rxfilter);
1748}
1749
1750Static void
1751zyd_set_chan(struct zyd_softc *sc, struct ieee80211_channel *c)
1752{
1753	struct ieee80211com *ic = &sc->sc_ic;
1754	struct zyd_rf *rf = &sc->sc_rf;
1755	u_int chan;
1756
1757	chan = ieee80211_chan2ieee(ic, c);
1758	if (chan == 0 || chan == IEEE80211_CHAN_ANY)
1759		return;
1760
1761	zyd_lock_phy(sc);
1762
1763	(*rf->set_channel)(rf, chan);
1764
1765	/* update Tx power */
1766	(void)zyd_write32(sc, ZYD_CR31, sc->pwr_int[chan - 1]);
1767	(void)zyd_write32(sc, ZYD_CR68, sc->pwr_cal[chan - 1]);
1768
1769	if (sc->mac_rev == ZYD_ZD1211B) {
1770		(void)zyd_write32(sc, ZYD_CR67, sc->ofdm36_cal[chan - 1]);
1771		(void)zyd_write32(sc, ZYD_CR66, sc->ofdm48_cal[chan - 1]);
1772		(void)zyd_write32(sc, ZYD_CR65, sc->ofdm54_cal[chan - 1]);
1773
1774		(void)zyd_write32(sc, ZYD_CR69, 0x28);
1775		(void)zyd_write32(sc, ZYD_CR69, 0x2a);
1776	}
1777
1778	zyd_unlock_phy(sc);
1779}
1780
1781Static int
1782zyd_set_beacon_interval(struct zyd_softc *sc, int bintval)
1783{
1784	/* XXX this is probably broken.. */
1785	(void)zyd_write32(sc, ZYD_CR_ATIM_WND_PERIOD, bintval - 2);
1786	(void)zyd_write32(sc, ZYD_CR_PRE_TBTT,        bintval - 1);
1787	(void)zyd_write32(sc, ZYD_CR_BCN_INTERVAL,    bintval);
1788
1789	return 0;
1790}
1791
1792Static uint8_t
1793zyd_plcp_signal(int rate)
1794{
1795	switch (rate) {
1796	/* CCK rates (returned values are device-dependent) */
1797	case 2:		return 0x0;
1798	case 4:		return 0x1;
1799	case 11:	return 0x2;
1800	case 22:	return 0x3;
1801
1802	/* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
1803	case 12:	return 0xb;
1804	case 18:	return 0xf;
1805	case 24:	return 0xa;
1806	case 36:	return 0xe;
1807	case 48:	return 0x9;
1808	case 72:	return 0xd;
1809	case 96:	return 0x8;
1810	case 108:	return 0xc;
1811
1812	/* unsupported rates (should not get there) */
1813	default:	return 0xff;
1814	}
1815}
1816
1817Static void
1818zyd_intr(struct usbd_xfer *xfer, void * priv, usbd_status status)
1819{
1820	struct zyd_softc *sc = (struct zyd_softc *)priv;
1821	struct zyd_cmd *cmd;
1822	uint32_t datalen;
1823
1824	if (status != USBD_NORMAL_COMPLETION) {
1825		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
1826			return;
1827
1828		if (status == USBD_STALLED) {
1829			usbd_clear_endpoint_stall_async(
1830			    sc->zyd_ep[ZYD_ENDPT_IIN]);
1831		}
1832		return;
1833	}
1834
1835	cmd = (struct zyd_cmd *)sc->ibuf;
1836
1837	if (le16toh(cmd->code) == ZYD_NOTIF_RETRYSTATUS) {
1838		struct zyd_notif_retry *retry =
1839		    (struct zyd_notif_retry *)cmd->data;
1840		struct ieee80211com *ic = &sc->sc_ic;
1841		struct ifnet *ifp = &sc->sc_if;
1842		struct ieee80211_node *ni;
1843
1844		DPRINTF(("retry intr: rate=%#x addr=%s count=%d (%#x)\n",
1845		    le16toh(retry->rate), ether_sprintf(retry->macaddr),
1846		    le16toh(retry->count) & 0xff, le16toh(retry->count)));
1847
1848		/*
1849		 * Find the node to which the packet was sent and update its
1850		 * retry statistics.  In BSS mode, this node is the AP we're
1851		 * associated to so no lookup is actually needed.
1852		 */
1853		if (ic->ic_opmode != IEEE80211_M_STA) {
1854			ni = ieee80211_find_node(&ic->ic_scan, retry->macaddr);
1855			if (ni == NULL)
1856				return;	/* just ignore */
1857		} else
1858			ni = ic->ic_bss;
1859
1860		((struct zyd_node *)ni)->amn.amn_retrycnt++;
1861
1862		if (le16toh(retry->count) & 0x100)
1863			if_statinc(ifp, if_oerrors);
1864
1865	} else if (le16toh(cmd->code) == ZYD_NOTIF_IORD) {
1866		struct rq *rqp;
1867
1868		if (le16toh(*(uint16_t *)cmd->data) == ZYD_CR_INTERRUPT)
1869			return;	/* HMAC interrupt */
1870
1871		usbd_get_xfer_status(xfer, NULL, NULL, &datalen, NULL);
1872		datalen -= sizeof(cmd->code);
1873		datalen -= 2;	/* XXX: padding? */
1874
1875		mutex_enter(&sc->sc_lock);
1876		SIMPLEQ_FOREACH(rqp, &sc->sc_rqh, rq) {
1877			int i;
1878
1879			if (sizeof(struct zyd_pair) * rqp->len != datalen)
1880				continue;
1881			for (i = 0; i < rqp->len; i++) {
1882				if (*(((const uint16_t *)rqp->idata) + i) !=
1883				    (((struct zyd_pair *)cmd->data) + i)->reg)
1884					break;
1885			}
1886			if (i != rqp->len)
1887				continue;
1888
1889			/* copy answer into caller-supplied buffer */
1890			memcpy(rqp->odata, cmd->data,
1891			    sizeof(struct zyd_pair) * rqp->len);
1892			cv_signal(&sc->sc_cmdcv);
1893			mutex_exit(&sc->sc_lock);
1894			return;
1895		}
1896		mutex_exit(&sc->sc_lock);
1897		return;	/* unexpected IORD notification */
1898	} else {
1899		printf("%s: unknown notification %x\n", device_xname(sc->sc_dev),
1900		    le16toh(cmd->code));
1901	}
1902}
1903
1904Static void
1905zyd_rx_data(struct zyd_softc *sc, const uint8_t *buf, uint16_t len)
1906{
1907	struct ieee80211com *ic = &sc->sc_ic;
1908	struct ifnet *ifp = &sc->sc_if;
1909	struct ieee80211_node *ni;
1910	struct ieee80211_frame *wh;
1911	const struct zyd_plcphdr *plcp;
1912	const struct zyd_rx_stat *stat;
1913	struct mbuf *m;
1914	int rlen, s;
1915
1916	if (len < ZYD_MIN_FRAGSZ) {
1917		printf("%s: frame too short (length=%d)\n",
1918		    device_xname(sc->sc_dev), len);
1919		if_statinc(ifp, if_ierrors);
1920		return;
1921	}
1922
1923	plcp = (const struct zyd_plcphdr *)buf;
1924	stat = (const struct zyd_rx_stat *)
1925	    (buf + len - sizeof(struct zyd_rx_stat));
1926
1927	if (stat->flags & ZYD_RX_ERROR) {
1928		DPRINTF(("%s: RX status indicated error (%x)\n",
1929		    device_xname(sc->sc_dev), stat->flags));
1930		if_statinc(ifp, if_ierrors);
1931		return;
1932	}
1933
1934	/* compute actual frame length */
1935	rlen = len - sizeof(struct zyd_plcphdr) -
1936	    sizeof(struct zyd_rx_stat) - IEEE80211_CRC_LEN;
1937
1938	/* allocate a mbuf to store the frame */
1939	MGETHDR(m, M_DONTWAIT, MT_DATA);
1940	if (m == NULL) {
1941		printf("%s: could not allocate rx mbuf\n",
1942		    device_xname(sc->sc_dev));
1943		if_statinc(ifp, if_ierrors);
1944		return;
1945	}
1946	if (rlen > MHLEN) {
1947		MCLGET(m, M_DONTWAIT);
1948		if (!(m->m_flags & M_EXT)) {
1949			printf("%s: could not allocate rx mbuf cluster\n",
1950			    device_xname(sc->sc_dev));
1951			m_freem(m);
1952			if_statinc(ifp, if_ierrors);
1953			return;
1954		}
1955	}
1956	m_set_rcvif(m, ifp);
1957	m->m_pkthdr.len = m->m_len = rlen;
1958	memcpy(mtod(m, uint8_t *), (const uint8_t *)(plcp + 1), rlen);
1959
1960	s = splnet();
1961
1962	if (sc->sc_drvbpf != NULL) {
1963		struct zyd_rx_radiotap_header *tap = &sc->sc_rxtap;
1964		static const uint8_t rates[] = {
1965			/* reverse function of zyd_plcp_signal() */
1966			2, 4, 11, 22, 0, 0, 0, 0,
1967			96, 48, 24, 12, 108, 72, 36, 18
1968		};
1969
1970		tap->wr_flags = IEEE80211_RADIOTAP_F_FCS;
1971		tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
1972		tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
1973		tap->wr_rssi = stat->rssi;
1974		tap->wr_rate = rates[plcp->signal & 0xf];
1975
1976		bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m, BPF_D_IN);
1977	}
1978
1979	wh = mtod(m, struct ieee80211_frame *);
1980	ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh);
1981	ieee80211_input(ic, m, ni, stat->rssi, 0);
1982
1983	/* node is no longer needed */
1984	ieee80211_free_node(ni);
1985
1986	splx(s);
1987}
1988
1989Static void
1990zyd_rxeof(struct usbd_xfer *xfer, void * priv, usbd_status status)
1991{
1992	struct zyd_rx_data *data = priv;
1993	struct zyd_softc *sc = data->sc;
1994	struct ifnet *ifp = &sc->sc_if;
1995	const struct zyd_rx_desc *desc;
1996	int len;
1997
1998	if (status != USBD_NORMAL_COMPLETION) {
1999		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
2000			return;
2001
2002		if (status == USBD_STALLED)
2003			usbd_clear_endpoint_stall(sc->zyd_ep[ZYD_ENDPT_BIN]);
2004
2005		goto skip;
2006	}
2007	usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL);
2008
2009	if (len < ZYD_MIN_RXBUFSZ) {
2010		printf("%s: xfer too short (length=%d)\n",
2011		    device_xname(sc->sc_dev), len);
2012		if_statinc(ifp, if_ierrors);
2013		goto skip;
2014	}
2015
2016	desc = (const struct zyd_rx_desc *)
2017	    (data->buf + len - sizeof(struct zyd_rx_desc));
2018
2019	if (UGETW(desc->tag) == ZYD_TAG_MULTIFRAME) {
2020		const uint8_t *p = data->buf, *end = p + len;
2021		int i;
2022
2023		DPRINTFN(3, ("received multi-frame transfer\n"));
2024
2025		for (i = 0; i < ZYD_MAX_RXFRAMECNT; i++) {
2026			const uint16_t len16 = UGETW(desc->len[i]);
2027
2028			if (len16 == 0 || p + len16 > end)
2029				break;
2030
2031			zyd_rx_data(sc, p, len16);
2032			/* next frame is aligned on a 32-bit boundary */
2033			p += (len16 + 3) & ~3;
2034		}
2035	} else {
2036		DPRINTFN(3, ("received single-frame transfer\n"));
2037
2038		zyd_rx_data(sc, data->buf, len);
2039	}
2040
2041skip:	/* setup a new transfer */
2042
2043	usbd_setup_xfer(xfer, data, NULL, ZYX_MAX_RXBUFSZ, USBD_SHORT_XFER_OK,
2044	    USBD_NO_TIMEOUT, zyd_rxeof);
2045	(void)usbd_transfer(xfer);
2046}
2047
2048Static int
2049zyd_tx_mgt(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
2050{
2051	struct ieee80211com *ic = &sc->sc_ic;
2052	struct ifnet *ifp = &sc->sc_if;
2053	struct zyd_tx_desc *desc;
2054	struct zyd_tx_data *data;
2055	struct ieee80211_frame *wh;
2056	struct ieee80211_key *k;
2057	int xferlen, totlen, rate;
2058	uint16_t pktlen;
2059	usbd_status error;
2060
2061	data = &sc->tx_data[0];
2062	desc = (struct zyd_tx_desc *)data->buf;
2063
2064	rate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 2;
2065
2066	wh = mtod(m0, struct ieee80211_frame *);
2067
2068	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
2069		k = ieee80211_crypto_encap(ic, ni, m0);
2070		if (k == NULL) {
2071			m_freem(m0);
2072			return ENOBUFS;
2073		}
2074	}
2075
2076	data->ni = ni;
2077
2078	wh = mtod(m0, struct ieee80211_frame *);
2079
2080	xferlen = sizeof(struct zyd_tx_desc) + m0->m_pkthdr.len;
2081	totlen = m0->m_pkthdr.len + IEEE80211_CRC_LEN;
2082
2083	/* fill Tx descriptor */
2084	desc->len = htole16(totlen);
2085
2086	desc->flags = ZYD_TX_FLAG_BACKOFF;
2087	if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
2088		/* multicast frames are not sent at OFDM rates in 802.11b/g */
2089		if (totlen > ic->ic_rtsthreshold) {
2090			desc->flags |= ZYD_TX_FLAG_RTS;
2091		} else if (ZYD_RATE_IS_OFDM(rate) &&
2092		    (ic->ic_flags & IEEE80211_F_USEPROT)) {
2093			if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
2094				desc->flags |= ZYD_TX_FLAG_CTS_TO_SELF;
2095			else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
2096				desc->flags |= ZYD_TX_FLAG_RTS;
2097		}
2098	} else
2099		desc->flags |= ZYD_TX_FLAG_MULTICAST;
2100
2101	if ((wh->i_fc[0] &
2102	    (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
2103	    (IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_PS_POLL))
2104		desc->flags |= ZYD_TX_FLAG_TYPE(ZYD_TX_TYPE_PS_POLL);
2105
2106	desc->phy = zyd_plcp_signal(rate);
2107	if (ZYD_RATE_IS_OFDM(rate)) {
2108		desc->phy |= ZYD_TX_PHY_OFDM;
2109		if (ic->ic_curmode == IEEE80211_MODE_11A)
2110			desc->phy |= ZYD_TX_PHY_5GHZ;
2111	} else if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
2112		desc->phy |= ZYD_TX_PHY_SHPREAMBLE;
2113
2114	/* actual transmit length (XXX why +10?) */
2115	pktlen = sizeof(struct zyd_tx_desc) + 10;
2116	if (sc->mac_rev == ZYD_ZD1211)
2117		pktlen += totlen;
2118	desc->pktlen = htole16(pktlen);
2119
2120	desc->plcp_length = (16 * totlen + rate - 1) / rate;
2121	desc->plcp_service = 0;
2122	if (rate == 22) {
2123		const int remainder = (16 * totlen) % 22;
2124		if (remainder != 0 && remainder < 7)
2125			desc->plcp_service |= ZYD_PLCP_LENGEXT;
2126	}
2127
2128	if (sc->sc_drvbpf != NULL) {
2129		struct zyd_tx_radiotap_header *tap = &sc->sc_txtap;
2130
2131		tap->wt_flags = 0;
2132		tap->wt_rate = rate;
2133		tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
2134		tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
2135
2136		bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0, BPF_D_OUT);
2137	}
2138
2139	m_copydata(m0, 0, m0->m_pkthdr.len,
2140	    data->buf + sizeof(struct zyd_tx_desc));
2141
2142	DPRINTFN(10, ("%s: sending mgt frame len=%zu rate=%u xferlen=%u\n",
2143	    device_xname(sc->sc_dev), (size_t)m0->m_pkthdr.len, rate, xferlen));
2144
2145	m_freem(m0);	/* mbuf no longer needed */
2146
2147	usbd_setup_xfer(data->xfer, data, data->buf, xferlen,
2148	    USBD_FORCE_SHORT_XFER, ZYD_TX_TIMEOUT, zyd_txeof);
2149	error = usbd_transfer(data->xfer);
2150	if (error != USBD_IN_PROGRESS && error != 0) {
2151		if_statinc(ifp, if_oerrors);
2152		return EIO;
2153	}
2154	sc->tx_queued++;
2155
2156	return 0;
2157}
2158
2159Static void
2160zyd_txeof(struct usbd_xfer *xfer, void * priv, usbd_status status)
2161{
2162	struct zyd_tx_data *data = priv;
2163	struct zyd_softc *sc = data->sc;
2164	struct ifnet *ifp = &sc->sc_if;
2165	int s;
2166
2167	if (status != USBD_NORMAL_COMPLETION) {
2168		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
2169			return;
2170
2171		printf("%s: could not transmit buffer: %s\n",
2172		    device_xname(sc->sc_dev), usbd_errstr(status));
2173
2174		if (status == USBD_STALLED) {
2175			usbd_clear_endpoint_stall_async(
2176			    sc->zyd_ep[ZYD_ENDPT_BOUT]);
2177		}
2178		if_statinc(ifp, if_oerrors);
2179		return;
2180	}
2181
2182	s = splnet();
2183
2184	/* update rate control statistics */
2185	((struct zyd_node *)data->ni)->amn.amn_txcnt++;
2186
2187	ieee80211_free_node(data->ni);
2188	data->ni = NULL;
2189
2190	sc->tx_queued--;
2191	if_statinc(ifp, if_opackets);
2192
2193	sc->tx_timer = 0;
2194	ifp->if_flags &= ~IFF_OACTIVE;
2195	zyd_start(ifp);
2196
2197	splx(s);
2198}
2199
2200Static int
2201zyd_tx_data(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
2202{
2203	struct ieee80211com *ic = &sc->sc_ic;
2204	struct ifnet *ifp = &sc->sc_if;
2205	struct zyd_tx_desc *desc;
2206	struct zyd_tx_data *data;
2207	struct ieee80211_frame *wh;
2208	struct ieee80211_key *k;
2209	int xferlen, totlen, rate;
2210	uint16_t pktlen;
2211	usbd_status error;
2212
2213	wh = mtod(m0, struct ieee80211_frame *);
2214
2215	if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE)
2216		rate = ic->ic_bss->ni_rates.rs_rates[ic->ic_fixed_rate];
2217	else
2218		rate = ni->ni_rates.rs_rates[ni->ni_txrate];
2219	rate &= IEEE80211_RATE_VAL;
2220
2221	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
2222		k = ieee80211_crypto_encap(ic, ni, m0);
2223		if (k == NULL) {
2224			m_freem(m0);
2225			return ENOBUFS;
2226		}
2227
2228		/* packet header may have moved, reset our local pointer */
2229		wh = mtod(m0, struct ieee80211_frame *);
2230	}
2231
2232	data = &sc->tx_data[0];
2233	desc = (struct zyd_tx_desc *)data->buf;
2234
2235	data->ni = ni;
2236
2237	xferlen = sizeof(struct zyd_tx_desc) + m0->m_pkthdr.len;
2238	totlen = m0->m_pkthdr.len + IEEE80211_CRC_LEN;
2239
2240	/* fill Tx descriptor */
2241	desc->len = htole16(totlen);
2242
2243	desc->flags = ZYD_TX_FLAG_BACKOFF;
2244	if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
2245		/* multicast frames are not sent at OFDM rates in 802.11b/g */
2246		if (totlen > ic->ic_rtsthreshold) {
2247			desc->flags |= ZYD_TX_FLAG_RTS;
2248		} else if (ZYD_RATE_IS_OFDM(rate) &&
2249		    (ic->ic_flags & IEEE80211_F_USEPROT)) {
2250			if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
2251				desc->flags |= ZYD_TX_FLAG_CTS_TO_SELF;
2252			else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
2253				desc->flags |= ZYD_TX_FLAG_RTS;
2254		}
2255	} else
2256		desc->flags |= ZYD_TX_FLAG_MULTICAST;
2257
2258	if ((wh->i_fc[0] &
2259	    (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
2260	    (IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_PS_POLL))
2261		desc->flags |= ZYD_TX_FLAG_TYPE(ZYD_TX_TYPE_PS_POLL);
2262
2263	desc->phy = zyd_plcp_signal(rate);
2264	if (ZYD_RATE_IS_OFDM(rate)) {
2265		desc->phy |= ZYD_TX_PHY_OFDM;
2266		if (ic->ic_curmode == IEEE80211_MODE_11A)
2267			desc->phy |= ZYD_TX_PHY_5GHZ;
2268	} else if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
2269		desc->phy |= ZYD_TX_PHY_SHPREAMBLE;
2270
2271	/* actual transmit length (XXX why +10?) */
2272	pktlen = sizeof(struct zyd_tx_desc) + 10;
2273	if (sc->mac_rev == ZYD_ZD1211)
2274		pktlen += totlen;
2275	desc->pktlen = htole16(pktlen);
2276
2277	desc->plcp_length = (16 * totlen + rate - 1) / rate;
2278	desc->plcp_service = 0;
2279	if (rate == 22) {
2280		const int remainder = (16 * totlen) % 22;
2281		if (remainder != 0 && remainder < 7)
2282			desc->plcp_service |= ZYD_PLCP_LENGEXT;
2283	}
2284
2285	if (sc->sc_drvbpf != NULL) {
2286		struct zyd_tx_radiotap_header *tap = &sc->sc_txtap;
2287
2288		tap->wt_flags = 0;
2289		tap->wt_rate = rate;
2290		tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
2291		tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
2292
2293		bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0, BPF_D_OUT);
2294	}
2295
2296	m_copydata(m0, 0, m0->m_pkthdr.len,
2297	    data->buf + sizeof(struct zyd_tx_desc));
2298
2299	DPRINTFN(10, ("%s: sending data frame len=%zu rate=%u xferlen=%u\n",
2300	    device_xname(sc->sc_dev), (size_t)m0->m_pkthdr.len, rate, xferlen));
2301
2302	m_freem(m0);	/* mbuf no longer needed */
2303
2304	usbd_setup_xfer(data->xfer, data, data->buf, xferlen,
2305	    USBD_FORCE_SHORT_XFER, ZYD_TX_TIMEOUT, zyd_txeof);
2306	error = usbd_transfer(data->xfer);
2307	if (error != USBD_IN_PROGRESS && error != 0) {
2308		if_statinc(ifp, if_oerrors);
2309		return EIO;
2310	}
2311	sc->tx_queued++;
2312
2313	return 0;
2314}
2315
2316Static void
2317zyd_start(struct ifnet *ifp)
2318{
2319	struct zyd_softc *sc = ifp->if_softc;
2320	struct ieee80211com *ic = &sc->sc_ic;
2321	struct ether_header *eh;
2322	struct ieee80211_node *ni;
2323	struct mbuf *m0;
2324
2325	for (;;) {
2326		IF_POLL(&ic->ic_mgtq, m0);
2327		if (m0 != NULL) {
2328			if (sc->tx_queued >= ZYD_TX_LIST_CNT) {
2329				ifp->if_flags |= IFF_OACTIVE;
2330				break;
2331			}
2332			IF_DEQUEUE(&ic->ic_mgtq, m0);
2333
2334			ni = M_GETCTX(m0, struct ieee80211_node *);
2335			M_CLEARCTX(m0);
2336			bpf_mtap3(ic->ic_rawbpf, m0, BPF_D_OUT);
2337			if (zyd_tx_mgt(sc, m0, ni) != 0)
2338				break;
2339		} else {
2340			if (ic->ic_state != IEEE80211_S_RUN)
2341				break;
2342			IFQ_POLL(&ifp->if_snd, m0);
2343			if (m0 == NULL)
2344				break;
2345			if (sc->tx_queued >= ZYD_TX_LIST_CNT) {
2346				ifp->if_flags |= IFF_OACTIVE;
2347				break;
2348			}
2349			IFQ_DEQUEUE(&ifp->if_snd, m0);
2350
2351			if (m0->m_len < sizeof(struct ether_header) &&
2352			    !(m0 = m_pullup(m0, sizeof(struct ether_header))))
2353				continue;
2354
2355			eh = mtod(m0, struct ether_header *);
2356			ni = ieee80211_find_txnode(ic, eh->ether_dhost);
2357			if (ni == NULL) {
2358				m_freem(m0);
2359				continue;
2360			}
2361			bpf_mtap(ifp, m0, BPF_D_OUT);
2362			if ((m0 = ieee80211_encap(ic, m0, ni)) == NULL) {
2363				ieee80211_free_node(ni);
2364				if_statinc(ifp, if_oerrors);
2365				continue;
2366			}
2367			bpf_mtap3(ic->ic_rawbpf, m0, BPF_D_OUT);
2368			if (zyd_tx_data(sc, m0, ni) != 0) {
2369				ieee80211_free_node(ni);
2370				if_statinc(ifp, if_oerrors);
2371				break;
2372			}
2373		}
2374
2375		sc->tx_timer = 5;
2376		ifp->if_timer = 1;
2377	}
2378}
2379
2380Static void
2381zyd_watchdog(struct ifnet *ifp)
2382{
2383	struct zyd_softc *sc = ifp->if_softc;
2384	struct ieee80211com *ic = &sc->sc_ic;
2385
2386	ifp->if_timer = 0;
2387
2388	if (sc->tx_timer > 0) {
2389		if (--sc->tx_timer == 0) {
2390			printf("%s: device timeout\n", device_xname(sc->sc_dev));
2391			/* zyd_init(ifp); XXX needs a process context ? */
2392			if_statinc(ifp, if_oerrors);
2393			return;
2394		}
2395		ifp->if_timer = 1;
2396	}
2397
2398	ieee80211_watchdog(ic);
2399}
2400
2401Static int
2402zyd_ioctl(struct ifnet *ifp, u_long cmd, void *data)
2403{
2404	struct zyd_softc *sc = ifp->if_softc;
2405	struct ieee80211com *ic = &sc->sc_ic;
2406	int s, error = 0;
2407
2408	s = splnet();
2409
2410	switch (cmd) {
2411	case SIOCSIFFLAGS:
2412		if ((error = ifioctl_common(ifp, cmd, data)) != 0)
2413			break;
2414		/* XXX re-use ether_ioctl() */
2415		switch (ifp->if_flags & (IFF_UP|IFF_RUNNING)) {
2416		case IFF_UP:
2417			zyd_init(ifp);
2418			break;
2419		case IFF_RUNNING:
2420			zyd_stop(ifp, 1);
2421			break;
2422		default:
2423			break;
2424		}
2425		break;
2426
2427	default:
2428		error = ieee80211_ioctl(ic, cmd, data);
2429	}
2430
2431	if (error == ENETRESET) {
2432		if ((ifp->if_flags & (IFF_RUNNING | IFF_UP)) ==
2433		    (IFF_RUNNING | IFF_UP))
2434			zyd_init(ifp);
2435		error = 0;
2436	}
2437
2438	splx(s);
2439
2440	return error;
2441}
2442
2443Static int
2444zyd_init(struct ifnet *ifp)
2445{
2446	struct zyd_softc *sc = ifp->if_softc;
2447	struct ieee80211com *ic = &sc->sc_ic;
2448	int i, error;
2449
2450	zyd_stop(ifp, 0);
2451
2452	IEEE80211_ADDR_COPY(ic->ic_myaddr, CLLADDR(ifp->if_sadl));
2453	DPRINTF(("setting MAC address to %s\n", ether_sprintf(ic->ic_myaddr)));
2454	error = zyd_set_macaddr(sc, ic->ic_myaddr);
2455	if (error != 0)
2456		return error;
2457
2458	/* we'll do software WEP decryption for now */
2459	DPRINTF(("setting encryption type\n"));
2460	error = zyd_write32(sc, ZYD_MAC_ENCRYPTION_TYPE, ZYD_ENC_SNIFFER);
2461	if (error != 0)
2462		return error;
2463
2464	/* promiscuous mode */
2465	(void)zyd_write32(sc, ZYD_MAC_SNIFFER,
2466	    (ic->ic_opmode == IEEE80211_M_MONITOR) ? 1 : 0);
2467
2468	(void)zyd_set_rxfilter(sc);
2469
2470	/* switch radio transmitter ON */
2471	(void)zyd_switch_radio(sc, 1);
2472
2473	/* set basic rates */
2474	if (ic->ic_curmode == IEEE80211_MODE_11B)
2475		(void)zyd_write32(sc, ZYD_MAC_BAS_RATE, 0x0003);
2476	else if (ic->ic_curmode == IEEE80211_MODE_11A)
2477		(void)zyd_write32(sc, ZYD_MAC_BAS_RATE, 0x1500);
2478	else	/* assumes 802.11b/g */
2479		(void)zyd_write32(sc, ZYD_MAC_BAS_RATE, 0x000f);
2480
2481	/* set mandatory rates */
2482	if (ic->ic_curmode == IEEE80211_MODE_11B)
2483		(void)zyd_write32(sc, ZYD_MAC_MAN_RATE, 0x000f);
2484	else if (ic->ic_curmode == IEEE80211_MODE_11A)
2485		(void)zyd_write32(sc, ZYD_MAC_MAN_RATE, 0x1500);
2486	else	/* assumes 802.11b/g */
2487		(void)zyd_write32(sc, ZYD_MAC_MAN_RATE, 0x150f);
2488
2489	/* set default BSS channel */
2490	ic->ic_bss->ni_chan = ic->ic_ibss_chan;
2491	zyd_set_chan(sc, ic->ic_bss->ni_chan);
2492
2493	/* enable interrupts */
2494	(void)zyd_write32(sc, ZYD_CR_INTERRUPT, ZYD_HWINT_MASK);
2495
2496	/*
2497	 * Allocate Tx and Rx xfer queues.
2498	 */
2499	if ((error = zyd_alloc_tx_list(sc)) != 0) {
2500		printf("%s: could not allocate Tx list\n",
2501		    device_xname(sc->sc_dev));
2502		goto fail;
2503	}
2504	if ((error = zyd_alloc_rx_list(sc)) != 0) {
2505		printf("%s: could not allocate Rx list\n",
2506		    device_xname(sc->sc_dev));
2507		goto fail;
2508	}
2509
2510	/*
2511	 * Start up the receive pipe.
2512	 */
2513	for (i = 0; i < ZYD_RX_LIST_CNT; i++) {
2514		struct zyd_rx_data *data = &sc->rx_data[i];
2515
2516		usbd_setup_xfer(data->xfer, data, NULL, ZYX_MAX_RXBUFSZ,
2517		    USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, zyd_rxeof);
2518		error = usbd_transfer(data->xfer);
2519		if (error != USBD_IN_PROGRESS && error != 0) {
2520			printf("%s: could not queue Rx transfer\n",
2521			    device_xname(sc->sc_dev));
2522			goto fail;
2523		}
2524	}
2525
2526	ifp->if_flags &= ~IFF_OACTIVE;
2527	ifp->if_flags |= IFF_RUNNING;
2528
2529	if (ic->ic_opmode == IEEE80211_M_MONITOR)
2530		ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
2531	else
2532		ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
2533
2534	return 0;
2535
2536fail:	zyd_stop(ifp, 1);
2537	return error;
2538}
2539
2540Static void
2541zyd_stop(struct ifnet *ifp, int disable)
2542{
2543	struct zyd_softc *sc = ifp->if_softc;
2544	struct ieee80211com *ic = &sc->sc_ic;
2545
2546	ieee80211_new_state(ic, IEEE80211_S_INIT, -1);	/* free all nodes */
2547
2548	sc->tx_timer = 0;
2549	ifp->if_timer = 0;
2550	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
2551
2552	/* switch radio transmitter OFF */
2553	(void)zyd_switch_radio(sc, 0);
2554
2555	/* disable Rx */
2556	(void)zyd_write32(sc, ZYD_MAC_RXFILTER, 0);
2557
2558	/* disable interrupts */
2559	(void)zyd_write32(sc, ZYD_CR_INTERRUPT, 0);
2560
2561	usbd_abort_pipe(sc->zyd_ep[ZYD_ENDPT_BIN]);
2562	usbd_abort_pipe(sc->zyd_ep[ZYD_ENDPT_BOUT]);
2563
2564	zyd_free_rx_list(sc);
2565	zyd_free_tx_list(sc);
2566}
2567
2568Static int
2569zyd_loadfirmware(struct zyd_softc *sc, u_char *fw, size_t size)
2570{
2571	usb_device_request_t req;
2572	uint16_t addr;
2573	uint8_t stat;
2574
2575	DPRINTF(("firmware size=%zu\n", size));
2576
2577	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
2578	req.bRequest = ZYD_DOWNLOADREQ;
2579	USETW(req.wIndex, 0);
2580
2581	addr = ZYD_FIRMWARE_START_ADDR;
2582	while (size > 0) {
2583#if 0
2584		const int mlen = uimin(size, 4096);
2585#else
2586		/*
2587		 * XXXX: When the transfer size is 4096 bytes, it is not
2588		 * likely to be able to transfer it.
2589		 * The cause is port or machine or chip?
2590		 */
2591		const int mlen = uimin(size, 64);
2592#endif
2593
2594		DPRINTF(("loading firmware block: len=%d, addr=%#x\n", mlen,
2595		    addr));
2596
2597		USETW(req.wValue, addr);
2598		USETW(req.wLength, mlen);
2599		if (usbd_do_request(sc->sc_udev, &req, fw) != 0)
2600			return EIO;
2601
2602		addr += mlen / 2;
2603		fw   += mlen;
2604		size -= mlen;
2605	}
2606
2607	/* check whether the upload succeeded */
2608	req.bmRequestType = UT_READ_VENDOR_DEVICE;
2609	req.bRequest = ZYD_DOWNLOADSTS;
2610	USETW(req.wValue, 0);
2611	USETW(req.wIndex, 0);
2612	USETW(req.wLength, sizeof(stat));
2613	if (usbd_do_request(sc->sc_udev, &req, &stat) != 0)
2614		return EIO;
2615
2616	return (stat & 0x80) ? EIO : 0;
2617}
2618
2619Static void
2620zyd_iter_func(void *arg, struct ieee80211_node *ni)
2621{
2622	struct zyd_softc *sc = arg;
2623	struct zyd_node *zn = (struct zyd_node *)ni;
2624
2625	ieee80211_amrr_choose(&sc->amrr, ni, &zn->amn);
2626}
2627
2628Static void
2629zyd_amrr_timeout(void *arg)
2630{
2631	struct zyd_softc *sc = arg;
2632	struct ieee80211com *ic = &sc->sc_ic;
2633	int s;
2634
2635	s = splnet();
2636	if (ic->ic_opmode == IEEE80211_M_STA)
2637		zyd_iter_func(sc, ic->ic_bss);
2638	else
2639		ieee80211_iterate_nodes(&ic->ic_sta, zyd_iter_func, sc);
2640	splx(s);
2641
2642	callout_reset(&sc->sc_amrr_ch, hz, zyd_amrr_timeout, sc);
2643}
2644
2645Static void
2646zyd_newassoc(struct ieee80211_node *ni, int isnew)
2647{
2648	struct zyd_softc *sc = ni->ni_ic->ic_ifp->if_softc;
2649	int i;
2650
2651	ieee80211_amrr_node_init(&sc->amrr, &((struct zyd_node *)ni)->amn);
2652
2653	/* set rate to some reasonable initial value */
2654	for (i = ni->ni_rates.rs_nrates - 1;
2655	     i > 0 && (ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL) > 72;
2656	     i--);
2657	ni->ni_txrate = i;
2658}
2659
2660static int
2661zyd_activate(device_t self, enum devact act)
2662{
2663	struct zyd_softc *sc = device_private(self);
2664
2665	switch (act) {
2666	case DVACT_DEACTIVATE:
2667		if_deactivate(&sc->sc_if);
2668		return 0;
2669	default:
2670		return EOPNOTSUPP;
2671	}
2672}
2673