cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ar9003_calib.c (46987B)


      1/*
      2 * Copyright (c) 2010-2011 Atheros Communications Inc.
      3 *
      4 * Permission to use, copy, modify, and/or distribute this software for any
      5 * purpose with or without fee is hereby granted, provided that the above
      6 * copyright notice and this permission notice appear in all copies.
      7 *
      8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     15 */
     16
     17#include "hw.h"
     18#include "hw-ops.h"
     19#include "ar9003_phy.h"
     20#include "ar9003_rtt.h"
     21#include "ar9003_mci.h"
     22
     23#define MAX_MEASUREMENT	MAX_IQCAL_MEASUREMENT
     24#define MAX_MAG_DELTA	11
     25#define MAX_PHS_DELTA	10
     26#define MAXIQCAL        3
     27
     28struct coeff {
     29	int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MAXIQCAL];
     30	int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MAXIQCAL];
     31	int iqc_coeff[2];
     32};
     33
     34enum ar9003_cal_types {
     35	IQ_MISMATCH_CAL = BIT(0),
     36};
     37
     38static void ar9003_hw_setup_calibration(struct ath_hw *ah,
     39					struct ath9k_cal_list *currCal)
     40{
     41	struct ath_common *common = ath9k_hw_common(ah);
     42
     43	/* Select calibration to run */
     44	switch (currCal->calData->calType) {
     45	case IQ_MISMATCH_CAL:
     46		/*
     47		 * Start calibration with
     48		 * 2^(INIT_IQCAL_LOG_COUNT_MAX+1) samples
     49		 */
     50		REG_RMW_FIELD(ah, AR_PHY_TIMING4,
     51			      AR_PHY_TIMING4_IQCAL_LOG_COUNT_MAX,
     52			      currCal->calData->calCountMax);
     53		REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
     54
     55		ath_dbg(common, CALIBRATE,
     56			"starting IQ Mismatch Calibration\n");
     57
     58		/* Kick-off cal */
     59		REG_SET_BIT(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_DO_CAL);
     60		break;
     61	default:
     62		ath_err(common, "Invalid calibration type\n");
     63		break;
     64	}
     65}
     66
     67/*
     68 * Generic calibration routine.
     69 * Recalibrate the lower PHY chips to account for temperature/environment
     70 * changes.
     71 */
     72static bool ar9003_hw_per_calibration(struct ath_hw *ah,
     73				      struct ath9k_channel *ichan,
     74				      u8 rxchainmask,
     75				      struct ath9k_cal_list *currCal)
     76{
     77	struct ath9k_hw_cal_data *caldata = ah->caldata;
     78	const struct ath9k_percal_data *cur_caldata = currCal->calData;
     79
     80	/* Calibration in progress. */
     81	if (currCal->calState == CAL_RUNNING) {
     82		/* Check to see if it has finished. */
     83		if (REG_READ(ah, AR_PHY_TIMING4) & AR_PHY_TIMING4_DO_CAL)
     84			return false;
     85
     86		/*
     87		* Accumulate cal measures for active chains
     88		*/
     89		cur_caldata->calCollect(ah);
     90		ah->cal_samples++;
     91
     92		if (ah->cal_samples >= cur_caldata->calNumSamples) {
     93			unsigned int i, numChains = 0;
     94			for (i = 0; i < AR9300_MAX_CHAINS; i++) {
     95				if (rxchainmask & (1 << i))
     96					numChains++;
     97			}
     98
     99			/*
    100			* Process accumulated data
    101			*/
    102			cur_caldata->calPostProc(ah, numChains);
    103
    104			/* Calibration has finished. */
    105			caldata->CalValid |= cur_caldata->calType;
    106			currCal->calState = CAL_DONE;
    107			return true;
    108		} else {
    109			/*
    110			 * Set-up collection of another sub-sample until we
    111			 * get desired number
    112			 */
    113			ar9003_hw_setup_calibration(ah, currCal);
    114		}
    115	} else if (!(caldata->CalValid & cur_caldata->calType)) {
    116		/* If current cal is marked invalid in channel, kick it off */
    117		ath9k_hw_reset_calibration(ah, currCal);
    118	}
    119
    120	return false;
    121}
    122
    123static int ar9003_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
    124			       u8 rxchainmask, bool longcal)
    125{
    126	bool iscaldone = true;
    127	struct ath9k_cal_list *currCal = ah->cal_list_curr;
    128	int ret;
    129
    130	/*
    131	 * For given calibration:
    132	 * 1. Call generic cal routine
    133	 * 2. When this cal is done (isCalDone) if we have more cals waiting
    134	 *    (eg after reset), mask this to upper layers by not propagating
    135	 *    isCalDone if it is set to TRUE.
    136	 *    Instead, change isCalDone to FALSE and setup the waiting cal(s)
    137	 *    to be run.
    138	 */
    139	if (currCal &&
    140	    (currCal->calState == CAL_RUNNING ||
    141	     currCal->calState == CAL_WAITING)) {
    142		iscaldone = ar9003_hw_per_calibration(ah, chan,
    143						      rxchainmask, currCal);
    144		if (iscaldone) {
    145			ah->cal_list_curr = currCal = currCal->calNext;
    146
    147			if (currCal->calState == CAL_WAITING) {
    148				iscaldone = false;
    149				ath9k_hw_reset_calibration(ah, currCal);
    150			}
    151		}
    152	}
    153
    154	/*
    155	 * Do NF cal only at longer intervals. Get the value from
    156	 * the previous NF cal and update history buffer.
    157	 */
    158	if (longcal && ath9k_hw_getnf(ah, chan)) {
    159		/*
    160		 * Load the NF from history buffer of the current channel.
    161		 * NF is slow time-variant, so it is OK to use a historical
    162		 * value.
    163		 */
    164		ret = ath9k_hw_loadnf(ah, ah->curchan);
    165		if (ret < 0)
    166			return ret;
    167
    168		/* start NF calibration, without updating BB NF register */
    169		ath9k_hw_start_nfcal(ah, false);
    170	}
    171
    172	return iscaldone;
    173}
    174
    175static void ar9003_hw_iqcal_collect(struct ath_hw *ah)
    176{
    177	int i;
    178
    179	/* Accumulate IQ cal measures for active chains */
    180	for (i = 0; i < AR9300_MAX_CHAINS; i++) {
    181		if (ah->txchainmask & BIT(i)) {
    182			ah->totalPowerMeasI[i] +=
    183				REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
    184			ah->totalPowerMeasQ[i] +=
    185				REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
    186			ah->totalIqCorrMeas[i] +=
    187				(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
    188			ath_dbg(ath9k_hw_common(ah), CALIBRATE,
    189				"%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
    190				ah->cal_samples, i, ah->totalPowerMeasI[i],
    191				ah->totalPowerMeasQ[i],
    192				ah->totalIqCorrMeas[i]);
    193		}
    194	}
    195}
    196
    197static void ar9003_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
    198{
    199	struct ath_common *common = ath9k_hw_common(ah);
    200	u32 powerMeasQ, powerMeasI, iqCorrMeas;
    201	u32 qCoffDenom, iCoffDenom;
    202	int32_t qCoff, iCoff;
    203	int iqCorrNeg, i;
    204	static const u_int32_t offset_array[3] = {
    205		AR_PHY_RX_IQCAL_CORR_B0,
    206		AR_PHY_RX_IQCAL_CORR_B1,
    207		AR_PHY_RX_IQCAL_CORR_B2,
    208	};
    209
    210	for (i = 0; i < numChains; i++) {
    211		powerMeasI = ah->totalPowerMeasI[i];
    212		powerMeasQ = ah->totalPowerMeasQ[i];
    213		iqCorrMeas = ah->totalIqCorrMeas[i];
    214
    215		ath_dbg(common, CALIBRATE,
    216			"Starting IQ Cal and Correction for Chain %d\n", i);
    217
    218		ath_dbg(common, CALIBRATE,
    219			"Original: Chn %d iq_corr_meas = 0x%08x\n",
    220			i, ah->totalIqCorrMeas[i]);
    221
    222		iqCorrNeg = 0;
    223
    224		if (iqCorrMeas > 0x80000000) {
    225			iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
    226			iqCorrNeg = 1;
    227		}
    228
    229		ath_dbg(common, CALIBRATE, "Chn %d pwr_meas_i = 0x%08x\n",
    230			i, powerMeasI);
    231		ath_dbg(common, CALIBRATE, "Chn %d pwr_meas_q = 0x%08x\n",
    232			i, powerMeasQ);
    233		ath_dbg(common, CALIBRATE, "iqCorrNeg is 0x%08x\n", iqCorrNeg);
    234
    235		iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 256;
    236		qCoffDenom = powerMeasQ / 64;
    237
    238		if ((iCoffDenom != 0) && (qCoffDenom != 0)) {
    239			iCoff = iqCorrMeas / iCoffDenom;
    240			qCoff = powerMeasI / qCoffDenom - 64;
    241			ath_dbg(common, CALIBRATE, "Chn %d iCoff = 0x%08x\n",
    242				i, iCoff);
    243			ath_dbg(common, CALIBRATE, "Chn %d qCoff = 0x%08x\n",
    244				i, qCoff);
    245
    246			/* Force bounds on iCoff */
    247			if (iCoff >= 63)
    248				iCoff = 63;
    249			else if (iCoff <= -63)
    250				iCoff = -63;
    251
    252			/* Negate iCoff if iqCorrNeg == 0 */
    253			if (iqCorrNeg == 0x0)
    254				iCoff = -iCoff;
    255
    256			/* Force bounds on qCoff */
    257			if (qCoff >= 63)
    258				qCoff = 63;
    259			else if (qCoff <= -63)
    260				qCoff = -63;
    261
    262			iCoff = iCoff & 0x7f;
    263			qCoff = qCoff & 0x7f;
    264
    265			ath_dbg(common, CALIBRATE,
    266				"Chn %d : iCoff = 0x%x  qCoff = 0x%x\n",
    267				i, iCoff, qCoff);
    268			ath_dbg(common, CALIBRATE,
    269				"Register offset (0x%04x) before update = 0x%x\n",
    270				offset_array[i],
    271				REG_READ(ah, offset_array[i]));
    272
    273			if (AR_SREV_9565(ah) &&
    274			    (iCoff == 63 || qCoff == 63 ||
    275			     iCoff == -63 || qCoff == -63))
    276				return;
    277
    278			REG_RMW_FIELD(ah, offset_array[i],
    279				      AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF,
    280				      iCoff);
    281			REG_RMW_FIELD(ah, offset_array[i],
    282				      AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF,
    283				      qCoff);
    284			ath_dbg(common, CALIBRATE,
    285				"Register offset (0x%04x) QI COFF (bitfields 0x%08x) after update = 0x%x\n",
    286				offset_array[i],
    287				AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF,
    288				REG_READ(ah, offset_array[i]));
    289			ath_dbg(common, CALIBRATE,
    290				"Register offset (0x%04x) QQ COFF (bitfields 0x%08x) after update = 0x%x\n",
    291				offset_array[i],
    292				AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF,
    293				REG_READ(ah, offset_array[i]));
    294
    295			ath_dbg(common, CALIBRATE,
    296				"IQ Cal and Correction done for Chain %d\n", i);
    297		}
    298	}
    299
    300	REG_SET_BIT(ah, AR_PHY_RX_IQCAL_CORR_B0,
    301		    AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE);
    302	ath_dbg(common, CALIBRATE,
    303		"IQ Cal and Correction (offset 0x%04x) enabled (bit position 0x%08x). New Value 0x%08x\n",
    304		(unsigned) (AR_PHY_RX_IQCAL_CORR_B0),
    305		AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE,
    306		REG_READ(ah, AR_PHY_RX_IQCAL_CORR_B0));
    307}
    308
    309static const struct ath9k_percal_data iq_cal_single_sample = {
    310	IQ_MISMATCH_CAL,
    311	MIN_CAL_SAMPLES,
    312	PER_MAX_LOG_COUNT,
    313	ar9003_hw_iqcal_collect,
    314	ar9003_hw_iqcalibrate
    315};
    316
    317static void ar9003_hw_init_cal_settings(struct ath_hw *ah)
    318{
    319	ah->iq_caldata.calData = &iq_cal_single_sample;
    320
    321	if (AR_SREV_9300_20_OR_LATER(ah)) {
    322		ah->enabled_cals |= TX_IQ_CAL;
    323		if (AR_SREV_9485_OR_LATER(ah) && !AR_SREV_9340(ah))
    324			ah->enabled_cals |= TX_IQ_ON_AGC_CAL;
    325	}
    326
    327	ah->supp_cals = IQ_MISMATCH_CAL;
    328}
    329
    330#define OFF_UPPER_LT 24
    331#define OFF_LOWER_LT 7
    332
    333static bool ar9003_hw_dynamic_osdac_selection(struct ath_hw *ah,
    334					      bool txiqcal_done)
    335{
    336	struct ath_common *common = ath9k_hw_common(ah);
    337	int ch0_done, osdac_ch0, dc_off_ch0_i1, dc_off_ch0_q1, dc_off_ch0_i2,
    338		dc_off_ch0_q2, dc_off_ch0_i3, dc_off_ch0_q3;
    339	int ch1_done, osdac_ch1, dc_off_ch1_i1, dc_off_ch1_q1, dc_off_ch1_i2,
    340		dc_off_ch1_q2, dc_off_ch1_i3, dc_off_ch1_q3;
    341	int ch2_done, osdac_ch2, dc_off_ch2_i1, dc_off_ch2_q1, dc_off_ch2_i2,
    342		dc_off_ch2_q2, dc_off_ch2_i3, dc_off_ch2_q3;
    343	bool status;
    344	u32 temp, val;
    345
    346	/*
    347	 * Clear offset and IQ calibration, run AGC cal.
    348	 */
    349	REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
    350		    AR_PHY_AGC_CONTROL_OFFSET_CAL);
    351	REG_CLR_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0,
    352		    AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL);
    353	REG_WRITE(ah, AR_PHY_AGC_CONTROL,
    354		  REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_CAL);
    355
    356	status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
    357			       AR_PHY_AGC_CONTROL_CAL,
    358			       0, AH_WAIT_TIMEOUT);
    359	if (!status) {
    360		ath_dbg(common, CALIBRATE,
    361			"AGC cal without offset cal failed to complete in 1ms");
    362		return false;
    363	}
    364
    365	/*
    366	 * Allow only offset calibration and disable the others
    367	 * (Carrier Leak calibration, TX Filter calibration and
    368	 *  Peak Detector offset calibration).
    369	 */
    370	REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
    371		    AR_PHY_AGC_CONTROL_OFFSET_CAL);
    372	REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL,
    373		    AR_PHY_CL_CAL_ENABLE);
    374	REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
    375		    AR_PHY_AGC_CONTROL_FLTR_CAL);
    376	REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
    377		    AR_PHY_AGC_CONTROL_PKDET_CAL);
    378
    379	ch0_done = 0;
    380	ch1_done = 0;
    381	ch2_done = 0;
    382
    383	while ((ch0_done == 0) || (ch1_done == 0) || (ch2_done == 0)) {
    384		osdac_ch0 = (REG_READ(ah, AR_PHY_65NM_CH0_BB1) >> 30) & 0x3;
    385		osdac_ch1 = (REG_READ(ah, AR_PHY_65NM_CH1_BB1) >> 30) & 0x3;
    386		osdac_ch2 = (REG_READ(ah, AR_PHY_65NM_CH2_BB1) >> 30) & 0x3;
    387
    388		REG_SET_BIT(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
    389
    390		REG_WRITE(ah, AR_PHY_AGC_CONTROL,
    391			  REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_CAL);
    392
    393		status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
    394				       AR_PHY_AGC_CONTROL_CAL,
    395				       0, AH_WAIT_TIMEOUT);
    396		if (!status) {
    397			ath_dbg(common, CALIBRATE,
    398				"DC offset cal failed to complete in 1ms");
    399			return false;
    400		}
    401
    402		REG_CLR_BIT(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
    403
    404		/*
    405		 * High gain.
    406		 */
    407		REG_WRITE(ah, AR_PHY_65NM_CH0_BB3,
    408			  ((REG_READ(ah, AR_PHY_65NM_CH0_BB3) & 0xfffffcff) | (1 << 8)));
    409		REG_WRITE(ah, AR_PHY_65NM_CH1_BB3,
    410			  ((REG_READ(ah, AR_PHY_65NM_CH1_BB3) & 0xfffffcff) | (1 << 8)));
    411		REG_WRITE(ah, AR_PHY_65NM_CH2_BB3,
    412			  ((REG_READ(ah, AR_PHY_65NM_CH2_BB3) & 0xfffffcff) | (1 << 8)));
    413
    414		temp = REG_READ(ah, AR_PHY_65NM_CH0_BB3);
    415		dc_off_ch0_i1 = (temp >> 26) & 0x1f;
    416		dc_off_ch0_q1 = (temp >> 21) & 0x1f;
    417
    418		temp = REG_READ(ah, AR_PHY_65NM_CH1_BB3);
    419		dc_off_ch1_i1 = (temp >> 26) & 0x1f;
    420		dc_off_ch1_q1 = (temp >> 21) & 0x1f;
    421
    422		temp = REG_READ(ah, AR_PHY_65NM_CH2_BB3);
    423		dc_off_ch2_i1 = (temp >> 26) & 0x1f;
    424		dc_off_ch2_q1 = (temp >> 21) & 0x1f;
    425
    426		/*
    427		 * Low gain.
    428		 */
    429		REG_WRITE(ah, AR_PHY_65NM_CH0_BB3,
    430			  ((REG_READ(ah, AR_PHY_65NM_CH0_BB3) & 0xfffffcff) | (2 << 8)));
    431		REG_WRITE(ah, AR_PHY_65NM_CH1_BB3,
    432			  ((REG_READ(ah, AR_PHY_65NM_CH1_BB3) & 0xfffffcff) | (2 << 8)));
    433		REG_WRITE(ah, AR_PHY_65NM_CH2_BB3,
    434			  ((REG_READ(ah, AR_PHY_65NM_CH2_BB3) & 0xfffffcff) | (2 << 8)));
    435
    436		temp = REG_READ(ah, AR_PHY_65NM_CH0_BB3);
    437		dc_off_ch0_i2 = (temp >> 26) & 0x1f;
    438		dc_off_ch0_q2 = (temp >> 21) & 0x1f;
    439
    440		temp = REG_READ(ah, AR_PHY_65NM_CH1_BB3);
    441		dc_off_ch1_i2 = (temp >> 26) & 0x1f;
    442		dc_off_ch1_q2 = (temp >> 21) & 0x1f;
    443
    444		temp = REG_READ(ah, AR_PHY_65NM_CH2_BB3);
    445		dc_off_ch2_i2 = (temp >> 26) & 0x1f;
    446		dc_off_ch2_q2 = (temp >> 21) & 0x1f;
    447
    448		/*
    449		 * Loopback.
    450		 */
    451		REG_WRITE(ah, AR_PHY_65NM_CH0_BB3,
    452			  ((REG_READ(ah, AR_PHY_65NM_CH0_BB3) & 0xfffffcff) | (3 << 8)));
    453		REG_WRITE(ah, AR_PHY_65NM_CH1_BB3,
    454			  ((REG_READ(ah, AR_PHY_65NM_CH1_BB3) & 0xfffffcff) | (3 << 8)));
    455		REG_WRITE(ah, AR_PHY_65NM_CH2_BB3,
    456			  ((REG_READ(ah, AR_PHY_65NM_CH2_BB3) & 0xfffffcff) | (3 << 8)));
    457
    458		temp = REG_READ(ah, AR_PHY_65NM_CH0_BB3);
    459		dc_off_ch0_i3 = (temp >> 26) & 0x1f;
    460		dc_off_ch0_q3 = (temp >> 21) & 0x1f;
    461
    462		temp = REG_READ(ah, AR_PHY_65NM_CH1_BB3);
    463		dc_off_ch1_i3 = (temp >> 26) & 0x1f;
    464		dc_off_ch1_q3 = (temp >> 21) & 0x1f;
    465
    466		temp = REG_READ(ah, AR_PHY_65NM_CH2_BB3);
    467		dc_off_ch2_i3 = (temp >> 26) & 0x1f;
    468		dc_off_ch2_q3 = (temp >> 21) & 0x1f;
    469
    470		if ((dc_off_ch0_i1 > OFF_UPPER_LT) || (dc_off_ch0_i1 < OFF_LOWER_LT) ||
    471		    (dc_off_ch0_i2 > OFF_UPPER_LT) || (dc_off_ch0_i2 < OFF_LOWER_LT) ||
    472		    (dc_off_ch0_i3 > OFF_UPPER_LT) || (dc_off_ch0_i3 < OFF_LOWER_LT) ||
    473		    (dc_off_ch0_q1 > OFF_UPPER_LT) || (dc_off_ch0_q1 < OFF_LOWER_LT) ||
    474		    (dc_off_ch0_q2 > OFF_UPPER_LT) || (dc_off_ch0_q2 < OFF_LOWER_LT) ||
    475		    (dc_off_ch0_q3 > OFF_UPPER_LT) || (dc_off_ch0_q3 < OFF_LOWER_LT)) {
    476			if (osdac_ch0 == 3) {
    477				ch0_done = 1;
    478			} else {
    479				osdac_ch0++;
    480
    481				val = REG_READ(ah, AR_PHY_65NM_CH0_BB1) & 0x3fffffff;
    482				val |= (osdac_ch0 << 30);
    483				REG_WRITE(ah, AR_PHY_65NM_CH0_BB1, val);
    484
    485				ch0_done = 0;
    486			}
    487		} else {
    488			ch0_done = 1;
    489		}
    490
    491		if ((dc_off_ch1_i1 > OFF_UPPER_LT) || (dc_off_ch1_i1 < OFF_LOWER_LT) ||
    492		    (dc_off_ch1_i2 > OFF_UPPER_LT) || (dc_off_ch1_i2 < OFF_LOWER_LT) ||
    493		    (dc_off_ch1_i3 > OFF_UPPER_LT) || (dc_off_ch1_i3 < OFF_LOWER_LT) ||
    494		    (dc_off_ch1_q1 > OFF_UPPER_LT) || (dc_off_ch1_q1 < OFF_LOWER_LT) ||
    495		    (dc_off_ch1_q2 > OFF_UPPER_LT) || (dc_off_ch1_q2 < OFF_LOWER_LT) ||
    496		    (dc_off_ch1_q3 > OFF_UPPER_LT) || (dc_off_ch1_q3 < OFF_LOWER_LT)) {
    497			if (osdac_ch1 == 3) {
    498				ch1_done = 1;
    499			} else {
    500				osdac_ch1++;
    501
    502				val = REG_READ(ah, AR_PHY_65NM_CH1_BB1) & 0x3fffffff;
    503				val |= (osdac_ch1 << 30);
    504				REG_WRITE(ah, AR_PHY_65NM_CH1_BB1, val);
    505
    506				ch1_done = 0;
    507			}
    508		} else {
    509			ch1_done = 1;
    510		}
    511
    512		if ((dc_off_ch2_i1 > OFF_UPPER_LT) || (dc_off_ch2_i1 < OFF_LOWER_LT) ||
    513		    (dc_off_ch2_i2 > OFF_UPPER_LT) || (dc_off_ch2_i2 < OFF_LOWER_LT) ||
    514		    (dc_off_ch2_i3 > OFF_UPPER_LT) || (dc_off_ch2_i3 < OFF_LOWER_LT) ||
    515		    (dc_off_ch2_q1 > OFF_UPPER_LT) || (dc_off_ch2_q1 < OFF_LOWER_LT) ||
    516		    (dc_off_ch2_q2 > OFF_UPPER_LT) || (dc_off_ch2_q2 < OFF_LOWER_LT) ||
    517		    (dc_off_ch2_q3 > OFF_UPPER_LT) || (dc_off_ch2_q3 < OFF_LOWER_LT)) {
    518			if (osdac_ch2 == 3) {
    519				ch2_done = 1;
    520			} else {
    521				osdac_ch2++;
    522
    523				val = REG_READ(ah, AR_PHY_65NM_CH2_BB1) & 0x3fffffff;
    524				val |= (osdac_ch2 << 30);
    525				REG_WRITE(ah, AR_PHY_65NM_CH2_BB1, val);
    526
    527				ch2_done = 0;
    528			}
    529		} else {
    530			ch2_done = 1;
    531		}
    532	}
    533
    534	REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
    535		    AR_PHY_AGC_CONTROL_OFFSET_CAL);
    536	REG_SET_BIT(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
    537
    538	/*
    539	 * We don't need to check txiqcal_done here since it is always
    540	 * set for AR9550.
    541	 */
    542	REG_SET_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0,
    543		    AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL);
    544
    545	return true;
    546}
    547
    548/*
    549 * solve 4x4 linear equation used in loopback iq cal.
    550 */
    551static bool ar9003_hw_solve_iq_cal(struct ath_hw *ah,
    552				   s32 sin_2phi_1,
    553				   s32 cos_2phi_1,
    554				   s32 sin_2phi_2,
    555				   s32 cos_2phi_2,
    556				   s32 mag_a0_d0,
    557				   s32 phs_a0_d0,
    558				   s32 mag_a1_d0,
    559				   s32 phs_a1_d0,
    560				   s32 solved_eq[])
    561{
    562	s32 f1 = cos_2phi_1 - cos_2phi_2,
    563	    f3 = sin_2phi_1 - sin_2phi_2,
    564	    f2;
    565	s32 mag_tx, phs_tx, mag_rx, phs_rx;
    566	const s32 result_shift = 1 << 15;
    567	struct ath_common *common = ath9k_hw_common(ah);
    568
    569	f2 = ((f1 >> 3) * (f1 >> 3) + (f3 >> 3) * (f3 >> 3)) >> 9;
    570
    571	if (!f2) {
    572		ath_dbg(common, CALIBRATE, "Divide by 0\n");
    573		return false;
    574	}
    575
    576	/* mag mismatch, tx */
    577	mag_tx = f1 * (mag_a0_d0  - mag_a1_d0) + f3 * (phs_a0_d0 - phs_a1_d0);
    578	/* phs mismatch, tx */
    579	phs_tx = f3 * (-mag_a0_d0 + mag_a1_d0) + f1 * (phs_a0_d0 - phs_a1_d0);
    580
    581	mag_tx = (mag_tx / f2);
    582	phs_tx = (phs_tx / f2);
    583
    584	/* mag mismatch, rx */
    585	mag_rx = mag_a0_d0 - (cos_2phi_1 * mag_tx + sin_2phi_1 * phs_tx) /
    586		 result_shift;
    587	/* phs mismatch, rx */
    588	phs_rx = phs_a0_d0 + (sin_2phi_1 * mag_tx - cos_2phi_1 * phs_tx) /
    589		 result_shift;
    590
    591	solved_eq[0] = mag_tx;
    592	solved_eq[1] = phs_tx;
    593	solved_eq[2] = mag_rx;
    594	solved_eq[3] = phs_rx;
    595
    596	return true;
    597}
    598
    599static s32 ar9003_hw_find_mag_approx(struct ath_hw *ah, s32 in_re, s32 in_im)
    600{
    601	s32 abs_i = abs(in_re),
    602	    abs_q = abs(in_im),
    603	    max_abs, min_abs;
    604
    605	if (abs_i > abs_q) {
    606		max_abs = abs_i;
    607		min_abs = abs_q;
    608	} else {
    609		max_abs = abs_q;
    610		min_abs = abs_i;
    611	}
    612
    613	return max_abs - (max_abs / 32) + (min_abs / 8) + (min_abs / 4);
    614}
    615
    616#define DELPT 32
    617
    618static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah,
    619				   s32 chain_idx,
    620				   const s32 iq_res[],
    621				   s32 iqc_coeff[])
    622{
    623	s32 i2_m_q2_a0_d0, i2_p_q2_a0_d0, iq_corr_a0_d0,
    624	    i2_m_q2_a0_d1, i2_p_q2_a0_d1, iq_corr_a0_d1,
    625	    i2_m_q2_a1_d0, i2_p_q2_a1_d0, iq_corr_a1_d0,
    626	    i2_m_q2_a1_d1, i2_p_q2_a1_d1, iq_corr_a1_d1;
    627	s32 mag_a0_d0, mag_a1_d0, mag_a0_d1, mag_a1_d1,
    628	    phs_a0_d0, phs_a1_d0, phs_a0_d1, phs_a1_d1,
    629	    sin_2phi_1, cos_2phi_1,
    630	    sin_2phi_2, cos_2phi_2;
    631	s32 mag_tx, phs_tx, mag_rx, phs_rx;
    632	s32 solved_eq[4], mag_corr_tx, phs_corr_tx, mag_corr_rx, phs_corr_rx,
    633	    q_q_coff, q_i_coff;
    634	const s32 res_scale = 1 << 15;
    635	const s32 delpt_shift = 1 << 8;
    636	s32 mag1, mag2;
    637	struct ath_common *common = ath9k_hw_common(ah);
    638
    639	i2_m_q2_a0_d0 = iq_res[0] & 0xfff;
    640	i2_p_q2_a0_d0 = (iq_res[0] >> 12) & 0xfff;
    641	iq_corr_a0_d0 = ((iq_res[0] >> 24) & 0xff) + ((iq_res[1] & 0xf) << 8);
    642
    643	if (i2_m_q2_a0_d0 > 0x800)
    644		i2_m_q2_a0_d0 = -((0xfff - i2_m_q2_a0_d0) + 1);
    645
    646	if (i2_p_q2_a0_d0 > 0x800)
    647		i2_p_q2_a0_d0 = -((0xfff - i2_p_q2_a0_d0) + 1);
    648
    649	if (iq_corr_a0_d0 > 0x800)
    650		iq_corr_a0_d0 = -((0xfff - iq_corr_a0_d0) + 1);
    651
    652	i2_m_q2_a0_d1 = (iq_res[1] >> 4) & 0xfff;
    653	i2_p_q2_a0_d1 = (iq_res[2] & 0xfff);
    654	iq_corr_a0_d1 = (iq_res[2] >> 12) & 0xfff;
    655
    656	if (i2_m_q2_a0_d1 > 0x800)
    657		i2_m_q2_a0_d1 = -((0xfff - i2_m_q2_a0_d1) + 1);
    658
    659	if (iq_corr_a0_d1 > 0x800)
    660		iq_corr_a0_d1 = -((0xfff - iq_corr_a0_d1) + 1);
    661
    662	i2_m_q2_a1_d0 = ((iq_res[2] >> 24) & 0xff) + ((iq_res[3] & 0xf) << 8);
    663	i2_p_q2_a1_d0 = (iq_res[3] >> 4) & 0xfff;
    664	iq_corr_a1_d0 = iq_res[4] & 0xfff;
    665
    666	if (i2_m_q2_a1_d0 > 0x800)
    667		i2_m_q2_a1_d0 = -((0xfff - i2_m_q2_a1_d0) + 1);
    668
    669	if (i2_p_q2_a1_d0 > 0x800)
    670		i2_p_q2_a1_d0 = -((0xfff - i2_p_q2_a1_d0) + 1);
    671
    672	if (iq_corr_a1_d0 > 0x800)
    673		iq_corr_a1_d0 = -((0xfff - iq_corr_a1_d0) + 1);
    674
    675	i2_m_q2_a1_d1 = (iq_res[4] >> 12) & 0xfff;
    676	i2_p_q2_a1_d1 = ((iq_res[4] >> 24) & 0xff) + ((iq_res[5] & 0xf) << 8);
    677	iq_corr_a1_d1 = (iq_res[5] >> 4) & 0xfff;
    678
    679	if (i2_m_q2_a1_d1 > 0x800)
    680		i2_m_q2_a1_d1 = -((0xfff - i2_m_q2_a1_d1) + 1);
    681
    682	if (i2_p_q2_a1_d1 > 0x800)
    683		i2_p_q2_a1_d1 = -((0xfff - i2_p_q2_a1_d1) + 1);
    684
    685	if (iq_corr_a1_d1 > 0x800)
    686		iq_corr_a1_d1 = -((0xfff - iq_corr_a1_d1) + 1);
    687
    688	if ((i2_p_q2_a0_d0 == 0) || (i2_p_q2_a0_d1 == 0) ||
    689	    (i2_p_q2_a1_d0 == 0) || (i2_p_q2_a1_d1 == 0)) {
    690		ath_dbg(common, CALIBRATE,
    691			"Divide by 0:\n"
    692			"a0_d0=%d\n"
    693			"a0_d1=%d\n"
    694			"a2_d0=%d\n"
    695			"a1_d1=%d\n",
    696			i2_p_q2_a0_d0, i2_p_q2_a0_d1,
    697			i2_p_q2_a1_d0, i2_p_q2_a1_d1);
    698		return false;
    699	}
    700
    701	if ((i2_p_q2_a0_d0 < 1024) || (i2_p_q2_a0_d0 > 2047) ||
    702            (i2_p_q2_a1_d0 < 0) || (i2_p_q2_a1_d1 < 0) ||
    703            (i2_p_q2_a0_d0 <= i2_m_q2_a0_d0) ||
    704            (i2_p_q2_a0_d0 <= iq_corr_a0_d0) ||
    705            (i2_p_q2_a0_d1 <= i2_m_q2_a0_d1) ||
    706            (i2_p_q2_a0_d1 <= iq_corr_a0_d1) ||
    707            (i2_p_q2_a1_d0 <= i2_m_q2_a1_d0) ||
    708            (i2_p_q2_a1_d0 <= iq_corr_a1_d0) ||
    709            (i2_p_q2_a1_d1 <= i2_m_q2_a1_d1) ||
    710            (i2_p_q2_a1_d1 <= iq_corr_a1_d1)) {
    711		return false;
    712	}
    713
    714	mag_a0_d0 = (i2_m_q2_a0_d0 * res_scale) / i2_p_q2_a0_d0;
    715	phs_a0_d0 = (iq_corr_a0_d0 * res_scale) / i2_p_q2_a0_d0;
    716
    717	mag_a0_d1 = (i2_m_q2_a0_d1 * res_scale) / i2_p_q2_a0_d1;
    718	phs_a0_d1 = (iq_corr_a0_d1 * res_scale) / i2_p_q2_a0_d1;
    719
    720	mag_a1_d0 = (i2_m_q2_a1_d0 * res_scale) / i2_p_q2_a1_d0;
    721	phs_a1_d0 = (iq_corr_a1_d0 * res_scale) / i2_p_q2_a1_d0;
    722
    723	mag_a1_d1 = (i2_m_q2_a1_d1 * res_scale) / i2_p_q2_a1_d1;
    724	phs_a1_d1 = (iq_corr_a1_d1 * res_scale) / i2_p_q2_a1_d1;
    725
    726	/* w/o analog phase shift */
    727	sin_2phi_1 = (((mag_a0_d0 - mag_a0_d1) * delpt_shift) / DELPT);
    728	/* w/o analog phase shift */
    729	cos_2phi_1 = (((phs_a0_d1 - phs_a0_d0) * delpt_shift) / DELPT);
    730	/* w/  analog phase shift */
    731	sin_2phi_2 = (((mag_a1_d0 - mag_a1_d1) * delpt_shift) / DELPT);
    732	/* w/  analog phase shift */
    733	cos_2phi_2 = (((phs_a1_d1 - phs_a1_d0) * delpt_shift) / DELPT);
    734
    735	/*
    736	 * force sin^2 + cos^2 = 1;
    737	 * find magnitude by approximation
    738	 */
    739	mag1 = ar9003_hw_find_mag_approx(ah, cos_2phi_1, sin_2phi_1);
    740	mag2 = ar9003_hw_find_mag_approx(ah, cos_2phi_2, sin_2phi_2);
    741
    742	if ((mag1 == 0) || (mag2 == 0)) {
    743		ath_dbg(common, CALIBRATE, "Divide by 0: mag1=%d, mag2=%d\n",
    744			mag1, mag2);
    745		return false;
    746	}
    747
    748	/* normalization sin and cos by mag */
    749	sin_2phi_1 = (sin_2phi_1 * res_scale / mag1);
    750	cos_2phi_1 = (cos_2phi_1 * res_scale / mag1);
    751	sin_2phi_2 = (sin_2phi_2 * res_scale / mag2);
    752	cos_2phi_2 = (cos_2phi_2 * res_scale / mag2);
    753
    754	/* calculate IQ mismatch */
    755	if (!ar9003_hw_solve_iq_cal(ah,
    756			     sin_2phi_1, cos_2phi_1,
    757			     sin_2phi_2, cos_2phi_2,
    758			     mag_a0_d0, phs_a0_d0,
    759			     mag_a1_d0,
    760			     phs_a1_d0, solved_eq)) {
    761		ath_dbg(common, CALIBRATE,
    762			"Call to ar9003_hw_solve_iq_cal() failed\n");
    763		return false;
    764	}
    765
    766	mag_tx = solved_eq[0];
    767	phs_tx = solved_eq[1];
    768	mag_rx = solved_eq[2];
    769	phs_rx = solved_eq[3];
    770
    771	ath_dbg(common, CALIBRATE,
    772		"chain %d: mag mismatch=%d phase mismatch=%d\n",
    773		chain_idx, mag_tx/res_scale, phs_tx/res_scale);
    774
    775	if (res_scale == mag_tx) {
    776		ath_dbg(common, CALIBRATE,
    777			"Divide by 0: mag_tx=%d, res_scale=%d\n",
    778			mag_tx, res_scale);
    779		return false;
    780	}
    781
    782	/* calculate and quantize Tx IQ correction factor */
    783	mag_corr_tx = (mag_tx * res_scale) / (res_scale - mag_tx);
    784	phs_corr_tx = -phs_tx;
    785
    786	q_q_coff = (mag_corr_tx * 128 / res_scale);
    787	q_i_coff = (phs_corr_tx * 256 / res_scale);
    788
    789	ath_dbg(common, CALIBRATE, "tx chain %d: mag corr=%d  phase corr=%d\n",
    790		chain_idx, q_q_coff, q_i_coff);
    791
    792	if (q_i_coff < -63)
    793		q_i_coff = -63;
    794	if (q_i_coff > 63)
    795		q_i_coff = 63;
    796	if (q_q_coff < -63)
    797		q_q_coff = -63;
    798	if (q_q_coff > 63)
    799		q_q_coff = 63;
    800
    801	iqc_coeff[0] = (q_q_coff * 128) + (0x7f & q_i_coff);
    802
    803	ath_dbg(common, CALIBRATE, "tx chain %d: iq corr coeff=%x\n",
    804		chain_idx, iqc_coeff[0]);
    805
    806	if (-mag_rx == res_scale) {
    807		ath_dbg(common, CALIBRATE,
    808			"Divide by 0: mag_rx=%d, res_scale=%d\n",
    809			mag_rx, res_scale);
    810		return false;
    811	}
    812
    813	/* calculate and quantize Rx IQ correction factors */
    814	mag_corr_rx = (-mag_rx * res_scale) / (res_scale + mag_rx);
    815	phs_corr_rx = -phs_rx;
    816
    817	q_q_coff = (mag_corr_rx * 128 / res_scale);
    818	q_i_coff = (phs_corr_rx * 256 / res_scale);
    819
    820	ath_dbg(common, CALIBRATE, "rx chain %d: mag corr=%d  phase corr=%d\n",
    821		chain_idx, q_q_coff, q_i_coff);
    822
    823	if (q_i_coff < -63)
    824		q_i_coff = -63;
    825	if (q_i_coff > 63)
    826		q_i_coff = 63;
    827	if (q_q_coff < -63)
    828		q_q_coff = -63;
    829	if (q_q_coff > 63)
    830		q_q_coff = 63;
    831
    832	iqc_coeff[1] = (q_q_coff * 128) + (0x7f & q_i_coff);
    833
    834	ath_dbg(common, CALIBRATE, "rx chain %d: iq corr coeff=%x\n",
    835		chain_idx, iqc_coeff[1]);
    836
    837	return true;
    838}
    839
    840static void ar9003_hw_detect_outlier(int mp_coeff[][MAXIQCAL],
    841				     int nmeasurement,
    842				     int max_delta)
    843{
    844	int mp_max = -64, max_idx = 0;
    845	int mp_min = 63, min_idx = 0;
    846	int mp_avg = 0, i, outlier_idx = 0, mp_count = 0;
    847
    848	/* find min/max mismatch across all calibrated gains */
    849	for (i = 0; i < nmeasurement; i++) {
    850		if (mp_coeff[i][0] > mp_max) {
    851			mp_max = mp_coeff[i][0];
    852			max_idx = i;
    853		} else if (mp_coeff[i][0] < mp_min) {
    854			mp_min = mp_coeff[i][0];
    855			min_idx = i;
    856		}
    857	}
    858
    859	/* find average (exclude max abs value) */
    860	for (i = 0; i < nmeasurement; i++) {
    861		if ((abs(mp_coeff[i][0]) < abs(mp_max)) ||
    862		    (abs(mp_coeff[i][0]) < abs(mp_min))) {
    863			mp_avg += mp_coeff[i][0];
    864			mp_count++;
    865		}
    866	}
    867
    868	/*
    869	 * finding mean magnitude/phase if possible, otherwise
    870	 * just use the last value as the mean
    871	 */
    872	if (mp_count)
    873		mp_avg /= mp_count;
    874	else
    875		mp_avg = mp_coeff[nmeasurement - 1][0];
    876
    877	/* detect outlier */
    878	if (abs(mp_max - mp_min) > max_delta) {
    879		if (abs(mp_max - mp_avg) > abs(mp_min - mp_avg))
    880			outlier_idx = max_idx;
    881		else
    882			outlier_idx = min_idx;
    883
    884		mp_coeff[outlier_idx][0] = mp_avg;
    885	}
    886}
    887
    888static void ar9003_hw_tx_iq_cal_outlier_detection(struct ath_hw *ah,
    889						  struct coeff *coeff,
    890						  bool is_reusable)
    891{
    892	int i, im, nmeasurement;
    893	int magnitude, phase;
    894	u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS];
    895	struct ath9k_hw_cal_data *caldata = ah->caldata;
    896
    897	memset(tx_corr_coeff, 0, sizeof(tx_corr_coeff));
    898	for (i = 0; i < MAX_MEASUREMENT / 2; i++) {
    899		tx_corr_coeff[i * 2][0] = tx_corr_coeff[(i * 2) + 1][0] =
    900					AR_PHY_TX_IQCAL_CORR_COEFF_B0(i);
    901		if (!AR_SREV_9485(ah)) {
    902			tx_corr_coeff[i * 2][1] =
    903			tx_corr_coeff[(i * 2) + 1][1] =
    904					AR_PHY_TX_IQCAL_CORR_COEFF_B1(i);
    905
    906			tx_corr_coeff[i * 2][2] =
    907			tx_corr_coeff[(i * 2) + 1][2] =
    908					AR_PHY_TX_IQCAL_CORR_COEFF_B2(i);
    909		}
    910	}
    911
    912	/* Load the average of 2 passes */
    913	for (i = 0; i < AR9300_MAX_CHAINS; i++) {
    914		if (!(ah->txchainmask & (1 << i)))
    915			continue;
    916		nmeasurement = REG_READ_FIELD(ah,
    917				AR_PHY_TX_IQCAL_STATUS_B0,
    918				AR_PHY_CALIBRATED_GAINS_0);
    919
    920		if (nmeasurement > MAX_MEASUREMENT)
    921			nmeasurement = MAX_MEASUREMENT;
    922
    923		/*
    924		 * Skip normal outlier detection for AR9550.
    925		 */
    926		if (!AR_SREV_9550(ah)) {
    927			/* detect outlier only if nmeasurement > 1 */
    928			if (nmeasurement > 1) {
    929				/* Detect magnitude outlier */
    930				ar9003_hw_detect_outlier(coeff->mag_coeff[i],
    931							 nmeasurement,
    932							 MAX_MAG_DELTA);
    933
    934				/* Detect phase outlier */
    935				ar9003_hw_detect_outlier(coeff->phs_coeff[i],
    936							 nmeasurement,
    937							 MAX_PHS_DELTA);
    938			}
    939		}
    940
    941		for (im = 0; im < nmeasurement; im++) {
    942			magnitude = coeff->mag_coeff[i][im][0];
    943			phase = coeff->phs_coeff[i][im][0];
    944
    945			coeff->iqc_coeff[0] =
    946				(phase & 0x7f) | ((magnitude & 0x7f) << 7);
    947
    948			if ((im % 2) == 0)
    949				REG_RMW_FIELD(ah, tx_corr_coeff[im][i],
    950					AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE,
    951					coeff->iqc_coeff[0]);
    952			else
    953				REG_RMW_FIELD(ah, tx_corr_coeff[im][i],
    954					AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
    955					coeff->iqc_coeff[0]);
    956
    957			if (caldata)
    958				caldata->tx_corr_coeff[im][i] =
    959					coeff->iqc_coeff[0];
    960		}
    961		if (caldata)
    962			caldata->num_measures[i] = nmeasurement;
    963	}
    964
    965	REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
    966		      AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1);
    967	REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
    968		      AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1);
    969
    970	if (caldata) {
    971		if (is_reusable)
    972			set_bit(TXIQCAL_DONE, &caldata->cal_flags);
    973		else
    974			clear_bit(TXIQCAL_DONE, &caldata->cal_flags);
    975	}
    976
    977	return;
    978}
    979
    980static bool ar9003_hw_tx_iq_cal_run(struct ath_hw *ah)
    981{
    982	struct ath_common *common = ath9k_hw_common(ah);
    983	u8 tx_gain_forced;
    984
    985	tx_gain_forced = REG_READ_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
    986					AR_PHY_TXGAIN_FORCE);
    987	if (tx_gain_forced)
    988		REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
    989			      AR_PHY_TXGAIN_FORCE, 0);
    990
    991	REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START,
    992		      AR_PHY_TX_IQCAL_START_DO_CAL, 1);
    993
    994	if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START,
    995			AR_PHY_TX_IQCAL_START_DO_CAL, 0,
    996			AH_WAIT_TIMEOUT)) {
    997		ath_dbg(common, CALIBRATE, "Tx IQ Cal is not completed\n");
    998		return false;
    999	}
   1000	return true;
   1001}
   1002
   1003static void __ar955x_tx_iq_cal_sort(struct ath_hw *ah,
   1004				    struct coeff *coeff,
   1005				    int i, int nmeasurement)
   1006{
   1007	struct ath_common *common = ath9k_hw_common(ah);
   1008	int im, ix, iy;
   1009
   1010	for (im = 0; im < nmeasurement; im++) {
   1011		for (ix = 0; ix < MAXIQCAL - 1; ix++) {
   1012			for (iy = ix + 1; iy <= MAXIQCAL - 1; iy++) {
   1013				if (coeff->mag_coeff[i][im][iy] <
   1014				    coeff->mag_coeff[i][im][ix]) {
   1015					swap(coeff->mag_coeff[i][im][ix],
   1016					     coeff->mag_coeff[i][im][iy]);
   1017				}
   1018				if (coeff->phs_coeff[i][im][iy] <
   1019				    coeff->phs_coeff[i][im][ix]) {
   1020					swap(coeff->phs_coeff[i][im][ix],
   1021					     coeff->phs_coeff[i][im][iy]);
   1022				}
   1023			}
   1024		}
   1025		coeff->mag_coeff[i][im][0] = coeff->mag_coeff[i][im][MAXIQCAL / 2];
   1026		coeff->phs_coeff[i][im][0] = coeff->phs_coeff[i][im][MAXIQCAL / 2];
   1027
   1028		ath_dbg(common, CALIBRATE,
   1029			"IQCAL: Median [ch%d][gain%d]: mag = %d phase = %d\n",
   1030			i, im,
   1031			coeff->mag_coeff[i][im][0],
   1032			coeff->phs_coeff[i][im][0]);
   1033	}
   1034}
   1035
   1036static bool ar955x_tx_iq_cal_median(struct ath_hw *ah,
   1037				    struct coeff *coeff,
   1038				    int iqcal_idx,
   1039				    int nmeasurement)
   1040{
   1041	int i;
   1042
   1043	if ((iqcal_idx + 1) != MAXIQCAL)
   1044		return false;
   1045
   1046	for (i = 0; i < AR9300_MAX_CHAINS; i++) {
   1047		__ar955x_tx_iq_cal_sort(ah, coeff, i, nmeasurement);
   1048	}
   1049
   1050	return true;
   1051}
   1052
   1053static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah,
   1054					  int iqcal_idx,
   1055					  bool is_reusable)
   1056{
   1057	struct ath_common *common = ath9k_hw_common(ah);
   1058	const u32 txiqcal_status[AR9300_MAX_CHAINS] = {
   1059		AR_PHY_TX_IQCAL_STATUS_B0,
   1060		AR_PHY_TX_IQCAL_STATUS_B1,
   1061		AR_PHY_TX_IQCAL_STATUS_B2,
   1062	};
   1063	const u_int32_t chan_info_tab[] = {
   1064		AR_PHY_CHAN_INFO_TAB_0,
   1065		AR_PHY_CHAN_INFO_TAB_1,
   1066		AR_PHY_CHAN_INFO_TAB_2,
   1067	};
   1068	static struct coeff coeff;
   1069	s32 iq_res[6];
   1070	int i, im, j;
   1071	int nmeasurement = 0;
   1072	bool outlier_detect = true;
   1073
   1074	for (i = 0; i < AR9300_MAX_CHAINS; i++) {
   1075		if (!(ah->txchainmask & (1 << i)))
   1076			continue;
   1077
   1078		nmeasurement = REG_READ_FIELD(ah,
   1079				AR_PHY_TX_IQCAL_STATUS_B0,
   1080				AR_PHY_CALIBRATED_GAINS_0);
   1081		if (nmeasurement > MAX_MEASUREMENT)
   1082			nmeasurement = MAX_MEASUREMENT;
   1083
   1084		for (im = 0; im < nmeasurement; im++) {
   1085			ath_dbg(common, CALIBRATE,
   1086				"Doing Tx IQ Cal for chain %d\n", i);
   1087
   1088			if (REG_READ(ah, txiqcal_status[i]) &
   1089					AR_PHY_TX_IQCAL_STATUS_FAILED) {
   1090				ath_dbg(common, CALIBRATE,
   1091					"Tx IQ Cal failed for chain %d\n", i);
   1092				goto tx_iqcal_fail;
   1093			}
   1094
   1095			for (j = 0; j < 3; j++) {
   1096				u32 idx = 2 * j, offset = 4 * (3 * im + j);
   1097
   1098				REG_RMW_FIELD(ah,
   1099						AR_PHY_CHAN_INFO_MEMORY,
   1100						AR_PHY_CHAN_INFO_TAB_S2_READ,
   1101						0);
   1102
   1103				/* 32 bits */
   1104				iq_res[idx] = REG_READ(ah,
   1105						chan_info_tab[i] +
   1106						offset);
   1107
   1108				REG_RMW_FIELD(ah,
   1109						AR_PHY_CHAN_INFO_MEMORY,
   1110						AR_PHY_CHAN_INFO_TAB_S2_READ,
   1111						1);
   1112
   1113				/* 16 bits */
   1114				iq_res[idx + 1] = 0xffff & REG_READ(ah,
   1115						chan_info_tab[i] + offset);
   1116
   1117				ath_dbg(common, CALIBRATE,
   1118					"IQ_RES[%d]=0x%x IQ_RES[%d]=0x%x\n",
   1119					idx, iq_res[idx], idx + 1,
   1120					iq_res[idx + 1]);
   1121			}
   1122
   1123			if (!ar9003_hw_calc_iq_corr(ah, i, iq_res,
   1124						coeff.iqc_coeff)) {
   1125				ath_dbg(common, CALIBRATE,
   1126					"Failed in calculation of IQ correction\n");
   1127				goto tx_iqcal_fail;
   1128			}
   1129
   1130			coeff.phs_coeff[i][im][iqcal_idx] =
   1131				coeff.iqc_coeff[0] & 0x7f;
   1132			coeff.mag_coeff[i][im][iqcal_idx] =
   1133				(coeff.iqc_coeff[0] >> 7) & 0x7f;
   1134
   1135			if (coeff.mag_coeff[i][im][iqcal_idx] > 63)
   1136				coeff.mag_coeff[i][im][iqcal_idx] -= 128;
   1137			if (coeff.phs_coeff[i][im][iqcal_idx] > 63)
   1138				coeff.phs_coeff[i][im][iqcal_idx] -= 128;
   1139		}
   1140	}
   1141
   1142	if (AR_SREV_9550(ah))
   1143		outlier_detect = ar955x_tx_iq_cal_median(ah, &coeff,
   1144							 iqcal_idx, nmeasurement);
   1145	if (outlier_detect)
   1146		ar9003_hw_tx_iq_cal_outlier_detection(ah, &coeff, is_reusable);
   1147
   1148	return;
   1149
   1150tx_iqcal_fail:
   1151	ath_dbg(common, CALIBRATE, "Tx IQ Cal failed\n");
   1152	return;
   1153}
   1154
   1155static void ar9003_hw_tx_iq_cal_reload(struct ath_hw *ah)
   1156{
   1157	struct ath9k_hw_cal_data *caldata = ah->caldata;
   1158	u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS];
   1159	int i, im;
   1160
   1161	memset(tx_corr_coeff, 0, sizeof(tx_corr_coeff));
   1162	for (i = 0; i < MAX_MEASUREMENT / 2; i++) {
   1163		tx_corr_coeff[i * 2][0] = tx_corr_coeff[(i * 2) + 1][0] =
   1164					AR_PHY_TX_IQCAL_CORR_COEFF_B0(i);
   1165		if (!AR_SREV_9485(ah)) {
   1166			tx_corr_coeff[i * 2][1] =
   1167			tx_corr_coeff[(i * 2) + 1][1] =
   1168					AR_PHY_TX_IQCAL_CORR_COEFF_B1(i);
   1169
   1170			tx_corr_coeff[i * 2][2] =
   1171			tx_corr_coeff[(i * 2) + 1][2] =
   1172					AR_PHY_TX_IQCAL_CORR_COEFF_B2(i);
   1173		}
   1174	}
   1175
   1176	for (i = 0; i < AR9300_MAX_CHAINS; i++) {
   1177		if (!(ah->txchainmask & (1 << i)))
   1178			continue;
   1179
   1180		for (im = 0; im < caldata->num_measures[i]; im++) {
   1181			if ((im % 2) == 0)
   1182				REG_RMW_FIELD(ah, tx_corr_coeff[im][i],
   1183				     AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE,
   1184				     caldata->tx_corr_coeff[im][i]);
   1185			else
   1186				REG_RMW_FIELD(ah, tx_corr_coeff[im][i],
   1187				     AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
   1188				     caldata->tx_corr_coeff[im][i]);
   1189		}
   1190	}
   1191
   1192	REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
   1193		      AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1);
   1194	REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
   1195		      AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1);
   1196}
   1197
   1198static void ar9003_hw_manual_peak_cal(struct ath_hw *ah, u8 chain, bool is_2g)
   1199{
   1200	int offset[8] = {0}, total = 0, test;
   1201	int agc_out, i, peak_detect_threshold = 0;
   1202
   1203	if (AR_SREV_9550(ah) || AR_SREV_9531(ah))
   1204		peak_detect_threshold = 8;
   1205	else if (AR_SREV_9561(ah))
   1206		peak_detect_threshold = 11;
   1207
   1208	/*
   1209	 * Turn off LNA/SW.
   1210	 */
   1211	REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
   1212		      AR_PHY_65NM_RXRF_GAINSTAGES_RX_OVERRIDE, 0x1);
   1213	REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
   1214		      AR_PHY_65NM_RXRF_GAINSTAGES_LNAON_CALDC, 0x0);
   1215
   1216	if (AR_SREV_9003_PCOEM(ah) || AR_SREV_9330_11(ah)) {
   1217		if (is_2g)
   1218			REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
   1219				      AR_PHY_65NM_RXRF_GAINSTAGES_LNA2G_GAIN_OVR, 0x0);
   1220		else
   1221			REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
   1222				      AR_PHY_65NM_RXRF_GAINSTAGES_LNA5G_GAIN_OVR, 0x0);
   1223	}
   1224
   1225	/*
   1226	 * Turn off RXON.
   1227	 */
   1228	REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain),
   1229		      AR_PHY_65NM_RXTX2_RXON_OVR, 0x1);
   1230	REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain),
   1231		      AR_PHY_65NM_RXTX2_RXON, 0x0);
   1232
   1233	/*
   1234	 * Turn on AGC for cal.
   1235	 */
   1236	REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
   1237		      AR_PHY_65NM_RXRF_AGC_AGC_OVERRIDE, 0x1);
   1238	REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
   1239		      AR_PHY_65NM_RXRF_AGC_AGC_ON_OVR, 0x1);
   1240	REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
   1241		      AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR, 0x1);
   1242
   1243	if (AR_SREV_9330_11(ah))
   1244		REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
   1245			      AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR, 0x0);
   1246
   1247	if (is_2g)
   1248		REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
   1249			      AR_PHY_65NM_RXRF_AGC_AGC2G_DBDAC_OVR,
   1250			      peak_detect_threshold);
   1251	else
   1252		REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
   1253			      AR_PHY_65NM_RXRF_AGC_AGC5G_DBDAC_OVR,
   1254			      peak_detect_threshold);
   1255
   1256	for (i = 6; i > 0; i--) {
   1257		offset[i] = BIT(i - 1);
   1258		test = total + offset[i];
   1259
   1260		if (is_2g)
   1261			REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
   1262				      AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR,
   1263				      test);
   1264		else
   1265			REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
   1266				      AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR,
   1267				      test);
   1268		udelay(100);
   1269		agc_out = REG_READ_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
   1270					 AR_PHY_65NM_RXRF_AGC_AGC_OUT);
   1271		offset[i] = (agc_out) ? 0 : 1;
   1272		total += (offset[i] << (i - 1));
   1273	}
   1274
   1275	if (is_2g)
   1276		REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
   1277			      AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR, total);
   1278	else
   1279		REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
   1280			      AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR, total);
   1281
   1282	/*
   1283	 * Turn on LNA.
   1284	 */
   1285	REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
   1286		      AR_PHY_65NM_RXRF_GAINSTAGES_RX_OVERRIDE, 0);
   1287	/*
   1288	 * Turn off RXON.
   1289	 */
   1290	REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain),
   1291		      AR_PHY_65NM_RXTX2_RXON_OVR, 0);
   1292	/*
   1293	 * Turn off peak detect calibration.
   1294	 */
   1295	REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
   1296		      AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR, 0);
   1297}
   1298
   1299static void ar9003_hw_do_pcoem_manual_peak_cal(struct ath_hw *ah,
   1300					       struct ath9k_channel *chan,
   1301					       bool run_rtt_cal)
   1302{
   1303	struct ath9k_hw_cal_data *caldata = ah->caldata;
   1304	int i;
   1305
   1306	if ((ah->caps.hw_caps & ATH9K_HW_CAP_RTT) && !run_rtt_cal)
   1307		return;
   1308
   1309	for (i = 0; i < AR9300_MAX_CHAINS; i++) {
   1310		if (!(ah->rxchainmask & (1 << i)))
   1311			continue;
   1312		ar9003_hw_manual_peak_cal(ah, i, IS_CHAN_2GHZ(chan));
   1313	}
   1314
   1315	if (caldata)
   1316		set_bit(SW_PKDET_DONE, &caldata->cal_flags);
   1317
   1318	if ((ah->caps.hw_caps & ATH9K_HW_CAP_RTT) && caldata) {
   1319		if (IS_CHAN_2GHZ(chan)){
   1320			caldata->caldac[0] = REG_READ_FIELD(ah,
   1321						    AR_PHY_65NM_RXRF_AGC(0),
   1322						    AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR);
   1323			caldata->caldac[1] = REG_READ_FIELD(ah,
   1324						    AR_PHY_65NM_RXRF_AGC(1),
   1325						    AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR);
   1326		} else {
   1327			caldata->caldac[0] = REG_READ_FIELD(ah,
   1328						    AR_PHY_65NM_RXRF_AGC(0),
   1329						    AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR);
   1330			caldata->caldac[1] = REG_READ_FIELD(ah,
   1331						    AR_PHY_65NM_RXRF_AGC(1),
   1332						    AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR);
   1333		}
   1334	}
   1335}
   1336
   1337static void ar9003_hw_cl_cal_post_proc(struct ath_hw *ah, bool is_reusable)
   1338{
   1339	u32 cl_idx[AR9300_MAX_CHAINS] = { AR_PHY_CL_TAB_0,
   1340					  AR_PHY_CL_TAB_1,
   1341					  AR_PHY_CL_TAB_2 };
   1342	struct ath9k_hw_cal_data *caldata = ah->caldata;
   1343	bool txclcal_done = false;
   1344	int i, j;
   1345
   1346	if (!caldata || !(ah->enabled_cals & TX_CL_CAL))
   1347		return;
   1348
   1349	txclcal_done = !!(REG_READ(ah, AR_PHY_AGC_CONTROL) &
   1350			  AR_PHY_AGC_CONTROL_CLC_SUCCESS);
   1351
   1352	if (test_bit(TXCLCAL_DONE, &caldata->cal_flags)) {
   1353		for (i = 0; i < AR9300_MAX_CHAINS; i++) {
   1354			if (!(ah->txchainmask & (1 << i)))
   1355				continue;
   1356			for (j = 0; j < MAX_CL_TAB_ENTRY; j++)
   1357				REG_WRITE(ah, CL_TAB_ENTRY(cl_idx[i]),
   1358					  caldata->tx_clcal[i][j]);
   1359		}
   1360	} else if (is_reusable && txclcal_done) {
   1361		for (i = 0; i < AR9300_MAX_CHAINS; i++) {
   1362			if (!(ah->txchainmask & (1 << i)))
   1363				continue;
   1364			for (j = 0; j < MAX_CL_TAB_ENTRY; j++)
   1365				caldata->tx_clcal[i][j] =
   1366					REG_READ(ah, CL_TAB_ENTRY(cl_idx[i]));
   1367		}
   1368		set_bit(TXCLCAL_DONE, &caldata->cal_flags);
   1369	}
   1370}
   1371
   1372static void ar9003_hw_init_cal_common(struct ath_hw *ah)
   1373{
   1374	struct ath9k_hw_cal_data *caldata = ah->caldata;
   1375
   1376	/* Initialize list pointers */
   1377	ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
   1378
   1379	INIT_CAL(&ah->iq_caldata);
   1380	INSERT_CAL(ah, &ah->iq_caldata);
   1381
   1382	/* Initialize current pointer to first element in list */
   1383	ah->cal_list_curr = ah->cal_list;
   1384
   1385	if (ah->cal_list_curr)
   1386		ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
   1387
   1388	if (caldata)
   1389		caldata->CalValid = 0;
   1390}
   1391
   1392static bool ar9003_hw_init_cal_pcoem(struct ath_hw *ah,
   1393				     struct ath9k_channel *chan)
   1394{
   1395	struct ath_common *common = ath9k_hw_common(ah);
   1396	struct ath9k_hw_cal_data *caldata = ah->caldata;
   1397	bool txiqcal_done = false;
   1398	bool is_reusable = true, status = true;
   1399	bool run_rtt_cal = false, run_agc_cal;
   1400	bool rtt = !!(ah->caps.hw_caps & ATH9K_HW_CAP_RTT);
   1401	u32 rx_delay = 0;
   1402	u32 agc_ctrl = 0, agc_supp_cals = AR_PHY_AGC_CONTROL_OFFSET_CAL |
   1403					  AR_PHY_AGC_CONTROL_FLTR_CAL   |
   1404					  AR_PHY_AGC_CONTROL_PKDET_CAL;
   1405
   1406	/* Use chip chainmask only for calibration */
   1407	ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask);
   1408
   1409	if (rtt) {
   1410		if (!ar9003_hw_rtt_restore(ah, chan))
   1411			run_rtt_cal = true;
   1412
   1413		if (run_rtt_cal)
   1414			ath_dbg(common, CALIBRATE, "RTT calibration to be done\n");
   1415	}
   1416
   1417	run_agc_cal = run_rtt_cal;
   1418
   1419	if (run_rtt_cal) {
   1420		ar9003_hw_rtt_enable(ah);
   1421		ar9003_hw_rtt_set_mask(ah, 0x00);
   1422		ar9003_hw_rtt_clear_hist(ah);
   1423	}
   1424
   1425	if (rtt) {
   1426		if (!run_rtt_cal) {
   1427			agc_ctrl = REG_READ(ah, AR_PHY_AGC_CONTROL);
   1428			agc_supp_cals &= agc_ctrl;
   1429			agc_ctrl &= ~(AR_PHY_AGC_CONTROL_OFFSET_CAL |
   1430				      AR_PHY_AGC_CONTROL_FLTR_CAL |
   1431				      AR_PHY_AGC_CONTROL_PKDET_CAL);
   1432			REG_WRITE(ah, AR_PHY_AGC_CONTROL, agc_ctrl);
   1433		} else {
   1434			if (ah->ah_flags & AH_FASTCC)
   1435				run_agc_cal = true;
   1436		}
   1437	}
   1438
   1439	if (ah->enabled_cals & TX_CL_CAL) {
   1440		if (caldata && test_bit(TXCLCAL_DONE, &caldata->cal_flags))
   1441			REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL,
   1442				    AR_PHY_CL_CAL_ENABLE);
   1443		else {
   1444			REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL,
   1445				    AR_PHY_CL_CAL_ENABLE);
   1446			run_agc_cal = true;
   1447		}
   1448	}
   1449
   1450	if ((IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan)) ||
   1451	    !(ah->enabled_cals & TX_IQ_CAL))
   1452		goto skip_tx_iqcal;
   1453
   1454	/* Do Tx IQ Calibration */
   1455	REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
   1456		      AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
   1457		      DELPT);
   1458
   1459	/*
   1460	 * For AR9485 or later chips, TxIQ cal runs as part of
   1461	 * AGC calibration
   1462	 */
   1463	if (ah->enabled_cals & TX_IQ_ON_AGC_CAL) {
   1464		if (caldata && !test_bit(TXIQCAL_DONE, &caldata->cal_flags))
   1465			REG_SET_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0,
   1466				    AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL);
   1467		else
   1468			REG_CLR_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0,
   1469				    AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL);
   1470		txiqcal_done = run_agc_cal = true;
   1471	}
   1472
   1473skip_tx_iqcal:
   1474	if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal)
   1475		ar9003_mci_init_cal_req(ah, &is_reusable);
   1476
   1477	if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE) {
   1478		rx_delay = REG_READ(ah, AR_PHY_RX_DELAY);
   1479		/* Disable BB_active */
   1480		REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
   1481		udelay(5);
   1482		REG_WRITE(ah, AR_PHY_RX_DELAY, AR_PHY_RX_DELAY_DELAY);
   1483		REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
   1484	}
   1485
   1486	if (run_agc_cal || !(ah->ah_flags & AH_FASTCC)) {
   1487		/* Calibrate the AGC */
   1488		REG_WRITE(ah, AR_PHY_AGC_CONTROL,
   1489			  REG_READ(ah, AR_PHY_AGC_CONTROL) |
   1490			  AR_PHY_AGC_CONTROL_CAL);
   1491
   1492		/* Poll for offset calibration complete */
   1493		status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
   1494				       AR_PHY_AGC_CONTROL_CAL,
   1495				       0, AH_WAIT_TIMEOUT);
   1496
   1497		ar9003_hw_do_pcoem_manual_peak_cal(ah, chan, run_rtt_cal);
   1498	}
   1499
   1500	if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE) {
   1501		REG_WRITE(ah, AR_PHY_RX_DELAY, rx_delay);
   1502		udelay(5);
   1503	}
   1504
   1505	if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal)
   1506		ar9003_mci_init_cal_done(ah);
   1507
   1508	if (rtt && !run_rtt_cal) {
   1509		agc_ctrl |= agc_supp_cals;
   1510		REG_WRITE(ah, AR_PHY_AGC_CONTROL, agc_ctrl);
   1511	}
   1512
   1513	if (!status) {
   1514		if (run_rtt_cal)
   1515			ar9003_hw_rtt_disable(ah);
   1516
   1517		ath_dbg(common, CALIBRATE,
   1518			"offset calibration failed to complete in %d ms; noisy environment?\n",
   1519			AH_WAIT_TIMEOUT / 1000);
   1520		return false;
   1521	}
   1522
   1523	if (txiqcal_done)
   1524		ar9003_hw_tx_iq_cal_post_proc(ah, 0, is_reusable);
   1525	else if (caldata && test_bit(TXIQCAL_DONE, &caldata->cal_flags))
   1526		ar9003_hw_tx_iq_cal_reload(ah);
   1527
   1528	ar9003_hw_cl_cal_post_proc(ah, is_reusable);
   1529
   1530	if (run_rtt_cal && caldata) {
   1531		if (is_reusable) {
   1532			if (!ath9k_hw_rfbus_req(ah)) {
   1533				ath_err(ath9k_hw_common(ah),
   1534					"Could not stop baseband\n");
   1535			} else {
   1536				ar9003_hw_rtt_fill_hist(ah);
   1537
   1538				if (test_bit(SW_PKDET_DONE, &caldata->cal_flags))
   1539					ar9003_hw_rtt_load_hist(ah);
   1540			}
   1541
   1542			ath9k_hw_rfbus_done(ah);
   1543		}
   1544
   1545		ar9003_hw_rtt_disable(ah);
   1546	}
   1547
   1548	/* Revert chainmask to runtime parameters */
   1549	ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
   1550
   1551	ar9003_hw_init_cal_common(ah);
   1552
   1553	return true;
   1554}
   1555
   1556static bool do_ar9003_agc_cal(struct ath_hw *ah)
   1557{
   1558	struct ath_common *common = ath9k_hw_common(ah);
   1559	bool status;
   1560
   1561	REG_WRITE(ah, AR_PHY_AGC_CONTROL,
   1562		  REG_READ(ah, AR_PHY_AGC_CONTROL) |
   1563		  AR_PHY_AGC_CONTROL_CAL);
   1564
   1565	status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
   1566			       AR_PHY_AGC_CONTROL_CAL,
   1567			       0, AH_WAIT_TIMEOUT);
   1568	if (!status) {
   1569		ath_dbg(common, CALIBRATE,
   1570			"offset calibration failed to complete in %d ms,"
   1571			"noisy environment?\n",
   1572			AH_WAIT_TIMEOUT / 1000);
   1573		return false;
   1574	}
   1575
   1576	return true;
   1577}
   1578
   1579static bool ar9003_hw_init_cal_soc(struct ath_hw *ah,
   1580				   struct ath9k_channel *chan)
   1581{
   1582	bool txiqcal_done = false;
   1583	bool status = true;
   1584	bool run_agc_cal = false, sep_iq_cal = false;
   1585	int i = 0;
   1586
   1587	/* Use chip chainmask only for calibration */
   1588	ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask);
   1589
   1590	if (ah->enabled_cals & TX_CL_CAL) {
   1591		REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
   1592		run_agc_cal = true;
   1593	}
   1594
   1595	if (IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan))
   1596		goto skip_tx_iqcal;
   1597
   1598	/* Do Tx IQ Calibration */
   1599	REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
   1600		      AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
   1601		      DELPT);
   1602
   1603	/*
   1604	 * For AR9485 or later chips, TxIQ cal runs as part of
   1605	 * AGC calibration. Specifically, AR9550 in SoC chips.
   1606	 */
   1607	if (ah->enabled_cals & TX_IQ_ON_AGC_CAL) {
   1608		if (REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_0,
   1609				   AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL)) {
   1610				txiqcal_done = true;
   1611		} else {
   1612			txiqcal_done = false;
   1613		}
   1614		run_agc_cal = true;
   1615	} else {
   1616		sep_iq_cal = true;
   1617		run_agc_cal = true;
   1618	}
   1619
   1620	/*
   1621	 * In the SoC family, this will run for AR9300, AR9331 and AR9340.
   1622	 */
   1623	if (sep_iq_cal) {
   1624		txiqcal_done = ar9003_hw_tx_iq_cal_run(ah);
   1625		REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
   1626		udelay(5);
   1627		REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
   1628	}
   1629
   1630	if (AR_SREV_9550(ah) && IS_CHAN_2GHZ(chan)) {
   1631		if (!ar9003_hw_dynamic_osdac_selection(ah, txiqcal_done))
   1632			return false;
   1633	}
   1634
   1635skip_tx_iqcal:
   1636	if (run_agc_cal || !(ah->ah_flags & AH_FASTCC)) {
   1637		for (i = 0; i < AR9300_MAX_CHAINS; i++) {
   1638			if (!(ah->rxchainmask & (1 << i)))
   1639				continue;
   1640
   1641			ar9003_hw_manual_peak_cal(ah, i,
   1642						  IS_CHAN_2GHZ(chan));
   1643		}
   1644
   1645		/*
   1646		 * For non-AR9550 chips, we just trigger AGC calibration
   1647		 * in the HW, poll for completion and then process
   1648		 * the results.
   1649		 *
   1650		 * For AR955x, we run it multiple times and use
   1651		 * median IQ correction.
   1652		 */
   1653		if (!AR_SREV_9550(ah)) {
   1654			status = do_ar9003_agc_cal(ah);
   1655			if (!status)
   1656				return false;
   1657
   1658			if (txiqcal_done)
   1659				ar9003_hw_tx_iq_cal_post_proc(ah, 0, false);
   1660		} else {
   1661			if (!txiqcal_done) {
   1662				status = do_ar9003_agc_cal(ah);
   1663				if (!status)
   1664					return false;
   1665			} else {
   1666				for (i = 0; i < MAXIQCAL; i++) {
   1667					status = do_ar9003_agc_cal(ah);
   1668					if (!status)
   1669						return false;
   1670					ar9003_hw_tx_iq_cal_post_proc(ah, i, false);
   1671				}
   1672			}
   1673		}
   1674	}
   1675
   1676	/* Revert chainmask to runtime parameters */
   1677	ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
   1678
   1679	ar9003_hw_init_cal_common(ah);
   1680
   1681	return true;
   1682}
   1683
   1684void ar9003_hw_attach_calib_ops(struct ath_hw *ah)
   1685{
   1686	struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
   1687	struct ath_hw_ops *ops = ath9k_hw_ops(ah);
   1688
   1689	if (AR_SREV_9003_PCOEM(ah))
   1690		priv_ops->init_cal = ar9003_hw_init_cal_pcoem;
   1691	else
   1692		priv_ops->init_cal = ar9003_hw_init_cal_soc;
   1693
   1694	priv_ops->init_cal_settings = ar9003_hw_init_cal_settings;
   1695	priv_ops->setup_calibration = ar9003_hw_setup_calibration;
   1696
   1697	ops->calibrate = ar9003_hw_calibrate;
   1698}