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 void ath9k_get_txgain_index ( struct ath_hw * ah ,
struct ath9k_channel * chan ,
struct calDataPerFreqOpLoop * rawDatasetOpLoop ,
u8 * calChans , u16 availPiers , u8 * pwr , u8 * pcdacIdx )
{
u8 pcdac , i = 0 ;
u16 idxL = 0 , idxR = 0 , numPiers ;
bool match ;
struct chan_centers centers ;
ath9k_hw_get_channel_centers ( ah , chan , & centers ) ;
for ( numPiers = 0 ; numPiers < availPiers ; numPiers + + )
if ( calChans [ numPiers ] = = AR5416_BCHAN_UNUSED )
break ;
match = ath9k_hw_get_lower_upper_index (
( u8 ) FREQ2FBIN ( centers . synth_center , IS_CHAN_2GHZ ( chan ) ) ,
calChans , numPiers , & idxL , & idxR ) ;
if ( match ) {
pcdac = rawDatasetOpLoop [ idxL ] . pcdac [ 0 ] [ 0 ] ;
* pwr = rawDatasetOpLoop [ idxL ] . pwrPdg [ 0 ] [ 0 ] ;
} else {
pcdac = rawDatasetOpLoop [ idxR ] . pcdac [ 0 ] [ 0 ] ;
* pwr = ( rawDatasetOpLoop [ idxL ] . pwrPdg [ 0 ] [ 0 ] +
rawDatasetOpLoop [ idxR ] . pwrPdg [ 0 ] [ 0 ] ) / 2 ;
}
while ( pcdac > ah - > originalGain [ i ] & &
i < ( AR9280_TX_GAIN_TABLE_SIZE - 1 ) )
i + + ;
* pcdacIdx = i ;
}
static void ath9k_olc_get_pdadcs ( struct ath_hw * ah ,
u32 initTxGain ,
int txPower ,
u8 * pPDADCValues )
{
u32 i ;
u32 offset ;
REG_RMW_FIELD ( ah , AR_PHY_TX_PWRCTRL6_0 ,
AR_PHY_TX_PWRCTRL_ERR_EST_MODE , 3 ) ;
REG_RMW_FIELD ( ah , AR_PHY_TX_PWRCTRL6_1 ,
AR_PHY_TX_PWRCTRL_ERR_EST_MODE , 3 ) ;
REG_RMW_FIELD ( ah , AR_PHY_TX_PWRCTRL7 ,
AR_PHY_TX_PWRCTRL_INIT_TX_GAIN , initTxGain ) ;
offset = txPower ;
for ( i = 0 ; i < AR5416_NUM_PDADC_VALUES ; i + + )
if ( i < offset )
pPDADCValues [ i ] = 0x0 ;
else
pPDADCValues [ i ] = 0xFF ;
}
static int ath9k_hw_def_get_eeprom_ver ( struct ath_hw * ah )
{
return ( ( ah - > eeprom . def . baseEepHeader . version > > 12 ) & 0xF ) ;
}
static int ath9k_hw_def_get_eeprom_rev ( struct ath_hw * ah )
{
return ( ( ah - > eeprom . def . baseEepHeader . version ) & 0xFFF ) ;
}
# define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16))
2011-01-04 13:17:28 +05:30
static bool __ath9k_hw_def_fill_eeprom ( struct ath_hw * ah )
{
2009-08-07 09:45:15 +05:30
u16 * eep_data = ( u16 * ) & ah - > eeprom . def ;
int addr , ar5416_eep_start_loc = 0x100 ;
for ( addr = 0 ; addr < SIZE_EEPROM_DEF ; addr + + ) {
2012-12-10 15:30:27 +01:00
if ( ! ath9k_hw_nvram_read ( ah , addr + ar5416_eep_start_loc ,
2012-12-10 15:30:25 +01:00
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_def_fill_eeprom ( struct ath_hw * ah )
{
u16 * eep_data = ( u16 * ) & ah - > eeprom . def ;
ath9k_hw_usb_gen_fill_eeprom ( ah , eep_data ,
0x100 , SIZE_EEPROM_DEF ) ;
return true ;
}
static bool ath9k_hw_def_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_def_fill_eeprom ( ah ) ;
else
return __ath9k_hw_def_fill_eeprom ( ah ) ;
}
# undef SIZE_EEPROM_DEF
2011-07-29 17:38:11 +05:30
# if defined(CONFIG_ATH9K_DEBUGFS) || defined(CONFIG_ATH9K_HTC_DEBUGFS)
static u32 ath9k_def_dump_modal_eeprom ( char * buf , u32 len , u32 size ,
struct modal_eep_header * modal_hdr )
{
PR_EEP ( " Chain0 Ant. Control " , modal_hdr - > antCtrlChain [ 0 ] ) ;
PR_EEP ( " Chain1 Ant. Control " , modal_hdr - > antCtrlChain [ 1 ] ) ;
PR_EEP ( " Chain2 Ant. Control " , modal_hdr - > antCtrlChain [ 2 ] ) ;
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 ( " Chain2 Ant. Gain " , modal_hdr - > antennaGainCh [ 2 ] ) ;
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 ( " Chain2 TxRxAtten " , modal_hdr - > txRxAttenCh [ 2 ] ) ;
PR_EEP ( " Chain0 RxTxMargin " , modal_hdr - > rxTxMarginCh [ 0 ] ) ;
PR_EEP ( " Chain1 RxTxMargin " , modal_hdr - > rxTxMarginCh [ 1 ] ) ;
PR_EEP ( " Chain2 RxTxMargin " , modal_hdr - > rxTxMarginCh [ 2 ] ) ;
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 ( " Chain1 xlna Gain " , modal_hdr - > xlnaGainCh [ 1 ] ) ;
PR_EEP ( " Chain2 xlna Gain " , modal_hdr - > xlnaGainCh [ 2 ] ) ;
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 ( " Chain2 NF Threshold " , modal_hdr - > noiseFloorThreshCh [ 2 ] ) ;
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 ( " Chain2 I Coefficient " , modal_hdr - > iqCalICh [ 2 ] ) ;
PR_EEP ( " Chain0 Q Coefficient " , modal_hdr - > iqCalQCh [ 0 ] ) ;
PR_EEP ( " Chain1 Q Coefficient " , modal_hdr - > iqCalQCh [ 1 ] ) ;
PR_EEP ( " Chain2 Q Coefficient " , modal_hdr - > iqCalQCh [ 2 ] ) ;
PR_EEP ( " pdGainOverlap " , modal_hdr - > pdGainOverlap ) ;
PR_EEP ( " Chain0 OutputBias " , modal_hdr - > ob ) ;
PR_EEP ( " Chain0 DriverBias " , modal_hdr - > db ) ;
PR_EEP ( " xPA Bias Level " , modal_hdr - > xpaBiasLvl ) ;
PR_EEP ( " 2chain pwr decrease " , modal_hdr - > pwrDecreaseFor2Chain ) ;
PR_EEP ( " 3chain pwr decrease " , modal_hdr - > pwrDecreaseFor3Chain ) ;
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 ( " Chain2 bswAtten " , modal_hdr - > bswAtten [ 2 ] ) ;
PR_EEP ( " Chain0 bswMargin " , modal_hdr - > bswMargin [ 0 ] ) ;
PR_EEP ( " Chain1 bswMargin " , modal_hdr - > bswMargin [ 1 ] ) ;
PR_EEP ( " Chain2 bswMargin " , modal_hdr - > bswMargin [ 2 ] ) ;
PR_EEP ( " HT40 Switch Settle " , modal_hdr - > swSettleHt40 ) ;
PR_EEP ( " Chain0 xatten2Db " , modal_hdr - > xatten2Db [ 0 ] ) ;
PR_EEP ( " Chain1 xatten2Db " , modal_hdr - > xatten2Db [ 1 ] ) ;
PR_EEP ( " Chain2 xatten2Db " , modal_hdr - > xatten2Db [ 2 ] ) ;
PR_EEP ( " Chain0 xatten2Margin " , modal_hdr - > xatten2Margin [ 0 ] ) ;
PR_EEP ( " Chain1 xatten2Margin " , modal_hdr - > xatten2Margin [ 1 ] ) ;
PR_EEP ( " Chain2 xatten2Margin " , modal_hdr - > xatten2Margin [ 2 ] ) ;
PR_EEP ( " Chain1 OutputBias " , modal_hdr - > ob_ch1 ) ;
PR_EEP ( " Chain1 DriverBias " , modal_hdr - > db_ch1 ) ;
PR_EEP ( " LNA Control " , modal_hdr - > lna_ctl ) ;
PR_EEP ( " XPA Bias Freq0 " , modal_hdr - > xpaBiasLvlFreq [ 0 ] ) ;
PR_EEP ( " XPA Bias Freq1 " , modal_hdr - > xpaBiasLvlFreq [ 1 ] ) ;
PR_EEP ( " XPA Bias Freq2 " , modal_hdr - > xpaBiasLvlFreq [ 2 ] ) ;
return len ;
}
static u32 ath9k_hw_def_dump_eeprom ( struct ath_hw * ah , bool dump_base_hdr ,
u8 * buf , u32 len , u32 size )
{
struct ar5416_eeprom_def * eep = & ah - > eeprom . def ;
struct base_eep_header * pBase = & eep - > baseEepHeader ;
if ( ! dump_base_hdr ) {
len + = snprintf ( buf + len , size - len ,
" %20s : \n " , " 2GHz modal Header " ) ;
2012-05-15 15:24:47 +05:30
len = ath9k_def_dump_modal_eeprom ( buf , len , size ,
2011-07-29 17:38:11 +05:30
& eep - > modalHeader [ 0 ] ) ;
len + = snprintf ( buf + len , size - len ,
" %20s : \n " , " 5GHz modal Header " ) ;
2012-05-15 15:24:47 +05:30
len = ath9k_def_dump_modal_eeprom ( buf , len , size ,
2011-07-29 17:38:11 +05:30
& eep - > modalHeader [ 1 ] ) ;
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 ( " OpenLoop Power Ctrl " , pBase - > openLoopPwrCntl ) ;
len + = snprintf ( buf + len , size - len , " %20s : %pM \n " , " MacAddress " ,
pBase - > macAddr ) ;
out :
if ( len > size )
len = size ;
return len ;
}
# else
static u32 ath9k_hw_def_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_def_check_eeprom ( struct ath_hw * ah )
{
2012-06-04 12:44:17 +00:00
struct ar5416_eeprom_def * eep = & ah - > eeprom . def ;
2009-09-13 02:42:02 -07:00
struct ath_common * common = ath9k_hw_common ( ah ) ;
2009-08-07 09:45:15 +05:30
u16 * eepdata , temp , magic , magic2 ;
u32 sum = 0 , el ;
bool need_swap = false ;
int i , addr , size ;
2012-12-10 15:30:27 +01:00
if ( ! ath9k_hw_nvram_read ( ah , AR5416_EEPROM_MAGIC_OFFSET , & magic ) ) {
2010-12-02 19:12:36 -08:00
ath_err ( common , " Reading Magic # failed \n " ) ;
2009-08-07 09:45:15 +05:30
return false ;
}
if ( ! ath9k_hw_use_flash ( ah ) ) {
2011-12-15 14:55:53 -08:00
ath_dbg ( common , EEPROM , " Read Magic = 0x%04X \n " , magic ) ;
2009-08-07 09:45:15 +05:30
if ( magic ! = AR5416_EEPROM_MAGIC ) {
magic2 = swab16 ( magic ) ;
if ( magic2 = = AR5416_EEPROM_MAGIC ) {
size = sizeof ( struct ar5416_eeprom_def ) ;
need_swap = true ;
eepdata = ( u16 * ) ( & ah - > eeprom ) ;
for ( addr = 0 ; addr < size / sizeof ( u16 ) ; addr + + ) {
temp = swab16 ( * eepdata ) ;
* eepdata = temp ;
eepdata + + ;
}
} else {
2010-12-02 19:12:36 -08:00
ath_err ( common ,
" Invalid EEPROM Magic. Endianness mismatch. \n " ) ;
2009-08-07 09:45:15 +05:30
return - EINVAL ;
}
}
}
2011-12-15 14:55:53 -08:00
ath_dbg ( common , EEPROM , " need_swap = %s \n " ,
2010-12-02 19:12:37 -08:00
need_swap ? " True " : " False " ) ;
2009-08-07 09:45:15 +05:30
if ( need_swap )
el = swab16 ( ah - > eeprom . def . baseEepHeader . length ) ;
else
el = ah - > eeprom . def . baseEepHeader . length ;
if ( el > sizeof ( struct ar5416_eeprom_def ) )
el = sizeof ( struct ar5416_eeprom_def ) / sizeof ( u16 ) ;
else
el = el / sizeof ( u16 ) ;
eepdata = ( u16 * ) ( & ah - > eeprom ) ;
for ( i = 0 ; i < el ; i + + )
sum ^ = * eepdata + + ;
if ( need_swap ) {
u32 integer , j ;
u16 word ;
2011-12-15 14:55:53 -08:00
ath_dbg ( common , EEPROM ,
2010-12-02 19:12:37 -08:00
" EEPROM Endianness is not native.. Changing. \n " ) ;
2009-08-07 09:45:15 +05:30
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 ;
for ( j = 0 ; j < ARRAY_SIZE ( eep - > modalHeader ) ; j + + ) {
struct modal_eep_header * pModal =
& eep - > modalHeader [ j ] ;
integer = swab32 ( pModal - > antCtrlCommon ) ;
pModal - > antCtrlCommon = integer ;
for ( i = 0 ; i < AR5416_MAX_CHAINS ; i + + ) {
integer = swab32 ( pModal - > antCtrlChain [ i ] ) ;
pModal - > antCtrlChain [ i ] = integer ;
}
2011-04-23 12:48:53 +08:00
for ( i = 0 ; i < 3 ; i + + ) {
word = swab16 ( pModal - > xpaBiasLvlFreq [ i ] ) ;
pModal - > xpaBiasLvlFreq [ i ] = word ;
}
2009-08-07 09:45:15 +05:30
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 ( pModal - > spurChans [ i ] . spurChan ) ;
pModal - > spurChans [ i ] . spurChan = word ;
}
}
}
if ( sum ! = 0xffff | | ah - > eep_ops - > get_eeprom_ver ( ah ) ! = AR5416_EEP_VER | |
ah - > eep_ops - > get_eeprom_rev ( ah ) < AR5416_EEP_NO_BACK_VER ) {
2010-12-02 19:12:36 -08:00
ath_err ( common , " Bad EEPROM checksum 0x%x or revision 0x%04x \n " ,
2009-08-07 09:45:15 +05:30
sum , ah - > eep_ops - > get_eeprom_ver ( ah ) ) ;
return - EINVAL ;
}
2010-04-15 17:39:17 -04:00
/* Enable fixup for AR_AN_TOP2 if necessary */
2011-01-26 21:59:18 +05:30
if ( ( ah - > hw_version . devid = = AR9280_DEVID_PCI ) & &
( ( eep - > baseEepHeader . version & 0xff ) > 0x0a ) & &
( eep - > baseEepHeader . pwdclkind = = 0 ) )
2011-12-19 13:56:45 +00:00
ah - > need_an_top2_fixup = true ;
2010-04-15 17:39:17 -04:00
2011-01-04 13:17:05 +05:30
if ( ( common - > bus_ops - > ath_bus_type = = ATH_USB ) & &
( AR_SREV_9280 ( ah ) ) )
eep - > modalHeader [ 0 ] . xpaBiasLvl = 0 ;
2009-08-07 09:45:15 +05:30
return 0 ;
}
static u32 ath9k_hw_def_get_eeprom ( struct ath_hw * ah ,
enum eeprom_param param )
{
struct ar5416_eeprom_def * eep = & ah - > eeprom . def ;
struct modal_eep_header * pModal = eep - > modalHeader ;
struct base_eep_header * pBase = & eep - > baseEepHeader ;
2011-10-08 20:06:20 +02:00
int band = 0 ;
2009-08-07 09:45:15 +05:30
switch ( param ) {
case EEP_NFTHRESH_5 :
return pModal [ 0 ] . noiseFloorThreshCh [ 0 ] ;
case EEP_NFTHRESH_2 :
return pModal [ 1 ] . 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_OB_5 :
return pModal [ 0 ] . ob ;
case EEP_DB_5 :
return pModal [ 0 ] . db ;
case EEP_OB_2 :
return pModal [ 1 ] . ob ;
case EEP_DB_2 :
return pModal [ 1 ] . db ;
case EEP_MINOR_REV :
return AR5416_VER_MASK ;
case EEP_TX_MASK :
return pBase - > txMask ;
case EEP_RX_MASK :
return pBase - > rxMask ;
2010-04-26 15:04:34 -04:00
case EEP_FSTCLK_5G :
return pBase - > fastClk5g ;
2009-08-07 09:45:15 +05:30
case EEP_RXGAIN_TYPE :
return pBase - > rxGainType ;
case EEP_TXGAIN_TYPE :
return pBase - > txGainType ;
case EEP_OL_PWRCTRL :
if ( AR5416_VER_MASK > = AR5416_EEP_MINOR_VER_19 )
return pBase - > openLoopPwrCntl ? true : false ;
else
return false ;
case EEP_RC_CHAIN_MASK :
if ( AR5416_VER_MASK > = AR5416_EEP_MINOR_VER_19 )
return pBase - > rcChainMask ;
else
return 0 ;
case EEP_DAC_HPWR_5G :
if ( AR5416_VER_MASK > = AR5416_EEP_MINOR_VER_20 )
return pBase - > dacHiPwrMode_5G ;
else
return 0 ;
case EEP_FRAC_N_5G :
if ( AR5416_VER_MASK > = AR5416_EEP_MINOR_VER_22 )
return pBase - > frac_n_5g ;
else
return 0 ;
2009-09-18 15:08:20 +05:30
case EEP_PWR_TABLE_OFFSET :
if ( AR5416_VER_MASK > = AR5416_EEP_MINOR_VER_21 )
return pBase - > pwr_table_offset ;
else
return AR5416_PWR_TABLE_OFFSET_DB ;
2011-10-08 20:06:20 +02:00
case EEP_ANTENNA_GAIN_2G :
band = 1 ;
/* fall through */
case EEP_ANTENNA_GAIN_5G :
return max_t ( u8 , max_t ( u8 ,
pModal [ band ] . antennaGainCh [ 0 ] ,
pModal [ band ] . antennaGainCh [ 1 ] ) ,
pModal [ band ] . antennaGainCh [ 2 ] ) ;
2009-08-07 09:45:15 +05:30
default :
return 0 ;
}
}
static void ath9k_hw_def_set_gain ( struct ath_hw * ah ,
struct modal_eep_header * pModal ,
struct ar5416_eeprom_def * eep ,
u8 txRxAttenLocal , int regChainOffset , int i )
{
if ( AR5416_VER_MASK > = AR5416_EEP_MINOR_VER_3 ) {
txRxAttenLocal = pModal - > txRxAttenCh [ i ] ;
2010-09-22 12:34:52 +02:00
if ( AR_SREV_9280_20_OR_LATER ( ah ) ) {
2009-08-07 09:45:15 +05:30
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_GAIN_2GHZ + regChainOffset ,
AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN ,
pModal - > xatten2Margin [ i ] ) ;
REG_RMW_FIELD ( ah , AR_PHY_GAIN_2GHZ + regChainOffset ,
AR_PHY_GAIN_2GHZ_XATTEN2_DB ,
pModal - > xatten2Db [ i ] ) ;
} else {
REG_WRITE ( ah , AR_PHY_GAIN_2GHZ + regChainOffset ,
( REG_READ ( ah , AR_PHY_GAIN_2GHZ + regChainOffset ) &
~ AR_PHY_GAIN_2GHZ_BSW_MARGIN )
| SM ( pModal - > bswMargin [ i ] ,
AR_PHY_GAIN_2GHZ_BSW_MARGIN ) ) ;
REG_WRITE ( ah , AR_PHY_GAIN_2GHZ + regChainOffset ,
( REG_READ ( ah , AR_PHY_GAIN_2GHZ + regChainOffset ) &
~ AR_PHY_GAIN_2GHZ_BSW_ATTEN )
| SM ( pModal - > bswAtten [ i ] ,
AR_PHY_GAIN_2GHZ_BSW_ATTEN ) ) ;
}
}
2010-09-22 12:34:52 +02:00
if ( AR_SREV_9280_20_OR_LATER ( ah ) ) {
2009-08-07 09:45:15 +05:30
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 ] ) ;
} else {
REG_WRITE ( ah ,
AR_PHY_RXGAIN + regChainOffset ,
( REG_READ ( ah , AR_PHY_RXGAIN + regChainOffset ) &
~ AR_PHY_RXGAIN_TXRX_ATTEN )
| SM ( txRxAttenLocal , AR_PHY_RXGAIN_TXRX_ATTEN ) ) ;
REG_WRITE ( ah ,
AR_PHY_GAIN_2GHZ + regChainOffset ,
( REG_READ ( ah , AR_PHY_GAIN_2GHZ + regChainOffset ) &
~ AR_PHY_GAIN_2GHZ_RXTX_MARGIN ) |
SM ( pModal - > rxTxMarginCh [ i ] , AR_PHY_GAIN_2GHZ_RXTX_MARGIN ) ) ;
}
}
static void ath9k_hw_def_set_board_values ( struct ath_hw * ah ,
struct ath9k_channel * chan )
{
struct modal_eep_header * pModal ;
struct ar5416_eeprom_def * eep = & ah - > eeprom . def ;
int i , regChainOffset ;
u8 txRxAttenLocal ;
pModal = & ( eep - > modalHeader [ IS_CHAN_2GHZ ( chan ) ] ) ;
txRxAttenLocal = IS_CHAN_2GHZ ( chan ) ? 23 : 44 ;
2010-12-12 00:51:11 +01:00
REG_WRITE ( ah , AR_PHY_SWITCH_COM , pModal - > antCtrlCommon & 0xffff ) ;
2009-08-07 09:45:15 +05:30
for ( i = 0 ; i < AR5416_MAX_CHAINS ; i + + ) {
if ( AR_SREV_9280 ( ah ) ) {
if ( i > = 2 )
break ;
}
2011-09-15 14:25:35 +02:00
if ( ( ah - > rxchainmask = = 5 | | ah - > txchainmask = = 5 ) & & ( i ! = 0 ) )
2009-08-07 09:45:15 +05:30
regChainOffset = ( i = = 1 ) ? 0x2000 : 0x1000 ;
else
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 ) ) ;
2011-09-15 14:25:35 +02:00
ath9k_hw_def_set_gain ( ah , pModal , eep , txRxAttenLocal ,
regChainOffset , i ) ;
2009-08-07 09:45:15 +05:30
}
2010-09-22 12:34:52 +02:00
if ( AR_SREV_9280_20_OR_LATER ( ah ) ) {
2009-08-07 09:45:15 +05:30
if ( IS_CHAN_2GHZ ( chan ) ) {
ath9k_hw_analog_shift_rmw ( ah , AR_AN_RF2G1_CH0 ,
AR_AN_RF2G1_CH0_OB ,
AR_AN_RF2G1_CH0_OB_S ,
pModal - > ob ) ;
ath9k_hw_analog_shift_rmw ( ah , AR_AN_RF2G1_CH0 ,
AR_AN_RF2G1_CH0_DB ,
AR_AN_RF2G1_CH0_DB_S ,
pModal - > db ) ;
ath9k_hw_analog_shift_rmw ( ah , AR_AN_RF2G1_CH1 ,
AR_AN_RF2G1_CH1_OB ,
AR_AN_RF2G1_CH1_OB_S ,
pModal - > ob_ch1 ) ;
ath9k_hw_analog_shift_rmw ( ah , AR_AN_RF2G1_CH1 ,
AR_AN_RF2G1_CH1_DB ,
AR_AN_RF2G1_CH1_DB_S ,
pModal - > db_ch1 ) ;
} else {
ath9k_hw_analog_shift_rmw ( ah , AR_AN_RF5G1_CH0 ,
AR_AN_RF5G1_CH0_OB5 ,
AR_AN_RF5G1_CH0_OB5_S ,
pModal - > ob ) ;
ath9k_hw_analog_shift_rmw ( ah , AR_AN_RF5G1_CH0 ,
AR_AN_RF5G1_CH0_DB5 ,
AR_AN_RF5G1_CH0_DB5_S ,
pModal - > db ) ;
ath9k_hw_analog_shift_rmw ( ah , AR_AN_RF5G1_CH1 ,
AR_AN_RF5G1_CH1_OB5 ,
AR_AN_RF5G1_CH1_OB5_S ,
pModal - > ob_ch1 ) ;
ath9k_hw_analog_shift_rmw ( ah , AR_AN_RF5G1_CH1 ,
AR_AN_RF5G1_CH1_DB5 ,
AR_AN_RF5G1_CH1_DB5_S ,
pModal - > db_ch1 ) ;
}
ath9k_hw_analog_shift_rmw ( ah , AR_AN_TOP2 ,
AR_AN_TOP2_XPABIAS_LVL ,
AR_AN_TOP2_XPABIAS_LVL_S ,
pModal - > xpaBiasLvl ) ;
ath9k_hw_analog_shift_rmw ( ah , AR_AN_TOP2 ,
AR_AN_TOP2_LOCALBIAS ,
AR_AN_TOP2_LOCALBIAS_S ,
2010-12-01 19:07:47 +01:00
! ! ( pModal - > lna_ctl &
LNA_CTL_LOCAL_BIAS ) ) ;
2009-08-07 09:45:15 +05:30
REG_RMW_FIELD ( ah , AR_PHY_XPA_CFG , AR_PHY_FORCE_XPA_CFG ,
2010-12-01 19:07:47 +01:00
! ! ( pModal - > lna_ctl & LNA_CTL_FORCE_XPA ) ) ;
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 ) ;
2010-09-22 12:34:52 +02:00
if ( ! AR_SREV_9280_20_OR_LATER ( ah ) )
2009-08-07 09:45:15 +05:30
REG_RMW_FIELD ( ah , AR_PHY_DESIRED_SZ ,
AR_PHY_DESIRED_SZ_PGA ,
pModal - > pgaDesiredSize ) ;
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 ) ;
2010-09-22 12:34:52 +02:00
if ( AR_SREV_9280_20_OR_LATER ( ah ) ) {
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 ) ;
} else {
REG_RMW_FIELD ( ah , AR_PHY_CCA , AR_PHY_CCA_THRESH62 ,
pModal - > thresh62 ) ;
REG_RMW_FIELD ( ah , AR_PHY_EXT_CCA ,
AR_PHY_EXT_CCA_THRESH62 ,
pModal - > thresh62 ) ;
}
if ( AR5416_VER_MASK > = AR5416_EEP_MINOR_VER_2 ) {
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 ) ;
}
if ( AR5416_VER_MASK > = AR5416_EEP_MINOR_VER_3 ) {
if ( IS_CHAN_HT40 ( chan ) )
REG_RMW_FIELD ( ah , AR_PHY_SETTLING ,
AR_PHY_SETTLING_SWITCH ,
pModal - > swSettleHt40 ) ;
}
if ( AR_SREV_9280_20_OR_LATER ( ah ) & &
AR5416_VER_MASK > = AR5416_EEP_MINOR_VER_19 )
REG_RMW_FIELD ( ah , AR_PHY_CCK_TX_CTRL ,
AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK ,
pModal - > miscBits ) ;
if ( AR_SREV_9280_20 ( ah ) & & AR5416_VER_MASK > = AR5416_EEP_MINOR_VER_20 ) {
if ( IS_CHAN_2GHZ ( chan ) )
REG_RMW_FIELD ( ah , AR_AN_TOP1 , AR_AN_TOP1_DACIPMODE ,
eep - > baseEepHeader . dacLpMode ) ;
else if ( eep - > baseEepHeader . dacHiPwrMode_5G )
REG_RMW_FIELD ( ah , AR_AN_TOP1 , AR_AN_TOP1_DACIPMODE , 0 ) ;
else
REG_RMW_FIELD ( ah , AR_AN_TOP1 , AR_AN_TOP1_DACIPMODE ,
eep - > baseEepHeader . dacLpMode ) ;
2009-09-17 09:28:21 +05:30
udelay ( 100 ) ;
2009-08-07 09:45:15 +05:30
REG_RMW_FIELD ( ah , AR_PHY_FRAME_CTL , AR_PHY_FRAME_CTL_TX_CLIP ,
pModal - > miscBits > > 2 ) ;
REG_RMW_FIELD ( ah , AR_PHY_TX_PWRCTRL9 ,
AR_PHY_TX_DESIRED_SCALE_CCK ,
eep - > baseEepHeader . desiredScaleCCK ) ;
}
}
static void ath9k_hw_def_set_addac ( struct ath_hw * ah ,
struct ath9k_channel * chan )
{
# define XPA_LVL_FREQ(cnt) (pModal->xpaBiasLvlFreq[cnt])
struct modal_eep_header * pModal ;
struct ar5416_eeprom_def * eep = & ah - > eeprom . def ;
u8 biaslevel ;
if ( ah - > hw_version . macVersion ! = AR_SREV_VERSION_9160 )
return ;
if ( ah - > eep_ops - > get_eeprom_rev ( ah ) < AR5416_EEP_MINOR_VER_7 )
return ;
pModal = & ( eep - > modalHeader [ IS_CHAN_2GHZ ( chan ) ] ) ;
if ( pModal - > xpaBiasLvl ! = 0xff ) {
biaslevel = pModal - > xpaBiasLvl ;
} else {
u16 resetFreqBin , freqBin , freqCount = 0 ;
struct chan_centers centers ;
ath9k_hw_get_channel_centers ( ah , chan , & centers ) ;
resetFreqBin = FREQ2FBIN ( centers . synth_center ,
IS_CHAN_2GHZ ( chan ) ) ;
freqBin = XPA_LVL_FREQ ( 0 ) & 0xff ;
biaslevel = ( u8 ) ( XPA_LVL_FREQ ( 0 ) > > 14 ) ;
freqCount + + ;
while ( freqCount < 3 ) {
if ( XPA_LVL_FREQ ( freqCount ) = = 0x0 )
break ;
freqBin = XPA_LVL_FREQ ( freqCount ) & 0xff ;
if ( resetFreqBin > = freqBin )
biaslevel = ( u8 ) ( XPA_LVL_FREQ ( freqCount ) > > 14 ) ;
else
break ;
freqCount + + ;
}
}
if ( IS_CHAN_2GHZ ( chan ) ) {
INI_RA ( & ah - > iniAddac , 7 , 1 ) = ( INI_RA ( & ah - > iniAddac ,
7 , 1 ) & ( ~ 0x18 ) ) | biaslevel < < 3 ;
} else {
INI_RA ( & ah - > iniAddac , 6 , 1 ) = ( INI_RA ( & ah - > iniAddac ,
6 , 1 ) & ( ~ 0xc0 ) ) | biaslevel < < 6 ;
}
# undef XPA_LVL_FREQ
}
2009-09-18 15:08:20 +05:30
static int16_t ath9k_change_gain_boundary_setting ( struct ath_hw * ah ,
u16 * gb ,
u16 numXpdGain ,
u16 pdGainOverlap_t2 ,
int8_t pwr_table_offset ,
int16_t * diff )
{
u16 k ;
/* Prior to writing the boundaries or the pdadc vs. power table
* into the chip registers the default starting point on the pdadc
* vs . power table needs to be checked and the curve boundaries
* adjusted accordingly
*/
if ( AR_SREV_9280_20_OR_LATER ( ah ) ) {
u16 gb_limit ;
if ( AR5416_PWR_TABLE_OFFSET_DB ! = pwr_table_offset ) {
/* get the difference in dB */
* diff = ( u16 ) ( pwr_table_offset - AR5416_PWR_TABLE_OFFSET_DB ) ;
/* get the number of half dB steps */
* diff * = 2 ;
/* change the original gain boundary settings
* by the number of half dB steps
*/
for ( k = 0 ; k < numXpdGain ; k + + )
gb [ k ] = ( u16 ) ( gb [ k ] - * diff ) ;
}
/* Because of a hardware limitation, ensure the gain boundary
* is not larger than ( 63 - overlap )
*/
2010-12-12 00:51:08 +01:00
gb_limit = ( u16 ) ( MAX_RATE_POWER - pdGainOverlap_t2 ) ;
2009-09-18 15:08:20 +05:30
for ( k = 0 ; k < numXpdGain ; k + + )
gb [ k ] = ( u16 ) min ( gb_limit , gb [ k ] ) ;
}
return * diff ;
}
static void ath9k_adjust_pdadc_values ( struct ath_hw * ah ,
int8_t pwr_table_offset ,
int16_t diff ,
u8 * pdadcValues )
{
# define NUM_PDADC(diff) (AR5416_NUM_PDADC_VALUES - diff)
u16 k ;
/* If this is a board that has a pwrTableOffset that differs from
* the default AR5416_PWR_TABLE_OFFSET_DB then the start of the
* pdadc vs pwr table needs to be adjusted prior to writing to the
* chip .
*/
if ( AR_SREV_9280_20_OR_LATER ( ah ) ) {
if ( AR5416_PWR_TABLE_OFFSET_DB ! = pwr_table_offset ) {
/* shift the table to start at the new offset */
for ( k = 0 ; k < ( u16 ) NUM_PDADC ( diff ) ; k + + ) {
pdadcValues [ k ] = pdadcValues [ k + diff ] ;
}
/* fill the back of the table */
for ( k = ( u16 ) NUM_PDADC ( diff ) ; k < NUM_PDADC ( 0 ) ; k + + ) {
pdadcValues [ k ] = pdadcValues [ NUM_PDADC ( diff ) ] ;
}
}
}
# undef NUM_PDADC
}
2009-08-07 09:45:15 +05:30
static void ath9k_hw_set_def_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
{
# define SM_PD_GAIN(x) SM(0x38, AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##x)
# define SM_PDGAIN_B(x, y) \
SM ( ( gainBoundaries [ x ] ) , AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_ # # y )
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_def * pEepData = & ah - > eeprom . def ;
struct cal_data_per_freq * pRawDataset ;
u8 * pCalBChans = NULL ;
u16 pdGainOverlap_t2 ;
static u8 pdadcValues [ AR5416_NUM_PDADC_VALUES ] ;
u16 gainBoundaries [ AR5416_PD_GAINS_IN_MASK ] ;
u16 numPiers , i , j ;
2010-07-06 12:51:27 -04:00
int16_t diff = 0 ;
2009-08-07 09:45:15 +05:30
u16 numXpdGain , xpdMask ;
u16 xpdGainValues [ AR5416_NUM_PD_GAINS ] = { 0 , 0 , 0 , 0 } ;
u32 reg32 , regOffset , regChainOffset ;
int16_t modalIdx ;
2009-09-18 15:08:20 +05:30
int8_t pwr_table_offset ;
2009-08-07 09:45:15 +05:30
modalIdx = IS_CHAN_2GHZ ( chan ) ? 1 : 0 ;
xpdMask = pEepData - > modalHeader [ modalIdx ] . xpdGain ;
2009-09-18 15:08:20 +05:30
pwr_table_offset = ah - > eep_ops - > get_eeprom ( ah , EEP_PWR_TABLE_OFFSET ) ;
2009-08-07 09:45:15 +05:30
if ( ( pEepData - > baseEepHeader . version & AR5416_EEP_VER_MINOR_MASK ) > =
AR5416_EEP_MINOR_VER_2 ) {
pdGainOverlap_t2 =
pEepData - > modalHeader [ modalIdx ] . 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 = AR5416_NUM_2G_CAL_PIERS ;
} else {
pCalBChans = pEepData - > calFreqPier5G ;
numPiers = AR5416_NUM_5G_CAL_PIERS ;
}
if ( OLC_FOR_AR9280_20_LATER & & IS_CHAN_2GHZ ( chan ) ) {
pRawDataset = pEepData - > calPierData2G [ 0 ] ;
ah - > initPDADC = ( ( struct calDataPerFreqOpLoop * )
pRawDataset ) - > vpdPdg [ 0 ] [ 0 ] ;
}
numXpdGain = 0 ;
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 )
break ;
xpdGainValues [ numXpdGain ] =
( u16 ) ( AR5416_PD_GAINS_IN_MASK - i ) ;
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 < AR5416_MAX_CHAINS ; i + + ) {
2011-09-15 14:25:35 +02:00
if ( ( ah - > rxchainmask = = 5 | | ah - > txchainmask = = 5 ) & &
2009-08-07 09:45:15 +05:30
( i ! = 0 ) ) {
regChainOffset = ( i = = 1 ) ? 0x2000 : 0x1000 ;
} else
regChainOffset = i * 0x1000 ;
if ( pEepData - > baseEepHeader . txMask & ( 1 < < i ) ) {
if ( IS_CHAN_2GHZ ( chan ) )
pRawDataset = pEepData - > calPierData2G [ i ] ;
else
pRawDataset = pEepData - > calPierData5G [ i ] ;
if ( OLC_FOR_AR9280_20_LATER ) {
u8 pcdacIdx ;
u8 txPower ;
ath9k_get_txgain_index ( ah , chan ,
( struct calDataPerFreqOpLoop * ) pRawDataset ,
pCalBChans , numPiers , & txPower , & pcdacIdx ) ;
ath9k_olc_get_pdadcs ( ah , pcdacIdx ,
txPower / 2 , pdadcValues ) ;
} else {
2010-12-12 00:51:09 +01:00
ath9k_hw_get_gain_boundaries_pdadcs ( ah ,
2009-08-07 09:45:15 +05:30
chan , pRawDataset ,
pCalBChans , numPiers ,
pdGainOverlap_t2 ,
gainBoundaries ,
pdadcValues ,
numXpdGain ) ;
}
2009-09-18 15:08:20 +05:30
diff = ath9k_change_gain_boundary_setting ( ah ,
gainBoundaries ,
numXpdGain ,
pdGainOverlap_t2 ,
pwr_table_offset ,
& diff ) ;
2011-03-15 23:11:35 +05:30
ENABLE_REGWRITE_BUFFER ( ah ) ;
2011-09-15 14:25:35 +02:00
if ( OLC_FOR_AR9280_20_LATER ) {
REG_WRITE ( ah ,
AR_PHY_TPCRG5 + regChainOffset ,
SM ( 0x6 ,
AR_PHY_TPCRG5_PD_GAIN_OVERLAP ) |
SM_PD_GAIN ( 1 ) | SM_PD_GAIN ( 2 ) |
SM_PD_GAIN ( 3 ) | SM_PD_GAIN ( 4 ) ) ;
} else {
REG_WRITE ( ah ,
AR_PHY_TPCRG5 + regChainOffset ,
SM ( pdGainOverlap_t2 ,
AR_PHY_TPCRG5_PD_GAIN_OVERLAP ) |
SM_PDGAIN_B ( 0 , 1 ) |
SM_PDGAIN_B ( 1 , 2 ) |
SM_PDGAIN_B ( 2 , 3 ) |
SM_PDGAIN_B ( 3 , 4 ) ) ;
2009-08-07 09:45:15 +05:30
}
2009-09-18 15:08:20 +05:30
ath9k_adjust_pdadc_values ( ah , pwr_table_offset ,
diff , pdadcValues ) ;
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 ,
" PDADC: Chain %d | PDADC %3d Value %3d | PDADC %3d Value %3d | PDADC %3d Value %3d | PDADC %3d Value %3d | \n " ,
2010-12-02 19:12:37 -08:00
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 ;
}
2011-03-15 23:11:35 +05:30
REGWRITE_BUFFER_FLUSH ( ah ) ;
2009-08-07 09:45:15 +05:30
}
}
# undef SM_PD_GAIN
# undef SM_PDGAIN_B
}
static void ath9k_hw_set_def_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 )
{
struct ar5416_eeprom_def * pEepData = & ah - > eeprom . def ;
2011-11-22 18:52:00 +05:30
u16 twiceMaxEdgePower ;
2009-08-07 09:45:15 +05:30
int i ;
struct cal_ctl_data * rep ;
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 }
} ;
2011-10-08 20:06:20 +02:00
u16 scaledPower = 0 , minCtlPower ;
2010-11-20 18:38:53 -08:00
static const u16 ctlModesFor11a [ ] = {
CTL_11A , CTL_5GHT20 , CTL_11A_EXT , CTL_5GHT40
} ;
static const u16 ctlModesFor11g [ ] = {
CTL_11B , CTL_11G , CTL_2GHT20 ,
CTL_11B_EXT , CTL_11G_EXT , CTL_2GHT40
} ;
u16 numCtlModes ;
const u16 * pCtlMode ;
u16 ctlMode , freq ;
2009-08-07 09:45:15 +05:30
struct chan_centers centers ;
int tx_chainmask ;
u16 twiceMinEdgePower ;
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
if ( IS_CHAN_2GHZ ( chan ) ) {
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 ) ;
}
} else {
numCtlModes = ARRAY_SIZE ( ctlModesFor11a ) -
SUB_NUM_CTL_MODES_AT_5G_40 ;
pCtlMode = ctlModesFor11a ;
ath9k_hw_get_legacy_target_powers ( ah , chan ,
pEepData - > calTargetPower5G ,
AR5416_NUM_5G_20_TARGET_POWERS ,
& targetPowerOfdm , 4 , false ) ;
ath9k_hw_get_target_powers ( ah , chan ,
pEepData - > calTargetPower5GHT20 ,
AR5416_NUM_5G_20_TARGET_POWERS ,
& targetPowerHt20 , 8 , false ) ;
if ( IS_CHAN_HT40 ( chan ) ) {
numCtlModes = ARRAY_SIZE ( ctlModesFor11a ) ;
ath9k_hw_get_target_powers ( ah , chan ,
pEepData - > calTargetPower5GHT40 ,
AR5416_NUM_5G_40_TARGET_POWERS ,
& targetPowerHt40 , 8 , true ) ;
ath9k_hw_get_legacy_target_powers ( ah , chan ,
pEepData - > calTargetPower5G ,
AR5416_NUM_5G_20_TARGET_POWERS ,
& targetPowerOfdmExt , 4 , true ) ;
}
}
for ( ctlMode = 0 ; ctlMode < numCtlModes ; ctlMode + + ) {
bool isHt40CtlMode = ( pCtlMode [ ctlMode ] = = CTL_5GHT40 ) | |
( pCtlMode [ ctlMode ] = = CTL_2GHT40 ) ;
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_NUM_CTLS ) & & pEepData - > ctlIndex [ i ] ; i + + ) {
if ( ( ( ( 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 ) ) ) {
rep = & ( pEepData - > ctlData [ i ] ) ;
twiceMinEdgePower = ath9k_hw_get_max_edge_power ( freq ,
rep - > ctlEdges [ ar5416_get_ntxchains ( tx_chainmask ) - 1 ] ,
IS_CHAN_2GHZ ( chan ) , AR5416_NUM_BAND_EDGES ) ;
if ( ( cfgCtl & ~ CTL_MODE_M ) = = SD_NO_CTL ) {
twiceMaxEdgePower = min ( twiceMaxEdgePower ,
twiceMinEdgePower ) ;
} else {
twiceMaxEdgePower = twiceMinEdgePower ;
break ;
}
}
}
minCtlPower = min ( twiceMaxEdgePower , scaledPower ) ;
switch ( pCtlMode [ ctlMode ] ) {
case CTL_11B :
for ( i = 0 ; i < ARRAY_SIZE ( targetPowerCck . tPow2x ) ; i + + ) {
targetPowerCck . tPow2x [ i ] =
min ( ( u16 ) targetPowerCck . tPow2x [ i ] ,
minCtlPower ) ;
}
break ;
case CTL_11A :
case CTL_11G :
for ( i = 0 ; i < ARRAY_SIZE ( targetPowerOfdm . tPow2x ) ; i + + ) {
targetPowerOfdm . tPow2x [ i ] =
min ( ( u16 ) targetPowerOfdm . tPow2x [ i ] ,
minCtlPower ) ;
}
break ;
case CTL_5GHT20 :
case CTL_2GHT20 :
for ( i = 0 ; i < ARRAY_SIZE ( targetPowerHt20 . tPow2x ) ; i + + ) {
targetPowerHt20 . tPow2x [ i ] =
min ( ( u16 ) targetPowerHt20 . tPow2x [ i ] ,
minCtlPower ) ;
}
break ;
case CTL_11B_EXT :
targetPowerCckExt . tPow2x [ 0 ] = min ( ( u16 )
targetPowerCckExt . tPow2x [ 0 ] ,
minCtlPower ) ;
break ;
case CTL_11A_EXT :
case CTL_11G_EXT :
targetPowerOfdmExt . tPow2x [ 0 ] = min ( ( u16 )
targetPowerOfdmExt . tPow2x [ 0 ] ,
minCtlPower ) ;
break ;
case CTL_5GHT40 :
case CTL_2GHT40 :
for ( i = 0 ; i < ARRAY_SIZE ( targetPowerHt40 . tPow2x ) ; i + + ) {
targetPowerHt40 . tPow2x [ i ] =
min ( ( u16 ) targetPowerHt40 . tPow2x [ i ] ,
minCtlPower ) ;
}
break ;
default :
break ;
}
}
ratesArray [ rate6mb ] = ratesArray [ rate9mb ] = ratesArray [ rate12mb ] =
ratesArray [ rate18mb ] = ratesArray [ rate24mb ] =
targetPowerOfdm . tPow2x [ 0 ] ;
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 ] ;
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 ] ;
if ( IS_CHAN_2GHZ ( chan ) ) {
ratesArray [ rateExtCck ] =
targetPowerCckExt . tPow2x [ 0 ] ;
}
}
}
static void ath9k_hw_def_set_txpower ( struct ath_hw * ah ,
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
{
# define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta)
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_def * pEepData = & ah - > eeprom . def ;
struct modal_eep_header * pModal =
& ( pEepData - > modalHeader [ IS_CHAN_2GHZ ( chan ) ] ) ;
int16_t ratesArray [ Ar5416RateSize ] ;
u8 ht40PowerIncForPdadc = 2 ;
int i , cck_ofdm_delta = 0 ;
memset ( ratesArray , 0 , sizeof ( ratesArray ) ) ;
if ( ( pEepData - > baseEepHeader . version & AR5416_EEP_VER_MINOR_MASK ) > =
AR5416_EEP_MINOR_VER_2 ) {
ht40PowerIncForPdadc = pModal - > ht40PowerIncForPdadc ;
}
ath9k_hw_set_def_power_per_rate_table ( ah , chan ,
& ratesArray [ 0 ] , cfgCtl ,
twiceAntennaReduction ,
powerLimit ) ;
2011-07-27 15:01:03 +02:00
ath9k_hw_set_def_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-14 20:35:19 +02:00
ath9k_hw_update_regulatory_maxpower ( ah ) ;
2010-10-20 03:08:53 +02:00
if ( test )
return ;
2010-09-22 12:34:52 +02:00
if ( AR_SREV_9280_20_OR_LATER ( ah ) ) {
2009-09-18 15:08:20 +05:30
for ( i = 0 ; i < Ar5416RateSize ; i + + ) {
int8_t pwr_table_offset ;
pwr_table_offset = ah - > eep_ops - > get_eeprom ( ah ,
EEP_PWR_TABLE_OFFSET ) ;
ratesArray [ i ] - = pwr_table_offset * 2 ;
}
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
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 ) ) ;
if ( IS_CHAN_2GHZ ( chan ) ) {
if ( OLC_FOR_AR9280_20_LATER ) {
cck_ofdm_delta = 2 ;
REG_WRITE ( ah , AR_PHY_POWER_TX_RATE3 ,
ATH9K_POW_SM ( RT_AR_DELTA ( rate2s ) , 24 )
| ATH9K_POW_SM ( RT_AR_DELTA ( rate2l ) , 16 )
| ATH9K_POW_SM ( ratesArray [ rateXr ] , 8 )
| ATH9K_POW_SM ( RT_AR_DELTA ( rate1l ) , 0 ) ) ;
REG_WRITE ( ah , AR_PHY_POWER_TX_RATE4 ,
ATH9K_POW_SM ( RT_AR_DELTA ( rate11s ) , 24 )
| ATH9K_POW_SM ( RT_AR_DELTA ( rate11l ) , 16 )
| ATH9K_POW_SM ( RT_AR_DELTA ( rate5_5s ) , 8 )
| ATH9K_POW_SM ( RT_AR_DELTA ( rate5_5l ) , 0 ) ) ;
} else {
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 ) ) ;
}
}
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 ) ) ;
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 ) ) ;
if ( OLC_FOR_AR9280_20_LATER ) {
REG_WRITE ( ah , AR_PHY_POWER_TX_RATE9 ,
ATH9K_POW_SM ( ratesArray [ rateExtOfdm ] , 24 )
| ATH9K_POW_SM ( RT_AR_DELTA ( rateExtCck ) , 16 )
| ATH9K_POW_SM ( ratesArray [ rateDupOfdm ] , 8 )
| ATH9K_POW_SM ( RT_AR_DELTA ( rateDupCck ) , 0 ) ) ;
} else {
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 ) ) ;
}
}
REG_WRITE ( ah , AR_PHY_POWER_TX_SUB ,
ATH9K_POW_SM ( pModal - > pwrDecreaseFor3Chain , 6 )
| ATH9K_POW_SM ( pModal - > pwrDecreaseFor2Chain , 0 ) ) ;
2011-03-15 23:11:35 +05:30
REGWRITE_BUFFER_FLUSH ( ah ) ;
2009-08-07 09:45:15 +05:30
}
static u16 ath9k_hw_def_get_spur_channel ( struct ath_hw * ah , u16 i , bool is2GHz )
{
# define EEP_DEF_SPURCHAN \
( ah - > eeprom . def . modalHeader [ is2GHz ] . spurChans [ i ] . spurChan )
2009-09-13 02:42:02 -07:00
struct ath_common * common = ath9k_hw_common ( ah ) ;
2009-08-07 09:45:15 +05:30
u16 spur_val = AR_NO_SPUR ;
2011-12-15 14:55:53 -08:00
ath_dbg ( common , ANI , " Getting spur idx:%d is2Ghz:%d val:%x \n " ,
2010-12-02 19:12:37 -08:00
i , is2GHz , ah - > config . spurchans [ i ] [ is2GHz ] ) ;
2009-08-07 09:45:15 +05:30
switch ( ah - > config . spurmode ) {
case SPUR_DISABLE :
break ;
case SPUR_ENABLE_IOCTL :
spur_val = ah - > config . spurchans [ i ] [ is2GHz ] ;
2011-12-15 14:55:53 -08:00
ath_dbg ( common , ANI , " Getting spur val from new loc. %d \n " ,
spur_val ) ;
2009-08-07 09:45:15 +05:30
break ;
case SPUR_ENABLE_EEPROM :
spur_val = EEP_DEF_SPURCHAN ;
break ;
}
return spur_val ;
# undef EEP_DEF_SPURCHAN
}
const struct eeprom_ops eep_def_ops = {
. check_eeprom = ath9k_hw_def_check_eeprom ,
. get_eeprom = ath9k_hw_def_get_eeprom ,
. fill_eeprom = ath9k_hw_def_fill_eeprom ,
2011-07-29 17:38:11 +05:30
. dump_eeprom = ath9k_hw_def_dump_eeprom ,
2009-08-07 09:45:15 +05:30
. get_eeprom_ver = ath9k_hw_def_get_eeprom_ver ,
. get_eeprom_rev = ath9k_hw_def_get_eeprom_rev ,
. set_board_values = ath9k_hw_def_set_board_values ,
. set_addac = ath9k_hw_def_set_addac ,
. set_txpower = ath9k_hw_def_set_txpower ,
. get_spur_channel = ath9k_hw_def_get_spur_channel
} ;