@ -23,6 +23,7 @@
# define MAX_MEASUREMENT MAX_IQCAL_MEASUREMENT
# define MAX_MAG_DELTA 11
# define MAX_PHS_DELTA 10
# define MAXIQCAL 3
struct coeff {
int mag_coeff [ AR9300_MAX_CHAINS ] [ MAX_MEASUREMENT ] ;
@ -797,7 +798,7 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah,
if ( q_q_coff > 63 )
q_q_coff = 63 ;
iqc_coeff [ 0 ] = ( q_q_coff * 128 ) + q_i_coff ;
iqc_coeff [ 0 ] = ( q_q_coff * 128 ) + ( 0x7f & q_i_coff ) ;
ath_dbg ( common , CALIBRATE , " tx chain %d: iq corr coeff=%x \n " ,
chain_idx , iqc_coeff [ 0 ] ) ;
@ -828,7 +829,7 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah,
if ( q_q_coff > 63 )
q_q_coff = 63 ;
iqc_coeff [ 1 ] = ( q_q_coff * 128 ) + q_i_coff ;
iqc_coeff [ 1 ] = ( q_q_coff * 128 ) + ( 0x7f & q_i_coff ) ;
ath_dbg ( common , CALIBRATE , " rx chain %d: iq corr coeff=%x \n " ,
chain_idx , iqc_coeff [ 1 ] ) ;
@ -991,7 +992,9 @@ static bool ar9003_hw_tx_iq_cal_run(struct ath_hw *ah)
return true ;
}
static void ar9003_hw_tx_iq_cal_post_proc ( struct ath_hw * ah , bool is_reusable )
static void ar9003_hw_tx_iq_cal_post_proc ( struct ath_hw * ah ,
int iqcal_idx ,
bool is_reusable )
{
struct ath_common * common = ath9k_hw_common ( ah ) ;
const u32 txiqcal_status [ AR9300_MAX_CHAINS ] = {
@ -1410,7 +1413,7 @@ skip_tx_iqcal:
}
if ( txiqcal_done )
ar9003_hw_tx_iq_cal_post_proc ( ah , is_reusable ) ;
ar9003_hw_tx_iq_cal_post_proc ( ah , 0 , is_reusable ) ;
else if ( caldata & & test_bit ( TXIQCAL_DONE , & caldata - > cal_flags ) )
ar9003_hw_tx_iq_cal_reload ( ah ) ;
@ -1456,6 +1459,29 @@ skip_tx_iqcal:
return true ;
}
static bool do_ar9003_agc_cal ( struct ath_hw * ah )
{
struct ath_common * common = ath9k_hw_common ( ah ) ;
bool status ;
REG_WRITE ( ah , AR_PHY_AGC_CONTROL ,
REG_READ ( ah , AR_PHY_AGC_CONTROL ) |
AR_PHY_AGC_CONTROL_CAL ) ;
status = ath9k_hw_wait ( ah , AR_PHY_AGC_CONTROL ,
AR_PHY_AGC_CONTROL_CAL ,
0 , AH_WAIT_TIMEOUT ) ;
if ( ! status ) {
ath_dbg ( common , CALIBRATE ,
" offset calibration failed to complete in %d ms, "
" noisy environment? \n " ,
AH_WAIT_TIMEOUT / 1000 ) ;
return false ;
}
return true ;
}
static bool ar9003_hw_init_cal_soc ( struct ath_hw * ah ,
struct ath9k_channel * chan )
{
@ -1464,6 +1490,7 @@ static bool ar9003_hw_init_cal_soc(struct ath_hw *ah,
bool txiqcal_done = false ;
bool status = true ;
bool run_agc_cal = false , sep_iq_cal = false ;
int i = 0 ;
/* Use chip chainmask only for calibration */
ar9003_hw_set_chain_masks ( ah , ah - > caps . rx_chainmask , ah - > caps . tx_chainmask ) ;
@ -1518,27 +1545,37 @@ skip_tx_iqcal:
if ( AR_SREV_9330_11 ( ah ) )
ar9003_hw_manual_peak_cal ( ah , 0 , IS_CHAN_2GHZ ( chan ) ) ;
/* Calibrate the AGC */
REG_WRITE ( ah , AR_PHY_AGC_CONTROL ,
REG_READ ( ah , AR_PHY_AGC_CONTROL ) |
AR_PHY_AGC_CONTROL_CAL ) ;
/* Poll for offset calibration complete */
status = ath9k_hw_wait ( ah , AR_PHY_AGC_CONTROL ,
AR_PHY_AGC_CONTROL_CAL ,
0 , AH_WAIT_TIMEOUT ) ;
}
/*
* For non - AR9550 chips , we just trigger AGC calibration
* in the HW , poll for completion and then process
* the results .
*
* For AR955x , we run it multiple times and use
* median IQ correction .
*/
if ( ! AR_SREV_9550 ( ah ) ) {
status = do_ar9003_agc_cal ( ah ) ;
if ( ! status )
return false ;
if ( ! status ) {
ath_dbg ( common , CALIBRATE ,
" offset calibration failed to complete in %d ms; noisy environment? \n " ,
AH_WAIT_TIMEOUT / 1000 ) ;
return false ;
if ( txiqcal_done )
ar9003_hw_tx_iq_cal_post_proc ( ah , 0 , false ) ;
} else {
if ( ! txiqcal_done ) {
status = do_ar9003_agc_cal ( ah ) ;
if ( ! status )
return false ;
} else {
for ( i = 0 ; i < MAXIQCAL ; i + + ) {
status = do_ar9003_agc_cal ( ah ) ;
if ( ! status )
return false ;
ar9003_hw_tx_iq_cal_post_proc ( ah , i , false ) ;
}
}
}
}
if ( txiqcal_done )
ar9003_hw_tx_iq_cal_post_proc ( ah , false ) ;
/* Revert chainmask to runtime parameters */
ar9003_hw_set_chain_masks ( ah , ah - > rxchainmask , ah - > txchainmask ) ;