PERFORCE change 43591 for review
Sam Leffler
sam at FreeBSD.org
Sun Dec 7 15:56:55 PST 2003
http://perforce.freebsd.org/chv.cgi?CH=43591
Change 43591 by sam at sam_ebb on 2003/12/07 15:55:58
call ath_reset instead of ath_init on ioctl calls to avoid
stirring the 802.11 state machine; this is unfinished, we need
to get the 802.11 code to inform us when a rescan is needed
(or have it start it itself)
Affected files ...
.. //depot/projects/netperf/sys/dev/ath/if_ath.c#46 edit
Differences ...
==== //depot/projects/netperf/sys/dev/ath/if_ath.c#46 (text+ko) ====
@@ -95,7 +95,7 @@
static void ath_init(void *);
static void ath_stop(struct ifnet *);
static void ath_start(struct ifnet *);
-static void ath_reset(struct ath_softc *);
+static void ath_reset(struct ath_softc *, int);
static int ath_media_change(struct ifnet *);
static void ath_watchdog(struct ifnet *);
static int ath_ioctl(struct ifnet *, u_long, caddr_t);
@@ -471,7 +471,7 @@
struct ath_softc *sc = arg;
device_printf(sc->sc_dev, "hardware error; resetting\n");
- ath_reset(sc);
+ ath_reset(sc, 0);
}
static void
@@ -480,7 +480,7 @@
struct ath_softc *sc = arg;
device_printf(sc->sc_dev, "rx FIFO overrun; resetting\n");
- ath_reset(sc);
+ ath_reset(sc, 0);
}
static void
@@ -647,7 +647,7 @@
* and to reset the hardware when rf gain settings must be reset.
*/
static void
-ath_reset(struct ath_softc *sc)
+ath_reset(struct ath_softc *sc, int full)
{
struct ieee80211com *ic = &sc->sc_ic;
struct ifnet *ifp = &ic->ic_if;
@@ -671,6 +671,9 @@
if (!ath_hal_reset(ah, ic->ic_opmode, &hchan, AH_TRUE, &status))
if_printf(ifp, "%s: unable to reset hardware; hal status %u\n",
__func__, status);
+ /* NB: only needed when called from ath_ioctl */
+ if (full && (ic->ic_flags & IEEE80211_F_WEPON))
+ ath_initkeytable(sc);
ath_hal_intrset(ah, sc->sc_imask);
if (ath_startrecv(sc) != 0) /* restart recv */
if_printf(ifp, "%s: unable to start recv logic\n", __func__);
@@ -822,7 +825,7 @@
if (ath_debug)
ath_hal_dumpstate(sc->sc_ah);
#endif /* AR_DEBUG */
- ath_init(ifp); /* XXX ath_reset??? */
+ ath_reset(sc, 0);
ifp->if_oerrors++;
sc->sc_stats.ast_watchdog++;
return;
@@ -845,6 +848,8 @@
static int
ath_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
{
+#define UP_RUNNING(_ifp) \
+ (((_ifp)->if_flags & (IFF_UP|IFF_RUNNING)) == (IFF_UP|IFF_RUNNING))
struct ath_softc *sc = ifp->if_softc;
struct ifreq *ifr = (struct ifreq *)data;
int error = 0;
@@ -852,29 +857,31 @@
ATH_LOCK(sc);
switch (cmd) {
case SIOCSIFFLAGS:
- if (ifp->if_flags & IFF_UP) {
- if (ifp->if_flags & IFF_RUNNING) {
- /*
- * To avoid rescanning another access point,
- * do not call ath_init() here. Instead,
- * only reflect promisc mode settings.
- */
- ath_mode_init(sc);
- } else {
- /*
- * Beware of being called during detach to
- * reset promiscuous mode. In that case we
- * will still be marked UP but not RUNNING.
- * However trying to re-init the interface
- * is the wrong thing to do as we've already
- * torn down much of our state. There's
- * probably a better way to deal with this.
- */
- if (!sc->sc_invalid)
- ath_init(ifp); /* XXX lose error */
- }
- } else
+ if (UP_RUNNING(ifp)) {
+ /*
+ * To avoid rescanning another access point,
+ * do not call ath_init() here. Instead,
+ * only reflect promisc mode settings.
+ */
+ ath_mode_init(sc);
+ } else if (ifp->if_flags & IFF_UP) {
+ /*
+ * Beware of being called during detach to
+ * reset promiscuous mode. In that case we
+ * will still be marked UP but not RUNNING.
+ * However trying to re-init the interface
+ * is the wrong thing to do as we've already
+ * torn down much of our state. There's
+ * probably a better way to deal with this.
+ */
+ if (!sc->sc_invalid)
+ ath_init(ifp); /* XXX lose error */
+ } else {
+ /*
+ * Interface marked down; clear the hardware.
+ */
ath_stop(ifp);
+ }
break;
case SIOCADDMULTI:
case SIOCDELMULTI:
@@ -908,9 +915,20 @@
default:
error = ieee80211_ioctl(ifp, cmd, data);
if (error == ENETRESET) {
- if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) ==
- (IFF_RUNNING|IFF_UP))
- ath_init(ifp); /* XXX lose error */
+ /*
+ * If the interface is up and running then we
+ * want the parameter changes to take effect
+ * immediately, so reset hardware state to
+ * reflect parameter change(s). We don't try to
+ * intuit exactly what changed here; we just
+ * bludgeon state which can have unfortunate
+ * side effects.
+ *
+ * XXX doesn't recognize when a rescan is needed;
+ * e.g. for ssid or channel change
+ */
+ if (UP_RUNNING(ifp))
+ ath_reset(sc, 1);
error = 0;
}
break;
@@ -2448,7 +2466,7 @@
* to load new gain values.
*/
sc->sc_stats.ast_per_rfgain++;
- ath_reset(sc);
+ ath_reset(sc, 0);
}
if (!ath_hal_calibrate(ah, &hchan)) {
DPRINTF(("%s: calibration of channel %u failed\n",
More information about the p4-projects
mailing list