aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorNick Kossifidis <mickflemm@gmail.com>2011-11-25 13:40:23 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-11-28 14:44:14 -0500
commitce169aca0d823d38465127023e3d571816e6666c (patch)
tree784171700f21de30a04f6154832ce6aca96f2f72 /drivers
parent34ce644aa8342f95eb1e187178f83febade4af37 (diff)
ath5k: Calibration re-work
Noise floor calibration does not interfere with traffic and should run more often as part of our "short calibration". The full calibration is not the noise floor calibration but the AGC + Gain_F (on RF5111 and RF5112) calibration and should run less often because it does interfere with traffic. So Short calibration -> I/Q & NF Calibration Long calibration -> Short + AGC + Gain_F This patch was for some time on my pub/ dir on www.kernel.org and has been tested by a few people and me. I think it's O.K. to go in. I also changed ah_calibration to ah_iq_cal_needed to make more sense. v2 Use a workqueue instead of a tasklet for calibration Signed-off-by: Nick Kossifidis <mickflemm@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/ath/ath5k/ath5k.h15
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c112
-rw-r--r--drivers/net/wireless/ath/ath5k/phy.c82
3 files changed, 147 insertions, 62 deletions
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index b8abdbcfb7b6..3e75d029b0a3 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -187,10 +187,9 @@
187#define AR5K_TUNE_MAX_TXPOWER 63 187#define AR5K_TUNE_MAX_TXPOWER 63
188#define AR5K_TUNE_DEFAULT_TXPOWER 25 188#define AR5K_TUNE_DEFAULT_TXPOWER 25
189#define AR5K_TUNE_TPC_TXPOWER false 189#define AR5K_TUNE_TPC_TXPOWER false
190#define ATH5K_TUNE_CALIBRATION_INTERVAL_FULL 10000 /* 10 sec */ 190#define ATH5K_TUNE_CALIBRATION_INTERVAL_FULL 60000 /* 60 sec */
191#define ATH5K_TUNE_CALIBRATION_INTERVAL_SHORT 10000 /* 10 sec */
191#define ATH5K_TUNE_CALIBRATION_INTERVAL_ANI 1000 /* 1 sec */ 192#define ATH5K_TUNE_CALIBRATION_INTERVAL_ANI 1000 /* 1 sec */
192#define ATH5K_TUNE_CALIBRATION_INTERVAL_NF 60000 /* 60 sec */
193
194#define ATH5K_TX_COMPLETE_POLL_INT 3000 /* 3 sec */ 193#define ATH5K_TX_COMPLETE_POLL_INT 3000 /* 3 sec */
195 194
196#define AR5K_INIT_CARR_SENSE_EN 1 195#define AR5K_INIT_CARR_SENSE_EN 1
@@ -896,7 +895,8 @@ enum ath5k_int {
896enum ath5k_calibration_mask { 895enum ath5k_calibration_mask {
897 AR5K_CALIBRATION_FULL = 0x01, 896 AR5K_CALIBRATION_FULL = 0x01,
898 AR5K_CALIBRATION_SHORT = 0x02, 897 AR5K_CALIBRATION_SHORT = 0x02,
899 AR5K_CALIBRATION_ANI = 0x04, 898 AR5K_CALIBRATION_NF = 0x04,
899 AR5K_CALIBRATION_ANI = 0x08,
900}; 900};
901 901
902/* 902/*
@@ -1098,6 +1098,7 @@ struct ath5k_hw {
1098 led_on; /* pin setting for LED on */ 1098 led_on; /* pin setting for LED on */
1099 1099
1100 struct work_struct reset_work; /* deferred chip reset */ 1100 struct work_struct reset_work; /* deferred chip reset */
1101 struct work_struct calib_work; /* deferred phy calibration */
1101 1102
1102 struct list_head rxbuf; /* receive buffer */ 1103 struct list_head rxbuf; /* receive buffer */
1103 spinlock_t rxbuflock; 1104 spinlock_t rxbuflock;
@@ -1114,8 +1115,6 @@ struct ath5k_hw {
1114 1115
1115 struct ath5k_rfkill rf_kill; 1116 struct ath5k_rfkill rf_kill;
1116 1117
1117 struct tasklet_struct calib; /* calibration tasklet */
1118
1119 spinlock_t block; /* protects beacon */ 1118 spinlock_t block; /* protects beacon */
1120 struct tasklet_struct beacontq; /* beacon intr tasklet */ 1119 struct tasklet_struct beacontq; /* beacon intr tasklet */
1121 struct list_head bcbuf; /* beacon buffer */ 1120 struct list_head bcbuf; /* beacon buffer */
@@ -1145,7 +1144,7 @@ struct ath5k_hw {
1145 enum ath5k_int ah_imr; 1144 enum ath5k_int ah_imr;
1146 1145
1147 struct ieee80211_channel *ah_current_channel; 1146 struct ieee80211_channel *ah_current_channel;
1148 bool ah_calibration; 1147 bool ah_iq_cal_needed;
1149 bool ah_single_chip; 1148 bool ah_single_chip;
1150 1149
1151 enum ath5k_version ah_version; 1150 enum ath5k_version ah_version;
@@ -1235,8 +1234,8 @@ struct ath5k_hw {
1235 1234
1236 /* Calibration timestamp */ 1235 /* Calibration timestamp */
1237 unsigned long ah_cal_next_full; 1236 unsigned long ah_cal_next_full;
1237 unsigned long ah_cal_next_short;
1238 unsigned long ah_cal_next_ani; 1238 unsigned long ah_cal_next_ani;
1239 unsigned long ah_cal_next_nf;
1240 1239
1241 /* Calibration mask */ 1240 /* Calibration mask */
1242 u8 ah_cal_mask; 1241 u8 ah_cal_mask;
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 47194a4e3652..a8cb1c7f4bfe 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -2112,16 +2112,29 @@ static void
2112ath5k_intr_calibration_poll(struct ath5k_hw *ah) 2112ath5k_intr_calibration_poll(struct ath5k_hw *ah)
2113{ 2113{
2114 if (time_is_before_eq_jiffies(ah->ah_cal_next_ani) && 2114 if (time_is_before_eq_jiffies(ah->ah_cal_next_ani) &&
2115 !(ah->ah_cal_mask & AR5K_CALIBRATION_FULL)) { 2115 !(ah->ah_cal_mask & AR5K_CALIBRATION_FULL) &&
2116 /* run ANI only when full calibration is not active */ 2116 !(ah->ah_cal_mask & AR5K_CALIBRATION_SHORT)) {
2117
2118 /* Run ANI only when calibration is not active */
2119
2117 ah->ah_cal_next_ani = jiffies + 2120 ah->ah_cal_next_ani = jiffies +
2118 msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_ANI); 2121 msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_ANI);
2119 tasklet_schedule(&ah->ani_tasklet); 2122 tasklet_schedule(&ah->ani_tasklet);
2120 2123
2121 } else if (time_is_before_eq_jiffies(ah->ah_cal_next_full)) { 2124 } else if (time_is_before_eq_jiffies(ah->ah_cal_next_short) &&
2122 ah->ah_cal_next_full = jiffies + 2125 !(ah->ah_cal_mask & AR5K_CALIBRATION_FULL) &&
2123 msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_FULL); 2126 !(ah->ah_cal_mask & AR5K_CALIBRATION_SHORT)) {
2124 tasklet_schedule(&ah->calib); 2127
2128 /* Run calibration only when another calibration
2129 * is not running.
2130 *
2131 * Note: This is for both full/short calibration,
2132 * if it's time for a full one, ath5k_calibrate_work will deal
2133 * with it. */
2134
2135 ah->ah_cal_next_short = jiffies +
2136 msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_SHORT);
2137 ieee80211_queue_work(ah->hw, &ah->calib_work);
2125 } 2138 }
2126 /* we could use SWI to generate enough interrupts to meet our 2139 /* we could use SWI to generate enough interrupts to meet our
2127 * calibration interval requirements, if necessary: 2140 * calibration interval requirements, if necessary:
@@ -2286,41 +2299,58 @@ ath5k_intr(int irq, void *dev_id)
2286 * for temperature/environment changes. 2299 * for temperature/environment changes.
2287 */ 2300 */
2288static void 2301static void
2289ath5k_tasklet_calibrate(unsigned long data) 2302ath5k_calibrate_work(struct work_struct *work)
2290{ 2303{
2291 struct ath5k_hw *ah = (void *)data; 2304 struct ath5k_hw *ah = container_of(work, struct ath5k_hw,
2305 calib_work);
2306
2307 /* Should we run a full calibration ? */
2308 if (time_is_before_eq_jiffies(ah->ah_cal_next_full)) {
2309
2310 ah->ah_cal_next_full = jiffies +
2311 msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_FULL);
2312 ah->ah_cal_mask |= AR5K_CALIBRATION_FULL;
2313
2314 ATH5K_DBG(ah, ATH5K_DEBUG_CALIBRATE,
2315 "running full calibration\n");
2316
2317 if (ath5k_hw_gainf_calibrate(ah) == AR5K_RFGAIN_NEED_CHANGE) {
2318 /*
2319 * Rfgain is out of bounds, reset the chip
2320 * to load new gain values.
2321 */
2322 ATH5K_DBG(ah, ATH5K_DEBUG_RESET,
2323 "got new rfgain, resetting\n");
2324 ieee80211_queue_work(ah->hw, &ah->reset_work);
2325 }
2326
2327 /* TODO: On full calibration we should stop TX here,
2328 * so that it doesn't interfere (mostly due to gain_f
2329 * calibration that messes with tx packets -see phy.c).
2330 *
2331 * NOTE: Stopping the queues from above is not enough
2332 * to stop TX but saves us from disconecting (at least
2333 * we don't lose packets). */
2334 ieee80211_stop_queues(ah->hw);
2335 } else
2336 ah->ah_cal_mask |= AR5K_CALIBRATION_SHORT;
2292 2337
2293 /* Only full calibration for now */
2294 ah->ah_cal_mask |= AR5K_CALIBRATION_FULL;
2295 2338
2296 ATH5K_DBG(ah, ATH5K_DEBUG_CALIBRATE, "channel %u/%x\n", 2339 ATH5K_DBG(ah, ATH5K_DEBUG_CALIBRATE, "channel %u/%x\n",
2297 ieee80211_frequency_to_channel(ah->curchan->center_freq), 2340 ieee80211_frequency_to_channel(ah->curchan->center_freq),
2298 ah->curchan->hw_value); 2341 ah->curchan->hw_value);
2299 2342
2300 if (ath5k_hw_gainf_calibrate(ah) == AR5K_RFGAIN_NEED_CHANGE) {
2301 /*
2302 * Rfgain is out of bounds, reset the chip
2303 * to load new gain values.
2304 */
2305 ATH5K_DBG(ah, ATH5K_DEBUG_RESET, "calibration, resetting\n");
2306 ieee80211_queue_work(ah->hw, &ah->reset_work);
2307 }
2308 if (ath5k_hw_phy_calibrate(ah, ah->curchan)) 2343 if (ath5k_hw_phy_calibrate(ah, ah->curchan))
2309 ATH5K_ERR(ah, "calibration of channel %u failed\n", 2344 ATH5K_ERR(ah, "calibration of channel %u failed\n",
2310 ieee80211_frequency_to_channel( 2345 ieee80211_frequency_to_channel(
2311 ah->curchan->center_freq)); 2346 ah->curchan->center_freq));
2312 2347
2313 /* Noise floor calibration interrupts rx/tx path while I/Q calibration 2348 /* Clear calibration flags */
2314 * doesn't. 2349 if (ah->ah_cal_mask & AR5K_CALIBRATION_FULL) {
2315 * TODO: We should stop TX here, so that it doesn't interfere. 2350 ieee80211_wake_queues(ah->hw);
2316 * Note that stopping the queues is not enough to stop TX! */ 2351 ah->ah_cal_mask &= ~AR5K_CALIBRATION_FULL;
2317 if (time_is_before_eq_jiffies(ah->ah_cal_next_nf)) { 2352 } else if (ah->ah_cal_mask & AR5K_CALIBRATION_SHORT)
2318 ah->ah_cal_next_nf = jiffies + 2353 ah->ah_cal_mask &= ~AR5K_CALIBRATION_SHORT;
2319 msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_NF);
2320 ath5k_hw_update_noise_floor(ah);
2321 }
2322
2323 ah->ah_cal_mask &= ~AR5K_CALIBRATION_FULL;
2324} 2354}
2325 2355
2326 2356
@@ -2639,7 +2669,6 @@ static void ath5k_stop_tasklets(struct ath5k_hw *ah)
2639 ah->tx_pending = false; 2669 ah->tx_pending = false;
2640 tasklet_kill(&ah->rxtq); 2670 tasklet_kill(&ah->rxtq);
2641 tasklet_kill(&ah->txtq); 2671 tasklet_kill(&ah->txtq);
2642 tasklet_kill(&ah->calib);
2643 tasklet_kill(&ah->beacontq); 2672 tasklet_kill(&ah->beacontq);
2644 tasklet_kill(&ah->ani_tasklet); 2673 tasklet_kill(&ah->ani_tasklet);
2645} 2674}
@@ -2743,9 +2772,24 @@ ath5k_reset(struct ath5k_hw *ah, struct ieee80211_channel *chan,
2743 2772
2744 ath5k_ani_init(ah, ani_mode); 2773 ath5k_ani_init(ah, ani_mode);
2745 2774
2746 ah->ah_cal_next_full = jiffies + msecs_to_jiffies(100); 2775 /*
2747 ah->ah_cal_next_ani = jiffies; 2776 * Set calibration intervals
2748 ah->ah_cal_next_nf = jiffies; 2777 *
2778 * Note: We don't need to run calibration imediately
2779 * since some initial calibration is done on reset
2780 * even for fast channel switching. Also on scanning
2781 * this will get set again and again and it won't get
2782 * executed unless we connect somewhere and spend some
2783 * time on the channel (that's what calibration needs
2784 * anyway to be accurate).
2785 */
2786 ah->ah_cal_next_full = jiffies +
2787 msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_FULL);
2788 ah->ah_cal_next_ani = jiffies +
2789 msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_ANI);
2790 ah->ah_cal_next_short = jiffies +
2791 msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_SHORT);
2792
2749 ewma_init(&ah->ah_beacon_rssi_avg, 1024, 8); 2793 ewma_init(&ah->ah_beacon_rssi_avg, 1024, 8);
2750 2794
2751 /* clear survey data and cycle counters */ 2795 /* clear survey data and cycle counters */
@@ -2895,11 +2939,11 @@ ath5k_init(struct ieee80211_hw *hw)
2895 2939
2896 tasklet_init(&ah->rxtq, ath5k_tasklet_rx, (unsigned long)ah); 2940 tasklet_init(&ah->rxtq, ath5k_tasklet_rx, (unsigned long)ah);
2897 tasklet_init(&ah->txtq, ath5k_tasklet_tx, (unsigned long)ah); 2941 tasklet_init(&ah->txtq, ath5k_tasklet_tx, (unsigned long)ah);
2898 tasklet_init(&ah->calib, ath5k_tasklet_calibrate, (unsigned long)ah);
2899 tasklet_init(&ah->beacontq, ath5k_tasklet_beacon, (unsigned long)ah); 2942 tasklet_init(&ah->beacontq, ath5k_tasklet_beacon, (unsigned long)ah);
2900 tasklet_init(&ah->ani_tasklet, ath5k_tasklet_ani, (unsigned long)ah); 2943 tasklet_init(&ah->ani_tasklet, ath5k_tasklet_ani, (unsigned long)ah);
2901 2944
2902 INIT_WORK(&ah->reset_work, ath5k_reset_work); 2945 INIT_WORK(&ah->reset_work, ath5k_reset_work);
2946 INIT_WORK(&ah->calib_work, ath5k_calibrate_work);
2903 INIT_DELAYED_WORK(&ah->tx_complete_work, ath5k_tx_complete_poll_work); 2947 INIT_DELAYED_WORK(&ah->tx_complete_work, ath5k_tx_complete_poll_work);
2904 2948
2905 ret = ath5k_hw_common(ah)->bus_ops->eeprom_read_mac(ah, mac); 2949 ret = ath5k_hw_common(ah)->bus_ops->eeprom_read_mac(ah, mac);
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index 01cb72de44cb..ca4241d2a774 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -338,9 +338,6 @@ static void ath5k_hw_wait_for_synth(struct ath5k_hw *ah,
338 * And this is the MadWiFi bug entry related to the above 338 * And this is the MadWiFi bug entry related to the above
339 * http://madwifi-project.org/ticket/1659 339 * http://madwifi-project.org/ticket/1659
340 * with various measurements and diagrams 340 * with various measurements and diagrams
341 *
342 * TODO: Deal with power drops due to probes by setting an appropriate
343 * tx power on the probe packets ! Make this part of the calibration process.
344 */ 341 */
345 342
346/* Initialize ah_gain during attach */ 343/* Initialize ah_gain during attach */
@@ -372,10 +369,9 @@ int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah)
372 * tx power and a Peak to Average Power Detector (PAPD) will try 369 * tx power and a Peak to Average Power Detector (PAPD) will try
373 * to measure the gain. 370 * to measure the gain.
374 * 371 *
375 * XXX: How about forcing a tx packet (bypassing PCU arbitrator etc) 372 * TODO: Force a tx packet (bypassing PCU arbitrator etc)
376 * just after we enable the probe so that we don't mess with 373 * just after we enable the probe so that we don't mess with
377 * standard traffic ? Maybe it's time to use sw interrupts and 374 * standard traffic.
378 * a probe tasklet !!!
379 */ 375 */
380static void ath5k_hw_request_rfgain_probe(struct ath5k_hw *ah) 376static void ath5k_hw_request_rfgain_probe(struct ath5k_hw *ah)
381{ 377{
@@ -575,9 +571,7 @@ done:
575/* Main callback for thermal RF gain calibration engine 571/* Main callback for thermal RF gain calibration engine
576 * Check for a new gain reading and schedule an adjustment 572 * Check for a new gain reading and schedule an adjustment
577 * if needed. 573 * if needed.
578 * 574 */
579 * TODO: Use sw interrupt to schedule reset if gain_F needs
580 * adjustment */
581enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah) 575enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah)
582{ 576{
583 u32 data, type; 577 u32 data, type;
@@ -1390,6 +1384,8 @@ void ath5k_hw_update_noise_floor(struct ath5k_hw *ah)
1390 return; 1384 return;
1391 } 1385 }
1392 1386
1387 ah->ah_cal_mask |= AR5K_CALIBRATION_NF;
1388
1393 ee_mode = ath5k_eeprom_mode_from_channel(ah->ah_current_channel); 1389 ee_mode = ath5k_eeprom_mode_from_channel(ah->ah_current_channel);
1394 1390
1395 /* completed NF calibration, test threshold */ 1391 /* completed NF calibration, test threshold */
@@ -1434,6 +1430,8 @@ void ath5k_hw_update_noise_floor(struct ath5k_hw *ah)
1434 1430
1435 ah->ah_noise_floor = nf; 1431 ah->ah_noise_floor = nf;
1436 1432
1433 ah->ah_cal_mask &= ~AR5K_CALIBRATION_NF;
1434
1437 ATH5K_DBG(ah, ATH5K_DEBUG_CALIBRATE, 1435 ATH5K_DBG(ah, ATH5K_DEBUG_CALIBRATE,
1438 "noise floor calibrated: %d\n", nf); 1436 "noise floor calibrated: %d\n", nf);
1439} 1437}
@@ -1547,12 +1545,19 @@ ath5k_hw_rf511x_iq_calibrate(struct ath5k_hw *ah)
1547 s32 iq_corr, i_coff, i_coffd, q_coff, q_coffd; 1545 s32 iq_corr, i_coff, i_coffd, q_coff, q_coffd;
1548 int i; 1546 int i;
1549 1547
1550 if (!ah->ah_calibration || 1548 /* Skip if I/Q calibration is not needed or if it's still running */
1551 ath5k_hw_reg_read(ah, AR5K_PHY_IQ) & AR5K_PHY_IQ_RUN) 1549 if (!ah->ah_iq_cal_needed)
1552 return 0; 1550 return -EINVAL;
1551 else if (ath5k_hw_reg_read(ah, AR5K_PHY_IQ) & AR5K_PHY_IQ_RUN) {
1552 ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_CALIBRATE,
1553 "I/Q calibration still running");
1554 return -EBUSY;
1555 }
1553 1556
1554 /* Calibration has finished, get the results and re-run */ 1557 /* Calibration has finished, get the results and re-run */
1555 /* work around empty results which can apparently happen on 5212 */ 1558
1559 /* Work around for empty results which can apparently happen on 5212:
1560 * Read registers up to 10 times until we get both i_pr and q_pwr */
1556 for (i = 0; i <= 10; i++) { 1561 for (i = 0; i <= 10; i++) {
1557 iq_corr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_CORR); 1562 iq_corr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_CORR);
1558 i_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_I); 1563 i_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_I);
@@ -1570,9 +1575,13 @@ ath5k_hw_rf511x_iq_calibrate(struct ath5k_hw *ah)
1570 else 1575 else
1571 q_coffd = q_pwr >> 7; 1576 q_coffd = q_pwr >> 7;
1572 1577
1573 /* protect against divide by 0 and loss of sign bits */ 1578 /* In case i_coffd became zero, cancel calibration
1579 * not only it's too small, it'll also result a divide
1580 * by zero later on. */
1574 if (i_coffd == 0 || q_coffd < 2) 1581 if (i_coffd == 0 || q_coffd < 2)
1575 return 0; 1582 return -ECANCELED;
1583
1584 /* Protect against loss of sign bits */
1576 1585
1577 i_coff = (-iq_corr) / i_coffd; 1586 i_coff = (-iq_corr) / i_coffd;
1578 i_coff = clamp(i_coff, -32, 31); /* signed 6 bit */ 1587 i_coff = clamp(i_coff, -32, 31); /* signed 6 bit */
@@ -1613,10 +1622,43 @@ int ath5k_hw_phy_calibrate(struct ath5k_hw *ah,
1613 return ath5k_hw_rf5110_calibrate(ah, channel); 1622 return ath5k_hw_rf5110_calibrate(ah, channel);
1614 1623
1615 ret = ath5k_hw_rf511x_iq_calibrate(ah); 1624 ret = ath5k_hw_rf511x_iq_calibrate(ah);
1625 if (ret) {
1626 ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_CALIBRATE,
1627 "No I/Q correction performed (%uMHz)\n",
1628 channel->center_freq);
1629
1630 /* Happens all the time if there is not much
1631 * traffic, consider it normal behaviour. */
1632 ret = 0;
1633 }
1634
1635 /* On full calibration do an AGC calibration and
1636 * request a PAPD probe for gainf calibration if
1637 * needed */
1638 if (ah->ah_cal_mask & AR5K_CALIBRATION_FULL) {
1639
1640 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
1641 AR5K_PHY_AGCCTL_CAL);
1642
1643 ret = ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
1644 AR5K_PHY_AGCCTL_CAL | AR5K_PHY_AGCCTL_NF,
1645 0, false);
1646 if (ret) {
1647 ATH5K_ERR(ah,
1648 "gain calibration timeout (%uMHz)\n",
1649 channel->center_freq);
1650 }
1651
1652 if ((ah->ah_radio == AR5K_RF5111 ||
1653 ah->ah_radio == AR5K_RF5112)
1654 && (channel->hw_value != AR5K_MODE_11B))
1655 ath5k_hw_request_rfgain_probe(ah);
1656 }
1616 1657
1617 if ((ah->ah_radio == AR5K_RF5111 || ah->ah_radio == AR5K_RF5112) && 1658 /* Update noise floor
1618 (channel->hw_value != AR5K_MODE_11B)) 1659 * XXX: Only do this after AGC calibration */
1619 ath5k_hw_request_rfgain_probe(ah); 1660 if (!(ah->ah_cal_mask & AR5K_CALIBRATION_NF))
1661 ath5k_hw_update_noise_floor(ah);
1620 1662
1621 return ret; 1663 return ret;
1622} 1664}
@@ -3433,9 +3475,9 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
3433 3475
3434 /* At the same time start I/Q calibration for QAM constellation 3476 /* At the same time start I/Q calibration for QAM constellation
3435 * -no need for CCK- */ 3477 * -no need for CCK- */
3436 ah->ah_calibration = false; 3478 ah->ah_iq_cal_needed = false;
3437 if (!(mode == AR5K_MODE_11B)) { 3479 if (!(mode == AR5K_MODE_11B)) {
3438 ah->ah_calibration = true; 3480 ah->ah_iq_cal_needed = true;
3439 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, 3481 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ,
3440 AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15); 3482 AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15);
3441 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, 3483 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,