summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/ath/ath9k/ar9003_rtt.c
diff options
context:
space:
mode:
authorSujith Manoharan <c_manoha@qca.qualcomm.com>2012-05-04 11:53:59 +0400
committerJohn W. Linville <linville@tuxdriver.com>2012-05-16 01:27:55 +0400
commit8a90555fea9f2e1498a9efe4f25c32d2846f257f (patch)
tree2679b3273669a2448ff41266e74431e88e914e0e /drivers/net/wireless/ath/ath9k/ar9003_rtt.c
parent7d4e15b177835dfddcab9851a889c28a85dde92e (diff)
downloadlinux-8a90555fea9f2e1498a9efe4f25c32d2846f257f.tar.xz
ath9k_hw: Fix RTT calibration
This patch fixes multiple issues with the current RTT implementation in ath9k. * The data that is obtained from the RTT interface registers are stored in 31:5 - mask out the extra bits when reading them. * A history buffer is maintained which is not needed at all. Remove this array and just store the baseband data for each chain (or bank). * A 'num_readings' variable was being used to handle the last entry. But it was being used in an improper manner, with the result that the RTT values were never being written to the RTT Interface registers. Fix this by using a simple flag. * Stop baseband operations before programming the calibration values to the HW. * Do not restore RX gain settings as part of RTT. Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/ar9003_rtt.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_rtt.c84
1 files changed, 69 insertions, 15 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_rtt.c b/drivers/net/wireless/ath/ath9k/ar9003_rtt.c
index 458bedf0b0ae..74de3539c2c8 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_rtt.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_rtt.c
@@ -15,6 +15,7 @@
*/
#include "hw.h"
+#include "hw-ops.h"
#include "ar9003_phy.h"
#include "ar9003_rtt.h"
@@ -69,7 +70,7 @@ bool ar9003_hw_rtt_force_restore(struct ath_hw *ah)
}
static void ar9003_hw_rtt_load_hist_entry(struct ath_hw *ah, u8 chain,
- u32 index, u32 data28)
+ u32 index, u32 data28)
{
u32 val;
@@ -100,12 +101,21 @@ static void ar9003_hw_rtt_load_hist_entry(struct ath_hw *ah, u8 chain,
RTT_ACCESS_TIMEOUT);
}
-void ar9003_hw_rtt_load_hist(struct ath_hw *ah, u8 chain, u32 *table)
+void ar9003_hw_rtt_load_hist(struct ath_hw *ah)
{
- int i;
+ int chain, i;
- for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++)
- ar9003_hw_rtt_load_hist_entry(ah, chain, i, table[i]);
+ for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
+ if (!(ah->rxchainmask & (1 << chain)))
+ continue;
+ for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++) {
+ ar9003_hw_rtt_load_hist_entry(ah, chain, i,
+ ah->caldata->rtt_table[chain][i]);
+ ath_dbg(ath9k_hw_common(ah), CALIBRATE,
+ "Load RTT value at idx %d, chain %d: 0x%x\n",
+ i, chain, ah->caldata->rtt_table[chain][i]);
+ }
+ }
}
static int ar9003_hw_rtt_fill_hist_entry(struct ath_hw *ah, u8 chain, u32 index)
@@ -128,27 +138,71 @@ static int ar9003_hw_rtt_fill_hist_entry(struct ath_hw *ah, u8 chain, u32 index)
RTT_ACCESS_TIMEOUT))
return RTT_BAD_VALUE;
- val = REG_READ(ah, AR_PHY_RTT_TABLE_SW_INTF_1_B(chain));
+ val = MS(REG_READ(ah, AR_PHY_RTT_TABLE_SW_INTF_1_B(chain)),
+ AR_PHY_RTT_SW_RTT_TABLE_DATA);
+
return val;
}
-void ar9003_hw_rtt_fill_hist(struct ath_hw *ah, u8 chain, u32 *table)
+void ar9003_hw_rtt_fill_hist(struct ath_hw *ah)
{
- int i;
+ int chain, i;
+
+ for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
+ if (!(ah->rxchainmask & (1 << chain)))
+ continue;
+ for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++) {
+ ah->caldata->rtt_table[chain][i] =
+ ar9003_hw_rtt_fill_hist_entry(ah, chain, i);
+ ath_dbg(ath9k_hw_common(ah), CALIBRATE,
+ "RTT value at idx %d, chain %d is: 0x%x\n",
+ i, chain, ah->caldata->rtt_table[chain][i]);
+ }
+ }
- for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++)
- table[i] = ar9003_hw_rtt_fill_hist_entry(ah, chain, i);
+ ah->caldata->rtt_done = true;
}
void ar9003_hw_rtt_clear_hist(struct ath_hw *ah)
{
- int i, j;
+ int chain, i;
- for (i = 0; i < AR9300_MAX_CHAINS; i++) {
- if (!(ah->rxchainmask & (1 << i)))
+ for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
+ if (!(ah->rxchainmask & (1 << chain)))
continue;
- for (j = 0; j < MAX_RTT_TABLE_ENTRY; j++)
- ar9003_hw_rtt_load_hist_entry(ah, i, j, 0);
+ for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++)
+ ar9003_hw_rtt_load_hist_entry(ah, chain, i, 0);
}
+
+ if (ah->caldata)
+ ah->caldata->rtt_done = false;
+}
+
+bool ar9003_hw_rtt_restore(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+ bool restore;
+
+ if (!ah->caldata)
+ return false;
+
+ if (!ah->caldata->rtt_done)
+ return false;
+
+ ar9003_hw_rtt_enable(ah);
+ ar9003_hw_rtt_set_mask(ah, 0x10);
+
+ if (!ath9k_hw_rfbus_req(ah)) {
+ ath_err(ath9k_hw_common(ah), "Could not stop baseband\n");
+ restore = false;
+ goto fail;
+ }
+
+ ar9003_hw_rtt_load_hist(ah);
+ restore = ar9003_hw_rtt_force_restore(ah);
+
+fail:
+ ath9k_hw_rfbus_done(ah);
+ ar9003_hw_rtt_disable(ah);
+ return restore;
}