diff options
author | adrian <adrian@FreeBSD.org> | 2011-03-13 13:00:45 +0000 |
---|---|---|
committer | adrian <adrian@FreeBSD.org> | 2011-03-13 13:00:45 +0000 |
commit | f90fad94e2ec9dfbc2a662976f25512bc7625bcb (patch) | |
tree | 4d463114e5a3c66776ac7ac0e8308800414ac4d7 | |
parent | 2671ddd1130068db9891f66a1b48e6440675936d (diff) | |
download | FreeBSD-src-f90fad94e2ec9dfbc2a662976f25512bc7625bcb.zip FreeBSD-src-f90fad94e2ec9dfbc2a662976f25512bc7625bcb.tar.gz |
Fix the nfarray offsets for the ar2133/ar5133 radio - (AR5416, AR9160, etc.)
The offsets didn't match the assumption that nfarray[] is ordered by the
chainmask bits and programmed via the register order in ar5416_cca_regs[].
This repairs that damage and ensures that chain 1 is programmed correctly.
(And extension channels will now be programmed correctly also.)
This fixes some of the stuck beacons I've been seeing on my AR9160/AR5416
setups - because Chain 1 would be programmed -80 or -85 dBm, which is
higher than the actual noise floor and thus convincing the radio that
indeed it can't ever transmit.
-rw-r--r-- | sys/dev/ath/ath_hal/ar5416/ar2133.c | 25 | ||||
-rw-r--r-- | sys/dev/ath/ath_hal/ar9002/ar9280.c | 15 | ||||
-rw-r--r-- | sys/dev/ath/ath_hal/ar9002/ar9285.c | 17 |
3 files changed, 52 insertions, 5 deletions
diff --git a/sys/dev/ath/ath_hal/ar5416/ar2133.c b/sys/dev/ath/ath_hal/ar5416/ar2133.c index 11fd648..f57b3ca 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar2133.c +++ b/sys/dev/ath/ath_hal/ar5416/ar2133.c @@ -386,12 +386,29 @@ ar2133GetChannelMaxMinPower(struct ath_hal *ah, #endif } +/* + * The ordering of nfarray is thus: + * + * nfarray[0]: Chain 0 ctl + * nfarray[1]: Chain 1 ctl + * nfarray[2]: Chain 2 ctl + * nfarray[3]: Chain 0 ext + * nfarray[4]: Chain 1 ext + * nfarray[5]: Chain 2 ext + */ static void ar2133GetNoiseFloor(struct ath_hal *ah, int16_t nfarray[]) { struct ath_hal_5416 *ahp = AH5416(ah); int16_t nf; + /* + * Blank nf array - some chips may only + * have one or two RX chainmasks enabled. + */ + nfarray[0] = nfarray[1] = nfarray[2] = 0; + nfarray[3] = nfarray[4] = nfarray[5] = 0; + switch (ahp->ah_rx_chainmask) { case 0x7: nf = MS(OS_REG_READ(ah, AR_PHY_CH2_CCA), AR_PHY_CH2_MINCCA_PWR); @@ -399,7 +416,7 @@ ar2133GetNoiseFloor(struct ath_hal *ah, int16_t nfarray[]) nf = 0 - ((nf ^ 0x1ff) + 1); HALDEBUG(ah, HAL_DEBUG_NFCAL, "NF calibrated [ctl] [chain 2] is %d\n", nf); - nfarray[4] = nf; + nfarray[2] = nf; nf = MS(OS_REG_READ(ah, AR_PHY_CH2_EXT_CCA), AR_PHY_CH2_EXT_MINCCA_PWR); if (nf & 0x100) @@ -415,7 +432,7 @@ ar2133GetNoiseFloor(struct ath_hal *ah, int16_t nfarray[]) nf = 0 - ((nf ^ 0x1ff) + 1); HALDEBUG(ah, HAL_DEBUG_NFCAL, "NF calibrated [ctl] [chain 1] is %d\n", nf); - nfarray[2] = nf; + nfarray[1] = nf; nf = MS(OS_REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR_PHY_CH1_EXT_MINCCA_PWR); @@ -423,7 +440,7 @@ ar2133GetNoiseFloor(struct ath_hal *ah, int16_t nfarray[]) nf = 0 - ((nf ^ 0x1ff) + 1); HALDEBUG(ah, HAL_DEBUG_NFCAL, "NF calibrated [ext] [chain 1] is %d\n", nf); - nfarray[3] = nf; + nfarray[4] = nf; /* fall thru... */ case 0x1: nf = MS(OS_REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR); @@ -438,7 +455,7 @@ ar2133GetNoiseFloor(struct ath_hal *ah, int16_t nfarray[]) nf = 0 - ((nf ^ 0x1ff) + 1); HALDEBUG(ah, HAL_DEBUG_NFCAL, "NF calibrated [ext] [chain 0] is %d\n", nf); - nfarray[1] = nf; + nfarray[3] = nf; break; } diff --git a/sys/dev/ath/ath_hal/ar9002/ar9280.c b/sys/dev/ath/ath_hal/ar9002/ar9280.c index 85fb6bc..f1bb4fe 100644 --- a/sys/dev/ath/ath_hal/ar9002/ar9280.c +++ b/sys/dev/ath/ath_hal/ar9002/ar9280.c @@ -265,6 +265,16 @@ ar9280GetChannelMaxMinPower(struct ath_hal *ah, #endif } +/* + * The ordering of nfarray is thus: + * + * nfarray[0]: Chain 0 ctl + * nfarray[1]: Chain 1 ctl + * nfarray[2]: Chain 2 ctl + * nfarray[3]: Chain 0 ext + * nfarray[4]: Chain 1 ext + * nfarray[5]: Chain 2 ext + */ static void ar9280GetNoiseFloor(struct ath_hal *ah, int16_t nfarray[]) { @@ -297,6 +307,11 @@ ar9280GetNoiseFloor(struct ath_hal *ah, int16_t nfarray[]) HALDEBUG(ah, HAL_DEBUG_NFCAL, "NF calibrated [ext] [chain 1] is %d\n", nf); nfarray[4] = nf; + + /* Chain 2 - invalid */ + nfarray[2] = 0; + nfarray[5] = 0; + } /* diff --git a/sys/dev/ath/ath_hal/ar9002/ar9285.c b/sys/dev/ath/ath_hal/ar9002/ar9285.c index 9b7da66..f1851cc 100644 --- a/sys/dev/ath/ath_hal/ar9002/ar9285.c +++ b/sys/dev/ath/ath_hal/ar9002/ar9285.c @@ -28,6 +28,16 @@ #include "ar5416/ar5416reg.h" #include "ar5416/ar5416phy.h" +/* + * The ordering of nfarray is thus: + * + * nfarray[0]: Chain 0 ctl + * nfarray[1]: Chain 1 ctl + * nfarray[2]: Chain 2 ctl + * nfarray[3]: Chain 0 ext + * nfarray[4]: Chain 1 ext + * nfarray[5]: Chain 2 ext + */ static void ar9285GetNoiseFloor(struct ath_hal *ah, int16_t nfarray[]) { @@ -40,7 +50,6 @@ ar9285GetNoiseFloor(struct ath_hal *ah, int16_t nfarray[]) "NF calibrated [ctl] [chain 0] is %d\n", nf); nfarray[0] = nf; - nfarray[1] = 0; nf = MS(OS_REG_READ(ah, AR_PHY_EXT_CCA), AR9280_PHY_EXT_MINCCA_PWR); if (nf & 0x100) @@ -49,7 +58,13 @@ ar9285GetNoiseFloor(struct ath_hal *ah, int16_t nfarray[]) "NF calibrated [ext] [chain 0] is %d\n", nf); nfarray[3] = nf; + /* Chain 1 - invalid */ + nfarray[1] = 0; nfarray[4] = 0; + + /* Chain 2 - invalid */ + nfarray[2] = 0; + nfarray[5] = 0; } HAL_BOOL |