summaryrefslogtreecommitdiffstats
path: root/sys/dev/usb
diff options
context:
space:
mode:
authorthompsa <thompsa@FreeBSD.org>2009-05-02 15:14:18 +0000
committerthompsa <thompsa@FreeBSD.org>2009-05-02 15:14:18 +0000
commited7c3176b96444dc82c6a07114013192611024f3 (patch)
tree46c2c9933cb1753f24ffd7c0096b2ba9074180d2 /sys/dev/usb
parentb704e6092a4076e74c276c0d531447a8cb3bf6a6 (diff)
downloadFreeBSD-src-ed7c3176b96444dc82c6a07114013192611024f3.zip
FreeBSD-src-ed7c3176b96444dc82c6a07114013192611024f3.tar.gz
Create a taskqueue for each wireless interface which provides a serialised
sleepable context for net80211 driver callbacks. This removes the need for USB and firmware based drivers to roll their own code to defer the chip programming for state changes, scan requests, channel changes and mcast/promisc updates. When a driver callback completes the hardware state is now guaranteed to have been updated and is in sync with net80211 layer. This nukes around 1300 lines of code from the wireless device drivers making them more readable and less race prone. The net80211 layer has been updated as follows - all state/channel changes are serialised on the taskqueue. - ieee80211_new_state() always queues and can now be called from any context - scanning runs from a single taskq function and executes to completion. driver callbacks are synchronous so the channel, phy mode and rx filters are guaranteed to be set in hardware before probe request frames are transmitted. Help and contributions from Sam Leffler. Reviewed by: sam
Diffstat (limited to 'sys/dev/usb')
-rw-r--r--sys/dev/usb/wlan/if_rum.c385
-rw-r--r--sys/dev/usb/wlan/if_rumvar.h23
-rw-r--r--sys/dev/usb/wlan/if_uath.c18
-rw-r--r--sys/dev/usb/wlan/if_uathvar.h1
-rw-r--r--sys/dev/usb/wlan/if_ural.c390
-rw-r--r--sys/dev/usb/wlan/if_uralvar.h20
-rw-r--r--sys/dev/usb/wlan/if_zyd.c361
-rw-r--r--sys/dev/usb/wlan/if_zydreg.h21
-rw-r--r--sys/dev/usb/wlan/usb_wlan.h56
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_ */
OpenPOWER on IntegriCloud