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