From owner-svn-src-all@FreeBSD.ORG Mon May 5 08:12:21 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id CBC45333; Mon, 5 May 2014 08:12:21 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 9FFA61CA7; Mon, 5 May 2014 08:12:21 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s458CLSv054609; Mon, 5 May 2014 08:12:21 GMT (envelope-from adrian@svn.freebsd.org) Received: (from adrian@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s458CLXZ054608; Mon, 5 May 2014 08:12:21 GMT (envelope-from adrian@svn.freebsd.org) Message-Id: <201405050812.s458CLXZ054608@svn.freebsd.org> From: Adrian Chadd Date: Mon, 5 May 2014 08:12:21 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r265350 - head/sys/dev/ath X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 05 May 2014 08:12:21 -0000 Author: adrian Date: Mon May 5 08:12:21 2014 New Revision: 265350 URL: http://svnweb.freebsd.org/changeset/base/265350 Log: Break out the multicast programming into its own hardware specific call, which assumes the hardware is awake. Turn ath_update_mcast() into a routine that's only called from the net80211 layer - and it forces the hardware awake first. This fixes a LOR from the EDMA RX path which calls ath_mode_init() with the RX lock held - the driver lock can't also be grabbed. This path assumes that the ath_mode_init() callers all wake up the NIC first. Tested: * AR9485, STA mode, powersave Modified: head/sys/dev/ath/if_ath.c Modified: head/sys/dev/ath/if_ath.c ============================================================================== --- head/sys/dev/ath/if_ath.c Mon May 5 08:00:50 2014 (r265349) +++ head/sys/dev/ath/if_ath.c Mon May 5 08:12:21 2014 (r265350) @@ -165,6 +165,7 @@ static void ath_bmiss_vap(struct ieee802 static void ath_bmiss_proc(void *, int); static void ath_key_update_begin(struct ieee80211vap *); static void ath_key_update_end(struct ieee80211vap *); +static void ath_update_mcast_hw(struct ath_softc *); static void ath_update_mcast(struct ifnet *); static void ath_update_promisc(struct ifnet *); static void ath_updateslot(struct ifnet *); @@ -3379,10 +3380,15 @@ ath_update_promisc(struct ifnet *ifp) DPRINTF(sc, ATH_DEBUG_MODE, "%s: RX filter 0x%x\n", __func__, rfilt); } +/* + * Driver-internal mcast update call. + * + * Assumes the hardware is already awake. + */ static void -ath_update_mcast(struct ifnet *ifp) +ath_update_mcast_hw(struct ath_softc *sc) { - struct ath_softc *sc = ifp->if_softc; + struct ifnet *ifp = sc->sc_ifp; u_int32_t mfilt[2]; /* calculate and install multicast filter */ @@ -3410,13 +3416,31 @@ ath_update_mcast(struct ifnet *ifp) if_maddr_runlock(ifp); } else mfilt[0] = mfilt[1] = ~0; + + ath_hal_setmcastfilter(sc->sc_ah, mfilt[0], mfilt[1]); + + DPRINTF(sc, ATH_DEBUG_MODE, "%s: MC filter %08x:%08x\n", + __func__, mfilt[0], mfilt[1]); +} + +/* + * Called from the net80211 layer - force the hardware + * awake before operating. + */ +static void +ath_update_mcast(struct ifnet *ifp) +{ + struct ath_softc *sc = ifp->if_softc; + ATH_LOCK(sc); ath_power_set_power_state(sc, HAL_PM_AWAKE); - ath_hal_setmcastfilter(sc->sc_ah, mfilt[0], mfilt[1]); + ATH_UNLOCK(sc); + + ath_update_mcast_hw(sc); + + ATH_LOCK(sc); ath_power_restore_power_state(sc); ATH_UNLOCK(sc); - DPRINTF(sc, ATH_DEBUG_MODE, "%s: MC filter %08x:%08x\n", - __func__, mfilt[0], mfilt[1]); } void @@ -3444,7 +3468,7 @@ ath_mode_init(struct ath_softc *sc) ath_hal_setmac(ah, IF_LLADDR(ifp)); /* calculate and install multicast filter */ - ath_update_mcast(ifp); + ath_update_mcast_hw(sc); } /*