Deleted Added
sdiff udiff text old ( 283540 ) new ( 286410 )
full compact
1/* $OpenBSD: if_zyd.c,v 1.52 2007/02/11 00:08:04 jsg Exp $ */
2/* $NetBSD: if_zyd.c,v 1.7 2007/06/21 04:04:29 kiyohara Exp $ */
3/* $FreeBSD: head/sys/dev/usb/wlan/if_zyd.c 286410 2015-08-07 11:43:14Z glebius $ */
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 286410 2015-08-07 11:43:14Z glebius $");
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>

--- 117 unchanged lines hidden (view full) ---

149static void zyd_set_multi(struct zyd_softc *);
150static void zyd_update_mcast(struct ieee80211com *);
151static int zyd_set_rxfilter(struct zyd_softc *);
152static void zyd_set_chan(struct zyd_softc *, struct ieee80211_channel *);
153static int zyd_set_beacon_interval(struct zyd_softc *, int);
154static void zyd_rx_data(struct usb_xfer *, int, uint16_t);
155static int zyd_tx_start(struct zyd_softc *, struct mbuf *,
156 struct ieee80211_node *);
157static int zyd_transmit(struct ieee80211com *, struct mbuf *);
158static void zyd_start(struct zyd_softc *);
159static int zyd_raw_xmit(struct ieee80211_node *, struct mbuf *,
160 const struct ieee80211_bpf_params *);
161static void zyd_parent(struct ieee80211com *);
162static void zyd_init_locked(struct zyd_softc *);
163static void zyd_stop(struct zyd_softc *);
164static int zyd_loadfirmware(struct zyd_softc *);
165static void zyd_scan_start(struct ieee80211com *);
166static void zyd_scan_end(struct ieee80211com *);
167static void zyd_set_channel(struct ieee80211com *);
168static int zyd_rfmd_init(struct zyd_rf *);
169static int zyd_rfmd_switch_radio(struct zyd_rf *, int);
170static int zyd_rfmd_set_channel(struct zyd_rf *, uint8_t);

--- 157 unchanged lines hidden (view full) ---

328 return (usbd_lookup_id_by_uaa(zyd_devs, sizeof(zyd_devs), uaa));
329}
330
331static int
332zyd_attach(device_t dev)
333{
334 struct usb_attach_arg *uaa = device_get_ivars(dev);
335 struct zyd_softc *sc = device_get_softc(dev);
336 struct ieee80211com *ic = &sc->sc_ic;
337 uint8_t iface_index, bands;
338 int error;
339
340 if (uaa->info.bcdDevice < 0x4330) {
341 device_printf(dev, "device version mismatch: 0x%X "
342 "(only >= 43.30 supported)\n",
343 uaa->info.bcdDevice);
344 return (EINVAL);
345 }
346
347 device_set_usb_desc(dev);
348 sc->sc_dev = dev;
349 sc->sc_udev = uaa->device;
350 sc->sc_macrev = USB_GET_DRIVER_INFO(uaa);
351
352 mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev),
353 MTX_NETWORK_LOCK, MTX_DEF);
354 STAILQ_INIT(&sc->sc_rqh);
355 mbufq_init(&sc->sc_snd, ifqmaxlen);
356
357 iface_index = ZYD_IFACE_INDEX;
358 error = usbd_transfer_setup(uaa->device,
359 &iface_index, sc->sc_xfer, zyd_config,
360 ZYD_N_TRANSFER, sc, &sc->sc_mtx);
361 if (error) {
362 device_printf(dev, "could not allocate USB transfers, "
363 "err=%s\n", usbd_errstr(error));
364 goto detach;
365 }
366
367 ZYD_LOCK(sc);
368 if ((error = zyd_get_macaddr(sc)) != 0) {
369 device_printf(sc->sc_dev, "could not read EEPROM\n");
370 ZYD_UNLOCK(sc);
371 goto detach;
372 }
373 ZYD_UNLOCK(sc);
374
375 ic->ic_softc = sc;
376 ic->ic_name = device_get_nameunit(dev);
377 ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
378 ic->ic_opmode = IEEE80211_M_STA;
379
380 /* set device capabilities */
381 ic->ic_caps =
382 IEEE80211_C_STA /* station mode */

