Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/usb some more urtwn fixes:
details: https://anonhg.NetBSD.org/src/rev/6ce29919babe
branches: trunk
changeset: 784204:6ce29919babe
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Mon Jan 21 23:42:45 2013 +0000
description:
some more urtwn fixes:
- support manual roaming (used by wpa_supplicant)
- simplify ioctl handler
- add our own reset callback
- acquire KERNEL_LOCK before using net80211 or the network stack
- clear IFF_OACTIVE even in the event of an endpoint stall
diffstat:
sys/dev/usb/if_urtwn.c | 90 ++++++++++++++++++++++++++-----------------------
1 files changed, 48 insertions(+), 42 deletions(-)
diffs (223 lines):
diff -r c0340f2e95f3 -r 6ce29919babe sys/dev/usb/if_urtwn.c
--- a/sys/dev/usb/if_urtwn.c Mon Jan 21 21:38:02 2013 +0000
+++ b/sys/dev/usb/if_urtwn.c Mon Jan 21 23:42:45 2013 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_urtwn.c,v 1.15 2013/01/21 16:52:56 christos Exp $ */
+/* $NetBSD: if_urtwn.c,v 1.16 2013/01/21 23:42:45 jmcneill Exp $ */
/* $OpenBSD: if_urtwn.c,v 1.20 2011/11/26 06:39:33 ckuethe Exp $ */
/*-
@@ -22,7 +22,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_urtwn.c,v 1.15 2013/01/21 16:52:56 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_urtwn.c,v 1.16 2013/01/21 23:42:45 jmcneill Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -243,6 +243,7 @@
static void urtwn_temp_calib(struct urtwn_softc *);
static int urtwn_init(struct ifnet *);
static void urtwn_stop(struct ifnet *, int);
+static int urtwn_reset(struct ifnet *);
static void urtwn_chip_stop(struct urtwn_softc *);
/* Aliases. */
@@ -378,7 +379,9 @@
if_attach(ifp);
ieee80211_ifattach(ic);
+
/* override default methods */
+ ic->ic_reset = urtwn_reset;
ic->ic_wme.wme_update = urtwn_wme_update;
/* Override state transition machine. */
@@ -685,8 +688,10 @@
cmd = &ring->cmd[ring->next];
mutex_spin_exit(&sc->sc_task_mtx);
splx(s);
- /* Invoke callback. */
+ /* Invoke callback with kernel lock held. */
+ KERNEL_LOCK(1, curlwp);
cmd->cb(sc, cmd->data);
+ KERNEL_UNLOCK_ONE(curlwp);
s = splusb();
mutex_spin_enter(&sc->sc_task_mtx);
ring->queued--;
@@ -1475,14 +1480,17 @@
urtwn_next_scan(void *arg)
{
struct urtwn_softc *sc = arg;
+ int s;
DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
if (sc->sc_dying)
return;
+ s = splnet();
if (sc->sc_ic.ic_state == IEEE80211_S_SCAN)
ieee80211_next_scan(&sc->sc_ic);
+ splx(s);
}
static int
@@ -2072,7 +2080,9 @@
}
/* Process 802.11 frame. */
+ KERNEL_LOCK(1, curlwp);
urtwn_rx_frame(sc, buf, pktlen);
+ KERNEL_UNLOCK_ONE(curlwp);
/* Next chunk is 128-byte aligned. */
totlen = roundup2(totlen, 128);
@@ -2103,23 +2113,26 @@
TAILQ_INSERT_TAIL(&sc->tx_free_list, data, next);
mutex_exit(&sc->sc_tx_mtx);
+ s = splnet();
+ sc->tx_timer = 0;
+ ifp->if_flags &= ~IFF_OACTIVE;
+ ifp->if_opackets++;
+
if (__predict_false(status != USBD_NORMAL_COMPLETION)) {
if (status != USBD_NOT_STARTED && status != USBD_CANCELLED) {
if (status == USBD_STALLED)
usbd_clear_endpoint_stall_async(data->pipe);
ifp->if_oerrors++;
}
+ splx(s);
return;
}
- ifp->if_opackets++;
-
- s = splnet();
- sc->tx_timer = 0;
- ifp->if_flags &= ~IFF_OACTIVE;
+ KERNEL_LOCK(1, curlwp);
+ urtwn_start(ifp);
+ KERNEL_UNLOCK_ONE(curlwp);
+
splx(s);
-
- urtwn_start(ifp);
}
static int
@@ -2415,7 +2428,6 @@
{
struct urtwn_softc *sc = ifp->if_softc;
struct ieee80211com *ic = &sc->sc_ic;
- struct ifaddr *ifa;
int s, error = 0;
DPRINTFN(DBG_FN, ("%s: %s: cmd=0x%08lx, data=%p\n",
@@ -2424,14 +2436,6 @@
s = splnet();
switch (cmd) {
- case SIOCSIFADDR:
- ifa = (struct ifaddr *)data;
- ifp->if_flags |= IFF_UP;
-#ifdef INET
- if (ifa->ifa_addr->sa_family == AF_INET)
- arp_ifinit(ifp, ifa);
-#endif
- /*FALLTHROUGH*/
case SIOCSIFFLAGS:
if ((error = ifioctl_common(ifp, cmd, data)) != 0)
break;
@@ -2457,28 +2461,14 @@
}
break;
- case SIOCS80211CHANNEL:
- error = ieee80211_ioctl(ic, cmd, data);
- if (error == ENETRESET &&
- ic->ic_opmode == IEEE80211_M_MONITOR) {
- if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
- (IFF_UP | IFF_RUNNING)) {
- mutex_enter(&sc->sc_write_mtx);
- urtwn_set_chan(sc, ic->ic_curchan,
- IEEE80211_HTINFO_2NDCHAN_NONE);
- mutex_exit(&sc->sc_write_mtx);
- }
- error = 0;
- }
- break;
-
default:
error = ieee80211_ioctl(ic, cmd, data);
break;
}
if (error == ENETRESET) {
if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
- (IFF_UP | IFF_RUNNING)) {
+ (IFF_UP | IFF_RUNNING) &&
+ ic->ic_roaming != IEEE80211_ROAMING_MANUAL) {
urtwn_init(ifp);
}
error = 0;
@@ -3805,12 +3795,14 @@
ifp->if_flags &= ~IFF_OACTIVE;
ifp->if_flags |= IFF_RUNNING;
+ mutex_exit(&sc->sc_write_mtx);
+
if (ic->ic_opmode == IEEE80211_M_MONITOR)
ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
- else
+ else if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL)
ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
-
- mutex_exit(&sc->sc_write_mtx);
+ urtwn_wait_async(sc);
+
return (0);
fail:
@@ -3829,15 +3821,15 @@
DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
- sc->tx_timer = 0;
- ifp->if_timer = 0;
- ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
-
s = splusb();
ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
urtwn_wait_async(sc);
splx(s);
+ sc->tx_timer = 0;
+ ifp->if_timer = 0;
+ ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
+
callout_stop(&sc->sc_scan_to);
callout_stop(&sc->sc_calib_to);
@@ -3858,6 +3850,20 @@
urtwn_chip_stop(sc);
}
+static int
+urtwn_reset(struct ifnet *ifp)
+{
+ struct urtwn_softc *sc = ifp->if_softc;
+ struct ieee80211com *ic = &sc->sc_ic;
+
+ if (ic->ic_opmode != IEEE80211_M_MONITOR)
+ return ENETRESET;
+
+ urtwn_set_chan(sc, ic->ic_curchan, IEEE80211_HTINFO_2NDCHAN_NONE);
+
+ return 0;
+}
+
static void
urtwn_chip_stop(struct urtwn_softc *sc)
{
Home |
Main Index |
Thread Index |
Old Index