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
static int ath9k_hw_4k_get_eeprom_ver ( struct ath_hw * ah )
{
2016-12-05 13:27:37 +02:00
u16 version = le16_to_cpu ( ah - > eeprom . map4k . baseEepHeader . version ) ;
2016-12-05 13:27:35 +02:00
return ( version & AR5416_EEP_VER_MAJOR_MASK ) > >
AR5416_EEP_VER_MAJOR_SHIFT ;
2009-08-07 09:45:15 +05:30
}
static int ath9k_hw_4k_get_eeprom_rev ( struct ath_hw * ah )
{
2016-12-05 13:27:37 +02:00
u16 version = le16_to_cpu ( ah - > eeprom . map4k . baseEepHeader . version ) ;
2016-12-05 13:27:35 +02:00
return version & AR5416_EEP_VER_MINOR_MASK ;
2009-08-07 09:45:15 +05:30
}
# define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
2011-01-04 13:17:28 +05:30
static bool __ath9k_hw_4k_fill_eeprom ( struct ath_hw * ah )
{
2009-08-07 09:45:15 +05:30
u16 * eep_data = ( u16 * ) & ah - > eeprom . map4k ;
2011-01-04 13:17:28 +05:30
int addr , eep_start_loc = 64 ;
2009-08-07 09:45:15 +05:30
for ( addr = 0 ; addr < SIZE_EEPROM_4K ; 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 + + ;
}
return true ;
}
2011-01-04 13:17:28 +05:30
static bool __ath9k_hw_usb_4k_fill_eeprom ( struct ath_hw * ah )
{
u16 * eep_data = ( u16 * ) & ah - > eeprom . map4k ;
ath9k_hw_usb_gen_fill_eeprom ( ah , eep_data , 64 , SIZE_EEPROM_4K ) ;
return true ;
}
static bool ath9k_hw_4k_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_4k_fill_eeprom ( ah ) ;
else
return __ath9k_hw_4k_fill_eeprom ( ah ) ;
}
2017-01-12 13:02:23 +02:00
# ifdef CONFIG_ATH9K_COMMON_DEBUG
2011-07-29 17:38:09 +05:30
static u32 ath9k_dump_4k_modal_eeprom ( char * buf , u32 len , u32 size ,
struct modal_eep_4k_header * modal_hdr )
{
2016-12-05 13:27:37 +02:00
PR_EEP ( " Chain0 Ant. Control " , le16_to_cpu ( modal_hdr - > antCtrlChain [ 0 ] ) ) ;
PR_EEP ( " Ant. Common Control " , le32_to_cpu ( modal_hdr - > antCtrlCommon ) ) ;
2011-07-29 17:38:09 +05:30
PR_EEP ( " Chain0 Ant. Gain " , modal_hdr - > antennaGainCh [ 0 ] ) ;
PR_EEP ( " Switch Settle " , modal_hdr - > switchSettling ) ;
PR_EEP ( " Chain0 TxRxAtten " , modal_hdr - > txRxAttenCh [ 0 ] ) ;
PR_EEP ( " Chain0 RxTxMargin " , modal_hdr - > rxTxMarginCh [ 0 ] ) ;
PR_EEP ( " ADC Desired size " , modal_hdr - > adcDesiredSize ) ;
PR_EEP ( " PGA Desired size " , modal_hdr - > pgaDesiredSize ) ;
PR_EEP ( " Chain0 xlna Gain " , modal_hdr - > xlnaGainCh [ 0 ] ) ;
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 ( " xpdGain " , modal_hdr - > xpdGain ) ;
PR_EEP ( " External PD " , modal_hdr - > xpd ) ;
PR_EEP ( " Chain0 I Coefficient " , modal_hdr - > iqCalICh [ 0 ] ) ;
PR_EEP ( " Chain0 Q Coefficient " , modal_hdr - > iqCalQCh [ 0 ] ) ;
PR_EEP ( " pdGainOverlap " , modal_hdr - > pdGainOverlap ) ;
PR_EEP ( " O/D Bias Version " , modal_hdr - > version ) ;
PR_EEP ( " CCK OutputBias " , modal_hdr - > ob_0 ) ;
PR_EEP ( " BPSK OutputBias " , modal_hdr - > ob_1 ) ;
PR_EEP ( " QPSK OutputBias " , modal_hdr - > ob_2 ) ;
PR_EEP ( " 16QAM OutputBias " , modal_hdr - > ob_3 ) ;
PR_EEP ( " 64QAM OutputBias " , modal_hdr - > ob_4 ) ;
PR_EEP ( " CCK Driver1_Bias " , modal_hdr - > db1_0 ) ;
PR_EEP ( " BPSK Driver1_Bias " , modal_hdr - > db1_1 ) ;
PR_EEP ( " QPSK Driver1_Bias " , modal_hdr - > db1_2 ) ;
PR_EEP ( " 16QAM Driver1_Bias " , modal_hdr - > db1_3 ) ;
PR_EEP ( " 64QAM Driver1_Bias " , modal_hdr - > db1_4 ) ;
PR_EEP ( " CCK Driver2_Bias " , modal_hdr - > db2_0 ) ;
PR_EEP ( " BPSK Driver2_Bias " , modal_hdr - > db2_1 ) ;
PR_EEP ( " QPSK Driver2_Bias " , modal_hdr - > db2_2 ) ;
PR_EEP ( " 16QAM Driver2_Bias " , modal_hdr - > db2_3 ) ;
PR_EEP ( " 64QAM Driver2_Bias " , modal_hdr - > db2_4 ) ;
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 ( " Chain0 bswMargin " , modal_hdr - > bswMargin [ 0 ] ) ;
PR_EEP ( " HT40 Switch Settle " , modal_hdr - > swSettleHt40 ) ;
PR_EEP ( " Chain0 xatten2Db " , modal_hdr - > xatten2Db [ 0 ] ) ;
PR_EEP ( " Chain0 xatten2Margin " , modal_hdr - > xatten2Margin [ 0 ] ) ;
PR_EEP ( " Ant. Diversity ctl1 " , modal_hdr - > antdiv_ctl1 ) ;
PR_EEP ( " Ant. Diversity ctl2 " , modal_hdr - > antdiv_ctl2 ) ;
PR_EEP ( " TX Diversity " , modal_hdr - > tx_diversity ) ;
return len ;
}
static u32 ath9k_hw_4k_dump_eeprom ( struct ath_hw * ah , bool dump_base_hdr ,
u8 * buf , u32 len , u32 size )
{
struct ar5416_eeprom_4k * eep = & ah - > eeprom . map4k ;
struct base_eep_header_4k * pBase = & eep - > baseEepHeader ;
2016-12-05 13:27:37 +02:00
u32 binBuildNumber = le32_to_cpu ( pBase - > binBuildNumber ) ;
2011-07-29 17:38:09 +05:30
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 = ath9k_dump_4k_modal_eeprom ( buf , len , size ,
2013-09-05 14:11:57 +02:00
& eep - > modalHeader ) ;
2011-07-29 17:38:09 +05:30
goto out ;
}
2016-12-05 13:27:35 +02:00
PR_EEP ( " Major Version " , ath9k_hw_4k_get_eeprom_ver ( ah ) ) ;
PR_EEP ( " Minor Version " , ath9k_hw_4k_get_eeprom_rev ( ah ) ) ;
2016-12-05 13:27:37 +02:00
PR_EEP ( " Checksum " , le16_to_cpu ( pBase - > checksum ) ) ;
PR_EEP ( " Length " , le16_to_cpu ( pBase - > length ) ) ;
PR_EEP ( " RegDomain1 " , le16_to_cpu ( pBase - > regDmn [ 0 ] ) ) ;
PR_EEP ( " RegDomain2 " , le16_to_cpu ( pBase - > regDmn [ 1 ] ) ) ;
2011-07-29 17:38:09 +05:30
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 ) ) ;
2016-12-05 13:27:32 +02:00
PR_EEP ( " Big Endian " , ! ! ( pBase - > eepMisc & AR5416_EEPMISC_BIG_ENDIAN ) ) ;
2016-12-05 13:27:37 +02:00
PR_EEP ( " Cal Bin Major Ver " , ( binBuildNumber > > 24 ) & 0xFF ) ;
PR_EEP ( " Cal Bin Minor Ver " , ( binBuildNumber > > 16 ) & 0xFF ) ;
PR_EEP ( " Cal Bin Build " , ( binBuildNumber > > 8 ) & 0xFF ) ;
2011-07-29 17:38:09 +05:30
PR_EEP ( " TX Gain type " , pBase - > txGainType ) ;
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:09 +05:30
out :
if ( len > size )
len = size ;
return len ;
}
# else
static u32 ath9k_hw_4k_dump_eeprom ( struct ath_hw * ah , bool dump_base_hdr ,
u8 * buf , u32 len , u32 size )
{
return 0 ;
}
# endif
2009-08-07 09:45:15 +05:30
static int ath9k_hw_4k_check_eeprom ( struct ath_hw * ah )
{
2012-06-04 12:44:17 +00:00
struct ar5416_eeprom_4k * eep = & ah - > eeprom . map4k ;
2015-10-31 13:57:32 +01:00
u32 el ;
bool need_swap ;
int i , err ;
2009-08-07 09:45:15 +05:30
2015-10-31 13:57:32 +01:00
err = ath9k_hw_nvram_swap_data ( ah , & need_swap , SIZE_EEPROM_4K ) ;
if ( err )
return err ;
2009-08-07 09:45:15 +05:30
if ( need_swap )
2016-12-05 13:27:37 +02:00
el = swab16 ( ( __force u16 ) eep - > baseEepHeader . length ) ;
2009-08-07 09:45:15 +05:30
else
2016-12-05 13:27:37 +02:00
el = le16_to_cpu ( eep - > baseEepHeader . length ) ;
2009-08-07 09:45:15 +05:30
2015-10-31 13:57:32 +01:00
el = min ( el / sizeof ( u16 ) , SIZE_EEPROM_4K ) ;
if ( ! ath9k_hw_nvram_validate_checksum ( ah , el ) )
return - EINVAL ;
2009-08-07 09:45:15 +05:30
if ( need_swap ) {
2016-12-05 13:27:37 +02:00
EEPROM_FIELD_SWAB16 ( eep - > baseEepHeader . length ) ;
EEPROM_FIELD_SWAB16 ( eep - > baseEepHeader . checksum ) ;
EEPROM_FIELD_SWAB16 ( eep - > baseEepHeader . version ) ;
EEPROM_FIELD_SWAB16 ( eep - > baseEepHeader . regDmn [ 0 ] ) ;
EEPROM_FIELD_SWAB16 ( eep - > baseEepHeader . regDmn [ 1 ] ) ;
EEPROM_FIELD_SWAB16 ( eep - > baseEepHeader . rfSilent ) ;
EEPROM_FIELD_SWAB16 ( eep - > baseEepHeader . blueToothOptions ) ;
EEPROM_FIELD_SWAB16 ( eep - > baseEepHeader . deviceCap ) ;
EEPROM_FIELD_SWAB32 ( eep - > modalHeader . antCtrlCommon ) ;
for ( i = 0 ; i < AR5416_EEP4K_MAX_CHAINS ; i + + )
EEPROM_FIELD_SWAB32 ( eep - > modalHeader . antCtrlChain [ i ] ) ;
for ( i = 0 ; i < AR_EEPROM_MODAL_SPURS ; i + + )
EEPROM_FIELD_SWAB16 (
eep - > modalHeader . spurChans [ i ] . spurChan ) ;
2009-08-07 09:45:15 +05:30
}
2015-10-31 13:57:32 +01:00
if ( ! ath9k_hw_nvram_check_version ( ah , AR5416_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_4K
2009-08-07 09:45:15 +05:30
static u32 ath9k_hw_4k_get_eeprom ( struct ath_hw * ah ,
enum eeprom_param param )
{
struct ar5416_eeprom_4k * eep = & ah - > eeprom . map4k ;
struct modal_eep_4k_header * pModal = & eep - > modalHeader ;
struct base_eep_header_4k * pBase = & eep - > baseEepHeader ;
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 :
2016-12-05 13:27:37 +02:00
return le16_to_cpu ( pBase - > regDmn [ 0 ] ) ;
2009-08-07 09:45:15 +05:30
case EEP_OP_CAP :
2016-12-05 13:27:37 +02:00
return le16_to_cpu ( pBase - > deviceCap ) ;
2009-08-07 09:45:15 +05:30
case EEP_OP_MODE :
return pBase - > opCapFlags ;
case EEP_RF_SILENT :
2016-12-05 13:27:37 +02:00
return le16_to_cpu ( pBase - > rfSilent ) ;
2009-08-07 09:45:15 +05:30
case EEP_OB_2 :
2009-08-07 09:45:23 +05:30
return pModal - > ob_0 ;
2009-08-07 09:45:15 +05:30
case EEP_DB_2 :
2009-08-07 09:45:23 +05:30
return pModal - > db1_1 ;
2009-08-07 09:45:15 +05:30
case EEP_TX_MASK :
return pBase - > txMask ;
case EEP_RX_MASK :
return pBase - > rxMask ;
case EEP_FRAC_N_5G :
return 0 ;
2009-09-18 15:08:20 +05:30
case EEP_PWR_TABLE_OFFSET :
return AR5416_PWR_TABLE_OFFSET_DB ;
2010-09-02 01:34:41 -07:00
case EEP_MODAL_VER :
return pModal - > version ;
case EEP_ANT_DIV_CTL1 :
return pModal - > antdiv_ctl1 ;
2010-10-05 11:32:17 +02:00
case EEP_TXGAIN_TYPE :
2011-08-03 16:35:16 +02:00
return pBase - > txGainType ;
2011-10-08 20:06:20 +02:00
case EEP_ANTENNA_GAIN_2G :
return pModal - > antennaGainCh [ 0 ] ;
2009-08-07 09:45:15 +05:30
default :
return 0 ;
}
}
static void ath9k_hw_set_4k_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
{
2009-09-13 02:42:02 -07:00
struct ath_common * common = ath9k_hw_common ( ah ) ;
2009-08-07 09:45:15 +05:30
struct ar5416_eeprom_4k * pEepData = & ah - > eeprom . map4k ;
struct cal_data_per_freq_4k * pRawDataset ;
u8 * pCalBChans = NULL ;
u16 pdGainOverlap_t2 ;
static u8 pdadcValues [ AR5416_NUM_PDADC_VALUES ] ;
2010-12-12 00:51:08 +01:00
u16 gainBoundaries [ AR5416_PD_GAINS_IN_MASK ] ;
2009-08-07 09:45:15 +05:30
u16 numPiers , i , j ;
u16 numXpdGain , xpdMask ;
u16 xpdGainValues [ AR5416_EEP4K_NUM_PD_GAINS ] = { 0 , 0 } ;
u32 reg32 , regOffset , regChainOffset ;
xpdMask = pEepData - > modalHeader . xpdGain ;
2016-12-05 13:27:35 +02:00
if ( ath9k_hw_4k_get_eeprom_rev ( ah ) > = AR5416_EEP_MINOR_VER_2 )
2009-08-07 09:45:15 +05:30
pdGainOverlap_t2 =
pEepData - > modalHeader . pdGainOverlap ;
2016-12-05 13:27:35 +02:00
else
2009-08-07 09:45:15 +05:30
pdGainOverlap_t2 = ( u16 ) ( MS ( REG_READ ( ah , AR_PHY_TPCRG5 ) ,
AR_PHY_TPCRG5_PD_GAIN_OVERLAP ) ) ;
pCalBChans = pEepData - > calFreqPier2G ;
numPiers = AR5416_EEP4K_NUM_2G_CAL_PIERS ;
numXpdGain = 0 ;
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 ) {
2009-08-07 09:45:15 +05:30
if ( numXpdGain > = AR5416_EEP4K_NUM_PD_GAINS )
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 + + ;
}
}
2015-03-22 19:29:56 +01:00
ENABLE_REG_RMW_BUFFER ( ah ) ;
2009-08-07 09:45:15 +05:30
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 , 0 ) ;
2015-03-22 19:29:56 +01:00
REG_RMW_BUFFER_FLUSH ( ah ) ;
2009-08-07 09:45:15 +05:30
for ( i = 0 ; i < AR5416_EEP4K_MAX_CHAINS ; i + + ) {
2011-09-15 14:25:35 +02:00
regChainOffset = i * 0x1000 ;
2009-08-07 09:45:15 +05:30
if ( pEepData - > baseEepHeader . txMask & ( 1 < < i ) ) {
pRawDataset = pEepData - > calPierData2G [ i ] ;
2010-12-12 00:51:09 +01:00
ath9k_hw_get_gain_boundaries_pdadcs ( ah , chan ,
2009-08-07 09:45:15 +05:30
pRawDataset , pCalBChans ,
numPiers , pdGainOverlap_t2 ,
2010-07-06 12:51:27 -04:00
gainBoundaries ,
2009-08-07 09:45:15 +05:30
pdadcValues , numXpdGain ) ;
2010-04-16 11:53:57 +05:30
ENABLE_REGWRITE_BUFFER ( ah ) ;
2011-09-15 14:25:35 +02:00
REG_WRITE ( ah , AR_PHY_TPCRG5 + regChainOffset ,
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 ) ) ;
2009-08-07 09:45:15 +05:30
regOffset = AR_PHY_BASE + ( 672 < < 2 ) + regChainOffset ;
for ( j = 0 ; j < 32 ; j + + ) {
2011-07-15 19:06:33 -04:00
reg32 = get_unaligned_le32 ( & pdadcValues [ 4 * j ] ) ;
2009-08-07 09:45:15 +05:30
REG_WRITE ( ah , regOffset , reg32 ) ;
2011-12-15 14:55:53 -08:00
ath_dbg ( common , EEPROM ,
2010-12-02 19:12:37 -08:00
" PDADC (%d,%4x): %4.4x %8.8x \n " ,
i , regChainOffset , regOffset ,
reg32 ) ;
2011-12-15 14:55:53 -08:00
ath_dbg ( common , EEPROM ,
2010-12-02 19:12:37 -08:00
" PDADC: Chain %d | "
" PDADC %3d Value %3d | "
" PDADC %3d Value %3d | "
" PDADC %3d Value %3d | "
" PDADC %3d Value %3d | \n " ,
i , 4 * j , pdadcValues [ 4 * j ] ,
4 * j + 1 , pdadcValues [ 4 * j + 1 ] ,
4 * j + 2 , pdadcValues [ 4 * j + 2 ] ,
4 * j + 3 , pdadcValues [ 4 * j + 3 ] ) ;
2009-08-07 09:45:15 +05:30
regOffset + = 4 ;
}
2010-04-16 11:53:57 +05:30
REGWRITE_BUFFER_FLUSH ( ah ) ;
2009-08-07 09:45:15 +05:30
}
}
}
static void ath9k_hw_set_4k_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 ,
2009-08-07 09:45:15 +05:30
u16 powerLimit )
{
2009-08-07 09:45:33 +05:30
# define CMP_TEST_GRP \
( ( ( cfgCtl & ~ CTL_MODE_M ) | ( pCtlMode [ ctlMode ] & CTL_MODE_M ) ) = = \
pEepData - > ctlIndex [ i ] ) \
| | ( ( ( cfgCtl & ~ CTL_MODE_M ) | ( pCtlMode [ ctlMode ] & CTL_MODE_M ) ) = = \
( ( pEepData - > ctlIndex [ i ] & CTL_MODE_M ) | SD_NO_CTL ) )
2009-08-07 09:45:15 +05:30
int i ;
2009-08-07 09:45:33 +05:30
u16 twiceMinEdgePower ;
2011-11-22 18:52:00 +05:30
u16 twiceMaxEdgePower ;
2011-10-08 20:06:20 +02:00
u16 scaledPower = 0 , minCtlPower ;
2010-11-20 18:38:53 -08:00
u16 numCtlModes ;
const u16 * pCtlMode ;
u16 ctlMode , freq ;
2009-08-07 09:45:33 +05:30
struct chan_centers centers ;
2009-08-07 09:45:15 +05:30
struct cal_ctl_data_4k * rep ;
2009-08-07 09:45:33 +05:30
struct ar5416_eeprom_4k * pEepData = & ah - > eeprom . map4k ;
2009-08-07 09:45:15 +05:30
struct cal_target_power_leg targetPowerOfdm , targetPowerCck = {
0 , { 0 , 0 , 0 , 0 }
} ;
struct cal_target_power_leg targetPowerOfdmExt = {
0 , { 0 , 0 , 0 , 0 } } , targetPowerCckExt = {
0 , { 0 , 0 , 0 , 0 }
} ;
struct cal_target_power_ht targetPowerHt20 , targetPowerHt40 = {
0 , { 0 , 0 , 0 , 0 }
} ;
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
} ;
2009-08-07 09:45:15 +05:30
ath9k_hw_get_channel_centers ( ah , chan , & centers ) ;
2011-10-08 20:06:20 +02:00
scaledPower = powerLimit - antenna_reduction ;
2009-08-07 09:45:15 +05:30
numCtlModes = ARRAY_SIZE ( ctlModesFor11g ) - SUB_NUM_CTL_MODES_AT_2G_40 ;
pCtlMode = ctlModesFor11g ;
ath9k_hw_get_legacy_target_powers ( ah , chan ,
pEepData - > calTargetPowerCck ,
AR5416_NUM_2G_CCK_TARGET_POWERS ,
& targetPowerCck , 4 , false ) ;
ath9k_hw_get_legacy_target_powers ( ah , chan ,
pEepData - > calTargetPower2G ,
AR5416_NUM_2G_20_TARGET_POWERS ,
& targetPowerOfdm , 4 , false ) ;
ath9k_hw_get_target_powers ( ah , chan ,
pEepData - > calTargetPower2GHT20 ,
AR5416_NUM_2G_20_TARGET_POWERS ,
& targetPowerHt20 , 8 , false ) ;
if ( IS_CHAN_HT40 ( chan ) ) {
numCtlModes = ARRAY_SIZE ( ctlModesFor11g ) ;
ath9k_hw_get_target_powers ( ah , chan ,
pEepData - > calTargetPower2GHT40 ,
AR5416_NUM_2G_40_TARGET_POWERS ,
& targetPowerHt40 , 8 , true ) ;
ath9k_hw_get_legacy_target_powers ( ah , chan ,
pEepData - > calTargetPowerCck ,
AR5416_NUM_2G_CCK_TARGET_POWERS ,
& targetPowerCckExt , 4 , true ) ;
ath9k_hw_get_legacy_target_powers ( ah , chan ,
pEepData - > calTargetPower2G ,
AR5416_NUM_2G_20_TARGET_POWERS ,
& targetPowerOfdmExt , 4 , true ) ;
}
for ( ctlMode = 0 ; ctlMode < numCtlModes ; ctlMode + + ) {
bool isHt40CtlMode = ( pCtlMode [ ctlMode ] = = CTL_5GHT40 ) | |
( pCtlMode [ ctlMode ] = = CTL_2GHT40 ) ;
2009-08-07 09:45:33 +05:30
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 ;
2009-08-07 09:45:15 +05:30
for ( i = 0 ; ( i < AR5416_EEP4K_NUM_CTLS ) & &
2009-08-07 09:45:33 +05:30
pEepData - > ctlIndex [ i ] ; i + + ) {
if ( CMP_TEST_GRP ) {
2009-08-07 09:45:15 +05:30
rep = & ( pEepData - > ctlData [ i ] ) ;
2009-08-07 09:45:33 +05:30
twiceMinEdgePower = ath9k_hw_get_max_edge_power (
freq ,
rep - > ctlEdges [
ar5416_get_ntxchains ( ah - > txchainmask ) - 1 ] ,
IS_CHAN_2GHZ ( chan ) ,
AR5416_EEP4K_NUM_BAND_EDGES ) ;
2009-08-07 09:45:15 +05:30
if ( ( cfgCtl & ~ CTL_MODE_M ) = = SD_NO_CTL ) {
twiceMaxEdgePower =
min ( twiceMaxEdgePower ,
twiceMinEdgePower ) ;
} else {
twiceMaxEdgePower = twiceMinEdgePower ;
break ;
}
}
}
minCtlPower = ( u8 ) min ( twiceMaxEdgePower , scaledPower ) ;
switch ( pCtlMode [ ctlMode ] ) {
case CTL_11B :
2009-08-07 09:45:33 +05:30
for ( i = 0 ; i < ARRAY_SIZE ( targetPowerCck . tPow2x ) ; i + + ) {
2009-08-07 09:45:15 +05:30
targetPowerCck . tPow2x [ i ] =
min ( ( u16 ) targetPowerCck . tPow2x [ i ] ,
minCtlPower ) ;
}
break ;
case CTL_11G :
2009-08-07 09:45:33 +05:30
for ( i = 0 ; i < ARRAY_SIZE ( targetPowerOfdm . tPow2x ) ; i + + ) {
2009-08-07 09:45:15 +05:30
targetPowerOfdm . tPow2x [ i ] =
min ( ( u16 ) targetPowerOfdm . tPow2x [ i ] ,
minCtlPower ) ;
}
break ;
case CTL_2GHT20 :
2009-08-07 09:45:33 +05:30
for ( i = 0 ; i < ARRAY_SIZE ( targetPowerHt20 . tPow2x ) ; i + + ) {
2009-08-07 09:45:15 +05:30
targetPowerHt20 . tPow2x [ i ] =
min ( ( u16 ) targetPowerHt20 . tPow2x [ i ] ,
minCtlPower ) ;
}
break ;
case CTL_11B_EXT :
2009-08-07 09:45:33 +05:30
targetPowerCckExt . tPow2x [ 0 ] =
min ( ( u16 ) targetPowerCckExt . tPow2x [ 0 ] ,
minCtlPower ) ;
2009-08-07 09:45:15 +05:30
break ;
case CTL_11G_EXT :
2009-08-07 09:45:33 +05:30
targetPowerOfdmExt . tPow2x [ 0 ] =
min ( ( u16 ) targetPowerOfdmExt . tPow2x [ 0 ] ,
minCtlPower ) ;
2009-08-07 09:45:15 +05:30
break ;
case CTL_2GHT40 :
2009-08-07 09:45:33 +05:30
for ( i = 0 ; i < ARRAY_SIZE ( targetPowerHt40 . tPow2x ) ; i + + ) {
2009-08-07 09:45:15 +05:30
targetPowerHt40 . tPow2x [ i ] =
min ( ( u16 ) targetPowerHt40 . tPow2x [ i ] ,
minCtlPower ) ;
}
break ;
default :
break ;
}
}
2009-08-07 09:45:33 +05:30
ratesArray [ rate6mb ] =
ratesArray [ rate9mb ] =
ratesArray [ rate12mb ] =
ratesArray [ rate18mb ] =
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 ] ;
ratesArray [ rate1l ] = targetPowerCck . tPow2x [ 0 ] ;
ratesArray [ rate2s ] = ratesArray [ rate2l ] = targetPowerCck . tPow2x [ 1 ] ;
ratesArray [ rate5_5s ] = ratesArray [ rate5_5l ] = targetPowerCck . tPow2x [ 2 ] ;
ratesArray [ rate11s ] = ratesArray [ rate11l ] = targetPowerCck . tPow2x [ 3 ] ;
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 ] ;
ratesArray [ rateExtCck ] = targetPowerCckExt . tPow2x [ 0 ] ;
}
2009-08-07 09:45:33 +05:30
# undef CMP_TEST_GRP
2009-08-07 09:45:15 +05:30
}
static void ath9k_hw_4k_set_txpower ( struct ath_hw * ah ,
2009-08-07 09:45:30 +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 ar5416_eeprom_4k * pEepData = & ah - > eeprom . map4k ;
struct modal_eep_4k_header * pModal = & pEepData - > modalHeader ;
int16_t ratesArray [ Ar5416RateSize ] ;
u8 ht40PowerIncForPdadc = 2 ;
int i ;
memset ( ratesArray , 0 , sizeof ( ratesArray ) ) ;
2016-12-05 13:27:35 +02:00
if ( ath9k_hw_4k_get_eeprom_rev ( ah ) > = AR5416_EEP_MINOR_VER_2 )
2009-08-07 09:45:15 +05:30
ht40PowerIncForPdadc = pModal - > ht40PowerIncForPdadc ;
ath9k_hw_set_4k_power_per_rate_table ( ah , chan ,
2009-08-07 09:45:30 +05:30
& ratesArray [ 0 ] , cfgCtl ,
twiceAntennaReduction ,
powerLimit ) ;
2009-08-07 09:45:15 +05:30
2011-07-27 15:01:03 +02:00
ath9k_hw_set_4k_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
}
2010-10-20 03:08:53 +02:00
if ( test )
return ;
2009-08-07 09:45:30 +05:30
2011-09-15 14:25:35 +02:00
for ( i = 0 ; i < Ar5416RateSize ; i + + )
ratesArray [ i ] - = AR5416_PWR_TABLE_OFFSET_DB * 2 ;
2009-08-07 09:45:15 +05:30
2010-04-16 11:53:57 +05:30
ENABLE_REGWRITE_BUFFER ( ah ) ;
2009-08-07 09:45:30 +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 ) ) ;
2009-08-07 09:45:30 +05:30
/* CCK power per rate */
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 ) ) ;
/* 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 ) ) ;
2009-08-07 09:45:30 +05:30
/* HT40 power per rate */
2009-08-07 09:45:15 +05:30
if ( IS_CHAN_HT40 ( chan ) ) {
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 ) ) ;
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 ) ) ;
}
2010-04-16 11:53:57 +05:30
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 ) ;
}
2010-04-16 11:53:57 +05:30
REGWRITE_BUFFER_FLUSH ( ah ) ;
2009-08-07 09:45:15 +05:30
}
static void ath9k_hw_4k_set_gain ( struct ath_hw * ah ,
struct modal_eep_4k_header * pModal ,
struct ar5416_eeprom_4k * eep ,
2009-08-07 09:45:19 +05:30
u8 txRxAttenLocal )
2009-08-07 09:45:15 +05:30
{
2015-03-22 19:30:01 +01:00
ENABLE_REG_RMW_BUFFER ( ah ) ;
REG_RMW ( ah , AR_PHY_SWITCH_CHAIN_0 ,
2016-12-05 13:27:37 +02:00
le32_to_cpu ( pModal - > antCtrlChain [ 0 ] ) , 0 ) ;
2009-08-07 09:45:15 +05:30
2015-03-22 19:30:01 +01:00
REG_RMW ( ah , AR_PHY_TIMING_CTRL4 ( 0 ) ,
SM ( pModal - > iqCalICh [ 0 ] , AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF ) |
SM ( pModal - > iqCalQCh [ 0 ] , AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF ) ,
AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF | AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF ) ;
2009-08-07 09:45:15 +05:30
2016-12-05 13:27:35 +02:00
if ( ath9k_hw_4k_get_eeprom_rev ( ah ) > = AR5416_EEP_MINOR_VER_3 ) {
2009-08-07 09:45:15 +05:30
txRxAttenLocal = pModal - > txRxAttenCh [ 0 ] ;
2009-08-07 09:45:19 +05:30
REG_RMW_FIELD ( ah , AR_PHY_GAIN_2GHZ ,
2009-08-07 09:45:15 +05:30
AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN , pModal - > bswMargin [ 0 ] ) ;
2009-08-07 09:45:19 +05:30
REG_RMW_FIELD ( ah , AR_PHY_GAIN_2GHZ ,
2009-08-07 09:45:15 +05:30
AR_PHY_GAIN_2GHZ_XATTEN1_DB , pModal - > bswAtten [ 0 ] ) ;
2009-08-07 09:45:19 +05:30
REG_RMW_FIELD ( ah , AR_PHY_GAIN_2GHZ ,
2009-08-07 09:45:15 +05:30
AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN ,
pModal - > xatten2Margin [ 0 ] ) ;
2009-08-07 09:45:19 +05:30
REG_RMW_FIELD ( ah , AR_PHY_GAIN_2GHZ ,
2009-08-07 09:45:15 +05:30
AR_PHY_GAIN_2GHZ_XATTEN2_DB , pModal - > xatten2Db [ 0 ] ) ;
/* Set the block 1 value to block 0 value */
REG_RMW_FIELD ( ah , AR_PHY_GAIN_2GHZ + 0x1000 ,
AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN ,
pModal - > bswMargin [ 0 ] ) ;
REG_RMW_FIELD ( ah , AR_PHY_GAIN_2GHZ + 0x1000 ,
AR_PHY_GAIN_2GHZ_XATTEN1_DB , pModal - > bswAtten [ 0 ] ) ;
REG_RMW_FIELD ( ah , AR_PHY_GAIN_2GHZ + 0x1000 ,
AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN ,
pModal - > xatten2Margin [ 0 ] ) ;
REG_RMW_FIELD ( ah , AR_PHY_GAIN_2GHZ + 0x1000 ,
AR_PHY_GAIN_2GHZ_XATTEN2_DB ,
pModal - > xatten2Db [ 0 ] ) ;
}
2009-08-07 09:45:19 +05:30
REG_RMW_FIELD ( ah , AR_PHY_RXGAIN ,
2009-08-07 09:45:15 +05:30
AR9280_PHY_RXGAIN_TXRX_ATTEN , txRxAttenLocal ) ;
2009-08-07 09:45:19 +05:30
REG_RMW_FIELD ( ah , AR_PHY_RXGAIN ,
2009-08-07 09:45:15 +05:30
AR9280_PHY_RXGAIN_TXRX_MARGIN , pModal - > rxTxMarginCh [ 0 ] ) ;
REG_RMW_FIELD ( ah , AR_PHY_RXGAIN + 0x1000 ,
AR9280_PHY_RXGAIN_TXRX_ATTEN , txRxAttenLocal ) ;
REG_RMW_FIELD ( ah , AR_PHY_RXGAIN + 0x1000 ,
AR9280_PHY_RXGAIN_TXRX_MARGIN , pModal - > rxTxMarginCh [ 0 ] ) ;
2015-03-22 19:30:01 +01:00
REG_RMW_BUFFER_FLUSH ( ah ) ;
2009-08-07 09:45:15 +05:30
}
/*
* Read EEPROM header info and program the device for correct operation
* given the channel value .
*/
static void ath9k_hw_4k_set_board_values ( struct ath_hw * ah ,
struct ath9k_channel * chan )
{
2013-07-23 16:25:17 +05:30
struct ath9k_hw_capabilities * pCap = & ah - > caps ;
2009-08-07 09:45:15 +05:30
struct modal_eep_4k_header * pModal ;
struct ar5416_eeprom_4k * eep = & ah - > eeprom . map4k ;
2011-04-06 21:42:52 +05:30
struct base_eep_header_4k * pBase = & eep - > baseEepHeader ;
2009-08-07 09:45:15 +05:30
u8 txRxAttenLocal ;
u8 ob [ 5 ] , db1 [ 5 ] , db2 [ 5 ] ;
u8 ant_div_control1 , ant_div_control2 ;
2011-09-15 14:25:35 +02:00
u8 bb_desired_scale ;
2009-08-07 09:45:15 +05:30
u32 regVal ;
pModal = & eep - > modalHeader ;
txRxAttenLocal = 23 ;
2016-12-05 13:27:37 +02:00
REG_WRITE ( ah , AR_PHY_SWITCH_COM , le32_to_cpu ( pModal - > antCtrlCommon ) ) ;
2009-08-07 09:45:15 +05:30
/* Single chain for 4K EEPROM*/
2009-08-07 09:45:19 +05:30
ath9k_hw_4k_set_gain ( ah , pModal , eep , txRxAttenLocal ) ;
2009-08-07 09:45:15 +05:30
/* Initialize Ant Diversity settings from EEPROM */
if ( pModal - > version > = 3 ) {
2009-08-07 09:45:23 +05:30
ant_div_control1 = pModal - > antdiv_ctl1 ;
ant_div_control2 = pModal - > antdiv_ctl2 ;
regVal = REG_READ ( ah , AR_PHY_MULTICHAIN_GAIN_CTL ) ;
regVal & = ( ~ ( AR_PHY_9285_ANT_DIV_CTL_ALL ) ) ;
regVal | = SM ( ant_div_control1 ,
AR_PHY_9285_ANT_DIV_CTL ) ;
regVal | = SM ( ant_div_control2 ,
AR_PHY_9285_ANT_DIV_ALT_LNACONF ) ;
regVal | = SM ( ( ant_div_control2 > > 2 ) ,
AR_PHY_9285_ANT_DIV_MAIN_LNACONF ) ;
regVal | = SM ( ( ant_div_control1 > > 1 ) ,
AR_PHY_9285_ANT_DIV_ALT_GAINTB ) ;
regVal | = SM ( ( ant_div_control1 > > 2 ) ,
AR_PHY_9285_ANT_DIV_MAIN_GAINTB ) ;
REG_WRITE ( ah , AR_PHY_MULTICHAIN_GAIN_CTL , regVal ) ;
regVal = REG_READ ( ah , AR_PHY_MULTICHAIN_GAIN_CTL ) ;
regVal = REG_READ ( ah , AR_PHY_CCK_DETECT ) ;
regVal & = ( ~ AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV ) ;
regVal | = SM ( ( ant_div_control1 > > 3 ) ,
AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV ) ;
REG_WRITE ( ah , AR_PHY_CCK_DETECT , regVal ) ;
regVal = REG_READ ( ah , AR_PHY_CCK_DETECT ) ;
2013-07-23 16:25:17 +05:30
if ( pCap - > hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB ) {
/*
* If diversity combining is enabled ,
* set MAIN to LNA1 and ALT to LNA2 initially .
*/
regVal = REG_READ ( ah , AR_PHY_MULTICHAIN_GAIN_CTL ) ;
regVal & = ( ~ ( AR_PHY_9285_ANT_DIV_MAIN_LNACONF |
AR_PHY_9285_ANT_DIV_ALT_LNACONF ) ) ;
regVal | = ( ATH_ANT_DIV_COMB_LNA1 < <
AR_PHY_9285_ANT_DIV_MAIN_LNACONF_S ) ;
regVal | = ( ATH_ANT_DIV_COMB_LNA2 < <
AR_PHY_9285_ANT_DIV_ALT_LNACONF_S ) ;
regVal & = ( ~ ( AR_PHY_9285_FAST_DIV_BIAS ) ) ;
regVal | = ( 0 < < AR_PHY_9285_FAST_DIV_BIAS_S ) ;
REG_WRITE ( ah , AR_PHY_MULTICHAIN_GAIN_CTL , regVal ) ;
}
2009-08-07 09:45:15 +05:30
}
if ( pModal - > version > = 2 ) {
2009-08-07 09:45:23 +05:30
ob [ 0 ] = pModal - > ob_0 ;
ob [ 1 ] = pModal - > ob_1 ;
ob [ 2 ] = pModal - > ob_2 ;
ob [ 3 ] = pModal - > ob_3 ;
ob [ 4 ] = pModal - > ob_4 ;
db1 [ 0 ] = pModal - > db1_0 ;
db1 [ 1 ] = pModal - > db1_1 ;
db1 [ 2 ] = pModal - > db1_2 ;
db1 [ 3 ] = pModal - > db1_3 ;
db1 [ 4 ] = pModal - > db1_4 ;
db2 [ 0 ] = pModal - > db2_0 ;
db2 [ 1 ] = pModal - > db2_1 ;
db2 [ 2 ] = pModal - > db2_2 ;
db2 [ 3 ] = pModal - > db2_3 ;
db2 [ 4 ] = pModal - > db2_4 ;
2009-08-07 09:45:15 +05:30
} else if ( pModal - > version = = 1 ) {
2009-08-07 09:45:23 +05:30
ob [ 0 ] = pModal - > ob_0 ;
ob [ 1 ] = ob [ 2 ] = ob [ 3 ] = ob [ 4 ] = pModal - > ob_1 ;
db1 [ 0 ] = pModal - > db1_0 ;
db1 [ 1 ] = db1 [ 2 ] = db1 [ 3 ] = db1 [ 4 ] = pModal - > db1_1 ;
db2 [ 0 ] = pModal - > db2_0 ;
db2 [ 1 ] = db2 [ 2 ] = db2 [ 3 ] = db2 [ 4 ] = pModal - > db2_1 ;
2009-08-07 09:45:15 +05:30
} else {
int i ;
2009-08-07 09:45:23 +05:30
2009-08-07 09:45:15 +05:30
for ( i = 0 ; i < 5 ; i + + ) {
2009-08-07 09:45:23 +05:30
ob [ i ] = pModal - > ob_0 ;
db1 [ i ] = pModal - > db1_0 ;
db2 [ i ] = pModal - > db1_0 ;
2009-08-07 09:45:15 +05:30
}
}
2015-03-22 19:30:00 +01:00
ENABLE_REG_RMW_BUFFER ( ah ) ;
2009-08-07 09:45:15 +05:30
if ( AR_SREV_9271 ( ah ) ) {
ath9k_hw_analog_shift_rmw ( ah ,
AR9285_AN_RF2G3 ,
AR9271_AN_RF2G3_OB_cck ,
AR9271_AN_RF2G3_OB_cck_S ,
ob [ 0 ] ) ;
ath9k_hw_analog_shift_rmw ( ah ,
AR9285_AN_RF2G3 ,
AR9271_AN_RF2G3_OB_psk ,
AR9271_AN_RF2G3_OB_psk_S ,
ob [ 1 ] ) ;
ath9k_hw_analog_shift_rmw ( ah ,
AR9285_AN_RF2G3 ,
AR9271_AN_RF2G3_OB_qam ,
AR9271_AN_RF2G3_OB_qam_S ,
ob [ 2 ] ) ;
ath9k_hw_analog_shift_rmw ( ah ,
AR9285_AN_RF2G3 ,
AR9271_AN_RF2G3_DB_1 ,
AR9271_AN_RF2G3_DB_1_S ,
db1 [ 0 ] ) ;
ath9k_hw_analog_shift_rmw ( ah ,
AR9285_AN_RF2G4 ,
AR9271_AN_RF2G4_DB_2 ,
AR9271_AN_RF2G4_DB_2_S ,
db2 [ 0 ] ) ;
} else {
ath9k_hw_analog_shift_rmw ( ah ,
AR9285_AN_RF2G3 ,
AR9285_AN_RF2G3_OB_0 ,
AR9285_AN_RF2G3_OB_0_S ,
ob [ 0 ] ) ;
ath9k_hw_analog_shift_rmw ( ah ,
AR9285_AN_RF2G3 ,
AR9285_AN_RF2G3_OB_1 ,
AR9285_AN_RF2G3_OB_1_S ,
ob [ 1 ] ) ;
ath9k_hw_analog_shift_rmw ( ah ,
AR9285_AN_RF2G3 ,
AR9285_AN_RF2G3_OB_2 ,
AR9285_AN_RF2G3_OB_2_S ,
ob [ 2 ] ) ;
ath9k_hw_analog_shift_rmw ( ah ,
AR9285_AN_RF2G3 ,
AR9285_AN_RF2G3_OB_3 ,
AR9285_AN_RF2G3_OB_3_S ,
ob [ 3 ] ) ;
ath9k_hw_analog_shift_rmw ( ah ,
AR9285_AN_RF2G3 ,
AR9285_AN_RF2G3_OB_4 ,
AR9285_AN_RF2G3_OB_4_S ,
ob [ 4 ] ) ;
ath9k_hw_analog_shift_rmw ( ah ,
AR9285_AN_RF2G3 ,
AR9285_AN_RF2G3_DB1_0 ,
AR9285_AN_RF2G3_DB1_0_S ,
db1 [ 0 ] ) ;
ath9k_hw_analog_shift_rmw ( ah ,
AR9285_AN_RF2G3 ,
AR9285_AN_RF2G3_DB1_1 ,
AR9285_AN_RF2G3_DB1_1_S ,
db1 [ 1 ] ) ;
ath9k_hw_analog_shift_rmw ( ah ,
AR9285_AN_RF2G3 ,
AR9285_AN_RF2G3_DB1_2 ,
AR9285_AN_RF2G3_DB1_2_S ,
db1 [ 2 ] ) ;
ath9k_hw_analog_shift_rmw ( ah ,
AR9285_AN_RF2G4 ,
AR9285_AN_RF2G4_DB1_3 ,
AR9285_AN_RF2G4_DB1_3_S ,
db1 [ 3 ] ) ;
ath9k_hw_analog_shift_rmw ( ah ,
AR9285_AN_RF2G4 ,
AR9285_AN_RF2G4_DB1_4 ,
AR9285_AN_RF2G4_DB1_4_S , db1 [ 4 ] ) ;
ath9k_hw_analog_shift_rmw ( ah ,
AR9285_AN_RF2G4 ,
AR9285_AN_RF2G4_DB2_0 ,
AR9285_AN_RF2G4_DB2_0_S ,
db2 [ 0 ] ) ;
ath9k_hw_analog_shift_rmw ( ah ,
AR9285_AN_RF2G4 ,
AR9285_AN_RF2G4_DB2_1 ,
AR9285_AN_RF2G4_DB2_1_S ,
db2 [ 1 ] ) ;
ath9k_hw_analog_shift_rmw ( ah ,
AR9285_AN_RF2G4 ,
AR9285_AN_RF2G4_DB2_2 ,
AR9285_AN_RF2G4_DB2_2_S ,
db2 [ 2 ] ) ;
ath9k_hw_analog_shift_rmw ( ah ,
AR9285_AN_RF2G4 ,
AR9285_AN_RF2G4_DB2_3 ,
AR9285_AN_RF2G4_DB2_3_S ,
db2 [ 3 ] ) ;
ath9k_hw_analog_shift_rmw ( ah ,
AR9285_AN_RF2G4 ,
AR9285_AN_RF2G4_DB2_4 ,
AR9285_AN_RF2G4_DB2_4_S ,
db2 [ 4 ] ) ;
}
2015-03-22 19:30:00 +01:00
REG_RMW_BUFFER_FLUSH ( ah ) ;
2009-08-07 09:45:15 +05:30
2015-03-22 19:30:02 +01:00
ENABLE_REG_RMW_BUFFER ( ah ) ;
2009-08-07 09:45:15 +05:30
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 ) ;
2015-03-22 19:30:02 +01:00
REG_RMW ( 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 ) , 0 ) ;
2009-08-07 09:45:15 +05:30
REG_RMW_FIELD ( ah , AR_PHY_RF_CTL3 , AR_PHY_TX_END_TO_A2_RX_ON ,
pModal - > txEndToRxOn ) ;
2009-10-19 02:33:32 -04:00
if ( AR_SREV_9271_10 ( ah ) )
REG_RMW_FIELD ( ah , AR_PHY_RF_CTL3 , AR_PHY_TX_END_TO_A2_RX_ON ,
pModal - > txEndToRxOn ) ;
2009-08-07 09:45:15 +05:30
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 ) ;
2016-12-05 13:27:35 +02:00
if ( ath9k_hw_4k_get_eeprom_rev ( ah ) > = AR5416_EEP_MINOR_VER_2 ) {
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 ) ;
}
2016-12-05 13:27:35 +02:00
if ( ath9k_hw_4k_get_eeprom_rev ( ah ) > = AR5416_EEP_MINOR_VER_3 ) {
2009-08-07 09:45:15 +05:30
if ( IS_CHAN_HT40 ( chan ) )
REG_RMW_FIELD ( ah , AR_PHY_SETTLING ,
AR_PHY_SETTLING_SWITCH ,
pModal - > swSettleHt40 ) ;
}
2011-09-15 14:25:35 +02:00
2015-03-22 19:30:02 +01:00
REG_RMW_BUFFER_FLUSH ( ah ) ;
2011-09-15 14:25:35 +02:00
bb_desired_scale = ( pModal - > bb_scale_smrt_antenna &
EEP_4K_BB_DESIRED_SCALE_MASK ) ;
if ( ( pBase - > txGainType = = 0 ) & & ( bb_desired_scale ! = 0 ) ) {
u32 pwrctrl , mask , clr ;
mask = BIT ( 0 ) | BIT ( 5 ) | BIT ( 10 ) | BIT ( 15 ) | BIT ( 20 ) | BIT ( 25 ) ;
pwrctrl = mask * bb_desired_scale ;
clr = mask * 0x1f ;
2015-03-22 19:29:58 +01:00
ENABLE_REG_RMW_BUFFER ( ah ) ;
2011-09-15 14:25:35 +02:00
REG_RMW ( ah , AR_PHY_TX_PWRCTRL8 , pwrctrl , clr ) ;
REG_RMW ( ah , AR_PHY_TX_PWRCTRL10 , pwrctrl , clr ) ;
REG_RMW ( ah , AR_PHY_CH0_TX_PWRCTRL12 , pwrctrl , clr ) ;
mask = BIT ( 0 ) | BIT ( 5 ) | BIT ( 15 ) ;
pwrctrl = mask * bb_desired_scale ;
clr = mask * 0x1f ;
REG_RMW ( ah , AR_PHY_TX_PWRCTRL9 , pwrctrl , clr ) ;
mask = BIT ( 0 ) | BIT ( 5 ) ;
pwrctrl = mask * bb_desired_scale ;
clr = mask * 0x1f ;
REG_RMW ( ah , AR_PHY_CH0_TX_PWRCTRL11 , pwrctrl , clr ) ;
REG_RMW ( ah , AR_PHY_CH0_TX_PWRCTRL13 , pwrctrl , clr ) ;
2015-03-22 19:29:58 +01:00
REG_RMW_BUFFER_FLUSH ( ah ) ;
2011-04-06 21:42:52 +05:30
}
2009-08-07 09:45:15 +05:30
}
static u16 ath9k_hw_4k_get_spur_channel ( struct ath_hw * ah , u16 i , bool is2GHz )
{
2016-12-05 13:27:37 +02:00
return le16_to_cpu ( ah - > eeprom . map4k . modalHeader . spurChans [ i ] . spurChan ) ;
2009-08-07 09:45:15 +05:30
}
2016-12-05 13:27:34 +02:00
static u8 ath9k_hw_4k_get_eepmisc ( struct ath_hw * ah )
{
return ah - > eeprom . map4k . baseEepHeader . eepMisc ;
}
2009-08-07 09:45:15 +05:30
const struct eeprom_ops eep_4k_ops = {
. check_eeprom = ath9k_hw_4k_check_eeprom ,
. get_eeprom = ath9k_hw_4k_get_eeprom ,
. fill_eeprom = ath9k_hw_4k_fill_eeprom ,
2011-07-29 17:38:09 +05:30
. dump_eeprom = ath9k_hw_4k_dump_eeprom ,
2009-08-07 09:45:15 +05:30
. get_eeprom_ver = ath9k_hw_4k_get_eeprom_ver ,
. get_eeprom_rev = ath9k_hw_4k_get_eeprom_rev ,
. set_board_values = ath9k_hw_4k_set_board_values ,
. set_txpower = ath9k_hw_4k_set_txpower ,
2016-12-05 13:27:34 +02:00
. get_spur_channel = ath9k_hw_4k_get_spur_channel ,
. get_eepmisc = ath9k_hw_4k_get_eepmisc
2009-08-07 09:45:15 +05:30
} ;