--- 4 unchanged lines hidden (view full) ---

387 | IEEE80211_C_WPA /* 802.11i */
388 ;
389
390 bands = 0;
391 setbit(&bands, IEEE80211_MODE_11B);
392 setbit(&bands, IEEE80211_MODE_11G);
393 ieee80211_init_channels(ic, NULL, &bands);
394
395 ieee80211_ifattach(ic);
396 ic->ic_raw_xmit = zyd_raw_xmit;
397 ic->ic_scan_start = zyd_scan_start;
398 ic->ic_scan_end = zyd_scan_end;
399 ic->ic_set_channel = zyd_set_channel;
400 ic->ic_vap_create = zyd_vap_create;
401 ic->ic_vap_delete = zyd_vap_delete;
402 ic->ic_update_mcast = zyd_update_mcast;
403 ic->ic_update_promisc = zyd_update_mcast;
404 ic->ic_parent = zyd_parent;
405 ic->ic_transmit = zyd_transmit;
406
407 ieee80211_radiotap_attach(ic,
408 &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
409 ZYD_TX_RADIOTAP_PRESENT,
410 &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
411 ZYD_RX_RADIOTAP_PRESENT);
412
413 if (bootverbose)

--- 5 unchanged lines hidden (view full) ---

419 zyd_detach(dev);
420 return (ENXIO); /* failure */
421}
422
423static int
424zyd_detach(device_t dev)
425{
426 struct zyd_softc *sc = device_get_softc(dev);
427 struct ieee80211com *ic = &sc->sc_ic;
428 unsigned int x;
429
430 /*
431 * Prevent further allocations from RX/TX data
432 * lists and ioctls:
433 */
434 ZYD_LOCK(sc);
435 sc->sc_flags |= ZYD_FLAG_DETACHED;

--- 8 unchanged lines hidden (view full) ---

444 /* free TX list, if any */
445 ZYD_LOCK(sc);
446 zyd_unsetup_tx_list(sc);
447 ZYD_UNLOCK(sc);
448
449 /* free USB transfers and some data buffers */
450 usbd_transfer_unsetup(sc->sc_xfer, ZYD_N_TRANSFER);
451
452 if (ic->ic_softc == sc)
453 ieee80211_ifdetach(ic);
454 mbufq_drain(&sc->sc_snd);
455 mtx_destroy(&sc->sc_mtx);
456
457 return (0);
458}
459
460static struct ieee80211vap *
461zyd_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
462 enum ieee80211_opmode opmode, int flags,
463 const uint8_t bssid[IEEE80211_ADDR_LEN],
464 const uint8_t mac[IEEE80211_ADDR_LEN])
465{
466 struct zyd_vap *zvp;
467 struct ieee80211vap *vap;
468
469 if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
470 return (NULL);
471 zvp = malloc(sizeof(struct zyd_vap), M_80211_VAP, M_WAITOK | M_ZERO);
472 vap = &zvp->vap;
473
474 /* enable s/w bmiss handling for sta mode */
475 if (ieee80211_vap_setup(ic, vap, name, unit, opmode,
476 flags | IEEE80211_CLONE_NOBEACONS, bssid) != 0) {
477 /* out of memory */
478 free(zvp, M_80211_VAP);
479 return (NULL);
480 }
481
482 /* override state transition machine */
483 zvp->newstate = vap->iv_newstate;
484 vap->iv_newstate = zyd_newstate;
485
486 ieee80211_ratectl_init(vap);
487 ieee80211_ratectl_setinterval(vap, 1000 /* 1 sec */);
488
489 /* complete setup */
490 ieee80211_vap_attach(vap, ieee80211_media_change,
491 ieee80211_media_status, mac);
492 ic->ic_opmode = opmode;
493 return (vap);
494}
495
496static void
497zyd_vap_delete(struct ieee80211vap *vap)
498{
499 struct zyd_vap *zvp = ZYD_VAP(vap);

--- 4 unchanged lines hidden (view full) ---

504}
505
506static void
507zyd_tx_free(struct zyd_tx_data *data, int txerr)
508{
509 struct zyd_softc *sc = data->sc;
510
511 if (data->m != NULL) {
512 ieee80211_tx_complete(data->ni, data->m, txerr);
513 data->m = NULL;
514 data->ni = NULL;
515 }
516 STAILQ_INSERT_TAIL(&sc->tx_free, data, next);
517 sc->tx_nfree++;
518}
519
520static void
521zyd_setup_tx_list(struct zyd_softc *sc)

