svn commit: r188419 - head/sys/dev/usb2/wlan
Andrew Thompson
thompsa at FreeBSD.org
Mon Feb 9 14:18:12 PST 2009
Author: thompsa
Date: Mon Feb 9 22:18:11 2009
New Revision: 188419
URL: http://svn.freebsd.org/changeset/base/188419
Log:
MFp4 //depot/projects/usb; 157429, 157433, 157443
Various changes wrt. usb procs and tasks.
Submitted by: Hans Petter Selasky
Modified:
head/sys/dev/usb2/wlan/if_rum2.c
head/sys/dev/usb2/wlan/if_rumvar.h
head/sys/dev/usb2/wlan/if_ural2.c
head/sys/dev/usb2/wlan/if_uralvar.h
head/sys/dev/usb2/wlan/if_zyd2.c
head/sys/dev/usb2/wlan/if_zydreg.h
Modified: head/sys/dev/usb2/wlan/if_rum2.c
==============================================================================
--- head/sys/dev/usb2/wlan/if_rum2.c Mon Feb 9 22:14:38 2009 (r188418)
+++ head/sys/dev/usb2/wlan/if_rum2.c Mon Feb 9 22:18:11 2009 (r188419)
@@ -54,6 +54,9 @@ SYSCTL_INT(_hw_usb2_rum, OID_AUTO, debug
"Debug level");
#endif
+#define rum_do_request(sc,req,data) \
+ usb2_do_request_proc((sc)->sc_udev, &(sc)->sc_tq, req, data, 0, NULL, 5000)
+
static const struct usb2_device_id rum_devs[] = {
{ USB_VP(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_HWU54DM) },
{ USB_VP(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2573_2) },
@@ -116,10 +119,13 @@ 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_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 struct ieee80211vap *rum_vap_create(struct ieee80211com *,
const char name[IFNAMSIZ], int unit, int opmode,
@@ -127,8 +133,8 @@ static struct ieee80211vap *rum_vap_crea
const uint8_t mac[IEEE80211_ADDR_LEN]);
static void rum_vap_delete(struct ieee80211vap *);
static void rum_tx_free(struct rum_tx_data *, int);
-static int rum_alloc_tx_list(struct rum_softc *);
-static void rum_free_tx_list(struct rum_softc *);
+static void rum_setup_tx_list(struct rum_softc *);
+static void rum_unsetup_tx_list(struct rum_softc *);
static int rum_newstate(struct ieee80211vap *,
enum ieee80211_state, int);
static void rum_setup_tx_desc(struct rum_softc *,
@@ -169,9 +175,7 @@ static void rum_set_macaddr(struct rum_
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(void *);
static int rum_load_microcode(struct rum_softc *, const u_char *,
size_t);
static int rum_prepare_beacon(struct rum_softc *,
@@ -391,12 +395,8 @@ rum_attach(device_t self)
{
struct usb2_attach_arg *uaa = device_get_ivars(self);
struct rum_softc *sc = device_get_softc(self);
- struct ieee80211com *ic;
- struct ifnet *ifp;
- const uint8_t *ucode = NULL;
- uint8_t bands, iface_index;
- uint32_t tmp;
- int error, ntries, size;
+ uint8_t iface_index;
+ int error;
device_set_usb2_desc(self);
sc->sc_udev = uaa->device;
@@ -420,42 +420,64 @@ rum_attach(device_t self)
goto detach;
}
- ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(sc->sc_dev, "can not if_alloc()\n");
- goto detach;
- }
- ic = ifp->if_l2com;
-
+ /* 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;
+ int error;
+ uint32_t tmp;
+ uint8_t bands;
+
/* retrieve RT2573 rev. no */
- for (ntries = 0; ntries < 1000; ntries++) {
+ for (ntries = 0; ntries != 1000; ntries++) {
if ((tmp = rum_read(sc, RT2573_MAC_CSR0)) != 0)
break;
- DELAY(1000);
+ usb2_pause_mtx(&sc->sc_mtx, hz / 1000);
}
if (ntries == 1000) {
- device_printf(self, "timeout waiting for chip to settle\n");
- RUM_UNLOCK(sc);
- goto detach;
+ device_printf(sc->sc_dev, "timeout waiting for chip to settle\n");
+ return;
}
/* retrieve MAC address and various other things from EEPROM */
rum_read_eeprom(sc);
- device_printf(self, "MAC/BBP RT2573 (rev 0x%05x), RF %s\n",
+ device_printf(sc->sc_dev, "MAC/BBP RT2573 (rev 0x%05x), RF %s\n",
tmp, rum_get_rf(sc->rf_rev));
- ucode = rt2573_ucode;
- size = sizeof rt2573_ucode;
- error = rum_load_microcode(sc, ucode, size);
+ error = rum_load_microcode(sc, rt2573_ucode, sizeof(rt2573_ucode));
if (error != 0) {
- device_printf(self, "could not load 8051 microcode\n");
RUM_UNLOCK(sc);
- goto detach;
+ device_printf(sc->sc_dev, "could not load 8051 microcode\n");
+ 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;
+ }
+ ic = ifp->if_l2com;
+
ifp->if_softc = sc;
if_initname(ifp, "rum", device_get_unit(sc->sc_dev));
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
@@ -468,6 +490,7 @@ rum_attach(device_t self)
ic->ic_ifp = ifp;
ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
+ IEEE80211_ADDR_COPY(ic->ic_myaddr, sc->sc_bssid);
/* set device capabilities */
ic->ic_caps =
@@ -516,10 +539,7 @@ rum_attach(device_t self)
if (bootverbose)
ieee80211_announce(ic);
- return 0;
-detach:
- rum_detach(self);
- return (ENXIO); /* failure */
+ RUM_LOCK(sc);
}
static int
@@ -529,20 +549,24 @@ rum_detach(device_t self)
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic = ifp->if_l2com;
- RUM_LOCK(sc);
- sc->sc_flags |= RUM_FLAG_DETACH;
- rum_stop(sc);
- RUM_UNLOCK(sc);
+ /* wait for any post attach or other command to complete */
+ usb2_proc_drain(&sc->sc_tq);
- /* stop all USB transfers first */
+ /* 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);
+ rum_unsetup_tx_list(sc);
+ RUM_UNLOCK(sc);
+
if (ifp) {
bpfdetach(ifp);
ieee80211_ifdetach(ic);
if_free(ifp);
}
+
mtx_destroy(&sc->sc_mtx);
return (0);
@@ -590,11 +614,8 @@ static void
rum_vap_delete(struct ieee80211vap *vap)
{
struct rum_vap *rvp = RUM_VAP(vap);
- struct rum_softc *sc = rvp->sc;
- RUM_LOCK(sc);
- usb2_callout_stop(&rvp->amrr_ch);
- RUM_UNLOCK(sc);
+ usb2_callout_drain(&rvp->amrr_ch);
ieee80211_amrr_cleanup(&rvp->amrr);
ieee80211_vap_detach(vap);
free(rvp, M_80211_VAP);
@@ -619,17 +640,12 @@ rum_tx_free(struct rum_tx_data *data, in
sc->tx_nfree++;
}
-static int
-rum_alloc_tx_list(struct rum_softc *sc)
+static void
+rum_setup_tx_list(struct rum_softc *sc)
{
struct rum_tx_data *data;
int i;
- sc->tx_data = malloc(sizeof(struct rum_tx_data) * RUM_TX_LIST_COUNT,
- M_USB, M_NOWAIT|M_ZERO);
- if (sc->tx_data == NULL)
- return (ENOMEM);
-
sc->tx_nfree = 0;
STAILQ_INIT(&sc->tx_q);
STAILQ_INIT(&sc->tx_free);
@@ -641,18 +657,20 @@ rum_alloc_tx_list(struct rum_softc *sc)
STAILQ_INSERT_TAIL(&sc->tx_free, data, next);
sc->tx_nfree++;
}
- return 0;
}
static void
-rum_free_tx_list(struct rum_softc *sc)
+rum_unsetup_tx_list(struct rum_softc *sc)
{
struct rum_tx_data *data;
int i;
- if (sc->tx_data == NULL)
- return;
+ /* make sure any subsequent use of the queues will fail */
+ sc->tx_nfree = 0;
+ STAILQ_INIT(&sc->tx_q);
+ STAILQ_INIT(&sc->tx_free);
+ /* free up all node references and mbufs */
for (i = 0; i < RUM_TX_LIST_COUNT; i++) {
data = &sc->tx_data[i];
@@ -665,8 +683,6 @@ rum_free_tx_list(struct rum_softc *sc)
data->ni = NULL;
}
}
- free(sc->tx_data, M_USB);
- sc->tx_data = NULL;
}
static void
@@ -683,9 +699,6 @@ rum_task(struct usb2_proc_msg *pm)
struct ieee80211_node *ni;
uint32_t tmp;
- if (sc->sc_flags & RUM_FLAG_DETACH)
- return;
-
ostate = vap->iv_state;
switch (sc->sc_state) {
@@ -705,7 +718,8 @@ rum_task(struct usb2_proc_msg *pm)
rum_enable_mrr(sc);
rum_set_txpreamble(sc);
rum_set_basicrates(sc);
- rum_set_bssid(sc, ni->ni_bssid);
+ IEEE80211_ADDR_COPY(sc->sc_bssid, ni->ni_bssid);
+ rum_set_bssid(sc, sc->sc_bssid);
}
if (vap->iv_opmode == IEEE80211_M_HOSTAP ||
@@ -773,7 +787,7 @@ rum_bulk_write_callback(struct usb2_xfer
struct ieee80211_channel *c = ic->ic_curchan;
struct rum_tx_data *data;
struct mbuf *m;
- int len;
+ unsigned int len;
switch (USB_GET_STATE(xfer)) {
case USB_ST_TRANSFERRED:
@@ -790,15 +804,6 @@ rum_bulk_write_callback(struct usb2_xfer
/* FALLTHROUGH */
case USB_ST_SETUP:
tr_setup:
-#if 0
- if (sc->sc_flags & RUM_FLAG_WAIT_COMMAND) {
- /*
- * don't send anything while a command is pending !
- */
- break;
- }
-#endif
-
data = STAILQ_FIRST(&sc->tx_q);
if (data) {
STAILQ_REMOVE_HEAD(&sc->tx_q, next);
@@ -845,6 +850,13 @@ tr_setup:
DPRINTFN(11, "transfer error, %s\n",
usb2_errstr(xfer->error));
+ ifp->if_oerrors++;
+ data = xfer->priv_fifo;
+ if (data != NULL) {
+ rum_tx_free(data, xfer->error);
+ xfer->priv_fifo = NULL;
+ }
+
if (xfer->error == USB_ERR_STALLED) {
/* try to clear stall first */
xfer->flags.stall_pipe = 1;
@@ -852,13 +864,6 @@ tr_setup:
}
if (xfer->error == USB_ERR_TIMEOUT)
device_printf(sc->sc_dev, "device timeout\n");
-
- ifp->if_oerrors++;
- data = xfer->priv_fifo;
- if (data != NULL) {
- rum_tx_free(data, xfer->error);
- xfer->priv_fifo = NULL;
- }
break;
}
}
@@ -873,7 +878,7 @@ rum_bulk_read_callback(struct usb2_xfer
struct mbuf *m = NULL;
uint32_t flags;
uint8_t rssi = 0;
- int len;
+ unsigned int len;
switch (USB_GET_STATE(xfer)) {
case USB_ST_TRANSFERRED:
@@ -965,7 +970,6 @@ tr_setup:
goto tr_setup;
}
return;
-
}
}
@@ -1333,15 +1337,20 @@ rum_ioctl(struct ifnet *ifp, u_long cmd,
RUM_LOCK(sc);
if (ifp->if_flags & IFF_UP) {
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
- rum_init_locked(sc);
+ rum_queue_command(sc, rum_init_task,
+ &sc->sc_synctask[0].hdr,
+ &sc->sc_synctask[1].hdr);
startall = 1;
} else
rum_queue_command(sc, rum_promisctask,
&sc->sc_promisctask[0].hdr,
&sc->sc_promisctask[1].hdr);
} else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- rum_stop(sc);
+ 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);
+ }
}
RUM_UNLOCK(sc);
if (startall)
@@ -1372,7 +1381,7 @@ rum_eeprom_read(struct rum_softc *sc, ui
USETW(req.wIndex, addr);
USETW(req.wLength, len);
- error = usb2_do_request(sc->sc_udev, &sc->sc_mtx, &req, buf);
+ error = rum_do_request(sc, &req, buf);
if (error != 0) {
device_printf(sc->sc_dev, "could not read EEPROM: %s\n",
usb2_errstr(error));
@@ -1401,7 +1410,7 @@ rum_read_multi(struct rum_softc *sc, uin
USETW(req.wIndex, reg);
USETW(req.wLength, len);
- error = usb2_do_request(sc->sc_udev, &sc->sc_mtx, &req, buf);
+ error = rum_do_request(sc, &req, buf);
if (error != 0) {
device_printf(sc->sc_dev,
"could not multi read MAC register: %s\n",
@@ -1429,7 +1438,7 @@ rum_write_multi(struct rum_softc *sc, ui
USETW(req.wIndex, reg);
USETW(req.wLength, len);
- error = usb2_do_request(sc->sc_udev, &sc->sc_mtx, &req, buf);
+ error = rum_do_request(sc, &req, buf);
if (error != 0) {
device_printf(sc->sc_dev,
"could not multi write MAC register: %s\n",
@@ -1787,9 +1796,6 @@ rum_promisctask(struct usb2_proc_msg *pm
struct ifnet *ifp = sc->sc_ifp;
uint32_t tmp;
- if (sc->sc_flags & RUM_FLAG_DETACH)
- return;
-
tmp = rum_read(sc, RT2573_TXRX_CSR0);
tmp &= ~RT2573_DROP_NOT_TO_ME;
@@ -1817,15 +1823,13 @@ rum_get_rf(int rev)
static void
rum_read_eeprom(struct rum_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
uint16_t val;
#ifdef RUM_DEBUG
int i;
#endif
/* read MAC address */
- rum_eeprom_read(sc, RT2573_EEPROM_ADDRESS, ic->ic_myaddr, 6);
+ rum_eeprom_read(sc, RT2573_EEPROM_ADDRESS, sc->sc_bssid, 6);
rum_eeprom_read(sc, RT2573_EEPROM_ANTENNA, &val, 2);
val = le16toh(val);
@@ -1933,9 +1937,11 @@ rum_bbp_init(struct rum_softc *sc)
}
static void
-rum_init_locked(struct rum_softc *sc)
+rum_init_task(struct usb2_proc_msg *pm)
{
#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;
@@ -1944,10 +1950,7 @@ rum_init_locked(struct rum_softc *sc)
RUM_LOCK_ASSERT(sc, MA_OWNED);
- if (sc->sc_flags & RUM_FLAG_DETACH)
- return;
-
- rum_stop(sc);
+ rum_stop_task(pm);
/* initialize MAC registers to default values */
for (i = 0; i < N(rum_def_mac); i++)
@@ -1990,11 +1993,7 @@ rum_init_locked(struct rum_softc *sc)
/*
* Allocate Tx and Rx xfer queues.
*/
- error = rum_alloc_tx_list(sc);
- if (error != 0) {
- device_printf(sc->sc_dev, "could not allocate Tx list\n");
- goto fail;
- }
+ rum_setup_tx_list(sc);
/* update Rx filter */
tmp = rum_read(sc, RT2573_TXRX_CSR0) & 0xffff;
@@ -2015,7 +2014,7 @@ rum_init_locked(struct rum_softc *sc)
usb2_transfer_start(sc->sc_xfer[RUM_BULK_RD]);
return;
-fail: rum_stop(sc);
+fail: rum_stop_task(pm);
#undef N
}
@@ -2027,7 +2026,9 @@ rum_init(void *priv)
struct ieee80211com *ic = ifp->if_l2com;
RUM_LOCK(sc);
- rum_init_locked(sc);
+ rum_queue_command(sc, rum_init_task,
+ &sc->sc_synctask[0].hdr,
+ &sc->sc_synctask[1].hdr);
RUM_UNLOCK(sc);
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
@@ -2035,9 +2036,10 @@ rum_init(void *priv)
}
static void
-rum_stop(void *priv)
+rum_stop_task(struct usb2_proc_msg *pm)
{
- struct rum_softc *sc = priv;
+ struct rum_task *task = (struct rum_task *)pm;
+ struct rum_softc *sc = task->sc;
struct ifnet *ifp = sc->sc_ifp;
uint32_t tmp;
@@ -2045,17 +2047,17 @@ rum_stop(void *priv)
ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+ RUM_UNLOCK(sc);
+
/*
- * stop all the transfers, if not already stopped:
+ * Drain the USB transfers, if not already drained:
*/
- usb2_transfer_stop(sc->sc_xfer[RUM_BULK_WR]);
- usb2_transfer_stop(sc->sc_xfer[RUM_BULK_RD]);
+ usb2_transfer_drain(sc->sc_xfer[RUM_BULK_WR]);
+ usb2_transfer_drain(sc->sc_xfer[RUM_BULK_RD]);
- rum_free_tx_list(sc);
+ RUM_LOCK(sc);
- /* Stop now if the device has vanished */
- if (sc->sc_flags & RUM_FLAG_DETACH)
- return;
+ rum_unsetup_tx_list(sc);
/* disable Rx */
tmp = rum_read(sc, RT2573_TXRX_CSR0);
@@ -2083,7 +2085,7 @@ rum_load_microcode(struct rum_softc *sc,
USETW(req.wIndex, 0);
USETW(req.wLength, 0);
- error = usb2_do_request(sc->sc_udev, &sc->sc_mtx, &req, NULL);
+ error = rum_do_request(sc, &req, NULL);
if (error != 0) {
device_printf(sc->sc_dev, "could not run firmware: %s\n",
usb2_errstr(error));
@@ -2291,14 +2293,10 @@ rum_scantask(struct usb2_proc_msg *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);
uint32_t tmp;
RUM_LOCK_ASSERT(sc, MA_OWNED);
- if (sc->sc_flags & RUM_FLAG_DETACH)
- return;
-
switch (sc->sc_scan_action) {
case RUM_SCAN_START:
/* abort TSF synchronization */
@@ -2307,19 +2305,13 @@ rum_scantask(struct usb2_proc_msg *pm)
rum_set_bssid(sc, ifp->if_broadcastaddr);
break;
- case RUM_SCAN_END:
- rum_enable_tsf_sync(sc);
- /* XXX keep local copy */
- rum_set_bssid(sc, vap->iv_bss->ni_bssid);
- break;
-
case RUM_SET_CHANNEL:
rum_set_chan(sc, ic->ic_curchan);
break;
- default:
- panic("unknown scan action %d\n", sc->sc_scan_action);
- /* NEVER REACHED */
+ default: /* RUM_SCAN_END */
+ rum_enable_tsf_sync(sc);
+ rum_set_bssid(sc, sc->sc_bssid);
break;
}
}
@@ -2395,6 +2387,11 @@ rum_queue_command(struct rum_softc *sc,
task->hdr.pm_callback = fn;
task->sc = sc;
+ /*
+ * Init and stop must be synchronous!
+ */
+ if ((fn == rum_init_task) || (fn == rum_stop_task))
+ usb2_proc_mwait(&sc->sc_tq, t0, t1);
}
static device_method_t rum_methods[] = {
Modified: head/sys/dev/usb2/wlan/if_rumvar.h
==============================================================================
--- head/sys/dev/usb2/wlan/if_rumvar.h Mon Feb 9 22:14:38 2009 (r188418)
+++ head/sys/dev/usb2/wlan/if_rumvar.h Mon Feb 9 22:18:11 2009 (r188419)
@@ -100,14 +100,14 @@ struct rum_softc {
struct usb2_process sc_tq;
const struct ieee80211_rate_table *sc_rates;
+ struct usb2_xfer *sc_xfer[RUM_N_TRANSFER];
uint8_t rf_rev;
uint8_t rffreq;
- struct usb2_xfer *sc_xfer[RUM_N_TRANSFER];
-
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];
@@ -116,7 +116,7 @@ struct rum_softc {
#define RUM_SCAN_END 1
#define RUM_SET_CHANNEL 2
- struct rum_tx_data *tx_data;
+ struct rum_tx_data tx_data[RUM_TX_LIST_COUNT];
rum_txdhead tx_q;
rum_txdhead tx_free;
int tx_nfree;
@@ -124,12 +124,10 @@ struct rum_softc {
struct mtx sc_mtx;
- int sc_flags;
-#define RUM_FLAG_DETACH 0x0001
-
uint32_t sta[6];
uint32_t rf_regs[4];
uint8_t txpow[44];
+ uint8_t sc_bssid[6];
struct {
uint8_t val;
Modified: head/sys/dev/usb2/wlan/if_ural2.c
==============================================================================
--- head/sys/dev/usb2/wlan/if_ural2.c Mon Feb 9 22:14:38 2009 (r188418)
+++ head/sys/dev/usb2/wlan/if_ural2.c Mon Feb 9 22:18:11 2009 (r188419)
@@ -55,6 +55,9 @@ SYSCTL_INT(_hw_usb2_ural, OID_AUTO, debu
"Debug level");
#endif
+#define ural_do_request(sc,req,data) \
+ usb2_do_request_proc((sc)->sc_udev, &(sc)->sc_tq, req, data, 0, NULL, 5000)
+
#define URAL_RSSI(rssi) \
((rssi) > (RAL_NOISE_FLOOR + RAL_RSSI_CORR) ? \
((rssi) - (RAL_NOISE_FLOOR + RAL_RSSI_CORR)) : 0)
@@ -95,10 +98,13 @@ static const struct usb2_device_id ural_
static usb2_callback_t ural_bulk_read_callback;
static usb2_callback_t ural_bulk_write_callback;
+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 struct ieee80211vap *ural_vap_create(struct ieee80211com *,
const char name[IFNAMSIZ], int unit, int opmode,
@@ -106,8 +112,8 @@ static struct ieee80211vap *ural_vap_cre
const uint8_t mac[IEEE80211_ADDR_LEN]);
static void ural_vap_delete(struct ieee80211vap *);
static void ural_tx_free(struct ural_tx_data *, int);
-static int ural_alloc_tx_list(struct ural_softc *);
-static void ural_free_tx_list(struct ural_softc *);
+static void ural_setup_tx_list(struct ural_softc *);
+static void ural_unsetup_tx_list(struct ural_softc *);
static int ural_newstate(struct ieee80211vap *,
enum ieee80211_state, int);
static void ural_setup_tx_desc(struct ural_softc *,
@@ -153,9 +159,7 @@ static void ural_read_eeprom(struct ura
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(void *);
static int ural_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
static void ural_amrr_start(struct ural_softc *,
@@ -394,10 +398,8 @@ 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;
int error;
- uint8_t bands, iface_index;
+ uint8_t iface_index;
device_set_usb2_desc(self);
sc->sc_udev = uaa->device;
@@ -422,14 +424,28 @@ ural_attach(device_t self)
goto detach;
}
- ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(sc->sc_dev, "can not if_alloc()\n");
- goto detach;
- }
- ic = ifp->if_l2com;
-
+ /* 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);
@@ -440,6 +456,14 @@ ural_attach(device_t self)
device_printf(sc->sc_dev, "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;
+ }
+ ic = ifp->if_l2com;
+
ifp->if_softc = sc;
if_initname(ifp, "ural", device_get_unit(sc->sc_dev));
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
@@ -452,6 +476,7 @@ ural_attach(device_t self)
ic->ic_ifp = ifp;
ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
+ IEEE80211_ADDR_COPY(ic->ic_myaddr, sc->sc_bssid);
/* set device capabilities */
ic->ic_caps =
@@ -500,11 +525,7 @@ ural_attach(device_t self)
if (bootverbose)
ieee80211_announce(ic);
- return (0); /* success */
-
-detach:
- ural_detach(self);
- return (ENXIO); /* failure */
+ RAL_LOCK(sc);
}
static int
@@ -514,20 +535,24 @@ ural_detach(device_t self)
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic = ifp->if_l2com;
- RAL_LOCK(sc);
- sc->sc_flags |= URAL_FLAG_DETACH;
- ural_stop(sc);
- RAL_UNLOCK(sc);
+ /* wait for any post attach or other command to complete */
+ usb2_proc_drain(&sc->sc_tq);
- /* stop all USB transfers first */
+ /* 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);
+ ural_unsetup_tx_list(sc);
+ RAL_UNLOCK(sc);
+
if (ifp) {
bpfdetach(ifp);
ieee80211_ifdetach(ic);
if_free(ifp);
}
+
mtx_destroy(&sc->sc_mtx);
return (0);
@@ -575,11 +600,8 @@ static void
ural_vap_delete(struct ieee80211vap *vap)
{
struct ural_vap *uvp = URAL_VAP(vap);
- struct ural_softc *sc = uvp->sc;
- RAL_LOCK(sc);
- usb2_callout_stop(&uvp->amrr_ch);
- RAL_UNLOCK(sc);
+ usb2_callout_drain(&uvp->amrr_ch);
ieee80211_amrr_cleanup(&uvp->amrr);
ieee80211_vap_detach(vap);
free(uvp, M_80211_VAP);
@@ -604,17 +626,12 @@ ural_tx_free(struct ural_tx_data *data,
sc->tx_nfree++;
}
-static int
-ural_alloc_tx_list(struct ural_softc *sc)
+static void
+ural_setup_tx_list(struct ural_softc *sc)
{
struct ural_tx_data *data;
int i;
- sc->tx_data = malloc(sizeof(struct ural_tx_data) * RAL_TX_LIST_COUNT,
- M_USB, M_NOWAIT|M_ZERO);
- if (sc->tx_data == NULL)
- return (ENOMEM);
-
sc->tx_nfree = 0;
STAILQ_INIT(&sc->tx_q);
STAILQ_INIT(&sc->tx_free);
@@ -626,18 +643,20 @@ ural_alloc_tx_list(struct ural_softc *sc
STAILQ_INSERT_TAIL(&sc->tx_free, data, next);
sc->tx_nfree++;
}
- return 0;
}
static void
-ural_free_tx_list(struct ural_softc *sc)
+ural_unsetup_tx_list(struct ural_softc *sc)
{
struct ural_tx_data *data;
int i;
- if (sc->tx_data == NULL)
- return;
+ /* make sure any subsequent use of the queues will fail */
+ sc->tx_nfree = 0;
+ STAILQ_INIT(&sc->tx_q);
+ STAILQ_INIT(&sc->tx_free);
+ /* free up all node references and mbufs */
for (i = 0; i < RAL_TX_LIST_COUNT; i++) {
data = &sc->tx_data[i];
@@ -650,8 +669,6 @@ ural_free_tx_list(struct ural_softc *sc)
data->ni = NULL;
}
}
- free(sc->tx_data, M_USB);
- sc->tx_data = NULL;
}
static void
@@ -668,9 +685,6 @@ ural_task(struct usb2_proc_msg *pm)
struct ieee80211_node *ni;
struct mbuf *m;
- if (sc->sc_flags & URAL_FLAG_DETACH)
- return;
-
ostate = vap->iv_state;
switch (sc->sc_state) {
@@ -691,7 +705,8 @@ ural_task(struct usb2_proc_msg *pm)
ural_update_slot(ic->ic_ifp);
ural_set_txpreamble(sc);
ural_set_basicrates(sc, ic->ic_bsschan);
- ural_set_bssid(sc, ni->ni_bssid);
+ IEEE80211_ADDR_COPY(sc->sc_bssid, ni->ni_bssid);
+ ural_set_bssid(sc, sc->sc_bssid);
}
if (vap->iv_opmode == IEEE80211_M_HOSTAP ||
@@ -743,26 +758,27 @@ ural_scantask(struct usb2_proc_msg *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);
RAL_LOCK_ASSERT(sc, MA_OWNED);
- if (sc->sc_flags & URAL_FLAG_DETACH)
- return;
-
- if (sc->sc_scan_action == URAL_SCAN_START) {
+ 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);
- } else if (sc->sc_scan_action == URAL_SET_CHANNEL) {
+ break;
+
+ case URAL_SET_CHANNEL:
ural_set_chan(sc, ic->ic_curchan);
- } else {
+ break;
+
+ default: /* URAL_SCAN_END */
DPRINTF("stopping scan\n");
ural_enable_tsf_sync(sc);
- /* XXX keep local copy */
- ural_set_bssid(sc, vap->iv_bss->ni_bssid);
- }
+ ural_set_bssid(sc, sc->sc_bssid);
+ break;
+ }
}
static int
@@ -806,7 +822,7 @@ ural_bulk_write_callback(struct usb2_xfe
struct ieee80211_channel *c = ic->ic_curchan;
struct ural_tx_data *data;
struct mbuf *m;
- int len;
+ unsigned int len;
switch (USB_GET_STATE(xfer)) {
case USB_ST_TRANSFERRED:
@@ -823,15 +839,6 @@ ural_bulk_write_callback(struct usb2_xfe
/* FALLTHROUGH */
case USB_ST_SETUP:
tr_setup:
-#if 0
- if (sc->sc_flags & URAL_FLAG_WAIT_COMMAND) {
- /*
- * don't send anything while a command is pending !
- */
- break;
- }
-#endif
-
data = STAILQ_FIRST(&sc->tx_q);
if (data) {
STAILQ_REMOVE_HEAD(&sc->tx_q, next);
@@ -878,6 +885,13 @@ tr_setup:
DPRINTFN(11, "transfer error, %s\n",
usb2_errstr(xfer->error));
+ ifp->if_oerrors++;
+ data = xfer->priv_fifo;
+ if (data != NULL) {
+ ural_tx_free(data, xfer->error);
+ xfer->priv_fifo = NULL;
+ }
+
if (xfer->error == USB_ERR_STALLED) {
/* try to clear stall first */
xfer->flags.stall_pipe = 1;
@@ -885,13 +899,6 @@ tr_setup:
}
if (xfer->error == USB_ERR_TIMEOUT)
device_printf(sc->sc_dev, "device timeout\n");
-
- ifp->if_oerrors++;
- data = xfer->priv_fifo;
- if (data != NULL) {
- ural_tx_free(data, xfer->error);
- xfer->priv_fifo = NULL;
- }
break;
}
}
@@ -906,7 +913,7 @@ ural_bulk_read_callback(struct usb2_xfer
struct mbuf *m = NULL;
uint32_t flags;
uint8_t rssi = 0;
- int len;
+ unsigned int len;
switch (USB_GET_STATE(xfer)) {
case USB_ST_TRANSFERRED:
@@ -1001,7 +1008,6 @@ tr_setup:
goto tr_setup;
}
return;
-
}
}
@@ -1406,15 +1412,20 @@ ural_ioctl(struct ifnet *ifp, u_long cmd
RAL_LOCK(sc);
if (ifp->if_flags & IFF_UP) {
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
- ural_init_locked(sc);
+ ural_queue_command(sc, ural_init_task,
+ &sc->sc_synctask[0].hdr,
+ &sc->sc_synctask[1].hdr);
startall = 1;
} else
ural_queue_command(sc, ural_promisctask,
&sc->sc_promisctask[0].hdr,
&sc->sc_promisctask[1].hdr);
} else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- ural_stop(sc);
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-all
mailing list