summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/if_ndis/if_ndis.c145
-rw-r--r--sys/dev/if_ndis/if_ndisvar.h5
-rw-r--r--sys/dev/ipw/if_ipw.c138
-rw-r--r--sys/dev/ipw/if_ipwvar.h8
-rw-r--r--sys/dev/iwi/if_iwi.c315
-rw-r--r--sys/dev/iwi/if_iwivar.h33
-rw-r--r--sys/dev/iwn/if_iwn.c326
-rw-r--r--sys/dev/iwn/if_iwnvar.h35
-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
-rw-r--r--sys/dev/wi/if_wi.c72
-rw-r--r--sys/dev/wi/if_wivar.h4
-rw-r--r--sys/dev/wpi/if_wpi.c252
-rw-r--r--sys/dev/wpi/if_wpivar.h41
21 files changed, 681 insertions, 1968 deletions
diff --git a/sys/dev/if_ndis/if_ndis.c b/sys/dev/if_ndis/if_ndis.c
index dfff9e8..8f5054b 100644
--- a/sys/dev/if_ndis/if_ndis.c
+++ b/sys/dev/if_ndis/if_ndis.c
@@ -50,7 +50,6 @@ __FBSDID("$FreeBSD$");
#include <sys/proc.h>
#include <sys/sysctl.h>
#include <sys/kthread.h>
-#include <sys/taskqueue.h>
#include <net/if.h>
@@ -173,7 +172,7 @@ static int ndis_newstate (struct ieee80211vap *, enum ieee80211_state,
int);
static int ndis_nettype_chan (uint32_t);
static int ndis_nettype_mode (uint32_t);
-static void ndis_scan (void *, int);
+static void ndis_scan (void *);
static void ndis_scan_results (struct ndis_softc *);
static void ndis_scan_start (struct ieee80211com *);
static void ndis_scan_end (struct ieee80211com *);
@@ -184,8 +183,6 @@ static void ndis_init (void *);
static void ndis_stop (struct ndis_softc *);
static int ndis_ifmedia_upd (struct ifnet *);
static void ndis_ifmedia_sts (struct ifnet *, struct ifmediareq *);
-static void ndis_auth (void *, int);
-static void ndis_assoc (void *, int);
static int ndis_get_assoc (struct ndis_softc *, ndis_wlan_bssid_ex **);
static int ndis_probe_offload (struct ndis_softc *);
static int ndis_set_offload (struct ndis_softc *);
@@ -741,13 +738,7 @@ ndis_attach(dev)
uint32_t arg;
int r;
- sc->ndis_tq = taskqueue_create("nids_taskq", M_NOWAIT | M_ZERO,
- taskqueue_thread_enqueue, &sc->ndis_tq);
- taskqueue_start_threads(&sc->ndis_tq, 1, PI_NET, "%s taskq",
- device_get_nameunit(dev));
- TASK_INIT(&sc->ndis_scantask, 0, ndis_scan, sc);
- TASK_INIT(&sc->ndis_authtask, 0, ndis_auth, sc);
- TASK_INIT(&sc->ndis_assoctask, 0, ndis_assoc, sc);
+ callout_init(&sc->ndis_scan_callout, CALLOUT_MPSAFE);
ifp->if_ioctl = ndis_ioctl_80211;
ic->ic_ifp = ifp;
@@ -1054,12 +1045,6 @@ ndis_detach(dev)
} else
NDIS_UNLOCK(sc);
- if (sc->ndis_80211) {
- taskqueue_drain(sc->ndis_tq, &sc->ndis_scantask);
- taskqueue_drain(sc->ndis_tq, &sc->ndis_authtask);
- taskqueue_drain(sc->ndis_tq, &sc->ndis_assoctask);
- }
-
if (sc->ndis_tickitem != NULL)
IoFreeWorkItem(sc->ndis_tickitem);
if (sc->ndis_startitem != NULL)
@@ -1121,8 +1106,6 @@ ndis_detach(dev)
if (sc->ndis_iftype == PCIBus)
bus_dma_tag_destroy(sc->ndis_parent_tag);
- if (sc->ndis_80211)
- taskqueue_free(sc->ndis_tq);
return(0);
}
@@ -2419,30 +2402,6 @@ ndis_setstate_80211(sc)
}
static void
-ndis_auth(void *arg, int npending)
-{
- struct ndis_softc *sc = arg;
- struct ifnet *ifp = sc->ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
-
- vap->iv_state = IEEE80211_S_AUTH;
- ndis_auth_and_assoc(sc, vap);
-}
-
-static void
-ndis_assoc(void *arg, int npending)
-{
- struct ndis_softc *sc = arg;
- struct ifnet *ifp = sc->ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
-
- vap->iv_state = IEEE80211_S_ASSOC;
- ndis_auth_and_assoc(sc, vap);
-}
-
-static void
ndis_auth_and_assoc(sc, vap)
struct ndis_softc *sc;
struct ieee80211vap *vap;
@@ -2656,9 +2615,6 @@ ndis_auth_and_assoc(sc, vap)
if (rval)
device_printf (sc->ndis_dev, "set ssid failed: %d\n", rval);
- if (vap->iv_state == IEEE80211_S_AUTH)
- ieee80211_new_state(vap, IEEE80211_S_ASSOC, 0);
-
return;
}
@@ -3304,13 +3260,18 @@ ndis_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
return nvp->newstate(vap, nstate, arg);
case IEEE80211_S_ASSOC:
if (ostate != IEEE80211_S_AUTH) {
- taskqueue_enqueue(sc->ndis_tq, &sc->ndis_assoctask);
- return EINPROGRESS;
+ IEEE80211_UNLOCK(ic);
+ ndis_auth_and_assoc(sc, vap);
+ IEEE80211_LOCK(ic);
}
break;
case IEEE80211_S_AUTH:
- taskqueue_enqueue(sc->ndis_tq, &sc->ndis_authtask);
- return EINPROGRESS;
+ IEEE80211_UNLOCK(ic);
+ ndis_auth_and_assoc(sc, vap);
+ if (vap->iv_state == IEEE80211_S_AUTH) /* XXX */
+ ieee80211_new_state(vap, IEEE80211_S_ASSOC, 0);
+ IEEE80211_LOCK(ic);
+ break;
default:
break;
}
@@ -3318,54 +3279,18 @@ ndis_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
}
static void
-ndis_scan(void *arg, int npending)
+ndis_scan(void *arg)
{
struct ndis_softc *sc = arg;
struct ieee80211com *ic;
struct ieee80211vap *vap;
- struct ieee80211_scan_state *ss;
- ndis_80211_ssid ssid;
- int error, len;
ic = sc->ifp->if_l2com;
- ss = ic->ic_scan;
vap = TAILQ_FIRST(&ic->ic_vaps);
- if (!NDIS_INITIALIZED(sc)) {
- DPRINTF(("%s: scan aborted\n", __func__));
- ieee80211_cancel_scan(vap);
- return;
- }
-
- len = sizeof(ssid);
- bzero((char *)&ssid, len);
- if (ss->ss_nssid == 0)
- ssid.ns_ssidlen = 1;
- else {
- /* Perform a directed scan */
- ssid.ns_ssidlen = ss->ss_ssid[0].len;
- bcopy(ss->ss_ssid[0].ssid, ssid.ns_ssid, ssid.ns_ssidlen);
- }
-
- error = ndis_set_info(sc, OID_802_11_SSID, &ssid, &len);
- if (error)
- DPRINTF(("%s: set ESSID failed\n", __func__));
-
- len = 0;
- error = ndis_set_info(sc, OID_802_11_BSSID_LIST_SCAN,
- NULL, &len);
- if (error) {
- DPRINTF(("%s: scan command failed\n", __func__));
- ieee80211_cancel_scan(vap);
- return;
- }
-
- pause("ssidscan", hz * 3);
- if (!NDIS_INITIALIZED(sc))
- /* The interface was downed while we were sleeping */
- return;
-
+ NDIS_LOCK(sc);
ndis_scan_results(sc);
+ NDIS_UNLOCK(sc);
ieee80211_scan_done(vap);
}
@@ -3496,8 +3421,48 @@ ndis_scan_start(struct ieee80211com *ic)
{
struct ifnet *ifp = ic->ic_ifp;
struct ndis_softc *sc = ifp->if_softc;
+ struct ieee80211vap *vap;
+ struct ieee80211_scan_state *ss;
+ ndis_80211_ssid ssid;
+ int error, len;
+
+ ss = ic->ic_scan;
+ vap = TAILQ_FIRST(&ic->ic_vaps);
+
+ NDIS_LOCK(sc);
+ if (!NDIS_INITIALIZED(sc)) {
+ DPRINTF(("%s: scan aborted\n", __func__));
+ NDIS_UNLOCK(sc);
+ ieee80211_cancel_scan(vap);
+ return;
+ }
- taskqueue_enqueue(sc->ndis_tq, &sc->ndis_scantask);
+ len = sizeof(ssid);
+ bzero((char *)&ssid, len);
+ if (ss->ss_nssid == 0)
+ ssid.ns_ssidlen = 1;
+ else {
+ /* Perform a directed scan */
+ ssid.ns_ssidlen = ss->ss_ssid[0].len;
+ bcopy(ss->ss_ssid[0].ssid, ssid.ns_ssid, ssid.ns_ssidlen);
+ }
+
+ error = ndis_set_info(sc, OID_802_11_SSID, &ssid, &len);
+ if (error)
+ DPRINTF(("%s: set ESSID failed\n", __func__));
+
+ len = 0;
+ error = ndis_set_info(sc, OID_802_11_BSSID_LIST_SCAN,
+ NULL, &len);
+ if (error) {
+ DPRINTF(("%s: scan command failed\n", __func__));
+ NDIS_UNLOCK(sc);
+ ieee80211_cancel_scan(vap);
+ return;
+ }
+ NDIS_UNLOCK(sc);
+ /* Set a timer to collect the results */
+ callout_reset(&sc->ndis_scan_callout, hz * 3, ndis_scan, sc);
}
static void
diff --git a/sys/dev/if_ndis/if_ndisvar.h b/sys/dev/if_ndis/if_ndisvar.h
index 6db48a6..fc7ae4c 100644
--- a/sys/dev/if_ndis/if_ndisvar.h
+++ b/sys/dev/if_ndis/if_ndisvar.h
@@ -180,6 +180,7 @@ struct ndis_softc {
ndis_miniport_block *ndis_block;
ndis_miniport_characteristics *ndis_chars;
interface_type ndis_type;
+ struct callout ndis_scan_callout;
struct callout ndis_stat_callout;
int ndis_maxpkts;
ndis_oid *ndis_oids;
@@ -219,10 +220,6 @@ struct ndis_softc {
struct ifqueue ndis_rxqueue;
kspin_lock ndis_rxlock;
- struct taskqueue *ndis_tq; /* private task queue */
- struct task ndis_scantask;
- struct task ndis_authtask;
- struct task ndis_assoctask;
int (*ndis_newstate)(struct ieee80211com *,
enum ieee80211_state, int);
int ndis_tx_timer;
diff --git a/sys/dev/ipw/if_ipw.c b/sys/dev/ipw/if_ipw.c
index 5463f0a..9d67724 100644
--- a/sys/dev/ipw/if_ipw.c
+++ b/sys/dev/ipw/if_ipw.c
@@ -118,10 +118,6 @@ static void ipw_media_status(struct ifnet *, struct ifmediareq *);
static int ipw_newstate(struct ieee80211vap *, enum ieee80211_state, int);
static uint16_t ipw_read_prom_word(struct ipw_softc *, uint8_t);
static void ipw_rx_cmd_intr(struct ipw_softc *, struct ipw_soft_buf *);
-static void ipw_assocsuccess(void *, int);
-static void ipw_assocfailed(void *, int);
-static void ipw_scandone(void *, int);
-static void ipw_bmiss(void *, int);
static void ipw_rx_newstate_intr(struct ipw_softc *, struct ipw_soft_buf *);
static void ipw_rx_data_intr(struct ipw_softc *, struct ipw_status *,
struct ipw_soft_bd *, struct ipw_soft_buf *);
@@ -147,8 +143,8 @@ static int ipw_reset(struct ipw_softc *);
static int ipw_load_ucode(struct ipw_softc *, const char *, int);
static int ipw_load_firmware(struct ipw_softc *, const char *, int);
static int ipw_config(struct ipw_softc *);
-static void ipw_assoc_task(void *, int);
-static void ipw_disassoc_task(void *, int);
+static void ipw_assoc(struct ieee80211com *, struct ieee80211vap *);
+static void ipw_disassoc(struct ieee80211com *, struct ieee80211vap *);
static void ipw_init_task(void *, int);
static void ipw_init(void *);
static void ipw_init_locked(struct ipw_softc *);
@@ -166,7 +162,6 @@ static void ipw_read_mem_1(struct ipw_softc *, bus_size_t, uint8_t *,
#endif
static void ipw_write_mem_1(struct ipw_softc *, bus_size_t,
const uint8_t *, bus_size_t);
-static void ipw_scan_task(void *, int);
static int ipw_scan(struct ipw_softc *);
static void ipw_scan_start(struct ieee80211com *);
static void ipw_scan_end(struct ieee80211com *);
@@ -239,8 +234,6 @@ ipw_attach(device_t dev)
MTX_DEF | MTX_RECURSE);
TASK_INIT(&sc->sc_init_task, 0, ipw_init_task, sc);
- TASK_INIT(&sc->sc_scan_task, 0, ipw_scan_task, sc);
- TASK_INIT(&sc->sc_bmiss_task, 0, ipw_bmiss, sc);
callout_init_mtx(&sc->sc_wdtimer, &sc->sc_mtx, 0);
if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0) {
@@ -417,9 +410,7 @@ ipw_detach(device_t dev)
ieee80211_ifdetach(ic);
callout_drain(&sc->sc_wdtimer);
- taskqueue_drain(taskqueue_swi, &sc->sc_init_task);
- taskqueue_drain(taskqueue_swi, &sc->sc_scan_task);
- taskqueue_drain(taskqueue_swi, &sc->sc_bmiss_task);
+ ieee80211_draintask(ic, &sc->sc_init_task);
ipw_release(sc);
@@ -511,12 +502,6 @@ ipw_vap_create(struct ieee80211com *ic,
return NULL;
vap = &ivp->vap;
- TASK_INIT(&ivp->assoc_task, 0, ipw_assoc_task, vap);
- TASK_INIT(&ivp->disassoc_task, 0, ipw_disassoc_task, vap);
- TASK_INIT(&ivp->assoc_success_task, 0, ipw_assocsuccess, vap);
- TASK_INIT(&ivp->assoc_failed_task, 0, ipw_assocfailed, vap);
- TASK_INIT(&ivp->scandone_task, 0, ipw_scandone, vap);
-
ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
/* override with driver methods */
ivp->newstate = vap->iv_newstate;
@@ -894,11 +879,15 @@ ipw_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
struct ieee80211com *ic = vap->iv_ic;
struct ifnet *ifp = ic->ic_ifp;
struct ipw_softc *sc = ifp->if_softc;
+ enum ieee80211_state ostate;
DPRINTF(("%s: %s -> %s flags 0x%x\n", __func__,
ieee80211_state_name[vap->iv_state],
ieee80211_state_name[nstate], sc->flags));
+ ostate = vap->iv_state;
+ IEEE80211_UNLOCK(ic);
+
switch (nstate) {
case IEEE80211_S_RUN:
if (ic->ic_opmode == IEEE80211_M_IBSS) {
@@ -910,39 +899,33 @@ ipw_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
* AUTH -> RUN transition and we want to do nothing.
* This is all totally bogus and needs to be redone.
*/
- if (vap->iv_state == IEEE80211_S_SCAN) {
- taskqueue_enqueue(taskqueue_swi,
- &IPW_VAP(vap)->assoc_task);
- return EINPROGRESS;
- }
+ if (ostate == IEEE80211_S_SCAN)
+ ipw_assoc(ic, vap);
}
break;
case IEEE80211_S_INIT:
if (sc->flags & IPW_FLAG_ASSOCIATED)
- taskqueue_enqueue(taskqueue_swi,
- &IPW_VAP(vap)->disassoc_task);
+ ipw_disassoc(ic, vap);
break;
case IEEE80211_S_AUTH:
- taskqueue_enqueue(taskqueue_swi, &IPW_VAP(vap)->assoc_task);
- return EINPROGRESS;
+ ipw_assoc(ic, vap);
+ break;
case IEEE80211_S_ASSOC:
/*
* If we are not transitioning from AUTH the resend the
* association request.
*/
- if (vap->iv_state != IEEE80211_S_AUTH) {
- taskqueue_enqueue(taskqueue_swi,
- &IPW_VAP(vap)->assoc_task);
- return EINPROGRESS;
- }
+ if (ostate != IEEE80211_S_AUTH)
+ ipw_assoc(ic, vap);
break;
default:
break;
}
+ IEEE80211_LOCK(ic);
return ivp->newstate(vap, nstate, arg);
}
@@ -1020,38 +1003,6 @@ ipw_rx_cmd_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf)
}
static void
-ipw_assocsuccess(void *arg, int npending)
-{
- struct ieee80211vap *vap = arg;
-
- ieee80211_new_state(vap, IEEE80211_S_RUN, -1);
-}
-
-static void
-ipw_assocfailed(void *arg, int npending)
-{
- struct ieee80211vap *vap = arg;
-
- ieee80211_new_state(vap, IEEE80211_S_SCAN, -1);
-}
-
-static void
-ipw_scandone(void *arg, int npending)
-{
- struct ieee80211vap *vap = arg;
-
- ieee80211_scan_done(vap);
-}
-
-static void
-ipw_bmiss(void *arg, int npending)
-{
- struct ieee80211com *ic = arg;
-
- ieee80211_beacon_miss(ic);
-}
-
-static void
ipw_rx_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf)
{
#define IEEESTATE(vap) ieee80211_state_name[vap->iv_state]
@@ -1076,8 +1027,7 @@ ipw_rx_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf)
}
sc->flags &= ~IPW_FLAG_ASSOCIATING;
sc->flags |= IPW_FLAG_ASSOCIATED;
- taskqueue_enqueue(taskqueue_swi,
- &IPW_VAP(vap)->assoc_success_task);
+ ieee80211_new_state(vap, IEEE80211_S_RUN, -1);
break;
case IPW_STATE_SCANNING:
@@ -1091,7 +1041,7 @@ ipw_rx_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf)
*/
if (sc->flags & IPW_FLAG_ASSOCIATED) {
/* XXX probably need to issue disassoc to fw */
- taskqueue_enqueue(taskqueue_swi, &sc->sc_bmiss_task);
+ ieee80211_beacon_miss(ic);
}
break;
@@ -1110,8 +1060,7 @@ ipw_rx_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf)
break;
}
if (sc->flags & IPW_FLAG_SCANNING) {
- taskqueue_enqueue(taskqueue_swi,
- &IPW_VAP(vap)->scandone_task);
+ ieee80211_scan_done(vap);
sc->flags &= ~IPW_FLAG_SCANNING;
sc->sc_scan_timer = 0;
}
@@ -1122,8 +1071,7 @@ ipw_rx_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf)
IEEESTATE(vap), sc->flags));
sc->flags &= ~(IPW_FLAG_ASSOCIATING | IPW_FLAG_ASSOCIATED);
if (vap->iv_state == IEEE80211_S_RUN)
- taskqueue_enqueue(taskqueue_swi,
- &IPW_VAP(vap)->assoc_failed_task);
+ ieee80211_new_state(vap, IEEE80211_S_SCAN, -1);
break;
case IPW_STATE_DISABLED:
@@ -1432,6 +1380,16 @@ ipw_tx_intr(struct ipw_softc *sc)
}
static void
+ipw_fatal_error_intr(struct ipw_softc *sc)
+{
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
+
+ device_printf(sc->sc_dev, "firmware error\n");
+ ieee80211_runtask(ic, &sc->sc_init_task);
+}
+
+static void
ipw_intr(void *arg)
{
struct ipw_softc *sc = arg;
@@ -1440,10 +1398,9 @@ ipw_intr(void *arg)
IPW_LOCK(sc);
- if ((r = CSR_READ_4(sc, IPW_CSR_INTR)) == 0 || r == 0xffffffff) {
- IPW_UNLOCK(sc);
- return;
- }
+ r = CSR_READ_4(sc, IPW_CSR_INTR);
+ if (r == 0 || r == 0xffffffff)
+ goto done;
/* disable interrupts */
CSR_WRITE_4(sc, IPW_CSR_INTR_MASK, 0);
@@ -1452,9 +1409,8 @@ ipw_intr(void *arg)
CSR_WRITE_4(sc, IPW_CSR_INTR, r);
if (r & (IPW_INTR_FATAL_ERROR | IPW_INTR_PARITY_ERROR)) {
- device_printf(sc->sc_dev, "firmware error\n");
- taskqueue_enqueue(taskqueue_swi, &sc->sc_init_task);
- r = 0; /* don't process more interrupts */
+ ipw_fatal_error_intr(sc);
+ goto done;
}
if (r & IPW_INTR_FW_INIT_DONE)
@@ -1468,7 +1424,7 @@ ipw_intr(void *arg)
/* re-enable interrupts */
CSR_WRITE_4(sc, IPW_CSR_INTR_MASK, IPW_INTR_MASK);
-
+done:
IPW_UNLOCK(sc);
}
@@ -2181,20 +2137,6 @@ ipw_setscanopts(struct ipw_softc *sc, uint32_t chanmask, uint32_t flags)
return ipw_cmd(sc, IPW_CMD_SET_SCAN_OPTIONS, &opts, sizeof(opts));
}
-/*
- * Handler for sc_scan_task. This is a simple wrapper around ipw_scan().
- */
-static void
-ipw_scan_task(void *context, int pending)
-{
- struct ipw_softc *sc = context;
- IPW_LOCK_DECL;
-
- IPW_LOCK(sc);
- ipw_scan(sc);
- IPW_UNLOCK(sc);
-}
-
static int
ipw_scan(struct ipw_softc *sc)
{
@@ -2258,11 +2200,9 @@ ipw_setchannel(struct ipw_softc *sc, struct ieee80211_channel *chan)
}
static void
-ipw_assoc_task(void *context, int pending)
+ipw_assoc(struct ieee80211com *ic, struct ieee80211vap *vap)
{
- struct ieee80211vap *vap = context;
struct ifnet *ifp = vap->iv_ic->ic_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
struct ipw_softc *sc = ifp->if_softc;
struct ieee80211_node *ni = vap->iv_bss;
struct ipw_security security;
@@ -2353,9 +2293,8 @@ done:
}
static void
-ipw_disassoc_task(void *context, int pending)
+ipw_disassoc(struct ieee80211com *ic, struct ieee80211vap *vap)
{
- struct ieee80211vap *vap = context;
struct ifnet *ifp = vap->iv_ic->ic_ifp;
struct ieee80211_node *ni = vap->iv_bss;
struct ipw_softc *sc = ifp->if_softc;
@@ -2729,8 +2668,7 @@ ipw_scan_start(struct ieee80211com *ic)
IPW_LOCK_DECL;
IPW_LOCK(sc);
- if (!(sc->flags & IPW_FLAG_SCANNING))
- taskqueue_enqueue(taskqueue_swi, &sc->sc_scan_task);
+ ipw_scan(sc);
IPW_UNLOCK(sc);
}
diff --git a/sys/dev/ipw/if_ipwvar.h b/sys/dev/ipw/if_ipwvar.h
index de35019..24fb8e8 100644
--- a/sys/dev/ipw/if_ipwvar.h
+++ b/sys/dev/ipw/if_ipwvar.h
@@ -78,11 +78,6 @@ struct ipw_tx_radiotap_header {
struct ipw_vap {
struct ieee80211vap vap;
- struct task assoc_task;
- struct task disassoc_task;
- struct task assoc_success_task;
- struct task assoc_failed_task;
- struct task scandone_task;
int (*newstate)(struct ieee80211vap *,
enum ieee80211_state, int);
@@ -95,9 +90,6 @@ struct ipw_softc {
struct mtx sc_mtx;
struct task sc_init_task;
- struct task sc_scan_task;
- struct task sc_chan_task;
- struct task sc_bmiss_task;
struct callout sc_wdtimer; /* watchdog timer */
uint32_t flags;
diff --git a/sys/dev/iwi/if_iwi.c b/sys/dev/iwi/if_iwi.c
index 83ab3e5..6957f9b 100644
--- a/sys/dev/iwi/if_iwi.c
+++ b/sys/dev/iwi/if_iwi.c
@@ -158,9 +158,6 @@ static int iwi_wme_update(struct ieee80211com *);
static uint16_t iwi_read_prom_word(struct iwi_softc *, uint8_t);
static void iwi_frame_intr(struct iwi_softc *, struct iwi_rx_data *, int,
struct iwi_frame *);
-static void iwi_authsuccess(void *, int);
-static void iwi_assocsuccess(void *, int);
-static void iwi_assocfailed(void *, int);
static void iwi_notification_intr(struct iwi_softc *, struct iwi_notif *);
static void iwi_rx_intr(struct iwi_softc *);
static void iwi_tx_intr(struct iwi_softc *, struct iwi_tx_ring *);
@@ -186,16 +183,11 @@ static void iwi_put_firmware(struct iwi_softc *);
static int iwi_scanchan(struct iwi_softc *, unsigned long, int);
static void iwi_scan_start(struct ieee80211com *);
static void iwi_scan_end(struct ieee80211com *);
-static void iwi_scanabort(void *, int);
static void iwi_set_channel(struct ieee80211com *);
static void iwi_scan_curchan(struct ieee80211_scan_state *, unsigned long maxdwell);
-#if 0
-static void iwi_scan_allchan(struct ieee80211com *, unsigned long maxdwell);
-#endif
static void iwi_scan_mindwell(struct ieee80211_scan_state *);
-static void iwi_ops(void *, int);
-static int iwi_queue_cmd(struct iwi_softc *, int, unsigned long);
static int iwi_auth_and_assoc(struct iwi_softc *, struct ieee80211vap *);
+static void iwi_disassoc(void *, int);
static int iwi_disassociate(struct iwi_softc *, int quiet);
static void iwi_init_locked(struct iwi_softc *);
static void iwi_init(void *);
@@ -292,24 +284,14 @@ iwi_attach(device_t dev)
ic = ifp->if_l2com;
IWI_LOCK_INIT(sc);
- IWI_CMD_LOCK_INIT(sc);
sc->sc_unr = new_unrhdr(1, IWI_MAX_IBSSNODE-1, &sc->sc_mtx);
- sc->sc_tq = taskqueue_create("iwi_taskq", M_NOWAIT | M_ZERO,
- taskqueue_thread_enqueue, &sc->sc_tq);
- taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, "%s taskq",
- device_get_nameunit(dev));
- sc->sc_tq2 = taskqueue_create("iwi_taskq2", M_NOWAIT | M_ZERO,
- taskqueue_thread_enqueue, &sc->sc_tq2);
- taskqueue_start_threads(&sc->sc_tq2, 1, PI_NET, "%s taskq2",
- device_get_nameunit(dev));
-
TASK_INIT(&sc->sc_radiontask, 0, iwi_radio_on, sc);
TASK_INIT(&sc->sc_radiofftask, 0, iwi_radio_off, sc);
TASK_INIT(&sc->sc_restarttask, 0, iwi_restart, sc);
- TASK_INIT(&sc->sc_opstask, 0, iwi_ops, sc);
- TASK_INIT(&sc->sc_scanaborttask, 0, iwi_scanabort, sc);
+ TASK_INIT(&sc->sc_disassoctask, 0, iwi_disassoc, sc);
+
callout_init_mtx(&sc->sc_wdtimer, &sc->sc_mtx, 0);
callout_init_mtx(&sc->sc_rftimer, &sc->sc_mtx, 0);
@@ -483,8 +465,10 @@ iwi_detach(device_t dev)
ieee80211_ifdetach(ic);
/* NB: do early to drain any pending tasks */
- taskqueue_free(sc->sc_tq);
- taskqueue_free(sc->sc_tq2);
+ ieee80211_draintask(ic, &sc->sc_radiontask);
+ ieee80211_draintask(ic, &sc->sc_radiofftask);
+ ieee80211_draintask(ic, &sc->sc_restarttask);
+ ieee80211_draintask(ic, &sc->sc_disassoctask);
iwi_put_firmware(sc);
iwi_release_fw_dma(sc);
@@ -504,7 +488,6 @@ iwi_detach(device_t dev)
delete_unrhdr(sc->sc_unr);
IWI_LOCK_DESTROY(sc);
- IWI_CMD_LOCK_DESTROY(sc);
if_free(ifp);
@@ -552,10 +535,6 @@ iwi_vap_create(struct ieee80211com *ic,
ivp->iwi_newstate = vap->iv_newstate;
vap->iv_newstate = iwi_newstate;
- TASK_INIT(&ivp->iwi_authsuccess_task, 0, iwi_authsuccess, vap);
- TASK_INIT(&ivp->iwi_assocsuccess_task, 0, iwi_assocsuccess, vap);
- TASK_INIT(&ivp->iwi_assocfailed_task, 0, iwi_assocfailed, vap);
-
/* complete setup */
ieee80211_vap_attach(vap, ieee80211_media_change, iwi_media_status);
ic->ic_opmode = opmode;
@@ -987,21 +966,21 @@ iwi_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
ieee80211_state_name[vap->iv_state],
ieee80211_state_name[nstate], sc->flags));
+ IEEE80211_UNLOCK(ic);
+ IWI_LOCK(sc);
switch (nstate) {
case IEEE80211_S_INIT:
- IWI_LOCK(sc);
/*
* NB: don't try to do this if iwi_stop_master has
* shutdown the firmware and disabled interrupts.
*/
if (vap->iv_state == IEEE80211_S_RUN &&
(sc->flags & IWI_FLAG_FW_INITED))
- iwi_queue_cmd(sc, IWI_DISASSOC, 1);
- IWI_UNLOCK(sc);
+ iwi_disassociate(sc, 0);
break;
case IEEE80211_S_AUTH:
- iwi_queue_cmd(sc, IWI_AUTH, arg);
- return EINPROGRESS;
+ iwi_auth_and_assoc(sc, vap);
+ break;
case IEEE80211_S_RUN:
if (vap->iv_opmode == IEEE80211_M_IBSS &&
vap->iv_state == IEEE80211_S_SCAN) {
@@ -1013,8 +992,7 @@ iwi_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
* AUTH -> RUN transition and we want to do nothing.
* This is all totally bogus and needs to be redone.
*/
- iwi_queue_cmd(sc, IWI_ASSOC, 0);
- return EINPROGRESS;
+ iwi_auth_and_assoc(sc, vap);
}
break;
case IEEE80211_S_ASSOC:
@@ -1025,11 +1003,13 @@ iwi_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
*/
if (vap->iv_state == IEEE80211_S_AUTH)
break;
- iwi_queue_cmd(sc, IWI_ASSOC, arg);
- return EINPROGRESS;
+ iwi_auth_and_assoc(sc, vap);
+ break;
default:
break;
}
+ IWI_UNLOCK(sc);
+ IEEE80211_LOCK(ic);
return ivp->iwi_newstate(vap, nstate, arg);
}
@@ -1106,6 +1086,7 @@ static int
iwi_wme_update(struct ieee80211com *ic)
{
struct iwi_softc *sc = ic->ic_ifp->if_softc;
+ struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
/*
* We may be called to update the WME parameters in
@@ -1115,7 +1096,9 @@ iwi_wme_update(struct ieee80211com *ic)
* will get sent down to the adapter as part of the
* work iwi_auth_and_assoc does.
*/
- return iwi_queue_cmd(sc, IWI_SET_WME, 0);
+ if (vap->iv_state == IEEE80211_S_RUN)
+ (void) iwi_wme_setparams(sc, ic);
+ return (0);
}
static int
@@ -1389,30 +1372,6 @@ iwi_checkforqos(struct ieee80211vap *vap,
*/
static void
-iwi_authsuccess(void *arg, int npending)
-{
- struct ieee80211vap *vap = arg;
-
- ieee80211_new_state(vap, IEEE80211_S_ASSOC, -1);
-}
-
-static void
-iwi_assocsuccess(void *arg, int npending)
-{
- struct ieee80211vap *vap = arg;
-
- ieee80211_new_state(vap, IEEE80211_S_RUN, -1);
-}
-
-static void
-iwi_assocfailed(void *arg, int npending)
-{
- struct ieee80211vap *vap = arg;
-
- ieee80211_new_state(vap, IEEE80211_S_SCAN, -1);
-}
-
-static void
iwi_notification_intr(struct iwi_softc *sc, struct iwi_notif *notif)
{
struct ifnet *ifp = sc->sc_ifp;
@@ -1454,8 +1413,7 @@ iwi_notification_intr(struct iwi_softc *sc, struct iwi_notif *notif)
switch (auth->state) {
case IWI_AUTH_SUCCESS:
DPRINTFN(2, ("Authentication succeeeded\n"));
- taskqueue_enqueue(taskqueue_swi,
- &IWI_VAP(vap)->iwi_authsuccess_task);
+ ieee80211_new_state(vap, IEEE80211_S_ASSOC, -1);
break;
case IWI_AUTH_FAIL:
/*
@@ -1472,8 +1430,7 @@ iwi_notification_intr(struct iwi_softc *sc, struct iwi_notif *notif)
DPRINTFN(2, ("Deauthenticated\n"));
vap->iv_stats.is_rx_deauth++;
}
- taskqueue_enqueue(taskqueue_swi,
- &IWI_VAP(vap)->iwi_assocfailed_task);
+ ieee80211_new_state(vap, IEEE80211_S_SCAN, -1);
break;
case IWI_AUTH_SENT_1:
case IWI_AUTH_RECV_2:
@@ -1506,8 +1463,7 @@ iwi_notification_intr(struct iwi_softc *sc, struct iwi_notif *notif)
iwi_checkforqos(vap,
(const struct ieee80211_frame *)(assoc+1),
le16toh(notif->len) - sizeof(*assoc));
- taskqueue_enqueue(taskqueue_swi,
- &IWI_VAP(vap)->iwi_assocsuccess_task);
+ ieee80211_new_state(vap, IEEE80211_S_RUN, -1);
break;
case IWI_ASSOC_INIT:
sc->flags &= ~IWI_FLAG_ASSOCIATED;
@@ -1515,16 +1471,14 @@ iwi_notification_intr(struct iwi_softc *sc, struct iwi_notif *notif)
case IWI_FW_ASSOCIATING:
DPRINTFN(2, ("Association failed\n"));
IWI_STATE_END(sc, IWI_FW_ASSOCIATING);
- taskqueue_enqueue(taskqueue_swi,
- &IWI_VAP(vap)->iwi_assocfailed_task);
+ ieee80211_new_state(vap, IEEE80211_S_SCAN, -1);
break;
case IWI_FW_DISASSOCIATING:
DPRINTFN(2, ("Dissassociated\n"));
IWI_STATE_END(sc, IWI_FW_DISASSOCIATING);
vap->iv_stats.is_rx_disassoc++;
- taskqueue_enqueue(taskqueue_swi,
- &IWI_VAP(vap)->iwi_assocfailed_task);
+ ieee80211_new_state(vap, IEEE80211_S_SCAN, -1);
break;
}
break;
@@ -1563,7 +1517,7 @@ iwi_notification_intr(struct iwi_softc *sc, struct iwi_notif *notif)
* to disassociate and then on completion we'll
* kick the state machine to scan.
*/
- iwi_queue_cmd(sc, IWI_DISASSOC, 1);
+ ieee80211_runtask(ic, &sc->sc_disassoctask);
}
}
break;
@@ -1664,6 +1618,29 @@ iwi_tx_intr(struct iwi_softc *sc, struct iwi_tx_ring *txq)
}
static void
+iwi_fatal_error_intr(struct iwi_softc *sc)
+{
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
+
+ device_printf(sc->sc_dev, "firmware error\n");
+ ieee80211_runtask(ic, &sc->sc_restarttask);
+
+ sc->flags &= ~IWI_FLAG_BUSY;
+ sc->sc_busy_timer = 0;
+ wakeup(sc);
+}
+
+static void
+iwi_radio_off_intr(struct iwi_softc *sc)
+{
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
+
+ ieee80211_runtask(ic, &sc->sc_radiofftask);
+}
+
+static void
iwi_intr(void *arg)
{
struct iwi_softc *sc = arg;
@@ -1681,12 +1658,8 @@ iwi_intr(void *arg)
CSR_WRITE_4(sc, IWI_CSR_INTR, r);
if (r & IWI_INTR_FATAL_ERROR) {
- device_printf(sc->sc_dev, "firmware error\n");
- taskqueue_enqueue(sc->sc_tq2, &sc->sc_restarttask);
-
- sc->flags &= ~IWI_FLAG_BUSY;
- sc->sc_busy_timer = 0;
- wakeup(sc);
+ iwi_fatal_error_intr(sc);
+ goto done;
}
if (r & IWI_INTR_FW_INITED) {
@@ -1695,7 +1668,7 @@ iwi_intr(void *arg)
}
if (r & IWI_INTR_RADIO_OFF)
- taskqueue_enqueue(sc->sc_tq, &sc->sc_radiofftask);
+ iwi_radio_off_intr(sc);
if (r & IWI_INTR_CMD_DONE) {
sc->flags &= ~IWI_FLAG_BUSY;
@@ -1722,7 +1695,7 @@ iwi_intr(void *arg)
/* XXX rate-limit */
device_printf(sc->sc_dev, "parity error\n");
}
-
+done:
IWI_UNLOCK(sc);
}
@@ -2008,6 +1981,7 @@ iwi_watchdog(void *arg)
{
struct iwi_softc *sc = arg;
struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
IWI_LOCK_ASSERT(sc);
@@ -2015,25 +1989,25 @@ iwi_watchdog(void *arg)
if (--sc->sc_tx_timer == 0) {
if_printf(ifp, "device timeout\n");
ifp->if_oerrors++;
- taskqueue_enqueue(sc->sc_tq2, &sc->sc_restarttask);
+ ieee80211_runtask(ic, &sc->sc_restarttask);
}
}
if (sc->sc_state_timer > 0) {
if (--sc->sc_state_timer == 0) {
if_printf(ifp, "firmware stuck in state %d, resetting\n",
sc->fw_state);
- taskqueue_enqueue(sc->sc_tq2, &sc->sc_restarttask);
if (sc->fw_state == IWI_FW_SCANNING) {
struct ieee80211com *ic = ifp->if_l2com;
ieee80211_cancel_scan(TAILQ_FIRST(&ic->ic_vaps));
}
+ ieee80211_runtask(ic, &sc->sc_restarttask);
sc->sc_state_timer = 3;
}
}
if (sc->sc_busy_timer > 0) {
if (--sc->sc_busy_timer == 0) {
if_printf(ifp, "firmware command timeout, resetting\n");
- taskqueue_enqueue(sc->sc_tq2, &sc->sc_restarttask);
+ ieee80211_runtask(ic, &sc->sc_restarttask);
}
}
callout_reset(&sc->sc_wdtimer, hz, iwi_watchdog, sc);
@@ -2665,7 +2639,7 @@ scan_band(const struct ieee80211_channel *c)
* Start a scan on the current channel or all channels.
*/
static int
-iwi_scanchan(struct iwi_softc *sc, unsigned long maxdwell, int mode)
+iwi_scanchan(struct iwi_softc *sc, unsigned long maxdwell, int allchan)
{
struct ieee80211com *ic;
struct ieee80211_channel *chan;
@@ -2712,7 +2686,7 @@ iwi_scanchan(struct iwi_softc *sc, unsigned long maxdwell, int mode)
return (error);
}
- if (mode == IWI_SCAN_ALLCHAN) {
+ if (allchan) {
int i, next, band, b, bstart;
/*
* Convert scan list to run-length encoded channel list
@@ -2781,20 +2755,6 @@ iwi_scanchan(struct iwi_softc *sc, unsigned long maxdwell, int mode)
return (iwi_cmd(sc, IWI_CMD_SCAN_EXT, &scan, sizeof scan));
}
-static void
-iwi_scanabort(void *arg, int npending)
-{
- struct iwi_softc *sc = arg;
- IWI_LOCK_DECL;
-
- IWI_LOCK(sc);
- sc->flags &= ~IWI_FLAG_CHANNEL_SCAN;
- /* NB: make sure we're still scanning */
- if (sc->fw_state == IWI_FW_SCANNING)
- iwi_cmd(sc, IWI_CMD_ABORT_SCAN, NULL, 0);
- IWI_UNLOCK(sc);
-}
-
static int
iwi_set_sensitivity(struct iwi_softc *sc, int8_t rssi_dbm)
{
@@ -2986,6 +2946,17 @@ done:
return (error);
}
+static void
+iwi_disassoc(void *arg, int pending)
+{
+ struct iwi_softc *sc = arg;
+ IWI_LOCK_DECL;
+
+ IWI_LOCK(sc);
+ iwi_disassociate(sc, 0);
+ IWI_UNLOCK(sc);
+}
+
static int
iwi_disassociate(struct iwi_softc *sc, int quiet)
{
@@ -3086,9 +3057,6 @@ iwi_init_locked(struct iwi_softc *sc)
IWI_STATE_BEGIN(sc, IWI_FW_LOADING);
- taskqueue_unblock(sc->sc_tq);
- taskqueue_unblock(sc->sc_tq2);
-
if (iwi_reset(sc) != 0) {
device_printf(sc->sc_dev, "could not reset adapter\n");
goto fail;
@@ -3183,8 +3151,6 @@ iwi_stop_locked(void *priv)
ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
- taskqueue_block(sc->sc_tq);
- taskqueue_block(sc->sc_tq2);
if (sc->sc_softled) {
callout_stop(&sc->sc_ledtimer);
sc->sc_blinking = 0;
@@ -3204,7 +3170,6 @@ iwi_stop_locked(void *priv)
iwi_reset_tx_ring(sc, &sc->txq[3]);
iwi_reset_rx_ring(sc, &sc->rxq);
- memset(sc->sc_cmd, 0, sizeof(sc->sc_cmd));
sc->sc_tx_timer = 0;
sc->sc_state_timer = 0;
sc->sc_busy_timer = 0;
@@ -3266,8 +3231,10 @@ iwi_rfkill_poll(void *arg)
* it is enabled so we must poll for the latter.
*/
if (!iwi_getrfkill(sc)) {
- taskqueue_unblock(sc->sc_tq);
- taskqueue_enqueue(sc->sc_tq, &sc->sc_radiontask);
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
+
+ ieee80211_runtask(ic, &sc->sc_radiontask);
return;
}
callout_reset(&sc->sc_rftimer, 2*hz, iwi_rfkill_poll, sc);
@@ -3533,114 +3500,9 @@ iwi_ledattach(struct iwi_softc *sc)
}
static void
-iwi_ops(void *arg0, int npending)
-{
- static const char *opnames[] = {
- [IWI_CMD_FREE] = "FREE",
- [IWI_SCAN_START] = "SCAN_START",
- [IWI_SET_CHANNEL] = "SET_CHANNEL",
- [IWI_AUTH] = "AUTH",
- [IWI_ASSOC] = "ASSOC",
- [IWI_DISASSOC] = "DISASSOC",
- [IWI_SCAN_CURCHAN] = "SCAN_CURCHAN",
- [IWI_SCAN_ALLCHAN] = "SCAN_ALLCHAN",
- [IWI_SET_WME] = "SET_WME",
- };
- struct iwi_softc *sc = arg0;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
- IWI_LOCK_DECL;
- int cmd;
- unsigned long arg;
-
-again:
- IWI_CMD_LOCK(sc);
- cmd = sc->sc_cmd[sc->sc_cmd_cur];
- if (cmd == IWI_CMD_FREE) {
- /* No more commands to process */
- IWI_CMD_UNLOCK(sc);
- return;
- }
- arg = sc->sc_arg[sc->sc_cmd_cur];
- sc->sc_cmd[sc->sc_cmd_cur] = IWI_CMD_FREE; /* free the slot */
- sc->sc_cmd_cur = (sc->sc_cmd_cur + 1) % IWI_CMD_MAXOPS;
- IWI_CMD_UNLOCK(sc);
-
- IWI_LOCK(sc);
- while (sc->fw_state != IWI_FW_IDLE || (sc->flags & IWI_FLAG_BUSY)) {
- msleep(sc, &sc->sc_mtx, 0, "iwicmd", hz/10);
- }
-
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
- IWI_UNLOCK(sc);
- return;
- }
-
- DPRINTF(("%s: %s arg %lu\n", __func__, opnames[cmd], arg));
- switch (cmd) {
- case IWI_AUTH:
- case IWI_ASSOC:
- if (cmd == IWI_AUTH)
- vap->iv_state = IEEE80211_S_AUTH;
- else
- vap->iv_state = IEEE80211_S_ASSOC;
- iwi_auth_and_assoc(sc, vap);
- /* NB: completion done in iwi_notification_intr */
- break;
- case IWI_DISASSOC:
- iwi_disassociate(sc, 0);
- break;
- case IWI_SET_WME:
- if (vap->iv_state == IEEE80211_S_RUN)
- (void) iwi_wme_setparams(sc, ic);
- break;
- case IWI_SCAN_START:
- sc->flags |= IWI_FLAG_CHANNEL_SCAN;
- break;
- case IWI_SCAN_CURCHAN:
- case IWI_SCAN_ALLCHAN:
- if (!(sc->flags & IWI_FLAG_CHANNEL_SCAN)) {
- DPRINTF(("%s: ic_scan_curchan while not scanning\n",
- __func__));
- goto done;
- }
- if (iwi_scanchan(sc, arg, cmd))
- ieee80211_cancel_scan(vap);
- break;
- }
-done:
- IWI_UNLOCK(sc);
-
- /* Take another pass */
- goto again;
-}
-
-static int
-iwi_queue_cmd(struct iwi_softc *sc, int cmd, unsigned long arg)
-{
- IWI_CMD_LOCK(sc);
- if (sc->sc_cmd[sc->sc_cmd_next] != 0) {
- IWI_CMD_UNLOCK(sc);
- DPRINTF(("%s: command %d dropped\n", __func__, cmd));
- return (EBUSY);
- }
-
- sc->sc_cmd[sc->sc_cmd_next] = cmd;
- sc->sc_arg[sc->sc_cmd_next] = arg;
- sc->sc_cmd_next = (sc->sc_cmd_next + 1) % IWI_CMD_MAXOPS;
- taskqueue_enqueue(sc->sc_tq, &sc->sc_opstask);
- IWI_CMD_UNLOCK(sc);
- return (0);
-}
-
-static void
iwi_scan_start(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct iwi_softc *sc = ifp->if_softc;
-
- iwi_queue_cmd(sc, IWI_SCAN_START, 0);
+ /* ignore */
}
static void
@@ -3658,20 +3520,13 @@ iwi_scan_curchan(struct ieee80211_scan_state *ss, unsigned long maxdwell)
struct ieee80211vap *vap = ss->ss_vap;
struct ifnet *ifp = vap->iv_ic->ic_ifp;
struct iwi_softc *sc = ifp->if_softc;
+ IWI_LOCK_DECL;
- iwi_queue_cmd(sc, IWI_SCAN_CURCHAN, maxdwell);
-}
-
-#if 0
-static void
-iwi_scan_allchan(struct ieee80211com *ic, unsigned long maxdwell)
-{
- struct ifnet *ifp = ic->ic_ifp;
- struct iwi_softc *sc = ifp->if_softc;
-
- iwi_queue_cmd(sc, IWI_SCAN_ALLCHAN, maxdwell);
+ IWI_LOCK(sc);
+ if (iwi_scanchan(sc, maxdwell, 0))
+ ieee80211_cancel_scan(vap);
+ IWI_UNLOCK(sc);
}
-#endif
static void
iwi_scan_mindwell(struct ieee80211_scan_state *ss)
@@ -3684,6 +3539,12 @@ iwi_scan_end(struct ieee80211com *ic)
{
struct ifnet *ifp = ic->ic_ifp;
struct iwi_softc *sc = ifp->if_softc;
+ IWI_LOCK_DECL;
- taskqueue_enqueue(sc->sc_tq2, &sc->sc_scanaborttask);
+ IWI_LOCK(sc);
+ sc->flags &= ~IWI_FLAG_CHANNEL_SCAN;
+ /* NB: make sure we're still scanning */
+ if (sc->fw_state == IWI_FW_SCANNING)
+ iwi_cmd(sc, IWI_CMD_ABORT_SCAN, NULL, 0);
+ IWI_UNLOCK(sc);
}
diff --git a/sys/dev/iwi/if_iwivar.h b/sys/dev/iwi/if_iwivar.h
index abc6f9c..25db9cf 100644
--- a/sys/dev/iwi/if_iwivar.h
+++ b/sys/dev/iwi/if_iwivar.h
@@ -116,9 +116,6 @@ struct iwi_fw {
struct iwi_vap {
struct ieee80211vap iwi_vap;
- struct task iwi_authsuccess_task;
- struct task iwi_assocsuccess_task;
- struct task iwi_assocfailed_task;
int (*iwi_newstate)(struct ieee80211vap *,
enum ieee80211_state, int);
@@ -131,12 +128,8 @@ struct iwi_softc {
device_t sc_dev;
struct mtx sc_mtx;
- struct mtx sc_cmdlock;
- char sc_cmdname[12]; /* e.g. "iwi0_cmd" */
uint8_t sc_mcast[IEEE80211_ADDR_LEN];
struct unrhdr *sc_unr;
- struct taskqueue *sc_tq; /* private task queue */
- struct taskqueue *sc_tq2; /* reset task queue */
uint32_t flags;
#define IWI_FLAG_FW_INITED (1 << 0)
@@ -195,9 +188,8 @@ struct iwi_softc {
struct task sc_radiontask; /* radio on processing */
struct task sc_radiofftask; /* radio off processing */
- struct task sc_scanaborttask; /* cancel active scan */
struct task sc_restarttask; /* restart adapter processing */
- struct task sc_opstask; /* scan / auth processing */
+ struct task sc_disassoctask;
unsigned int sc_softled : 1, /* enable LED gpio status */
sc_ledstate: 1, /* LED on/off state */
@@ -219,21 +211,6 @@ struct iwi_softc {
int sc_state_timer; /* firmware state timer */
int sc_busy_timer; /* firmware cmd timer */
-#define IWI_CMD_MAXOPS 10
- int sc_cmd[IWI_CMD_MAXOPS];
- unsigned long sc_arg[IWI_CMD_MAXOPS];
- int sc_cmd_cur; /* current queued scan task */
- int sc_cmd_next; /* last queued scan task */
-#define IWI_CMD_FREE 0 /* for marking slots unused */
-#define IWI_SCAN_START 1
-#define IWI_SET_CHANNEL 2
-#define IWI_AUTH 3
-#define IWI_ASSOC 4
-#define IWI_DISASSOC 5
-#define IWI_SCAN_CURCHAN 6
-#define IWI_SCAN_ALLCHAN 7
-#define IWI_SET_WME 8
-
struct iwi_rx_radiotap_header sc_rxtap;
int sc_rxtap_len;
@@ -277,11 +254,3 @@ struct iwi_softc {
if (!__waslocked) \
mtx_unlock(&(sc)->sc_mtx); \
} while (0)
-#define IWI_CMD_LOCK_INIT(sc) do { \
- snprintf((sc)->sc_cmdname, sizeof((sc)->sc_cmdname), "%s_cmd", \
- device_get_nameunit((sc)->sc_dev)); \
- mtx_init(&(sc)->sc_cmdlock, (sc)->sc_cmdname, NULL, MTX_DEF); \
-} while (0)
-#define IWI_CMD_LOCK_DESTROY(sc) mtx_destroy(&(sc)->sc_cmdlock)
-#define IWI_CMD_LOCK(sc) mtx_lock(&(sc)->sc_cmdlock)
-#define IWI_CMD_UNLOCK(sc) mtx_unlock(&(sc)->sc_cmdlock)
diff --git a/sys/dev/iwn/if_iwn.c b/sys/dev/iwn/if_iwn.c
index 2928c0f..f32bdaa 100644
--- a/sys/dev/iwn/if_iwn.c
+++ b/sys/dev/iwn/if_iwn.c
@@ -129,7 +129,6 @@ void iwn_rx_intr(struct iwn_softc *, struct iwn_rx_desc *,
void iwn_rx_statistics(struct iwn_softc *, struct iwn_rx_desc *);
void iwn_tx_intr(struct iwn_softc *, struct iwn_rx_desc *);
void iwn_cmd_intr(struct iwn_softc *, struct iwn_rx_desc *);
-static void iwn_bmiss(void *, int);
void iwn_notif_intr(struct iwn_softc *);
void iwn_intr(void *);
void iwn_read_eeprom(struct iwn_softc *,
@@ -166,8 +165,8 @@ void iwn_compute_differential_gain(struct iwn_softc *,
void iwn_tune_sensitivity(struct iwn_softc *,
const struct iwn_rx_stats *);
int iwn_send_sensitivity(struct iwn_softc *);
-int iwn_auth(struct iwn_softc *);
-int iwn_run(struct iwn_softc *);
+int iwn_auth(struct iwn_softc *, struct ieee80211vap *);
+int iwn_run(struct iwn_softc *, struct ieee80211vap *);
int iwn_scan(struct iwn_softc *);
int iwn_config(struct iwn_softc *);
void iwn_post_alive(struct iwn_softc *);
@@ -183,8 +182,9 @@ static void iwn_scan_end(struct ieee80211com *);
static void iwn_set_channel(struct ieee80211com *);
static void iwn_scan_curchan(struct ieee80211_scan_state *, unsigned long);
static void iwn_scan_mindwell(struct ieee80211_scan_state *);
-static void iwn_ops(void *, int);
-static int iwn_queue_cmd( struct iwn_softc *, int, int, int);
+static void iwn_hwreset(void *, int);
+static void iwn_radioon(void *, int);
+static void iwn_radiooff(void *, int);
static void iwn_bpfattach(struct iwn_softc *);
static void iwn_sysctlattach(struct iwn_softc *);
@@ -213,7 +213,6 @@ enum {
printf(fmt, __VA_ARGS__); \
} while (0)
-static const char *iwn_ops_str(int);
static const char *iwn_intr_str(uint8_t);
#else
#define DPRINTF(sc, m, fmt, ...) do { (void) sc; } while (0)
@@ -296,20 +295,10 @@ iwn_attach(device_t dev)
}
IWN_LOCK_INIT(sc);
- IWN_CMD_LOCK_INIT(sc);
callout_init_mtx(&sc->sc_timer_to, &sc->sc_mtx, 0);
-
- /*
- * Create the taskqueues used by the driver. Primarily
- * sc_tq handles most the task
- */
- sc->sc_tq = taskqueue_create("iwn_taskq", M_NOWAIT | M_ZERO,
- taskqueue_thread_enqueue, &sc->sc_tq);
- taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, "%s taskq",
- device_get_nameunit(dev));
-
- TASK_INIT(&sc->sc_ops_task, 0, iwn_ops, sc );
- TASK_INIT(&sc->sc_bmiss_task, 0, iwn_bmiss, sc);
+ TASK_INIT(&sc->sc_reinit_task, 0, iwn_hwreset, sc );
+ TASK_INIT(&sc->sc_radioon_task, 0, iwn_radioon, sc );
+ TASK_INIT(&sc->sc_radiooff_task, 0, iwn_radiooff, sc );
/*
* Put adapter into a known state.
@@ -475,6 +464,10 @@ iwn_cleanup(device_t dev)
struct ieee80211com *ic = ifp->if_l2com;
int i;
+ ieee80211_draintask(ic, &sc->sc_reinit_task);
+ ieee80211_draintask(ic, &sc->sc_radioon_task);
+ ieee80211_draintask(ic, &sc->sc_radiooff_task);
+
if (ifp != NULL) {
iwn_stop(sc);
callout_drain(&sc->sc_timer_to);
@@ -499,8 +492,6 @@ iwn_cleanup(device_t dev)
bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem);
if (ifp != NULL)
if_free(ifp);
- taskqueue_free(sc->sc_tq);
- IWN_CMD_LOCK_DESTROY(sc);
IWN_LOCK_DESTROY(sc);
return 0;
}
@@ -983,20 +974,13 @@ iwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
ieee80211_state_name[vap->iv_state],
ieee80211_state_name[nstate]);
+ IEEE80211_UNLOCK(ic);
IWN_LOCK(sc);
callout_stop(&sc->sc_timer_to);
- IWN_UNLOCK(sc);
- /*
- * Some state transitions require issuing a configure request
- * to the adapter. This must be done in a blocking context
- * so we toss control to the task q thread where the state
- * change will be finished after the command completes.
- */
if (nstate == IEEE80211_S_AUTH && vap->iv_state != IEEE80211_S_AUTH) {
/* !AUTH -> AUTH requires adapter config */
- error = iwn_queue_cmd(sc, IWN_AUTH, arg, IWN_QUEUE_NORMAL);
- return (error != 0 ? error : EINPROGRESS);
+ error = iwn_auth(sc, vap);
}
if (nstate == IEEE80211_S_RUN && vap->iv_state != IEEE80211_S_RUN) {
/*
@@ -1004,8 +988,7 @@ iwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
* which is done with a firmware cmd. We also defer
* starting the timers until that work is done.
*/
- error = iwn_queue_cmd(sc, IWN_RUN, arg, IWN_QUEUE_NORMAL);
- return (error != 0 ? error : EINPROGRESS);
+ error = iwn_run(sc, vap);
}
if (nstate == IEEE80211_S_RUN) {
/*
@@ -1013,6 +996,8 @@ iwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
*/
iwn_calib_reset(sc);
}
+ IWN_UNLOCK(sc);
+ IEEE80211_LOCK(ic);
return ivp->iv_newstate(vap, nstate, arg);
}
@@ -1657,15 +1642,6 @@ iwn_cmd_intr(struct iwn_softc *sc, struct iwn_rx_desc *desc)
wakeup(&ring->cmd[desc->idx]);
}
-static void
-iwn_bmiss(void *arg, int npending)
-{
- struct iwn_softc *sc = arg;
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
-
- ieee80211_beacon_miss(ic);
-}
-
void
iwn_notif_intr(struct iwn_softc *sc)
{
@@ -1726,8 +1702,7 @@ iwn_notif_intr(struct iwn_softc *sc)
if (vap->iv_state == IEEE80211_S_RUN && misses > 5)
(void) iwn_init_sensitivity(sc);
if (misses >= vap->iv_bmissthreshold)
- taskqueue_enqueue(taskqueue_swi,
- &sc->sc_bmiss_task);
+ ieee80211_beacon_miss(ic);
break;
}
case IWN_UC_READY: {
@@ -1780,7 +1755,7 @@ iwn_notif_intr(struct iwn_softc *sc)
"scan finished nchan=%d status=%d chan=%d\n",
scan->nchan, scan->status, scan->chan);
- iwn_queue_cmd(sc, IWN_SCAN_NEXT, 0, IWN_QUEUE_NORMAL);
+ ieee80211_scan_next(vap);
break;
}
}
@@ -1792,6 +1767,36 @@ iwn_notif_intr(struct iwn_softc *sc)
IWN_WRITE(sc, IWN_RX_WIDX, hw & ~7);
}
+static void
+iwn_rftoggle_intr(struct iwn_softc *sc)
+{
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
+ uint32_t tmp = IWN_READ(sc, IWN_GPIO_CTL);
+
+ IWN_LOCK_ASSERT(sc);
+
+ device_printf(sc->sc_dev, "RF switch: radio %s\n",
+ (tmp & IWN_GPIO_RF_ENABLED) ? "enabled" : "disabled");
+ if (tmp & IWN_GPIO_RF_ENABLED)
+ ieee80211_runtask(ic, &sc->sc_radioon_task);
+ else
+ ieee80211_runtask(ic, &sc->sc_radiooff_task);
+}
+
+static void
+iwn_error_intr(struct iwn_softc *sc, uint32_t r1, uint32_t r2)
+{
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
+
+ IWN_LOCK_ASSERT(sc);
+
+ device_printf(sc->sc_dev, "error, INTR=%b STATUS=0x%x\n",
+ r1, IWN_INTR_BITS, r2);
+ ieee80211_runtask(ic, &sc->sc_reinit_task);
+}
+
void
iwn_intr(void *arg)
{
@@ -1820,21 +1825,12 @@ iwn_intr(void *arg)
DPRINTF(sc, IWN_DEBUG_INTR, "interrupt reg1=%x reg2=%x\n", r1, r2);
- if (r1 & IWN_RF_TOGGLED) {
- uint32_t tmp = IWN_READ(sc, IWN_GPIO_CTL);
- device_printf(sc->sc_dev, "RF switch: radio %s\n",
- (tmp & IWN_GPIO_RF_ENABLED) ? "enabled" : "disabled");
- if (tmp & IWN_GPIO_RF_ENABLED)
- iwn_queue_cmd(sc, IWN_RADIO_ENABLE, 0, IWN_QUEUE_CLEAR);
- else
- iwn_queue_cmd(sc, IWN_RADIO_DISABLE, 0, IWN_QUEUE_CLEAR);
- }
+ if (r1 & IWN_RF_TOGGLED)
+ iwn_rftoggle_intr(sc);
if (r1 & IWN_CT_REACHED)
device_printf(sc->sc_dev, "critical temperature reached!\n");
if (r1 & (IWN_SW_ERROR | IWN_HW_ERROR)) {
- device_printf(sc->sc_dev, "error, INTR=%b STATUS=0x%x\n",
- r1, IWN_INTR_BITS, r2);
- iwn_queue_cmd(sc, IWN_REINIT, 0, IWN_QUEUE_CLEAR);
+ iwn_error_intr(sc, r1, r2);
goto done;
}
if ((r1 & (IWN_RX_INTR | IWN_SW_RX_INTR)) || (r2 & IWN_RX_STATUS_INTR))
@@ -2361,9 +2357,10 @@ iwn_watchdog(struct iwn_softc *sc)
{
if (sc->sc_tx_timer > 0 && --sc->sc_tx_timer == 0) {
struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
if_printf(ifp, "device timeout\n");
- iwn_queue_cmd(sc, IWN_REINIT, 0, IWN_QUEUE_CLEAR);
+ ieee80211_runtask(ic, &sc->sc_reinit_task);
}
}
@@ -3446,11 +3443,10 @@ iwn_send_sensitivity(struct iwn_softc *sc)
}
int
-iwn_auth(struct iwn_softc *sc)
+iwn_auth(struct iwn_softc *sc, struct ieee80211vap *vap)
{
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); /*XXX*/
struct ieee80211_node *ni = vap->iv_bss;
struct iwn_node_info node;
int error;
@@ -3539,12 +3535,11 @@ iwn_auth(struct iwn_softc *sc)
* Configure the adapter for associated state.
*/
int
-iwn_run(struct iwn_softc *sc)
+iwn_run(struct iwn_softc *sc, struct ieee80211vap *vap)
{
#define MS(v,x) (((v) & x) >> x##_S)
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); /*XXX*/
struct ieee80211_node *ni = vap->iv_bss;
struct iwn_node_info node;
int error, maxrxampdu, ampdudensity;
@@ -4270,9 +4265,6 @@ iwn_stop_locked(struct iwn_softc *sc)
IWN_WRITE(sc, IWN_INTR, 0xffffffff);
IWN_WRITE(sc, IWN_INTR_STATUS, 0xffffffff);
- /* Clear any commands left in the taskq command buffer */
- memset(sc->sc_cmd, 0, sizeof(sc->sc_cmd));
-
/* reset all Tx rings */
for (i = 0; i < IWN_NTXQUEUES; i++)
iwn_reset_tx_ring(sc, &sc->txq[i]);
@@ -4308,7 +4300,10 @@ iwn_scan_start(struct ieee80211com *ic)
struct ifnet *ifp = ic->ic_ifp;
struct iwn_softc *sc = ifp->if_softc;
- iwn_queue_cmd(sc, IWN_SCAN_START, 0, IWN_QUEUE_NORMAL);
+ IWN_LOCK(sc);
+ /* make the link LED blink while we're scanning */
+ iwn_set_led(sc, IWN_LED_LINK, 20, 2);
+ IWN_UNLOCK(sc);
}
/*
@@ -4317,10 +4312,7 @@ iwn_scan_start(struct ieee80211com *ic)
static void
iwn_scan_end(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct iwn_softc *sc = ifp->if_softc;
-
- iwn_queue_cmd(sc, IWN_SCAN_STOP, 0, IWN_QUEUE_NORMAL);
+ /* ignore */
}
/*
@@ -4331,15 +4323,29 @@ iwn_set_channel(struct ieee80211com *ic)
{
struct ifnet *ifp = ic->ic_ifp;
struct iwn_softc *sc = ifp->if_softc;
+ struct ieee80211vap *vap;
const struct ieee80211_channel *c = ic->ic_curchan;
+ int error;
+
+ vap = TAILQ_FIRST(&ic->ic_vaps); /* XXX */
+ IWN_LOCK(sc);
if (c != sc->sc_curchan) {
sc->sc_rxtap.wr_chan_freq = htole16(c->ic_freq);
sc->sc_rxtap.wr_chan_flags = htole16(c->ic_flags);
sc->sc_txtap.wt_chan_freq = htole16(c->ic_freq);
sc->sc_txtap.wt_chan_flags = htole16(c->ic_flags);
- iwn_queue_cmd(sc, IWN_SET_CHAN, 0, IWN_QUEUE_NORMAL);
+
+ error = iwn_config(sc);
+ if (error != 0) {
+ DPRINTF(sc, IWN_DEBUG_STATE,
+ "%s: set chan failed, cancel scan\n",
+ __func__);
+ //XXX Handle failed scan correctly
+ ieee80211_cancel_scan(vap);
+ }
}
+ IWN_UNLOCK(sc);
}
/*
@@ -4350,8 +4356,13 @@ iwn_scan_curchan(struct ieee80211_scan_state *ss, unsigned long maxdwell)
{
struct ieee80211vap *vap = ss->ss_vap;
struct iwn_softc *sc = vap->iv_ic->ic_ifp->if_softc;
+ int error;
- iwn_queue_cmd(sc, IWN_SCAN_CURCHAN, 0, IWN_QUEUE_NORMAL);
+ IWN_LOCK(sc);
+ error = iwn_scan(sc);
+ IWN_UNLOCK(sc);
+ if (error != 0)
+ ieee80211_cancel_scan(vap);
}
/*
@@ -4365,149 +4376,36 @@ iwn_scan_mindwell(struct ieee80211_scan_state *ss)
/* NB: don't try to abort scan; wait for firmware to finish */
}
-/*
- * Carry out work in the taskq context.
- */
static void
-iwn_ops(void *arg0, int pending)
+iwn_hwreset(void *arg0, int pending)
{
struct iwn_softc *sc = arg0;
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211vap *vap;
- int cmd, arg, error;
- enum ieee80211_state nstate;
- for (;;) {
- IWN_CMD_LOCK(sc);
- cmd = sc->sc_cmd[sc->sc_cmd_cur];
- if (cmd == 0) {
- /* No more commands to process */
- IWN_CMD_UNLOCK(sc);
- return;
- }
- if ((sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 &&
- cmd != IWN_RADIO_ENABLE ) {
- IWN_CMD_UNLOCK(sc);
- return;
- }
- arg = sc->sc_cmd_arg[sc->sc_cmd_cur];
- sc->sc_cmd[sc->sc_cmd_cur] = 0; /* free the slot */
- sc->sc_cmd_cur = (sc->sc_cmd_cur + 1) % IWN_CMD_MAXOPS;
- IWN_CMD_UNLOCK(sc);
-
- IWN_LOCK(sc); /* NB: sync debug printfs on smp */
- DPRINTF(sc, IWN_DEBUG_OPS, "%s: %s (cmd 0x%x)\n",
- __func__, iwn_ops_str(cmd), cmd);
-
- vap = TAILQ_FIRST(&ic->ic_vaps); /* XXX */
- switch (cmd) {
- case IWN_SCAN_START:
- /* make the link LED blink while we're scanning */
- iwn_set_led(sc, IWN_LED_LINK, 20, 2);
- break;
- case IWN_SCAN_STOP:
- break;
- case IWN_SCAN_NEXT:
- ieee80211_scan_next(vap);
- break;
- case IWN_SCAN_CURCHAN:
- error = iwn_scan(sc);
- if (error != 0) {
- IWN_UNLOCK(sc);
- ieee80211_cancel_scan(vap);
- IWN_LOCK(sc);
- return;
- }
- break;
- case IWN_SET_CHAN:
- error = iwn_config(sc);
- if (error != 0) {
- DPRINTF(sc, IWN_DEBUG_STATE,
- "%s: set chan failed, cancel scan\n",
- __func__);
- IWN_UNLOCK(sc);
- //XXX Handle failed scan correctly
- ieee80211_cancel_scan(vap);
- return;
- }
- break;
- case IWN_AUTH:
- case IWN_RUN:
- if (cmd == IWN_AUTH) {
- error = iwn_auth(sc);
- nstate = IEEE80211_S_AUTH;
- } else {
- error = iwn_run(sc);
- nstate = IEEE80211_S_RUN;
- }
- if (error == 0) {
- IWN_UNLOCK(sc);
- IEEE80211_LOCK(ic);
- IWN_VAP(vap)->iv_newstate(vap, nstate, arg);
- if (vap->iv_newstate_cb != NULL)
- vap->iv_newstate_cb(vap, nstate, arg);
- IEEE80211_UNLOCK(ic);
- IWN_LOCK(sc);
- } else {
- device_printf(sc->sc_dev,
- "%s: %s state change failed, error %d\n",
- __func__, ieee80211_state_name[nstate],
- error);
- }
- break;
- case IWN_REINIT:
- IWN_UNLOCK(sc);
- iwn_init(sc);
- IWN_LOCK(sc);
- ieee80211_notify_radio(ic, 1);
- break;
- case IWN_RADIO_ENABLE:
- KASSERT(sc->fw_fp != NULL,
- ("Fware Not Loaded, can't load from tq"));
- IWN_UNLOCK(sc);
- iwn_init(sc);
- IWN_LOCK(sc);
- break;
- case IWN_RADIO_DISABLE:
- ieee80211_notify_radio(ic, 0);
- iwn_stop_locked(sc);
- break;
- }
- IWN_UNLOCK(sc);
- }
+ iwn_init(sc);
+ ieee80211_notify_radio(ic, 1);
}
-/*
- * Queue a command for execution in the taskq thread.
- * This is needed as the net80211 callbacks do not allow
- * sleeping, since we need to sleep to confirm commands have
- * been processed by the firmware, we must defer execution to
- * a sleep enabled thread.
- */
-static int
-iwn_queue_cmd(struct iwn_softc *sc, int cmd, int arg, int clear)
+static void
+iwn_radioon(void *arg0, int pending)
{
- IWN_CMD_LOCK(sc);
- if (clear) {
- sc->sc_cmd[0] = cmd;
- sc->sc_cmd_arg[0] = arg;
- sc->sc_cmd_cur = 0;
- sc->sc_cmd_next = 1;
- } else {
- if (sc->sc_cmd[sc->sc_cmd_next] != 0) {
- IWN_CMD_UNLOCK(sc);
- DPRINTF(sc, IWN_DEBUG_ANY, "%s: command %d dropped\n",
- __func__, cmd);
- return EBUSY;
- }
- sc->sc_cmd[sc->sc_cmd_next] = cmd;
- sc->sc_cmd_arg[sc->sc_cmd_next] = arg;
- sc->sc_cmd_next = (sc->sc_cmd_next + 1) % IWN_CMD_MAXOPS;
- }
- taskqueue_enqueue(sc->sc_tq, &sc->sc_ops_task);
- IWN_CMD_UNLOCK(sc);
- return 0;
+ struct iwn_softc *sc = arg0;
+
+ iwn_init(sc);
+}
+
+static void
+iwn_radiooff(void *arg0, int pending)
+{
+ struct iwn_softc *sc = arg0;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
+
+ IWN_LOCK(sc);
+ ieee80211_notify_radio(ic, 0);
+ iwn_stop_locked(sc);
+ IWN_UNLOCK(sc);
}
static void
@@ -4542,24 +4440,6 @@ iwn_sysctlattach(struct iwn_softc *sc)
#ifdef IWN_DEBUG
static const char *
-iwn_ops_str(int cmd)
-{
- switch (cmd) {
- case IWN_SCAN_START: return "SCAN_START";
- case IWN_SCAN_CURCHAN: return "SCAN_CURCHAN";
- case IWN_SCAN_STOP: return "SCAN_STOP";
- case IWN_SET_CHAN: return "SET_CHAN";
- case IWN_AUTH: return "AUTH";
- case IWN_SCAN_NEXT: return "SCAN_NEXT";
- case IWN_RUN: return "RUN";
- case IWN_RADIO_ENABLE: return "RADIO_ENABLE";
- case IWN_RADIO_DISABLE: return "RADIO_DISABLE";
- case IWN_REINIT: return "REINIT";
- }
- return "UNKNOWN COMMAND";
-}
-
-static const char *
iwn_intr_str(uint8_t cmd)
{
switch (cmd) {
diff --git a/sys/dev/iwn/if_iwnvar.h b/sys/dev/iwn/if_iwnvar.h
index 4620342..d956525 100644
--- a/sys/dev/iwn/if_iwnvar.h
+++ b/sys/dev/iwn/if_iwnvar.h
@@ -180,33 +180,10 @@ struct iwn_softc {
void *sc_ih;
bus_size_t sc_sz;
- /* command queue related variables */
-#define IWN_SCAN_START (1<<0)
-#define IWN_SCAN_CURCHAN (1<<1)
-#define IWN_SCAN_STOP (1<<2)
-#define IWN_SET_CHAN (1<<3)
-#define IWN_AUTH (1<<4)
-#define IWN_SCAN_NEXT (1<<5)
-#define IWN_RUN (1<<6)
-#define IWN_RADIO_ENABLE (1<<7)
-#define IWN_RADIO_DISABLE (1<<8)
-#define IWN_REINIT (1<<9)
-#define IWN_CMD_MAXOPS 10
- /* command queuing request type */
-#define IWN_QUEUE_NORMAL 0
-#define IWN_QUEUE_CLEAR 1
- int sc_cmd[IWN_CMD_MAXOPS];
- int sc_cmd_arg[IWN_CMD_MAXOPS];
- int sc_cmd_cur; /* current queued scan task */
- int sc_cmd_next; /* last queued scan task */
- struct mtx sc_cmdlock;
-
- /* Task queues used to control the driver */
- struct taskqueue *sc_tq; /* Main command task queue */
-
/* Tasks used by the driver */
- struct task sc_ops_task; /* deferred ops */
- struct task sc_bmiss_task; /* beacon miss */
+ struct task sc_reinit_task;
+ struct task sc_radioon_task;
+ struct task sc_radiooff_task;
/* Thermal calibration */
int calib_cnt;
@@ -234,9 +211,3 @@ struct iwn_softc {
#define IWN_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_mtx, MA_OWNED)
#define IWN_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
#define IWN_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_mtx)
-#define IWN_CMD_LOCK_INIT(_sc) \
- mtx_init(&(_sc)->sc_cmdlock, device_get_nameunit((_sc)->sc_dev), \
- NULL, MTX_DEF);
-#define IWN_CMD_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_cmdlock)
-#define IWN_CMD_LOCK(_sc) mtx_lock(&(_sc)->sc_cmdlock)
-#define IWN_CMD_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_cmdlock)
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_ */
diff --git a/sys/dev/wi/if_wi.c b/sys/dev/wi/if_wi.c
index a4a74e4..3dce847 100644
--- a/sys/dev/wi/if_wi.c
+++ b/sys/dev/wi/if_wi.c
@@ -78,7 +78,6 @@ __FBSDID("$FreeBSD$");
#include <sys/random.h>
#include <sys/syslog.h>
#include <sys/sysctl.h>
-#include <sys/taskqueue.h>
#include <machine/bus.h>
#include <machine/resource.h>
@@ -134,10 +133,6 @@ static void wi_rx_intr(struct wi_softc *);
static void wi_tx_intr(struct wi_softc *);
static void wi_tx_ex_intr(struct wi_softc *);
-static void wi_status_connected(void *, int);
-static void wi_status_disconnected(void *, int);
-static void wi_status_oor(void *, int);
-static void wi_status_assoc_failed(void *, int);
static void wi_info_intr(struct wi_softc *);
static int wi_write_txrate(struct wi_softc *, struct ieee80211vap *);
@@ -451,7 +446,6 @@ wi_attach(device_t dev)
}
sc->sc_portnum = WI_DEFAULT_PORT;
- TASK_INIT(&sc->sc_oor_task, 0, wi_status_oor, ic);
ieee80211_ifattach(ic, macaddr);
ic->ic_raw_xmit = wi_raw_xmit;
@@ -574,10 +568,6 @@ wi_vap_create(struct ieee80211com *ic,
break;
}
- TASK_INIT(&wvp->wv_connected_task, 0, wi_status_connected, vap);
- TASK_INIT(&wvp->wv_disconnected_task, 0, wi_status_disconnected, vap);
- TASK_INIT(&wvp->wv_assoc_failed_task, 0, wi_status_assoc_failed, vap);
-
/* complete setup */
ieee80211_vap_attach(vap, ieee80211_media_change, wi_media_status);
ic->ic_opmode = opmode;
@@ -902,7 +892,7 @@ wi_newstate_sta(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
* notification we get on association.
*/
vap->iv_state = nstate;
- return EINPROGRESS;
+ return (0);
}
return WI_VAP(vap)->wv_newstate(vap, nstate, arg);
}
@@ -1512,55 +1502,12 @@ wi_tx_intr(struct wi_softc *sc)
}
}
-static void
-wi_status_connected(void *arg, int pending)
-{
- struct ieee80211vap *vap = arg;
- struct ieee80211com *ic = vap->iv_ic;
-
- IEEE80211_LOCK(ic);
- vap->iv_bss->ni_associd = 1 | 0xc000; /* NB: anything will do */
- WI_VAP(vap)->wv_newstate(vap, IEEE80211_S_RUN, 0);
- if (vap->iv_newstate_cb != NULL)
- vap->iv_newstate_cb(vap, IEEE80211_S_RUN, 0);
- IEEE80211_UNLOCK(ic);
-}
-
-static void
-wi_status_disconnected(void *arg, int pending)
-{
- struct ieee80211vap *vap = arg;
-
- if (vap->iv_state == IEEE80211_S_RUN) {
- vap->iv_bss->ni_associd = 0;
- vap->iv_stats.is_rx_deauth++;
- ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
- }
-}
-
-static void
-wi_status_oor(void *arg, int pending)
-{
- struct ieee80211com *ic = arg;
-
- ieee80211_beacon_miss(ic);
-}
-
-static void
-wi_status_assoc_failed(void *arg, int pending)
-{
- struct ieee80211vap *vap = arg;
-
- ieee80211_new_state(vap, IEEE80211_S_SCAN, IEEE80211_SCAN_FAIL_TIMEOUT);
-}
-
static __noinline void
wi_info_intr(struct wi_softc *sc)
{
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic = ifp->if_l2com;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
- struct wi_vap *wvp = WI_VAP(vap);
int i, fid, len, off;
u_int16_t ltbuf[2];
u_int16_t stat;
@@ -1580,22 +1527,29 @@ wi_info_intr(struct wi_softc *sc)
break;
/* fall thru... */
case WI_INFO_LINK_STAT_AP_CHG:
- taskqueue_enqueue(taskqueue_swi, &wvp->wv_connected_task);
+ IEEE80211_LOCK(ic);
+ vap->iv_bss->ni_associd = 1 | 0xc000; /* NB: anything will do */
+ ieee80211_new_state(vap, IEEE80211_S_RUN, 0);
+ IEEE80211_UNLOCK(ic);
break;
case WI_INFO_LINK_STAT_AP_INR:
break;
case WI_INFO_LINK_STAT_DISCONNECTED:
/* we dropped off the net; e.g. due to deauth/disassoc */
- taskqueue_enqueue(taskqueue_swi, &wvp->wv_disconnected_task);
+ IEEE80211_LOCK(ic);
+ vap->iv_bss->ni_associd = 0;
+ vap->iv_stats.is_rx_deauth++;
+ ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
+ IEEE80211_UNLOCK(ic);
break;
case WI_INFO_LINK_STAT_AP_OOR:
/* XXX does this need to be per-vap? */
- taskqueue_enqueue(taskqueue_swi, &sc->sc_oor_task);
+ ieee80211_beacon_miss(ic);
break;
case WI_INFO_LINK_STAT_ASSOC_FAILED:
if (vap->iv_opmode == IEEE80211_M_STA)
- taskqueue_enqueue(taskqueue_swi,
- &wvp->wv_assoc_failed_task);
+ ieee80211_new_state(vap, IEEE80211_S_SCAN,
+ IEEE80211_SCAN_FAIL_TIMEOUT);
break;
}
break;
diff --git a/sys/dev/wi/if_wivar.h b/sys/dev/wi/if_wivar.h
index a66c74b..fdcedd8 100644
--- a/sys/dev/wi/if_wivar.h
+++ b/sys/dev/wi/if_wivar.h
@@ -59,9 +59,6 @@
struct wi_vap {
struct ieee80211vap wv_vap;
struct ieee80211_beacon_offsets wv_bo;
- struct task wv_connected_task;
- struct task wv_disconnected_task;
- struct task wv_assoc_failed_task;
void (*wv_recv_mgmt)(struct ieee80211_node *,
struct mbuf *, int, int, int, u_int32_t);
@@ -75,7 +72,6 @@ struct wi_softc {
device_t sc_dev;
struct mtx sc_mtx;
struct callout sc_watchdog;
- struct task sc_oor_task;
int sc_unit;
int wi_gone;
int sc_enabled;
diff --git a/sys/dev/wpi/if_wpi.c b/sys/dev/wpi/if_wpi.c
index 1e980aa..0ab8680 100644
--- a/sys/dev/wpi/if_wpi.c
+++ b/sys/dev/wpi/if_wpi.c
@@ -192,12 +192,9 @@ static void wpi_rx_intr(struct wpi_softc *, struct wpi_rx_desc *,
struct wpi_rx_data *);
static void wpi_tx_intr(struct wpi_softc *, struct wpi_rx_desc *);
static void wpi_cmd_intr(struct wpi_softc *, struct wpi_rx_desc *);
-static void wpi_bmiss(void *, int);
static void wpi_notif_intr(struct wpi_softc *);
static void wpi_intr(void *);
-static void wpi_ops(void *, int);
static uint8_t wpi_plcp_signal(int);
-static int wpi_queue_cmd(struct wpi_softc *, int, int, int);
static void wpi_watchdog(void *);
static int wpi_tx_data(struct wpi_softc *, struct mbuf *,
struct ieee80211_node *, int);
@@ -230,6 +227,8 @@ static int wpi_config(struct wpi_softc *);
static void wpi_stop_master(struct wpi_softc *);
static int wpi_power_up(struct wpi_softc *);
static int wpi_reset(struct wpi_softc *);
+static void wpi_hwreset(void *, int);
+static void wpi_rfreset(void *, int);
static void wpi_hw_config(struct wpi_softc *);
static void wpi_init(void *);
static void wpi_init_locked(struct wpi_softc *, int);
@@ -514,21 +513,11 @@ wpi_attach(device_t dev)
}
}
- /*
- * Create the taskqueues used by the driver. Primarily
- * sc_tq handles most the task
- */
- sc->sc_tq = taskqueue_create("wpi_taskq", M_NOWAIT | M_ZERO,
- taskqueue_thread_enqueue, &sc->sc_tq);
- taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, "%s taskq",
- device_get_nameunit(dev));
-
/* Create the tasks that can be queued */
- TASK_INIT(&sc->sc_opstask, 0, wpi_ops, sc);
- TASK_INIT(&sc->sc_bmiss_task, 0, wpi_bmiss, sc);
+ TASK_INIT(&sc->sc_restarttask, 0, wpi_hwreset, sc);
+ TASK_INIT(&sc->sc_radiotask, 0, wpi_rfreset, sc);
WPI_LOCK_INIT(sc);
- WPI_CMD_LOCK_INIT(sc);
callout_init_mtx(&sc->calib_to, &sc->sc_mtx, 0);
callout_init_mtx(&sc->watchdog_to, &sc->sc_mtx, 0);
@@ -732,6 +721,9 @@ wpi_detach(device_t dev)
struct ieee80211com *ic = ifp->if_l2com;
int ac;
+ ieee80211_draintask(ic, &sc->sc_restarttask);
+ ieee80211_draintask(ic, &sc->sc_radiotask);
+
if (ifp != NULL) {
wpi_stop(sc);
callout_drain(&sc->watchdog_to);
@@ -769,10 +761,7 @@ wpi_detach(device_t dev)
if (ifp != NULL)
if_free(ifp);
- taskqueue_free(sc->sc_tq);
-
WPI_LOCK_DESTROY(sc);
- WPI_CMD_LOCK_DESTROY(sc);
return 0;
}
@@ -1280,21 +1269,32 @@ wpi_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
ieee80211_state_name[vap->iv_state],
ieee80211_state_name[nstate], sc->flags));
+ IEEE80211_UNLOCK(ic);
+ WPI_LOCK(sc);
if (nstate == IEEE80211_S_AUTH) {
- /* Delay the auth transition until we can update the firmware */
- error = wpi_queue_cmd(sc, WPI_AUTH, arg, WPI_QUEUE_NORMAL);
- return (error != 0 ? error : EINPROGRESS);
+ /* The node must be registered in the firmware before auth */
+ error = wpi_auth(sc, vap);
+ if (error != 0) {
+ device_printf(sc->sc_dev,
+ "%s: could not move to auth state, error %d\n",
+ __func__, error);
+ }
}
if (nstate == IEEE80211_S_RUN && vap->iv_state != IEEE80211_S_RUN) {
- /* set the association id first */
- error = wpi_queue_cmd(sc, WPI_RUN, arg, WPI_QUEUE_NORMAL);
- return (error != 0 ? error : EINPROGRESS);
+ error = wpi_run(sc, vap);
+ if (error != 0) {
+ device_printf(sc->sc_dev,
+ "%s: could not move to run state, error %d\n",
+ __func__, error);
+ }
}
if (nstate == IEEE80211_S_RUN) {
/* RUN -> RUN transition; just restart the timers */
wpi_calib_timeout(sc);
/* XXX split out rate control timer */
}
+ WPI_UNLOCK(sc);
+ IEEE80211_LOCK(ic);
return wvp->newstate(vap, nstate, arg);
}
@@ -1642,15 +1642,6 @@ wpi_cmd_intr(struct wpi_softc *sc, struct wpi_rx_desc *desc)
}
static void
-wpi_bmiss(void *arg, int npending)
-{
- struct wpi_softc *sc = arg;
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
-
- ieee80211_beacon_miss(ic);
-}
-
-static void
wpi_notif_intr(struct wpi_softc *sc)
{
struct ifnet *ifp = sc->sc_ifp;
@@ -1759,8 +1750,7 @@ wpi_notif_intr(struct wpi_softc *sc)
DPRINTF(("Beacon miss: %u >= %u\n",
le32toh(beacon->consecutive),
vap->iv_bmissthreshold));
- taskqueue_enqueue(taskqueue_swi,
- &sc->sc_bmiss_task);
+ ieee80211_beacon_miss(ic);
}
break;
}
@@ -1794,10 +1784,13 @@ wpi_intr(void *arg)
WPI_WRITE(sc, WPI_INTR, r);
if (r & (WPI_SW_ERROR | WPI_HW_ERROR)) {
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
+
device_printf(sc->sc_dev, "fatal firmware error\n");
DPRINTFN(6,("(%s)\n", (r & WPI_SW_ERROR) ? "(Software Error)" :
"(Hardware Error)"));
- wpi_queue_cmd(sc, WPI_RESTART, 0, WPI_QUEUE_CLEAR);
+ ieee80211_runtask(ic, &sc->sc_restarttask);
sc->flags &= ~WPI_FLAG_BUSY;
WPI_UNLOCK(sc);
return;
@@ -3030,8 +3023,7 @@ wpi_rfkill_resume(struct wpi_softc *sc)
if (vap != NULL) {
if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) {
if (vap->iv_opmode != IEEE80211_M_MONITOR) {
- taskqueue_enqueue(taskqueue_swi,
- &sc->sc_bmiss_task);
+ ieee80211_beacon_miss(ic);
wpi_set_led(sc, WPI_LED_LINK, 0, 1);
} else
wpi_set_led(sc, WPI_LED_LINK, 5, 5);
@@ -3189,12 +3181,6 @@ wpi_stop_locked(struct wpi_softc *sc)
WPI_WRITE(sc, WPI_INTR_STATUS, 0xff);
WPI_WRITE(sc, WPI_INTR_STATUS, 0x00070000);
- /* Clear any commands left in the command buffer */
- memset(sc->sc_cmd, 0, sizeof(sc->sc_cmd));
- memset(sc->sc_cmd_arg, 0, sizeof(sc->sc_cmd_arg));
- sc->sc_cmd_cur = 0;
- sc->sc_cmd_next = 0;
-
wpi_mem_lock(sc);
wpi_mem_write(sc, WPI_MEM_MODE, 0);
wpi_mem_unlock(sc);
@@ -3538,7 +3524,9 @@ wpi_scan_start(struct ieee80211com *ic)
struct ifnet *ifp = ic->ic_ifp;
struct wpi_softc *sc = ifp->if_softc;
- wpi_queue_cmd(sc, WPI_SCAN_START, 0, WPI_QUEUE_NORMAL);
+ WPI_LOCK(sc);
+ wpi_set_led(sc, WPI_LED_LINK, 20, 2);
+ WPI_UNLOCK(sc);
}
/**
@@ -3549,10 +3537,7 @@ wpi_scan_start(struct ieee80211com *ic)
static void
wpi_scan_end(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct wpi_softc *sc = ifp->if_softc;
-
- wpi_queue_cmd(sc, WPI_SCAN_STOP, 0, WPI_QUEUE_NORMAL);
+ /* XXX ignore */
}
/**
@@ -3564,13 +3549,18 @@ wpi_set_channel(struct ieee80211com *ic)
{
struct ifnet *ifp = ic->ic_ifp;
struct wpi_softc *sc = ifp->if_softc;
+ int error;
/*
* Only need to set the channel in Monitor mode. AP scanning and auth
* are already taken care of by their respective firmware commands.
*/
- if (ic->ic_opmode == IEEE80211_M_MONITOR)
- wpi_queue_cmd(sc, WPI_SET_CHAN, 0, WPI_QUEUE_NORMAL);
+ if (ic->ic_opmode == IEEE80211_M_MONITOR) {
+ error = wpi_config(sc);
+ if (error != 0)
+ device_printf(sc->sc_dev,
+ "error %d settting channel\n", error);
+ }
}
/**
@@ -3585,7 +3575,10 @@ wpi_scan_curchan(struct ieee80211_scan_state *ss, unsigned long maxdwell)
struct ifnet *ifp = vap->iv_ic->ic_ifp;
struct wpi_softc *sc = ifp->if_softc;
- wpi_queue_cmd(sc, WPI_SCAN_CURCHAN, 0, WPI_QUEUE_NORMAL);
+ WPI_LOCK(sc);
+ if (wpi_scan(sc))
+ ieee80211_cancel_scan(vap);
+ WPI_UNLOCK(sc);
}
/**
@@ -3600,152 +3593,24 @@ wpi_scan_mindwell(struct ieee80211_scan_state *ss)
/* NB: don't try to abort scan; wait for firmware to finish */
}
-/**
- * The ops function is called to perform some actual work.
- * because we can't sleep from any of the ic callbacks, we queue an
- * op task with wpi_queue_cmd and have the taskqueue process that task.
- * The task that gets cued is a op task, which ends up calling this function.
- */
static void
-wpi_ops(void *arg0, int pending)
+wpi_hwreset(void *arg, int pending)
{
- struct wpi_softc *sc = arg0;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- int cmd, arg, error;
- struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
-
-again:
- WPI_CMD_LOCK(sc);
- cmd = sc->sc_cmd[sc->sc_cmd_cur];
- arg = sc->sc_cmd_arg[sc->sc_cmd_cur];
+ struct wpi_softc *sc = arg;
- if (cmd == 0) {
- /* No more commands to process */
- WPI_CMD_UNLOCK(sc);
- return;
- }
- sc->sc_cmd[sc->sc_cmd_cur] = 0; /* free the slot */
- sc->sc_cmd_arg[sc->sc_cmd_cur] = 0; /* free the slot */
- sc->sc_cmd_cur = (sc->sc_cmd_cur + 1) % WPI_CMD_MAXOPS;
- WPI_CMD_UNLOCK(sc);
WPI_LOCK(sc);
-
- DPRINTFN(WPI_DEBUG_OPS,("wpi_ops: command: %d\n", cmd));
-
- switch (cmd) {
- case WPI_RESTART:
- wpi_init_locked(sc, 0);
- WPI_UNLOCK(sc);
- return;
-
- case WPI_RF_RESTART:
- wpi_rfkill_resume(sc);
- WPI_UNLOCK(sc);
- return;
- }
-
- if (!(sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING)) {
- WPI_UNLOCK(sc);
- return;
- }
-
- switch (cmd) {
- case WPI_SCAN_START:
- /* make the link LED blink while we're scanning */
- wpi_set_led(sc, WPI_LED_LINK, 20, 2);
- sc->flags |= WPI_FLAG_SCANNING;
- break;
-
- case WPI_SCAN_STOP:
- sc->flags &= ~WPI_FLAG_SCANNING;
- break;
-
- case WPI_SCAN_CURCHAN:
- if (wpi_scan(sc))
- ieee80211_cancel_scan(vap);
- break;
-
- case WPI_SET_CHAN:
- error = wpi_config(sc);
- if (error != 0)
- device_printf(sc->sc_dev,
- "error %d settting channel\n", error);
- break;
-
- case WPI_AUTH:
- /* The node must be registered in the firmware before auth */
- error = wpi_auth(sc, vap);
- WPI_UNLOCK(sc);
- if (error != 0) {
- device_printf(sc->sc_dev,
- "%s: could not move to auth state, error %d\n",
- __func__, error);
- return;
- }
- IEEE80211_LOCK(ic);
- WPI_VAP(vap)->newstate(vap, IEEE80211_S_AUTH, arg);
- if (vap->iv_newstate_cb != NULL)
- vap->iv_newstate_cb(vap, IEEE80211_S_AUTH, arg);
- IEEE80211_UNLOCK(ic);
- goto again;
-
- case WPI_RUN:
- error = wpi_run(sc, vap);
- WPI_UNLOCK(sc);
- if (error != 0) {
- device_printf(sc->sc_dev,
- "%s: could not move to run state, error %d\n",
- __func__, error);
- return;
- }
- IEEE80211_LOCK(ic);
- WPI_VAP(vap)->newstate(vap, IEEE80211_S_RUN, arg);
- if (vap->iv_newstate_cb != NULL)
- vap->iv_newstate_cb(vap, IEEE80211_S_RUN, arg);
- IEEE80211_UNLOCK(ic);
- goto again;
- }
+ wpi_init_locked(sc, 0);
WPI_UNLOCK(sc);
-
- /* Take another pass */
- goto again;
}
-/**
- * queue a command for later execution in a different thread.
- * This is needed as the net80211 callbacks do not allow
- * sleeping, since we need to sleep to confirm commands have
- * been processed by the firmware, we must defer execution to
- * a sleep enabled thread.
- */
-static int
-wpi_queue_cmd(struct wpi_softc *sc, int cmd, int arg, int flush)
+static void
+wpi_rfreset(void *arg, int pending)
{
- WPI_CMD_LOCK(sc);
-
- if (flush) {
- memset(sc->sc_cmd, 0, sizeof (sc->sc_cmd));
- memset(sc->sc_cmd_arg, 0, sizeof (sc->sc_cmd_arg));
- sc->sc_cmd_cur = 0;
- sc->sc_cmd_next = 0;
- }
-
- if (sc->sc_cmd[sc->sc_cmd_next] != 0) {
- WPI_CMD_UNLOCK(sc);
- DPRINTF(("%s: command %d dropped\n", __func__, cmd));
- return (EBUSY);
- }
-
- sc->sc_cmd[sc->sc_cmd_next] = cmd;
- sc->sc_cmd_arg[sc->sc_cmd_next] = arg;
- sc->sc_cmd_next = (sc->sc_cmd_next + 1) % WPI_CMD_MAXOPS;
-
- taskqueue_enqueue(sc->sc_tq, &sc->sc_opstask);
-
- WPI_CMD_UNLOCK(sc);
+ struct wpi_softc *sc = arg;
- return 0;
+ WPI_LOCK(sc);
+ wpi_rfkill_resume(sc);
+ WPI_UNLOCK(sc);
}
/*
@@ -3775,6 +3640,7 @@ wpi_watchdog(void *arg)
{
struct wpi_softc *sc = arg;
struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
uint32_t tmp;
DPRINTFN(WPI_DEBUG_WATCHDOG,("Watchdog: tick\n"));
@@ -3790,7 +3656,7 @@ wpi_watchdog(void *arg)
}
device_printf(sc->sc_dev, "Hardware Switch Enabled\n");
- wpi_queue_cmd(sc, WPI_RF_RESTART, 0, WPI_QUEUE_CLEAR);
+ ieee80211_runtask(ic, &sc->sc_radiotask);
return;
}
@@ -3798,17 +3664,15 @@ wpi_watchdog(void *arg)
if (--sc->sc_tx_timer == 0) {
device_printf(sc->sc_dev,"device timeout\n");
ifp->if_oerrors++;
- wpi_queue_cmd(sc, WPI_RESTART, 0, WPI_QUEUE_CLEAR);
+ ieee80211_runtask(ic, &sc->sc_restarttask);
}
}
if (sc->sc_scan_timer > 0) {
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
if (--sc->sc_scan_timer == 0 && vap != NULL) {
device_printf(sc->sc_dev,"scan timeout\n");
ieee80211_cancel_scan(vap);
- wpi_queue_cmd(sc, WPI_RESTART, 0, WPI_QUEUE_CLEAR);
+ ieee80211_runtask(ic, &sc->sc_restarttask);
}
}
diff --git a/sys/dev/wpi/if_wpivar.h b/sys/dev/wpi/if_wpivar.h
index a447fd3..36da3b1 100644
--- a/sys/dev/wpi/if_wpivar.h
+++ b/sys/dev/wpi/if_wpivar.h
@@ -144,9 +144,8 @@ struct wpi_softc {
*/
uint32_t flags;
#define WPI_FLAG_HW_RADIO_OFF (1 << 0)
-#define WPI_FLAG_SCANNING (1 << 1)
-#define WPI_FLAG_BUSY (1 << 2)
-#define WPI_FLAG_AUTH (1 << 3)
+#define WPI_FLAG_BUSY (1 << 1)
+#define WPI_FLAG_AUTH (1 << 2)
/* shared area */
struct wpi_dma_info shared_dma;
@@ -193,36 +192,9 @@ struct wpi_softc {
/* firmware DMA transfer */
struct wpi_dma_info fw_dma;
- /* command queue related variables */
-#define WPI_SCAN_START (1<<0)
-#define WPI_SCAN_CURCHAN (1<<1)
-#define WPI_SCAN_STOP (1<<2)
-#define WPI_SET_CHAN (1<<3)
-#define WPI_AUTH (1<<4)
-#define WPI_RUN (1<<5)
-#define WPI_SCAN_NEXT (1<<6)
-#define WPI_RESTART (1<<7)
-#define WPI_RF_RESTART (1<<8)
-#define WPI_CMD_MAXOPS 10
- /* command queuing request type */
-#define WPI_QUEUE_NORMAL 0
-#define WPI_QUEUE_CLEAR 1
- int sc_cmd[WPI_CMD_MAXOPS];
- int sc_cmd_arg[WPI_CMD_MAXOPS];
- int sc_cmd_cur; /* current queued scan task */
- int sc_cmd_next; /* last queued scan task */
- struct mtx sc_cmdlock;
-
- /* Task queues used to control the driver */
- struct taskqueue *sc_tq; /* Main command task queue */
- struct taskqueue *sc_tq2; /* firmware reset task queue */
-
/* Tasks used by the driver */
- struct task sc_radioontask; /* enable rf transmitter task*/
- struct task sc_radioofftask;/* disable rf transmitter task*/
- struct task sc_opstask; /* operation handling task */
struct task sc_restarttask; /* reset firmware task */
- struct task sc_bmiss_task; /* beacon miss */
+ struct task sc_radiotask; /* reset rf task */
/* Eeprom info */
uint8_t cap;
@@ -239,10 +211,3 @@ struct wpi_softc {
#define WPI_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
#define WPI_LOCK_ASSERT(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED)
#define WPI_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_mtx)
-
-#define WPI_CMD_LOCK_INIT(_sc) \
- mtx_init(&(_sc)->sc_cmdlock, device_get_nameunit((_sc)->sc_dev), \
- NULL, MTX_DEF)
-#define WPI_CMD_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_cmdlock)
-#define WPI_CMD_LOCK(_sc) mtx_lock(&(_sc)->sc_cmdlock)
-#define WPI_CMD_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_cmdlock)
OpenPOWER on IntegriCloud