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