--- 40 unchanged lines hidden (view full) ---

562 }
563}
564
565static int
566zyd_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
567{
568 struct zyd_vap *zvp = ZYD_VAP(vap);
569 struct ieee80211com *ic = vap->iv_ic;
570 struct zyd_softc *sc = ic->ic_softc;
571 int error;
572
573 DPRINTF(sc, ZYD_DEBUG_STATE, "%s: %s -> %s\n", __func__,
574 ieee80211_state_name[vap->iv_state],
575 ieee80211_state_name[nstate]);
576
577 IEEE80211_UNLOCK(ic);
578 ZYD_LOCK(sc);

--- 8 unchanged lines hidden (view full) ---

587 /* turn link LED on */
588 error = zyd_set_led(sc, ZYD_LED1, 1);
589 if (error != 0)
590 break;
591
592 /* make data LED blink upon Tx */
593 zyd_write32_m(sc, sc->sc_fwbase + ZYD_FW_LINK_STATUS, 1);
594
595 IEEE80211_ADDR_COPY(ic->ic_macaddr, vap->iv_bss->ni_bssid);
596 zyd_set_bssid(sc, ic->ic_macaddr);
597 break;
598 default:
599 break;
600 }
601fail:
602 ZYD_UNLOCK(sc);
603 IEEE80211_LOCK(ic);
604 return (zvp->newstate(vap, nstate, arg));
605}
606
607/*
608 * Callback handler for interrupt transfer
609 */
610static void
611zyd_intr_read_callback(struct usb_xfer *xfer, usb_error_t error)
612{
613 struct zyd_softc *sc = usbd_xfer_softc(xfer);
614 struct ieee80211com *ic = &sc->sc_ic;
615 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
616 struct ieee80211_node *ni;
617 struct zyd_cmd *cmd = &sc->sc_ibuf;
618 struct usb_page_cache *pc;
619 int datalen;
620 int actlen;
621
622 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);

--- 26 unchanged lines hidden (view full) ---

649 (int)(le16toh(retry->count) & 0xff);
650
651 ieee80211_ratectl_tx_complete(vap, ni,
652 IEEE80211_RATECTL_TX_FAILURE,
653 &retrycnt, NULL);
654 ieee80211_free_node(ni);
655 }
656 if (le16toh(retry->count) & 0x100)
657 /* too many retries */
658 if_inc_counter(vap->iv_ifp, IFCOUNTER_OERRORS,
659 1);
660 break;
661 }
662 case ZYD_NOTIF_IORD:
663 {
664 struct zyd_rq *rqp;
665
666 if (le16toh(*(uint16_t *)cmd->data) == ZYD_CR_INTERRUPT)
667 break; /* HMAC interrupt */

--- 545 unchanged lines hidden (view full) ---

1213}
1214
1215static int
1216zyd_al2230_bandedge6(struct zyd_rf *rf, struct ieee80211_channel *c)
1217{
1218#define N(a) ((int)(sizeof(a) / sizeof((a)[0])))
1219 int error = 0, i;
1220 struct zyd_softc *sc = rf->rf_sc;
1221 struct ieee80211com *ic = &sc->sc_ic;
1222 struct zyd_phy_pair r[] = ZYD_AL2230_PHY_BANDEDGE6;
1223 int chan = ieee80211_chan2ieee(ic, c);
1224
1225 if (chan == 1 || chan == 11)
1226 r[0].val = 0x12;
1227
1228 for (i = 0; i < N(r); i++)
1229 zyd_write16_m(sc, r[i].reg, r[i].val);

--- 671 unchanged lines hidden (view full) ---

1901 usb_error_t error;
1902
1903 req.bmRequestType = UT_READ_VENDOR_DEVICE;
1904 req.bRequest = ZYD_READFWDATAREQ;
1905 USETW(req.wValue, ZYD_EEPROM_MAC_ADDR_P1);
1906 USETW(req.wIndex, 0);
1907 USETW(req.wLength, IEEE80211_ADDR_LEN);
1908
1909 error = zyd_do_request(sc, &req, sc->sc_ic.ic_macaddr);
1910 if (error != 0) {
1911 device_printf(sc->sc_dev, "could not read EEPROM: %s\n",
1912 usbd_errstr(error));
1913 }
1914
1915 return (error);
1916}
1917

