From owner-p4-projects@FreeBSD.ORG Sun Dec 7 15:56:55 2003 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id E98EE16A4D6; Sun, 7 Dec 2003 15:56:54 -0800 (PST) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 76A6316A4E7 for ; Sun, 7 Dec 2003 15:56:54 -0800 (PST) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 28E4443F3F for ; Sun, 7 Dec 2003 15:56:52 -0800 (PST) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.9/8.12.9) with ESMTP id hB7NuqXJ011481 for ; Sun, 7 Dec 2003 15:56:52 -0800 (PST) (envelope-from sam@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.9/8.12.9/Submit) id hB7NupSc011478 for perforce@freebsd.org; Sun, 7 Dec 2003 15:56:51 -0800 (PST) (envelope-from sam@freebsd.org) Date: Sun, 7 Dec 2003 15:56:51 -0800 (PST) Message-Id: <200312072356.hB7NupSc011478@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to sam@freebsd.org using -f From: Sam Leffler To: Perforce Change Reviews Subject: PERFORCE change 43591 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 07 Dec 2003 23:56:55 -0000 http://perforce.freebsd.org/chv.cgi?CH=43591 Change 43591 by sam@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",