From owner-svn-src-all@FreeBSD.ORG Sat Aug 23 18:55:52 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 C6C91EA9; Sat, 23 Aug 2014 18:55:52 +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 B1D1A3200; Sat, 23 Aug 2014 18:55:52 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id s7NItqRn082674; Sat, 23 Aug 2014 18:55:52 GMT (envelope-from adrian@FreeBSD.org) Received: (from adrian@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id s7NItqOM082671; Sat, 23 Aug 2014 18:55:52 GMT (envelope-from adrian@FreeBSD.org) Message-Id: <201408231855.s7NItqOM082671@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: adrian set sender to adrian@FreeBSD.org using -f From: Adrian Chadd Date: Sat, 23 Aug 2014 18:55:52 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r270430 - 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-1 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: Sat, 23 Aug 2014 18:55:53 -0000 Author: adrian Date: Sat Aug 23 18:55:51 2014 New Revision: 270430 URL: http://svnweb.freebsd.org/changeset/base/270430 Log: Shut down RX before TX - in theory, this should make the chip less likely to get upset. The Qualcomm Atheros reference design code goes through significant hacks to shut down RX before TX. It doesn't even try do do it in the driver - it actually makes the DMA stop routines in the HAL shut down RX before shutting down TX. So, to make this work for chips that aren't the AR9380 and later, do it in the driver. Shuffle the TX stop/drain HAL calls to be called *after* the RX stop HAL call. Tested: * AR5413 (STA) * AR5212 (STA) * AR5416 (STA) * AR9380 (STA) * AR9331 (AP) * AR9341 (AP) TODO: * test ar92xx series NIC and the AR5210/AR5211, in case there's something even odder about those. Modified: head/sys/dev/ath/if_ath.c head/sys/dev/ath/if_ath_beacon.c Modified: head/sys/dev/ath/if_ath.c ============================================================================== --- head/sys/dev/ath/if_ath.c Sat Aug 23 18:11:54 2014 (r270429) +++ head/sys/dev/ath/if_ath.c Sat Aug 23 18:55:51 2014 (r270430) @@ -1599,9 +1599,9 @@ ath_vap_delete(struct ieee80211vap *vap) * the vap state by any frames pending on the tx queues. */ ath_hal_intrset(ah, 0); /* disable interrupts */ - ath_draintxq(sc, ATH_RESET_DEFAULT); /* stop hw xmit side */ /* XXX Do all frames from all vaps/nodes need draining here? */ ath_stoprecv(sc, 1); /* stop recv side */ + ath_draintxq(sc, ATH_RESET_DEFAULT); /* stop hw xmit side */ } /* .. leave the hardware awake for now. */ @@ -2503,12 +2503,13 @@ ath_stop_locked(struct ifnet *ifp) } ath_hal_intrset(ah, 0); } - ath_draintxq(sc, ATH_RESET_DEFAULT); + /* XXX we should stop RX regardless of whether it's valid */ if (!sc->sc_invalid) { ath_stoprecv(sc, 1); ath_hal_phydisable(ah); } else sc->sc_rxlink = NULL; + ath_draintxq(sc, ATH_RESET_DEFAULT); ath_beacon_free(sc); /* XXX not needed */ } @@ -2710,13 +2711,6 @@ ath_reset(struct ifnet *ifp, ATH_RESET_T ATH_PCU_UNLOCK(sc); /* - * Should now wait for pending TX/RX to complete - * and block future ones from occuring. This needs to be - * done before the TX queue is drained. - */ - ath_draintxq(sc, reset_type); /* stop xmit side */ - - /* * Regardless of whether we're doing a no-loss flush or * not, stop the PCU and handle what's in the RX queue. * That way frames aren't dropped which shouldn't be. @@ -2724,6 +2718,13 @@ ath_reset(struct ifnet *ifp, ATH_RESET_T ath_stoprecv(sc, (reset_type != ATH_RESET_NOLOSS)); ath_rx_flush(sc); + /* + * Should now wait for pending TX/RX to complete + * and block future ones from occuring. This needs to be + * done before the TX queue is drained. + */ + ath_draintxq(sc, reset_type); /* stop xmit side */ + ath_settkipmic(sc); /* configure TKIP MIC handling */ /* NB: indicate channel change so we do a full reset */ ath_update_chainmasks(sc, ic->ic_curchan); Modified: head/sys/dev/ath/if_ath_beacon.c ============================================================================== --- head/sys/dev/ath/if_ath_beacon.c Sat Aug 23 18:11:54 2014 (r270429) +++ head/sys/dev/ath/if_ath_beacon.c Sat Aug 23 18:55:51 2014 (r270430) @@ -749,6 +749,11 @@ ath_beacon_generate(struct ath_softc *sc * * More thought is required here. */ + /* + * XXX can we even stop TX DMA here? Check what the + * reference driver does for cabq for beacons, given + * that stopping TX requires RX is paused. + */ ath_tx_draintxq(sc, cabq); } }