Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 9 Aug 2014 09:12:25 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r269748 - head/sys/contrib/dev/ath/ath_hal/ar9300
Message-ID:  <53e5e5f9.2eeb.7727ac5c@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Sat Aug  9 09:12:25 2014
New Revision: 269748
URL: http://svnweb.freebsd.org/changeset/base/269748

Log:
  Work around some rather annoying chip hangs in the AR9331 chip.
  
  If powersave is enabled and there are any transitions to network
  or full sleep - even if they're pretty damned brief - eventually
  something messes up somewhere and the bus glue between the AR9331
  SoC and the AR9331 wifi stops working.  It shows up as stuck DMA
  and LOCAL_TIMEOUT interrupts.
  
  Both ath9k and the reference driver does a full chip reset if things
  get stuck.
  
  So:
  
  * teach the AR9330 HAL about the force_full_reset option I added a
    couple of years ago;
  * if the chip is currently in full-sleep, do a full-reset;
  * if TX DMA and/or RX DMA are still enabled (eg, they did get
    stuck during reset) then do a full-reset.
  
  Tested:
  
  * AR9331 SoC, STA mode

Modified:
  head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_reset.c

Modified: head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_reset.c
==============================================================================
--- head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_reset.c	Sat Aug  9 09:11:26 2014	(r269747)
+++ head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_reset.c	Sat Aug  9 09:12:25 2014	(r269748)
@@ -1987,13 +1987,25 @@ HAL_BOOL
 ar9300_chip_reset(struct ath_hal *ah, struct ieee80211_channel *chan)
 {
     struct ath_hal_9300     *ahp = AH9300(ah);
+    int type = HAL_RESET_WARM;
 
     OS_MARK(ah, AH_MARK_CHIPRESET, chan ? chan->ic_freq : 0);
 
     /*
      * Warm reset is optimistic.
-     */
-    if (!ar9300_set_reset_reg(ah, HAL_RESET_WARM)) {
+     *
+     * If the TX/RX DMA engines aren't shut down (eg, they're
+     * wedged) then we're better off doing a full cold reset
+     * to try and shake that condition.
+     */
+    if (ahp->ah_chip_full_sleep ||
+        (ah->ah_config.ah_force_full_reset == 1) ||
+        OS_REG_READ(ah, AR_Q_TXE) ||
+        (OS_REG_READ(ah, AR_CR) & AR_CR_RXE)) {
+            type = HAL_RESET_COLD;
+    }
+
+    if (!ar9300_set_reset_reg(ah, type)) {
         return AH_FALSE;
     }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?53e5e5f9.2eeb.7727ac5c>