svn commit: r227374 - in head/sys/dev/ath/ath_hal: . ar5416

Adrian Chadd adrian at FreeBSD.org
Wed Nov 9 05:25:30 UTC 2011


Author: adrian
Date: Wed Nov  9 05:25:30 2011
New Revision: 227374
URL: http://svn.freebsd.org/changeset/base/227374

Log:
  Port over a new routine which grabs the percentage of time spent in TX frame, RX frame,
  RX clear, RX extension clear.
  
  This is useful for estimating channel business.
  
  The same routines should be written for AR5210->AR5212 where appopriate.
  
  Obtained from:	Atheros

Modified:
  head/sys/dev/ath/ath_hal/ah.h
  head/sys/dev/ath/ath_hal/ar5416/ar5416.h
  head/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c

Modified: head/sys/dev/ath/ath_hal/ah.h
==============================================================================
--- head/sys/dev/ath/ath_hal/ah.h	Wed Nov  9 04:38:27 2011	(r227373)
+++ head/sys/dev/ath/ath_hal/ah.h	Wed Nov  9 05:25:30 2011	(r227374)
@@ -1025,6 +1025,9 @@ struct ath_hal {
 	    			struct ath_desc *);
 	void	  __ahdecl(*ah_set11nBurstDuration)(struct ath_hal *,
 	    			struct ath_desc *, u_int);
+	uint32_t  __ahdecl(*ah_get_mib_cycle_counts_pct) (struct ath_hal *,
+				uint32_t *, uint32_t *, uint32_t *, uint32_t *);
+
 	uint32_t  __ahdecl(*ah_get11nExtBusy)(struct ath_hal *);
 	void      __ahdecl(*ah_set11nMac2040)(struct ath_hal *,
 				HAL_HT_MACMODE);

Modified: head/sys/dev/ath/ath_hal/ar5416/ar5416.h
==============================================================================
--- head/sys/dev/ath/ath_hal/ar5416/ar5416.h	Wed Nov  9 04:38:27 2011	(r227373)
+++ head/sys/dev/ath/ath_hal/ar5416/ar5416.h	Wed Nov  9 05:25:30 2011	(r227374)
@@ -112,11 +112,13 @@ struct ath_hal_5416 {
 	int		ah_hangs;		/* h/w hangs state */
 	uint8_t		ah_keytype[AR5416_KEYTABLE_SIZE];
 	/*
-	 * Extension Channel Rx Clear State
+	 * Primary/Extension Channel Tx, Rx, Rx Clear State
 	 */
 	uint32_t	ah_cycleCount;
 	uint32_t	ah_ctlBusy;
 	uint32_t	ah_extBusy;
+	uint32_t	ah_rxBusy;
+	uint32_t	ah_txBusy;
 	uint32_t	ah_rx_chainmask;
 	uint32_t	ah_tx_chainmask;
 
@@ -194,6 +196,9 @@ extern	uint32_t ar5416GetCurRssi(struct 
 extern	HAL_BOOL ar5416SetAntennaSwitch(struct ath_hal *, HAL_ANT_SETTING);
 extern	HAL_BOOL ar5416SetDecompMask(struct ath_hal *, uint16_t, int);
 extern	void ar5416SetCoverageClass(struct ath_hal *, uint8_t, int);
+extern	uint32_t ar5416GetMibCycleCountsPct(struct ath_hal *ah,
+    uint32_t *rxc_pcnt, uint32_t *rxextc_pcnt, uint32_t *rxf_pcnt,
+    uint32_t *txf_pcnt);
 extern	uint32_t ar5416Get11nExtBusy(struct ath_hal *ah);
 extern	void ar5416Set11nMac2040(struct ath_hal *ah, HAL_HT_MACMODE mode);
 extern	HAL_HT_RXCLEAR ar5416Get11nRxClear(struct ath_hal *ah);

Modified: head/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c
==============================================================================
--- head/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c	Wed Nov  9 04:38:27 2011	(r227373)
+++ head/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c	Wed Nov  9 05:25:30 2011	(r227374)
@@ -172,6 +172,57 @@ ar5416SetCoverageClass(struct ath_hal *a
 }
 
 /*
+ * Return the busy for rx_frame, rx_clear, and tx_frame
+ */
+uint32_t
+ar5416GetMibCycleCountsPct(struct ath_hal *ah, uint32_t *rxc_pcnt,
+    uint32_t *extc_pcnt, uint32_t *rxf_pcnt, uint32_t *txf_pcnt)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	u_int32_t good = 1;
+
+	/* XXX freeze/unfreeze mib counters */
+	uint32_t rc = OS_REG_READ(ah, AR_RCCNT);
+	uint32_t ec = OS_REG_READ(ah, AR_EXTRCCNT);
+	uint32_t rf = OS_REG_READ(ah, AR_RFCNT);
+	uint32_t tf = OS_REG_READ(ah, AR_TFCNT);
+	uint32_t cc = OS_REG_READ(ah, AR_CCCNT); /* read cycles last */
+
+	if (ahp->ah_cycleCount == 0 || ahp->ah_cycleCount > cc) {
+		/*
+		 * Cycle counter wrap (or initial call); it's not possible
+		 * to accurately calculate a value because the registers
+		 * right shift rather than wrap--so punt and return 0.
+		 */
+		HALDEBUG(ah, HAL_DEBUG_ANY,
+			    "%s: cycle counter wrap. ExtBusy = 0\n", __func__);
+			good = 0;
+	} else {
+		uint32_t cc_d = cc - ahp->ah_cycleCount;
+		uint32_t rc_d = rc - ahp->ah_ctlBusy;
+		uint32_t ec_d = ec - ahp->ah_extBusy;
+		uint32_t rf_d = rf - ahp->ah_rxBusy;
+		uint32_t tf_d = tf - ahp->ah_txBusy;
+
+		if (cc_d != 0) {
+			*rxc_pcnt = rc_d * 100 / cc_d;
+			*rxf_pcnt = rf_d * 100 / cc_d;
+			*txf_pcnt = tf_d * 100 / cc_d;
+			*extc_pcnt = ec_d * 100 / cc_d;
+		} else {
+			good = 0;
+		}
+	}
+	ahp->ah_cycleCount = cc;
+	ahp->ah_rxBusy = rf;
+	ahp->ah_ctlBusy = rc;
+	ahp->ah_txBusy = tf;
+	ahp->ah_extBusy = ec;
+
+	return good;
+}
+
+/*
  * Return approximation of extension channel busy over an time interval
  * 0% (clear) -> 100% (busy)
  *


More information about the svn-src-head mailing list