svn commit: r334849 - in head/sys: contrib/dev/ath/ath_hal/ar9300 dev/ath/ath_hal/ar5416

Adrian Chadd adrian at FreeBSD.org
Fri Jun 8 18:21:59 UTC 2018


Author: adrian
Date: Fri Jun  8 18:21:57 2018
New Revision: 334849
URL: https://svnweb.freebsd.org/changeset/base/334849

Log:
  [ath_hal] Return failure if noise floor calibration fails.
  
  If we fail noise floor calibration then we may end up with a deaf NIC
  which we can't recover without a full chip reset.
  
  Earlier chips seem to get less stuck in this condition versus AR9280/later
  and AR9300/later, but whilst here just fix up the AR5212 era chips to also
  return NF calibration failures.
  
  This HAL routine would only return failure if the channel was not configured.
  
  This is a no-op until the driver side code for doing resets and the HAL
  code for being told about the reset type (and then handling it!) is
  implemented.
  
  Tested:
  
  * AR9280, STA mode
  * AR2425, STA mode
  * AR9380, STA mode

Modified:
  head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_ani.c
  head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.c
  head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_reset.c
  head/sys/dev/ath/ath_hal/ar5416/ar5416_cal.c

Modified: head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_ani.c
==============================================================================
--- head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_ani.c	Fri Jun  8 18:15:23 2018	(r334848)
+++ head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_ani.c	Fri Jun  8 18:21:57 2018	(r334849)
@@ -1188,6 +1188,15 @@ ar9300_ani_ar_poll(struct ath_hal *ah, const HAL_NODE_
         cck_phy_err_cnt - ani_state->cck_phy_err_count;
     ani_state->cck_phy_err_count = cck_phy_err_cnt;
 
+    /*
+     * Note - the ANI code is using the aggregate listen time.
+     * The AR_PHY_CNT1/AR_PHY_CNT2 registers here are also
+     * free running, not clear-on-read and are free-running.
+     *
+     * So, ofdm_phy_err_rate / cck_phy_err_rate are accumulating
+     * the same as listenTime is accumulating.
+     */
+
 #if HAL_ANI_DEBUG
     HALDEBUG(ah, HAL_DEBUG_ANI,
         "%s: Errors: OFDM=0x%08x-0x0=%d   CCK=0x%08x-0x0=%d\n",

Modified: head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.c
==============================================================================
--- head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.c	Fri Jun  8 18:15:23 2018	(r334848)
+++ head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.c	Fri Jun  8 18:21:57 2018	(r334849)
@@ -704,11 +704,16 @@ ar9300_proc_rx_desc_freebsd(struct ath_hal *ah, struct
 	    (void *) ds));
 }
 
+/*
+ * This is the primary way the ANI code gets the node statistics per packet.
+ */
 void
 ar9300_ani_rxmonitor_freebsd(struct ath_hal *ah, const HAL_NODE_STATS *stats,
     const struct ieee80211_channel *chan)
 {
+	struct ath_hal_9300 *ahp = AH9300(ah);
 
+	ahp->ah_stats.ast_nodestats.ns_avgbrssi = stats->ns_avgbrssi;
 }
 
 void

Modified: head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_reset.c
==============================================================================
--- head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_reset.c	Fri Jun  8 18:15:23 2018	(r334848)
+++ head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_reset.c	Fri Jun  8 18:21:57 2018	(r334849)
@@ -2493,15 +2493,23 @@ ar9300_calibration(struct ath_hal *ah, struct ieee8021
         chan->ic_state &= ~IEEE80211_CHANSTATE_CWINT;
 
         if (nf_done) {
+            int ret;
             /*
              * Load the NF from history buffer of the current channel.
              * NF is slow time-variant, so it is OK to use a historical value.
              */
             ar9300_get_nf_hist_base(ah, ichan, is_scan, nf_buf);
-            ar9300_load_nf(ah, nf_buf);
-    
+
+            ret = ar9300_load_nf(ah, nf_buf);
             /* start NF calibration, without updating BB NF register*/
-            ar9300_start_nf_cal(ah);	
+            ar9300_start_nf_cal(ah);
+
+            /*
+             * If we failed the NF cal then tell the upper layer that we
+             * failed so we can do a full reset
+             */
+            if (! ret)
+                return AH_FALSE;
         }
     }
     return AH_TRUE;
