From owner-p4-projects@FreeBSD.ORG Sun Oct 24 05:36:42 2004 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 4D68016A4D0; Sun, 24 Oct 2004 05:36:42 +0000 (GMT) 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 296D516A4CE for ; Sun, 24 Oct 2004 05:36:42 +0000 (GMT) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 08E4743D48 for ; Sun, 24 Oct 2004 05:36:42 +0000 (GMT) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.11/8.12.11) with ESMTP id i9O5afCj067962 for ; Sun, 24 Oct 2004 05:36:41 GMT (envelope-from sam@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.11/8.12.11/Submit) id i9O5afJs067959 for perforce@freebsd.org; Sun, 24 Oct 2004 05:36:41 GMT (envelope-from sam@freebsd.org) Date: Sun, 24 Oct 2004 05:36:41 GMT Message-Id: <200410240536.i9O5afJs067959@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 63621 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, 24 Oct 2004 05:36:43 -0000 http://perforce.freebsd.org/chv.cgi?CH=63621 Change 63621 by sam@sam_ebb on 2004/10/24 05:36:39 o put the chip in full sleep only when suspending, detaching, or otherwise bringing the device to a complete stop (e.g. not when changing channels); this fixes a race condition where the chip might be put to sleep then immediately followed by a read of a register in the PCI clock domain--which would lock the bus o improve radio revision printing; only display radio rev when the hardware is really there and print an unadorned rev when the radio is multi-band o move the WME<->h/w tx queue mapping prints to bootverbose Affected files ... .. //depot/projects/wifi/sys/dev/ath/if_ath.c#3 edit Differences ... ==== //depot/projects/wifi/sys/dev/ath/if_ath.c#3 (text+ko) ==== @@ -94,6 +94,7 @@ (((u_int8_t *)(p))[2] << 16) | (((u_int8_t *)(p))[3] << 24))) static void ath_init(void *); +static void ath_stop_locked(struct ifnet *); static void ath_stop(struct ifnet *); static void ath_start(struct ifnet *); static int ath_reset(struct ifnet *); @@ -778,7 +779,7 @@ * Stop anything previously setup. This is safe * whether this is the first time through or not. */ - ath_stop(ifp); + ath_stop_locked(ifp); /* * The basic interface to setting the hardware in a good @@ -845,7 +846,7 @@ } static void -ath_stop(struct ifnet *ifp) +ath_stop_locked(struct ifnet *ifp) { struct ath_softc *sc = ifp->if_softc; struct ieee80211com *ic = &sc->sc_ic; @@ -854,7 +855,7 @@ DPRINTF(sc, ATH_DEBUG_ANY, "%s: invalid %u if_flags 0x%x\n", __func__, sc->sc_invalid, ifp->if_flags); - ATH_LOCK(sc); + ATH_LOCK_ASSERT(sc); if (ifp->if_flags & IFF_RUNNING) { /* * Shutdown the hardware and driver: @@ -887,8 +888,27 @@ sc->sc_rxlink = NULL; IFQ_DRV_PURGE(&ifp->if_snd); ath_beacon_free(sc); - if (!sc->sc_invalid) - ath_hal_setpower(ah, HAL_PM_FULL_SLEEP, 0); + } +} + +static void +ath_stop(struct ifnet *ifp) +{ + struct ath_softc *sc = ifp->if_softc; + + ATH_LOCK(sc); + ath_stop_locked(ifp); + if (!sc->sc_invalid) { + /* + * Set the chip in full sleep mode. Note that we are + * careful to do this only when bringing the interface + * completely to a stop. When the chip is in this state + * it must be carefully woken up or references to + * registers in the PCI clock domain may freeze the bus + * (and system). This varies by chip and is mostly an + * issue with newer parts that go to sleep more quickly. + */ + ath_hal_setpower(sc->sc_ah, HAL_PM_FULL_SLEEP, 0); } ATH_UNLOCK(sc); } @@ -3775,7 +3795,7 @@ if (!sc->sc_invalid) ath_init(ifp); /* XXX lose error */ } else - ath_stop(ifp); + ath_stop_locked(ifp); break; case SIOCADDMULTI: case SIOCDELMULTI: @@ -3988,23 +4008,42 @@ static void ath_announce(struct ath_softc *sc) { +#define HAL_MODE_DUALBAND (HAL_MODE_11A|HAL_MODE_11B) struct ifnet *ifp = &sc->sc_if; struct ath_hal *ah = sc->sc_ah; - int i; + u_int modes, cc; if_printf(ifp, "mac %d.%d phy %d.%d", ah->ah_macVersion, ah->ah_macRev, ah->ah_phyRev >> 4, ah->ah_phyRev & 0xf); - if (ah->ah_analog5GhzRev) - printf(" 5ghz radio %d.%d", - ah->ah_analog5GhzRev >> 4, ah->ah_analog5GhzRev & 0xf); - if (ah->ah_analog2GhzRev) - printf(" 2ghz radio %d.%d", - ah->ah_analog2GhzRev >> 4, ah->ah_analog2GhzRev & 0xf); + /* + * Print radio revision(s). We check the wireless modes + * to avoid falsely printing revs for inoperable parts. + * Dual-band radio revs are returned in the 5Ghz rev number. + */ + ath_hal_getcountrycode(ah, &cc); + modes = ath_hal_getwirelessmodes(ah, cc); + if ((modes & HAL_MODE_DUALBAND) == HAL_MODE_DUALBAND) { + if (ah->ah_analog5GhzRev && ah->ah_analog2GhzRev) + printf(" 5ghz radio %d.%d 2ghz radio %d.%d", + ah->ah_analog5GhzRev >> 4, + ah->ah_analog5GhzRev & 0xf, + ah->ah_analog2GhzRev >> 4, + ah->ah_analog2GhzRev & 0xf); + else + printf(" radio %d.%d", ah->ah_analog5GhzRev >> 4, + ah->ah_analog5GhzRev & 0xf); + } else + printf(" radio %d.%d", ah->ah_analog5GhzRev >> 4, + ah->ah_analog5GhzRev & 0xf); printf("\n"); - for (i = 0; i <= WME_AC_VO; i++) { - struct ath_txq *txq = sc->sc_ac2q[i]; - if_printf(ifp, "Use hw queue %u for %s traffic\n", - txq->axq_qnum, acnames[i]); + if (bootverbose) { + int i; + for (i = 0; i <= WME_AC_VO; i++) { + struct ath_txq *txq = sc->sc_ac2q[i]; + if_printf(ifp, "Use hw queue %u for %s traffic\n", + txq->axq_qnum, acnames[i]); + } } +#undef HAL_MODE_DUALBAND }