2010-04-15 17:39:03 -04:00
/*
2011-05-17 13:36:18 +05:30
* Copyright ( c ) 2008 - 2011 Atheros Communications Inc .
2010-04-15 17:39:03 -04:00
*
* 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-09-15 19:46:05 -04:00
# include <linux/moduleparam.h>
2010-04-15 17:39:03 -04:00
# include "hw.h"
# include "ar5008_initvals.h"
# include "ar9001_initvals.h"
# include "ar9002_initvals.h"
2010-06-01 15:14:10 +05:30
# include "ar9002_phy.h"
2010-04-15 17:39:03 -04:00
/* General hardware code for the A5008/AR9001/AR9002 hadware families */
2013-01-13 19:54:58 +01:00
static int ar9002_hw_init_mode_regs ( struct ath_hw * ah )
2010-04-15 17:39:03 -04:00
{
if ( AR_SREV_9271 ( ah ) ) {
2012-07-15 19:53:33 +02:00
INIT_INI_ARRAY ( & ah - > iniModes , ar9271Modes_9271 ) ;
INIT_INI_ARRAY ( & ah - > iniCommon , ar9271Common_9271 ) ;
INIT_INI_ARRAY ( & ah - > iniModes_9271_ANI_reg , ar9271Modes_9271_ANI_reg ) ;
2013-01-13 19:54:58 +01:00
return 0 ;
2010-04-15 17:39:03 -04:00
}
2013-12-14 18:03:40 +01:00
INIT_INI_ARRAY ( & ah - > iniPcieSerdes ,
ar9280PciePhy_clkreq_always_on_L1_9280 ) ;
2012-02-15 21:53:16 +01:00
2010-04-15 17:39:03 -04:00
if ( AR_SREV_9287_11_OR_LATER ( ah ) ) {
2012-07-15 19:53:33 +02:00
INIT_INI_ARRAY ( & ah - > iniModes , ar9287Modes_9287_1_1 ) ;
INIT_INI_ARRAY ( & ah - > iniCommon , ar9287Common_9287_1_1 ) ;
2010-04-15 17:39:03 -04:00
} else if ( AR_SREV_9285_12_OR_LATER ( ah ) ) {
2012-07-15 19:53:33 +02:00
INIT_INI_ARRAY ( & ah - > iniModes , ar9285Modes_9285_1_2 ) ;
INIT_INI_ARRAY ( & ah - > iniCommon , ar9285Common_9285_1_2 ) ;
2010-04-15 17:39:03 -04:00
} else if ( AR_SREV_9280_20_OR_LATER ( ah ) ) {
2012-07-15 19:53:33 +02:00
INIT_INI_ARRAY ( & ah - > iniModes , ar9280Modes_9280_2 ) ;
INIT_INI_ARRAY ( & ah - > iniCommon , ar9280Common_9280_2 ) ;
2010-04-15 17:39:03 -04:00
2012-03-14 16:40:31 +01:00
INIT_INI_ARRAY ( & ah - > iniModesFastClock ,
2012-07-15 19:53:33 +02:00
ar9280Modes_fast_clock_9280_2 ) ;
2010-04-15 17:39:03 -04:00
} else if ( AR_SREV_9160_10_OR_LATER ( ah ) ) {
2012-07-15 19:53:33 +02:00
INIT_INI_ARRAY ( & ah - > iniModes , ar5416Modes_9160 ) ;
INIT_INI_ARRAY ( & ah - > iniCommon , ar5416Common_9160 ) ;
2010-04-15 17:39:03 -04:00
if ( AR_SREV_9160_11 ( ah ) ) {
INIT_INI_ARRAY ( & ah - > iniAddac ,
2012-07-15 19:53:33 +02:00
ar5416Addac_9160_1_1 ) ;
2010-04-15 17:39:03 -04:00
} else {
2012-07-15 19:53:33 +02:00
INIT_INI_ARRAY ( & ah - > iniAddac , ar5416Addac_9160 ) ;
2010-04-15 17:39:03 -04:00
}
} else if ( AR_SREV_9100_OR_LATER ( ah ) ) {
2012-07-15 19:53:33 +02:00
INIT_INI_ARRAY ( & ah - > iniModes , ar5416Modes_9100 ) ;
INIT_INI_ARRAY ( & ah - > iniCommon , ar5416Common_9100 ) ;
INIT_INI_ARRAY ( & ah - > iniAddac , ar5416Addac_9100 ) ;
2010-04-15 17:39:03 -04:00
} else {
2012-07-15 19:53:33 +02:00
INIT_INI_ARRAY ( & ah - > iniModes , ar5416Modes ) ;
INIT_INI_ARRAY ( & ah - > iniCommon , ar5416Common ) ;
INIT_INI_ARRAY ( & ah - > iniAddac , ar5416Addac ) ;
2012-02-15 21:53:16 +01:00
}
if ( ! AR_SREV_9280_20_OR_LATER ( ah ) ) {
/* Common for AR5416, AR913x, AR9160 */
2012-07-15 19:53:33 +02:00
INIT_INI_ARRAY ( & ah - > iniBB_RfGain , ar5416BB_RfGain ) ;
2012-02-15 21:53:16 +01:00
/* Common for AR913x, AR9160 */
if ( ! AR_SREV_5416 ( ah ) )
2013-04-08 00:04:07 +02:00
INIT_INI_ARRAY ( & ah - > iniBank6 , ar5416Bank6TPC_9100 ) ;
else
INIT_INI_ARRAY ( & ah - > iniBank6 , ar5416Bank6TPC ) ;
2010-04-15 17:39:03 -04:00
}
2012-02-15 19:31:20 +01:00
/* iniAddac needs to be modified for these chips */
if ( AR_SREV_9160 ( ah ) | | ! AR_SREV_5416_22_OR_LATER ( ah ) ) {
struct ar5416IniArray * addac = & ah - > iniAddac ;
u32 size = sizeof ( u32 ) * addac - > ia_rows * addac - > ia_columns ;
u32 * data ;
2012-12-12 13:14:23 +01:00
data = devm_kzalloc ( ah - > dev , size , GFP_KERNEL ) ;
2012-02-15 19:31:20 +01:00
if ( ! data )
2013-01-13 19:54:58 +01:00
return - ENOMEM ;
2012-02-15 19:31:20 +01:00
memcpy ( data , addac - > ia_array , size ) ;
addac - > ia_array = data ;
if ( ! AR_SREV_5416_22_OR_LATER ( ah ) ) {
/* override CLKDRV value */
INI_RA ( addac , 31 , 1 ) = 0 ;
}
}
2010-04-15 17:39:04 -04:00
if ( AR_SREV_9287_11_OR_LATER ( ah ) ) {
INIT_INI_ARRAY ( & ah - > iniCckfirNormal ,
2012-07-15 19:53:33 +02:00
ar9287Common_normal_cck_fir_coeff_9287_1_1 ) ;
2010-04-15 17:39:04 -04:00
INIT_INI_ARRAY ( & ah - > iniCckfirJapan2484 ,
2012-07-15 19:53:33 +02:00
ar9287Common_japan_2484_cck_fir_coeff_9287_1_1 ) ;
2010-04-15 17:39:04 -04:00
}
2013-01-13 19:54:58 +01:00
return 0 ;
2010-04-15 17:39:04 -04:00
}
2010-04-15 17:39:05 -04:00
static void ar9280_20_hw_init_rxgain_ini ( struct ath_hw * ah )
{
u32 rxgain_type ;
if ( ah - > eep_ops - > get_eeprom ( ah , EEP_MINOR_REV ) > =
AR5416_EEP_MINOR_VER_17 ) {
rxgain_type = ah - > eep_ops - > get_eeprom ( ah , EEP_RXGAIN_TYPE ) ;
if ( rxgain_type = = AR5416_EEP_RXGAIN_13DB_BACKOFF )
INIT_INI_ARRAY ( & ah - > iniModesRxGain ,
2012-07-15 19:53:33 +02:00
ar9280Modes_backoff_13db_rxgain_9280_2 ) ;
2010-04-15 17:39:05 -04:00
else if ( rxgain_type = = AR5416_EEP_RXGAIN_23DB_BACKOFF )
INIT_INI_ARRAY ( & ah - > iniModesRxGain ,
2012-07-15 19:53:33 +02:00
ar9280Modes_backoff_23db_rxgain_9280_2 ) ;
2010-04-15 17:39:05 -04:00
else
INIT_INI_ARRAY ( & ah - > iniModesRxGain ,
2012-07-15 19:53:33 +02:00
ar9280Modes_original_rxgain_9280_2 ) ;
2010-04-15 17:39:05 -04:00
} else {
INIT_INI_ARRAY ( & ah - > iniModesRxGain ,
2012-07-15 19:53:33 +02:00
ar9280Modes_original_rxgain_9280_2 ) ;
2010-04-15 17:39:05 -04:00
}
}
2012-03-14 16:40:32 +01:00
static void ar9280_20_hw_init_txgain_ini ( struct ath_hw * ah , u32 txgain_type )
2010-04-15 17:39:05 -04:00
{
if ( ah - > eep_ops - > get_eeprom ( ah , EEP_MINOR_REV ) > =
AR5416_EEP_MINOR_VER_19 ) {
if ( txgain_type = = AR5416_EEP_TXGAIN_HIGH_POWER )
INIT_INI_ARRAY ( & ah - > iniModesTxGain ,
2012-07-15 19:53:33 +02:00
ar9280Modes_high_power_tx_gain_9280_2 ) ;
2010-04-15 17:39:05 -04:00
else
INIT_INI_ARRAY ( & ah - > iniModesTxGain ,
2012-07-15 19:53:33 +02:00
ar9280Modes_original_tx_gain_9280_2 ) ;
2010-04-15 17:39:05 -04:00
} else {
INIT_INI_ARRAY ( & ah - > iniModesTxGain ,
2012-07-15 19:53:33 +02:00
ar9280Modes_original_tx_gain_9280_2 ) ;
2010-04-15 17:39:05 -04:00
}
}
2012-03-14 16:40:32 +01:00
static void ar9271_hw_init_txgain_ini ( struct ath_hw * ah , u32 txgain_type )
{
if ( txgain_type = = AR5416_EEP_TXGAIN_HIGH_POWER )
INIT_INI_ARRAY ( & ah - > iniModesTxGain ,
2012-07-15 19:53:33 +02:00
ar9271Modes_high_power_tx_gain_9271 ) ;
2012-03-14 16:40:32 +01:00
else
INIT_INI_ARRAY ( & ah - > iniModesTxGain ,
2012-07-15 19:53:33 +02:00
ar9271Modes_normal_power_tx_gain_9271 ) ;
2012-03-14 16:40:32 +01:00
}
2010-04-15 17:39:05 -04:00
static void ar9002_hw_init_mode_gain_regs ( struct ath_hw * ah )
{
2012-03-14 16:40:32 +01:00
u32 txgain_type = ah - > eep_ops - > get_eeprom ( ah , EEP_TXGAIN_TYPE ) ;
2010-04-15 17:39:05 -04:00
if ( AR_SREV_9287_11_OR_LATER ( ah ) )
INIT_INI_ARRAY ( & ah - > iniModesRxGain ,
2012-07-15 19:53:33 +02:00
ar9287Modes_rx_gain_9287_1_1 ) ;
2010-04-15 17:39:05 -04:00
else if ( AR_SREV_9280_20 ( ah ) )
ar9280_20_hw_init_rxgain_ini ( ah ) ;
2012-03-14 16:40:32 +01:00
if ( AR_SREV_9271 ( ah ) ) {
ar9271_hw_init_txgain_ini ( ah , txgain_type ) ;
} else if ( AR_SREV_9287_11_OR_LATER ( ah ) ) {
2010-04-15 17:39:05 -04:00
INIT_INI_ARRAY ( & ah - > iniModesTxGain ,
2012-07-15 19:53:33 +02:00
ar9287Modes_tx_gain_9287_1_1 ) ;
2010-04-15 17:39:05 -04:00
} else if ( AR_SREV_9280_20 ( ah ) ) {
2012-03-14 16:40:32 +01:00
ar9280_20_hw_init_txgain_ini ( ah , txgain_type ) ;
2010-04-15 17:39:05 -04:00
} else if ( AR_SREV_9285_12_OR_LATER ( ah ) ) {
/* txgain table */
if ( txgain_type = = AR5416_EEP_TXGAIN_HIGH_POWER ) {
if ( AR_SREV_9285E_20 ( ah ) ) {
INIT_INI_ARRAY ( & ah - > iniModesTxGain ,
2012-07-15 19:53:33 +02:00
ar9285Modes_XE2_0_high_power ) ;
2010-04-15 17:39:05 -04:00
} else {
INIT_INI_ARRAY ( & ah - > iniModesTxGain ,
2012-07-15 19:53:33 +02:00
ar9285Modes_high_power_tx_gain_9285_1_2 ) ;
2010-04-15 17:39:05 -04:00
}
} else {
if ( AR_SREV_9285E_20 ( ah ) ) {
INIT_INI_ARRAY ( & ah - > iniModesTxGain ,
2012-07-15 19:53:33 +02:00
ar9285Modes_XE2_0_normal_power ) ;
2010-04-15 17:39:05 -04:00
} else {
INIT_INI_ARRAY ( & ah - > iniModesTxGain ,
2012-07-15 19:53:33 +02:00
ar9285Modes_original_tx_gain_9285_1_2 ) ;
2010-04-15 17:39:05 -04:00
}
}
}
}
2010-04-15 17:39:03 -04:00
/*
* Helper for ASPM support .
*
* Disable PLL when in L0s as well as receiver clock when in L1 .
* This power saving option must be enabled through the SerDes .
*
* Programming the SerDes must go through the same 288 bit serial shift
* register as the other analog registers . Hence the 9 writes .
*/
static void ar9002_hw_configpcipowersave ( struct ath_hw * ah ,
2011-08-05 13:10:32 +02:00
bool power_off )
2010-04-15 17:39:03 -04:00
{
u8 i ;
u32 val ;
/* Nothing to do on restore for 11N */
2011-08-05 13:10:32 +02:00
if ( ! power_off /* !restore */ ) {
2010-04-15 17:39:03 -04:00
if ( AR_SREV_9280_20_OR_LATER ( ah ) ) {
/*
* AR9280 2.0 or later chips use SerDes values from the
* initvals . h initialized depending on chipset during
* __ath9k_hw_init ( )
*/
for ( i = 0 ; i < ah - > iniPcieSerdes . ia_rows ; i + + ) {
REG_WRITE ( ah , INI_RA ( & ah - > iniPcieSerdes , i , 0 ) ,
INI_RA ( & ah - > iniPcieSerdes , i , 1 ) ) ;
}
} else {
2010-04-23 10:28:11 +05:30
ENABLE_REGWRITE_BUFFER ( ah ) ;
2010-04-15 17:39:03 -04:00
REG_WRITE ( ah , AR_PCIE_SERDES , 0x9248fc00 ) ;
REG_WRITE ( ah , AR_PCIE_SERDES , 0x24924924 ) ;
/* RX shut off when elecidle is asserted */
REG_WRITE ( ah , AR_PCIE_SERDES , 0x28000039 ) ;
REG_WRITE ( ah , AR_PCIE_SERDES , 0x53160824 ) ;
REG_WRITE ( ah , AR_PCIE_SERDES , 0xe5980579 ) ;
/*
* Ignore ah - > ah_config . pcie_clock_req setting for
* pre - AR9280 11 n
*/
REG_WRITE ( ah , AR_PCIE_SERDES , 0x001defff ) ;
REG_WRITE ( ah , AR_PCIE_SERDES , 0x1aaabe40 ) ;
REG_WRITE ( ah , AR_PCIE_SERDES , 0xbe105554 ) ;
REG_WRITE ( ah , AR_PCIE_SERDES , 0x000e3007 ) ;
/* Load the new settings */
REG_WRITE ( ah , AR_PCIE_SERDES2 , 0x00000000 ) ;
2010-04-23 10:28:11 +05:30
REGWRITE_BUFFER_FLUSH ( ah ) ;
2010-04-15 17:39:03 -04:00
}
udelay ( 1000 ) ;
2010-06-01 15:14:09 +05:30
}
2010-04-15 17:39:03 -04:00
2010-06-01 15:14:09 +05:30
if ( power_off ) {
/* clear bit 19 to disable L1 */
REG_CLR_BIT ( ah , AR_PCIE_PM_CTRL , AR_PCIE_PM_CTRL_ENA ) ;
val = REG_READ ( ah , AR_WA ) ;
2010-04-15 17:39:03 -04:00
2010-06-01 15:14:09 +05:30
/*
* Set PCIe workaround bits
* In AR9280 and AR9285 , bit 14 in WA register ( disable L1 )
* should only be set when device enters D3 and be
* cleared when device comes back to D0 .
*/
if ( ah - > config . pcie_waen ) {
if ( ah - > config . pcie_waen & AR_WA_D3_L1_DISABLE )
val | = AR_WA_D3_L1_DISABLE ;
} else {
2013-08-25 16:30:40 +05:30
if ( AR_SREV_9285 ( ah ) | | AR_SREV_9271 ( ah ) | | AR_SREV_9287 ( ah ) ) {
if ( AR9285_WA_DEFAULT & AR_WA_D3_L1_DISABLE )
val | = AR_WA_D3_L1_DISABLE ;
} else if ( AR_SREV_9280 ( ah ) ) {
if ( AR9280_WA_DEFAULT & AR_WA_D3_L1_DISABLE )
val | = AR_WA_D3_L1_DISABLE ;
2010-06-01 15:14:09 +05:30
}
}
if ( AR_SREV_9280 ( ah ) | | AR_SREV_9285 ( ah ) | | AR_SREV_9287 ( ah ) ) {
/*
* Disable bit 6 and 7 before entering D3 to
* prevent system hang .
*/
val & = ~ ( AR_WA_BIT6 | AR_WA_BIT7 ) ;
}
2010-11-04 17:41:25 -07:00
if ( AR_SREV_9280 ( ah ) )
val | = AR_WA_BIT22 ;
2010-06-01 15:14:09 +05:30
if ( AR_SREV_9285E_20 ( ah ) )
val | = AR_WA_BIT23 ;
REG_WRITE ( ah , AR_WA , val ) ;
} else {
2010-04-15 17:39:03 -04:00
if ( ah - > config . pcie_waen ) {
val = ah - > config . pcie_waen ;
2013-08-25 16:30:40 +05:30
val & = ( ~ AR_WA_D3_L1_DISABLE ) ;
2010-04-15 17:39:03 -04:00
} else {
2013-08-25 16:30:40 +05:30
if ( AR_SREV_9285 ( ah ) | | AR_SREV_9271 ( ah ) | | AR_SREV_9287 ( ah ) ) {
2010-04-15 17:39:03 -04:00
val = AR9285_WA_DEFAULT ;
2013-08-25 16:30:40 +05:30
val & = ( ~ AR_WA_D3_L1_DISABLE ) ;
} else if ( AR_SREV_9280 ( ah ) ) {
2010-04-15 17:39:03 -04:00
/*
2010-06-01 15:14:09 +05:30
* For AR9280 chips , bit 22 of 0x4004
* needs to be set .
2010-04-15 17:39:03 -04:00
*/
val = AR9280_WA_DEFAULT ;
2013-08-25 16:30:40 +05:30
val & = ( ~ AR_WA_D3_L1_DISABLE ) ;
2010-06-01 15:14:09 +05:30
} else {
2010-04-15 17:39:03 -04:00
val = AR_WA_DEFAULT ;
2010-06-01 15:14:09 +05:30
}
}
/* WAR for ASPM system hang */
2011-01-27 18:39:37 +05:30
if ( AR_SREV_9285 ( ah ) | | AR_SREV_9287 ( ah ) )
2010-06-01 15:14:09 +05:30
val | = ( AR_WA_BIT6 | AR_WA_BIT7 ) ;
2010-04-15 17:39:03 -04:00
2010-06-01 15:14:09 +05:30
if ( AR_SREV_9285E_20 ( ah ) )
val | = AR_WA_BIT23 ;
2010-04-15 17:39:03 -04:00
REG_WRITE ( ah , AR_WA , val ) ;
2010-06-01 15:14:09 +05:30
/* set bit 19 to allow forcing of pcie core into L1 state */
REG_SET_BIT ( ah , AR_PCIE_PM_CTRL , AR_PCIE_PM_CTRL_ENA ) ;
2010-04-15 17:39:03 -04:00
}
}
2010-04-15 17:39:18 -04:00
static int ar9002_hw_get_radiorev ( struct ath_hw * ah )
{
u32 val ;
int i ;
2010-04-16 11:53:57 +05:30
ENABLE_REGWRITE_BUFFER ( ah ) ;
2010-04-15 17:39:18 -04:00
2010-04-16 11:53:57 +05:30
REG_WRITE ( ah , AR_PHY ( 0x36 ) , 0x00007058 ) ;
2010-04-15 17:39:18 -04:00
for ( i = 0 ; i < 8 ; i + + )
REG_WRITE ( ah , AR_PHY ( 0x20 ) , 0x00010000 ) ;
2010-04-16 11:53:57 +05:30
REGWRITE_BUFFER_FLUSH ( ah ) ;
2010-04-15 17:39:18 -04:00
val = ( REG_READ ( ah , AR_PHY ( 256 ) ) > > 24 ) & 0xff ;
val = ( ( val & 0xf0 ) > > 4 ) | ( ( val & 0x0f ) < < 4 ) ;
return ath9k_hw_reverse_bits ( val , 8 ) ;
}
int ar9002_hw_rf_claim ( struct ath_hw * ah )
{
u32 val ;
REG_WRITE ( ah , AR_PHY ( 0 ) , 0x00000007 ) ;
val = ar9002_hw_get_radiorev ( ah ) ;
switch ( val & AR_RADIO_SREV_MAJOR ) {
case 0 :
val = AR_RAD5133_SREV_MAJOR ;
break ;
case AR_RAD5133_SREV_MAJOR :
case AR_RAD5122_SREV_MAJOR :
case AR_RAD2133_SREV_MAJOR :
case AR_RAD2122_SREV_MAJOR :
break ;
default :
2010-12-02 19:12:36 -08:00
ath_err ( ath9k_hw_common ( ah ) ,
" Radio Chip Rev 0x%02X not supported \n " ,
val & AR_RADIO_SREV_MAJOR ) ;
2010-04-15 17:39:18 -04:00
return - EOPNOTSUPP ;
}
ah - > hw_version . analog5GhzRev = val ;
return 0 ;
}
2010-06-01 15:14:10 +05:30
void ar9002_hw_enable_async_fifo ( struct ath_hw * ah )
{
if ( AR_SREV_9287_13_OR_LATER ( ah ) ) {
REG_SET_BIT ( ah , AR_MAC_PCU_ASYNC_FIFO_REG3 ,
AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL ) ;
REG_SET_BIT ( ah , AR_PHY_MODE , AR_PHY_MODE_ASYNCFIFO ) ;
REG_CLR_BIT ( ah , AR_MAC_PCU_ASYNC_FIFO_REG3 ,
AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET ) ;
REG_SET_BIT ( ah , AR_MAC_PCU_ASYNC_FIFO_REG3 ,
AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET ) ;
}
}
2013-12-24 10:44:18 +05:30
static void ar9002_hw_init_hang_checks ( struct ath_hw * ah )
{
if ( AR_SREV_9100 ( ah ) | | AR_SREV_9160 ( ah ) ) {
ah - > config . hw_hang_checks | = HW_BB_RIFS_HANG ;
ah - > config . hw_hang_checks | = HW_BB_DFS_HANG ;
}
if ( AR_SREV_9280 ( ah ) )
ah - > config . hw_hang_checks | = HW_BB_RX_CLEAR_STUCK_HANG ;
if ( AR_SREV_5416 ( ah ) | | AR_SREV_9100 ( ah ) | | AR_SREV_9160 ( ah ) )
ah - > config . hw_hang_checks | = HW_MAC_HANG ;
}
2010-04-15 17:39:03 -04:00
/* Sets up the AR5008/AR9001/AR9002 hardware familiy callbacks */
2012-12-12 13:14:23 +01:00
int ar9002_hw_attach_ops ( struct ath_hw * ah )
2010-04-15 17:39:03 -04:00
{
struct ath_hw_private_ops * priv_ops = ath9k_hw_private_ops ( ah ) ;
struct ath_hw_ops * ops = ath9k_hw_ops ( ah ) ;
2012-12-12 13:14:23 +01:00
int ret ;
2010-04-15 17:39:03 -04:00
2013-01-13 19:54:58 +01:00
ret = ar9002_hw_init_mode_regs ( ah ) ;
if ( ret )
return ret ;
2010-04-15 17:39:05 -04:00
priv_ops - > init_mode_gain_regs = ar9002_hw_init_mode_gain_regs ;
2013-12-24 10:44:18 +05:30
priv_ops - > init_hang_checks = ar9002_hw_init_hang_checks ;
2010-04-15 17:39:03 -04:00
ops - > config_pci_powersave = ar9002_hw_configpcipowersave ;
2012-12-12 13:14:23 +01:00
ret = ar5008_hw_attach_phy_ops ( ah ) ;
if ( ret )
return ret ;
2010-09-22 12:34:52 +02:00
if ( AR_SREV_9280_20_OR_LATER ( ah ) )
2010-04-15 17:39:03 -04:00
ar9002_hw_attach_phy_ops ( ah ) ;
ar9002_hw_attach_calib_ops ( ah ) ;
ar9002_hw_attach_mac_ops ( ah ) ;
2012-12-12 13:14:23 +01:00
return 0 ;
2010-04-15 17:39:03 -04:00
}
2010-09-03 16:00:00 +05:30
void ar9002_hw_load_ani_reg ( struct ath_hw * ah , struct ath9k_channel * chan )
{
u32 modesIndex ;
int i ;
2013-10-11 23:30:53 +02:00
if ( IS_CHAN_5GHZ ( chan ) )
modesIndex = IS_CHAN_HT40 ( chan ) ? 2 : 1 ;
else
modesIndex = IS_CHAN_HT40 ( chan ) ? 3 : 4 ;
2010-09-03 16:00:00 +05:30
ENABLE_REGWRITE_BUFFER ( ah ) ;
for ( i = 0 ; i < ah - > iniModes_9271_ANI_reg . ia_rows ; i + + ) {
u32 reg = INI_RA ( & ah - > iniModes_9271_ANI_reg , i , 0 ) ;
u32 val = INI_RA ( & ah - > iniModes_9271_ANI_reg , i , modesIndex ) ;
u32 val_orig ;
if ( reg = = AR_PHY_CCK_DETECT ) {
val_orig = REG_READ ( ah , reg ) ;
val & = AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK ;
val_orig & = ~ AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK ;
REG_WRITE ( ah , reg , val | val_orig ) ;
} else
REG_WRITE ( ah , reg , val ) ;
}
REGWRITE_BUFFER_FLUSH ( ah ) ;
}