0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include "ath9k.h"
0018
0019
0020
0021
0022
0023 static bool ath_tx_complete_check(struct ath_softc *sc)
0024 {
0025 struct ath_txq *txq;
0026 int i;
0027
0028 if (sc->tx99_state)
0029 return true;
0030
0031 for (i = 0; i < IEEE80211_NUM_ACS; i++) {
0032 txq = sc->tx.txq_map[i];
0033
0034 ath_txq_lock(sc, txq);
0035 if (txq->axq_depth) {
0036 if (txq->axq_tx_inprogress) {
0037 ath_txq_unlock(sc, txq);
0038 goto reset;
0039 }
0040
0041 txq->axq_tx_inprogress = true;
0042 }
0043 ath_txq_unlock(sc, txq);
0044 }
0045
0046 return true;
0047
0048 reset:
0049 ath_dbg(ath9k_hw_common(sc->sc_ah), RESET,
0050 "tx hung, resetting the chip\n");
0051 ath9k_queue_reset(sc, RESET_TYPE_TX_HANG);
0052 return false;
0053
0054 }
0055
0056 void ath_hw_check_work(struct work_struct *work)
0057 {
0058 struct ath_softc *sc = container_of(work, struct ath_softc,
0059 hw_check_work.work);
0060
0061 if (!ath_hw_check(sc) ||
0062 !ath_tx_complete_check(sc))
0063 return;
0064
0065 ieee80211_queue_delayed_work(sc->hw, &sc->hw_check_work,
0066 msecs_to_jiffies(ATH_HW_CHECK_POLL_INT));
0067 }
0068
0069
0070
0071
0072 bool ath_hw_check(struct ath_softc *sc)
0073 {
0074 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
0075 enum ath_reset_type type;
0076 bool is_alive;
0077
0078 ath9k_ps_wakeup(sc);
0079
0080 is_alive = ath9k_hw_check_alive(sc->sc_ah);
0081
0082 if (!is_alive) {
0083 ath_dbg(common, RESET,
0084 "HW hang detected, schedule chip reset\n");
0085 type = RESET_TYPE_MAC_HANG;
0086 ath9k_queue_reset(sc, type);
0087 }
0088
0089 ath9k_ps_restore(sc);
0090
0091 return is_alive;
0092 }
0093
0094
0095
0096
0097 static bool ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum)
0098 {
0099 static int count;
0100 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
0101
0102 if (pll_sqsum >= 0x40000) {
0103 count++;
0104 if (count == 3) {
0105 ath_dbg(common, RESET, "PLL WAR, resetting the chip\n");
0106 ath9k_queue_reset(sc, RESET_TYPE_PLL_HANG);
0107 count = 0;
0108 return true;
0109 }
0110 } else {
0111 count = 0;
0112 }
0113
0114 return false;
0115 }
0116
0117 void ath_hw_pll_work(struct work_struct *work)
0118 {
0119 u32 pll_sqsum;
0120 struct ath_softc *sc = container_of(work, struct ath_softc,
0121 hw_pll_work.work);
0122 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
0123
0124
0125
0126
0127
0128
0129 if (!test_bit(ATH_OP_BEACONS, &common->op_flags))
0130 return;
0131
0132 if (sc->tx99_state)
0133 return;
0134
0135 ath9k_ps_wakeup(sc);
0136 pll_sqsum = ar9003_get_pll_sqsum_dvc(sc->sc_ah);
0137 ath9k_ps_restore(sc);
0138 if (ath_hw_pll_rx_hang_check(sc, pll_sqsum))
0139 return;
0140
0141 ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work,
0142 msecs_to_jiffies(ATH_PLL_WORK_INTERVAL));
0143 }
0144
0145
0146
0147
0148 static void ath_paprd_activate(struct ath_softc *sc)
0149 {
0150 struct ath_hw *ah = sc->sc_ah;
0151 struct ath_common *common = ath9k_hw_common(ah);
0152 struct ath9k_hw_cal_data *caldata = ah->caldata;
0153 int chain;
0154
0155 if (!caldata || !test_bit(PAPRD_DONE, &caldata->cal_flags)) {
0156 ath_dbg(common, CALIBRATE, "Failed to activate PAPRD\n");
0157 return;
0158 }
0159
0160 ar9003_paprd_enable(ah, false);
0161 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
0162 if (!(ah->txchainmask & BIT(chain)))
0163 continue;
0164
0165 ar9003_paprd_populate_single_table(ah, caldata, chain);
0166 }
0167
0168 ath_dbg(common, CALIBRATE, "Activating PAPRD\n");
0169 ar9003_paprd_enable(ah, true);
0170 }
0171
0172 static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int chain)
0173 {
0174 struct ieee80211_hw *hw = sc->hw;
0175 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
0176 struct ath_hw *ah = sc->sc_ah;
0177 struct ath_common *common = ath9k_hw_common(ah);
0178 struct ath_tx_control txctl;
0179 unsigned long time_left;
0180
0181 memset(&txctl, 0, sizeof(txctl));
0182 txctl.txq = sc->tx.txq_map[IEEE80211_AC_BE];
0183
0184 memset(tx_info, 0, sizeof(*tx_info));
0185 tx_info->band = sc->cur_chandef.chan->band;
0186 tx_info->flags |= IEEE80211_TX_CTL_NO_ACK;
0187 tx_info->control.rates[0].idx = 0;
0188 tx_info->control.rates[0].count = 1;
0189 tx_info->control.rates[0].flags = IEEE80211_TX_RC_MCS;
0190 tx_info->control.rates[1].idx = -1;
0191
0192 init_completion(&sc->paprd_complete);
0193 txctl.paprd = BIT(chain);
0194
0195 if (ath_tx_start(hw, skb, &txctl) != 0) {
0196 ath_dbg(common, CALIBRATE, "PAPRD TX failed\n");
0197 dev_kfree_skb_any(skb);
0198 return false;
0199 }
0200
0201 time_left = wait_for_completion_timeout(&sc->paprd_complete,
0202 msecs_to_jiffies(ATH_PAPRD_TIMEOUT));
0203
0204 if (!time_left)
0205 ath_dbg(common, CALIBRATE,
0206 "Timeout waiting for paprd training on TX chain %d\n",
0207 chain);
0208
0209 return !!time_left;
0210 }
0211
0212 void ath_paprd_calibrate(struct work_struct *work)
0213 {
0214 struct ath_softc *sc = container_of(work, struct ath_softc, paprd_work);
0215 struct ieee80211_hw *hw = sc->hw;
0216 struct ath_hw *ah = sc->sc_ah;
0217 struct ieee80211_hdr *hdr;
0218 struct sk_buff *skb = NULL;
0219 struct ath9k_hw_cal_data *caldata = ah->caldata;
0220 struct ath_common *common = ath9k_hw_common(ah);
0221 int ftype;
0222 int chain_ok = 0;
0223 int chain;
0224 int len = 1800;
0225 int ret;
0226
0227 if (!caldata ||
0228 !test_bit(PAPRD_PACKET_SENT, &caldata->cal_flags) ||
0229 test_bit(PAPRD_DONE, &caldata->cal_flags)) {
0230 ath_dbg(common, CALIBRATE, "Skipping PAPRD calibration\n");
0231 return;
0232 }
0233
0234 ath9k_ps_wakeup(sc);
0235
0236 if (ar9003_paprd_init_table(ah) < 0)
0237 goto fail_paprd;
0238
0239 skb = alloc_skb(len, GFP_KERNEL);
0240 if (!skb)
0241 goto fail_paprd;
0242
0243 skb_put(skb, len);
0244 memset(skb->data, 0, len);
0245 hdr = (struct ieee80211_hdr *)skb->data;
0246 ftype = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC;
0247 hdr->frame_control = cpu_to_le16(ftype);
0248 hdr->duration_id = cpu_to_le16(10);
0249 memcpy(hdr->addr1, hw->wiphy->perm_addr, ETH_ALEN);
0250 memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN);
0251 memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN);
0252
0253 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
0254 if (!(ah->txchainmask & BIT(chain)))
0255 continue;
0256
0257 chain_ok = 0;
0258 ar9003_paprd_setup_gain_table(ah, chain);
0259
0260 ath_dbg(common, CALIBRATE,
0261 "Sending PAPRD training frame on chain %d\n", chain);
0262 if (!ath_paprd_send_frame(sc, skb, chain))
0263 goto fail_paprd;
0264
0265 if (!ar9003_paprd_is_done(ah)) {
0266 ath_dbg(common, CALIBRATE,
0267 "PAPRD not yet done on chain %d\n", chain);
0268 break;
0269 }
0270
0271 ret = ar9003_paprd_create_curve(ah, caldata, chain);
0272 if (ret == -EINPROGRESS) {
0273 ath_dbg(common, CALIBRATE,
0274 "PAPRD curve on chain %d needs to be re-trained\n",
0275 chain);
0276 break;
0277 } else if (ret) {
0278 ath_dbg(common, CALIBRATE,
0279 "PAPRD create curve failed on chain %d\n",
0280 chain);
0281 break;
0282 }
0283
0284 chain_ok = 1;
0285 }
0286 kfree_skb(skb);
0287
0288 if (chain_ok) {
0289 set_bit(PAPRD_DONE, &caldata->cal_flags);
0290 ath_paprd_activate(sc);
0291 }
0292
0293 fail_paprd:
0294 ath9k_ps_restore(sc);
0295 }
0296
0297
0298
0299
0300
0301
0302
0303
0304 void ath_ani_calibrate(struct timer_list *t)
0305 {
0306 struct ath_common *common = from_timer(common, t, ani.timer);
0307 struct ath_softc *sc = (struct ath_softc *)common->priv;
0308 struct ath_hw *ah = sc->sc_ah;
0309 bool longcal = false;
0310 bool shortcal = false;
0311 bool aniflag = false;
0312 unsigned int timestamp = jiffies_to_msecs(jiffies);
0313 u32 cal_interval, short_cal_interval, long_cal_interval;
0314 unsigned long flags;
0315
0316 if (ah->caldata && test_bit(NFCAL_INTF, &ah->caldata->cal_flags))
0317 long_cal_interval = ATH_LONG_CALINTERVAL_INT;
0318 else
0319 long_cal_interval = ATH_LONG_CALINTERVAL;
0320
0321 short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ?
0322 ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL;
0323
0324
0325 if (sc->sc_ah->power_mode != ATH9K_PM_AWAKE) {
0326 if (++ah->ani_skip_count >= ATH_ANI_MAX_SKIP_COUNT) {
0327 spin_lock_irqsave(&sc->sc_pm_lock, flags);
0328 sc->ps_flags |= PS_WAIT_FOR_ANI;
0329 spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
0330 }
0331 goto set_timer;
0332 }
0333 ah->ani_skip_count = 0;
0334 spin_lock_irqsave(&sc->sc_pm_lock, flags);
0335 sc->ps_flags &= ~PS_WAIT_FOR_ANI;
0336 spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
0337
0338 ath9k_ps_wakeup(sc);
0339
0340
0341 if ((timestamp - common->ani.longcal_timer) >= long_cal_interval) {
0342 longcal = true;
0343 common->ani.longcal_timer = timestamp;
0344 }
0345
0346
0347 if (!common->ani.caldone) {
0348 if ((timestamp - common->ani.shortcal_timer) >= short_cal_interval) {
0349 shortcal = true;
0350 common->ani.shortcal_timer = timestamp;
0351 common->ani.resetcal_timer = timestamp;
0352 }
0353 } else {
0354 if ((timestamp - common->ani.resetcal_timer) >=
0355 ATH_RESTART_CALINTERVAL) {
0356 common->ani.caldone = ath9k_hw_reset_calvalid(ah);
0357 if (common->ani.caldone)
0358 common->ani.resetcal_timer = timestamp;
0359 }
0360 }
0361
0362
0363 if ((timestamp - common->ani.checkani_timer) >= ah->config.ani_poll_interval) {
0364 aniflag = true;
0365 common->ani.checkani_timer = timestamp;
0366 }
0367
0368
0369 if (aniflag) {
0370 spin_lock_irqsave(&common->cc_lock, flags);
0371 ath9k_hw_ani_monitor(ah, ah->curchan);
0372 ath_update_survey_stats(sc);
0373 spin_unlock_irqrestore(&common->cc_lock, flags);
0374 }
0375
0376
0377 if (longcal || shortcal) {
0378 int ret = ath9k_hw_calibrate(ah, ah->curchan, ah->rxchainmask,
0379 longcal);
0380 if (ret < 0) {
0381 common->ani.caldone = 0;
0382 ath9k_queue_reset(sc, RESET_TYPE_CALIBRATION);
0383 return;
0384 }
0385
0386 common->ani.caldone = ret;
0387 }
0388
0389 ath_dbg(common, ANI,
0390 "Calibration @%lu finished: %s %s %s, caldone: %s\n",
0391 jiffies,
0392 longcal ? "long" : "", shortcal ? "short" : "",
0393 aniflag ? "ani" : "", common->ani.caldone ? "true" : "false");
0394
0395 ath9k_ps_restore(sc);
0396
0397 set_timer:
0398
0399
0400
0401
0402
0403 cal_interval = ATH_LONG_CALINTERVAL;
0404 cal_interval = min(cal_interval, (u32)ah->config.ani_poll_interval);
0405 if (!common->ani.caldone)
0406 cal_interval = min(cal_interval, (u32)short_cal_interval);
0407
0408 mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval));
0409
0410 if (ar9003_is_paprd_enabled(ah) && ah->caldata) {
0411 if (!test_bit(PAPRD_DONE, &ah->caldata->cal_flags)) {
0412 ieee80211_queue_work(sc->hw, &sc->paprd_work);
0413 } else if (!ah->paprd_table_write_done) {
0414 ath9k_ps_wakeup(sc);
0415 ath_paprd_activate(sc);
0416 ath9k_ps_restore(sc);
0417 }
0418 }
0419 }
0420
0421 void ath_start_ani(struct ath_softc *sc)
0422 {
0423 struct ath_hw *ah = sc->sc_ah;
0424 struct ath_common *common = ath9k_hw_common(ah);
0425 unsigned long timestamp = jiffies_to_msecs(jiffies);
0426
0427 if (common->disable_ani ||
0428 !test_bit(ATH_OP_ANI_RUN, &common->op_flags) ||
0429 sc->cur_chan->offchannel)
0430 return;
0431
0432 common->ani.longcal_timer = timestamp;
0433 common->ani.shortcal_timer = timestamp;
0434 common->ani.checkani_timer = timestamp;
0435
0436 ath_dbg(common, ANI, "Starting ANI\n");
0437 mod_timer(&common->ani.timer,
0438 jiffies + msecs_to_jiffies((u32)ah->config.ani_poll_interval));
0439 }
0440
0441 void ath_stop_ani(struct ath_softc *sc)
0442 {
0443 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
0444
0445 ath_dbg(common, ANI, "Stopping ANI\n");
0446 del_timer_sync(&common->ani.timer);
0447 }
0448
0449 void ath_check_ani(struct ath_softc *sc)
0450 {
0451 struct ath_hw *ah = sc->sc_ah;
0452 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
0453 struct ath_beacon_config *cur_conf = &sc->cur_chan->beacon;
0454
0455
0456
0457
0458
0459 if (ah->opmode == NL80211_IFTYPE_ADHOC) {
0460 if (!cur_conf->enable_beacon)
0461 goto stop_ani;
0462 } else if (ah->opmode == NL80211_IFTYPE_AP) {
0463 if (!cur_conf->enable_beacon) {
0464
0465
0466
0467
0468 if (!test_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags))
0469 goto stop_ani;
0470 }
0471 } else if (ah->opmode == NL80211_IFTYPE_STATION) {
0472 if (!test_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags))
0473 goto stop_ani;
0474 }
0475
0476 if (!test_bit(ATH_OP_ANI_RUN, &common->op_flags)) {
0477 set_bit(ATH_OP_ANI_RUN, &common->op_flags);
0478 ath_start_ani(sc);
0479 }
0480
0481 return;
0482
0483 stop_ani:
0484 clear_bit(ATH_OP_ANI_RUN, &common->op_flags);
0485 ath_stop_ani(sc);
0486 }
0487
0488 void ath_update_survey_nf(struct ath_softc *sc, int channel)
0489 {
0490 struct ath_hw *ah = sc->sc_ah;
0491 struct ath9k_channel *chan = &ah->channels[channel];
0492 struct survey_info *survey = &sc->survey[channel];
0493
0494 if (chan->noisefloor) {
0495 survey->filled |= SURVEY_INFO_NOISE_DBM;
0496 survey->noise = ath9k_hw_getchan_noise(ah, chan,
0497 chan->noisefloor);
0498 }
0499 }
0500
0501
0502
0503
0504
0505
0506 int ath_update_survey_stats(struct ath_softc *sc)
0507 {
0508 struct ath_hw *ah = sc->sc_ah;
0509 struct ath_common *common = ath9k_hw_common(ah);
0510 int pos = ah->curchan - &ah->channels[0];
0511 struct survey_info *survey = &sc->survey[pos];
0512 struct ath_cycle_counters *cc = &common->cc_survey;
0513 unsigned int div = common->clockrate * 1000;
0514 int ret = 0;
0515
0516 if (!ah->curchan)
0517 return -1;
0518
0519 if (ah->power_mode == ATH9K_PM_AWAKE)
0520 ath_hw_cycle_counters_update(common);
0521
0522 if (cc->cycles > 0) {
0523 survey->filled |= SURVEY_INFO_TIME |
0524 SURVEY_INFO_TIME_BUSY |
0525 SURVEY_INFO_TIME_RX |
0526 SURVEY_INFO_TIME_TX;
0527 survey->time += cc->cycles / div;
0528 survey->time_busy += cc->rx_busy / div;
0529 survey->time_rx += cc->rx_frame / div;
0530 survey->time_tx += cc->tx_frame / div;
0531 }
0532
0533 if (cc->cycles < div)
0534 return -1;
0535
0536 if (cc->cycles > 0)
0537 ret = cc->rx_busy * 100 / cc->cycles;
0538
0539 memset(cc, 0, sizeof(*cc));
0540
0541 ath_update_survey_nf(sc, pos);
0542
0543 return ret;
0544 }