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