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