aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/ath/ath9k/ar5008_phy.c81
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c110
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.c94
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/hw-ops.h6
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h3
6 files changed, 114 insertions, 181 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index 48c5a5f38caf..4a910b78de52 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -1516,77 +1516,6 @@ static void ar5008_hw_do_getnf(struct ath_hw *ah,
1516 nfarray[5] = sign_extend(nf, 9); 1516 nfarray[5] = sign_extend(nf, 9);
1517} 1517}
1518 1518
1519static void ar5008_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
1520{
1521 struct ath9k_nfcal_hist *h;
1522 int i, j;
1523 int32_t val;
1524 const u32 ar5416_cca_regs[6] = {
1525 AR_PHY_CCA,
1526 AR_PHY_CH1_CCA,
1527 AR_PHY_CH2_CCA,
1528 AR_PHY_EXT_CCA,
1529 AR_PHY_CH1_EXT_CCA,
1530 AR_PHY_CH2_EXT_CCA
1531 };
1532 u8 chainmask, rx_chain_status;
1533
1534 rx_chain_status = REG_READ(ah, AR_PHY_RX_CHAINMASK);
1535 if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
1536 chainmask = 0x9;
1537 else if (AR_SREV_9280(ah) || AR_SREV_9287(ah)) {
1538 if ((rx_chain_status & 0x2) || (rx_chain_status & 0x4))
1539 chainmask = 0x1B;
1540 else
1541 chainmask = 0x09;
1542 } else {
1543 if (rx_chain_status & 0x4)
1544 chainmask = 0x3F;
1545 else if (rx_chain_status & 0x2)
1546 chainmask = 0x1B;
1547 else
1548 chainmask = 0x09;
1549 }
1550
1551 h = ah->nfCalHist;
1552
1553 for (i = 0; i < NUM_NF_READINGS; i++) {
1554 if (chainmask & (1 << i)) {
1555 val = REG_READ(ah, ar5416_cca_regs[i]);
1556 val &= 0xFFFFFE00;
1557 val |= (((u32) (h[i].privNF) << 1) & 0x1ff);
1558 REG_WRITE(ah, ar5416_cca_regs[i], val);
1559 }
1560 }
1561
1562 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
1563 AR_PHY_AGC_CONTROL_ENABLE_NF);
1564 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
1565 AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
1566 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
1567
1568 for (j = 0; j < 5; j++) {
1569 if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
1570 AR_PHY_AGC_CONTROL_NF) == 0)
1571 break;
1572 udelay(50);
1573 }
1574
1575 ENABLE_REGWRITE_BUFFER(ah);
1576
1577 for (i = 0; i < NUM_NF_READINGS; i++) {
1578 if (chainmask & (1 << i)) {
1579 val = REG_READ(ah, ar5416_cca_regs[i]);
1580 val &= 0xFFFFFE00;
1581 val |= (((u32) (-50) << 1) & 0x1ff);
1582 REG_WRITE(ah, ar5416_cca_regs[i], val);
1583 }
1584 }
1585
1586 REGWRITE_BUFFER_FLUSH(ah);
1587 DISABLE_REGWRITE_BUFFER(ah);
1588}
1589
1590/* 1519/*
1591 * Initialize the ANI register values with default (ini) values. 1520 * Initialize the ANI register values with default (ini) values.
1592 * This routine is called during a (full) hardware reset after 1521 * This routine is called during a (full) hardware reset after
@@ -1664,6 +1593,14 @@ static void ar5008_hw_set_nf_limits(struct ath_hw *ah)
1664void ar5008_hw_attach_phy_ops(struct ath_hw *ah) 1593void ar5008_hw_attach_phy_ops(struct ath_hw *ah)
1665{ 1594{
1666 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); 1595 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
1596 const u32 ar5416_cca_regs[6] = {
1597 AR_PHY_CCA,
1598 AR_PHY_CH1_CCA,
1599 AR_PHY_CH2_CCA,
1600 AR_PHY_EXT_CCA,
1601 AR_PHY_CH1_EXT_CCA,
1602 AR_PHY_CH2_EXT_CCA
1603 };
1667 1604
1668 priv_ops->rf_set_freq = ar5008_hw_set_channel; 1605 priv_ops->rf_set_freq = ar5008_hw_set_channel;
1669 priv_ops->spur_mitigate_freq = ar5008_hw_spur_mitigate; 1606 priv_ops->spur_mitigate_freq = ar5008_hw_spur_mitigate;
@@ -1683,7 +1620,6 @@ void ar5008_hw_attach_phy_ops(struct ath_hw *ah)
1683 priv_ops->restore_chainmask = ar5008_restore_chainmask; 1620 priv_ops->restore_chainmask = ar5008_restore_chainmask;
1684 priv_ops->set_diversity = ar5008_set_diversity; 1621 priv_ops->set_diversity = ar5008_set_diversity;
1685 priv_ops->do_getnf = ar5008_hw_do_getnf; 1622 priv_ops->do_getnf = ar5008_hw_do_getnf;
1686 priv_ops->loadnf = ar5008_hw_loadnf;
1687 1623
1688 if (modparam_force_new_ani) { 1624 if (modparam_force_new_ani) {
1689 priv_ops->ani_control = ar5008_hw_ani_control_new; 1625 priv_ops->ani_control = ar5008_hw_ani_control_new;
@@ -1699,4 +1635,5 @@ void ar5008_hw_attach_phy_ops(struct ath_hw *ah)
1699 priv_ops->compute_pll_control = ar5008_hw_compute_pll_control; 1635 priv_ops->compute_pll_control = ar5008_hw_compute_pll_control;
1700 1636
1701 ar5008_hw_set_nf_limits(ah); 1637 ar5008_hw_set_nf_limits(ah);
1638 memcpy(ah->nf_regs, ar5416_cca_regs, sizeof(ah->nf_regs));
1702} 1639}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index 868b24ab347a..7c93338540ae 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -1050,106 +1050,6 @@ static void ar9003_hw_set_nf_limits(struct ath_hw *ah)
1050} 1050}
1051 1051
1052/* 1052/*
1053 * Find out which of the RX chains are enabled
1054 */
1055static u32 ar9003_hw_get_rx_chainmask(struct ath_hw *ah)
1056{
1057 u32 chain = REG_READ(ah, AR_PHY_RX_CHAINMASK);
1058 /*
1059 * The bits [2:0] indicate the rx chain mask and are to be
1060 * interpreted as follows:
1061 * 00x => Only chain 0 is enabled
1062 * 01x => Chain 1 and 0 enabled
1063 * 1xx => Chain 2,1 and 0 enabled
1064 */
1065 return chain & 0x7;
1066}
1067
1068static void ar9003_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
1069{
1070 struct ath9k_nfcal_hist *h;
1071 unsigned i, j;
1072 int32_t val;
1073 const u32 ar9300_cca_regs[6] = {
1074 AR_PHY_CCA_0,
1075 AR_PHY_CCA_1,
1076 AR_PHY_CCA_2,
1077 AR_PHY_EXT_CCA,
1078 AR_PHY_EXT_CCA_1,
1079 AR_PHY_EXT_CCA_2,
1080 };
1081 u8 chainmask, rx_chain_status;
1082 struct ath_common *common = ath9k_hw_common(ah);
1083
1084 rx_chain_status = ar9003_hw_get_rx_chainmask(ah);
1085
1086 chainmask = 0x3F;
1087 h = ah->nfCalHist;
1088
1089 for (i = 0; i < NUM_NF_READINGS; i++) {
1090 if (chainmask & (1 << i)) {
1091 val = REG_READ(ah, ar9300_cca_regs[i]);
1092 val &= 0xFFFFFE00;
1093 val |= (((u32) (h[i].privNF) << 1) & 0x1ff);
1094 REG_WRITE(ah, ar9300_cca_regs[i], val);
1095 }
1096 }
1097
1098 /*
1099 * Load software filtered NF value into baseband internal minCCApwr
1100 * variable.
1101 */
1102 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
1103 AR_PHY_AGC_CONTROL_ENABLE_NF);
1104 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
1105 AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
1106 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
1107
1108 /*
1109 * Wait for load to complete, should be fast, a few 10s of us.
1110 * The max delay was changed from an original 250us to 10000us
1111 * since 250us often results in NF load timeout and causes deaf
1112 * condition during stress testing 12/12/2009
1113 */
1114 for (j = 0; j < 1000; j++) {
1115 if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
1116 AR_PHY_AGC_CONTROL_NF) == 0)
1117 break;
1118 udelay(10);
1119 }
1120
1121 /*
1122 * We timed out waiting for the noisefloor to load, probably due to an
1123 * in-progress rx. Simply return here and allow the load plenty of time
1124 * to complete before the next calibration interval. We need to avoid
1125 * trying to load -50 (which happens below) while the previous load is
1126 * still in progress as this can cause rx deafness. Instead by returning
1127 * here, the baseband nf cal will just be capped by our present
1128 * noisefloor until the next calibration timer.
1129 */
1130 if (j == 1000) {
1131 ath_print(common, ATH_DBG_ANY, "Timeout while waiting for nf "
1132 "to load: AR_PHY_AGC_CONTROL=0x%x\n",
1133 REG_READ(ah, AR_PHY_AGC_CONTROL));
1134 return;
1135 }
1136
1137 /*
1138 * Restore maxCCAPower register parameter again so that we're not capped
1139 * by the median we just loaded. This will be initial (and max) value
1140 * of next noise floor calibration the baseband does.
1141 */
1142 for (i = 0; i < NUM_NF_READINGS; i++) {
1143 if (chainmask & (1 << i)) {
1144 val = REG_READ(ah, ar9300_cca_regs[i]);
1145 val &= 0xFFFFFE00;
1146 val |= (((u32) (-50) << 1) & 0x1ff);
1147 REG_WRITE(ah, ar9300_cca_regs[i], val);
1148 }
1149 }
1150}
1151
1152/*
1153 * Initialize the ANI register values with default (ini) values. 1053 * Initialize the ANI register values with default (ini) values.
1154 * This routine is called during a (full) hardware reset after 1054 * This routine is called during a (full) hardware reset after
1155 * all the registers are initialised from the INI. 1055 * all the registers are initialised from the INI.
@@ -1216,6 +1116,14 @@ static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah)
1216void ar9003_hw_attach_phy_ops(struct ath_hw *ah) 1116void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
1217{ 1117{
1218 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); 1118 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
1119 const u32 ar9300_cca_regs[6] = {
1120 AR_PHY_CCA_0,
1121 AR_PHY_CCA_1,
1122 AR_PHY_CCA_2,
1123 AR_PHY_EXT_CCA,
1124 AR_PHY_EXT_CCA_1,
1125 AR_PHY_EXT_CCA_2,
1126 };
1219 1127
1220 priv_ops->rf_set_freq = ar9003_hw_set_channel; 1128 priv_ops->rf_set_freq = ar9003_hw_set_channel;
1221 priv_ops->spur_mitigate_freq = ar9003_hw_spur_mitigate; 1129 priv_ops->spur_mitigate_freq = ar9003_hw_spur_mitigate;
@@ -1232,10 +1140,10 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
1232 priv_ops->set_diversity = ar9003_hw_set_diversity; 1140 priv_ops->set_diversity = ar9003_hw_set_diversity;
1233 priv_ops->ani_control = ar9003_hw_ani_control; 1141 priv_ops->ani_control = ar9003_hw_ani_control;
1234 priv_ops->do_getnf = ar9003_hw_do_getnf; 1142 priv_ops->do_getnf = ar9003_hw_do_getnf;
1235 priv_ops->loadnf = ar9003_hw_loadnf;
1236 priv_ops->ani_cache_ini_regs = ar9003_hw_ani_cache_ini_regs; 1143 priv_ops->ani_cache_ini_regs = ar9003_hw_ani_cache_ini_regs;
1237 1144
1238 ar9003_hw_set_nf_limits(ah); 1145 ar9003_hw_set_nf_limits(ah);
1146 memcpy(ah->nf_regs, ar9300_cca_regs, sizeof(ah->nf_regs));
1239} 1147}
1240 1148
1241void ar9003_hw_bb_watchdog_config(struct ath_hw *ah) 1149void ar9003_hw_bb_watchdog_config(struct ath_hw *ah)
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index cc29ef78d1bf..7f4c55f90e74 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -167,6 +167,100 @@ void ath9k_hw_start_nfcal(struct ath_hw *ah)
167 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF); 167 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
168} 168}
169 169
170void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
171{
172 struct ath9k_nfcal_hist *h;
173 unsigned i, j;
174 int32_t val;
175 u8 chainmask;
176 struct ath_common *common = ath9k_hw_common(ah);
177
178 if (AR_SREV_9300_20_OR_LATER(ah))
179 chainmask = 0x3F;
180 else if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
181 chainmask = 0x9;
182 else if (AR_SREV_9280(ah) || AR_SREV_9287(ah)) {
183 if ((ah->rxchainmask & 0x2) || (ah->rxchainmask & 0x4))
184 chainmask = 0x1B;
185 else
186 chainmask = 0x09;
187 } else {
188 if (ah->rxchainmask & 0x4)
189 chainmask = 0x3F;
190 else if (ah->rxchainmask & 0x2)
191 chainmask = 0x1B;
192 else
193 chainmask = 0x09;
194 }
195 h = ah->nfCalHist;
196
197 for (i = 0; i < NUM_NF_READINGS; i++) {
198 if (chainmask & (1 << i)) {
199 val = REG_READ(ah, ah->nf_regs[i]);
200 val &= 0xFFFFFE00;
201 val |= (((u32) (h[i].privNF) << 1) & 0x1ff);
202 REG_WRITE(ah, ah->nf_regs[i], val);
203 }
204 }
205
206 /*
207 * Load software filtered NF value into baseband internal minCCApwr
208 * variable.
209 */
210 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
211 AR_PHY_AGC_CONTROL_ENABLE_NF);
212 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
213 AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
214 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
215
216 /*
217 * Wait for load to complete, should be fast, a few 10s of us.
218 * The max delay was changed from an original 250us to 10000us
219 * since 250us often results in NF load timeout and causes deaf
220 * condition during stress testing 12/12/2009
221 */
222 for (j = 0; j < 1000; j++) {
223 if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
224 AR_PHY_AGC_CONTROL_NF) == 0)
225 break;
226 udelay(10);
227 }
228
229 /*
230 * We timed out waiting for the noisefloor to load, probably due to an
231 * in-progress rx. Simply return here and allow the load plenty of time
232 * to complete before the next calibration interval. We need to avoid
233 * trying to load -50 (which happens below) while the previous load is
234 * still in progress as this can cause rx deafness. Instead by returning
235 * here, the baseband nf cal will just be capped by our present
236 * noisefloor until the next calibration timer.
237 */
238 if (j == 1000) {
239 ath_print(common, ATH_DBG_ANY, "Timeout while waiting for nf "
240 "to load: AR_PHY_AGC_CONTROL=0x%x\n",
241 REG_READ(ah, AR_PHY_AGC_CONTROL));
242 return;
243 }
244
245 /*
246 * Restore maxCCAPower register parameter again so that we're not capped
247 * by the median we just loaded. This will be initial (and max) value
248 * of next noise floor calibration the baseband does.
249 */
250 ENABLE_REGWRITE_BUFFER(ah);
251 for (i = 0; i < NUM_NF_READINGS; i++) {
252 if (chainmask & (1 << i)) {
253 val = REG_READ(ah, ah->nf_regs[i]);
254 val &= 0xFFFFFE00;
255 val |= (((u32) (-50) << 1) & 0x1ff);
256 REG_WRITE(ah, ah->nf_regs[i], val);
257 }
258 }
259 REGWRITE_BUFFER_FLUSH(ah);
260 DISABLE_REGWRITE_BUFFER(ah);
261}
262
263
170static void ath9k_hw_nf_sanitize(struct ath_hw *ah, s16 *nf) 264static void ath9k_hw_nf_sanitize(struct ath_hw *ah, s16 *nf)
171{ 265{
172 struct ath_common *common = ath9k_hw_common(ah); 266 struct ath_common *common = ath9k_hw_common(ah);
diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h
index ca4638d500b8..cd60d09cdda7 100644
--- a/drivers/net/wireless/ath/ath9k/calib.h
+++ b/drivers/net/wireless/ath/ath9k/calib.h
@@ -109,6 +109,7 @@ struct ath9k_pacal_info{
109 109
110bool ath9k_hw_reset_calvalid(struct ath_hw *ah); 110bool ath9k_hw_reset_calvalid(struct ath_hw *ah);
111void ath9k_hw_start_nfcal(struct ath_hw *ah); 111void ath9k_hw_start_nfcal(struct ath_hw *ah);
112void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan);
112int16_t ath9k_hw_getnf(struct ath_hw *ah, 113int16_t ath9k_hw_getnf(struct ath_hw *ah,
113 struct ath9k_channel *chan); 114 struct ath9k_channel *chan);
114void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah); 115void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah);
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h
index 381da6c93b14..ffecbadaea4a 100644
--- a/drivers/net/wireless/ath/ath9k/hw-ops.h
+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
@@ -264,12 +264,6 @@ static inline void ath9k_hw_do_getnf(struct ath_hw *ah,
264 ath9k_hw_private_ops(ah)->do_getnf(ah, nfarray); 264 ath9k_hw_private_ops(ah)->do_getnf(ah, nfarray);
265} 265}
266 266
267static inline void ath9k_hw_loadnf(struct ath_hw *ah,
268 struct ath9k_channel *chan)
269{
270 ath9k_hw_private_ops(ah)->loadnf(ah, chan);
271}
272
273static inline bool ath9k_hw_init_cal(struct ath_hw *ah, 267static inline bool ath9k_hw_init_cal(struct ath_hw *ah,
274 struct ath9k_channel *chan) 268 struct ath9k_channel *chan)
275{ 269{
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 92e2502caafa..2d30efc0b94f 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -510,7 +510,6 @@ struct ath_gen_timer_table {
510 * AR_RTC_PLL_CONTROL for a given channel 510 * AR_RTC_PLL_CONTROL for a given channel
511 * @setup_calibration: set up calibration 511 * @setup_calibration: set up calibration
512 * @iscal_supported: used to query if a type of calibration is supported 512 * @iscal_supported: used to query if a type of calibration is supported
513 * @loadnf: load noise floor read from each chain on the CCA registers
514 * 513 *
515 * @ani_reset: reset ANI parameters to default values 514 * @ani_reset: reset ANI parameters to default values
516 * @ani_lower_immunity: lower the noise immunity level. The level controls 515 * @ani_lower_immunity: lower the noise immunity level. The level controls
@@ -564,7 +563,6 @@ struct ath_hw_private_ops {
564 bool (*ani_control)(struct ath_hw *ah, enum ath9k_ani_cmd cmd, 563 bool (*ani_control)(struct ath_hw *ah, enum ath9k_ani_cmd cmd,
565 int param); 564 int param);
566 void (*do_getnf)(struct ath_hw *ah, int16_t nfarray[NUM_NF_READINGS]); 565 void (*do_getnf)(struct ath_hw *ah, int16_t nfarray[NUM_NF_READINGS]);
567 void (*loadnf)(struct ath_hw *ah, struct ath9k_channel *chan);
568 566
569 /* ANI */ 567 /* ANI */
570 void (*ani_reset)(struct ath_hw *ah, bool is_scanning); 568 void (*ani_reset)(struct ath_hw *ah, bool is_scanning);
@@ -658,6 +656,7 @@ struct ath_hw {
658 bool need_an_top2_fixup; 656 bool need_an_top2_fixup;
659 u16 tx_trig_level; 657 u16 tx_trig_level;
660 658
659 u32 nf_regs[6];
661 struct ath_nf_limits nf_2g; 660 struct ath_nf_limits nf_2g;
662 struct ath_nf_limits nf_5g; 661 struct ath_nf_limits nf_5g;
663 u16 rfsilent; 662 u16 rfsilent;