Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 8 May 2011 03:24:18 +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: r221616 - head/sys/dev/ath/ath_hal/ar5416
Message-ID:  <201105080324.p483OIfF027042@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Sun May  8 03:24:17 2011
New Revision: 221616
URL: http://svn.freebsd.org/changeset/base/221616

Log:
  Fiddle with the AR5416 1.0 chainmask setup.
  
  Apparently all three RX chains need to be enabled before initial calibration
  is done, even if only two are configured.
  
  Reorder the alt chain swap bit to match what the Atheros HAL is doing.
  
  Obtained From:	ath9k, Atheros

Modified:
  head/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c

Modified: head/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c
==============================================================================
--- head/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c	Sun May  8 01:01:27 2011	(r221615)
+++ head/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c	Sun May  8 03:24:17 2011	(r221616)
@@ -1285,26 +1285,46 @@ ar5416SetReset(struct ath_hal *ah, int t
 void
 ar5416InitChainMasks(struct ath_hal *ah)
 {
-	if (AH5416(ah)->ah_rx_chainmask == 0x5 ||
-	    AH5416(ah)->ah_tx_chainmask == 0x5)
-		OS_REG_WRITE(ah, AR_PHY_ANALOG_SWAP, AR_PHY_SWAP_ALT_CHAIN);
-	/* Setup Chain Masks */
-	OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, AH5416(ah)->ah_rx_chainmask);
-	OS_REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, AH5416(ah)->ah_rx_chainmask);
+	int rx_chainmask = AH5416(ah)->ah_rx_chainmask;
+
+	if (rx_chainmask)
+		OS_REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, AR_PHY_SWAP_ALT_CHAIN);
+
+	/*
+	 * Workaround for OWL 1.0 calibration failure; enable multi-chain;
+	 * then set true mask after calibration.
+	 */
+	if (IS_5416V1(ah) && (rx_chainmask == 0x5 || rx_chainmask == 0x3)) {
+		OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7);
+		OS_REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7);
+	} else {
+		OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, AH5416(ah)->ah_rx_chainmask);
+		OS_REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, AH5416(ah)->ah_rx_chainmask);
+	}
 	OS_REG_WRITE(ah, AR_SELFGEN_MASK, AH5416(ah)->ah_tx_chainmask);
 
+	if (AH5416(ah)->ah_tx_chainmask == 0x5)
+		OS_REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, AR_PHY_SWAP_ALT_CHAIN);
+
 	if (AR_SREV_HOWL(ah)) {
 		OS_REG_WRITE(ah, AR_PHY_ANALOG_SWAP,
 		OS_REG_READ(ah, AR_PHY_ANALOG_SWAP) | 0x00000001);
 	}
 }
 
+/*
+ * Work-around for Owl 1.0 calibration failure.
+ *
+ * ar5416InitChainMasks sets the RX chainmask to 0x7 if it's Owl 1.0
+ * due to init calibration failures. ar5416RestoreChainMask restores
+ * these registers to the correct setting.
+ */
 void
 ar5416RestoreChainMask(struct ath_hal *ah)
 {
 	int rx_chainmask = AH5416(ah)->ah_rx_chainmask;
 
-	if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) {
+	if (IS_5416V1(ah) && (rx_chainmask == 0x5 || rx_chainmask == 0x3)) {
 		OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
 		OS_REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
 	}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201105080324.p483OIfF027042>