2009-08-07 09:45:15 +05:30
/*
2011-05-17 13:36:18 +05:30
* Copyright ( c ) 2008 - 2011 Atheros Communications Inc .
2009-08-07 09:45:15 +05:30
*
* 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 .
*/
2011-07-15 19:06:33 -04:00
# include <asm/unaligned.h>
2009-09-13 02:42:02 -07:00
# include "hw.h"
2010-04-15 17:38:14 -04:00
# include "ar9002_phy.h"
2009-08-07 09:45:15 +05:30
2011-01-04 13:17:28 +05:30
# define SIZE_EEPROM_AR9287 (sizeof(struct ar9287_eeprom) / sizeof(u16))
2010-06-01 15:14:04 +05:30
static int ath9k_hw_ar9287_get_eeprom_ver ( struct ath_hw * ah )
2009-08-07 09:45:15 +05:30
{
return ( ah - > eeprom . map9287 . baseEepHeader . version > > 12 ) & 0xF ;
}
2010-06-01 15:14:04 +05:30
static int ath9k_hw_ar9287_get_eeprom_rev ( struct ath_hw * ah )
2009-08-07 09:45:15 +05:30
{
return ( ah - > eeprom . map9287 . baseEepHeader . version ) & 0xFFF ;
}
2011-01-04 13:17:28 +05:30
static bool __ath9k_hw_ar9287_fill_eeprom ( struct ath_hw * ah )
2009-08-07 09:45:15 +05:30
{
struct ar9287_eeprom * eep = & ah - > eeprom . map9287 ;
u16 * eep_data ;
2011-01-04 13:17:28 +05:30
int addr , eep_start_loc = AR9287_EEP_START_LOC ;
2009-08-07 09:45:15 +05:30
eep_data = ( u16 * ) eep ;
2011-01-04 13:17:28 +05:30
for ( addr = 0 ; addr < SIZE_EEPROM_AR9287 ; addr + + ) {
2012-12-10 15:30:27 +01:00
if ( ! ath9k_hw_nvram_read ( ah , addr + eep_start_loc , eep_data ) )
2009-08-07 09:45:15 +05:30
return false ;
eep_data + + ;
}
2010-06-01 15:14:04 +05:30
2009-08-07 09:45:15 +05:30
return true ;
}
2011-01-04 13:17:28 +05:30
static bool __ath9k_hw_usb_ar9287_fill_eeprom ( struct ath_hw * ah )
{
u16 * eep_data = ( u16 * ) & ah - > eeprom . map9287 ;
ath9k_hw_usb_gen_fill_eeprom ( ah , eep_data ,
AR9287_HTC_EEP_START_LOC ,
SIZE_EEPROM_AR9287 ) ;
return true ;
}
static bool ath9k_hw_ar9287_fill_eeprom ( struct ath_hw * ah )
{
struct ath_common * common = ath9k_hw_common ( ah ) ;
if ( ! ath9k_hw_use_flash ( ah ) ) {
2011-12-15 14:55:53 -08:00
ath_dbg ( common , EEPROM , " Reading from EEPROM, not flash \n " ) ;
2011-01-04 13:17:28 +05:30
}
if ( common - > bus_ops - > ath_bus_type = = ATH_USB )
return __ath9k_hw_usb_ar9287_fill_eeprom ( ah ) ;
else
return __ath9k_hw_ar9287_fill_eeprom ( ah ) ;
}
2011-07-29 17:38:10 +05:30
# if defined(CONFIG_ATH9K_DEBUGFS) || defined(CONFIG_ATH9K_HTC_DEBUGFS)
static u32 ar9287_dump_modal_eeprom ( char * buf , u32 len , u32 size ,
struct modal_eep_ar9287_header * modal_hdr )
{
PR_EEP ( " Chain0 Ant. Control " , modal_hdr - > antCtrlChain [ 0 ] ) ;
PR_EEP ( " Chain1 Ant. Control " , modal_hdr - > antCtrlChain [ 1 ] ) ;
PR_EEP ( " Ant. Common Control " , modal_hdr - > antCtrlCommon ) ;
PR_EEP ( " Chain0 Ant. Gain " , modal_hdr - > antennaGainCh [ 0 ] ) ;
PR_EEP ( " Chain1 Ant. Gain " , modal_hdr - > antennaGainCh [ 1 ] ) ;
PR_EEP ( " Switch Settle " , modal_hdr - > switchSettling ) ;
PR_EEP ( " Chain0 TxRxAtten " , modal_hdr - > txRxAttenCh [ 0 ] ) ;
PR_EEP ( " Chain1 TxRxAtten " , modal_hdr - > txRxAttenCh [ 1 ] ) ;
PR_EEP ( " Chain0 RxTxMargin " , modal_hdr - > rxTxMarginCh [ 0 ] ) ;
PR_EEP ( " Chain1 RxTxMargin " , modal_hdr - > rxTxMarginCh [ 1 ] ) ;
PR_EEP ( " ADC Desired size " , modal_hdr - > adcDesiredSize ) ;
PR_EEP ( " txEndToXpaOff " , modal_hdr - > txEndToXpaOff ) ;
PR_EEP ( " txEndToRxOn " , modal_hdr - > txEndToRxOn ) ;
PR_EEP ( " txFrameToXpaOn " , modal_hdr - > txFrameToXpaOn ) ;
PR_EEP ( " CCA Threshold) " , modal_hdr - > thresh62 ) ;
PR_EEP ( " Chain0 NF Threshold " , modal_hdr - > noiseFloorThreshCh [ 0 ] ) ;
PR_EEP ( " Chain1 NF Threshold " , modal_hdr - > noiseFloorThreshCh [ 1 ] ) ;
PR_EEP ( " xpdGain " , modal_hdr - > xpdGain ) ;
PR_EEP ( " External PD " , modal_hdr - > xpd ) ;
PR_EEP ( " Chain0 I Coefficient " , modal_hdr - > iqCalICh [ 0 ] ) ;
PR_EEP ( " Chain1 I Coefficient " , modal_hdr - > iqCalICh [ 1 ] ) ;
PR_EEP ( " Chain0 Q Coefficient " , modal_hdr - > iqCalQCh [ 0 ] ) ;
PR_EEP ( " Chain1 Q Coefficient " , modal_hdr - > iqCalQCh [ 1 ] ) ;
PR_EEP ( " pdGainOverlap " , modal_hdr - > pdGainOverlap ) ;
PR_EEP ( " xPA Bias Level " , modal_hdr - > xpaBiasLvl ) ;
PR_EEP ( " txFrameToDataStart " , modal_hdr - > txFrameToDataStart ) ;
PR_EEP ( " txFrameToPaOn " , modal_hdr - > txFrameToPaOn ) ;
PR_EEP ( " HT40 Power Inc. " , modal_hdr - > ht40PowerIncForPdadc ) ;
PR_EEP ( " Chain0 bswAtten " , modal_hdr - > bswAtten [ 0 ] ) ;
PR_EEP ( " Chain1 bswAtten " , modal_hdr - > bswAtten [ 1 ] ) ;
PR_EEP ( " Chain0 bswMargin " , modal_hdr - > bswMargin [ 0 ] ) ;
PR_EEP ( " Chain1 bswMargin " , modal_hdr - > bswMargin [ 1 ] ) ;
PR_EEP ( " HT40 Switch Settle " , modal_hdr - > swSettleHt40 ) ;
PR_EEP ( " AR92x7 Version " , modal_hdr - > version ) ;
PR_EEP ( " DriverBias1 " , modal_hdr - > db1 ) ;
PR_EEP ( " DriverBias2 " , modal_hdr - > db1 ) ;
PR_EEP ( " CCK OutputBias " , modal_hdr - > ob_cck ) ;
PR_EEP ( " PSK OutputBias " , modal_hdr - > ob_psk ) ;
PR_EEP ( " QAM OutputBias " , modal_hdr - > ob_qam ) ;
PR_EEP ( " PAL_OFF OutputBias " , modal_hdr - > ob_pal_off ) ;
return len ;
}
static u32 ath9k_hw_ar9287_dump_eeprom ( struct ath_hw * ah , bool dump_base_hdr ,
u8 * buf , u32 len , u32 size )
{
struct ar9287_eeprom * eep = & ah - > eeprom . map9287 ;
struct base_eep_ar9287_header * pBase = & eep - > baseEepHeader ;
if ( ! dump_base_hdr ) {
2013-09-05 14:11:57 +02:00
len + = scnprintf ( buf + len , size - len ,
" %20s : \n " , " 2GHz modal Header " ) ;
2012-05-15 15:24:47 +05:30
len = ar9287_dump_modal_eeprom ( buf , len , size ,
2011-07-29 17:38:10 +05:30
& eep - > modalHeader ) ;
goto out ;
}
PR_EEP ( " Major Version " , pBase - > version > > 12 ) ;
PR_EEP ( " Minor Version " , pBase - > version & 0xFFF ) ;
PR_EEP ( " Checksum " , pBase - > checksum ) ;
PR_EEP ( " Length " , pBase - > length ) ;
PR_EEP ( " RegDomain1 " , pBase - > regDmn [ 0 ] ) ;
PR_EEP ( " RegDomain2 " , pBase - > regDmn [ 1 ] ) ;
PR_EEP ( " TX Mask " , pBase - > txMask ) ;
PR_EEP ( " RX Mask " , pBase - > rxMask ) ;
PR_EEP ( " Allow 5GHz " , ! ! ( pBase - > opCapFlags & AR5416_OPFLAGS_11A ) ) ;
PR_EEP ( " Allow 2GHz " , ! ! ( pBase - > opCapFlags & AR5416_OPFLAGS_11G ) ) ;
PR_EEP ( " Disable 2GHz HT20 " , ! ! ( pBase - > opCapFlags &
AR5416_OPFLAGS_N_2G_HT20 ) ) ;
PR_EEP ( " Disable 2GHz HT40 " , ! ! ( pBase - > opCapFlags &
AR5416_OPFLAGS_N_2G_HT40 ) ) ;
PR_EEP ( " Disable 5Ghz HT20 " , ! ! ( pBase - > opCapFlags &
AR5416_OPFLAGS_N_5G_HT20 ) ) ;
PR_EEP ( " Disable 5Ghz HT40 " , ! ! ( pBase - > opCapFlags &
AR5416_OPFLAGS_N_5G_HT40 ) ) ;
PR_EEP ( " Big Endian " , ! ! ( pBase - > eepMisc & 0x01 ) ) ;
PR_EEP ( " Cal Bin Major Ver " , ( pBase - > binBuildNumber > > 24 ) & 0xFF ) ;
PR_EEP ( " Cal Bin Minor Ver " , ( pBase - > binBuildNumber > > 16 ) & 0xFF ) ;
PR_EEP ( " Cal Bin Build " , ( pBase - > binBuildNumber > > 8 ) & 0xFF ) ;
PR_EEP ( " Power Table Offset " , pBase - > pwrTableOffset ) ;
PR_EEP ( " OpenLoop Power Ctrl " , pBase - > openLoopPwrCntl ) ;
2013-09-05 14:11:57 +02:00
len + = scnprintf ( buf + len , size - len , " %20s : %pM \n " , " MacAddress " ,
pBase - > macAddr ) ;
2011-07-29 17:38:10 +05:30
out :
if ( len > size )
len = size ;
return len ;
}
# else
static u32 ath9k_hw_ar9287_dump_eeprom ( struct ath_hw * ah , bool dump_base_hdr ,
u8 * buf , u32 len , u32 size )
{
return 0 ;
}
# endif
2010-06-01 15:14:04 +05:30
static int ath9k_hw_ar9287_check_eeprom ( struct ath_hw * ah )
2009-08-07 09:45:15 +05:30
{
2015-10-31 13:57:32 +01:00
u32 el , integer ;
u16 word ;
int i , err ;
bool need_swap ;
2009-08-07 09:45:15 +05:30
struct ar9287_eeprom * eep = & ah - > eeprom . map9287 ;
2010-06-01 15:14:04 +05:30
2015-10-31 13:57:32 +01:00
err = ath9k_hw_nvram_swap_data ( ah , & need_swap , SIZE_EEPROM_AR9287 ) ;
if ( err )
return err ;
2009-08-07 09:45:15 +05:30
if ( need_swap )
2015-10-31 13:57:32 +01:00
el = swab16 ( eep - > baseEepHeader . length ) ;
2009-08-07 09:45:15 +05:30
else
2015-10-31 13:57:32 +01:00
el = eep - > baseEepHeader . length ;
2010-06-01 15:14:04 +05:30
2015-10-31 13:57:32 +01:00
el = min ( el / sizeof ( u16 ) , SIZE_EEPROM_AR9287 ) ;
if ( ! ath9k_hw_nvram_validate_checksum ( ah , el ) )
return - EINVAL ;
2009-08-07 09:45:15 +05:30
if ( need_swap ) {
word = swab16 ( eep - > baseEepHeader . length ) ;
eep - > baseEepHeader . length = word ;
word = swab16 ( eep - > baseEepHeader . checksum ) ;
eep - > baseEepHeader . checksum = word ;
word = swab16 ( eep - > baseEepHeader . version ) ;
eep - > baseEepHeader . version = word ;
word = swab16 ( eep - > baseEepHeader . regDmn [ 0 ] ) ;
eep - > baseEepHeader . regDmn [ 0 ] = word ;
word = swab16 ( eep - > baseEepHeader . regDmn [ 1 ] ) ;
eep - > baseEepHeader . regDmn [ 1 ] = word ;
word = swab16 ( eep - > baseEepHeader . rfSilent ) ;
eep - > baseEepHeader . rfSilent = word ;
word = swab16 ( eep - > baseEepHeader . blueToothOptions ) ;
eep - > baseEepHeader . blueToothOptions = word ;
word = swab16 ( eep - > baseEepHeader . deviceCap ) ;
eep - > baseEepHeader . deviceCap = word ;
integer = swab32 ( eep - > modalHeader . antCtrlCommon ) ;
eep - > modalHeader . antCtrlCommon = integer ;
for ( i = 0 ; i < AR9287_MAX_CHAINS ; i + + ) {
integer = swab32 ( eep - > modalHeader . antCtrlChain [ i ] ) ;
eep - > modalHeader . antCtrlChain [ i ] = integer ;
}
2010-12-12 00:51:08 +01:00
for ( i = 0 ; i < AR_EEPROM_MODAL_SPURS ; i + + ) {
2009-08-07 09:45:15 +05:30
word = swab16 ( eep - > modalHeader . spurChans [ i ] . spurChan ) ;
eep - > modalHeader . spurChans [ i ] . spurChan = word ;
}
}
2015-10-31 13:57:32 +01:00
if ( ! ath9k_hw_nvram_check_version ( ah , AR9287_EEP_VER ,
AR5416_EEP_NO_BACK_VER ) )
2009-08-07 09:45:15 +05:30
return - EINVAL ;
return 0 ;
}
2015-10-31 13:57:32 +01:00
# undef SIZE_EEPROM_AR9287
2010-06-01 15:14:04 +05:30
static u32 ath9k_hw_ar9287_get_eeprom ( struct ath_hw * ah ,
2009-08-07 09:45:15 +05:30
enum eeprom_param param )
{
struct ar9287_eeprom * eep = & ah - > eeprom . map9287 ;
struct modal_eep_ar9287_header * pModal = & eep - > modalHeader ;
struct base_eep_ar9287_header * pBase = & eep - > baseEepHeader ;
u16 ver_minor ;
ver_minor = pBase - > version & AR9287_EEP_VER_MINOR_MASK ;
2010-06-01 15:14:04 +05:30
2009-08-07 09:45:15 +05:30
switch ( param ) {
case EEP_NFTHRESH_2 :
return pModal - > noiseFloorThreshCh [ 0 ] ;
2010-04-15 17:39:13 -04:00
case EEP_MAC_LSW :
2011-07-15 19:06:33 -04:00
return get_unaligned_be16 ( pBase - > macAddr ) ;
2010-04-15 17:39:13 -04:00
case EEP_MAC_MID :
2011-07-15 19:06:33 -04:00
return get_unaligned_be16 ( pBase - > macAddr + 2 ) ;
2010-04-15 17:39:13 -04:00
case EEP_MAC_MSW :
2011-07-15 19:06:33 -04:00
return get_unaligned_be16 ( pBase - > macAddr + 4 ) ;
2009-08-07 09:45:15 +05:30
case EEP_REG_0 :
return pBase - > regDmn [ 0 ] ;
case EEP_OP_CAP :
return pBase - > deviceCap ;
case EEP_OP_MODE :
return pBase - > opCapFlags ;
case EEP_RF_SILENT :
return pBase - > rfSilent ;
case EEP_MINOR_REV :
return ver_minor ;
case EEP_TX_MASK :
return pBase - > txMask ;
case EEP_RX_MASK :
return pBase - > rxMask ;
case EEP_DEV_TYPE :
return pBase - > deviceType ;
case EEP_OL_PWRCTRL :
return pBase - > openLoopPwrCntl ;
case EEP_TEMPSENSE_SLOPE :
if ( ver_minor > = AR9287_EEP_MINOR_VER_2 )
return pBase - > tempSensSlope ;
else
return 0 ;
case EEP_TEMPSENSE_SLOPE_PAL_ON :
if ( ver_minor > = AR9287_EEP_MINOR_VER_3 )
return pBase - > tempSensSlopePalOn ;
else
return 0 ;
2011-10-08 20:06:20 +02:00
case EEP_ANTENNA_GAIN_2G :
return max_t ( u8 , pModal - > antennaGainCh [ 0 ] ,
pModal - > antennaGainCh [ 1 ] ) ;
2009-08-07 09:45:15 +05:30
default :
return 0 ;
}
}
static void ar9287_eeprom_get_tx_gain_index ( struct ath_hw * ah ,
struct ath9k_channel * chan ,
struct cal_data_op_loop_ar9287 * pRawDatasetOpLoop ,
2010-06-01 15:14:04 +05:30
u8 * pCalChans , u16 availPiers , int8_t * pPwr )
2009-08-07 09:45:15 +05:30
{
2010-06-01 15:14:04 +05:30
u16 idxL = 0 , idxR = 0 , numPiers ;
2009-08-07 09:45:15 +05:30
bool match ;
struct chan_centers centers ;
ath9k_hw_get_channel_centers ( ah , chan , & centers ) ;
for ( numPiers = 0 ; numPiers < availPiers ; numPiers + + ) {
2010-12-12 00:51:08 +01:00
if ( pCalChans [ numPiers ] = = AR5416_BCHAN_UNUSED )
2009-08-07 09:45:15 +05:30
break ;
}
match = ath9k_hw_get_lower_upper_index (
2010-06-01 15:14:07 +05:30
( u8 ) FREQ2FBIN ( centers . synth_center , IS_CHAN_2GHZ ( chan ) ) ,
pCalChans , numPiers , & idxL , & idxR ) ;
2009-08-07 09:45:15 +05:30
if ( match ) {
2009-08-14 11:32:04 +05:30
* pPwr = ( int8_t ) pRawDatasetOpLoop [ idxL ] . pwrPdg [ 0 ] [ 0 ] ;
2009-08-07 09:45:15 +05:30
} else {
2009-08-14 11:32:04 +05:30
* pPwr = ( ( int8_t ) pRawDatasetOpLoop [ idxL ] . pwrPdg [ 0 ] [ 0 ] +
2010-06-01 15:14:04 +05:30
( int8_t ) pRawDatasetOpLoop [ idxR ] . pwrPdg [ 0 ] [ 0 ] ) / 2 ;
2009-08-07 09:45:15 +05:30
}
}
static void ar9287_eeprom_olpc_set_pdadcs ( struct ath_hw * ah ,
int32_t txPower , u16 chain )
{
u32 tmpVal ;
u32 a ;
2010-06-01 15:14:04 +05:30
/* Enable OLPC for chain 0 */
2009-08-07 09:45:15 +05:30
tmpVal = REG_READ ( ah , 0xa270 ) ;
tmpVal = tmpVal & 0xFCFFFFFF ;
tmpVal = tmpVal | ( 0x3 < < 24 ) ;
REG_WRITE ( ah , 0xa270 , tmpVal ) ;
2010-06-01 15:14:04 +05:30
/* Enable OLPC for chain 1 */
2009-08-07 09:45:15 +05:30
tmpVal = REG_READ ( ah , 0xb270 ) ;
tmpVal = tmpVal & 0xFCFFFFFF ;
tmpVal = tmpVal | ( 0x3 < < 24 ) ;
REG_WRITE ( ah , 0xb270 , tmpVal ) ;
2010-06-01 15:14:04 +05:30
/* Write the OLPC ref power for chain 0 */
2009-08-07 09:45:15 +05:30
if ( chain = = 0 ) {
tmpVal = REG_READ ( ah , 0xa398 ) ;
tmpVal = tmpVal & 0xff00ffff ;
a = ( txPower ) & 0xff ;
tmpVal = tmpVal | ( a < < 16 ) ;
REG_WRITE ( ah , 0xa398 , tmpVal ) ;
}
2010-06-01 15:14:04 +05:30
/* Write the OLPC ref power for chain 1 */
2009-08-07 09:45:15 +05:30
if ( chain = = 1 ) {
tmpVal = REG_READ ( ah , 0xb398 ) ;
tmpVal = tmpVal & 0xff00ffff ;
a = ( txPower ) & 0xff ;
tmpVal = tmpVal | ( a < < 16 ) ;
REG_WRITE ( ah , 0xb398 , tmpVal ) ;
}
}
2010-06-01 15:14:04 +05:30
static void ath9k_hw_set_ar9287_power_cal_table ( struct ath_hw * ah ,
2011-07-27 15:01:03 +02:00
struct ath9k_channel * chan )
2009-08-07 09:45:15 +05:30
{
struct cal_data_per_freq_ar9287 * pRawDataset ;
struct cal_data_op_loop_ar9287 * pRawDatasetOpenLoop ;
2010-06-01 15:14:04 +05:30
u8 * pCalBChans = NULL ;
2009-08-07 09:45:15 +05:30
u16 pdGainOverlap_t2 ;
2010-12-12 00:51:08 +01:00
u8 pdadcValues [ AR5416_NUM_PDADC_VALUES ] ;
u16 gainBoundaries [ AR5416_PD_GAINS_IN_MASK ] ;
2009-08-07 09:45:15 +05:30
u16 numPiers = 0 , i , j ;
u16 numXpdGain , xpdMask ;
2010-12-12 00:51:08 +01:00
u16 xpdGainValues [ AR5416_NUM_PD_GAINS ] = { 0 , 0 , 0 , 0 } ;
2010-06-01 15:14:07 +05:30
u32 reg32 , regOffset , regChainOffset , regval ;
2011-04-20 11:00:34 +05:30
int16_t diff = 0 ;
2009-08-07 09:45:15 +05:30
struct ar9287_eeprom * pEepData = & ah - > eeprom . map9287 ;
2010-06-01 15:14:04 +05:30
2009-08-07 09:45:15 +05:30
xpdMask = pEepData - > modalHeader . xpdGain ;
2010-06-01 15:14:04 +05:30
2009-08-07 09:45:15 +05:30
if ( ( pEepData - > baseEepHeader . version & AR9287_EEP_VER_MINOR_MASK ) > =
2010-06-01 15:14:07 +05:30
AR9287_EEP_MINOR_VER_2 )
2009-08-07 09:45:15 +05:30
pdGainOverlap_t2 = pEepData - > modalHeader . pdGainOverlap ;
else
pdGainOverlap_t2 = ( u16 ) ( MS ( REG_READ ( ah , AR_PHY_TPCRG5 ) ,
AR_PHY_TPCRG5_PD_GAIN_OVERLAP ) ) ;
if ( IS_CHAN_2GHZ ( chan ) ) {
pCalBChans = pEepData - > calFreqPier2G ;
numPiers = AR9287_NUM_2G_CAL_PIERS ;
2010-06-01 15:14:04 +05:30
if ( ath9k_hw_ar9287_get_eeprom ( ah , EEP_OL_PWRCTRL ) ) {
2009-08-07 09:45:15 +05:30
pRawDatasetOpenLoop =
2010-06-01 15:14:07 +05:30
( struct cal_data_op_loop_ar9287 * ) pEepData - > calPierData2G [ 0 ] ;
2009-08-07 09:45:15 +05:30
ah - > initPDADC = pRawDatasetOpenLoop - > vpdPdg [ 0 ] [ 0 ] ;
}
}
numXpdGain = 0 ;
2010-06-01 15:14:04 +05:30
2010-06-01 15:14:07 +05:30
/* Calculate the value of xpdgains from the xpdGain Mask */
2010-12-12 00:51:08 +01:00
for ( i = 1 ; i < = AR5416_PD_GAINS_IN_MASK ; i + + ) {
if ( ( xpdMask > > ( AR5416_PD_GAINS_IN_MASK - i ) ) & 1 ) {
if ( numXpdGain > = AR5416_NUM_PD_GAINS )
2009-08-07 09:45:15 +05:30
break ;
xpdGainValues [ numXpdGain ] =
2010-12-12 00:51:08 +01:00
( u16 ) ( AR5416_PD_GAINS_IN_MASK - i ) ;
2009-08-07 09:45:15 +05:30
numXpdGain + + ;
}
}
REG_RMW_FIELD ( ah , AR_PHY_TPCRG1 , AR_PHY_TPCRG1_NUM_PD_GAIN ,
( numXpdGain - 1 ) & 0x3 ) ;
REG_RMW_FIELD ( ah , AR_PHY_TPCRG1 , AR_PHY_TPCRG1_PD_GAIN_1 ,
xpdGainValues [ 0 ] ) ;
REG_RMW_FIELD ( ah , AR_PHY_TPCRG1 , AR_PHY_TPCRG1_PD_GAIN_2 ,
xpdGainValues [ 1 ] ) ;
REG_RMW_FIELD ( ah , AR_PHY_TPCRG1 , AR_PHY_TPCRG1_PD_GAIN_3 ,
xpdGainValues [ 2 ] ) ;
for ( i = 0 ; i < AR9287_MAX_CHAINS ; i + + ) {
regChainOffset = i * 0x1000 ;
2010-06-01 15:14:07 +05:30
2009-08-07 09:45:15 +05:30
if ( pEepData - > baseEepHeader . txMask & ( 1 < < i ) ) {
2010-06-01 15:14:07 +05:30
pRawDatasetOpenLoop =
( struct cal_data_op_loop_ar9287 * ) pEepData - > calPierData2G [ i ] ;
2010-06-01 15:14:04 +05:30
if ( ath9k_hw_ar9287_get_eeprom ( ah , EEP_OL_PWRCTRL ) ) {
2009-08-07 09:45:15 +05:30
int8_t txPower ;
ar9287_eeprom_get_tx_gain_index ( ah , chan ,
2010-06-01 15:14:07 +05:30
pRawDatasetOpenLoop ,
pCalBChans , numPiers ,
& txPower ) ;
2009-08-07 09:45:15 +05:30
ar9287_eeprom_olpc_set_pdadcs ( ah , txPower , i ) ;
} else {
pRawDataset =
( struct cal_data_per_freq_ar9287 * )
pEepData - > calPierData2G [ i ] ;
2010-06-01 15:14:07 +05:30
2010-12-12 00:51:10 +01:00
ath9k_hw_get_gain_boundaries_pdadcs ( ah , chan ,
2010-06-01 15:14:07 +05:30
pRawDataset ,
pCalBChans , numPiers ,
pdGainOverlap_t2 ,
gainBoundaries ,
pdadcValues ,
numXpdGain ) ;
2009-08-07 09:45:15 +05:30
}
2011-03-15 23:11:35 +05:30
ENABLE_REGWRITE_BUFFER ( ah ) ;
2009-08-07 09:45:15 +05:30
if ( i = = 0 ) {
2010-06-01 15:14:07 +05:30
if ( ! ath9k_hw_ar9287_get_eeprom ( ah ,
EEP_OL_PWRCTRL ) ) {
regval = SM ( pdGainOverlap_t2 ,
AR_PHY_TPCRG5_PD_GAIN_OVERLAP )
| SM ( gainBoundaries [ 0 ] ,
AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1 )
| SM ( gainBoundaries [ 1 ] ,
AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2 )
| SM ( gainBoundaries [ 2 ] ,
AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3 )
| SM ( gainBoundaries [ 3 ] ,
AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4 ) ;
REG_WRITE ( ah ,
AR_PHY_TPCRG5 + regChainOffset ,
regval ) ;
2009-08-07 09:45:15 +05:30
}
}
if ( ( int32_t ) AR9287_PWR_TABLE_OFFSET_DB ! =
2010-06-01 15:14:07 +05:30
pEepData - > baseEepHeader . pwrTableOffset ) {
diff = ( u16 ) ( pEepData - > baseEepHeader . pwrTableOffset -
( int32_t ) AR9287_PWR_TABLE_OFFSET_DB ) ;
2009-08-07 09:45:15 +05:30
diff * = 2 ;
2010-12-12 00:51:08 +01:00
for ( j = 0 ; j < ( ( u16 ) AR5416_NUM_PDADC_VALUES - diff ) ; j + + )
2009-08-07 09:45:15 +05:30
pdadcValues [ j ] = pdadcValues [ j + diff ] ;
2010-12-12 00:51:08 +01:00
for ( j = ( u16 ) ( AR5416_NUM_PDADC_VALUES - diff ) ;
j < AR5416_NUM_PDADC_VALUES ; j + + )
2009-08-07 09:45:15 +05:30
pdadcValues [ j ] =
2010-12-12 00:51:08 +01:00
pdadcValues [ AR5416_NUM_PDADC_VALUES - diff ] ;
2009-08-07 09:45:15 +05:30
}
2010-06-01 15:14:04 +05:30
if ( ! ath9k_hw_ar9287_get_eeprom ( ah , EEP_OL_PWRCTRL ) ) {
2010-06-01 15:14:07 +05:30
regOffset = AR_PHY_BASE +
( 672 < < 2 ) + regChainOffset ;
2009-08-07 09:45:15 +05:30
for ( j = 0 ; j < 32 ; j + + ) {
2011-07-15 19:06:33 -04:00
reg32 = get_unaligned_le32 ( & pdadcValues [ 4 * j ] ) ;
2010-06-01 15:14:07 +05:30
2009-08-07 09:45:15 +05:30
REG_WRITE ( ah , regOffset , reg32 ) ;
regOffset + = 4 ;
}
}
2011-03-15 23:11:35 +05:30
REGWRITE_BUFFER_FLUSH ( ah ) ;
2009-08-07 09:45:15 +05:30
}
}
}
2010-06-01 15:14:04 +05:30
static void ath9k_hw_set_ar9287_power_per_rate_table ( struct ath_hw * ah ,
struct ath9k_channel * chan ,
int16_t * ratesArray ,
u16 cfgCtl ,
2011-10-08 20:06:20 +02:00
u16 antenna_reduction ,
2010-06-01 15:14:04 +05:30
u16 powerLimit )
2009-08-07 09:45:15 +05:30
{
2010-06-01 15:14:07 +05:30
# define CMP_CTL \
( ( ( cfgCtl & ~ CTL_MODE_M ) | ( pCtlMode [ ctlMode ] & CTL_MODE_M ) ) = = \
pEepData - > ctlIndex [ i ] )
# define CMP_NO_CTL \
( ( ( cfgCtl & ~ CTL_MODE_M ) | ( pCtlMode [ ctlMode ] & CTL_MODE_M ) ) = = \
( ( pEepData - > ctlIndex [ i ] & CTL_MODE_M ) | SD_NO_CTL ) )
2011-11-22 18:52:00 +05:30
u16 twiceMaxEdgePower ;
2009-08-07 09:45:15 +05:30
int i ;
struct cal_ctl_data_ar9287 * rep ;
struct cal_target_power_leg targetPowerOfdm = { 0 , { 0 , 0 , 0 , 0 } } ,
targetPowerCck = { 0 , { 0 , 0 , 0 , 0 } } ;
struct cal_target_power_leg targetPowerOfdmExt = { 0 , { 0 , 0 , 0 , 0 } } ,
targetPowerCckExt = { 0 , { 0 , 0 , 0 , 0 } } ;
2010-06-01 15:14:04 +05:30
struct cal_target_power_ht targetPowerHt20 ,
2009-08-07 09:45:15 +05:30
targetPowerHt40 = { 0 , { 0 , 0 , 0 , 0 } } ;
2011-10-08 20:06:20 +02:00
u16 scaledPower = 0 , minCtlPower ;
2010-11-20 18:38:53 -08:00
static const u16 ctlModesFor11g [ ] = {
CTL_11B , CTL_11G , CTL_2GHT20 ,
CTL_11B_EXT , CTL_11G_EXT , CTL_2GHT40
} ;
u16 numCtlModes = 0 ;
const u16 * pCtlMode = NULL ;
u16 ctlMode , freq ;
2009-08-07 09:45:15 +05:30
struct chan_centers centers ;
int tx_chainmask ;
u16 twiceMinEdgePower ;
struct ar9287_eeprom * pEepData = & ah - > eeprom . map9287 ;
tx_chainmask = ah - > txchainmask ;
ath9k_hw_get_channel_centers ( ah , chan , & centers ) ;
2012-04-14 22:01:58 +02:00
scaledPower = ath9k_hw_get_scaled_power ( ah , powerLimit ,
antenna_reduction ) ;
2009-08-07 09:45:15 +05:30
2010-06-01 15:14:07 +05:30
/*
* Get TX power from EEPROM .
*/
2009-08-07 09:45:15 +05:30
if ( IS_CHAN_2GHZ ( chan ) ) {
2010-06-01 15:14:07 +05:30
/* CTL_11B, CTL_11G, CTL_2GHT20 */
2009-08-07 09:45:15 +05:30
numCtlModes =
ARRAY_SIZE ( ctlModesFor11g ) - SUB_NUM_CTL_MODES_AT_2G_40 ;
2010-06-01 15:14:04 +05:30
2009-08-07 09:45:15 +05:30
pCtlMode = ctlModesFor11g ;
ath9k_hw_get_legacy_target_powers ( ah , chan ,
pEepData - > calTargetPowerCck ,
AR9287_NUM_2G_CCK_TARGET_POWERS ,
& targetPowerCck , 4 , false ) ;
ath9k_hw_get_legacy_target_powers ( ah , chan ,
pEepData - > calTargetPower2G ,
AR9287_NUM_2G_20_TARGET_POWERS ,
& targetPowerOfdm , 4 , false ) ;
ath9k_hw_get_target_powers ( ah , chan ,
pEepData - > calTargetPower2GHT20 ,
AR9287_NUM_2G_20_TARGET_POWERS ,
& targetPowerHt20 , 8 , false ) ;
if ( IS_CHAN_HT40 ( chan ) ) {
2010-06-01 15:14:07 +05:30
/* All 2G CTLs */
2009-08-07 09:45:15 +05:30
numCtlModes = ARRAY_SIZE ( ctlModesFor11g ) ;
ath9k_hw_get_target_powers ( ah , chan ,
pEepData - > calTargetPower2GHT40 ,
AR9287_NUM_2G_40_TARGET_POWERS ,
& targetPowerHt40 , 8 , true ) ;
ath9k_hw_get_legacy_target_powers ( ah , chan ,
pEepData - > calTargetPowerCck ,
AR9287_NUM_2G_CCK_TARGET_POWERS ,
& targetPowerCckExt , 4 , true ) ;
ath9k_hw_get_legacy_target_powers ( ah , chan ,
pEepData - > calTargetPower2G ,
AR9287_NUM_2G_20_TARGET_POWERS ,
& targetPowerOfdmExt , 4 , true ) ;
}
}
for ( ctlMode = 0 ; ctlMode < numCtlModes ; ctlMode + + ) {
2010-06-01 15:14:07 +05:30
bool isHt40CtlMode =
( pCtlMode [ ctlMode ] = = CTL_2GHT40 ) ? true : false ;
2009-08-07 09:45:15 +05:30
if ( isHt40CtlMode )
freq = centers . synth_center ;
else if ( pCtlMode [ ctlMode ] & EXT_ADDITIVE )
freq = centers . ext_center ;
else
freq = centers . ctl_center ;
2011-11-22 18:52:00 +05:30
twiceMaxEdgePower = MAX_RATE_POWER ;
2010-06-01 15:14:07 +05:30
/* Walk through the CTL indices stored in EEPROM */
2009-08-07 09:45:15 +05:30
for ( i = 0 ; ( i < AR9287_NUM_CTLS ) & & pEepData - > ctlIndex [ i ] ; i + + ) {
2010-06-01 15:14:07 +05:30
struct cal_ctl_edges * pRdEdgesPower ;
2009-08-07 09:45:15 +05:30
2010-06-01 15:14:07 +05:30
/*
* Compare test group from regulatory channel list
* with test mode from pCtlMode list
*/
if ( CMP_CTL | | CMP_NO_CTL ) {
2009-08-07 09:45:15 +05:30
rep = & ( pEepData - > ctlData [ i ] ) ;
2010-06-01 15:14:07 +05:30
pRdEdgesPower =
rep - > ctlEdges [ ar5416_get_ntxchains ( tx_chainmask ) - 1 ] ;
twiceMinEdgePower = ath9k_hw_get_max_edge_power ( freq ,
pRdEdgesPower ,
IS_CHAN_2GHZ ( chan ) ,
AR5416_NUM_BAND_EDGES ) ;
if ( ( cfgCtl & ~ CTL_MODE_M ) = = SD_NO_CTL ) {
twiceMaxEdgePower = min ( twiceMaxEdgePower ,
twiceMinEdgePower ) ;
} else {
2009-08-07 09:45:15 +05:30
twiceMaxEdgePower = twiceMinEdgePower ;
break ;
}
}
}
minCtlPower = ( u8 ) min ( twiceMaxEdgePower , scaledPower ) ;
2010-06-01 15:14:07 +05:30
/* Apply ctl mode to correct target power set */
2009-08-07 09:45:15 +05:30
switch ( pCtlMode [ ctlMode ] ) {
case CTL_11B :
2010-06-01 15:14:07 +05:30
for ( i = 0 ; i < ARRAY_SIZE ( targetPowerCck . tPow2x ) ; i + + ) {
targetPowerCck . tPow2x [ i ] =
( u8 ) min ( ( u16 ) targetPowerCck . tPow2x [ i ] ,
minCtlPower ) ;
2009-08-07 09:45:15 +05:30
}
break ;
case CTL_11A :
case CTL_11G :
2010-06-01 15:14:07 +05:30
for ( i = 0 ; i < ARRAY_SIZE ( targetPowerOfdm . tPow2x ) ; i + + ) {
targetPowerOfdm . tPow2x [ i ] =
( u8 ) min ( ( u16 ) targetPowerOfdm . tPow2x [ i ] ,
minCtlPower ) ;
2009-08-07 09:45:15 +05:30
}
break ;
case CTL_5GHT20 :
case CTL_2GHT20 :
2010-06-01 15:14:07 +05:30
for ( i = 0 ; i < ARRAY_SIZE ( targetPowerHt20 . tPow2x ) ; i + + ) {
targetPowerHt20 . tPow2x [ i ] =
( u8 ) min ( ( u16 ) targetPowerHt20 . tPow2x [ i ] ,
minCtlPower ) ;
2009-08-07 09:45:15 +05:30
}
break ;
case CTL_11B_EXT :
2010-06-01 15:14:07 +05:30
targetPowerCckExt . tPow2x [ 0 ] =
( u8 ) min ( ( u16 ) targetPowerCckExt . tPow2x [ 0 ] ,
minCtlPower ) ;
2009-08-07 09:45:15 +05:30
break ;
case CTL_11A_EXT :
case CTL_11G_EXT :
2010-06-01 15:14:07 +05:30
targetPowerOfdmExt . tPow2x [ 0 ] =
( u8 ) min ( ( u16 ) targetPowerOfdmExt . tPow2x [ 0 ] ,
minCtlPower ) ;
2009-08-07 09:45:15 +05:30
break ;
case CTL_5GHT40 :
case CTL_2GHT40 :
2010-06-01 15:14:07 +05:30
for ( i = 0 ; i < ARRAY_SIZE ( targetPowerHt40 . tPow2x ) ; i + + ) {
targetPowerHt40 . tPow2x [ i ] =
( u8 ) min ( ( u16 ) targetPowerHt40 . tPow2x [ i ] ,
minCtlPower ) ;
2009-08-07 09:45:15 +05:30
}
break ;
default :
break ;
}
}
2010-06-01 15:14:07 +05:30
/* Now set the rates array */
2009-08-07 09:45:15 +05:30
ratesArray [ rate6mb ] =
ratesArray [ rate9mb ] =
ratesArray [ rate12mb ] =
ratesArray [ rate18mb ] =
2010-06-01 15:14:07 +05:30
ratesArray [ rate24mb ] = targetPowerOfdm . tPow2x [ 0 ] ;
2009-08-07 09:45:15 +05:30
ratesArray [ rate36mb ] = targetPowerOfdm . tPow2x [ 1 ] ;
ratesArray [ rate48mb ] = targetPowerOfdm . tPow2x [ 2 ] ;
ratesArray [ rate54mb ] = targetPowerOfdm . tPow2x [ 3 ] ;
ratesArray [ rateXr ] = targetPowerOfdm . tPow2x [ 0 ] ;
for ( i = 0 ; i < ARRAY_SIZE ( targetPowerHt20 . tPow2x ) ; i + + )
ratesArray [ rateHt20_0 + i ] = targetPowerHt20 . tPow2x [ i ] ;
if ( IS_CHAN_2GHZ ( chan ) ) {
ratesArray [ rate1l ] = targetPowerCck . tPow2x [ 0 ] ;
2010-06-01 15:14:07 +05:30
ratesArray [ rate2s ] =
ratesArray [ rate2l ] = targetPowerCck . tPow2x [ 1 ] ;
ratesArray [ rate5_5s ] =
ratesArray [ rate5_5l ] = targetPowerCck . tPow2x [ 2 ] ;
ratesArray [ rate11s ] =
ratesArray [ rate11l ] = targetPowerCck . tPow2x [ 3 ] ;
2009-08-07 09:45:15 +05:30
}
if ( IS_CHAN_HT40 ( chan ) ) {
for ( i = 0 ; i < ARRAY_SIZE ( targetPowerHt40 . tPow2x ) ; i + + )
ratesArray [ rateHt40_0 + i ] = targetPowerHt40 . tPow2x [ i ] ;
ratesArray [ rateDupOfdm ] = targetPowerHt40 . tPow2x [ 0 ] ;
ratesArray [ rateDupCck ] = targetPowerHt40 . tPow2x [ 0 ] ;
ratesArray [ rateExtOfdm ] = targetPowerOfdmExt . tPow2x [ 0 ] ;
2010-06-01 15:14:07 +05:30
2009-08-07 09:45:15 +05:30
if ( IS_CHAN_2GHZ ( chan ) )
ratesArray [ rateExtCck ] = targetPowerCckExt . tPow2x [ 0 ] ;
}
2010-06-01 15:14:07 +05:30
# undef CMP_CTL
# undef CMP_NO_CTL
2009-08-07 09:45:15 +05:30
}
2010-06-01 15:14:04 +05:30
static void ath9k_hw_ar9287_set_txpower ( struct ath_hw * ah ,
2009-08-07 09:45:15 +05:30
struct ath9k_channel * chan , u16 cfgCtl ,
u8 twiceAntennaReduction ,
2010-10-20 03:08:53 +02:00
u8 powerLimit , bool test )
2009-08-07 09:45:15 +05:30
{
2009-08-17 18:07:23 -07:00
struct ath_regulatory * regulatory = ath9k_hw_regulatory ( ah ) ;
2009-08-07 09:45:15 +05:30
struct ar9287_eeprom * pEepData = & ah - > eeprom . map9287 ;
struct modal_eep_ar9287_header * pModal = & pEepData - > modalHeader ;
int16_t ratesArray [ Ar5416RateSize ] ;
u8 ht40PowerIncForPdadc = 2 ;
int i ;
memset ( ratesArray , 0 , sizeof ( ratesArray ) ) ;
if ( ( pEepData - > baseEepHeader . version & AR9287_EEP_VER_MINOR_MASK ) > =
AR9287_EEP_MINOR_VER_2 )
ht40PowerIncForPdadc = pModal - > ht40PowerIncForPdadc ;
2010-06-01 15:14:04 +05:30
ath9k_hw_set_ar9287_power_per_rate_table ( ah , chan ,
2009-08-07 09:45:15 +05:30
& ratesArray [ 0 ] , cfgCtl ,
twiceAntennaReduction ,
powerLimit ) ;
2011-07-27 15:01:03 +02:00
ath9k_hw_set_ar9287_power_cal_table ( ah , chan ) ;
2009-08-07 09:45:15 +05:30
2010-10-20 03:08:53 +02:00
regulatory - > max_power_level = 0 ;
2009-08-07 09:45:15 +05:30
for ( i = 0 ; i < ARRAY_SIZE ( ratesArray ) ; i + + ) {
2010-12-12 00:51:08 +01:00
if ( ratesArray [ i ] > MAX_RATE_POWER )
ratesArray [ i ] = MAX_RATE_POWER ;
2010-10-20 03:08:53 +02:00
if ( ratesArray [ i ] > regulatory - > max_power_level )
regulatory - > max_power_level = ratesArray [ i ] ;
2009-08-07 09:45:15 +05:30
}
2012-04-15 20:38:06 +02:00
ath9k_hw_update_regulatory_maxpower ( ah ) ;
2010-10-20 03:08:53 +02:00
if ( test )
return ;
2011-09-15 14:25:35 +02:00
for ( i = 0 ; i < Ar5416RateSize ; i + + )
ratesArray [ i ] - = AR9287_PWR_TABLE_OFFSET_DB * 2 ;
2009-08-07 09:45:15 +05:30
2011-03-15 23:11:35 +05:30
ENABLE_REGWRITE_BUFFER ( ah ) ;
2010-06-01 15:14:07 +05:30
/* OFDM power per rate */
2009-08-07 09:45:15 +05:30
REG_WRITE ( ah , AR_PHY_POWER_TX_RATE1 ,
ATH9K_POW_SM ( ratesArray [ rate18mb ] , 24 )
| ATH9K_POW_SM ( ratesArray [ rate12mb ] , 16 )
| ATH9K_POW_SM ( ratesArray [ rate9mb ] , 8 )
| ATH9K_POW_SM ( ratesArray [ rate6mb ] , 0 ) ) ;
REG_WRITE ( ah , AR_PHY_POWER_TX_RATE2 ,
ATH9K_POW_SM ( ratesArray [ rate54mb ] , 24 )
| ATH9K_POW_SM ( ratesArray [ rate48mb ] , 16 )
| ATH9K_POW_SM ( ratesArray [ rate36mb ] , 8 )
| ATH9K_POW_SM ( ratesArray [ rate24mb ] , 0 ) ) ;
2010-06-01 15:14:07 +05:30
/* CCK power per rate */
2009-08-07 09:45:15 +05:30
if ( IS_CHAN_2GHZ ( chan ) ) {
REG_WRITE ( ah , AR_PHY_POWER_TX_RATE3 ,
ATH9K_POW_SM ( ratesArray [ rate2s ] , 24 )
| ATH9K_POW_SM ( ratesArray [ rate2l ] , 16 )
| ATH9K_POW_SM ( ratesArray [ rateXr ] , 8 )
| ATH9K_POW_SM ( ratesArray [ rate1l ] , 0 ) ) ;
REG_WRITE ( ah , AR_PHY_POWER_TX_RATE4 ,
ATH9K_POW_SM ( ratesArray [ rate11s ] , 24 )
| ATH9K_POW_SM ( ratesArray [ rate11l ] , 16 )
| ATH9K_POW_SM ( ratesArray [ rate5_5s ] , 8 )
| ATH9K_POW_SM ( ratesArray [ rate5_5l ] , 0 ) ) ;
}
2010-06-01 15:14:07 +05:30
/* HT20 power per rate */
2009-08-07 09:45:15 +05:30
REG_WRITE ( ah , AR_PHY_POWER_TX_RATE5 ,
ATH9K_POW_SM ( ratesArray [ rateHt20_3 ] , 24 )
| ATH9K_POW_SM ( ratesArray [ rateHt20_2 ] , 16 )
| ATH9K_POW_SM ( ratesArray [ rateHt20_1 ] , 8 )
| ATH9K_POW_SM ( ratesArray [ rateHt20_0 ] , 0 ) ) ;
REG_WRITE ( ah , AR_PHY_POWER_TX_RATE6 ,
ATH9K_POW_SM ( ratesArray [ rateHt20_7 ] , 24 )
| ATH9K_POW_SM ( ratesArray [ rateHt20_6 ] , 16 )
| ATH9K_POW_SM ( ratesArray [ rateHt20_5 ] , 8 )
| ATH9K_POW_SM ( ratesArray [ rateHt20_4 ] , 0 ) ) ;
2010-06-01 15:14:07 +05:30
/* HT40 power per rate */
2009-08-07 09:45:15 +05:30
if ( IS_CHAN_HT40 ( chan ) ) {
2010-06-01 15:14:04 +05:30
if ( ath9k_hw_ar9287_get_eeprom ( ah , EEP_OL_PWRCTRL ) ) {
2009-08-07 09:45:15 +05:30
REG_WRITE ( ah , AR_PHY_POWER_TX_RATE7 ,
ATH9K_POW_SM ( ratesArray [ rateHt40_3 ] , 24 )
| ATH9K_POW_SM ( ratesArray [ rateHt40_2 ] , 16 )
| ATH9K_POW_SM ( ratesArray [ rateHt40_1 ] , 8 )
| ATH9K_POW_SM ( ratesArray [ rateHt40_0 ] , 0 ) ) ;
REG_WRITE ( ah , AR_PHY_POWER_TX_RATE8 ,
ATH9K_POW_SM ( ratesArray [ rateHt40_7 ] , 24 )
| ATH9K_POW_SM ( ratesArray [ rateHt40_6 ] , 16 )
| ATH9K_POW_SM ( ratesArray [ rateHt40_5 ] , 8 )
| ATH9K_POW_SM ( ratesArray [ rateHt40_4 ] , 0 ) ) ;
} else {
REG_WRITE ( ah , AR_PHY_POWER_TX_RATE7 ,
ATH9K_POW_SM ( ratesArray [ rateHt40_3 ] +
ht40PowerIncForPdadc , 24 )
| ATH9K_POW_SM ( ratesArray [ rateHt40_2 ] +
ht40PowerIncForPdadc , 16 )
| ATH9K_POW_SM ( ratesArray [ rateHt40_1 ] +
ht40PowerIncForPdadc , 8 )
| ATH9K_POW_SM ( ratesArray [ rateHt40_0 ] +
ht40PowerIncForPdadc , 0 ) ) ;
REG_WRITE ( ah , AR_PHY_POWER_TX_RATE8 ,
ATH9K_POW_SM ( ratesArray [ rateHt40_7 ] +
ht40PowerIncForPdadc , 24 )
| ATH9K_POW_SM ( ratesArray [ rateHt40_6 ] +
ht40PowerIncForPdadc , 16 )
| ATH9K_POW_SM ( ratesArray [ rateHt40_5 ] +
ht40PowerIncForPdadc , 8 )
| ATH9K_POW_SM ( ratesArray [ rateHt40_4 ] +
ht40PowerIncForPdadc , 0 ) ) ;
}
2010-06-01 15:14:07 +05:30
/* Dup/Ext power per rate */
2009-08-07 09:45:15 +05:30
REG_WRITE ( ah , AR_PHY_POWER_TX_RATE9 ,
ATH9K_POW_SM ( ratesArray [ rateExtOfdm ] , 24 )
| ATH9K_POW_SM ( ratesArray [ rateExtCck ] , 16 )
| ATH9K_POW_SM ( ratesArray [ rateDupOfdm ] , 8 )
| ATH9K_POW_SM ( ratesArray [ rateDupCck ] , 0 ) ) ;
}
2014-12-30 23:10:18 +01:00
/* TPC initializations */
if ( ah - > tpc_enabled ) {
int ht40_delta ;
ht40_delta = ( IS_CHAN_HT40 ( chan ) ) ? ht40PowerIncForPdadc : 0 ;
ar5008_hw_init_rate_txpower ( ah , ratesArray , chan , ht40_delta ) ;
/* Enable TPC */
REG_WRITE ( ah , AR_PHY_POWER_TX_RATE_MAX ,
MAX_RATE_POWER | AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE ) ;
} else {
/* Disable TPC */
REG_WRITE ( ah , AR_PHY_POWER_TX_RATE_MAX , MAX_RATE_POWER ) ;
}
2011-03-15 23:11:35 +05:30
REGWRITE_BUFFER_FLUSH ( ah ) ;
2009-08-07 09:45:15 +05:30
}
2010-06-01 15:14:04 +05:30
static void ath9k_hw_ar9287_set_board_values ( struct ath_hw * ah ,
2009-08-07 09:45:15 +05:30
struct ath9k_channel * chan )
{
struct ar9287_eeprom * eep = & ah - > eeprom . map9287 ;
struct modal_eep_ar9287_header * pModal = & eep - > modalHeader ;
2010-06-01 15:14:06 +05:30
u32 regChainOffset , regval ;
2009-08-07 09:45:15 +05:30
u8 txRxAttenLocal ;
2011-04-11 20:22:28 +05:30
int i ;
2009-08-07 09:45:15 +05:30
pModal = & eep - > modalHeader ;
2010-12-12 00:51:11 +01:00
REG_WRITE ( ah , AR_PHY_SWITCH_COM , pModal - > antCtrlCommon ) ;
2009-08-07 09:45:15 +05:30
for ( i = 0 ; i < AR9287_MAX_CHAINS ; i + + ) {
regChainOffset = i * 0x1000 ;
REG_WRITE ( ah , AR_PHY_SWITCH_CHAIN_0 + regChainOffset ,
pModal - > antCtrlChain [ i ] ) ;
REG_WRITE ( ah , AR_PHY_TIMING_CTRL4 ( 0 ) + regChainOffset ,
( REG_READ ( ah , AR_PHY_TIMING_CTRL4 ( 0 ) + regChainOffset )
& ~ ( AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF ) ) |
SM ( pModal - > iqCalICh [ i ] ,
AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF ) |
SM ( pModal - > iqCalQCh [ i ] ,
AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF ) ) ;
txRxAttenLocal = pModal - > txRxAttenCh [ i ] ;
REG_RMW_FIELD ( ah , AR_PHY_GAIN_2GHZ + regChainOffset ,
AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN ,
pModal - > bswMargin [ i ] ) ;
REG_RMW_FIELD ( ah , AR_PHY_GAIN_2GHZ + regChainOffset ,
AR_PHY_GAIN_2GHZ_XATTEN1_DB ,
pModal - > bswAtten [ i ] ) ;
REG_RMW_FIELD ( ah , AR_PHY_RXGAIN + regChainOffset ,
AR9280_PHY_RXGAIN_TXRX_ATTEN ,
txRxAttenLocal ) ;
REG_RMW_FIELD ( ah , AR_PHY_RXGAIN + regChainOffset ,
AR9280_PHY_RXGAIN_TXRX_MARGIN ,
pModal - > rxTxMarginCh [ i ] ) ;
}
if ( IS_CHAN_HT40 ( chan ) )
REG_RMW_FIELD ( ah , AR_PHY_SETTLING ,
AR_PHY_SETTLING_SWITCH , pModal - > swSettleHt40 ) ;
else
REG_RMW_FIELD ( ah , AR_PHY_SETTLING ,
AR_PHY_SETTLING_SWITCH , pModal - > switchSettling ) ;
REG_RMW_FIELD ( ah , AR_PHY_DESIRED_SZ ,
AR_PHY_DESIRED_SZ_ADC , pModal - > adcDesiredSize ) ;
REG_WRITE ( ah , AR_PHY_RF_CTL4 ,
SM ( pModal - > txEndToXpaOff , AR_PHY_RF_CTL4_TX_END_XPAA_OFF )
| SM ( pModal - > txEndToXpaOff , AR_PHY_RF_CTL4_TX_END_XPAB_OFF )
| SM ( pModal - > txFrameToXpaOn , AR_PHY_RF_CTL4_FRAME_XPAA_ON )
| SM ( pModal - > txFrameToXpaOn , AR_PHY_RF_CTL4_FRAME_XPAB_ON ) ) ;
REG_RMW_FIELD ( ah , AR_PHY_RF_CTL3 ,
AR_PHY_TX_END_TO_A2_RX_ON , pModal - > txEndToRxOn ) ;
REG_RMW_FIELD ( ah , AR_PHY_CCA ,
AR9280_PHY_CCA_THRESH62 , pModal - > thresh62 ) ;
REG_RMW_FIELD ( ah , AR_PHY_EXT_CCA0 ,
AR_PHY_EXT_CCA0_THRESH62 , pModal - > thresh62 ) ;
2010-06-01 15:14:06 +05:30
regval = REG_READ ( ah , AR9287_AN_RF2G3_CH0 ) ;
regval & = ~ ( AR9287_AN_RF2G3_DB1 |
AR9287_AN_RF2G3_DB2 |
AR9287_AN_RF2G3_OB_CCK |
AR9287_AN_RF2G3_OB_PSK |
AR9287_AN_RF2G3_OB_QAM |
AR9287_AN_RF2G3_OB_PAL_OFF ) ;
regval | = ( SM ( pModal - > db1 , AR9287_AN_RF2G3_DB1 ) |
SM ( pModal - > db2 , AR9287_AN_RF2G3_DB2 ) |
SM ( pModal - > ob_cck , AR9287_AN_RF2G3_OB_CCK ) |
SM ( pModal - > ob_psk , AR9287_AN_RF2G3_OB_PSK ) |
SM ( pModal - > ob_qam , AR9287_AN_RF2G3_OB_QAM ) |
SM ( pModal - > ob_pal_off , AR9287_AN_RF2G3_OB_PAL_OFF ) ) ;
ath9k_hw_analog_shift_regwrite ( ah , AR9287_AN_RF2G3_CH0 , regval ) ;
regval = REG_READ ( ah , AR9287_AN_RF2G3_CH1 ) ;
regval & = ~ ( AR9287_AN_RF2G3_DB1 |
AR9287_AN_RF2G3_DB2 |
AR9287_AN_RF2G3_OB_CCK |
AR9287_AN_RF2G3_OB_PSK |
AR9287_AN_RF2G3_OB_QAM |
AR9287_AN_RF2G3_OB_PAL_OFF ) ;
regval | = ( SM ( pModal - > db1 , AR9287_AN_RF2G3_DB1 ) |
SM ( pModal - > db2 , AR9287_AN_RF2G3_DB2 ) |
SM ( pModal - > ob_cck , AR9287_AN_RF2G3_OB_CCK ) |
SM ( pModal - > ob_psk , AR9287_AN_RF2G3_OB_PSK ) |
SM ( pModal - > ob_qam , AR9287_AN_RF2G3_OB_QAM ) |
SM ( pModal - > ob_pal_off , AR9287_AN_RF2G3_OB_PAL_OFF ) ) ;
ath9k_hw_analog_shift_regwrite ( ah , AR9287_AN_RF2G3_CH1 , regval ) ;
2009-08-07 09:45:15 +05:30
REG_RMW_FIELD ( ah , AR_PHY_RF_CTL2 ,
AR_PHY_TX_END_DATA_START , pModal - > txFrameToDataStart ) ;
REG_RMW_FIELD ( ah , AR_PHY_RF_CTL2 ,
AR_PHY_TX_END_PA_ON , pModal - > txFrameToPaOn ) ;
ath9k_hw_analog_shift_rmw ( ah , AR9287_AN_TOP2 ,
AR9287_AN_TOP2_XPABIAS_LVL ,
AR9287_AN_TOP2_XPABIAS_LVL_S ,
pModal - > xpaBiasLvl ) ;
}
2010-06-01 15:14:04 +05:30
static u16 ath9k_hw_ar9287_get_spur_channel ( struct ath_hw * ah ,
2009-08-07 09:45:15 +05:30
u16 i , bool is2GHz )
{
2013-12-14 18:03:41 +01:00
return ah - > eeprom . map9287 . modalHeader . spurChans [ i ] . spurChan ;
2009-08-07 09:45:15 +05:30
}
2010-04-15 17:39:12 -04:00
const struct eeprom_ops eep_ar9287_ops = {
2010-06-01 15:14:04 +05:30
. check_eeprom = ath9k_hw_ar9287_check_eeprom ,
. get_eeprom = ath9k_hw_ar9287_get_eeprom ,
. fill_eeprom = ath9k_hw_ar9287_fill_eeprom ,
2011-07-29 17:38:10 +05:30
. dump_eeprom = ath9k_hw_ar9287_dump_eeprom ,
2010-06-01 15:14:04 +05:30
. get_eeprom_ver = ath9k_hw_ar9287_get_eeprom_ver ,
. get_eeprom_rev = ath9k_hw_ar9287_get_eeprom_rev ,
. set_board_values = ath9k_hw_ar9287_set_board_values ,
. set_txpower = ath9k_hw_ar9287_set_txpower ,
. get_spur_channel = ath9k_hw_ar9287_get_spur_channel
2009-08-07 09:45:15 +05:30
} ;