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