@@ -4479,6 +4487,7 @@ First_NFCal(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *
         ar9300_reset_nf_hist_buff(ah, ichan);
         ar9300_get_nf_hist_base(ah, ichan, is_scan, nf_buf);
         ar9300_load_nf(ah, nf_buf);
+        /* XXX TODO: handle failure from load_nf */
         stats = 0;
 	} else {
         stats = 1;	
@@ -5303,6 +5312,7 @@ ar9300_reset(struct ath_hal *ah, HAL_OPMODE opmode, st
     /* XXX FreeBSD is ichan appropariate? It was curchan.. */
     ar9300_get_nf_hist_base(ah, ichan, is_scan, nf_buf);
     ar9300_load_nf(ah, nf_buf);
+    /* XXX TODO: handle NF load failure */
     if (nf_hist_buff_reset == 1)    
     {
         nf_hist_buff_reset = 0;

Modified: head/sys/dev/ath/ath_hal/ar5416/ar5416_cal.c
==============================================================================
--- head/sys/dev/ath/ath_hal/ar5416/ar5416_cal.c	Fri Jun  8 18:15:23 2018	(r334848)
+++ head/sys/dev/ath/ath_hal/ar5416/ar5416_cal.c	Fri Jun  8 18:21:57 2018	(r334849)
@@ -36,7 +36,7 @@
 #define NUM_NOISEFLOOR_READINGS 6       /* 3 chains * (ctl + ext) */
 
 static void ar5416StartNFCal(struct ath_hal *ah);
-static void ar5416LoadNF(struct ath_hal *ah, const struct ieee80211_channel *);
+static HAL_BOOL ar5416LoadNF(struct ath_hal *ah, const struct ieee80211_channel *);
 static int16_t ar5416GetNf(struct ath_hal *, struct ieee80211_channel *);
 
 static uint16_t ar5416GetDefaultNF(struct ath_hal *ah, const struct ieee80211_channel *chan);
@@ -513,6 +513,7 @@ ar5416PerCalibrationN(struct ath_hal *ah, struct ieee8
 			HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "%s: NF calibration"
 			    " didn't finish; delaying CCA\n", __func__);
 		} else {
+			int ret;
 			/* 
 			 * NF calibration result is valid.
 			 *
@@ -520,10 +521,17 @@ ar5416PerCalibrationN(struct ath_hal *ah, struct ieee8
 			 * NF is slow time-variant, so it is OK to use a
 			 * historical value.
 			 */
-			ar5416LoadNF(ah, AH_PRIVATE(ah)->ah_curchan);
+			ret = ar5416LoadNF(ah, AH_PRIVATE(ah)->ah_curchan);
 
 			/* start NF calibration, without updating BB NF register*/
 			ar5416StartNFCal(ah);
+
+			/*
+			 * If we failed calibration then tell the driver
+			 * we failed and it should do a full chip reset
+			 */
+			if (! ret)
+				return AH_FALSE;
 		}
 	}
 	return AH_TRUE;
@@ -578,7 +586,7 @@ ar5416StartNFCal(struct ath_hal *ah)
 	OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
 }
 
-static void
+static HAL_BOOL
 ar5416LoadNF(struct ath_hal *ah, const struct ieee80211_channel *chan)
 {
 	static const uint32_t ar5416_cca_regs[] = {
@@ -657,7 +665,7 @@ ar5416LoadNF(struct ath_hal *ah, const struct ieee8021
 		HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "Timeout while waiting for "
 		    "nf to load: AR_PHY_AGC_CONTROL=0x%x\n",
 		    OS_REG_READ(ah, AR_PHY_AGC_CONTROL));
-		return;
+		return AH_FALSE;
 	}
 
 	/*
@@ -679,6 +687,7 @@ ar5416LoadNF(struct ath_hal *ah, const struct ieee8021
 			OS_REG_WRITE(ah, ar5416_cca_regs[i], val);
 		}
 	}
+	return AH_TRUE;
 }
 
 /*


More information about the svn-src-all mailing list