diff options
Diffstat (limited to 'sys/dev/usb/wlan')
-rw-r--r-- | sys/dev/usb/wlan/if_rum.c | 385 | ||||
-rw-r--r-- | sys/dev/usb/wlan/if_rumvar.h | 23 | ||||
-rw-r--r-- | sys/dev/usb/wlan/if_uath.c | 18 | ||||
-rw-r--r-- | sys/dev/usb/wlan/if_uathvar.h | 1 | ||||
-rw-r--r-- | sys/dev/usb/wlan/if_ural.c | 390 | ||||
-rw-r--r-- | sys/dev/usb/wlan/if_uralvar.h | 20 | ||||
-rw-r--r-- | sys/dev/usb/wlan/if_zyd.c | 361 | ||||
-rw-r--r-- | sys/dev/usb/wlan/if_zydreg.h | 21 | ||||
-rw-r--r-- | sys/dev/usb/wlan/usb_wlan.h | 56 |
9 files changed, 318 insertions, 957 deletions
diff --git a/sys/dev/usb/wlan/if_rum.c b/sys/dev/usb/wlan/if_rum.c index 856ed38..0c3012e 100644 --- a/sys/dev/usb/wlan/if_rum.c +++ b/sys/dev/usb/wlan/if_rum.c @@ -26,22 +26,58 @@ __FBSDID("$FreeBSD$"); * http://www.ralinktech.com.tw/ */ -#include "usbdevs.h" -#include <dev/usb/usb.h> -#include <dev/usb/usb_mfunc.h> -#include <dev/usb/usb_error.h> +#include <sys/param.h> +#include <sys/sockio.h> +#include <sys/sysctl.h> +#include <sys/lock.h> +#include <sys/mutex.h> +#include <sys/mbuf.h> +#include <sys/kernel.h> +#include <sys/socket.h> +#include <sys/systm.h> +#include <sys/malloc.h> +#include <sys/module.h> +#include <sys/bus.h> +#include <sys/endian.h> +#include <sys/kdb.h> + +#include <machine/bus.h> +#include <machine/resource.h> +#include <sys/rman.h> + +#include <net/bpf.h> +#include <net/if.h> +#include <net/if_arp.h> +#include <net/ethernet.h> +#include <net/if_dl.h> +#include <net/if_media.h> +#include <net/if_types.h> + +#ifdef INET +#include <netinet/in.h> +#include <netinet/in_systm.h> +#include <netinet/in_var.h> +#include <netinet/if_ether.h> +#include <netinet/ip.h> +#endif + +#include <net80211/ieee80211_var.h> +#include <net80211/ieee80211_regdomain.h> +#include <net80211/ieee80211_radiotap.h> +#include <net80211/ieee80211_amrr.h> #define USB_DEBUG_VAR rum_debug +#include <dev/usb/usb.h> +#include <dev/usb/usb_error.h> #include <dev/usb/usb_core.h> #include <dev/usb/usb_lookup.h> -#include <dev/usb/usb_process.h> #include <dev/usb/usb_debug.h> #include <dev/usb/usb_request.h> #include <dev/usb/usb_busdma.h> #include <dev/usb/usb_util.h> +#include "usbdevs.h" -#include <dev/usb/wlan/usb_wlan.h> #include <dev/usb/wlan/if_rumreg.h> #include <dev/usb/wlan/if_rumvar.h> #include <dev/usb/wlan/if_rumfw.h> @@ -116,16 +152,6 @@ static device_detach_t rum_detach; static usb2_callback_t rum_bulk_read_callback; static usb2_callback_t rum_bulk_write_callback; -static usb2_proc_callback_t rum_command_wrapper; -static usb2_proc_callback_t rum_attach_post; -static usb2_proc_callback_t rum_task; -static usb2_proc_callback_t rum_scantask; -static usb2_proc_callback_t rum_promisctask; -static usb2_proc_callback_t rum_amrr_task; -static usb2_proc_callback_t rum_init_task; -static usb2_proc_callback_t rum_stop_task; -static usb2_proc_callback_t rum_flush_task; - static usb2_error_t rum_do_request(struct rum_softc *sc, struct usb2_device_request *req, void *data); static struct ieee80211vap *rum_vap_create(struct ieee80211com *, @@ -174,10 +200,13 @@ static void rum_update_slot(struct ifnet *); static void rum_set_bssid(struct rum_softc *, const uint8_t *); static void rum_set_macaddr(struct rum_softc *, const uint8_t *); static void rum_update_promisc(struct ifnet *); +static void rum_setpromisc(struct rum_softc *); static const char *rum_get_rf(int); static void rum_read_eeprom(struct rum_softc *); static int rum_bbp_init(struct rum_softc *); +static void rum_init_locked(struct rum_softc *); static void rum_init(void *); +static void rum_stop(struct rum_softc *); static void rum_load_microcode(struct rum_softc *, const uint8_t *, size_t); static int rum_prepare_beacon(struct rum_softc *, @@ -194,10 +223,8 @@ static int rum_get_rssi(struct rum_softc *, uint8_t); static void rum_amrr_start(struct rum_softc *, struct ieee80211_node *); static void rum_amrr_timeout(void *); +static void rum_amrr_task(void *, int); static int rum_pause(struct rum_softc *, int); -static void rum_queue_command(struct rum_softc *, - usb2_proc_callback_t *, struct usb2_proc_msg *, - struct usb2_proc_msg *); static const struct { uint32_t reg; @@ -398,8 +425,11 @@ rum_attach(device_t self) { struct usb2_attach_arg *uaa = device_get_ivars(self); struct rum_softc *sc = device_get_softc(self); - uint8_t iface_index; - int error; + struct ieee80211com *ic; + struct ifnet *ifp; + uint8_t iface_index, bands; + uint32_t tmp; + int error, ntries; device_set_usb2_desc(self); sc->sc_udev = uaa->device; @@ -408,8 +438,6 @@ rum_attach(device_t self) mtx_init(&sc->sc_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK, MTX_DEF); - cv_init(&sc->sc_cmd_cv, "wtxdone"); - iface_index = RT2573_IFACE_INDEX; error = usb2_transfer_setup(uaa->device, &iface_index, sc->sc_xfer, rum_config, RUM_N_TRANSFER, sc, &sc->sc_mtx); @@ -418,37 +446,8 @@ rum_attach(device_t self) "err=%s\n", usb2_errstr(error)); goto detach; } - error = usb2_proc_create(&sc->sc_tq, &sc->sc_mtx, - device_get_nameunit(self), USB_PRI_MED); - if (error) { - device_printf(self, "could not setup config thread!\n"); - goto detach; - } - /* fork rest of the attach code */ RUM_LOCK(sc); - rum_queue_command(sc, rum_attach_post, - &sc->sc_synctask[0].hdr, - &sc->sc_synctask[1].hdr); - RUM_UNLOCK(sc); - return (0); - -detach: - rum_detach(self); - return (ENXIO); /* failure */ -} - -static void -rum_attach_post(struct usb2_proc_msg *pm) -{ - struct rum_task *task = (struct rum_task *)pm; - struct rum_softc *sc = task->sc; - struct ifnet *ifp; - struct ieee80211com *ic; - unsigned int ntries; - uint32_t tmp; - uint8_t bands; - /* retrieve RT2573 rev. no */ for (ntries = 0; ntries < 100; ntries++) { if ((tmp = rum_read(sc, RT2573_MAC_CSR0)) != 0) @@ -458,7 +457,8 @@ rum_attach_post(struct usb2_proc_msg *pm) } if (ntries == 100) { device_printf(sc->sc_dev, "timeout waiting for chip to settle\n"); - return; + RUM_UNLOCK(sc); + goto detach; } /* retrieve MAC address and various other things from EEPROM */ @@ -468,18 +468,12 @@ rum_attach_post(struct usb2_proc_msg *pm) tmp, rum_get_rf(sc->rf_rev)); rum_load_microcode(sc, rt2573_ucode, sizeof(rt2573_ucode)); - - /* XXX Async attach race */ - if (usb2_proc_is_gone(&sc->sc_tq)) - return; - RUM_UNLOCK(sc); ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); if (ifp == NULL) { device_printf(sc->sc_dev, "can not if_alloc()\n"); - RUM_LOCK(sc); - return; + goto detach; } ic = ifp->if_l2com; @@ -542,7 +536,11 @@ rum_attach_post(struct usb2_proc_msg *pm) if (bootverbose) ieee80211_announce(ic); - RUM_LOCK(sc); + return (0); + +detach: + rum_detach(self); + return (ENXIO); /* failure */ } static int @@ -552,12 +550,8 @@ rum_detach(device_t self) struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic; - /* wait for any post attach or other command to complete */ - usb2_proc_drain(&sc->sc_tq); - /* stop all USB transfers */ usb2_transfer_unsetup(sc->sc_xfer, RUM_N_TRANSFER); - usb2_proc_free(&sc->sc_tq); /* free TX list, if any */ RUM_LOCK(sc); @@ -570,7 +564,6 @@ rum_detach(device_t self) ieee80211_ifdetach(ic); if_free(ifp); } - cv_destroy(&sc->sc_cmd_cv); mtx_destroy(&sc->sc_mtx); return (0); @@ -584,7 +577,7 @@ rum_do_request(struct rum_softc *sc, int ntries = 10; while (ntries--) { - err = usb2_do_request_proc(sc->sc_udev, &sc->sc_tq, + err = usb2_do_request_flags(sc->sc_udev, &sc->sc_mtx, req, data, 0, NULL, 250 /* ms */); if (err == 0) break; @@ -622,8 +615,8 @@ rum_vap_create(struct ieee80211com *ic, rvp->newstate = vap->iv_newstate; vap->iv_newstate = rum_newstate; - rvp->sc = sc; usb2_callout_init_mtx(&rvp->amrr_ch, &sc->sc_mtx, 0); + TASK_INIT(&rvp->amrr_task, 0, rum_amrr_task, rvp); ieee80211_amrr_init(&rvp->amrr, vap, IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD, IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD, @@ -636,25 +629,13 @@ rum_vap_create(struct ieee80211com *ic, } static void -rum_flush_task(struct usb2_proc_msg *pm) -{ - /* Nothing to do */ -} - -static void rum_vap_delete(struct ieee80211vap *vap) { struct rum_vap *rvp = RUM_VAP(vap); - struct rum_softc *sc = rvp->sc; - - RUM_LOCK(sc); - /* wait for any pending tasks to complete */ - rum_queue_command(sc, rum_flush_task, - &sc->sc_synctask[0].hdr, - &sc->sc_synctask[1].hdr); - RUM_UNLOCK(sc); + struct ieee80211com *ic = vap->iv_ic; usb2_callout_drain(&rvp->amrr_ch); + ieee80211_draintask(ic, &rvp->amrr_task); ieee80211_amrr_cleanup(&rvp->amrr); ieee80211_vap_detach(vap); free(rvp, M_80211_VAP); @@ -724,23 +705,27 @@ rum_unsetup_tx_list(struct rum_softc *sc) } } -static void -rum_task(struct usb2_proc_msg *pm) +static int +rum_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { - struct rum_task *task = (struct rum_task *)pm; - struct rum_softc *sc = task->sc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); struct rum_vap *rvp = RUM_VAP(vap); + struct ieee80211com *ic = vap->iv_ic; + struct rum_softc *sc = ic->ic_ifp->if_softc; const struct ieee80211_txparam *tp; enum ieee80211_state ostate; struct ieee80211_node *ni; uint32_t tmp; ostate = vap->iv_state; + DPRINTF("%s -> %s\n", + ieee80211_state_name[ostate], + ieee80211_state_name[nstate]); - switch (sc->sc_state) { + IEEE80211_UNLOCK(ic); + RUM_LOCK(sc); + usb2_callout_stop(&rvp->amrr_ch); + + switch (nstate) { case IEEE80211_S_INIT: if (ostate == IEEE80211_S_RUN) { /* abort TSF synchronization */ @@ -776,45 +761,9 @@ rum_task(struct usb2_proc_msg *pm) default: break; } - RUM_UNLOCK(sc); IEEE80211_LOCK(ic); - rvp->newstate(vap, sc->sc_state, sc->sc_arg); - if (vap->iv_newstate_cb != NULL) - vap->iv_newstate_cb(vap, sc->sc_state, sc->sc_arg); - IEEE80211_UNLOCK(ic); - RUM_LOCK(sc); -} - -static int -rum_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) -{ - struct rum_vap *rvp = RUM_VAP(vap); - struct ieee80211com *ic = vap->iv_ic; - struct rum_softc *sc = ic->ic_ifp->if_softc; - - DPRINTF("%s -> %s\n", - ieee80211_state_name[vap->iv_state], - ieee80211_state_name[nstate]); - - RUM_LOCK(sc); - usb2_callout_stop(&rvp->amrr_ch); - - /* do it in a process context */ - sc->sc_state = nstate; - sc->sc_arg = arg; - RUM_UNLOCK(sc); - - if (nstate == IEEE80211_S_INIT) { - rvp->newstate(vap, nstate, arg); - return 0; - } else { - RUM_LOCK(sc); - rum_queue_command(sc, rum_task, &sc->sc_task[0].hdr, - &sc->sc_task[1].hdr); - RUM_UNLOCK(sc); - return EINPROGRESS; - } + return (rvp->newstate(vap, nstate, arg)); } static void @@ -828,10 +777,6 @@ rum_bulk_write_callback(struct usb2_xfer *xfer) struct mbuf *m; unsigned int len; - /* wakeup waiting command, if any */ - if (sc->sc_last_task != NULL) - cv_signal(&sc->sc_cmd_cv); - switch (USB_GET_STATE(xfer)) { case USB_ST_TRANSFERRED: DPRINTFN(11, "transfer complete, %d bytes\n", xfer->actlen); @@ -847,10 +792,6 @@ rum_bulk_write_callback(struct usb2_xfer *xfer) /* FALLTHROUGH */ case USB_ST_SETUP: tr_setup: - /* wait for command to complete, if any */ - if (sc->sc_last_task != NULL) - break; - data = STAILQ_FIRST(&sc->tx_q); if (data) { STAILQ_REMOVE_HEAD(&sc->tx_q, next); @@ -1377,20 +1318,13 @@ rum_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) RUM_LOCK(sc); if (ifp->if_flags & IFF_UP) { if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { - rum_queue_command(sc, rum_init_task, - &sc->sc_synctask[0].hdr, - &sc->sc_synctask[1].hdr); + rum_init_locked(sc); startall = 1; } else - rum_queue_command(sc, rum_promisctask, - &sc->sc_promisctask[0].hdr, - &sc->sc_promisctask[1].hdr); + rum_setpromisc(sc); } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - rum_queue_command(sc, rum_stop_task, - &sc->sc_synctask[0].hdr, - &sc->sc_synctask[1].hdr); - } + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + rum_stop(sc); } RUM_UNLOCK(sc); if (startall) @@ -1844,10 +1778,8 @@ rum_set_macaddr(struct rum_softc *sc, const uint8_t *addr) } static void -rum_promisctask(struct usb2_proc_msg *pm) +rum_setpromisc(struct rum_softc *sc) { - struct rum_task *task = (struct rum_task *)pm; - struct rum_softc *sc = task->sc; struct ifnet *ifp = sc->sc_ifp; uint32_t tmp; @@ -1872,9 +1804,7 @@ rum_update_promisc(struct ifnet *ifp) return; RUM_LOCK(sc); - rum_queue_command(sc, rum_promisctask, - &sc->sc_promisctask[0].hdr, - &sc->sc_promisctask[1].hdr); + rum_setpromisc(sc); RUM_UNLOCK(sc); } @@ -2008,11 +1938,9 @@ rum_bbp_init(struct rum_softc *sc) } static void -rum_init_task(struct usb2_proc_msg *pm) +rum_init_locked(struct rum_softc *sc) { #define N(a) (sizeof (a) / sizeof ((a)[0])) - struct rum_task *task = (struct rum_task *)pm; - struct rum_softc *sc = task->sc; struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = ifp->if_l2com; uint32_t tmp; @@ -2021,7 +1949,7 @@ rum_init_task(struct usb2_proc_msg *pm) RUM_LOCK_ASSERT(sc, MA_OWNED); - rum_stop_task(pm); + rum_stop(sc); /* initialize MAC registers to default values */ for (i = 0; i < N(rum_def_mac); i++) @@ -2086,7 +2014,7 @@ rum_init_task(struct usb2_proc_msg *pm) usb2_transfer_start(sc->sc_xfer[RUM_BULK_RD]); return; -fail: rum_stop_task(pm); +fail: rum_stop(sc); #undef N } @@ -2098,9 +2026,7 @@ rum_init(void *priv) struct ieee80211com *ic = ifp->if_l2com; RUM_LOCK(sc); - rum_queue_command(sc, rum_init_task, - &sc->sc_synctask[0].hdr, - &sc->sc_synctask[1].hdr); + rum_init_locked(sc); RUM_UNLOCK(sc); if (ifp->if_drv_flags & IFF_DRV_RUNNING) @@ -2108,10 +2034,8 @@ rum_init(void *priv) } static void -rum_stop_task(struct usb2_proc_msg *pm) +rum_stop(struct rum_softc *sc) { - struct rum_task *task = (struct rum_task *)pm; - struct rum_softc *sc = task->sc; struct ifnet *ifp = sc->sc_ifp; uint32_t tmp; @@ -2271,24 +2195,24 @@ static void rum_amrr_timeout(void *arg) { struct rum_vap *rvp = arg; - struct rum_softc *sc = rvp->sc; + struct ieee80211vap *vap = &rvp->vap; + struct ieee80211com *ic = vap->iv_ic; - rum_queue_command(sc, rum_amrr_task, - &rvp->amrr_task[0].hdr, &rvp->amrr_task[1].hdr); + ieee80211_runtask(ic, &rvp->amrr_task); } static void -rum_amrr_task(struct usb2_proc_msg *pm) +rum_amrr_task(void *arg, int pending) { - struct rum_task *task = (struct rum_task *)pm; - struct rum_softc *sc = task->sc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); - struct rum_vap *rvp = RUM_VAP(vap); + struct rum_vap *rvp = arg; + struct ieee80211vap *vap = &rvp->vap; + struct ieee80211com *ic = vap->iv_ic; + struct ifnet *ifp = ic->ic_ifp; + struct rum_softc *sc = ifp->if_softc; struct ieee80211_node *ni = vap->iv_bss; int ok, fail; + RUM_LOCK(sc); /* read and clear statistic registers (STA_CSR0 to STA_CSR10) */ rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof(sc->sta)); @@ -2303,6 +2227,7 @@ rum_amrr_task(struct usb2_proc_msg *pm) ifp->if_oerrors += fail; /* count TX retry-fail as Tx errors */ usb2_callout_reset(&rvp->amrr_ch, hz, rum_amrr_timeout, rvp); + RUM_UNLOCK(sc); } /* ARGUSED */ @@ -2327,13 +2252,15 @@ rum_newassoc(struct ieee80211_node *ni, int isnew) static void rum_scan_start(struct ieee80211com *ic) { - struct rum_softc *sc = ic->ic_ifp->if_softc; + struct ifnet *ifp = ic->ic_ifp; + struct rum_softc *sc = ifp->if_softc; + uint32_t tmp; RUM_LOCK(sc); - /* do it in a process context */ - sc->sc_scan_action = RUM_SCAN_START; - rum_queue_command(sc, rum_scantask, - &sc->sc_scantask[0].hdr, &sc->sc_scantask[1].hdr); + /* abort TSF synchronization */ + tmp = rum_read(sc, RT2573_TXRX_CSR9); + rum_write(sc, RT2573_TXRX_CSR9, tmp & ~0x00ffffff); + rum_set_bssid(sc, ifp->if_broadcastaddr); RUM_UNLOCK(sc); } @@ -2344,10 +2271,8 @@ rum_scan_end(struct ieee80211com *ic) struct rum_softc *sc = ic->ic_ifp->if_softc; RUM_LOCK(sc); - /* do it in a process context */ - sc->sc_scan_action = RUM_SCAN_END; - rum_queue_command(sc, rum_scantask, - &sc->sc_scantask[0].hdr, &sc->sc_scantask[1].hdr); + rum_enable_tsf_sync(sc); + rum_set_bssid(sc, sc->sc_bssid); RUM_UNLOCK(sc); } @@ -2358,43 +2283,10 @@ rum_set_channel(struct ieee80211com *ic) struct rum_softc *sc = ic->ic_ifp->if_softc; RUM_LOCK(sc); - /* do it in a process context */ - sc->sc_scan_action = RUM_SET_CHANNEL; - rum_queue_command(sc, rum_scantask, - &sc->sc_scantask[0].hdr, &sc->sc_scantask[1].hdr); + rum_set_chan(sc, ic->ic_curchan); RUM_UNLOCK(sc); } -static void -rum_scantask(struct usb2_proc_msg *pm) -{ - struct rum_task *task = (struct rum_task *)pm; - struct rum_softc *sc = task->sc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - uint32_t tmp; - - RUM_LOCK_ASSERT(sc, MA_OWNED); - - switch (sc->sc_scan_action) { - case RUM_SCAN_START: - /* abort TSF synchronization */ - tmp = rum_read(sc, RT2573_TXRX_CSR9); - rum_write(sc, RT2573_TXRX_CSR9, tmp & ~0x00ffffff); - rum_set_bssid(sc, ifp->if_broadcastaddr); - break; - - case RUM_SET_CHANNEL: - rum_set_chan(sc, ic->ic_curchan); - break; - - default: /* RUM_SCAN_END */ - rum_enable_tsf_sync(sc); - rum_set_bssid(sc, sc->sc_bssid); - break; - } -} - static int rum_get_rssi(struct rum_softc *sc, uint8_t raw) { @@ -2445,72 +2337,11 @@ rum_get_rssi(struct rum_softc *sc, uint8_t raw) static int rum_pause(struct rum_softc *sc, int timeout) { - if (usb2_proc_is_gone(&sc->sc_tq)) - return (1); usb2_pause_mtx(&sc->sc_mtx, timeout); return (0); } -static void -rum_command_wrapper(struct usb2_proc_msg *pm) -{ - struct rum_task *task = (struct rum_task *)pm; - struct rum_softc *sc = task->sc; - struct ifnet *ifp; - - /* wait for pending transfer, if any */ - while (usb2_transfer_pending(sc->sc_xfer[RUM_BULK_WR])) - cv_wait(&sc->sc_cmd_cv, &sc->sc_mtx); - - /* make sure any hardware buffers are emptied */ - rum_pause(sc, hz / 1000); - - /* execute task */ - task->func(pm); - - /* check if this is the last task executed */ - if (sc->sc_last_task == task) { - sc->sc_last_task = NULL; - ifp = sc->sc_ifp; - /* re-start TX, if any */ - if ((ifp != NULL) && (ifp->if_drv_flags & IFF_DRV_RUNNING)) - usb2_transfer_start(sc->sc_xfer[RUM_BULK_WR]); - } -} - -static void -rum_queue_command(struct rum_softc *sc, usb2_proc_callback_t *fn, - struct usb2_proc_msg *t0, struct usb2_proc_msg *t1) -{ - struct rum_task *task; - - RUM_LOCK_ASSERT(sc, MA_OWNED); - - /* - * NOTE: The task cannot get executed before we drop the - * "sc_mtx" mutex. It is safe to update fields in the message - * structure after that the message got queued. - */ - task = (struct rum_task *) - usb2_proc_msignal(&sc->sc_tq, t0, t1); - - /* Setup callback and softc pointers */ - task->hdr.pm_callback = rum_command_wrapper; - task->func = fn; - task->sc = sc; - - /* Make sure that any TX operation will stop */ - sc->sc_last_task = task; - - /* - * Init, stop and flush must be synchronous! - */ - if ((fn == rum_init_task) || (fn == rum_stop_task) || - (fn == rum_flush_task)) - usb2_proc_mwait(&sc->sc_tq, t0, t1); -} - static device_method_t rum_methods[] = { /* Device interface */ DEVMETHOD(device_probe, rum_match), diff --git a/sys/dev/usb/wlan/if_rumvar.h b/sys/dev/usb/wlan/if_rumvar.h index d6b8137..2ba4007 100644 --- a/sys/dev/usb/wlan/if_rumvar.h +++ b/sys/dev/usb/wlan/if_rumvar.h @@ -54,12 +54,6 @@ struct rum_tx_radiotap_header { struct rum_softc; -struct rum_task { - struct usb2_proc_msg hdr; - usb2_proc_callback_t *func; - struct rum_softc *sc; -}; - struct rum_tx_data { STAILQ_ENTRY(rum_tx_data) next; struct rum_softc *sc; @@ -78,11 +72,10 @@ struct rum_node { struct rum_vap { struct ieee80211vap vap; - struct rum_softc *sc; struct ieee80211_beacon_offsets bo; struct ieee80211_amrr amrr; struct usb2_callout amrr_ch; - struct rum_task amrr_task[2]; + struct task amrr_task; int (*newstate)(struct ieee80211vap *, enum ieee80211_state, int); @@ -99,32 +92,18 @@ struct rum_softc { struct ifnet *sc_ifp; device_t sc_dev; struct usb2_device *sc_udev; - struct usb2_process sc_tq; struct usb2_xfer *sc_xfer[RUM_N_TRANSFER]; - struct rum_task *sc_last_task; uint8_t rf_rev; uint8_t rffreq; - enum ieee80211_state sc_state; - int sc_arg; - struct rum_task sc_synctask[2]; - struct rum_task sc_task[2]; - struct rum_task sc_promisctask[2]; - struct rum_task sc_scantask[2]; - int sc_scan_action; -#define RUM_SCAN_START 0 -#define RUM_SCAN_END 1 -#define RUM_SET_CHANNEL 2 - struct rum_tx_data tx_data[RUM_TX_LIST_COUNT]; rum_txdhead tx_q; rum_txdhead tx_free; int tx_nfree; struct rum_rx_desc sc_rx_desc; - struct cv sc_cmd_cv; struct mtx sc_mtx; uint32_t sta[6]; diff --git a/sys/dev/usb/wlan/if_uath.c b/sys/dev/usb/wlan/if_uath.c index eb1c31c..8e65770 100644 --- a/sys/dev/usb/wlan/if_uath.c +++ b/sys/dev/usb/wlan/if_uath.c @@ -1602,6 +1602,7 @@ uath_tx_start(struct uath_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, { struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211vap *vap = ni->ni_vap; struct uath_chunk *chunk; struct uath_tx_desc *desc; const struct ieee80211_frame *wh; @@ -1677,9 +1678,9 @@ uath_tx_start(struct uath_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, m_freem(m0); return (EIO); } - if (sc->sc_state == IEEE80211_S_AUTH || - sc->sc_state == IEEE80211_S_ASSOC || - sc->sc_state == IEEE80211_S_RUN) + if (vap->iv_state == IEEE80211_S_AUTH || + vap->iv_state == IEEE80211_S_ASSOC || + vap->iv_state == IEEE80211_S_RUN) desc->connid = htobe32(UATH_ID_BSS); else desc->connid = htobe32(UATH_ID_INVALID); @@ -2061,11 +2062,10 @@ uath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) "%s: %s -> %s\n", __func__, ieee80211_state_name[vap->iv_state], ieee80211_state_name[nstate]); + IEEE80211_UNLOCK(ic); UATH_LOCK(sc); - callout_stop(&sc->stat_ch); callout_stop(&sc->watchdog_ch); - sc->sc_state = nstate; switch (nstate) { case IEEE80211_S_INIT: @@ -2139,14 +2139,8 @@ uath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) break; } UATH_UNLOCK(sc); - IEEE80211_LOCK(ic); - uvp->newstate(vap, nstate, arg); - if (vap->iv_newstate_cb != NULL) - vap->iv_newstate_cb(vap, nstate, arg); - IEEE80211_UNLOCK(ic); - - return (0); + return (uvp->newstate(vap, nstate, arg)); } static int diff --git a/sys/dev/usb/wlan/if_uathvar.h b/sys/dev/usb/wlan/if_uathvar.h index 2717399..2757ad4 100644 --- a/sys/dev/usb/wlan/if_uathvar.h +++ b/sys/dev/usb/wlan/if_uathvar.h @@ -183,7 +183,6 @@ struct uath_softc { struct uath_stat sc_stat; int (*sc_newstate)(struct ieee80211com *, enum ieee80211_state, int); - enum ieee80211_state sc_state; struct usb2_xfer *sc_xfer[UATH_N_XFERS]; struct uath_cmd sc_cmd[UATH_CMD_LIST_COUNT]; diff --git a/sys/dev/usb/wlan/if_ural.c b/sys/dev/usb/wlan/if_ural.c index b865a41..523cc61 100644 --- a/sys/dev/usb/wlan/if_ural.c +++ b/sys/dev/usb/wlan/if_ural.c @@ -28,22 +28,59 @@ __FBSDID("$FreeBSD$"); * http://www.ralinktech.com/ */ -#include "usbdevs.h" -#include <dev/usb/usb.h> -#include <dev/usb/usb_mfunc.h> -#include <dev/usb/usb_error.h> +#include <sys/param.h> +#include <sys/sockio.h> +#include <sys/sysctl.h> +#include <sys/lock.h> +#include <sys/mutex.h> +#include <sys/mbuf.h> +#include <sys/kernel.h> +#include <sys/socket.h> +#include <sys/systm.h> +#include <sys/malloc.h> +#include <sys/module.h> +#include <sys/bus.h> +#include <sys/endian.h> +#include <sys/kdb.h> + +#include <machine/bus.h> +#include <machine/resource.h> +#include <sys/rman.h> + +#include <net/bpf.h> +#include <net/if.h> +#include <net/if_arp.h> +#include <net/ethernet.h> +#include <net/if_dl.h> +#include <net/if_media.h> +#include <net/if_types.h> + +#ifdef INET +#include <netinet/in.h> +#include <netinet/in_systm.h> +#include <netinet/in_var.h> +#include <netinet/if_ether.h> +#include <netinet/ip.h> +#endif + +#include <net80211/ieee80211_var.h> +#include <net80211/ieee80211_regdomain.h> +#include <net80211/ieee80211_radiotap.h> +#include <net80211/ieee80211_amrr.h> #define USB_DEBUG_VAR ural_debug +#include <dev/usb/usb.h> +#include <dev/usb/usb_error.h> #include <dev/usb/usb_core.h> #include <dev/usb/usb_lookup.h> -#include <dev/usb/usb_process.h> #include <dev/usb/usb_debug.h> #include <dev/usb/usb_request.h> #include <dev/usb/usb_busdma.h> #include <dev/usb/usb_util.h> +#include "usbdevs.h" + -#include <dev/usb/wlan/usb_wlan.h> #include <dev/usb/wlan/if_uralreg.h> #include <dev/usb/wlan/if_uralvar.h> @@ -95,16 +132,6 @@ static const struct usb2_device_id ural_devs[] = { static usb2_callback_t ural_bulk_read_callback; static usb2_callback_t ural_bulk_write_callback; -static usb2_proc_callback_t ural_command_wrapper; -static usb2_proc_callback_t ural_attach_post; -static usb2_proc_callback_t ural_task; -static usb2_proc_callback_t ural_scantask; -static usb2_proc_callback_t ural_promisctask; -static usb2_proc_callback_t ural_amrr_task; -static usb2_proc_callback_t ural_init_task; -static usb2_proc_callback_t ural_stop_task; -static usb2_proc_callback_t ural_flush_task; - static usb2_error_t ural_do_request(struct ural_softc *sc, struct usb2_device_request *req, void *data); static struct ieee80211vap *ural_vap_create(struct ieee80211com *, @@ -156,21 +183,22 @@ static void ural_set_basicrates(struct ural_softc *, static void ural_set_bssid(struct ural_softc *, const uint8_t *); static void ural_set_macaddr(struct ural_softc *, uint8_t *); static void ural_update_promisc(struct ifnet *); +static void ural_setpromisc(struct ural_softc *); static const char *ural_get_rf(int); static void ural_read_eeprom(struct ural_softc *); static int ural_bbp_init(struct ural_softc *); static void ural_set_txantenna(struct ural_softc *, int); static void ural_set_rxantenna(struct ural_softc *, int); +static void ural_init_locked(struct ural_softc *); static void ural_init(void *); +static void ural_stop(struct ural_softc *); static int ural_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); static void ural_amrr_start(struct ural_softc *, struct ieee80211_node *); static void ural_amrr_timeout(void *); +static void ural_amrr_task(void *, int); static int ural_pause(struct ural_softc *sc, int timeout); -static void ural_queue_command(struct ural_softc *, - usb2_proc_callback_t *, struct usb2_proc_msg *, - struct usb2_proc_msg *); /* * Default values for MAC registers; values taken from the reference driver. @@ -400,8 +428,10 @@ ural_attach(device_t self) { struct usb2_attach_arg *uaa = device_get_ivars(self); struct ural_softc *sc = device_get_softc(self); + struct ifnet *ifp; + struct ieee80211com *ic; + uint8_t iface_index, bands; int error; - uint8_t iface_index; device_set_usb2_desc(self); sc->sc_udev = uaa->device; @@ -410,8 +440,6 @@ ural_attach(device_t self) mtx_init(&sc->sc_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK, MTX_DEF); - cv_init(&sc->sc_cmd_cv, "wtxdone"); - iface_index = RAL_IFACE_INDEX; error = usb2_transfer_setup(uaa->device, &iface_index, sc->sc_xfer, ural_config, @@ -421,55 +449,22 @@ ural_attach(device_t self) "err=%s\n", usb2_errstr(error)); goto detach; } - error = usb2_proc_create(&sc->sc_tq, &sc->sc_mtx, - device_get_nameunit(self), USB_PRI_MED); - if (error) { - device_printf(self, "could not setup config thread!\n"); - goto detach; - } - /* fork rest of the attach code */ RAL_LOCK(sc); - ural_queue_command(sc, ural_attach_post, - &sc->sc_synctask[0].hdr, - &sc->sc_synctask[1].hdr); - RAL_UNLOCK(sc); - return (0); - -detach: - ural_detach(self); - return (ENXIO); /* failure */ -} - -static void -ural_attach_post(struct usb2_proc_msg *pm) -{ - struct ural_task *task = (struct ural_task *)pm; - struct ural_softc *sc = task->sc; - struct ifnet *ifp; - struct ieee80211com *ic; - uint8_t bands; - /* retrieve RT2570 rev. no */ sc->asic_rev = ural_read(sc, RAL_MAC_CSR0); /* retrieve MAC address and various other things from EEPROM */ ural_read_eeprom(sc); - - /* XXX Async attach race */ - if (usb2_proc_is_gone(&sc->sc_tq)) - return; - RAL_UNLOCK(sc); - device_printf(sc->sc_dev, "MAC/BBP RT2570 (rev 0x%02x), RF %s\n", + device_printf(self, "MAC/BBP RT2570 (rev 0x%02x), RF %s\n", sc->asic_rev, ural_get_rf(sc->rf_rev)); ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); if (ifp == NULL) { device_printf(sc->sc_dev, "can not if_alloc()\n"); - RAL_LOCK(sc); - return; + goto detach; } ic = ifp->if_l2com; @@ -532,7 +527,11 @@ ural_attach_post(struct usb2_proc_msg *pm) if (bootverbose) ieee80211_announce(ic); - RAL_LOCK(sc); + return (0); + +detach: + ural_detach(self); + return (ENXIO); /* failure */ } static int @@ -542,12 +541,8 @@ ural_detach(device_t self) struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic; - /* wait for any post attach or other command to complete */ - usb2_proc_drain(&sc->sc_tq); - /* stop all USB transfers */ usb2_transfer_unsetup(sc->sc_xfer, URAL_N_TRANSFER); - usb2_proc_free(&sc->sc_tq); /* free TX list, if any */ RAL_LOCK(sc); @@ -560,7 +555,6 @@ ural_detach(device_t self) ieee80211_ifdetach(ic); if_free(ifp); } - cv_destroy(&sc->sc_cmd_cv); mtx_destroy(&sc->sc_mtx); return (0); @@ -574,7 +568,7 @@ ural_do_request(struct ural_softc *sc, int ntries = 10; while (ntries--) { - err = usb2_do_request_proc(sc->sc_udev, &sc->sc_tq, + err = usb2_do_request_flags(sc->sc_udev, &sc->sc_mtx, req, data, 0, NULL, 250 /* ms */); if (err == 0) break; @@ -612,8 +606,8 @@ ural_vap_create(struct ieee80211com *ic, uvp->newstate = vap->iv_newstate; vap->iv_newstate = ural_newstate; - uvp->sc = sc; usb2_callout_init_mtx(&uvp->amrr_ch, &sc->sc_mtx, 0); + TASK_INIT(&uvp->amrr_task, 0, ural_amrr_task, uvp); ieee80211_amrr_init(&uvp->amrr, vap, IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD, IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD, @@ -626,25 +620,13 @@ ural_vap_create(struct ieee80211com *ic, } static void -ural_flush_task(struct usb2_proc_msg *pm) -{ - /* nothing to do */ -} - -static void ural_vap_delete(struct ieee80211vap *vap) { struct ural_vap *uvp = URAL_VAP(vap); - struct ural_softc *sc = uvp->sc; - - RAL_LOCK(sc); - /* wait for any pending tasks to complete */ - ural_queue_command(sc, ural_flush_task, - &sc->sc_synctask[0].hdr, - &sc->sc_synctask[1].hdr); - RAL_UNLOCK(sc); + struct ieee80211com *ic = vap->iv_ic; usb2_callout_drain(&uvp->amrr_ch); + ieee80211_draintask(ic, &uvp->amrr_task); ieee80211_amrr_cleanup(&uvp->amrr); ieee80211_vap_detach(vap); free(uvp, M_80211_VAP); @@ -714,25 +696,27 @@ ural_unsetup_tx_list(struct ural_softc *sc) } } -static void -ural_task(struct usb2_proc_msg *pm) +static int +ural_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { - struct ural_task *task = (struct ural_task *)pm; - struct ural_softc *sc = task->sc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); struct ural_vap *uvp = URAL_VAP(vap); + struct ieee80211com *ic = vap->iv_ic; + struct ural_softc *sc = ic->ic_ifp->if_softc; const struct ieee80211_txparam *tp; - enum ieee80211_state ostate; struct ieee80211_node *ni; struct mbuf *m; - ostate = vap->iv_state; + DPRINTF("%s -> %s\n", + ieee80211_state_name[vap->iv_state], + ieee80211_state_name[nstate]); + + IEEE80211_UNLOCK(ic); + RAL_LOCK(sc); + usb2_callout_stop(&uvp->amrr_ch); - switch (sc->sc_state) { + switch (nstate) { case IEEE80211_S_INIT: - if (ostate == IEEE80211_S_RUN) { + if (vap->iv_state == IEEE80211_S_RUN) { /* abort TSF synchronization */ ural_write(sc, RAL_TXRX_CSR19, 0); @@ -758,13 +742,17 @@ ural_task(struct usb2_proc_msg *pm) if (m == NULL) { device_printf(sc->sc_dev, "could not allocate beacon\n"); - return; + RAL_UNLOCK(sc); + IEEE80211_LOCK(ic); + return (-1); } ieee80211_ref_node(ni); if (ural_tx_bcn(sc, m, ni) != 0) { device_printf(sc->sc_dev, "could not send beacon\n"); - return; + RAL_UNLOCK(sc); + IEEE80211_LOCK(ic); + return (-1); } } @@ -784,75 +772,9 @@ ural_task(struct usb2_proc_msg *pm) default: break; } - RAL_UNLOCK(sc); IEEE80211_LOCK(ic); - uvp->newstate(vap, sc->sc_state, sc->sc_arg); - if (vap->iv_newstate_cb != NULL) - vap->iv_newstate_cb(vap, sc->sc_state, sc->sc_arg); - IEEE80211_UNLOCK(ic); - RAL_LOCK(sc); -} - -static void -ural_scantask(struct usb2_proc_msg *pm) -{ - struct ural_task *task = (struct ural_task *)pm; - struct ural_softc *sc = task->sc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - - RAL_LOCK_ASSERT(sc, MA_OWNED); - - switch (sc->sc_scan_action) { - case URAL_SCAN_START: - /* abort TSF synchronization */ - DPRINTF("starting scan\n"); - ural_write(sc, RAL_TXRX_CSR19, 0); - ural_set_bssid(sc, ifp->if_broadcastaddr); - break; - - case URAL_SET_CHANNEL: - ural_set_chan(sc, ic->ic_curchan); - break; - - default: /* URAL_SCAN_END */ - DPRINTF("stopping scan\n"); - ural_enable_tsf_sync(sc); - ural_set_bssid(sc, sc->sc_bssid); - break; - } -} - -static int -ural_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) -{ - struct ural_vap *uvp = URAL_VAP(vap); - struct ieee80211com *ic = vap->iv_ic; - struct ural_softc *sc = ic->ic_ifp->if_softc; - - DPRINTF("%s -> %s\n", - ieee80211_state_name[vap->iv_state], - ieee80211_state_name[nstate]); - - RAL_LOCK(sc); - usb2_callout_stop(&uvp->amrr_ch); - - /* do it in a process context */ - sc->sc_state = nstate; - sc->sc_arg = arg; - RAL_UNLOCK(sc); - - if (nstate == IEEE80211_S_INIT) { - uvp->newstate(vap, nstate, arg); - return 0; - } else { - RAL_LOCK(sc); - ural_queue_command(sc, ural_task, &sc->sc_task[0].hdr, - &sc->sc_task[1].hdr); - RAL_UNLOCK(sc); - return EINPROGRESS; - } + return (uvp->newstate(vap, nstate, arg)); } @@ -867,10 +789,6 @@ ural_bulk_write_callback(struct usb2_xfer *xfer) struct mbuf *m; unsigned int len; - /* wakeup waiting command, if any */ - if (sc->sc_last_task != NULL) - cv_signal(&sc->sc_cmd_cv); - switch (USB_GET_STATE(xfer)) { case USB_ST_TRANSFERRED: DPRINTFN(11, "transfer complete, %d bytes\n", xfer->actlen); @@ -886,10 +804,6 @@ ural_bulk_write_callback(struct usb2_xfer *xfer) /* FALLTHROUGH */ case USB_ST_SETUP: tr_setup: - /* wait for command to complete, if any */ - if (sc->sc_last_task != NULL) - break; - data = STAILQ_FIRST(&sc->tx_q); if (data) { STAILQ_REMOVE_HEAD(&sc->tx_q, next); @@ -1458,20 +1372,13 @@ ural_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) RAL_LOCK(sc); if (ifp->if_flags & IFF_UP) { if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { - ural_queue_command(sc, ural_init_task, - &sc->sc_synctask[0].hdr, - &sc->sc_synctask[1].hdr); + ural_init_locked(sc); startall = 1; } else - ural_queue_command(sc, ural_promisctask, - &sc->sc_promisctask[0].hdr, - &sc->sc_promisctask[1].hdr); + ural_setpromisc(sc); } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - ural_queue_command(sc, ural_stop_task, - &sc->sc_synctask[0].hdr, - &sc->sc_synctask[1].hdr); - } + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + ural_stop(sc); } RAL_UNLOCK(sc); if (startall) @@ -1699,15 +1606,13 @@ ural_newassoc(struct ieee80211_node *ni, int isnew) static void ural_scan_start(struct ieee80211com *ic) { - struct ural_softc *sc = ic->ic_ifp->if_softc; + struct ifnet *ifp = ic->ic_ifp; + struct ural_softc *sc = ifp->if_softc; RAL_LOCK(sc); - /* do it in a process context */ - sc->sc_scan_action = URAL_SCAN_START; - ural_queue_command(sc, ural_scantask, - &sc->sc_scantask[0].hdr, &sc->sc_scantask[1].hdr); + ural_write(sc, RAL_TXRX_CSR19, 0); + ural_set_bssid(sc, ifp->if_broadcastaddr); RAL_UNLOCK(sc); - } static void @@ -1716,10 +1621,8 @@ ural_scan_end(struct ieee80211com *ic) struct ural_softc *sc = ic->ic_ifp->if_softc; RAL_LOCK(sc); - /* do it in a process context */ - sc->sc_scan_action = URAL_SCAN_END; - ural_queue_command(sc, ural_scantask, - &sc->sc_scantask[0].hdr, &sc->sc_scantask[1].hdr); + ural_enable_tsf_sync(sc); + ural_set_bssid(sc, sc->sc_bssid); RAL_UNLOCK(sc); } @@ -1730,10 +1633,7 @@ ural_set_channel(struct ieee80211com *ic) struct ural_softc *sc = ic->ic_ifp->if_softc; RAL_LOCK(sc); - /* do it in a process context */ - sc->sc_scan_action = URAL_SET_CHANNEL; - ural_queue_command(sc, ural_scantask, - &sc->sc_scantask[0].hdr, &sc->sc_scantask[1].hdr); + ural_set_chan(sc, ic->ic_curchan); RAL_UNLOCK(sc); } @@ -1994,10 +1894,8 @@ ural_set_macaddr(struct ural_softc *sc, uint8_t *addr) } static void -ural_promisctask(struct usb2_proc_msg *pm) +ural_setpromisc(struct ural_softc *sc) { - struct ural_task *task = (struct ural_task *)pm; - struct ural_softc *sc = task->sc; struct ifnet *ifp = sc->sc_ifp; uint32_t tmp; @@ -2022,9 +1920,7 @@ ural_update_promisc(struct ifnet *ifp) return; RAL_LOCK(sc); - ural_queue_command(sc, ural_promisctask, - &sc->sc_promisctask[0].hdr, - &sc->sc_promisctask[1].hdr); + ural_setpromisc(sc); RAL_UNLOCK(sc); } @@ -2152,11 +2048,9 @@ ural_set_rxantenna(struct ural_softc *sc, int antenna) } static void -ural_init_task(struct usb2_proc_msg *pm) +ural_init_locked(struct ural_softc *sc) { #define N(a) (sizeof (a) / sizeof ((a)[0])) - struct ural_task *task = (struct ural_task *)pm; - struct ural_softc *sc = task->sc; struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = ifp->if_l2com; uint16_t tmp; @@ -2167,7 +2061,7 @@ ural_init_task(struct usb2_proc_msg *pm) ural_set_testmode(sc); ural_write(sc, 0x308, 0x00f0); /* XXX magic */ - ural_stop_task(pm); + ural_stop(sc); /* initialize MAC registers to default values */ for (i = 0; i < N(ural_def_mac); i++) @@ -2229,7 +2123,7 @@ ural_init_task(struct usb2_proc_msg *pm) usb2_transfer_start(sc->sc_xfer[URAL_BULK_RD]); return; -fail: ural_stop_task(pm); +fail: ural_stop(sc); #undef N } @@ -2241,9 +2135,7 @@ ural_init(void *priv) struct ieee80211com *ic = ifp->if_l2com; RAL_LOCK(sc); - ural_queue_command(sc, ural_init_task, - &sc->sc_synctask[0].hdr, - &sc->sc_synctask[1].hdr); + ural_init_locked(sc); RAL_UNLOCK(sc); if (ifp->if_drv_flags & IFF_DRV_RUNNING) @@ -2251,10 +2143,8 @@ ural_init(void *priv) } static void -ural_stop_task(struct usb2_proc_msg *pm) +ural_stop(struct ural_softc *sc) { - struct ural_task *task = (struct ural_task *)pm; - struct ural_softc *sc = task->sc; struct ifnet *ifp = sc->sc_ifp; RAL_LOCK_ASSERT(sc, MA_OWNED); @@ -2350,24 +2240,24 @@ static void ural_amrr_timeout(void *arg) { struct ural_vap *uvp = arg; - struct ural_softc *sc = uvp->sc; + struct ieee80211vap *vap = &uvp->vap; + struct ieee80211com *ic = vap->iv_ic; - ural_queue_command(sc, ural_amrr_task, - &uvp->amrr_task[0].hdr, &uvp->amrr_task[1].hdr); + ieee80211_runtask(ic, &uvp->amrr_task); } static void -ural_amrr_task(struct usb2_proc_msg *pm) +ural_amrr_task(void *arg, int pending) { - struct ural_task *task = (struct ural_task *)pm; - struct ural_softc *sc = task->sc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); - struct ural_vap *uvp = URAL_VAP(vap); + struct ural_vap *uvp = arg; + struct ieee80211vap *vap = &uvp->vap; + struct ieee80211com *ic = vap->iv_ic; + struct ifnet *ifp = ic->ic_ifp; + struct ural_softc *sc = ifp->if_softc; struct ieee80211_node *ni = vap->iv_bss; int ok, fail; + RAL_LOCK(sc); /* read and clear statistic registers (STA_CSR0 to STA_CSR10) */ ural_read_multi(sc, RAL_STA_CSR0, sc->sta, sizeof(sc->sta)); @@ -2382,73 +2272,13 @@ ural_amrr_task(struct usb2_proc_msg *pm) ifp->if_oerrors += fail; /* count TX retry-fail as Tx errors */ usb2_callout_reset(&uvp->amrr_ch, hz, ural_amrr_timeout, uvp); + RAL_UNLOCK(sc); } static int ural_pause(struct ural_softc *sc, int timeout) { - if (usb2_proc_is_gone(&sc->sc_tq)) - return (1); usb2_pause_mtx(&sc->sc_mtx, timeout); return (0); } - -static void -ural_command_wrapper(struct usb2_proc_msg *pm) -{ - struct ural_task *task = (struct ural_task *)pm; - struct ural_softc *sc = task->sc; - struct ifnet *ifp; - - /* wait for pending transfer, if any */ - while (usb2_transfer_pending(sc->sc_xfer[URAL_BULK_WR])) - cv_wait(&sc->sc_cmd_cv, &sc->sc_mtx); - - /* make sure any hardware FIFOs are emptied */ - ural_pause(sc, hz / 1000); - - /* execute task */ - task->func(pm); - - /* check if this is the last task executed */ - if (sc->sc_last_task == task) { - sc->sc_last_task = NULL; - ifp = sc->sc_ifp; - /* re-start TX, if any */ - if ((ifp != NULL) && (ifp->if_drv_flags & IFF_DRV_RUNNING)) - usb2_transfer_start(sc->sc_xfer[URAL_BULK_WR]); - } -} - -static void -ural_queue_command(struct ural_softc *sc, usb2_proc_callback_t *fn, - struct usb2_proc_msg *t0, struct usb2_proc_msg *t1) -{ - struct ural_task *task; - - RAL_LOCK_ASSERT(sc, MA_OWNED); - - /* - * NOTE: The task cannot get executed before we drop the - * "sc_mtx" mutex. It is safe to update fields in the message - * structure after that the message got queued. - */ - task = (struct ural_task *) - usb2_proc_msignal(&sc->sc_tq, t0, t1); - - /* Setup callback and softc pointers */ - task->hdr.pm_callback = ural_command_wrapper; - task->func = fn; - task->sc = sc; - - /* Make sure that any TX operation will stop */ - sc->sc_last_task = task; - - /* - * Init, stop and flush must be synchronous! - */ - if ((fn == ural_init_task) || (fn == ural_stop_task) || - (fn == ural_stop_task)) - usb2_proc_mwait(&sc->sc_tq, t0, t1); -} diff --git a/sys/dev/usb/wlan/if_uralvar.h b/sys/dev/usb/wlan/if_uralvar.h index 13a3df8..5149f6b 100644 --- a/sys/dev/usb/wlan/if_uralvar.h +++ b/sys/dev/usb/wlan/if_uralvar.h @@ -59,12 +59,6 @@ struct ural_tx_radiotap_header { struct ural_softc; -struct ural_task { - struct usb2_proc_msg hdr; - usb2_proc_callback_t *func; - struct ural_softc *sc; -}; - struct ural_tx_data { STAILQ_ENTRY(ural_tx_data) next; struct ural_softc *sc; @@ -83,11 +77,10 @@ struct ural_node { struct ural_vap { struct ieee80211vap vap; - struct ural_softc *sc; struct ieee80211_beacon_offsets bo; struct ieee80211_amrr amrr; struct usb2_callout amrr_ch; - struct ural_task amrr_task[2]; + struct task amrr_task; int (*newstate)(struct ieee80211vap *, enum ieee80211_state, int); @@ -104,21 +97,11 @@ struct ural_softc { struct ifnet *sc_ifp; device_t sc_dev; struct usb2_device *sc_udev; - struct usb2_process sc_tq; uint32_t asic_rev; uint8_t rf_rev; struct usb2_xfer *sc_xfer[URAL_N_TRANSFER]; - struct ural_task *sc_last_task; - - enum ieee80211_state sc_state; - int sc_arg; - int sc_scan_action; /* should be an enum */ - struct ural_task sc_synctask[2]; - struct ural_task sc_task[2]; - struct ural_task sc_promisctask[2]; - struct ural_task sc_scantask[2]; struct ural_tx_data tx_data[RAL_TX_LIST_COUNT]; ural_txdhead tx_q; @@ -127,7 +110,6 @@ struct ural_softc { struct ural_rx_desc sc_rx_desc; struct mtx sc_mtx; - struct cv sc_cmd_cv; uint16_t sta[11]; uint32_t rf_regs[4]; diff --git a/sys/dev/usb/wlan/if_zyd.c b/sys/dev/usb/wlan/if_zyd.c index 6858d55..c386ea8 100644 --- a/sys/dev/usb/wlan/if_zyd.c +++ b/sys/dev/usb/wlan/if_zyd.c @@ -26,20 +26,56 @@ __FBSDID("$FreeBSD$"); * ZyDAS ZD1211/ZD1211B USB WLAN driver. */ -#include "usbdevs.h" +#include <sys/param.h> +#include <sys/sockio.h> +#include <sys/sysctl.h> +#include <sys/lock.h> +#include <sys/mutex.h> +#include <sys/mbuf.h> +#include <sys/kernel.h> +#include <sys/socket.h> +#include <sys/systm.h> +#include <sys/malloc.h> +#include <sys/module.h> +#include <sys/bus.h> +#include <sys/endian.h> +#include <sys/kdb.h> + +#include <machine/bus.h> +#include <machine/resource.h> +#include <sys/rman.h> + +#include <net/bpf.h> +#include <net/if.h> +#include <net/if_arp.h> +#include <net/ethernet.h> +#include <net/if_dl.h> +#include <net/if_media.h> +#include <net/if_types.h> + +#ifdef INET +#include <netinet/in.h> +#include <netinet/in_systm.h> +#include <netinet/in_var.h> +#include <netinet/if_ether.h> +#include <netinet/ip.h> +#endif + +#include <net80211/ieee80211_var.h> +#include <net80211/ieee80211_regdomain.h> +#include <net80211/ieee80211_radiotap.h> +#include <net80211/ieee80211_amrr.h> + #include <dev/usb/usb.h> -#include <dev/usb/usb_mfunc.h> #include <dev/usb/usb_error.h> - #include <dev/usb/usb_core.h> #include <dev/usb/usb_lookup.h> -#include <dev/usb/usb_process.h> #include <dev/usb/usb_debug.h> #include <dev/usb/usb_request.h> #include <dev/usb/usb_busdma.h> #include <dev/usb/usb_util.h> +#include "usbdevs.h" -#include <dev/usb/wlan/usb_wlan.h> #include <dev/usb/wlan/if_zydreg.h> #include <dev/usb/wlan/if_zydfw.h> @@ -74,7 +110,7 @@ enum { #endif #define zyd_do_request(sc,req,data) \ - usb2_do_request_proc((sc)->sc_udev, &(sc)->sc_tq, req, data, 0, NULL, 5000) + usb2_do_request_flags((sc)->sc_udev, &(sc)->sc_mtx, req, data, 0, NULL, 5000) static device_probe_t zyd_match; static device_attach_t zyd_attach; @@ -85,14 +121,6 @@ static usb2_callback_t zyd_intr_write_callback; static usb2_callback_t zyd_bulk_read_callback; static usb2_callback_t zyd_bulk_write_callback; -static usb2_proc_callback_t zyd_attach_post; -static usb2_proc_callback_t zyd_task; -static usb2_proc_callback_t zyd_scantask; -static usb2_proc_callback_t zyd_multitask; -static usb2_proc_callback_t zyd_init_task; -static usb2_proc_callback_t zyd_stop_task; -static usb2_proc_callback_t zyd_flush_task; - static struct ieee80211vap *zyd_vap_create(struct ieee80211com *, const char name[IFNAMSIZ], int unit, int opmode, int flags, const uint8_t bssid[IEEE80211_ADDR_LEN], @@ -137,7 +165,9 @@ static void zyd_start(struct ifnet *); static int zyd_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); static int zyd_ioctl(struct ifnet *, u_long, caddr_t); +static void zyd_init_locked(struct zyd_softc *); static void zyd_init(void *); +static void zyd_stop(struct zyd_softc *); static int zyd_loadfirmware(struct zyd_softc *); static void zyd_newassoc(struct ieee80211_node *, int); static void zyd_scan_start(struct ieee80211com *); @@ -166,8 +196,6 @@ static int zyd_maxim_set_channel(struct zyd_rf *, uint8_t); static int zyd_maxim2_init(struct zyd_rf *); static int zyd_maxim2_switch_radio(struct zyd_rf *, int); static int zyd_maxim2_set_channel(struct zyd_rf *, uint8_t); -static void zyd_queue_command(struct zyd_softc *, usb2_proc_callback_t *, - struct usb2_proc_msg *, struct usb2_proc_msg *); static const struct zyd_phy_pair zyd_def_phy[] = ZYD_DEF_PHY; static const struct zyd_phy_pair zyd_def_phyB[] = ZYD_DEF_PHYB; @@ -307,8 +335,10 @@ zyd_attach(device_t dev) { struct usb2_attach_arg *uaa = device_get_ivars(dev); struct zyd_softc *sc = device_get_softc(dev); + struct ifnet *ifp; + struct ieee80211com *ic; + uint8_t iface_index, bands; int error; - uint8_t iface_index; if (uaa->info.bcdDevice < 0x4330) { device_printf(dev, "device version mismatch: 0x%X " @@ -324,7 +354,6 @@ zyd_attach(device_t dev) mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev), MTX_NETWORK_LOCK, MTX_DEF); - cv_init(&sc->sc_cmd_cv, "wtxdone"); STAILQ_INIT(&sc->sc_rqh); iface_index = ZYD_IFACE_INDEX; @@ -336,52 +365,19 @@ zyd_attach(device_t dev) "err=%s\n", usb2_errstr(error)); goto detach; } - error = usb2_proc_create(&sc->sc_tq, &sc->sc_mtx, - device_get_nameunit(dev), USB_PRI_MED); - if (error) { - device_printf(dev, "could not setup config thread!\n"); - goto detach; - } - /* fork rest of the attach code */ ZYD_LOCK(sc); - zyd_queue_command(sc, zyd_attach_post, - &sc->sc_synctask[0].hdr, - &sc->sc_synctask[1].hdr); - ZYD_UNLOCK(sc); - return (0); - -detach: - zyd_detach(dev); - return (ENXIO); /* failure */ -} - -static void -zyd_attach_post(struct usb2_proc_msg *pm) -{ - struct zyd_task *task = (struct zyd_task *)pm; - struct zyd_softc *sc = task->sc; - struct ifnet *ifp; - struct ieee80211com *ic; - int error; - uint8_t bands; - if ((error = zyd_get_macaddr(sc)) != 0) { device_printf(sc->sc_dev, "could not read EEPROM\n"); - return; + ZYD_UNLOCK(sc); + goto detach; } - - /* XXX Async attach race */ - if (usb2_proc_is_gone(&sc->sc_tq)) - return; - ZYD_UNLOCK(sc); ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); if (ifp == NULL) { device_printf(sc->sc_dev, "can not if_alloc()\n"); - ZYD_LOCK(sc); - return; + goto detach; } ifp->if_softc = sc; if_initname(ifp, "zyd", device_get_unit(sc->sc_dev)); @@ -437,7 +433,11 @@ zyd_attach_post(struct usb2_proc_msg *pm) if (bootverbose) ieee80211_announce(ic); - ZYD_LOCK(sc); + return (0); + +detach: + zyd_detach(dev); + return (ENXIO); /* failure */ } static int @@ -447,12 +447,8 @@ zyd_detach(device_t dev) struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic; - /* wait for any post attach or other command to complete */ - usb2_proc_drain(&sc->sc_tq); - /* stop all USB transfers */ usb2_transfer_unsetup(sc->sc_xfer, ZYD_N_TRANSFER); - usb2_proc_free(&sc->sc_tq); /* free TX list, if any */ zyd_unsetup_tx_list(sc); @@ -463,7 +459,6 @@ zyd_detach(device_t dev) ieee80211_ifdetach(ic); if_free(ifp); } - cv_destroy(&sc->sc_cmd_cv); mtx_destroy(&sc->sc_mtx); return (0); @@ -475,7 +470,6 @@ zyd_vap_create(struct ieee80211com *ic, const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t mac[IEEE80211_ADDR_LEN]) { - struct zyd_softc *sc = ic->ic_ifp->if_softc; struct zyd_vap *zvp; struct ieee80211vap *vap; @@ -494,7 +488,6 @@ zyd_vap_create(struct ieee80211com *ic, zvp->newstate = vap->iv_newstate; vap->iv_newstate = zyd_newstate; - zvp->sc = sc; ieee80211_amrr_init(&zvp->amrr, vap, IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD, IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD, @@ -508,23 +501,9 @@ zyd_vap_create(struct ieee80211com *ic, } static void -zyd_flush_task(struct usb2_proc_msg *_pm) -{ - /* nothing to do */ -} - -static void zyd_vap_delete(struct ieee80211vap *vap) { struct zyd_vap *zvp = ZYD_VAP(vap); - struct zyd_softc *sc = zvp->sc; - - ZYD_LOCK(sc); - /* wait for any pending tasks to complete */ - zyd_queue_command(sc, zyd_flush_task, - &sc->sc_synctask[0].hdr, - &sc->sc_synctask[1].hdr); - ZYD_UNLOCK(sc); ieee80211_amrr_cleanup(&zvp->amrr); ieee80211_vap_detach(vap); @@ -606,34 +585,38 @@ zyd_node_alloc(struct ieee80211vap *vap __unused, return (zn != NULL) ? (&zn->ni) : (NULL); } -static void -zyd_task(struct usb2_proc_msg *pm) +static int +zyd_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { - struct zyd_task *task = (struct zyd_task *)pm; - struct zyd_softc *sc = task->sc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); - struct ieee80211_node *ni = vap->iv_bss; struct zyd_vap *zvp = ZYD_VAP(vap); + struct ieee80211com *ic = vap->iv_ic; + struct zyd_softc *sc = ic->ic_ifp->if_softc; + struct ieee80211_node *ni; int error; - switch (sc->sc_state) { + DPRINTF(sc, ZYD_DEBUG_STATE, "%s: %s -> %s\n", __func__, + ieee80211_state_name[vap->iv_state], + ieee80211_state_name[nstate]); + + IEEE80211_UNLOCK(ic); + ZYD_LOCK(sc); + switch (nstate) { case IEEE80211_S_AUTH: zyd_set_chan(sc, ic->ic_curchan); break; case IEEE80211_S_RUN: + ni = vap->iv_bss; if (vap->iv_opmode == IEEE80211_M_MONITOR) break; /* turn link LED on */ error = zyd_set_led(sc, ZYD_LED1, 1); if (error != 0) - goto fail; - + break; + /* make data LED blink upon Tx */ zyd_write32_m(sc, sc->sc_fwbase + ZYD_FW_LINK_STATUS, 1); - + IEEE80211_ADDR_COPY(sc->sc_bssid, ni->ni_bssid); zyd_set_bssid(sc, sc->sc_bssid); break; @@ -643,40 +626,7 @@ zyd_task(struct usb2_proc_msg *pm) fail: ZYD_UNLOCK(sc); IEEE80211_LOCK(ic); - zvp->newstate(vap, sc->sc_state, sc->sc_arg); - if (vap->iv_newstate_cb != NULL) - vap->iv_newstate_cb(vap, sc->sc_state, sc->sc_arg); - IEEE80211_UNLOCK(ic); - ZYD_LOCK(sc); -} - -static int -zyd_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) -{ - struct zyd_vap *zvp = ZYD_VAP(vap); - struct ieee80211com *ic = vap->iv_ic; - struct zyd_softc *sc = ic->ic_ifp->if_softc; - - DPRINTF(sc, ZYD_DEBUG_STATE, "%s: %s -> %s\n", __func__, - ieee80211_state_name[vap->iv_state], - ieee80211_state_name[nstate]); - - ZYD_LOCK(sc); - /* do it in a process context */ - sc->sc_state = nstate; - sc->sc_arg = arg; - ZYD_UNLOCK(sc); - - if (nstate == IEEE80211_S_INIT) { - zvp->newstate(vap, nstate, arg); - return (0); - } else { - ZYD_LOCK(sc); - zyd_queue_command(sc, zyd_task, &sc->sc_task[0].hdr, - &sc->sc_task[1].hdr); - ZYD_UNLOCK(sc); - return (EINPROGRESS); - } + return (zvp->newstate(vap, nstate, arg)); } /* @@ -845,9 +795,6 @@ zyd_cmd(struct zyd_softc *sc, uint16_t code, const void *idata, int ilen, if (ilen > sizeof(cmd.data)) return (EINVAL); - if (usb2_proc_is_gone(&sc->sc_tq)) - return (ENXIO); - cmd.code = htole16(code); bcopy(idata, cmd.data, ilen); DPRINTF(sc, ZYD_DEBUG_CMD, "sending cmd %p = %*D\n", @@ -2012,15 +1959,6 @@ fail: } static void -zyd_multitask(struct usb2_proc_msg *pm) -{ - struct zyd_task *task = (struct zyd_task *)pm; - struct zyd_softc *sc = task->sc; - - zyd_set_multi(sc); -} - -static void zyd_set_multi(struct zyd_softc *sc) { int error; @@ -2073,8 +2011,7 @@ zyd_update_mcast(struct ifnet *ifp) return; ZYD_LOCK(sc); - zyd_queue_command(sc, zyd_multitask, - &sc->sc_mcasttask[0].hdr, &sc->sc_mcasttask[1].hdr); + zyd_set_multi(sc); ZYD_UNLOCK(sc); } @@ -2502,10 +2439,6 @@ zyd_bulk_write_callback(struct usb2_xfer *xfer) struct zyd_tx_data *data; struct mbuf *m; - /* wakeup any waiting command, if any */ - if (sc->sc_last_task != NULL) - cv_signal(&sc->sc_cmd_cv); - switch (USB_GET_STATE(xfer)) { case USB_ST_TRANSFERRED: DPRINTF(sc, ZYD_DEBUG_ANY, "transfer complete, %u bytes\n", @@ -2522,10 +2455,6 @@ zyd_bulk_write_callback(struct usb2_xfer *xfer) /* FALLTHROUGH */ case USB_ST_SETUP: tr_setup: - /* wait for command to complete, if any */ - if (sc->sc_last_task != NULL) - break; - data = STAILQ_FIRST(&sc->tx_q); if (data) { STAILQ_REMOVE_HEAD(&sc->tx_q, next); @@ -2757,22 +2686,14 @@ zyd_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) case SIOCSIFFLAGS: ZYD_LOCK(sc); if (ifp->if_flags & IFF_UP) { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - zyd_queue_command(sc, zyd_multitask, - &sc->sc_mcasttask[0].hdr, - &sc->sc_mcasttask[1].hdr); - } else { - zyd_queue_command(sc, zyd_init_task, - &sc->sc_synctask[0].hdr, - &sc->sc_synctask[1].hdr); + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { + zyd_init_locked(sc); startall = 1; - } + } else + zyd_set_multi(sc); } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - zyd_queue_command(sc, zyd_stop_task, - &sc->sc_synctask[0].hdr, - &sc->sc_synctask[1].hdr); - } + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + zyd_stop(sc); } ZYD_UNLOCK(sc); if (startall) @@ -2792,10 +2713,8 @@ zyd_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) } static void -zyd_init_task(struct usb2_proc_msg *pm) +zyd_init_locked(struct zyd_softc *sc) { - struct zyd_task *task = (struct zyd_task *)pm; - struct zyd_softc *sc = task->sc; struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = ifp->if_l2com; struct usb2_config_descriptor *cd; @@ -2850,7 +2769,7 @@ zyd_init_task(struct usb2_proc_msg *pm) } if (ifp->if_drv_flags & IFF_DRV_RUNNING) - zyd_stop_task(pm); + zyd_stop(sc); DPRINTF(sc, ZYD_DEBUG_INIT, "setting MAC address to %6D\n", IF_LLADDR(ifp), ":"); @@ -2898,7 +2817,7 @@ zyd_init_task(struct usb2_proc_msg *pm) return; -fail: zyd_stop_task(pm); +fail: zyd_stop(sc); return; } @@ -2910,9 +2829,7 @@ zyd_init(void *priv) struct ieee80211com *ic = ifp->if_l2com; ZYD_LOCK(sc); - zyd_queue_command(sc, zyd_init_task, - &sc->sc_synctask[0].hdr, - &sc->sc_synctask[1].hdr); + zyd_init_locked(sc); ZYD_UNLOCK(sc); if (ifp->if_drv_flags & IFF_DRV_RUNNING) @@ -2920,10 +2837,8 @@ zyd_init(void *priv) } static void -zyd_stop_task(struct usb2_proc_msg *pm) +zyd_stop(struct zyd_softc *sc) { - struct zyd_task *task = (struct zyd_task *)pm; - struct zyd_softc *sc = task->sc; struct ifnet *ifp = sc->sc_ifp; int error; @@ -3029,13 +2944,12 @@ zyd_newassoc(struct ieee80211_node *ni, int isnew) static void zyd_scan_start(struct ieee80211com *ic) { - struct zyd_softc *sc = ic->ic_ifp->if_softc; + struct ifnet *ifp = ic->ic_ifp; + struct zyd_softc *sc = ifp->if_softc; ZYD_LOCK(sc); - /* do it in a process context */ - sc->sc_scan_action = ZYD_SCAN_START; - zyd_queue_command(sc, zyd_scantask, - &sc->sc_scantask[0].hdr, &sc->sc_scantask[1].hdr); + /* want broadcast address while scanning */ + zyd_set_bssid(sc, ifp->if_broadcastaddr); ZYD_UNLOCK(sc); } @@ -3045,10 +2959,8 @@ zyd_scan_end(struct ieee80211com *ic) struct zyd_softc *sc = ic->ic_ifp->if_softc; ZYD_LOCK(sc); - /* do it in a process context */ - sc->sc_scan_action = ZYD_SCAN_END; - zyd_queue_command(sc, zyd_scantask, - &sc->sc_scantask[0].hdr, &sc->sc_scantask[1].hdr); + /* restore previous bssid */ + zyd_set_bssid(sc, sc->sc_bssid); ZYD_UNLOCK(sc); } @@ -3058,105 +2970,16 @@ zyd_set_channel(struct ieee80211com *ic) struct zyd_softc *sc = ic->ic_ifp->if_softc; ZYD_LOCK(sc); - /* do it in a process context */ - sc->sc_scan_action = ZYD_SET_CHANNEL; - zyd_queue_command(sc, zyd_scantask, - &sc->sc_scantask[0].hdr, &sc->sc_scantask[1].hdr); + zyd_set_chan(sc, ic->ic_curchan); ZYD_UNLOCK(sc); } -static void -zyd_scantask(struct usb2_proc_msg *pm) -{ - struct zyd_task *task = (struct zyd_task *)pm; - struct zyd_softc *sc = task->sc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - - ZYD_LOCK_ASSERT(sc, MA_OWNED); - - switch (sc->sc_scan_action) { - case ZYD_SCAN_START: - /* want broadcast address while scanning */ - zyd_set_bssid(sc, ifp->if_broadcastaddr); - break; - - case ZYD_SET_CHANNEL: - zyd_set_chan(sc, ic->ic_curchan); - break; - - default: /* ZYD_SCAN_END */ - /* restore previous bssid */ - zyd_set_bssid(sc, sc->sc_bssid); - break; - } -} - -static void -zyd_command_wrapper(struct usb2_proc_msg *pm) -{ - struct zyd_task *task = (struct zyd_task *)pm; - struct zyd_softc *sc = task->sc; - struct ifnet *ifp; - - /* wait for pending transfer, if any */ - while (usb2_transfer_pending(sc->sc_xfer[ZYD_BULK_WR])) - cv_wait(&sc->sc_cmd_cv, &sc->sc_mtx); - - /* make sure any hardware FIFOs are emptied */ - usb2_pause_mtx(&sc->sc_mtx, hz / 1000); - - /* execute task */ - task->func(pm); - - /* check if this is the last task executed */ - if (sc->sc_last_task == task) { - sc->sc_last_task = NULL; - ifp = sc->sc_ifp; - /* re-start TX, if any */ - if ((ifp != NULL) && (ifp->if_drv_flags & IFF_DRV_RUNNING)) - usb2_transfer_start(sc->sc_xfer[ZYD_BULK_WR]); - } -} - -static void -zyd_queue_command(struct zyd_softc *sc, usb2_proc_callback_t *fn, - struct usb2_proc_msg *t0, struct usb2_proc_msg *t1) -{ - struct zyd_task *task; - - ZYD_LOCK_ASSERT(sc, MA_OWNED); - - /* - * NOTE: The task cannot get executed before we drop the - * "sc_mtx" mutex. It is safe to update fields in the message - * structure after that the message got queued. - */ - task = (struct zyd_task *) - usb2_proc_msignal(&sc->sc_tq, t0, t1); - - /* Setup callback and softc pointers */ - task->hdr.pm_callback = zyd_command_wrapper; - task->func = fn; - task->sc = sc; - - /* Make sure that any TX operation will stop */ - sc->sc_last_task = task; - - /* - * Init and stop must be synchronous! - */ - if ((fn == zyd_init_task) || (fn == zyd_stop_task) || - (fn == zyd_flush_task)) - usb2_proc_mwait(&sc->sc_tq, t0, t1); -} - static device_method_t zyd_methods[] = { /* Device interface */ DEVMETHOD(device_probe, zyd_match), DEVMETHOD(device_attach, zyd_attach), DEVMETHOD(device_detach, zyd_detach), - + { 0, 0 } }; diff --git a/sys/dev/usb/wlan/if_zydreg.h b/sys/dev/usb/wlan/if_zydreg.h index fabed61..cd60593 100644 --- a/sys/dev/usb/wlan/if_zydreg.h +++ b/sys/dev/usb/wlan/if_zydreg.h @@ -1163,12 +1163,6 @@ struct zyd_mac_pair { uint32_t val; }; -struct zyd_task { - struct usb2_proc_msg hdr; - usb2_proc_callback_t *func; - struct zyd_softc *sc; -}; - struct zyd_tx_data { STAILQ_ENTRY(zyd_tx_data) next; struct zyd_softc *sc; @@ -1248,7 +1242,6 @@ struct zyd_vap { struct ieee80211vap vap; int (*newstate)(struct ieee80211vap *, enum ieee80211_state, int); - struct zyd_softc *sc; struct ieee80211_amrr amrr; }; #define ZYD_VAP(vap) ((struct zyd_vap *)(vap)) @@ -1265,27 +1258,14 @@ struct zyd_softc { struct ifnet *sc_ifp; device_t sc_dev; struct usb2_device *sc_udev; - struct usb2_process sc_tq; struct usb2_xfer *sc_xfer[ZYD_N_TRANSFER]; - struct zyd_task *sc_last_task; - enum ieee80211_state sc_state; - int sc_arg; int sc_flags; #define ZYD_FLAG_FWLOADED (1 << 0) #define ZYD_FLAG_INITONCE (1 << 1) #define ZYD_FLAG_INITDONE (1 << 2) - struct zyd_task sc_synctask[2]; - struct zyd_task sc_mcasttask[2]; - struct zyd_task sc_scantask[2]; - int sc_scan_action; -#define ZYD_SCAN_START 0 -#define ZYD_SCAN_END 1 -#define ZYD_SET_CHANNEL 2 - struct zyd_task sc_task[2]; - struct zyd_rf sc_rf; STAILQ_HEAD(, zyd_rq) sc_rtx; @@ -1317,7 +1297,6 @@ struct zyd_softc { uint8_t sc_ofdm54_cal[14]; struct mtx sc_mtx; - struct cv sc_cmd_cv; struct zyd_tx_data tx_data[ZYD_TX_LIST_CNT]; zyd_txdhead tx_q; zyd_txdhead tx_free; diff --git a/sys/dev/usb/wlan/usb_wlan.h b/sys/dev/usb/wlan/usb_wlan.h deleted file mode 100644 index aa0f1c4..0000000 --- a/sys/dev/usb/wlan/usb_wlan.h +++ /dev/null @@ -1,56 +0,0 @@ -/* $FreeBSD$ */ -/*- - * Copyright (c) 2008 Hans Petter Selasky. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef _USB2_WLAN_H_ -#define _USB2_WLAN_H_ - -#include <sys/param.h> -#include <sys/sockio.h> -#include <sys/mbuf.h> -#include <sys/kernel.h> -#include <sys/socket.h> - -#include <net/bpf.h> -#include <net/if.h> -#include <net/if_arp.h> -#include <net/ethernet.h> -#include <net/if_dl.h> -#include <net/if_media.h> -#include <net/if_types.h> -#include <net/if_clone.h> - -#include <net80211/ieee80211_var.h> -#include <net80211/ieee80211_radiotap.h> -#include <net80211/ieee80211_amrr.h> -#include <net80211/ieee80211_regdomain.h> - -#include <netinet/in.h> -#include <netinet/in_systm.h> -#include <netinet/in_var.h> -#include <netinet/ip.h> -#include <netinet/if_ether.h> - -#endif /* _USB2_WLAN_H_ */ |