--- 55 unchanged lines hidden (view full) ---

1973 zyd_write32_m(sc, ZYD_MAC_TX_PE_CONTROL, tmp);
1974fail:
1975 return (error);
1976}
1977
1978static void
1979zyd_set_multi(struct zyd_softc *sc)
1980{
1981 struct ieee80211com *ic = &sc->sc_ic;
1982 uint32_t low, high;
1983 int error;
1984
1985 if ((sc->sc_flags & ZYD_FLAG_RUNNING) == 0)
1986 return;
1987
1988 low = 0x00000000;
1989 high = 0x80000000;
1990
1991 if (ic->ic_opmode == IEEE80211_M_MONITOR || ic->ic_allmulti > 0 ||
1992 ic->ic_promisc > 0) {
1993 low = 0xffffffff;
1994 high = 0xffffffff;
1995 } else {
1996 struct ieee80211vap *vap;
1997 struct ifnet *ifp;
1998 struct ifmultiaddr *ifma;
1999 uint8_t v;
2000
2001 TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
2002 ifp = vap->iv_ifp;
2003 if_maddr_rlock(ifp);
2004 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
2005 if (ifma->ifma_addr->sa_family != AF_LINK)
2006 continue;
2007 v = ((uint8_t *)LLADDR((struct sockaddr_dl *)
2008 ifma->ifma_addr))[5] >> 2;
2009 if (v < 32)
2010 low |= 1 << v;
2011 else
2012 high |= 1 << (v - 32);
2013 }
2014 if_maddr_runlock(ifp);
2015 }
2016 }
2017
2018 /* reprogram multicast global hash table */
2019 zyd_write32_m(sc, ZYD_MAC_GHTBL, low);
2020 zyd_write32_m(sc, ZYD_MAC_GHTBH, high);
2021fail:
2022 if (error != 0)
2023 device_printf(sc->sc_dev,
2024 "could not set multicast hash table\n");
2025}
2026
2027static void
2028zyd_update_mcast(struct ieee80211com *ic)
2029{
2030 struct zyd_softc *sc = ic->ic_softc;
2031
2032 ZYD_LOCK(sc);
2033 zyd_set_multi(sc);
2034 ZYD_UNLOCK(sc);
2035}
2036
2037static int
2038zyd_set_rxfilter(struct zyd_softc *sc)
2039{
2040 struct ieee80211com *ic = &sc->sc_ic;
2041 uint32_t rxfilter;
2042
2043 switch (ic->ic_opmode) {
2044 case IEEE80211_M_STA:
2045 rxfilter = ZYD_FILTER_BSS;
2046 break;
2047 case IEEE80211_M_IBSS:
2048 case IEEE80211_M_HOSTAP:

--- 8 unchanged lines hidden (view full) ---

2057 }
2058 return zyd_write32(sc, ZYD_MAC_RXFILTER, rxfilter);
2059}
2060
2061static void
2062zyd_set_chan(struct zyd_softc *sc, struct ieee80211_channel *c)
2063{
2064 int error;
2065 struct ieee80211com *ic = &sc->sc_ic;
2066 struct zyd_rf *rf = &sc->sc_rf;
2067 uint32_t tmp;
2068 int chan;
2069
2070 chan = ieee80211_chan2ieee(ic, c);
2071 if (chan == 0 || chan == IEEE80211_CHAN_ANY) {
2072 /* XXX should NEVER happen */
2073 device_printf(sc->sc_dev,

--- 74 unchanged lines hidden (view full) ---

2148fail:
2149 return (error);
2150}
2151
2152static void
2153zyd_rx_data(struct usb_xfer *xfer, int offset, uint16_t len)
2154{
2155 struct zyd_softc *sc = usbd_xfer_softc(xfer);
2156 struct ieee80211com *ic = &sc->sc_ic;
2157 struct zyd_plcphdr plcp;
2158 struct zyd_rx_stat stat;
2159 struct usb_page_cache *pc;
2160 struct mbuf *m;
2161 int rlen, rssi;
2162
2163 if (len < ZYD_MIN_FRAGSZ) {
2164 DPRINTF(sc, ZYD_DEBUG_RECV, "%s: frame too short (length=%d)\n",
2165 device_get_nameunit(sc->sc_dev), len);
2166 counter_u64_add(ic->ic_ierrors, 1);
2167 return;
2168 }
2169 pc = usbd_xfer_get_frame(xfer, 0);
2170 usbd_copy_out(pc, offset, &plcp, sizeof(plcp));
2171 usbd_copy_out(pc, offset + len - sizeof(stat), &stat, sizeof(stat));
2172
2173 if (stat.flags & ZYD_RX_ERROR) {
2174 DPRINTF(sc, ZYD_DEBUG_RECV,
2175 "%s: RX status indicated error (%x)\n",
2176 device_get_nameunit(sc->sc_dev), stat.flags);
2177 counter_u64_add(ic->ic_ierrors, 1);
2178 return;
2179 }
2180
2181 /* compute actual frame length */
2182 rlen = len - sizeof(struct zyd_plcphdr) -
2183 sizeof(struct zyd_rx_stat) - IEEE80211_CRC_LEN;
2184
2185 /* allocate a mbuf to store the frame */
2186 if (rlen > (int)MCLBYTES) {
2187 DPRINTF(sc, ZYD_DEBUG_RECV, "%s: frame too long (length=%d)\n",
2188 device_get_nameunit(sc->sc_dev), rlen);
2189 counter_u64_add(ic->ic_ierrors, 1);
2190 return;
2191 } else if (rlen > (int)MHLEN)
2192 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
2193 else
2194 m = m_gethdr(M_NOWAIT, MT_DATA);
2195 if (m == NULL) {
2196 DPRINTF(sc, ZYD_DEBUG_RECV, "%s: could not allocate rx mbuf\n",
2197 device_get_nameunit(sc->sc_dev));
2198 counter_u64_add(ic->ic_ierrors, 1);
2199 return;
2200 }
2201 m->m_pkthdr.len = m->m_len = rlen;
2202 usbd_copy_out(pc, offset + sizeof(plcp), mtod(m, uint8_t *), rlen);
2203
2204 if (ieee80211_radiotap_active(ic)) {
2205 struct zyd_rx_radiotap_header *tap = &sc->sc_rxtap;
2206
2207 tap->wr_flags = 0;
2208 if (stat.flags & (ZYD_RX_BADCRC16 | ZYD_RX_BADCRC32))

--- 13 unchanged lines hidden (view full) ---

2222 sc->sc_rx_data[sc->sc_rx_count].m = m;
2223 sc->sc_rx_count++;
2224}
2225
2226static void
2227zyd_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
2228{
2229 struct zyd_softc *sc = usbd_xfer_softc(xfer);
2230 struct ieee80211com *ic = &sc->sc_ic;
2231 struct ieee80211_node *ni;
2232 struct zyd_rx_desc desc;
2233 struct mbuf *m;
2234 struct usb_page_cache *pc;
2235 uint32_t offset;
2236 uint8_t rssi;
2237 int8_t nf;
2238 int i;

--- 55 unchanged lines hidden (view full) ---

2294 ni = ieee80211_find_rxnode(ic,
2295 mtod(m, struct ieee80211_frame_min *));
2296 if (ni != NULL) {
2297 (void)ieee80211_input(ni, m, rssi, nf);
2298 ieee80211_free_node(ni);
2299 } else
2300 (void)ieee80211_input_all(ic, m, rssi, nf);
2301 }
2302 ZYD_LOCK(sc);
2303 zyd_start(sc);
2304 break;
2305
2306 default: /* Error */
2307 DPRINTF(sc, ZYD_DEBUG_ANY, "frame error: %s\n", usbd_errstr(error));
2308
2309 if (error != USB_ERR_CANCELLED) {
2310 /* try to clear stall first */
2311 usbd_xfer_set_stall(xfer);

--- 38 unchanged lines hidden (view full) ---

2350 device_printf(sc->sc_dev, "unsupported rate %d\n", rate);
2351 return (0x0);
2352}
2353
2354static void
2355zyd_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error)
2356{
2357 struct zyd_softc *sc = usbd_xfer_softc(xfer);
2358 struct ieee80211vap *vap;
2359 struct zyd_tx_data *data;
2360 struct mbuf *m;
2361 struct usb_page_cache *pc;
2362 int actlen;
2363
2364 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
2365
2366 switch (USB_GET_STATE(xfer)) {
2367 case USB_ST_TRANSFERRED:
2368 DPRINTF(sc, ZYD_DEBUG_ANY, "transfer complete, %u bytes\n",
2369 actlen);
2370
2371 /* free resources */
2372 data = usbd_xfer_get_priv(xfer);
2373 zyd_tx_free(data, 0);
2374 usbd_xfer_set_priv(xfer, NULL);
2375
2376 /* FALLTHROUGH */
2377 case USB_ST_SETUP:
2378tr_setup:
2379 data = STAILQ_FIRST(&sc->tx_q);
2380 if (data) {
2381 STAILQ_REMOVE_HEAD(&sc->tx_q, next);
2382 m = data->m;
2383

--- 16 unchanged lines hidden (view full) ---

2400
2401 ieee80211_radiotap_tx(vap, m);
2402 }
2403
2404 usbd_xfer_set_frame_len(xfer, 0, ZYD_TX_DESC_SIZE + m->m_pkthdr.len);
2405 usbd_xfer_set_priv(xfer, data);
2406 usbd_transfer_submit(xfer);
2407 }
2408 zyd_start(sc);
2409 break;
2410
2411 default: /* Error */
2412 DPRINTF(sc, ZYD_DEBUG_ANY, "transfer error, %s\n",
2413 usbd_errstr(error));
2414
2415 counter_u64_add(sc->sc_ic.ic_oerrors, 1);
2416 data = usbd_xfer_get_priv(xfer);
2417 usbd_xfer_set_priv(xfer, NULL);
2418 if (data != NULL)
2419 zyd_tx_free(data, error);
2420
2421 if (error != USB_ERR_CANCELLED) {
2422 if (error == USB_ERR_TIMEOUT)
2423 device_printf(sc->sc_dev, "device timeout\n");

--- 124 unchanged lines hidden (view full) ---

2548 rate);
2549
2550 STAILQ_INSERT_TAIL(&sc->tx_q, data, next);
2551 usbd_transfer_start(sc->sc_xfer[ZYD_BULK_WR]);
2552
2553 return (0);
2554}
2555
2556static int
2557zyd_transmit(struct ieee80211com *ic, struct mbuf *m)
2558{
2559 struct zyd_softc *sc = ic->ic_softc;
2560 int error;
2561
2562 ZYD_LOCK(sc);
2563 if ((sc->sc_flags & ZYD_FLAG_RUNNING) == 0) {
2564 ZYD_UNLOCK(sc);
2565 return (ENXIO);
2566 }
2567 error = mbufq_enqueue(&sc->sc_snd, m);
2568 if (error) {
2569 ZYD_UNLOCK(sc);
2570 return (error);
2571 }
2572 zyd_start(sc);
2573 ZYD_UNLOCK(sc);
2574
2575 return (0);
2576}
2577
2578static void
2579zyd_start(struct zyd_softc *sc)
2580{
2581 struct ieee80211_node *ni;
2582 struct mbuf *m;
2583
2584 ZYD_LOCK_ASSERT(sc, MA_LOCKED);
2585
2586 while (sc->tx_nfree > 0 && (m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
2587 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
2588 if (zyd_tx_start(sc, m, ni) != 0) {
2589 ieee80211_free_node(ni);
2590 if_inc_counter(ni->ni_vap->iv_ifp,
2591 IFCOUNTER_OERRORS, 1);
2592 break;
2593 }
2594 }
2595}
2596
2597static int
2598zyd_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
2599 const struct ieee80211_bpf_params *params)
2600{
2601 struct ieee80211com *ic = ni->ni_ic;
2602 struct zyd_softc *sc = ic->ic_softc;
2603
2604 ZYD_LOCK(sc);
2605 /* prevent management frames from being sent if we're not ready */
2606 if (!(sc->sc_flags & ZYD_FLAG_RUNNING)) {
2607 ZYD_UNLOCK(sc);
2608 m_freem(m);
2609 ieee80211_free_node(ni);
2610 return (ENETDOWN);
2611 }
2612 if (sc->tx_nfree == 0) {
2613 ZYD_UNLOCK(sc);
2614 m_freem(m);
2615 ieee80211_free_node(ni);
2616 return (ENOBUFS); /* XXX */
2617 }
2618
2619 /*
2620 * Legacy path; interpret frame contents to decide
2621 * precisely how to send the frame.
2622 * XXX raw path
2623 */
2624 if (zyd_tx_start(sc, m, ni) != 0) {
2625 ZYD_UNLOCK(sc);
2626 ieee80211_free_node(ni);
2627 return (EIO);
2628 }
2629 ZYD_UNLOCK(sc);
2630 return (0);
2631}
2632
2633static void
2634zyd_parent(struct ieee80211com *ic)
2635{
2636 struct zyd_softc *sc = ic->ic_softc;
2637 int startall = 0;
2638
2639 ZYD_LOCK(sc);
2640 if (sc->sc_flags & ZYD_FLAG_DETACHED) {
2641 ZYD_UNLOCK(sc);
2642 return;
2643 }
2644 if (ic->ic_nrunning > 0) {
2645 if ((sc->sc_flags & ZYD_FLAG_RUNNING) == 0) {
2646 zyd_init_locked(sc);
2647 startall = 1;
2648 } else
2649 zyd_set_multi(sc);
2650 } else if (sc->sc_flags & ZYD_FLAG_RUNNING)
2651 zyd_stop(sc);
2652 ZYD_UNLOCK(sc);
2653 if (startall)
2654 ieee80211_start_all(ic);
2655}
2656
2657static void
2658zyd_init_locked(struct zyd_softc *sc)
2659{
2660 struct ieee80211com *ic = &sc->sc_ic;
2661 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
2662 struct usb_config_descriptor *cd;
2663 int error;
2664 uint32_t val;
2665
2666 ZYD_LOCK_ASSERT(sc, MA_OWNED);
2667
2668 if (!(sc->sc_flags & ZYD_FLAG_INITONCE)) {
2669 error = zyd_loadfirmware(sc);

--- 35 unchanged lines hidden (view full) ---

2705 /* we'll do software WEP decryption for now */
2706 DPRINTF(sc, ZYD_DEBUG_INIT, "%s: setting encryption type\n",
2707 __func__);
2708 zyd_write32_m(sc, ZYD_MAC_ENCRYPTION_TYPE, ZYD_ENC_SNIFFER);
2709
2710 sc->sc_flags |= ZYD_FLAG_INITONCE;
2711 }
2712
2713 if (sc->sc_flags & ZYD_FLAG_RUNNING)
2714 zyd_stop(sc);
2715
2716 DPRINTF(sc, ZYD_DEBUG_INIT, "setting MAC address to %6D\n",
2717 vap ? vap->iv_myaddr : ic->ic_macaddr, ":");
2718 error = zyd_set_macaddr(sc, vap ? vap->iv_myaddr : ic->ic_macaddr);
2719 if (error != 0)
2720 return;
2721
2722 /* set basic rates */
2723 if (ic->ic_curmode == IEEE80211_MODE_11B)
2724 zyd_write32_m(sc, ZYD_MAC_BAS_RATE, 0x0003);
2725 else if (ic->ic_curmode == IEEE80211_MODE_11A)
2726 zyd_write32_m(sc, ZYD_MAC_BAS_RATE, 0x1500);

--- 19 unchanged lines hidden (view full) ---

2746 /*
2747 * Allocate Tx and Rx xfer queues.
2748 */
2749 zyd_setup_tx_list(sc);
2750
2751 /* enable interrupts */
2752 zyd_write32_m(sc, ZYD_CR_INTERRUPT, ZYD_HWINT_MASK);
2753
2754 sc->sc_flags |= ZYD_FLAG_RUNNING;
2755 usbd_xfer_set_stall(sc->sc_xfer[ZYD_BULK_WR]);
2756 usbd_transfer_start(sc->sc_xfer[ZYD_BULK_RD]);
2757 usbd_transfer_start(sc->sc_xfer[ZYD_INTR_RD]);
2758
2759 return;
2760
2761fail: zyd_stop(sc);
2762 return;
2763}
2764
2765static void
2766zyd_stop(struct zyd_softc *sc)
2767{
2768 int error;
2769
2770 ZYD_LOCK_ASSERT(sc, MA_OWNED);
2771
2772 sc->sc_flags &= ~ZYD_FLAG_RUNNING;
2773
2774 /*
2775 * Drain all the transfers, if not already drained:
2776 */
2777 ZYD_UNLOCK(sc);
2778 usbd_transfer_drain(sc->sc_xfer[ZYD_BULK_WR]);
2779 usbd_transfer_drain(sc->sc_xfer[ZYD_BULK_RD]);
2780 ZYD_LOCK(sc);

--- 75 unchanged lines hidden (view full) ---

2856 sc->sc_flags |= ZYD_FLAG_FWLOADED;
2857
2858 return (stat & 0x80) ? (EIO) : (0);
2859}
2860
2861static void
2862zyd_scan_start(struct ieee80211com *ic)
2863{
2864 struct zyd_softc *sc = ic->ic_softc;
2865
2866 ZYD_LOCK(sc);
2867 /* want broadcast address while scanning */
2868 zyd_set_bssid(sc, ieee80211broadcastaddr);
2869 ZYD_UNLOCK(sc);
2870}
2871
2872static void
2873zyd_scan_end(struct ieee80211com *ic)
2874{
2875 struct zyd_softc *sc = ic->ic_softc;
2876
2877 ZYD_LOCK(sc);
2878 /* restore previous bssid */
2879 zyd_set_bssid(sc, ic->ic_macaddr);
2880 ZYD_UNLOCK(sc);
2881}
2882
2883static void
2884zyd_set_channel(struct ieee80211com *ic)
2885{
2886 struct zyd_softc *sc = ic->ic_softc;
2887
2888 ZYD_LOCK(sc);
2889 zyd_set_chan(sc, ic->ic_curchan);
2890 ZYD_UNLOCK(sc);
2891}
2892
2893static device_method_t zyd_methods[] = {
2894 /* Device interface */

--- 18 unchanged lines hidden ---