aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSujith Manoharan <c_manoha@qca.qualcomm.com>2012-05-04 03:53:59 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-05-15 17:27:55 -0400
commit8a90555fea9f2e1498a9efe4f25c32d2846f257f (patch)
tree2679b3273669a2448ff41266e74431e88e914e0e
parent7d4e15b177835dfddcab9851a889c28a85dde92e (diff)
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>
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_calib.c50
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mci.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_rtt.c84
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_rtt.h5
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c9
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h9
6 files changed, 89 insertions, 70 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
index a0387a027db0..9fdd70fcaf5b 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
@@ -892,34 +892,6 @@ static void ar9003_hw_tx_iq_cal_reload(struct ath_hw *ah)
892 AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1); 892 AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1);
893} 893}
894 894
895static bool ar9003_hw_rtt_restore(struct ath_hw *ah, struct ath9k_channel *chan)
896{
897 struct ath9k_rtt_hist *hist;
898 u32 *table;
899 int i;
900 bool restore;
901
902 if (!ah->caldata)
903 return false;
904
905 hist = &ah->caldata->rtt_hist;
906 if (!hist->num_readings)
907 return false;
908
909 ar9003_hw_rtt_enable(ah);
910 ar9003_hw_rtt_set_mask(ah, 0x00);
911 for (i = 0; i < AR9300_MAX_CHAINS; i++) {
912 if (!(ah->rxchainmask & (1 << i)))
913 continue;
914 table = &hist->table[i][hist->num_readings][0];
915 ar9003_hw_rtt_load_hist(ah, i, table);
916 }
917 restore = ar9003_hw_rtt_force_restore(ah);
918 ar9003_hw_rtt_disable(ah);
919
920 return restore;
921}
922
923static bool ar9003_hw_init_cal(struct ath_hw *ah, 895static bool ar9003_hw_init_cal(struct ath_hw *ah,
924 struct ath9k_channel *chan) 896 struct ath9k_channel *chan)
925{ 897{
@@ -942,9 +914,10 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
942 if (!ar9003_hw_rtt_restore(ah, chan)) 914 if (!ar9003_hw_rtt_restore(ah, chan))
943 run_rtt_cal = true; 915 run_rtt_cal = true;
944 916
945 ath_dbg(common, CALIBRATE, "RTT restore %s\n", 917 if (run_rtt_cal)
946 run_rtt_cal ? "failed" : "succeed"); 918 ath_dbg(common, CALIBRATE, "RTT calibration to be done\n");
947 } 919 }
920
948 run_agc_cal = run_rtt_cal; 921 run_agc_cal = run_rtt_cal;
949 922
950 if (run_rtt_cal) { 923 if (run_rtt_cal) {
@@ -1069,17 +1042,14 @@ skip_tx_iqcal:
1069#undef CL_TAB_ENTRY 1042#undef CL_TAB_ENTRY
1070 1043
1071 if (run_rtt_cal && caldata) { 1044 if (run_rtt_cal && caldata) {
1072 struct ath9k_rtt_hist *hist = &caldata->rtt_hist; 1045 if (is_reusable) {
1073 if (is_reusable && (hist->num_readings < RTT_HIST_MAX)) { 1046 if (!ath9k_hw_rfbus_req(ah))
1074 u32 *table; 1047 ath_err(ath9k_hw_common(ah),
1048 "Could not stop baseband\n");
1049 else
1050 ar9003_hw_rtt_fill_hist(ah);
1075 1051
1076 hist->num_readings++; 1052 ath9k_hw_rfbus_done(ah);
1077 for (i = 0; i < AR9300_MAX_CHAINS; i++) {
1078 if (!(ah->rxchainmask & (1 << i)))
1079 continue;
1080 table = &hist->table[i][hist->num_readings][0];
1081 ar9003_hw_rtt_fill_hist(ah, i, table);
1082 }
1083 } 1053 }
1084 1054
1085 ar9003_hw_rtt_disable(ah); 1055 ar9003_hw_rtt_disable(ah);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/drivers/net/wireless/ath/ath9k/ar9003_mci.c
index 3cac293a2849..ffbb180f91e1 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mci.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.c
@@ -756,7 +756,7 @@ int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan,
756 if (caldata) { 756 if (caldata) {
757 caldata->done_txiqcal_once = false; 757 caldata->done_txiqcal_once = false;
758 caldata->done_txclcal_once = false; 758 caldata->done_txclcal_once = false;
759 caldata->rtt_hist.num_readings = 0; 759 caldata->rtt_done = false;
760 } 760 }
761 761
762 if (!ath9k_hw_init_cal(ah, chan)) 762 if (!ath9k_hw_init_cal(ah, chan))
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 @@
15 */ 15 */
16 16
17#include "hw.h" 17#include "hw.h"
18#include "hw-ops.h"
18#include "ar9003_phy.h" 19#include "ar9003_phy.h"
19#include "ar9003_rtt.h" 20#include "ar9003_rtt.h"
20 21
@@ -69,7 +70,7 @@ bool ar9003_hw_rtt_force_restore(struct ath_hw *ah)
69} 70}
70 71
71static void ar9003_hw_rtt_load_hist_entry(struct ath_hw *ah, u8 chain, 72static void ar9003_hw_rtt_load_hist_entry(struct ath_hw *ah, u8 chain,
72 u32 index, u32 data28) 73 u32 index, u32 data28)
73{ 74{
74 u32 val; 75 u32 val;
75 76
@@ -100,12 +101,21 @@ static void ar9003_hw_rtt_load_hist_entry(struct ath_hw *ah, u8 chain,
100 RTT_ACCESS_TIMEOUT); 101 RTT_ACCESS_TIMEOUT);
101} 102}
102 103
103void ar9003_hw_rtt_load_hist(struct ath_hw *ah, u8 chain, u32 *table) 104void ar9003_hw_rtt_load_hist(struct ath_hw *ah)
104{ 105{
105 int i; 106 int chain, i;
106 107
107 for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++) 108 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
108 ar9003_hw_rtt_load_hist_entry(ah, chain, i, table[i]); 109 if (!(ah->rxchainmask & (1 << chain)))
110 continue;
111 for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++) {
112 ar9003_hw_rtt_load_hist_entry(ah, chain, i,
113 ah->caldata->rtt_table[chain][i]);
114 ath_dbg(ath9k_hw_common(ah), CALIBRATE,
115 "Load RTT value at idx %d, chain %d: 0x%x\n",
116 i, chain, ah->caldata->rtt_table[chain][i]);
117 }
118 }
109} 119}
110 120
111static int ar9003_hw_rtt_fill_hist_entry(struct ath_hw *ah, u8 chain, u32 index) 121static 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)
128 RTT_ACCESS_TIMEOUT)) 138 RTT_ACCESS_TIMEOUT))
129 return RTT_BAD_VALUE; 139 return RTT_BAD_VALUE;
130 140
131 val = REG_READ(ah, AR_PHY_RTT_TABLE_SW_INTF_1_B(chain)); 141 val = MS(REG_READ(ah, AR_PHY_RTT_TABLE_SW_INTF_1_B(chain)),
142 AR_PHY_RTT_SW_RTT_TABLE_DATA);
143
132 144
133 return val; 145 return val;
134} 146}
135 147
136void ar9003_hw_rtt_fill_hist(struct ath_hw *ah, u8 chain, u32 *table) 148void ar9003_hw_rtt_fill_hist(struct ath_hw *ah)
137{ 149{
138 int i; 150 int chain, i;
151
152 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
153 if (!(ah->rxchainmask & (1 << chain)))
154 continue;
155 for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++) {
156 ah->caldata->rtt_table[chain][i] =
157 ar9003_hw_rtt_fill_hist_entry(ah, chain, i);
158 ath_dbg(ath9k_hw_common(ah), CALIBRATE,
159 "RTT value at idx %d, chain %d is: 0x%x\n",
160 i, chain, ah->caldata->rtt_table[chain][i]);
161 }
162 }
139 163
140 for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++) 164 ah->caldata->rtt_done = true;
141 table[i] = ar9003_hw_rtt_fill_hist_entry(ah, chain, i);
142} 165}
143 166
144void ar9003_hw_rtt_clear_hist(struct ath_hw *ah) 167void ar9003_hw_rtt_clear_hist(struct ath_hw *ah)
145{ 168{
146 int i, j; 169 int chain, i;
147 170
148 for (i = 0; i < AR9300_MAX_CHAINS; i++) { 171 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
149 if (!(ah->rxchainmask & (1 << i))) 172 if (!(ah->rxchainmask & (1 << chain)))
150 continue; 173 continue;
151 for (j = 0; j < MAX_RTT_TABLE_ENTRY; j++) 174 for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++)
152 ar9003_hw_rtt_load_hist_entry(ah, i, j, 0); 175 ar9003_hw_rtt_load_hist_entry(ah, chain, i, 0);
153 } 176 }
177
178 if (ah->caldata)
179 ah->caldata->rtt_done = false;
180}
181
182bool ar9003_hw_rtt_restore(struct ath_hw *ah, struct ath9k_channel *chan)
183{
184 bool restore;
185
186 if (!ah->caldata)
187 return false;
188
189 if (!ah->caldata->rtt_done)
190 return false;
191
192 ar9003_hw_rtt_enable(ah);
193 ar9003_hw_rtt_set_mask(ah, 0x10);
194
195 if (!ath9k_hw_rfbus_req(ah)) {
196 ath_err(ath9k_hw_common(ah), "Could not stop baseband\n");
197 restore = false;
198 goto fail;
199 }
200
201 ar9003_hw_rtt_load_hist(ah);
202 restore = ar9003_hw_rtt_force_restore(ah);
203
204fail:
205 ath9k_hw_rfbus_done(ah);
206 ar9003_hw_rtt_disable(ah);
207 return restore;
154} 208}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_rtt.h b/drivers/net/wireless/ath/ath9k/ar9003_rtt.h
index 030758d087d6..a43b30d723a4 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_rtt.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_rtt.h
@@ -21,8 +21,9 @@ void ar9003_hw_rtt_enable(struct ath_hw *ah);
21void ar9003_hw_rtt_disable(struct ath_hw *ah); 21void ar9003_hw_rtt_disable(struct ath_hw *ah);
22void ar9003_hw_rtt_set_mask(struct ath_hw *ah, u32 rtt_mask); 22void ar9003_hw_rtt_set_mask(struct ath_hw *ah, u32 rtt_mask);
23bool ar9003_hw_rtt_force_restore(struct ath_hw *ah); 23bool ar9003_hw_rtt_force_restore(struct ath_hw *ah);
24void ar9003_hw_rtt_load_hist(struct ath_hw *ah, u8 chain, u32 *table); 24void ar9003_hw_rtt_load_hist(struct ath_hw *ah);
25void ar9003_hw_rtt_fill_hist(struct ath_hw *ah, u8 chain, u32 *table); 25void ar9003_hw_rtt_fill_hist(struct ath_hw *ah);
26void ar9003_hw_rtt_clear_hist(struct ath_hw *ah); 26void ar9003_hw_rtt_clear_hist(struct ath_hw *ah);
27bool ar9003_hw_rtt_restore(struct ath_hw *ah, struct ath9k_channel *chan);
27 28
28#endif 29#endif
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index f84477c5ebb1..abe05ec85d50 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1702,10 +1702,10 @@ static int ath9k_hw_do_fastcc(struct ath_hw *ah, struct ath9k_channel *chan)
1702 * For AR9462, make sure that calibration data for 1702 * For AR9462, make sure that calibration data for
1703 * re-using are present. 1703 * re-using are present.
1704 */ 1704 */
1705 if (AR_SREV_9462(ah) && (!ah->caldata || 1705 if (AR_SREV_9462(ah) && (ah->caldata &&
1706 !ah->caldata->done_txiqcal_once || 1706 (!ah->caldata->done_txiqcal_once ||
1707 !ah->caldata->done_txclcal_once || 1707 !ah->caldata->done_txclcal_once ||
1708 !ah->caldata->rtt_hist.num_readings)) 1708 !ah->caldata->rtt_done)))
1709 goto fail; 1709 goto fail;
1710 1710
1711 ath_dbg(common, RESET, "FastChannelChange for %d -> %d\n", 1711 ath_dbg(common, RESET, "FastChannelChange for %d -> %d\n",
@@ -1941,7 +1941,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1941 if (caldata) { 1941 if (caldata) {
1942 caldata->done_txiqcal_once = false; 1942 caldata->done_txiqcal_once = false;
1943 caldata->done_txclcal_once = false; 1943 caldata->done_txclcal_once = false;
1944 caldata->rtt_hist.num_readings = 0;
1945 } 1944 }
1946 if (!ath9k_hw_init_cal(ah, chan)) 1945 if (!ath9k_hw_init_cal(ah, chan))
1947 return -EIO; 1946 return -EIO;
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 828b9bbc456d..b620c557c2a6 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -348,12 +348,6 @@ enum ath9k_int {
348 CHANNEL_HT40MINUS) 348 CHANNEL_HT40MINUS)
349 349
350#define MAX_RTT_TABLE_ENTRY 6 350#define MAX_RTT_TABLE_ENTRY 6
351#define RTT_HIST_MAX 3
352struct ath9k_rtt_hist {
353 u32 table[AR9300_MAX_CHAINS][RTT_HIST_MAX][MAX_RTT_TABLE_ENTRY];
354 u8 num_readings;
355};
356
357#define MAX_IQCAL_MEASUREMENT 8 351#define MAX_IQCAL_MEASUREMENT 8
358#define MAX_CL_TAB_ENTRY 16 352#define MAX_CL_TAB_ENTRY 16
359 353
@@ -363,6 +357,7 @@ struct ath9k_hw_cal_data {
363 int32_t CalValid; 357 int32_t CalValid;
364 int8_t iCoff; 358 int8_t iCoff;
365 int8_t qCoff; 359 int8_t qCoff;
360 bool rtt_done;
366 bool paprd_done; 361 bool paprd_done;
367 bool nfcal_pending; 362 bool nfcal_pending;
368 bool nfcal_interference; 363 bool nfcal_interference;
@@ -373,8 +368,8 @@ struct ath9k_hw_cal_data {
373 u32 num_measures[AR9300_MAX_CHAINS]; 368 u32 num_measures[AR9300_MAX_CHAINS];
374 int tx_corr_coeff[MAX_IQCAL_MEASUREMENT][AR9300_MAX_CHAINS]; 369 int tx_corr_coeff[MAX_IQCAL_MEASUREMENT][AR9300_MAX_CHAINS];
375 u32 tx_clcal[AR9300_MAX_CHAINS][MAX_CL_TAB_ENTRY]; 370 u32 tx_clcal[AR9300_MAX_CHAINS][MAX_CL_TAB_ENTRY];
371 u32 rtt_table[AR9300_MAX_CHAINS][MAX_RTT_TABLE_ENTRY];
376 struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS]; 372 struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
377 struct ath9k_rtt_hist rtt_hist;
378}; 373};
379 374
380struct ath9k_channel { 375struct ath9k_channel {