| .. | .. |
|---|
| 19 | 19 | #include "ar9002_phy.h" |
|---|
| 20 | 20 | |
|---|
| 21 | 21 | #define AR9285_CLCAL_REDO_THRESH 1 |
|---|
| 22 | +/* AGC & I/Q calibrations time limit, ms */ |
|---|
| 23 | +#define AR9002_CAL_MAX_TIME 30000 |
|---|
| 22 | 24 | |
|---|
| 23 | 25 | enum ar9002_cal_types { |
|---|
| 24 | 26 | ADC_GAIN_CAL = BIT(0), |
|---|
| .. | .. |
|---|
| 37 | 39 | break; |
|---|
| 38 | 40 | case ADC_GAIN_CAL: |
|---|
| 39 | 41 | case ADC_DC_CAL: |
|---|
| 40 | | - /* Run ADC Gain Cal for non-CCK & non 2GHz-HT20 only */ |
|---|
| 41 | | - if (!((IS_CHAN_2GHZ(chan) || IS_CHAN_A_FAST_CLOCK(ah, chan)) && |
|---|
| 42 | | - IS_CHAN_HT20(chan))) |
|---|
| 42 | + /* Run even/odd ADCs calibrations for HT40 channels only */ |
|---|
| 43 | + if (IS_CHAN_HT40(chan)) |
|---|
| 43 | 44 | supported = true; |
|---|
| 44 | 45 | break; |
|---|
| 45 | 46 | } |
|---|
| .. | .. |
|---|
| 105 | 106 | } else { |
|---|
| 106 | 107 | ar9002_hw_setup_calibration(ah, currCal); |
|---|
| 107 | 108 | } |
|---|
| 109 | + } else if (time_after(jiffies, ah->cal_start_time + |
|---|
| 110 | + msecs_to_jiffies(AR9002_CAL_MAX_TIME))) { |
|---|
| 111 | + REG_CLR_BIT(ah, AR_PHY_TIMING_CTRL4(0), |
|---|
| 112 | + AR_PHY_TIMING_CTRL4_DO_CAL); |
|---|
| 113 | + ath_dbg(ath9k_hw_common(ah), CALIBRATE, |
|---|
| 114 | + "calibration timeout\n"); |
|---|
| 115 | + currCal->calState = CAL_WAITING; /* Try later */ |
|---|
| 116 | + iscaldone = true; |
|---|
| 108 | 117 | } |
|---|
| 109 | 118 | } else if (!(caldata->CalValid & currCal->calData->calType)) { |
|---|
| 110 | 119 | ath9k_hw_reset_calibration(ah, currCal); |
|---|
| .. | .. |
|---|
| 664 | 673 | int ret; |
|---|
| 665 | 674 | |
|---|
| 666 | 675 | nfcal = !!(REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF); |
|---|
| 667 | | - if (ah->caldata) |
|---|
| 676 | + if (ah->caldata) { |
|---|
| 668 | 677 | nfcal_pending = test_bit(NFCAL_PENDING, &ah->caldata->cal_flags); |
|---|
| 678 | + if (longcal) /* Remember to not miss */ |
|---|
| 679 | + set_bit(LONGCAL_PENDING, &ah->caldata->cal_flags); |
|---|
| 680 | + else if (test_bit(LONGCAL_PENDING, &ah->caldata->cal_flags)) |
|---|
| 681 | + longcal = true; /* Respin a previous one */ |
|---|
| 682 | + } |
|---|
| 669 | 683 | |
|---|
| 670 | 684 | percal_pending = (currCal && |
|---|
| 671 | 685 | (currCal->calState == CAL_RUNNING || |
|---|
| .. | .. |
|---|
| 675 | 689 | if (!ar9002_hw_per_calibration(ah, chan, rxchainmask, currCal)) |
|---|
| 676 | 690 | return 0; |
|---|
| 677 | 691 | |
|---|
| 678 | | - ah->cal_list_curr = currCal = currCal->calNext; |
|---|
| 679 | | - if (currCal->calState == CAL_WAITING) |
|---|
| 680 | | - ath9k_hw_reset_calibration(ah, currCal); |
|---|
| 692 | + /* Looking for next waiting calibration if any */ |
|---|
| 693 | + for (currCal = currCal->calNext; currCal != ah->cal_list_curr; |
|---|
| 694 | + currCal = currCal->calNext) { |
|---|
| 695 | + if (currCal->calState == CAL_WAITING) |
|---|
| 696 | + break; |
|---|
| 697 | + } |
|---|
| 698 | + if (currCal->calState == CAL_WAITING) { |
|---|
| 699 | + percal_pending = true; |
|---|
| 700 | + ah->cal_list_curr = currCal; |
|---|
| 701 | + } else { |
|---|
| 702 | + percal_pending = false; |
|---|
| 703 | + ah->cal_list_curr = ah->cal_list; |
|---|
| 704 | + } |
|---|
| 705 | + } |
|---|
| 706 | + |
|---|
| 707 | + /* Do not start a next calibration if the longcal is in action */ |
|---|
| 708 | + if (percal_pending && !nfcal && !longcal) { |
|---|
| 709 | + ath9k_hw_reset_calibration(ah, currCal); |
|---|
| 681 | 710 | |
|---|
| 682 | 711 | return 0; |
|---|
| 683 | 712 | } |
|---|
| .. | .. |
|---|
| 701 | 730 | } |
|---|
| 702 | 731 | |
|---|
| 703 | 732 | if (longcal) { |
|---|
| 733 | + if (ah->caldata) |
|---|
| 734 | + clear_bit(LONGCAL_PENDING, |
|---|
| 735 | + &ah->caldata->cal_flags); |
|---|
| 704 | 736 | ath9k_hw_start_nfcal(ah, false); |
|---|
| 705 | 737 | /* Do periodic PAOffset Cal */ |
|---|
| 706 | 738 | ar9002_hw_pa_cal(ah, false); |
|---|
| .. | .. |
|---|
| 857 | 889 | ar9002_hw_pa_cal(ah, true); |
|---|
| 858 | 890 | ath9k_hw_loadnf(ah, chan); |
|---|
| 859 | 891 | ath9k_hw_start_nfcal(ah, true); |
|---|
| 860 | | - |
|---|
| 861 | | - if (ah->caldata) |
|---|
| 862 | | - set_bit(NFCAL_PENDING, &ah->caldata->cal_flags); |
|---|
| 863 | 892 | |
|---|
| 864 | 893 | ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL; |
|---|
| 865 | 894 | |
|---|