2010-04-15 17:38:14 -04:00
/*
* Copyright ( c ) 2008 - 2010 Atheros Communications Inc .
*
* Permission to use , copy , modify , and / or distribute this software for any
* purpose with or without fee is hereby granted , provided that the above
* copyright notice and this permission notice appear in all copies .
*
* THE SOFTWARE IS PROVIDED " AS IS " AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS . IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL , DIRECT , INDIRECT , OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE , DATA OR PROFITS , WHETHER IN AN
* ACTION OF CONTRACT , NEGLIGENCE OR OTHER TORTIOUS ACTION , ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE .
*/
/**
* DOC : Programming Atheros 802.11 n analog front end radios
*
* AR5416 MAC based PCI devices and AR518 MAC based PCI - Express
* devices have either an external AR2133 analog front end radio for single
* band 2.4 GHz communication or an AR5133 analog front end radio for dual
* band 2.4 GHz / 5 GHz communication .
*
* All devices after the AR5416 and AR5418 family starting with the AR9280
* have their analog front radios , MAC / BB and host PCIe / USB interface embedded
* into a single - chip and require less programming .
*
* The following single - chips exist with a respective embedded radio :
*
* AR9280 - 11 n dual - band 2 x2 MIMO for PCIe
* AR9281 - 11 n single - band 1 x2 MIMO for PCIe
* AR9285 - 11 n single - band 1 x1 for PCIe
* AR9287 - 11 n single - band 2 x2 MIMO for PCIe
*
* AR9220 - 11 n dual - band 2 x2 MIMO for PCI
* AR9223 - 11 n single - band 2 x2 MIMO for PCI
*
* AR9287 - 11 n single - band 1 x1 MIMO for USB
*/
# include "hw.h"
# include "ar9002_phy.h"
/**
* ar9002_hw_set_channel - set channel on single - chip device
* @ ah : atheros hardware structure
* @ chan :
*
* This is the function to change channel on single - chip devices , that is
* all devices after ar9280 .
*
* This function takes the channel value in MHz and sets
* hardware channel value . Assumes writes have been enabled to analog bus .
*
* Actual Expression ,
*
* For 2 GHz channel ,
* Channel Frequency = ( 3 / 4 ) * freq_ref * ( chansel [ 8 : 0 ] + chanfrac [ 16 : 0 ] / 2 ^ 17 )
* ( freq_ref = 40 MHz )
*
* For 5 GHz channel ,
* Channel Frequency = ( 3 / 2 ) * freq_ref * ( chansel [ 8 : 0 ] + chanfrac [ 16 : 0 ] / 2 ^ 10 )
* ( freq_ref = 40 MHz / ( 24 > > amodeRefSel ) )
*/
static int ar9002_hw_set_channel ( struct ath_hw * ah , struct ath9k_channel * chan )
{
u16 bMode , fracMode , aModeRefSel = 0 ;
u32 freq , ndiv , channelSel = 0 , channelFrac = 0 , reg32 = 0 ;
struct chan_centers centers ;
u32 refDivA = 24 ;
ath9k_hw_get_channel_centers ( ah , chan , & centers ) ;
freq = centers . synth_center ;
reg32 = REG_READ ( ah , AR_PHY_SYNTH_CONTROL ) ;
reg32 & = 0xc0000000 ;
if ( freq < 4800 ) { /* 2 GHz, fractional mode */
u32 txctl ;
int regWrites = 0 ;
bMode = 1 ;
fracMode = 1 ;
aModeRefSel = 0 ;
2010-04-15 17:38:32 -04:00
channelSel = CHANSEL_2G ( freq ) ;
2010-04-15 17:38:14 -04:00
if ( AR_SREV_9287_11_OR_LATER ( ah ) ) {
if ( freq = = 2484 ) {
/* Enable channel spreading for channel 14 */
REG_WRITE_ARRAY ( & ah - > iniCckfirJapan2484 ,
1 , regWrites ) ;
} else {
REG_WRITE_ARRAY ( & ah - > iniCckfirNormal ,
1 , regWrites ) ;
}
} else {
txctl = REG_READ ( ah , AR_PHY_CCK_TX_CTRL ) ;
if ( freq = = 2484 ) {
/* Enable channel spreading for channel 14 */
REG_WRITE ( ah , AR_PHY_CCK_TX_CTRL ,
txctl | AR_PHY_CCK_TX_CTRL_JAPAN ) ;
} else {
REG_WRITE ( ah , AR_PHY_CCK_TX_CTRL ,
txctl & ~ AR_PHY_CCK_TX_CTRL_JAPAN ) ;
}
}
} else {
bMode = 0 ;
fracMode = 0 ;
switch ( ah - > eep_ops - > get_eeprom ( ah , EEP_FRAC_N_5G ) ) {
case 0 :
if ( ( freq % 20 ) = = 0 )
aModeRefSel = 3 ;
else if ( ( freq % 10 ) = = 0 )
aModeRefSel = 2 ;
if ( aModeRefSel )
break ;
case 1 :
default :
aModeRefSel = 0 ;
/*
* Enable 2 G ( fractional ) mode for channels
* which are 5 MHz spaced .
*/
fracMode = 1 ;
refDivA = 1 ;
2010-04-15 17:38:32 -04:00
channelSel = CHANSEL_5G ( freq ) ;
2010-04-15 17:38:14 -04:00
/* RefDivA setting */
REG_RMW_FIELD ( ah , AR_AN_SYNTH9 ,
AR_AN_SYNTH9_REFDIVA , refDivA ) ;
}
if ( ! fracMode ) {
ndiv = ( freq * ( refDivA > > aModeRefSel ) ) / 60 ;
channelSel = ndiv & 0x1ff ;
channelFrac = ( ndiv & 0xfffffe00 ) * 2 ;
channelSel = ( channelSel < < 17 ) | channelFrac ;
}
}
reg32 = reg32 |
( bMode < < 29 ) |
( fracMode < < 28 ) | ( aModeRefSel < < 26 ) | ( channelSel ) ;
REG_WRITE ( ah , AR_PHY_SYNTH_CONTROL , reg32 ) ;
ah - > curchan = chan ;
ah - > curchan_rad_index = - 1 ;
return 0 ;
}
/**
* ar9002_hw_spur_mitigate - convert baseband spur frequency
* @ ah : atheros hardware structure
* @ chan :
*
* For single - chip solutions . Converts to baseband spur frequency given the
* input channel frequency and compute register settings below .
*/
static void ar9002_hw_spur_mitigate ( struct ath_hw * ah ,
struct ath9k_channel * chan )
{
int bb_spur = AR_NO_SPUR ;
int freq ;
int bin , cur_bin ;
int bb_spur_off , spur_subchannel_sd ;
int spur_freq_sd ;
int spur_delta_phase ;
int denominator ;
int upper , lower , cur_vit_mask ;
int tmp , newVal ;
int i ;
int pilot_mask_reg [ 4 ] = { AR_PHY_TIMING7 , AR_PHY_TIMING8 ,
AR_PHY_PILOT_MASK_01_30 , AR_PHY_PILOT_MASK_31_60
} ;
int chan_mask_reg [ 4 ] = { AR_PHY_TIMING9 , AR_PHY_TIMING10 ,
AR_PHY_CHANNEL_MASK_01_30 , AR_PHY_CHANNEL_MASK_31_60
} ;
int inc [ 4 ] = { 0 , 100 , 0 , 0 } ;
struct chan_centers centers ;
int8_t mask_m [ 123 ] ;
int8_t mask_p [ 123 ] ;
int8_t mask_amt ;
int tmp_mask ;
int cur_bb_spur ;
bool is2GHz = IS_CHAN_2GHZ ( chan ) ;
memset ( & mask_m , 0 , sizeof ( int8_t ) * 123 ) ;
memset ( & mask_p , 0 , sizeof ( int8_t ) * 123 ) ;
ath9k_hw_get_channel_centers ( ah , chan , & centers ) ;
freq = centers . synth_center ;
ah - > config . spurmode = SPUR_ENABLE_EEPROM ;
for ( i = 0 ; i < AR_EEPROM_MODAL_SPURS ; i + + ) {
cur_bb_spur = ah - > eep_ops - > get_spur_channel ( ah , i , is2GHz ) ;
if ( is2GHz )
cur_bb_spur = ( cur_bb_spur / 10 ) + AR_BASE_FREQ_2GHZ ;
else
cur_bb_spur = ( cur_bb_spur / 10 ) + AR_BASE_FREQ_5GHZ ;
if ( AR_NO_SPUR = = cur_bb_spur )
break ;
cur_bb_spur = cur_bb_spur - freq ;
if ( IS_CHAN_HT40 ( chan ) ) {
if ( ( cur_bb_spur > - AR_SPUR_FEEQ_BOUND_HT40 ) & &
( cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT40 ) ) {
bb_spur = cur_bb_spur ;
break ;
}
} else if ( ( cur_bb_spur > - AR_SPUR_FEEQ_BOUND_HT20 ) & &
( cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT20 ) ) {
bb_spur = cur_bb_spur ;
break ;
}
}
if ( AR_NO_SPUR = = bb_spur ) {
REG_CLR_BIT ( ah , AR_PHY_FORCE_CLKEN_CCK ,
AR_PHY_FORCE_CLKEN_CCK_MRC_MUX ) ;
return ;
} else {
REG_CLR_BIT ( ah , AR_PHY_FORCE_CLKEN_CCK ,
AR_PHY_FORCE_CLKEN_CCK_MRC_MUX ) ;
}
bin = bb_spur * 320 ;
tmp = REG_READ ( ah , AR_PHY_TIMING_CTRL4 ( 0 ) ) ;
2010-04-16 11:53:57 +05:30
ENABLE_REGWRITE_BUFFER ( ah ) ;
2010-04-15 17:38:14 -04:00
newVal = tmp | ( AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK ) ;
REG_WRITE ( ah , AR_PHY_TIMING_CTRL4 ( 0 ) , newVal ) ;
newVal = ( AR_PHY_SPUR_REG_MASK_RATE_CNTL |
AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
AR_PHY_SPUR_REG_MASK_RATE_SELECT |
AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
SM ( SPUR_RSSI_THRESH , AR_PHY_SPUR_REG_SPUR_RSSI_THRESH ) ) ;
REG_WRITE ( ah , AR_PHY_SPUR_REG , newVal ) ;
if ( IS_CHAN_HT40 ( chan ) ) {
if ( bb_spur < 0 ) {
spur_subchannel_sd = 1 ;
bb_spur_off = bb_spur + 10 ;
} else {
spur_subchannel_sd = 0 ;
bb_spur_off = bb_spur - 10 ;
}
} else {
spur_subchannel_sd = 0 ;
bb_spur_off = bb_spur ;
}
if ( IS_CHAN_HT40 ( chan ) )
spur_delta_phase =
( ( bb_spur * 262144 ) /
10 ) & AR_PHY_TIMING11_SPUR_DELTA_PHASE ;
else
spur_delta_phase =
( ( bb_spur * 524288 ) /
10 ) & AR_PHY_TIMING11_SPUR_DELTA_PHASE ;
denominator = IS_CHAN_2GHZ ( chan ) ? 44 : 40 ;
spur_freq_sd = ( ( bb_spur_off * 2048 ) / denominator ) & 0x3ff ;
newVal = ( AR_PHY_TIMING11_USE_SPUR_IN_AGC |
SM ( spur_freq_sd , AR_PHY_TIMING11_SPUR_FREQ_SD ) |
SM ( spur_delta_phase , AR_PHY_TIMING11_SPUR_DELTA_PHASE ) ) ;
REG_WRITE ( ah , AR_PHY_TIMING11 , newVal ) ;
newVal = spur_subchannel_sd < < AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S ;
REG_WRITE ( ah , AR_PHY_SFCORR_EXT , newVal ) ;
cur_bin = - 6000 ;
upper = bin + 100 ;
lower = bin - 100 ;
for ( i = 0 ; i < 4 ; i + + ) {
int pilot_mask = 0 ;
int chan_mask = 0 ;
int bp = 0 ;
for ( bp = 0 ; bp < 30 ; bp + + ) {
if ( ( cur_bin > lower ) & & ( cur_bin < upper ) ) {
pilot_mask = pilot_mask | 0x1 < < bp ;
chan_mask = chan_mask | 0x1 < < bp ;
}
cur_bin + = 100 ;
}
cur_bin + = inc [ i ] ;
REG_WRITE ( ah , pilot_mask_reg [ i ] , pilot_mask ) ;
REG_WRITE ( ah , chan_mask_reg [ i ] , chan_mask ) ;
}
cur_vit_mask = 6100 ;
upper = bin + 120 ;
lower = bin - 120 ;
for ( i = 0 ; i < 123 ; i + + ) {
if ( ( cur_vit_mask > lower ) & & ( cur_vit_mask < upper ) ) {
/* workaround for gcc bug #37014 */
volatile int tmp_v = abs ( cur_vit_mask - bin ) ;
if ( tmp_v < 75 )
mask_amt = 1 ;
else
mask_amt = 0 ;
if ( cur_vit_mask < 0 )
mask_m [ abs ( cur_vit_mask / 100 ) ] = mask_amt ;
else
mask_p [ cur_vit_mask / 100 ] = mask_amt ;
}
cur_vit_mask - = 100 ;
}
tmp_mask = ( mask_m [ 46 ] < < 30 ) | ( mask_m [ 47 ] < < 28 )
| ( mask_m [ 48 ] < < 26 ) | ( mask_m [ 49 ] < < 24 )
| ( mask_m [ 50 ] < < 22 ) | ( mask_m [ 51 ] < < 20 )
| ( mask_m [ 52 ] < < 18 ) | ( mask_m [ 53 ] < < 16 )
| ( mask_m [ 54 ] < < 14 ) | ( mask_m [ 55 ] < < 12 )
| ( mask_m [ 56 ] < < 10 ) | ( mask_m [ 57 ] < < 8 )
| ( mask_m [ 58 ] < < 6 ) | ( mask_m [ 59 ] < < 4 )
| ( mask_m [ 60 ] < < 2 ) | ( mask_m [ 61 ] < < 0 ) ;
REG_WRITE ( ah , AR_PHY_BIN_MASK_1 , tmp_mask ) ;
REG_WRITE ( ah , AR_PHY_VIT_MASK2_M_46_61 , tmp_mask ) ;
tmp_mask = ( mask_m [ 31 ] < < 28 )
| ( mask_m [ 32 ] < < 26 ) | ( mask_m [ 33 ] < < 24 )
| ( mask_m [ 34 ] < < 22 ) | ( mask_m [ 35 ] < < 20 )
| ( mask_m [ 36 ] < < 18 ) | ( mask_m [ 37 ] < < 16 )
| ( mask_m [ 48 ] < < 14 ) | ( mask_m [ 39 ] < < 12 )
| ( mask_m [ 40 ] < < 10 ) | ( mask_m [ 41 ] < < 8 )
| ( mask_m [ 42 ] < < 6 ) | ( mask_m [ 43 ] < < 4 )
| ( mask_m [ 44 ] < < 2 ) | ( mask_m [ 45 ] < < 0 ) ;
REG_WRITE ( ah , AR_PHY_BIN_MASK_2 , tmp_mask ) ;
REG_WRITE ( ah , AR_PHY_MASK2_M_31_45 , tmp_mask ) ;
tmp_mask = ( mask_m [ 16 ] < < 30 ) | ( mask_m [ 16 ] < < 28 )
| ( mask_m [ 18 ] < < 26 ) | ( mask_m [ 18 ] < < 24 )
| ( mask_m [ 20 ] < < 22 ) | ( mask_m [ 20 ] < < 20 )
| ( mask_m [ 22 ] < < 18 ) | ( mask_m [ 22 ] < < 16 )
| ( mask_m [ 24 ] < < 14 ) | ( mask_m [ 24 ] < < 12 )
| ( mask_m [ 25 ] < < 10 ) | ( mask_m [ 26 ] < < 8 )
| ( mask_m [ 27 ] < < 6 ) | ( mask_m [ 28 ] < < 4 )
| ( mask_m [ 29 ] < < 2 ) | ( mask_m [ 30 ] < < 0 ) ;
REG_WRITE ( ah , AR_PHY_BIN_MASK_3 , tmp_mask ) ;
REG_WRITE ( ah , AR_PHY_MASK2_M_16_30 , tmp_mask ) ;
tmp_mask = ( mask_m [ 0 ] < < 30 ) | ( mask_m [ 1 ] < < 28 )
| ( mask_m [ 2 ] < < 26 ) | ( mask_m [ 3 ] < < 24 )
| ( mask_m [ 4 ] < < 22 ) | ( mask_m [ 5 ] < < 20 )
| ( mask_m [ 6 ] < < 18 ) | ( mask_m [ 7 ] < < 16 )
| ( mask_m [ 8 ] < < 14 ) | ( mask_m [ 9 ] < < 12 )
| ( mask_m [ 10 ] < < 10 ) | ( mask_m [ 11 ] < < 8 )
| ( mask_m [ 12 ] < < 6 ) | ( mask_m [ 13 ] < < 4 )
| ( mask_m [ 14 ] < < 2 ) | ( mask_m [ 15 ] < < 0 ) ;
REG_WRITE ( ah , AR_PHY_MASK_CTL , tmp_mask ) ;
REG_WRITE ( ah , AR_PHY_MASK2_M_00_15 , tmp_mask ) ;
tmp_mask = ( mask_p [ 15 ] < < 28 )
| ( mask_p [ 14 ] < < 26 ) | ( mask_p [ 13 ] < < 24 )
| ( mask_p [ 12 ] < < 22 ) | ( mask_p [ 11 ] < < 20 )
| ( mask_p [ 10 ] < < 18 ) | ( mask_p [ 9 ] < < 16 )
| ( mask_p [ 8 ] < < 14 ) | ( mask_p [ 7 ] < < 12 )
| ( mask_p [ 6 ] < < 10 ) | ( mask_p [ 5 ] < < 8 )
| ( mask_p [ 4 ] < < 6 ) | ( mask_p [ 3 ] < < 4 )
| ( mask_p [ 2 ] < < 2 ) | ( mask_p [ 1 ] < < 0 ) ;
REG_WRITE ( ah , AR_PHY_BIN_MASK2_1 , tmp_mask ) ;
REG_WRITE ( ah , AR_PHY_MASK2_P_15_01 , tmp_mask ) ;
tmp_mask = ( mask_p [ 30 ] < < 28 )
| ( mask_p [ 29 ] < < 26 ) | ( mask_p [ 28 ] < < 24 )
| ( mask_p [ 27 ] < < 22 ) | ( mask_p [ 26 ] < < 20 )
| ( mask_p [ 25 ] < < 18 ) | ( mask_p [ 24 ] < < 16 )
| ( mask_p [ 23 ] < < 14 ) | ( mask_p [ 22 ] < < 12 )
| ( mask_p [ 21 ] < < 10 ) | ( mask_p [ 20 ] < < 8 )
| ( mask_p [ 19 ] < < 6 ) | ( mask_p [ 18 ] < < 4 )
| ( mask_p [ 17 ] < < 2 ) | ( mask_p [ 16 ] < < 0 ) ;
REG_WRITE ( ah , AR_PHY_BIN_MASK2_2 , tmp_mask ) ;
REG_WRITE ( ah , AR_PHY_MASK2_P_30_16 , tmp_mask ) ;
tmp_mask = ( mask_p [ 45 ] < < 28 )
| ( mask_p [ 44 ] < < 26 ) | ( mask_p [ 43 ] < < 24 )
| ( mask_p [ 42 ] < < 22 ) | ( mask_p [ 41 ] < < 20 )
| ( mask_p [ 40 ] < < 18 ) | ( mask_p [ 39 ] < < 16 )
| ( mask_p [ 38 ] < < 14 ) | ( mask_p [ 37 ] < < 12 )
| ( mask_p [ 36 ] < < 10 ) | ( mask_p [ 35 ] < < 8 )
| ( mask_p [ 34 ] < < 6 ) | ( mask_p [ 33 ] < < 4 )
| ( mask_p [ 32 ] < < 2 ) | ( mask_p [ 31 ] < < 0 ) ;
REG_WRITE ( ah , AR_PHY_BIN_MASK2_3 , tmp_mask ) ;
REG_WRITE ( ah , AR_PHY_MASK2_P_45_31 , tmp_mask ) ;
tmp_mask = ( mask_p [ 61 ] < < 30 ) | ( mask_p [ 60 ] < < 28 )
| ( mask_p [ 59 ] < < 26 ) | ( mask_p [ 58 ] < < 24 )
| ( mask_p [ 57 ] < < 22 ) | ( mask_p [ 56 ] < < 20 )
| ( mask_p [ 55 ] < < 18 ) | ( mask_p [ 54 ] < < 16 )
| ( mask_p [ 53 ] < < 14 ) | ( mask_p [ 52 ] < < 12 )
| ( mask_p [ 51 ] < < 10 ) | ( mask_p [ 50 ] < < 8 )
| ( mask_p [ 49 ] < < 6 ) | ( mask_p [ 48 ] < < 4 )
| ( mask_p [ 47 ] < < 2 ) | ( mask_p [ 46 ] < < 0 ) ;
REG_WRITE ( ah , AR_PHY_BIN_MASK2_4 , tmp_mask ) ;
REG_WRITE ( ah , AR_PHY_MASK2_P_61_45 , tmp_mask ) ;
2010-04-16 11:53:57 +05:30
REGWRITE_BUFFER_FLUSH ( ah ) ;
DISABLE_REGWRITE_BUFFER ( ah ) ;
2010-04-15 17:38:14 -04:00
}
static void ar9002_olc_init ( struct ath_hw * ah )
{
u32 i ;
if ( ! OLC_FOR_AR9280_20_LATER )
return ;
if ( OLC_FOR_AR9287_10_LATER ) {
REG_SET_BIT ( ah , AR_PHY_TX_PWRCTRL9 ,
AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL ) ;
ath9k_hw_analog_shift_rmw ( ah , AR9287_AN_TXPC0 ,
AR9287_AN_TXPC0_TXPCMODE ,
AR9287_AN_TXPC0_TXPCMODE_S ,
AR9287_AN_TXPC0_TXPCMODE_TEMPSENSE ) ;
udelay ( 100 ) ;
} else {
for ( i = 0 ; i < AR9280_TX_GAIN_TABLE_SIZE ; i + + )
ah - > originalGain [ i ] =
MS ( REG_READ ( ah , AR_PHY_TX_GAIN_TBL1 + i * 4 ) ,
AR_PHY_TX_GAIN ) ;
ah - > PDADCdelta = 0 ;
}
}
2010-04-15 17:38:17 -04:00
static u32 ar9002_hw_compute_pll_control ( struct ath_hw * ah ,
struct ath9k_channel * chan )
{
u32 pll ;
pll = SM ( 0x5 , AR_RTC_9160_PLL_REFDIV ) ;
if ( chan & & IS_CHAN_HALF_RATE ( chan ) )
pll | = SM ( 0x1 , AR_RTC_9160_PLL_CLKSEL ) ;
else if ( chan & & IS_CHAN_QUARTER_RATE ( chan ) )
pll | = SM ( 0x2 , AR_RTC_9160_PLL_CLKSEL ) ;
if ( chan & & IS_CHAN_5GHZ ( chan ) ) {
2010-04-26 15:04:35 -04:00
if ( IS_CHAN_A_FAST_CLOCK ( ah , chan ) )
pll = 0x142c ;
else if ( AR_SREV_9280_20 ( ah ) )
pll = 0x2850 ;
else
pll | = SM ( 0x28 , AR_RTC_9160_PLL_DIV ) ;
2010-04-15 17:38:17 -04:00
} else {
pll | = SM ( 0x2c , AR_RTC_9160_PLL_DIV ) ;
}
return pll ;
}
2010-04-15 17:38:49 -04:00
static void ar9002_hw_do_getnf ( struct ath_hw * ah ,
int16_t nfarray [ NUM_NF_READINGS ] )
{
struct ath_common * common = ath9k_hw_common ( ah ) ;
int16_t nf ;
nf = MS ( REG_READ ( ah , AR_PHY_CCA ) , AR9280_PHY_MINCCA_PWR ) ;
if ( nf & 0x100 )
nf = 0 - ( ( nf ^ 0x1ff ) + 1 ) ;
ath_print ( common , ATH_DBG_CALIBRATE ,
" NF calibrated [ctl] [chain 0] is %d \n " , nf ) ;
if ( AR_SREV_9271 ( ah ) & & ( nf > = - 114 ) )
nf = - 116 ;
nfarray [ 0 ] = nf ;
if ( ! AR_SREV_9285 ( ah ) & & ! AR_SREV_9271 ( ah ) ) {
nf = MS ( REG_READ ( ah , AR_PHY_CH1_CCA ) ,
AR9280_PHY_CH1_MINCCA_PWR ) ;
if ( nf & 0x100 )
nf = 0 - ( ( nf ^ 0x1ff ) + 1 ) ;
ath_print ( common , ATH_DBG_CALIBRATE ,
" NF calibrated [ctl] [chain 1] is %d \n " , nf ) ;
nfarray [ 1 ] = nf ;
}
nf = MS ( REG_READ ( ah , AR_PHY_EXT_CCA ) , AR9280_PHY_EXT_MINCCA_PWR ) ;
if ( nf & 0x100 )
nf = 0 - ( ( nf ^ 0x1ff ) + 1 ) ;
ath_print ( common , ATH_DBG_CALIBRATE ,
" NF calibrated [ext] [chain 0] is %d \n " , nf ) ;
if ( AR_SREV_9271 ( ah ) & & ( nf > = - 114 ) )
nf = - 116 ;
nfarray [ 3 ] = nf ;
if ( ! AR_SREV_9285 ( ah ) & & ! AR_SREV_9271 ( ah ) ) {
nf = MS ( REG_READ ( ah , AR_PHY_CH1_EXT_CCA ) ,
AR9280_PHY_CH1_EXT_MINCCA_PWR ) ;
if ( nf & 0x100 )
nf = 0 - ( ( nf ^ 0x1ff ) + 1 ) ;
ath_print ( common , ATH_DBG_CALIBRATE ,
" NF calibrated [ext] [chain 1] is %d \n " , nf ) ;
nfarray [ 4 ] = nf ;
}
}
2010-04-15 17:38:14 -04:00
void ar9002_hw_attach_phy_ops ( struct ath_hw * ah )
{
struct ath_hw_private_ops * priv_ops = ath9k_hw_private_ops ( ah ) ;
priv_ops - > set_rf_regs = NULL ;
priv_ops - > rf_alloc_ext_banks = NULL ;
priv_ops - > rf_free_ext_banks = NULL ;
priv_ops - > rf_set_freq = ar9002_hw_set_channel ;
priv_ops - > spur_mitigate_freq = ar9002_hw_spur_mitigate ;
priv_ops - > olc_init = ar9002_olc_init ;
2010-04-15 17:38:17 -04:00
priv_ops - > compute_pll_control = ar9002_hw_compute_pll_control ;
2010-04-15 17:38:49 -04:00
priv_ops - > do_getnf = ar9002_hw_do_getnf ;
2010-04-15 17:38:14 -04:00
}