Merge branch 'master' into for-davem
Conflicts: drivers/net/wireless/ath/ath9k/phy.c drivers/net/wireless/iwlwifi/iwl-6000.c drivers/net/wireless/iwlwifi/iwl-debugfs.c
This commit is contained in:
commit
3b51cc996e
@ -210,90 +210,7 @@ config USB_NET_RNDIS_WLAN
|
||||
|
||||
If you choose to build a module, it'll be called rndis_wlan.
|
||||
|
||||
config RTL8180
|
||||
tristate "Realtek 8180/8185 PCI support"
|
||||
depends on MAC80211 && PCI && EXPERIMENTAL
|
||||
select EEPROM_93CX6
|
||||
---help---
|
||||
This is a driver for RTL8180 and RTL8185 based cards.
|
||||
These are PCI based chips found in cards such as:
|
||||
|
||||
(RTL8185 802.11g)
|
||||
A-Link WL54PC
|
||||
|
||||
(RTL8180 802.11b)
|
||||
Belkin F5D6020 v3
|
||||
Belkin F5D6020 v3
|
||||
Dlink DWL-610
|
||||
Dlink DWL-510
|
||||
Netgear MA521
|
||||
Level-One WPC-0101
|
||||
Acer Aspire 1357 LMi
|
||||
VCTnet PC-11B1
|
||||
Ovislink AirLive WL-1120PCM
|
||||
Mentor WL-PCI
|
||||
Linksys WPC11 v4
|
||||
TrendNET TEW-288PI
|
||||
D-Link DWL-520 Rev D
|
||||
Repotec RP-WP7126
|
||||
TP-Link TL-WN250/251
|
||||
Zonet ZEW1000
|
||||
Longshine LCS-8031-R
|
||||
HomeLine HLW-PCC200
|
||||
GigaFast WF721-AEX
|
||||
Planet WL-3553
|
||||
Encore ENLWI-PCI1-NT
|
||||
TrendNET TEW-266PC
|
||||
Gigabyte GN-WLMR101
|
||||
Siemens-fujitsu Amilo D1840W
|
||||
Edimax EW-7126
|
||||
PheeNet WL-11PCIR
|
||||
Tonze PC-2100T
|
||||
Planet WL-8303
|
||||
Dlink DWL-650 v M1
|
||||
Edimax EW-7106
|
||||
Q-Tec 770WC
|
||||
Topcom Skyr@cer 4011b
|
||||
Roper FreeLan 802.11b (edition 2004)
|
||||
Wistron Neweb Corp CB-200B
|
||||
Pentagram HorNET
|
||||
QTec 775WC
|
||||
TwinMOS Booming B Series
|
||||
Micronet SP906BB
|
||||
Sweex LC700010
|
||||
Surecom EP-9428
|
||||
Safecom SWLCR-1100
|
||||
|
||||
Thanks to Realtek for their support!
|
||||
|
||||
config RTL8187
|
||||
tristate "Realtek 8187 and 8187B USB support"
|
||||
depends on MAC80211 && USB
|
||||
select EEPROM_93CX6
|
||||
---help---
|
||||
This is a driver for RTL8187 and RTL8187B based cards.
|
||||
These are USB based chips found in devices such as:
|
||||
|
||||
Netgear WG111v2
|
||||
Level 1 WNC-0301USB
|
||||
Micronet SP907GK V5
|
||||
Encore ENUWI-G2
|
||||
Trendnet TEW-424UB
|
||||
ASUS P5B Deluxe/P5K Premium motherboards
|
||||
Toshiba Satellite Pro series of laptops
|
||||
Asus Wireless Link
|
||||
Linksys WUSB54GC-EU v2
|
||||
(v1 = rt73usb; v3 is rt2070-based,
|
||||
use staging/rt3070 or try rt2800usb)
|
||||
|
||||
Thanks to Realtek for their support!
|
||||
|
||||
# If possible, automatically enable LEDs for RTL8187.
|
||||
|
||||
config RTL8187_LEDS
|
||||
bool
|
||||
depends on RTL8187 && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = RTL8187)
|
||||
default y
|
||||
source "drivers/net/wireless/rtl818x/Kconfig"
|
||||
|
||||
config ADM8211
|
||||
tristate "ADMtek ADM8211 support"
|
||||
|
@ -71,9 +71,21 @@ struct ath_regulatory {
|
||||
struct reg_dmn_pair_mapping *regpair;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ath_ops - Register read/write operations
|
||||
*
|
||||
* @read: Register read
|
||||
* @write: Register write
|
||||
* @enable_write_buffer: Enable multiple register writes
|
||||
* @disable_write_buffer: Disable multiple register writes
|
||||
* @write_flush: Flush buffered register writes
|
||||
*/
|
||||
struct ath_ops {
|
||||
unsigned int (*read)(void *, u32 reg_offset);
|
||||
void (*write)(void *, u32 val, u32 reg_offset);
|
||||
void (*write)(void *, u32 val, u32 reg_offset);
|
||||
void (*enable_write_buffer)(void *);
|
||||
void (*disable_write_buffer)(void *);
|
||||
void (*write_flush) (void *);
|
||||
};
|
||||
|
||||
struct ath_common;
|
||||
|
@ -242,6 +242,8 @@ static int ath5k_set_key(struct ieee80211_hw *hw,
|
||||
struct ieee80211_key_conf *key);
|
||||
static int ath5k_get_stats(struct ieee80211_hw *hw,
|
||||
struct ieee80211_low_level_stats *stats);
|
||||
static int ath5k_get_survey(struct ieee80211_hw *hw,
|
||||
int idx, struct survey_info *survey);
|
||||
static u64 ath5k_get_tsf(struct ieee80211_hw *hw);
|
||||
static void ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf);
|
||||
static void ath5k_reset_tsf(struct ieee80211_hw *hw);
|
||||
@ -267,6 +269,7 @@ static const struct ieee80211_ops ath5k_hw_ops = {
|
||||
.configure_filter = ath5k_configure_filter,
|
||||
.set_key = ath5k_set_key,
|
||||
.get_stats = ath5k_get_stats,
|
||||
.get_survey = ath5k_get_survey,
|
||||
.conf_tx = NULL,
|
||||
.get_tsf = ath5k_get_tsf,
|
||||
.set_tsf = ath5k_set_tsf,
|
||||
@ -3292,6 +3295,22 @@ ath5k_get_stats(struct ieee80211_hw *hw,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath5k_get_survey(struct ieee80211_hw *hw, int idx,
|
||||
struct survey_info *survey)
|
||||
{
|
||||
struct ath5k_softc *sc = hw->priv;
|
||||
struct ieee80211_conf *conf = &hw->conf;
|
||||
|
||||
if (idx != 0)
|
||||
return -ENOENT;
|
||||
|
||||
survey->channel = conf->channel;
|
||||
survey->filled = SURVEY_INFO_NOISE_DBM;
|
||||
survey->noise = sc->ah->ah_noise_floor;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u64
|
||||
ath5k_get_tsf(struct ieee80211_hw *hw)
|
||||
{
|
||||
|
@ -496,6 +496,8 @@ void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter)
|
||||
* Beacon control *
|
||||
\****************/
|
||||
|
||||
#define ATH5K_MAX_TSF_READ 10
|
||||
|
||||
/**
|
||||
* ath5k_hw_get_tsf64 - Get the full 64bit TSF
|
||||
*
|
||||
@ -505,10 +507,35 @@ void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter)
|
||||
*/
|
||||
u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah)
|
||||
{
|
||||
u64 tsf = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
|
||||
u32 tsf_lower, tsf_upper1, tsf_upper2;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* While reading TSF upper and then lower part, the clock is still
|
||||
* counting (or jumping in case of IBSS merge) so we might get
|
||||
* inconsistent values. To avoid this, we read the upper part again
|
||||
* and check it has not been changed. We make the hypothesis that a
|
||||
* maximum of 3 changes can happens in a row (we use 10 as a safe
|
||||
* value).
|
||||
*
|
||||
* Impact on performance is pretty small, since in most cases, only
|
||||
* 3 register reads are needed.
|
||||
*/
|
||||
|
||||
tsf_upper1 = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
|
||||
for (i = 0; i < ATH5K_MAX_TSF_READ; i++) {
|
||||
tsf_lower = ath5k_hw_reg_read(ah, AR5K_TSF_L32);
|
||||
tsf_upper2 = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
|
||||
if (tsf_upper2 == tsf_upper1)
|
||||
break;
|
||||
tsf_upper1 = tsf_upper2;
|
||||
}
|
||||
|
||||
WARN_ON( i == ATH5K_MAX_TSF_READ );
|
||||
|
||||
ATH5K_TRACE(ah->ah_sc);
|
||||
|
||||
return ath5k_hw_reg_read(ah, AR5K_TSF_L32) | (tsf << 32);
|
||||
return (((u64)tsf_upper1 << 32) | tsf_lower);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -13,16 +13,26 @@ ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o
|
||||
|
||||
obj-$(CONFIG_ATH9K) += ath9k.o
|
||||
|
||||
ath9k_hw-y:= hw.o \
|
||||
ath9k_hw-y:= \
|
||||
ar9002_hw.o \
|
||||
ar9003_hw.o \
|
||||
hw.o \
|
||||
ar9003_phy.o \
|
||||
ar9002_phy.o \
|
||||
ar5008_phy.o \
|
||||
ar9002_calib.o \
|
||||
ar9003_calib.o \
|
||||
calib.o \
|
||||
eeprom.o \
|
||||
eeprom_def.o \
|
||||
eeprom_4k.o \
|
||||
eeprom_9287.o \
|
||||
calib.o \
|
||||
ani.o \
|
||||
phy.o \
|
||||
btcoex.o \
|
||||
mac.o \
|
||||
ar9002_mac.o \
|
||||
ar9003_mac.o \
|
||||
ar9003_eeprom.o
|
||||
|
||||
obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
#include "hw.h"
|
||||
#include "hw-ops.h"
|
||||
|
||||
static int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
@ -37,190 +38,6 @@ static int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool ath9k_hw_ani_control(struct ath_hw *ah,
|
||||
enum ath9k_ani_cmd cmd, int param)
|
||||
{
|
||||
struct ar5416AniState *aniState = ah->curani;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
|
||||
switch (cmd & ah->ani_function) {
|
||||
case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{
|
||||
u32 level = param;
|
||||
|
||||
if (level >= ARRAY_SIZE(ah->totalSizeDesired)) {
|
||||
ath_print(common, ATH_DBG_ANI,
|
||||
"level out of range (%u > %u)\n",
|
||||
level,
|
||||
(unsigned)ARRAY_SIZE(ah->totalSizeDesired));
|
||||
return false;
|
||||
}
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
|
||||
AR_PHY_DESIRED_SZ_TOT_DES,
|
||||
ah->totalSizeDesired[level]);
|
||||
REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
|
||||
AR_PHY_AGC_CTL1_COARSE_LOW,
|
||||
ah->coarse_low[level]);
|
||||
REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
|
||||
AR_PHY_AGC_CTL1_COARSE_HIGH,
|
||||
ah->coarse_high[level]);
|
||||
REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
|
||||
AR_PHY_FIND_SIG_FIRPWR,
|
||||
ah->firpwr[level]);
|
||||
|
||||
if (level > aniState->noiseImmunityLevel)
|
||||
ah->stats.ast_ani_niup++;
|
||||
else if (level < aniState->noiseImmunityLevel)
|
||||
ah->stats.ast_ani_nidown++;
|
||||
aniState->noiseImmunityLevel = level;
|
||||
break;
|
||||
}
|
||||
case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{
|
||||
const int m1ThreshLow[] = { 127, 50 };
|
||||
const int m2ThreshLow[] = { 127, 40 };
|
||||
const int m1Thresh[] = { 127, 0x4d };
|
||||
const int m2Thresh[] = { 127, 0x40 };
|
||||
const int m2CountThr[] = { 31, 16 };
|
||||
const int m2CountThrLow[] = { 63, 48 };
|
||||
u32 on = param ? 1 : 0;
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
|
||||
AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
|
||||
m1ThreshLow[on]);
|
||||
REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
|
||||
AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
|
||||
m2ThreshLow[on]);
|
||||
REG_RMW_FIELD(ah, AR_PHY_SFCORR,
|
||||
AR_PHY_SFCORR_M1_THRESH,
|
||||
m1Thresh[on]);
|
||||
REG_RMW_FIELD(ah, AR_PHY_SFCORR,
|
||||
AR_PHY_SFCORR_M2_THRESH,
|
||||
m2Thresh[on]);
|
||||
REG_RMW_FIELD(ah, AR_PHY_SFCORR,
|
||||
AR_PHY_SFCORR_M2COUNT_THR,
|
||||
m2CountThr[on]);
|
||||
REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
|
||||
AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
|
||||
m2CountThrLow[on]);
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
|
||||
AR_PHY_SFCORR_EXT_M1_THRESH_LOW,
|
||||
m1ThreshLow[on]);
|
||||
REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
|
||||
AR_PHY_SFCORR_EXT_M2_THRESH_LOW,
|
||||
m2ThreshLow[on]);
|
||||
REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
|
||||
AR_PHY_SFCORR_EXT_M1_THRESH,
|
||||
m1Thresh[on]);
|
||||
REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
|
||||
AR_PHY_SFCORR_EXT_M2_THRESH,
|
||||
m2Thresh[on]);
|
||||
|
||||
if (on)
|
||||
REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
|
||||
AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
|
||||
else
|
||||
REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW,
|
||||
AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
|
||||
|
||||
if (!on != aniState->ofdmWeakSigDetectOff) {
|
||||
if (on)
|
||||
ah->stats.ast_ani_ofdmon++;
|
||||
else
|
||||
ah->stats.ast_ani_ofdmoff++;
|
||||
aniState->ofdmWeakSigDetectOff = !on;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{
|
||||
const int weakSigThrCck[] = { 8, 6 };
|
||||
u32 high = param ? 1 : 0;
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT,
|
||||
AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK,
|
||||
weakSigThrCck[high]);
|
||||
if (high != aniState->cckWeakSigThreshold) {
|
||||
if (high)
|
||||
ah->stats.ast_ani_cckhigh++;
|
||||
else
|
||||
ah->stats.ast_ani_ccklow++;
|
||||
aniState->cckWeakSigThreshold = high;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ATH9K_ANI_FIRSTEP_LEVEL:{
|
||||
const int firstep[] = { 0, 4, 8 };
|
||||
u32 level = param;
|
||||
|
||||
if (level >= ARRAY_SIZE(firstep)) {
|
||||
ath_print(common, ATH_DBG_ANI,
|
||||
"level out of range (%u > %u)\n",
|
||||
level,
|
||||
(unsigned) ARRAY_SIZE(firstep));
|
||||
return false;
|
||||
}
|
||||
REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
|
||||
AR_PHY_FIND_SIG_FIRSTEP,
|
||||
firstep[level]);
|
||||
if (level > aniState->firstepLevel)
|
||||
ah->stats.ast_ani_stepup++;
|
||||
else if (level < aniState->firstepLevel)
|
||||
ah->stats.ast_ani_stepdown++;
|
||||
aniState->firstepLevel = level;
|
||||
break;
|
||||
}
|
||||
case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{
|
||||
const int cycpwrThr1[] =
|
||||
{ 2, 4, 6, 8, 10, 12, 14, 16 };
|
||||
u32 level = param;
|
||||
|
||||
if (level >= ARRAY_SIZE(cycpwrThr1)) {
|
||||
ath_print(common, ATH_DBG_ANI,
|
||||
"level out of range (%u > %u)\n",
|
||||
level,
|
||||
(unsigned) ARRAY_SIZE(cycpwrThr1));
|
||||
return false;
|
||||
}
|
||||
REG_RMW_FIELD(ah, AR_PHY_TIMING5,
|
||||
AR_PHY_TIMING5_CYCPWR_THR1,
|
||||
cycpwrThr1[level]);
|
||||
if (level > aniState->spurImmunityLevel)
|
||||
ah->stats.ast_ani_spurup++;
|
||||
else if (level < aniState->spurImmunityLevel)
|
||||
ah->stats.ast_ani_spurdown++;
|
||||
aniState->spurImmunityLevel = level;
|
||||
break;
|
||||
}
|
||||
case ATH9K_ANI_PRESENT:
|
||||
break;
|
||||
default:
|
||||
ath_print(common, ATH_DBG_ANI,
|
||||
"invalid cmd %u\n", cmd);
|
||||
return false;
|
||||
}
|
||||
|
||||
ath_print(common, ATH_DBG_ANI, "ANI parameters:\n");
|
||||
ath_print(common, ATH_DBG_ANI,
|
||||
"noiseImmunityLevel=%d, spurImmunityLevel=%d, "
|
||||
"ofdmWeakSigDetectOff=%d\n",
|
||||
aniState->noiseImmunityLevel,
|
||||
aniState->spurImmunityLevel,
|
||||
!aniState->ofdmWeakSigDetectOff);
|
||||
ath_print(common, ATH_DBG_ANI,
|
||||
"cckWeakSigThreshold=%d, "
|
||||
"firstepLevel=%d, listenTime=%d\n",
|
||||
aniState->cckWeakSigThreshold,
|
||||
aniState->firstepLevel,
|
||||
aniState->listenTime);
|
||||
ath_print(common, ATH_DBG_ANI,
|
||||
"cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
|
||||
aniState->cycleCount,
|
||||
aniState->ofdmPhyErrCount,
|
||||
aniState->cckPhyErrCount);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ath9k_hw_update_mibstats(struct ath_hw *ah,
|
||||
struct ath9k_mib_stats *stats)
|
||||
{
|
||||
@ -262,11 +79,17 @@ static void ath9k_ani_restart(struct ath_hw *ah)
|
||||
"Writing ofdmbase=%u cckbase=%u\n",
|
||||
aniState->ofdmPhyErrBase,
|
||||
aniState->cckPhyErrBase);
|
||||
|
||||
ENABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase);
|
||||
REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase);
|
||||
REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
|
||||
REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
|
||||
|
||||
aniState->ofdmPhyErrCount = 0;
|
||||
@ -540,8 +363,14 @@ void ath9k_ani_reset(struct ath_hw *ah)
|
||||
ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) &
|
||||
~ATH9K_RX_FILTER_PHYERR);
|
||||
ath9k_ani_restart(ah);
|
||||
|
||||
ENABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
|
||||
REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
}
|
||||
|
||||
void ath9k_hw_ani_monitor(struct ath_hw *ah,
|
||||
@ -639,6 +468,8 @@ void ath9k_enable_mib_counters(struct ath_hw *ah)
|
||||
|
||||
ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
|
||||
|
||||
ENABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
REG_WRITE(ah, AR_FILT_OFDM, 0);
|
||||
REG_WRITE(ah, AR_FILT_CCK, 0);
|
||||
REG_WRITE(ah, AR_MIBC,
|
||||
@ -646,6 +477,9 @@ void ath9k_enable_mib_counters(struct ath_hw *ah)
|
||||
& 0x0f);
|
||||
REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
|
||||
REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
}
|
||||
|
||||
/* Freeze the MIB counters, get the stats and then clear them */
|
||||
@ -809,8 +643,14 @@ void ath9k_hw_ani_init(struct ath_hw *ah)
|
||||
ath_print(common, ATH_DBG_ANI, "Setting cckErrBase = 0x%08x\n",
|
||||
ah->ani[0].cckPhyErrBase);
|
||||
|
||||
ENABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
REG_WRITE(ah, AR_PHY_ERR_1, ah->ani[0].ofdmPhyErrBase);
|
||||
REG_WRITE(ah, AR_PHY_ERR_2, ah->ani[0].cckPhyErrBase);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
ath9k_enable_mib_counters(ah);
|
||||
|
||||
ah->aniperiod = ATH9K_ANI_PERIOD;
|
||||
|
742
drivers/net/wireless/ath/ath9k/ar5008_initvals.h
Normal file
742
drivers/net/wireless/ath/ath9k/ar5008_initvals.h
Normal file
@ -0,0 +1,742 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2009 Atheros Communications Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef INITVALS_AR5008_H
|
||||
#define INITVALS_AR5008_H
|
||||
|
||||
static const u32 ar5416Modes[][6] = {
|
||||
{ 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
|
||||
{ 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
|
||||
{ 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
|
||||
{ 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 },
|
||||
{ 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
|
||||
{ 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf },
|
||||
{ 0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810 },
|
||||
{ 0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a, 0x0000320a },
|
||||
{ 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
|
||||
{ 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
|
||||
{ 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
|
||||
{ 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
|
||||
{ 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
|
||||
{ 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
|
||||
{ 0x00009844, 0x1372161e, 0x1372161e, 0x137216a0, 0x137216a0, 0x137216a0 },
|
||||
{ 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
|
||||
{ 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
|
||||
{ 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
|
||||
{ 0x00009850, 0x6c48b4e0, 0x6d48b4e0, 0x6d48b0de, 0x6c48b0de, 0x6c48b0de },
|
||||
{ 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e },
|
||||
{ 0x0000985c, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e, 0x31395d5e },
|
||||
{ 0x00009860, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18 },
|
||||
{ 0x00009864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
|
||||
{ 0x00009868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190 },
|
||||
{ 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 },
|
||||
{ 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 },
|
||||
{ 0x00009918, 0x000001b8, 0x00000370, 0x00000268, 0x00000134, 0x00000134 },
|
||||
{ 0x00009924, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b },
|
||||
{ 0x00009944, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020 },
|
||||
{ 0x00009960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 },
|
||||
{ 0x0000a960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 },
|
||||
{ 0x0000b960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 },
|
||||
{ 0x00009964, 0x00000000, 0x00000000, 0x00001120, 0x00001120, 0x00001120 },
|
||||
{ 0x000099bc, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00 },
|
||||
{ 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be },
|
||||
{ 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
|
||||
{ 0x000099c8, 0x6af6532c, 0x6af6532c, 0x6af6532c, 0x6af6532c, 0x6af6532c },
|
||||
{ 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
|
||||
{ 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
|
||||
{ 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
|
||||
{ 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
|
||||
{ 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 },
|
||||
{ 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 },
|
||||
{ 0x0000a20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 },
|
||||
{ 0x0000b20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 },
|
||||
{ 0x0000c20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 },
|
||||
{ 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
|
||||
{ 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
|
||||
{ 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa },
|
||||
{ 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 },
|
||||
{ 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 },
|
||||
{ 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 },
|
||||
{ 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b },
|
||||
{ 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b },
|
||||
{ 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a },
|
||||
{ 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf },
|
||||
{ 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f },
|
||||
{ 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f },
|
||||
{ 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f },
|
||||
{ 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 },
|
||||
{ 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
|
||||
{ 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
|
||||
{ 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
|
||||
};
|
||||
|
||||
static const u32 ar5416Common[][2] = {
|
||||
{ 0x0000000c, 0x00000000 },
|
||||
{ 0x00000030, 0x00020015 },
|
||||
{ 0x00000034, 0x00000005 },
|
||||
{ 0x00000040, 0x00000000 },
|
||||
{ 0x00000044, 0x00000008 },
|
||||
{ 0x00000048, 0x00000008 },
|
||||
{ 0x0000004c, 0x00000010 },
|
||||
{ 0x00000050, 0x00000000 },
|
||||
{ 0x00000054, 0x0000001f },
|
||||
{ 0x00000800, 0x00000000 },
|
||||
{ 0x00000804, 0x00000000 },
|
||||
{ 0x00000808, 0x00000000 },
|
||||
{ 0x0000080c, 0x00000000 },
|
||||
{ 0x00000810, 0x00000000 },
|
||||
{ 0x00000814, 0x00000000 },
|
||||
{ 0x00000818, 0x00000000 },
|
||||
{ 0x0000081c, 0x00000000 },
|
||||
{ 0x00000820, 0x00000000 },
|
||||
{ 0x00000824, 0x00000000 },
|
||||
{ 0x00001040, 0x002ffc0f },
|
||||
{ 0x00001044, 0x002ffc0f },
|
||||
{ 0x00001048, 0x002ffc0f },
|
||||
{ 0x0000104c, 0x002ffc0f },
|
||||
{ 0x00001050, 0x002ffc0f },
|
||||
{ 0x00001054, 0x002ffc0f },
|
||||
{ 0x00001058, 0x002ffc0f },
|
||||
{ 0x0000105c, 0x002ffc0f },
|
||||
{ 0x00001060, 0x002ffc0f },
|
||||
{ 0x00001064, 0x002ffc0f },
|
||||
{ 0x00001230, 0x00000000 },
|
||||
{ 0x00001270, 0x00000000 },
|
||||
{ 0x00001038, 0x00000000 },
|
||||
{ 0x00001078, 0x00000000 },
|
||||
{ 0x000010b8, 0x00000000 },
|
||||
{ 0x000010f8, 0x00000000 },
|
||||
{ 0x00001138, 0x00000000 },
|
||||
{ 0x00001178, 0x00000000 },
|
||||
{ 0x000011b8, 0x00000000 },
|
||||
{ 0x000011f8, 0x00000000 },
|
||||
{ 0x00001238, 0x00000000 },
|
||||
{ 0x00001278, 0x00000000 },
|
||||
{ 0x000012b8, 0x00000000 },
|
||||
{ 0x000012f8, 0x00000000 },
|
||||
{ 0x00001338, 0x00000000 },
|
||||
{ 0x00001378, 0x00000000 },
|
||||
{ 0x000013b8, 0x00000000 },
|
||||
{ 0x000013f8, 0x00000000 },
|
||||
{ 0x00001438, 0x00000000 },
|
||||
{ 0x00001478, 0x00000000 },
|
||||
{ 0x000014b8, 0x00000000 },
|
||||
{ 0x000014f8, 0x00000000 },
|
||||
{ 0x00001538, 0x00000000 },
|
||||
{ 0x00001578, 0x00000000 },
|
||||
{ 0x000015b8, 0x00000000 },
|
||||
{ 0x000015f8, 0x00000000 },
|
||||
{ 0x00001638, 0x00000000 },
|
||||
{ 0x00001678, 0x00000000 },
|
||||
{ 0x000016b8, 0x00000000 },
|
||||
{ 0x000016f8, 0x00000000 },
|
||||
{ 0x00001738, 0x00000000 },
|
||||
{ 0x00001778, 0x00000000 },
|
||||
{ 0x000017b8, 0x00000000 },
|
||||
{ 0x000017f8, 0x00000000 },
|
||||
{ 0x0000103c, 0x00000000 },
|
||||
{ 0x0000107c, 0x00000000 },
|
||||
{ 0x000010bc, 0x00000000 },
|
||||
{ 0x000010fc, 0x00000000 },
|
||||
{ 0x0000113c, 0x00000000 },
|
||||
{ 0x0000117c, 0x00000000 },
|
||||
{ 0x000011bc, 0x00000000 },
|
||||
{ 0x000011fc, 0x00000000 },
|
||||
{ 0x0000123c, 0x00000000 },
|
||||
{ 0x0000127c, 0x00000000 },
|
||||
{ 0x000012bc, 0x00000000 },
|
||||
{ 0x000012fc, 0x00000000 },
|
||||
{ 0x0000133c, 0x00000000 },
|
||||
{ 0x0000137c, 0x00000000 },
|
||||
{ 0x000013bc, 0x00000000 },
|
||||
{ 0x000013fc, 0x00000000 },
|
||||
{ 0x0000143c, 0x00000000 },
|
||||
{ 0x0000147c, 0x00000000 },
|
||||
{ 0x00004030, 0x00000002 },
|
||||
{ 0x0000403c, 0x00000002 },
|
||||
{ 0x00007010, 0x00000000 },
|
||||
{ 0x00007038, 0x000004c2 },
|
||||
{ 0x00008004, 0x00000000 },
|
||||
{ 0x00008008, 0x00000000 },
|
||||
{ 0x0000800c, 0x00000000 },
|
||||
{ 0x00008018, 0x00000700 },
|
||||
{ 0x00008020, 0x00000000 },
|
||||
{ 0x00008038, 0x00000000 },
|
||||
{ 0x0000803c, 0x00000000 },
|
||||
{ 0x00008048, 0x40000000 },
|
||||
{ 0x00008054, 0x00000000 },
|
||||
{ 0x00008058, 0x00000000 },
|
||||
{ 0x0000805c, 0x000fc78f },
|
||||
{ 0x00008060, 0x0000000f },
|
||||
{ 0x00008064, 0x00000000 },
|
||||
{ 0x000080c0, 0x2a82301a },
|
||||
{ 0x000080c4, 0x05dc01e0 },
|
||||
{ 0x000080c8, 0x1f402710 },
|
||||
{ 0x000080cc, 0x01f40000 },
|
||||
{ 0x000080d0, 0x00001e00 },
|
||||
{ 0x000080d4, 0x00000000 },
|
||||
{ 0x000080d8, 0x00400000 },
|
||||
{ 0x000080e0, 0xffffffff },
|
||||
{ 0x000080e4, 0x0000ffff },
|
||||
{ 0x000080e8, 0x003f3f3f },
|
||||
{ 0x000080ec, 0x00000000 },
|
||||
{ 0x000080f0, 0x00000000 },
|
||||
{ 0x000080f4, 0x00000000 },
|
||||
{ 0x000080f8, 0x00000000 },
|
||||
{ 0x000080fc, 0x00020000 },
|
||||
{ 0x00008100, 0x00020000 },
|
||||
{ 0x00008104, 0x00000001 },
|
||||
{ 0x00008108, 0x00000052 },
|
||||
{ 0x0000810c, 0x00000000 },
|
||||
{ 0x00008110, 0x00000168 },
|
||||
{ 0x00008118, 0x000100aa },
|
||||
{ 0x0000811c, 0x00003210 },
|
||||
{ 0x00008124, 0x00000000 },
|
||||
{ 0x00008128, 0x00000000 },
|
||||
{ 0x0000812c, 0x00000000 },
|
||||
{ 0x00008130, 0x00000000 },
|
||||
{ 0x00008134, 0x00000000 },
|
||||
{ 0x00008138, 0x00000000 },
|
||||
{ 0x0000813c, 0x00000000 },
|
||||
{ 0x00008144, 0xffffffff },
|
||||
{ 0x00008168, 0x00000000 },
|
||||
{ 0x0000816c, 0x00000000 },
|
||||
{ 0x00008170, 0x32143320 },
|
||||
{ 0x00008174, 0xfaa4fa50 },
|
||||
{ 0x00008178, 0x00000100 },
|
||||
{ 0x0000817c, 0x00000000 },
|
||||
{ 0x000081c4, 0x00000000 },
|
||||
{ 0x000081ec, 0x00000000 },
|
||||
{ 0x000081f0, 0x00000000 },
|
||||
{ 0x000081f4, 0x00000000 },
|
||||
{ 0x000081f8, 0x00000000 },
|
||||
{ 0x000081fc, 0x00000000 },
|
||||
{ 0x00008200, 0x00000000 },
|
||||
{ 0x00008204, 0x00000000 },
|
||||
{ 0x00008208, 0x00000000 },
|
||||
{ 0x0000820c, 0x00000000 },
|
||||
{ 0x00008210, 0x00000000 },
|
||||
{ 0x00008214, 0x00000000 },
|
||||
{ 0x00008218, 0x00000000 },
|
||||
{ 0x0000821c, 0x00000000 },
|
||||
{ 0x00008220, 0x00000000 },
|
||||
{ 0x00008224, 0x00000000 },
|
||||
{ 0x00008228, 0x00000000 },
|
||||
{ 0x0000822c, 0x00000000 },
|
||||
{ 0x00008230, 0x00000000 },
|
||||
{ 0x00008234, 0x00000000 },
|
||||
{ 0x00008238, 0x00000000 },
|
||||
{ 0x0000823c, 0x00000000 },
|
||||
{ 0x00008240, 0x00100000 },
|
||||
{ 0x00008244, 0x0010f400 },
|
||||
{ 0x00008248, 0x00000100 },
|
||||
{ 0x0000824c, 0x0001e800 },
|
||||
{ 0x00008250, 0x00000000 },
|
||||
{ 0x00008254, 0x00000000 },
|
||||
{ 0x00008258, 0x00000000 },
|
||||
{ 0x0000825c, 0x400000ff },
|
||||
{ 0x00008260, 0x00080922 },
|
||||
{ 0x00008264, 0xa8000010 },
|
||||
{ 0x00008270, 0x00000000 },
|
||||
{ 0x00008274, 0x40000000 },
|
||||
{ 0x00008278, 0x003e4180 },
|
||||
{ 0x0000827c, 0x00000000 },
|
||||
{ 0x00008284, 0x0000002c },
|
||||
{ 0x00008288, 0x0000002c },
|
||||
{ 0x0000828c, 0x00000000 },
|
||||
{ 0x00008294, 0x00000000 },
|
||||
{ 0x00008298, 0x00000000 },
|
||||
{ 0x00008300, 0x00000000 },
|
||||
{ 0x00008304, 0x00000000 },
|
||||
{ 0x00008308, 0x00000000 },
|
||||
{ 0x0000830c, 0x00000000 },
|
||||
{ 0x00008310, 0x00000000 },
|
||||
{ 0x00008314, 0x00000000 },
|
||||
{ 0x00008318, 0x00000000 },
|
||||
{ 0x00008328, 0x00000000 },
|
||||
{ 0x0000832c, 0x00000007 },
|
||||
{ 0x00008330, 0x00000302 },
|
||||
{ 0x00008334, 0x00000e00 },
|
||||
{ 0x00008338, 0x00070000 },
|
||||
{ 0x0000833c, 0x00000000 },
|
||||
{ 0x00008340, 0x000107ff },
|
||||
{ 0x00009808, 0x00000000 },
|
||||
{ 0x0000980c, 0xad848e19 },
|
||||
{ 0x00009810, 0x7d14e000 },
|
||||
{ 0x00009814, 0x9c0a9f6b },
|
||||
{ 0x0000981c, 0x00000000 },
|
||||
{ 0x0000982c, 0x0000a000 },
|
||||
{ 0x00009830, 0x00000000 },
|
||||
{ 0x0000983c, 0x00200400 },
|
||||
{ 0x00009840, 0x206a002e },
|
||||
{ 0x0000984c, 0x1284233c },
|
||||
{ 0x00009854, 0x00000859 },
|
||||
{ 0x00009900, 0x00000000 },
|
||||
{ 0x00009904, 0x00000000 },
|
||||
{ 0x00009908, 0x00000000 },
|
||||
{ 0x0000990c, 0x00000000 },
|
||||
{ 0x0000991c, 0x10000fff },
|
||||
{ 0x00009920, 0x05100000 },
|
||||
{ 0x0000a920, 0x05100000 },
|
||||
{ 0x0000b920, 0x05100000 },
|
||||
{ 0x00009928, 0x00000001 },
|
||||
{ 0x0000992c, 0x00000004 },
|
||||
{ 0x00009934, 0x1e1f2022 },
|
||||
{ 0x00009938, 0x0a0b0c0d },
|
||||
{ 0x0000993c, 0x00000000 },
|
||||
{ 0x00009948, 0x9280b212 },
|
||||
{ 0x0000994c, 0x00020028 },
|
||||
{ 0x00009954, 0x5d50e188 },
|
||||
{ 0x00009958, 0x00081fff },
|
||||
{ 0x0000c95c, 0x004b6a8e },
|
||||
{ 0x0000c968, 0x000003ce },
|
||||
{ 0x00009970, 0x190fb515 },
|
||||
{ 0x00009974, 0x00000000 },
|
||||
{ 0x00009978, 0x00000001 },
|
||||
{ 0x0000997c, 0x00000000 },
|
||||
{ 0x00009980, 0x00000000 },
|
||||
{ 0x00009984, 0x00000000 },
|
||||
{ 0x00009988, 0x00000000 },
|
||||
{ 0x0000998c, 0x00000000 },
|
||||
{ 0x00009990, 0x00000000 },
|
||||
{ 0x00009994, 0x00000000 },
|
||||
{ 0x00009998, 0x00000000 },
|
||||
{ 0x0000999c, 0x00000000 },
|
||||
{ 0x000099a0, 0x00000000 },
|
||||
{ 0x000099a4, 0x00000001 },
|
||||
{ 0x000099a8, 0x001fff00 },
|
||||
{ 0x000099ac, 0x00000000 },
|
||||
{ 0x000099b0, 0x03051000 },
|
||||
{ 0x000099dc, 0x00000000 },
|
||||
{ 0x000099e0, 0x00000200 },
|
||||
{ 0x000099e4, 0xaaaaaaaa },
|
||||
{ 0x000099e8, 0x3c466478 },
|
||||
{ 0x000099ec, 0x000000aa },
|
||||
{ 0x000099fc, 0x00001042 },
|
||||
{ 0x00009b00, 0x00000000 },
|
||||
{ 0x00009b04, 0x00000001 },
|
||||
{ 0x00009b08, 0x00000002 },
|
||||
{ 0x00009b0c, 0x00000003 },
|
||||
{ 0x00009b10, 0x00000004 },
|
||||
{ 0x00009b14, 0x00000005 },
|
||||
{ 0x00009b18, 0x00000008 },
|
||||
{ 0x00009b1c, 0x00000009 },
|
||||
{ 0x00009b20, 0x0000000a },
|
||||
{ 0x00009b24, 0x0000000b },
|
||||
{ 0x00009b28, 0x0000000c },
|
||||
{ 0x00009b2c, 0x0000000d },
|
||||
{ 0x00009b30, 0x00000010 },
|
||||
{ 0x00009b34, 0x00000011 },
|
||||
{ 0x00009b38, 0x00000012 },
|
||||
{ 0x00009b3c, 0x00000013 },
|
||||
{ 0x00009b40, 0x00000014 },
|
||||
{ 0x00009b44, 0x00000015 },
|
||||
{ 0x00009b48, 0x00000018 },
|
||||
{ 0x00009b4c, 0x00000019 },
|
||||
{ 0x00009b50, 0x0000001a },
|
||||
{ 0x00009b54, 0x0000001b },
|
||||
{ 0x00009b58, 0x0000001c },
|
||||
{ 0x00009b5c, 0x0000001d },
|
||||
{ 0x00009b60, 0x00000020 },
|
||||
{ 0x00009b64, 0x00000021 },
|
||||
{ 0x00009b68, 0x00000022 },
|
||||
{ 0x00009b6c, 0x00000023 },
|
||||
{ 0x00009b70, 0x00000024 },
|
||||
{ 0x00009b74, 0x00000025 },
|
||||
{ 0x00009b78, 0x00000028 },
|
||||
{ 0x00009b7c, 0x00000029 },
|
||||
{ 0x00009b80, 0x0000002a },
|
||||
{ 0x00009b84, 0x0000002b },
|
||||
{ 0x00009b88, 0x0000002c },
|
||||
{ 0x00009b8c, 0x0000002d },
|
||||
{ 0x00009b90, 0x00000030 },
|
||||
{ 0x00009b94, 0x00000031 },
|
||||
{ 0x00009b98, 0x00000032 },
|
||||
{ 0x00009b9c, 0x00000033 },
|
||||
{ 0x00009ba0, 0x00000034 },
|
||||
{ 0x00009ba4, 0x00000035 },
|
||||
{ 0x00009ba8, 0x00000035 },
|
||||
{ 0x00009bac, 0x00000035 },
|
||||
{ 0x00009bb0, 0x00000035 },
|
||||
{ 0x00009bb4, 0x00000035 },
|
||||
{ 0x00009bb8, 0x00000035 },
|
||||
{ 0x00009bbc, 0x00000035 },
|
||||
{ 0x00009bc0, 0x00000035 },
|
||||
{ 0x00009bc4, 0x00000035 },
|
||||
{ 0x00009bc8, 0x00000035 },
|
||||
{ 0x00009bcc, 0x00000035 },
|
||||
{ 0x00009bd0, 0x00000035 },
|
||||
{ 0x00009bd4, 0x00000035 },
|
||||
{ 0x00009bd8, 0x00000035 },
|
||||
{ 0x00009bdc, 0x00000035 },
|
||||
{ 0x00009be0, 0x00000035 },
|
||||
{ 0x00009be4, 0x00000035 },
|
||||
{ 0x00009be8, 0x00000035 },
|
||||
{ 0x00009bec, 0x00000035 },
|
||||
{ 0x00009bf0, 0x00000035 },
|
||||
{ 0x00009bf4, 0x00000035 },
|
||||
{ 0x00009bf8, 0x00000010 },
|
||||
{ 0x00009bfc, 0x0000001a },
|
||||
{ 0x0000a210, 0x40806333 },
|
||||
{ 0x0000a214, 0x00106c10 },
|
||||
{ 0x0000a218, 0x009c4060 },
|
||||
{ 0x0000a220, 0x018830c6 },
|
||||
{ 0x0000a224, 0x00000400 },
|
||||
{ 0x0000a228, 0x00000bb5 },
|
||||
{ 0x0000a22c, 0x00000011 },
|
||||
{ 0x0000a234, 0x20202020 },
|
||||
{ 0x0000a238, 0x20202020 },
|
||||
{ 0x0000a23c, 0x13c889af },
|
||||
{ 0x0000a240, 0x38490a20 },
|
||||
{ 0x0000a244, 0x00007bb6 },
|
||||
{ 0x0000a248, 0x0fff3ffc },
|
||||
{ 0x0000a24c, 0x00000001 },
|
||||
{ 0x0000a250, 0x0000a000 },
|
||||
{ 0x0000a254, 0x00000000 },
|
||||
{ 0x0000a258, 0x0cc75380 },
|
||||
{ 0x0000a25c, 0x0f0f0f01 },
|
||||
{ 0x0000a260, 0xdfa91f01 },
|
||||
{ 0x0000a268, 0x00000000 },
|
||||
{ 0x0000a26c, 0x0e79e5c6 },
|
||||
{ 0x0000b26c, 0x0e79e5c6 },
|
||||
{ 0x0000c26c, 0x0e79e5c6 },
|
||||
{ 0x0000d270, 0x00820820 },
|
||||
{ 0x0000a278, 0x1ce739ce },
|
||||
{ 0x0000a27c, 0x051701ce },
|
||||
{ 0x0000a338, 0x00000000 },
|
||||
{ 0x0000a33c, 0x00000000 },
|
||||
{ 0x0000a340, 0x00000000 },
|
||||
{ 0x0000a344, 0x00000000 },
|
||||
{ 0x0000a348, 0x3fffffff },
|
||||
{ 0x0000a34c, 0x3fffffff },
|
||||
{ 0x0000a350, 0x3fffffff },
|
||||
{ 0x0000a354, 0x0003ffff },
|
||||
{ 0x0000a358, 0x79a8aa1f },
|
||||
{ 0x0000d35c, 0x07ffffef },
|
||||
{ 0x0000d360, 0x0fffffe7 },
|
||||
{ 0x0000d364, 0x17ffffe5 },
|
||||
{ 0x0000d368, 0x1fffffe4 },
|
||||
{ 0x0000d36c, 0x37ffffe3 },
|
||||
{ 0x0000d370, 0x3fffffe3 },
|
||||
{ 0x0000d374, 0x57ffffe3 },
|
||||
{ 0x0000d378, 0x5fffffe2 },
|
||||
{ 0x0000d37c, 0x7fffffe2 },
|
||||
{ 0x0000d380, 0x7f3c7bba },
|
||||
{ 0x0000d384, 0xf3307ff0 },
|
||||
{ 0x0000a388, 0x08000000 },
|
||||
{ 0x0000a38c, 0x20202020 },
|
||||
{ 0x0000a390, 0x20202020 },
|
||||
{ 0x0000a394, 0x1ce739ce },
|
||||
{ 0x0000a398, 0x000001ce },
|
||||
{ 0x0000a39c, 0x00000001 },
|
||||
{ 0x0000a3a0, 0x00000000 },
|
||||
{ 0x0000a3a4, 0x00000000 },
|
||||
{ 0x0000a3a8, 0x00000000 },
|
||||
{ 0x0000a3ac, 0x00000000 },
|
||||
{ 0x0000a3b0, 0x00000000 },
|
||||
{ 0x0000a3b4, 0x00000000 },
|
||||
{ 0x0000a3b8, 0x00000000 },
|
||||
{ 0x0000a3bc, 0x00000000 },
|
||||
{ 0x0000a3c0, 0x00000000 },
|
||||
{ 0x0000a3c4, 0x00000000 },
|
||||
{ 0x0000a3c8, 0x00000246 },
|
||||
{ 0x0000a3cc, 0x20202020 },
|
||||
{ 0x0000a3d0, 0x20202020 },
|
||||
{ 0x0000a3d4, 0x20202020 },
|
||||
{ 0x0000a3dc, 0x1ce739ce },
|
||||
{ 0x0000a3e0, 0x000001ce },
|
||||
};
|
||||
|
||||
static const u32 ar5416Bank0[][2] = {
|
||||
{ 0x000098b0, 0x1e5795e5 },
|
||||
{ 0x000098e0, 0x02008020 },
|
||||
};
|
||||
|
||||
static const u32 ar5416BB_RfGain[][3] = {
|
||||
{ 0x00009a00, 0x00000000, 0x00000000 },
|
||||
{ 0x00009a04, 0x00000040, 0x00000040 },
|
||||
{ 0x00009a08, 0x00000080, 0x00000080 },
|
||||
{ 0x00009a0c, 0x000001a1, 0x00000141 },
|
||||
{ 0x00009a10, 0x000001e1, 0x00000181 },
|
||||
{ 0x00009a14, 0x00000021, 0x000001c1 },
|
||||
{ 0x00009a18, 0x00000061, 0x00000001 },
|
||||
{ 0x00009a1c, 0x00000168, 0x00000041 },
|
||||
{ 0x00009a20, 0x000001a8, 0x000001a8 },
|
||||
{ 0x00009a24, 0x000001e8, 0x000001e8 },
|
||||
{ 0x00009a28, 0x00000028, 0x00000028 },
|
||||
{ 0x00009a2c, 0x00000068, 0x00000068 },
|
||||
{ 0x00009a30, 0x00000189, 0x000000a8 },
|
||||
{ 0x00009a34, 0x000001c9, 0x00000169 },
|
||||
{ 0x00009a38, 0x00000009, 0x000001a9 },
|
||||
{ 0x00009a3c, 0x00000049, 0x000001e9 },
|
||||
{ 0x00009a40, 0x00000089, 0x00000029 },
|
||||
{ 0x00009a44, 0x00000170, 0x00000069 },
|
||||
{ 0x00009a48, 0x000001b0, 0x00000190 },
|
||||
{ 0x00009a4c, 0x000001f0, 0x000001d0 },
|
||||
{ 0x00009a50, 0x00000030, 0x00000010 },
|
||||
{ 0x00009a54, 0x00000070, 0x00000050 },
|
||||
{ 0x00009a58, 0x00000191, 0x00000090 },
|
||||
{ 0x00009a5c, 0x000001d1, 0x00000151 },
|
||||
{ 0x00009a60, 0x00000011, 0x00000191 },
|
||||
{ 0x00009a64, 0x00000051, 0x000001d1 },
|
||||
{ 0x00009a68, 0x00000091, 0x00000011 },
|
||||
{ 0x00009a6c, 0x000001b8, 0x00000051 },
|
||||
{ 0x00009a70, 0x000001f8, 0x00000198 },
|
||||
{ 0x00009a74, 0x00000038, 0x000001d8 },
|
||||
{ 0x00009a78, 0x00000078, 0x00000018 },
|
||||
{ 0x00009a7c, 0x00000199, 0x00000058 },
|
||||
{ 0x00009a80, 0x000001d9, 0x00000098 },
|
||||
{ 0x00009a84, 0x00000019, 0x00000159 },
|
||||
{ 0x00009a88, 0x00000059, 0x00000199 },
|
||||
{ 0x00009a8c, 0x00000099, 0x000001d9 },
|
||||
{ 0x00009a90, 0x000000d9, 0x00000019 },
|
||||
{ 0x00009a94, 0x000000f9, 0x00000059 },
|
||||
{ 0x00009a98, 0x000000f9, 0x00000099 },
|
||||
{ 0x00009a9c, 0x000000f9, 0x000000d9 },
|
||||
{ 0x00009aa0, 0x000000f9, 0x000000f9 },
|
||||
{ 0x00009aa4, 0x000000f9, 0x000000f9 },
|
||||
{ 0x00009aa8, 0x000000f9, 0x000000f9 },
|
||||
{ 0x00009aac, 0x000000f9, 0x000000f9 },
|
||||
{ 0x00009ab0, 0x000000f9, 0x000000f9 },
|
||||
{ 0x00009ab4, 0x000000f9, 0x000000f9 },
|
||||
{ 0x00009ab8, 0x000000f9, 0x000000f9 },
|
||||
{ 0x00009abc, 0x000000f9, 0x000000f9 },
|
||||
{ 0x00009ac0, 0x000000f9, 0x000000f9 },
|
||||
{ 0x00009ac4, 0x000000f9, 0x000000f9 },
|
||||
{ 0x00009ac8, 0x000000f9, 0x000000f9 },
|
||||
{ 0x00009acc, 0x000000f9, 0x000000f9 },
|
||||
{ 0x00009ad0, 0x000000f9, 0x000000f9 },
|
||||
{ 0x00009ad4, 0x000000f9, 0x000000f9 },
|
||||
{ 0x00009ad8, 0x000000f9, 0x000000f9 },
|
||||
{ 0x00009adc, 0x000000f9, 0x000000f9 },
|
||||
{ 0x00009ae0, 0x000000f9, 0x000000f9 },
|
||||
{ 0x00009ae4, 0x000000f9, 0x000000f9 },
|
||||
{ 0x00009ae8, 0x000000f9, 0x000000f9 },
|
||||
{ 0x00009aec, 0x000000f9, 0x000000f9 },
|
||||
{ 0x00009af0, 0x000000f9, 0x000000f9 },
|
||||
{ 0x00009af4, 0x000000f9, 0x000000f9 },
|
||||
{ 0x00009af8, 0x000000f9, 0x000000f9 },
|
||||
{ 0x00009afc, 0x000000f9, 0x000000f9 },
|
||||
};
|
||||
|
||||
static const u32 ar5416Bank1[][2] = {
|
||||
{ 0x000098b0, 0x02108421 },
|
||||
{ 0x000098ec, 0x00000008 },
|
||||
};
|
||||
|
||||
static const u32 ar5416Bank2[][2] = {
|
||||
{ 0x000098b0, 0x0e73ff17 },
|
||||
{ 0x000098e0, 0x00000420 },
|
||||
};
|
||||
|
||||
static const u32 ar5416Bank3[][3] = {
|
||||
{ 0x000098f0, 0x01400018, 0x01c00018 },
|
||||
};
|
||||
|
||||
static const u32 ar5416Bank6[][3] = {
|
||||
|
||||
{ 0x0000989c, 0x00000000, 0x00000000 },
|
||||
{ 0x0000989c, 0x00000000, 0x00000000 },
|
||||
{ 0x0000989c, 0x00000000, 0x00000000 },
|
||||
{ 0x0000989c, 0x00e00000, 0x00e00000 },
|
||||
{ 0x0000989c, 0x005e0000, 0x005e0000 },
|
||||
{ 0x0000989c, 0x00120000, 0x00120000 },
|
||||
{ 0x0000989c, 0x00620000, 0x00620000 },
|
||||
{ 0x0000989c, 0x00020000, 0x00020000 },
|
||||
{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
|
||||
{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
|
||||
{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
|
||||
{ 0x0000989c, 0x40ff0000, 0x40ff0000 },
|
||||
{ 0x0000989c, 0x005f0000, 0x005f0000 },
|
||||
{ 0x0000989c, 0x00870000, 0x00870000 },
|
||||
{ 0x0000989c, 0x00f90000, 0x00f90000 },
|
||||
{ 0x0000989c, 0x007b0000, 0x007b0000 },
|
||||
{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
|
||||
{ 0x0000989c, 0x00f50000, 0x00f50000 },
|
||||
{ 0x0000989c, 0x00dc0000, 0x00dc0000 },
|
||||
{ 0x0000989c, 0x00110000, 0x00110000 },
|
||||
{ 0x0000989c, 0x006100a8, 0x006100a8 },
|
||||
{ 0x0000989c, 0x004210a2, 0x004210a2 },
|
||||
{ 0x0000989c, 0x0014008f, 0x0014008f },
|
||||
{ 0x0000989c, 0x00c40003, 0x00c40003 },
|
||||
{ 0x0000989c, 0x003000f2, 0x003000f2 },
|
||||
{ 0x0000989c, 0x00440016, 0x00440016 },
|
||||
{ 0x0000989c, 0x00410040, 0x00410040 },
|
||||
{ 0x0000989c, 0x0001805e, 0x0001805e },
|
||||
{ 0x0000989c, 0x0000c0ab, 0x0000c0ab },
|
||||
{ 0x0000989c, 0x000000f1, 0x000000f1 },
|
||||
{ 0x0000989c, 0x00002081, 0x00002081 },
|
||||
{ 0x0000989c, 0x000000d4, 0x000000d4 },
|
||||
{ 0x000098d0, 0x0000000f, 0x0010000f },
|
||||
};
|
||||
|
||||
static const u32 ar5416Bank6TPC[][3] = {
|
||||
{ 0x0000989c, 0x00000000, 0x00000000 },
|
||||
{ 0x0000989c, 0x00000000, 0x00000000 },
|
||||
{ 0x0000989c, 0x00000000, 0x00000000 },
|
||||
{ 0x0000989c, 0x00e00000, 0x00e00000 },
|
||||
{ 0x0000989c, 0x005e0000, 0x005e0000 },
|
||||
{ 0x0000989c, 0x00120000, 0x00120000 },
|
||||
{ 0x0000989c, 0x00620000, 0x00620000 },
|
||||
{ 0x0000989c, 0x00020000, 0x00020000 },
|
||||
{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
|
||||
{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
|
||||
{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
|
||||
{ 0x0000989c, 0x40ff0000, 0x40ff0000 },
|
||||
{ 0x0000989c, 0x005f0000, 0x005f0000 },
|
||||
{ 0x0000989c, 0x00870000, 0x00870000 },
|
||||
{ 0x0000989c, 0x00f90000, 0x00f90000 },
|
||||
{ 0x0000989c, 0x007b0000, 0x007b0000 },
|
||||
{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
|
||||
{ 0x0000989c, 0x00f50000, 0x00f50000 },
|
||||
{ 0x0000989c, 0x00dc0000, 0x00dc0000 },
|
||||
{ 0x0000989c, 0x00110000, 0x00110000 },
|
||||
{ 0x0000989c, 0x006100a8, 0x006100a8 },
|
||||
{ 0x0000989c, 0x00423022, 0x00423022 },
|
||||
{ 0x0000989c, 0x201400df, 0x201400df },
|
||||
{ 0x0000989c, 0x00c40002, 0x00c40002 },
|
||||
{ 0x0000989c, 0x003000f2, 0x003000f2 },
|
||||
{ 0x0000989c, 0x00440016, 0x00440016 },
|
||||
{ 0x0000989c, 0x00410040, 0x00410040 },
|
||||
{ 0x0000989c, 0x0001805e, 0x0001805e },
|
||||
{ 0x0000989c, 0x0000c0ab, 0x0000c0ab },
|
||||
{ 0x0000989c, 0x000000e1, 0x000000e1 },
|
||||
{ 0x0000989c, 0x00007081, 0x00007081 },
|
||||
{ 0x0000989c, 0x000000d4, 0x000000d4 },
|
||||
{ 0x000098d0, 0x0000000f, 0x0010000f },
|
||||
};
|
||||
|
||||
static const u32 ar5416Bank7[][2] = {
|
||||
{ 0x0000989c, 0x00000500 },
|
||||
{ 0x0000989c, 0x00000800 },
|
||||
{ 0x000098cc, 0x0000000e },
|
||||
};
|
||||
|
||||
static const u32 ar5416Addac[][2] = {
|
||||
{0x0000989c, 0x00000000 },
|
||||
{0x0000989c, 0x00000003 },
|
||||
{0x0000989c, 0x00000000 },
|
||||
{0x0000989c, 0x0000000c },
|
||||
{0x0000989c, 0x00000000 },
|
||||
{0x0000989c, 0x00000030 },
|
||||
{0x0000989c, 0x00000000 },
|
||||
{0x0000989c, 0x00000000 },
|
||||
{0x0000989c, 0x00000000 },
|
||||
{0x0000989c, 0x00000000 },
|
||||
{0x0000989c, 0x00000000 },
|
||||
{0x0000989c, 0x00000000 },
|
||||
{0x0000989c, 0x00000000 },
|
||||
{0x0000989c, 0x00000000 },
|
||||
{0x0000989c, 0x00000000 },
|
||||
{0x0000989c, 0x00000000 },
|
||||
{0x0000989c, 0x00000000 },
|
||||
{0x0000989c, 0x00000000 },
|
||||
{0x0000989c, 0x00000060 },
|
||||
{0x0000989c, 0x00000000 },
|
||||
{0x0000989c, 0x00000000 },
|
||||
{0x0000989c, 0x00000000 },
|
||||
{0x0000989c, 0x00000000 },
|
||||
{0x0000989c, 0x00000000 },
|
||||
{0x0000989c, 0x00000000 },
|
||||
{0x0000989c, 0x00000000 },
|
||||
{0x0000989c, 0x00000000 },
|
||||
{0x0000989c, 0x00000000 },
|
||||
{0x0000989c, 0x00000000 },
|
||||
{0x0000989c, 0x00000000 },
|
||||
{0x0000989c, 0x00000000 },
|
||||
{0x0000989c, 0x00000058 },
|
||||
{0x0000989c, 0x00000000 },
|
||||
{0x0000989c, 0x00000000 },
|
||||
{0x0000989c, 0x00000000 },
|
||||
{0x0000989c, 0x00000000 },
|
||||
{0x000098cc, 0x00000000 },
|
||||
};
|
||||
|
||||
static const u32 ar5416Modes_9100[][6] = {
|
||||
{ 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
|
||||
{ 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
|
||||
{ 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
|
||||
{ 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 },
|
||||
{ 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
|
||||
{ 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf },
|
||||
{ 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
|
||||
{ 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
|
||||
{ 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
|
||||
{ 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
|
||||
{ 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
|
||||
{ 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
|
||||
{ 0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0 },
|
||||
{ 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
|
||||
{ 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
|
||||
{ 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
|
||||
{ 0x00009850, 0x6d48b4e2, 0x6d48b4e2, 0x6d48b0e2, 0x6d48b0e2, 0x6d48b0e2 },
|
||||
{ 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec86d2e, 0x7ec84d2e, 0x7ec82d2e },
|
||||
{ 0x0000985c, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e },
|
||||
{ 0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18 },
|
||||
{ 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
|
||||
{ 0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0 },
|
||||
{ 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 },
|
||||
{ 0x00009914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, 0x000007d0 },
|
||||
{ 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
|
||||
{ 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a11, 0xd00a8a0d, 0xd00a8a0d },
|
||||
{ 0x00009940, 0x00754604, 0x00754604, 0xfff81204, 0xfff81204, 0xfff81204 },
|
||||
{ 0x00009944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020 },
|
||||
{ 0x00009954, 0x5f3ca3de, 0x5f3ca3de, 0xe250a51e, 0xe250a51e, 0xe250a51e },
|
||||
{ 0x00009958, 0x2108ecff, 0x2108ecff, 0x3388ffff, 0x3388ffff, 0x3388ffff },
|
||||
#ifdef TB243
|
||||
{ 0x00009960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 },
|
||||
{ 0x0000a960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 },
|
||||
{ 0x0000b960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 },
|
||||
{ 0x00009964, 0x00000000, 0x00000000, 0x00002210, 0x00002210, 0x00001120 },
|
||||
#else
|
||||
{ 0x00009960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 },
|
||||
{ 0x0000a960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 },
|
||||
{ 0x0000b960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 },
|
||||
{ 0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, 0x00001120 },
|
||||
#endif
|
||||
{ 0x0000c9bc, 0x001a0600, 0x001a0600, 0x001a1000, 0x001a0c00, 0x001a0c00 },
|
||||
{ 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be },
|
||||
{ 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
|
||||
{ 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 },
|
||||
{ 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
|
||||
{ 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
|
||||
{ 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
|
||||
{ 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
|
||||
{ 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 },
|
||||
{ 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 },
|
||||
{ 0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
|
||||
{ 0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
|
||||
{ 0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
|
||||
{ 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
|
||||
{ 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
|
||||
{ 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa },
|
||||
{ 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 },
|
||||
{ 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 },
|
||||
{ 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 },
|
||||
{ 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b },
|
||||
{ 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b },
|
||||
{ 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a },
|
||||
{ 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf },
|
||||
{ 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f },
|
||||
{ 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f },
|
||||
{ 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f },
|
||||
{ 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 },
|
||||
{ 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
|
||||
{ 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
|
||||
{ 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
|
||||
};
|
||||
|
||||
#endif /* INITVALS_AR5008_H */
|
1375
drivers/net/wireless/ath/ath9k/ar5008_phy.c
Normal file
1375
drivers/net/wireless/ath/ath9k/ar5008_phy.c
Normal file
File diff suppressed because it is too large
Load Diff
1254
drivers/net/wireless/ath/ath9k/ar9001_initvals.h
Normal file
1254
drivers/net/wireless/ath/ath9k/ar9001_initvals.h
Normal file
File diff suppressed because it is too large
Load Diff
1000
drivers/net/wireless/ath/ath9k/ar9002_calib.c
Normal file
1000
drivers/net/wireless/ath/ath9k/ar9002_calib.c
Normal file
File diff suppressed because it is too large
Load Diff
593
drivers/net/wireless/ath/ath9k/ar9002_hw.c
Normal file
593
drivers/net/wireless/ath/ath9k/ar9002_hw.c
Normal file
@ -0,0 +1,593 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2010 Atheros Communications Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "hw.h"
|
||||
#include "ar5008_initvals.h"
|
||||
#include "ar9001_initvals.h"
|
||||
#include "ar9002_initvals.h"
|
||||
|
||||
/* General hardware code for the A5008/AR9001/AR9002 hadware families */
|
||||
|
||||
static bool ar9002_hw_macversion_supported(u32 macversion)
|
||||
{
|
||||
switch (macversion) {
|
||||
case AR_SREV_VERSION_5416_PCI:
|
||||
case AR_SREV_VERSION_5416_PCIE:
|
||||
case AR_SREV_VERSION_9160:
|
||||
case AR_SREV_VERSION_9100:
|
||||
case AR_SREV_VERSION_9280:
|
||||
case AR_SREV_VERSION_9285:
|
||||
case AR_SREV_VERSION_9287:
|
||||
case AR_SREV_VERSION_9271:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
|
||||
{
|
||||
if (AR_SREV_9271(ah)) {
|
||||
INIT_INI_ARRAY(&ah->iniModes, ar9271Modes_9271,
|
||||
ARRAY_SIZE(ar9271Modes_9271), 6);
|
||||
INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271,
|
||||
ARRAY_SIZE(ar9271Common_9271), 2);
|
||||
INIT_INI_ARRAY(&ah->iniCommon_normal_cck_fir_coeff_9271,
|
||||
ar9271Common_normal_cck_fir_coeff_9271,
|
||||
ARRAY_SIZE(ar9271Common_normal_cck_fir_coeff_9271), 2);
|
||||
INIT_INI_ARRAY(&ah->iniCommon_japan_2484_cck_fir_coeff_9271,
|
||||
ar9271Common_japan_2484_cck_fir_coeff_9271,
|
||||
ARRAY_SIZE(ar9271Common_japan_2484_cck_fir_coeff_9271), 2);
|
||||
INIT_INI_ARRAY(&ah->iniModes_9271_1_0_only,
|
||||
ar9271Modes_9271_1_0_only,
|
||||
ARRAY_SIZE(ar9271Modes_9271_1_0_only), 6);
|
||||
INIT_INI_ARRAY(&ah->iniModes_9271_ANI_reg, ar9271Modes_9271_ANI_reg,
|
||||
ARRAY_SIZE(ar9271Modes_9271_ANI_reg), 6);
|
||||
INIT_INI_ARRAY(&ah->iniModes_high_power_tx_gain_9271,
|
||||
ar9271Modes_high_power_tx_gain_9271,
|
||||
ARRAY_SIZE(ar9271Modes_high_power_tx_gain_9271), 6);
|
||||
INIT_INI_ARRAY(&ah->iniModes_normal_power_tx_gain_9271,
|
||||
ar9271Modes_normal_power_tx_gain_9271,
|
||||
ARRAY_SIZE(ar9271Modes_normal_power_tx_gain_9271), 6);
|
||||
return;
|
||||
}
|
||||
|
||||
if (AR_SREV_9287_11_OR_LATER(ah)) {
|
||||
INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1,
|
||||
ARRAY_SIZE(ar9287Modes_9287_1_1), 6);
|
||||
INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_1,
|
||||
ARRAY_SIZE(ar9287Common_9287_1_1), 2);
|
||||
if (ah->config.pcie_clock_req)
|
||||
INIT_INI_ARRAY(&ah->iniPcieSerdes,
|
||||
ar9287PciePhy_clkreq_off_L1_9287_1_1,
|
||||
ARRAY_SIZE(ar9287PciePhy_clkreq_off_L1_9287_1_1), 2);
|
||||
else
|
||||
INIT_INI_ARRAY(&ah->iniPcieSerdes,
|
||||
ar9287PciePhy_clkreq_always_on_L1_9287_1_1,
|
||||
ARRAY_SIZE(ar9287PciePhy_clkreq_always_on_L1_9287_1_1),
|
||||
2);
|
||||
} else if (AR_SREV_9287_10_OR_LATER(ah)) {
|
||||
INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_0,
|
||||
ARRAY_SIZE(ar9287Modes_9287_1_0), 6);
|
||||
INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_0,
|
||||
ARRAY_SIZE(ar9287Common_9287_1_0), 2);
|
||||
|
||||
if (ah->config.pcie_clock_req)
|
||||
INIT_INI_ARRAY(&ah->iniPcieSerdes,
|
||||
ar9287PciePhy_clkreq_off_L1_9287_1_0,
|
||||
ARRAY_SIZE(ar9287PciePhy_clkreq_off_L1_9287_1_0), 2);
|
||||
else
|
||||
INIT_INI_ARRAY(&ah->iniPcieSerdes,
|
||||
ar9287PciePhy_clkreq_always_on_L1_9287_1_0,
|
||||
ARRAY_SIZE(ar9287PciePhy_clkreq_always_on_L1_9287_1_0),
|
||||
2);
|
||||
} else if (AR_SREV_9285_12_OR_LATER(ah)) {
|
||||
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2,
|
||||
ARRAY_SIZE(ar9285Modes_9285_1_2), 6);
|
||||
INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285_1_2,
|
||||
ARRAY_SIZE(ar9285Common_9285_1_2), 2);
|
||||
|
||||
if (ah->config.pcie_clock_req) {
|
||||
INIT_INI_ARRAY(&ah->iniPcieSerdes,
|
||||
ar9285PciePhy_clkreq_off_L1_9285_1_2,
|
||||
ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285_1_2), 2);
|
||||
} else {
|
||||
INIT_INI_ARRAY(&ah->iniPcieSerdes,
|
||||
ar9285PciePhy_clkreq_always_on_L1_9285_1_2,
|
||||
ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285_1_2),
|
||||
2);
|
||||
}
|
||||
} else if (AR_SREV_9285_10_OR_LATER(ah)) {
|
||||
INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285,
|
||||
ARRAY_SIZE(ar9285Modes_9285), 6);
|
||||
INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285,
|
||||
ARRAY_SIZE(ar9285Common_9285), 2);
|
||||
|
||||
if (ah->config.pcie_clock_req) {
|
||||
INIT_INI_ARRAY(&ah->iniPcieSerdes,
|
||||
ar9285PciePhy_clkreq_off_L1_9285,
|
||||
ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285), 2);
|
||||
} else {
|
||||
INIT_INI_ARRAY(&ah->iniPcieSerdes,
|
||||
ar9285PciePhy_clkreq_always_on_L1_9285,
|
||||
ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285), 2);
|
||||
}
|
||||
} else if (AR_SREV_9280_20_OR_LATER(ah)) {
|
||||
INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280_2,
|
||||
ARRAY_SIZE(ar9280Modes_9280_2), 6);
|
||||
INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280_2,
|
||||
ARRAY_SIZE(ar9280Common_9280_2), 2);
|
||||
|
||||
if (ah->config.pcie_clock_req) {
|
||||
INIT_INI_ARRAY(&ah->iniPcieSerdes,
|
||||
ar9280PciePhy_clkreq_off_L1_9280,
|
||||
ARRAY_SIZE(ar9280PciePhy_clkreq_off_L1_9280), 2);
|
||||
} else {
|
||||
INIT_INI_ARRAY(&ah->iniPcieSerdes,
|
||||
ar9280PciePhy_clkreq_always_on_L1_9280,
|
||||
ARRAY_SIZE(ar9280PciePhy_clkreq_always_on_L1_9280), 2);
|
||||
}
|
||||
INIT_INI_ARRAY(&ah->iniModesAdditional,
|
||||
ar9280Modes_fast_clock_9280_2,
|
||||
ARRAY_SIZE(ar9280Modes_fast_clock_9280_2), 3);
|
||||
} else if (AR_SREV_9280_10_OR_LATER(ah)) {
|
||||
INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280,
|
||||
ARRAY_SIZE(ar9280Modes_9280), 6);
|
||||
INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280,
|
||||
ARRAY_SIZE(ar9280Common_9280), 2);
|
||||
} else if (AR_SREV_9160_10_OR_LATER(ah)) {
|
||||
INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9160,
|
||||
ARRAY_SIZE(ar5416Modes_9160), 6);
|
||||
INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9160,
|
||||
ARRAY_SIZE(ar5416Common_9160), 2);
|
||||
INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9160,
|
||||
ARRAY_SIZE(ar5416Bank0_9160), 2);
|
||||
INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9160,
|
||||
ARRAY_SIZE(ar5416BB_RfGain_9160), 3);
|
||||
INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9160,
|
||||
ARRAY_SIZE(ar5416Bank1_9160), 2);
|
||||
INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9160,
|
||||
ARRAY_SIZE(ar5416Bank2_9160), 2);
|
||||
INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9160,
|
||||
ARRAY_SIZE(ar5416Bank3_9160), 3);
|
||||
INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9160,
|
||||
ARRAY_SIZE(ar5416Bank6_9160), 3);
|
||||
INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9160,
|
||||
ARRAY_SIZE(ar5416Bank6TPC_9160), 3);
|
||||
INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9160,
|
||||
ARRAY_SIZE(ar5416Bank7_9160), 2);
|
||||
if (AR_SREV_9160_11(ah)) {
|
||||
INIT_INI_ARRAY(&ah->iniAddac,
|
||||
ar5416Addac_91601_1,
|
||||
ARRAY_SIZE(ar5416Addac_91601_1), 2);
|
||||
} else {
|
||||
INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9160,
|
||||
ARRAY_SIZE(ar5416Addac_9160), 2);
|
||||
}
|
||||
} else if (AR_SREV_9100_OR_LATER(ah)) {
|
||||
INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9100,
|
||||
ARRAY_SIZE(ar5416Modes_9100), 6);
|
||||
INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9100,
|
||||
ARRAY_SIZE(ar5416Common_9100), 2);
|
||||
INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9100,
|
||||
ARRAY_SIZE(ar5416Bank0_9100), 2);
|
||||
INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9100,
|
||||
ARRAY_SIZE(ar5416BB_RfGain_9100), 3);
|
||||
INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9100,
|
||||
ARRAY_SIZE(ar5416Bank1_9100), 2);
|
||||
INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9100,
|
||||
ARRAY_SIZE(ar5416Bank2_9100), 2);
|
||||
INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9100,
|
||||
ARRAY_SIZE(ar5416Bank3_9100), 3);
|
||||
INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9100,
|
||||
ARRAY_SIZE(ar5416Bank6_9100), 3);
|
||||
INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9100,
|
||||
ARRAY_SIZE(ar5416Bank6TPC_9100), 3);
|
||||
INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9100,
|
||||
ARRAY_SIZE(ar5416Bank7_9100), 2);
|
||||
INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9100,
|
||||
ARRAY_SIZE(ar5416Addac_9100), 2);
|
||||
} else {
|
||||
INIT_INI_ARRAY(&ah->iniModes, ar5416Modes,
|
||||
ARRAY_SIZE(ar5416Modes), 6);
|
||||
INIT_INI_ARRAY(&ah->iniCommon, ar5416Common,
|
||||
ARRAY_SIZE(ar5416Common), 2);
|
||||
INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0,
|
||||
ARRAY_SIZE(ar5416Bank0), 2);
|
||||
INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain,
|
||||
ARRAY_SIZE(ar5416BB_RfGain), 3);
|
||||
INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1,
|
||||
ARRAY_SIZE(ar5416Bank1), 2);
|
||||
INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2,
|
||||
ARRAY_SIZE(ar5416Bank2), 2);
|
||||
INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3,
|
||||
ARRAY_SIZE(ar5416Bank3), 3);
|
||||
INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6,
|
||||
ARRAY_SIZE(ar5416Bank6), 3);
|
||||
INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC,
|
||||
ARRAY_SIZE(ar5416Bank6TPC), 3);
|
||||
INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7,
|
||||
ARRAY_SIZE(ar5416Bank7), 2);
|
||||
INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac,
|
||||
ARRAY_SIZE(ar5416Addac), 2);
|
||||
}
|
||||
}
|
||||
|
||||
/* Support for Japan ch.14 (2484) spread */
|
||||
void ar9002_hw_cck_chan14_spread(struct ath_hw *ah)
|
||||
{
|
||||
if (AR_SREV_9287_11_OR_LATER(ah)) {
|
||||
INIT_INI_ARRAY(&ah->iniCckfirNormal,
|
||||
ar9287Common_normal_cck_fir_coeff_92871_1,
|
||||
ARRAY_SIZE(ar9287Common_normal_cck_fir_coeff_92871_1),
|
||||
2);
|
||||
INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
|
||||
ar9287Common_japan_2484_cck_fir_coeff_92871_1,
|
||||
ARRAY_SIZE(ar9287Common_japan_2484_cck_fir_coeff_92871_1),
|
||||
2);
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
ar9280Modes_backoff_13db_rxgain_9280_2,
|
||||
ARRAY_SIZE(ar9280Modes_backoff_13db_rxgain_9280_2), 6);
|
||||
else if (rxgain_type == AR5416_EEP_RXGAIN_23DB_BACKOFF)
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9280Modes_backoff_23db_rxgain_9280_2,
|
||||
ARRAY_SIZE(ar9280Modes_backoff_23db_rxgain_9280_2), 6);
|
||||
else
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9280Modes_original_rxgain_9280_2,
|
||||
ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6);
|
||||
} else {
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9280Modes_original_rxgain_9280_2,
|
||||
ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6);
|
||||
}
|
||||
}
|
||||
|
||||
static void ar9280_20_hw_init_txgain_ini(struct ath_hw *ah)
|
||||
{
|
||||
u32 txgain_type;
|
||||
|
||||
if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >=
|
||||
AR5416_EEP_MINOR_VER_19) {
|
||||
txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
|
||||
|
||||
if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER)
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9280Modes_high_power_tx_gain_9280_2,
|
||||
ARRAY_SIZE(ar9280Modes_high_power_tx_gain_9280_2), 6);
|
||||
else
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9280Modes_original_tx_gain_9280_2,
|
||||
ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6);
|
||||
} else {
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9280Modes_original_tx_gain_9280_2,
|
||||
ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6);
|
||||
}
|
||||
}
|
||||
|
||||
static void ar9002_hw_init_mode_gain_regs(struct ath_hw *ah)
|
||||
{
|
||||
if (AR_SREV_9287_11_OR_LATER(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9287Modes_rx_gain_9287_1_1,
|
||||
ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_1), 6);
|
||||
else if (AR_SREV_9287_10(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9287Modes_rx_gain_9287_1_0,
|
||||
ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_0), 6);
|
||||
else if (AR_SREV_9280_20(ah))
|
||||
ar9280_20_hw_init_rxgain_ini(ah);
|
||||
|
||||
if (AR_SREV_9287_11_OR_LATER(ah)) {
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9287Modes_tx_gain_9287_1_1,
|
||||
ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_1), 6);
|
||||
} else if (AR_SREV_9287_10(ah)) {
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9287Modes_tx_gain_9287_1_0,
|
||||
ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_0), 6);
|
||||
} else if (AR_SREV_9280_20(ah)) {
|
||||
ar9280_20_hw_init_txgain_ini(ah);
|
||||
} else if (AR_SREV_9285_12_OR_LATER(ah)) {
|
||||
u32 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
|
||||
|
||||
/* txgain table */
|
||||
if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) {
|
||||
if (AR_SREV_9285E_20(ah)) {
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9285Modes_XE2_0_high_power,
|
||||
ARRAY_SIZE(
|
||||
ar9285Modes_XE2_0_high_power), 6);
|
||||
} else {
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9285Modes_high_power_tx_gain_9285_1_2,
|
||||
ARRAY_SIZE(
|
||||
ar9285Modes_high_power_tx_gain_9285_1_2), 6);
|
||||
}
|
||||
} else {
|
||||
if (AR_SREV_9285E_20(ah)) {
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9285Modes_XE2_0_normal_power,
|
||||
ARRAY_SIZE(
|
||||
ar9285Modes_XE2_0_normal_power), 6);
|
||||
} else {
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9285Modes_original_tx_gain_9285_1_2,
|
||||
ARRAY_SIZE(
|
||||
ar9285Modes_original_tx_gain_9285_1_2), 6);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 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,
|
||||
int restore,
|
||||
int power_off)
|
||||
{
|
||||
u8 i;
|
||||
u32 val;
|
||||
|
||||
if (ah->is_pciexpress != true)
|
||||
return;
|
||||
|
||||
/* Do not touch SerDes registers */
|
||||
if (ah->config.pcie_powersave_enable == 2)
|
||||
return;
|
||||
|
||||
/* Nothing to do on restore for 11N */
|
||||
if (!restore) {
|
||||
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 if (AR_SREV_9280(ah) &&
|
||||
(ah->hw_version.macRev == AR_SREV_REVISION_9280_10)) {
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00);
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
|
||||
|
||||
/* RX shut off when elecidle is asserted */
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019);
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820);
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560);
|
||||
|
||||
/* Shut off CLKREQ active in L1 */
|
||||
if (ah->config.pcie_clock_req)
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc);
|
||||
else
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffd);
|
||||
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007);
|
||||
|
||||
/* Load the new settings */
|
||||
REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
|
||||
|
||||
} else {
|
||||
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 11n
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
udelay(1000);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Several PCIe massages to ensure proper behaviour */
|
||||
if (ah->config.pcie_waen) {
|
||||
val = ah->config.pcie_waen;
|
||||
if (!power_off)
|
||||
val &= (~AR_WA_D3_L1_DISABLE);
|
||||
} else {
|
||||
if (AR_SREV_9285(ah) || AR_SREV_9271(ah) ||
|
||||
AR_SREV_9287(ah)) {
|
||||
val = AR9285_WA_DEFAULT;
|
||||
if (!power_off)
|
||||
val &= (~AR_WA_D3_L1_DISABLE);
|
||||
} else if (AR_SREV_9280(ah)) {
|
||||
/*
|
||||
* On AR9280 chips bit 22 of 0x4004 needs to be
|
||||
* set otherwise card may disappear.
|
||||
*/
|
||||
val = AR9280_WA_DEFAULT;
|
||||
if (!power_off)
|
||||
val &= (~AR_WA_D3_L1_DISABLE);
|
||||
} else
|
||||
val = AR_WA_DEFAULT;
|
||||
}
|
||||
|
||||
REG_WRITE(ah, AR_WA, val);
|
||||
}
|
||||
|
||||
if (power_off) {
|
||||
/*
|
||||
* Set PCIe workaround bits
|
||||
* 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)
|
||||
REG_SET_BIT(ah, AR_WA, AR_WA_D3_L1_DISABLE);
|
||||
} else {
|
||||
if (((AR_SREV_9285(ah) || AR_SREV_9271(ah) ||
|
||||
AR_SREV_9287(ah)) &&
|
||||
(AR9285_WA_DEFAULT & AR_WA_D3_L1_DISABLE)) ||
|
||||
(AR_SREV_9280(ah) &&
|
||||
(AR9280_WA_DEFAULT & AR_WA_D3_L1_DISABLE))) {
|
||||
REG_SET_BIT(ah, AR_WA, AR_WA_D3_L1_DISABLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int ar9002_hw_get_radiorev(struct ath_hw *ah)
|
||||
{
|
||||
u32 val;
|
||||
int i;
|
||||
|
||||
ENABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
REG_WRITE(ah, AR_PHY(0x36), 0x00007058);
|
||||
for (i = 0; i < 8; i++)
|
||||
REG_WRITE(ah, AR_PHY(0x20), 0x00010000);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
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:
|
||||
ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
|
||||
"Radio Chip Rev 0x%02X not supported\n",
|
||||
val & AR_RADIO_SREV_MAJOR);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
ah->hw_version.analog5GhzRev = val;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable ASYNC FIFO
|
||||
*
|
||||
* If Async FIFO is enabled, the following counters change as MAC now runs
|
||||
* at 117 Mhz instead of 88/44MHz when async FIFO is disabled.
|
||||
*
|
||||
* The values below tested for ht40 2 chain.
|
||||
* Overwrite the delay/timeouts initialized in process ini.
|
||||
*/
|
||||
void ar9002_hw_enable_async_fifo(struct ath_hw *ah)
|
||||
{
|
||||
if (AR_SREV_9287_12_OR_LATER(ah)) {
|
||||
REG_WRITE(ah, AR_D_GBL_IFS_SIFS,
|
||||
AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR);
|
||||
REG_WRITE(ah, AR_D_GBL_IFS_SLOT,
|
||||
AR_D_GBL_IFS_SLOT_ASYNC_FIFO_DUR);
|
||||
REG_WRITE(ah, AR_D_GBL_IFS_EIFS,
|
||||
AR_D_GBL_IFS_EIFS_ASYNC_FIFO_DUR);
|
||||
|
||||
REG_WRITE(ah, AR_TIME_OUT, AR_TIME_OUT_ACK_CTS_ASYNC_FIFO_DUR);
|
||||
REG_WRITE(ah, AR_USEC, AR_USEC_ASYNC_FIFO_DUR);
|
||||
|
||||
REG_SET_BIT(ah, AR_MAC_PCU_LOGIC_ANALYZER,
|
||||
AR_MAC_PCU_LOGIC_ANALYZER_DISBUG20768);
|
||||
REG_RMW_FIELD(ah, AR_AHB_MODE, AR_AHB_CUSTOM_BURST_EN,
|
||||
AR_AHB_CUSTOM_BURST_ASYNC_FIFO_VAL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We don't enable WEP aggregation on mac80211 but we keep this
|
||||
* around for HAL unification purposes.
|
||||
*/
|
||||
void ar9002_hw_enable_wep_aggregation(struct ath_hw *ah)
|
||||
{
|
||||
if (AR_SREV_9287_12_OR_LATER(ah)) {
|
||||
REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
|
||||
AR_PCU_MISC_MODE2_ENABLE_AGGWEP);
|
||||
}
|
||||
}
|
||||
|
||||
/* Sets up the AR5008/AR9001/AR9002 hardware familiy callbacks */
|
||||
void ar9002_hw_attach_ops(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
|
||||
struct ath_hw_ops *ops = ath9k_hw_ops(ah);
|
||||
|
||||
priv_ops->init_mode_regs = ar9002_hw_init_mode_regs;
|
||||
priv_ops->init_mode_gain_regs = ar9002_hw_init_mode_gain_regs;
|
||||
priv_ops->macversion_supported = ar9002_hw_macversion_supported;
|
||||
|
||||
ops->config_pci_powersave = ar9002_hw_configpcipowersave;
|
||||
|
||||
ar5008_hw_attach_phy_ops(ah);
|
||||
if (AR_SREV_9280_10_OR_LATER(ah))
|
||||
ar9002_hw_attach_phy_ops(ah);
|
||||
|
||||
ar9002_hw_attach_calib_ops(ah);
|
||||
ar9002_hw_attach_mac_ops(ah);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
480
drivers/net/wireless/ath/ath9k/ar9002_mac.c
Normal file
480
drivers/net/wireless/ath/ath9k/ar9002_mac.c
Normal file
@ -0,0 +1,480 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2009 Atheros Communications Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "hw.h"
|
||||
|
||||
#define AR_BufLen 0x00000fff
|
||||
|
||||
static void ar9002_hw_rx_enable(struct ath_hw *ah)
|
||||
{
|
||||
REG_WRITE(ah, AR_CR, AR_CR_RXE);
|
||||
}
|
||||
|
||||
static void ar9002_hw_set_desc_link(void *ds, u32 ds_link)
|
||||
{
|
||||
((struct ath_desc*) ds)->ds_link = ds_link;
|
||||
}
|
||||
|
||||
static void ar9002_hw_get_desc_link(void *ds, u32 **ds_link)
|
||||
{
|
||||
*ds_link = &((struct ath_desc *)ds)->ds_link;
|
||||
}
|
||||
|
||||
static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
|
||||
{
|
||||
u32 isr = 0;
|
||||
u32 mask2 = 0;
|
||||
struct ath9k_hw_capabilities *pCap = &ah->caps;
|
||||
u32 sync_cause = 0;
|
||||
bool fatal_int = false;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
|
||||
if (!AR_SREV_9100(ah)) {
|
||||
if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) {
|
||||
if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M)
|
||||
== AR_RTC_STATUS_ON) {
|
||||
isr = REG_READ(ah, AR_ISR);
|
||||
}
|
||||
}
|
||||
|
||||
sync_cause = REG_READ(ah, AR_INTR_SYNC_CAUSE) &
|
||||
AR_INTR_SYNC_DEFAULT;
|
||||
|
||||
*masked = 0;
|
||||
|
||||
if (!isr && !sync_cause)
|
||||
return false;
|
||||
} else {
|
||||
*masked = 0;
|
||||
isr = REG_READ(ah, AR_ISR);
|
||||
}
|
||||
|
||||
if (isr) {
|
||||
if (isr & AR_ISR_BCNMISC) {
|
||||
u32 isr2;
|
||||
isr2 = REG_READ(ah, AR_ISR_S2);
|
||||
if (isr2 & AR_ISR_S2_TIM)
|
||||
mask2 |= ATH9K_INT_TIM;
|
||||
if (isr2 & AR_ISR_S2_DTIM)
|
||||
mask2 |= ATH9K_INT_DTIM;
|
||||
if (isr2 & AR_ISR_S2_DTIMSYNC)
|
||||
mask2 |= ATH9K_INT_DTIMSYNC;
|
||||
if (isr2 & (AR_ISR_S2_CABEND))
|
||||
mask2 |= ATH9K_INT_CABEND;
|
||||
if (isr2 & AR_ISR_S2_GTT)
|
||||
mask2 |= ATH9K_INT_GTT;
|
||||
if (isr2 & AR_ISR_S2_CST)
|
||||
mask2 |= ATH9K_INT_CST;
|
||||
if (isr2 & AR_ISR_S2_TSFOOR)
|
||||
mask2 |= ATH9K_INT_TSFOOR;
|
||||
}
|
||||
|
||||
isr = REG_READ(ah, AR_ISR_RAC);
|
||||
if (isr == 0xffffffff) {
|
||||
*masked = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
*masked = isr & ATH9K_INT_COMMON;
|
||||
|
||||
if (ah->config.rx_intr_mitigation) {
|
||||
if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
|
||||
*masked |= ATH9K_INT_RX;
|
||||
}
|
||||
|
||||
if (isr & (AR_ISR_RXOK | AR_ISR_RXERR))
|
||||
*masked |= ATH9K_INT_RX;
|
||||
if (isr &
|
||||
(AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR |
|
||||
AR_ISR_TXEOL)) {
|
||||
u32 s0_s, s1_s;
|
||||
|
||||
*masked |= ATH9K_INT_TX;
|
||||
|
||||
s0_s = REG_READ(ah, AR_ISR_S0_S);
|
||||
ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK);
|
||||
ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC);
|
||||
|
||||
s1_s = REG_READ(ah, AR_ISR_S1_S);
|
||||
ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR);
|
||||
ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL);
|
||||
}
|
||||
|
||||
if (isr & AR_ISR_RXORN) {
|
||||
ath_print(common, ATH_DBG_INTERRUPT,
|
||||
"receive FIFO overrun interrupt\n");
|
||||
}
|
||||
|
||||
if (!AR_SREV_9100(ah)) {
|
||||
if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
|
||||
u32 isr5 = REG_READ(ah, AR_ISR_S5_S);
|
||||
if (isr5 & AR_ISR_S5_TIM_TIMER)
|
||||
*masked |= ATH9K_INT_TIM_TIMER;
|
||||
}
|
||||
}
|
||||
|
||||
*masked |= mask2;
|
||||
}
|
||||
|
||||
if (AR_SREV_9100(ah))
|
||||
return true;
|
||||
|
||||
if (isr & AR_ISR_GENTMR) {
|
||||
u32 s5_s;
|
||||
|
||||
s5_s = REG_READ(ah, AR_ISR_S5_S);
|
||||
if (isr & AR_ISR_GENTMR) {
|
||||
ah->intr_gen_timer_trigger =
|
||||
MS(s5_s, AR_ISR_S5_GENTIMER_TRIG);
|
||||
|
||||
ah->intr_gen_timer_thresh =
|
||||
MS(s5_s, AR_ISR_S5_GENTIMER_THRESH);
|
||||
|
||||
if (ah->intr_gen_timer_trigger)
|
||||
*masked |= ATH9K_INT_GENTIMER;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (sync_cause) {
|
||||
fatal_int =
|
||||
(sync_cause &
|
||||
(AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR))
|
||||
? true : false;
|
||||
|
||||
if (fatal_int) {
|
||||
if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) {
|
||||
ath_print(common, ATH_DBG_ANY,
|
||||
"received PCI FATAL interrupt\n");
|
||||
}
|
||||
if (sync_cause & AR_INTR_SYNC_HOST1_PERR) {
|
||||
ath_print(common, ATH_DBG_ANY,
|
||||
"received PCI PERR interrupt\n");
|
||||
}
|
||||
*masked |= ATH9K_INT_FATAL;
|
||||
}
|
||||
if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
|
||||
ath_print(common, ATH_DBG_INTERRUPT,
|
||||
"AR_INTR_SYNC_RADM_CPL_TIMEOUT\n");
|
||||
REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
|
||||
REG_WRITE(ah, AR_RC, 0);
|
||||
*masked |= ATH9K_INT_FATAL;
|
||||
}
|
||||
if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) {
|
||||
ath_print(common, ATH_DBG_INTERRUPT,
|
||||
"AR_INTR_SYNC_LOCAL_TIMEOUT\n");
|
||||
}
|
||||
|
||||
REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
|
||||
(void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ar9002_hw_fill_txdesc(struct ath_hw *ah, void *ds, u32 seglen,
|
||||
bool is_firstseg, bool is_lastseg,
|
||||
const void *ds0, dma_addr_t buf_addr,
|
||||
unsigned int qcu)
|
||||
{
|
||||
struct ar5416_desc *ads = AR5416DESC(ds);
|
||||
|
||||
ads->ds_data = buf_addr;
|
||||
|
||||
if (is_firstseg) {
|
||||
ads->ds_ctl1 |= seglen | (is_lastseg ? 0 : AR_TxMore);
|
||||
} else if (is_lastseg) {
|
||||
ads->ds_ctl0 = 0;
|
||||
ads->ds_ctl1 = seglen;
|
||||
ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2;
|
||||
ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3;
|
||||
} else {
|
||||
ads->ds_ctl0 = 0;
|
||||
ads->ds_ctl1 = seglen | AR_TxMore;
|
||||
ads->ds_ctl2 = 0;
|
||||
ads->ds_ctl3 = 0;
|
||||
}
|
||||
ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
|
||||
ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
|
||||
ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
|
||||
ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
|
||||
ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
|
||||
}
|
||||
|
||||
static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds,
|
||||
struct ath_tx_status *ts)
|
||||
{
|
||||
struct ar5416_desc *ads = AR5416DESC(ds);
|
||||
|
||||
if ((ads->ds_txstatus9 & AR_TxDone) == 0)
|
||||
return -EINPROGRESS;
|
||||
|
||||
ts->ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum);
|
||||
ts->ts_tstamp = ads->AR_SendTimestamp;
|
||||
ts->ts_status = 0;
|
||||
ts->ts_flags = 0;
|
||||
|
||||
if (ads->ds_txstatus1 & AR_FrmXmitOK)
|
||||
ts->ts_status |= ATH9K_TX_ACKED;
|
||||
if (ads->ds_txstatus1 & AR_ExcessiveRetries)
|
||||
ts->ts_status |= ATH9K_TXERR_XRETRY;
|
||||
if (ads->ds_txstatus1 & AR_Filtered)
|
||||
ts->ts_status |= ATH9K_TXERR_FILT;
|
||||
if (ads->ds_txstatus1 & AR_FIFOUnderrun) {
|
||||
ts->ts_status |= ATH9K_TXERR_FIFO;
|
||||
ath9k_hw_updatetxtriglevel(ah, true);
|
||||
}
|
||||
if (ads->ds_txstatus9 & AR_TxOpExceeded)
|
||||
ts->ts_status |= ATH9K_TXERR_XTXOP;
|
||||
if (ads->ds_txstatus1 & AR_TxTimerExpired)
|
||||
ts->ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
|
||||
|
||||
if (ads->ds_txstatus1 & AR_DescCfgErr)
|
||||
ts->ts_flags |= ATH9K_TX_DESC_CFG_ERR;
|
||||
if (ads->ds_txstatus1 & AR_TxDataUnderrun) {
|
||||
ts->ts_flags |= ATH9K_TX_DATA_UNDERRUN;
|
||||
ath9k_hw_updatetxtriglevel(ah, true);
|
||||
}
|
||||
if (ads->ds_txstatus1 & AR_TxDelimUnderrun) {
|
||||
ts->ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
|
||||
ath9k_hw_updatetxtriglevel(ah, true);
|
||||
}
|
||||
if (ads->ds_txstatus0 & AR_TxBaStatus) {
|
||||
ts->ts_flags |= ATH9K_TX_BA;
|
||||
ts->ba_low = ads->AR_BaBitmapLow;
|
||||
ts->ba_high = ads->AR_BaBitmapHigh;
|
||||
}
|
||||
|
||||
ts->ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx);
|
||||
switch (ts->ts_rateindex) {
|
||||
case 0:
|
||||
ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0);
|
||||
break;
|
||||
case 1:
|
||||
ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1);
|
||||
break;
|
||||
case 2:
|
||||
ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2);
|
||||
break;
|
||||
case 3:
|
||||
ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3);
|
||||
break;
|
||||
}
|
||||
|
||||
ts->ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined);
|
||||
ts->ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00);
|
||||
ts->ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01);
|
||||
ts->ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02);
|
||||
ts->ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10);
|
||||
ts->ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11);
|
||||
ts->ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12);
|
||||
ts->evm0 = ads->AR_TxEVM0;
|
||||
ts->evm1 = ads->AR_TxEVM1;
|
||||
ts->evm2 = ads->AR_TxEVM2;
|
||||
ts->ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt);
|
||||
ts->ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt);
|
||||
ts->ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt);
|
||||
ts->ts_antenna = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ar9002_hw_set11n_txdesc(struct ath_hw *ah, void *ds,
|
||||
u32 pktLen, enum ath9k_pkt_type type,
|
||||
u32 txPower, u32 keyIx,
|
||||
enum ath9k_key_type keyType, u32 flags)
|
||||
{
|
||||
struct ar5416_desc *ads = AR5416DESC(ds);
|
||||
|
||||
txPower += ah->txpower_indexoffset;
|
||||
if (txPower > 63)
|
||||
txPower = 63;
|
||||
|
||||
ads->ds_ctl0 = (pktLen & AR_FrameLen)
|
||||
| (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
|
||||
| SM(txPower, AR_XmitPower)
|
||||
| (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
|
||||
| (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
|
||||
| (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0)
|
||||
| (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0);
|
||||
|
||||
ads->ds_ctl1 =
|
||||
(keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0)
|
||||
| SM(type, AR_FrameType)
|
||||
| (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
|
||||
| (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
|
||||
| (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
|
||||
|
||||
ads->ds_ctl6 = SM(keyType, AR_EncrType);
|
||||
|
||||
if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) {
|
||||
ads->ds_ctl8 = 0;
|
||||
ads->ds_ctl9 = 0;
|
||||
ads->ds_ctl10 = 0;
|
||||
ads->ds_ctl11 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void ar9002_hw_set11n_ratescenario(struct ath_hw *ah, void *ds,
|
||||
void *lastds,
|
||||
u32 durUpdateEn, u32 rtsctsRate,
|
||||
u32 rtsctsDuration,
|
||||
struct ath9k_11n_rate_series series[],
|
||||
u32 nseries, u32 flags)
|
||||
{
|
||||
struct ar5416_desc *ads = AR5416DESC(ds);
|
||||
struct ar5416_desc *last_ads = AR5416DESC(lastds);
|
||||
u32 ds_ctl0;
|
||||
|
||||
if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
|
||||
ds_ctl0 = ads->ds_ctl0;
|
||||
|
||||
if (flags & ATH9K_TXDESC_RTSENA) {
|
||||
ds_ctl0 &= ~AR_CTSEnable;
|
||||
ds_ctl0 |= AR_RTSEnable;
|
||||
} else {
|
||||
ds_ctl0 &= ~AR_RTSEnable;
|
||||
ds_ctl0 |= AR_CTSEnable;
|
||||
}
|
||||
|
||||
ads->ds_ctl0 = ds_ctl0;
|
||||
} else {
|
||||
ads->ds_ctl0 =
|
||||
(ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable));
|
||||
}
|
||||
|
||||
ads->ds_ctl2 = set11nTries(series, 0)
|
||||
| set11nTries(series, 1)
|
||||
| set11nTries(series, 2)
|
||||
| set11nTries(series, 3)
|
||||
| (durUpdateEn ? AR_DurUpdateEna : 0)
|
||||
| SM(0, AR_BurstDur);
|
||||
|
||||
ads->ds_ctl3 = set11nRate(series, 0)
|
||||
| set11nRate(series, 1)
|
||||
| set11nRate(series, 2)
|
||||
| set11nRate(series, 3);
|
||||
|
||||
ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0)
|
||||
| set11nPktDurRTSCTS(series, 1);
|
||||
|
||||
ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2)
|
||||
| set11nPktDurRTSCTS(series, 3);
|
||||
|
||||
ads->ds_ctl7 = set11nRateFlags(series, 0)
|
||||
| set11nRateFlags(series, 1)
|
||||
| set11nRateFlags(series, 2)
|
||||
| set11nRateFlags(series, 3)
|
||||
| SM(rtsctsRate, AR_RTSCTSRate);
|
||||
last_ads->ds_ctl2 = ads->ds_ctl2;
|
||||
last_ads->ds_ctl3 = ads->ds_ctl3;
|
||||
}
|
||||
|
||||
static void ar9002_hw_set11n_aggr_first(struct ath_hw *ah, void *ds,
|
||||
u32 aggrLen)
|
||||
{
|
||||
struct ar5416_desc *ads = AR5416DESC(ds);
|
||||
|
||||
ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
|
||||
ads->ds_ctl6 &= ~AR_AggrLen;
|
||||
ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
|
||||
}
|
||||
|
||||
static void ar9002_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds,
|
||||
u32 numDelims)
|
||||
{
|
||||
struct ar5416_desc *ads = AR5416DESC(ds);
|
||||
unsigned int ctl6;
|
||||
|
||||
ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
|
||||
|
||||
ctl6 = ads->ds_ctl6;
|
||||
ctl6 &= ~AR_PadDelim;
|
||||
ctl6 |= SM(numDelims, AR_PadDelim);
|
||||
ads->ds_ctl6 = ctl6;
|
||||
}
|
||||
|
||||
static void ar9002_hw_set11n_aggr_last(struct ath_hw *ah, void *ds)
|
||||
{
|
||||
struct ar5416_desc *ads = AR5416DESC(ds);
|
||||
|
||||
ads->ds_ctl1 |= AR_IsAggr;
|
||||
ads->ds_ctl1 &= ~AR_MoreAggr;
|
||||
ads->ds_ctl6 &= ~AR_PadDelim;
|
||||
}
|
||||
|
||||
static void ar9002_hw_clr11n_aggr(struct ath_hw *ah, void *ds)
|
||||
{
|
||||
struct ar5416_desc *ads = AR5416DESC(ds);
|
||||
|
||||
ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
|
||||
}
|
||||
|
||||
static void ar9002_hw_set11n_burstduration(struct ath_hw *ah, void *ds,
|
||||
u32 burstDuration)
|
||||
{
|
||||
struct ar5416_desc *ads = AR5416DESC(ds);
|
||||
|
||||
ads->ds_ctl2 &= ~AR_BurstDur;
|
||||
ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
|
||||
}
|
||||
|
||||
static void ar9002_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds,
|
||||
u32 vmf)
|
||||
{
|
||||
struct ar5416_desc *ads = AR5416DESC(ds);
|
||||
|
||||
if (vmf)
|
||||
ads->ds_ctl0 |= AR_VirtMoreFrag;
|
||||
else
|
||||
ads->ds_ctl0 &= ~AR_VirtMoreFrag;
|
||||
}
|
||||
|
||||
void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
|
||||
u32 size, u32 flags)
|
||||
{
|
||||
struct ar5416_desc *ads = AR5416DESC(ds);
|
||||
struct ath9k_hw_capabilities *pCap = &ah->caps;
|
||||
|
||||
ads->ds_ctl1 = size & AR_BufLen;
|
||||
if (flags & ATH9K_RXDESC_INTREQ)
|
||||
ads->ds_ctl1 |= AR_RxIntrReq;
|
||||
|
||||
ads->ds_rxstatus8 &= ~AR_RxDone;
|
||||
if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
|
||||
memset(&(ads->u), 0, sizeof(ads->u));
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_setuprxdesc);
|
||||
|
||||
void ar9002_hw_attach_mac_ops(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_hw_ops *ops = ath9k_hw_ops(ah);
|
||||
|
||||
ops->rx_enable = ar9002_hw_rx_enable;
|
||||
ops->set_desc_link = ar9002_hw_set_desc_link;
|
||||
ops->get_desc_link = ar9002_hw_get_desc_link;
|
||||
ops->get_isr = ar9002_hw_get_isr;
|
||||
ops->fill_txdesc = ar9002_hw_fill_txdesc;
|
||||
ops->proc_txdesc = ar9002_hw_proc_txdesc;
|
||||
ops->set11n_txdesc = ar9002_hw_set11n_txdesc;
|
||||
ops->set11n_ratescenario = ar9002_hw_set11n_ratescenario;
|
||||
ops->set11n_aggr_first = ar9002_hw_set11n_aggr_first;
|
||||
ops->set11n_aggr_middle = ar9002_hw_set11n_aggr_middle;
|
||||
ops->set11n_aggr_last = ar9002_hw_set11n_aggr_last;
|
||||
ops->clr11n_aggr = ar9002_hw_clr11n_aggr;
|
||||
ops->set11n_burstduration = ar9002_hw_set11n_burstduration;
|
||||
ops->set11n_virtualmorefrag = ar9002_hw_set11n_virtualmorefrag;
|
||||
}
|
539
drivers/net/wireless/ath/ath9k/ar9002_phy.c
Normal file
539
drivers/net/wireless/ath/ath9k/ar9002_phy.c
Normal file
@ -0,0 +1,539 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2010 Atheros Communications Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* DOC: Programming Atheros 802.11n analog front end radios
|
||||
*
|
||||
* AR5416 MAC based PCI devices and AR518 MAC based PCI-Express
|
||||
* devices have either an external AR2133 analog front end radio for single
|
||||
* band 2.4 GHz communication or an AR5133 analog front end radio for dual
|
||||
* band 2.4 GHz / 5 GHz communication.
|
||||
*
|
||||
* All devices after the AR5416 and AR5418 family starting with the AR9280
|
||||
* have their analog front radios, MAC/BB and host PCIe/USB interface embedded
|
||||
* into a single-chip and require less programming.
|
||||
*
|
||||
* The following single-chips exist with a respective embedded radio:
|
||||
*
|
||||
* AR9280 - 11n dual-band 2x2 MIMO for PCIe
|
||||
* AR9281 - 11n single-band 1x2 MIMO for PCIe
|
||||
* AR9285 - 11n single-band 1x1 for PCIe
|
||||
* AR9287 - 11n single-band 2x2 MIMO for PCIe
|
||||
*
|
||||
* AR9220 - 11n dual-band 2x2 MIMO for PCI
|
||||
* AR9223 - 11n single-band 2x2 MIMO for PCI
|
||||
*
|
||||
* AR9287 - 11n single-band 1x1 MIMO for USB
|
||||
*/
|
||||
|
||||
#include "hw.h"
|
||||
#include "ar9002_phy.h"
|
||||
|
||||
/**
|
||||
* ar9002_hw_set_channel - set channel on single-chip device
|
||||
* @ah: atheros hardware structure
|
||||
* @chan:
|
||||
*
|
||||
* This is the function to change channel on single-chip devices, that is
|
||||
* all devices after ar9280.
|
||||
*
|
||||
* This function takes the channel value in MHz and sets
|
||||
* hardware channel value. Assumes writes have been enabled to analog bus.
|
||||
*
|
||||
* Actual Expression,
|
||||
*
|
||||
* For 2GHz channel,
|
||||
* Channel Frequency = (3/4) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17)
|
||||
* (freq_ref = 40MHz)
|
||||
*
|
||||
* For 5GHz channel,
|
||||
* Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^10)
|
||||
* (freq_ref = 40MHz/(24>>amodeRefSel))
|
||||
*/
|
||||
static int ar9002_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
|
||||
{
|
||||
u16 bMode, fracMode, aModeRefSel = 0;
|
||||
u32 freq, ndiv, channelSel = 0, channelFrac = 0, reg32 = 0;
|
||||
struct chan_centers centers;
|
||||
u32 refDivA = 24;
|
||||
|
||||
ath9k_hw_get_channel_centers(ah, chan, ¢ers);
|
||||
freq = centers.synth_center;
|
||||
|
||||
reg32 = REG_READ(ah, AR_PHY_SYNTH_CONTROL);
|
||||
reg32 &= 0xc0000000;
|
||||
|
||||
if (freq < 4800) { /* 2 GHz, fractional mode */
|
||||
u32 txctl;
|
||||
int regWrites = 0;
|
||||
|
||||
bMode = 1;
|
||||
fracMode = 1;
|
||||
aModeRefSel = 0;
|
||||
channelSel = CHANSEL_2G(freq);
|
||||
|
||||
if (AR_SREV_9287_11_OR_LATER(ah)) {
|
||||
if (freq == 2484) {
|
||||
/* Enable channel spreading for channel 14 */
|
||||
REG_WRITE_ARRAY(&ah->iniCckfirJapan2484,
|
||||
1, regWrites);
|
||||
} else {
|
||||
REG_WRITE_ARRAY(&ah->iniCckfirNormal,
|
||||
1, regWrites);
|
||||
}
|
||||
} else {
|
||||
txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL);
|
||||
if (freq == 2484) {
|
||||
/* Enable channel spreading for channel 14 */
|
||||
REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
|
||||
txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
|
||||
} else {
|
||||
REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
|
||||
txctl & ~AR_PHY_CCK_TX_CTRL_JAPAN);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bMode = 0;
|
||||
fracMode = 0;
|
||||
|
||||
switch (ah->eep_ops->get_eeprom(ah, EEP_FRAC_N_5G)) {
|
||||
case 0:
|
||||
if ((freq % 20) == 0)
|
||||
aModeRefSel = 3;
|
||||
else if ((freq % 10) == 0)
|
||||
aModeRefSel = 2;
|
||||
if (aModeRefSel)
|
||||
break;
|
||||
case 1:
|
||||
default:
|
||||
aModeRefSel = 0;
|
||||
/*
|
||||
* Enable 2G (fractional) mode for channels
|
||||
* which are 5MHz spaced.
|
||||
*/
|
||||
fracMode = 1;
|
||||
refDivA = 1;
|
||||
channelSel = CHANSEL_5G(freq);
|
||||
|
||||
/* RefDivA setting */
|
||||
REG_RMW_FIELD(ah, AR_AN_SYNTH9,
|
||||
AR_AN_SYNTH9_REFDIVA, refDivA);
|
||||
|
||||
}
|
||||
|
||||
if (!fracMode) {
|
||||
ndiv = (freq * (refDivA >> aModeRefSel)) / 60;
|
||||
channelSel = ndiv & 0x1ff;
|
||||
channelFrac = (ndiv & 0xfffffe00) * 2;
|
||||
channelSel = (channelSel << 17) | channelFrac;
|
||||
}
|
||||
}
|
||||
|
||||
reg32 = reg32 |
|
||||
(bMode << 29) |
|
||||
(fracMode << 28) | (aModeRefSel << 26) | (channelSel);
|
||||
|
||||
REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32);
|
||||
|
||||
ah->curchan = chan;
|
||||
ah->curchan_rad_index = -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ar9002_hw_spur_mitigate - convert baseband spur frequency
|
||||
* @ah: atheros hardware structure
|
||||
* @chan:
|
||||
*
|
||||
* For single-chip solutions. Converts to baseband spur frequency given the
|
||||
* input channel frequency and compute register settings below.
|
||||
*/
|
||||
static void ar9002_hw_spur_mitigate(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
int bb_spur = AR_NO_SPUR;
|
||||
int freq;
|
||||
int bin, cur_bin;
|
||||
int bb_spur_off, spur_subchannel_sd;
|
||||
int spur_freq_sd;
|
||||
int spur_delta_phase;
|
||||
int denominator;
|
||||
int upper, lower, cur_vit_mask;
|
||||
int tmp, newVal;
|
||||
int i;
|
||||
int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
|
||||
AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
|
||||
};
|
||||
int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
|
||||
AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
|
||||
};
|
||||
int inc[4] = { 0, 100, 0, 0 };
|
||||
struct chan_centers centers;
|
||||
|
||||
int8_t mask_m[123];
|
||||
int8_t mask_p[123];
|
||||
int8_t mask_amt;
|
||||
int tmp_mask;
|
||||
int cur_bb_spur;
|
||||
bool is2GHz = IS_CHAN_2GHZ(chan);
|
||||
|
||||
memset(&mask_m, 0, sizeof(int8_t) * 123);
|
||||
memset(&mask_p, 0, sizeof(int8_t) * 123);
|
||||
|
||||
ath9k_hw_get_channel_centers(ah, chan, ¢ers);
|
||||
freq = centers.synth_center;
|
||||
|
||||
ah->config.spurmode = SPUR_ENABLE_EEPROM;
|
||||
for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
|
||||
cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz);
|
||||
|
||||
if (is2GHz)
|
||||
cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ;
|
||||
else
|
||||
cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ;
|
||||
|
||||
if (AR_NO_SPUR == cur_bb_spur)
|
||||
break;
|
||||
cur_bb_spur = cur_bb_spur - freq;
|
||||
|
||||
if (IS_CHAN_HT40(chan)) {
|
||||
if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT40) &&
|
||||
(cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT40)) {
|
||||
bb_spur = cur_bb_spur;
|
||||
break;
|
||||
}
|
||||
} else if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT20) &&
|
||||
(cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT20)) {
|
||||
bb_spur = cur_bb_spur;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (AR_NO_SPUR == bb_spur) {
|
||||
REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
|
||||
AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
|
||||
return;
|
||||
} else {
|
||||
REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
|
||||
AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
|
||||
}
|
||||
|
||||
bin = bb_spur * 320;
|
||||
|
||||
tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
|
||||
|
||||
ENABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
newVal = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
|
||||
AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
|
||||
AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
|
||||
AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
|
||||
REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), newVal);
|
||||
|
||||
newVal = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
|
||||
AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
|
||||
AR_PHY_SPUR_REG_MASK_RATE_SELECT |
|
||||
AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
|
||||
SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
|
||||
REG_WRITE(ah, AR_PHY_SPUR_REG, newVal);
|
||||
|
||||
if (IS_CHAN_HT40(chan)) {
|
||||
if (bb_spur < 0) {
|
||||
spur_subchannel_sd = 1;
|
||||
bb_spur_off = bb_spur + 10;
|
||||
} else {
|
||||
spur_subchannel_sd = 0;
|
||||
bb_spur_off = bb_spur - 10;
|
||||
}
|
||||
} else {
|
||||
spur_subchannel_sd = 0;
|
||||
bb_spur_off = bb_spur;
|
||||
}
|
||||
|
||||
if (IS_CHAN_HT40(chan))
|
||||
spur_delta_phase =
|
||||
((bb_spur * 262144) /
|
||||
10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
|
||||
else
|
||||
spur_delta_phase =
|
||||
((bb_spur * 524288) /
|
||||
10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
|
||||
|
||||
denominator = IS_CHAN_2GHZ(chan) ? 44 : 40;
|
||||
spur_freq_sd = ((bb_spur_off * 2048) / denominator) & 0x3ff;
|
||||
|
||||
newVal = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
|
||||
SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
|
||||
SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
|
||||
REG_WRITE(ah, AR_PHY_TIMING11, newVal);
|
||||
|
||||
newVal = spur_subchannel_sd << AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S;
|
||||
REG_WRITE(ah, AR_PHY_SFCORR_EXT, newVal);
|
||||
|
||||
cur_bin = -6000;
|
||||
upper = bin + 100;
|
||||
lower = bin - 100;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
int pilot_mask = 0;
|
||||
int chan_mask = 0;
|
||||
int bp = 0;
|
||||
for (bp = 0; bp < 30; bp++) {
|
||||
if ((cur_bin > lower) && (cur_bin < upper)) {
|
||||
pilot_mask = pilot_mask | 0x1 << bp;
|
||||
chan_mask = chan_mask | 0x1 << bp;
|
||||
}
|
||||
cur_bin += 100;
|
||||
}
|
||||
cur_bin += inc[i];
|
||||
REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
|
||||
REG_WRITE(ah, chan_mask_reg[i], chan_mask);
|
||||
}
|
||||
|
||||
cur_vit_mask = 6100;
|
||||
upper = bin + 120;
|
||||
lower = bin - 120;
|
||||
|
||||
for (i = 0; i < 123; i++) {
|
||||
if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
|
||||
|
||||
/* workaround for gcc bug #37014 */
|
||||
volatile int tmp_v = abs(cur_vit_mask - bin);
|
||||
|
||||
if (tmp_v < 75)
|
||||
mask_amt = 1;
|
||||
else
|
||||
mask_amt = 0;
|
||||
if (cur_vit_mask < 0)
|
||||
mask_m[abs(cur_vit_mask / 100)] = mask_amt;
|
||||
else
|
||||
mask_p[cur_vit_mask / 100] = mask_amt;
|
||||
}
|
||||
cur_vit_mask -= 100;
|
||||
}
|
||||
|
||||
tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
|
||||
| (mask_m[48] << 26) | (mask_m[49] << 24)
|
||||
| (mask_m[50] << 22) | (mask_m[51] << 20)
|
||||
| (mask_m[52] << 18) | (mask_m[53] << 16)
|
||||
| (mask_m[54] << 14) | (mask_m[55] << 12)
|
||||
| (mask_m[56] << 10) | (mask_m[57] << 8)
|
||||
| (mask_m[58] << 6) | (mask_m[59] << 4)
|
||||
| (mask_m[60] << 2) | (mask_m[61] << 0);
|
||||
REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
|
||||
REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
|
||||
|
||||
tmp_mask = (mask_m[31] << 28)
|
||||
| (mask_m[32] << 26) | (mask_m[33] << 24)
|
||||
| (mask_m[34] << 22) | (mask_m[35] << 20)
|
||||
| (mask_m[36] << 18) | (mask_m[37] << 16)
|
||||
| (mask_m[48] << 14) | (mask_m[39] << 12)
|
||||
| (mask_m[40] << 10) | (mask_m[41] << 8)
|
||||
| (mask_m[42] << 6) | (mask_m[43] << 4)
|
||||
| (mask_m[44] << 2) | (mask_m[45] << 0);
|
||||
REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
|
||||
REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
|
||||
|
||||
tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
|
||||
| (mask_m[18] << 26) | (mask_m[18] << 24)
|
||||
| (mask_m[20] << 22) | (mask_m[20] << 20)
|
||||
| (mask_m[22] << 18) | (mask_m[22] << 16)
|
||||
| (mask_m[24] << 14) | (mask_m[24] << 12)
|
||||
| (mask_m[25] << 10) | (mask_m[26] << 8)
|
||||
| (mask_m[27] << 6) | (mask_m[28] << 4)
|
||||
| (mask_m[29] << 2) | (mask_m[30] << 0);
|
||||
REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
|
||||
REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
|
||||
|
||||
tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
|
||||
| (mask_m[2] << 26) | (mask_m[3] << 24)
|
||||
| (mask_m[4] << 22) | (mask_m[5] << 20)
|
||||
| (mask_m[6] << 18) | (mask_m[7] << 16)
|
||||
| (mask_m[8] << 14) | (mask_m[9] << 12)
|
||||
| (mask_m[10] << 10) | (mask_m[11] << 8)
|
||||
| (mask_m[12] << 6) | (mask_m[13] << 4)
|
||||
| (mask_m[14] << 2) | (mask_m[15] << 0);
|
||||
REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
|
||||
REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
|
||||
|
||||
tmp_mask = (mask_p[15] << 28)
|
||||
| (mask_p[14] << 26) | (mask_p[13] << 24)
|
||||
| (mask_p[12] << 22) | (mask_p[11] << 20)
|
||||
| (mask_p[10] << 18) | (mask_p[9] << 16)
|
||||
| (mask_p[8] << 14) | (mask_p[7] << 12)
|
||||
| (mask_p[6] << 10) | (mask_p[5] << 8)
|
||||
| (mask_p[4] << 6) | (mask_p[3] << 4)
|
||||
| (mask_p[2] << 2) | (mask_p[1] << 0);
|
||||
REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
|
||||
REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
|
||||
|
||||
tmp_mask = (mask_p[30] << 28)
|
||||
| (mask_p[29] << 26) | (mask_p[28] << 24)
|
||||
| (mask_p[27] << 22) | (mask_p[26] << 20)
|
||||
| (mask_p[25] << 18) | (mask_p[24] << 16)
|
||||
| (mask_p[23] << 14) | (mask_p[22] << 12)
|
||||
| (mask_p[21] << 10) | (mask_p[20] << 8)
|
||||
| (mask_p[19] << 6) | (mask_p[18] << 4)
|
||||
| (mask_p[17] << 2) | (mask_p[16] << 0);
|
||||
REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
|
||||
REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
|
||||
|
||||
tmp_mask = (mask_p[45] << 28)
|
||||
| (mask_p[44] << 26) | (mask_p[43] << 24)
|
||||
| (mask_p[42] << 22) | (mask_p[41] << 20)
|
||||
| (mask_p[40] << 18) | (mask_p[39] << 16)
|
||||
| (mask_p[38] << 14) | (mask_p[37] << 12)
|
||||
| (mask_p[36] << 10) | (mask_p[35] << 8)
|
||||
| (mask_p[34] << 6) | (mask_p[33] << 4)
|
||||
| (mask_p[32] << 2) | (mask_p[31] << 0);
|
||||
REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
|
||||
REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
|
||||
|
||||
tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
|
||||
| (mask_p[59] << 26) | (mask_p[58] << 24)
|
||||
| (mask_p[57] << 22) | (mask_p[56] << 20)
|
||||
| (mask_p[55] << 18) | (mask_p[54] << 16)
|
||||
| (mask_p[53] << 14) | (mask_p[52] << 12)
|
||||
| (mask_p[51] << 10) | (mask_p[50] << 8)
|
||||
| (mask_p[49] << 6) | (mask_p[48] << 4)
|
||||
| (mask_p[47] << 2) | (mask_p[46] << 0);
|
||||
REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
|
||||
REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
}
|
||||
|
||||
static void ar9002_olc_init(struct ath_hw *ah)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
if (!OLC_FOR_AR9280_20_LATER)
|
||||
return;
|
||||
|
||||
if (OLC_FOR_AR9287_10_LATER) {
|
||||
REG_SET_BIT(ah, AR_PHY_TX_PWRCTRL9,
|
||||
AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL);
|
||||
ath9k_hw_analog_shift_rmw(ah, AR9287_AN_TXPC0,
|
||||
AR9287_AN_TXPC0_TXPCMODE,
|
||||
AR9287_AN_TXPC0_TXPCMODE_S,
|
||||
AR9287_AN_TXPC0_TXPCMODE_TEMPSENSE);
|
||||
udelay(100);
|
||||
} else {
|
||||
for (i = 0; i < AR9280_TX_GAIN_TABLE_SIZE; i++)
|
||||
ah->originalGain[i] =
|
||||
MS(REG_READ(ah, AR_PHY_TX_GAIN_TBL1 + i * 4),
|
||||
AR_PHY_TX_GAIN);
|
||||
ah->PDADCdelta = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static u32 ar9002_hw_compute_pll_control(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
u32 pll;
|
||||
|
||||
pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
|
||||
|
||||
if (chan && IS_CHAN_HALF_RATE(chan))
|
||||
pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
|
||||
else if (chan && IS_CHAN_QUARTER_RATE(chan))
|
||||
pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
|
||||
|
||||
if (chan && IS_CHAN_5GHZ(chan)) {
|
||||
pll |= SM(0x28, AR_RTC_9160_PLL_DIV);
|
||||
|
||||
|
||||
if (AR_SREV_9280_20(ah)) {
|
||||
if (((chan->channel % 20) == 0)
|
||||
|| ((chan->channel % 10) == 0))
|
||||
pll = 0x2850;
|
||||
else
|
||||
pll = 0x142c;
|
||||
}
|
||||
} else {
|
||||
pll |= SM(0x2c, AR_RTC_9160_PLL_DIV);
|
||||
}
|
||||
|
||||
return pll;
|
||||
}
|
||||
|
||||
static void ar9002_hw_do_getnf(struct ath_hw *ah,
|
||||
int16_t nfarray[NUM_NF_READINGS])
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
int16_t nf;
|
||||
|
||||
nf = MS(REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR);
|
||||
|
||||
if (nf & 0x100)
|
||||
nf = 0 - ((nf ^ 0x1ff) + 1);
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"NF calibrated [ctl] [chain 0] is %d\n", nf);
|
||||
|
||||
if (AR_SREV_9271(ah) && (nf >= -114))
|
||||
nf = -116;
|
||||
|
||||
nfarray[0] = nf;
|
||||
|
||||
if (!AR_SREV_9285(ah) && !AR_SREV_9271(ah)) {
|
||||
nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
|
||||
AR9280_PHY_CH1_MINCCA_PWR);
|
||||
|
||||
if (nf & 0x100)
|
||||
nf = 0 - ((nf ^ 0x1ff) + 1);
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"NF calibrated [ctl] [chain 1] is %d\n", nf);
|
||||
nfarray[1] = nf;
|
||||
}
|
||||
|
||||
nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR9280_PHY_EXT_MINCCA_PWR);
|
||||
if (nf & 0x100)
|
||||
nf = 0 - ((nf ^ 0x1ff) + 1);
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"NF calibrated [ext] [chain 0] is %d\n", nf);
|
||||
|
||||
if (AR_SREV_9271(ah) && (nf >= -114))
|
||||
nf = -116;
|
||||
|
||||
nfarray[3] = nf;
|
||||
|
||||
if (!AR_SREV_9285(ah) && !AR_SREV_9271(ah)) {
|
||||
nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
|
||||
AR9280_PHY_CH1_EXT_MINCCA_PWR);
|
||||
|
||||
if (nf & 0x100)
|
||||
nf = 0 - ((nf ^ 0x1ff) + 1);
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"NF calibrated [ext] [chain 1] is %d\n", nf);
|
||||
nfarray[4] = nf;
|
||||
}
|
||||
}
|
||||
|
||||
void ar9002_hw_attach_phy_ops(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
|
||||
|
||||
priv_ops->set_rf_regs = NULL;
|
||||
priv_ops->rf_alloc_ext_banks = NULL;
|
||||
priv_ops->rf_free_ext_banks = NULL;
|
||||
priv_ops->rf_set_freq = ar9002_hw_set_channel;
|
||||
priv_ops->spur_mitigate_freq = ar9002_hw_spur_mitigate;
|
||||
priv_ops->olc_init = ar9002_olc_init;
|
||||
priv_ops->compute_pll_control = ar9002_hw_compute_pll_control;
|
||||
priv_ops->do_getnf = ar9002_hw_do_getnf;
|
||||
}
|
572
drivers/net/wireless/ath/ath9k/ar9002_phy.h
Normal file
572
drivers/net/wireless/ath/ath9k/ar9002_phy.h
Normal file
@ -0,0 +1,572 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2010 Atheros Communications Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifndef AR9002_PHY_H
|
||||
#define AR9002_PHY_H
|
||||
|
||||
#define AR_PHY_TEST 0x9800
|
||||
#define PHY_AGC_CLR 0x10000000
|
||||
#define RFSILENT_BB 0x00002000
|
||||
|
||||
#define AR_PHY_TURBO 0x9804
|
||||
#define AR_PHY_FC_TURBO_MODE 0x00000001
|
||||
#define AR_PHY_FC_TURBO_SHORT 0x00000002
|
||||
#define AR_PHY_FC_DYN2040_EN 0x00000004
|
||||
#define AR_PHY_FC_DYN2040_PRI_ONLY 0x00000008
|
||||
#define AR_PHY_FC_DYN2040_PRI_CH 0x00000010
|
||||
/* For 25 MHz channel spacing -- not used but supported by hw */
|
||||
#define AR_PHY_FC_DYN2040_EXT_CH 0x00000020
|
||||
#define AR_PHY_FC_HT_EN 0x00000040
|
||||
#define AR_PHY_FC_SHORT_GI_40 0x00000080
|
||||
#define AR_PHY_FC_WALSH 0x00000100
|
||||
#define AR_PHY_FC_SINGLE_HT_LTF1 0x00000200
|
||||
#define AR_PHY_FC_ENABLE_DAC_FIFO 0x00000800
|
||||
|
||||
#define AR_PHY_TEST2 0x9808
|
||||
|
||||
#define AR_PHY_TIMING2 0x9810
|
||||
#define AR_PHY_TIMING3 0x9814
|
||||
#define AR_PHY_TIMING3_DSC_MAN 0xFFFE0000
|
||||
#define AR_PHY_TIMING3_DSC_MAN_S 17
|
||||
#define AR_PHY_TIMING3_DSC_EXP 0x0001E000
|
||||
#define AR_PHY_TIMING3_DSC_EXP_S 13
|
||||
|
||||
#define AR_PHY_CHIP_ID_REV_0 0x80
|
||||
#define AR_PHY_CHIP_ID_REV_1 0x81
|
||||
#define AR_PHY_CHIP_ID_9160_REV_0 0xb0
|
||||
|
||||
#define AR_PHY_ACTIVE 0x981C
|
||||
#define AR_PHY_ACTIVE_EN 0x00000001
|
||||
#define AR_PHY_ACTIVE_DIS 0x00000000
|
||||
|
||||
#define AR_PHY_RF_CTL2 0x9824
|
||||
#define AR_PHY_TX_END_DATA_START 0x000000FF
|
||||
#define AR_PHY_TX_END_DATA_START_S 0
|
||||
#define AR_PHY_TX_END_PA_ON 0x0000FF00
|
||||
#define AR_PHY_TX_END_PA_ON_S 8
|
||||
|
||||
#define AR_PHY_RF_CTL3 0x9828
|
||||
#define AR_PHY_TX_END_TO_A2_RX_ON 0x00FF0000
|
||||
#define AR_PHY_TX_END_TO_A2_RX_ON_S 16
|
||||
|
||||
#define AR_PHY_ADC_CTL 0x982C
|
||||
#define AR_PHY_ADC_CTL_OFF_INBUFGAIN 0x00000003
|
||||
#define AR_PHY_ADC_CTL_OFF_INBUFGAIN_S 0
|
||||
#define AR_PHY_ADC_CTL_OFF_PWDDAC 0x00002000
|
||||
#define AR_PHY_ADC_CTL_OFF_PWDBANDGAP 0x00004000
|
||||
#define AR_PHY_ADC_CTL_OFF_PWDADC 0x00008000
|
||||
#define AR_PHY_ADC_CTL_ON_INBUFGAIN 0x00030000
|
||||
#define AR_PHY_ADC_CTL_ON_INBUFGAIN_S 16
|
||||
|
||||
#define AR_PHY_ADC_SERIAL_CTL 0x9830
|
||||
#define AR_PHY_SEL_INTERNAL_ADDAC 0x00000000
|
||||
#define AR_PHY_SEL_EXTERNAL_RADIO 0x00000001
|
||||
|
||||
#define AR_PHY_RF_CTL4 0x9834
|
||||
#define AR_PHY_RF_CTL4_TX_END_XPAB_OFF 0xFF000000
|
||||
#define AR_PHY_RF_CTL4_TX_END_XPAB_OFF_S 24
|
||||
#define AR_PHY_RF_CTL4_TX_END_XPAA_OFF 0x00FF0000
|
||||
#define AR_PHY_RF_CTL4_TX_END_XPAA_OFF_S 16
|
||||
#define AR_PHY_RF_CTL4_FRAME_XPAB_ON 0x0000FF00
|
||||
#define AR_PHY_RF_CTL4_FRAME_XPAB_ON_S 8
|
||||
#define AR_PHY_RF_CTL4_FRAME_XPAA_ON 0x000000FF
|
||||
#define AR_PHY_RF_CTL4_FRAME_XPAA_ON_S 0
|
||||
|
||||
#define AR_PHY_TSTDAC_CONST 0x983c
|
||||
|
||||
#define AR_PHY_SETTLING 0x9844
|
||||
#define AR_PHY_SETTLING_SWITCH 0x00003F80
|
||||
#define AR_PHY_SETTLING_SWITCH_S 7
|
||||
|
||||
#define AR_PHY_RXGAIN 0x9848
|
||||
#define AR_PHY_RXGAIN_TXRX_ATTEN 0x0003F000
|
||||
#define AR_PHY_RXGAIN_TXRX_ATTEN_S 12
|
||||
#define AR_PHY_RXGAIN_TXRX_RF_MAX 0x007C0000
|
||||
#define AR_PHY_RXGAIN_TXRX_RF_MAX_S 18
|
||||
#define AR9280_PHY_RXGAIN_TXRX_ATTEN 0x00003F80
|
||||
#define AR9280_PHY_RXGAIN_TXRX_ATTEN_S 7
|
||||
#define AR9280_PHY_RXGAIN_TXRX_MARGIN 0x001FC000
|
||||
#define AR9280_PHY_RXGAIN_TXRX_MARGIN_S 14
|
||||
|
||||
#define AR_PHY_DESIRED_SZ 0x9850
|
||||
#define AR_PHY_DESIRED_SZ_ADC 0x000000FF
|
||||
#define AR_PHY_DESIRED_SZ_ADC_S 0
|
||||
#define AR_PHY_DESIRED_SZ_PGA 0x0000FF00
|
||||
#define AR_PHY_DESIRED_SZ_PGA_S 8
|
||||
#define AR_PHY_DESIRED_SZ_TOT_DES 0x0FF00000
|
||||
#define AR_PHY_DESIRED_SZ_TOT_DES_S 20
|
||||
|
||||
#define AR_PHY_FIND_SIG 0x9858
|
||||
#define AR_PHY_FIND_SIG_FIRSTEP 0x0003F000
|
||||
#define AR_PHY_FIND_SIG_FIRSTEP_S 12
|
||||
#define AR_PHY_FIND_SIG_FIRPWR 0x03FC0000
|
||||
#define AR_PHY_FIND_SIG_FIRPWR_S 18
|
||||
|
||||
#define AR_PHY_AGC_CTL1 0x985C
|
||||
#define AR_PHY_AGC_CTL1_COARSE_LOW 0x00007F80
|
||||
#define AR_PHY_AGC_CTL1_COARSE_LOW_S 7
|
||||
#define AR_PHY_AGC_CTL1_COARSE_HIGH 0x003F8000
|
||||
#define AR_PHY_AGC_CTL1_COARSE_HIGH_S 15
|
||||
|
||||
#define AR_PHY_CCA 0x9864
|
||||
#define AR_PHY_MINCCA_PWR 0x0FF80000
|
||||
#define AR_PHY_MINCCA_PWR_S 19
|
||||
#define AR_PHY_CCA_THRESH62 0x0007F000
|
||||
#define AR_PHY_CCA_THRESH62_S 12
|
||||
#define AR9280_PHY_MINCCA_PWR 0x1FF00000
|
||||
#define AR9280_PHY_MINCCA_PWR_S 20
|
||||
#define AR9280_PHY_CCA_THRESH62 0x000FF000
|
||||
#define AR9280_PHY_CCA_THRESH62_S 12
|
||||
|
||||
#define AR_PHY_SFCORR_LOW 0x986C
|
||||
#define AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW 0x00000001
|
||||
#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW 0x00003F00
|
||||
#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW_S 8
|
||||
#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW 0x001FC000
|
||||
#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW_S 14
|
||||
#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW 0x0FE00000
|
||||
#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW_S 21
|
||||
|
||||
#define AR_PHY_SFCORR 0x9868
|
||||
#define AR_PHY_SFCORR_M2COUNT_THR 0x0000001F
|
||||
#define AR_PHY_SFCORR_M2COUNT_THR_S 0
|
||||
#define AR_PHY_SFCORR_M1_THRESH 0x00FE0000
|
||||
#define AR_PHY_SFCORR_M1_THRESH_S 17
|
||||
#define AR_PHY_SFCORR_M2_THRESH 0x7F000000
|
||||
#define AR_PHY_SFCORR_M2_THRESH_S 24
|
||||
|
||||
#define AR_PHY_SLEEP_CTR_CONTROL 0x9870
|
||||
#define AR_PHY_SLEEP_CTR_LIMIT 0x9874
|
||||
#define AR_PHY_SYNTH_CONTROL 0x9874
|
||||
#define AR_PHY_SLEEP_SCAL 0x9878
|
||||
|
||||
#define AR_PHY_PLL_CTL 0x987c
|
||||
#define AR_PHY_PLL_CTL_40 0xaa
|
||||
#define AR_PHY_PLL_CTL_40_5413 0x04
|
||||
#define AR_PHY_PLL_CTL_44 0xab
|
||||
#define AR_PHY_PLL_CTL_44_2133 0xeb
|
||||
#define AR_PHY_PLL_CTL_40_2133 0xea
|
||||
|
||||
#define AR_PHY_SPECTRAL_SCAN 0x9910 /* AR9280 spectral scan configuration register */
|
||||
#define AR_PHY_SPECTRAL_SCAN_ENABLE 0x1
|
||||
#define AR_PHY_SPECTRAL_SCAN_ENA 0x00000001 /* Enable spectral scan, reg 68, bit 0 */
|
||||
#define AR_PHY_SPECTRAL_SCAN_ENA_S 0 /* Enable spectral scan, reg 68, bit 0 */
|
||||
#define AR_PHY_SPECTRAL_SCAN_ACTIVE 0x00000002 /* Activate spectral scan reg 68, bit 1*/
|
||||
#define AR_PHY_SPECTRAL_SCAN_ACTIVE_S 1 /* Activate spectral scan reg 68, bit 1*/
|
||||
#define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD 0x000000F0 /* Interval for FFT reports, reg 68, bits 4-7*/
|
||||
#define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD_S 4
|
||||
#define AR_PHY_SPECTRAL_SCAN_PERIOD 0x0000FF00 /* Interval for FFT reports, reg 68, bits 8-15*/
|
||||
#define AR_PHY_SPECTRAL_SCAN_PERIOD_S 8
|
||||
#define AR_PHY_SPECTRAL_SCAN_COUNT 0x00FF0000 /* Number of reports, reg 68, bits 16-23*/
|
||||
#define AR_PHY_SPECTRAL_SCAN_COUNT_S 16
|
||||
#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT 0x01000000 /* Short repeat, reg 68, bit 24*/
|
||||
#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S 24 /* Short repeat, reg 68, bit 24*/
|
||||
|
||||
#define AR_PHY_RX_DELAY 0x9914
|
||||
#define AR_PHY_SEARCH_START_DELAY 0x9918
|
||||
#define AR_PHY_RX_DELAY_DELAY 0x00003FFF
|
||||
|
||||
#define AR_PHY_TIMING_CTRL4(_i) (0x9920 + ((_i) << 12))
|
||||
#define AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF 0x01F
|
||||
#define AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF_S 0
|
||||
#define AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF 0x7E0
|
||||
#define AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF_S 5
|
||||
#define AR_PHY_TIMING_CTRL4_IQCORR_ENABLE 0x800
|
||||
#define AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX 0xF000
|
||||
#define AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX_S 12
|
||||
#define AR_PHY_TIMING_CTRL4_DO_CAL 0x10000
|
||||
|
||||
#define AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI 0x80000000
|
||||
#define AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER 0x40000000
|
||||
#define AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK 0x20000000
|
||||
#define AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK 0x10000000
|
||||
|
||||
#define AR_PHY_TIMING5 0x9924
|
||||
#define AR_PHY_TIMING5_CYCPWR_THR1 0x000000FE
|
||||
#define AR_PHY_TIMING5_CYCPWR_THR1_S 1
|
||||
|
||||
#define AR_PHY_POWER_TX_RATE1 0x9934
|
||||
#define AR_PHY_POWER_TX_RATE2 0x9938
|
||||
#define AR_PHY_POWER_TX_RATE_MAX 0x993c
|
||||
#define AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE 0x00000040
|
||||
|
||||
#define AR_PHY_FRAME_CTL 0x9944
|
||||
#define AR_PHY_FRAME_CTL_TX_CLIP 0x00000038
|
||||
#define AR_PHY_FRAME_CTL_TX_CLIP_S 3
|
||||
|
||||
#define AR_PHY_TXPWRADJ 0x994C
|
||||
#define AR_PHY_TXPWRADJ_CCK_GAIN_DELTA 0x00000FC0
|
||||
#define AR_PHY_TXPWRADJ_CCK_GAIN_DELTA_S 6
|
||||
#define AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX 0x00FC0000
|
||||
#define AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX_S 18
|
||||
|
||||
#define AR_PHY_RADAR_EXT 0x9940
|
||||
#define AR_PHY_RADAR_EXT_ENA 0x00004000
|
||||
|
||||
#define AR_PHY_RADAR_0 0x9954
|
||||
#define AR_PHY_RADAR_0_ENA 0x00000001
|
||||
#define AR_PHY_RADAR_0_FFT_ENA 0x80000000
|
||||
#define AR_PHY_RADAR_0_INBAND 0x0000003e
|
||||
#define AR_PHY_RADAR_0_INBAND_S 1
|
||||
#define AR_PHY_RADAR_0_PRSSI 0x00000FC0
|
||||
#define AR_PHY_RADAR_0_PRSSI_S 6
|
||||
#define AR_PHY_RADAR_0_HEIGHT 0x0003F000
|
||||
#define AR_PHY_RADAR_0_HEIGHT_S 12
|
||||
#define AR_PHY_RADAR_0_RRSSI 0x00FC0000
|
||||
#define AR_PHY_RADAR_0_RRSSI_S 18
|
||||
#define AR_PHY_RADAR_0_FIRPWR 0x7F000000
|
||||
#define AR_PHY_RADAR_0_FIRPWR_S 24
|
||||
|
||||
#define AR_PHY_RADAR_1 0x9958
|
||||
#define AR_PHY_RADAR_1_RELPWR_ENA 0x00800000
|
||||
#define AR_PHY_RADAR_1_USE_FIR128 0x00400000
|
||||
#define AR_PHY_RADAR_1_RELPWR_THRESH 0x003F0000
|
||||
#define AR_PHY_RADAR_1_RELPWR_THRESH_S 16
|
||||
#define AR_PHY_RADAR_1_BLOCK_CHECK 0x00008000
|
||||
#define AR_PHY_RADAR_1_MAX_RRSSI 0x00004000
|
||||
#define AR_PHY_RADAR_1_RELSTEP_CHECK 0x00002000
|
||||
#define AR_PHY_RADAR_1_RELSTEP_THRESH 0x00001F00
|
||||
#define AR_PHY_RADAR_1_RELSTEP_THRESH_S 8
|
||||
#define AR_PHY_RADAR_1_MAXLEN 0x000000FF
|
||||
#define AR_PHY_RADAR_1_MAXLEN_S 0
|
||||
|
||||
#define AR_PHY_SWITCH_CHAIN_0 0x9960
|
||||
#define AR_PHY_SWITCH_COM 0x9964
|
||||
|
||||
#define AR_PHY_SIGMA_DELTA 0x996C
|
||||
#define AR_PHY_SIGMA_DELTA_ADC_SEL 0x00000003
|
||||
#define AR_PHY_SIGMA_DELTA_ADC_SEL_S 0
|
||||
#define AR_PHY_SIGMA_DELTA_FILT2 0x000000F8
|
||||
#define AR_PHY_SIGMA_DELTA_FILT2_S 3
|
||||
#define AR_PHY_SIGMA_DELTA_FILT1 0x00001F00
|
||||
#define AR_PHY_SIGMA_DELTA_FILT1_S 8
|
||||
#define AR_PHY_SIGMA_DELTA_ADC_CLIP 0x01FFE000
|
||||
#define AR_PHY_SIGMA_DELTA_ADC_CLIP_S 13
|
||||
|
||||
#define AR_PHY_RESTART 0x9970
|
||||
#define AR_PHY_RESTART_DIV_GC 0x001C0000
|
||||
#define AR_PHY_RESTART_DIV_GC_S 18
|
||||
|
||||
#define AR_PHY_RFBUS_REQ 0x997C
|
||||
#define AR_PHY_RFBUS_REQ_EN 0x00000001
|
||||
|
||||
#define AR_PHY_TIMING7 0x9980
|
||||
#define AR_PHY_TIMING8 0x9984
|
||||
#define AR_PHY_TIMING8_PILOT_MASK_2 0x000FFFFF
|
||||
#define AR_PHY_TIMING8_PILOT_MASK_2_S 0
|
||||
|
||||
#define AR_PHY_BIN_MASK2_1 0x9988
|
||||
#define AR_PHY_BIN_MASK2_2 0x998c
|
||||
#define AR_PHY_BIN_MASK2_3 0x9990
|
||||
#define AR_PHY_BIN_MASK2_4 0x9994
|
||||
|
||||
#define AR_PHY_BIN_MASK_1 0x9900
|
||||
#define AR_PHY_BIN_MASK_2 0x9904
|
||||
#define AR_PHY_BIN_MASK_3 0x9908
|
||||
|
||||
#define AR_PHY_MASK_CTL 0x990c
|
||||
|
||||
#define AR_PHY_BIN_MASK2_4_MASK_4 0x00003FFF
|
||||
#define AR_PHY_BIN_MASK2_4_MASK_4_S 0
|
||||
|
||||
#define AR_PHY_TIMING9 0x9998
|
||||
#define AR_PHY_TIMING10 0x999c
|
||||
#define AR_PHY_TIMING10_PILOT_MASK_2 0x000FFFFF
|
||||
#define AR_PHY_TIMING10_PILOT_MASK_2_S 0
|
||||
|
||||
#define AR_PHY_TIMING11 0x99a0
|
||||
#define AR_PHY_TIMING11_SPUR_DELTA_PHASE 0x000FFFFF
|
||||
#define AR_PHY_TIMING11_SPUR_DELTA_PHASE_S 0
|
||||
#define AR_PHY_TIMING11_USE_SPUR_IN_AGC 0x40000000
|
||||
#define AR_PHY_TIMING11_USE_SPUR_IN_SELFCOR 0x80000000
|
||||
|
||||
#define AR_PHY_RX_CHAINMASK 0x99a4
|
||||
#define AR_PHY_NEW_ADC_DC_GAIN_CORR(_i) (0x99b4 + ((_i) << 12))
|
||||
#define AR_PHY_NEW_ADC_GAIN_CORR_ENABLE 0x40000000
|
||||
#define AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE 0x80000000
|
||||
|
||||
#define AR_PHY_MULTICHAIN_GAIN_CTL 0x99ac
|
||||
#define AR_PHY_9285_ANT_DIV_CTL_ALL 0x7f000000
|
||||
#define AR_PHY_9285_ANT_DIV_CTL 0x01000000
|
||||
#define AR_PHY_9285_ANT_DIV_CTL_S 24
|
||||
#define AR_PHY_9285_ANT_DIV_ALT_LNACONF 0x06000000
|
||||
#define AR_PHY_9285_ANT_DIV_ALT_LNACONF_S 25
|
||||
#define AR_PHY_9285_ANT_DIV_MAIN_LNACONF 0x18000000
|
||||
#define AR_PHY_9285_ANT_DIV_MAIN_LNACONF_S 27
|
||||
#define AR_PHY_9285_ANT_DIV_ALT_GAINTB 0x20000000
|
||||
#define AR_PHY_9285_ANT_DIV_ALT_GAINTB_S 29
|
||||
#define AR_PHY_9285_ANT_DIV_MAIN_GAINTB 0x40000000
|
||||
#define AR_PHY_9285_ANT_DIV_MAIN_GAINTB_S 30
|
||||
#define AR_PHY_9285_ANT_DIV_LNA1 2
|
||||
#define AR_PHY_9285_ANT_DIV_LNA2 1
|
||||
#define AR_PHY_9285_ANT_DIV_LNA1_PLUS_LNA2 3
|
||||
#define AR_PHY_9285_ANT_DIV_LNA1_MINUS_LNA2 0
|
||||
#define AR_PHY_9285_ANT_DIV_GAINTB_0 0
|
||||
#define AR_PHY_9285_ANT_DIV_GAINTB_1 1
|
||||
|
||||
#define AR_PHY_EXT_CCA0 0x99b8
|
||||
#define AR_PHY_EXT_CCA0_THRESH62 0x000000FF
|
||||
#define AR_PHY_EXT_CCA0_THRESH62_S 0
|
||||
|
||||
#define AR_PHY_EXT_CCA 0x99bc
|
||||
#define AR_PHY_EXT_CCA_CYCPWR_THR1 0x0000FE00
|
||||
#define AR_PHY_EXT_CCA_CYCPWR_THR1_S 9
|
||||
#define AR_PHY_EXT_CCA_THRESH62 0x007F0000
|
||||
#define AR_PHY_EXT_CCA_THRESH62_S 16
|
||||
#define AR_PHY_EXT_MINCCA_PWR 0xFF800000
|
||||
#define AR_PHY_EXT_MINCCA_PWR_S 23
|
||||
#define AR9280_PHY_EXT_MINCCA_PWR 0x01FF0000
|
||||
#define AR9280_PHY_EXT_MINCCA_PWR_S 16
|
||||
|
||||
#define AR_PHY_SFCORR_EXT 0x99c0
|
||||
#define AR_PHY_SFCORR_EXT_M1_THRESH 0x0000007F
|
||||
#define AR_PHY_SFCORR_EXT_M1_THRESH_S 0
|
||||
#define AR_PHY_SFCORR_EXT_M2_THRESH 0x00003F80
|
||||
#define AR_PHY_SFCORR_EXT_M2_THRESH_S 7
|
||||
#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW 0x001FC000
|
||||
#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW_S 14
|
||||
#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW 0x0FE00000
|
||||
#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW_S 21
|
||||
#define AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S 28
|
||||
|
||||
#define AR_PHY_HALFGI 0x99D0
|
||||
#define AR_PHY_HALFGI_DSC_MAN 0x0007FFF0
|
||||
#define AR_PHY_HALFGI_DSC_MAN_S 4
|
||||
#define AR_PHY_HALFGI_DSC_EXP 0x0000000F
|
||||
#define AR_PHY_HALFGI_DSC_EXP_S 0
|
||||
|
||||
#define AR_PHY_CHAN_INFO_MEMORY 0x99DC
|
||||
#define AR_PHY_CHAN_INFO_MEMORY_CAPTURE_MASK 0x0001
|
||||
|
||||
#define AR_PHY_HEAVY_CLIP_ENABLE 0x99E0
|
||||
|
||||
#define AR_PHY_HEAVY_CLIP_FACTOR_RIFS 0x99EC
|
||||
#define AR_PHY_RIFS_INIT_DELAY 0x03ff0000
|
||||
|
||||
#define AR_PHY_M_SLEEP 0x99f0
|
||||
#define AR_PHY_REFCLKDLY 0x99f4
|
||||
#define AR_PHY_REFCLKPD 0x99f8
|
||||
|
||||
#define AR_PHY_CALMODE 0x99f0
|
||||
|
||||
#define AR_PHY_CALMODE_IQ 0x00000000
|
||||
#define AR_PHY_CALMODE_ADC_GAIN 0x00000001
|
||||
#define AR_PHY_CALMODE_ADC_DC_PER 0x00000002
|
||||
#define AR_PHY_CALMODE_ADC_DC_INIT 0x00000003
|
||||
|
||||
#define AR_PHY_CAL_MEAS_0(_i) (0x9c10 + ((_i) << 12))
|
||||
#define AR_PHY_CAL_MEAS_1(_i) (0x9c14 + ((_i) << 12))
|
||||
#define AR_PHY_CAL_MEAS_2(_i) (0x9c18 + ((_i) << 12))
|
||||
#define AR_PHY_CAL_MEAS_3(_i) (0x9c1c + ((_i) << 12))
|
||||
|
||||
#define AR_PHY_CURRENT_RSSI 0x9c1c
|
||||
#define AR9280_PHY_CURRENT_RSSI 0x9c3c
|
||||
|
||||
#define AR_PHY_RFBUS_GRANT 0x9C20
|
||||
#define AR_PHY_RFBUS_GRANT_EN 0x00000001
|
||||
|
||||
#define AR_PHY_CHAN_INFO_GAIN_DIFF 0x9CF4
|
||||
#define AR_PHY_CHAN_INFO_GAIN_DIFF_UPPER_LIMIT 320
|
||||
|
||||
#define AR_PHY_CHAN_INFO_GAIN 0x9CFC
|
||||
|
||||
#define AR_PHY_MODE 0xA200
|
||||
#define AR_PHY_MODE_ASYNCFIFO 0x80
|
||||
#define AR_PHY_MODE_AR2133 0x08
|
||||
#define AR_PHY_MODE_AR5111 0x00
|
||||
#define AR_PHY_MODE_AR5112 0x08
|
||||
#define AR_PHY_MODE_DYNAMIC 0x04
|
||||
#define AR_PHY_MODE_RF2GHZ 0x02
|
||||
#define AR_PHY_MODE_RF5GHZ 0x00
|
||||
#define AR_PHY_MODE_CCK 0x01
|
||||
#define AR_PHY_MODE_OFDM 0x00
|
||||
#define AR_PHY_MODE_DYN_CCK_DISABLE 0x100
|
||||
|
||||
#define AR_PHY_CCK_TX_CTRL 0xA204
|
||||
#define AR_PHY_CCK_TX_CTRL_JAPAN 0x00000010
|
||||
#define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK 0x0000000C
|
||||
#define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK_S 2
|
||||
|
||||
#define AR_PHY_CCK_DETECT 0xA208
|
||||
#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK 0x0000003F
|
||||
#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_S 0
|
||||
/* [12:6] settling time for antenna switch */
|
||||
#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME 0x00001FC0
|
||||
#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME_S 6
|
||||
#define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV 0x2000
|
||||
#define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV_S 13
|
||||
|
||||
#define AR_PHY_GAIN_2GHZ 0xA20C
|
||||
#define AR_PHY_GAIN_2GHZ_RXTX_MARGIN 0x00FC0000
|
||||
#define AR_PHY_GAIN_2GHZ_RXTX_MARGIN_S 18
|
||||
#define AR_PHY_GAIN_2GHZ_BSW_MARGIN 0x00003C00
|
||||
#define AR_PHY_GAIN_2GHZ_BSW_MARGIN_S 10
|
||||
#define AR_PHY_GAIN_2GHZ_BSW_ATTEN 0x0000001F
|
||||
#define AR_PHY_GAIN_2GHZ_BSW_ATTEN_S 0
|
||||
|
||||
#define AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN 0x003E0000
|
||||
#define AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN_S 17
|
||||
#define AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN 0x0001F000
|
||||
#define AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN_S 12
|
||||
#define AR_PHY_GAIN_2GHZ_XATTEN2_DB 0x00000FC0
|
||||
#define AR_PHY_GAIN_2GHZ_XATTEN2_DB_S 6
|
||||
#define AR_PHY_GAIN_2GHZ_XATTEN1_DB 0x0000003F
|
||||
#define AR_PHY_GAIN_2GHZ_XATTEN1_DB_S 0
|
||||
|
||||
#define AR_PHY_CCK_RXCTRL4 0xA21C
|
||||
#define AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT 0x01F80000
|
||||
#define AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT_S 19
|
||||
|
||||
#define AR_PHY_DAG_CTRLCCK 0xA228
|
||||
#define AR_PHY_DAG_CTRLCCK_EN_RSSI_THR 0x00000200
|
||||
#define AR_PHY_DAG_CTRLCCK_RSSI_THR 0x0001FC00
|
||||
#define AR_PHY_DAG_CTRLCCK_RSSI_THR_S 10
|
||||
|
||||
#define AR_PHY_FORCE_CLKEN_CCK 0xA22C
|
||||
#define AR_PHY_FORCE_CLKEN_CCK_MRC_MUX 0x00000040
|
||||
|
||||
#define AR_PHY_POWER_TX_RATE3 0xA234
|
||||
#define AR_PHY_POWER_TX_RATE4 0xA238
|
||||
|
||||
#define AR_PHY_SCRM_SEQ_XR 0xA23C
|
||||
#define AR_PHY_HEADER_DETECT_XR 0xA240
|
||||
#define AR_PHY_CHIRP_DETECTED_XR 0xA244
|
||||
#define AR_PHY_BLUETOOTH 0xA254
|
||||
|
||||
#define AR_PHY_TPCRG1 0xA258
|
||||
#define AR_PHY_TPCRG1_NUM_PD_GAIN 0x0000c000
|
||||
#define AR_PHY_TPCRG1_NUM_PD_GAIN_S 14
|
||||
|
||||
#define AR_PHY_TPCRG1_PD_GAIN_1 0x00030000
|
||||
#define AR_PHY_TPCRG1_PD_GAIN_1_S 16
|
||||
#define AR_PHY_TPCRG1_PD_GAIN_2 0x000C0000
|
||||
#define AR_PHY_TPCRG1_PD_GAIN_2_S 18
|
||||
#define AR_PHY_TPCRG1_PD_GAIN_3 0x00300000
|
||||
#define AR_PHY_TPCRG1_PD_GAIN_3_S 20
|
||||
|
||||
#define AR_PHY_TPCRG1_PD_CAL_ENABLE 0x00400000
|
||||
#define AR_PHY_TPCRG1_PD_CAL_ENABLE_S 22
|
||||
|
||||
#define AR_PHY_TX_PWRCTRL4 0xa264
|
||||
#define AR_PHY_TX_PWRCTRL_PD_AVG_VALID 0x00000001
|
||||
#define AR_PHY_TX_PWRCTRL_PD_AVG_VALID_S 0
|
||||
#define AR_PHY_TX_PWRCTRL_PD_AVG_OUT 0x000001FE
|
||||
#define AR_PHY_TX_PWRCTRL_PD_AVG_OUT_S 1
|
||||
|
||||
#define AR_PHY_TX_PWRCTRL6_0 0xa270
|
||||
#define AR_PHY_TX_PWRCTRL6_1 0xb270
|
||||
#define AR_PHY_TX_PWRCTRL_ERR_EST_MODE 0x03000000
|
||||
#define AR_PHY_TX_PWRCTRL_ERR_EST_MODE_S 24
|
||||
|
||||
#define AR_PHY_TX_PWRCTRL7 0xa274
|
||||
#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN 0x01F80000
|
||||
#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN_S 19
|
||||
|
||||
#define AR_PHY_TX_PWRCTRL9 0xa27C
|
||||
#define AR_PHY_TX_DESIRED_SCALE_CCK 0x00007C00
|
||||
#define AR_PHY_TX_DESIRED_SCALE_CCK_S 10
|
||||
#define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL 0x80000000
|
||||
#define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL_S 31
|
||||
|
||||
#define AR_PHY_TX_GAIN_TBL1 0xa300
|
||||
#define AR_PHY_TX_GAIN 0x0007F000
|
||||
#define AR_PHY_TX_GAIN_S 12
|
||||
|
||||
#define AR_PHY_CH0_TX_PWRCTRL11 0xa398
|
||||
#define AR_PHY_CH1_TX_PWRCTRL11 0xb398
|
||||
#define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP 0x0000FC00
|
||||
#define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP_S 10
|
||||
|
||||
#define AR_PHY_VIT_MASK2_M_46_61 0xa3a0
|
||||
#define AR_PHY_MASK2_M_31_45 0xa3a4
|
||||
#define AR_PHY_MASK2_M_16_30 0xa3a8
|
||||
#define AR_PHY_MASK2_M_00_15 0xa3ac
|
||||
#define AR_PHY_MASK2_P_15_01 0xa3b8
|
||||
#define AR_PHY_MASK2_P_30_16 0xa3bc
|
||||
#define AR_PHY_MASK2_P_45_31 0xa3c0
|
||||
#define AR_PHY_MASK2_P_61_45 0xa3c4
|
||||
#define AR_PHY_SPUR_REG 0x994c
|
||||
|
||||
#define AR_PHY_SPUR_REG_MASK_RATE_CNTL (0xFF << 18)
|
||||
#define AR_PHY_SPUR_REG_MASK_RATE_CNTL_S 18
|
||||
|
||||
#define AR_PHY_SPUR_REG_ENABLE_MASK_PPM 0x20000
|
||||
#define AR_PHY_SPUR_REG_MASK_RATE_SELECT (0xFF << 9)
|
||||
#define AR_PHY_SPUR_REG_MASK_RATE_SELECT_S 9
|
||||
#define AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI 0x100
|
||||
#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH 0x7F
|
||||
#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH_S 0
|
||||
|
||||
#define AR_PHY_PILOT_MASK_01_30 0xa3b0
|
||||
#define AR_PHY_PILOT_MASK_31_60 0xa3b4
|
||||
|
||||
#define AR_PHY_CHANNEL_MASK_01_30 0x99d4
|
||||
#define AR_PHY_CHANNEL_MASK_31_60 0x99d8
|
||||
|
||||
#define AR_PHY_ANALOG_SWAP 0xa268
|
||||
#define AR_PHY_SWAP_ALT_CHAIN 0x00000040
|
||||
|
||||
#define AR_PHY_TPCRG5 0xA26C
|
||||
#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP 0x0000000F
|
||||
#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP_S 0
|
||||
#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1 0x000003F0
|
||||
#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1_S 4
|
||||
#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2 0x0000FC00
|
||||
#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2_S 10
|
||||
#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3 0x003F0000
|
||||
#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3_S 16
|
||||
#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4 0x0FC00000
|
||||
#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4_S 22
|
||||
|
||||
/* Carrier leak calibration control, do it after AGC calibration */
|
||||
#define AR_PHY_CL_CAL_CTL 0xA358
|
||||
#define AR_PHY_CL_CAL_ENABLE 0x00000002
|
||||
#define AR_PHY_PARALLEL_CAL_ENABLE 0x00000001
|
||||
|
||||
#define AR_PHY_POWER_TX_RATE5 0xA38C
|
||||
#define AR_PHY_POWER_TX_RATE6 0xA390
|
||||
|
||||
#define AR_PHY_CAL_CHAINMASK 0xA39C
|
||||
|
||||
#define AR_PHY_POWER_TX_SUB 0xA3C8
|
||||
#define AR_PHY_POWER_TX_RATE7 0xA3CC
|
||||
#define AR_PHY_POWER_TX_RATE8 0xA3D0
|
||||
#define AR_PHY_POWER_TX_RATE9 0xA3D4
|
||||
|
||||
#define AR_PHY_XPA_CFG 0xA3D8
|
||||
#define AR_PHY_FORCE_XPA_CFG 0x000000001
|
||||
#define AR_PHY_FORCE_XPA_CFG_S 0
|
||||
|
||||
#define AR_PHY_CH1_CCA 0xa864
|
||||
#define AR_PHY_CH1_MINCCA_PWR 0x0FF80000
|
||||
#define AR_PHY_CH1_MINCCA_PWR_S 19
|
||||
#define AR9280_PHY_CH1_MINCCA_PWR 0x1FF00000
|
||||
#define AR9280_PHY_CH1_MINCCA_PWR_S 20
|
||||
|
||||
#define AR_PHY_CH2_CCA 0xb864
|
||||
#define AR_PHY_CH2_MINCCA_PWR 0x0FF80000
|
||||
#define AR_PHY_CH2_MINCCA_PWR_S 19
|
||||
|
||||
#define AR_PHY_CH1_EXT_CCA 0xa9bc
|
||||
#define AR_PHY_CH1_EXT_MINCCA_PWR 0xFF800000
|
||||
#define AR_PHY_CH1_EXT_MINCCA_PWR_S 23
|
||||
#define AR9280_PHY_CH1_EXT_MINCCA_PWR 0x01FF0000
|
||||
#define AR9280_PHY_CH1_EXT_MINCCA_PWR_S 16
|
||||
|
||||
#define AR_PHY_CH2_EXT_CCA 0xb9bc
|
||||
#define AR_PHY_CH2_EXT_MINCCA_PWR 0xFF800000
|
||||
#define AR_PHY_CH2_EXT_MINCCA_PWR_S 23
|
||||
|
||||
#endif
|
802
drivers/net/wireless/ath/ath9k/ar9003_calib.c
Normal file
802
drivers/net/wireless/ath/ath9k/ar9003_calib.c
Normal file
@ -0,0 +1,802 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Atheros Communications Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "hw.h"
|
||||
#include "hw-ops.h"
|
||||
#include "ar9003_phy.h"
|
||||
|
||||
static void ar9003_hw_setup_calibration(struct ath_hw *ah,
|
||||
struct ath9k_cal_list *currCal)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
|
||||
/* Select calibration to run */
|
||||
switch (currCal->calData->calType) {
|
||||
case IQ_MISMATCH_CAL:
|
||||
/*
|
||||
* Start calibration with
|
||||
* 2^(INIT_IQCAL_LOG_COUNT_MAX+1) samples
|
||||
*/
|
||||
REG_RMW_FIELD(ah, AR_PHY_TIMING4,
|
||||
AR_PHY_TIMING4_IQCAL_LOG_COUNT_MAX,
|
||||
currCal->calData->calCountMax);
|
||||
REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
|
||||
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"starting IQ Mismatch Calibration\n");
|
||||
|
||||
/* Kick-off cal */
|
||||
REG_SET_BIT(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_DO_CAL);
|
||||
break;
|
||||
case TEMP_COMP_CAL:
|
||||
REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_THERM,
|
||||
AR_PHY_65NM_CH0_THERM_LOCAL, 1);
|
||||
REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_THERM,
|
||||
AR_PHY_65NM_CH0_THERM_START, 1);
|
||||
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"starting Temperature Compensation Calibration\n");
|
||||
break;
|
||||
case ADC_DC_INIT_CAL:
|
||||
case ADC_GAIN_CAL:
|
||||
case ADC_DC_CAL:
|
||||
/* Not yet */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Generic calibration routine.
|
||||
* Recalibrate the lower PHY chips to account for temperature/environment
|
||||
* changes.
|
||||
*/
|
||||
static bool ar9003_hw_per_calibration(struct ath_hw *ah,
|
||||
struct ath9k_channel *ichan,
|
||||
u8 rxchainmask,
|
||||
struct ath9k_cal_list *currCal)
|
||||
{
|
||||
/* Cal is assumed not done until explicitly set below */
|
||||
bool iscaldone = false;
|
||||
|
||||
/* Calibration in progress. */
|
||||
if (currCal->calState == CAL_RUNNING) {
|
||||
/* Check to see if it has finished. */
|
||||
if (!(REG_READ(ah, AR_PHY_TIMING4) & AR_PHY_TIMING4_DO_CAL)) {
|
||||
/*
|
||||
* Accumulate cal measures for active chains
|
||||
*/
|
||||
currCal->calData->calCollect(ah);
|
||||
ah->cal_samples++;
|
||||
|
||||
if (ah->cal_samples >=
|
||||
currCal->calData->calNumSamples) {
|
||||
unsigned int i, numChains = 0;
|
||||
for (i = 0; i < AR9300_MAX_CHAINS; i++) {
|
||||
if (rxchainmask & (1 << i))
|
||||
numChains++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Process accumulated data
|
||||
*/
|
||||
currCal->calData->calPostProc(ah, numChains);
|
||||
|
||||
/* Calibration has finished. */
|
||||
ichan->CalValid |= currCal->calData->calType;
|
||||
currCal->calState = CAL_DONE;
|
||||
iscaldone = true;
|
||||
} else {
|
||||
/*
|
||||
* Set-up collection of another sub-sample until we
|
||||
* get desired number
|
||||
*/
|
||||
ar9003_hw_setup_calibration(ah, currCal);
|
||||
}
|
||||
}
|
||||
} else if (!(ichan->CalValid & currCal->calData->calType)) {
|
||||
/* If current cal is marked invalid in channel, kick it off */
|
||||
ath9k_hw_reset_calibration(ah, currCal);
|
||||
}
|
||||
|
||||
return iscaldone;
|
||||
}
|
||||
|
||||
static bool ar9003_hw_calibrate(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan,
|
||||
u8 rxchainmask,
|
||||
bool longcal)
|
||||
{
|
||||
bool iscaldone = true;
|
||||
struct ath9k_cal_list *currCal = ah->cal_list_curr;
|
||||
|
||||
/*
|
||||
* For given calibration:
|
||||
* 1. Call generic cal routine
|
||||
* 2. When this cal is done (isCalDone) if we have more cals waiting
|
||||
* (eg after reset), mask this to upper layers by not propagating
|
||||
* isCalDone if it is set to TRUE.
|
||||
* Instead, change isCalDone to FALSE and setup the waiting cal(s)
|
||||
* to be run.
|
||||
*/
|
||||
if (currCal &&
|
||||
(currCal->calState == CAL_RUNNING ||
|
||||
currCal->calState == CAL_WAITING)) {
|
||||
iscaldone = ar9003_hw_per_calibration(ah, chan,
|
||||
rxchainmask, currCal);
|
||||
if (iscaldone) {
|
||||
ah->cal_list_curr = currCal = currCal->calNext;
|
||||
|
||||
if (currCal->calState == CAL_WAITING) {
|
||||
iscaldone = false;
|
||||
ath9k_hw_reset_calibration(ah, currCal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Do NF cal only at longer intervals */
|
||||
if (longcal) {
|
||||
/*
|
||||
* Load the NF from history buffer of the current channel.
|
||||
* NF is slow time-variant, so it is OK to use a historical
|
||||
* value.
|
||||
*/
|
||||
ath9k_hw_loadnf(ah, ah->curchan);
|
||||
|
||||
/* start NF calibration, without updating BB NF register */
|
||||
ath9k_hw_start_nfcal(ah);
|
||||
}
|
||||
|
||||
return iscaldone;
|
||||
}
|
||||
|
||||
static void ar9003_hw_iqcal_collect(struct ath_hw *ah)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Accumulate IQ cal measures for active chains */
|
||||
for (i = 0; i < AR5416_MAX_CHAINS; i++) {
|
||||
ah->totalPowerMeasI[i] +=
|
||||
REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
|
||||
ah->totalPowerMeasQ[i] +=
|
||||
REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
|
||||
ah->totalIqCorrMeas[i] +=
|
||||
(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
|
||||
ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
|
||||
"%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
|
||||
ah->cal_samples, i, ah->totalPowerMeasI[i],
|
||||
ah->totalPowerMeasQ[i],
|
||||
ah->totalIqCorrMeas[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void ar9003_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
u32 powerMeasQ, powerMeasI, iqCorrMeas;
|
||||
u32 qCoffDenom, iCoffDenom;
|
||||
int32_t qCoff, iCoff;
|
||||
int iqCorrNeg, i;
|
||||
const u_int32_t offset_array[3] = {
|
||||
AR_PHY_RX_IQCAL_CORR_B0,
|
||||
AR_PHY_RX_IQCAL_CORR_B1,
|
||||
AR_PHY_RX_IQCAL_CORR_B2,
|
||||
};
|
||||
|
||||
for (i = 0; i < numChains; i++) {
|
||||
powerMeasI = ah->totalPowerMeasI[i];
|
||||
powerMeasQ = ah->totalPowerMeasQ[i];
|
||||
iqCorrMeas = ah->totalIqCorrMeas[i];
|
||||
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"Starting IQ Cal and Correction for Chain %d\n",
|
||||
i);
|
||||
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"Orignal: Chn %diq_corr_meas = 0x%08x\n",
|
||||
i, ah->totalIqCorrMeas[i]);
|
||||
|
||||
iqCorrNeg = 0;
|
||||
|
||||
if (iqCorrMeas > 0x80000000) {
|
||||
iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
|
||||
iqCorrNeg = 1;
|
||||
}
|
||||
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
|
||||
ath_print(common, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n",
|
||||
iqCorrNeg);
|
||||
|
||||
iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 256;
|
||||
qCoffDenom = powerMeasQ / 64;
|
||||
|
||||
if ((iCoffDenom != 0) && (qCoffDenom != 0)) {
|
||||
iCoff = iqCorrMeas / iCoffDenom;
|
||||
qCoff = powerMeasI / qCoffDenom - 64;
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"Chn %d iCoff = 0x%08x\n", i, iCoff);
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"Chn %d qCoff = 0x%08x\n", i, qCoff);
|
||||
|
||||
/* Force bounds on iCoff */
|
||||
if (iCoff >= 63)
|
||||
iCoff = 63;
|
||||
else if (iCoff <= -63)
|
||||
iCoff = -63;
|
||||
|
||||
/* Negate iCoff if iqCorrNeg == 0 */
|
||||
if (iqCorrNeg == 0x0)
|
||||
iCoff = -iCoff;
|
||||
|
||||
/* Force bounds on qCoff */
|
||||
if (qCoff >= 63)
|
||||
qCoff = 63;
|
||||
else if (qCoff <= -63)
|
||||
qCoff = -63;
|
||||
|
||||
iCoff = iCoff & 0x7f;
|
||||
qCoff = qCoff & 0x7f;
|
||||
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"Chn %d : iCoff = 0x%x qCoff = 0x%x\n",
|
||||
i, iCoff, qCoff);
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"Register offset (0x%04x) "
|
||||
"before update = 0x%x\n",
|
||||
offset_array[i],
|
||||
REG_READ(ah, offset_array[i]));
|
||||
|
||||
REG_RMW_FIELD(ah, offset_array[i],
|
||||
AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF,
|
||||
iCoff);
|
||||
REG_RMW_FIELD(ah, offset_array[i],
|
||||
AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF,
|
||||
qCoff);
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"Register offset (0x%04x) QI COFF "
|
||||
"(bitfields 0x%08x) after update = 0x%x\n",
|
||||
offset_array[i],
|
||||
AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF,
|
||||
REG_READ(ah, offset_array[i]));
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"Register offset (0x%04x) QQ COFF "
|
||||
"(bitfields 0x%08x) after update = 0x%x\n",
|
||||
offset_array[i],
|
||||
AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF,
|
||||
REG_READ(ah, offset_array[i]));
|
||||
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"IQ Cal and Correction done for Chain %d\n",
|
||||
i);
|
||||
}
|
||||
}
|
||||
|
||||
REG_SET_BIT(ah, AR_PHY_RX_IQCAL_CORR_B0,
|
||||
AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE);
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"IQ Cal and Correction (offset 0x%04x) enabled "
|
||||
"(bit position 0x%08x). New Value 0x%08x\n",
|
||||
(unsigned) (AR_PHY_RX_IQCAL_CORR_B0),
|
||||
AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE,
|
||||
REG_READ(ah, AR_PHY_RX_IQCAL_CORR_B0));
|
||||
}
|
||||
|
||||
static const struct ath9k_percal_data iq_cal_single_sample = {
|
||||
IQ_MISMATCH_CAL,
|
||||
MIN_CAL_SAMPLES,
|
||||
PER_MAX_LOG_COUNT,
|
||||
ar9003_hw_iqcal_collect,
|
||||
ar9003_hw_iqcalibrate
|
||||
};
|
||||
|
||||
static void ar9003_hw_init_cal_settings(struct ath_hw *ah)
|
||||
{
|
||||
ah->iq_caldata.calData = &iq_cal_single_sample;
|
||||
ah->supp_cals = IQ_MISMATCH_CAL;
|
||||
}
|
||||
|
||||
static bool ar9003_hw_iscal_supported(struct ath_hw *ah,
|
||||
enum ath9k_cal_types calType)
|
||||
{
|
||||
switch (calType & ah->supp_cals) {
|
||||
case IQ_MISMATCH_CAL:
|
||||
/*
|
||||
* XXX: Run IQ Mismatch for non-CCK only
|
||||
* Note that CHANNEL_B is never set though.
|
||||
*/
|
||||
return true;
|
||||
case ADC_GAIN_CAL:
|
||||
case ADC_DC_CAL:
|
||||
return false;
|
||||
case TEMP_COMP_CAL:
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* solve 4x4 linear equation used in loopback iq cal.
|
||||
*/
|
||||
static bool ar9003_hw_solve_iq_cal(struct ath_hw *ah,
|
||||
s32 sin_2phi_1,
|
||||
s32 cos_2phi_1,
|
||||
s32 sin_2phi_2,
|
||||
s32 cos_2phi_2,
|
||||
s32 mag_a0_d0,
|
||||
s32 phs_a0_d0,
|
||||
s32 mag_a1_d0,
|
||||
s32 phs_a1_d0,
|
||||
s32 solved_eq[])
|
||||
{
|
||||
s32 f1 = cos_2phi_1 - cos_2phi_2,
|
||||
f3 = sin_2phi_1 - sin_2phi_2,
|
||||
f2;
|
||||
s32 mag_tx, phs_tx, mag_rx, phs_rx;
|
||||
const s32 result_shift = 1 << 15;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
|
||||
f2 = (f1 * f1 + f3 * f3) / result_shift;
|
||||
|
||||
if (!f2) {
|
||||
ath_print(common, ATH_DBG_CALIBRATE, "Divide by 0\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* mag mismatch, tx */
|
||||
mag_tx = f1 * (mag_a0_d0 - mag_a1_d0) + f3 * (phs_a0_d0 - phs_a1_d0);
|
||||
/* phs mismatch, tx */
|
||||
phs_tx = f3 * (-mag_a0_d0 + mag_a1_d0) + f1 * (phs_a0_d0 - phs_a1_d0);
|
||||
|
||||
mag_tx = (mag_tx / f2);
|
||||
phs_tx = (phs_tx / f2);
|
||||
|
||||
/* mag mismatch, rx */
|
||||
mag_rx = mag_a0_d0 - (cos_2phi_1 * mag_tx + sin_2phi_1 * phs_tx) /
|
||||
result_shift;
|
||||
/* phs mismatch, rx */
|
||||
phs_rx = phs_a0_d0 + (sin_2phi_1 * mag_tx - cos_2phi_1 * phs_tx) /
|
||||
result_shift;
|
||||
|
||||
solved_eq[0] = mag_tx;
|
||||
solved_eq[1] = phs_tx;
|
||||
solved_eq[2] = mag_rx;
|
||||
solved_eq[3] = phs_rx;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static s32 ar9003_hw_find_mag_approx(struct ath_hw *ah, s32 in_re, s32 in_im)
|
||||
{
|
||||
s32 abs_i = abs(in_re),
|
||||
abs_q = abs(in_im),
|
||||
max_abs, min_abs;
|
||||
|
||||
if (abs_i > abs_q) {
|
||||
max_abs = abs_i;
|
||||
min_abs = abs_q;
|
||||
} else {
|
||||
max_abs = abs_q;
|
||||
min_abs = abs_i;
|
||||
}
|
||||
|
||||
return max_abs - (max_abs / 32) + (min_abs / 8) + (min_abs / 4);
|
||||
}
|
||||
|
||||
#define DELPT 32
|
||||
|
||||
static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah,
|
||||
s32 chain_idx,
|
||||
const s32 iq_res[],
|
||||
s32 iqc_coeff[])
|
||||
{
|
||||
s32 i2_m_q2_a0_d0, i2_p_q2_a0_d0, iq_corr_a0_d0,
|
||||
i2_m_q2_a0_d1, i2_p_q2_a0_d1, iq_corr_a0_d1,
|
||||
i2_m_q2_a1_d0, i2_p_q2_a1_d0, iq_corr_a1_d0,
|
||||
i2_m_q2_a1_d1, i2_p_q2_a1_d1, iq_corr_a1_d1;
|
||||
s32 mag_a0_d0, mag_a1_d0, mag_a0_d1, mag_a1_d1,
|
||||
phs_a0_d0, phs_a1_d0, phs_a0_d1, phs_a1_d1,
|
||||
sin_2phi_1, cos_2phi_1,
|
||||
sin_2phi_2, cos_2phi_2;
|
||||
s32 mag_tx, phs_tx, mag_rx, phs_rx;
|
||||
s32 solved_eq[4], mag_corr_tx, phs_corr_tx, mag_corr_rx, phs_corr_rx,
|
||||
q_q_coff, q_i_coff;
|
||||
const s32 res_scale = 1 << 15;
|
||||
const s32 delpt_shift = 1 << 8;
|
||||
s32 mag1, mag2;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
|
||||
i2_m_q2_a0_d0 = iq_res[0] & 0xfff;
|
||||
i2_p_q2_a0_d0 = (iq_res[0] >> 12) & 0xfff;
|
||||
iq_corr_a0_d0 = ((iq_res[0] >> 24) & 0xff) + ((iq_res[1] & 0xf) << 8);
|
||||
|
||||
if (i2_m_q2_a0_d0 > 0x800)
|
||||
i2_m_q2_a0_d0 = -((0xfff - i2_m_q2_a0_d0) + 1);
|
||||
|
||||
if (i2_p_q2_a0_d0 > 0x800)
|
||||
i2_p_q2_a0_d0 = -((0xfff - i2_p_q2_a0_d0) + 1);
|
||||
|
||||
if (iq_corr_a0_d0 > 0x800)
|
||||
iq_corr_a0_d0 = -((0xfff - iq_corr_a0_d0) + 1);
|
||||
|
||||
i2_m_q2_a0_d1 = (iq_res[1] >> 4) & 0xfff;
|
||||
i2_p_q2_a0_d1 = (iq_res[2] & 0xfff);
|
||||
iq_corr_a0_d1 = (iq_res[2] >> 12) & 0xfff;
|
||||
|
||||
if (i2_m_q2_a0_d1 > 0x800)
|
||||
i2_m_q2_a0_d1 = -((0xfff - i2_m_q2_a0_d1) + 1);
|
||||
|
||||
if (i2_p_q2_a0_d1 > 0x800)
|
||||
i2_p_q2_a0_d1 = -((0xfff - i2_p_q2_a0_d1) + 1);
|
||||
|
||||
if (iq_corr_a0_d1 > 0x800)
|
||||
iq_corr_a0_d1 = -((0xfff - iq_corr_a0_d1) + 1);
|
||||
|
||||
i2_m_q2_a1_d0 = ((iq_res[2] >> 24) & 0xff) + ((iq_res[3] & 0xf) << 8);
|
||||
i2_p_q2_a1_d0 = (iq_res[3] >> 4) & 0xfff;
|
||||
iq_corr_a1_d0 = iq_res[4] & 0xfff;
|
||||
|
||||
if (i2_m_q2_a1_d0 > 0x800)
|
||||
i2_m_q2_a1_d0 = -((0xfff - i2_m_q2_a1_d0) + 1);
|
||||
|
||||
if (i2_p_q2_a1_d0 > 0x800)
|
||||
i2_p_q2_a1_d0 = -((0xfff - i2_p_q2_a1_d0) + 1);
|
||||
|
||||
if (iq_corr_a1_d0 > 0x800)
|
||||
iq_corr_a1_d0 = -((0xfff - iq_corr_a1_d0) + 1);
|
||||
|
||||
i2_m_q2_a1_d1 = (iq_res[4] >> 12) & 0xfff;
|
||||
i2_p_q2_a1_d1 = ((iq_res[4] >> 24) & 0xff) + ((iq_res[5] & 0xf) << 8);
|
||||
iq_corr_a1_d1 = (iq_res[5] >> 4) & 0xfff;
|
||||
|
||||
if (i2_m_q2_a1_d1 > 0x800)
|
||||
i2_m_q2_a1_d1 = -((0xfff - i2_m_q2_a1_d1) + 1);
|
||||
|
||||
if (i2_p_q2_a1_d1 > 0x800)
|
||||
i2_p_q2_a1_d1 = -((0xfff - i2_p_q2_a1_d1) + 1);
|
||||
|
||||
if (iq_corr_a1_d1 > 0x800)
|
||||
iq_corr_a1_d1 = -((0xfff - iq_corr_a1_d1) + 1);
|
||||
|
||||
if ((i2_p_q2_a0_d0 == 0) || (i2_p_q2_a0_d1 == 0) ||
|
||||
(i2_p_q2_a1_d0 == 0) || (i2_p_q2_a1_d1 == 0)) {
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"Divide by 0:\na0_d0=%d\n"
|
||||
"a0_d1=%d\na2_d0=%d\na1_d1=%d\n",
|
||||
i2_p_q2_a0_d0, i2_p_q2_a0_d1,
|
||||
i2_p_q2_a1_d0, i2_p_q2_a1_d1);
|
||||
return false;
|
||||
}
|
||||
|
||||
mag_a0_d0 = (i2_m_q2_a0_d0 * res_scale) / i2_p_q2_a0_d0;
|
||||
phs_a0_d0 = (iq_corr_a0_d0 * res_scale) / i2_p_q2_a0_d0;
|
||||
|
||||
mag_a0_d1 = (i2_m_q2_a0_d1 * res_scale) / i2_p_q2_a0_d1;
|
||||
phs_a0_d1 = (iq_corr_a0_d1 * res_scale) / i2_p_q2_a0_d1;
|
||||
|
||||
mag_a1_d0 = (i2_m_q2_a1_d0 * res_scale) / i2_p_q2_a1_d0;
|
||||
phs_a1_d0 = (iq_corr_a1_d0 * res_scale) / i2_p_q2_a1_d0;
|
||||
|
||||
mag_a1_d1 = (i2_m_q2_a1_d1 * res_scale) / i2_p_q2_a1_d1;
|
||||
phs_a1_d1 = (iq_corr_a1_d1 * res_scale) / i2_p_q2_a1_d1;
|
||||
|
||||
/* w/o analog phase shift */
|
||||
sin_2phi_1 = (((mag_a0_d0 - mag_a0_d1) * delpt_shift) / DELPT);
|
||||
/* w/o analog phase shift */
|
||||
cos_2phi_1 = (((phs_a0_d1 - phs_a0_d0) * delpt_shift) / DELPT);
|
||||
/* w/ analog phase shift */
|
||||
sin_2phi_2 = (((mag_a1_d0 - mag_a1_d1) * delpt_shift) / DELPT);
|
||||
/* w/ analog phase shift */
|
||||
cos_2phi_2 = (((phs_a1_d1 - phs_a1_d0) * delpt_shift) / DELPT);
|
||||
|
||||
/*
|
||||
* force sin^2 + cos^2 = 1;
|
||||
* find magnitude by approximation
|
||||
*/
|
||||
mag1 = ar9003_hw_find_mag_approx(ah, cos_2phi_1, sin_2phi_1);
|
||||
mag2 = ar9003_hw_find_mag_approx(ah, cos_2phi_2, sin_2phi_2);
|
||||
|
||||
if ((mag1 == 0) || (mag2 == 0)) {
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"Divide by 0: mag1=%d, mag2=%d\n",
|
||||
mag1, mag2);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* normalization sin and cos by mag */
|
||||
sin_2phi_1 = (sin_2phi_1 * res_scale / mag1);
|
||||
cos_2phi_1 = (cos_2phi_1 * res_scale / mag1);
|
||||
sin_2phi_2 = (sin_2phi_2 * res_scale / mag2);
|
||||
cos_2phi_2 = (cos_2phi_2 * res_scale / mag2);
|
||||
|
||||
/* calculate IQ mismatch */
|
||||
if (!ar9003_hw_solve_iq_cal(ah,
|
||||
sin_2phi_1, cos_2phi_1,
|
||||
sin_2phi_2, cos_2phi_2,
|
||||
mag_a0_d0, phs_a0_d0,
|
||||
mag_a1_d0,
|
||||
phs_a1_d0, solved_eq)) {
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"Call to ar9003_hw_solve_iq_cal() failed.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
mag_tx = solved_eq[0];
|
||||
phs_tx = solved_eq[1];
|
||||
mag_rx = solved_eq[2];
|
||||
phs_rx = solved_eq[3];
|
||||
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"chain %d: mag mismatch=%d phase mismatch=%d\n",
|
||||
chain_idx, mag_tx/res_scale, phs_tx/res_scale);
|
||||
|
||||
if (res_scale == mag_tx) {
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"Divide by 0: mag_tx=%d, res_scale=%d\n",
|
||||
mag_tx, res_scale);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* calculate and quantize Tx IQ correction factor */
|
||||
mag_corr_tx = (mag_tx * res_scale) / (res_scale - mag_tx);
|
||||
phs_corr_tx = -phs_tx;
|
||||
|
||||
q_q_coff = (mag_corr_tx * 128 / res_scale);
|
||||
q_i_coff = (phs_corr_tx * 256 / res_scale);
|
||||
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"tx chain %d: mag corr=%d phase corr=%d\n",
|
||||
chain_idx, q_q_coff, q_i_coff);
|
||||
|
||||
if (q_i_coff < -63)
|
||||
q_i_coff = -63;
|
||||
if (q_i_coff > 63)
|
||||
q_i_coff = 63;
|
||||
if (q_q_coff < -63)
|
||||
q_q_coff = -63;
|
||||
if (q_q_coff > 63)
|
||||
q_q_coff = 63;
|
||||
|
||||
iqc_coeff[0] = (q_q_coff * 128) + q_i_coff;
|
||||
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"tx chain %d: iq corr coeff=%x\n",
|
||||
chain_idx, iqc_coeff[0]);
|
||||
|
||||
if (-mag_rx == res_scale) {
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"Divide by 0: mag_rx=%d, res_scale=%d\n",
|
||||
mag_rx, res_scale);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* calculate and quantize Rx IQ correction factors */
|
||||
mag_corr_rx = (-mag_rx * res_scale) / (res_scale + mag_rx);
|
||||
phs_corr_rx = -phs_rx;
|
||||
|
||||
q_q_coff = (mag_corr_rx * 128 / res_scale);
|
||||
q_i_coff = (phs_corr_rx * 256 / res_scale);
|
||||
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"rx chain %d: mag corr=%d phase corr=%d\n",
|
||||
chain_idx, q_q_coff, q_i_coff);
|
||||
|
||||
if (q_i_coff < -63)
|
||||
q_i_coff = -63;
|
||||
if (q_i_coff > 63)
|
||||
q_i_coff = 63;
|
||||
if (q_q_coff < -63)
|
||||
q_q_coff = -63;
|
||||
if (q_q_coff > 63)
|
||||
q_q_coff = 63;
|
||||
|
||||
iqc_coeff[1] = (q_q_coff * 128) + q_i_coff;
|
||||
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"rx chain %d: iq corr coeff=%x\n",
|
||||
chain_idx, iqc_coeff[1]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ar9003_hw_tx_iq_cal(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
const u32 txiqcal_status[AR9300_MAX_CHAINS] = {
|
||||
AR_PHY_TX_IQCAL_STATUS_B0,
|
||||
AR_PHY_TX_IQCAL_STATUS_B1,
|
||||
AR_PHY_TX_IQCAL_STATUS_B2,
|
||||
};
|
||||
const u32 tx_corr_coeff[AR9300_MAX_CHAINS] = {
|
||||
AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
|
||||
AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
|
||||
AR_PHY_TX_IQCAL_CORR_COEFF_01_B2,
|
||||
};
|
||||
const u32 rx_corr[AR9300_MAX_CHAINS] = {
|
||||
AR_PHY_RX_IQCAL_CORR_B0,
|
||||
AR_PHY_RX_IQCAL_CORR_B1,
|
||||
AR_PHY_RX_IQCAL_CORR_B2,
|
||||
};
|
||||
const u_int32_t chan_info_tab[] = {
|
||||
AR_PHY_CHAN_INFO_TAB_0,
|
||||
AR_PHY_CHAN_INFO_TAB_1,
|
||||
AR_PHY_CHAN_INFO_TAB_2,
|
||||
};
|
||||
s32 iq_res[6];
|
||||
s32 iqc_coeff[2];
|
||||
s32 i, j;
|
||||
u32 num_chains = 0;
|
||||
|
||||
for (i = 0; i < AR9300_MAX_CHAINS; i++) {
|
||||
if (ah->txchainmask & (1 << i))
|
||||
num_chains++;
|
||||
}
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
|
||||
AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
|
||||
DELPT);
|
||||
REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START,
|
||||
AR_PHY_TX_IQCAL_START_DO_CAL,
|
||||
AR_PHY_TX_IQCAL_START_DO_CAL);
|
||||
|
||||
if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START,
|
||||
AR_PHY_TX_IQCAL_START_DO_CAL,
|
||||
0, AH_WAIT_TIMEOUT)) {
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"Tx IQ Cal not complete.\n");
|
||||
goto TX_IQ_CAL_FAILED;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_chains; i++) {
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"Doing Tx IQ Cal for chain %d.\n", i);
|
||||
|
||||
if (REG_READ(ah, txiqcal_status[i]) &
|
||||
AR_PHY_TX_IQCAL_STATUS_FAILED) {
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"Tx IQ Cal failed for chain %d.\n", i);
|
||||
goto TX_IQ_CAL_FAILED;
|
||||
}
|
||||
|
||||
for (j = 0; j < 3; j++) {
|
||||
u_int8_t idx = 2 * j,
|
||||
offset = 4 * j;
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
|
||||
AR_PHY_CHAN_INFO_TAB_S2_READ, 0);
|
||||
|
||||
/* 32 bits */
|
||||
iq_res[idx] = REG_READ(ah, chan_info_tab[i] + offset);
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
|
||||
AR_PHY_CHAN_INFO_TAB_S2_READ, 1);
|
||||
|
||||
/* 16 bits */
|
||||
iq_res[idx+1] = 0xffff & REG_READ(ah,
|
||||
chan_info_tab[i] +
|
||||
offset);
|
||||
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"IQ RES[%d]=0x%x IQ_RES[%d]=0x%x\n",
|
||||
idx, iq_res[idx], idx+1, iq_res[idx+1]);
|
||||
}
|
||||
|
||||
if (!ar9003_hw_calc_iq_corr(ah, i, iq_res, iqc_coeff)) {
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"Failed in calculation of IQ correction.\n");
|
||||
goto TX_IQ_CAL_FAILED;
|
||||
}
|
||||
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"IQ_COEFF[0] = 0x%x IQ_COEFF[1] = 0x%x\n",
|
||||
iqc_coeff[0], iqc_coeff[1]);
|
||||
|
||||
REG_RMW_FIELD(ah, tx_corr_coeff[i],
|
||||
AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
|
||||
iqc_coeff[0]);
|
||||
REG_RMW_FIELD(ah, rx_corr[i],
|
||||
AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_Q_COFF,
|
||||
iqc_coeff[1] >> 7);
|
||||
REG_RMW_FIELD(ah, rx_corr[i],
|
||||
AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_I_COFF,
|
||||
iqc_coeff[1]);
|
||||
}
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
|
||||
AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1);
|
||||
REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
|
||||
AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1);
|
||||
|
||||
return;
|
||||
|
||||
TX_IQ_CAL_FAILED:
|
||||
ath_print(common, ATH_DBG_CALIBRATE, "Tx IQ Cal failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
static bool ar9003_hw_init_cal(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
|
||||
/*
|
||||
* 0x7 = 0b111 , AR9003 needs to be configured for 3-chain mode before
|
||||
* running AGC/TxIQ cals
|
||||
*/
|
||||
ar9003_hw_set_chain_masks(ah, 0x7, 0x7);
|
||||
|
||||
/* Calibrate the AGC */
|
||||
REG_WRITE(ah, AR_PHY_AGC_CONTROL,
|
||||
REG_READ(ah, AR_PHY_AGC_CONTROL) |
|
||||
AR_PHY_AGC_CONTROL_CAL);
|
||||
|
||||
/* Poll for offset calibration complete */
|
||||
if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
|
||||
0, AH_WAIT_TIMEOUT)) {
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"offset calibration failed to "
|
||||
"complete in 1ms; noisy environment?\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Do Tx IQ Calibration */
|
||||
ar9003_hw_tx_iq_cal(ah);
|
||||
|
||||
/* Revert chainmasks to their original values before NF cal */
|
||||
ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
|
||||
|
||||
/* Initialize list pointers */
|
||||
ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
|
||||
|
||||
if (ar9003_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) {
|
||||
INIT_CAL(&ah->iq_caldata);
|
||||
INSERT_CAL(ah, &ah->iq_caldata);
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"enabling IQ Calibration.\n");
|
||||
}
|
||||
|
||||
if (ar9003_hw_iscal_supported(ah, TEMP_COMP_CAL)) {
|
||||
INIT_CAL(&ah->tempCompCalData);
|
||||
INSERT_CAL(ah, &ah->tempCompCalData);
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"enabling Temperature Compensation Calibration.\n");
|
||||
}
|
||||
|
||||
/* Initialize current pointer to first element in list */
|
||||
ah->cal_list_curr = ah->cal_list;
|
||||
|
||||
if (ah->cal_list_curr)
|
||||
ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
|
||||
|
||||
chan->CalValid = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ar9003_hw_attach_calib_ops(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
|
||||
struct ath_hw_ops *ops = ath9k_hw_ops(ah);
|
||||
|
||||
priv_ops->init_cal_settings = ar9003_hw_init_cal_settings;
|
||||
priv_ops->init_cal = ar9003_hw_init_cal;
|
||||
priv_ops->setup_calibration = ar9003_hw_setup_calibration;
|
||||
priv_ops->iscal_supported = ar9003_hw_iscal_supported;
|
||||
|
||||
ops->calibrate = ar9003_hw_calibrate;
|
||||
}
|
1856
drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
Normal file
1856
drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
Normal file
File diff suppressed because it is too large
Load Diff
323
drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
Normal file
323
drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
Normal file
@ -0,0 +1,323 @@
|
||||
#ifndef AR9003_EEPROM_H
|
||||
#define AR9003_EEPROM_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#define AR9300_EEP_VER 0xD000
|
||||
#define AR9300_EEP_VER_MINOR_MASK 0xFFF
|
||||
#define AR9300_EEP_MINOR_VER_1 0x1
|
||||
#define AR9300_EEP_MINOR_VER AR9300_EEP_MINOR_VER_1
|
||||
|
||||
/* 16-bit offset location start of calibration struct */
|
||||
#define AR9300_EEP_START_LOC 256
|
||||
#define AR9300_NUM_5G_CAL_PIERS 8
|
||||
#define AR9300_NUM_2G_CAL_PIERS 3
|
||||
#define AR9300_NUM_5G_20_TARGET_POWERS 8
|
||||
#define AR9300_NUM_5G_40_TARGET_POWERS 8
|
||||
#define AR9300_NUM_2G_CCK_TARGET_POWERS 2
|
||||
#define AR9300_NUM_2G_20_TARGET_POWERS 3
|
||||
#define AR9300_NUM_2G_40_TARGET_POWERS 3
|
||||
/* #define AR9300_NUM_CTLS 21 */
|
||||
#define AR9300_NUM_CTLS_5G 9
|
||||
#define AR9300_NUM_CTLS_2G 12
|
||||
#define AR9300_CTL_MODE_M 0xF
|
||||
#define AR9300_NUM_BAND_EDGES_5G 8
|
||||
#define AR9300_NUM_BAND_EDGES_2G 4
|
||||
#define AR9300_NUM_PD_GAINS 4
|
||||
#define AR9300_PD_GAINS_IN_MASK 4
|
||||
#define AR9300_PD_GAIN_ICEPTS 5
|
||||
#define AR9300_EEPROM_MODAL_SPURS 5
|
||||
#define AR9300_MAX_RATE_POWER 63
|
||||
#define AR9300_NUM_PDADC_VALUES 128
|
||||
#define AR9300_NUM_RATES 16
|
||||
#define AR9300_BCHAN_UNUSED 0xFF
|
||||
#define AR9300_MAX_PWR_RANGE_IN_HALF_DB 64
|
||||
#define AR9300_OPFLAGS_11A 0x01
|
||||
#define AR9300_OPFLAGS_11G 0x02
|
||||
#define AR9300_OPFLAGS_5G_HT40 0x04
|
||||
#define AR9300_OPFLAGS_2G_HT40 0x08
|
||||
#define AR9300_OPFLAGS_5G_HT20 0x10
|
||||
#define AR9300_OPFLAGS_2G_HT20 0x20
|
||||
#define AR9300_EEPMISC_BIG_ENDIAN 0x01
|
||||
#define AR9300_EEPMISC_WOW 0x02
|
||||
#define AR9300_CUSTOMER_DATA_SIZE 20
|
||||
|
||||
#define FREQ2FBIN(x, y) ((y) ? ((x) - 2300) : (((x) - 4800) / 5))
|
||||
#define FBIN2FREQ(x, y) ((y) ? (2300 + x) : (4800 + 5 * x))
|
||||
#define AR9300_MAX_CHAINS 3
|
||||
#define AR9300_ANT_16S 25
|
||||
#define AR9300_FUTURE_MODAL_SZ 6
|
||||
|
||||
#define AR9300_NUM_ANT_CHAIN_FIELDS 7
|
||||
#define AR9300_NUM_ANT_COMMON_FIELDS 4
|
||||
#define AR9300_SIZE_ANT_CHAIN_FIELD 3
|
||||
#define AR9300_SIZE_ANT_COMMON_FIELD 4
|
||||
#define AR9300_ANT_CHAIN_MASK 0x7
|
||||
#define AR9300_ANT_COMMON_MASK 0xf
|
||||
#define AR9300_CHAIN_0_IDX 0
|
||||
#define AR9300_CHAIN_1_IDX 1
|
||||
#define AR9300_CHAIN_2_IDX 2
|
||||
|
||||
#define AR928X_NUM_ANT_CHAIN_FIELDS 6
|
||||
#define AR928X_SIZE_ANT_CHAIN_FIELD 2
|
||||
#define AR928X_ANT_CHAIN_MASK 0x3
|
||||
|
||||
/* Delta from which to start power to pdadc table */
|
||||
/* This offset is used in both open loop and closed loop power control
|
||||
* schemes. In open loop power control, it is not really needed, but for
|
||||
* the "sake of consistency" it was kept. For certain AP designs, this
|
||||
* value is overwritten by the value in the flag "pwrTableOffset" just
|
||||
* before writing the pdadc vs pwr into the chip registers.
|
||||
*/
|
||||
#define AR9300_PWR_TABLE_OFFSET 0
|
||||
|
||||
/* enable flags for voltage and temp compensation */
|
||||
#define ENABLE_TEMP_COMPENSATION 0x01
|
||||
#define ENABLE_VOLT_COMPENSATION 0x02
|
||||
/* byte addressable */
|
||||
#define AR9300_EEPROM_SIZE (16*1024)
|
||||
#define FIXED_CCA_THRESHOLD 15
|
||||
|
||||
#define AR9300_BASE_ADDR 0x3ff
|
||||
|
||||
enum targetPowerHTRates {
|
||||
HT_TARGET_RATE_0_8_16,
|
||||
HT_TARGET_RATE_1_3_9_11_17_19,
|
||||
HT_TARGET_RATE_4,
|
||||
HT_TARGET_RATE_5,
|
||||
HT_TARGET_RATE_6,
|
||||
HT_TARGET_RATE_7,
|
||||
HT_TARGET_RATE_12,
|
||||
HT_TARGET_RATE_13,
|
||||
HT_TARGET_RATE_14,
|
||||
HT_TARGET_RATE_15,
|
||||
HT_TARGET_RATE_20,
|
||||
HT_TARGET_RATE_21,
|
||||
HT_TARGET_RATE_22,
|
||||
HT_TARGET_RATE_23
|
||||
};
|
||||
|
||||
enum targetPowerLegacyRates {
|
||||
LEGACY_TARGET_RATE_6_24,
|
||||
LEGACY_TARGET_RATE_36,
|
||||
LEGACY_TARGET_RATE_48,
|
||||
LEGACY_TARGET_RATE_54
|
||||
};
|
||||
|
||||
enum targetPowerCckRates {
|
||||
LEGACY_TARGET_RATE_1L_5L,
|
||||
LEGACY_TARGET_RATE_5S,
|
||||
LEGACY_TARGET_RATE_11L,
|
||||
LEGACY_TARGET_RATE_11S
|
||||
};
|
||||
|
||||
enum ar9300_Rates {
|
||||
ALL_TARGET_LEGACY_6_24,
|
||||
ALL_TARGET_LEGACY_36,
|
||||
ALL_TARGET_LEGACY_48,
|
||||
ALL_TARGET_LEGACY_54,
|
||||
ALL_TARGET_LEGACY_1L_5L,
|
||||
ALL_TARGET_LEGACY_5S,
|
||||
ALL_TARGET_LEGACY_11L,
|
||||
ALL_TARGET_LEGACY_11S,
|
||||
ALL_TARGET_HT20_0_8_16,
|
||||
ALL_TARGET_HT20_1_3_9_11_17_19,
|
||||
ALL_TARGET_HT20_4,
|
||||
ALL_TARGET_HT20_5,
|
||||
ALL_TARGET_HT20_6,
|
||||
ALL_TARGET_HT20_7,
|
||||
ALL_TARGET_HT20_12,
|
||||
ALL_TARGET_HT20_13,
|
||||
ALL_TARGET_HT20_14,
|
||||
ALL_TARGET_HT20_15,
|
||||
ALL_TARGET_HT20_20,
|
||||
ALL_TARGET_HT20_21,
|
||||
ALL_TARGET_HT20_22,
|
||||
ALL_TARGET_HT20_23,
|
||||
ALL_TARGET_HT40_0_8_16,
|
||||
ALL_TARGET_HT40_1_3_9_11_17_19,
|
||||
ALL_TARGET_HT40_4,
|
||||
ALL_TARGET_HT40_5,
|
||||
ALL_TARGET_HT40_6,
|
||||
ALL_TARGET_HT40_7,
|
||||
ALL_TARGET_HT40_12,
|
||||
ALL_TARGET_HT40_13,
|
||||
ALL_TARGET_HT40_14,
|
||||
ALL_TARGET_HT40_15,
|
||||
ALL_TARGET_HT40_20,
|
||||
ALL_TARGET_HT40_21,
|
||||
ALL_TARGET_HT40_22,
|
||||
ALL_TARGET_HT40_23,
|
||||
ar9300RateSize,
|
||||
};
|
||||
|
||||
|
||||
struct eepFlags {
|
||||
u8 opFlags;
|
||||
u8 eepMisc;
|
||||
} __packed;
|
||||
|
||||
enum CompressAlgorithm {
|
||||
_CompressNone = 0,
|
||||
_CompressLzma,
|
||||
_CompressPairs,
|
||||
_CompressBlock,
|
||||
_Compress4,
|
||||
_Compress5,
|
||||
_Compress6,
|
||||
_Compress7,
|
||||
};
|
||||
|
||||
struct ar9300_base_eep_hdr {
|
||||
u16 regDmn[2];
|
||||
/* 4 bits tx and 4 bits rx */
|
||||
u8 txrxMask;
|
||||
struct eepFlags opCapFlags;
|
||||
u8 rfSilent;
|
||||
u8 blueToothOptions;
|
||||
u8 deviceCap;
|
||||
/* takes lower byte in eeprom location */
|
||||
u8 deviceType;
|
||||
/* offset in dB to be added to beginning
|
||||
* of pdadc table in calibration
|
||||
*/
|
||||
int8_t pwrTableOffset;
|
||||
u8 params_for_tuning_caps[2];
|
||||
/*
|
||||
* bit0 - enable tx temp comp
|
||||
* bit1 - enable tx volt comp
|
||||
* bit2 - enable fastClock - default to 1
|
||||
* bit3 - enable doubling - default to 1
|
||||
* bit4 - enable internal regulator - default to 1
|
||||
*/
|
||||
u8 featureEnable;
|
||||
/* misc flags: bit0 - turn down drivestrength */
|
||||
u8 miscConfiguration;
|
||||
u8 eepromWriteEnableGpio;
|
||||
u8 wlanDisableGpio;
|
||||
u8 wlanLedGpio;
|
||||
u8 rxBandSelectGpio;
|
||||
u8 txrxgain;
|
||||
/* SW controlled internal regulator fields */
|
||||
u32 swreg;
|
||||
} __packed;
|
||||
|
||||
struct ar9300_modal_eep_header {
|
||||
/* 4 idle, t1, t2, b (4 bits per setting) */
|
||||
u32 antCtrlCommon;
|
||||
/* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
|
||||
u32 antCtrlCommon2;
|
||||
/* 6 idle, t, r, rx1, rx12, b (2 bits each) */
|
||||
u16 antCtrlChain[AR9300_MAX_CHAINS];
|
||||
/* 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
|
||||
u8 xatten1DB[AR9300_MAX_CHAINS];
|
||||
/* 3 xatten1_margin for merlin (0xa20c/b20c 16:12 */
|
||||
u8 xatten1Margin[AR9300_MAX_CHAINS];
|
||||
int8_t tempSlope;
|
||||
int8_t voltSlope;
|
||||
/* spur channels in usual fbin coding format */
|
||||
u8 spurChans[AR9300_EEPROM_MODAL_SPURS];
|
||||
/* 3 Check if the register is per chain */
|
||||
int8_t noiseFloorThreshCh[AR9300_MAX_CHAINS];
|
||||
u8 ob[AR9300_MAX_CHAINS];
|
||||
u8 db_stage2[AR9300_MAX_CHAINS];
|
||||
u8 db_stage3[AR9300_MAX_CHAINS];
|
||||
u8 db_stage4[AR9300_MAX_CHAINS];
|
||||
u8 xpaBiasLvl;
|
||||
u8 txFrameToDataStart;
|
||||
u8 txFrameToPaOn;
|
||||
u8 txClip;
|
||||
int8_t antennaGain;
|
||||
u8 switchSettling;
|
||||
int8_t adcDesiredSize;
|
||||
u8 txEndToXpaOff;
|
||||
u8 txEndToRxOn;
|
||||
u8 txFrameToXpaOn;
|
||||
u8 thresh62;
|
||||
u8 futureModal[32];
|
||||
} __packed;
|
||||
|
||||
struct ar9300_cal_data_per_freq_op_loop {
|
||||
int8_t refPower;
|
||||
/* pdadc voltage at power measurement */
|
||||
u8 voltMeas;
|
||||
/* pcdac used for power measurement */
|
||||
u8 tempMeas;
|
||||
/* range is -60 to -127 create a mapping equation 1db resolution */
|
||||
int8_t rxNoisefloorCal;
|
||||
/*range is same as noisefloor */
|
||||
int8_t rxNoisefloorPower;
|
||||
/* temp measured when noisefloor cal was performed */
|
||||
u8 rxTempMeas;
|
||||
} __packed;
|
||||
|
||||
struct cal_tgt_pow_legacy {
|
||||
u8 tPow2x[4];
|
||||
} __packed;
|
||||
|
||||
struct cal_tgt_pow_ht {
|
||||
u8 tPow2x[14];
|
||||
} __packed;
|
||||
|
||||
struct cal_ctl_edge_pwr {
|
||||
u8 tPower:6,
|
||||
flag:2;
|
||||
} __packed;
|
||||
|
||||
struct cal_ctl_data_2g {
|
||||
struct cal_ctl_edge_pwr ctlEdges[AR9300_NUM_BAND_EDGES_5G];
|
||||
} __packed;
|
||||
|
||||
struct cal_ctl_data_5g {
|
||||
struct cal_ctl_edge_pwr ctlEdges[AR9300_NUM_BAND_EDGES_5G];
|
||||
} __packed;
|
||||
|
||||
struct ar9300_eeprom {
|
||||
u8 eepromVersion;
|
||||
u8 templateVersion;
|
||||
u8 macAddr[6];
|
||||
u8 custData[AR9300_CUSTOMER_DATA_SIZE];
|
||||
|
||||
struct ar9300_base_eep_hdr baseEepHeader;
|
||||
|
||||
struct ar9300_modal_eep_header modalHeader2G;
|
||||
u8 calFreqPier2G[AR9300_NUM_2G_CAL_PIERS];
|
||||
struct ar9300_cal_data_per_freq_op_loop
|
||||
calPierData2G[AR9300_MAX_CHAINS][AR9300_NUM_2G_CAL_PIERS];
|
||||
u8 calTarget_freqbin_Cck[AR9300_NUM_2G_CCK_TARGET_POWERS];
|
||||
u8 calTarget_freqbin_2G[AR9300_NUM_2G_20_TARGET_POWERS];
|
||||
u8 calTarget_freqbin_2GHT20[AR9300_NUM_2G_20_TARGET_POWERS];
|
||||
u8 calTarget_freqbin_2GHT40[AR9300_NUM_2G_40_TARGET_POWERS];
|
||||
struct cal_tgt_pow_legacy
|
||||
calTargetPowerCck[AR9300_NUM_2G_CCK_TARGET_POWERS];
|
||||
struct cal_tgt_pow_legacy
|
||||
calTargetPower2G[AR9300_NUM_2G_20_TARGET_POWERS];
|
||||
struct cal_tgt_pow_ht
|
||||
calTargetPower2GHT20[AR9300_NUM_2G_20_TARGET_POWERS];
|
||||
struct cal_tgt_pow_ht
|
||||
calTargetPower2GHT40[AR9300_NUM_2G_40_TARGET_POWERS];
|
||||
u8 ctlIndex_2G[AR9300_NUM_CTLS_2G];
|
||||
u8 ctl_freqbin_2G[AR9300_NUM_CTLS_2G][AR9300_NUM_BAND_EDGES_2G];
|
||||
struct cal_ctl_data_2g ctlPowerData_2G[AR9300_NUM_CTLS_2G];
|
||||
struct ar9300_modal_eep_header modalHeader5G;
|
||||
u8 calFreqPier5G[AR9300_NUM_5G_CAL_PIERS];
|
||||
struct ar9300_cal_data_per_freq_op_loop
|
||||
calPierData5G[AR9300_MAX_CHAINS][AR9300_NUM_5G_CAL_PIERS];
|
||||
u8 calTarget_freqbin_5G[AR9300_NUM_5G_20_TARGET_POWERS];
|
||||
u8 calTarget_freqbin_5GHT20[AR9300_NUM_5G_20_TARGET_POWERS];
|
||||
u8 calTarget_freqbin_5GHT40[AR9300_NUM_5G_40_TARGET_POWERS];
|
||||
struct cal_tgt_pow_legacy
|
||||
calTargetPower5G[AR9300_NUM_5G_20_TARGET_POWERS];
|
||||
struct cal_tgt_pow_ht
|
||||
calTargetPower5GHT20[AR9300_NUM_5G_20_TARGET_POWERS];
|
||||
struct cal_tgt_pow_ht
|
||||
calTargetPower5GHT40[AR9300_NUM_5G_40_TARGET_POWERS];
|
||||
u8 ctlIndex_5G[AR9300_NUM_CTLS_5G];
|
||||
u8 ctl_freqbin_5G[AR9300_NUM_CTLS_5G][AR9300_NUM_BAND_EDGES_5G];
|
||||
struct cal_ctl_data_5g ctlPowerData_5G[AR9300_NUM_CTLS_5G];
|
||||
} __packed;
|
||||
|
||||
s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah);
|
||||
s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah);
|
||||
|
||||
#endif
|
205
drivers/net/wireless/ath/ath9k/ar9003_hw.c
Normal file
205
drivers/net/wireless/ath/ath9k/ar9003_hw.c
Normal file
@ -0,0 +1,205 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2010 Atheros Communications Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "hw.h"
|
||||
#include "ar9003_mac.h"
|
||||
#include "ar9003_initvals.h"
|
||||
|
||||
/* General hardware code for the AR9003 hadware family */
|
||||
|
||||
static bool ar9003_hw_macversion_supported(u32 macversion)
|
||||
{
|
||||
switch (macversion) {
|
||||
case AR_SREV_VERSION_9300:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* AR9003 2.0 - new INI format (pre, core, post arrays per subsystem) */
|
||||
/*
|
||||
* XXX: move TX/RX gain INI to its own init_mode_gain_regs after
|
||||
* ensuring it does not affect hardware bring up
|
||||
*/
|
||||
static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
|
||||
{
|
||||
/* mac */
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
|
||||
ar9300_2p0_mac_core,
|
||||
ARRAY_SIZE(ar9300_2p0_mac_core), 2);
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
|
||||
ar9300_2p0_mac_postamble,
|
||||
ARRAY_SIZE(ar9300_2p0_mac_postamble), 5);
|
||||
|
||||
/* bb */
|
||||
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
|
||||
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
|
||||
ar9300_2p0_baseband_core,
|
||||
ARRAY_SIZE(ar9300_2p0_baseband_core), 2);
|
||||
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
|
||||
ar9300_2p0_baseband_postamble,
|
||||
ARRAY_SIZE(ar9300_2p0_baseband_postamble), 5);
|
||||
|
||||
/* radio */
|
||||
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
|
||||
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
|
||||
ar9300_2p0_radio_core,
|
||||
ARRAY_SIZE(ar9300_2p0_radio_core), 2);
|
||||
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
|
||||
ar9300_2p0_radio_postamble,
|
||||
ARRAY_SIZE(ar9300_2p0_radio_postamble), 5);
|
||||
|
||||
/* soc */
|
||||
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
|
||||
ar9300_2p0_soc_preamble,
|
||||
ARRAY_SIZE(ar9300_2p0_soc_preamble), 2);
|
||||
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
|
||||
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
|
||||
ar9300_2p0_soc_postamble,
|
||||
ARRAY_SIZE(ar9300_2p0_soc_postamble), 5);
|
||||
|
||||
/* rx/tx gain */
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9300Common_rx_gain_table_2p0,
|
||||
ARRAY_SIZE(ar9300Common_rx_gain_table_2p0), 2);
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9300Modes_lowest_ob_db_tx_gain_table_2p0,
|
||||
ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p0),
|
||||
5);
|
||||
|
||||
/* Load PCIE SERDES settings from INI */
|
||||
|
||||
/* Awake Setting */
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniPcieSerdes,
|
||||
ar9300PciePhy_pll_on_clkreq_disable_L1_2p0,
|
||||
ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p0),
|
||||
2);
|
||||
|
||||
/* Sleep Setting */
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
|
||||
ar9300PciePhy_clkreq_enable_L1_2p0,
|
||||
ARRAY_SIZE(ar9300PciePhy_clkreq_enable_L1_2p0),
|
||||
2);
|
||||
|
||||
/* Fast clock modal settings */
|
||||
INIT_INI_ARRAY(&ah->iniModesAdditional,
|
||||
ar9300Modes_fast_clock_2p0,
|
||||
ARRAY_SIZE(ar9300Modes_fast_clock_2p0),
|
||||
3);
|
||||
}
|
||||
|
||||
static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
|
||||
{
|
||||
switch (ar9003_hw_get_tx_gain_idx(ah)) {
|
||||
case 0:
|
||||
default:
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9300Modes_lowest_ob_db_tx_gain_table_2p0,
|
||||
ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p0),
|
||||
5);
|
||||
break;
|
||||
case 1:
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9300Modes_high_ob_db_tx_gain_table_2p0,
|
||||
ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p0),
|
||||
5);
|
||||
break;
|
||||
case 2:
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9300Modes_low_ob_db_tx_gain_table_2p0,
|
||||
ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p0),
|
||||
5);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
|
||||
{
|
||||
switch (ar9003_hw_get_rx_gain_idx(ah)) {
|
||||
case 0:
|
||||
default:
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain, ar9300Common_rx_gain_table_2p0,
|
||||
ARRAY_SIZE(ar9300Common_rx_gain_table_2p0),
|
||||
2);
|
||||
break;
|
||||
case 1:
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9300Common_wo_xlna_rx_gain_table_2p0,
|
||||
ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p0),
|
||||
2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* set gain table pointers according to values read from the eeprom */
|
||||
static void ar9003_hw_init_mode_gain_regs(struct ath_hw *ah)
|
||||
{
|
||||
ar9003_tx_gain_table_apply(ah);
|
||||
ar9003_rx_gain_table_apply(ah);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 ar9003_hw_configpcipowersave(struct ath_hw *ah,
|
||||
int restore,
|
||||
int power_off)
|
||||
{
|
||||
if (ah->is_pciexpress != true)
|
||||
return;
|
||||
|
||||
/* Do not touch SerDes registers */
|
||||
if (ah->config.pcie_powersave_enable == 2)
|
||||
return;
|
||||
|
||||
/* Nothing to do on restore for 11N */
|
||||
if (!restore) {
|
||||
/* 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);
|
||||
|
||||
/* Several PCIe massages to ensure proper behaviour */
|
||||
if (ah->config.pcie_waen)
|
||||
REG_WRITE(ah, AR_WA, ah->config.pcie_waen);
|
||||
}
|
||||
}
|
||||
|
||||
/* Sets up the AR9003 hardware familiy callbacks */
|
||||
void ar9003_hw_attach_ops(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
|
||||
struct ath_hw_ops *ops = ath9k_hw_ops(ah);
|
||||
|
||||
priv_ops->init_mode_regs = ar9003_hw_init_mode_regs;
|
||||
priv_ops->init_mode_gain_regs = ar9003_hw_init_mode_gain_regs;
|
||||
priv_ops->macversion_supported = ar9003_hw_macversion_supported;
|
||||
|
||||
ops->config_pci_powersave = ar9003_hw_configpcipowersave;
|
||||
|
||||
ar9003_hw_attach_phy_ops(ah);
|
||||
ar9003_hw_attach_calib_ops(ah);
|
||||
ar9003_hw_attach_mac_ops(ah);
|
||||
}
|
1793
drivers/net/wireless/ath/ath9k/ar9003_initvals.h
Normal file
1793
drivers/net/wireless/ath/ath9k/ar9003_initvals.h
Normal file
File diff suppressed because it is too large
Load Diff
611
drivers/net/wireless/ath/ath9k/ar9003_mac.c
Normal file
611
drivers/net/wireless/ath/ath9k/ar9003_mac.c
Normal file
@ -0,0 +1,611 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Atheros Communications Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include "hw.h"
|
||||
#include "ar9003_mac.h"
|
||||
|
||||
static void ar9003_hw_rx_enable(struct ath_hw *hw)
|
||||
{
|
||||
REG_WRITE(hw, AR_CR, 0);
|
||||
}
|
||||
|
||||
static u16 ar9003_calc_ptr_chksum(struct ar9003_txc *ads)
|
||||
{
|
||||
int checksum;
|
||||
|
||||
checksum = ads->info + ads->link
|
||||
+ ads->data0 + ads->ctl3
|
||||
+ ads->data1 + ads->ctl5
|
||||
+ ads->data2 + ads->ctl7
|
||||
+ ads->data3 + ads->ctl9;
|
||||
|
||||
return ((checksum & 0xffff) + (checksum >> 16)) & AR_TxPtrChkSum;
|
||||
}
|
||||
|
||||
static void ar9003_hw_set_desc_link(void *ds, u32 ds_link)
|
||||
{
|
||||
struct ar9003_txc *ads = ds;
|
||||
|
||||
ads->link = ds_link;
|
||||
ads->ctl10 &= ~AR_TxPtrChkSum;
|
||||
ads->ctl10 |= ar9003_calc_ptr_chksum(ads);
|
||||
}
|
||||
|
||||
static void ar9003_hw_get_desc_link(void *ds, u32 **ds_link)
|
||||
{
|
||||
struct ar9003_txc *ads = ds;
|
||||
|
||||
*ds_link = &ads->link;
|
||||
}
|
||||
|
||||
static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
|
||||
{
|
||||
u32 isr = 0;
|
||||
u32 mask2 = 0;
|
||||
struct ath9k_hw_capabilities *pCap = &ah->caps;
|
||||
u32 sync_cause = 0;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
|
||||
if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) {
|
||||
if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M)
|
||||
== AR_RTC_STATUS_ON)
|
||||
isr = REG_READ(ah, AR_ISR);
|
||||
}
|
||||
|
||||
sync_cause = REG_READ(ah, AR_INTR_SYNC_CAUSE) & AR_INTR_SYNC_DEFAULT;
|
||||
|
||||
*masked = 0;
|
||||
|
||||
if (!isr && !sync_cause)
|
||||
return false;
|
||||
|
||||
if (isr) {
|
||||
if (isr & AR_ISR_BCNMISC) {
|
||||
u32 isr2;
|
||||
isr2 = REG_READ(ah, AR_ISR_S2);
|
||||
|
||||
mask2 |= ((isr2 & AR_ISR_S2_TIM) >>
|
||||
MAP_ISR_S2_TIM);
|
||||
mask2 |= ((isr2 & AR_ISR_S2_DTIM) >>
|
||||
MAP_ISR_S2_DTIM);
|
||||
mask2 |= ((isr2 & AR_ISR_S2_DTIMSYNC) >>
|
||||
MAP_ISR_S2_DTIMSYNC);
|
||||
mask2 |= ((isr2 & AR_ISR_S2_CABEND) >>
|
||||
MAP_ISR_S2_CABEND);
|
||||
mask2 |= ((isr2 & AR_ISR_S2_GTT) <<
|
||||
MAP_ISR_S2_GTT);
|
||||
mask2 |= ((isr2 & AR_ISR_S2_CST) <<
|
||||
MAP_ISR_S2_CST);
|
||||
mask2 |= ((isr2 & AR_ISR_S2_TSFOOR) >>
|
||||
MAP_ISR_S2_TSFOOR);
|
||||
|
||||
if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) {
|
||||
REG_WRITE(ah, AR_ISR_S2, isr2);
|
||||
isr &= ~AR_ISR_BCNMISC;
|
||||
}
|
||||
}
|
||||
|
||||
if ((pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED))
|
||||
isr = REG_READ(ah, AR_ISR_RAC);
|
||||
|
||||
if (isr == 0xffffffff) {
|
||||
*masked = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
*masked = isr & ATH9K_INT_COMMON;
|
||||
|
||||
if (ah->config.rx_intr_mitigation)
|
||||
if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
|
||||
*masked |= ATH9K_INT_RXLP;
|
||||
|
||||
if (ah->config.tx_intr_mitigation)
|
||||
if (isr & (AR_ISR_TXMINTR | AR_ISR_TXINTM))
|
||||
*masked |= ATH9K_INT_TX;
|
||||
|
||||
if (isr & (AR_ISR_LP_RXOK | AR_ISR_RXERR))
|
||||
*masked |= ATH9K_INT_RXLP;
|
||||
|
||||
if (isr & AR_ISR_HP_RXOK)
|
||||
*masked |= ATH9K_INT_RXHP;
|
||||
|
||||
if (isr & (AR_ISR_TXOK | AR_ISR_TXERR | AR_ISR_TXEOL)) {
|
||||
*masked |= ATH9K_INT_TX;
|
||||
|
||||
if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) {
|
||||
u32 s0, s1;
|
||||
s0 = REG_READ(ah, AR_ISR_S0);
|
||||
REG_WRITE(ah, AR_ISR_S0, s0);
|
||||
s1 = REG_READ(ah, AR_ISR_S1);
|
||||
REG_WRITE(ah, AR_ISR_S1, s1);
|
||||
|
||||
isr &= ~(AR_ISR_TXOK | AR_ISR_TXERR |
|
||||
AR_ISR_TXEOL);
|
||||
}
|
||||
}
|
||||
|
||||
if (isr & AR_ISR_GENTMR) {
|
||||
u32 s5;
|
||||
|
||||
if (pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)
|
||||
s5 = REG_READ(ah, AR_ISR_S5_S);
|
||||
else
|
||||
s5 = REG_READ(ah, AR_ISR_S5);
|
||||
|
||||
ah->intr_gen_timer_trigger =
|
||||
MS(s5, AR_ISR_S5_GENTIMER_TRIG);
|
||||
|
||||
ah->intr_gen_timer_thresh =
|
||||
MS(s5, AR_ISR_S5_GENTIMER_THRESH);
|
||||
|
||||
if (ah->intr_gen_timer_trigger)
|
||||
*masked |= ATH9K_INT_GENTIMER;
|
||||
|
||||
if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) {
|
||||
REG_WRITE(ah, AR_ISR_S5, s5);
|
||||
isr &= ~AR_ISR_GENTMR;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
*masked |= mask2;
|
||||
|
||||
if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) {
|
||||
REG_WRITE(ah, AR_ISR, isr);
|
||||
|
||||
(void) REG_READ(ah, AR_ISR);
|
||||
}
|
||||
}
|
||||
|
||||
if (sync_cause) {
|
||||
if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
|
||||
REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
|
||||
REG_WRITE(ah, AR_RC, 0);
|
||||
*masked |= ATH9K_INT_FATAL;
|
||||
}
|
||||
|
||||
if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT)
|
||||
ath_print(common, ATH_DBG_INTERRUPT,
|
||||
"AR_INTR_SYNC_LOCAL_TIMEOUT\n");
|
||||
|
||||
REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
|
||||
(void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ar9003_hw_fill_txdesc(struct ath_hw *ah, void *ds, u32 seglen,
|
||||
bool is_firstseg, bool is_lastseg,
|
||||
const void *ds0, dma_addr_t buf_addr,
|
||||
unsigned int qcu)
|
||||
{
|
||||
struct ar9003_txc *ads = (struct ar9003_txc *) ds;
|
||||
unsigned int descid = 0;
|
||||
|
||||
ads->info = (ATHEROS_VENDOR_ID << AR_DescId_S) |
|
||||
(1 << AR_TxRxDesc_S) |
|
||||
(1 << AR_CtrlStat_S) |
|
||||
(qcu << AR_TxQcuNum_S) | 0x17;
|
||||
|
||||
ads->data0 = buf_addr;
|
||||
ads->data1 = 0;
|
||||
ads->data2 = 0;
|
||||
ads->data3 = 0;
|
||||
|
||||
ads->ctl3 = (seglen << AR_BufLen_S);
|
||||
ads->ctl3 &= AR_BufLen;
|
||||
|
||||
/* Fill in pointer checksum and descriptor id */
|
||||
ads->ctl10 = ar9003_calc_ptr_chksum(ads);
|
||||
ads->ctl10 |= (descid << AR_TxDescId_S);
|
||||
|
||||
if (is_firstseg) {
|
||||
ads->ctl12 |= (is_lastseg ? 0 : AR_TxMore);
|
||||
} else if (is_lastseg) {
|
||||
ads->ctl11 = 0;
|
||||
ads->ctl12 = 0;
|
||||
ads->ctl13 = AR9003TXC_CONST(ds0)->ctl13;
|
||||
ads->ctl14 = AR9003TXC_CONST(ds0)->ctl14;
|
||||
} else {
|
||||
/* XXX Intermediate descriptor in a multi-descriptor frame.*/
|
||||
ads->ctl11 = 0;
|
||||
ads->ctl12 = AR_TxMore;
|
||||
ads->ctl13 = 0;
|
||||
ads->ctl14 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
|
||||
struct ath_tx_status *ts)
|
||||
{
|
||||
struct ar9003_txs *ads;
|
||||
|
||||
ads = &ah->ts_ring[ah->ts_tail];
|
||||
|
||||
if ((ads->status8 & AR_TxDone) == 0)
|
||||
return -EINPROGRESS;
|
||||
|
||||
ah->ts_tail = (ah->ts_tail + 1) % ah->ts_size;
|
||||
|
||||
if ((MS(ads->ds_info, AR_DescId) != ATHEROS_VENDOR_ID) ||
|
||||
(MS(ads->ds_info, AR_TxRxDesc) != 1)) {
|
||||
ath_print(ath9k_hw_common(ah), ATH_DBG_XMIT,
|
||||
"Tx Descriptor error %x\n", ads->ds_info);
|
||||
memset(ads, 0, sizeof(*ads));
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
ts->qid = MS(ads->ds_info, AR_TxQcuNum);
|
||||
ts->desc_id = MS(ads->status1, AR_TxDescId);
|
||||
ts->ts_seqnum = MS(ads->status8, AR_SeqNum);
|
||||
ts->ts_tstamp = ads->status4;
|
||||
ts->ts_status = 0;
|
||||
ts->ts_flags = 0;
|
||||
|
||||
if (ads->status3 & AR_ExcessiveRetries)
|
||||
ts->ts_status |= ATH9K_TXERR_XRETRY;
|
||||
if (ads->status3 & AR_Filtered)
|
||||
ts->ts_status |= ATH9K_TXERR_FILT;
|
||||
if (ads->status3 & AR_FIFOUnderrun) {
|
||||
ts->ts_status |= ATH9K_TXERR_FIFO;
|
||||
ath9k_hw_updatetxtriglevel(ah, true);
|
||||
}
|
||||
if (ads->status8 & AR_TxOpExceeded)
|
||||
ts->ts_status |= ATH9K_TXERR_XTXOP;
|
||||
if (ads->status3 & AR_TxTimerExpired)
|
||||
ts->ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
|
||||
|
||||
if (ads->status3 & AR_DescCfgErr)
|
||||
ts->ts_flags |= ATH9K_TX_DESC_CFG_ERR;
|
||||
if (ads->status3 & AR_TxDataUnderrun) {
|
||||
ts->ts_flags |= ATH9K_TX_DATA_UNDERRUN;
|
||||
ath9k_hw_updatetxtriglevel(ah, true);
|
||||
}
|
||||
if (ads->status3 & AR_TxDelimUnderrun) {
|
||||
ts->ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
|
||||
ath9k_hw_updatetxtriglevel(ah, true);
|
||||
}
|
||||
if (ads->status2 & AR_TxBaStatus) {
|
||||
ts->ts_flags |= ATH9K_TX_BA;
|
||||
ts->ba_low = ads->status5;
|
||||
ts->ba_high = ads->status6;
|
||||
}
|
||||
|
||||
ts->ts_rateindex = MS(ads->status8, AR_FinalTxIdx);
|
||||
|
||||
ts->ts_rssi = MS(ads->status7, AR_TxRSSICombined);
|
||||
ts->ts_rssi_ctl0 = MS(ads->status2, AR_TxRSSIAnt00);
|
||||
ts->ts_rssi_ctl1 = MS(ads->status2, AR_TxRSSIAnt01);
|
||||
ts->ts_rssi_ctl2 = MS(ads->status2, AR_TxRSSIAnt02);
|
||||
ts->ts_rssi_ext0 = MS(ads->status7, AR_TxRSSIAnt10);
|
||||
ts->ts_rssi_ext1 = MS(ads->status7, AR_TxRSSIAnt11);
|
||||
ts->ts_rssi_ext2 = MS(ads->status7, AR_TxRSSIAnt12);
|
||||
ts->ts_shortretry = MS(ads->status3, AR_RTSFailCnt);
|
||||
ts->ts_longretry = MS(ads->status3, AR_DataFailCnt);
|
||||
ts->ts_virtcol = MS(ads->status3, AR_VirtRetryCnt);
|
||||
ts->ts_antenna = 0;
|
||||
|
||||
ts->tid = MS(ads->status8, AR_TxTid);
|
||||
|
||||
memset(ads, 0, sizeof(*ads));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ar9003_hw_set11n_txdesc(struct ath_hw *ah, void *ds,
|
||||
u32 pktlen, enum ath9k_pkt_type type, u32 txpower,
|
||||
u32 keyIx, enum ath9k_key_type keyType, u32 flags)
|
||||
{
|
||||
struct ar9003_txc *ads = (struct ar9003_txc *) ds;
|
||||
|
||||
txpower += ah->txpower_indexoffset;
|
||||
if (txpower > 63)
|
||||
txpower = 63;
|
||||
|
||||
ads->ctl11 = (pktlen & AR_FrameLen)
|
||||
| (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
|
||||
| SM(txpower, AR_XmitPower)
|
||||
| (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
|
||||
| (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
|
||||
| (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0)
|
||||
| (flags & ATH9K_TXDESC_LOWRXCHAIN ? AR_LowRxChain : 0);
|
||||
|
||||
ads->ctl12 =
|
||||
(keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0)
|
||||
| SM(type, AR_FrameType)
|
||||
| (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
|
||||
| (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
|
||||
| (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
|
||||
|
||||
ads->ctl17 = SM(keyType, AR_EncrType) |
|
||||
(flags & ATH9K_TXDESC_LDPC ? AR_LDPC : 0);
|
||||
ads->ctl18 = 0;
|
||||
ads->ctl19 = AR_Not_Sounding;
|
||||
|
||||
ads->ctl20 = 0;
|
||||
ads->ctl21 = 0;
|
||||
ads->ctl22 = 0;
|
||||
}
|
||||
|
||||
static void ar9003_hw_set11n_ratescenario(struct ath_hw *ah, void *ds,
|
||||
void *lastds,
|
||||
u32 durUpdateEn, u32 rtsctsRate,
|
||||
u32 rtsctsDuration,
|
||||
struct ath9k_11n_rate_series series[],
|
||||
u32 nseries, u32 flags)
|
||||
{
|
||||
struct ar9003_txc *ads = (struct ar9003_txc *) ds;
|
||||
struct ar9003_txc *last_ads = (struct ar9003_txc *) lastds;
|
||||
u_int32_t ctl11;
|
||||
|
||||
if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
|
||||
ctl11 = ads->ctl11;
|
||||
|
||||
if (flags & ATH9K_TXDESC_RTSENA) {
|
||||
ctl11 &= ~AR_CTSEnable;
|
||||
ctl11 |= AR_RTSEnable;
|
||||
} else {
|
||||
ctl11 &= ~AR_RTSEnable;
|
||||
ctl11 |= AR_CTSEnable;
|
||||
}
|
||||
|
||||
ads->ctl11 = ctl11;
|
||||
} else {
|
||||
ads->ctl11 = (ads->ctl11 & ~(AR_RTSEnable | AR_CTSEnable));
|
||||
}
|
||||
|
||||
ads->ctl13 = set11nTries(series, 0)
|
||||
| set11nTries(series, 1)
|
||||
| set11nTries(series, 2)
|
||||
| set11nTries(series, 3)
|
||||
| (durUpdateEn ? AR_DurUpdateEna : 0)
|
||||
| SM(0, AR_BurstDur);
|
||||
|
||||
ads->ctl14 = set11nRate(series, 0)
|
||||
| set11nRate(series, 1)
|
||||
| set11nRate(series, 2)
|
||||
| set11nRate(series, 3);
|
||||
|
||||
ads->ctl15 = set11nPktDurRTSCTS(series, 0)
|
||||
| set11nPktDurRTSCTS(series, 1);
|
||||
|
||||
ads->ctl16 = set11nPktDurRTSCTS(series, 2)
|
||||
| set11nPktDurRTSCTS(series, 3);
|
||||
|
||||
ads->ctl18 = set11nRateFlags(series, 0)
|
||||
| set11nRateFlags(series, 1)
|
||||
| set11nRateFlags(series, 2)
|
||||
| set11nRateFlags(series, 3)
|
||||
| SM(rtsctsRate, AR_RTSCTSRate);
|
||||
ads->ctl19 = AR_Not_Sounding;
|
||||
|
||||
last_ads->ctl13 = ads->ctl13;
|
||||
last_ads->ctl14 = ads->ctl14;
|
||||
}
|
||||
|
||||
static void ar9003_hw_set11n_aggr_first(struct ath_hw *ah, void *ds,
|
||||
u32 aggrLen)
|
||||
{
|
||||
struct ar9003_txc *ads = (struct ar9003_txc *) ds;
|
||||
|
||||
ads->ctl12 |= (AR_IsAggr | AR_MoreAggr);
|
||||
|
||||
ads->ctl17 &= ~AR_AggrLen;
|
||||
ads->ctl17 |= SM(aggrLen, AR_AggrLen);
|
||||
}
|
||||
|
||||
static void ar9003_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds,
|
||||
u32 numDelims)
|
||||
{
|
||||
struct ar9003_txc *ads = (struct ar9003_txc *) ds;
|
||||
unsigned int ctl17;
|
||||
|
||||
ads->ctl12 |= (AR_IsAggr | AR_MoreAggr);
|
||||
|
||||
/*
|
||||
* We use a stack variable to manipulate ctl6 to reduce uncached
|
||||
* read modify, modfiy, write.
|
||||
*/
|
||||
ctl17 = ads->ctl17;
|
||||
ctl17 &= ~AR_PadDelim;
|
||||
ctl17 |= SM(numDelims, AR_PadDelim);
|
||||
ads->ctl17 = ctl17;
|
||||
}
|
||||
|
||||
static void ar9003_hw_set11n_aggr_last(struct ath_hw *ah, void *ds)
|
||||
{
|
||||
struct ar9003_txc *ads = (struct ar9003_txc *) ds;
|
||||
|
||||
ads->ctl12 |= AR_IsAggr;
|
||||
ads->ctl12 &= ~AR_MoreAggr;
|
||||
ads->ctl17 &= ~AR_PadDelim;
|
||||
}
|
||||
|
||||
static void ar9003_hw_clr11n_aggr(struct ath_hw *ah, void *ds)
|
||||
{
|
||||
struct ar9003_txc *ads = (struct ar9003_txc *) ds;
|
||||
|
||||
ads->ctl12 &= (~AR_IsAggr & ~AR_MoreAggr);
|
||||
}
|
||||
|
||||
static void ar9003_hw_set11n_burstduration(struct ath_hw *ah, void *ds,
|
||||
u32 burstDuration)
|
||||
{
|
||||
struct ar9003_txc *ads = (struct ar9003_txc *) ds;
|
||||
|
||||
ads->ctl13 &= ~AR_BurstDur;
|
||||
ads->ctl13 |= SM(burstDuration, AR_BurstDur);
|
||||
|
||||
}
|
||||
|
||||
static void ar9003_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds,
|
||||
u32 vmf)
|
||||
{
|
||||
struct ar9003_txc *ads = (struct ar9003_txc *) ds;
|
||||
|
||||
if (vmf)
|
||||
ads->ctl11 |= AR_VirtMoreFrag;
|
||||
else
|
||||
ads->ctl11 &= ~AR_VirtMoreFrag;
|
||||
}
|
||||
|
||||
void ar9003_hw_attach_mac_ops(struct ath_hw *hw)
|
||||
{
|
||||
struct ath_hw_ops *ops = ath9k_hw_ops(hw);
|
||||
|
||||
ops->rx_enable = ar9003_hw_rx_enable;
|
||||
ops->set_desc_link = ar9003_hw_set_desc_link;
|
||||
ops->get_desc_link = ar9003_hw_get_desc_link;
|
||||
ops->get_isr = ar9003_hw_get_isr;
|
||||
ops->fill_txdesc = ar9003_hw_fill_txdesc;
|
||||
ops->proc_txdesc = ar9003_hw_proc_txdesc;
|
||||
ops->set11n_txdesc = ar9003_hw_set11n_txdesc;
|
||||
ops->set11n_ratescenario = ar9003_hw_set11n_ratescenario;
|
||||
ops->set11n_aggr_first = ar9003_hw_set11n_aggr_first;
|
||||
ops->set11n_aggr_middle = ar9003_hw_set11n_aggr_middle;
|
||||
ops->set11n_aggr_last = ar9003_hw_set11n_aggr_last;
|
||||
ops->clr11n_aggr = ar9003_hw_clr11n_aggr;
|
||||
ops->set11n_burstduration = ar9003_hw_set11n_burstduration;
|
||||
ops->set11n_virtualmorefrag = ar9003_hw_set11n_virtualmorefrag;
|
||||
}
|
||||
|
||||
void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size)
|
||||
{
|
||||
REG_WRITE(ah, AR_DATABUF_SIZE, buf_size & AR_DATABUF_SIZE_MASK);
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_set_rx_bufsize);
|
||||
|
||||
void ath9k_hw_addrxbuf_edma(struct ath_hw *ah, u32 rxdp,
|
||||
enum ath9k_rx_qtype qtype)
|
||||
{
|
||||
if (qtype == ATH9K_RX_QUEUE_HP)
|
||||
REG_WRITE(ah, AR_HP_RXDP, rxdp);
|
||||
else
|
||||
REG_WRITE(ah, AR_LP_RXDP, rxdp);
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_addrxbuf_edma);
|
||||
|
||||
int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
|
||||
void *buf_addr)
|
||||
{
|
||||
struct ar9003_rxs *rxsp = (struct ar9003_rxs *) buf_addr;
|
||||
unsigned int phyerr;
|
||||
|
||||
/* TODO: byte swap on big endian for ar9300_10 */
|
||||
|
||||
if ((rxsp->status11 & AR_RxDone) == 0)
|
||||
return -EINPROGRESS;
|
||||
|
||||
if (MS(rxsp->ds_info, AR_DescId) != 0x168c)
|
||||
return -EINVAL;
|
||||
|
||||
if ((rxsp->ds_info & (AR_TxRxDesc | AR_CtrlStat)) != 0)
|
||||
return -EINPROGRESS;
|
||||
|
||||
if (!rxs)
|
||||
return 0;
|
||||
|
||||
rxs->rs_status = 0;
|
||||
rxs->rs_flags = 0;
|
||||
|
||||
rxs->rs_datalen = rxsp->status2 & AR_DataLen;
|
||||
rxs->rs_tstamp = rxsp->status3;
|
||||
|
||||
/* XXX: Keycache */
|
||||
rxs->rs_rssi = MS(rxsp->status5, AR_RxRSSICombined);
|
||||
rxs->rs_rssi_ctl0 = MS(rxsp->status1, AR_RxRSSIAnt00);
|
||||
rxs->rs_rssi_ctl1 = MS(rxsp->status1, AR_RxRSSIAnt01);
|
||||
rxs->rs_rssi_ctl2 = MS(rxsp->status1, AR_RxRSSIAnt02);
|
||||
rxs->rs_rssi_ext0 = MS(rxsp->status5, AR_RxRSSIAnt10);
|
||||
rxs->rs_rssi_ext1 = MS(rxsp->status5, AR_RxRSSIAnt11);
|
||||
rxs->rs_rssi_ext2 = MS(rxsp->status5, AR_RxRSSIAnt12);
|
||||
|
||||
if (rxsp->status11 & AR_RxKeyIdxValid)
|
||||
rxs->rs_keyix = MS(rxsp->status11, AR_KeyIdx);
|
||||
else
|
||||
rxs->rs_keyix = ATH9K_RXKEYIX_INVALID;
|
||||
|
||||
rxs->rs_rate = MS(rxsp->status1, AR_RxRate);
|
||||
rxs->rs_more = (rxsp->status2 & AR_RxMore) ? 1 : 0;
|
||||
|
||||
rxs->rs_isaggr = (rxsp->status11 & AR_RxAggr) ? 1 : 0;
|
||||
rxs->rs_moreaggr = (rxsp->status11 & AR_RxMoreAggr) ? 1 : 0;
|
||||
rxs->rs_antenna = (MS(rxsp->status4, AR_RxAntenna) & 0x7);
|
||||
rxs->rs_flags = (rxsp->status4 & AR_GI) ? ATH9K_RX_GI : 0;
|
||||
rxs->rs_flags |= (rxsp->status4 & AR_2040) ? ATH9K_RX_2040 : 0;
|
||||
|
||||
rxs->evm0 = rxsp->status6;
|
||||
rxs->evm1 = rxsp->status7;
|
||||
rxs->evm2 = rxsp->status8;
|
||||
rxs->evm3 = rxsp->status9;
|
||||
rxs->evm4 = (rxsp->status10 & 0xffff);
|
||||
|
||||
if (rxsp->status11 & AR_PreDelimCRCErr)
|
||||
rxs->rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
|
||||
|
||||
if (rxsp->status11 & AR_PostDelimCRCErr)
|
||||
rxs->rs_flags |= ATH9K_RX_DELIM_CRC_POST;
|
||||
|
||||
if (rxsp->status11 & AR_DecryptBusyErr)
|
||||
rxs->rs_flags |= ATH9K_RX_DECRYPT_BUSY;
|
||||
|
||||
if ((rxsp->status11 & AR_RxFrameOK) == 0) {
|
||||
if (rxsp->status11 & AR_CRCErr) {
|
||||
rxs->rs_status |= ATH9K_RXERR_CRC;
|
||||
} else if (rxsp->status11 & AR_PHYErr) {
|
||||
rxs->rs_status |= ATH9K_RXERR_PHY;
|
||||
phyerr = MS(rxsp->status11, AR_PHYErrCode);
|
||||
rxs->rs_phyerr = phyerr;
|
||||
} else if (rxsp->status11 & AR_DecryptCRCErr) {
|
||||
rxs->rs_status |= ATH9K_RXERR_DECRYPT;
|
||||
} else if (rxsp->status11 & AR_MichaelErr) {
|
||||
rxs->rs_status |= ATH9K_RXERR_MIC;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_process_rxdesc_edma);
|
||||
|
||||
void ath9k_hw_reset_txstatus_ring(struct ath_hw *ah)
|
||||
{
|
||||
ah->ts_tail = 0;
|
||||
|
||||
memset((void *) ah->ts_ring, 0,
|
||||
ah->ts_size * sizeof(struct ar9003_txs));
|
||||
|
||||
ath_print(ath9k_hw_common(ah), ATH_DBG_XMIT,
|
||||
"TS Start 0x%x End 0x%x Virt %p, Size %d\n",
|
||||
ah->ts_paddr_start, ah->ts_paddr_end,
|
||||
ah->ts_ring, ah->ts_size);
|
||||
|
||||
REG_WRITE(ah, AR_Q_STATUS_RING_START, ah->ts_paddr_start);
|
||||
REG_WRITE(ah, AR_Q_STATUS_RING_END, ah->ts_paddr_end);
|
||||
}
|
||||
|
||||
void ath9k_hw_setup_statusring(struct ath_hw *ah, void *ts_start,
|
||||
u32 ts_paddr_start,
|
||||
u8 size)
|
||||
{
|
||||
|
||||
ah->ts_paddr_start = ts_paddr_start;
|
||||
ah->ts_paddr_end = ts_paddr_start + (size * sizeof(struct ar9003_txs));
|
||||
ah->ts_size = size;
|
||||
ah->ts_ring = (struct ar9003_txs *) ts_start;
|
||||
|
||||
ath9k_hw_reset_txstatus_ring(ah);
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_setup_statusring);
|
120
drivers/net/wireless/ath/ath9k/ar9003_mac.h
Normal file
120
drivers/net/wireless/ath/ath9k/ar9003_mac.h
Normal file
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Atheros Communications Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef AR9003_MAC_H
|
||||
#define AR9003_MAC_H
|
||||
|
||||
#define AR_DescId 0xffff0000
|
||||
#define AR_DescId_S 16
|
||||
#define AR_CtrlStat 0x00004000
|
||||
#define AR_CtrlStat_S 14
|
||||
#define AR_TxRxDesc 0x00008000
|
||||
#define AR_TxRxDesc_S 15
|
||||
#define AR_TxQcuNum 0x00000f00
|
||||
#define AR_TxQcuNum_S 8
|
||||
|
||||
#define AR_BufLen 0x0fff0000
|
||||
#define AR_BufLen_S 16
|
||||
|
||||
#define AR_TxDescId 0xffff0000
|
||||
#define AR_TxDescId_S 16
|
||||
#define AR_TxPtrChkSum 0x0000ffff
|
||||
|
||||
#define AR_TxTid 0xf0000000
|
||||
#define AR_TxTid_S 28
|
||||
|
||||
#define AR_LowRxChain 0x00004000
|
||||
|
||||
#define AR_Not_Sounding 0x20000000
|
||||
|
||||
#define MAP_ISR_S2_CST 6
|
||||
#define MAP_ISR_S2_GTT 6
|
||||
#define MAP_ISR_S2_TIM 3
|
||||
#define MAP_ISR_S2_CABEND 0
|
||||
#define MAP_ISR_S2_DTIMSYNC 7
|
||||
#define MAP_ISR_S2_DTIM 7
|
||||
#define MAP_ISR_S2_TSFOOR 4
|
||||
|
||||
#define AR9003TXC_CONST(_ds) ((const struct ar9003_txc *) _ds)
|
||||
|
||||
struct ar9003_rxs {
|
||||
u32 ds_info;
|
||||
u32 status1;
|
||||
u32 status2;
|
||||
u32 status3;
|
||||
u32 status4;
|
||||
u32 status5;
|
||||
u32 status6;
|
||||
u32 status7;
|
||||
u32 status8;
|
||||
u32 status9;
|
||||
u32 status10;
|
||||
u32 status11;
|
||||
} __packed;
|
||||
|
||||
/* Transmit Control Descriptor */
|
||||
struct ar9003_txc {
|
||||
u32 info; /* descriptor information */
|
||||
u32 link; /* link pointer */
|
||||
u32 data0; /* data pointer to 1st buffer */
|
||||
u32 ctl3; /* DMA control 3 */
|
||||
u32 data1; /* data pointer to 2nd buffer */
|
||||
u32 ctl5; /* DMA control 5 */
|
||||
u32 data2; /* data pointer to 3rd buffer */
|
||||
u32 ctl7; /* DMA control 7 */
|
||||
u32 data3; /* data pointer to 4th buffer */
|
||||
u32 ctl9; /* DMA control 9 */
|
||||
u32 ctl10; /* DMA control 10 */
|
||||
u32 ctl11; /* DMA control 11 */
|
||||
u32 ctl12; /* DMA control 12 */
|
||||
u32 ctl13; /* DMA control 13 */
|
||||
u32 ctl14; /* DMA control 14 */
|
||||
u32 ctl15; /* DMA control 15 */
|
||||
u32 ctl16; /* DMA control 16 */
|
||||
u32 ctl17; /* DMA control 17 */
|
||||
u32 ctl18; /* DMA control 18 */
|
||||
u32 ctl19; /* DMA control 19 */
|
||||
u32 ctl20; /* DMA control 20 */
|
||||
u32 ctl21; /* DMA control 21 */
|
||||
u32 ctl22; /* DMA control 22 */
|
||||
u32 pad[9]; /* pad to cache line (128 bytes/32 dwords) */
|
||||
} __packed;
|
||||
|
||||
struct ar9003_txs {
|
||||
u32 ds_info;
|
||||
u32 status1;
|
||||
u32 status2;
|
||||
u32 status3;
|
||||
u32 status4;
|
||||
u32 status5;
|
||||
u32 status6;
|
||||
u32 status7;
|
||||
u32 status8;
|
||||
} __packed;
|
||||
|
||||
void ar9003_hw_attach_mac_ops(struct ath_hw *hw);
|
||||
void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size);
|
||||
void ath9k_hw_addrxbuf_edma(struct ath_hw *ah, u32 rxdp,
|
||||
enum ath9k_rx_qtype qtype);
|
||||
|
||||
int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah,
|
||||
struct ath_rx_status *rxs,
|
||||
void *buf_addr);
|
||||
void ath9k_hw_reset_txstatus_ring(struct ath_hw *ah);
|
||||
void ath9k_hw_setup_statusring(struct ath_hw *ah, void *ts_start,
|
||||
u32 ts_paddr_start,
|
||||
u8 size);
|
||||
#endif
|
1142
drivers/net/wireless/ath/ath9k/ar9003_phy.c
Normal file
1142
drivers/net/wireless/ath/ath9k/ar9003_phy.c
Normal file
File diff suppressed because it is too large
Load Diff
847
drivers/net/wireless/ath/ath9k/ar9003_phy.h
Normal file
847
drivers/net/wireless/ath/ath9k/ar9003_phy.h
Normal file
@ -0,0 +1,847 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2010 Atheros Communications, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef AR9003_PHY_H
|
||||
#define AR9003_PHY_H
|
||||
|
||||
/*
|
||||
* Channel Register Map
|
||||
*/
|
||||
#define AR_CHAN_BASE 0x9800
|
||||
|
||||
#define AR_PHY_TIMING1 (AR_CHAN_BASE + 0x0)
|
||||
#define AR_PHY_TIMING2 (AR_CHAN_BASE + 0x4)
|
||||
#define AR_PHY_TIMING3 (AR_CHAN_BASE + 0x8)
|
||||
#define AR_PHY_TIMING4 (AR_CHAN_BASE + 0xc)
|
||||
#define AR_PHY_TIMING5 (AR_CHAN_BASE + 0x10)
|
||||
#define AR_PHY_TIMING6 (AR_CHAN_BASE + 0x14)
|
||||
#define AR_PHY_TIMING11 (AR_CHAN_BASE + 0x18)
|
||||
#define AR_PHY_SPUR_REG (AR_CHAN_BASE + 0x1c)
|
||||
#define AR_PHY_RX_IQCAL_CORR_B0 (AR_CHAN_BASE + 0xdc)
|
||||
#define AR_PHY_TX_IQCAL_CONTROL_3 (AR_CHAN_BASE + 0xb0)
|
||||
|
||||
#define AR_PHY_TIMING11_SPUR_FREQ_SD 0x3FF00000
|
||||
#define AR_PHY_TIMING11_SPUR_FREQ_SD_S 20
|
||||
|
||||
#define AR_PHY_TIMING11_SPUR_DELTA_PHASE 0x000FFFFF
|
||||
#define AR_PHY_TIMING11_SPUR_DELTA_PHASE_S 0
|
||||
|
||||
#define AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC 0x40000000
|
||||
#define AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC_S 30
|
||||
|
||||
#define AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR 0x80000000
|
||||
#define AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR_S 31
|
||||
|
||||
#define AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT 0x4000000
|
||||
#define AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT_S 26
|
||||
|
||||
#define AR_PHY_SPUR_REG_ENABLE_MASK_PPM 0x20000 /* bins move with freq offset */
|
||||
#define AR_PHY_SPUR_REG_ENABLE_MASK_PPM_S 17
|
||||
#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH 0x000000FF
|
||||
#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH_S 0
|
||||
#define AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI 0x00000100
|
||||
#define AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI_S 8
|
||||
#define AR_PHY_SPUR_REG_MASK_RATE_CNTL 0x03FC0000
|
||||
#define AR_PHY_SPUR_REG_MASK_RATE_CNTL_S 18
|
||||
|
||||
#define AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN 0x20000000
|
||||
#define AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN_S 29
|
||||
|
||||
#define AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN 0x80000000
|
||||
#define AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN_S 31
|
||||
|
||||
#define AR_PHY_FIND_SIG_LOW (AR_CHAN_BASE + 0x20)
|
||||
|
||||
#define AR_PHY_SFCORR (AR_CHAN_BASE + 0x24)
|
||||
#define AR_PHY_SFCORR_LOW (AR_CHAN_BASE + 0x28)
|
||||
#define AR_PHY_SFCORR_EXT (AR_CHAN_BASE + 0x2c)
|
||||
|
||||
#define AR_PHY_EXT_CCA (AR_CHAN_BASE + 0x30)
|
||||
#define AR_PHY_RADAR_0 (AR_CHAN_BASE + 0x34)
|
||||
#define AR_PHY_RADAR_1 (AR_CHAN_BASE + 0x38)
|
||||
#define AR_PHY_RADAR_EXT (AR_CHAN_BASE + 0x3c)
|
||||
#define AR_PHY_MULTICHAIN_CTRL (AR_CHAN_BASE + 0x80)
|
||||
#define AR_PHY_PERCHAIN_CSD (AR_CHAN_BASE + 0x84)
|
||||
|
||||
#define AR_PHY_TX_PHASE_RAMP_0 (AR_CHAN_BASE + 0xd0)
|
||||
#define AR_PHY_ADC_GAIN_DC_CORR_0 (AR_CHAN_BASE + 0xd4)
|
||||
#define AR_PHY_IQ_ADC_MEAS_0_B0 (AR_CHAN_BASE + 0xc0)
|
||||
#define AR_PHY_IQ_ADC_MEAS_1_B0 (AR_CHAN_BASE + 0xc4)
|
||||
#define AR_PHY_IQ_ADC_MEAS_2_B0 (AR_CHAN_BASE + 0xc8)
|
||||
#define AR_PHY_IQ_ADC_MEAS_3_B0 (AR_CHAN_BASE + 0xcc)
|
||||
|
||||
/* The following registers changed position from AR9300 1.0 to AR9300 2.0 */
|
||||
#define AR_PHY_TX_PHASE_RAMP_0_9300_10 (AR_CHAN_BASE + 0xd0 - 0x10)
|
||||
#define AR_PHY_ADC_GAIN_DC_CORR_0_9300_10 (AR_CHAN_BASE + 0xd4 - 0x10)
|
||||
#define AR_PHY_IQ_ADC_MEAS_0_B0_9300_10 (AR_CHAN_BASE + 0xc0 + 0x8)
|
||||
#define AR_PHY_IQ_ADC_MEAS_1_B0_9300_10 (AR_CHAN_BASE + 0xc4 + 0x8)
|
||||
#define AR_PHY_IQ_ADC_MEAS_2_B0_9300_10 (AR_CHAN_BASE + 0xc8 + 0x8)
|
||||
#define AR_PHY_IQ_ADC_MEAS_3_B0_9300_10 (AR_CHAN_BASE + 0xcc + 0x8)
|
||||
|
||||
#define AR_PHY_TX_CRC (AR_CHAN_BASE + 0xa0)
|
||||
#define AR_PHY_TST_DAC_CONST (AR_CHAN_BASE + 0xa4)
|
||||
#define AR_PHY_SPUR_REPORT_0 (AR_CHAN_BASE + 0xa8)
|
||||
#define AR_PHY_CHAN_INFO_TAB_0 (AR_CHAN_BASE + 0x300)
|
||||
|
||||
/*
|
||||
* Channel Field Definitions
|
||||
*/
|
||||
#define AR_PHY_TIMING2_USE_FORCE_PPM 0x00001000
|
||||
#define AR_PHY_TIMING2_FORCE_PPM_VAL 0x00000fff
|
||||
#define AR_PHY_TIMING3_DSC_MAN 0xFFFE0000
|
||||
#define AR_PHY_TIMING3_DSC_MAN_S 17
|
||||
#define AR_PHY_TIMING3_DSC_EXP 0x0001E000
|
||||
#define AR_PHY_TIMING3_DSC_EXP_S 13
|
||||
#define AR_PHY_TIMING4_IQCAL_LOG_COUNT_MAX 0xF000
|
||||
#define AR_PHY_TIMING4_IQCAL_LOG_COUNT_MAX_S 12
|
||||
#define AR_PHY_TIMING4_DO_CAL 0x10000
|
||||
|
||||
#define AR_PHY_TIMING4_ENABLE_PILOT_MASK 0x10000000
|
||||
#define AR_PHY_TIMING4_ENABLE_PILOT_MASK_S 28
|
||||
#define AR_PHY_TIMING4_ENABLE_CHAN_MASK 0x20000000
|
||||
#define AR_PHY_TIMING4_ENABLE_CHAN_MASK_S 29
|
||||
|
||||
#define AR_PHY_TIMING4_ENABLE_SPUR_FILTER 0x40000000
|
||||
#define AR_PHY_TIMING4_ENABLE_SPUR_FILTER_S 30
|
||||
#define AR_PHY_TIMING4_ENABLE_SPUR_RSSI 0x80000000
|
||||
#define AR_PHY_TIMING4_ENABLE_SPUR_RSSI_S 31
|
||||
|
||||
#define AR_PHY_NEW_ADC_GAIN_CORR_ENABLE 0x40000000
|
||||
#define AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE 0x80000000
|
||||
#define AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW 0x00000001
|
||||
#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW 0x00003F00
|
||||
#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW_S 8
|
||||
#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW 0x001FC000
|
||||
#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW_S 14
|
||||
#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW 0x0FE00000
|
||||
#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW_S 21
|
||||
#define AR_PHY_SFCORR_M2COUNT_THR 0x0000001F
|
||||
#define AR_PHY_SFCORR_M2COUNT_THR_S 0
|
||||
#define AR_PHY_SFCORR_M1_THRESH 0x00FE0000
|
||||
#define AR_PHY_SFCORR_M1_THRESH_S 17
|
||||
#define AR_PHY_SFCORR_M2_THRESH 0x7F000000
|
||||
#define AR_PHY_SFCORR_M2_THRESH_S 24
|
||||
#define AR_PHY_SFCORR_EXT_M1_THRESH 0x0000007F
|
||||
#define AR_PHY_SFCORR_EXT_M1_THRESH_S 0
|
||||
#define AR_PHY_SFCORR_EXT_M2_THRESH 0x00003F80
|
||||
#define AR_PHY_SFCORR_EXT_M2_THRESH_S 7
|
||||
#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW 0x001FC000
|
||||
#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW_S 14
|
||||
#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW 0x0FE00000
|
||||
#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW_S 21
|
||||
#define AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD 0x10000000
|
||||
#define AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD_S 28
|
||||
#define AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S 28
|
||||
#define AR_PHY_EXT_CCA_THRESH62 0x007F0000
|
||||
#define AR_PHY_EXT_CCA_THRESH62_S 16
|
||||
#define AR_PHY_EXT_MINCCA_PWR 0x01FF0000
|
||||
#define AR_PHY_EXT_MINCCA_PWR_S 16
|
||||
#define AR_PHY_TIMING5_CYCPWR_THR1 0x000000FE
|
||||
#define AR_PHY_TIMING5_CYCPWR_THR1_S 1
|
||||
#define AR_PHY_TIMING5_CYCPWR_THR1_ENABLE 0x00000001
|
||||
#define AR_PHY_TIMING5_CYCPWR_THR1_ENABLE_S 0
|
||||
#define AR_PHY_TIMING5_CYCPWR_THR1A 0x007F0000
|
||||
#define AR_PHY_TIMING5_CYCPWR_THR1A_S 16
|
||||
#define AR_PHY_TIMING5_RSSI_THR1A (0x7F << 16)
|
||||
#define AR_PHY_TIMING5_RSSI_THR1A_S 16
|
||||
#define AR_PHY_TIMING5_RSSI_THR1A_ENA (0x1 << 15)
|
||||
#define AR_PHY_RADAR_0_ENA 0x00000001
|
||||
#define AR_PHY_RADAR_0_FFT_ENA 0x80000000
|
||||
#define AR_PHY_RADAR_0_INBAND 0x0000003e
|
||||
#define AR_PHY_RADAR_0_INBAND_S 1
|
||||
#define AR_PHY_RADAR_0_PRSSI 0x00000FC0
|
||||
#define AR_PHY_RADAR_0_PRSSI_S 6
|
||||
#define AR_PHY_RADAR_0_HEIGHT 0x0003F000
|
||||
#define AR_PHY_RADAR_0_HEIGHT_S 12
|
||||
#define AR_PHY_RADAR_0_RRSSI 0x00FC0000
|
||||
#define AR_PHY_RADAR_0_RRSSI_S 18
|
||||
#define AR_PHY_RADAR_0_FIRPWR 0x7F000000
|
||||
#define AR_PHY_RADAR_0_FIRPWR_S 24
|
||||
#define AR_PHY_RADAR_1_RELPWR_ENA 0x00800000
|
||||
#define AR_PHY_RADAR_1_USE_FIR128 0x00400000
|
||||
#define AR_PHY_RADAR_1_RELPWR_THRESH 0x003F0000
|
||||
#define AR_PHY_RADAR_1_RELPWR_THRESH_S 16
|
||||
#define AR_PHY_RADAR_1_BLOCK_CHECK 0x00008000
|
||||
#define AR_PHY_RADAR_1_MAX_RRSSI 0x00004000
|
||||
#define AR_PHY_RADAR_1_RELSTEP_CHECK 0x00002000
|
||||
#define AR_PHY_RADAR_1_RELSTEP_THRESH 0x00001F00
|
||||
#define AR_PHY_RADAR_1_RELSTEP_THRESH_S 8
|
||||
#define AR_PHY_RADAR_1_MAXLEN 0x000000FF
|
||||
#define AR_PHY_RADAR_1_MAXLEN_S 0
|
||||
#define AR_PHY_RADAR_EXT_ENA 0x00004000
|
||||
#define AR_PHY_RADAR_DC_PWR_THRESH 0x007f8000
|
||||
#define AR_PHY_RADAR_DC_PWR_THRESH_S 15
|
||||
#define AR_PHY_RADAR_LB_DC_CAP 0x7f800000
|
||||
#define AR_PHY_RADAR_LB_DC_CAP_S 23
|
||||
#define AR_PHY_FIND_SIG_LOW_FIRSTEP_LOW (0x3f << 6)
|
||||
#define AR_PHY_FIND_SIG_LOW_FIRSTEP_LOW_S 6
|
||||
#define AR_PHY_FIND_SIG_LOW_FIRPWR (0x7f << 12)
|
||||
#define AR_PHY_FIND_SIG_LOW_FIRPWR_S 12
|
||||
#define AR_PHY_FIND_SIG_LOW_FIRPWR_SIGN_BIT 19
|
||||
#define AR_PHY_FIND_SIG_LOW_RELSTEP 0x1f
|
||||
#define AR_PHY_FIND_SIG_LOW_RELSTEP_S 0
|
||||
#define AR_PHY_FIND_SIG_LOW_RELSTEP_SIGN_BIT 5
|
||||
#define AR_PHY_CHAN_INFO_TAB_S2_READ 0x00000008
|
||||
#define AR_PHY_CHAN_INFO_TAB_S2_READ_S 3
|
||||
#define AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF 0x0000007F
|
||||
#define AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF_S 0
|
||||
#define AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF 0x00003F80
|
||||
#define AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF_S 7
|
||||
#define AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE 0x00004000
|
||||
#define AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_Q_COFF 0x003f8000
|
||||
#define AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_Q_COFF_S 15
|
||||
#define AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_I_COFF 0x1fc00000
|
||||
#define AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_I_COFF_S 22
|
||||
|
||||
/*
|
||||
* MRC Register Map
|
||||
*/
|
||||
#define AR_MRC_BASE 0x9c00
|
||||
|
||||
#define AR_PHY_TIMING_3A (AR_MRC_BASE + 0x0)
|
||||
#define AR_PHY_LDPC_CNTL1 (AR_MRC_BASE + 0x4)
|
||||
#define AR_PHY_LDPC_CNTL2 (AR_MRC_BASE + 0x8)
|
||||
#define AR_PHY_PILOT_SPUR_MASK (AR_MRC_BASE + 0xc)
|
||||
#define AR_PHY_CHAN_SPUR_MASK (AR_MRC_BASE + 0x10)
|
||||
#define AR_PHY_SGI_DELTA (AR_MRC_BASE + 0x14)
|
||||
#define AR_PHY_ML_CNTL_1 (AR_MRC_BASE + 0x18)
|
||||
#define AR_PHY_ML_CNTL_2 (AR_MRC_BASE + 0x1c)
|
||||
#define AR_PHY_TST_ADC (AR_MRC_BASE + 0x20)
|
||||
|
||||
#define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A 0x00000FE0
|
||||
#define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A_S 5
|
||||
#define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A 0x1F
|
||||
#define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A_S 0
|
||||
|
||||
#define AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A 0x00000FE0
|
||||
#define AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A_S 5
|
||||
#define AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_A 0x1F
|
||||
#define AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_A_S 0
|
||||
|
||||
/*
|
||||
* MRC Feild Definitions
|
||||
*/
|
||||
#define AR_PHY_SGI_DSC_MAN 0x0007FFF0
|
||||
#define AR_PHY_SGI_DSC_MAN_S 4
|
||||
#define AR_PHY_SGI_DSC_EXP 0x0000000F
|
||||
#define AR_PHY_SGI_DSC_EXP_S 0
|
||||
/*
|
||||
* BBB Register Map
|
||||
*/
|
||||
#define AR_BBB_BASE 0x9d00
|
||||
|
||||
/*
|
||||
* AGC Register Map
|
||||
*/
|
||||
#define AR_AGC_BASE 0x9e00
|
||||
|
||||
#define AR_PHY_SETTLING (AR_AGC_BASE + 0x0)
|
||||
#define AR_PHY_FORCEMAX_GAINS_0 (AR_AGC_BASE + 0x4)
|
||||
#define AR_PHY_GAINS_MINOFF0 (AR_AGC_BASE + 0x8)
|
||||
#define AR_PHY_DESIRED_SZ (AR_AGC_BASE + 0xc)
|
||||
#define AR_PHY_FIND_SIG (AR_AGC_BASE + 0x10)
|
||||
#define AR_PHY_AGC (AR_AGC_BASE + 0x14)
|
||||
#define AR_PHY_EXT_ATTEN_CTL_0 (AR_AGC_BASE + 0x18)
|
||||
#define AR_PHY_CCA_0 (AR_AGC_BASE + 0x1c)
|
||||
#define AR_PHY_EXT_CCA0 (AR_AGC_BASE + 0x20)
|
||||
#define AR_PHY_RESTART (AR_AGC_BASE + 0x24)
|
||||
#define AR_PHY_MC_GAIN_CTRL (AR_AGC_BASE + 0x28)
|
||||
#define AR_PHY_EXTCHN_PWRTHR1 (AR_AGC_BASE + 0x2c)
|
||||
#define AR_PHY_EXT_CHN_WIN (AR_AGC_BASE + 0x30)
|
||||
#define AR_PHY_20_40_DET_THR (AR_AGC_BASE + 0x34)
|
||||
#define AR_PHY_RIFS_SRCH (AR_AGC_BASE + 0x38)
|
||||
#define AR_PHY_PEAK_DET_CTRL_1 (AR_AGC_BASE + 0x3c)
|
||||
#define AR_PHY_PEAK_DET_CTRL_2 (AR_AGC_BASE + 0x40)
|
||||
#define AR_PHY_RX_GAIN_BOUNDS_1 (AR_AGC_BASE + 0x44)
|
||||
#define AR_PHY_RX_GAIN_BOUNDS_2 (AR_AGC_BASE + 0x48)
|
||||
#define AR_PHY_RSSI_0 (AR_AGC_BASE + 0x180)
|
||||
#define AR_PHY_SPUR_CCK_REP0 (AR_AGC_BASE + 0x184)
|
||||
#define AR_PHY_CCK_DETECT (AR_AGC_BASE + 0x1c0)
|
||||
#define AR_PHY_DAG_CTRLCCK (AR_AGC_BASE + 0x1c4)
|
||||
#define AR_PHY_IQCORR_CTRL_CCK (AR_AGC_BASE + 0x1c8)
|
||||
|
||||
#define AR_PHY_CCK_SPUR_MIT (AR_AGC_BASE + 0x1cc)
|
||||
#define AR_PHY_CCK_SPUR_MIT_SPUR_RSSI_THR 0x000001fe
|
||||
#define AR_PHY_CCK_SPUR_MIT_SPUR_RSSI_THR_S 1
|
||||
#define AR_PHY_CCK_SPUR_MIT_SPUR_FILTER_TYPE 0x60000000
|
||||
#define AR_PHY_CCK_SPUR_MIT_SPUR_FILTER_TYPE_S 29
|
||||
#define AR_PHY_CCK_SPUR_MIT_USE_CCK_SPUR_MIT 0x00000001
|
||||
#define AR_PHY_CCK_SPUR_MIT_USE_CCK_SPUR_MIT_S 0
|
||||
#define AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ 0x1ffffe00
|
||||
#define AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ_S 9
|
||||
|
||||
#define AR_PHY_RX_OCGAIN (AR_AGC_BASE + 0x200)
|
||||
|
||||
#define AR_PHY_CCA_NOM_VAL_9300_2GHZ -110
|
||||
#define AR_PHY_CCA_NOM_VAL_9300_5GHZ -115
|
||||
#define AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ -125
|
||||
#define AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ -125
|
||||
#define AR_PHY_CCA_MAX_GOOD_VAL_9300_2GHZ -95
|
||||
#define AR_PHY_CCA_MAX_GOOD_VAL_9300_5GHZ -100
|
||||
|
||||
/*
|
||||
* AGC Field Definitions
|
||||
*/
|
||||
#define AR_PHY_EXT_ATTEN_CTL_RXTX_MARGIN 0x00FC0000
|
||||
#define AR_PHY_EXT_ATTEN_CTL_RXTX_MARGIN_S 18
|
||||
#define AR_PHY_EXT_ATTEN_CTL_BSW_MARGIN 0x00003C00
|
||||
#define AR_PHY_EXT_ATTEN_CTL_BSW_MARGIN_S 10
|
||||
#define AR_PHY_EXT_ATTEN_CTL_BSW_ATTEN 0x0000001F
|
||||
#define AR_PHY_EXT_ATTEN_CTL_BSW_ATTEN_S 0
|
||||
#define AR_PHY_EXT_ATTEN_CTL_XATTEN2_MARGIN 0x003E0000
|
||||
#define AR_PHY_EXT_ATTEN_CTL_XATTEN2_MARGIN_S 17
|
||||
#define AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN 0x0001F000
|
||||
#define AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN_S 12
|
||||
#define AR_PHY_EXT_ATTEN_CTL_XATTEN2_DB 0x00000FC0
|
||||
#define AR_PHY_EXT_ATTEN_CTL_XATTEN2_DB_S 6
|
||||
#define AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB 0x0000003F
|
||||
#define AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB_S 0
|
||||
#define AR_PHY_RXGAIN_TXRX_ATTEN 0x0003F000
|
||||
#define AR_PHY_RXGAIN_TXRX_ATTEN_S 12
|
||||
#define AR_PHY_RXGAIN_TXRX_RF_MAX 0x007C0000
|
||||
#define AR_PHY_RXGAIN_TXRX_RF_MAX_S 18
|
||||
#define AR9280_PHY_RXGAIN_TXRX_ATTEN 0x00003F80
|
||||
#define AR9280_PHY_RXGAIN_TXRX_ATTEN_S 7
|
||||
#define AR9280_PHY_RXGAIN_TXRX_MARGIN 0x001FC000
|
||||
#define AR9280_PHY_RXGAIN_TXRX_MARGIN_S 14
|
||||
#define AR_PHY_SETTLING_SWITCH 0x00003F80
|
||||
#define AR_PHY_SETTLING_SWITCH_S 7
|
||||
#define AR_PHY_DESIRED_SZ_ADC 0x000000FF
|
||||
#define AR_PHY_DESIRED_SZ_ADC_S 0
|
||||
#define AR_PHY_DESIRED_SZ_PGA 0x0000FF00
|
||||
#define AR_PHY_DESIRED_SZ_PGA_S 8
|
||||
#define AR_PHY_DESIRED_SZ_TOT_DES 0x0FF00000
|
||||
#define AR_PHY_DESIRED_SZ_TOT_DES_S 20
|
||||
#define AR_PHY_MINCCA_PWR 0x1FF00000
|
||||
#define AR_PHY_MINCCA_PWR_S 20
|
||||
#define AR_PHY_CCA_THRESH62 0x0007F000
|
||||
#define AR_PHY_CCA_THRESH62_S 12
|
||||
#define AR9280_PHY_MINCCA_PWR 0x1FF00000
|
||||
#define AR9280_PHY_MINCCA_PWR_S 20
|
||||
#define AR9280_PHY_CCA_THRESH62 0x000FF000
|
||||
#define AR9280_PHY_CCA_THRESH62_S 12
|
||||
#define AR_PHY_EXT_CCA0_THRESH62 0x000000FF
|
||||
#define AR_PHY_EXT_CCA0_THRESH62_S 0
|
||||
#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK 0x0000003F
|
||||
#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_S 0
|
||||
#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME 0x00001FC0
|
||||
#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME_S 6
|
||||
#define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV 0x2000
|
||||
|
||||
#define AR_PHY_DAG_CTRLCCK_EN_RSSI_THR 0x00000200
|
||||
#define AR_PHY_DAG_CTRLCCK_EN_RSSI_THR_S 9
|
||||
#define AR_PHY_DAG_CTRLCCK_RSSI_THR 0x0001FC00
|
||||
#define AR_PHY_DAG_CTRLCCK_RSSI_THR_S 10
|
||||
|
||||
#define AR_PHY_RIFS_INIT_DELAY 0x3ff0000
|
||||
#define AR_PHY_AGC_COARSE_LOW 0x00007F80
|
||||
#define AR_PHY_AGC_COARSE_LOW_S 7
|
||||
#define AR_PHY_AGC_COARSE_HIGH 0x003F8000
|
||||
#define AR_PHY_AGC_COARSE_HIGH_S 15
|
||||
#define AR_PHY_AGC_COARSE_PWR_CONST 0x0000007F
|
||||
#define AR_PHY_AGC_COARSE_PWR_CONST_S 0
|
||||
#define AR_PHY_FIND_SIG_FIRSTEP 0x0003F000
|
||||
#define AR_PHY_FIND_SIG_FIRSTEP_S 12
|
||||
#define AR_PHY_FIND_SIG_FIRPWR 0x03FC0000
|
||||
#define AR_PHY_FIND_SIG_FIRPWR_S 18
|
||||
#define AR_PHY_FIND_SIG_FIRPWR_SIGN_BIT 25
|
||||
#define AR_PHY_FIND_SIG_RELPWR (0x1f << 6)
|
||||
#define AR_PHY_FIND_SIG_RELPWR_S 6
|
||||
#define AR_PHY_FIND_SIG_RELPWR_SIGN_BIT 11
|
||||
#define AR_PHY_FIND_SIG_RELSTEP 0x1f
|
||||
#define AR_PHY_FIND_SIG_RELSTEP_S 0
|
||||
#define AR_PHY_FIND_SIG_RELSTEP_SIGN_BIT 5
|
||||
#define AR_PHY_RESTART_DIV_GC 0x001C0000
|
||||
#define AR_PHY_RESTART_DIV_GC_S 18
|
||||
#define AR_PHY_RESTART_ENA 0x01
|
||||
#define AR_PHY_DC_RESTART_DIS 0x40000000
|
||||
|
||||
#define AR_PHY_TPC_OLPC_GAIN_DELTA_PAL_ON 0xFF000000
|
||||
#define AR_PHY_TPC_OLPC_GAIN_DELTA_PAL_ON_S 24
|
||||
#define AR_PHY_TPC_OLPC_GAIN_DELTA 0x00FF0000
|
||||
#define AR_PHY_TPC_OLPC_GAIN_DELTA_S 16
|
||||
|
||||
#define AR_PHY_TPC_6_ERROR_EST_MODE 0x03000000
|
||||
#define AR_PHY_TPC_6_ERROR_EST_MODE_S 24
|
||||
|
||||
/*
|
||||
* SM Register Map
|
||||
*/
|
||||
#define AR_SM_BASE 0xa200
|
||||
|
||||
#define AR_PHY_D2_CHIP_ID (AR_SM_BASE + 0x0)
|
||||
#define AR_PHY_GEN_CTRL (AR_SM_BASE + 0x4)
|
||||
#define AR_PHY_MODE (AR_SM_BASE + 0x8)
|
||||
#define AR_PHY_ACTIVE (AR_SM_BASE + 0xc)
|
||||
#define AR_PHY_SPUR_MASK_A (AR_SM_BASE + 0x20)
|
||||
#define AR_PHY_SPUR_MASK_B (AR_SM_BASE + 0x24)
|
||||
#define AR_PHY_SPECTRAL_SCAN (AR_SM_BASE + 0x28)
|
||||
#define AR_PHY_RADAR_BW_FILTER (AR_SM_BASE + 0x2c)
|
||||
#define AR_PHY_SEARCH_START_DELAY (AR_SM_BASE + 0x30)
|
||||
#define AR_PHY_MAX_RX_LEN (AR_SM_BASE + 0x34)
|
||||
#define AR_PHY_FRAME_CTL (AR_SM_BASE + 0x38)
|
||||
#define AR_PHY_RFBUS_REQ (AR_SM_BASE + 0x3c)
|
||||
#define AR_PHY_RFBUS_GRANT (AR_SM_BASE + 0x40)
|
||||
#define AR_PHY_RIFS (AR_SM_BASE + 0x44)
|
||||
#define AR_PHY_RX_CLR_DELAY (AR_SM_BASE + 0x50)
|
||||
#define AR_PHY_RX_DELAY (AR_SM_BASE + 0x54)
|
||||
|
||||
#define AR_PHY_XPA_TIMING_CTL (AR_SM_BASE + 0x64)
|
||||
#define AR_PHY_MISC_PA_CTL (AR_SM_BASE + 0x80)
|
||||
#define AR_PHY_SWITCH_CHAIN_0 (AR_SM_BASE + 0x84)
|
||||
#define AR_PHY_SWITCH_COM (AR_SM_BASE + 0x88)
|
||||
#define AR_PHY_SWITCH_COM_2 (AR_SM_BASE + 0x8c)
|
||||
#define AR_PHY_RX_CHAINMASK (AR_SM_BASE + 0xa0)
|
||||
#define AR_PHY_CAL_CHAINMASK (AR_SM_BASE + 0xc0)
|
||||
#define AR_PHY_CALMODE (AR_SM_BASE + 0xc8)
|
||||
#define AR_PHY_FCAL_1 (AR_SM_BASE + 0xcc)
|
||||
#define AR_PHY_FCAL_2_0 (AR_SM_BASE + 0xd0)
|
||||
#define AR_PHY_DFT_TONE_CTL_0 (AR_SM_BASE + 0xd4)
|
||||
#define AR_PHY_CL_CAL_CTL (AR_SM_BASE + 0xd8)
|
||||
#define AR_PHY_CL_TAB_0 (AR_SM_BASE + 0x100)
|
||||
#define AR_PHY_SYNTH_CONTROL (AR_SM_BASE + 0x140)
|
||||
#define AR_PHY_ADDAC_CLK_SEL (AR_SM_BASE + 0x144)
|
||||
#define AR_PHY_PLL_CTL (AR_SM_BASE + 0x148)
|
||||
#define AR_PHY_ANALOG_SWAP (AR_SM_BASE + 0x14c)
|
||||
#define AR_PHY_ADDAC_PARA_CTL (AR_SM_BASE + 0x150)
|
||||
#define AR_PHY_XPA_CFG (AR_SM_BASE + 0x158)
|
||||
|
||||
#define AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A 0x0001FC00
|
||||
#define AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A_S 10
|
||||
#define AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A 0x3FF
|
||||
#define AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A_S 0
|
||||
|
||||
#define AR_PHY_TEST (AR_SM_BASE + 0x160)
|
||||
|
||||
#define AR_PHY_TEST_BBB_OBS_SEL 0x780000
|
||||
#define AR_PHY_TEST_BBB_OBS_SEL_S 19
|
||||
|
||||
#define AR_PHY_TEST_RX_OBS_SEL_BIT5_S 23
|
||||
#define AR_PHY_TEST_RX_OBS_SEL_BIT5 (1 << AR_PHY_TEST_RX_OBS_SEL_BIT5_S)
|
||||
|
||||
#define AR_PHY_TEST_CHAIN_SEL 0xC0000000
|
||||
#define AR_PHY_TEST_CHAIN_SEL_S 30
|
||||
|
||||
#define AR_PHY_TEST_CTL_STATUS (AR_SM_BASE + 0x164)
|
||||
#define AR_PHY_TEST_CTL_TSTDAC_EN 0x1
|
||||
#define AR_PHY_TEST_CTL_TSTDAC_EN_S 0
|
||||
#define AR_PHY_TEST_CTL_TX_OBS_SEL 0x1C
|
||||
#define AR_PHY_TEST_CTL_TX_OBS_SEL_S 2
|
||||
#define AR_PHY_TEST_CTL_TX_OBS_MUX_SEL 0x60
|
||||
#define AR_PHY_TEST_CTL_TX_OBS_MUX_SEL_S 5
|
||||
#define AR_PHY_TEST_CTL_TSTADC_EN 0x100
|
||||
#define AR_PHY_TEST_CTL_TSTADC_EN_S 8
|
||||
#define AR_PHY_TEST_CTL_RX_OBS_SEL 0x3C00
|
||||
#define AR_PHY_TEST_CTL_RX_OBS_SEL_S 10
|
||||
|
||||
|
||||
#define AR_PHY_TSTDAC (AR_SM_BASE + 0x168)
|
||||
|
||||
#define AR_PHY_CHAN_STATUS (AR_SM_BASE + 0x16c)
|
||||
#define AR_PHY_CHAN_INFO_MEMORY (AR_SM_BASE + 0x170)
|
||||
#define AR_PHY_CHNINFO_NOISEPWR (AR_SM_BASE + 0x174)
|
||||
#define AR_PHY_CHNINFO_GAINDIFF (AR_SM_BASE + 0x178)
|
||||
#define AR_PHY_CHNINFO_FINETIM (AR_SM_BASE + 0x17c)
|
||||
#define AR_PHY_CHAN_INFO_GAIN_0 (AR_SM_BASE + 0x180)
|
||||
#define AR_PHY_SCRAMBLER_SEED (AR_SM_BASE + 0x190)
|
||||
#define AR_PHY_CCK_TX_CTRL (AR_SM_BASE + 0x194)
|
||||
|
||||
#define AR_PHY_HEAVYCLIP_CTL (AR_SM_BASE + 0x1a4)
|
||||
#define AR_PHY_HEAVYCLIP_20 (AR_SM_BASE + 0x1a8)
|
||||
#define AR_PHY_HEAVYCLIP_40 (AR_SM_BASE + 0x1ac)
|
||||
#define AR_PHY_ILLEGAL_TXRATE (AR_SM_BASE + 0x1b0)
|
||||
|
||||
#define AR_PHY_PWRTX_MAX (AR_SM_BASE + 0x1f0)
|
||||
#define AR_PHY_POWER_TX_SUB (AR_SM_BASE + 0x1f4)
|
||||
|
||||
#define AR_PHY_TPC_4_B0 (AR_SM_BASE + 0x204)
|
||||
#define AR_PHY_TPC_5_B0 (AR_SM_BASE + 0x208)
|
||||
#define AR_PHY_TPC_6_B0 (AR_SM_BASE + 0x20c)
|
||||
#define AR_PHY_TPC_11_B0 (AR_SM_BASE + 0x220)
|
||||
#define AR_PHY_TPC_18 (AR_SM_BASE + 0x23c)
|
||||
#define AR_PHY_TPC_19 (AR_SM_BASE + 0x240)
|
||||
|
||||
#define AR_PHY_TX_FORCED_GAIN (AR_SM_BASE + 0x258)
|
||||
|
||||
#define AR_PHY_PDADC_TAB_0 (AR_SM_BASE + 0x280)
|
||||
|
||||
#define AR_PHY_TX_IQCAL_CONTROL_1 (AR_SM_BASE + 0x448)
|
||||
#define AR_PHY_TX_IQCAL_START (AR_SM_BASE + 0x440)
|
||||
#define AR_PHY_TX_IQCAL_STATUS_B0 (AR_SM_BASE + 0x48c)
|
||||
#define AR_PHY_TX_IQCAL_CORR_COEFF_01_B0 (AR_SM_BASE + 0x450)
|
||||
|
||||
#define AR_PHY_PANIC_WD_STATUS (AR_SM_BASE + 0x5c0)
|
||||
#define AR_PHY_PANIC_WD_CTL_1 (AR_SM_BASE + 0x5c4)
|
||||
#define AR_PHY_PANIC_WD_CTL_2 (AR_SM_BASE + 0x5c8)
|
||||
#define AR_PHY_BT_CTL (AR_SM_BASE + 0x5cc)
|
||||
#define AR_PHY_ONLY_WARMRESET (AR_SM_BASE + 0x5d0)
|
||||
#define AR_PHY_ONLY_CTL (AR_SM_BASE + 0x5d4)
|
||||
#define AR_PHY_ECO_CTRL (AR_SM_BASE + 0x5dc)
|
||||
#define AR_PHY_BB_THERM_ADC_1 (AR_SM_BASE + 0x248)
|
||||
|
||||
#define AR_PHY_65NM_CH0_SYNTH4 0x1608c
|
||||
#define AR_PHY_SYNTH4_LONG_SHIFT_SELECT 0x00000002
|
||||
#define AR_PHY_SYNTH4_LONG_SHIFT_SELECT_S 1
|
||||
#define AR_PHY_65NM_CH0_SYNTH7 0x16098
|
||||
#define AR_PHY_65NM_CH0_BIAS1 0x160c0
|
||||
#define AR_PHY_65NM_CH0_BIAS2 0x160c4
|
||||
#define AR_PHY_65NM_CH0_BIAS4 0x160cc
|
||||
#define AR_PHY_65NM_CH0_RXTX4 0x1610c
|
||||
#define AR_PHY_65NM_CH0_THERM 0x16290
|
||||
|
||||
#define AR_PHY_65NM_CH0_THERM_LOCAL 0x80000000
|
||||
#define AR_PHY_65NM_CH0_THERM_LOCAL_S 31
|
||||
#define AR_PHY_65NM_CH0_THERM_START 0x20000000
|
||||
#define AR_PHY_65NM_CH0_THERM_START_S 29
|
||||
#define AR_PHY_65NM_CH0_THERM_SAR_ADC_OUT 0x0000ff00
|
||||
#define AR_PHY_65NM_CH0_THERM_SAR_ADC_OUT_S 8
|
||||
|
||||
#define AR_PHY_65NM_CH0_RXTX1 0x16100
|
||||
#define AR_PHY_65NM_CH0_RXTX2 0x16104
|
||||
#define AR_PHY_65NM_CH1_RXTX1 0x16500
|
||||
#define AR_PHY_65NM_CH1_RXTX2 0x16504
|
||||
#define AR_PHY_65NM_CH2_RXTX1 0x16900
|
||||
#define AR_PHY_65NM_CH2_RXTX2 0x16904
|
||||
|
||||
#define AR_PHY_RX1DB_BIQUAD_LONG_SHIFT 0x00380000
|
||||
#define AR_PHY_RX1DB_BIQUAD_LONG_SHIFT_S 19
|
||||
#define AR_PHY_RX6DB_BIQUAD_LONG_SHIFT 0x00c00000
|
||||
#define AR_PHY_RX6DB_BIQUAD_LONG_SHIFT_S 22
|
||||
#define AR_PHY_LNAGAIN_LONG_SHIFT 0xe0000000
|
||||
#define AR_PHY_LNAGAIN_LONG_SHIFT_S 29
|
||||
#define AR_PHY_MXRGAIN_LONG_SHIFT 0x03000000
|
||||
#define AR_PHY_MXRGAIN_LONG_SHIFT_S 24
|
||||
#define AR_PHY_VGAGAIN_LONG_SHIFT 0x1c000000
|
||||
#define AR_PHY_VGAGAIN_LONG_SHIFT_S 26
|
||||
#define AR_PHY_SCFIR_GAIN_LONG_SHIFT 0x00000001
|
||||
#define AR_PHY_SCFIR_GAIN_LONG_SHIFT_S 0
|
||||
#define AR_PHY_MANRXGAIN_LONG_SHIFT 0x00000002
|
||||
#define AR_PHY_MANRXGAIN_LONG_SHIFT_S 1
|
||||
|
||||
/*
|
||||
* SM Field Definitions
|
||||
*/
|
||||
#define AR_PHY_CL_CAL_ENABLE 0x00000002
|
||||
#define AR_PHY_PARALLEL_CAL_ENABLE 0x00000001
|
||||
#define AR_PHY_TPCRG1_PD_CAL_ENABLE 0x00400000
|
||||
#define AR_PHY_TPCRG1_PD_CAL_ENABLE_S 22
|
||||
|
||||
#define AR_PHY_ADDAC_PARACTL_OFF_PWDADC 0x00008000
|
||||
|
||||
#define AR_PHY_FCAL20_CAP_STATUS_0 0x01f00000
|
||||
#define AR_PHY_FCAL20_CAP_STATUS_0_S 20
|
||||
|
||||
#define AR_PHY_RFBUS_REQ_EN 0x00000001 /* request for RF bus */
|
||||
#define AR_PHY_RFBUS_GRANT_EN 0x00000001 /* RF bus granted */
|
||||
#define AR_PHY_GC_TURBO_MODE 0x00000001 /* set turbo mode bits */
|
||||
#define AR_PHY_GC_TURBO_SHORT 0x00000002 /* set short symbols to turbo mode setting */
|
||||
#define AR_PHY_GC_DYN2040_EN 0x00000004 /* enable dyn 20/40 mode */
|
||||
#define AR_PHY_GC_DYN2040_PRI_ONLY 0x00000008 /* dyn 20/40 - primary only */
|
||||
#define AR_PHY_GC_DYN2040_PRI_CH 0x00000010 /* dyn 20/40 - primary ch offset (0=+10MHz, 1=-10MHz)*/
|
||||
#define AR_PHY_GC_DYN2040_PRI_CH_S 4
|
||||
#define AR_PHY_GC_DYN2040_EXT_CH 0x00000020 /* dyn 20/40 - ext ch spacing (0=20MHz/ 1=25MHz) */
|
||||
#define AR_PHY_GC_HT_EN 0x00000040 /* ht enable */
|
||||
#define AR_PHY_GC_SHORT_GI_40 0x00000080 /* allow short GI for HT 40 */
|
||||
#define AR_PHY_GC_WALSH 0x00000100 /* walsh spatial spreading for 2 chains,2 streams TX */
|
||||
#define AR_PHY_GC_SINGLE_HT_LTF1 0x00000200 /* single length (4us) 1st HT long training symbol */
|
||||
#define AR_PHY_GC_GF_DETECT_EN 0x00000400 /* enable Green Field detection. Only affects rx, not tx */
|
||||
#define AR_PHY_GC_ENABLE_DAC_FIFO 0x00000800 /* fifo between bb and dac */
|
||||
#define AR_PHY_RX_DELAY_DELAY 0x00003FFF /* delay from wakeup to rx ena */
|
||||
|
||||
#define AR_PHY_CALMODE_IQ 0x00000000
|
||||
#define AR_PHY_CALMODE_ADC_GAIN 0x00000001
|
||||
#define AR_PHY_CALMODE_ADC_DC_PER 0x00000002
|
||||
#define AR_PHY_CALMODE_ADC_DC_INIT 0x00000003
|
||||
#define AR_PHY_SWAP_ALT_CHAIN 0x00000040
|
||||
#define AR_PHY_MODE_OFDM 0x00000000
|
||||
#define AR_PHY_MODE_CCK 0x00000001
|
||||
#define AR_PHY_MODE_DYNAMIC 0x00000004
|
||||
#define AR_PHY_MODE_DYNAMIC_S 2
|
||||
#define AR_PHY_MODE_HALF 0x00000020
|
||||
#define AR_PHY_MODE_QUARTER 0x00000040
|
||||
#define AR_PHY_MAC_CLK_MODE 0x00000080
|
||||
#define AR_PHY_MODE_DYN_CCK_DISABLE 0x00000100
|
||||
#define AR_PHY_MODE_SVD_HALF 0x00000200
|
||||
#define AR_PHY_ACTIVE_EN 0x00000001
|
||||
#define AR_PHY_ACTIVE_DIS 0x00000000
|
||||
#define AR_PHY_FORCE_XPA_CFG 0x000000001
|
||||
#define AR_PHY_FORCE_XPA_CFG_S 0
|
||||
#define AR_PHY_XPA_TIMING_CTL_TX_END_XPAB_OFF 0xFF000000
|
||||
#define AR_PHY_XPA_TIMING_CTL_TX_END_XPAB_OFF_S 24
|
||||
#define AR_PHY_XPA_TIMING_CTL_TX_END_XPAA_OFF 0x00FF0000
|
||||
#define AR_PHY_XPA_TIMING_CTL_TX_END_XPAA_OFF_S 16
|
||||
#define AR_PHY_XPA_TIMING_CTL_FRAME_XPAB_ON 0x0000FF00
|
||||
#define AR_PHY_XPA_TIMING_CTL_FRAME_XPAB_ON_S 8
|
||||
#define AR_PHY_XPA_TIMING_CTL_FRAME_XPAA_ON 0x000000FF
|
||||
#define AR_PHY_XPA_TIMING_CTL_FRAME_XPAA_ON_S 0
|
||||
#define AR_PHY_TX_END_TO_A2_RX_ON 0x00FF0000
|
||||
#define AR_PHY_TX_END_TO_A2_RX_ON_S 16
|
||||
#define AR_PHY_TX_END_DATA_START 0x000000FF
|
||||
#define AR_PHY_TX_END_DATA_START_S 0
|
||||
#define AR_PHY_TX_END_PA_ON 0x0000FF00
|
||||
#define AR_PHY_TX_END_PA_ON_S 8
|
||||
#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP 0x0000000F
|
||||
#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP_S 0
|
||||
#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1 0x000003F0
|
||||
#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1_S 4
|
||||
#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2 0x0000FC00
|
||||
#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2_S 10
|
||||
#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3 0x003F0000
|
||||
#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3_S 16
|
||||
#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4 0x0FC00000
|
||||
#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4_S 22
|
||||
#define AR_PHY_TPCRG1_NUM_PD_GAIN 0x0000c000
|
||||
#define AR_PHY_TPCRG1_NUM_PD_GAIN_S 14
|
||||
#define AR_PHY_TPCRG1_PD_GAIN_1 0x00030000
|
||||
#define AR_PHY_TPCRG1_PD_GAIN_1_S 16
|
||||
#define AR_PHY_TPCRG1_PD_GAIN_2 0x000C0000
|
||||
#define AR_PHY_TPCRG1_PD_GAIN_2_S 18
|
||||
#define AR_PHY_TPCRG1_PD_GAIN_3 0x00300000
|
||||
#define AR_PHY_TPCRG1_PD_GAIN_3_S 20
|
||||
#define AR_PHY_TPCGR1_FORCED_DAC_GAIN 0x0000003e
|
||||
#define AR_PHY_TPCGR1_FORCED_DAC_GAIN_S 1
|
||||
#define AR_PHY_TPCGR1_FORCE_DAC_GAIN 0x00000001
|
||||
#define AR_PHY_TXGAIN_FORCE 0x00000001
|
||||
#define AR_PHY_TXGAIN_FORCED_PADVGNRA 0x00003c00
|
||||
#define AR_PHY_TXGAIN_FORCED_PADVGNRA_S 10
|
||||
#define AR_PHY_TXGAIN_FORCED_PADVGNRB 0x0003c000
|
||||
#define AR_PHY_TXGAIN_FORCED_PADVGNRB_S 14
|
||||
#define AR_PHY_TXGAIN_FORCED_PADVGNRD 0x00c00000
|
||||
#define AR_PHY_TXGAIN_FORCED_PADVGNRD_S 22
|
||||
#define AR_PHY_TXGAIN_FORCED_TXMXRGAIN 0x000003c0
|
||||
#define AR_PHY_TXGAIN_FORCED_TXMXRGAIN_S 6
|
||||
#define AR_PHY_TXGAIN_FORCED_TXBB1DBGAIN 0x0000000e
|
||||
#define AR_PHY_TXGAIN_FORCED_TXBB1DBGAIN_S 1
|
||||
|
||||
#define AR_PHY_POWER_TX_RATE1 0x9934
|
||||
#define AR_PHY_POWER_TX_RATE2 0x9938
|
||||
#define AR_PHY_POWER_TX_RATE_MAX 0x993c
|
||||
#define AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE 0x00000040
|
||||
#define PHY_AGC_CLR 0x10000000
|
||||
#define RFSILENT_BB 0x00002000
|
||||
#define AR_PHY_CHAN_INFO_GAIN_DIFF_PPM_MASK 0xFFF
|
||||
#define AR_PHY_CHAN_INFO_GAIN_DIFF_PPM_SIGNED_BIT 0x800
|
||||
#define AR_PHY_CHAN_INFO_GAIN_DIFF_UPPER_LIMIT 320
|
||||
#define AR_PHY_CHAN_INFO_MEMORY_CAPTURE_MASK 0x0001
|
||||
#define AR_PHY_RX_DELAY_DELAY 0x00003FFF
|
||||
#define AR_PHY_CCK_TX_CTRL_JAPAN 0x00000010
|
||||
#define AR_PHY_SPECTRAL_SCAN_ENABLE 0x00000001
|
||||
#define AR_PHY_SPECTRAL_SCAN_ENABLE_S 0
|
||||
#define AR_PHY_SPECTRAL_SCAN_ACTIVE 0x00000002
|
||||
#define AR_PHY_SPECTRAL_SCAN_ACTIVE_S 1
|
||||
#define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD 0x000000F0
|
||||
#define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD_S 4
|
||||
#define AR_PHY_SPECTRAL_SCAN_PERIOD 0x0000FF00
|
||||
#define AR_PHY_SPECTRAL_SCAN_PERIOD_S 8
|
||||
#define AR_PHY_SPECTRAL_SCAN_COUNT 0x00FF0000
|
||||
#define AR_PHY_SPECTRAL_SCAN_COUNT_S 16
|
||||
#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT 0x01000000
|
||||
#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S 24
|
||||
#define AR_PHY_CHANNEL_STATUS_RX_CLEAR 0x00000004
|
||||
#define AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT 0x01fc0000
|
||||
#define AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT_S 18
|
||||
#define AR_PHY_TX_IQCAL_START_DO_CAL 0x00000001
|
||||
#define AR_PHY_TX_IQCAL_START_DO_CAL_S 0
|
||||
|
||||
#define AR_PHY_TX_IQCAL_STATUS_FAILED 0x00000001
|
||||
#define AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE 0x00003fff
|
||||
#define AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE_S 0
|
||||
|
||||
#define AR_PHY_TPC_18_THERM_CAL_VALUE 0xff
|
||||
#define AR_PHY_TPC_18_THERM_CAL_VALUE_S 0
|
||||
#define AR_PHY_TPC_19_ALPHA_THERM 0xff
|
||||
#define AR_PHY_TPC_19_ALPHA_THERM_S 0
|
||||
|
||||
#define AR_PHY_65NM_CH0_RXTX4_THERM_ON 0x10000000
|
||||
#define AR_PHY_65NM_CH0_RXTX4_THERM_ON_S 28
|
||||
|
||||
#define AR_PHY_BB_THERM_ADC_1_INIT_THERM 0x000000ff
|
||||
#define AR_PHY_BB_THERM_ADC_1_INIT_THERM_S 0
|
||||
|
||||
/*
|
||||
* Channel 1 Register Map
|
||||
*/
|
||||
#define AR_CHAN1_BASE 0xa800
|
||||
|
||||
#define AR_PHY_EXT_CCA_1 (AR_CHAN1_BASE + 0x30)
|
||||
#define AR_PHY_TX_PHASE_RAMP_1 (AR_CHAN1_BASE + 0xd0)
|
||||
#define AR_PHY_ADC_GAIN_DC_CORR_1 (AR_CHAN1_BASE + 0xd4)
|
||||
|
||||
#define AR_PHY_SPUR_REPORT_1 (AR_CHAN1_BASE + 0xa8)
|
||||
#define AR_PHY_CHAN_INFO_TAB_1 (AR_CHAN1_BASE + 0x300)
|
||||
#define AR_PHY_RX_IQCAL_CORR_B1 (AR_CHAN1_BASE + 0xdc)
|
||||
|
||||
/*
|
||||
* Channel 1 Field Definitions
|
||||
*/
|
||||
#define AR_PHY_CH1_EXT_MINCCA_PWR 0x01FF0000
|
||||
#define AR_PHY_CH1_EXT_MINCCA_PWR_S 16
|
||||
|
||||
/*
|
||||
* AGC 1 Register Map
|
||||
*/
|
||||
#define AR_AGC1_BASE 0xae00
|
||||
|
||||
#define AR_PHY_FORCEMAX_GAINS_1 (AR_AGC1_BASE + 0x4)
|
||||
#define AR_PHY_EXT_ATTEN_CTL_1 (AR_AGC1_BASE + 0x18)
|
||||
#define AR_PHY_CCA_1 (AR_AGC1_BASE + 0x1c)
|
||||
#define AR_PHY_CCA_CTRL_1 (AR_AGC1_BASE + 0x20)
|
||||
#define AR_PHY_RSSI_1 (AR_AGC1_BASE + 0x180)
|
||||
#define AR_PHY_SPUR_CCK_REP_1 (AR_AGC1_BASE + 0x184)
|
||||
#define AR_PHY_RX_OCGAIN_2 (AR_AGC1_BASE + 0x200)
|
||||
|
||||
/*
|
||||
* AGC 1 Field Definitions
|
||||
*/
|
||||
#define AR_PHY_CH1_MINCCA_PWR 0x1FF00000
|
||||
#define AR_PHY_CH1_MINCCA_PWR_S 20
|
||||
|
||||
/*
|
||||
* SM 1 Register Map
|
||||
*/
|
||||
#define AR_SM1_BASE 0xb200
|
||||
|
||||
#define AR_PHY_SWITCH_CHAIN_1 (AR_SM1_BASE + 0x84)
|
||||
#define AR_PHY_FCAL_2_1 (AR_SM1_BASE + 0xd0)
|
||||
#define AR_PHY_DFT_TONE_CTL_1 (AR_SM1_BASE + 0xd4)
|
||||
#define AR_PHY_CL_TAB_1 (AR_SM1_BASE + 0x100)
|
||||
#define AR_PHY_CHAN_INFO_GAIN_1 (AR_SM1_BASE + 0x180)
|
||||
#define AR_PHY_TPC_4_B1 (AR_SM1_BASE + 0x204)
|
||||
#define AR_PHY_TPC_5_B1 (AR_SM1_BASE + 0x208)
|
||||
#define AR_PHY_TPC_6_B1 (AR_SM1_BASE + 0x20c)
|
||||
#define AR_PHY_TPC_11_B1 (AR_SM1_BASE + 0x220)
|
||||
#define AR_PHY_PDADC_TAB_1 (AR_SM1_BASE + 0x240)
|
||||
#define AR_PHY_TX_IQCAL_STATUS_B1 (AR_SM1_BASE + 0x48c)
|
||||
#define AR_PHY_TX_IQCAL_CORR_COEFF_01_B1 (AR_SM1_BASE + 0x450)
|
||||
|
||||
/*
|
||||
* Channel 2 Register Map
|
||||
*/
|
||||
#define AR_CHAN2_BASE 0xb800
|
||||
|
||||
#define AR_PHY_EXT_CCA_2 (AR_CHAN2_BASE + 0x30)
|
||||
#define AR_PHY_TX_PHASE_RAMP_2 (AR_CHAN2_BASE + 0xd0)
|
||||
#define AR_PHY_ADC_GAIN_DC_CORR_2 (AR_CHAN2_BASE + 0xd4)
|
||||
|
||||
#define AR_PHY_SPUR_REPORT_2 (AR_CHAN2_BASE + 0xa8)
|
||||
#define AR_PHY_CHAN_INFO_TAB_2 (AR_CHAN2_BASE + 0x300)
|
||||
#define AR_PHY_RX_IQCAL_CORR_B2 (AR_CHAN2_BASE + 0xdc)
|
||||
|
||||
/*
|
||||
* Channel 2 Field Definitions
|
||||
*/
|
||||
#define AR_PHY_CH2_EXT_MINCCA_PWR 0x01FF0000
|
||||
#define AR_PHY_CH2_EXT_MINCCA_PWR_S 16
|
||||
/*
|
||||
* AGC 2 Register Map
|
||||
*/
|
||||
#define AR_AGC2_BASE 0xbe00
|
||||
|
||||
#define AR_PHY_FORCEMAX_GAINS_2 (AR_AGC2_BASE + 0x4)
|
||||
#define AR_PHY_EXT_ATTEN_CTL_2 (AR_AGC2_BASE + 0x18)
|
||||
#define AR_PHY_CCA_2 (AR_AGC2_BASE + 0x1c)
|
||||
#define AR_PHY_CCA_CTRL_2 (AR_AGC2_BASE + 0x20)
|
||||
#define AR_PHY_RSSI_2 (AR_AGC2_BASE + 0x180)
|
||||
|
||||
/*
|
||||
* AGC 2 Field Definitions
|
||||
*/
|
||||
#define AR_PHY_CH2_MINCCA_PWR 0x1FF00000
|
||||
#define AR_PHY_CH2_MINCCA_PWR_S 20
|
||||
|
||||
/*
|
||||
* SM 2 Register Map
|
||||
*/
|
||||
#define AR_SM2_BASE 0xc200
|
||||
|
||||
#define AR_PHY_SWITCH_CHAIN_2 (AR_SM2_BASE + 0x84)
|
||||
#define AR_PHY_FCAL_2_2 (AR_SM2_BASE + 0xd0)
|
||||
#define AR_PHY_DFT_TONE_CTL_2 (AR_SM2_BASE + 0xd4)
|
||||
#define AR_PHY_CL_TAB_2 (AR_SM2_BASE + 0x100)
|
||||
#define AR_PHY_CHAN_INFO_GAIN_2 (AR_SM2_BASE + 0x180)
|
||||
#define AR_PHY_TPC_4_B2 (AR_SM2_BASE + 0x204)
|
||||
#define AR_PHY_TPC_5_B2 (AR_SM2_BASE + 0x208)
|
||||
#define AR_PHY_TPC_6_B2 (AR_SM2_BASE + 0x20c)
|
||||
#define AR_PHY_TPC_11_B2 (AR_SM2_BASE + 0x220)
|
||||
#define AR_PHY_PDADC_TAB_2 (AR_SM2_BASE + 0x240)
|
||||
#define AR_PHY_TX_IQCAL_STATUS_B2 (AR_SM2_BASE + 0x48c)
|
||||
#define AR_PHY_TX_IQCAL_CORR_COEFF_01_B2 (AR_SM2_BASE + 0x450)
|
||||
|
||||
#define AR_PHY_TX_IQCAL_STATUS_B2_FAILED 0x00000001
|
||||
|
||||
/*
|
||||
* AGC 3 Register Map
|
||||
*/
|
||||
#define AR_AGC3_BASE 0xce00
|
||||
|
||||
#define AR_PHY_RSSI_3 (AR_AGC3_BASE + 0x180)
|
||||
|
||||
/*
|
||||
* Misc helper defines
|
||||
*/
|
||||
#define AR_PHY_CHAIN_OFFSET (AR_CHAN1_BASE - AR_CHAN_BASE)
|
||||
|
||||
#define AR_PHY_NEW_ADC_DC_GAIN_CORR(_i) (AR_PHY_ADC_GAIN_DC_CORR_0 + (AR_PHY_CHAIN_OFFSET * (_i)))
|
||||
#define AR_PHY_NEW_ADC_DC_GAIN_CORR_9300_10(_i) (AR_PHY_ADC_GAIN_DC_CORR_0_9300_10 + (AR_PHY_CHAIN_OFFSET * (_i)))
|
||||
#define AR_PHY_SWITCH_CHAIN(_i) (AR_PHY_SWITCH_CHAIN_0 + (AR_PHY_CHAIN_OFFSET * (_i)))
|
||||
#define AR_PHY_EXT_ATTEN_CTL(_i) (AR_PHY_EXT_ATTEN_CTL_0 + (AR_PHY_CHAIN_OFFSET * (_i)))
|
||||
|
||||
#define AR_PHY_RXGAIN(_i) (AR_PHY_FORCEMAX_GAINS_0 + (AR_PHY_CHAIN_OFFSET * (_i)))
|
||||
#define AR_PHY_TPCRG5(_i) (AR_PHY_TPC_5_B0 + (AR_PHY_CHAIN_OFFSET * (_i)))
|
||||
#define AR_PHY_PDADC_TAB(_i) (AR_PHY_PDADC_TAB_0 + (AR_PHY_CHAIN_OFFSET * (_i)))
|
||||
|
||||
#define AR_PHY_CAL_MEAS_0(_i) (AR_PHY_IQ_ADC_MEAS_0_B0 + (AR_PHY_CHAIN_OFFSET * (_i)))
|
||||
#define AR_PHY_CAL_MEAS_1(_i) (AR_PHY_IQ_ADC_MEAS_1_B0 + (AR_PHY_CHAIN_OFFSET * (_i)))
|
||||
#define AR_PHY_CAL_MEAS_2(_i) (AR_PHY_IQ_ADC_MEAS_2_B0 + (AR_PHY_CHAIN_OFFSET * (_i)))
|
||||
#define AR_PHY_CAL_MEAS_3(_i) (AR_PHY_IQ_ADC_MEAS_3_B0 + (AR_PHY_CHAIN_OFFSET * (_i)))
|
||||
#define AR_PHY_CAL_MEAS_0_9300_10(_i) (AR_PHY_IQ_ADC_MEAS_0_B0_9300_10 + (AR_PHY_CHAIN_OFFSET * (_i)))
|
||||
#define AR_PHY_CAL_MEAS_1_9300_10(_i) (AR_PHY_IQ_ADC_MEAS_1_B0_9300_10 + (AR_PHY_CHAIN_OFFSET * (_i)))
|
||||
#define AR_PHY_CAL_MEAS_2_9300_10(_i) (AR_PHY_IQ_ADC_MEAS_2_B0_9300_10 + (AR_PHY_CHAIN_OFFSET * (_i)))
|
||||
#define AR_PHY_CAL_MEAS_3_9300_10(_i) (AR_PHY_IQ_ADC_MEAS_3_B0_9300_10 + (AR_PHY_CHAIN_OFFSET * (_i)))
|
||||
|
||||
#define AR_PHY_BB_PANIC_NON_IDLE_ENABLE 0x00000001
|
||||
#define AR_PHY_BB_PANIC_IDLE_ENABLE 0x00000002
|
||||
#define AR_PHY_BB_PANIC_IDLE_MASK 0xFFFF0000
|
||||
#define AR_PHY_BB_PANIC_NON_IDLE_MASK 0x0000FFFC
|
||||
|
||||
#define AR_PHY_BB_PANIC_RST_ENABLE 0x00000002
|
||||
#define AR_PHY_BB_PANIC_IRQ_ENABLE 0x00000004
|
||||
#define AR_PHY_BB_PANIC_CNTL2_MASK 0xFFFFFFF9
|
||||
|
||||
#define AR_PHY_BB_WD_STATUS 0x00000007
|
||||
#define AR_PHY_BB_WD_STATUS_S 0
|
||||
#define AR_PHY_BB_WD_DET_HANG 0x00000008
|
||||
#define AR_PHY_BB_WD_DET_HANG_S 3
|
||||
#define AR_PHY_BB_WD_RADAR_SM 0x000000F0
|
||||
#define AR_PHY_BB_WD_RADAR_SM_S 4
|
||||
#define AR_PHY_BB_WD_RX_OFDM_SM 0x00000F00
|
||||
#define AR_PHY_BB_WD_RX_OFDM_SM_S 8
|
||||
#define AR_PHY_BB_WD_RX_CCK_SM 0x0000F000
|
||||
#define AR_PHY_BB_WD_RX_CCK_SM_S 12
|
||||
#define AR_PHY_BB_WD_TX_OFDM_SM 0x000F0000
|
||||
#define AR_PHY_BB_WD_TX_OFDM_SM_S 16
|
||||
#define AR_PHY_BB_WD_TX_CCK_SM 0x00F00000
|
||||
#define AR_PHY_BB_WD_TX_CCK_SM_S 20
|
||||
#define AR_PHY_BB_WD_AGC_SM 0x0F000000
|
||||
#define AR_PHY_BB_WD_AGC_SM_S 24
|
||||
#define AR_PHY_BB_WD_SRCH_SM 0xF0000000
|
||||
#define AR_PHY_BB_WD_SRCH_SM_S 28
|
||||
|
||||
#define AR_PHY_BB_WD_STATUS_CLR 0x00000008
|
||||
|
||||
void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx);
|
||||
|
||||
#endif /* AR9003_PHY_H */
|
@ -114,8 +114,10 @@ enum buffer_type {
|
||||
#define bf_isretried(bf) (bf->bf_state.bf_type & BUF_RETRY)
|
||||
#define bf_isxretried(bf) (bf->bf_state.bf_type & BUF_XRETRY)
|
||||
|
||||
#define ATH_TXSTATUS_RING_SIZE 64
|
||||
|
||||
struct ath_descdma {
|
||||
struct ath_desc *dd_desc;
|
||||
void *dd_desc;
|
||||
dma_addr_t dd_desc_paddr;
|
||||
u32 dd_desc_len;
|
||||
struct ath_buf *dd_bufptr;
|
||||
@ -123,7 +125,7 @@ struct ath_descdma {
|
||||
|
||||
int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
|
||||
struct list_head *head, const char *name,
|
||||
int nbuf, int ndesc);
|
||||
int nbuf, int ndesc, bool is_tx);
|
||||
void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
|
||||
struct list_head *head);
|
||||
|
||||
@ -188,6 +190,7 @@ enum ATH_AGGR_STATUS {
|
||||
ATH_AGGR_LIMITED,
|
||||
};
|
||||
|
||||
#define ATH_TXFIFO_DEPTH 8
|
||||
struct ath_txq {
|
||||
u32 axq_qnum;
|
||||
u32 *axq_link;
|
||||
@ -197,6 +200,10 @@ struct ath_txq {
|
||||
bool stopped;
|
||||
bool axq_tx_inprogress;
|
||||
struct list_head axq_acq;
|
||||
struct list_head txq_fifo[ATH_TXFIFO_DEPTH];
|
||||
struct list_head txq_fifo_pending;
|
||||
u8 txq_headidx;
|
||||
u8 txq_tailidx;
|
||||
};
|
||||
|
||||
#define AGGR_CLEANUP BIT(1)
|
||||
@ -223,6 +230,12 @@ struct ath_tx {
|
||||
struct ath_descdma txdma;
|
||||
};
|
||||
|
||||
struct ath_rx_edma {
|
||||
struct sk_buff_head rx_fifo;
|
||||
struct sk_buff_head rx_buffers;
|
||||
u32 rx_fifo_hwsize;
|
||||
};
|
||||
|
||||
struct ath_rx {
|
||||
u8 defant;
|
||||
u8 rxotherant;
|
||||
@ -232,6 +245,8 @@ struct ath_rx {
|
||||
spinlock_t rxbuflock;
|
||||
struct list_head rxbuf;
|
||||
struct ath_descdma rxdma;
|
||||
struct ath_buf *rx_bufptr;
|
||||
struct ath_rx_edma rx_edma[ATH9K_RX_QUEUE_MAX];
|
||||
};
|
||||
|
||||
int ath_startrecv(struct ath_softc *sc);
|
||||
@ -240,7 +255,7 @@ void ath_flushrecv(struct ath_softc *sc);
|
||||
u32 ath_calcrxfilter(struct ath_softc *sc);
|
||||
int ath_rx_init(struct ath_softc *sc, int nbufs);
|
||||
void ath_rx_cleanup(struct ath_softc *sc);
|
||||
int ath_rx_tasklet(struct ath_softc *sc, int flush);
|
||||
int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp);
|
||||
struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype);
|
||||
void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
|
||||
int ath_tx_setup(struct ath_softc *sc, int haltype);
|
||||
@ -258,6 +273,7 @@ int ath_txq_update(struct ath_softc *sc, int qnum,
|
||||
int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
|
||||
struct ath_tx_control *txctl);
|
||||
void ath_tx_tasklet(struct ath_softc *sc);
|
||||
void ath_tx_edma_tasklet(struct ath_softc *sc);
|
||||
void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb);
|
||||
bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno);
|
||||
void ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
|
||||
@ -507,6 +523,8 @@ struct ath_softc {
|
||||
struct ath_beacon_config cur_beacon_conf;
|
||||
struct delayed_work tx_complete_work;
|
||||
struct ath_btcoex btcoex;
|
||||
|
||||
struct ath_descdma txsdma;
|
||||
};
|
||||
|
||||
struct ath_wiphy {
|
||||
|
@ -93,8 +93,6 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
|
||||
antenna = ((sc->beacon.ast_be_xmit / sc->nbcnvifs) & 1 ? 2 : 1);
|
||||
}
|
||||
|
||||
ds->ds_data = bf->bf_buf_addr;
|
||||
|
||||
sband = &sc->sbands[common->hw->conf.channel->band];
|
||||
rate = sband->bitrates[rateidx].hw_value;
|
||||
if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
|
||||
@ -109,7 +107,8 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
|
||||
|
||||
/* NB: beacon's BufLen must be a multiple of 4 bytes */
|
||||
ath9k_hw_filltxdesc(ah, ds, roundup(skb->len, 4),
|
||||
true, true, ds);
|
||||
true, true, ds, bf->bf_buf_addr,
|
||||
sc->beacon.beaconq);
|
||||
|
||||
memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
|
||||
series[0].Tries = 1;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -19,14 +19,6 @@
|
||||
|
||||
#include "hw.h"
|
||||
|
||||
extern const struct ath9k_percal_data iq_cal_multi_sample;
|
||||
extern const struct ath9k_percal_data iq_cal_single_sample;
|
||||
extern const struct ath9k_percal_data adc_gain_cal_multi_sample;
|
||||
extern const struct ath9k_percal_data adc_gain_cal_single_sample;
|
||||
extern const struct ath9k_percal_data adc_dc_cal_multi_sample;
|
||||
extern const struct ath9k_percal_data adc_dc_cal_single_sample;
|
||||
extern const struct ath9k_percal_data adc_init_dc_cal;
|
||||
|
||||
#define AR_PHY_CCA_MAX_AR5416_GOOD_VALUE -85
|
||||
#define AR_PHY_CCA_MAX_AR9280_GOOD_VALUE -112
|
||||
#define AR_PHY_CCA_MAX_AR9285_GOOD_VALUE -118
|
||||
@ -76,7 +68,8 @@ enum ath9k_cal_types {
|
||||
ADC_DC_INIT_CAL = 0x1,
|
||||
ADC_GAIN_CAL = 0x2,
|
||||
ADC_DC_CAL = 0x4,
|
||||
IQ_MISMATCH_CAL = 0x8
|
||||
IQ_MISMATCH_CAL = 0x8,
|
||||
TEMP_COMP_CAL = 0x10,
|
||||
};
|
||||
|
||||
enum ath9k_cal_state {
|
||||
@ -122,14 +115,12 @@ struct ath9k_pacal_info{
|
||||
|
||||
bool ath9k_hw_reset_calvalid(struct ath_hw *ah);
|
||||
void ath9k_hw_start_nfcal(struct ath_hw *ah);
|
||||
void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan);
|
||||
int16_t ath9k_hw_getnf(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan);
|
||||
void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah);
|
||||
s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan);
|
||||
bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
u8 rxchainmask, bool longcal);
|
||||
bool ath9k_hw_init_cal(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan);
|
||||
void ath9k_hw_reset_calibration(struct ath_hw *ah,
|
||||
struct ath9k_cal_list *currCal);
|
||||
|
||||
|
||||
#endif /* CALIB_H */
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "../debug.h"
|
||||
|
||||
#include "hw.h"
|
||||
#include "hw-ops.h"
|
||||
|
||||
/* Common header for Atheros 802.11n base driver cores */
|
||||
|
||||
@ -76,11 +77,12 @@ struct ath_buf {
|
||||
an aggregate) */
|
||||
struct ath_buf *bf_next; /* next subframe in the aggregate */
|
||||
struct sk_buff *bf_mpdu; /* enclosing frame structure */
|
||||
struct ath_desc *bf_desc; /* virtual addr of desc */
|
||||
void *bf_desc; /* virtual addr of desc */
|
||||
dma_addr_t bf_daddr; /* physical addr of desc */
|
||||
dma_addr_t bf_buf_addr; /* physical addr of data buffer */
|
||||
bool bf_stale;
|
||||
bool bf_isnullfunc;
|
||||
bool bf_tx_aborted;
|
||||
u16 bf_flags;
|
||||
struct ath_buf_state bf_state;
|
||||
dma_addr_t bf_dmacontext;
|
||||
|
@ -180,8 +180,15 @@ void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status)
|
||||
{
|
||||
if (status)
|
||||
sc->debug.stats.istats.total++;
|
||||
if (status & ATH9K_INT_RX)
|
||||
sc->debug.stats.istats.rxok++;
|
||||
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
|
||||
if (status & ATH9K_INT_RXLP)
|
||||
sc->debug.stats.istats.rxlp++;
|
||||
if (status & ATH9K_INT_RXHP)
|
||||
sc->debug.stats.istats.rxhp++;
|
||||
} else {
|
||||
if (status & ATH9K_INT_RX)
|
||||
sc->debug.stats.istats.rxok++;
|
||||
}
|
||||
if (status & ATH9K_INT_RXEOL)
|
||||
sc->debug.stats.istats.rxeol++;
|
||||
if (status & ATH9K_INT_RXORN)
|
||||
@ -223,8 +230,15 @@ static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
|
||||
char buf[512];
|
||||
unsigned int len = 0;
|
||||
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"%8s: %10u\n", "RX", sc->debug.stats.istats.rxok);
|
||||
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"%8s: %10u\n", "RXLP", sc->debug.stats.istats.rxlp);
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"%8s: %10u\n", "RXHP", sc->debug.stats.istats.rxhp);
|
||||
} else {
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"%8s: %10u\n", "RX", sc->debug.stats.istats.rxok);
|
||||
}
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"%8s: %10u\n", "RXEOL", sc->debug.stats.istats.rxeol);
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
|
@ -35,6 +35,8 @@ struct ath_buf;
|
||||
* struct ath_interrupt_stats - Contains statistics about interrupts
|
||||
* @total: Total no. of interrupts generated so far
|
||||
* @rxok: RX with no errors
|
||||
* @rxlp: RX with low priority RX
|
||||
* @rxhp: RX with high priority, uapsd only
|
||||
* @rxeol: RX with no more RXDESC available
|
||||
* @rxorn: RX FIFO overrun
|
||||
* @txok: TX completed at the requested rate
|
||||
@ -55,6 +57,8 @@ struct ath_buf;
|
||||
struct ath_interrupt_stats {
|
||||
u32 total;
|
||||
u32 rxok;
|
||||
u32 rxlp;
|
||||
u32 rxhp;
|
||||
u32 rxeol;
|
||||
u32 rxorn;
|
||||
u32 txok;
|
||||
|
@ -256,14 +256,13 @@ int ath9k_hw_eeprom_init(struct ath_hw *ah)
|
||||
{
|
||||
int status;
|
||||
|
||||
if (AR_SREV_9287(ah)) {
|
||||
ah->eep_map = EEP_MAP_AR9287;
|
||||
ah->eep_ops = &eep_AR9287_ops;
|
||||
if (AR_SREV_9300_20_OR_LATER(ah))
|
||||
ah->eep_ops = &eep_ar9300_ops;
|
||||
else if (AR_SREV_9287(ah)) {
|
||||
ah->eep_ops = &eep_ar9287_ops;
|
||||
} else if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) {
|
||||
ah->eep_map = EEP_MAP_4KBITS;
|
||||
ah->eep_ops = &eep_4k_ops;
|
||||
} else {
|
||||
ah->eep_map = EEP_MAP_DEFAULT;
|
||||
ah->eep_ops = &eep_def_ops;
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include "../ath.h"
|
||||
#include <net/cfg80211.h>
|
||||
#include "ar9003_eeprom.h"
|
||||
|
||||
#define AH_USE_EEPROM 0x1
|
||||
|
||||
@ -93,7 +94,6 @@
|
||||
*/
|
||||
#define AR9285_RDEXT_DEFAULT 0x1F
|
||||
|
||||
#define AR_EEPROM_MAC(i) (0x1d+(i))
|
||||
#define ATH9K_POW_SM(_r, _s) (((_r) & 0x3f) << (_s))
|
||||
#define FREQ2FBIN(x, y) ((y) ? ((x) - 2300) : (((x) - 4800) / 5))
|
||||
#define ath9k_hw_use_flash(_ah) (!(_ah->ah_flags & AH_USE_EEPROM))
|
||||
@ -155,6 +155,7 @@
|
||||
#define AR5416_BCHAN_UNUSED 0xFF
|
||||
#define AR5416_MAX_PWR_RANGE_IN_HALF_DB 64
|
||||
#define AR5416_MAX_CHAINS 3
|
||||
#define AR9300_MAX_CHAINS 3
|
||||
#define AR5416_PWR_TABLE_OFFSET_DB -5
|
||||
|
||||
/* Rx gain type values */
|
||||
@ -249,16 +250,20 @@ enum eeprom_param {
|
||||
EEP_MINOR_REV,
|
||||
EEP_TX_MASK,
|
||||
EEP_RX_MASK,
|
||||
EEP_FSTCLK_5G,
|
||||
EEP_RXGAIN_TYPE,
|
||||
EEP_TXGAIN_TYPE,
|
||||
EEP_OL_PWRCTRL,
|
||||
EEP_TXGAIN_TYPE,
|
||||
EEP_RC_CHAIN_MASK,
|
||||
EEP_DAC_HPWR_5G,
|
||||
EEP_FRAC_N_5G,
|
||||
EEP_DEV_TYPE,
|
||||
EEP_TEMPSENSE_SLOPE,
|
||||
EEP_TEMPSENSE_SLOPE_PAL_ON,
|
||||
EEP_PWR_TABLE_OFFSET
|
||||
EEP_PWR_TABLE_OFFSET,
|
||||
EEP_DRIVE_STRENGTH,
|
||||
EEP_INTERNAL_REGULATOR,
|
||||
EEP_SWREG
|
||||
};
|
||||
|
||||
enum ar5416_rates {
|
||||
@ -656,13 +661,6 @@ struct ath9k_country_entry {
|
||||
u8 iso[3];
|
||||
};
|
||||
|
||||
enum ath9k_eep_map {
|
||||
EEP_MAP_DEFAULT = 0x0,
|
||||
EEP_MAP_4KBITS,
|
||||
EEP_MAP_AR9287,
|
||||
EEP_MAP_MAX
|
||||
};
|
||||
|
||||
struct eeprom_ops {
|
||||
int (*check_eeprom)(struct ath_hw *hw);
|
||||
u32 (*get_eeprom)(struct ath_hw *hw, enum eeprom_param param);
|
||||
@ -713,6 +711,8 @@ int ath9k_hw_eeprom_init(struct ath_hw *ah);
|
||||
|
||||
extern const struct eeprom_ops eep_def_ops;
|
||||
extern const struct eeprom_ops eep_4k_ops;
|
||||
extern const struct eeprom_ops eep_AR9287_ops;
|
||||
extern const struct eeprom_ops eep_ar9287_ops;
|
||||
extern const struct eeprom_ops eep_ar9287_ops;
|
||||
extern const struct eeprom_ops eep_ar9300_ops;
|
||||
|
||||
#endif /* EEPROM_H */
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
#include "hw.h"
|
||||
#include "ar9002_phy.h"
|
||||
|
||||
static int ath9k_hw_4k_get_eeprom_ver(struct ath_hw *ah)
|
||||
{
|
||||
@ -182,11 +183,11 @@ static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
|
||||
switch (param) {
|
||||
case EEP_NFTHRESH_2:
|
||||
return pModal->noiseFloorThreshCh[0];
|
||||
case AR_EEPROM_MAC(0):
|
||||
case EEP_MAC_LSW:
|
||||
return pBase->macAddr[0] << 8 | pBase->macAddr[1];
|
||||
case AR_EEPROM_MAC(1):
|
||||
case EEP_MAC_MID:
|
||||
return pBase->macAddr[2] << 8 | pBase->macAddr[3];
|
||||
case AR_EEPROM_MAC(2):
|
||||
case EEP_MAC_MSW:
|
||||
return pBase->macAddr[4] << 8 | pBase->macAddr[5];
|
||||
case EEP_REG_0:
|
||||
return pBase->regDmn[0];
|
||||
@ -453,6 +454,8 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
|
||||
&tMinCalPower, gainBoundaries,
|
||||
pdadcValues, numXpdGain);
|
||||
|
||||
ENABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) {
|
||||
REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset,
|
||||
SM(pdGainOverlap_t2,
|
||||
@ -493,6 +496,9 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
|
||||
|
||||
regOffset += 4;
|
||||
}
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
}
|
||||
}
|
||||
|
||||
@ -758,6 +764,8 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
|
||||
ratesArray[i] -= AR5416_PWR_TABLE_OFFSET_DB * 2;
|
||||
}
|
||||
|
||||
ENABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
/* OFDM power per rate */
|
||||
REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
|
||||
ATH9K_POW_SM(ratesArray[rate18mb], 24)
|
||||
@ -820,6 +828,9 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
|
||||
| ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
|
||||
| ATH9K_POW_SM(ratesArray[rateDupCck], 0));
|
||||
}
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
}
|
||||
|
||||
static void ath9k_hw_4k_set_addac(struct ath_hw *ah,
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
#include "hw.h"
|
||||
#include "ar9002_phy.h"
|
||||
|
||||
static int ath9k_hw_AR9287_get_eeprom_ver(struct ath_hw *ah)
|
||||
{
|
||||
@ -172,11 +173,11 @@ static u32 ath9k_hw_AR9287_get_eeprom(struct ath_hw *ah,
|
||||
switch (param) {
|
||||
case EEP_NFTHRESH_2:
|
||||
return pModal->noiseFloorThreshCh[0];
|
||||
case AR_EEPROM_MAC(0):
|
||||
case EEP_MAC_LSW:
|
||||
return pBase->macAddr[0] << 8 | pBase->macAddr[1];
|
||||
case AR_EEPROM_MAC(1):
|
||||
case EEP_MAC_MID:
|
||||
return pBase->macAddr[2] << 8 | pBase->macAddr[3];
|
||||
case AR_EEPROM_MAC(2):
|
||||
case EEP_MAC_MSW:
|
||||
return pBase->macAddr[4] << 8 | pBase->macAddr[5];
|
||||
case EEP_REG_0:
|
||||
return pBase->regDmn[0];
|
||||
@ -1169,7 +1170,7 @@ static u16 ath9k_hw_AR9287_get_spur_channel(struct ath_hw *ah,
|
||||
#undef EEP_MAP9287_SPURCHAN
|
||||
}
|
||||
|
||||
const struct eeprom_ops eep_AR9287_ops = {
|
||||
const struct eeprom_ops eep_ar9287_ops = {
|
||||
.check_eeprom = ath9k_hw_AR9287_check_eeprom,
|
||||
.get_eeprom = ath9k_hw_AR9287_get_eeprom,
|
||||
.fill_eeprom = ath9k_hw_AR9287_fill_eeprom,
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
#include "hw.h"
|
||||
#include "ar9002_phy.h"
|
||||
|
||||
static void ath9k_get_txgain_index(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan,
|
||||
@ -222,6 +223,12 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Enable fixup for AR_AN_TOP2 if necessary */
|
||||
if (AR_SREV_9280_10_OR_LATER(ah) &&
|
||||
(eep->baseEepHeader.version & 0xff) > 0x0a &&
|
||||
eep->baseEepHeader.pwdclkind == 0)
|
||||
ah->need_an_top2_fixup = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -237,11 +244,11 @@ static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah,
|
||||
return pModal[0].noiseFloorThreshCh[0];
|
||||
case EEP_NFTHRESH_2:
|
||||
return pModal[1].noiseFloorThreshCh[0];
|
||||
case AR_EEPROM_MAC(0):
|
||||
case EEP_MAC_LSW:
|
||||
return pBase->macAddr[0] << 8 | pBase->macAddr[1];
|
||||
case AR_EEPROM_MAC(1):
|
||||
case EEP_MAC_MID:
|
||||
return pBase->macAddr[2] << 8 | pBase->macAddr[3];
|
||||
case AR_EEPROM_MAC(2):
|
||||
case EEP_MAC_MSW:
|
||||
return pBase->macAddr[4] << 8 | pBase->macAddr[5];
|
||||
case EEP_REG_0:
|
||||
return pBase->regDmn[0];
|
||||
|
@ -129,6 +129,7 @@ static void hif_usb_tx_cb(struct urb *urb)
|
||||
TX_STAT_INC(skb_completed);
|
||||
} else {
|
||||
dev_kfree_skb_any(skb);
|
||||
TX_STAT_INC(skb_dropped);
|
||||
}
|
||||
}
|
||||
|
||||
@ -149,11 +150,15 @@ static void hif_usb_tx_cb(struct urb *urb)
|
||||
}
|
||||
}
|
||||
|
||||
static inline void ath9k_skb_queue_purge(struct sk_buff_head *list)
|
||||
static inline void ath9k_skb_queue_purge(struct hif_device_usb *hif_dev,
|
||||
struct sk_buff_head *list)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
while ((skb = __skb_dequeue(list)) != NULL)
|
||||
|
||||
while ((skb = __skb_dequeue(list)) != NULL) {
|
||||
dev_kfree_skb_any(skb);
|
||||
TX_STAT_INC(skb_dropped);
|
||||
}
|
||||
}
|
||||
|
||||
/* TX lock has to be taken */
|
||||
@ -214,7 +219,7 @@ static int __hif_usb_tx(struct hif_device_usb *hif_dev)
|
||||
ret = usb_submit_urb(tx_buf->urb, GFP_ATOMIC);
|
||||
if (ret) {
|
||||
tx_buf->len = tx_buf->offset = 0;
|
||||
ath9k_skb_queue_purge(&tx_buf->skb_queue);
|
||||
ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue);
|
||||
__skb_queue_head_init(&tx_buf->skb_queue);
|
||||
list_move_tail(&tx_buf->list, &hif_dev->tx.tx_buf);
|
||||
hif_dev->tx.tx_buf_cnt++;
|
||||
@ -281,7 +286,7 @@ static void hif_usb_stop(void *hif_handle, u8 pipe_id)
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
|
||||
ath9k_skb_queue_purge(&hif_dev->tx.tx_skb_queue);
|
||||
ath9k_skb_queue_purge(hif_dev, &hif_dev->tx.tx_skb_queue);
|
||||
hif_dev->tx.tx_skb_cnt = 0;
|
||||
hif_dev->tx.flags |= HIF_USB_TX_STOP;
|
||||
spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
|
||||
|
@ -124,13 +124,13 @@ struct ath9k_htc_cap_target {
|
||||
struct ath9k_htc_target_vif {
|
||||
u8 index;
|
||||
u8 des_bssid[ETH_ALEN];
|
||||
enum htc_opmode opmode;
|
||||
__be32 opmode;
|
||||
u8 myaddr[ETH_ALEN];
|
||||
u8 bssid[ETH_ALEN];
|
||||
u32 flags;
|
||||
u32 flags_ext;
|
||||
u16 ps_sta;
|
||||
u16 rtsthreshold;
|
||||
__be16 rtsthreshold;
|
||||
u8 ath_cap;
|
||||
u8 node;
|
||||
s8 mcast_rate;
|
||||
@ -151,7 +151,7 @@ struct ath9k_htc_target_sta {
|
||||
u8 sta_index;
|
||||
u8 vif_index;
|
||||
u8 vif_sta;
|
||||
u16 flags; /* ATH_HTC_STA_* */
|
||||
__be16 flags; /* ATH_HTC_STA_* */
|
||||
u16 htcap;
|
||||
u8 valid;
|
||||
u16 capinfo;
|
||||
@ -191,16 +191,16 @@ struct ath9k_htc_rate {
|
||||
struct ath9k_htc_target_rate {
|
||||
u8 sta_index;
|
||||
u8 isnew;
|
||||
u32 capflags;
|
||||
__be32 capflags;
|
||||
struct ath9k_htc_rate rates;
|
||||
};
|
||||
|
||||
struct ath9k_htc_target_stats {
|
||||
u32 tx_shortretry;
|
||||
u32 tx_longretry;
|
||||
u32 tx_xretries;
|
||||
u32 ht_txunaggr_xretry;
|
||||
u32 ht_tx_xretries;
|
||||
__be32 tx_shortretry;
|
||||
__be32 tx_longretry;
|
||||
__be32 tx_xretries;
|
||||
__be32 ht_txunaggr_xretry;
|
||||
__be32 ht_tx_xretries;
|
||||
} __packed;
|
||||
|
||||
struct ath9k_htc_vif {
|
||||
@ -261,6 +261,7 @@ struct ath_tx_stats {
|
||||
u32 buf_completed;
|
||||
u32 skb_queued;
|
||||
u32 skb_completed;
|
||||
u32 skb_dropped;
|
||||
};
|
||||
|
||||
struct ath_rx_stats {
|
||||
|
@ -26,7 +26,8 @@ static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv,
|
||||
enum ath9k_int imask = 0;
|
||||
int dtimperiod, dtimcount, sleepduration;
|
||||
int cfpperiod, cfpcount, bmiss_timeout;
|
||||
u32 nexttbtt = 0, intval, tsftu, htc_imask = 0;
|
||||
u32 nexttbtt = 0, intval, tsftu;
|
||||
__be32 htc_imask = 0;
|
||||
u64 tsf;
|
||||
int num_beacons, offset, dtim_dec_count, cfp_dec_count;
|
||||
int ret;
|
||||
@ -142,7 +143,8 @@ static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv,
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(priv->ah);
|
||||
enum ath9k_int imask = 0;
|
||||
u32 nexttbtt, intval, htc_imask = 0;
|
||||
u32 nexttbtt, intval;
|
||||
__be32 htc_imask = 0;
|
||||
int ret;
|
||||
u8 cmd_rsp;
|
||||
|
||||
@ -244,25 +246,20 @@ void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(priv->ah);
|
||||
enum nl80211_iftype iftype;
|
||||
struct htc_beacon_config *cur_conf = &priv->cur_beacon_conf;
|
||||
struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
|
||||
|
||||
if (vif) {
|
||||
struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
|
||||
iftype = vif->type;
|
||||
cur_conf->beacon_interval = bss_conf->beacon_int;
|
||||
cur_conf->dtim_period = bss_conf->dtim_period;
|
||||
cur_conf->listen_interval = 1;
|
||||
cur_conf->dtim_count = 1;
|
||||
cur_conf->bmiss_timeout =
|
||||
ATH_DEFAULT_BMISS_LIMIT * cur_conf->beacon_interval;
|
||||
} else
|
||||
iftype = priv->ah->opmode;
|
||||
|
||||
cur_conf->beacon_interval = bss_conf->beacon_int;
|
||||
if (cur_conf->beacon_interval == 0)
|
||||
cur_conf->beacon_interval = 100;
|
||||
|
||||
switch (iftype) {
|
||||
cur_conf->dtim_period = bss_conf->dtim_period;
|
||||
cur_conf->listen_interval = 1;
|
||||
cur_conf->dtim_count = 1;
|
||||
cur_conf->bmiss_timeout =
|
||||
ATH_DEFAULT_BMISS_LIMIT * cur_conf->beacon_interval;
|
||||
|
||||
switch (vif->type) {
|
||||
case NL80211_IFTYPE_STATION:
|
||||
ath9k_htc_beacon_config_sta(priv, cur_conf);
|
||||
break;
|
||||
|
@ -213,7 +213,7 @@ static int ath9k_reg_notifier(struct wiphy *wiphy,
|
||||
ath9k_hw_regulatory(priv->ah));
|
||||
}
|
||||
|
||||
static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset)
|
||||
static unsigned int ath9k_regread(void *hw_priv, u32 reg_offset)
|
||||
{
|
||||
struct ath_hw *ah = (struct ath_hw *) hw_priv;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
@ -235,7 +235,7 @@ static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset)
|
||||
return be32_to_cpu(val);
|
||||
}
|
||||
|
||||
static void ath9k_iowrite32(void *hw_priv, u32 val, u32 reg_offset)
|
||||
static void ath9k_regwrite_single(void *hw_priv, u32 val, u32 reg_offset)
|
||||
{
|
||||
struct ath_hw *ah = (struct ath_hw *) hw_priv;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
@ -257,9 +257,105 @@ static void ath9k_iowrite32(void *hw_priv, u32 val, u32 reg_offset)
|
||||
}
|
||||
}
|
||||
|
||||
static void ath9k_regwrite_buffer(void *hw_priv, u32 val, u32 reg_offset)
|
||||
{
|
||||
struct ath_hw *ah = (struct ath_hw *) hw_priv;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
|
||||
u32 rsp_status;
|
||||
int r;
|
||||
|
||||
mutex_lock(&priv->wmi->multi_write_mutex);
|
||||
|
||||
/* Store the register/value */
|
||||
priv->wmi->multi_write[priv->wmi->multi_write_idx].reg =
|
||||
cpu_to_be32(reg_offset);
|
||||
priv->wmi->multi_write[priv->wmi->multi_write_idx].val =
|
||||
cpu_to_be32(val);
|
||||
|
||||
priv->wmi->multi_write_idx++;
|
||||
|
||||
/* If the buffer is full, send it out. */
|
||||
if (priv->wmi->multi_write_idx == MAX_CMD_NUMBER) {
|
||||
r = ath9k_wmi_cmd(priv->wmi, WMI_REG_WRITE_CMDID,
|
||||
(u8 *) &priv->wmi->multi_write,
|
||||
sizeof(struct register_write) * priv->wmi->multi_write_idx,
|
||||
(u8 *) &rsp_status, sizeof(rsp_status),
|
||||
100);
|
||||
if (unlikely(r)) {
|
||||
ath_print(common, ATH_DBG_WMI,
|
||||
"REGISTER WRITE FAILED, multi len: %d\n",
|
||||
priv->wmi->multi_write_idx);
|
||||
}
|
||||
priv->wmi->multi_write_idx = 0;
|
||||
}
|
||||
|
||||
mutex_unlock(&priv->wmi->multi_write_mutex);
|
||||
}
|
||||
|
||||
static void ath9k_regwrite(void *hw_priv, u32 val, u32 reg_offset)
|
||||
{
|
||||
struct ath_hw *ah = (struct ath_hw *) hw_priv;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
|
||||
|
||||
if (atomic_read(&priv->wmi->mwrite_cnt))
|
||||
ath9k_regwrite_buffer(hw_priv, val, reg_offset);
|
||||
else
|
||||
ath9k_regwrite_single(hw_priv, val, reg_offset);
|
||||
}
|
||||
|
||||
static void ath9k_enable_regwrite_buffer(void *hw_priv)
|
||||
{
|
||||
struct ath_hw *ah = (struct ath_hw *) hw_priv;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
|
||||
|
||||
atomic_inc(&priv->wmi->mwrite_cnt);
|
||||
}
|
||||
|
||||
static void ath9k_disable_regwrite_buffer(void *hw_priv)
|
||||
{
|
||||
struct ath_hw *ah = (struct ath_hw *) hw_priv;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
|
||||
|
||||
atomic_dec(&priv->wmi->mwrite_cnt);
|
||||
}
|
||||
|
||||
static void ath9k_regwrite_flush(void *hw_priv)
|
||||
{
|
||||
struct ath_hw *ah = (struct ath_hw *) hw_priv;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
|
||||
u32 rsp_status;
|
||||
int r;
|
||||
|
||||
mutex_lock(&priv->wmi->multi_write_mutex);
|
||||
|
||||
if (priv->wmi->multi_write_idx) {
|
||||
r = ath9k_wmi_cmd(priv->wmi, WMI_REG_WRITE_CMDID,
|
||||
(u8 *) &priv->wmi->multi_write,
|
||||
sizeof(struct register_write) * priv->wmi->multi_write_idx,
|
||||
(u8 *) &rsp_status, sizeof(rsp_status),
|
||||
100);
|
||||
if (unlikely(r)) {
|
||||
ath_print(common, ATH_DBG_WMI,
|
||||
"REGISTER WRITE FAILED, multi len: %d\n",
|
||||
priv->wmi->multi_write_idx);
|
||||
}
|
||||
priv->wmi->multi_write_idx = 0;
|
||||
}
|
||||
|
||||
mutex_unlock(&priv->wmi->multi_write_mutex);
|
||||
}
|
||||
|
||||
static const struct ath_ops ath9k_common_ops = {
|
||||
.read = ath9k_ioread32,
|
||||
.write = ath9k_iowrite32,
|
||||
.read = ath9k_regread,
|
||||
.write = ath9k_regwrite,
|
||||
.enable_write_buffer = ath9k_enable_regwrite_buffer,
|
||||
.disable_write_buffer = ath9k_disable_regwrite_buffer,
|
||||
.write_flush = ath9k_regwrite_flush,
|
||||
};
|
||||
|
||||
static void ath_usb_read_cachesize(struct ath_common *common, int *csz)
|
||||
|
@ -125,7 +125,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
|
||||
bool fastcc = true;
|
||||
struct ieee80211_channel *channel = hw->conf.channel;
|
||||
enum htc_phymode mode;
|
||||
u16 htc_mode;
|
||||
__be16 htc_mode;
|
||||
u8 cmd_rsp;
|
||||
int ret;
|
||||
|
||||
@ -378,7 +378,7 @@ static int ath9k_htc_init_rate(struct ath9k_htc_priv *priv,
|
||||
priv->tgt_rate.sta_index = ista->index;
|
||||
priv->tgt_rate.isnew = 1;
|
||||
trate = priv->tgt_rate;
|
||||
priv->tgt_rate.capflags = caps;
|
||||
priv->tgt_rate.capflags = cpu_to_be32(caps);
|
||||
trate.capflags = cpu_to_be32(caps);
|
||||
|
||||
WMI_CMD_BUF(WMI_RC_RATE_UPDATE_CMDID, &trate);
|
||||
@ -426,6 +426,7 @@ static void ath9k_htc_rc_update(struct ath9k_htc_priv *priv, bool is_cw40)
|
||||
struct ath9k_htc_target_rate trate;
|
||||
struct ath_common *common = ath9k_hw_common(priv->ah);
|
||||
int ret;
|
||||
u32 caps = be32_to_cpu(priv->tgt_rate.capflags);
|
||||
u8 cmd_rsp;
|
||||
|
||||
memset(&trate, 0, sizeof(trate));
|
||||
@ -433,11 +434,12 @@ static void ath9k_htc_rc_update(struct ath9k_htc_priv *priv, bool is_cw40)
|
||||
trate = priv->tgt_rate;
|
||||
|
||||
if (is_cw40)
|
||||
priv->tgt_rate.capflags |= WLAN_RC_40_FLAG;
|
||||
caps |= WLAN_RC_40_FLAG;
|
||||
else
|
||||
priv->tgt_rate.capflags &= ~WLAN_RC_40_FLAG;
|
||||
caps &= ~WLAN_RC_40_FLAG;
|
||||
|
||||
trate.capflags = cpu_to_be32(priv->tgt_rate.capflags);
|
||||
priv->tgt_rate.capflags = cpu_to_be32(caps);
|
||||
trate.capflags = cpu_to_be32(caps);
|
||||
|
||||
WMI_CMD_BUF(WMI_RC_RATE_UPDATE_CMDID, &trate);
|
||||
if (ret) {
|
||||
@ -609,6 +611,9 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"%20s : %10u\n", "SKBs completed",
|
||||
priv->debug.tx_stats.skb_completed);
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"%20s : %10u\n", "SKBs dropped",
|
||||
priv->debug.tx_stats.skb_dropped);
|
||||
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
}
|
||||
@ -960,7 +965,6 @@ void ath9k_deinit_leds(struct ath9k_htc_priv *priv)
|
||||
ath9k_unregister_led(&priv->tx_led);
|
||||
ath9k_unregister_led(&priv->rx_led);
|
||||
ath9k_unregister_led(&priv->radio_led);
|
||||
ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 1);
|
||||
}
|
||||
|
||||
void ath9k_init_leds(struct ath9k_htc_priv *priv)
|
||||
@ -1102,7 +1106,7 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
|
||||
struct ath9k_channel *init_channel;
|
||||
int ret = 0;
|
||||
enum htc_phymode mode;
|
||||
u16 htc_mode;
|
||||
__be16 htc_mode;
|
||||
u8 cmd_rsp;
|
||||
|
||||
ath_print(common, ATH_DBG_CONFIG,
|
||||
@ -1687,7 +1691,7 @@ static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw)
|
||||
spin_unlock_bh(&priv->beacon_lock);
|
||||
priv->op_flags |= OP_FULL_RESET;
|
||||
if (priv->op_flags & OP_ASSOCIATED)
|
||||
ath9k_htc_beacon_config(priv, NULL);
|
||||
ath9k_htc_beacon_config(priv, priv->vif);
|
||||
ath_start_ani(priv);
|
||||
mutex_unlock(&priv->mutex);
|
||||
ath9k_htc_ps_restore(priv);
|
||||
|
@ -530,7 +530,7 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv,
|
||||
priv->ah->stats.avgbrssi = rxbuf->rxstatus.rs_rssi;
|
||||
}
|
||||
|
||||
rx_status->mactime = rxbuf->rxstatus.rs_tstamp;
|
||||
rx_status->mactime = be64_to_cpu(rxbuf->rxstatus.rs_tstamp);
|
||||
rx_status->band = hw->conf.channel->band;
|
||||
rx_status->freq = hw->conf.channel->center_freq;
|
||||
rx_status->signal = rxbuf->rxstatus.rs_rssi + ATH_DEFAULT_NOISE_FLOOR;
|
||||
@ -634,13 +634,8 @@ void ath9k_htc_rxep(void *drv_priv, struct sk_buff *skb,
|
||||
|
||||
rxstatus = (struct ath_htc_rx_status *)skb->data;
|
||||
|
||||
rxstatus->rs_tstamp = be64_to_cpu(rxstatus->rs_tstamp);
|
||||
rxstatus->rs_datalen = be16_to_cpu(rxstatus->rs_datalen);
|
||||
rxstatus->evm0 = be32_to_cpu(rxstatus->evm0);
|
||||
rxstatus->evm1 = be32_to_cpu(rxstatus->evm1);
|
||||
rxstatus->evm2 = be32_to_cpu(rxstatus->evm2);
|
||||
|
||||
if (rxstatus->rs_datalen - (len - HTC_RX_FRAME_HEADER_SIZE) != 0) {
|
||||
if (be16_to_cpu(rxstatus->rs_datalen) -
|
||||
(len - HTC_RX_FRAME_HEADER_SIZE) != 0) {
|
||||
ath_print(common, ATH_DBG_FATAL,
|
||||
"Corrupted RX data len, dropping "
|
||||
"(epid: %d, dlen: %d, skblen: %d)\n",
|
||||
|
@ -368,7 +368,7 @@ void ath9k_htc_rx_msg(struct htc_target *htc_handle,
|
||||
struct htc_frame_hdr *htc_hdr;
|
||||
enum htc_endpoint_id epid;
|
||||
struct htc_endpoint *endpoint;
|
||||
u16 *msg_id;
|
||||
__be16 *msg_id;
|
||||
|
||||
if (!htc_handle || !skb)
|
||||
return;
|
||||
@ -388,14 +388,14 @@ void ath9k_htc_rx_msg(struct htc_target *htc_handle,
|
||||
|
||||
/* Handle trailer */
|
||||
if (htc_hdr->flags & HTC_FLAGS_RECV_TRAILER) {
|
||||
if (be32_to_cpu(*(u32 *) skb->data) == 0x00C60000)
|
||||
if (be32_to_cpu(*(__be32 *) skb->data) == 0x00C60000)
|
||||
/* Move past the Watchdog pattern */
|
||||
htc_hdr = (struct htc_frame_hdr *)(skb->data + 4);
|
||||
}
|
||||
|
||||
/* Get the message ID */
|
||||
msg_id = (u16 *) ((void *) htc_hdr +
|
||||
sizeof(struct htc_frame_hdr));
|
||||
msg_id = (__be16 *) ((void *) htc_hdr +
|
||||
sizeof(struct htc_frame_hdr));
|
||||
|
||||
/* Now process HTC messages */
|
||||
switch (be16_to_cpu(*msg_id)) {
|
||||
|
@ -59,20 +59,20 @@ enum htc_endpoint_id {
|
||||
struct htc_frame_hdr {
|
||||
u8 endpoint_id;
|
||||
u8 flags;
|
||||
u16 payload_len;
|
||||
__be16 payload_len;
|
||||
u8 control[4];
|
||||
} __packed;
|
||||
|
||||
struct htc_ready_msg {
|
||||
u16 message_id;
|
||||
u16 credits;
|
||||
u16 credit_size;
|
||||
__be16 message_id;
|
||||
__be16 credits;
|
||||
__be16 credit_size;
|
||||
u8 max_endpoints;
|
||||
u8 pad;
|
||||
} __packed;
|
||||
|
||||
struct htc_config_pipe_msg {
|
||||
u16 message_id;
|
||||
__be16 message_id;
|
||||
u8 pipe_id;
|
||||
u8 credits;
|
||||
} __packed;
|
||||
@ -192,9 +192,9 @@ enum htc_service_group_ids{
|
||||
#define WMI_DATA_BK_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 8)
|
||||
|
||||
struct htc_conn_svc_msg {
|
||||
u16 msg_id;
|
||||
u16 service_id;
|
||||
u16 con_flags;
|
||||
__be16 msg_id;
|
||||
__be16 service_id;
|
||||
__be16 con_flags;
|
||||
u8 dl_pipeid;
|
||||
u8 ul_pipeid;
|
||||
u8 svc_meta_len;
|
||||
@ -209,17 +209,17 @@ struct htc_conn_svc_msg {
|
||||
#define HTC_SERVICE_NO_MORE_EP 4
|
||||
|
||||
struct htc_conn_svc_rspmsg {
|
||||
u16 msg_id;
|
||||
u16 service_id;
|
||||
__be16 msg_id;
|
||||
__be16 service_id;
|
||||
u8 status;
|
||||
u8 endpoint_id;
|
||||
u16 max_msg_len;
|
||||
__be16 max_msg_len;
|
||||
u8 svc_meta_len;
|
||||
u8 pad;
|
||||
} __packed;
|
||||
|
||||
struct htc_comp_msg {
|
||||
u16 msg_id;
|
||||
__be16 msg_id;
|
||||
} __packed;
|
||||
|
||||
int htc_init(struct htc_target *target);
|
||||
|
280
drivers/net/wireless/ath/ath9k/hw-ops.h
Normal file
280
drivers/net/wireless/ath/ath9k/hw-ops.h
Normal file
@ -0,0 +1,280 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Atheros Communications Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef ATH9K_HW_OPS_H
|
||||
#define ATH9K_HW_OPS_H
|
||||
|
||||
#include "hw.h"
|
||||
|
||||
/* Hardware core and driver accessible callbacks */
|
||||
|
||||
static inline void ath9k_hw_configpcipowersave(struct ath_hw *ah,
|
||||
int restore,
|
||||
int power_off)
|
||||
{
|
||||
ath9k_hw_ops(ah)->config_pci_powersave(ah, restore, power_off);
|
||||
}
|
||||
|
||||
static inline void ath9k_hw_rxena(struct ath_hw *ah)
|
||||
{
|
||||
ath9k_hw_ops(ah)->rx_enable(ah);
|
||||
}
|
||||
|
||||
static inline void ath9k_hw_set_desc_link(struct ath_hw *ah, void *ds,
|
||||
u32 link)
|
||||
{
|
||||
ath9k_hw_ops(ah)->set_desc_link(ds, link);
|
||||
}
|
||||
|
||||
static inline void ath9k_hw_get_desc_link(struct ath_hw *ah, void *ds,
|
||||
u32 **link)
|
||||
{
|
||||
ath9k_hw_ops(ah)->get_desc_link(ds, link);
|
||||
}
|
||||
static inline bool ath9k_hw_calibrate(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan,
|
||||
u8 rxchainmask,
|
||||
bool longcal)
|
||||
{
|
||||
return ath9k_hw_ops(ah)->calibrate(ah, chan, rxchainmask, longcal);
|
||||
}
|
||||
|
||||
static inline bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked)
|
||||
{
|
||||
return ath9k_hw_ops(ah)->get_isr(ah, masked);
|
||||
}
|
||||
|
||||
static inline void ath9k_hw_filltxdesc(struct ath_hw *ah, void *ds, u32 seglen,
|
||||
bool is_firstseg, bool is_lastseg,
|
||||
const void *ds0, dma_addr_t buf_addr,
|
||||
unsigned int qcu)
|
||||
{
|
||||
ath9k_hw_ops(ah)->fill_txdesc(ah, ds, seglen, is_firstseg, is_lastseg,
|
||||
ds0, buf_addr, qcu);
|
||||
}
|
||||
|
||||
static inline int ath9k_hw_txprocdesc(struct ath_hw *ah, void *ds,
|
||||
struct ath_tx_status *ts)
|
||||
{
|
||||
return ath9k_hw_ops(ah)->proc_txdesc(ah, ds, ts);
|
||||
}
|
||||
|
||||
static inline void ath9k_hw_set11n_txdesc(struct ath_hw *ah, void *ds,
|
||||
u32 pktLen, enum ath9k_pkt_type type,
|
||||
u32 txPower, u32 keyIx,
|
||||
enum ath9k_key_type keyType,
|
||||
u32 flags)
|
||||
{
|
||||
ath9k_hw_ops(ah)->set11n_txdesc(ah, ds, pktLen, type, txPower, keyIx,
|
||||
keyType, flags);
|
||||
}
|
||||
|
||||
static inline void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, void *ds,
|
||||
void *lastds,
|
||||
u32 durUpdateEn, u32 rtsctsRate,
|
||||
u32 rtsctsDuration,
|
||||
struct ath9k_11n_rate_series series[],
|
||||
u32 nseries, u32 flags)
|
||||
{
|
||||
ath9k_hw_ops(ah)->set11n_ratescenario(ah, ds, lastds, durUpdateEn,
|
||||
rtsctsRate, rtsctsDuration, series,
|
||||
nseries, flags);
|
||||
}
|
||||
|
||||
static inline void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, void *ds,
|
||||
u32 aggrLen)
|
||||
{
|
||||
ath9k_hw_ops(ah)->set11n_aggr_first(ah, ds, aggrLen);
|
||||
}
|
||||
|
||||
static inline void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds,
|
||||
u32 numDelims)
|
||||
{
|
||||
ath9k_hw_ops(ah)->set11n_aggr_middle(ah, ds, numDelims);
|
||||
}
|
||||
|
||||
static inline void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, void *ds)
|
||||
{
|
||||
ath9k_hw_ops(ah)->set11n_aggr_last(ah, ds);
|
||||
}
|
||||
|
||||
static inline void ath9k_hw_clr11n_aggr(struct ath_hw *ah, void *ds)
|
||||
{
|
||||
ath9k_hw_ops(ah)->clr11n_aggr(ah, ds);
|
||||
}
|
||||
|
||||
static inline void ath9k_hw_set11n_burstduration(struct ath_hw *ah, void *ds,
|
||||
u32 burstDuration)
|
||||
{
|
||||
ath9k_hw_ops(ah)->set11n_burstduration(ah, ds, burstDuration);
|
||||
}
|
||||
|
||||
static inline void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds,
|
||||
u32 vmf)
|
||||
{
|
||||
ath9k_hw_ops(ah)->set11n_virtualmorefrag(ah, ds, vmf);
|
||||
}
|
||||
|
||||
/* Private hardware call ops */
|
||||
|
||||
/* PHY ops */
|
||||
|
||||
static inline int ath9k_hw_rf_set_freq(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
return ath9k_hw_private_ops(ah)->rf_set_freq(ah, chan);
|
||||
}
|
||||
|
||||
static inline void ath9k_hw_spur_mitigate_freq(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
ath9k_hw_private_ops(ah)->spur_mitigate_freq(ah, chan);
|
||||
}
|
||||
|
||||
static inline int ath9k_hw_rf_alloc_ext_banks(struct ath_hw *ah)
|
||||
{
|
||||
if (!ath9k_hw_private_ops(ah)->rf_alloc_ext_banks)
|
||||
return 0;
|
||||
|
||||
return ath9k_hw_private_ops(ah)->rf_alloc_ext_banks(ah);
|
||||
}
|
||||
|
||||
static inline void ath9k_hw_rf_free_ext_banks(struct ath_hw *ah)
|
||||
{
|
||||
if (!ath9k_hw_private_ops(ah)->rf_free_ext_banks)
|
||||
return;
|
||||
|
||||
ath9k_hw_private_ops(ah)->rf_free_ext_banks(ah);
|
||||
}
|
||||
|
||||
static inline bool ath9k_hw_set_rf_regs(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan,
|
||||
u16 modesIndex)
|
||||
{
|
||||
if (!ath9k_hw_private_ops(ah)->set_rf_regs)
|
||||
return true;
|
||||
|
||||
return ath9k_hw_private_ops(ah)->set_rf_regs(ah, chan, modesIndex);
|
||||
}
|
||||
|
||||
static inline void ath9k_hw_init_bb(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
return ath9k_hw_private_ops(ah)->init_bb(ah, chan);
|
||||
}
|
||||
|
||||
static inline void ath9k_hw_set_channel_regs(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
return ath9k_hw_private_ops(ah)->set_channel_regs(ah, chan);
|
||||
}
|
||||
|
||||
static inline int ath9k_hw_process_ini(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
return ath9k_hw_private_ops(ah)->process_ini(ah, chan);
|
||||
}
|
||||
|
||||
static inline void ath9k_olc_init(struct ath_hw *ah)
|
||||
{
|
||||
if (!ath9k_hw_private_ops(ah)->olc_init)
|
||||
return;
|
||||
|
||||
return ath9k_hw_private_ops(ah)->olc_init(ah);
|
||||
}
|
||||
|
||||
static inline void ath9k_hw_set_rfmode(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
return ath9k_hw_private_ops(ah)->set_rfmode(ah, chan);
|
||||
}
|
||||
|
||||
static inline void ath9k_hw_mark_phy_inactive(struct ath_hw *ah)
|
||||
{
|
||||
return ath9k_hw_private_ops(ah)->mark_phy_inactive(ah);
|
||||
}
|
||||
|
||||
static inline void ath9k_hw_set_delta_slope(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
return ath9k_hw_private_ops(ah)->set_delta_slope(ah, chan);
|
||||
}
|
||||
|
||||
static inline bool ath9k_hw_rfbus_req(struct ath_hw *ah)
|
||||
{
|
||||
return ath9k_hw_private_ops(ah)->rfbus_req(ah);
|
||||
}
|
||||
|
||||
static inline void ath9k_hw_rfbus_done(struct ath_hw *ah)
|
||||
{
|
||||
return ath9k_hw_private_ops(ah)->rfbus_done(ah);
|
||||
}
|
||||
|
||||
static inline void ath9k_enable_rfkill(struct ath_hw *ah)
|
||||
{
|
||||
return ath9k_hw_private_ops(ah)->enable_rfkill(ah);
|
||||
}
|
||||
|
||||
static inline void ath9k_hw_restore_chainmask(struct ath_hw *ah)
|
||||
{
|
||||
if (!ath9k_hw_private_ops(ah)->restore_chainmask)
|
||||
return;
|
||||
|
||||
return ath9k_hw_private_ops(ah)->restore_chainmask(ah);
|
||||
}
|
||||
|
||||
static inline void ath9k_hw_set_diversity(struct ath_hw *ah, bool value)
|
||||
{
|
||||
return ath9k_hw_private_ops(ah)->set_diversity(ah, value);
|
||||
}
|
||||
|
||||
static inline bool ath9k_hw_ani_control(struct ath_hw *ah,
|
||||
enum ath9k_ani_cmd cmd, int param)
|
||||
{
|
||||
return ath9k_hw_private_ops(ah)->ani_control(ah, cmd, param);
|
||||
}
|
||||
|
||||
static inline void ath9k_hw_do_getnf(struct ath_hw *ah,
|
||||
int16_t nfarray[NUM_NF_READINGS])
|
||||
{
|
||||
ath9k_hw_private_ops(ah)->do_getnf(ah, nfarray);
|
||||
}
|
||||
|
||||
static inline void ath9k_hw_loadnf(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
ath9k_hw_private_ops(ah)->loadnf(ah, chan);
|
||||
}
|
||||
|
||||
static inline bool ath9k_hw_init_cal(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
return ath9k_hw_private_ops(ah)->init_cal(ah, chan);
|
||||
}
|
||||
|
||||
static inline void ath9k_hw_setup_calibration(struct ath_hw *ah,
|
||||
struct ath9k_cal_list *currCal)
|
||||
{
|
||||
ath9k_hw_private_ops(ah)->setup_calibration(ah, currCal);
|
||||
}
|
||||
|
||||
static inline bool ath9k_hw_iscal_supported(struct ath_hw *ah,
|
||||
enum ath9k_cal_types calType)
|
||||
{
|
||||
return ath9k_hw_private_ops(ah)->iscal_supported(ah, calType);
|
||||
}
|
||||
|
||||
#endif /* ATH9K_HW_OPS_H */
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2009 Atheros Communications Inc.
|
||||
* Copyright (c) 2008-2010 Atheros Communications Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -41,6 +41,9 @@
|
||||
#define AR9280_DEVID_PCIE 0x002a
|
||||
#define AR9285_DEVID_PCIE 0x002b
|
||||
#define AR2427_DEVID_PCIE 0x002c
|
||||
#define AR9287_DEVID_PCI 0x002d
|
||||
#define AR9287_DEVID_PCIE 0x002e
|
||||
#define AR9300_DEVID_PCIE 0x0030
|
||||
|
||||
#define AR5416_AR9100_DEVID 0x000b
|
||||
|
||||
@ -48,9 +51,6 @@
|
||||
#define AR_SUBVENDOR_ID_NEW_A 0x7065
|
||||
#define AR5416_MAGIC 0x19641014
|
||||
|
||||
#define AR5416_DEVID_AR9287_PCI 0x002D
|
||||
#define AR5416_DEVID_AR9287_PCIE 0x002E
|
||||
|
||||
#define AR9280_COEX2WIRE_SUBSYSID 0x309b
|
||||
#define AT9285_COEX3WIRE_SA_SUBSYSID 0x30aa
|
||||
#define AT9285_COEX3WIRE_DA_SUBSYSID 0x30ab
|
||||
@ -68,6 +68,24 @@
|
||||
#define REG_READ(_ah, _reg) \
|
||||
ath9k_hw_common(_ah)->ops->read((_ah), (_reg))
|
||||
|
||||
#define ENABLE_REGWRITE_BUFFER(_ah) \
|
||||
do { \
|
||||
if (AR_SREV_9271(_ah)) \
|
||||
ath9k_hw_common(_ah)->ops->enable_write_buffer((_ah)); \
|
||||
} while (0)
|
||||
|
||||
#define DISABLE_REGWRITE_BUFFER(_ah) \
|
||||
do { \
|
||||
if (AR_SREV_9271(_ah)) \
|
||||
ath9k_hw_common(_ah)->ops->disable_write_buffer((_ah)); \
|
||||
} while (0)
|
||||
|
||||
#define REGWRITE_BUFFER_FLUSH(_ah) \
|
||||
do { \
|
||||
if (AR_SREV_9271(_ah)) \
|
||||
ath9k_hw_common(_ah)->ops->write_flush((_ah)); \
|
||||
} while (0)
|
||||
|
||||
#define SM(_v, _f) (((_v) << _f##_S) & _f)
|
||||
#define MS(_v, _f) (((_v) & _f) >> _f##_S)
|
||||
#define REG_RMW(_a, _r, _set, _clr) \
|
||||
@ -75,6 +93,8 @@
|
||||
#define REG_RMW_FIELD(_a, _r, _f, _v) \
|
||||
REG_WRITE(_a, _r, \
|
||||
(REG_READ(_a, _r) & ~_f) | (((_v) << _f##_S) & _f))
|
||||
#define REG_READ_FIELD(_a, _r, _f) \
|
||||
(((REG_READ(_a, _r) & _f) >> _f##_S))
|
||||
#define REG_SET_BIT(_a, _r, _f) \
|
||||
REG_WRITE(_a, _r, REG_READ(_a, _r) | _f)
|
||||
#define REG_CLR_BIT(_a, _r, _f) \
|
||||
@ -135,6 +155,16 @@
|
||||
|
||||
#define TU_TO_USEC(_tu) ((_tu) << 10)
|
||||
|
||||
#define ATH9K_HW_RX_HP_QDEPTH 16
|
||||
#define ATH9K_HW_RX_LP_QDEPTH 128
|
||||
|
||||
enum ath_ini_subsys {
|
||||
ATH_INI_PRE = 0,
|
||||
ATH_INI_CORE,
|
||||
ATH_INI_POST,
|
||||
ATH_INI_NUM_SPLIT,
|
||||
};
|
||||
|
||||
enum wireless_mode {
|
||||
ATH9K_MODE_11A = 0,
|
||||
ATH9K_MODE_11G,
|
||||
@ -165,13 +195,15 @@ enum ath9k_hw_caps {
|
||||
ATH9K_HW_CAP_ENHANCEDPM = BIT(14),
|
||||
ATH9K_HW_CAP_AUTOSLEEP = BIT(15),
|
||||
ATH9K_HW_CAP_4KB_SPLITTRANS = BIT(16),
|
||||
ATH9K_HW_CAP_EDMA = BIT(17),
|
||||
ATH9K_HW_CAP_RAC_SUPPORTED = BIT(18),
|
||||
ATH9K_HW_CAP_LDPC = BIT(19),
|
||||
};
|
||||
|
||||
enum ath9k_capability_type {
|
||||
ATH9K_CAP_CIPHER = 0,
|
||||
ATH9K_CAP_TKIP_MIC,
|
||||
ATH9K_CAP_TKIP_SPLIT,
|
||||
ATH9K_CAP_DIVERSITY,
|
||||
ATH9K_CAP_TXPOW,
|
||||
ATH9K_CAP_MCAST_KEYSRCH,
|
||||
ATH9K_CAP_DS
|
||||
@ -192,6 +224,11 @@ struct ath9k_hw_capabilities {
|
||||
u8 num_gpio_pins;
|
||||
u8 num_antcfg_2ghz;
|
||||
u8 num_antcfg_5ghz;
|
||||
u8 rx_hp_qdepth;
|
||||
u8 rx_lp_qdepth;
|
||||
u8 rx_status_len;
|
||||
u8 tx_desc_len;
|
||||
u8 txs_len;
|
||||
};
|
||||
|
||||
struct ath9k_ops_config {
|
||||
@ -212,6 +249,7 @@ struct ath9k_ops_config {
|
||||
u32 enable_ani;
|
||||
int serialize_regmode;
|
||||
bool rx_intr_mitigation;
|
||||
bool tx_intr_mitigation;
|
||||
#define SPUR_DISABLE 0
|
||||
#define SPUR_ENABLE_IOCTL 1
|
||||
#define SPUR_ENABLE_EEPROM 2
|
||||
@ -231,6 +269,8 @@ struct ath9k_ops_config {
|
||||
enum ath9k_int {
|
||||
ATH9K_INT_RX = 0x00000001,
|
||||
ATH9K_INT_RXDESC = 0x00000002,
|
||||
ATH9K_INT_RXHP = 0x00000001,
|
||||
ATH9K_INT_RXLP = 0x00000002,
|
||||
ATH9K_INT_RXNOFRM = 0x00000008,
|
||||
ATH9K_INT_RXEOL = 0x00000010,
|
||||
ATH9K_INT_RXORN = 0x00000020,
|
||||
@ -363,6 +403,12 @@ enum ser_reg_mode {
|
||||
SER_REG_MODE_AUTO = 2,
|
||||
};
|
||||
|
||||
enum ath9k_rx_qtype {
|
||||
ATH9K_RX_QUEUE_HP,
|
||||
ATH9K_RX_QUEUE_LP,
|
||||
ATH9K_RX_QUEUE_MAX,
|
||||
};
|
||||
|
||||
struct ath9k_beacon_state {
|
||||
u32 bs_nexttbtt;
|
||||
u32 bs_nextdtim;
|
||||
@ -440,6 +486,124 @@ struct ath_gen_timer_table {
|
||||
} timer_mask;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ath_hw_private_ops - callbacks used internally by hardware code
|
||||
*
|
||||
* This structure contains private callbacks designed to only be used internally
|
||||
* by the hardware core.
|
||||
*
|
||||
* @init_cal_settings: setup types of calibrations supported
|
||||
* @init_cal: starts actual calibration
|
||||
*
|
||||
* @init_mode_regs: Initializes mode registers
|
||||
* @init_mode_gain_regs: Initialize TX/RX gain registers
|
||||
* @macversion_supported: If this specific mac revision is supported
|
||||
*
|
||||
* @rf_set_freq: change frequency
|
||||
* @spur_mitigate_freq: spur mitigation
|
||||
* @rf_alloc_ext_banks:
|
||||
* @rf_free_ext_banks:
|
||||
* @set_rf_regs:
|
||||
* @compute_pll_control: compute the PLL control value to use for
|
||||
* AR_RTC_PLL_CONTROL for a given channel
|
||||
* @setup_calibration: set up calibration
|
||||
* @iscal_supported: used to query if a type of calibration is supported
|
||||
* @loadnf: load noise floor read from each chain on the CCA registers
|
||||
*/
|
||||
struct ath_hw_private_ops {
|
||||
/* Calibration ops */
|
||||
void (*init_cal_settings)(struct ath_hw *ah);
|
||||
bool (*init_cal)(struct ath_hw *ah, struct ath9k_channel *chan);
|
||||
|
||||
void (*init_mode_regs)(struct ath_hw *ah);
|
||||
void (*init_mode_gain_regs)(struct ath_hw *ah);
|
||||
bool (*macversion_supported)(u32 macversion);
|
||||
void (*setup_calibration)(struct ath_hw *ah,
|
||||
struct ath9k_cal_list *currCal);
|
||||
bool (*iscal_supported)(struct ath_hw *ah,
|
||||
enum ath9k_cal_types calType);
|
||||
|
||||
/* PHY ops */
|
||||
int (*rf_set_freq)(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan);
|
||||
void (*spur_mitigate_freq)(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan);
|
||||
int (*rf_alloc_ext_banks)(struct ath_hw *ah);
|
||||
void (*rf_free_ext_banks)(struct ath_hw *ah);
|
||||
bool (*set_rf_regs)(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan,
|
||||
u16 modesIndex);
|
||||
void (*set_channel_regs)(struct ath_hw *ah, struct ath9k_channel *chan);
|
||||
void (*init_bb)(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan);
|
||||
int (*process_ini)(struct ath_hw *ah, struct ath9k_channel *chan);
|
||||
void (*olc_init)(struct ath_hw *ah);
|
||||
void (*set_rfmode)(struct ath_hw *ah, struct ath9k_channel *chan);
|
||||
void (*mark_phy_inactive)(struct ath_hw *ah);
|
||||
void (*set_delta_slope)(struct ath_hw *ah, struct ath9k_channel *chan);
|
||||
bool (*rfbus_req)(struct ath_hw *ah);
|
||||
void (*rfbus_done)(struct ath_hw *ah);
|
||||
void (*enable_rfkill)(struct ath_hw *ah);
|
||||
void (*restore_chainmask)(struct ath_hw *ah);
|
||||
void (*set_diversity)(struct ath_hw *ah, bool value);
|
||||
u32 (*compute_pll_control)(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan);
|
||||
bool (*ani_control)(struct ath_hw *ah, enum ath9k_ani_cmd cmd,
|
||||
int param);
|
||||
void (*do_getnf)(struct ath_hw *ah, int16_t nfarray[NUM_NF_READINGS]);
|
||||
void (*loadnf)(struct ath_hw *ah, struct ath9k_channel *chan);
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ath_hw_ops - callbacks used by hardware code and driver code
|
||||
*
|
||||
* This structure contains callbacks designed to to be used internally by
|
||||
* hardware code and also by the lower level driver.
|
||||
*
|
||||
* @config_pci_powersave:
|
||||
* @calibrate: periodic calibration for NF, ANI, IQ, ADC gain, ADC-DC
|
||||
*/
|
||||
struct ath_hw_ops {
|
||||
void (*config_pci_powersave)(struct ath_hw *ah,
|
||||
int restore,
|
||||
int power_off);
|
||||
void (*rx_enable)(struct ath_hw *ah);
|
||||
void (*set_desc_link)(void *ds, u32 link);
|
||||
void (*get_desc_link)(void *ds, u32 **link);
|
||||
bool (*calibrate)(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan,
|
||||
u8 rxchainmask,
|
||||
bool longcal);
|
||||
bool (*get_isr)(struct ath_hw *ah, enum ath9k_int *masked);
|
||||
void (*fill_txdesc)(struct ath_hw *ah, void *ds, u32 seglen,
|
||||
bool is_firstseg, bool is_is_lastseg,
|
||||
const void *ds0, dma_addr_t buf_addr,
|
||||
unsigned int qcu);
|
||||
int (*proc_txdesc)(struct ath_hw *ah, void *ds,
|
||||
struct ath_tx_status *ts);
|
||||
void (*set11n_txdesc)(struct ath_hw *ah, void *ds,
|
||||
u32 pktLen, enum ath9k_pkt_type type,
|
||||
u32 txPower, u32 keyIx,
|
||||
enum ath9k_key_type keyType,
|
||||
u32 flags);
|
||||
void (*set11n_ratescenario)(struct ath_hw *ah, void *ds,
|
||||
void *lastds,
|
||||
u32 durUpdateEn, u32 rtsctsRate,
|
||||
u32 rtsctsDuration,
|
||||
struct ath9k_11n_rate_series series[],
|
||||
u32 nseries, u32 flags);
|
||||
void (*set11n_aggr_first)(struct ath_hw *ah, void *ds,
|
||||
u32 aggrLen);
|
||||
void (*set11n_aggr_middle)(struct ath_hw *ah, void *ds,
|
||||
u32 numDelims);
|
||||
void (*set11n_aggr_last)(struct ath_hw *ah, void *ds);
|
||||
void (*clr11n_aggr)(struct ath_hw *ah, void *ds);
|
||||
void (*set11n_burstduration)(struct ath_hw *ah, void *ds,
|
||||
u32 burstDuration);
|
||||
void (*set11n_virtualmorefrag)(struct ath_hw *ah, void *ds,
|
||||
u32 vmf);
|
||||
};
|
||||
|
||||
struct ath_hw {
|
||||
struct ieee80211_hw *hw;
|
||||
struct ath_common common;
|
||||
@ -453,14 +617,18 @@ struct ath_hw {
|
||||
struct ar5416_eeprom_def def;
|
||||
struct ar5416_eeprom_4k map4k;
|
||||
struct ar9287_eeprom map9287;
|
||||
struct ar9300_eeprom ar9300_eep;
|
||||
} eeprom;
|
||||
const struct eeprom_ops *eep_ops;
|
||||
enum ath9k_eep_map eep_map;
|
||||
|
||||
bool sw_mgmt_crypto;
|
||||
bool is_pciexpress;
|
||||
bool need_an_top2_fixup;
|
||||
u16 tx_trig_level;
|
||||
s16 nf_2g_max;
|
||||
s16 nf_2g_min;
|
||||
s16 nf_5g_max;
|
||||
s16 nf_5g_min;
|
||||
u16 rfsilent;
|
||||
u32 rfkill_gpio;
|
||||
u32 rfkill_polarity;
|
||||
@ -493,6 +661,7 @@ struct ath_hw {
|
||||
struct ath9k_cal_list adcgain_caldata;
|
||||
struct ath9k_cal_list adcdc_calinitdata;
|
||||
struct ath9k_cal_list adcdc_caldata;
|
||||
struct ath9k_cal_list tempCompCalData;
|
||||
struct ath9k_cal_list *cal_list;
|
||||
struct ath9k_cal_list *cal_list_last;
|
||||
struct ath9k_cal_list *cal_list_curr;
|
||||
@ -533,12 +702,10 @@ struct ath_hw {
|
||||
DONT_USE_32KHZ,
|
||||
} enable_32kHz_clock;
|
||||
|
||||
/* Callback for radio frequency change */
|
||||
int (*ath9k_hw_rf_set_freq)(struct ath_hw *ah, struct ath9k_channel *chan);
|
||||
|
||||
/* Callback for baseband spur frequency */
|
||||
void (*ath9k_hw_spur_mitigate_freq)(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan);
|
||||
/* Private to hardware code */
|
||||
struct ath_hw_private_ops private_ops;
|
||||
/* Accessed by the lower level driver */
|
||||
struct ath_hw_ops ops;
|
||||
|
||||
/* Used to program the radio on non single-chip devices */
|
||||
u32 *analogBank0Data;
|
||||
@ -592,6 +759,7 @@ struct ath_hw {
|
||||
struct ar5416IniArray iniBank7;
|
||||
struct ar5416IniArray iniAddac;
|
||||
struct ar5416IniArray iniPcieSerdes;
|
||||
struct ar5416IniArray iniPcieSerdesLowPower;
|
||||
struct ar5416IniArray iniModesAdditional;
|
||||
struct ar5416IniArray iniModesRxGain;
|
||||
struct ar5416IniArray iniModesTxGain;
|
||||
@ -604,9 +772,21 @@ struct ath_hw {
|
||||
struct ar5416IniArray iniModes_high_power_tx_gain_9271;
|
||||
struct ar5416IniArray iniModes_normal_power_tx_gain_9271;
|
||||
|
||||
struct ar5416IniArray iniMac[ATH_INI_NUM_SPLIT];
|
||||
struct ar5416IniArray iniBB[ATH_INI_NUM_SPLIT];
|
||||
struct ar5416IniArray iniRadio[ATH_INI_NUM_SPLIT];
|
||||
struct ar5416IniArray iniSOC[ATH_INI_NUM_SPLIT];
|
||||
|
||||
u32 intr_gen_timer_trigger;
|
||||
u32 intr_gen_timer_thresh;
|
||||
struct ath_gen_timer_table hw_gen_timers;
|
||||
|
||||
struct ar9003_txs *ts_ring;
|
||||
void *ts_start;
|
||||
u32 ts_paddr_start;
|
||||
u32 ts_paddr_end;
|
||||
u16 ts_tail;
|
||||
u8 ts_size;
|
||||
};
|
||||
|
||||
static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah)
|
||||
@ -619,6 +799,16 @@ static inline struct ath_regulatory *ath9k_hw_regulatory(struct ath_hw *ah)
|
||||
return &(ath9k_hw_common(ah)->regulatory);
|
||||
}
|
||||
|
||||
static inline struct ath_hw_private_ops *ath9k_hw_private_ops(struct ath_hw *ah)
|
||||
{
|
||||
return &ah->private_ops;
|
||||
}
|
||||
|
||||
static inline struct ath_hw_ops *ath9k_hw_ops(struct ath_hw *ah)
|
||||
{
|
||||
return &ah->ops;
|
||||
}
|
||||
|
||||
/* Initialization, Detach, Reset */
|
||||
const char *ath9k_hw_probe(u16 vendorid, u16 devid);
|
||||
void ath9k_hw_deinit(struct ath_hw *ah);
|
||||
@ -630,6 +820,7 @@ bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type,
|
||||
u32 capability, u32 *result);
|
||||
bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type,
|
||||
u32 capability, u32 setting, int *status);
|
||||
u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan);
|
||||
|
||||
/* Key Cache Management */
|
||||
bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry);
|
||||
@ -678,16 +869,10 @@ void ath9k_hw_set11nmac2040(struct ath_hw *ah);
|
||||
void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period);
|
||||
void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
|
||||
const struct ath9k_beacon_state *bs);
|
||||
bool ath9k_hw_check_alive(struct ath_hw *ah);
|
||||
|
||||
bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode);
|
||||
|
||||
void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore, int power_off);
|
||||
|
||||
/* Interrupt Handling */
|
||||
bool ath9k_hw_intrpend(struct ath_hw *ah);
|
||||
bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked);
|
||||
enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints);
|
||||
|
||||
/* Generic hw timer primitives */
|
||||
struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah,
|
||||
void (*trigger)(void *),
|
||||
@ -709,6 +894,36 @@ void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len);
|
||||
/* HTC */
|
||||
void ath9k_hw_htc_resetinit(struct ath_hw *ah);
|
||||
|
||||
/* PHY */
|
||||
void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled,
|
||||
u32 *coef_mantissa, u32 *coef_exponent);
|
||||
|
||||
/*
|
||||
* Code Specific to AR5008, AR9001 or AR9002,
|
||||
* we stuff these here to avoid callbacks for AR9003.
|
||||
*/
|
||||
void ar9002_hw_cck_chan14_spread(struct ath_hw *ah);
|
||||
int ar9002_hw_rf_claim(struct ath_hw *ah);
|
||||
void ar9002_hw_enable_async_fifo(struct ath_hw *ah);
|
||||
void ar9002_hw_enable_wep_aggregation(struct ath_hw *ah);
|
||||
|
||||
/*
|
||||
* Code specifric to AR9003, we stuff these here to avoid callbacks
|
||||
* for older families
|
||||
*/
|
||||
void ar9003_hw_set_nf_limits(struct ath_hw *ah);
|
||||
|
||||
/* Hardware family op attach helpers */
|
||||
void ar5008_hw_attach_phy_ops(struct ath_hw *ah);
|
||||
void ar9002_hw_attach_phy_ops(struct ath_hw *ah);
|
||||
void ar9003_hw_attach_phy_ops(struct ath_hw *ah);
|
||||
|
||||
void ar9002_hw_attach_calib_ops(struct ath_hw *ah);
|
||||
void ar9003_hw_attach_calib_ops(struct ath_hw *ah);
|
||||
|
||||
void ar9002_hw_attach_ops(struct ath_hw *ah);
|
||||
void ar9003_hw_attach_ops(struct ath_hw *ah);
|
||||
|
||||
#define ATH_PCIE_CAP_LINK_CTRL 0x70
|
||||
#define ATH_PCIE_CAP_LINK_L0S 1
|
||||
#define ATH_PCIE_CAP_LINK_L1 2
|
||||
|
@ -175,6 +175,18 @@ static const struct ath_ops ath9k_common_ops = {
|
||||
.write = ath9k_iowrite32,
|
||||
};
|
||||
|
||||
static int count_streams(unsigned int chainmask, int max)
|
||||
{
|
||||
int streams = 0;
|
||||
|
||||
do {
|
||||
if (++streams == max)
|
||||
break;
|
||||
} while ((chainmask = chainmask & (chainmask - 1)));
|
||||
|
||||
return streams;
|
||||
}
|
||||
|
||||
/**************************/
|
||||
/* Initialization */
|
||||
/**************************/
|
||||
@ -182,8 +194,10 @@ static const struct ath_ops ath9k_common_ops = {
|
||||
static void setup_ht_cap(struct ath_softc *sc,
|
||||
struct ieee80211_sta_ht_cap *ht_info)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
u8 tx_streams, rx_streams;
|
||||
int i, max_streams;
|
||||
|
||||
ht_info->ht_supported = true;
|
||||
ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
|
||||
@ -191,28 +205,40 @@ static void setup_ht_cap(struct ath_softc *sc,
|
||||
IEEE80211_HT_CAP_SGI_40 |
|
||||
IEEE80211_HT_CAP_DSSSCCK40;
|
||||
|
||||
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_LDPC)
|
||||
ht_info->cap |= IEEE80211_HT_CAP_LDPC_CODING;
|
||||
|
||||
ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
|
||||
ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
|
||||
|
||||
if (AR_SREV_9300_20_OR_LATER(ah))
|
||||
max_streams = 3;
|
||||
else
|
||||
max_streams = 2;
|
||||
|
||||
if (AR_SREV_9280_10_OR_LATER(ah)) {
|
||||
if (max_streams >= 2)
|
||||
ht_info->cap |= IEEE80211_HT_CAP_TX_STBC;
|
||||
ht_info->cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
|
||||
}
|
||||
|
||||
/* set up supported mcs set */
|
||||
memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
|
||||
tx_streams = !(common->tx_chainmask & (common->tx_chainmask - 1)) ?
|
||||
1 : 2;
|
||||
rx_streams = !(common->rx_chainmask & (common->rx_chainmask - 1)) ?
|
||||
1 : 2;
|
||||
tx_streams = count_streams(common->tx_chainmask, max_streams);
|
||||
rx_streams = count_streams(common->rx_chainmask, max_streams);
|
||||
|
||||
ath_print(common, ATH_DBG_CONFIG,
|
||||
"TX streams %d, RX streams: %d\n",
|
||||
tx_streams, rx_streams);
|
||||
|
||||
if (tx_streams != rx_streams) {
|
||||
ath_print(common, ATH_DBG_CONFIG,
|
||||
"TX streams %d, RX streams: %d\n",
|
||||
tx_streams, rx_streams);
|
||||
ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF;
|
||||
ht_info->mcs.tx_params |= ((tx_streams - 1) <<
|
||||
IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT);
|
||||
}
|
||||
|
||||
ht_info->mcs.rx_mask[0] = 0xff;
|
||||
if (rx_streams >= 2)
|
||||
ht_info->mcs.rx_mask[1] = 0xff;
|
||||
for (i = 0; i < rx_streams; i++)
|
||||
ht_info->mcs.rx_mask[i] = 0xff;
|
||||
|
||||
ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
|
||||
}
|
||||
@ -235,31 +261,37 @@ static int ath9k_reg_notifier(struct wiphy *wiphy,
|
||||
*/
|
||||
int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
|
||||
struct list_head *head, const char *name,
|
||||
int nbuf, int ndesc)
|
||||
int nbuf, int ndesc, bool is_tx)
|
||||
{
|
||||
#define DS2PHYS(_dd, _ds) \
|
||||
((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc))
|
||||
#define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0)
|
||||
#define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096)
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
struct ath_desc *ds;
|
||||
u8 *ds;
|
||||
struct ath_buf *bf;
|
||||
int i, bsize, error;
|
||||
int i, bsize, error, desc_len;
|
||||
|
||||
ath_print(common, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n",
|
||||
name, nbuf, ndesc);
|
||||
|
||||
INIT_LIST_HEAD(head);
|
||||
|
||||
if (is_tx)
|
||||
desc_len = sc->sc_ah->caps.tx_desc_len;
|
||||
else
|
||||
desc_len = sizeof(struct ath_desc);
|
||||
|
||||
/* ath_desc must be a multiple of DWORDs */
|
||||
if ((sizeof(struct ath_desc) % 4) != 0) {
|
||||
if ((desc_len % 4) != 0) {
|
||||
ath_print(common, ATH_DBG_FATAL,
|
||||
"ath_desc not DWORD aligned\n");
|
||||
BUG_ON((sizeof(struct ath_desc) % 4) != 0);
|
||||
BUG_ON((desc_len % 4) != 0);
|
||||
error = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
dd->dd_desc_len = sizeof(struct ath_desc) * nbuf * ndesc;
|
||||
dd->dd_desc_len = desc_len * nbuf * ndesc;
|
||||
|
||||
/*
|
||||
* Need additional DMA memory because we can't use
|
||||
@ -272,7 +304,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
|
||||
u32 dma_len;
|
||||
|
||||
while (ndesc_skipped) {
|
||||
dma_len = ndesc_skipped * sizeof(struct ath_desc);
|
||||
dma_len = ndesc_skipped * desc_len;
|
||||
dd->dd_desc_len += dma_len;
|
||||
|
||||
ndesc_skipped = ATH_DESC_4KB_BOUND_NUM_SKIPPED(dma_len);
|
||||
@ -286,7 +318,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
|
||||
error = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
ds = dd->dd_desc;
|
||||
ds = (u8 *) dd->dd_desc;
|
||||
ath_print(common, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n",
|
||||
name, ds, (u32) dd->dd_desc_len,
|
||||
ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);
|
||||
@ -300,7 +332,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
|
||||
}
|
||||
dd->dd_bufptr = bf;
|
||||
|
||||
for (i = 0; i < nbuf; i++, bf++, ds += ndesc) {
|
||||
for (i = 0; i < nbuf; i++, bf++, ds += (desc_len * ndesc)) {
|
||||
bf->bf_desc = ds;
|
||||
bf->bf_daddr = DS2PHYS(dd, ds);
|
||||
|
||||
@ -316,7 +348,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
|
||||
((caddr_t) dd->dd_desc +
|
||||
dd->dd_desc_len));
|
||||
|
||||
ds += ndesc;
|
||||
ds += (desc_len * ndesc);
|
||||
bf->bf_desc = ds;
|
||||
bf->bf_daddr = DS2PHYS(dd, ds);
|
||||
}
|
||||
@ -514,7 +546,7 @@ static void ath9k_init_misc(struct ath_softc *sc)
|
||||
common->tx_chainmask = sc->sc_ah->caps.tx_chainmask;
|
||||
common->rx_chainmask = sc->sc_ah->caps.rx_chainmask;
|
||||
|
||||
ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_DIVERSITY, 1, true, NULL);
|
||||
ath9k_hw_set_diversity(sc->sc_ah, true);
|
||||
sc->rx.defant = ath9k_hw_getdefantenna(sc->sc_ah);
|
||||
|
||||
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
|
||||
@ -568,13 +600,10 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
|
||||
ath_read_cachesize(common, &csz);
|
||||
common->cachelsz = csz << 2; /* convert to bytes */
|
||||
|
||||
/* Initializes the hardware for all supported chipsets */
|
||||
ret = ath9k_hw_init(ah);
|
||||
if (ret) {
|
||||
ath_print(common, ATH_DBG_FATAL,
|
||||
"Unable to initialize hardware; "
|
||||
"initialization status: %d\n", ret);
|
||||
if (ret)
|
||||
goto err_hw;
|
||||
}
|
||||
|
||||
ret = ath9k_init_debug(ah);
|
||||
if (ret) {
|
||||
|
@ -25,6 +25,8 @@ static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
|
||||
ah->txdesc_interrupt_mask, ah->txeol_interrupt_mask,
|
||||
ah->txurn_interrupt_mask);
|
||||
|
||||
ENABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
REG_WRITE(ah, AR_IMR_S0,
|
||||
SM(ah->txok_interrupt_mask, AR_IMR_S0_QCU_TXOK)
|
||||
| SM(ah->txdesc_interrupt_mask, AR_IMR_S0_QCU_TXDESC));
|
||||
@ -35,6 +37,9 @@ static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
|
||||
ah->imrs2_reg &= ~AR_IMR_S2_QCU_TXURN;
|
||||
ah->imrs2_reg |= (ah->txurn_interrupt_mask & AR_IMR_S2_QCU_TXURN);
|
||||
REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
}
|
||||
|
||||
u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q)
|
||||
@ -57,6 +62,18 @@ void ath9k_hw_txstart(struct ath_hw *ah, u32 q)
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_txstart);
|
||||
|
||||
void ath9k_hw_cleartxdesc(struct ath_hw *ah, void *ds)
|
||||
{
|
||||
struct ar5416_desc *ads = AR5416DESC(ds);
|
||||
|
||||
ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
|
||||
ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
|
||||
ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
|
||||
ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
|
||||
ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_cleartxdesc);
|
||||
|
||||
u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q)
|
||||
{
|
||||
u32 npend;
|
||||
@ -207,281 +224,6 @@ bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_stoptxdma);
|
||||
|
||||
void ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
|
||||
u32 segLen, bool firstSeg,
|
||||
bool lastSeg, const struct ath_desc *ds0)
|
||||
{
|
||||
struct ar5416_desc *ads = AR5416DESC(ds);
|
||||
|
||||
if (firstSeg) {
|
||||
ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_TxMore);
|
||||
} else if (lastSeg) {
|
||||
ads->ds_ctl0 = 0;
|
||||
ads->ds_ctl1 = segLen;
|
||||
ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2;
|
||||
ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3;
|
||||
} else {
|
||||
ads->ds_ctl0 = 0;
|
||||
ads->ds_ctl1 = segLen | AR_TxMore;
|
||||
ads->ds_ctl2 = 0;
|
||||
ads->ds_ctl3 = 0;
|
||||
}
|
||||
ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
|
||||
ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
|
||||
ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
|
||||
ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
|
||||
ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_filltxdesc);
|
||||
|
||||
void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds)
|
||||
{
|
||||
struct ar5416_desc *ads = AR5416DESC(ds);
|
||||
|
||||
ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
|
||||
ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
|
||||
ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
|
||||
ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
|
||||
ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_cleartxdesc);
|
||||
|
||||
int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds,
|
||||
struct ath_tx_status *ts)
|
||||
{
|
||||
struct ar5416_desc *ads = AR5416DESC(ds);
|
||||
|
||||
if ((ads->ds_txstatus9 & AR_TxDone) == 0)
|
||||
return -EINPROGRESS;
|
||||
|
||||
ts->ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum);
|
||||
ts->ts_tstamp = ads->AR_SendTimestamp;
|
||||
ts->ts_status = 0;
|
||||
ts->ts_flags = 0;
|
||||
|
||||
if (ads->ds_txstatus1 & AR_FrmXmitOK)
|
||||
ts->ts_status |= ATH9K_TX_ACKED;
|
||||
if (ads->ds_txstatus1 & AR_ExcessiveRetries)
|
||||
ts->ts_status |= ATH9K_TXERR_XRETRY;
|
||||
if (ads->ds_txstatus1 & AR_Filtered)
|
||||
ts->ts_status |= ATH9K_TXERR_FILT;
|
||||
if (ads->ds_txstatus1 & AR_FIFOUnderrun) {
|
||||
ts->ts_status |= ATH9K_TXERR_FIFO;
|
||||
ath9k_hw_updatetxtriglevel(ah, true);
|
||||
}
|
||||
if (ads->ds_txstatus9 & AR_TxOpExceeded)
|
||||
ts->ts_status |= ATH9K_TXERR_XTXOP;
|
||||
if (ads->ds_txstatus1 & AR_TxTimerExpired)
|
||||
ts->ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
|
||||
|
||||
if (ads->ds_txstatus1 & AR_DescCfgErr)
|
||||
ts->ts_flags |= ATH9K_TX_DESC_CFG_ERR;
|
||||
if (ads->ds_txstatus1 & AR_TxDataUnderrun) {
|
||||
ts->ts_flags |= ATH9K_TX_DATA_UNDERRUN;
|
||||
ath9k_hw_updatetxtriglevel(ah, true);
|
||||
}
|
||||
if (ads->ds_txstatus1 & AR_TxDelimUnderrun) {
|
||||
ts->ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
|
||||
ath9k_hw_updatetxtriglevel(ah, true);
|
||||
}
|
||||
if (ads->ds_txstatus0 & AR_TxBaStatus) {
|
||||
ts->ts_flags |= ATH9K_TX_BA;
|
||||
ts->ba_low = ads->AR_BaBitmapLow;
|
||||
ts->ba_high = ads->AR_BaBitmapHigh;
|
||||
}
|
||||
|
||||
ts->ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx);
|
||||
switch (ts->ts_rateindex) {
|
||||
case 0:
|
||||
ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0);
|
||||
break;
|
||||
case 1:
|
||||
ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1);
|
||||
break;
|
||||
case 2:
|
||||
ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2);
|
||||
break;
|
||||
case 3:
|
||||
ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3);
|
||||
break;
|
||||
}
|
||||
|
||||
ts->ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined);
|
||||
ts->ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00);
|
||||
ts->ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01);
|
||||
ts->ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02);
|
||||
ts->ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10);
|
||||
ts->ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11);
|
||||
ts->ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12);
|
||||
ts->evm0 = ads->AR_TxEVM0;
|
||||
ts->evm1 = ads->AR_TxEVM1;
|
||||
ts->evm2 = ads->AR_TxEVM2;
|
||||
ts->ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt);
|
||||
ts->ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt);
|
||||
ts->ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt);
|
||||
ts->ts_antenna = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_txprocdesc);
|
||||
|
||||
void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds,
|
||||
u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
|
||||
u32 keyIx, enum ath9k_key_type keyType, u32 flags)
|
||||
{
|
||||
struct ar5416_desc *ads = AR5416DESC(ds);
|
||||
|
||||
txPower += ah->txpower_indexoffset;
|
||||
if (txPower > 63)
|
||||
txPower = 63;
|
||||
|
||||
ads->ds_ctl0 = (pktLen & AR_FrameLen)
|
||||
| (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
|
||||
| SM(txPower, AR_XmitPower)
|
||||
| (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
|
||||
| (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
|
||||
| (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0)
|
||||
| (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0);
|
||||
|
||||
ads->ds_ctl1 =
|
||||
(keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0)
|
||||
| SM(type, AR_FrameType)
|
||||
| (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
|
||||
| (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
|
||||
| (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
|
||||
|
||||
ads->ds_ctl6 = SM(keyType, AR_EncrType);
|
||||
|
||||
if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) {
|
||||
ads->ds_ctl8 = 0;
|
||||
ads->ds_ctl9 = 0;
|
||||
ads->ds_ctl10 = 0;
|
||||
ads->ds_ctl11 = 0;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_set11n_txdesc);
|
||||
|
||||
void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, struct ath_desc *ds,
|
||||
struct ath_desc *lastds,
|
||||
u32 durUpdateEn, u32 rtsctsRate,
|
||||
u32 rtsctsDuration,
|
||||
struct ath9k_11n_rate_series series[],
|
||||
u32 nseries, u32 flags)
|
||||
{
|
||||
struct ar5416_desc *ads = AR5416DESC(ds);
|
||||
struct ar5416_desc *last_ads = AR5416DESC(lastds);
|
||||
u32 ds_ctl0;
|
||||
|
||||
if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
|
||||
ds_ctl0 = ads->ds_ctl0;
|
||||
|
||||
if (flags & ATH9K_TXDESC_RTSENA) {
|
||||
ds_ctl0 &= ~AR_CTSEnable;
|
||||
ds_ctl0 |= AR_RTSEnable;
|
||||
} else {
|
||||
ds_ctl0 &= ~AR_RTSEnable;
|
||||
ds_ctl0 |= AR_CTSEnable;
|
||||
}
|
||||
|
||||
ads->ds_ctl0 = ds_ctl0;
|
||||
} else {
|
||||
ads->ds_ctl0 =
|
||||
(ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable));
|
||||
}
|
||||
|
||||
ads->ds_ctl2 = set11nTries(series, 0)
|
||||
| set11nTries(series, 1)
|
||||
| set11nTries(series, 2)
|
||||
| set11nTries(series, 3)
|
||||
| (durUpdateEn ? AR_DurUpdateEna : 0)
|
||||
| SM(0, AR_BurstDur);
|
||||
|
||||
ads->ds_ctl3 = set11nRate(series, 0)
|
||||
| set11nRate(series, 1)
|
||||
| set11nRate(series, 2)
|
||||
| set11nRate(series, 3);
|
||||
|
||||
ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0)
|
||||
| set11nPktDurRTSCTS(series, 1);
|
||||
|
||||
ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2)
|
||||
| set11nPktDurRTSCTS(series, 3);
|
||||
|
||||
ads->ds_ctl7 = set11nRateFlags(series, 0)
|
||||
| set11nRateFlags(series, 1)
|
||||
| set11nRateFlags(series, 2)
|
||||
| set11nRateFlags(series, 3)
|
||||
| SM(rtsctsRate, AR_RTSCTSRate);
|
||||
last_ads->ds_ctl2 = ads->ds_ctl2;
|
||||
last_ads->ds_ctl3 = ads->ds_ctl3;
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_set11n_ratescenario);
|
||||
|
||||
void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, struct ath_desc *ds,
|
||||
u32 aggrLen)
|
||||
{
|
||||
struct ar5416_desc *ads = AR5416DESC(ds);
|
||||
|
||||
ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
|
||||
ads->ds_ctl6 &= ~AR_AggrLen;
|
||||
ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_set11n_aggr_first);
|
||||
|
||||
void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, struct ath_desc *ds,
|
||||
u32 numDelims)
|
||||
{
|
||||
struct ar5416_desc *ads = AR5416DESC(ds);
|
||||
unsigned int ctl6;
|
||||
|
||||
ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
|
||||
|
||||
ctl6 = ads->ds_ctl6;
|
||||
ctl6 &= ~AR_PadDelim;
|
||||
ctl6 |= SM(numDelims, AR_PadDelim);
|
||||
ads->ds_ctl6 = ctl6;
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_set11n_aggr_middle);
|
||||
|
||||
void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, struct ath_desc *ds)
|
||||
{
|
||||
struct ar5416_desc *ads = AR5416DESC(ds);
|
||||
|
||||
ads->ds_ctl1 |= AR_IsAggr;
|
||||
ads->ds_ctl1 &= ~AR_MoreAggr;
|
||||
ads->ds_ctl6 &= ~AR_PadDelim;
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_set11n_aggr_last);
|
||||
|
||||
void ath9k_hw_clr11n_aggr(struct ath_hw *ah, struct ath_desc *ds)
|
||||
{
|
||||
struct ar5416_desc *ads = AR5416DESC(ds);
|
||||
|
||||
ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_clr11n_aggr);
|
||||
|
||||
void ath9k_hw_set11n_burstduration(struct ath_hw *ah, struct ath_desc *ds,
|
||||
u32 burstDuration)
|
||||
{
|
||||
struct ar5416_desc *ads = AR5416DESC(ds);
|
||||
|
||||
ads->ds_ctl2 &= ~AR_BurstDur;
|
||||
ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_set11n_burstduration);
|
||||
|
||||
void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, struct ath_desc *ds,
|
||||
u32 vmf)
|
||||
{
|
||||
struct ar5416_desc *ads = AR5416DESC(ds);
|
||||
|
||||
if (vmf)
|
||||
ads->ds_ctl0 |= AR_VirtMoreFrag;
|
||||
else
|
||||
ads->ds_ctl0 &= ~AR_VirtMoreFrag;
|
||||
}
|
||||
|
||||
void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs)
|
||||
{
|
||||
*txqs &= ah->intr_txqs;
|
||||
@ -733,6 +475,8 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
|
||||
} else
|
||||
cwMin = qi->tqi_cwmin;
|
||||
|
||||
ENABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
REG_WRITE(ah, AR_DLCL_IFS(q),
|
||||
SM(cwMin, AR_D_LCL_IFS_CWMIN) |
|
||||
SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX) |
|
||||
@ -747,6 +491,8 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
|
||||
REG_WRITE(ah, AR_DMISC(q),
|
||||
AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
|
||||
if (qi->tqi_cbrPeriod) {
|
||||
REG_WRITE(ah, AR_QCBRCFG(q),
|
||||
SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL) |
|
||||
@ -762,6 +508,8 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
|
||||
AR_Q_RDYTIMECFG_EN);
|
||||
}
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
|
||||
REG_WRITE(ah, AR_DCHNTIME(q),
|
||||
SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) |
|
||||
(qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
|
||||
@ -779,6 +527,10 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
|
||||
REG_READ(ah, AR_DMISC(q)) |
|
||||
AR_D_MISC_POST_FR_BKOFF_DIS);
|
||||
}
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {
|
||||
REG_WRITE(ah, AR_DMISC(q),
|
||||
REG_READ(ah, AR_DMISC(q)) |
|
||||
@ -786,6 +538,8 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
|
||||
}
|
||||
switch (qi->tqi_type) {
|
||||
case ATH9K_TX_QUEUE_BEACON:
|
||||
ENABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
|
||||
| AR_Q_MISC_FSP_DBA_GATED
|
||||
| AR_Q_MISC_BEACON_USE
|
||||
@ -796,8 +550,20 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
|
||||
AR_D_MISC_ARB_LOCKOUT_CNTRL_S)
|
||||
| AR_D_MISC_BEACON_USE
|
||||
| AR_D_MISC_POST_FR_BKOFF_DIS);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
/* cwmin and cwmax should be 0 for beacon queue */
|
||||
if (AR_SREV_9300_20_OR_LATER(ah)) {
|
||||
REG_WRITE(ah, AR_DLCL_IFS(q), SM(0, AR_D_LCL_IFS_CWMIN)
|
||||
| SM(0, AR_D_LCL_IFS_CWMAX)
|
||||
| SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS));
|
||||
}
|
||||
break;
|
||||
case ATH9K_TX_QUEUE_CAB:
|
||||
ENABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
|
||||
| AR_Q_MISC_FSP_DBA_GATED
|
||||
| AR_Q_MISC_CBR_INCR_DIS1
|
||||
@ -811,6 +577,10 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
|
||||
REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
|
||||
| (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
|
||||
AR_D_MISC_ARB_LOCKOUT_CNTRL_S));
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
DISABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
break;
|
||||
case ATH9K_TX_QUEUE_PSPOLL:
|
||||
REG_WRITE(ah, AR_QMISC(q),
|
||||
@ -832,6 +602,9 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
|
||||
AR_D_MISC_POST_FR_BKOFF_DIS);
|
||||
}
|
||||
|
||||
if (AR_SREV_9300_20_OR_LATER(ah))
|
||||
REG_WRITE(ah, AR_Q_DESC_CRCCHK, AR_Q_DESC_CRCCHK_EN);
|
||||
|
||||
if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE)
|
||||
ah->txok_interrupt_mask |= 1 << q;
|
||||
else
|
||||
@ -940,22 +713,6 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_rxprocdesc);
|
||||
|
||||
void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
|
||||
u32 size, u32 flags)
|
||||
{
|
||||
struct ar5416_desc *ads = AR5416DESC(ds);
|
||||
struct ath9k_hw_capabilities *pCap = &ah->caps;
|
||||
|
||||
ads->ds_ctl1 = size & AR_BufLen;
|
||||
if (flags & ATH9K_RXDESC_INTREQ)
|
||||
ads->ds_ctl1 |= AR_RxIntrReq;
|
||||
|
||||
ads->ds_rxstatus8 &= ~AR_RxDone;
|
||||
if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
|
||||
memset(&(ads->u), 0, sizeof(ads->u));
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_setuprxdesc);
|
||||
|
||||
/*
|
||||
* This can stop or re-enables RX.
|
||||
*
|
||||
@ -999,12 +756,6 @@ void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp)
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_putrxbuf);
|
||||
|
||||
void ath9k_hw_rxena(struct ath_hw *ah)
|
||||
{
|
||||
REG_WRITE(ah, AR_CR, AR_CR_RXE);
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_rxena);
|
||||
|
||||
void ath9k_hw_startpcureceive(struct ath_hw *ah)
|
||||
{
|
||||
ath9k_enable_mib_counters(ah);
|
||||
@ -1023,6 +774,14 @@ void ath9k_hw_stoppcurecv(struct ath_hw *ah)
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_stoppcurecv);
|
||||
|
||||
void ath9k_hw_abortpcurecv(struct ath_hw *ah)
|
||||
{
|
||||
REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_ABORT | AR_DIAG_RX_DIS);
|
||||
|
||||
ath9k_hw_disable_mib_counters(ah);
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_abortpcurecv);
|
||||
|
||||
bool ath9k_hw_stopdmarecv(struct ath_hw *ah)
|
||||
{
|
||||
#define AH_RX_STOP_DMA_TIMEOUT 10000 /* usec */
|
||||
@ -1068,3 +827,140 @@ int ath9k_hw_beaconq_setup(struct ath_hw *ah)
|
||||
return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi);
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_beaconq_setup);
|
||||
|
||||
bool ath9k_hw_intrpend(struct ath_hw *ah)
|
||||
{
|
||||
u32 host_isr;
|
||||
|
||||
if (AR_SREV_9100(ah))
|
||||
return true;
|
||||
|
||||
host_isr = REG_READ(ah, AR_INTR_ASYNC_CAUSE);
|
||||
if ((host_isr & AR_INTR_MAC_IRQ) && (host_isr != AR_INTR_SPURIOUS))
|
||||
return true;
|
||||
|
||||
host_isr = REG_READ(ah, AR_INTR_SYNC_CAUSE);
|
||||
if ((host_isr & AR_INTR_SYNC_DEFAULT)
|
||||
&& (host_isr != AR_INTR_SPURIOUS))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_intrpend);
|
||||
|
||||
enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah,
|
||||
enum ath9k_int ints)
|
||||
{
|
||||
enum ath9k_int omask = ah->imask;
|
||||
u32 mask, mask2;
|
||||
struct ath9k_hw_capabilities *pCap = &ah->caps;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
|
||||
ath_print(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints);
|
||||
|
||||
if (omask & ATH9K_INT_GLOBAL) {
|
||||
ath_print(common, ATH_DBG_INTERRUPT, "disable IER\n");
|
||||
REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
|
||||
(void) REG_READ(ah, AR_IER);
|
||||
if (!AR_SREV_9100(ah)) {
|
||||
REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0);
|
||||
(void) REG_READ(ah, AR_INTR_ASYNC_ENABLE);
|
||||
|
||||
REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
|
||||
(void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: global int Ref count */
|
||||
mask = ints & ATH9K_INT_COMMON;
|
||||
mask2 = 0;
|
||||
|
||||
if (ints & ATH9K_INT_TX) {
|
||||
if (ah->config.tx_intr_mitigation)
|
||||
mask |= AR_IMR_TXMINTR | AR_IMR_TXINTM;
|
||||
if (ah->txok_interrupt_mask)
|
||||
mask |= AR_IMR_TXOK;
|
||||
if (ah->txdesc_interrupt_mask)
|
||||
mask |= AR_IMR_TXDESC;
|
||||
if (ah->txerr_interrupt_mask)
|
||||
mask |= AR_IMR_TXERR;
|
||||
if (ah->txeol_interrupt_mask)
|
||||
mask |= AR_IMR_TXEOL;
|
||||
}
|
||||
if (ints & ATH9K_INT_RX) {
|
||||
if (AR_SREV_9300_20_OR_LATER(ah)) {
|
||||
mask |= AR_IMR_RXERR | AR_IMR_RXOK_HP;
|
||||
if (ah->config.rx_intr_mitigation) {
|
||||
mask &= ~AR_IMR_RXOK_LP;
|
||||
mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
|
||||
} else {
|
||||
mask |= AR_IMR_RXOK_LP;
|
||||
}
|
||||
} else {
|
||||
if (ah->config.rx_intr_mitigation)
|
||||
mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
|
||||
else
|
||||
mask |= AR_IMR_RXOK | AR_IMR_RXDESC;
|
||||
}
|
||||
if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
|
||||
mask |= AR_IMR_GENTMR;
|
||||
}
|
||||
|
||||
if (ints & (ATH9K_INT_BMISC)) {
|
||||
mask |= AR_IMR_BCNMISC;
|
||||
if (ints & ATH9K_INT_TIM)
|
||||
mask2 |= AR_IMR_S2_TIM;
|
||||
if (ints & ATH9K_INT_DTIM)
|
||||
mask2 |= AR_IMR_S2_DTIM;
|
||||
if (ints & ATH9K_INT_DTIMSYNC)
|
||||
mask2 |= AR_IMR_S2_DTIMSYNC;
|
||||
if (ints & ATH9K_INT_CABEND)
|
||||
mask2 |= AR_IMR_S2_CABEND;
|
||||
if (ints & ATH9K_INT_TSFOOR)
|
||||
mask2 |= AR_IMR_S2_TSFOOR;
|
||||
}
|
||||
|
||||
if (ints & (ATH9K_INT_GTT | ATH9K_INT_CST)) {
|
||||
mask |= AR_IMR_BCNMISC;
|
||||
if (ints & ATH9K_INT_GTT)
|
||||
mask2 |= AR_IMR_S2_GTT;
|
||||
if (ints & ATH9K_INT_CST)
|
||||
mask2 |= AR_IMR_S2_CST;
|
||||
}
|
||||
|
||||
ath_print(common, ATH_DBG_INTERRUPT, "new IMR 0x%x\n", mask);
|
||||
REG_WRITE(ah, AR_IMR, mask);
|
||||
ah->imrs2_reg &= ~(AR_IMR_S2_TIM | AR_IMR_S2_DTIM | AR_IMR_S2_DTIMSYNC |
|
||||
AR_IMR_S2_CABEND | AR_IMR_S2_CABTO |
|
||||
AR_IMR_S2_TSFOOR | AR_IMR_S2_GTT | AR_IMR_S2_CST);
|
||||
ah->imrs2_reg |= mask2;
|
||||
REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg);
|
||||
|
||||
if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
|
||||
if (ints & ATH9K_INT_TIM_TIMER)
|
||||
REG_SET_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
|
||||
else
|
||||
REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
|
||||
}
|
||||
|
||||
if (ints & ATH9K_INT_GLOBAL) {
|
||||
ath_print(common, ATH_DBG_INTERRUPT, "enable IER\n");
|
||||
REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
|
||||
if (!AR_SREV_9100(ah)) {
|
||||
REG_WRITE(ah, AR_INTR_ASYNC_ENABLE,
|
||||
AR_INTR_MAC_IRQ);
|
||||
REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
|
||||
|
||||
|
||||
REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
|
||||
AR_INTR_SYNC_DEFAULT);
|
||||
REG_WRITE(ah, AR_INTR_SYNC_MASK,
|
||||
AR_INTR_SYNC_DEFAULT);
|
||||
}
|
||||
ath_print(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
|
||||
REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
|
||||
}
|
||||
|
||||
return omask;
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_set_interrupts);
|
||||
|
@ -37,6 +37,8 @@
|
||||
AR_2040_##_index : 0) \
|
||||
|((_series)[_index].RateFlags & ATH9K_RATESERIES_HALFGI ? \
|
||||
AR_GI##_index : 0) \
|
||||
|((_series)[_index].RateFlags & ATH9K_RATESERIES_STBC ? \
|
||||
AR_STBC##_index : 0) \
|
||||
|SM((_series)[_index].ChSel, AR_ChainSel##_index))
|
||||
|
||||
#define CCK_SIFS_TIME 10
|
||||
@ -86,7 +88,6 @@
|
||||
#define ATH9K_TX_DESC_CFG_ERR 0x04
|
||||
#define ATH9K_TX_DATA_UNDERRUN 0x08
|
||||
#define ATH9K_TX_DELIM_UNDERRUN 0x10
|
||||
#define ATH9K_TX_SW_ABORTED 0x40
|
||||
#define ATH9K_TX_SW_FILTERED 0x80
|
||||
|
||||
/* 64 bytes */
|
||||
@ -117,7 +118,10 @@ struct ath_tx_status {
|
||||
int8_t ts_rssi_ext0;
|
||||
int8_t ts_rssi_ext1;
|
||||
int8_t ts_rssi_ext2;
|
||||
u8 pad[3];
|
||||
u8 qid;
|
||||
u16 desc_id;
|
||||
u8 tid;
|
||||
u8 pad[2];
|
||||
u32 ba_low;
|
||||
u32 ba_high;
|
||||
u32 evm0;
|
||||
@ -148,11 +152,13 @@ struct ath_rx_status {
|
||||
u32 evm0;
|
||||
u32 evm1;
|
||||
u32 evm2;
|
||||
u32 evm3;
|
||||
u32 evm4;
|
||||
};
|
||||
|
||||
struct ath_htc_rx_status {
|
||||
u64 rs_tstamp;
|
||||
u16 rs_datalen;
|
||||
__be64 rs_tstamp;
|
||||
__be16 rs_datalen;
|
||||
u8 rs_status;
|
||||
u8 rs_phyerr;
|
||||
int8_t rs_rssi;
|
||||
@ -171,9 +177,9 @@ struct ath_htc_rx_status {
|
||||
u8 rs_num_delims;
|
||||
u8 rs_flags;
|
||||
u8 rs_dummy;
|
||||
u32 evm0;
|
||||
u32 evm1;
|
||||
u32 evm2;
|
||||
__be32 evm0;
|
||||
__be32 evm1;
|
||||
__be32 evm2;
|
||||
};
|
||||
|
||||
#define ATH9K_RXERR_CRC 0x01
|
||||
@ -259,7 +265,8 @@ struct ath_desc {
|
||||
#define ATH9K_TXDESC_EXT_AND_CTL 0x0080
|
||||
#define ATH9K_TXDESC_VMF 0x0100
|
||||
#define ATH9K_TXDESC_FRAG_IS_ON 0x0200
|
||||
#define ATH9K_TXDESC_CAB 0x0400
|
||||
#define ATH9K_TXDESC_LOWRXCHAIN 0x0400
|
||||
#define ATH9K_TXDESC_LDPC 0x00010000
|
||||
|
||||
#define ATH9K_RXDESC_INTREQ 0x0020
|
||||
|
||||
@ -353,7 +360,6 @@ struct ar5416_desc {
|
||||
#define AR_DestIdxValid 0x40000000
|
||||
#define AR_CTSEnable 0x80000000
|
||||
|
||||
#define AR_BufLen 0x00000fff
|
||||
#define AR_TxMore 0x00001000
|
||||
#define AR_DestIdx 0x000fe000
|
||||
#define AR_DestIdx_S 13
|
||||
@ -410,6 +416,7 @@ struct ar5416_desc {
|
||||
#define AR_EncrType 0x0c000000
|
||||
#define AR_EncrType_S 26
|
||||
#define AR_TxCtlRsvd61 0xf0000000
|
||||
#define AR_LDPC 0x80000000
|
||||
|
||||
#define AR_2040_0 0x00000001
|
||||
#define AR_GI0 0x00000002
|
||||
@ -429,7 +436,10 @@ struct ar5416_desc {
|
||||
#define AR_ChainSel3_S 17
|
||||
#define AR_RTSCTSRate 0x0ff00000
|
||||
#define AR_RTSCTSRate_S 20
|
||||
#define AR_TxCtlRsvd70 0xf0000000
|
||||
#define AR_STBC0 0x10000000
|
||||
#define AR_STBC1 0x20000000
|
||||
#define AR_STBC2 0x40000000
|
||||
#define AR_STBC3 0x80000000
|
||||
|
||||
#define AR_TxRSSIAnt00 0x000000ff
|
||||
#define AR_TxRSSIAnt00_S 0
|
||||
@ -493,7 +503,6 @@ struct ar5416_desc {
|
||||
|
||||
#define AR_RxCTLRsvd00 0xffffffff
|
||||
|
||||
#define AR_BufLen 0x00000fff
|
||||
#define AR_RxCtlRsvd00 0x00001000
|
||||
#define AR_RxIntrReq 0x00002000
|
||||
#define AR_RxCtlRsvd01 0xffffc000
|
||||
@ -643,6 +652,7 @@ enum ath9k_rx_filter {
|
||||
#define ATH9K_RATESERIES_RTS_CTS 0x0001
|
||||
#define ATH9K_RATESERIES_2040 0x0002
|
||||
#define ATH9K_RATESERIES_HALFGI 0x0004
|
||||
#define ATH9K_RATESERIES_STBC 0x0008
|
||||
|
||||
struct ath9k_11n_rate_series {
|
||||
u32 Tries;
|
||||
@ -686,34 +696,10 @@ struct ath9k_channel;
|
||||
u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q);
|
||||
void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp);
|
||||
void ath9k_hw_txstart(struct ath_hw *ah, u32 q);
|
||||
void ath9k_hw_cleartxdesc(struct ath_hw *ah, void *ds);
|
||||
u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q);
|
||||
bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel);
|
||||
bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q);
|
||||
void ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
|
||||
u32 segLen, bool firstSeg,
|
||||
bool lastSeg, const struct ath_desc *ds0);
|
||||
void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds);
|
||||
int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds,
|
||||
struct ath_tx_status *ts);
|
||||
void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds,
|
||||
u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
|
||||
u32 keyIx, enum ath9k_key_type keyType, u32 flags);
|
||||
void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, struct ath_desc *ds,
|
||||
struct ath_desc *lastds,
|
||||
u32 durUpdateEn, u32 rtsctsRate,
|
||||
u32 rtsctsDuration,
|
||||
struct ath9k_11n_rate_series series[],
|
||||
u32 nseries, u32 flags);
|
||||
void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, struct ath_desc *ds,
|
||||
u32 aggrLen);
|
||||
void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, struct ath_desc *ds,
|
||||
u32 numDelims);
|
||||
void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, struct ath_desc *ds);
|
||||
void ath9k_hw_clr11n_aggr(struct ath_hw *ah, struct ath_desc *ds);
|
||||
void ath9k_hw_set11n_burstduration(struct ath_hw *ah, struct ath_desc *ds,
|
||||
u32 burstDuration);
|
||||
void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, struct ath_desc *ds,
|
||||
u32 vmf);
|
||||
void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs);
|
||||
bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
|
||||
const struct ath9k_tx_queue_info *qinfo);
|
||||
@ -729,10 +715,17 @@ void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
|
||||
u32 size, u32 flags);
|
||||
bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set);
|
||||
void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp);
|
||||
void ath9k_hw_rxena(struct ath_hw *ah);
|
||||
void ath9k_hw_startpcureceive(struct ath_hw *ah);
|
||||
void ath9k_hw_stoppcurecv(struct ath_hw *ah);
|
||||
void ath9k_hw_abortpcurecv(struct ath_hw *ah);
|
||||
bool ath9k_hw_stopdmarecv(struct ath_hw *ah);
|
||||
int ath9k_hw_beaconq_setup(struct ath_hw *ah);
|
||||
|
||||
/* Interrupt Handling */
|
||||
bool ath9k_hw_intrpend(struct ath_hw *ah);
|
||||
enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah,
|
||||
enum ath9k_int ints);
|
||||
|
||||
void ar9002_hw_attach_mac_ops(struct ath_hw *ah);
|
||||
|
||||
#endif /* MAC_H */
|
||||
|
@ -401,23 +401,41 @@ void ath9k_tasklet(unsigned long data)
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
|
||||
u32 status = sc->intrstatus;
|
||||
u32 rxmask;
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
|
||||
if (status & ATH9K_INT_FATAL) {
|
||||
if ((status & ATH9K_INT_FATAL) ||
|
||||
!ath9k_hw_check_alive(ah)) {
|
||||
ath_reset(sc, false);
|
||||
ath9k_ps_restore(sc);
|
||||
return;
|
||||
}
|
||||
|
||||
if (status & (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN)) {
|
||||
if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
|
||||
rxmask = (ATH9K_INT_RXHP | ATH9K_INT_RXLP | ATH9K_INT_RXEOL |
|
||||
ATH9K_INT_RXORN);
|
||||
else
|
||||
rxmask = (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
|
||||
|
||||
if (status & rxmask) {
|
||||
spin_lock_bh(&sc->rx.rxflushlock);
|
||||
ath_rx_tasklet(sc, 0);
|
||||
|
||||
/* Check for high priority Rx first */
|
||||
if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) &&
|
||||
(status & ATH9K_INT_RXHP))
|
||||
ath_rx_tasklet(sc, 0, true);
|
||||
|
||||
ath_rx_tasklet(sc, 0, false);
|
||||
spin_unlock_bh(&sc->rx.rxflushlock);
|
||||
}
|
||||
|
||||
if (status & ATH9K_INT_TX)
|
||||
ath_tx_tasklet(sc);
|
||||
if (status & ATH9K_INT_TX) {
|
||||
if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
|
||||
ath_tx_edma_tasklet(sc);
|
||||
else
|
||||
ath_tx_tasklet(sc);
|
||||
}
|
||||
|
||||
if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) {
|
||||
/*
|
||||
@ -445,6 +463,8 @@ irqreturn_t ath_isr(int irq, void *dev)
|
||||
ATH9K_INT_RXORN | \
|
||||
ATH9K_INT_RXEOL | \
|
||||
ATH9K_INT_RX | \
|
||||
ATH9K_INT_RXLP | \
|
||||
ATH9K_INT_RXHP | \
|
||||
ATH9K_INT_TX | \
|
||||
ATH9K_INT_BMISS | \
|
||||
ATH9K_INT_CST | \
|
||||
@ -496,7 +516,8 @@ irqreturn_t ath_isr(int irq, void *dev)
|
||||
* If a FATAL or RXORN interrupt is received, we have to reset the
|
||||
* chip immediately.
|
||||
*/
|
||||
if (status & (ATH9K_INT_FATAL | ATH9K_INT_RXORN))
|
||||
if ((status & ATH9K_INT_FATAL) || ((status & ATH9K_INT_RXORN) &&
|
||||
!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)))
|
||||
goto chip_reset;
|
||||
|
||||
if (status & ATH9K_INT_SWBA)
|
||||
@ -505,6 +526,13 @@ irqreturn_t ath_isr(int irq, void *dev)
|
||||
if (status & ATH9K_INT_TXURN)
|
||||
ath9k_hw_updatetxtriglevel(ah, true);
|
||||
|
||||
if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
|
||||
if (status & ATH9K_INT_RXEOL) {
|
||||
ah->imask &= ~(ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
|
||||
ath9k_hw_set_interrupts(ah, ah->imask);
|
||||
}
|
||||
}
|
||||
|
||||
if (status & ATH9K_INT_MIB) {
|
||||
/*
|
||||
* Disable interrupts until we service the MIB
|
||||
@ -724,6 +752,7 @@ static int ath_key_config(struct ath_common *common,
|
||||
struct ath_hw *ah = common->ah;
|
||||
struct ath9k_keyval hk;
|
||||
const u8 *mac = NULL;
|
||||
u8 gmac[ETH_ALEN];
|
||||
int ret = 0;
|
||||
int idx;
|
||||
|
||||
@ -747,9 +776,30 @@ static int ath_key_config(struct ath_common *common,
|
||||
memcpy(hk.kv_val, key->key, key->keylen);
|
||||
|
||||
if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
|
||||
/* For now, use the default keys for broadcast keys. This may
|
||||
* need to change with virtual interfaces. */
|
||||
idx = key->keyidx;
|
||||
|
||||
if (key->ap_addr) {
|
||||
/*
|
||||
* Group keys on hardware that supports multicast frame
|
||||
* key search use a mac that is the sender's address with
|
||||
* the high bit set instead of the app-specified address.
|
||||
*/
|
||||
memcpy(gmac, key->ap_addr, ETH_ALEN);
|
||||
gmac[0] |= 0x80;
|
||||
mac = gmac;
|
||||
|
||||
if (key->alg == ALG_TKIP)
|
||||
idx = ath_reserve_key_cache_slot_tkip(common);
|
||||
else
|
||||
idx = ath_reserve_key_cache_slot(common);
|
||||
if (idx < 0)
|
||||
mac = NULL; /* no free key cache entries */
|
||||
}
|
||||
|
||||
if (!mac) {
|
||||
/* For now, use the default keys for broadcast keys. This may
|
||||
* need to change with virtual interfaces. */
|
||||
idx = key->keyidx;
|
||||
}
|
||||
} else if (key->keyidx) {
|
||||
if (WARN_ON(!sta))
|
||||
return -EOPNOTSUPP;
|
||||
@ -1162,9 +1212,14 @@ static int ath9k_start(struct ieee80211_hw *hw)
|
||||
}
|
||||
|
||||
/* Setup our intr mask. */
|
||||
ah->imask = ATH9K_INT_RX | ATH9K_INT_TX
|
||||
| ATH9K_INT_RXEOL | ATH9K_INT_RXORN
|
||||
| ATH9K_INT_FATAL | ATH9K_INT_GLOBAL;
|
||||
ah->imask = ATH9K_INT_TX | ATH9K_INT_RXEOL |
|
||||
ATH9K_INT_RXORN | ATH9K_INT_FATAL |
|
||||
ATH9K_INT_GLOBAL;
|
||||
|
||||
if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
|
||||
ah->imask |= ATH9K_INT_RXHP | ATH9K_INT_RXLP;
|
||||
else
|
||||
ah->imask |= ATH9K_INT_RX;
|
||||
|
||||
if (ah->caps.hw_caps & ATH9K_HW_CAP_GTT)
|
||||
ah->imask |= ATH9K_INT_GTT;
|
||||
@ -1436,7 +1491,8 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
|
||||
if ((vif->type == NL80211_IFTYPE_STATION) ||
|
||||
(vif->type == NL80211_IFTYPE_ADHOC) ||
|
||||
(vif->type == NL80211_IFTYPE_MESH_POINT)) {
|
||||
ah->imask |= ATH9K_INT_MIB;
|
||||
if (ah->config.enable_ani)
|
||||
ah->imask |= ATH9K_INT_MIB;
|
||||
ah->imask |= ATH9K_INT_TSFOOR;
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
|
||||
{ PCI_VDEVICE(ATHEROS, 0x002C) }, /* PCI-E 802.11n bonded out */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x0030) }, /* PCI-E AR9300 */
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
|
@ -1,978 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2009 Atheros Communications Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* DOC: Programming Atheros 802.11n analog front end radios
|
||||
*
|
||||
* AR5416 MAC based PCI devices and AR518 MAC based PCI-Express
|
||||
* devices have either an external AR2133 analog front end radio for single
|
||||
* band 2.4 GHz communication or an AR5133 analog front end radio for dual
|
||||
* band 2.4 GHz / 5 GHz communication.
|
||||
*
|
||||
* All devices after the AR5416 and AR5418 family starting with the AR9280
|
||||
* have their analog front radios, MAC/BB and host PCIe/USB interface embedded
|
||||
* into a single-chip and require less programming.
|
||||
*
|
||||
* The following single-chips exist with a respective embedded radio:
|
||||
*
|
||||
* AR9280 - 11n dual-band 2x2 MIMO for PCIe
|
||||
* AR9281 - 11n single-band 1x2 MIMO for PCIe
|
||||
* AR9285 - 11n single-band 1x1 for PCIe
|
||||
* AR9287 - 11n single-band 2x2 MIMO for PCIe
|
||||
*
|
||||
* AR9220 - 11n dual-band 2x2 MIMO for PCI
|
||||
* AR9223 - 11n single-band 2x2 MIMO for PCI
|
||||
*
|
||||
* AR9287 - 11n single-band 1x1 MIMO for USB
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "hw.h"
|
||||
|
||||
/**
|
||||
* ath9k_hw_write_regs - ??
|
||||
*
|
||||
* @ah: atheros hardware structure
|
||||
* @freqIndex:
|
||||
* @regWrites:
|
||||
*
|
||||
* Used for both the chipsets with an external AR2133/AR5133 radios and
|
||||
* single-chip devices.
|
||||
*/
|
||||
void ath9k_hw_write_regs(struct ath_hw *ah, u32 freqIndex, int regWrites)
|
||||
{
|
||||
REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites);
|
||||
}
|
||||
|
||||
/**
|
||||
* ath9k_hw_ar9280_set_channel - set channel on single-chip device
|
||||
* @ah: atheros hardware structure
|
||||
* @chan:
|
||||
*
|
||||
* This is the function to change channel on single-chip devices, that is
|
||||
* all devices after ar9280.
|
||||
*
|
||||
* This function takes the channel value in MHz and sets
|
||||
* hardware channel value. Assumes writes have been enabled to analog bus.
|
||||
*
|
||||
* Actual Expression,
|
||||
*
|
||||
* For 2GHz channel,
|
||||
* Channel Frequency = (3/4) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17)
|
||||
* (freq_ref = 40MHz)
|
||||
*
|
||||
* For 5GHz channel,
|
||||
* Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^10)
|
||||
* (freq_ref = 40MHz/(24>>amodeRefSel))
|
||||
*/
|
||||
int ath9k_hw_ar9280_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
|
||||
{
|
||||
u16 bMode, fracMode, aModeRefSel = 0;
|
||||
u32 freq, ndiv, channelSel = 0, channelFrac = 0, reg32 = 0;
|
||||
struct chan_centers centers;
|
||||
u32 refDivA = 24;
|
||||
|
||||
ath9k_hw_get_channel_centers(ah, chan, ¢ers);
|
||||
freq = centers.synth_center;
|
||||
|
||||
reg32 = REG_READ(ah, AR_PHY_SYNTH_CONTROL);
|
||||
reg32 &= 0xc0000000;
|
||||
|
||||
if (freq < 4800) { /* 2 GHz, fractional mode */
|
||||
u32 txctl;
|
||||
int regWrites = 0;
|
||||
|
||||
bMode = 1;
|
||||
fracMode = 1;
|
||||
aModeRefSel = 0;
|
||||
channelSel = (freq * 0x10000) / 15;
|
||||
|
||||
if (AR_SREV_9287_11_OR_LATER(ah)) {
|
||||
if (freq == 2484) {
|
||||
/* Enable channel spreading for channel 14 */
|
||||
REG_WRITE_ARRAY(&ah->iniCckfirJapan2484,
|
||||
1, regWrites);
|
||||
} else {
|
||||
REG_WRITE_ARRAY(&ah->iniCckfirNormal,
|
||||
1, regWrites);
|
||||
}
|
||||
} else {
|
||||
txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL);
|
||||
if (freq == 2484) {
|
||||
/* Enable channel spreading for channel 14 */
|
||||
REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
|
||||
txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
|
||||
} else {
|
||||
REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
|
||||
txctl &~ AR_PHY_CCK_TX_CTRL_JAPAN);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bMode = 0;
|
||||
fracMode = 0;
|
||||
|
||||
switch(ah->eep_ops->get_eeprom(ah, EEP_FRAC_N_5G)) {
|
||||
case 0:
|
||||
if ((freq % 20) == 0) {
|
||||
aModeRefSel = 3;
|
||||
} else if ((freq % 10) == 0) {
|
||||
aModeRefSel = 2;
|
||||
}
|
||||
if (aModeRefSel)
|
||||
break;
|
||||
case 1:
|
||||
default:
|
||||
aModeRefSel = 0;
|
||||
/*
|
||||
* Enable 2G (fractional) mode for channels
|
||||
* which are 5MHz spaced.
|
||||
*/
|
||||
fracMode = 1;
|
||||
refDivA = 1;
|
||||
channelSel = (freq * 0x8000) / 15;
|
||||
|
||||
/* RefDivA setting */
|
||||
REG_RMW_FIELD(ah, AR_AN_SYNTH9,
|
||||
AR_AN_SYNTH9_REFDIVA, refDivA);
|
||||
|
||||
}
|
||||
|
||||
if (!fracMode) {
|
||||
ndiv = (freq * (refDivA >> aModeRefSel)) / 60;
|
||||
channelSel = ndiv & 0x1ff;
|
||||
channelFrac = (ndiv & 0xfffffe00) * 2;
|
||||
channelSel = (channelSel << 17) | channelFrac;
|
||||
}
|
||||
}
|
||||
|
||||
reg32 = reg32 |
|
||||
(bMode << 29) |
|
||||
(fracMode << 28) | (aModeRefSel << 26) | (channelSel);
|
||||
|
||||
REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32);
|
||||
|
||||
ah->curchan = chan;
|
||||
ah->curchan_rad_index = -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ath9k_hw_9280_spur_mitigate - convert baseband spur frequency
|
||||
* @ah: atheros hardware structure
|
||||
* @chan:
|
||||
*
|
||||
* For single-chip solutions. Converts to baseband spur frequency given the
|
||||
* input channel frequency and compute register settings below.
|
||||
*/
|
||||
void ath9k_hw_9280_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan)
|
||||
{
|
||||
int bb_spur = AR_NO_SPUR;
|
||||
int freq;
|
||||
int bin, cur_bin;
|
||||
int bb_spur_off, spur_subchannel_sd;
|
||||
int spur_freq_sd;
|
||||
int spur_delta_phase;
|
||||
int denominator;
|
||||
int upper, lower, cur_vit_mask;
|
||||
int tmp, newVal;
|
||||
int i;
|
||||
int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
|
||||
AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
|
||||
};
|
||||
int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
|
||||
AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
|
||||
};
|
||||
int inc[4] = { 0, 100, 0, 0 };
|
||||
struct chan_centers centers;
|
||||
|
||||
int8_t mask_m[123];
|
||||
int8_t mask_p[123];
|
||||
int8_t mask_amt;
|
||||
int tmp_mask;
|
||||
int cur_bb_spur;
|
||||
bool is2GHz = IS_CHAN_2GHZ(chan);
|
||||
|
||||
memset(&mask_m, 0, sizeof(int8_t) * 123);
|
||||
memset(&mask_p, 0, sizeof(int8_t) * 123);
|
||||
|
||||
ath9k_hw_get_channel_centers(ah, chan, ¢ers);
|
||||
freq = centers.synth_center;
|
||||
|
||||
ah->config.spurmode = SPUR_ENABLE_EEPROM;
|
||||
for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
|
||||
cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz);
|
||||
|
||||
if (is2GHz)
|
||||
cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ;
|
||||
else
|
||||
cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ;
|
||||
|
||||
if (AR_NO_SPUR == cur_bb_spur)
|
||||
break;
|
||||
cur_bb_spur = cur_bb_spur - freq;
|
||||
|
||||
if (IS_CHAN_HT40(chan)) {
|
||||
if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT40) &&
|
||||
(cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT40)) {
|
||||
bb_spur = cur_bb_spur;
|
||||
break;
|
||||
}
|
||||
} else if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT20) &&
|
||||
(cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT20)) {
|
||||
bb_spur = cur_bb_spur;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (AR_NO_SPUR == bb_spur) {
|
||||
REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
|
||||
AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
|
||||
return;
|
||||
} else {
|
||||
REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
|
||||
AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
|
||||
}
|
||||
|
||||
bin = bb_spur * 320;
|
||||
|
||||
tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
|
||||
|
||||
newVal = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
|
||||
AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
|
||||
AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
|
||||
AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
|
||||
REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), newVal);
|
||||
|
||||
newVal = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
|
||||
AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
|
||||
AR_PHY_SPUR_REG_MASK_RATE_SELECT |
|
||||
AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
|
||||
SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
|
||||
REG_WRITE(ah, AR_PHY_SPUR_REG, newVal);
|
||||
|
||||
if (IS_CHAN_HT40(chan)) {
|
||||
if (bb_spur < 0) {
|
||||
spur_subchannel_sd = 1;
|
||||
bb_spur_off = bb_spur + 10;
|
||||
} else {
|
||||
spur_subchannel_sd = 0;
|
||||
bb_spur_off = bb_spur - 10;
|
||||
}
|
||||
} else {
|
||||
spur_subchannel_sd = 0;
|
||||
bb_spur_off = bb_spur;
|
||||
}
|
||||
|
||||
if (IS_CHAN_HT40(chan))
|
||||
spur_delta_phase =
|
||||
((bb_spur * 262144) /
|
||||
10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
|
||||
else
|
||||
spur_delta_phase =
|
||||
((bb_spur * 524288) /
|
||||
10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
|
||||
|
||||
denominator = IS_CHAN_2GHZ(chan) ? 44 : 40;
|
||||
spur_freq_sd = ((bb_spur_off * 2048) / denominator) & 0x3ff;
|
||||
|
||||
newVal = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
|
||||
SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
|
||||
SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
|
||||
REG_WRITE(ah, AR_PHY_TIMING11, newVal);
|
||||
|
||||
newVal = spur_subchannel_sd << AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S;
|
||||
REG_WRITE(ah, AR_PHY_SFCORR_EXT, newVal);
|
||||
|
||||
cur_bin = -6000;
|
||||
upper = bin + 100;
|
||||
lower = bin - 100;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
int pilot_mask = 0;
|
||||
int chan_mask = 0;
|
||||
int bp = 0;
|
||||
for (bp = 0; bp < 30; bp++) {
|
||||
if ((cur_bin > lower) && (cur_bin < upper)) {
|
||||
pilot_mask = pilot_mask | 0x1 << bp;
|
||||
chan_mask = chan_mask | 0x1 << bp;
|
||||
}
|
||||
cur_bin += 100;
|
||||
}
|
||||
cur_bin += inc[i];
|
||||
REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
|
||||
REG_WRITE(ah, chan_mask_reg[i], chan_mask);
|
||||
}
|
||||
|
||||
cur_vit_mask = 6100;
|
||||
upper = bin + 120;
|
||||
lower = bin - 120;
|
||||
|
||||
for (i = 0; i < 123; i++) {
|
||||
if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
|
||||
|
||||
/* workaround for gcc bug #37014 */
|
||||
volatile int tmp_v = abs(cur_vit_mask - bin);
|
||||
|
||||
if (tmp_v < 75)
|
||||
mask_amt = 1;
|
||||
else
|
||||
mask_amt = 0;
|
||||
if (cur_vit_mask < 0)
|
||||
mask_m[abs(cur_vit_mask / 100)] = mask_amt;
|
||||
else
|
||||
mask_p[cur_vit_mask / 100] = mask_amt;
|
||||
}
|
||||
cur_vit_mask -= 100;
|
||||
}
|
||||
|
||||
tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
|
||||
| (mask_m[48] << 26) | (mask_m[49] << 24)
|
||||
| (mask_m[50] << 22) | (mask_m[51] << 20)
|
||||
| (mask_m[52] << 18) | (mask_m[53] << 16)
|
||||
| (mask_m[54] << 14) | (mask_m[55] << 12)
|
||||
| (mask_m[56] << 10) | (mask_m[57] << 8)
|
||||
| (mask_m[58] << 6) | (mask_m[59] << 4)
|
||||
| (mask_m[60] << 2) | (mask_m[61] << 0);
|
||||
REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
|
||||
REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
|
||||
|
||||
tmp_mask = (mask_m[31] << 28)
|
||||
| (mask_m[32] << 26) | (mask_m[33] << 24)
|
||||
| (mask_m[34] << 22) | (mask_m[35] << 20)
|
||||
| (mask_m[36] << 18) | (mask_m[37] << 16)
|
||||
| (mask_m[48] << 14) | (mask_m[39] << 12)
|
||||
| (mask_m[40] << 10) | (mask_m[41] << 8)
|
||||
| (mask_m[42] << 6) | (mask_m[43] << 4)
|
||||
| (mask_m[44] << 2) | (mask_m[45] << 0);
|
||||
REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
|
||||
REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
|
||||
|
||||
tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
|
||||
| (mask_m[18] << 26) | (mask_m[18] << 24)
|
||||
| (mask_m[20] << 22) | (mask_m[20] << 20)
|
||||
| (mask_m[22] << 18) | (mask_m[22] << 16)
|
||||
| (mask_m[24] << 14) | (mask_m[24] << 12)
|
||||
| (mask_m[25] << 10) | (mask_m[26] << 8)
|
||||
| (mask_m[27] << 6) | (mask_m[28] << 4)
|
||||
| (mask_m[29] << 2) | (mask_m[30] << 0);
|
||||
REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
|
||||
REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
|
||||
|
||||
tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
|
||||
| (mask_m[2] << 26) | (mask_m[3] << 24)
|
||||
| (mask_m[4] << 22) | (mask_m[5] << 20)
|
||||
| (mask_m[6] << 18) | (mask_m[7] << 16)
|
||||
| (mask_m[8] << 14) | (mask_m[9] << 12)
|
||||
| (mask_m[10] << 10) | (mask_m[11] << 8)
|
||||
| (mask_m[12] << 6) | (mask_m[13] << 4)
|
||||
| (mask_m[14] << 2) | (mask_m[15] << 0);
|
||||
REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
|
||||
REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
|
||||
|
||||
tmp_mask = (mask_p[15] << 28)
|
||||
| (mask_p[14] << 26) | (mask_p[13] << 24)
|
||||
| (mask_p[12] << 22) | (mask_p[11] << 20)
|
||||
| (mask_p[10] << 18) | (mask_p[9] << 16)
|
||||
| (mask_p[8] << 14) | (mask_p[7] << 12)
|
||||
| (mask_p[6] << 10) | (mask_p[5] << 8)
|
||||
| (mask_p[4] << 6) | (mask_p[3] << 4)
|
||||
| (mask_p[2] << 2) | (mask_p[1] << 0);
|
||||
REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
|
||||
REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
|
||||
|
||||
tmp_mask = (mask_p[30] << 28)
|
||||
| (mask_p[29] << 26) | (mask_p[28] << 24)
|
||||
| (mask_p[27] << 22) | (mask_p[26] << 20)
|
||||
| (mask_p[25] << 18) | (mask_p[24] << 16)
|
||||
| (mask_p[23] << 14) | (mask_p[22] << 12)
|
||||
| (mask_p[21] << 10) | (mask_p[20] << 8)
|
||||
| (mask_p[19] << 6) | (mask_p[18] << 4)
|
||||
| (mask_p[17] << 2) | (mask_p[16] << 0);
|
||||
REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
|
||||
REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
|
||||
|
||||
tmp_mask = (mask_p[45] << 28)
|
||||
| (mask_p[44] << 26) | (mask_p[43] << 24)
|
||||
| (mask_p[42] << 22) | (mask_p[41] << 20)
|
||||
| (mask_p[40] << 18) | (mask_p[39] << 16)
|
||||
| (mask_p[38] << 14) | (mask_p[37] << 12)
|
||||
| (mask_p[36] << 10) | (mask_p[35] << 8)
|
||||
| (mask_p[34] << 6) | (mask_p[33] << 4)
|
||||
| (mask_p[32] << 2) | (mask_p[31] << 0);
|
||||
REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
|
||||
REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
|
||||
|
||||
tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
|
||||
| (mask_p[59] << 26) | (mask_p[58] << 24)
|
||||
| (mask_p[57] << 22) | (mask_p[56] << 20)
|
||||
| (mask_p[55] << 18) | (mask_p[54] << 16)
|
||||
| (mask_p[53] << 14) | (mask_p[52] << 12)
|
||||
| (mask_p[51] << 10) | (mask_p[50] << 8)
|
||||
| (mask_p[49] << 6) | (mask_p[48] << 4)
|
||||
| (mask_p[47] << 2) | (mask_p[46] << 0);
|
||||
REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
|
||||
REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
|
||||
}
|
||||
|
||||
/* All code below is for non single-chip solutions */
|
||||
|
||||
/**
|
||||
* ath9k_phy_modify_rx_buffer() - perform analog swizzling of parameters
|
||||
* @rfbuf:
|
||||
* @reg32:
|
||||
* @numBits:
|
||||
* @firstBit:
|
||||
* @column:
|
||||
*
|
||||
* Performs analog "swizzling" of parameters into their location.
|
||||
* Used on external AR2133/AR5133 radios.
|
||||
*/
|
||||
static void ath9k_phy_modify_rx_buffer(u32 *rfBuf, u32 reg32,
|
||||
u32 numBits, u32 firstBit,
|
||||
u32 column)
|
||||
{
|
||||
u32 tmp32, mask, arrayEntry, lastBit;
|
||||
int32_t bitPosition, bitsLeft;
|
||||
|
||||
tmp32 = ath9k_hw_reverse_bits(reg32, numBits);
|
||||
arrayEntry = (firstBit - 1) / 8;
|
||||
bitPosition = (firstBit - 1) % 8;
|
||||
bitsLeft = numBits;
|
||||
while (bitsLeft > 0) {
|
||||
lastBit = (bitPosition + bitsLeft > 8) ?
|
||||
8 : bitPosition + bitsLeft;
|
||||
mask = (((1 << lastBit) - 1) ^ ((1 << bitPosition) - 1)) <<
|
||||
(column * 8);
|
||||
rfBuf[arrayEntry] &= ~mask;
|
||||
rfBuf[arrayEntry] |= ((tmp32 << bitPosition) <<
|
||||
(column * 8)) & mask;
|
||||
bitsLeft -= 8 - bitPosition;
|
||||
tmp32 = tmp32 >> (8 - bitPosition);
|
||||
bitPosition = 0;
|
||||
arrayEntry++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Fix on 2.4 GHz band for orientation sensitivity issue by increasing
|
||||
* rf_pwd_icsyndiv.
|
||||
*
|
||||
* Theoretical Rules:
|
||||
* if 2 GHz band
|
||||
* if forceBiasAuto
|
||||
* if synth_freq < 2412
|
||||
* bias = 0
|
||||
* else if 2412 <= synth_freq <= 2422
|
||||
* bias = 1
|
||||
* else // synth_freq > 2422
|
||||
* bias = 2
|
||||
* else if forceBias > 0
|
||||
* bias = forceBias & 7
|
||||
* else
|
||||
* no change, use value from ini file
|
||||
* else
|
||||
* no change, invalid band
|
||||
*
|
||||
* 1st Mod:
|
||||
* 2422 also uses value of 2
|
||||
* <approved>
|
||||
*
|
||||
* 2nd Mod:
|
||||
* Less than 2412 uses value of 0, 2412 and above uses value of 2
|
||||
*/
|
||||
static void ath9k_hw_force_bias(struct ath_hw *ah, u16 synth_freq)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
u32 tmp_reg;
|
||||
int reg_writes = 0;
|
||||
u32 new_bias = 0;
|
||||
|
||||
if (!AR_SREV_5416(ah) || synth_freq >= 3000) {
|
||||
return;
|
||||
}
|
||||
|
||||
BUG_ON(AR_SREV_9280_10_OR_LATER(ah));
|
||||
|
||||
if (synth_freq < 2412)
|
||||
new_bias = 0;
|
||||
else if (synth_freq < 2422)
|
||||
new_bias = 1;
|
||||
else
|
||||
new_bias = 2;
|
||||
|
||||
/* pre-reverse this field */
|
||||
tmp_reg = ath9k_hw_reverse_bits(new_bias, 3);
|
||||
|
||||
ath_print(common, ATH_DBG_CONFIG,
|
||||
"Force rf_pwd_icsyndiv to %1d on %4d\n",
|
||||
new_bias, synth_freq);
|
||||
|
||||
/* swizzle rf_pwd_icsyndiv */
|
||||
ath9k_phy_modify_rx_buffer(ah->analogBank6Data, tmp_reg, 3, 181, 3);
|
||||
|
||||
/* write Bank 6 with new params */
|
||||
REG_WRITE_RF_ARRAY(&ah->iniBank6, ah->analogBank6Data, reg_writes);
|
||||
}
|
||||
|
||||
/**
|
||||
* ath9k_hw_set_channel - tune to a channel on the external AR2133/AR5133 radios
|
||||
* @ah: atheros hardware stucture
|
||||
* @chan:
|
||||
*
|
||||
* For the external AR2133/AR5133 radios, takes the MHz channel value and set
|
||||
* the channel value. Assumes writes enabled to analog bus and bank6 register
|
||||
* cache in ah->analogBank6Data.
|
||||
*/
|
||||
int ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
u32 channelSel = 0;
|
||||
u32 bModeSynth = 0;
|
||||
u32 aModeRefSel = 0;
|
||||
u32 reg32 = 0;
|
||||
u16 freq;
|
||||
struct chan_centers centers;
|
||||
|
||||
ath9k_hw_get_channel_centers(ah, chan, ¢ers);
|
||||
freq = centers.synth_center;
|
||||
|
||||
if (freq < 4800) {
|
||||
u32 txctl;
|
||||
|
||||
if (((freq - 2192) % 5) == 0) {
|
||||
channelSel = ((freq - 672) * 2 - 3040) / 10;
|
||||
bModeSynth = 0;
|
||||
} else if (((freq - 2224) % 5) == 0) {
|
||||
channelSel = ((freq - 704) * 2 - 3040) / 10;
|
||||
bModeSynth = 1;
|
||||
} else {
|
||||
ath_print(common, ATH_DBG_FATAL,
|
||||
"Invalid channel %u MHz\n", freq);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
channelSel = (channelSel << 2) & 0xff;
|
||||
channelSel = ath9k_hw_reverse_bits(channelSel, 8);
|
||||
|
||||
txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL);
|
||||
if (freq == 2484) {
|
||||
|
||||
REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
|
||||
txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
|
||||
} else {
|
||||
REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
|
||||
txctl & ~AR_PHY_CCK_TX_CTRL_JAPAN);
|
||||
}
|
||||
|
||||
} else if ((freq % 20) == 0 && freq >= 5120) {
|
||||
channelSel =
|
||||
ath9k_hw_reverse_bits(((freq - 4800) / 20 << 2), 8);
|
||||
aModeRefSel = ath9k_hw_reverse_bits(1, 2);
|
||||
} else if ((freq % 10) == 0) {
|
||||
channelSel =
|
||||
ath9k_hw_reverse_bits(((freq - 4800) / 10 << 1), 8);
|
||||
if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah))
|
||||
aModeRefSel = ath9k_hw_reverse_bits(2, 2);
|
||||
else
|
||||
aModeRefSel = ath9k_hw_reverse_bits(1, 2);
|
||||
} else if ((freq % 5) == 0) {
|
||||
channelSel = ath9k_hw_reverse_bits((freq - 4800) / 5, 8);
|
||||
aModeRefSel = ath9k_hw_reverse_bits(1, 2);
|
||||
} else {
|
||||
ath_print(common, ATH_DBG_FATAL,
|
||||
"Invalid channel %u MHz\n", freq);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ath9k_hw_force_bias(ah, freq);
|
||||
|
||||
reg32 =
|
||||
(channelSel << 8) | (aModeRefSel << 2) | (bModeSynth << 1) |
|
||||
(1 << 5) | 0x1;
|
||||
|
||||
REG_WRITE(ah, AR_PHY(0x37), reg32);
|
||||
|
||||
ah->curchan = chan;
|
||||
ah->curchan_rad_index = -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ath9k_hw_spur_mitigate - convert baseband spur frequency for external radios
|
||||
* @ah: atheros hardware structure
|
||||
* @chan:
|
||||
*
|
||||
* For non single-chip solutions. Converts to baseband spur frequency given the
|
||||
* input channel frequency and compute register settings below.
|
||||
*/
|
||||
void ath9k_hw_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan)
|
||||
{
|
||||
int bb_spur = AR_NO_SPUR;
|
||||
int bin, cur_bin;
|
||||
int spur_freq_sd;
|
||||
int spur_delta_phase;
|
||||
int denominator;
|
||||
int upper, lower, cur_vit_mask;
|
||||
int tmp, new;
|
||||
int i;
|
||||
int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
|
||||
AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
|
||||
};
|
||||
int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
|
||||
AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
|
||||
};
|
||||
int inc[4] = { 0, 100, 0, 0 };
|
||||
|
||||
int8_t mask_m[123];
|
||||
int8_t mask_p[123];
|
||||
int8_t mask_amt;
|
||||
int tmp_mask;
|
||||
int cur_bb_spur;
|
||||
bool is2GHz = IS_CHAN_2GHZ(chan);
|
||||
|
||||
memset(&mask_m, 0, sizeof(int8_t) * 123);
|
||||
memset(&mask_p, 0, sizeof(int8_t) * 123);
|
||||
|
||||
for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
|
||||
cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz);
|
||||
if (AR_NO_SPUR == cur_bb_spur)
|
||||
break;
|
||||
cur_bb_spur = cur_bb_spur - (chan->channel * 10);
|
||||
if ((cur_bb_spur > -95) && (cur_bb_spur < 95)) {
|
||||
bb_spur = cur_bb_spur;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (AR_NO_SPUR == bb_spur)
|
||||
return;
|
||||
|
||||
bin = bb_spur * 32;
|
||||
|
||||
tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
|
||||
new = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
|
||||
AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
|
||||
AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
|
||||
AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
|
||||
|
||||
REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), new);
|
||||
|
||||
new = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
|
||||
AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
|
||||
AR_PHY_SPUR_REG_MASK_RATE_SELECT |
|
||||
AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
|
||||
SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
|
||||
REG_WRITE(ah, AR_PHY_SPUR_REG, new);
|
||||
|
||||
spur_delta_phase = ((bb_spur * 524288) / 100) &
|
||||
AR_PHY_TIMING11_SPUR_DELTA_PHASE;
|
||||
|
||||
denominator = IS_CHAN_2GHZ(chan) ? 440 : 400;
|
||||
spur_freq_sd = ((bb_spur * 2048) / denominator) & 0x3ff;
|
||||
|
||||
new = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
|
||||
SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
|
||||
SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
|
||||
REG_WRITE(ah, AR_PHY_TIMING11, new);
|
||||
|
||||
cur_bin = -6000;
|
||||
upper = bin + 100;
|
||||
lower = bin - 100;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
int pilot_mask = 0;
|
||||
int chan_mask = 0;
|
||||
int bp = 0;
|
||||
for (bp = 0; bp < 30; bp++) {
|
||||
if ((cur_bin > lower) && (cur_bin < upper)) {
|
||||
pilot_mask = pilot_mask | 0x1 << bp;
|
||||
chan_mask = chan_mask | 0x1 << bp;
|
||||
}
|
||||
cur_bin += 100;
|
||||
}
|
||||
cur_bin += inc[i];
|
||||
REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
|
||||
REG_WRITE(ah, chan_mask_reg[i], chan_mask);
|
||||
}
|
||||
|
||||
cur_vit_mask = 6100;
|
||||
upper = bin + 120;
|
||||
lower = bin - 120;
|
||||
|
||||
for (i = 0; i < 123; i++) {
|
||||
if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
|
||||
|
||||
/* workaround for gcc bug #37014 */
|
||||
volatile int tmp_v = abs(cur_vit_mask - bin);
|
||||
|
||||
if (tmp_v < 75)
|
||||
mask_amt = 1;
|
||||
else
|
||||
mask_amt = 0;
|
||||
if (cur_vit_mask < 0)
|
||||
mask_m[abs(cur_vit_mask / 100)] = mask_amt;
|
||||
else
|
||||
mask_p[cur_vit_mask / 100] = mask_amt;
|
||||
}
|
||||
cur_vit_mask -= 100;
|
||||
}
|
||||
|
||||
tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
|
||||
| (mask_m[48] << 26) | (mask_m[49] << 24)
|
||||
| (mask_m[50] << 22) | (mask_m[51] << 20)
|
||||
| (mask_m[52] << 18) | (mask_m[53] << 16)
|
||||
| (mask_m[54] << 14) | (mask_m[55] << 12)
|
||||
| (mask_m[56] << 10) | (mask_m[57] << 8)
|
||||
| (mask_m[58] << 6) | (mask_m[59] << 4)
|
||||
| (mask_m[60] << 2) | (mask_m[61] << 0);
|
||||
REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
|
||||
REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
|
||||
|
||||
tmp_mask = (mask_m[31] << 28)
|
||||
| (mask_m[32] << 26) | (mask_m[33] << 24)
|
||||
| (mask_m[34] << 22) | (mask_m[35] << 20)
|
||||
| (mask_m[36] << 18) | (mask_m[37] << 16)
|
||||
| (mask_m[48] << 14) | (mask_m[39] << 12)
|
||||
| (mask_m[40] << 10) | (mask_m[41] << 8)
|
||||
| (mask_m[42] << 6) | (mask_m[43] << 4)
|
||||
| (mask_m[44] << 2) | (mask_m[45] << 0);
|
||||
REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
|
||||
REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
|
||||
|
||||
tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
|
||||
| (mask_m[18] << 26) | (mask_m[18] << 24)
|
||||
| (mask_m[20] << 22) | (mask_m[20] << 20)
|
||||
| (mask_m[22] << 18) | (mask_m[22] << 16)
|
||||
| (mask_m[24] << 14) | (mask_m[24] << 12)
|
||||
| (mask_m[25] << 10) | (mask_m[26] << 8)
|
||||
| (mask_m[27] << 6) | (mask_m[28] << 4)
|
||||
| (mask_m[29] << 2) | (mask_m[30] << 0);
|
||||
REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
|
||||
REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
|
||||
|
||||
tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
|
||||
| (mask_m[2] << 26) | (mask_m[3] << 24)
|
||||
| (mask_m[4] << 22) | (mask_m[5] << 20)
|
||||
| (mask_m[6] << 18) | (mask_m[7] << 16)
|
||||
| (mask_m[8] << 14) | (mask_m[9] << 12)
|
||||
| (mask_m[10] << 10) | (mask_m[11] << 8)
|
||||
| (mask_m[12] << 6) | (mask_m[13] << 4)
|
||||
| (mask_m[14] << 2) | (mask_m[15] << 0);
|
||||
REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
|
||||
REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
|
||||
|
||||
tmp_mask = (mask_p[15] << 28)
|
||||
| (mask_p[14] << 26) | (mask_p[13] << 24)
|
||||
| (mask_p[12] << 22) | (mask_p[11] << 20)
|
||||
| (mask_p[10] << 18) | (mask_p[9] << 16)
|
||||
| (mask_p[8] << 14) | (mask_p[7] << 12)
|
||||
| (mask_p[6] << 10) | (mask_p[5] << 8)
|
||||
| (mask_p[4] << 6) | (mask_p[3] << 4)
|
||||
| (mask_p[2] << 2) | (mask_p[1] << 0);
|
||||
REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
|
||||
REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
|
||||
|
||||
tmp_mask = (mask_p[30] << 28)
|
||||
| (mask_p[29] << 26) | (mask_p[28] << 24)
|
||||
| (mask_p[27] << 22) | (mask_p[26] << 20)
|
||||
| (mask_p[25] << 18) | (mask_p[24] << 16)
|
||||
| (mask_p[23] << 14) | (mask_p[22] << 12)
|
||||
| (mask_p[21] << 10) | (mask_p[20] << 8)
|
||||
| (mask_p[19] << 6) | (mask_p[18] << 4)
|
||||
| (mask_p[17] << 2) | (mask_p[16] << 0);
|
||||
REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
|
||||
REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
|
||||
|
||||
tmp_mask = (mask_p[45] << 28)
|
||||
| (mask_p[44] << 26) | (mask_p[43] << 24)
|
||||
| (mask_p[42] << 22) | (mask_p[41] << 20)
|
||||
| (mask_p[40] << 18) | (mask_p[39] << 16)
|
||||
| (mask_p[38] << 14) | (mask_p[37] << 12)
|
||||
| (mask_p[36] << 10) | (mask_p[35] << 8)
|
||||
| (mask_p[34] << 6) | (mask_p[33] << 4)
|
||||
| (mask_p[32] << 2) | (mask_p[31] << 0);
|
||||
REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
|
||||
REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
|
||||
|
||||
tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
|
||||
| (mask_p[59] << 26) | (mask_p[58] << 24)
|
||||
| (mask_p[57] << 22) | (mask_p[56] << 20)
|
||||
| (mask_p[55] << 18) | (mask_p[54] << 16)
|
||||
| (mask_p[53] << 14) | (mask_p[52] << 12)
|
||||
| (mask_p[51] << 10) | (mask_p[50] << 8)
|
||||
| (mask_p[49] << 6) | (mask_p[48] << 4)
|
||||
| (mask_p[47] << 2) | (mask_p[46] << 0);
|
||||
REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
|
||||
REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* ath9k_hw_rf_alloc_ext_banks - allocates banks for external radio programming
|
||||
* @ah: atheros hardware structure
|
||||
*
|
||||
* Only required for older devices with external AR2133/AR5133 radios.
|
||||
*/
|
||||
int ath9k_hw_rf_alloc_ext_banks(struct ath_hw *ah)
|
||||
{
|
||||
#define ATH_ALLOC_BANK(bank, size) do { \
|
||||
bank = kzalloc((sizeof(u32) * size), GFP_KERNEL); \
|
||||
if (!bank) { \
|
||||
ath_print(common, ATH_DBG_FATAL, \
|
||||
"Cannot allocate RF banks\n"); \
|
||||
return -ENOMEM; \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
|
||||
BUG_ON(AR_SREV_9280_10_OR_LATER(ah));
|
||||
|
||||
ATH_ALLOC_BANK(ah->analogBank0Data, ah->iniBank0.ia_rows);
|
||||
ATH_ALLOC_BANK(ah->analogBank1Data, ah->iniBank1.ia_rows);
|
||||
ATH_ALLOC_BANK(ah->analogBank2Data, ah->iniBank2.ia_rows);
|
||||
ATH_ALLOC_BANK(ah->analogBank3Data, ah->iniBank3.ia_rows);
|
||||
ATH_ALLOC_BANK(ah->analogBank6Data, ah->iniBank6.ia_rows);
|
||||
ATH_ALLOC_BANK(ah->analogBank6TPCData, ah->iniBank6TPC.ia_rows);
|
||||
ATH_ALLOC_BANK(ah->analogBank7Data, ah->iniBank7.ia_rows);
|
||||
ATH_ALLOC_BANK(ah->addac5416_21,
|
||||
ah->iniAddac.ia_rows * ah->iniAddac.ia_columns);
|
||||
ATH_ALLOC_BANK(ah->bank6Temp, ah->iniBank6.ia_rows);
|
||||
|
||||
return 0;
|
||||
#undef ATH_ALLOC_BANK
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ath9k_hw_rf_free_ext_banks - Free memory for analog bank scratch buffers
|
||||
* @ah: atheros hardware struture
|
||||
* For the external AR2133/AR5133 radios banks.
|
||||
*/
|
||||
void
|
||||
ath9k_hw_rf_free_ext_banks(struct ath_hw *ah)
|
||||
{
|
||||
#define ATH_FREE_BANK(bank) do { \
|
||||
kfree(bank); \
|
||||
bank = NULL; \
|
||||
} while (0);
|
||||
|
||||
BUG_ON(AR_SREV_9280_10_OR_LATER(ah));
|
||||
|
||||
ATH_FREE_BANK(ah->analogBank0Data);
|
||||
ATH_FREE_BANK(ah->analogBank1Data);
|
||||
ATH_FREE_BANK(ah->analogBank2Data);
|
||||
ATH_FREE_BANK(ah->analogBank3Data);
|
||||
ATH_FREE_BANK(ah->analogBank6Data);
|
||||
ATH_FREE_BANK(ah->analogBank6TPCData);
|
||||
ATH_FREE_BANK(ah->analogBank7Data);
|
||||
ATH_FREE_BANK(ah->addac5416_21);
|
||||
ATH_FREE_BANK(ah->bank6Temp);
|
||||
|
||||
#undef ATH_FREE_BANK
|
||||
}
|
||||
|
||||
/* *
|
||||
* ath9k_hw_set_rf_regs - programs rf registers based on EEPROM
|
||||
* @ah: atheros hardware structure
|
||||
* @chan:
|
||||
* @modesIndex:
|
||||
*
|
||||
* Used for the external AR2133/AR5133 radios.
|
||||
*
|
||||
* Reads the EEPROM header info from the device structure and programs
|
||||
* all rf registers. This routine requires access to the analog
|
||||
* rf device. This is not required for single-chip devices.
|
||||
*/
|
||||
bool ath9k_hw_set_rf_regs(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
u16 modesIndex)
|
||||
{
|
||||
u32 eepMinorRev;
|
||||
u32 ob5GHz = 0, db5GHz = 0;
|
||||
u32 ob2GHz = 0, db2GHz = 0;
|
||||
int regWrites = 0;
|
||||
|
||||
/*
|
||||
* Software does not need to program bank data
|
||||
* for single chip devices, that is AR9280 or anything
|
||||
* after that.
|
||||
*/
|
||||
if (AR_SREV_9280_10_OR_LATER(ah))
|
||||
return true;
|
||||
|
||||
/* Setup rf parameters */
|
||||
eepMinorRev = ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV);
|
||||
|
||||
/* Setup Bank 0 Write */
|
||||
RF_BANK_SETUP(ah->analogBank0Data, &ah->iniBank0, 1);
|
||||
|
||||
/* Setup Bank 1 Write */
|
||||
RF_BANK_SETUP(ah->analogBank1Data, &ah->iniBank1, 1);
|
||||
|
||||
/* Setup Bank 2 Write */
|
||||
RF_BANK_SETUP(ah->analogBank2Data, &ah->iniBank2, 1);
|
||||
|
||||
/* Setup Bank 6 Write */
|
||||
RF_BANK_SETUP(ah->analogBank3Data, &ah->iniBank3,
|
||||
modesIndex);
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < ah->iniBank6TPC.ia_rows; i++) {
|
||||
ah->analogBank6Data[i] =
|
||||
INI_RA(&ah->iniBank6TPC, i, modesIndex);
|
||||
}
|
||||
}
|
||||
|
||||
/* Only the 5 or 2 GHz OB/DB need to be set for a mode */
|
||||
if (eepMinorRev >= 2) {
|
||||
if (IS_CHAN_2GHZ(chan)) {
|
||||
ob2GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_2);
|
||||
db2GHz = ah->eep_ops->get_eeprom(ah, EEP_DB_2);
|
||||
ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
|
||||
ob2GHz, 3, 197, 0);
|
||||
ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
|
||||
db2GHz, 3, 194, 0);
|
||||
} else {
|
||||
ob5GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_5);
|
||||
db5GHz = ah->eep_ops->get_eeprom(ah, EEP_DB_5);
|
||||
ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
|
||||
ob5GHz, 3, 203, 0);
|
||||
ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
|
||||
db5GHz, 3, 200, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Setup Bank 7 Setup */
|
||||
RF_BANK_SETUP(ah->analogBank7Data, &ah->iniBank7, 1);
|
||||
|
||||
/* Write Analog registers */
|
||||
REG_WRITE_RF_ARRAY(&ah->iniBank0, ah->analogBank0Data,
|
||||
regWrites);
|
||||
REG_WRITE_RF_ARRAY(&ah->iniBank1, ah->analogBank1Data,
|
||||
regWrites);
|
||||
REG_WRITE_RF_ARRAY(&ah->iniBank2, ah->analogBank2Data,
|
||||
regWrites);
|
||||
REG_WRITE_RF_ARRAY(&ah->iniBank3, ah->analogBank3Data,
|
||||
regWrites);
|
||||
REG_WRITE_RF_ARRAY(&ah->iniBank6TPC, ah->analogBank6Data,
|
||||
regWrites);
|
||||
REG_WRITE_RF_ARRAY(&ah->iniBank7, ah->analogBank7Data,
|
||||
regWrites);
|
||||
|
||||
return true;
|
||||
}
|
@ -17,504 +17,15 @@
|
||||
#ifndef PHY_H
|
||||
#define PHY_H
|
||||
|
||||
/* Common between single chip and non single-chip solutions */
|
||||
void ath9k_hw_write_regs(struct ath_hw *ah, u32 freqIndex, int regWrites);
|
||||
|
||||
/* Single chip radio settings */
|
||||
int ath9k_hw_ar9280_set_channel(struct ath_hw *ah, struct ath9k_channel *chan);
|
||||
void ath9k_hw_9280_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan);
|
||||
|
||||
/* Routines below are for non single-chip solutions */
|
||||
int ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan);
|
||||
void ath9k_hw_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan);
|
||||
|
||||
int ath9k_hw_rf_alloc_ext_banks(struct ath_hw *ah);
|
||||
void ath9k_hw_rf_free_ext_banks(struct ath_hw *ah);
|
||||
|
||||
bool ath9k_hw_set_rf_regs(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan,
|
||||
u16 modesIndex);
|
||||
#define CHANSEL_DIV 15
|
||||
#define CHANSEL_2G(_freq) (((_freq) * 0x10000) / CHANSEL_DIV)
|
||||
#define CHANSEL_5G(_freq) (((_freq) * 0x8000) / CHANSEL_DIV)
|
||||
|
||||
#define AR_PHY_BASE 0x9800
|
||||
#define AR_PHY(_n) (AR_PHY_BASE + ((_n)<<2))
|
||||
|
||||
#define AR_PHY_TEST 0x9800
|
||||
#define PHY_AGC_CLR 0x10000000
|
||||
#define RFSILENT_BB 0x00002000
|
||||
|
||||
#define AR_PHY_TURBO 0x9804
|
||||
#define AR_PHY_FC_TURBO_MODE 0x00000001
|
||||
#define AR_PHY_FC_TURBO_SHORT 0x00000002
|
||||
#define AR_PHY_FC_DYN2040_EN 0x00000004
|
||||
#define AR_PHY_FC_DYN2040_PRI_ONLY 0x00000008
|
||||
#define AR_PHY_FC_DYN2040_PRI_CH 0x00000010
|
||||
/* For 25 MHz channel spacing -- not used but supported by hw */
|
||||
#define AR_PHY_FC_DYN2040_EXT_CH 0x00000020
|
||||
#define AR_PHY_FC_HT_EN 0x00000040
|
||||
#define AR_PHY_FC_SHORT_GI_40 0x00000080
|
||||
#define AR_PHY_FC_WALSH 0x00000100
|
||||
#define AR_PHY_FC_SINGLE_HT_LTF1 0x00000200
|
||||
#define AR_PHY_FC_ENABLE_DAC_FIFO 0x00000800
|
||||
|
||||
#define AR_PHY_TEST2 0x9808
|
||||
|
||||
#define AR_PHY_TIMING2 0x9810
|
||||
#define AR_PHY_TIMING3 0x9814
|
||||
#define AR_PHY_TIMING3_DSC_MAN 0xFFFE0000
|
||||
#define AR_PHY_TIMING3_DSC_MAN_S 17
|
||||
#define AR_PHY_TIMING3_DSC_EXP 0x0001E000
|
||||
#define AR_PHY_TIMING3_DSC_EXP_S 13
|
||||
|
||||
#define AR_PHY_CHIP_ID 0x9818
|
||||
#define AR_PHY_CHIP_ID_REV_0 0x80
|
||||
#define AR_PHY_CHIP_ID_REV_1 0x81
|
||||
#define AR_PHY_CHIP_ID_9160_REV_0 0xb0
|
||||
|
||||
#define AR_PHY_ACTIVE 0x981C
|
||||
#define AR_PHY_ACTIVE_EN 0x00000001
|
||||
#define AR_PHY_ACTIVE_DIS 0x00000000
|
||||
|
||||
#define AR_PHY_RF_CTL2 0x9824
|
||||
#define AR_PHY_TX_END_DATA_START 0x000000FF
|
||||
#define AR_PHY_TX_END_DATA_START_S 0
|
||||
#define AR_PHY_TX_END_PA_ON 0x0000FF00
|
||||
#define AR_PHY_TX_END_PA_ON_S 8
|
||||
|
||||
#define AR_PHY_RF_CTL3 0x9828
|
||||
#define AR_PHY_TX_END_TO_A2_RX_ON 0x00FF0000
|
||||
#define AR_PHY_TX_END_TO_A2_RX_ON_S 16
|
||||
|
||||
#define AR_PHY_ADC_CTL 0x982C
|
||||
#define AR_PHY_ADC_CTL_OFF_INBUFGAIN 0x00000003
|
||||
#define AR_PHY_ADC_CTL_OFF_INBUFGAIN_S 0
|
||||
#define AR_PHY_ADC_CTL_OFF_PWDDAC 0x00002000
|
||||
#define AR_PHY_ADC_CTL_OFF_PWDBANDGAP 0x00004000
|
||||
#define AR_PHY_ADC_CTL_OFF_PWDADC 0x00008000
|
||||
#define AR_PHY_ADC_CTL_ON_INBUFGAIN 0x00030000
|
||||
#define AR_PHY_ADC_CTL_ON_INBUFGAIN_S 16
|
||||
|
||||
#define AR_PHY_ADC_SERIAL_CTL 0x9830
|
||||
#define AR_PHY_SEL_INTERNAL_ADDAC 0x00000000
|
||||
#define AR_PHY_SEL_EXTERNAL_RADIO 0x00000001
|
||||
|
||||
#define AR_PHY_RF_CTL4 0x9834
|
||||
#define AR_PHY_RF_CTL4_TX_END_XPAB_OFF 0xFF000000
|
||||
#define AR_PHY_RF_CTL4_TX_END_XPAB_OFF_S 24
|
||||
#define AR_PHY_RF_CTL4_TX_END_XPAA_OFF 0x00FF0000
|
||||
#define AR_PHY_RF_CTL4_TX_END_XPAA_OFF_S 16
|
||||
#define AR_PHY_RF_CTL4_FRAME_XPAB_ON 0x0000FF00
|
||||
#define AR_PHY_RF_CTL4_FRAME_XPAB_ON_S 8
|
||||
#define AR_PHY_RF_CTL4_FRAME_XPAA_ON 0x000000FF
|
||||
#define AR_PHY_RF_CTL4_FRAME_XPAA_ON_S 0
|
||||
|
||||
#define AR_PHY_TSTDAC_CONST 0x983c
|
||||
|
||||
#define AR_PHY_SETTLING 0x9844
|
||||
#define AR_PHY_SETTLING_SWITCH 0x00003F80
|
||||
#define AR_PHY_SETTLING_SWITCH_S 7
|
||||
|
||||
#define AR_PHY_RXGAIN 0x9848
|
||||
#define AR_PHY_RXGAIN_TXRX_ATTEN 0x0003F000
|
||||
#define AR_PHY_RXGAIN_TXRX_ATTEN_S 12
|
||||
#define AR_PHY_RXGAIN_TXRX_RF_MAX 0x007C0000
|
||||
#define AR_PHY_RXGAIN_TXRX_RF_MAX_S 18
|
||||
#define AR9280_PHY_RXGAIN_TXRX_ATTEN 0x00003F80
|
||||
#define AR9280_PHY_RXGAIN_TXRX_ATTEN_S 7
|
||||
#define AR9280_PHY_RXGAIN_TXRX_MARGIN 0x001FC000
|
||||
#define AR9280_PHY_RXGAIN_TXRX_MARGIN_S 14
|
||||
|
||||
#define AR_PHY_DESIRED_SZ 0x9850
|
||||
#define AR_PHY_DESIRED_SZ_ADC 0x000000FF
|
||||
#define AR_PHY_DESIRED_SZ_ADC_S 0
|
||||
#define AR_PHY_DESIRED_SZ_PGA 0x0000FF00
|
||||
#define AR_PHY_DESIRED_SZ_PGA_S 8
|
||||
#define AR_PHY_DESIRED_SZ_TOT_DES 0x0FF00000
|
||||
#define AR_PHY_DESIRED_SZ_TOT_DES_S 20
|
||||
|
||||
#define AR_PHY_FIND_SIG 0x9858
|
||||
#define AR_PHY_FIND_SIG_FIRSTEP 0x0003F000
|
||||
#define AR_PHY_FIND_SIG_FIRSTEP_S 12
|
||||
#define AR_PHY_FIND_SIG_FIRPWR 0x03FC0000
|
||||
#define AR_PHY_FIND_SIG_FIRPWR_S 18
|
||||
|
||||
#define AR_PHY_AGC_CTL1 0x985C
|
||||
#define AR_PHY_AGC_CTL1_COARSE_LOW 0x00007F80
|
||||
#define AR_PHY_AGC_CTL1_COARSE_LOW_S 7
|
||||
#define AR_PHY_AGC_CTL1_COARSE_HIGH 0x003F8000
|
||||
#define AR_PHY_AGC_CTL1_COARSE_HIGH_S 15
|
||||
|
||||
#define AR_PHY_AGC_CONTROL 0x9860
|
||||
#define AR_PHY_AGC_CONTROL_CAL 0x00000001
|
||||
#define AR_PHY_AGC_CONTROL_NF 0x00000002
|
||||
#define AR_PHY_AGC_CONTROL_ENABLE_NF 0x00008000
|
||||
#define AR_PHY_AGC_CONTROL_FLTR_CAL 0x00010000
|
||||
#define AR_PHY_AGC_CONTROL_NO_UPDATE_NF 0x00020000
|
||||
|
||||
#define AR_PHY_CCA 0x9864
|
||||
#define AR_PHY_MINCCA_PWR 0x0FF80000
|
||||
#define AR_PHY_MINCCA_PWR_S 19
|
||||
#define AR_PHY_CCA_THRESH62 0x0007F000
|
||||
#define AR_PHY_CCA_THRESH62_S 12
|
||||
#define AR9280_PHY_MINCCA_PWR 0x1FF00000
|
||||
#define AR9280_PHY_MINCCA_PWR_S 20
|
||||
#define AR9280_PHY_CCA_THRESH62 0x000FF000
|
||||
#define AR9280_PHY_CCA_THRESH62_S 12
|
||||
|
||||
#define AR_PHY_SFCORR_LOW 0x986C
|
||||
#define AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW 0x00000001
|
||||
#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW 0x00003F00
|
||||
#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW_S 8
|
||||
#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW 0x001FC000
|
||||
#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW_S 14
|
||||
#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW 0x0FE00000
|
||||
#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW_S 21
|
||||
|
||||
#define AR_PHY_SFCORR 0x9868
|
||||
#define AR_PHY_SFCORR_M2COUNT_THR 0x0000001F
|
||||
#define AR_PHY_SFCORR_M2COUNT_THR_S 0
|
||||
#define AR_PHY_SFCORR_M1_THRESH 0x00FE0000
|
||||
#define AR_PHY_SFCORR_M1_THRESH_S 17
|
||||
#define AR_PHY_SFCORR_M2_THRESH 0x7F000000
|
||||
#define AR_PHY_SFCORR_M2_THRESH_S 24
|
||||
|
||||
#define AR_PHY_SLEEP_CTR_CONTROL 0x9870
|
||||
#define AR_PHY_SLEEP_CTR_LIMIT 0x9874
|
||||
#define AR_PHY_SYNTH_CONTROL 0x9874
|
||||
#define AR_PHY_SLEEP_SCAL 0x9878
|
||||
|
||||
#define AR_PHY_PLL_CTL 0x987c
|
||||
#define AR_PHY_PLL_CTL_40 0xaa
|
||||
#define AR_PHY_PLL_CTL_40_5413 0x04
|
||||
#define AR_PHY_PLL_CTL_44 0xab
|
||||
#define AR_PHY_PLL_CTL_44_2133 0xeb
|
||||
#define AR_PHY_PLL_CTL_40_2133 0xea
|
||||
|
||||
#define AR_PHY_SPECTRAL_SCAN 0x9910 /* AR9280 spectral scan configuration register */
|
||||
#define AR_PHY_SPECTRAL_SCAN_ENABLE 0x1
|
||||
#define AR_PHY_SPECTRAL_SCAN_ENA 0x00000001 /* Enable spectral scan, reg 68, bit 0 */
|
||||
#define AR_PHY_SPECTRAL_SCAN_ENA_S 0 /* Enable spectral scan, reg 68, bit 0 */
|
||||
#define AR_PHY_SPECTRAL_SCAN_ACTIVE 0x00000002 /* Activate spectral scan reg 68, bit 1*/
|
||||
#define AR_PHY_SPECTRAL_SCAN_ACTIVE_S 1 /* Activate spectral scan reg 68, bit 1*/
|
||||
#define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD 0x000000F0 /* Interval for FFT reports, reg 68, bits 4-7*/
|
||||
#define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD_S 4
|
||||
#define AR_PHY_SPECTRAL_SCAN_PERIOD 0x0000FF00 /* Interval for FFT reports, reg 68, bits 8-15*/
|
||||
#define AR_PHY_SPECTRAL_SCAN_PERIOD_S 8
|
||||
#define AR_PHY_SPECTRAL_SCAN_COUNT 0x00FF0000 /* Number of reports, reg 68, bits 16-23*/
|
||||
#define AR_PHY_SPECTRAL_SCAN_COUNT_S 16
|
||||
#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT 0x01000000 /* Short repeat, reg 68, bit 24*/
|
||||
#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S 24 /* Short repeat, reg 68, bit 24*/
|
||||
|
||||
#define AR_PHY_RX_DELAY 0x9914
|
||||
#define AR_PHY_SEARCH_START_DELAY 0x9918
|
||||
#define AR_PHY_RX_DELAY_DELAY 0x00003FFF
|
||||
|
||||
#define AR_PHY_TIMING_CTRL4(_i) (0x9920 + ((_i) << 12))
|
||||
#define AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF 0x01F
|
||||
#define AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF_S 0
|
||||
#define AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF 0x7E0
|
||||
#define AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF_S 5
|
||||
#define AR_PHY_TIMING_CTRL4_IQCORR_ENABLE 0x800
|
||||
#define AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX 0xF000
|
||||
#define AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX_S 12
|
||||
#define AR_PHY_TIMING_CTRL4_DO_CAL 0x10000
|
||||
|
||||
#define AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI 0x80000000
|
||||
#define AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER 0x40000000
|
||||
#define AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK 0x20000000
|
||||
#define AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK 0x10000000
|
||||
|
||||
#define AR_PHY_TIMING5 0x9924
|
||||
#define AR_PHY_TIMING5_CYCPWR_THR1 0x000000FE
|
||||
#define AR_PHY_TIMING5_CYCPWR_THR1_S 1
|
||||
|
||||
#define AR_PHY_POWER_TX_RATE1 0x9934
|
||||
#define AR_PHY_POWER_TX_RATE2 0x9938
|
||||
#define AR_PHY_POWER_TX_RATE_MAX 0x993c
|
||||
#define AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE 0x00000040
|
||||
|
||||
#define AR_PHY_FRAME_CTL 0x9944
|
||||
#define AR_PHY_FRAME_CTL_TX_CLIP 0x00000038
|
||||
#define AR_PHY_FRAME_CTL_TX_CLIP_S 3
|
||||
|
||||
#define AR_PHY_TXPWRADJ 0x994C
|
||||
#define AR_PHY_TXPWRADJ_CCK_GAIN_DELTA 0x00000FC0
|
||||
#define AR_PHY_TXPWRADJ_CCK_GAIN_DELTA_S 6
|
||||
#define AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX 0x00FC0000
|
||||
#define AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX_S 18
|
||||
|
||||
#define AR_PHY_RADAR_EXT 0x9940
|
||||
#define AR_PHY_RADAR_EXT_ENA 0x00004000
|
||||
|
||||
#define AR_PHY_RADAR_0 0x9954
|
||||
#define AR_PHY_RADAR_0_ENA 0x00000001
|
||||
#define AR_PHY_RADAR_0_FFT_ENA 0x80000000
|
||||
#define AR_PHY_RADAR_0_INBAND 0x0000003e
|
||||
#define AR_PHY_RADAR_0_INBAND_S 1
|
||||
#define AR_PHY_RADAR_0_PRSSI 0x00000FC0
|
||||
#define AR_PHY_RADAR_0_PRSSI_S 6
|
||||
#define AR_PHY_RADAR_0_HEIGHT 0x0003F000
|
||||
#define AR_PHY_RADAR_0_HEIGHT_S 12
|
||||
#define AR_PHY_RADAR_0_RRSSI 0x00FC0000
|
||||
#define AR_PHY_RADAR_0_RRSSI_S 18
|
||||
#define AR_PHY_RADAR_0_FIRPWR 0x7F000000
|
||||
#define AR_PHY_RADAR_0_FIRPWR_S 24
|
||||
|
||||
#define AR_PHY_RADAR_1 0x9958
|
||||
#define AR_PHY_RADAR_1_RELPWR_ENA 0x00800000
|
||||
#define AR_PHY_RADAR_1_USE_FIR128 0x00400000
|
||||
#define AR_PHY_RADAR_1_RELPWR_THRESH 0x003F0000
|
||||
#define AR_PHY_RADAR_1_RELPWR_THRESH_S 16
|
||||
#define AR_PHY_RADAR_1_BLOCK_CHECK 0x00008000
|
||||
#define AR_PHY_RADAR_1_MAX_RRSSI 0x00004000
|
||||
#define AR_PHY_RADAR_1_RELSTEP_CHECK 0x00002000
|
||||
#define AR_PHY_RADAR_1_RELSTEP_THRESH 0x00001F00
|
||||
#define AR_PHY_RADAR_1_RELSTEP_THRESH_S 8
|
||||
#define AR_PHY_RADAR_1_MAXLEN 0x000000FF
|
||||
#define AR_PHY_RADAR_1_MAXLEN_S 0
|
||||
|
||||
#define AR_PHY_SWITCH_CHAIN_0 0x9960
|
||||
#define AR_PHY_SWITCH_COM 0x9964
|
||||
|
||||
#define AR_PHY_SIGMA_DELTA 0x996C
|
||||
#define AR_PHY_SIGMA_DELTA_ADC_SEL 0x00000003
|
||||
#define AR_PHY_SIGMA_DELTA_ADC_SEL_S 0
|
||||
#define AR_PHY_SIGMA_DELTA_FILT2 0x000000F8
|
||||
#define AR_PHY_SIGMA_DELTA_FILT2_S 3
|
||||
#define AR_PHY_SIGMA_DELTA_FILT1 0x00001F00
|
||||
#define AR_PHY_SIGMA_DELTA_FILT1_S 8
|
||||
#define AR_PHY_SIGMA_DELTA_ADC_CLIP 0x01FFE000
|
||||
#define AR_PHY_SIGMA_DELTA_ADC_CLIP_S 13
|
||||
|
||||
#define AR_PHY_RESTART 0x9970
|
||||
#define AR_PHY_RESTART_DIV_GC 0x001C0000
|
||||
#define AR_PHY_RESTART_DIV_GC_S 18
|
||||
|
||||
#define AR_PHY_RFBUS_REQ 0x997C
|
||||
#define AR_PHY_RFBUS_REQ_EN 0x00000001
|
||||
|
||||
#define AR_PHY_TIMING7 0x9980
|
||||
#define AR_PHY_TIMING8 0x9984
|
||||
#define AR_PHY_TIMING8_PILOT_MASK_2 0x000FFFFF
|
||||
#define AR_PHY_TIMING8_PILOT_MASK_2_S 0
|
||||
|
||||
#define AR_PHY_BIN_MASK2_1 0x9988
|
||||
#define AR_PHY_BIN_MASK2_2 0x998c
|
||||
#define AR_PHY_BIN_MASK2_3 0x9990
|
||||
#define AR_PHY_BIN_MASK2_4 0x9994
|
||||
|
||||
#define AR_PHY_BIN_MASK_1 0x9900
|
||||
#define AR_PHY_BIN_MASK_2 0x9904
|
||||
#define AR_PHY_BIN_MASK_3 0x9908
|
||||
|
||||
#define AR_PHY_MASK_CTL 0x990c
|
||||
|
||||
#define AR_PHY_BIN_MASK2_4_MASK_4 0x00003FFF
|
||||
#define AR_PHY_BIN_MASK2_4_MASK_4_S 0
|
||||
|
||||
#define AR_PHY_TIMING9 0x9998
|
||||
#define AR_PHY_TIMING10 0x999c
|
||||
#define AR_PHY_TIMING10_PILOT_MASK_2 0x000FFFFF
|
||||
#define AR_PHY_TIMING10_PILOT_MASK_2_S 0
|
||||
|
||||
#define AR_PHY_TIMING11 0x99a0
|
||||
#define AR_PHY_TIMING11_SPUR_DELTA_PHASE 0x000FFFFF
|
||||
#define AR_PHY_TIMING11_SPUR_DELTA_PHASE_S 0
|
||||
#define AR_PHY_TIMING11_SPUR_FREQ_SD 0x3FF00000
|
||||
#define AR_PHY_TIMING11_SPUR_FREQ_SD_S 20
|
||||
#define AR_PHY_TIMING11_USE_SPUR_IN_AGC 0x40000000
|
||||
#define AR_PHY_TIMING11_USE_SPUR_IN_SELFCOR 0x80000000
|
||||
|
||||
#define AR_PHY_RX_CHAINMASK 0x99a4
|
||||
#define AR_PHY_NEW_ADC_DC_GAIN_CORR(_i) (0x99b4 + ((_i) << 12))
|
||||
#define AR_PHY_NEW_ADC_GAIN_CORR_ENABLE 0x40000000
|
||||
#define AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE 0x80000000
|
||||
|
||||
#define AR_PHY_MULTICHAIN_GAIN_CTL 0x99ac
|
||||
#define AR_PHY_9285_ANT_DIV_CTL_ALL 0x7f000000
|
||||
#define AR_PHY_9285_ANT_DIV_CTL 0x01000000
|
||||
#define AR_PHY_9285_ANT_DIV_CTL_S 24
|
||||
#define AR_PHY_9285_ANT_DIV_ALT_LNACONF 0x06000000
|
||||
#define AR_PHY_9285_ANT_DIV_ALT_LNACONF_S 25
|
||||
#define AR_PHY_9285_ANT_DIV_MAIN_LNACONF 0x18000000
|
||||
#define AR_PHY_9285_ANT_DIV_MAIN_LNACONF_S 27
|
||||
#define AR_PHY_9285_ANT_DIV_ALT_GAINTB 0x20000000
|
||||
#define AR_PHY_9285_ANT_DIV_ALT_GAINTB_S 29
|
||||
#define AR_PHY_9285_ANT_DIV_MAIN_GAINTB 0x40000000
|
||||
#define AR_PHY_9285_ANT_DIV_MAIN_GAINTB_S 30
|
||||
#define AR_PHY_9285_ANT_DIV_LNA1 2
|
||||
#define AR_PHY_9285_ANT_DIV_LNA2 1
|
||||
#define AR_PHY_9285_ANT_DIV_LNA1_PLUS_LNA2 3
|
||||
#define AR_PHY_9285_ANT_DIV_LNA1_MINUS_LNA2 0
|
||||
#define AR_PHY_9285_ANT_DIV_GAINTB_0 0
|
||||
#define AR_PHY_9285_ANT_DIV_GAINTB_1 1
|
||||
|
||||
#define AR_PHY_EXT_CCA0 0x99b8
|
||||
#define AR_PHY_EXT_CCA0_THRESH62 0x000000FF
|
||||
#define AR_PHY_EXT_CCA0_THRESH62_S 0
|
||||
|
||||
#define AR_PHY_EXT_CCA 0x99bc
|
||||
#define AR_PHY_EXT_CCA_CYCPWR_THR1 0x0000FE00
|
||||
#define AR_PHY_EXT_CCA_CYCPWR_THR1_S 9
|
||||
#define AR_PHY_EXT_CCA_THRESH62 0x007F0000
|
||||
#define AR_PHY_EXT_CCA_THRESH62_S 16
|
||||
#define AR_PHY_EXT_MINCCA_PWR 0xFF800000
|
||||
#define AR_PHY_EXT_MINCCA_PWR_S 23
|
||||
#define AR9280_PHY_EXT_MINCCA_PWR 0x01FF0000
|
||||
#define AR9280_PHY_EXT_MINCCA_PWR_S 16
|
||||
|
||||
#define AR_PHY_SFCORR_EXT 0x99c0
|
||||
#define AR_PHY_SFCORR_EXT_M1_THRESH 0x0000007F
|
||||
#define AR_PHY_SFCORR_EXT_M1_THRESH_S 0
|
||||
#define AR_PHY_SFCORR_EXT_M2_THRESH 0x00003F80
|
||||
#define AR_PHY_SFCORR_EXT_M2_THRESH_S 7
|
||||
#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW 0x001FC000
|
||||
#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW_S 14
|
||||
#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW 0x0FE00000
|
||||
#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW_S 21
|
||||
#define AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S 28
|
||||
|
||||
#define AR_PHY_HALFGI 0x99D0
|
||||
#define AR_PHY_HALFGI_DSC_MAN 0x0007FFF0
|
||||
#define AR_PHY_HALFGI_DSC_MAN_S 4
|
||||
#define AR_PHY_HALFGI_DSC_EXP 0x0000000F
|
||||
#define AR_PHY_HALFGI_DSC_EXP_S 0
|
||||
|
||||
#define AR_PHY_CHAN_INFO_MEMORY 0x99DC
|
||||
#define AR_PHY_CHAN_INFO_MEMORY_CAPTURE_MASK 0x0001
|
||||
|
||||
#define AR_PHY_HEAVY_CLIP_ENABLE 0x99E0
|
||||
|
||||
#define AR_PHY_HEAVY_CLIP_FACTOR_RIFS 0x99EC
|
||||
#define AR_PHY_RIFS_INIT_DELAY 0x03ff0000
|
||||
|
||||
#define AR_PHY_M_SLEEP 0x99f0
|
||||
#define AR_PHY_REFCLKDLY 0x99f4
|
||||
#define AR_PHY_REFCLKPD 0x99f8
|
||||
|
||||
#define AR_PHY_CALMODE 0x99f0
|
||||
|
||||
#define AR_PHY_CALMODE_IQ 0x00000000
|
||||
#define AR_PHY_CALMODE_ADC_GAIN 0x00000001
|
||||
#define AR_PHY_CALMODE_ADC_DC_PER 0x00000002
|
||||
#define AR_PHY_CALMODE_ADC_DC_INIT 0x00000003
|
||||
|
||||
#define AR_PHY_CAL_MEAS_0(_i) (0x9c10 + ((_i) << 12))
|
||||
#define AR_PHY_CAL_MEAS_1(_i) (0x9c14 + ((_i) << 12))
|
||||
#define AR_PHY_CAL_MEAS_2(_i) (0x9c18 + ((_i) << 12))
|
||||
#define AR_PHY_CAL_MEAS_3(_i) (0x9c1c + ((_i) << 12))
|
||||
|
||||
#define AR_PHY_CURRENT_RSSI 0x9c1c
|
||||
#define AR9280_PHY_CURRENT_RSSI 0x9c3c
|
||||
|
||||
#define AR_PHY_RFBUS_GRANT 0x9C20
|
||||
#define AR_PHY_RFBUS_GRANT_EN 0x00000001
|
||||
|
||||
#define AR_PHY_CHAN_INFO_GAIN_DIFF 0x9CF4
|
||||
#define AR_PHY_CHAN_INFO_GAIN_DIFF_UPPER_LIMIT 320
|
||||
|
||||
#define AR_PHY_CHAN_INFO_GAIN 0x9CFC
|
||||
|
||||
#define AR_PHY_MODE 0xA200
|
||||
#define AR_PHY_MODE_ASYNCFIFO 0x80
|
||||
#define AR_PHY_MODE_AR2133 0x08
|
||||
#define AR_PHY_MODE_AR5111 0x00
|
||||
#define AR_PHY_MODE_AR5112 0x08
|
||||
#define AR_PHY_MODE_DYNAMIC 0x04
|
||||
#define AR_PHY_MODE_RF2GHZ 0x02
|
||||
#define AR_PHY_MODE_RF5GHZ 0x00
|
||||
#define AR_PHY_MODE_CCK 0x01
|
||||
#define AR_PHY_MODE_OFDM 0x00
|
||||
#define AR_PHY_MODE_DYN_CCK_DISABLE 0x100
|
||||
|
||||
#define AR_PHY_CCK_TX_CTRL 0xA204
|
||||
#define AR_PHY_CCK_TX_CTRL_JAPAN 0x00000010
|
||||
#define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK 0x0000000C
|
||||
#define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK_S 2
|
||||
|
||||
#define AR_PHY_CCK_DETECT 0xA208
|
||||
#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK 0x0000003F
|
||||
#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_S 0
|
||||
/* [12:6] settling time for antenna switch */
|
||||
#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME 0x00001FC0
|
||||
#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME_S 6
|
||||
#define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV 0x2000
|
||||
#define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV_S 13
|
||||
|
||||
#define AR_PHY_GAIN_2GHZ 0xA20C
|
||||
#define AR_PHY_GAIN_2GHZ_RXTX_MARGIN 0x00FC0000
|
||||
#define AR_PHY_GAIN_2GHZ_RXTX_MARGIN_S 18
|
||||
#define AR_PHY_GAIN_2GHZ_BSW_MARGIN 0x00003C00
|
||||
#define AR_PHY_GAIN_2GHZ_BSW_MARGIN_S 10
|
||||
#define AR_PHY_GAIN_2GHZ_BSW_ATTEN 0x0000001F
|
||||
#define AR_PHY_GAIN_2GHZ_BSW_ATTEN_S 0
|
||||
|
||||
#define AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN 0x003E0000
|
||||
#define AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN_S 17
|
||||
#define AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN 0x0001F000
|
||||
#define AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN_S 12
|
||||
#define AR_PHY_GAIN_2GHZ_XATTEN2_DB 0x00000FC0
|
||||
#define AR_PHY_GAIN_2GHZ_XATTEN2_DB_S 6
|
||||
#define AR_PHY_GAIN_2GHZ_XATTEN1_DB 0x0000003F
|
||||
#define AR_PHY_GAIN_2GHZ_XATTEN1_DB_S 0
|
||||
|
||||
#define AR_PHY_CCK_RXCTRL4 0xA21C
|
||||
#define AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT 0x01F80000
|
||||
#define AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT_S 19
|
||||
|
||||
#define AR_PHY_DAG_CTRLCCK 0xA228
|
||||
#define AR_PHY_DAG_CTRLCCK_EN_RSSI_THR 0x00000200
|
||||
#define AR_PHY_DAG_CTRLCCK_RSSI_THR 0x0001FC00
|
||||
#define AR_PHY_DAG_CTRLCCK_RSSI_THR_S 10
|
||||
|
||||
#define AR_PHY_FORCE_CLKEN_CCK 0xA22C
|
||||
#define AR_PHY_FORCE_CLKEN_CCK_MRC_MUX 0x00000040
|
||||
|
||||
#define AR_PHY_POWER_TX_RATE3 0xA234
|
||||
#define AR_PHY_POWER_TX_RATE4 0xA238
|
||||
|
||||
#define AR_PHY_SCRM_SEQ_XR 0xA23C
|
||||
#define AR_PHY_HEADER_DETECT_XR 0xA240
|
||||
#define AR_PHY_CHIRP_DETECTED_XR 0xA244
|
||||
#define AR_PHY_BLUETOOTH 0xA254
|
||||
|
||||
#define AR_PHY_TPCRG1 0xA258
|
||||
#define AR_PHY_TPCRG1_NUM_PD_GAIN 0x0000c000
|
||||
#define AR_PHY_TPCRG1_NUM_PD_GAIN_S 14
|
||||
|
||||
#define AR_PHY_TPCRG1_PD_GAIN_1 0x00030000
|
||||
#define AR_PHY_TPCRG1_PD_GAIN_1_S 16
|
||||
#define AR_PHY_TPCRG1_PD_GAIN_2 0x000C0000
|
||||
#define AR_PHY_TPCRG1_PD_GAIN_2_S 18
|
||||
#define AR_PHY_TPCRG1_PD_GAIN_3 0x00300000
|
||||
#define AR_PHY_TPCRG1_PD_GAIN_3_S 20
|
||||
|
||||
#define AR_PHY_TPCRG1_PD_CAL_ENABLE 0x00400000
|
||||
#define AR_PHY_TPCRG1_PD_CAL_ENABLE_S 22
|
||||
|
||||
#define AR_PHY_TX_PWRCTRL4 0xa264
|
||||
#define AR_PHY_TX_PWRCTRL_PD_AVG_VALID 0x00000001
|
||||
#define AR_PHY_TX_PWRCTRL_PD_AVG_VALID_S 0
|
||||
#define AR_PHY_TX_PWRCTRL_PD_AVG_OUT 0x000001FE
|
||||
#define AR_PHY_TX_PWRCTRL_PD_AVG_OUT_S 1
|
||||
|
||||
#define AR_PHY_TX_PWRCTRL6_0 0xa270
|
||||
#define AR_PHY_TX_PWRCTRL6_1 0xb270
|
||||
#define AR_PHY_TX_PWRCTRL_ERR_EST_MODE 0x03000000
|
||||
#define AR_PHY_TX_PWRCTRL_ERR_EST_MODE_S 24
|
||||
|
||||
#define AR_PHY_TX_PWRCTRL7 0xa274
|
||||
#define AR_PHY_TX_PWRCTRL_TX_GAIN_TAB_MAX 0x0007E000
|
||||
#define AR_PHY_TX_PWRCTRL_TX_GAIN_TAB_MAX_S 13
|
||||
#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN 0x01F80000
|
||||
#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN_S 19
|
||||
|
||||
#define AR_PHY_TX_PWRCTRL9 0xa27C
|
||||
#define AR_PHY_TX_DESIRED_SCALE_CCK 0x00007C00
|
||||
#define AR_PHY_TX_DESIRED_SCALE_CCK_S 10
|
||||
#define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL 0x80000000
|
||||
#define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL_S 31
|
||||
|
||||
#define AR_PHY_TX_GAIN_TBL1 0xa300
|
||||
#define AR_PHY_TX_GAIN_CLC 0x0000001E
|
||||
#define AR_PHY_TX_GAIN_CLC_S 1
|
||||
#define AR_PHY_TX_GAIN 0x0007F000
|
||||
@ -526,91 +37,6 @@ bool ath9k_hw_set_rf_regs(struct ath_hw *ah,
|
||||
#define AR_PHY_CLC_Q0 0x0000ffd0
|
||||
#define AR_PHY_CLC_Q0_S 5
|
||||
|
||||
#define AR_PHY_CH0_TX_PWRCTRL11 0xa398
|
||||
#define AR_PHY_CH1_TX_PWRCTRL11 0xb398
|
||||
#define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP 0x0000FC00
|
||||
#define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP_S 10
|
||||
|
||||
#define AR_PHY_VIT_MASK2_M_46_61 0xa3a0
|
||||
#define AR_PHY_MASK2_M_31_45 0xa3a4
|
||||
#define AR_PHY_MASK2_M_16_30 0xa3a8
|
||||
#define AR_PHY_MASK2_M_00_15 0xa3ac
|
||||
#define AR_PHY_MASK2_P_15_01 0xa3b8
|
||||
#define AR_PHY_MASK2_P_30_16 0xa3bc
|
||||
#define AR_PHY_MASK2_P_45_31 0xa3c0
|
||||
#define AR_PHY_MASK2_P_61_45 0xa3c4
|
||||
#define AR_PHY_SPUR_REG 0x994c
|
||||
|
||||
#define AR_PHY_SPUR_REG_MASK_RATE_CNTL (0xFF << 18)
|
||||
#define AR_PHY_SPUR_REG_MASK_RATE_CNTL_S 18
|
||||
|
||||
#define AR_PHY_SPUR_REG_ENABLE_MASK_PPM 0x20000
|
||||
#define AR_PHY_SPUR_REG_MASK_RATE_SELECT (0xFF << 9)
|
||||
#define AR_PHY_SPUR_REG_MASK_RATE_SELECT_S 9
|
||||
#define AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI 0x100
|
||||
#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH 0x7F
|
||||
#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH_S 0
|
||||
|
||||
#define AR_PHY_PILOT_MASK_01_30 0xa3b0
|
||||
#define AR_PHY_PILOT_MASK_31_60 0xa3b4
|
||||
|
||||
#define AR_PHY_CHANNEL_MASK_01_30 0x99d4
|
||||
#define AR_PHY_CHANNEL_MASK_31_60 0x99d8
|
||||
|
||||
#define AR_PHY_ANALOG_SWAP 0xa268
|
||||
#define AR_PHY_SWAP_ALT_CHAIN 0x00000040
|
||||
|
||||
#define AR_PHY_TPCRG5 0xA26C
|
||||
#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP 0x0000000F
|
||||
#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP_S 0
|
||||
#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1 0x000003F0
|
||||
#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1_S 4
|
||||
#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2 0x0000FC00
|
||||
#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2_S 10
|
||||
#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3 0x003F0000
|
||||
#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3_S 16
|
||||
#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4 0x0FC00000
|
||||
#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4_S 22
|
||||
|
||||
/* Carrier leak calibration control, do it after AGC calibration */
|
||||
#define AR_PHY_CL_CAL_CTL 0xA358
|
||||
#define AR_PHY_CL_CAL_ENABLE 0x00000002
|
||||
#define AR_PHY_PARALLEL_CAL_ENABLE 0x00000001
|
||||
|
||||
#define AR_PHY_POWER_TX_RATE5 0xA38C
|
||||
#define AR_PHY_POWER_TX_RATE6 0xA390
|
||||
|
||||
#define AR_PHY_CAL_CHAINMASK 0xA39C
|
||||
|
||||
#define AR_PHY_POWER_TX_SUB 0xA3C8
|
||||
#define AR_PHY_POWER_TX_RATE7 0xA3CC
|
||||
#define AR_PHY_POWER_TX_RATE8 0xA3D0
|
||||
#define AR_PHY_POWER_TX_RATE9 0xA3D4
|
||||
|
||||
#define AR_PHY_XPA_CFG 0xA3D8
|
||||
#define AR_PHY_FORCE_XPA_CFG 0x000000001
|
||||
#define AR_PHY_FORCE_XPA_CFG_S 0
|
||||
|
||||
#define AR_PHY_CH1_CCA 0xa864
|
||||
#define AR_PHY_CH1_MINCCA_PWR 0x0FF80000
|
||||
#define AR_PHY_CH1_MINCCA_PWR_S 19
|
||||
#define AR9280_PHY_CH1_MINCCA_PWR 0x1FF00000
|
||||
#define AR9280_PHY_CH1_MINCCA_PWR_S 20
|
||||
|
||||
#define AR_PHY_CH2_CCA 0xb864
|
||||
#define AR_PHY_CH2_MINCCA_PWR 0x0FF80000
|
||||
#define AR_PHY_CH2_MINCCA_PWR_S 19
|
||||
|
||||
#define AR_PHY_CH1_EXT_CCA 0xa9bc
|
||||
#define AR_PHY_CH1_EXT_MINCCA_PWR 0xFF800000
|
||||
#define AR_PHY_CH1_EXT_MINCCA_PWR_S 23
|
||||
#define AR9280_PHY_CH1_EXT_MINCCA_PWR 0x01FF0000
|
||||
#define AR9280_PHY_CH1_EXT_MINCCA_PWR_S 16
|
||||
|
||||
#define AR_PHY_CH2_EXT_CCA 0xb9bc
|
||||
#define AR_PHY_CH2_EXT_MINCCA_PWR 0xFF800000
|
||||
#define AR_PHY_CH2_EXT_MINCCA_PWR_S 23
|
||||
|
||||
#define REG_WRITE_RF_ARRAY(iniarray, regData, regWr) do { \
|
||||
int r; \
|
||||
for (r = 0; r < ((iniarray)->ia_rows); r++) { \
|
||||
@ -625,6 +51,7 @@ bool ath9k_hw_set_rf_regs(struct ath_hw *ah,
|
||||
#define ANTSWAP_AB 0x0001
|
||||
#define REDUCE_CHAIN_0 0x00000050
|
||||
#define REDUCE_CHAIN_1 0x00000051
|
||||
#define AR_PHY_CHIP_ID 0x9818
|
||||
|
||||
#define RF_BANK_SETUP(_bank, _iniarray, _col) do { \
|
||||
int i; \
|
||||
@ -632,4 +59,7 @@ bool ath9k_hw_set_rf_regs(struct ath_hw *ah,
|
||||
(_bank)[i] = INI_RA((_iniarray), i, _col);; \
|
||||
} while (0)
|
||||
|
||||
#define AR_PHY_TIMING11_SPUR_FREQ_SD 0x3FF00000
|
||||
#define AR_PHY_TIMING11_SPUR_FREQ_SD_S 20
|
||||
|
||||
#endif
|
||||
|
@ -691,6 +691,19 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
|
||||
rate_table = sc->cur_rate_table;
|
||||
rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe);
|
||||
|
||||
/*
|
||||
* If we're in HT mode and both us and our peer supports LDPC.
|
||||
* We don't need to check our own device's capabilities as our own
|
||||
* ht capabilities would have already been intersected with our peer's.
|
||||
*/
|
||||
if (conf_is_ht(&sc->hw->conf) &&
|
||||
(sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING))
|
||||
tx_info->flags |= IEEE80211_TX_CTL_LDPC;
|
||||
|
||||
if (conf_is_ht(&sc->hw->conf) &&
|
||||
(sta->ht_cap.cap & IEEE80211_HT_CAP_TX_STBC))
|
||||
tx_info->flags |= (1 << IEEE80211_TX_CTL_STBC_SHIFT);
|
||||
|
||||
if (is_probe) {
|
||||
/* set one try for probe rates. For the
|
||||
* probes don't enable rts */
|
||||
|
@ -15,6 +15,9 @@
|
||||
*/
|
||||
|
||||
#include "ath9k.h"
|
||||
#include "ar9003_mac.h"
|
||||
|
||||
#define SKB_CB_ATHBUF(__skb) (*((struct ath_buf **)__skb->cb))
|
||||
|
||||
static struct ieee80211_hw * ath_get_virt_hw(struct ath_softc *sc,
|
||||
struct ieee80211_hdr *hdr)
|
||||
@ -115,6 +118,190 @@ static void ath_opmode_init(struct ath_softc *sc)
|
||||
ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]);
|
||||
}
|
||||
|
||||
static bool ath_rx_edma_buf_link(struct ath_softc *sc,
|
||||
enum ath9k_rx_qtype qtype)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_rx_edma *rx_edma;
|
||||
struct sk_buff *skb;
|
||||
struct ath_buf *bf;
|
||||
|
||||
rx_edma = &sc->rx.rx_edma[qtype];
|
||||
if (skb_queue_len(&rx_edma->rx_fifo) >= rx_edma->rx_fifo_hwsize)
|
||||
return false;
|
||||
|
||||
bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list);
|
||||
list_del_init(&bf->list);
|
||||
|
||||
skb = bf->bf_mpdu;
|
||||
|
||||
ATH_RXBUF_RESET(bf);
|
||||
memset(skb->data, 0, ah->caps.rx_status_len);
|
||||
dma_sync_single_for_device(sc->dev, bf->bf_buf_addr,
|
||||
ah->caps.rx_status_len, DMA_TO_DEVICE);
|
||||
|
||||
SKB_CB_ATHBUF(skb) = bf;
|
||||
ath9k_hw_addrxbuf_edma(ah, bf->bf_buf_addr, qtype);
|
||||
skb_queue_tail(&rx_edma->rx_fifo, skb);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ath_rx_addbuffer_edma(struct ath_softc *sc,
|
||||
enum ath9k_rx_qtype qtype, int size)
|
||||
{
|
||||
struct ath_rx_edma *rx_edma;
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
u32 nbuf = 0;
|
||||
|
||||
rx_edma = &sc->rx.rx_edma[qtype];
|
||||
if (list_empty(&sc->rx.rxbuf)) {
|
||||
ath_print(common, ATH_DBG_QUEUE, "No free rx buf available\n");
|
||||
return;
|
||||
}
|
||||
|
||||
while (!list_empty(&sc->rx.rxbuf)) {
|
||||
nbuf++;
|
||||
|
||||
if (!ath_rx_edma_buf_link(sc, qtype))
|
||||
break;
|
||||
|
||||
if (nbuf >= size)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void ath_rx_remove_buffer(struct ath_softc *sc,
|
||||
enum ath9k_rx_qtype qtype)
|
||||
{
|
||||
struct ath_buf *bf;
|
||||
struct ath_rx_edma *rx_edma;
|
||||
struct sk_buff *skb;
|
||||
|
||||
rx_edma = &sc->rx.rx_edma[qtype];
|
||||
|
||||
while ((skb = skb_dequeue(&rx_edma->rx_fifo)) != NULL) {
|
||||
bf = SKB_CB_ATHBUF(skb);
|
||||
BUG_ON(!bf);
|
||||
list_add_tail(&bf->list, &sc->rx.rxbuf);
|
||||
}
|
||||
}
|
||||
|
||||
static void ath_rx_edma_cleanup(struct ath_softc *sc)
|
||||
{
|
||||
struct ath_buf *bf;
|
||||
|
||||
ath_rx_remove_buffer(sc, ATH9K_RX_QUEUE_LP);
|
||||
ath_rx_remove_buffer(sc, ATH9K_RX_QUEUE_HP);
|
||||
|
||||
list_for_each_entry(bf, &sc->rx.rxbuf, list) {
|
||||
if (bf->bf_mpdu)
|
||||
dev_kfree_skb_any(bf->bf_mpdu);
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&sc->rx.rxbuf);
|
||||
|
||||
kfree(sc->rx.rx_bufptr);
|
||||
sc->rx.rx_bufptr = NULL;
|
||||
}
|
||||
|
||||
static void ath_rx_edma_init_queue(struct ath_rx_edma *rx_edma, int size)
|
||||
{
|
||||
skb_queue_head_init(&rx_edma->rx_fifo);
|
||||
skb_queue_head_init(&rx_edma->rx_buffers);
|
||||
rx_edma->rx_fifo_hwsize = size;
|
||||
}
|
||||
|
||||
static int ath_rx_edma_init(struct ath_softc *sc, int nbufs)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct sk_buff *skb;
|
||||
struct ath_buf *bf;
|
||||
int error = 0, i;
|
||||
u32 size;
|
||||
|
||||
|
||||
common->rx_bufsize = roundup(IEEE80211_MAX_MPDU_LEN +
|
||||
ah->caps.rx_status_len,
|
||||
min(common->cachelsz, (u16)64));
|
||||
|
||||
ath9k_hw_set_rx_bufsize(ah, common->rx_bufsize -
|
||||
ah->caps.rx_status_len);
|
||||
|
||||
ath_rx_edma_init_queue(&sc->rx.rx_edma[ATH9K_RX_QUEUE_LP],
|
||||
ah->caps.rx_lp_qdepth);
|
||||
ath_rx_edma_init_queue(&sc->rx.rx_edma[ATH9K_RX_QUEUE_HP],
|
||||
ah->caps.rx_hp_qdepth);
|
||||
|
||||
size = sizeof(struct ath_buf) * nbufs;
|
||||
bf = kzalloc(size, GFP_KERNEL);
|
||||
if (!bf)
|
||||
return -ENOMEM;
|
||||
|
||||
INIT_LIST_HEAD(&sc->rx.rxbuf);
|
||||
sc->rx.rx_bufptr = bf;
|
||||
|
||||
for (i = 0; i < nbufs; i++, bf++) {
|
||||
skb = ath_rxbuf_alloc(common, common->rx_bufsize, GFP_KERNEL);
|
||||
if (!skb) {
|
||||
error = -ENOMEM;
|
||||
goto rx_init_fail;
|
||||
}
|
||||
|
||||
memset(skb->data, 0, common->rx_bufsize);
|
||||
bf->bf_mpdu = skb;
|
||||
|
||||
bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
|
||||
common->rx_bufsize,
|
||||
DMA_BIDIRECTIONAL);
|
||||
if (unlikely(dma_mapping_error(sc->dev,
|
||||
bf->bf_buf_addr))) {
|
||||
dev_kfree_skb_any(skb);
|
||||
bf->bf_mpdu = NULL;
|
||||
ath_print(common, ATH_DBG_FATAL,
|
||||
"dma_mapping_error() on RX init\n");
|
||||
error = -ENOMEM;
|
||||
goto rx_init_fail;
|
||||
}
|
||||
|
||||
list_add_tail(&bf->list, &sc->rx.rxbuf);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
rx_init_fail:
|
||||
ath_rx_edma_cleanup(sc);
|
||||
return error;
|
||||
}
|
||||
|
||||
static void ath_edma_start_recv(struct ath_softc *sc)
|
||||
{
|
||||
spin_lock_bh(&sc->rx.rxbuflock);
|
||||
|
||||
ath9k_hw_rxena(sc->sc_ah);
|
||||
|
||||
ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_HP,
|
||||
sc->rx.rx_edma[ATH9K_RX_QUEUE_HP].rx_fifo_hwsize);
|
||||
|
||||
ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_LP,
|
||||
sc->rx.rx_edma[ATH9K_RX_QUEUE_LP].rx_fifo_hwsize);
|
||||
|
||||
spin_unlock_bh(&sc->rx.rxbuflock);
|
||||
|
||||
ath_opmode_init(sc);
|
||||
|
||||
ath9k_hw_startpcureceive(sc->sc_ah);
|
||||
}
|
||||
|
||||
static void ath_edma_stop_recv(struct ath_softc *sc)
|
||||
{
|
||||
spin_lock_bh(&sc->rx.rxbuflock);
|
||||
ath_rx_remove_buffer(sc, ATH9K_RX_QUEUE_HP);
|
||||
ath_rx_remove_buffer(sc, ATH9K_RX_QUEUE_LP);
|
||||
spin_unlock_bh(&sc->rx.rxbuflock);
|
||||
}
|
||||
|
||||
int ath_rx_init(struct ath_softc *sc, int nbufs)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
@ -126,45 +313,51 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
|
||||
sc->sc_flags &= ~SC_OP_RXFLUSH;
|
||||
spin_lock_init(&sc->rx.rxbuflock);
|
||||
|
||||
common->rx_bufsize = roundup(IEEE80211_MAX_MPDU_LEN,
|
||||
min(common->cachelsz, (u16)64));
|
||||
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
|
||||
return ath_rx_edma_init(sc, nbufs);
|
||||
} else {
|
||||
common->rx_bufsize = roundup(IEEE80211_MAX_MPDU_LEN,
|
||||
min(common->cachelsz, (u16)64));
|
||||
|
||||
ath_print(common, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n",
|
||||
common->cachelsz, common->rx_bufsize);
|
||||
ath_print(common, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n",
|
||||
common->cachelsz, common->rx_bufsize);
|
||||
|
||||
/* Initialize rx descriptors */
|
||||
/* Initialize rx descriptors */
|
||||
|
||||
error = ath_descdma_setup(sc, &sc->rx.rxdma, &sc->rx.rxbuf,
|
||||
"rx", nbufs, 1);
|
||||
if (error != 0) {
|
||||
ath_print(common, ATH_DBG_FATAL,
|
||||
"failed to allocate rx descriptors: %d\n", error);
|
||||
goto err;
|
||||
}
|
||||
|
||||
list_for_each_entry(bf, &sc->rx.rxbuf, list) {
|
||||
skb = ath_rxbuf_alloc(common, common->rx_bufsize, GFP_KERNEL);
|
||||
if (skb == NULL) {
|
||||
error = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
bf->bf_mpdu = skb;
|
||||
bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
|
||||
common->rx_bufsize,
|
||||
DMA_FROM_DEVICE);
|
||||
if (unlikely(dma_mapping_error(sc->dev,
|
||||
bf->bf_buf_addr))) {
|
||||
dev_kfree_skb_any(skb);
|
||||
bf->bf_mpdu = NULL;
|
||||
error = ath_descdma_setup(sc, &sc->rx.rxdma, &sc->rx.rxbuf,
|
||||
"rx", nbufs, 1, 0);
|
||||
if (error != 0) {
|
||||
ath_print(common, ATH_DBG_FATAL,
|
||||
"dma_mapping_error() on RX init\n");
|
||||
error = -ENOMEM;
|
||||
"failed to allocate rx descriptors: %d\n",
|
||||
error);
|
||||
goto err;
|
||||
}
|
||||
bf->bf_dmacontext = bf->bf_buf_addr;
|
||||
|
||||
list_for_each_entry(bf, &sc->rx.rxbuf, list) {
|
||||
skb = ath_rxbuf_alloc(common, common->rx_bufsize,
|
||||
GFP_KERNEL);
|
||||
if (skb == NULL) {
|
||||
error = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
bf->bf_mpdu = skb;
|
||||
bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
|
||||
common->rx_bufsize,
|
||||
DMA_FROM_DEVICE);
|
||||
if (unlikely(dma_mapping_error(sc->dev,
|
||||
bf->bf_buf_addr))) {
|
||||
dev_kfree_skb_any(skb);
|
||||
bf->bf_mpdu = NULL;
|
||||
ath_print(common, ATH_DBG_FATAL,
|
||||
"dma_mapping_error() on RX init\n");
|
||||
error = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
bf->bf_dmacontext = bf->bf_buf_addr;
|
||||
}
|
||||
sc->rx.rxlink = NULL;
|
||||
}
|
||||
sc->rx.rxlink = NULL;
|
||||
|
||||
err:
|
||||
if (error)
|
||||
@ -180,17 +373,23 @@ void ath_rx_cleanup(struct ath_softc *sc)
|
||||
struct sk_buff *skb;
|
||||
struct ath_buf *bf;
|
||||
|
||||
list_for_each_entry(bf, &sc->rx.rxbuf, list) {
|
||||
skb = bf->bf_mpdu;
|
||||
if (skb) {
|
||||
dma_unmap_single(sc->dev, bf->bf_buf_addr,
|
||||
common->rx_bufsize, DMA_FROM_DEVICE);
|
||||
dev_kfree_skb(skb);
|
||||
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
|
||||
ath_rx_edma_cleanup(sc);
|
||||
return;
|
||||
} else {
|
||||
list_for_each_entry(bf, &sc->rx.rxbuf, list) {
|
||||
skb = bf->bf_mpdu;
|
||||
if (skb) {
|
||||
dma_unmap_single(sc->dev, bf->bf_buf_addr,
|
||||
common->rx_bufsize,
|
||||
DMA_FROM_DEVICE);
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sc->rx.rxdma.dd_desc_len != 0)
|
||||
ath_descdma_cleanup(sc, &sc->rx.rxdma, &sc->rx.rxbuf);
|
||||
if (sc->rx.rxdma.dd_desc_len != 0)
|
||||
ath_descdma_cleanup(sc, &sc->rx.rxdma, &sc->rx.rxbuf);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -273,6 +472,11 @@ int ath_startrecv(struct ath_softc *sc)
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_buf *bf, *tbf;
|
||||
|
||||
if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
|
||||
ath_edma_start_recv(sc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
spin_lock_bh(&sc->rx.rxbuflock);
|
||||
if (list_empty(&sc->rx.rxbuf))
|
||||
goto start_recv;
|
||||
@ -306,7 +510,11 @@ bool ath_stoprecv(struct ath_softc *sc)
|
||||
ath9k_hw_stoppcurecv(ah);
|
||||
ath9k_hw_setrxfilter(ah, 0);
|
||||
stopped = ath9k_hw_stopdmarecv(ah);
|
||||
sc->rx.rxlink = NULL;
|
||||
|
||||
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
|
||||
ath_edma_stop_recv(sc);
|
||||
else
|
||||
sc->rx.rxlink = NULL;
|
||||
|
||||
return stopped;
|
||||
}
|
||||
@ -315,7 +523,9 @@ void ath_flushrecv(struct ath_softc *sc)
|
||||
{
|
||||
spin_lock_bh(&sc->rx.rxflushlock);
|
||||
sc->sc_flags |= SC_OP_RXFLUSH;
|
||||
ath_rx_tasklet(sc, 1);
|
||||
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
|
||||
ath_rx_tasklet(sc, 1, true);
|
||||
ath_rx_tasklet(sc, 1, false);
|
||||
sc->sc_flags &= ~SC_OP_RXFLUSH;
|
||||
spin_unlock_bh(&sc->rx.rxflushlock);
|
||||
}
|
||||
@ -469,14 +679,147 @@ static void ath_rx_send_to_mac80211(struct ieee80211_hw *hw,
|
||||
ieee80211_rx(hw, skb);
|
||||
}
|
||||
|
||||
int ath_rx_tasklet(struct ath_softc *sc, int flush)
|
||||
static bool ath_edma_get_buffers(struct ath_softc *sc,
|
||||
enum ath9k_rx_qtype qtype)
|
||||
{
|
||||
#define PA2DESC(_sc, _pa) \
|
||||
((struct ath_desc *)((caddr_t)(_sc)->rx.rxdma.dd_desc + \
|
||||
((_pa) - (_sc)->rx.rxdma.dd_desc_paddr)))
|
||||
|
||||
struct ath_rx_edma *rx_edma = &sc->rx.rx_edma[qtype];
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct sk_buff *skb;
|
||||
struct ath_buf *bf;
|
||||
int ret;
|
||||
|
||||
skb = skb_peek(&rx_edma->rx_fifo);
|
||||
if (!skb)
|
||||
return false;
|
||||
|
||||
bf = SKB_CB_ATHBUF(skb);
|
||||
BUG_ON(!bf);
|
||||
|
||||
dma_sync_single_for_device(sc->dev, bf->bf_buf_addr,
|
||||
common->rx_bufsize, DMA_FROM_DEVICE);
|
||||
|
||||
ret = ath9k_hw_process_rxdesc_edma(ah, NULL, skb->data);
|
||||
if (ret == -EINPROGRESS)
|
||||
return false;
|
||||
|
||||
__skb_unlink(skb, &rx_edma->rx_fifo);
|
||||
if (ret == -EINVAL) {
|
||||
/* corrupt descriptor, skip this one and the following one */
|
||||
list_add_tail(&bf->list, &sc->rx.rxbuf);
|
||||
ath_rx_edma_buf_link(sc, qtype);
|
||||
skb = skb_peek(&rx_edma->rx_fifo);
|
||||
if (!skb)
|
||||
return true;
|
||||
|
||||
bf = SKB_CB_ATHBUF(skb);
|
||||
BUG_ON(!bf);
|
||||
|
||||
__skb_unlink(skb, &rx_edma->rx_fifo);
|
||||
list_add_tail(&bf->list, &sc->rx.rxbuf);
|
||||
ath_rx_edma_buf_link(sc, qtype);
|
||||
}
|
||||
skb_queue_tail(&rx_edma->rx_buffers, skb);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct ath_buf *ath_edma_get_next_rx_buf(struct ath_softc *sc,
|
||||
struct ath_rx_status *rs,
|
||||
enum ath9k_rx_qtype qtype)
|
||||
{
|
||||
struct ath_rx_edma *rx_edma = &sc->rx.rx_edma[qtype];
|
||||
struct sk_buff *skb;
|
||||
struct ath_buf *bf;
|
||||
|
||||
while (ath_edma_get_buffers(sc, qtype));
|
||||
skb = __skb_dequeue(&rx_edma->rx_buffers);
|
||||
if (!skb)
|
||||
return NULL;
|
||||
|
||||
bf = SKB_CB_ATHBUF(skb);
|
||||
ath9k_hw_process_rxdesc_edma(sc->sc_ah, rs, skb->data);
|
||||
return bf;
|
||||
}
|
||||
|
||||
static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc,
|
||||
struct ath_rx_status *rs)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ath_desc *ds;
|
||||
struct ath_buf *bf;
|
||||
int ret;
|
||||
|
||||
if (list_empty(&sc->rx.rxbuf)) {
|
||||
sc->rx.rxlink = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list);
|
||||
ds = bf->bf_desc;
|
||||
|
||||
/*
|
||||
* Must provide the virtual address of the current
|
||||
* descriptor, the physical address, and the virtual
|
||||
* address of the next descriptor in the h/w chain.
|
||||
* This allows the HAL to look ahead to see if the
|
||||
* hardware is done with a descriptor by checking the
|
||||
* done bit in the following descriptor and the address
|
||||
* of the current descriptor the DMA engine is working
|
||||
* on. All this is necessary because of our use of
|
||||
* a self-linked list to avoid rx overruns.
|
||||
*/
|
||||
ret = ath9k_hw_rxprocdesc(ah, ds, rs, 0);
|
||||
if (ret == -EINPROGRESS) {
|
||||
struct ath_rx_status trs;
|
||||
struct ath_buf *tbf;
|
||||
struct ath_desc *tds;
|
||||
|
||||
memset(&trs, 0, sizeof(trs));
|
||||
if (list_is_last(&bf->list, &sc->rx.rxbuf)) {
|
||||
sc->rx.rxlink = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tbf = list_entry(bf->list.next, struct ath_buf, list);
|
||||
|
||||
/*
|
||||
* On some hardware the descriptor status words could
|
||||
* get corrupted, including the done bit. Because of
|
||||
* this, check if the next descriptor's done bit is
|
||||
* set or not.
|
||||
*
|
||||
* If the next descriptor's done bit is set, the current
|
||||
* descriptor has been corrupted. Force s/w to discard
|
||||
* this descriptor and continue...
|
||||
*/
|
||||
|
||||
tds = tbf->bf_desc;
|
||||
ret = ath9k_hw_rxprocdesc(ah, tds, &trs, 0);
|
||||
if (ret == -EINPROGRESS)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!bf->bf_mpdu)
|
||||
return bf;
|
||||
|
||||
/*
|
||||
* Synchronize the DMA transfer with CPU before
|
||||
* 1. accessing the frame
|
||||
* 2. requeueing the same buffer to h/w
|
||||
*/
|
||||
dma_sync_single_for_device(sc->dev, bf->bf_buf_addr,
|
||||
common->rx_bufsize,
|
||||
DMA_FROM_DEVICE);
|
||||
|
||||
return bf;
|
||||
}
|
||||
|
||||
|
||||
int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
|
||||
{
|
||||
struct ath_buf *bf;
|
||||
struct sk_buff *skb = NULL, *requeue_skb;
|
||||
struct ieee80211_rx_status *rxs;
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
@ -491,7 +834,16 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
|
||||
int retval;
|
||||
bool decrypt_error = false;
|
||||
struct ath_rx_status rs;
|
||||
enum ath9k_rx_qtype qtype;
|
||||
bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA);
|
||||
int dma_type;
|
||||
|
||||
if (edma)
|
||||
dma_type = DMA_FROM_DEVICE;
|
||||
else
|
||||
dma_type = DMA_BIDIRECTIONAL;
|
||||
|
||||
qtype = hp ? ATH9K_RX_QUEUE_HP : ATH9K_RX_QUEUE_LP;
|
||||
spin_lock_bh(&sc->rx.rxbuflock);
|
||||
|
||||
do {
|
||||
@ -499,71 +851,19 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
|
||||
if ((sc->sc_flags & SC_OP_RXFLUSH) && (flush == 0))
|
||||
break;
|
||||
|
||||
if (list_empty(&sc->rx.rxbuf)) {
|
||||
sc->rx.rxlink = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list);
|
||||
ds = bf->bf_desc;
|
||||
|
||||
/*
|
||||
* Must provide the virtual address of the current
|
||||
* descriptor, the physical address, and the virtual
|
||||
* address of the next descriptor in the h/w chain.
|
||||
* This allows the HAL to look ahead to see if the
|
||||
* hardware is done with a descriptor by checking the
|
||||
* done bit in the following descriptor and the address
|
||||
* of the current descriptor the DMA engine is working
|
||||
* on. All this is necessary because of our use of
|
||||
* a self-linked list to avoid rx overruns.
|
||||
*/
|
||||
memset(&rs, 0, sizeof(rs));
|
||||
retval = ath9k_hw_rxprocdesc(ah, ds, &rs, 0);
|
||||
if (retval == -EINPROGRESS) {
|
||||
struct ath_rx_status trs;
|
||||
struct ath_buf *tbf;
|
||||
struct ath_desc *tds;
|
||||
if (edma)
|
||||
bf = ath_edma_get_next_rx_buf(sc, &rs, qtype);
|
||||
else
|
||||
bf = ath_get_next_rx_buf(sc, &rs);
|
||||
|
||||
memset(&trs, 0, sizeof(trs));
|
||||
if (list_is_last(&bf->list, &sc->rx.rxbuf)) {
|
||||
sc->rx.rxlink = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
tbf = list_entry(bf->list.next, struct ath_buf, list);
|
||||
|
||||
/*
|
||||
* On some hardware the descriptor status words could
|
||||
* get corrupted, including the done bit. Because of
|
||||
* this, check if the next descriptor's done bit is
|
||||
* set or not.
|
||||
*
|
||||
* If the next descriptor's done bit is set, the current
|
||||
* descriptor has been corrupted. Force s/w to discard
|
||||
* this descriptor and continue...
|
||||
*/
|
||||
|
||||
tds = tbf->bf_desc;
|
||||
retval = ath9k_hw_rxprocdesc(ah, tds, &trs, 0);
|
||||
if (retval == -EINPROGRESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!bf)
|
||||
break;
|
||||
|
||||
skb = bf->bf_mpdu;
|
||||
if (!skb)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Synchronize the DMA transfer with CPU before
|
||||
* 1. accessing the frame
|
||||
* 2. requeueing the same buffer to h/w
|
||||
*/
|
||||
dma_sync_single_for_cpu(sc->dev, bf->bf_buf_addr,
|
||||
common->rx_bufsize,
|
||||
DMA_FROM_DEVICE);
|
||||
|
||||
hdr = (struct ieee80211_hdr *) skb->data;
|
||||
rxs = IEEE80211_SKB_RXCB(skb);
|
||||
|
||||
@ -597,9 +897,11 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
|
||||
/* Unmap the frame */
|
||||
dma_unmap_single(sc->dev, bf->bf_buf_addr,
|
||||
common->rx_bufsize,
|
||||
DMA_FROM_DEVICE);
|
||||
dma_type);
|
||||
|
||||
skb_put(skb, rs.rs_datalen);
|
||||
skb_put(skb, rs.rs_datalen + ah->caps.rx_status_len);
|
||||
if (ah->caps.rx_status_len)
|
||||
skb_pull(skb, ah->caps.rx_status_len);
|
||||
|
||||
ath9k_cmn_rx_skb_postprocess(common, skb, &rs,
|
||||
rxs, decrypt_error);
|
||||
@ -608,7 +910,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
|
||||
bf->bf_mpdu = requeue_skb;
|
||||
bf->bf_buf_addr = dma_map_single(sc->dev, requeue_skb->data,
|
||||
common->rx_bufsize,
|
||||
DMA_FROM_DEVICE);
|
||||
dma_type);
|
||||
if (unlikely(dma_mapping_error(sc->dev,
|
||||
bf->bf_buf_addr))) {
|
||||
dev_kfree_skb_any(requeue_skb);
|
||||
@ -639,12 +941,16 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
|
||||
ath_rx_send_to_mac80211(hw, sc, skb, rxs);
|
||||
|
||||
requeue:
|
||||
list_move_tail(&bf->list, &sc->rx.rxbuf);
|
||||
ath_rx_buf_link(sc, bf);
|
||||
if (edma) {
|
||||
list_add_tail(&bf->list, &sc->rx.rxbuf);
|
||||
ath_rx_edma_buf_link(sc, qtype);
|
||||
} else {
|
||||
list_move_tail(&bf->list, &sc->rx.rxbuf);
|
||||
ath_rx_buf_link(sc, bf);
|
||||
}
|
||||
} while (1);
|
||||
|
||||
spin_unlock_bh(&sc->rx.rxbuflock);
|
||||
|
||||
return 0;
|
||||
#undef PA2DESC
|
||||
}
|
||||
|
@ -20,7 +20,7 @@
|
||||
#include "../reg.h"
|
||||
|
||||
#define AR_CR 0x0008
|
||||
#define AR_CR_RXE 0x00000004
|
||||
#define AR_CR_RXE (AR_SREV_9300_20_OR_LATER(ah) ? 0x0000000c : 0x00000004)
|
||||
#define AR_CR_RXD 0x00000020
|
||||
#define AR_CR_SWI 0x00000040
|
||||
|
||||
@ -39,6 +39,12 @@
|
||||
#define AR_CFG_PCI_MASTER_REQ_Q_THRESH 0x00060000
|
||||
#define AR_CFG_PCI_MASTER_REQ_Q_THRESH_S 17
|
||||
|
||||
#define AR_RXBP_THRESH 0x0018
|
||||
#define AR_RXBP_THRESH_HP 0x0000000f
|
||||
#define AR_RXBP_THRESH_HP_S 0
|
||||
#define AR_RXBP_THRESH_LP 0x00003f00
|
||||
#define AR_RXBP_THRESH_LP_S 8
|
||||
|
||||
#define AR_MIRT 0x0020
|
||||
#define AR_MIRT_VAL 0x0000ffff
|
||||
#define AR_MIRT_VAL_S 16
|
||||
@ -144,6 +150,9 @@
|
||||
#define AR_MACMISC_MISC_OBS_BUS_MSB_S 15
|
||||
#define AR_MACMISC_MISC_OBS_BUS_1 1
|
||||
|
||||
#define AR_DATABUF_SIZE 0x0060
|
||||
#define AR_DATABUF_SIZE_MASK 0x00000FFF
|
||||
|
||||
#define AR_GTXTO 0x0064
|
||||
#define AR_GTXTO_TIMEOUT_COUNTER 0x0000FFFF
|
||||
#define AR_GTXTO_TIMEOUT_LIMIT 0xFFFF0000
|
||||
@ -160,9 +169,14 @@
|
||||
#define AR_CST_TIMEOUT_LIMIT 0xFFFF0000
|
||||
#define AR_CST_TIMEOUT_LIMIT_S 16
|
||||
|
||||
#define AR_HP_RXDP 0x0074
|
||||
#define AR_LP_RXDP 0x0078
|
||||
|
||||
#define AR_ISR 0x0080
|
||||
#define AR_ISR_RXOK 0x00000001
|
||||
#define AR_ISR_RXDESC 0x00000002
|
||||
#define AR_ISR_HP_RXOK 0x00000001
|
||||
#define AR_ISR_LP_RXOK 0x00000002
|
||||
#define AR_ISR_RXERR 0x00000004
|
||||
#define AR_ISR_RXNOPKT 0x00000008
|
||||
#define AR_ISR_RXEOL 0x00000010
|
||||
@ -232,7 +246,6 @@
|
||||
#define AR_ISR_S5_TIMER_THRESH 0x0007FE00
|
||||
#define AR_ISR_S5_TIM_TIMER 0x00000010
|
||||
#define AR_ISR_S5_DTIM_TIMER 0x00000020
|
||||
#define AR_ISR_S5_S 0x00d8
|
||||
#define AR_IMR_S5 0x00b8
|
||||
#define AR_IMR_S5_TIM_TIMER 0x00000010
|
||||
#define AR_IMR_S5_DTIM_TIMER 0x00000020
|
||||
@ -240,7 +253,6 @@
|
||||
#define AR_ISR_S5_GENTIMER_TRIG_S 0
|
||||
#define AR_ISR_S5_GENTIMER_THRESH 0xFF800000
|
||||
#define AR_ISR_S5_GENTIMER_THRESH_S 16
|
||||
#define AR_ISR_S5_S 0x00d8
|
||||
#define AR_IMR_S5_GENTIMER_TRIG 0x0000FF80
|
||||
#define AR_IMR_S5_GENTIMER_TRIG_S 0
|
||||
#define AR_IMR_S5_GENTIMER_THRESH 0xFF800000
|
||||
@ -249,6 +261,8 @@
|
||||
#define AR_IMR 0x00a0
|
||||
#define AR_IMR_RXOK 0x00000001
|
||||
#define AR_IMR_RXDESC 0x00000002
|
||||
#define AR_IMR_RXOK_HP 0x00000001
|
||||
#define AR_IMR_RXOK_LP 0x00000002
|
||||
#define AR_IMR_RXERR 0x00000004
|
||||
#define AR_IMR_RXNOPKT 0x00000008
|
||||
#define AR_IMR_RXEOL 0x00000010
|
||||
@ -332,10 +346,10 @@
|
||||
#define AR_ISR_S1_QCU_TXEOL 0x03FF0000
|
||||
#define AR_ISR_S1_QCU_TXEOL_S 16
|
||||
|
||||
#define AR_ISR_S2_S 0x00cc
|
||||
#define AR_ISR_S3_S 0x00d0
|
||||
#define AR_ISR_S4_S 0x00d4
|
||||
#define AR_ISR_S5_S 0x00d8
|
||||
#define AR_ISR_S2_S (AR_SREV_9300_20_OR_LATER(ah) ? 0x00d0 : 0x00cc)
|
||||
#define AR_ISR_S3_S (AR_SREV_9300_20_OR_LATER(ah) ? 0x00d4 : 0x00d0)
|
||||
#define AR_ISR_S4_S (AR_SREV_9300_20_OR_LATER(ah) ? 0x00d8 : 0x00d4)
|
||||
#define AR_ISR_S5_S (AR_SREV_9300_20_OR_LATER(ah) ? 0x00dc : 0x00d8)
|
||||
#define AR_DMADBG_0 0x00e0
|
||||
#define AR_DMADBG_1 0x00e4
|
||||
#define AR_DMADBG_2 0x00e8
|
||||
@ -369,6 +383,9 @@
|
||||
#define AR_Q9_TXDP 0x0824
|
||||
#define AR_QTXDP(_i) (AR_Q0_TXDP + ((_i)<<2))
|
||||
|
||||
#define AR_Q_STATUS_RING_START 0x830
|
||||
#define AR_Q_STATUS_RING_END 0x834
|
||||
|
||||
#define AR_Q_TXE 0x0840
|
||||
#define AR_Q_TXE_M 0x000003FF
|
||||
|
||||
@ -461,6 +478,10 @@
|
||||
#define AR_Q_RDYTIMESHDN 0x0a40
|
||||
#define AR_Q_RDYTIMESHDN_M 0x000003FF
|
||||
|
||||
/* MAC Descriptor CRC check */
|
||||
#define AR_Q_DESC_CRCCHK 0xa44
|
||||
/* Enable CRC check on the descriptor fetched from host */
|
||||
#define AR_Q_DESC_CRCCHK_EN 1
|
||||
|
||||
#define AR_NUM_DCU 10
|
||||
#define AR_DCU_0 0x0001
|
||||
@ -759,6 +780,8 @@
|
||||
#define AR_SREV_VERSION_9271 0x140
|
||||
#define AR_SREV_REVISION_9271_10 0
|
||||
#define AR_SREV_REVISION_9271_11 1
|
||||
#define AR_SREV_VERSION_9300 0x1c0
|
||||
#define AR_SREV_REVISION_9300_20 2 /* 2.0 and 2.1 */
|
||||
|
||||
#define AR_SREV_5416(_ah) \
|
||||
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \
|
||||
@ -844,6 +867,15 @@
|
||||
#define AR_SREV_9271_11(_ah) \
|
||||
(AR_SREV_9271(_ah) && \
|
||||
((_ah)->hw_version.macRev == AR_SREV_REVISION_9271_11))
|
||||
#define AR_SREV_9300(_ah) \
|
||||
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300))
|
||||
#define AR_SREV_9300_20(_ah) \
|
||||
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300) && \
|
||||
((_ah)->hw_version.macRev == AR_SREV_REVISION_9300_20))
|
||||
#define AR_SREV_9300_20_OR_LATER(_ah) \
|
||||
(((_ah)->hw_version.macVersion > AR_SREV_VERSION_9300) || \
|
||||
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300) && \
|
||||
((_ah)->hw_version.macRev >= AR_SREV_REVISION_9300_20)))
|
||||
|
||||
#define AR_SREV_9285E_20(_ah) \
|
||||
(AR_SREV_9285_12_OR_LATER(_ah) && \
|
||||
@ -945,6 +977,7 @@ enum {
|
||||
#define AR9285_NUM_GPIO 12
|
||||
#define AR9287_NUM_GPIO 11
|
||||
#define AR9271_NUM_GPIO 16
|
||||
#define AR9300_NUM_GPIO 17
|
||||
|
||||
#define AR_GPIO_IN_OUT 0x4048
|
||||
#define AR_GPIO_IN_VAL 0x0FFFC000
|
||||
@ -957,19 +990,21 @@ enum {
|
||||
#define AR9287_GPIO_IN_VAL_S 11
|
||||
#define AR9271_GPIO_IN_VAL 0xFFFF0000
|
||||
#define AR9271_GPIO_IN_VAL_S 16
|
||||
#define AR9300_GPIO_IN_VAL 0x0001FFFF
|
||||
#define AR9300_GPIO_IN_VAL_S 0
|
||||
|
||||
#define AR_GPIO_OE_OUT 0x404c
|
||||
#define AR_GPIO_OE_OUT (AR_SREV_9300_20_OR_LATER(ah) ? 0x4050 : 0x404c)
|
||||
#define AR_GPIO_OE_OUT_DRV 0x3
|
||||
#define AR_GPIO_OE_OUT_DRV_NO 0x0
|
||||
#define AR_GPIO_OE_OUT_DRV_LOW 0x1
|
||||
#define AR_GPIO_OE_OUT_DRV_HI 0x2
|
||||
#define AR_GPIO_OE_OUT_DRV_ALL 0x3
|
||||
|
||||
#define AR_GPIO_INTR_POL 0x4050
|
||||
#define AR_GPIO_INTR_POL_VAL 0x00001FFF
|
||||
#define AR_GPIO_INTR_POL (AR_SREV_9300_20_OR_LATER(ah) ? 0x4058 : 0x4050)
|
||||
#define AR_GPIO_INTR_POL_VAL 0x0001FFFF
|
||||
#define AR_GPIO_INTR_POL_VAL_S 0
|
||||
|
||||
#define AR_GPIO_INPUT_EN_VAL 0x4054
|
||||
#define AR_GPIO_INPUT_EN_VAL (AR_SREV_9300_20_OR_LATER(ah) ? 0x405c : 0x4054)
|
||||
#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF 0x00000004
|
||||
#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_S 2
|
||||
#define AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF 0x00000008
|
||||
@ -987,13 +1022,13 @@ enum {
|
||||
#define AR_GPIO_RTC_RESET_OVERRIDE_ENABLE 0x00010000
|
||||
#define AR_GPIO_JTAG_DISABLE 0x00020000
|
||||
|
||||
#define AR_GPIO_INPUT_MUX1 0x4058
|
||||
#define AR_GPIO_INPUT_MUX1 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4060 : 0x4058)
|
||||
#define AR_GPIO_INPUT_MUX1_BT_ACTIVE 0x000f0000
|
||||
#define AR_GPIO_INPUT_MUX1_BT_ACTIVE_S 16
|
||||
#define AR_GPIO_INPUT_MUX1_BT_PRIORITY 0x00000f00
|
||||
#define AR_GPIO_INPUT_MUX1_BT_PRIORITY_S 8
|
||||
|
||||
#define AR_GPIO_INPUT_MUX2 0x405c
|
||||
#define AR_GPIO_INPUT_MUX2 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4064 : 0x405c)
|
||||
#define AR_GPIO_INPUT_MUX2_CLK25 0x0000000f
|
||||
#define AR_GPIO_INPUT_MUX2_CLK25_S 0
|
||||
#define AR_GPIO_INPUT_MUX2_RFSILENT 0x000000f0
|
||||
@ -1001,13 +1036,13 @@ enum {
|
||||
#define AR_GPIO_INPUT_MUX2_RTC_RESET 0x00000f00
|
||||
#define AR_GPIO_INPUT_MUX2_RTC_RESET_S 8
|
||||
|
||||
#define AR_GPIO_OUTPUT_MUX1 0x4060
|
||||
#define AR_GPIO_OUTPUT_MUX2 0x4064
|
||||
#define AR_GPIO_OUTPUT_MUX3 0x4068
|
||||
#define AR_GPIO_OUTPUT_MUX1 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4068 : 0x4060)
|
||||
#define AR_GPIO_OUTPUT_MUX2 (AR_SREV_9300_20_OR_LATER(ah) ? 0x406c : 0x4064)
|
||||
#define AR_GPIO_OUTPUT_MUX3 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4070 : 0x4068)
|
||||
|
||||
#define AR_INPUT_STATE 0x406c
|
||||
#define AR_INPUT_STATE (AR_SREV_9300_20_OR_LATER(ah) ? 0x4074 : 0x406c)
|
||||
|
||||
#define AR_EEPROM_STATUS_DATA 0x407c
|
||||
#define AR_EEPROM_STATUS_DATA (AR_SREV_9300_20_OR_LATER(ah) ? 0x4084 : 0x407c)
|
||||
#define AR_EEPROM_STATUS_DATA_VAL 0x0000ffff
|
||||
#define AR_EEPROM_STATUS_DATA_VAL_S 0
|
||||
#define AR_EEPROM_STATUS_DATA_BUSY 0x00010000
|
||||
@ -1015,13 +1050,24 @@ enum {
|
||||
#define AR_EEPROM_STATUS_DATA_PROT_ACCESS 0x00040000
|
||||
#define AR_EEPROM_STATUS_DATA_ABSENT_ACCESS 0x00080000
|
||||
|
||||
#define AR_OBS 0x4080
|
||||
#define AR_OBS (AR_SREV_9300_20_OR_LATER(ah) ? 0x4088 : 0x4080)
|
||||
|
||||
#define AR_GPIO_PDPU 0x4088
|
||||
#define AR_GPIO_PDPU (AR_SREV_9300_20_OR_LATER(ah) ? 0x4090 : 0x4088)
|
||||
|
||||
#define AR_PCIE_MSI 0x4094
|
||||
#define AR_PCIE_MSI (AR_SREV_9300_20_OR_LATER(ah) ? 0x40a4 : 0x4094)
|
||||
#define AR_PCIE_MSI_ENABLE 0x00000001
|
||||
|
||||
#define AR_INTR_PRIO_SYNC_ENABLE 0x40c4
|
||||
#define AR_INTR_PRIO_ASYNC_MASK 0x40c8
|
||||
#define AR_INTR_PRIO_SYNC_MASK 0x40cc
|
||||
#define AR_INTR_PRIO_ASYNC_ENABLE 0x40d4
|
||||
|
||||
#define AR_RTC_9300_PLL_DIV 0x000003ff
|
||||
#define AR_RTC_9300_PLL_DIV_S 0
|
||||
#define AR_RTC_9300_PLL_REFDIV 0x00003C00
|
||||
#define AR_RTC_9300_PLL_REFDIV_S 10
|
||||
#define AR_RTC_9300_PLL_CLKSEL 0x0000C000
|
||||
#define AR_RTC_9300_PLL_CLKSEL_S 14
|
||||
|
||||
#define AR_RTC_9160_PLL_DIV 0x000003ff
|
||||
#define AR_RTC_9160_PLL_DIV_S 0
|
||||
@ -1039,6 +1085,16 @@ enum {
|
||||
#define AR_RTC_RC_COLD_RESET 0x00000004
|
||||
#define AR_RTC_RC_WARM_RESET 0x00000008
|
||||
|
||||
/* Crystal Control */
|
||||
#define AR_RTC_XTAL_CONTROL 0x7004
|
||||
|
||||
/* Reg Control 0 */
|
||||
#define AR_RTC_REG_CONTROL0 0x7008
|
||||
|
||||
/* Reg Control 1 */
|
||||
#define AR_RTC_REG_CONTROL1 0x700c
|
||||
#define AR_RTC_REG_CONTROL1_SWREG_PROGRAM 0x00000001
|
||||
|
||||
#define AR_RTC_PLL_CONTROL \
|
||||
((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0014) : 0x7014)
|
||||
|
||||
@ -1069,6 +1125,7 @@ enum {
|
||||
#define AR_RTC_SLEEP_CLK \
|
||||
((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0048) : 0x7048)
|
||||
#define AR_RTC_FORCE_DERIVED_CLK 0x2
|
||||
#define AR_RTC_FORCE_SWREG_PRD 0x00000004
|
||||
|
||||
#define AR_RTC_FORCE_WAKE \
|
||||
((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x004c) : 0x704c)
|
||||
@ -1533,7 +1590,7 @@ enum {
|
||||
#define AR_TSFOOR_THRESHOLD 0x813c
|
||||
#define AR_TSFOOR_THRESHOLD_VAL 0x0000FFFF
|
||||
|
||||
#define AR_PHY_ERR_EIFS_MASK 8144
|
||||
#define AR_PHY_ERR_EIFS_MASK 0x8144
|
||||
|
||||
#define AR_PHY_ERR_3 0x8168
|
||||
#define AR_PHY_ERR_3_COUNT 0x00FFFFFF
|
||||
@ -1599,24 +1656,26 @@ enum {
|
||||
#define AR_FIRST_NDP_TIMER 7
|
||||
#define AR_NDP2_PERIOD 0x81a0
|
||||
#define AR_NDP2_TIMER_MODE 0x81c0
|
||||
#define AR_NEXT_TBTT_TIMER 0x8200
|
||||
#define AR_NEXT_DMA_BEACON_ALERT 0x8204
|
||||
#define AR_NEXT_SWBA 0x8208
|
||||
#define AR_NEXT_CFP 0x8208
|
||||
#define AR_NEXT_HCF 0x820C
|
||||
#define AR_NEXT_TIM 0x8210
|
||||
#define AR_NEXT_DTIM 0x8214
|
||||
#define AR_NEXT_QUIET_TIMER 0x8218
|
||||
#define AR_NEXT_NDP_TIMER 0x821C
|
||||
|
||||
#define AR_BEACON_PERIOD 0x8220
|
||||
#define AR_DMA_BEACON_PERIOD 0x8224
|
||||
#define AR_SWBA_PERIOD 0x8228
|
||||
#define AR_HCF_PERIOD 0x822C
|
||||
#define AR_TIM_PERIOD 0x8230
|
||||
#define AR_DTIM_PERIOD 0x8234
|
||||
#define AR_QUIET_PERIOD 0x8238
|
||||
#define AR_NDP_PERIOD 0x823C
|
||||
#define AR_GEN_TIMERS(_i) (0x8200 + ((_i) << 2))
|
||||
#define AR_NEXT_TBTT_TIMER AR_GEN_TIMERS(0)
|
||||
#define AR_NEXT_DMA_BEACON_ALERT AR_GEN_TIMERS(1)
|
||||
#define AR_NEXT_SWBA AR_GEN_TIMERS(2)
|
||||
#define AR_NEXT_CFP AR_GEN_TIMERS(2)
|
||||
#define AR_NEXT_HCF AR_GEN_TIMERS(3)
|
||||
#define AR_NEXT_TIM AR_GEN_TIMERS(4)
|
||||
#define AR_NEXT_DTIM AR_GEN_TIMERS(5)
|
||||
#define AR_NEXT_QUIET_TIMER AR_GEN_TIMERS(6)
|
||||
#define AR_NEXT_NDP_TIMER AR_GEN_TIMERS(7)
|
||||
|
||||
#define AR_BEACON_PERIOD AR_GEN_TIMERS(8)
|
||||
#define AR_DMA_BEACON_PERIOD AR_GEN_TIMERS(9)
|
||||
#define AR_SWBA_PERIOD AR_GEN_TIMERS(10)
|
||||
#define AR_HCF_PERIOD AR_GEN_TIMERS(11)
|
||||
#define AR_TIM_PERIOD AR_GEN_TIMERS(12)
|
||||
#define AR_DTIM_PERIOD AR_GEN_TIMERS(13)
|
||||
#define AR_QUIET_PERIOD AR_GEN_TIMERS(14)
|
||||
#define AR_NDP_PERIOD AR_GEN_TIMERS(15)
|
||||
|
||||
#define AR_TIMER_MODE 0x8240
|
||||
#define AR_TBTT_TIMER_EN 0x00000001
|
||||
@ -1730,4 +1789,32 @@ enum {
|
||||
#define AR9271_CORE_CLOCK 117 /* clock to 117Mhz */
|
||||
#define AR9271_TARGET_BAUD_RATE 19200 /* 115200 */
|
||||
|
||||
#define AR_AGG_WEP_ENABLE_FIX 0x00000008 /* This allows the use of AR_AGG_WEP_ENABLE */
|
||||
#define AR_ADHOC_MCAST_KEYID_ENABLE 0x00000040 /* This bit enables the Multicast search
|
||||
* based on both MAC Address and Key ID.
|
||||
* If bit is 0, then Multicast search is
|
||||
* based on MAC address only.
|
||||
* For Merlin and above only.
|
||||
*/
|
||||
#define AR_AGG_WEP_ENABLE 0x00020000 /* This field enables AGG_WEP feature,
|
||||
* when it is enable, AGG_WEP would takes
|
||||
* charge of the encryption interface of
|
||||
* pcu_txsm.
|
||||
*/
|
||||
|
||||
#define AR9300_SM_BASE 0xa200
|
||||
#define AR9002_PHY_AGC_CONTROL 0x9860
|
||||
#define AR9003_PHY_AGC_CONTROL AR9300_SM_BASE + 0xc4
|
||||
#define AR_PHY_AGC_CONTROL (AR_SREV_9300_20_OR_LATER(ah) ? AR9003_PHY_AGC_CONTROL : AR9002_PHY_AGC_CONTROL)
|
||||
#define AR_PHY_AGC_CONTROL_CAL 0x00000001 /* do internal calibration */
|
||||
#define AR_PHY_AGC_CONTROL_NF 0x00000002 /* do noise-floor calibration */
|
||||
#define AR_PHY_AGC_CONTROL_OFFSET_CAL 0x00000800 /* allow offset calibration */
|
||||
#define AR_PHY_AGC_CONTROL_ENABLE_NF 0x00008000 /* enable noise floor calibration to happen */
|
||||
#define AR_PHY_AGC_CONTROL_FLTR_CAL 0x00010000 /* allow tx filter calibration */
|
||||
#define AR_PHY_AGC_CONTROL_NO_UPDATE_NF 0x00020000 /* don't update noise floor automatically */
|
||||
#define AR_PHY_AGC_CONTROL_EXT_NF_PWR_MEAS 0x00040000 /* extend noise floor power measurement */
|
||||
#define AR_PHY_AGC_CONTROL_CLC_SUCCESS 0x00080000 /* carrier leak calibration done */
|
||||
#define AR_PHY_AGC_CONTROL_YCOK_MAX 0x000003c0
|
||||
#define AR_PHY_AGC_CONTROL_YCOK_MAX_S 6
|
||||
|
||||
#endif
|
||||
|
@ -101,6 +101,7 @@ struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv)
|
||||
wmi->drv_priv = priv;
|
||||
wmi->stopped = false;
|
||||
mutex_init(&wmi->op_mutex);
|
||||
mutex_init(&wmi->multi_write_mutex);
|
||||
init_completion(&wmi->cmd_wait);
|
||||
|
||||
return wmi;
|
||||
@ -128,7 +129,7 @@ void ath9k_wmi_tasklet(unsigned long data)
|
||||
void *wmi_event;
|
||||
unsigned long flags;
|
||||
#ifdef CONFIG_ATH9K_HTC_DEBUGFS
|
||||
u32 txrate;
|
||||
__be32 txrate;
|
||||
#endif
|
||||
|
||||
spin_lock_irqsave(&priv->wmi->wmi_lock, flags);
|
||||
@ -203,6 +204,14 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb,
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check if there has been a timeout. */
|
||||
spin_lock(&wmi->wmi_lock);
|
||||
if (cmd_id != wmi->last_cmd_id) {
|
||||
spin_unlock(&wmi->wmi_lock);
|
||||
goto free_skb;
|
||||
}
|
||||
spin_unlock(&wmi->wmi_lock);
|
||||
|
||||
/* WMI command response */
|
||||
ath9k_wmi_rsp_callback(wmi, skb);
|
||||
|
||||
@ -265,6 +274,7 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
|
||||
struct sk_buff *skb;
|
||||
u8 *data;
|
||||
int time_left, ret = 0;
|
||||
unsigned long flags;
|
||||
|
||||
if (!wmi)
|
||||
return -EINVAL;
|
||||
@ -296,6 +306,10 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
spin_lock_irqsave(&wmi->wmi_lock, flags);
|
||||
wmi->last_cmd_id = cmd_id;
|
||||
spin_unlock_irqrestore(&wmi->wmi_lock, flags);
|
||||
|
||||
time_left = wait_for_completion_timeout(&wmi->cmd_wait, timeout);
|
||||
if (!time_left) {
|
||||
ath_print(common, ATH_DBG_WMI,
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
|
||||
struct wmi_event_txrate {
|
||||
u32 txrate;
|
||||
__be32 txrate;
|
||||
struct {
|
||||
u8 rssi_thresh;
|
||||
u8 per;
|
||||
@ -27,8 +27,8 @@ struct wmi_event_txrate {
|
||||
} __packed;
|
||||
|
||||
struct wmi_cmd_hdr {
|
||||
u16 command_id;
|
||||
u16 seq_no;
|
||||
__be16 command_id;
|
||||
__be16 seq_no;
|
||||
} __packed;
|
||||
|
||||
struct wmi_swba {
|
||||
@ -84,12 +84,20 @@ enum wmi_event_id {
|
||||
WMI_TXRATE_EVENTID,
|
||||
};
|
||||
|
||||
#define MAX_CMD_NUMBER 62
|
||||
|
||||
struct register_write {
|
||||
__be32 reg;
|
||||
__be32 val;
|
||||
};
|
||||
|
||||
struct wmi {
|
||||
struct ath9k_htc_priv *drv_priv;
|
||||
struct htc_target *htc;
|
||||
enum htc_endpoint_id ctrl_epid;
|
||||
struct mutex op_mutex;
|
||||
struct completion cmd_wait;
|
||||
enum wmi_cmd_id last_cmd_id;
|
||||
u16 tx_seq_id;
|
||||
u8 *cmd_rsp_buf;
|
||||
u32 cmd_rsp_len;
|
||||
@ -97,6 +105,11 @@ struct wmi {
|
||||
|
||||
struct sk_buff *wmi_skb;
|
||||
spinlock_t wmi_lock;
|
||||
|
||||
atomic_t mwrite_cnt;
|
||||
struct register_write multi_write[MAX_CMD_NUMBER];
|
||||
u32 multi_write_idx;
|
||||
struct mutex multi_write_mutex;
|
||||
};
|
||||
|
||||
struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv);
|
||||
|
@ -15,10 +15,11 @@
|
||||
*/
|
||||
|
||||
#include "ath9k.h"
|
||||
#include "ar9003_mac.h"
|
||||
|
||||
#define BITS_PER_BYTE 8
|
||||
#define OFDM_PLCP_BITS 22
|
||||
#define HT_RC_2_MCS(_rc) ((_rc) & 0x0f)
|
||||
#define HT_RC_2_MCS(_rc) ((_rc) & 0x1f)
|
||||
#define HT_RC_2_STREAMS(_rc) ((((_rc) & 0x78) >> 3) + 1)
|
||||
#define L_STF 8
|
||||
#define L_LTF 8
|
||||
@ -33,7 +34,7 @@
|
||||
|
||||
#define OFDM_SIFS_TIME 16
|
||||
|
||||
static u32 bits_per_symbol[][2] = {
|
||||
static u16 bits_per_symbol[][2] = {
|
||||
/* 20MHz 40MHz */
|
||||
{ 26, 54 }, /* 0: BPSK */
|
||||
{ 52, 108 }, /* 1: QPSK 1/2 */
|
||||
@ -43,14 +44,6 @@ static u32 bits_per_symbol[][2] = {
|
||||
{ 208, 432 }, /* 5: 64-QAM 2/3 */
|
||||
{ 234, 486 }, /* 6: 64-QAM 3/4 */
|
||||
{ 260, 540 }, /* 7: 64-QAM 5/6 */
|
||||
{ 52, 108 }, /* 8: BPSK */
|
||||
{ 104, 216 }, /* 9: QPSK 1/2 */
|
||||
{ 156, 324 }, /* 10: QPSK 3/4 */
|
||||
{ 208, 432 }, /* 11: 16-QAM 1/2 */
|
||||
{ 312, 648 }, /* 12: 16-QAM 3/4 */
|
||||
{ 416, 864 }, /* 13: 64-QAM 2/3 */
|
||||
{ 468, 972 }, /* 14: 64-QAM 3/4 */
|
||||
{ 520, 1080 }, /* 15: 64-QAM 5/6 */
|
||||
};
|
||||
|
||||
#define IS_HT_RATE(_rate) ((_rate) & 0x80)
|
||||
@ -70,28 +63,39 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts,
|
||||
int nbad, int txok, bool update_rc);
|
||||
|
||||
enum {
|
||||
MCS_DEFAULT,
|
||||
MCS_HT20,
|
||||
MCS_HT20_SGI,
|
||||
MCS_HT40,
|
||||
MCS_HT40_SGI,
|
||||
};
|
||||
|
||||
static int ath_max_4ms_framelen[3][16] = {
|
||||
[MCS_DEFAULT] = {
|
||||
3216, 6434, 9650, 12868, 19304, 25740, 28956, 32180,
|
||||
6430, 12860, 19300, 25736, 38600, 51472, 57890, 64320,
|
||||
static int ath_max_4ms_framelen[4][32] = {
|
||||
[MCS_HT20] = {
|
||||
3212, 6432, 9648, 12864, 19300, 25736, 28952, 32172,
|
||||
6424, 12852, 19280, 25708, 38568, 51424, 57852, 64280,
|
||||
9628, 19260, 28896, 38528, 57792, 65532, 65532, 65532,
|
||||
12828, 25656, 38488, 51320, 65532, 65532, 65532, 65532,
|
||||
},
|
||||
[MCS_HT20_SGI] = {
|
||||
3572, 7144, 10720, 14296, 21444, 28596, 32172, 35744,
|
||||
7140, 14284, 21428, 28568, 42856, 57144, 64288, 65532,
|
||||
10700, 21408, 32112, 42816, 64228, 65532, 65532, 65532,
|
||||
14256, 28516, 42780, 57040, 65532, 65532, 65532, 65532,
|
||||
},
|
||||
[MCS_HT40] = {
|
||||
6684, 13368, 20052, 26738, 40104, 53476, 60156, 66840,
|
||||
13360, 26720, 40080, 53440, 80160, 106880, 120240, 133600,
|
||||
6680, 13360, 20044, 26724, 40092, 53456, 60140, 65532,
|
||||
13348, 26700, 40052, 53400, 65532, 65532, 65532, 65532,
|
||||
20004, 40008, 60016, 65532, 65532, 65532, 65532, 65532,
|
||||
26644, 53292, 65532, 65532, 65532, 65532, 65532, 65532,
|
||||
},
|
||||
[MCS_HT40_SGI] = {
|
||||
/* TODO: Only MCS 7 and 15 updated, recalculate the rest */
|
||||
6684, 13368, 20052, 26738, 40104, 53476, 60156, 74200,
|
||||
13360, 26720, 40080, 53440, 80160, 106880, 120240, 148400,
|
||||
7420, 14844, 22272, 29696, 44544, 59396, 65532, 65532,
|
||||
14832, 29668, 44504, 59340, 65532, 65532, 65532, 65532,
|
||||
22232, 44464, 65532, 65532, 65532, 65532, 65532, 65532,
|
||||
29616, 59232, 65532, 65532, 65532, 65532, 65532, 65532,
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*********************/
|
||||
/* Aggregation logic */
|
||||
/*********************/
|
||||
@ -261,25 +265,46 @@ static void ath_tx_set_retry(struct ath_softc *sc, struct ath_txq *txq,
|
||||
hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_RETRY);
|
||||
}
|
||||
|
||||
static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc)
|
||||
{
|
||||
struct ath_buf *bf = NULL;
|
||||
|
||||
spin_lock_bh(&sc->tx.txbuflock);
|
||||
|
||||
if (unlikely(list_empty(&sc->tx.txbuf))) {
|
||||
spin_unlock_bh(&sc->tx.txbuflock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
|
||||
list_del(&bf->list);
|
||||
|
||||
spin_unlock_bh(&sc->tx.txbuflock);
|
||||
|
||||
return bf;
|
||||
}
|
||||
|
||||
static void ath_tx_return_buffer(struct ath_softc *sc, struct ath_buf *bf)
|
||||
{
|
||||
spin_lock_bh(&sc->tx.txbuflock);
|
||||
list_add_tail(&bf->list, &sc->tx.txbuf);
|
||||
spin_unlock_bh(&sc->tx.txbuflock);
|
||||
}
|
||||
|
||||
static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf)
|
||||
{
|
||||
struct ath_buf *tbf;
|
||||
|
||||
spin_lock_bh(&sc->tx.txbuflock);
|
||||
if (WARN_ON(list_empty(&sc->tx.txbuf))) {
|
||||
spin_unlock_bh(&sc->tx.txbuflock);
|
||||
tbf = ath_tx_get_buffer(sc);
|
||||
if (WARN_ON(!tbf))
|
||||
return NULL;
|
||||
}
|
||||
tbf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
|
||||
list_del(&tbf->list);
|
||||
spin_unlock_bh(&sc->tx.txbuflock);
|
||||
|
||||
ATH_TXBUF_RESET(tbf);
|
||||
|
||||
tbf->aphy = bf->aphy;
|
||||
tbf->bf_mpdu = bf->bf_mpdu;
|
||||
tbf->bf_buf_addr = bf->bf_buf_addr;
|
||||
*(tbf->bf_desc) = *(bf->bf_desc);
|
||||
memcpy(tbf->bf_desc, bf->bf_desc, sc->sc_ah->caps.tx_desc_len);
|
||||
tbf->bf_state = bf->bf_state;
|
||||
tbf->bf_dmacontext = bf->bf_dmacontext;
|
||||
|
||||
@ -359,7 +384,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
|
||||
acked_cnt++;
|
||||
} else {
|
||||
if (!(tid->state & AGGR_CLEANUP) &&
|
||||
ts->ts_flags != ATH9K_TX_SW_ABORTED) {
|
||||
!bf_last->bf_tx_aborted) {
|
||||
if (bf->bf_retries < ATH_MAX_SW_RETRIES) {
|
||||
ath_tx_set_retry(sc, txq, bf);
|
||||
txpending = 1;
|
||||
@ -378,7 +403,8 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
|
||||
}
|
||||
}
|
||||
|
||||
if (bf_next == NULL) {
|
||||
if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) &&
|
||||
bf_next == NULL) {
|
||||
/*
|
||||
* Make sure the last desc is reclaimed if it
|
||||
* not a holding desc.
|
||||
@ -412,36 +438,43 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
|
||||
!txfail, sendbar);
|
||||
} else {
|
||||
/* retry the un-acked ones */
|
||||
if (bf->bf_next == NULL && bf_last->bf_stale) {
|
||||
struct ath_buf *tbf;
|
||||
if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)) {
|
||||
if (bf->bf_next == NULL && bf_last->bf_stale) {
|
||||
struct ath_buf *tbf;
|
||||
|
||||
tbf = ath_clone_txbuf(sc, bf_last);
|
||||
/*
|
||||
* Update tx baw and complete the frame with
|
||||
* failed status if we run out of tx buf
|
||||
*/
|
||||
if (!tbf) {
|
||||
spin_lock_bh(&txq->axq_lock);
|
||||
ath_tx_update_baw(sc, tid,
|
||||
bf->bf_seqno);
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
tbf = ath_clone_txbuf(sc, bf_last);
|
||||
/*
|
||||
* Update tx baw and complete the
|
||||
* frame with failed status if we
|
||||
* run out of tx buf.
|
||||
*/
|
||||
if (!tbf) {
|
||||
spin_lock_bh(&txq->axq_lock);
|
||||
ath_tx_update_baw(sc, tid,
|
||||
bf->bf_seqno);
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
|
||||
bf->bf_state.bf_type |= BUF_XRETRY;
|
||||
ath_tx_rc_status(bf, ts, nbad,
|
||||
0, false);
|
||||
ath_tx_complete_buf(sc, bf, txq,
|
||||
&bf_head, ts, 0, 0);
|
||||
break;
|
||||
bf->bf_state.bf_type |=
|
||||
BUF_XRETRY;
|
||||
ath_tx_rc_status(bf, ts, nbad,
|
||||
0, false);
|
||||
ath_tx_complete_buf(sc, bf, txq,
|
||||
&bf_head,
|
||||
ts, 0, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
ath9k_hw_cleartxdesc(sc->sc_ah,
|
||||
tbf->bf_desc);
|
||||
list_add_tail(&tbf->list, &bf_head);
|
||||
} else {
|
||||
/*
|
||||
* Clear descriptor status words for
|
||||
* software retry
|
||||
*/
|
||||
ath9k_hw_cleartxdesc(sc->sc_ah,
|
||||
bf->bf_desc);
|
||||
}
|
||||
|
||||
ath9k_hw_cleartxdesc(sc->sc_ah, tbf->bf_desc);
|
||||
list_add_tail(&tbf->list, &bf_head);
|
||||
} else {
|
||||
/*
|
||||
* Clear descriptor status words for
|
||||
* software retry
|
||||
*/
|
||||
ath9k_hw_cleartxdesc(sc->sc_ah, bf->bf_desc);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -509,12 +542,13 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
|
||||
break;
|
||||
}
|
||||
|
||||
if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI)
|
||||
modeidx = MCS_HT40_SGI;
|
||||
else if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
|
||||
if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
|
||||
modeidx = MCS_HT40;
|
||||
else
|
||||
modeidx = MCS_DEFAULT;
|
||||
modeidx = MCS_HT20;
|
||||
|
||||
if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI)
|
||||
modeidx++;
|
||||
|
||||
frmlen = ath_max_4ms_framelen[modeidx][rates[i].idx];
|
||||
max_4ms_framelen = min(max_4ms_framelen, frmlen);
|
||||
@ -559,7 +593,7 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
|
||||
u32 nsymbits, nsymbols;
|
||||
u16 minlen;
|
||||
u8 flags, rix;
|
||||
int width, half_gi, ndelim, mindelim;
|
||||
int width, streams, half_gi, ndelim, mindelim;
|
||||
|
||||
/* Select standard number of delimiters based on frame length alone */
|
||||
ndelim = ATH_AGGR_GET_NDELIM(frmlen);
|
||||
@ -599,7 +633,8 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
|
||||
if (nsymbols == 0)
|
||||
nsymbols = 1;
|
||||
|
||||
nsymbits = bits_per_symbol[rix][width];
|
||||
streams = HT_RC_2_STREAMS(rix);
|
||||
nsymbits = bits_per_symbol[rix % 8][width] * streams;
|
||||
minlen = (nsymbols * nsymbits) / BITS_PER_BYTE;
|
||||
|
||||
if (frmlen < minlen) {
|
||||
@ -665,7 +700,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
|
||||
bpad = PADBYTES(al_delta) + (ndelim << 2);
|
||||
|
||||
bf->bf_next = NULL;
|
||||
bf->bf_desc->ds_link = 0;
|
||||
ath9k_hw_set_desc_link(sc->sc_ah, bf->bf_desc, 0);
|
||||
|
||||
/* link buffers of this frame to the aggregate */
|
||||
ath_tx_addto_baw(sc, tid, bf);
|
||||
@ -673,7 +708,8 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
|
||||
list_move_tail(&bf->list, bf_q);
|
||||
if (bf_prev) {
|
||||
bf_prev->bf_next = bf;
|
||||
bf_prev->bf_desc->ds_link = bf->bf_daddr;
|
||||
ath9k_hw_set_desc_link(sc->sc_ah, bf_prev->bf_desc,
|
||||
bf->bf_daddr);
|
||||
}
|
||||
bf_prev = bf;
|
||||
|
||||
@ -853,7 +889,7 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ath9k_tx_queue_info qi;
|
||||
int qnum;
|
||||
int qnum, i;
|
||||
|
||||
memset(&qi, 0, sizeof(qi));
|
||||
qi.tqi_subtype = subtype;
|
||||
@ -877,11 +913,16 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
|
||||
* The UAPSD queue is an exception, since we take a desc-
|
||||
* based intr on the EOSP frames.
|
||||
*/
|
||||
if (qtype == ATH9K_TX_QUEUE_UAPSD)
|
||||
qi.tqi_qflags = TXQ_FLAG_TXDESCINT_ENABLE;
|
||||
else
|
||||
qi.tqi_qflags = TXQ_FLAG_TXEOLINT_ENABLE |
|
||||
TXQ_FLAG_TXDESCINT_ENABLE;
|
||||
if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
|
||||
qi.tqi_qflags = TXQ_FLAG_TXOKINT_ENABLE |
|
||||
TXQ_FLAG_TXERRINT_ENABLE;
|
||||
} else {
|
||||
if (qtype == ATH9K_TX_QUEUE_UAPSD)
|
||||
qi.tqi_qflags = TXQ_FLAG_TXDESCINT_ENABLE;
|
||||
else
|
||||
qi.tqi_qflags = TXQ_FLAG_TXEOLINT_ENABLE |
|
||||
TXQ_FLAG_TXDESCINT_ENABLE;
|
||||
}
|
||||
qnum = ath9k_hw_setuptxqueue(ah, qtype, &qi);
|
||||
if (qnum == -1) {
|
||||
/*
|
||||
@ -908,6 +949,11 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
|
||||
txq->axq_depth = 0;
|
||||
txq->axq_tx_inprogress = false;
|
||||
sc->tx.txqsetup |= 1<<qnum;
|
||||
|
||||
txq->txq_headidx = txq->txq_tailidx = 0;
|
||||
for (i = 0; i < ATH_TXFIFO_DEPTH; i++)
|
||||
INIT_LIST_HEAD(&txq->txq_fifo[i]);
|
||||
INIT_LIST_HEAD(&txq->txq_fifo_pending);
|
||||
}
|
||||
return &sc->tx.txq[qnum];
|
||||
}
|
||||
@ -1035,36 +1081,52 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
|
||||
struct ath_tx_status ts;
|
||||
|
||||
memset(&ts, 0, sizeof(ts));
|
||||
if (!retry_tx)
|
||||
ts.ts_flags = ATH9K_TX_SW_ABORTED;
|
||||
|
||||
INIT_LIST_HEAD(&bf_head);
|
||||
|
||||
for (;;) {
|
||||
spin_lock_bh(&txq->axq_lock);
|
||||
|
||||
if (list_empty(&txq->axq_q)) {
|
||||
txq->axq_link = NULL;
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
break;
|
||||
}
|
||||
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
|
||||
if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) {
|
||||
txq->txq_headidx = txq->txq_tailidx = 0;
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
break;
|
||||
} else {
|
||||
bf = list_first_entry(&txq->txq_fifo[txq->txq_tailidx],
|
||||
struct ath_buf, list);
|
||||
}
|
||||
} else {
|
||||
if (list_empty(&txq->axq_q)) {
|
||||
txq->axq_link = NULL;
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
break;
|
||||
}
|
||||
bf = list_first_entry(&txq->axq_q, struct ath_buf,
|
||||
list);
|
||||
|
||||
bf = list_first_entry(&txq->axq_q, struct ath_buf, list);
|
||||
if (bf->bf_stale) {
|
||||
list_del(&bf->list);
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
|
||||
if (bf->bf_stale) {
|
||||
list_del(&bf->list);
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
|
||||
spin_lock_bh(&sc->tx.txbuflock);
|
||||
list_add_tail(&bf->list, &sc->tx.txbuf);
|
||||
spin_unlock_bh(&sc->tx.txbuflock);
|
||||
continue;
|
||||
ath_tx_return_buffer(sc, bf);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
lastbf = bf->bf_lastbf;
|
||||
if (!retry_tx)
|
||||
lastbf->bf_tx_aborted = true;
|
||||
|
||||
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
|
||||
list_cut_position(&bf_head,
|
||||
&txq->txq_fifo[txq->txq_tailidx],
|
||||
&lastbf->list);
|
||||
INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH);
|
||||
} else {
|
||||
/* remove ath_buf's of the same mpdu from txq */
|
||||
list_cut_position(&bf_head, &txq->axq_q, &lastbf->list);
|
||||
}
|
||||
|
||||
/* remove ath_buf's of the same mpdu from txq */
|
||||
list_cut_position(&bf_head, &txq->axq_q, &lastbf->list);
|
||||
txq->axq_depth--;
|
||||
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
@ -1087,6 +1149,27 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
}
|
||||
}
|
||||
|
||||
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
|
||||
spin_lock_bh(&txq->axq_lock);
|
||||
while (!list_empty(&txq->txq_fifo_pending)) {
|
||||
bf = list_first_entry(&txq->txq_fifo_pending,
|
||||
struct ath_buf, list);
|
||||
list_cut_position(&bf_head,
|
||||
&txq->txq_fifo_pending,
|
||||
&bf->bf_lastbf->list);
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
|
||||
if (bf_isampdu(bf))
|
||||
ath_tx_complete_aggr(sc, txq, bf, &bf_head,
|
||||
&ts, 0);
|
||||
else
|
||||
ath_tx_complete_buf(sc, bf, txq, &bf_head,
|
||||
&ts, 0, 0);
|
||||
spin_lock_bh(&txq->axq_lock);
|
||||
}
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
}
|
||||
}
|
||||
|
||||
void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
|
||||
@ -1224,44 +1307,47 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
|
||||
|
||||
bf = list_first_entry(head, struct ath_buf, list);
|
||||
|
||||
list_splice_tail_init(head, &txq->axq_q);
|
||||
txq->axq_depth++;
|
||||
|
||||
ath_print(common, ATH_DBG_QUEUE,
|
||||
"qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth);
|
||||
|
||||
if (txq->axq_link == NULL) {
|
||||
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
|
||||
if (txq->axq_depth >= ATH_TXFIFO_DEPTH) {
|
||||
list_splice_tail_init(head, &txq->txq_fifo_pending);
|
||||
return;
|
||||
}
|
||||
if (!list_empty(&txq->txq_fifo[txq->txq_headidx]))
|
||||
ath_print(common, ATH_DBG_XMIT,
|
||||
"Initializing tx fifo %d which "
|
||||
"is non-empty\n",
|
||||
txq->txq_headidx);
|
||||
INIT_LIST_HEAD(&txq->txq_fifo[txq->txq_headidx]);
|
||||
list_splice_init(head, &txq->txq_fifo[txq->txq_headidx]);
|
||||
INCR(txq->txq_headidx, ATH_TXFIFO_DEPTH);
|
||||
ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
|
||||
ath_print(common, ATH_DBG_XMIT,
|
||||
"TXDP[%u] = %llx (%p)\n",
|
||||
txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc);
|
||||
} else {
|
||||
*txq->axq_link = bf->bf_daddr;
|
||||
ath_print(common, ATH_DBG_XMIT, "link[%u] (%p)=%llx (%p)\n",
|
||||
txq->axq_qnum, txq->axq_link,
|
||||
ito64(bf->bf_daddr), bf->bf_desc);
|
||||
list_splice_tail_init(head, &txq->axq_q);
|
||||
|
||||
if (txq->axq_link == NULL) {
|
||||
ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
|
||||
ath_print(common, ATH_DBG_XMIT,
|
||||
"TXDP[%u] = %llx (%p)\n",
|
||||
txq->axq_qnum, ito64(bf->bf_daddr),
|
||||
bf->bf_desc);
|
||||
} else {
|
||||
*txq->axq_link = bf->bf_daddr;
|
||||
ath_print(common, ATH_DBG_XMIT,
|
||||
"link[%u] (%p)=%llx (%p)\n",
|
||||
txq->axq_qnum, txq->axq_link,
|
||||
ito64(bf->bf_daddr), bf->bf_desc);
|
||||
}
|
||||
ath9k_hw_get_desc_link(ah, bf->bf_lastbf->bf_desc,
|
||||
&txq->axq_link);
|
||||
ath9k_hw_txstart(ah, txq->axq_qnum);
|
||||
}
|
||||
txq->axq_link = &(bf->bf_lastbf->bf_desc->ds_link);
|
||||
ath9k_hw_txstart(ah, txq->axq_qnum);
|
||||
}
|
||||
|
||||
static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc)
|
||||
{
|
||||
struct ath_buf *bf = NULL;
|
||||
|
||||
spin_lock_bh(&sc->tx.txbuflock);
|
||||
|
||||
if (unlikely(list_empty(&sc->tx.txbuf))) {
|
||||
spin_unlock_bh(&sc->tx.txbuflock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
|
||||
list_del(&bf->list);
|
||||
|
||||
spin_unlock_bh(&sc->tx.txbuflock);
|
||||
|
||||
return bf;
|
||||
txq->axq_depth++;
|
||||
}
|
||||
|
||||
static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
|
||||
@ -1408,8 +1494,7 @@ static void assign_aggr_tid_seqno(struct sk_buff *skb,
|
||||
INCR(tid->seq_next, IEEE80211_SEQ_MAX);
|
||||
}
|
||||
|
||||
static int setup_tx_flags(struct ath_softc *sc, struct sk_buff *skb,
|
||||
struct ath_txq *txq)
|
||||
static int setup_tx_flags(struct sk_buff *skb, bool use_ldpc)
|
||||
{
|
||||
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
|
||||
int flags = 0;
|
||||
@ -1420,6 +1505,9 @@ static int setup_tx_flags(struct ath_softc *sc, struct sk_buff *skb,
|
||||
if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK)
|
||||
flags |= ATH9K_TXDESC_NOACK;
|
||||
|
||||
if (use_ldpc)
|
||||
flags |= ATH9K_TXDESC_LDPC;
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
@ -1438,8 +1526,9 @@ static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf,
|
||||
pktlen = bf_isaggr(bf) ? bf->bf_al : bf->bf_frmlen;
|
||||
|
||||
/* find number of symbols: PLCP + data */
|
||||
streams = HT_RC_2_STREAMS(rix);
|
||||
nbits = (pktlen << 3) + OFDM_PLCP_BITS;
|
||||
nsymbits = bits_per_symbol[rix][width];
|
||||
nsymbits = bits_per_symbol[rix % 8][width] * streams;
|
||||
nsymbols = (nbits + nsymbits - 1) / nsymbits;
|
||||
|
||||
if (!half_gi)
|
||||
@ -1448,7 +1537,6 @@ static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf,
|
||||
duration = SYMBOL_TIME_HALFGI(nsymbols);
|
||||
|
||||
/* addup duration for legacy/ht training and signal fields */
|
||||
streams = HT_RC_2_STREAMS(rix);
|
||||
duration += L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams);
|
||||
|
||||
return duration;
|
||||
@ -1519,6 +1607,8 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
|
||||
series[i].Rate = rix | 0x80;
|
||||
series[i].PktDuration = ath_pkt_duration(sc, rix, bf,
|
||||
is_40, is_sgi, is_sp);
|
||||
if (rix < 8 && (tx_info->flags & IEEE80211_TX_CTL_STBC))
|
||||
series[i].RateFlags |= ATH9K_RATESERIES_STBC;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1571,6 +1661,7 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
|
||||
int hdrlen;
|
||||
__le16 fc;
|
||||
int padpos, padsize;
|
||||
bool use_ldpc = false;
|
||||
|
||||
tx_info->pad[0] = 0;
|
||||
switch (txctl->frame_type) {
|
||||
@ -1597,10 +1688,13 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
|
||||
bf->bf_frmlen -= padsize;
|
||||
}
|
||||
|
||||
if (conf_is_ht(&hw->conf))
|
||||
if (conf_is_ht(&hw->conf)) {
|
||||
bf->bf_state.bf_type |= BUF_HT;
|
||||
if (tx_info->flags & IEEE80211_TX_CTL_LDPC)
|
||||
use_ldpc = true;
|
||||
}
|
||||
|
||||
bf->bf_flags = setup_tx_flags(sc, skb, txctl->txq);
|
||||
bf->bf_flags = setup_tx_flags(skb, use_ldpc);
|
||||
|
||||
bf->bf_keytype = get_hw_crypto_keytype(skb);
|
||||
if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR) {
|
||||
@ -1659,8 +1753,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
|
||||
list_add_tail(&bf->list, &bf_head);
|
||||
|
||||
ds = bf->bf_desc;
|
||||
ds->ds_link = 0;
|
||||
ds->ds_data = bf->bf_buf_addr;
|
||||
ath9k_hw_set_desc_link(ah, ds, 0);
|
||||
|
||||
ath9k_hw_set11n_txdesc(ah, ds, bf->bf_frmlen, frm_type, MAX_RATE_POWER,
|
||||
bf->bf_keyix, bf->bf_keytype, bf->bf_flags);
|
||||
@ -1669,7 +1762,9 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
|
||||
skb->len, /* segment length */
|
||||
true, /* first segment */
|
||||
true, /* last segment */
|
||||
ds); /* first descriptor */
|
||||
ds, /* first descriptor */
|
||||
bf->bf_buf_addr,
|
||||
txctl->txq->axq_qnum);
|
||||
|
||||
spin_lock_bh(&txctl->txq->axq_lock);
|
||||
|
||||
@ -1738,9 +1833,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
|
||||
}
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
|
||||
spin_lock_bh(&sc->tx.txbuflock);
|
||||
list_add_tail(&bf->list, &sc->tx.txbuf);
|
||||
spin_unlock_bh(&sc->tx.txbuflock);
|
||||
ath_tx_return_buffer(sc, bf);
|
||||
|
||||
return r;
|
||||
}
|
||||
@ -1896,7 +1989,7 @@ static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
|
||||
int nbad = 0;
|
||||
int isaggr = 0;
|
||||
|
||||
if (ts->ts_flags == ATH9K_TX_SW_ABORTED)
|
||||
if (bf->bf_tx_aborted)
|
||||
return 0;
|
||||
|
||||
isaggr = bf_isaggr(bf);
|
||||
@ -2054,13 +2147,12 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
|
||||
txq->axq_depth--;
|
||||
txok = !(ts.ts_status & ATH9K_TXERR_MASK);
|
||||
txq->axq_tx_inprogress = false;
|
||||
if (bf_held)
|
||||
list_del(&bf_held->list);
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
|
||||
if (bf_held) {
|
||||
spin_lock_bh(&sc->tx.txbuflock);
|
||||
list_move_tail(&bf_held->list, &sc->tx.txbuf);
|
||||
spin_unlock_bh(&sc->tx.txbuflock);
|
||||
}
|
||||
if (bf_held)
|
||||
ath_tx_return_buffer(sc, bf_held);
|
||||
|
||||
if (!bf_isampdu(bf)) {
|
||||
/*
|
||||
@ -2138,10 +2230,119 @@ void ath_tx_tasklet(struct ath_softc *sc)
|
||||
}
|
||||
}
|
||||
|
||||
void ath_tx_edma_tasklet(struct ath_softc *sc)
|
||||
{
|
||||
struct ath_tx_status txs;
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_txq *txq;
|
||||
struct ath_buf *bf, *lastbf;
|
||||
struct list_head bf_head;
|
||||
int status;
|
||||
int txok;
|
||||
|
||||
for (;;) {
|
||||
status = ath9k_hw_txprocdesc(ah, NULL, (void *)&txs);
|
||||
if (status == -EINPROGRESS)
|
||||
break;
|
||||
if (status == -EIO) {
|
||||
ath_print(common, ATH_DBG_XMIT,
|
||||
"Error processing tx status\n");
|
||||
break;
|
||||
}
|
||||
|
||||
/* Skip beacon completions */
|
||||
if (txs.qid == sc->beacon.beaconq)
|
||||
continue;
|
||||
|
||||
txq = &sc->tx.txq[txs.qid];
|
||||
|
||||
spin_lock_bh(&txq->axq_lock);
|
||||
if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) {
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
bf = list_first_entry(&txq->txq_fifo[txq->txq_tailidx],
|
||||
struct ath_buf, list);
|
||||
lastbf = bf->bf_lastbf;
|
||||
|
||||
INIT_LIST_HEAD(&bf_head);
|
||||
list_cut_position(&bf_head, &txq->txq_fifo[txq->txq_tailidx],
|
||||
&lastbf->list);
|
||||
INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH);
|
||||
txq->axq_depth--;
|
||||
txq->axq_tx_inprogress = false;
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
|
||||
txok = !(txs.ts_status & ATH9K_TXERR_MASK);
|
||||
|
||||
if (!bf_isampdu(bf)) {
|
||||
bf->bf_retries = txs.ts_longretry;
|
||||
if (txs.ts_status & ATH9K_TXERR_XRETRY)
|
||||
bf->bf_state.bf_type |= BUF_XRETRY;
|
||||
ath_tx_rc_status(bf, &txs, 0, txok, true);
|
||||
}
|
||||
|
||||
if (bf_isampdu(bf))
|
||||
ath_tx_complete_aggr(sc, txq, bf, &bf_head, &txs, txok);
|
||||
else
|
||||
ath_tx_complete_buf(sc, bf, txq, &bf_head,
|
||||
&txs, txok, 0);
|
||||
|
||||
spin_lock_bh(&txq->axq_lock);
|
||||
if (!list_empty(&txq->txq_fifo_pending)) {
|
||||
INIT_LIST_HEAD(&bf_head);
|
||||
bf = list_first_entry(&txq->txq_fifo_pending,
|
||||
struct ath_buf, list);
|
||||
list_cut_position(&bf_head, &txq->txq_fifo_pending,
|
||||
&bf->bf_lastbf->list);
|
||||
ath_tx_txqaddbuf(sc, txq, &bf_head);
|
||||
} else if (sc->sc_flags & SC_OP_TXAGGR)
|
||||
ath_txq_schedule(sc, txq);
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************/
|
||||
/* Init, Cleanup */
|
||||
/*****************/
|
||||
|
||||
static int ath_txstatus_setup(struct ath_softc *sc, int size)
|
||||
{
|
||||
struct ath_descdma *dd = &sc->txsdma;
|
||||
u8 txs_len = sc->sc_ah->caps.txs_len;
|
||||
|
||||
dd->dd_desc_len = size * txs_len;
|
||||
dd->dd_desc = dma_alloc_coherent(sc->dev, dd->dd_desc_len,
|
||||
&dd->dd_desc_paddr, GFP_KERNEL);
|
||||
if (!dd->dd_desc)
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath_tx_edma_init(struct ath_softc *sc)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = ath_txstatus_setup(sc, ATH_TXSTATUS_RING_SIZE);
|
||||
if (!err)
|
||||
ath9k_hw_setup_statusring(sc->sc_ah, sc->txsdma.dd_desc,
|
||||
sc->txsdma.dd_desc_paddr,
|
||||
ATH_TXSTATUS_RING_SIZE);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void ath_tx_edma_cleanup(struct ath_softc *sc)
|
||||
{
|
||||
struct ath_descdma *dd = &sc->txsdma;
|
||||
|
||||
dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
|
||||
dd->dd_desc_paddr);
|
||||
}
|
||||
|
||||
int ath_tx_init(struct ath_softc *sc, int nbufs)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
@ -2150,7 +2351,7 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
|
||||
spin_lock_init(&sc->tx.txbuflock);
|
||||
|
||||
error = ath_descdma_setup(sc, &sc->tx.txdma, &sc->tx.txbuf,
|
||||
"tx", nbufs, 1);
|
||||
"tx", nbufs, 1, 1);
|
||||
if (error != 0) {
|
||||
ath_print(common, ATH_DBG_FATAL,
|
||||
"Failed to allocate tx descriptors: %d\n", error);
|
||||
@ -2158,7 +2359,7 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
|
||||
}
|
||||
|
||||
error = ath_descdma_setup(sc, &sc->beacon.bdma, &sc->beacon.bbuf,
|
||||
"beacon", ATH_BCBUF, 1);
|
||||
"beacon", ATH_BCBUF, 1, 1);
|
||||
if (error != 0) {
|
||||
ath_print(common, ATH_DBG_FATAL,
|
||||
"Failed to allocate beacon descriptors: %d\n", error);
|
||||
@ -2167,6 +2368,12 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
|
||||
|
||||
INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work);
|
||||
|
||||
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
|
||||
error = ath_tx_edma_init(sc);
|
||||
if (error)
|
||||
goto err;
|
||||
}
|
||||
|
||||
err:
|
||||
if (error != 0)
|
||||
ath_tx_cleanup(sc);
|
||||
@ -2181,6 +2388,9 @@ void ath_tx_cleanup(struct ath_softc *sc)
|
||||
|
||||
if (sc->tx.txdma.dd_desc_len != 0)
|
||||
ath_descdma_cleanup(sc, &sc->tx.txdma, &sc->tx.txbuf);
|
||||
|
||||
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
|
||||
ath_tx_edma_cleanup(sc);
|
||||
}
|
||||
|
||||
void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
|
||||
|
@ -12,6 +12,7 @@ obj-$(CONFIG_IWLAGN) += iwlagn.o
|
||||
iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o iwl-agn-ict.o
|
||||
iwlagn-objs += iwl-agn-ucode.o iwl-agn-hcmd.o iwl-agn-tx.o
|
||||
iwlagn-objs += iwl-agn-lib.o
|
||||
iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-agn-debugfs.o
|
||||
|
||||
iwlagn-$(CONFIG_IWL4965) += iwl-4965.o
|
||||
iwlagn-$(CONFIG_IWL5000) += iwl-5000.o
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include "iwl-helpers.h"
|
||||
#include "iwl-agn-hw.h"
|
||||
#include "iwl-agn-led.h"
|
||||
#include "iwl-agn-debugfs.h"
|
||||
|
||||
/* Highest firmware API version supported */
|
||||
#define IWL1000_UCODE_API_MAX 3
|
||||
@ -212,6 +213,11 @@ static struct iwl_lib_ops iwl1000_lib = {
|
||||
.set_ct_kill = iwl1000_set_ct_threshold,
|
||||
},
|
||||
.add_bcast_station = iwl_add_bcast_station,
|
||||
.debugfs_ops = {
|
||||
.rx_stats_read = iwl_ucode_rx_stats_read,
|
||||
.tx_stats_read = iwl_ucode_tx_stats_read,
|
||||
.general_stats_read = iwl_ucode_general_stats_read,
|
||||
},
|
||||
.recover_from_tx_stall = iwl_bg_monitor_recover,
|
||||
.check_plcp_health = iwl_good_plcp_health,
|
||||
.check_ack_health = iwl_good_ack_health,
|
||||
|
@ -2688,6 +2688,7 @@ IWL3945_UCODE_GET(boot_size);
|
||||
static struct iwl_hcmd_ops iwl3945_hcmd = {
|
||||
.rxon_assoc = iwl3945_send_rxon_assoc,
|
||||
.commit_rxon = iwl3945_commit_rxon,
|
||||
.send_bt_config = iwl_send_bt_config,
|
||||
};
|
||||
|
||||
static struct iwl_ucode_ops iwl3945_ucode = {
|
||||
@ -2741,6 +2742,7 @@ static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
|
||||
.get_hcmd_size = iwl3945_get_hcmd_size,
|
||||
.build_addsta_hcmd = iwl3945_build_addsta_hcmd,
|
||||
.rts_tx_cmd_flag = iwlcore_rts_tx_cmd_flag,
|
||||
.request_scan = iwl3945_request_scan,
|
||||
};
|
||||
|
||||
static const struct iwl_ops iwl3945_ops = {
|
||||
|
@ -294,6 +294,9 @@ extern const struct iwl_channel_info *iwl3945_get_channel_info(
|
||||
|
||||
extern int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate);
|
||||
|
||||
/* scanning */
|
||||
void iwl3945_request_scan(struct iwl_priv *priv);
|
||||
|
||||
/* Requires full declaration of iwl_priv before including */
|
||||
#include "iwl-io.h"
|
||||
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include "iwl-sta.h"
|
||||
#include "iwl-agn-led.h"
|
||||
#include "iwl-agn.h"
|
||||
#include "iwl-agn-debugfs.h"
|
||||
|
||||
static int iwl4965_send_tx_power(struct iwl_priv *priv);
|
||||
static int iwl4965_hw_get_temperature(struct iwl_priv *priv);
|
||||
@ -2143,6 +2144,7 @@ static struct iwl_hcmd_ops iwl4965_hcmd = {
|
||||
.rxon_assoc = iwl4965_send_rxon_assoc,
|
||||
.commit_rxon = iwl_commit_rxon,
|
||||
.set_rxon_chain = iwl_set_rxon_chain,
|
||||
.send_bt_config = iwl_send_bt_config,
|
||||
};
|
||||
|
||||
static struct iwl_ucode_ops iwl4965_ucode = {
|
||||
@ -2162,6 +2164,7 @@ static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
|
||||
.gain_computation = iwl4965_gain_computation,
|
||||
.rts_tx_cmd_flag = iwlcore_rts_tx_cmd_flag,
|
||||
.calc_rssi = iwl4965_calc_rssi,
|
||||
.request_scan = iwlagn_request_scan,
|
||||
};
|
||||
|
||||
static struct iwl_lib_ops iwl4965_lib = {
|
||||
@ -2216,6 +2219,11 @@ static struct iwl_lib_ops iwl4965_lib = {
|
||||
.set_ct_kill = iwl4965_set_ct_threshold,
|
||||
},
|
||||
.add_bcast_station = iwl_add_bcast_station,
|
||||
.debugfs_ops = {
|
||||
.rx_stats_read = iwl_ucode_rx_stats_read,
|
||||
.tx_stats_read = iwl_ucode_tx_stats_read,
|
||||
.general_stats_read = iwl_ucode_general_stats_read,
|
||||
},
|
||||
.check_plcp_health = iwl_good_plcp_health,
|
||||
};
|
||||
|
||||
@ -2253,8 +2261,13 @@ struct iwl_cfg iwl4965_agn_cfg = {
|
||||
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
|
||||
.monitor_recover_period = IWL_MONITORING_PERIOD,
|
||||
.temperature_kelvin = true,
|
||||
.off_channel_workaround = true,
|
||||
.max_event_log_size = 512,
|
||||
|
||||
/*
|
||||
* Force use of chains B and C for scan RX on 5 GHz band
|
||||
* because the device has off-channel reception on chain A.
|
||||
*/
|
||||
.scan_antennas[IEEE80211_BAND_5GHZ] = ANT_BC,
|
||||
};
|
||||
|
||||
/* Module firmware */
|
||||
|
@ -48,6 +48,7 @@
|
||||
#include "iwl-agn-led.h"
|
||||
#include "iwl-agn-hw.h"
|
||||
#include "iwl-5000-hw.h"
|
||||
#include "iwl-agn-debugfs.h"
|
||||
|
||||
/* Highest firmware API version supported */
|
||||
#define IWL5000_UCODE_API_MAX 2
|
||||
@ -320,6 +321,11 @@ static struct iwl_lib_ops iwl5000_lib = {
|
||||
.set_ct_kill = iwl5000_set_ct_threshold,
|
||||
},
|
||||
.add_bcast_station = iwl_add_bcast_station,
|
||||
.debugfs_ops = {
|
||||
.rx_stats_read = iwl_ucode_rx_stats_read,
|
||||
.tx_stats_read = iwl_ucode_tx_stats_read,
|
||||
.general_stats_read = iwl_ucode_general_stats_read,
|
||||
},
|
||||
.recover_from_tx_stall = iwl_bg_monitor_recover,
|
||||
.check_plcp_health = iwl_good_plcp_health,
|
||||
.check_ack_health = iwl_good_ack_health,
|
||||
@ -377,6 +383,11 @@ static struct iwl_lib_ops iwl5150_lib = {
|
||||
.set_ct_kill = iwl5150_set_ct_threshold,
|
||||
},
|
||||
.add_bcast_station = iwl_add_bcast_station,
|
||||
.debugfs_ops = {
|
||||
.rx_stats_read = iwl_ucode_rx_stats_read,
|
||||
.tx_stats_read = iwl_ucode_tx_stats_read,
|
||||
.general_stats_read = iwl_ucode_general_stats_read,
|
||||
},
|
||||
.recover_from_tx_stall = iwl_bg_monitor_recover,
|
||||
.check_plcp_health = iwl_good_plcp_health,
|
||||
.check_ack_health = iwl_good_ack_health,
|
||||
|
@ -47,17 +47,19 @@
|
||||
#include "iwl-agn-hw.h"
|
||||
#include "iwl-6000-hw.h"
|
||||
#include "iwl-agn-led.h"
|
||||
#include "iwl-agn-debugfs.h"
|
||||
|
||||
/* Highest firmware API version supported */
|
||||
#define IWL6000_UCODE_API_MAX 4
|
||||
#define IWL6050_UCODE_API_MAX 4
|
||||
#define IWL6000G2_UCODE_API_MAX 4
|
||||
|
||||
/* Lowest firmware API version supported */
|
||||
#define IWL6000_UCODE_API_MIN 4
|
||||
#define IWL6050_UCODE_API_MIN 4
|
||||
#define IWL6000G2_UCODE_API_MIN 4
|
||||
|
||||
#define IWL6000_FW_PRE "iwlwifi-6000-"
|
||||
#define IWL6000_G2_FW_PRE "iwlwifi-6005-"
|
||||
#define _IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE #api ".ucode"
|
||||
#define IWL6000_MODULE_FIRMWARE(api) _IWL6000_MODULE_FIRMWARE(api)
|
||||
|
||||
@ -65,6 +67,10 @@
|
||||
#define _IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE #api ".ucode"
|
||||
#define IWL6050_MODULE_FIRMWARE(api) _IWL6050_MODULE_FIRMWARE(api)
|
||||
|
||||
#define IWL6000G2_FW_PRE "iwlwifi-6005-"
|
||||
#define _IWL6000G2_MODULE_FIRMWARE(api) IWL6000G2_FW_PRE #api ".ucode"
|
||||
#define IWL6000G2_MODULE_FIRMWARE(api) _IWL6000G2_MODULE_FIRMWARE(api)
|
||||
|
||||
static void iwl6000_set_ct_threshold(struct iwl_priv *priv)
|
||||
{
|
||||
/* want Celsius */
|
||||
@ -261,7 +267,6 @@ static struct iwl_lib_ops iwl6000_lib = {
|
||||
EEPROM_REG_BAND_3_CHANNELS,
|
||||
EEPROM_REG_BAND_4_CHANNELS,
|
||||
EEPROM_REG_BAND_5_CHANNELS,
|
||||
EEPROM_REG_BAND_24_HT40_CHANNELS,
|
||||
EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
|
||||
EEPROM_REG_BAND_52_HT40_CHANNELS
|
||||
},
|
||||
@ -280,6 +285,11 @@ static struct iwl_lib_ops iwl6000_lib = {
|
||||
.set_ct_kill = iwl6000_set_ct_threshold,
|
||||
},
|
||||
.add_bcast_station = iwl_add_bcast_station,
|
||||
.debugfs_ops = {
|
||||
.rx_stats_read = iwl_ucode_rx_stats_read,
|
||||
.tx_stats_read = iwl_ucode_tx_stats_read,
|
||||
.general_stats_read = iwl_ucode_general_stats_read,
|
||||
},
|
||||
.recover_from_tx_stall = iwl_bg_monitor_recover,
|
||||
.check_plcp_health = iwl_good_plcp_health,
|
||||
.check_ack_health = iwl_good_ack_health,
|
||||
@ -348,6 +358,11 @@ static struct iwl_lib_ops iwl6050_lib = {
|
||||
.set_calib_version = iwl6050_set_calib_version,
|
||||
},
|
||||
.add_bcast_station = iwl_add_bcast_station,
|
||||
.debugfs_ops = {
|
||||
.rx_stats_read = iwl_ucode_rx_stats_read,
|
||||
.tx_stats_read = iwl_ucode_tx_stats_read,
|
||||
.general_stats_read = iwl_ucode_general_stats_read,
|
||||
},
|
||||
.recover_from_tx_stall = iwl_bg_monitor_recover,
|
||||
.check_plcp_health = iwl_good_plcp_health,
|
||||
.check_ack_health = iwl_good_ack_health,
|
||||
@ -364,16 +379,16 @@ static const struct iwl_ops iwl6050_ops = {
|
||||
/*
|
||||
* "i": Internal configuration, use internal Power Amplifier
|
||||
*/
|
||||
struct iwl_cfg iwl6000i_g2_2agn_cfg = {
|
||||
struct iwl_cfg iwl6000g2_2agn_cfg = {
|
||||
.name = "6000 Series 2x2 AGN Gen2",
|
||||
.fw_name_pre = IWL6000_G2_FW_PRE,
|
||||
.ucode_api_max = IWL6000_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL6000_UCODE_API_MIN,
|
||||
.fw_name_pre = IWL6000G2_FW_PRE,
|
||||
.ucode_api_max = IWL6000G2_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL6000G2_UCODE_API_MIN,
|
||||
.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
|
||||
.ops = &iwl6000_ops,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE,
|
||||
.eeprom_ver = EEPROM_6000_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
@ -382,7 +397,7 @@ struct iwl_cfg iwl6000i_g2_2agn_cfg = {
|
||||
.pll_cfg_val = 0,
|
||||
.set_l0s = true,
|
||||
.use_bsm = false,
|
||||
.pa_type = IWL_PA_INTERNAL,
|
||||
.pa_type = IWL_PA_SYSTEM,
|
||||
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
|
||||
.shadow_ram_support = true,
|
||||
.ht_greenfield_support = true,
|
||||
@ -601,3 +616,4 @@ struct iwl_cfg iwl6000_3agn_cfg = {
|
||||
|
||||
MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL6000G2_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
|
||||
|
834
drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
Normal file
834
drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
Normal file
@ -0,0 +1,834 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
|
||||
* USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution
|
||||
* in the file called LICENSE.GPL.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*****************************************************************************/
|
||||
|
||||
#include "iwl-agn-debugfs.h"
|
||||
|
||||
ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct iwl_priv *priv = file->private_data;
|
||||
int pos = 0;
|
||||
char *buf;
|
||||
int bufsz = sizeof(struct statistics_rx_phy) * 40 +
|
||||
sizeof(struct statistics_rx_non_phy) * 40 +
|
||||
sizeof(struct statistics_rx_ht_phy) * 40 + 400;
|
||||
ssize_t ret;
|
||||
struct statistics_rx_phy *ofdm, *accum_ofdm, *delta_ofdm, *max_ofdm;
|
||||
struct statistics_rx_phy *cck, *accum_cck, *delta_cck, *max_cck;
|
||||
struct statistics_rx_non_phy *general, *accum_general;
|
||||
struct statistics_rx_non_phy *delta_general, *max_general;
|
||||
struct statistics_rx_ht_phy *ht, *accum_ht, *delta_ht, *max_ht;
|
||||
|
||||
if (!iwl_is_alive(priv))
|
||||
return -EAGAIN;
|
||||
|
||||
buf = kzalloc(bufsz, GFP_KERNEL);
|
||||
if (!buf) {
|
||||
IWL_ERR(priv, "Can not allocate Buffer\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/*
|
||||
* the statistic information display here is based on
|
||||
* the last statistics notification from uCode
|
||||
* might not reflect the current uCode activity
|
||||
*/
|
||||
ofdm = &priv->statistics.rx.ofdm;
|
||||
cck = &priv->statistics.rx.cck;
|
||||
general = &priv->statistics.rx.general;
|
||||
ht = &priv->statistics.rx.ofdm_ht;
|
||||
accum_ofdm = &priv->accum_statistics.rx.ofdm;
|
||||
accum_cck = &priv->accum_statistics.rx.cck;
|
||||
accum_general = &priv->accum_statistics.rx.general;
|
||||
accum_ht = &priv->accum_statistics.rx.ofdm_ht;
|
||||
delta_ofdm = &priv->delta_statistics.rx.ofdm;
|
||||
delta_cck = &priv->delta_statistics.rx.cck;
|
||||
delta_general = &priv->delta_statistics.rx.general;
|
||||
delta_ht = &priv->delta_statistics.rx.ofdm_ht;
|
||||
max_ofdm = &priv->max_delta.rx.ofdm;
|
||||
max_cck = &priv->max_delta.rx.cck;
|
||||
max_general = &priv->max_delta.rx.general;
|
||||
max_ht = &priv->max_delta.rx.ofdm_ht;
|
||||
|
||||
pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
|
||||
"acumulative delta max\n",
|
||||
"Statistics_Rx - OFDM:");
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"ina_cnt:", le32_to_cpu(ofdm->ina_cnt),
|
||||
accum_ofdm->ina_cnt,
|
||||
delta_ofdm->ina_cnt, max_ofdm->ina_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"fina_cnt:",
|
||||
le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt,
|
||||
delta_ofdm->fina_cnt, max_ofdm->fina_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"plcp_err:",
|
||||
le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err,
|
||||
delta_ofdm->plcp_err, max_ofdm->plcp_err);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n", "crc32_err:",
|
||||
le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err,
|
||||
delta_ofdm->crc32_err, max_ofdm->crc32_err);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n", "overrun_err:",
|
||||
le32_to_cpu(ofdm->overrun_err),
|
||||
accum_ofdm->overrun_err, delta_ofdm->overrun_err,
|
||||
max_ofdm->overrun_err);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"early_overrun_err:",
|
||||
le32_to_cpu(ofdm->early_overrun_err),
|
||||
accum_ofdm->early_overrun_err,
|
||||
delta_ofdm->early_overrun_err,
|
||||
max_ofdm->early_overrun_err);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"crc32_good:", le32_to_cpu(ofdm->crc32_good),
|
||||
accum_ofdm->crc32_good, delta_ofdm->crc32_good,
|
||||
max_ofdm->crc32_good);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n", "false_alarm_cnt:",
|
||||
le32_to_cpu(ofdm->false_alarm_cnt),
|
||||
accum_ofdm->false_alarm_cnt,
|
||||
delta_ofdm->false_alarm_cnt,
|
||||
max_ofdm->false_alarm_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"fina_sync_err_cnt:",
|
||||
le32_to_cpu(ofdm->fina_sync_err_cnt),
|
||||
accum_ofdm->fina_sync_err_cnt,
|
||||
delta_ofdm->fina_sync_err_cnt,
|
||||
max_ofdm->fina_sync_err_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n", "sfd_timeout:",
|
||||
le32_to_cpu(ofdm->sfd_timeout),
|
||||
accum_ofdm->sfd_timeout, delta_ofdm->sfd_timeout,
|
||||
max_ofdm->sfd_timeout);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n", "fina_timeout:",
|
||||
le32_to_cpu(ofdm->fina_timeout),
|
||||
accum_ofdm->fina_timeout, delta_ofdm->fina_timeout,
|
||||
max_ofdm->fina_timeout);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"unresponded_rts:",
|
||||
le32_to_cpu(ofdm->unresponded_rts),
|
||||
accum_ofdm->unresponded_rts,
|
||||
delta_ofdm->unresponded_rts,
|
||||
max_ofdm->unresponded_rts);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"rxe_frame_lmt_ovrun:",
|
||||
le32_to_cpu(ofdm->rxe_frame_limit_overrun),
|
||||
accum_ofdm->rxe_frame_limit_overrun,
|
||||
delta_ofdm->rxe_frame_limit_overrun,
|
||||
max_ofdm->rxe_frame_limit_overrun);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n", "sent_ack_cnt:",
|
||||
le32_to_cpu(ofdm->sent_ack_cnt),
|
||||
accum_ofdm->sent_ack_cnt, delta_ofdm->sent_ack_cnt,
|
||||
max_ofdm->sent_ack_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n", "sent_cts_cnt:",
|
||||
le32_to_cpu(ofdm->sent_cts_cnt),
|
||||
accum_ofdm->sent_cts_cnt, delta_ofdm->sent_cts_cnt,
|
||||
max_ofdm->sent_cts_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"sent_ba_rsp_cnt:",
|
||||
le32_to_cpu(ofdm->sent_ba_rsp_cnt),
|
||||
accum_ofdm->sent_ba_rsp_cnt,
|
||||
delta_ofdm->sent_ba_rsp_cnt,
|
||||
max_ofdm->sent_ba_rsp_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n", "dsp_self_kill:",
|
||||
le32_to_cpu(ofdm->dsp_self_kill),
|
||||
accum_ofdm->dsp_self_kill,
|
||||
delta_ofdm->dsp_self_kill,
|
||||
max_ofdm->dsp_self_kill);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"mh_format_err:",
|
||||
le32_to_cpu(ofdm->mh_format_err),
|
||||
accum_ofdm->mh_format_err,
|
||||
delta_ofdm->mh_format_err,
|
||||
max_ofdm->mh_format_err);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"re_acq_main_rssi_sum:",
|
||||
le32_to_cpu(ofdm->re_acq_main_rssi_sum),
|
||||
accum_ofdm->re_acq_main_rssi_sum,
|
||||
delta_ofdm->re_acq_main_rssi_sum,
|
||||
max_ofdm->re_acq_main_rssi_sum);
|
||||
|
||||
pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
|
||||
"acumulative delta max\n",
|
||||
"Statistics_Rx - CCK:");
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"ina_cnt:",
|
||||
le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt,
|
||||
delta_cck->ina_cnt, max_cck->ina_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"fina_cnt:",
|
||||
le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt,
|
||||
delta_cck->fina_cnt, max_cck->fina_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"plcp_err:",
|
||||
le32_to_cpu(cck->plcp_err), accum_cck->plcp_err,
|
||||
delta_cck->plcp_err, max_cck->plcp_err);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"crc32_err:",
|
||||
le32_to_cpu(cck->crc32_err), accum_cck->crc32_err,
|
||||
delta_cck->crc32_err, max_cck->crc32_err);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"overrun_err:",
|
||||
le32_to_cpu(cck->overrun_err),
|
||||
accum_cck->overrun_err, delta_cck->overrun_err,
|
||||
max_cck->overrun_err);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"early_overrun_err:",
|
||||
le32_to_cpu(cck->early_overrun_err),
|
||||
accum_cck->early_overrun_err,
|
||||
delta_cck->early_overrun_err,
|
||||
max_cck->early_overrun_err);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"crc32_good:",
|
||||
le32_to_cpu(cck->crc32_good), accum_cck->crc32_good,
|
||||
delta_cck->crc32_good, max_cck->crc32_good);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"false_alarm_cnt:",
|
||||
le32_to_cpu(cck->false_alarm_cnt),
|
||||
accum_cck->false_alarm_cnt,
|
||||
delta_cck->false_alarm_cnt, max_cck->false_alarm_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"fina_sync_err_cnt:",
|
||||
le32_to_cpu(cck->fina_sync_err_cnt),
|
||||
accum_cck->fina_sync_err_cnt,
|
||||
delta_cck->fina_sync_err_cnt,
|
||||
max_cck->fina_sync_err_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"sfd_timeout:",
|
||||
le32_to_cpu(cck->sfd_timeout),
|
||||
accum_cck->sfd_timeout, delta_cck->sfd_timeout,
|
||||
max_cck->sfd_timeout);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n", "fina_timeout:",
|
||||
le32_to_cpu(cck->fina_timeout),
|
||||
accum_cck->fina_timeout, delta_cck->fina_timeout,
|
||||
max_cck->fina_timeout);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"unresponded_rts:",
|
||||
le32_to_cpu(cck->unresponded_rts),
|
||||
accum_cck->unresponded_rts, delta_cck->unresponded_rts,
|
||||
max_cck->unresponded_rts);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"rxe_frame_lmt_ovrun:",
|
||||
le32_to_cpu(cck->rxe_frame_limit_overrun),
|
||||
accum_cck->rxe_frame_limit_overrun,
|
||||
delta_cck->rxe_frame_limit_overrun,
|
||||
max_cck->rxe_frame_limit_overrun);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n", "sent_ack_cnt:",
|
||||
le32_to_cpu(cck->sent_ack_cnt),
|
||||
accum_cck->sent_ack_cnt, delta_cck->sent_ack_cnt,
|
||||
max_cck->sent_ack_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n", "sent_cts_cnt:",
|
||||
le32_to_cpu(cck->sent_cts_cnt),
|
||||
accum_cck->sent_cts_cnt, delta_cck->sent_cts_cnt,
|
||||
max_cck->sent_cts_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n", "sent_ba_rsp_cnt:",
|
||||
le32_to_cpu(cck->sent_ba_rsp_cnt),
|
||||
accum_cck->sent_ba_rsp_cnt,
|
||||
delta_cck->sent_ba_rsp_cnt,
|
||||
max_cck->sent_ba_rsp_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n", "dsp_self_kill:",
|
||||
le32_to_cpu(cck->dsp_self_kill),
|
||||
accum_cck->dsp_self_kill, delta_cck->dsp_self_kill,
|
||||
max_cck->dsp_self_kill);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n", "mh_format_err:",
|
||||
le32_to_cpu(cck->mh_format_err),
|
||||
accum_cck->mh_format_err, delta_cck->mh_format_err,
|
||||
max_cck->mh_format_err);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"re_acq_main_rssi_sum:",
|
||||
le32_to_cpu(cck->re_acq_main_rssi_sum),
|
||||
accum_cck->re_acq_main_rssi_sum,
|
||||
delta_cck->re_acq_main_rssi_sum,
|
||||
max_cck->re_acq_main_rssi_sum);
|
||||
|
||||
pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
|
||||
"acumulative delta max\n",
|
||||
"Statistics_Rx - GENERAL:");
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n", "bogus_cts:",
|
||||
le32_to_cpu(general->bogus_cts),
|
||||
accum_general->bogus_cts, delta_general->bogus_cts,
|
||||
max_general->bogus_cts);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n", "bogus_ack:",
|
||||
le32_to_cpu(general->bogus_ack),
|
||||
accum_general->bogus_ack, delta_general->bogus_ack,
|
||||
max_general->bogus_ack);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"non_bssid_frames:",
|
||||
le32_to_cpu(general->non_bssid_frames),
|
||||
accum_general->non_bssid_frames,
|
||||
delta_general->non_bssid_frames,
|
||||
max_general->non_bssid_frames);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"filtered_frames:",
|
||||
le32_to_cpu(general->filtered_frames),
|
||||
accum_general->filtered_frames,
|
||||
delta_general->filtered_frames,
|
||||
max_general->filtered_frames);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"non_channel_beacons:",
|
||||
le32_to_cpu(general->non_channel_beacons),
|
||||
accum_general->non_channel_beacons,
|
||||
delta_general->non_channel_beacons,
|
||||
max_general->non_channel_beacons);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"channel_beacons:",
|
||||
le32_to_cpu(general->channel_beacons),
|
||||
accum_general->channel_beacons,
|
||||
delta_general->channel_beacons,
|
||||
max_general->channel_beacons);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"num_missed_bcon:",
|
||||
le32_to_cpu(general->num_missed_bcon),
|
||||
accum_general->num_missed_bcon,
|
||||
delta_general->num_missed_bcon,
|
||||
max_general->num_missed_bcon);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"adc_rx_saturation_time:",
|
||||
le32_to_cpu(general->adc_rx_saturation_time),
|
||||
accum_general->adc_rx_saturation_time,
|
||||
delta_general->adc_rx_saturation_time,
|
||||
max_general->adc_rx_saturation_time);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"ina_detect_search_tm:",
|
||||
le32_to_cpu(general->ina_detection_search_time),
|
||||
accum_general->ina_detection_search_time,
|
||||
delta_general->ina_detection_search_time,
|
||||
max_general->ina_detection_search_time);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"beacon_silence_rssi_a:",
|
||||
le32_to_cpu(general->beacon_silence_rssi_a),
|
||||
accum_general->beacon_silence_rssi_a,
|
||||
delta_general->beacon_silence_rssi_a,
|
||||
max_general->beacon_silence_rssi_a);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"beacon_silence_rssi_b:",
|
||||
le32_to_cpu(general->beacon_silence_rssi_b),
|
||||
accum_general->beacon_silence_rssi_b,
|
||||
delta_general->beacon_silence_rssi_b,
|
||||
max_general->beacon_silence_rssi_b);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"beacon_silence_rssi_c:",
|
||||
le32_to_cpu(general->beacon_silence_rssi_c),
|
||||
accum_general->beacon_silence_rssi_c,
|
||||
delta_general->beacon_silence_rssi_c,
|
||||
max_general->beacon_silence_rssi_c);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"interference_data_flag:",
|
||||
le32_to_cpu(general->interference_data_flag),
|
||||
accum_general->interference_data_flag,
|
||||
delta_general->interference_data_flag,
|
||||
max_general->interference_data_flag);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"channel_load:",
|
||||
le32_to_cpu(general->channel_load),
|
||||
accum_general->channel_load,
|
||||
delta_general->channel_load,
|
||||
max_general->channel_load);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"dsp_false_alarms:",
|
||||
le32_to_cpu(general->dsp_false_alarms),
|
||||
accum_general->dsp_false_alarms,
|
||||
delta_general->dsp_false_alarms,
|
||||
max_general->dsp_false_alarms);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"beacon_rssi_a:",
|
||||
le32_to_cpu(general->beacon_rssi_a),
|
||||
accum_general->beacon_rssi_a,
|
||||
delta_general->beacon_rssi_a,
|
||||
max_general->beacon_rssi_a);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"beacon_rssi_b:",
|
||||
le32_to_cpu(general->beacon_rssi_b),
|
||||
accum_general->beacon_rssi_b,
|
||||
delta_general->beacon_rssi_b,
|
||||
max_general->beacon_rssi_b);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"beacon_rssi_c:",
|
||||
le32_to_cpu(general->beacon_rssi_c),
|
||||
accum_general->beacon_rssi_c,
|
||||
delta_general->beacon_rssi_c,
|
||||
max_general->beacon_rssi_c);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"beacon_energy_a:",
|
||||
le32_to_cpu(general->beacon_energy_a),
|
||||
accum_general->beacon_energy_a,
|
||||
delta_general->beacon_energy_a,
|
||||
max_general->beacon_energy_a);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"beacon_energy_b:",
|
||||
le32_to_cpu(general->beacon_energy_b),
|
||||
accum_general->beacon_energy_b,
|
||||
delta_general->beacon_energy_b,
|
||||
max_general->beacon_energy_b);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"beacon_energy_c:",
|
||||
le32_to_cpu(general->beacon_energy_c),
|
||||
accum_general->beacon_energy_c,
|
||||
delta_general->beacon_energy_c,
|
||||
max_general->beacon_energy_c);
|
||||
|
||||
pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - OFDM_HT:\n");
|
||||
pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
|
||||
"acumulative delta max\n",
|
||||
"Statistics_Rx - OFDM_HT:");
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"plcp_err:",
|
||||
le32_to_cpu(ht->plcp_err), accum_ht->plcp_err,
|
||||
delta_ht->plcp_err, max_ht->plcp_err);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"overrun_err:",
|
||||
le32_to_cpu(ht->overrun_err), accum_ht->overrun_err,
|
||||
delta_ht->overrun_err, max_ht->overrun_err);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"early_overrun_err:",
|
||||
le32_to_cpu(ht->early_overrun_err),
|
||||
accum_ht->early_overrun_err,
|
||||
delta_ht->early_overrun_err,
|
||||
max_ht->early_overrun_err);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"crc32_good:",
|
||||
le32_to_cpu(ht->crc32_good), accum_ht->crc32_good,
|
||||
delta_ht->crc32_good, max_ht->crc32_good);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"crc32_err:",
|
||||
le32_to_cpu(ht->crc32_err), accum_ht->crc32_err,
|
||||
delta_ht->crc32_err, max_ht->crc32_err);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"mh_format_err:",
|
||||
le32_to_cpu(ht->mh_format_err),
|
||||
accum_ht->mh_format_err,
|
||||
delta_ht->mh_format_err, max_ht->mh_format_err);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"agg_crc32_good:",
|
||||
le32_to_cpu(ht->agg_crc32_good),
|
||||
accum_ht->agg_crc32_good,
|
||||
delta_ht->agg_crc32_good, max_ht->agg_crc32_good);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"agg_mpdu_cnt:",
|
||||
le32_to_cpu(ht->agg_mpdu_cnt),
|
||||
accum_ht->agg_mpdu_cnt,
|
||||
delta_ht->agg_mpdu_cnt, max_ht->agg_mpdu_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"agg_cnt:",
|
||||
le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt,
|
||||
delta_ht->agg_cnt, max_ht->agg_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"unsupport_mcs:",
|
||||
le32_to_cpu(ht->unsupport_mcs),
|
||||
accum_ht->unsupport_mcs,
|
||||
delta_ht->unsupport_mcs, max_ht->unsupport_mcs);
|
||||
|
||||
ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
|
||||
kfree(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t iwl_ucode_tx_stats_read(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct iwl_priv *priv = file->private_data;
|
||||
int pos = 0;
|
||||
char *buf;
|
||||
int bufsz = (sizeof(struct statistics_tx) * 48) + 250;
|
||||
ssize_t ret;
|
||||
struct statistics_tx *tx, *accum_tx, *delta_tx, *max_tx;
|
||||
|
||||
if (!iwl_is_alive(priv))
|
||||
return -EAGAIN;
|
||||
|
||||
buf = kzalloc(bufsz, GFP_KERNEL);
|
||||
if (!buf) {
|
||||
IWL_ERR(priv, "Can not allocate Buffer\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* the statistic information display here is based on
|
||||
* the last statistics notification from uCode
|
||||
* might not reflect the current uCode activity
|
||||
*/
|
||||
tx = &priv->statistics.tx;
|
||||
accum_tx = &priv->accum_statistics.tx;
|
||||
delta_tx = &priv->delta_statistics.tx;
|
||||
max_tx = &priv->max_delta.tx;
|
||||
pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
|
||||
"acumulative delta max\n",
|
||||
"Statistics_Tx:");
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"preamble:",
|
||||
le32_to_cpu(tx->preamble_cnt),
|
||||
accum_tx->preamble_cnt,
|
||||
delta_tx->preamble_cnt, max_tx->preamble_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"rx_detected_cnt:",
|
||||
le32_to_cpu(tx->rx_detected_cnt),
|
||||
accum_tx->rx_detected_cnt,
|
||||
delta_tx->rx_detected_cnt, max_tx->rx_detected_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"bt_prio_defer_cnt:",
|
||||
le32_to_cpu(tx->bt_prio_defer_cnt),
|
||||
accum_tx->bt_prio_defer_cnt,
|
||||
delta_tx->bt_prio_defer_cnt,
|
||||
max_tx->bt_prio_defer_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"bt_prio_kill_cnt:",
|
||||
le32_to_cpu(tx->bt_prio_kill_cnt),
|
||||
accum_tx->bt_prio_kill_cnt,
|
||||
delta_tx->bt_prio_kill_cnt,
|
||||
max_tx->bt_prio_kill_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"few_bytes_cnt:",
|
||||
le32_to_cpu(tx->few_bytes_cnt),
|
||||
accum_tx->few_bytes_cnt,
|
||||
delta_tx->few_bytes_cnt, max_tx->few_bytes_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"cts_timeout:",
|
||||
le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout,
|
||||
delta_tx->cts_timeout, max_tx->cts_timeout);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"ack_timeout:",
|
||||
le32_to_cpu(tx->ack_timeout),
|
||||
accum_tx->ack_timeout,
|
||||
delta_tx->ack_timeout, max_tx->ack_timeout);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"expected_ack_cnt:",
|
||||
le32_to_cpu(tx->expected_ack_cnt),
|
||||
accum_tx->expected_ack_cnt,
|
||||
delta_tx->expected_ack_cnt,
|
||||
max_tx->expected_ack_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"actual_ack_cnt:",
|
||||
le32_to_cpu(tx->actual_ack_cnt),
|
||||
accum_tx->actual_ack_cnt,
|
||||
delta_tx->actual_ack_cnt,
|
||||
max_tx->actual_ack_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"dump_msdu_cnt:",
|
||||
le32_to_cpu(tx->dump_msdu_cnt),
|
||||
accum_tx->dump_msdu_cnt,
|
||||
delta_tx->dump_msdu_cnt,
|
||||
max_tx->dump_msdu_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"abort_nxt_frame_mismatch:",
|
||||
le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt),
|
||||
accum_tx->burst_abort_next_frame_mismatch_cnt,
|
||||
delta_tx->burst_abort_next_frame_mismatch_cnt,
|
||||
max_tx->burst_abort_next_frame_mismatch_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"abort_missing_nxt_frame:",
|
||||
le32_to_cpu(tx->burst_abort_missing_next_frame_cnt),
|
||||
accum_tx->burst_abort_missing_next_frame_cnt,
|
||||
delta_tx->burst_abort_missing_next_frame_cnt,
|
||||
max_tx->burst_abort_missing_next_frame_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"cts_timeout_collision:",
|
||||
le32_to_cpu(tx->cts_timeout_collision),
|
||||
accum_tx->cts_timeout_collision,
|
||||
delta_tx->cts_timeout_collision,
|
||||
max_tx->cts_timeout_collision);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"ack_ba_timeout_collision:",
|
||||
le32_to_cpu(tx->ack_or_ba_timeout_collision),
|
||||
accum_tx->ack_or_ba_timeout_collision,
|
||||
delta_tx->ack_or_ba_timeout_collision,
|
||||
max_tx->ack_or_ba_timeout_collision);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"agg ba_timeout:",
|
||||
le32_to_cpu(tx->agg.ba_timeout),
|
||||
accum_tx->agg.ba_timeout,
|
||||
delta_tx->agg.ba_timeout,
|
||||
max_tx->agg.ba_timeout);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"agg ba_resched_frames:",
|
||||
le32_to_cpu(tx->agg.ba_reschedule_frames),
|
||||
accum_tx->agg.ba_reschedule_frames,
|
||||
delta_tx->agg.ba_reschedule_frames,
|
||||
max_tx->agg.ba_reschedule_frames);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"agg scd_query_agg_frame:",
|
||||
le32_to_cpu(tx->agg.scd_query_agg_frame_cnt),
|
||||
accum_tx->agg.scd_query_agg_frame_cnt,
|
||||
delta_tx->agg.scd_query_agg_frame_cnt,
|
||||
max_tx->agg.scd_query_agg_frame_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"agg scd_query_no_agg:",
|
||||
le32_to_cpu(tx->agg.scd_query_no_agg),
|
||||
accum_tx->agg.scd_query_no_agg,
|
||||
delta_tx->agg.scd_query_no_agg,
|
||||
max_tx->agg.scd_query_no_agg);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"agg scd_query_agg:",
|
||||
le32_to_cpu(tx->agg.scd_query_agg),
|
||||
accum_tx->agg.scd_query_agg,
|
||||
delta_tx->agg.scd_query_agg,
|
||||
max_tx->agg.scd_query_agg);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"agg scd_query_mismatch:",
|
||||
le32_to_cpu(tx->agg.scd_query_mismatch),
|
||||
accum_tx->agg.scd_query_mismatch,
|
||||
delta_tx->agg.scd_query_mismatch,
|
||||
max_tx->agg.scd_query_mismatch);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"agg frame_not_ready:",
|
||||
le32_to_cpu(tx->agg.frame_not_ready),
|
||||
accum_tx->agg.frame_not_ready,
|
||||
delta_tx->agg.frame_not_ready,
|
||||
max_tx->agg.frame_not_ready);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"agg underrun:",
|
||||
le32_to_cpu(tx->agg.underrun),
|
||||
accum_tx->agg.underrun,
|
||||
delta_tx->agg.underrun, max_tx->agg.underrun);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"agg bt_prio_kill:",
|
||||
le32_to_cpu(tx->agg.bt_prio_kill),
|
||||
accum_tx->agg.bt_prio_kill,
|
||||
delta_tx->agg.bt_prio_kill,
|
||||
max_tx->agg.bt_prio_kill);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"agg rx_ba_rsp_cnt:",
|
||||
le32_to_cpu(tx->agg.rx_ba_rsp_cnt),
|
||||
accum_tx->agg.rx_ba_rsp_cnt,
|
||||
delta_tx->agg.rx_ba_rsp_cnt,
|
||||
max_tx->agg.rx_ba_rsp_cnt);
|
||||
|
||||
ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
|
||||
kfree(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct iwl_priv *priv = file->private_data;
|
||||
int pos = 0;
|
||||
char *buf;
|
||||
int bufsz = sizeof(struct statistics_general) * 10 + 300;
|
||||
ssize_t ret;
|
||||
struct statistics_general *general, *accum_general;
|
||||
struct statistics_general *delta_general, *max_general;
|
||||
struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg;
|
||||
struct statistics_div *div, *accum_div, *delta_div, *max_div;
|
||||
|
||||
if (!iwl_is_alive(priv))
|
||||
return -EAGAIN;
|
||||
|
||||
buf = kzalloc(bufsz, GFP_KERNEL);
|
||||
if (!buf) {
|
||||
IWL_ERR(priv, "Can not allocate Buffer\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* the statistic information display here is based on
|
||||
* the last statistics notification from uCode
|
||||
* might not reflect the current uCode activity
|
||||
*/
|
||||
general = &priv->statistics.general;
|
||||
dbg = &priv->statistics.general.dbg;
|
||||
div = &priv->statistics.general.div;
|
||||
accum_general = &priv->accum_statistics.general;
|
||||
delta_general = &priv->delta_statistics.general;
|
||||
max_general = &priv->max_delta.general;
|
||||
accum_dbg = &priv->accum_statistics.general.dbg;
|
||||
delta_dbg = &priv->delta_statistics.general.dbg;
|
||||
max_dbg = &priv->max_delta.general.dbg;
|
||||
accum_div = &priv->accum_statistics.general.div;
|
||||
delta_div = &priv->delta_statistics.general.div;
|
||||
max_div = &priv->max_delta.general.div;
|
||||
pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
|
||||
"acumulative delta max\n",
|
||||
"Statistics_General:");
|
||||
pos += scnprintf(buf + pos, bufsz - pos, " %-30s %10u\n",
|
||||
"temperature:",
|
||||
le32_to_cpu(general->temperature));
|
||||
pos += scnprintf(buf + pos, bufsz - pos, " %-30s %10u\n",
|
||||
"temperature_m:",
|
||||
le32_to_cpu(general->temperature_m));
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"burst_check:",
|
||||
le32_to_cpu(dbg->burst_check),
|
||||
accum_dbg->burst_check,
|
||||
delta_dbg->burst_check, max_dbg->burst_check);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"burst_count:",
|
||||
le32_to_cpu(dbg->burst_count),
|
||||
accum_dbg->burst_count,
|
||||
delta_dbg->burst_count, max_dbg->burst_count);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"sleep_time:",
|
||||
le32_to_cpu(general->sleep_time),
|
||||
accum_general->sleep_time,
|
||||
delta_general->sleep_time, max_general->sleep_time);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"slots_out:",
|
||||
le32_to_cpu(general->slots_out),
|
||||
accum_general->slots_out,
|
||||
delta_general->slots_out, max_general->slots_out);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"slots_idle:",
|
||||
le32_to_cpu(general->slots_idle),
|
||||
accum_general->slots_idle,
|
||||
delta_general->slots_idle, max_general->slots_idle);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, "ttl_timestamp:\t\t\t%u\n",
|
||||
le32_to_cpu(general->ttl_timestamp));
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"tx_on_a:",
|
||||
le32_to_cpu(div->tx_on_a), accum_div->tx_on_a,
|
||||
delta_div->tx_on_a, max_div->tx_on_a);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"tx_on_b:",
|
||||
le32_to_cpu(div->tx_on_b), accum_div->tx_on_b,
|
||||
delta_div->tx_on_b, max_div->tx_on_b);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"exec_time:",
|
||||
le32_to_cpu(div->exec_time), accum_div->exec_time,
|
||||
delta_div->exec_time, max_div->exec_time);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"probe_time:",
|
||||
le32_to_cpu(div->probe_time), accum_div->probe_time,
|
||||
delta_div->probe_time, max_div->probe_time);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"rx_enable_counter:",
|
||||
le32_to_cpu(general->rx_enable_counter),
|
||||
accum_general->rx_enable_counter,
|
||||
delta_general->rx_enable_counter,
|
||||
max_general->rx_enable_counter);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
" %-30s %10u %10u %10u %10u\n",
|
||||
"num_of_sos_states:",
|
||||
le32_to_cpu(general->num_of_sos_states),
|
||||
accum_general->num_of_sos_states,
|
||||
delta_general->num_of_sos_states,
|
||||
max_general->num_of_sos_states);
|
||||
ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
|
||||
kfree(buf);
|
||||
return ret;
|
||||
}
|
56
drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h
Normal file
56
drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h
Normal file
@ -0,0 +1,56 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
|
||||
* USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution
|
||||
* in the file called LICENSE.GPL.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*****************************************************************************/
|
||||
|
||||
#include "iwl-dev.h"
|
||||
#include "iwl-core.h"
|
||||
#include "iwl-debug.h"
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos);
|
||||
ssize_t iwl_ucode_tx_stats_read(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos);
|
||||
ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos);
|
||||
#else
|
||||
static ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static ssize_t iwl_ucode_tx_stats_read(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
@ -262,6 +262,7 @@ struct iwl_hcmd_ops iwlagn_hcmd = {
|
||||
.commit_rxon = iwl_commit_rxon,
|
||||
.set_rxon_chain = iwl_set_rxon_chain,
|
||||
.set_tx_ant = iwlagn_send_tx_ant_config,
|
||||
.send_bt_config = iwl_send_bt_config,
|
||||
};
|
||||
|
||||
struct iwl_hcmd_utils_ops iwlagn_hcmd_utils = {
|
||||
@ -271,4 +272,5 @@ struct iwl_hcmd_utils_ops iwlagn_hcmd_utils = {
|
||||
.chain_noise_reset = iwlagn_chain_noise_reset,
|
||||
.rts_tx_cmd_flag = iwlagn_rts_tx_cmd_flag,
|
||||
.calc_rssi = iwlagn_calc_rssi,
|
||||
.request_scan = iwlagn_request_scan,
|
||||
};
|
||||
|
@ -331,7 +331,7 @@ u16 iwlagn_eeprom_calib_version(struct iwl_priv *priv)
|
||||
} *hdr;
|
||||
|
||||
hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(priv,
|
||||
EEPROM_5000_CALIB_ALL);
|
||||
EEPROM_CALIB_ALL);
|
||||
return hdr->version;
|
||||
|
||||
}
|
||||
@ -348,22 +348,22 @@ static u32 eeprom_indirect_address(const struct iwl_priv *priv, u32 address)
|
||||
|
||||
switch (address & INDIRECT_TYPE_MSK) {
|
||||
case INDIRECT_HOST:
|
||||
offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_HOST);
|
||||
offset = iwl_eeprom_query16(priv, EEPROM_LINK_HOST);
|
||||
break;
|
||||
case INDIRECT_GENERAL:
|
||||
offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_GENERAL);
|
||||
offset = iwl_eeprom_query16(priv, EEPROM_LINK_GENERAL);
|
||||
break;
|
||||
case INDIRECT_REGULATORY:
|
||||
offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_REGULATORY);
|
||||
offset = iwl_eeprom_query16(priv, EEPROM_LINK_REGULATORY);
|
||||
break;
|
||||
case INDIRECT_CALIBRATION:
|
||||
offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_CALIBRATION);
|
||||
offset = iwl_eeprom_query16(priv, EEPROM_LINK_CALIBRATION);
|
||||
break;
|
||||
case INDIRECT_PROCESS_ADJST:
|
||||
offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_PROCESS_ADJST);
|
||||
offset = iwl_eeprom_query16(priv, EEPROM_LINK_PROCESS_ADJST);
|
||||
break;
|
||||
case INDIRECT_OTHERS:
|
||||
offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_OTHERS);
|
||||
offset = iwl_eeprom_query16(priv, EEPROM_LINK_OTHERS);
|
||||
break;
|
||||
default:
|
||||
IWL_ERR(priv, "illegal indirect type: 0x%X\n",
|
||||
@ -1111,3 +1111,392 @@ void iwlagn_rx_reply_rx_phy(struct iwl_priv *priv,
|
||||
memcpy(&priv->_agn.last_phy_res, pkt->u.raw,
|
||||
sizeof(struct iwl_rx_phy_res));
|
||||
}
|
||||
|
||||
static int iwl_get_single_channel_for_scan(struct iwl_priv *priv,
|
||||
enum ieee80211_band band,
|
||||
struct iwl_scan_channel *scan_ch)
|
||||
{
|
||||
const struct ieee80211_supported_band *sband;
|
||||
const struct iwl_channel_info *ch_info;
|
||||
u16 passive_dwell = 0;
|
||||
u16 active_dwell = 0;
|
||||
int i, added = 0;
|
||||
u16 channel = 0;
|
||||
|
||||
sband = iwl_get_hw_mode(priv, band);
|
||||
if (!sband) {
|
||||
IWL_ERR(priv, "invalid band\n");
|
||||
return added;
|
||||
}
|
||||
|
||||
active_dwell = iwl_get_active_dwell_time(priv, band, 0);
|
||||
passive_dwell = iwl_get_passive_dwell_time(priv, band);
|
||||
|
||||
if (passive_dwell <= active_dwell)
|
||||
passive_dwell = active_dwell + 1;
|
||||
|
||||
/* only scan single channel, good enough to reset the RF */
|
||||
/* pick the first valid not in-use channel */
|
||||
if (band == IEEE80211_BAND_5GHZ) {
|
||||
for (i = 14; i < priv->channel_count; i++) {
|
||||
if (priv->channel_info[i].channel !=
|
||||
le16_to_cpu(priv->staging_rxon.channel)) {
|
||||
channel = priv->channel_info[i].channel;
|
||||
ch_info = iwl_get_channel_info(priv,
|
||||
band, channel);
|
||||
if (is_channel_valid(ch_info))
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < 14; i++) {
|
||||
if (priv->channel_info[i].channel !=
|
||||
le16_to_cpu(priv->staging_rxon.channel)) {
|
||||
channel =
|
||||
priv->channel_info[i].channel;
|
||||
ch_info = iwl_get_channel_info(priv,
|
||||
band, channel);
|
||||
if (is_channel_valid(ch_info))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (channel) {
|
||||
scan_ch->channel = cpu_to_le16(channel);
|
||||
scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
|
||||
scan_ch->active_dwell = cpu_to_le16(active_dwell);
|
||||
scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
|
||||
/* Set txpower levels to defaults */
|
||||
scan_ch->dsp_atten = 110;
|
||||
if (band == IEEE80211_BAND_5GHZ)
|
||||
scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
|
||||
else
|
||||
scan_ch->tx_gain = ((1 << 5) | (5 << 3));
|
||||
added++;
|
||||
} else
|
||||
IWL_ERR(priv, "no valid channel found\n");
|
||||
return added;
|
||||
}
|
||||
|
||||
static int iwl_get_channels_for_scan(struct iwl_priv *priv,
|
||||
enum ieee80211_band band,
|
||||
u8 is_active, u8 n_probes,
|
||||
struct iwl_scan_channel *scan_ch)
|
||||
{
|
||||
struct ieee80211_channel *chan;
|
||||
const struct ieee80211_supported_band *sband;
|
||||
const struct iwl_channel_info *ch_info;
|
||||
u16 passive_dwell = 0;
|
||||
u16 active_dwell = 0;
|
||||
int added, i;
|
||||
u16 channel;
|
||||
|
||||
sband = iwl_get_hw_mode(priv, band);
|
||||
if (!sband)
|
||||
return 0;
|
||||
|
||||
active_dwell = iwl_get_active_dwell_time(priv, band, n_probes);
|
||||
passive_dwell = iwl_get_passive_dwell_time(priv, band);
|
||||
|
||||
if (passive_dwell <= active_dwell)
|
||||
passive_dwell = active_dwell + 1;
|
||||
|
||||
for (i = 0, added = 0; i < priv->scan_request->n_channels; i++) {
|
||||
chan = priv->scan_request->channels[i];
|
||||
|
||||
if (chan->band != band)
|
||||
continue;
|
||||
|
||||
channel = ieee80211_frequency_to_channel(chan->center_freq);
|
||||
scan_ch->channel = cpu_to_le16(channel);
|
||||
|
||||
ch_info = iwl_get_channel_info(priv, band, channel);
|
||||
if (!is_channel_valid(ch_info)) {
|
||||
IWL_DEBUG_SCAN(priv, "Channel %d is INVALID for this band.\n",
|
||||
channel);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!is_active || is_channel_passive(ch_info) ||
|
||||
(chan->flags & IEEE80211_CHAN_PASSIVE_SCAN))
|
||||
scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
|
||||
else
|
||||
scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE;
|
||||
|
||||
if (n_probes)
|
||||
scan_ch->type |= IWL_SCAN_PROBE_MASK(n_probes);
|
||||
|
||||
scan_ch->active_dwell = cpu_to_le16(active_dwell);
|
||||
scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
|
||||
|
||||
/* Set txpower levels to defaults */
|
||||
scan_ch->dsp_atten = 110;
|
||||
|
||||
/* NOTE: if we were doing 6Mb OFDM for scans we'd use
|
||||
* power level:
|
||||
* scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3;
|
||||
*/
|
||||
if (band == IEEE80211_BAND_5GHZ)
|
||||
scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
|
||||
else
|
||||
scan_ch->tx_gain = ((1 << 5) | (5 << 3));
|
||||
|
||||
IWL_DEBUG_SCAN(priv, "Scanning ch=%d prob=0x%X [%s %d]\n",
|
||||
channel, le32_to_cpu(scan_ch->type),
|
||||
(scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) ?
|
||||
"ACTIVE" : "PASSIVE",
|
||||
(scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) ?
|
||||
active_dwell : passive_dwell);
|
||||
|
||||
scan_ch++;
|
||||
added++;
|
||||
}
|
||||
|
||||
IWL_DEBUG_SCAN(priv, "total channels to scan %d\n", added);
|
||||
return added;
|
||||
}
|
||||
|
||||
void iwlagn_request_scan(struct iwl_priv *priv)
|
||||
{
|
||||
struct iwl_host_cmd cmd = {
|
||||
.id = REPLY_SCAN_CMD,
|
||||
.len = sizeof(struct iwl_scan_cmd),
|
||||
.flags = CMD_SIZE_HUGE,
|
||||
};
|
||||
struct iwl_scan_cmd *scan;
|
||||
struct ieee80211_conf *conf = NULL;
|
||||
u32 rate_flags = 0;
|
||||
u16 cmd_len;
|
||||
u16 rx_chain = 0;
|
||||
enum ieee80211_band band;
|
||||
u8 n_probes = 0;
|
||||
u8 rx_ant = priv->hw_params.valid_rx_ant;
|
||||
u8 rate;
|
||||
bool is_active = false;
|
||||
int chan_mod;
|
||||
u8 active_chains;
|
||||
|
||||
conf = ieee80211_get_hw_conf(priv->hw);
|
||||
|
||||
cancel_delayed_work(&priv->scan_check);
|
||||
|
||||
if (!iwl_is_ready(priv)) {
|
||||
IWL_WARN(priv, "request scan called when driver not ready.\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Make sure the scan wasn't canceled before this queued work
|
||||
* was given the chance to run... */
|
||||
if (!test_bit(STATUS_SCANNING, &priv->status))
|
||||
goto done;
|
||||
|
||||
/* This should never be called or scheduled if there is currently
|
||||
* a scan active in the hardware. */
|
||||
if (test_bit(STATUS_SCAN_HW, &priv->status)) {
|
||||
IWL_DEBUG_INFO(priv, "Multiple concurrent scan requests in parallel. "
|
||||
"Ignoring second request.\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
|
||||
IWL_DEBUG_SCAN(priv, "Aborting scan due to device shutdown\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
|
||||
IWL_DEBUG_HC(priv, "Scan request while abort pending. Queuing.\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (iwl_is_rfkill(priv)) {
|
||||
IWL_DEBUG_HC(priv, "Aborting scan due to RF Kill activation\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!test_bit(STATUS_READY, &priv->status)) {
|
||||
IWL_DEBUG_HC(priv, "Scan request while uninitialized. Queuing.\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!priv->scan_cmd) {
|
||||
priv->scan_cmd = kmalloc(sizeof(struct iwl_scan_cmd) +
|
||||
IWL_MAX_SCAN_SIZE, GFP_KERNEL);
|
||||
if (!priv->scan_cmd) {
|
||||
IWL_DEBUG_SCAN(priv,
|
||||
"fail to allocate memory for scan\n");
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
scan = priv->scan_cmd;
|
||||
memset(scan, 0, sizeof(struct iwl_scan_cmd) + IWL_MAX_SCAN_SIZE);
|
||||
|
||||
scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
|
||||
scan->quiet_time = IWL_ACTIVE_QUIET_TIME;
|
||||
|
||||
if (iwl_is_associated(priv)) {
|
||||
u16 interval = 0;
|
||||
u32 extra;
|
||||
u32 suspend_time = 100;
|
||||
u32 scan_suspend_time = 100;
|
||||
unsigned long flags;
|
||||
|
||||
IWL_DEBUG_INFO(priv, "Scanning while associated...\n");
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
interval = priv->beacon_int;
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
scan->suspend_time = 0;
|
||||
scan->max_out_time = cpu_to_le32(200 * 1024);
|
||||
if (!interval)
|
||||
interval = suspend_time;
|
||||
|
||||
extra = (suspend_time / interval) << 22;
|
||||
scan_suspend_time = (extra |
|
||||
((suspend_time % interval) * 1024));
|
||||
scan->suspend_time = cpu_to_le32(scan_suspend_time);
|
||||
IWL_DEBUG_SCAN(priv, "suspend_time 0x%X beacon interval %d\n",
|
||||
scan_suspend_time, interval);
|
||||
}
|
||||
|
||||
if (priv->is_internal_short_scan) {
|
||||
IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n");
|
||||
} else if (priv->scan_request->n_ssids) {
|
||||
int i, p = 0;
|
||||
IWL_DEBUG_SCAN(priv, "Kicking off active scan\n");
|
||||
for (i = 0; i < priv->scan_request->n_ssids; i++) {
|
||||
/* always does wildcard anyway */
|
||||
if (!priv->scan_request->ssids[i].ssid_len)
|
||||
continue;
|
||||
scan->direct_scan[p].id = WLAN_EID_SSID;
|
||||
scan->direct_scan[p].len =
|
||||
priv->scan_request->ssids[i].ssid_len;
|
||||
memcpy(scan->direct_scan[p].ssid,
|
||||
priv->scan_request->ssids[i].ssid,
|
||||
priv->scan_request->ssids[i].ssid_len);
|
||||
n_probes++;
|
||||
p++;
|
||||
}
|
||||
is_active = true;
|
||||
} else
|
||||
IWL_DEBUG_SCAN(priv, "Start passive scan.\n");
|
||||
|
||||
scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
|
||||
scan->tx_cmd.sta_id = priv->hw_params.bcast_sta_id;
|
||||
scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
|
||||
|
||||
switch (priv->scan_band) {
|
||||
case IEEE80211_BAND_2GHZ:
|
||||
scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
|
||||
chan_mod = le32_to_cpu(priv->active_rxon.flags & RXON_FLG_CHANNEL_MODE_MSK)
|
||||
>> RXON_FLG_CHANNEL_MODE_POS;
|
||||
if (chan_mod == CHANNEL_MODE_PURE_40) {
|
||||
rate = IWL_RATE_6M_PLCP;
|
||||
} else {
|
||||
rate = IWL_RATE_1M_PLCP;
|
||||
rate_flags = RATE_MCS_CCK_MSK;
|
||||
}
|
||||
scan->good_CRC_th = 0;
|
||||
break;
|
||||
case IEEE80211_BAND_5GHZ:
|
||||
rate = IWL_RATE_6M_PLCP;
|
||||
/*
|
||||
* If active scaning is requested but a certain channel
|
||||
* is marked passive, we can do active scanning if we
|
||||
* detect transmissions.
|
||||
*/
|
||||
scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH : 0;
|
||||
break;
|
||||
default:
|
||||
IWL_WARN(priv, "Invalid scan band count\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
band = priv->scan_band;
|
||||
|
||||
if (priv->cfg->scan_antennas[band])
|
||||
rx_ant = priv->cfg->scan_antennas[band];
|
||||
|
||||
priv->scan_tx_ant[band] =
|
||||
iwl_toggle_tx_ant(priv, priv->scan_tx_ant[band]);
|
||||
rate_flags |= iwl_ant_idx_to_flags(priv->scan_tx_ant[band]);
|
||||
scan->tx_cmd.rate_n_flags = iwl_hw_set_rate_n_flags(rate, rate_flags);
|
||||
|
||||
/* In power save mode use one chain, otherwise use all chains */
|
||||
if (test_bit(STATUS_POWER_PMI, &priv->status)) {
|
||||
/* rx_ant has been set to all valid chains previously */
|
||||
active_chains = rx_ant &
|
||||
((u8)(priv->chain_noise_data.active_chains));
|
||||
if (!active_chains)
|
||||
active_chains = rx_ant;
|
||||
|
||||
IWL_DEBUG_SCAN(priv, "chain_noise_data.active_chains: %u\n",
|
||||
priv->chain_noise_data.active_chains);
|
||||
|
||||
rx_ant = first_antenna(active_chains);
|
||||
}
|
||||
/* MIMO is not used here, but value is required */
|
||||
rx_chain |= priv->hw_params.valid_rx_ant << RXON_RX_CHAIN_VALID_POS;
|
||||
rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS;
|
||||
rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS;
|
||||
rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS;
|
||||
scan->rx_chain = cpu_to_le16(rx_chain);
|
||||
if (!priv->is_internal_short_scan) {
|
||||
cmd_len = iwl_fill_probe_req(priv,
|
||||
(struct ieee80211_mgmt *)scan->data,
|
||||
priv->scan_request->ie,
|
||||
priv->scan_request->ie_len,
|
||||
IWL_MAX_SCAN_SIZE - sizeof(*scan));
|
||||
} else {
|
||||
cmd_len = iwl_fill_probe_req(priv,
|
||||
(struct ieee80211_mgmt *)scan->data,
|
||||
NULL, 0,
|
||||
IWL_MAX_SCAN_SIZE - sizeof(*scan));
|
||||
|
||||
}
|
||||
scan->tx_cmd.len = cpu_to_le16(cmd_len);
|
||||
|
||||
scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK |
|
||||
RXON_FILTER_BCON_AWARE_MSK);
|
||||
|
||||
if (priv->is_internal_short_scan) {
|
||||
scan->channel_count =
|
||||
iwl_get_single_channel_for_scan(priv, band,
|
||||
(void *)&scan->data[le16_to_cpu(
|
||||
scan->tx_cmd.len)]);
|
||||
} else {
|
||||
scan->channel_count =
|
||||
iwl_get_channels_for_scan(priv, band,
|
||||
is_active, n_probes,
|
||||
(void *)&scan->data[le16_to_cpu(
|
||||
scan->tx_cmd.len)]);
|
||||
}
|
||||
if (scan->channel_count == 0) {
|
||||
IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count);
|
||||
goto done;
|
||||
}
|
||||
|
||||
cmd.len += le16_to_cpu(scan->tx_cmd.len) +
|
||||
scan->channel_count * sizeof(struct iwl_scan_channel);
|
||||
cmd.data = scan;
|
||||
scan->len = cpu_to_le16(cmd.len);
|
||||
|
||||
set_bit(STATUS_SCAN_HW, &priv->status);
|
||||
if (iwl_send_cmd_sync(priv, &cmd))
|
||||
goto done;
|
||||
|
||||
queue_delayed_work(priv->workqueue, &priv->scan_check,
|
||||
IWL_SCAN_CHECK_WATCHDOG);
|
||||
|
||||
return;
|
||||
|
||||
done:
|
||||
/* Cannot perform scan. Make sure we clear scanning
|
||||
* bits from status so next scan request can be performed.
|
||||
* If we don't clear scanning status bit here all next scan
|
||||
* will fail
|
||||
*/
|
||||
clear_bit(STATUS_SCAN_HW, &priv->status);
|
||||
clear_bit(STATUS_SCANNING, &priv->status);
|
||||
/* inform mac80211 scan aborted */
|
||||
queue_work(priv->workqueue, &priv->scan_completed);
|
||||
}
|
||||
|
@ -295,11 +295,11 @@ static u32 rs_tl_get_load(struct iwl_lq_sta *lq_data, u8 tid)
|
||||
return tl->total;
|
||||
}
|
||||
|
||||
static void rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
|
||||
static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
|
||||
struct iwl_lq_sta *lq_data, u8 tid,
|
||||
struct ieee80211_sta *sta)
|
||||
{
|
||||
int ret;
|
||||
int ret = -EAGAIN;
|
||||
|
||||
if (rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) {
|
||||
IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n",
|
||||
@ -313,29 +313,29 @@ static void rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
|
||||
*/
|
||||
IWL_DEBUG_HT(priv, "Fail start Tx agg on tid: %d\n",
|
||||
tid);
|
||||
ret = ieee80211_stop_tx_ba_session(sta, tid,
|
||||
ieee80211_stop_tx_ba_session(sta, tid,
|
||||
WLAN_BACK_INITIATOR);
|
||||
}
|
||||
}
|
||||
} else
|
||||
IWL_ERR(priv, "Fail finding valid aggregation tid: %d\n", tid);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void rs_tl_turn_on_agg(struct iwl_priv *priv, u8 tid,
|
||||
struct iwl_lq_sta *lq_data,
|
||||
struct ieee80211_sta *sta)
|
||||
{
|
||||
if ((tid < TID_MAX_LOAD_COUNT))
|
||||
rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta);
|
||||
else if (tid == IWL_AGG_ALL_TID)
|
||||
for (tid = 0; tid < TID_MAX_LOAD_COUNT; tid++)
|
||||
rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta);
|
||||
if (priv->cfg->use_rts_for_ht) {
|
||||
/*
|
||||
* switch to RTS/CTS if it is the prefer protection method
|
||||
* for HT traffic
|
||||
*/
|
||||
IWL_DEBUG_HT(priv, "use RTS/CTS protection for HT\n");
|
||||
priv->staging_rxon.flags &= ~RXON_FLG_SELF_CTS_EN;
|
||||
iwlcore_commit_rxon(priv);
|
||||
if ((tid < TID_MAX_LOAD_COUNT) &&
|
||||
!rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta)) {
|
||||
if (priv->cfg->use_rts_for_ht) {
|
||||
/*
|
||||
* switch to RTS/CTS if it is the prefer protection
|
||||
* method for HT traffic
|
||||
*/
|
||||
IWL_DEBUG_HT(priv, "use RTS/CTS protection for HT\n");
|
||||
priv->staging_rxon.flags &= ~RXON_FLG_SELF_CTS_EN;
|
||||
iwlcore_commit_rxon(priv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2558,8 +2558,17 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i
|
||||
lq_sta->active_mimo3_rate);
|
||||
|
||||
/* These values will be overridden later */
|
||||
lq_sta->lq.general_params.single_stream_ant_msk = ANT_A;
|
||||
lq_sta->lq.general_params.dual_stream_ant_msk = ANT_AB;
|
||||
lq_sta->lq.general_params.single_stream_ant_msk =
|
||||
first_antenna(priv->hw_params.valid_tx_ant);
|
||||
lq_sta->lq.general_params.dual_stream_ant_msk =
|
||||
priv->hw_params.valid_tx_ant &
|
||||
~first_antenna(priv->hw_params.valid_tx_ant);
|
||||
if (!lq_sta->lq.general_params.dual_stream_ant_msk) {
|
||||
lq_sta->lq.general_params.dual_stream_ant_msk = ANT_AB;
|
||||
} else if (num_of_ant(priv->hw_params.valid_tx_ant) == 2) {
|
||||
lq_sta->lq.general_params.dual_stream_ant_msk =
|
||||
priv->hw_params.valid_tx_ant;
|
||||
}
|
||||
|
||||
/* as default allow aggregation for all tids */
|
||||
lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID;
|
||||
|
@ -167,7 +167,7 @@ static int iwlagn_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid,
|
||||
scd_q2ratid = ra_tid & IWL_SCD_QUEUE_RA_TID_MAP_RATID_MSK;
|
||||
|
||||
tbl_dw_addr = priv->scd_base_addr +
|
||||
IWL50_SCD_TRANSLATE_TBL_OFFSET_QUEUE(txq_id);
|
||||
IWLAGN_SCD_TRANSLATE_TBL_OFFSET_QUEUE(txq_id);
|
||||
|
||||
tbl_dw = iwl_read_targ_mem(priv, tbl_dw_addr);
|
||||
|
||||
@ -186,9 +186,9 @@ static void iwlagn_tx_queue_stop_scheduler(struct iwl_priv *priv, u16 txq_id)
|
||||
/* Simply stop the queue, but don't change any configuration;
|
||||
* the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */
|
||||
iwl_write_prph(priv,
|
||||
IWL50_SCD_QUEUE_STATUS_BITS(txq_id),
|
||||
(0 << IWL50_SCD_QUEUE_STTS_REG_POS_ACTIVE)|
|
||||
(1 << IWL50_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
|
||||
IWLAGN_SCD_QUEUE_STATUS_BITS(txq_id),
|
||||
(0 << IWLAGN_SCD_QUEUE_STTS_REG_POS_ACTIVE)|
|
||||
(1 << IWLAGN_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
|
||||
}
|
||||
|
||||
void iwlagn_set_wr_ptrs(struct iwl_priv *priv,
|
||||
@ -196,7 +196,7 @@ void iwlagn_set_wr_ptrs(struct iwl_priv *priv,
|
||||
{
|
||||
iwl_write_direct32(priv, HBUS_TARG_WRPTR,
|
||||
(index & 0xff) | (txq_id << 8));
|
||||
iwl_write_prph(priv, IWL50_SCD_QUEUE_RDPTR(txq_id), index);
|
||||
iwl_write_prph(priv, IWLAGN_SCD_QUEUE_RDPTR(txq_id), index);
|
||||
}
|
||||
|
||||
void iwlagn_tx_queue_set_status(struct iwl_priv *priv,
|
||||
@ -206,11 +206,11 @@ void iwlagn_tx_queue_set_status(struct iwl_priv *priv,
|
||||
int txq_id = txq->q.id;
|
||||
int active = test_bit(txq_id, &priv->txq_ctx_active_msk) ? 1 : 0;
|
||||
|
||||
iwl_write_prph(priv, IWL50_SCD_QUEUE_STATUS_BITS(txq_id),
|
||||
(active << IWL50_SCD_QUEUE_STTS_REG_POS_ACTIVE) |
|
||||
(tx_fifo_id << IWL50_SCD_QUEUE_STTS_REG_POS_TXF) |
|
||||
(1 << IWL50_SCD_QUEUE_STTS_REG_POS_WSL) |
|
||||
IWL50_SCD_QUEUE_STTS_REG_MSK);
|
||||
iwl_write_prph(priv, IWLAGN_SCD_QUEUE_STATUS_BITS(txq_id),
|
||||
(active << IWLAGN_SCD_QUEUE_STTS_REG_POS_ACTIVE) |
|
||||
(tx_fifo_id << IWLAGN_SCD_QUEUE_STTS_REG_POS_TXF) |
|
||||
(1 << IWLAGN_SCD_QUEUE_STTS_REG_POS_WSL) |
|
||||
IWLAGN_SCD_QUEUE_STTS_REG_MSK);
|
||||
|
||||
txq->sched_retry = scd_retry;
|
||||
|
||||
@ -250,10 +250,10 @@ int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id,
|
||||
iwlagn_tx_queue_set_q2ratid(priv, ra_tid, txq_id);
|
||||
|
||||
/* Set this queue as a chain-building queue */
|
||||
iwl_set_bits_prph(priv, IWL50_SCD_QUEUECHAIN_SEL, (1<<txq_id));
|
||||
iwl_set_bits_prph(priv, IWLAGN_SCD_QUEUECHAIN_SEL, (1<<txq_id));
|
||||
|
||||
/* enable aggregations for the queue */
|
||||
iwl_set_bits_prph(priv, IWL50_SCD_AGGR_SEL, (1<<txq_id));
|
||||
iwl_set_bits_prph(priv, IWLAGN_SCD_AGGR_SEL, (1<<txq_id));
|
||||
|
||||
/* Place first TFD at index corresponding to start sequence number.
|
||||
* Assumes that ssn_idx is valid (!= 0xFFF) */
|
||||
@ -263,16 +263,16 @@ int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id,
|
||||
|
||||
/* Set up Tx window size and frame limit for this queue */
|
||||
iwl_write_targ_mem(priv, priv->scd_base_addr +
|
||||
IWL50_SCD_CONTEXT_QUEUE_OFFSET(txq_id) +
|
||||
IWLAGN_SCD_CONTEXT_QUEUE_OFFSET(txq_id) +
|
||||
sizeof(u32),
|
||||
((SCD_WIN_SIZE <<
|
||||
IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &
|
||||
IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |
|
||||
IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &
|
||||
IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |
|
||||
((SCD_FRAME_LIMIT <<
|
||||
IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
|
||||
IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
|
||||
IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
|
||||
IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
|
||||
|
||||
iwl_set_bits_prph(priv, IWL50_SCD_INTERRUPT_MASK, (1 << txq_id));
|
||||
iwl_set_bits_prph(priv, IWLAGN_SCD_INTERRUPT_MASK, (1 << txq_id));
|
||||
|
||||
/* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */
|
||||
iwlagn_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 1);
|
||||
@ -298,14 +298,14 @@ int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
|
||||
|
||||
iwlagn_tx_queue_stop_scheduler(priv, txq_id);
|
||||
|
||||
iwl_clear_bits_prph(priv, IWL50_SCD_AGGR_SEL, (1 << txq_id));
|
||||
iwl_clear_bits_prph(priv, IWLAGN_SCD_AGGR_SEL, (1 << txq_id));
|
||||
|
||||
priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff);
|
||||
priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff);
|
||||
/* supposes that ssn_idx is valid (!= 0xFFF) */
|
||||
iwlagn_set_wr_ptrs(priv, txq_id, ssn_idx);
|
||||
|
||||
iwl_clear_bits_prph(priv, IWL50_SCD_INTERRUPT_MASK, (1 << txq_id));
|
||||
iwl_clear_bits_prph(priv, IWLAGN_SCD_INTERRUPT_MASK, (1 << txq_id));
|
||||
iwl_txq_ctx_deactivate(priv, txq_id);
|
||||
iwlagn_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 0);
|
||||
|
||||
@ -318,7 +318,7 @@ int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
|
||||
*/
|
||||
void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask)
|
||||
{
|
||||
iwl_write_prph(priv, IWL50_SCD_TXFACT, mask);
|
||||
iwl_write_prph(priv, IWLAGN_SCD_TXFACT, mask);
|
||||
}
|
||||
|
||||
static inline int get_queue_from_ac(u16 ac)
|
||||
|
@ -207,7 +207,7 @@ static int iwlagn_set_Xtal_calib(struct iwl_priv *priv)
|
||||
{
|
||||
struct iwl_calib_xtal_freq_cmd cmd;
|
||||
__le16 *xtal_calib =
|
||||
(__le16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_XTAL);
|
||||
(__le16 *)iwl_eeprom_query_addr(priv, EEPROM_XTAL);
|
||||
|
||||
cmd.hdr.op_code = IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD;
|
||||
cmd.hdr.first_group = 0;
|
||||
@ -329,19 +329,19 @@ int iwlagn_alive_notify(struct iwl_priv *priv)
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
|
||||
priv->scd_base_addr = iwl_read_prph(priv, IWL50_SCD_SRAM_BASE_ADDR);
|
||||
a = priv->scd_base_addr + IWL50_SCD_CONTEXT_DATA_OFFSET;
|
||||
for (; a < priv->scd_base_addr + IWL50_SCD_TX_STTS_BITMAP_OFFSET;
|
||||
priv->scd_base_addr = iwl_read_prph(priv, IWLAGN_SCD_SRAM_BASE_ADDR);
|
||||
a = priv->scd_base_addr + IWLAGN_SCD_CONTEXT_DATA_OFFSET;
|
||||
for (; a < priv->scd_base_addr + IWLAGN_SCD_TX_STTS_BITMAP_OFFSET;
|
||||
a += 4)
|
||||
iwl_write_targ_mem(priv, a, 0);
|
||||
for (; a < priv->scd_base_addr + IWL50_SCD_TRANSLATE_TBL_OFFSET;
|
||||
for (; a < priv->scd_base_addr + IWLAGN_SCD_TRANSLATE_TBL_OFFSET;
|
||||
a += 4)
|
||||
iwl_write_targ_mem(priv, a, 0);
|
||||
for (; a < priv->scd_base_addr +
|
||||
IWL50_SCD_TRANSLATE_TBL_OFFSET_QUEUE(priv->hw_params.max_txq_num); a += 4)
|
||||
IWLAGN_SCD_TRANSLATE_TBL_OFFSET_QUEUE(priv->hw_params.max_txq_num); a += 4)
|
||||
iwl_write_targ_mem(priv, a, 0);
|
||||
|
||||
iwl_write_prph(priv, IWL50_SCD_DRAM_BASE_ADDR,
|
||||
iwl_write_prph(priv, IWLAGN_SCD_DRAM_BASE_ADDR,
|
||||
priv->scd_bc_tbls.dma >> 10);
|
||||
|
||||
/* Enable DMA channel */
|
||||
@ -355,28 +355,28 @@ int iwlagn_alive_notify(struct iwl_priv *priv)
|
||||
iwl_write_direct32(priv, FH_TX_CHICKEN_BITS_REG,
|
||||
reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN);
|
||||
|
||||
iwl_write_prph(priv, IWL50_SCD_QUEUECHAIN_SEL,
|
||||
IWL50_SCD_QUEUECHAIN_SEL_ALL(priv->hw_params.max_txq_num));
|
||||
iwl_write_prph(priv, IWL50_SCD_AGGR_SEL, 0);
|
||||
iwl_write_prph(priv, IWLAGN_SCD_QUEUECHAIN_SEL,
|
||||
IWLAGN_SCD_QUEUECHAIN_SEL_ALL(priv->hw_params.max_txq_num));
|
||||
iwl_write_prph(priv, IWLAGN_SCD_AGGR_SEL, 0);
|
||||
|
||||
/* initiate the queues */
|
||||
for (i = 0; i < priv->hw_params.max_txq_num; i++) {
|
||||
iwl_write_prph(priv, IWL50_SCD_QUEUE_RDPTR(i), 0);
|
||||
iwl_write_prph(priv, IWLAGN_SCD_QUEUE_RDPTR(i), 0);
|
||||
iwl_write_direct32(priv, HBUS_TARG_WRPTR, 0 | (i << 8));
|
||||
iwl_write_targ_mem(priv, priv->scd_base_addr +
|
||||
IWL50_SCD_CONTEXT_QUEUE_OFFSET(i), 0);
|
||||
IWLAGN_SCD_CONTEXT_QUEUE_OFFSET(i), 0);
|
||||
iwl_write_targ_mem(priv, priv->scd_base_addr +
|
||||
IWL50_SCD_CONTEXT_QUEUE_OFFSET(i) +
|
||||
IWLAGN_SCD_CONTEXT_QUEUE_OFFSET(i) +
|
||||
sizeof(u32),
|
||||
((SCD_WIN_SIZE <<
|
||||
IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &
|
||||
IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |
|
||||
IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &
|
||||
IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |
|
||||
((SCD_FRAME_LIMIT <<
|
||||
IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
|
||||
IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
|
||||
IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
|
||||
IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
|
||||
}
|
||||
|
||||
iwl_write_prph(priv, IWL50_SCD_INTERRUPT_MASK,
|
||||
iwl_write_prph(priv, IWLAGN_SCD_INTERRUPT_MASK,
|
||||
IWL_MASK(0, priv->hw_params.max_txq_num));
|
||||
|
||||
/* Activate all Tx DMA/FIFO channels */
|
||||
|
@ -2174,7 +2174,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
|
||||
}
|
||||
|
||||
/* Configure Bluetooth device coexistence support */
|
||||
iwl_send_bt_config(priv);
|
||||
priv->cfg->ops->hcmd->send_bt_config(priv);
|
||||
|
||||
iwl_reset_run_time_calib(priv);
|
||||
|
||||
@ -3178,44 +3178,6 @@ static ssize_t store_tx_power(struct device *d,
|
||||
|
||||
static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, show_tx_power, store_tx_power);
|
||||
|
||||
static ssize_t show_statistics(struct device *d,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct iwl_priv *priv = dev_get_drvdata(d);
|
||||
u32 size = sizeof(struct iwl_notif_statistics);
|
||||
u32 len = 0, ofs = 0;
|
||||
u8 *data = (u8 *)&priv->statistics;
|
||||
int rc = 0;
|
||||
|
||||
if (!iwl_is_alive(priv))
|
||||
return -EAGAIN;
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
rc = iwl_send_statistics_request(priv, CMD_SYNC, false);
|
||||
mutex_unlock(&priv->mutex);
|
||||
|
||||
if (rc) {
|
||||
len = sprintf(buf,
|
||||
"Error sending statistics request: 0x%08X\n", rc);
|
||||
return len;
|
||||
}
|
||||
|
||||
while (size && (PAGE_SIZE - len)) {
|
||||
hex_dump_to_buffer(data + ofs, size, 16, 1, buf + len,
|
||||
PAGE_SIZE - len, 1);
|
||||
len = strlen(buf);
|
||||
if (PAGE_SIZE - len)
|
||||
buf[len++] = '\n';
|
||||
|
||||
ofs += 16;
|
||||
size -= min(size, 16U);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(statistics, S_IRUGO, show_statistics, NULL);
|
||||
|
||||
static ssize_t show_rts_ht_protection(struct device *d,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
@ -3401,11 +3363,10 @@ static void iwl_uninit_drv(struct iwl_priv *priv)
|
||||
iwl_calib_free_results(priv);
|
||||
iwlcore_free_geos(priv);
|
||||
iwl_free_channel_map(priv);
|
||||
kfree(priv->scan);
|
||||
kfree(priv->scan_cmd);
|
||||
}
|
||||
|
||||
static struct attribute *iwl_sysfs_entries[] = {
|
||||
&dev_attr_statistics.attr,
|
||||
&dev_attr_temperature.attr,
|
||||
&dev_attr_tx_power.attr,
|
||||
&dev_attr_rts_ht_protection.attr,
|
||||
@ -3836,7 +3797,12 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
|
||||
{IWL_PCI_DEVICE(0x4238, 0x1111, iwl6000_3agn_cfg)},
|
||||
{IWL_PCI_DEVICE(0x4239, 0x1311, iwl6000i_2agn_cfg)},
|
||||
{IWL_PCI_DEVICE(0x4239, 0x1316, iwl6000i_2abg_cfg)},
|
||||
{IWL_PCI_DEVICE(0x0082, 0x1201, iwl6000i_g2_2agn_cfg)},
|
||||
|
||||
/* 6x00 Series Gen2 */
|
||||
{IWL_PCI_DEVICE(0x0082, 0x1201, iwl6000g2_2agn_cfg)},
|
||||
{IWL_PCI_DEVICE(0x0082, 0x1301, iwl6000g2_2agn_cfg)},
|
||||
{IWL_PCI_DEVICE(0x0082, 0x1321, iwl6000g2_2agn_cfg)},
|
||||
{IWL_PCI_DEVICE(0x0085, 0x1311, iwl6000g2_2agn_cfg)},
|
||||
|
||||
/* 6x50 WiFi/WiMax Series */
|
||||
{IWL_PCI_DEVICE(0x0087, 0x1301, iwl6050_2agn_cfg)},
|
||||
|
@ -171,4 +171,7 @@ static inline bool iwl_is_tx_success(u32 status)
|
||||
(status == TX_STATUS_DIRECT_DONE);
|
||||
}
|
||||
|
||||
/* scan */
|
||||
void iwlagn_request_scan(struct iwl_priv *priv);
|
||||
|
||||
#endif /* __iwl_agn_h__ */
|
||||
|
@ -1443,7 +1443,7 @@ struct iwl4965_rx_mpdu_res_start {
|
||||
|
||||
/* 1: Ignore Bluetooth priority for this frame.
|
||||
* 0: Delay Tx until Bluetooth device is done (normal usage). */
|
||||
#define TX_CMD_FLG_BT_DIS_MSK cpu_to_le32(1 << 12)
|
||||
#define TX_CMD_FLG_IGNORE_BT cpu_to_le32(1 << 12)
|
||||
|
||||
/* 1: uCode overrides sequence control field in MAC header.
|
||||
* 0: Driver provides sequence control field in MAC header.
|
||||
|
@ -828,19 +828,6 @@ static u8 iwl_count_chain_bitmap(u32 chain_bitmap)
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* iwl_is_monitor_mode - Determine if interface in monitor mode
|
||||
*
|
||||
* priv->iw_mode is set in add_interface, but add_interface is
|
||||
* never called for monitor mode. The only way mac80211 informs us about
|
||||
* monitor mode is through configuring filters (call to configure_filter).
|
||||
*/
|
||||
bool iwl_is_monitor_mode(struct iwl_priv *priv)
|
||||
{
|
||||
return !!(priv->staging_rxon.filter_flags & RXON_FILTER_PROMISC_MSK);
|
||||
}
|
||||
EXPORT_SYMBOL(iwl_is_monitor_mode);
|
||||
|
||||
/**
|
||||
* iwl_set_rxon_chain - Set up Rx chain usage in "staging" RXON image
|
||||
*
|
||||
@ -884,19 +871,6 @@ void iwl_set_rxon_chain(struct iwl_priv *priv)
|
||||
rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS;
|
||||
rx_chain |= idle_rx_cnt << RXON_RX_CHAIN_CNT_POS;
|
||||
|
||||
/* copied from 'iwl_bg_request_scan()' */
|
||||
/* Force use of chains B and C (0x6) for Rx
|
||||
* Avoid A (0x1) for the device has off-channel reception on A-band.
|
||||
* MIMO is not used here, but value is required */
|
||||
if (iwl_is_monitor_mode(priv) &&
|
||||
!(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) &&
|
||||
priv->cfg->off_channel_workaround) {
|
||||
rx_chain = ANT_ABC << RXON_RX_CHAIN_VALID_POS;
|
||||
rx_chain |= ANT_BC << RXON_RX_CHAIN_FORCE_SEL_POS;
|
||||
rx_chain |= ANT_ABC << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS;
|
||||
rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS;
|
||||
}
|
||||
|
||||
priv->staging_rxon.rx_chain = cpu_to_le16(rx_chain);
|
||||
|
||||
if (!is_single && (active_rx_cnt >= IWL_NUM_RX_CHAINS_SINGLE) && is_cam)
|
||||
@ -1480,7 +1454,7 @@ irqreturn_t iwl_isr_legacy(int irq, void *data)
|
||||
}
|
||||
EXPORT_SYMBOL(iwl_isr_legacy);
|
||||
|
||||
int iwl_send_bt_config(struct iwl_priv *priv)
|
||||
void iwl_send_bt_config(struct iwl_priv *priv)
|
||||
{
|
||||
struct iwl_bt_cmd bt_cmd = {
|
||||
.lead_time = BT_LEAD_TIME_DEF,
|
||||
@ -1497,8 +1471,9 @@ int iwl_send_bt_config(struct iwl_priv *priv)
|
||||
IWL_DEBUG_INFO(priv, "BT coex %s\n",
|
||||
(bt_cmd.flags == BT_COEX_DISABLE) ? "disable" : "active");
|
||||
|
||||
return iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG,
|
||||
sizeof(struct iwl_bt_cmd), &bt_cmd);
|
||||
if (iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG,
|
||||
sizeof(struct iwl_bt_cmd), &bt_cmd))
|
||||
IWL_ERR(priv, "failed to send BT Coex Config\n");
|
||||
}
|
||||
EXPORT_SYMBOL(iwl_send_bt_config);
|
||||
|
||||
@ -1868,7 +1843,6 @@ static inline void iwl_set_no_assoc(struct iwl_priv *priv)
|
||||
iwlcore_commit_rxon(priv);
|
||||
}
|
||||
|
||||
#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
|
||||
void iwl_bss_info_changed(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_bss_conf *bss_conf,
|
||||
@ -1989,14 +1963,6 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
|
||||
|
||||
iwl_led_associate(priv);
|
||||
|
||||
/*
|
||||
* We have just associated, don't start scan too early
|
||||
* leave time for EAPOL exchange to complete.
|
||||
*
|
||||
* XXX: do this in mac80211
|
||||
*/
|
||||
priv->next_scan_jiffies = jiffies +
|
||||
IWL_DELAY_NEXT_SCAN_AFTER_ASSOC;
|
||||
if (!iwl_is_rfkill(priv))
|
||||
priv->cfg->ops->lib->post_associate(priv);
|
||||
} else
|
||||
@ -2383,11 +2349,11 @@ EXPORT_SYMBOL(iwl_free_txq_mem);
|
||||
|
||||
int iwl_send_wimax_coex(struct iwl_priv *priv)
|
||||
{
|
||||
struct iwl_wimax_coex_cmd uninitialized_var(coex_cmd);
|
||||
struct iwl_wimax_coex_cmd coex_cmd;
|
||||
|
||||
if (priv->cfg->support_wimax_coexist) {
|
||||
/* UnMask wake up src at associated sleep */
|
||||
coex_cmd.flags |= COEX_FLAGS_ASSOC_WA_UNMASK_MSK;
|
||||
coex_cmd.flags = COEX_FLAGS_ASSOC_WA_UNMASK_MSK;
|
||||
|
||||
/* UnMask wake up src at unassociated sleep */
|
||||
coex_cmd.flags |= COEX_FLAGS_UNASSOC_WA_UNMASK_MSK;
|
||||
|
@ -90,6 +90,7 @@ struct iwl_hcmd_ops {
|
||||
int (*commit_rxon)(struct iwl_priv *priv);
|
||||
void (*set_rxon_chain)(struct iwl_priv *priv);
|
||||
int (*set_tx_ant)(struct iwl_priv *priv, u8 valid_tx_ant);
|
||||
void (*send_bt_config)(struct iwl_priv *priv);
|
||||
};
|
||||
|
||||
struct iwl_hcmd_utils_ops {
|
||||
@ -105,6 +106,7 @@ struct iwl_hcmd_utils_ops {
|
||||
__le32 *tx_flags);
|
||||
int (*calc_rssi)(struct iwl_priv *priv,
|
||||
struct iwl_rx_phy_res *rx_resp);
|
||||
void (*request_scan)(struct iwl_priv *priv);
|
||||
};
|
||||
|
||||
struct iwl_apm_ops {
|
||||
@ -114,6 +116,15 @@ struct iwl_apm_ops {
|
||||
int (*set_pwr_src)(struct iwl_priv *priv, enum iwl_pwr_src src);
|
||||
};
|
||||
|
||||
struct iwl_debugfs_ops {
|
||||
ssize_t (*rx_stats_read)(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos);
|
||||
ssize_t (*tx_stats_read)(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos);
|
||||
ssize_t (*general_stats_read)(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos);
|
||||
};
|
||||
|
||||
struct iwl_temp_ops {
|
||||
void (*temperature)(struct iwl_priv *priv);
|
||||
void (*set_ct_kill)(struct iwl_priv *priv);
|
||||
@ -199,6 +210,7 @@ struct iwl_lib_ops {
|
||||
/* check for ack health */
|
||||
bool (*check_ack_health)(struct iwl_priv *priv,
|
||||
struct iwl_rx_packet *pkt);
|
||||
struct iwl_debugfs_ops debugfs_ops;
|
||||
};
|
||||
|
||||
struct iwl_led_ops {
|
||||
@ -306,8 +318,8 @@ struct iwl_cfg {
|
||||
/* timer period for monitor the driver queues */
|
||||
u32 monitor_recover_period;
|
||||
bool temperature_kelvin;
|
||||
bool off_channel_workaround;
|
||||
u32 max_event_log_size;
|
||||
u8 scan_antennas[IEEE80211_NUM_BANDS];
|
||||
};
|
||||
|
||||
/***************************
|
||||
@ -339,7 +351,6 @@ void iwl_configure_filter(struct ieee80211_hw *hw,
|
||||
unsigned int changed_flags,
|
||||
unsigned int *total_flags, u64 multicast);
|
||||
int iwl_set_hw_params(struct iwl_priv *priv);
|
||||
bool iwl_is_monitor_mode(struct iwl_priv *priv);
|
||||
void iwl_post_associate(struct iwl_priv *priv);
|
||||
void iwl_bss_info_changed(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
@ -526,6 +537,7 @@ void iwl_setup_scan_deferred_work(struct iwl_priv *priv);
|
||||
#define IWL_ACTIVE_QUIET_TIME cpu_to_le16(10) /* msec */
|
||||
#define IWL_PLCP_QUIET_THRESH cpu_to_le16(1) /* packets */
|
||||
|
||||
#define IWL_SCAN_CHECK_WATCHDOG (HZ * 7)
|
||||
|
||||
/*******************************************************************************
|
||||
* Calibrations - implemented in iwl-calib.c
|
||||
@ -665,7 +677,7 @@ static inline int iwl_is_ready_rf(struct iwl_priv *priv)
|
||||
}
|
||||
|
||||
extern void iwl_rf_kill_ct_config(struct iwl_priv *priv);
|
||||
extern int iwl_send_bt_config(struct iwl_priv *priv);
|
||||
extern void iwl_send_bt_config(struct iwl_priv *priv);
|
||||
extern int iwl_send_statistics_request(struct iwl_priv *priv,
|
||||
u8 flags, bool clear);
|
||||
extern int iwl_verify_ucode(struct iwl_priv *priv);
|
||||
|
@ -298,6 +298,7 @@
|
||||
#define CSR_HW_REV_TYPE_1000 (0x0000060)
|
||||
#define CSR_HW_REV_TYPE_6x00 (0x0000070)
|
||||
#define CSR_HW_REV_TYPE_6x50 (0x0000080)
|
||||
#define CSR_HW_REV_TYPE_6x00g2 (0x00000B0)
|
||||
#define CSR_HW_REV_TYPE_NONE (0x00000F0)
|
||||
|
||||
/* EEPROM REG */
|
||||
|
@ -78,6 +78,8 @@ static inline void iwl_print_hex_dump(struct iwl_priv *priv, int level,
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
int iwl_dbgfs_register(struct iwl_priv *priv, const char *name);
|
||||
void iwl_dbgfs_unregister(struct iwl_priv *priv);
|
||||
extern int iwl_dbgfs_statistics_flag(struct iwl_priv *priv, char *buf,
|
||||
int bufsz);
|
||||
#else
|
||||
static inline int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
|
||||
{
|
||||
|
@ -106,6 +106,26 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \
|
||||
.open = iwl_dbgfs_open_file_generic, \
|
||||
};
|
||||
|
||||
int iwl_dbgfs_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz)
|
||||
{
|
||||
int p = 0;
|
||||
|
||||
p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n",
|
||||
le32_to_cpu(priv->statistics.flag));
|
||||
if (le32_to_cpu(priv->statistics.flag) & UCODE_STATISTICS_CLEAR_MSK)
|
||||
p += scnprintf(buf + p, bufsz - p,
|
||||
"\tStatistics have been cleared\n");
|
||||
p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n",
|
||||
(le32_to_cpu(priv->statistics.flag) &
|
||||
UCODE_STATISTICS_FREQUENCY_MSK)
|
||||
? "2.4 GHz" : "5.2 GHz");
|
||||
p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n",
|
||||
(le32_to_cpu(priv->statistics.flag) &
|
||||
UCODE_STATISTICS_NARROW_BAND_MSK)
|
||||
? "enabled" : "disabled");
|
||||
return p;
|
||||
}
|
||||
EXPORT_SYMBOL(iwl_dbgfs_statistics_flag);
|
||||
|
||||
static ssize_t iwl_dbgfs_tx_statistics_read(struct file *file,
|
||||
char __user *user_buf,
|
||||
@ -1034,474 +1054,15 @@ static ssize_t iwl_dbgfs_rx_queue_read(struct file *file,
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
|
||||
}
|
||||
|
||||
static int iwl_dbgfs_statistics_flag(struct iwl_priv *priv, char *buf,
|
||||
int bufsz)
|
||||
{
|
||||
int p = 0;
|
||||
|
||||
p += scnprintf(buf + p, bufsz - p,
|
||||
"Statistics Flag(0x%X):\n",
|
||||
le32_to_cpu(priv->statistics.flag));
|
||||
if (le32_to_cpu(priv->statistics.flag) & UCODE_STATISTICS_CLEAR_MSK)
|
||||
p += scnprintf(buf + p, bufsz - p,
|
||||
"\tStatistics have been cleared\n");
|
||||
p += scnprintf(buf + p, bufsz - p,
|
||||
"\tOperational Frequency: %s\n",
|
||||
(le32_to_cpu(priv->statistics.flag) &
|
||||
UCODE_STATISTICS_FREQUENCY_MSK)
|
||||
? "2.4 GHz" : "5.2 GHz");
|
||||
p += scnprintf(buf + p, bufsz - p,
|
||||
"\tTGj Narrow Band: %s\n",
|
||||
(le32_to_cpu(priv->statistics.flag) &
|
||||
UCODE_STATISTICS_NARROW_BAND_MSK)
|
||||
? "enabled" : "disabled");
|
||||
return p;
|
||||
}
|
||||
|
||||
static const char ucode_stats_header[] =
|
||||
"%-32s current acumulative delta max\n";
|
||||
static const char ucode_stats_short_format[] =
|
||||
" %-30s %10u\n";
|
||||
static const char ucode_stats_format[] =
|
||||
" %-30s %10u %10u %10u %10u\n";
|
||||
|
||||
static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct iwl_priv *priv = file->private_data;
|
||||
int pos = 0;
|
||||
char *buf;
|
||||
int bufsz = sizeof(struct statistics_rx_phy) * 40 +
|
||||
sizeof(struct statistics_rx_non_phy) * 40 +
|
||||
sizeof(struct statistics_rx_ht_phy) * 40 + 400;
|
||||
ssize_t ret;
|
||||
struct statistics_rx_phy *ofdm, *accum_ofdm, *delta_ofdm, *max_ofdm;
|
||||
struct statistics_rx_phy *cck, *accum_cck, *delta_cck, *max_cck;
|
||||
struct statistics_rx_non_phy *general, *accum_general;
|
||||
struct statistics_rx_non_phy *delta_general, *max_general;
|
||||
struct statistics_rx_ht_phy *ht, *accum_ht, *delta_ht, *max_ht;
|
||||
|
||||
if (!iwl_is_alive(priv))
|
||||
return -EAGAIN;
|
||||
|
||||
buf = kzalloc(bufsz, GFP_KERNEL);
|
||||
if (!buf) {
|
||||
IWL_ERR(priv, "Can not allocate Buffer\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* the statistic information display here is based on
|
||||
* the last statistics notification from uCode
|
||||
* might not reflect the current uCode activity
|
||||
*/
|
||||
ofdm = &priv->statistics.rx.ofdm;
|
||||
cck = &priv->statistics.rx.cck;
|
||||
general = &priv->statistics.rx.general;
|
||||
ht = &priv->statistics.rx.ofdm_ht;
|
||||
accum_ofdm = &priv->accum_statistics.rx.ofdm;
|
||||
accum_cck = &priv->accum_statistics.rx.cck;
|
||||
accum_general = &priv->accum_statistics.rx.general;
|
||||
accum_ht = &priv->accum_statistics.rx.ofdm_ht;
|
||||
delta_ofdm = &priv->delta_statistics.rx.ofdm;
|
||||
delta_cck = &priv->delta_statistics.rx.cck;
|
||||
delta_general = &priv->delta_statistics.rx.general;
|
||||
delta_ht = &priv->delta_statistics.rx.ofdm_ht;
|
||||
max_ofdm = &priv->max_delta.rx.ofdm;
|
||||
max_cck = &priv->max_delta.rx.cck;
|
||||
max_general = &priv->max_delta.rx.general;
|
||||
max_ht = &priv->max_delta.rx.ofdm_ht;
|
||||
|
||||
pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
|
||||
"Statistics_Rx - OFDM:");
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"ina_cnt:", le32_to_cpu(ofdm->ina_cnt),
|
||||
accum_ofdm->ina_cnt,
|
||||
delta_ofdm->ina_cnt, max_ofdm->ina_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"fina_cnt:",
|
||||
le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt,
|
||||
delta_ofdm->fina_cnt, max_ofdm->fina_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"plcp_err:",
|
||||
le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err,
|
||||
delta_ofdm->plcp_err, max_ofdm->plcp_err);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"crc32_err:",
|
||||
le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err,
|
||||
delta_ofdm->crc32_err, max_ofdm->crc32_err);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"overrun_err:",
|
||||
le32_to_cpu(ofdm->overrun_err),
|
||||
accum_ofdm->overrun_err,
|
||||
delta_ofdm->overrun_err, max_ofdm->overrun_err);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"early_overrun_err:",
|
||||
le32_to_cpu(ofdm->early_overrun_err),
|
||||
accum_ofdm->early_overrun_err,
|
||||
delta_ofdm->early_overrun_err,
|
||||
max_ofdm->early_overrun_err);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"crc32_good:",
|
||||
le32_to_cpu(ofdm->crc32_good),
|
||||
accum_ofdm->crc32_good,
|
||||
delta_ofdm->crc32_good, max_ofdm->crc32_good);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"false_alarm_cnt:",
|
||||
le32_to_cpu(ofdm->false_alarm_cnt),
|
||||
accum_ofdm->false_alarm_cnt,
|
||||
delta_ofdm->false_alarm_cnt,
|
||||
max_ofdm->false_alarm_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"fina_sync_err_cnt:",
|
||||
le32_to_cpu(ofdm->fina_sync_err_cnt),
|
||||
accum_ofdm->fina_sync_err_cnt,
|
||||
delta_ofdm->fina_sync_err_cnt,
|
||||
max_ofdm->fina_sync_err_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"sfd_timeout:",
|
||||
le32_to_cpu(ofdm->sfd_timeout),
|
||||
accum_ofdm->sfd_timeout,
|
||||
delta_ofdm->sfd_timeout,
|
||||
max_ofdm->sfd_timeout);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"fina_timeout:",
|
||||
le32_to_cpu(ofdm->fina_timeout),
|
||||
accum_ofdm->fina_timeout,
|
||||
delta_ofdm->fina_timeout,
|
||||
max_ofdm->fina_timeout);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"unresponded_rts:",
|
||||
le32_to_cpu(ofdm->unresponded_rts),
|
||||
accum_ofdm->unresponded_rts,
|
||||
delta_ofdm->unresponded_rts,
|
||||
max_ofdm->unresponded_rts);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"rxe_frame_lmt_ovrun:",
|
||||
le32_to_cpu(ofdm->rxe_frame_limit_overrun),
|
||||
accum_ofdm->rxe_frame_limit_overrun,
|
||||
delta_ofdm->rxe_frame_limit_overrun,
|
||||
max_ofdm->rxe_frame_limit_overrun);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"sent_ack_cnt:",
|
||||
le32_to_cpu(ofdm->sent_ack_cnt),
|
||||
accum_ofdm->sent_ack_cnt,
|
||||
delta_ofdm->sent_ack_cnt,
|
||||
max_ofdm->sent_ack_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"sent_cts_cnt:",
|
||||
le32_to_cpu(ofdm->sent_cts_cnt),
|
||||
accum_ofdm->sent_cts_cnt,
|
||||
delta_ofdm->sent_cts_cnt, max_ofdm->sent_cts_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"sent_ba_rsp_cnt:",
|
||||
le32_to_cpu(ofdm->sent_ba_rsp_cnt),
|
||||
accum_ofdm->sent_ba_rsp_cnt,
|
||||
delta_ofdm->sent_ba_rsp_cnt,
|
||||
max_ofdm->sent_ba_rsp_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"dsp_self_kill:",
|
||||
le32_to_cpu(ofdm->dsp_self_kill),
|
||||
accum_ofdm->dsp_self_kill,
|
||||
delta_ofdm->dsp_self_kill,
|
||||
max_ofdm->dsp_self_kill);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"mh_format_err:",
|
||||
le32_to_cpu(ofdm->mh_format_err),
|
||||
accum_ofdm->mh_format_err,
|
||||
delta_ofdm->mh_format_err,
|
||||
max_ofdm->mh_format_err);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"re_acq_main_rssi_sum:",
|
||||
le32_to_cpu(ofdm->re_acq_main_rssi_sum),
|
||||
accum_ofdm->re_acq_main_rssi_sum,
|
||||
delta_ofdm->re_acq_main_rssi_sum,
|
||||
max_ofdm->re_acq_main_rssi_sum);
|
||||
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
|
||||
"Statistics_Rx - CCK:");
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"ina_cnt:",
|
||||
le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt,
|
||||
delta_cck->ina_cnt, max_cck->ina_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"fina_cnt:",
|
||||
le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt,
|
||||
delta_cck->fina_cnt, max_cck->fina_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"plcp_err:",
|
||||
le32_to_cpu(cck->plcp_err), accum_cck->plcp_err,
|
||||
delta_cck->plcp_err, max_cck->plcp_err);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"crc32_err:",
|
||||
le32_to_cpu(cck->crc32_err), accum_cck->crc32_err,
|
||||
delta_cck->crc32_err, max_cck->crc32_err);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"overrun_err:",
|
||||
le32_to_cpu(cck->overrun_err),
|
||||
accum_cck->overrun_err,
|
||||
delta_cck->overrun_err, max_cck->overrun_err);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"early_overrun_err:",
|
||||
le32_to_cpu(cck->early_overrun_err),
|
||||
accum_cck->early_overrun_err,
|
||||
delta_cck->early_overrun_err,
|
||||
max_cck->early_overrun_err);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"crc32_good:",
|
||||
le32_to_cpu(cck->crc32_good), accum_cck->crc32_good,
|
||||
delta_cck->crc32_good,
|
||||
max_cck->crc32_good);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"false_alarm_cnt:",
|
||||
le32_to_cpu(cck->false_alarm_cnt),
|
||||
accum_cck->false_alarm_cnt,
|
||||
delta_cck->false_alarm_cnt, max_cck->false_alarm_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"fina_sync_err_cnt:",
|
||||
le32_to_cpu(cck->fina_sync_err_cnt),
|
||||
accum_cck->fina_sync_err_cnt,
|
||||
delta_cck->fina_sync_err_cnt,
|
||||
max_cck->fina_sync_err_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"sfd_timeout:",
|
||||
le32_to_cpu(cck->sfd_timeout),
|
||||
accum_cck->sfd_timeout,
|
||||
delta_cck->sfd_timeout, max_cck->sfd_timeout);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"fina_timeout:",
|
||||
le32_to_cpu(cck->fina_timeout),
|
||||
accum_cck->fina_timeout,
|
||||
delta_cck->fina_timeout, max_cck->fina_timeout);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"unresponded_rts:",
|
||||
le32_to_cpu(cck->unresponded_rts),
|
||||
accum_cck->unresponded_rts,
|
||||
delta_cck->unresponded_rts,
|
||||
max_cck->unresponded_rts);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"rxe_frame_lmt_ovrun:",
|
||||
le32_to_cpu(cck->rxe_frame_limit_overrun),
|
||||
accum_cck->rxe_frame_limit_overrun,
|
||||
delta_cck->rxe_frame_limit_overrun,
|
||||
max_cck->rxe_frame_limit_overrun);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"sent_ack_cnt:",
|
||||
le32_to_cpu(cck->sent_ack_cnt),
|
||||
accum_cck->sent_ack_cnt,
|
||||
delta_cck->sent_ack_cnt,
|
||||
max_cck->sent_ack_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"sent_cts_cnt:",
|
||||
le32_to_cpu(cck->sent_cts_cnt),
|
||||
accum_cck->sent_cts_cnt,
|
||||
delta_cck->sent_cts_cnt,
|
||||
max_cck->sent_cts_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"sent_ba_rsp_cnt:",
|
||||
le32_to_cpu(cck->sent_ba_rsp_cnt),
|
||||
accum_cck->sent_ba_rsp_cnt,
|
||||
delta_cck->sent_ba_rsp_cnt,
|
||||
max_cck->sent_ba_rsp_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"dsp_self_kill:",
|
||||
le32_to_cpu(cck->dsp_self_kill),
|
||||
accum_cck->dsp_self_kill,
|
||||
delta_cck->dsp_self_kill,
|
||||
max_cck->dsp_self_kill);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"mh_format_err:",
|
||||
le32_to_cpu(cck->mh_format_err),
|
||||
accum_cck->mh_format_err,
|
||||
delta_cck->mh_format_err, max_cck->mh_format_err);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"re_acq_main_rssi_sum:",
|
||||
le32_to_cpu(cck->re_acq_main_rssi_sum),
|
||||
accum_cck->re_acq_main_rssi_sum,
|
||||
delta_cck->re_acq_main_rssi_sum,
|
||||
max_cck->re_acq_main_rssi_sum);
|
||||
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
|
||||
"Statistics_Rx - GENERAL:");
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"bogus_cts:",
|
||||
le32_to_cpu(general->bogus_cts),
|
||||
accum_general->bogus_cts,
|
||||
delta_general->bogus_cts, max_general->bogus_cts);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"bogus_ack:",
|
||||
le32_to_cpu(general->bogus_ack),
|
||||
accum_general->bogus_ack,
|
||||
delta_general->bogus_ack, max_general->bogus_ack);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"non_bssid_frames:",
|
||||
le32_to_cpu(general->non_bssid_frames),
|
||||
accum_general->non_bssid_frames,
|
||||
delta_general->non_bssid_frames,
|
||||
max_general->non_bssid_frames);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"filtered_frames:",
|
||||
le32_to_cpu(general->filtered_frames),
|
||||
accum_general->filtered_frames,
|
||||
delta_general->filtered_frames,
|
||||
max_general->filtered_frames);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"non_channel_beacons:",
|
||||
le32_to_cpu(general->non_channel_beacons),
|
||||
accum_general->non_channel_beacons,
|
||||
delta_general->non_channel_beacons,
|
||||
max_general->non_channel_beacons);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"channel_beacons:",
|
||||
le32_to_cpu(general->channel_beacons),
|
||||
accum_general->channel_beacons,
|
||||
delta_general->channel_beacons,
|
||||
max_general->channel_beacons);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"num_missed_bcon:",
|
||||
le32_to_cpu(general->num_missed_bcon),
|
||||
accum_general->num_missed_bcon,
|
||||
delta_general->num_missed_bcon,
|
||||
max_general->num_missed_bcon);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"adc_rx_saturation_time:",
|
||||
le32_to_cpu(general->adc_rx_saturation_time),
|
||||
accum_general->adc_rx_saturation_time,
|
||||
delta_general->adc_rx_saturation_time,
|
||||
max_general->adc_rx_saturation_time);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"ina_detect_search_tm:",
|
||||
le32_to_cpu(general->ina_detection_search_time),
|
||||
accum_general->ina_detection_search_time,
|
||||
delta_general->ina_detection_search_time,
|
||||
max_general->ina_detection_search_time);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"beacon_silence_rssi_a:",
|
||||
le32_to_cpu(general->beacon_silence_rssi_a),
|
||||
accum_general->beacon_silence_rssi_a,
|
||||
delta_general->beacon_silence_rssi_a,
|
||||
max_general->beacon_silence_rssi_a);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"beacon_silence_rssi_b:",
|
||||
le32_to_cpu(general->beacon_silence_rssi_b),
|
||||
accum_general->beacon_silence_rssi_b,
|
||||
delta_general->beacon_silence_rssi_b,
|
||||
max_general->beacon_silence_rssi_b);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"beacon_silence_rssi_c:",
|
||||
le32_to_cpu(general->beacon_silence_rssi_c),
|
||||
accum_general->beacon_silence_rssi_c,
|
||||
delta_general->beacon_silence_rssi_c,
|
||||
max_general->beacon_silence_rssi_c);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"interference_data_flag:",
|
||||
le32_to_cpu(general->interference_data_flag),
|
||||
accum_general->interference_data_flag,
|
||||
delta_general->interference_data_flag,
|
||||
max_general->interference_data_flag);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"channel_load:",
|
||||
le32_to_cpu(general->channel_load),
|
||||
accum_general->channel_load,
|
||||
delta_general->channel_load,
|
||||
max_general->channel_load);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"dsp_false_alarms:",
|
||||
le32_to_cpu(general->dsp_false_alarms),
|
||||
accum_general->dsp_false_alarms,
|
||||
delta_general->dsp_false_alarms,
|
||||
max_general->dsp_false_alarms);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"beacon_rssi_a:",
|
||||
le32_to_cpu(general->beacon_rssi_a),
|
||||
accum_general->beacon_rssi_a,
|
||||
delta_general->beacon_rssi_a,
|
||||
max_general->beacon_rssi_a);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"beacon_rssi_b:",
|
||||
le32_to_cpu(general->beacon_rssi_b),
|
||||
accum_general->beacon_rssi_b,
|
||||
delta_general->beacon_rssi_b,
|
||||
max_general->beacon_rssi_b);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"beacon_rssi_c:",
|
||||
le32_to_cpu(general->beacon_rssi_c),
|
||||
accum_general->beacon_rssi_c,
|
||||
delta_general->beacon_rssi_c,
|
||||
max_general->beacon_rssi_c);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"beacon_energy_a:",
|
||||
le32_to_cpu(general->beacon_energy_a),
|
||||
accum_general->beacon_energy_a,
|
||||
delta_general->beacon_energy_a,
|
||||
max_general->beacon_energy_a);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"beacon_energy_b:",
|
||||
le32_to_cpu(general->beacon_energy_b),
|
||||
accum_general->beacon_energy_b,
|
||||
delta_general->beacon_energy_b,
|
||||
max_general->beacon_energy_b);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"beacon_energy_c:",
|
||||
le32_to_cpu(general->beacon_energy_c),
|
||||
accum_general->beacon_energy_c,
|
||||
delta_general->beacon_energy_c,
|
||||
max_general->beacon_energy_c);
|
||||
|
||||
pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - OFDM_HT:\n");
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
|
||||
"Statistics_Rx - OFDM_HT:");
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"plcp_err:",
|
||||
le32_to_cpu(ht->plcp_err), accum_ht->plcp_err,
|
||||
delta_ht->plcp_err, max_ht->plcp_err);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"overrun_err:",
|
||||
le32_to_cpu(ht->overrun_err), accum_ht->overrun_err,
|
||||
delta_ht->overrun_err, max_ht->overrun_err);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"early_overrun_err:",
|
||||
le32_to_cpu(ht->early_overrun_err),
|
||||
accum_ht->early_overrun_err,
|
||||
delta_ht->early_overrun_err,
|
||||
max_ht->early_overrun_err);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"crc32_good:",
|
||||
le32_to_cpu(ht->crc32_good), accum_ht->crc32_good,
|
||||
delta_ht->crc32_good, max_ht->crc32_good);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"crc32_err:",
|
||||
le32_to_cpu(ht->crc32_err), accum_ht->crc32_err,
|
||||
delta_ht->crc32_err, max_ht->crc32_err);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"mh_format_err:",
|
||||
le32_to_cpu(ht->mh_format_err),
|
||||
accum_ht->mh_format_err,
|
||||
delta_ht->mh_format_err, max_ht->mh_format_err);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"agg_crc32_good:",
|
||||
le32_to_cpu(ht->agg_crc32_good),
|
||||
accum_ht->agg_crc32_good,
|
||||
delta_ht->agg_crc32_good, max_ht->agg_crc32_good);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"agg_mpdu_cnt:",
|
||||
le32_to_cpu(ht->agg_mpdu_cnt),
|
||||
accum_ht->agg_mpdu_cnt,
|
||||
delta_ht->agg_mpdu_cnt, max_ht->agg_mpdu_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"agg_cnt:",
|
||||
le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt,
|
||||
delta_ht->agg_cnt, max_ht->agg_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"unsupport_mcs:",
|
||||
le32_to_cpu(ht->unsupport_mcs),
|
||||
accum_ht->unsupport_mcs,
|
||||
delta_ht->unsupport_mcs, max_ht->unsupport_mcs);
|
||||
|
||||
ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
|
||||
kfree(buf);
|
||||
return ret;
|
||||
if (priv->cfg->ops->lib->debugfs_ops.rx_stats_read)
|
||||
return priv->cfg->ops->lib->debugfs_ops.rx_stats_read(file,
|
||||
user_buf, count, ppos);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
|
||||
@ -1509,173 +1070,10 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct iwl_priv *priv = file->private_data;
|
||||
int pos = 0;
|
||||
char *buf;
|
||||
int bufsz = (sizeof(struct statistics_tx) * 48) + 250;
|
||||
ssize_t ret;
|
||||
struct statistics_tx *tx, *accum_tx, *delta_tx, *max_tx;
|
||||
|
||||
if (!iwl_is_alive(priv))
|
||||
return -EAGAIN;
|
||||
|
||||
buf = kzalloc(bufsz, GFP_KERNEL);
|
||||
if (!buf) {
|
||||
IWL_ERR(priv, "Can not allocate Buffer\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* the statistic information display here is based on
|
||||
* the last statistics notification from uCode
|
||||
* might not reflect the current uCode activity
|
||||
*/
|
||||
tx = &priv->statistics.tx;
|
||||
accum_tx = &priv->accum_statistics.tx;
|
||||
delta_tx = &priv->delta_statistics.tx;
|
||||
max_tx = &priv->max_delta.tx;
|
||||
pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
|
||||
"Statistics_Tx:");
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"preamble:",
|
||||
le32_to_cpu(tx->preamble_cnt),
|
||||
accum_tx->preamble_cnt,
|
||||
delta_tx->preamble_cnt, max_tx->preamble_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"rx_detected_cnt:",
|
||||
le32_to_cpu(tx->rx_detected_cnt),
|
||||
accum_tx->rx_detected_cnt,
|
||||
delta_tx->rx_detected_cnt, max_tx->rx_detected_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"bt_prio_defer_cnt:",
|
||||
le32_to_cpu(tx->bt_prio_defer_cnt),
|
||||
accum_tx->bt_prio_defer_cnt,
|
||||
delta_tx->bt_prio_defer_cnt,
|
||||
max_tx->bt_prio_defer_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"bt_prio_kill_cnt:",
|
||||
le32_to_cpu(tx->bt_prio_kill_cnt),
|
||||
accum_tx->bt_prio_kill_cnt,
|
||||
delta_tx->bt_prio_kill_cnt,
|
||||
max_tx->bt_prio_kill_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"few_bytes_cnt:",
|
||||
le32_to_cpu(tx->few_bytes_cnt),
|
||||
accum_tx->few_bytes_cnt,
|
||||
delta_tx->few_bytes_cnt, max_tx->few_bytes_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"cts_timeout:",
|
||||
le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout,
|
||||
delta_tx->cts_timeout, max_tx->cts_timeout);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"ack_timeout:",
|
||||
le32_to_cpu(tx->ack_timeout),
|
||||
accum_tx->ack_timeout,
|
||||
delta_tx->ack_timeout, max_tx->ack_timeout);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"expected_ack_cnt:",
|
||||
le32_to_cpu(tx->expected_ack_cnt),
|
||||
accum_tx->expected_ack_cnt,
|
||||
delta_tx->expected_ack_cnt,
|
||||
max_tx->expected_ack_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"actual_ack_cnt:",
|
||||
le32_to_cpu(tx->actual_ack_cnt),
|
||||
accum_tx->actual_ack_cnt,
|
||||
delta_tx->actual_ack_cnt,
|
||||
max_tx->actual_ack_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"dump_msdu_cnt:",
|
||||
le32_to_cpu(tx->dump_msdu_cnt),
|
||||
accum_tx->dump_msdu_cnt,
|
||||
delta_tx->dump_msdu_cnt,
|
||||
max_tx->dump_msdu_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"abort_nxt_frame_mismatch:",
|
||||
le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt),
|
||||
accum_tx->burst_abort_next_frame_mismatch_cnt,
|
||||
delta_tx->burst_abort_next_frame_mismatch_cnt,
|
||||
max_tx->burst_abort_next_frame_mismatch_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"abort_missing_nxt_frame:",
|
||||
le32_to_cpu(tx->burst_abort_missing_next_frame_cnt),
|
||||
accum_tx->burst_abort_missing_next_frame_cnt,
|
||||
delta_tx->burst_abort_missing_next_frame_cnt,
|
||||
max_tx->burst_abort_missing_next_frame_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"cts_timeout_collision:",
|
||||
le32_to_cpu(tx->cts_timeout_collision),
|
||||
accum_tx->cts_timeout_collision,
|
||||
delta_tx->cts_timeout_collision,
|
||||
max_tx->cts_timeout_collision);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"ack_ba_timeout_collision:",
|
||||
le32_to_cpu(tx->ack_or_ba_timeout_collision),
|
||||
accum_tx->ack_or_ba_timeout_collision,
|
||||
delta_tx->ack_or_ba_timeout_collision,
|
||||
max_tx->ack_or_ba_timeout_collision);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"agg ba_timeout:",
|
||||
le32_to_cpu(tx->agg.ba_timeout),
|
||||
accum_tx->agg.ba_timeout,
|
||||
delta_tx->agg.ba_timeout,
|
||||
max_tx->agg.ba_timeout);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"agg ba_resched_frames:",
|
||||
le32_to_cpu(tx->agg.ba_reschedule_frames),
|
||||
accum_tx->agg.ba_reschedule_frames,
|
||||
delta_tx->agg.ba_reschedule_frames,
|
||||
max_tx->agg.ba_reschedule_frames);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"agg scd_query_agg_frame:",
|
||||
le32_to_cpu(tx->agg.scd_query_agg_frame_cnt),
|
||||
accum_tx->agg.scd_query_agg_frame_cnt,
|
||||
delta_tx->agg.scd_query_agg_frame_cnt,
|
||||
max_tx->agg.scd_query_agg_frame_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"agg scd_query_no_agg:",
|
||||
le32_to_cpu(tx->agg.scd_query_no_agg),
|
||||
accum_tx->agg.scd_query_no_agg,
|
||||
delta_tx->agg.scd_query_no_agg,
|
||||
max_tx->agg.scd_query_no_agg);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"agg scd_query_agg:",
|
||||
le32_to_cpu(tx->agg.scd_query_agg),
|
||||
accum_tx->agg.scd_query_agg,
|
||||
delta_tx->agg.scd_query_agg,
|
||||
max_tx->agg.scd_query_agg);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"agg scd_query_mismatch:",
|
||||
le32_to_cpu(tx->agg.scd_query_mismatch),
|
||||
accum_tx->agg.scd_query_mismatch,
|
||||
delta_tx->agg.scd_query_mismatch,
|
||||
max_tx->agg.scd_query_mismatch);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"agg frame_not_ready:",
|
||||
le32_to_cpu(tx->agg.frame_not_ready),
|
||||
accum_tx->agg.frame_not_ready,
|
||||
delta_tx->agg.frame_not_ready,
|
||||
max_tx->agg.frame_not_ready);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"agg underrun:",
|
||||
le32_to_cpu(tx->agg.underrun),
|
||||
accum_tx->agg.underrun,
|
||||
delta_tx->agg.underrun, max_tx->agg.underrun);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"agg bt_prio_kill:",
|
||||
le32_to_cpu(tx->agg.bt_prio_kill),
|
||||
accum_tx->agg.bt_prio_kill,
|
||||
delta_tx->agg.bt_prio_kill,
|
||||
max_tx->agg.bt_prio_kill);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"agg rx_ba_rsp_cnt:",
|
||||
le32_to_cpu(tx->agg.rx_ba_rsp_cnt),
|
||||
accum_tx->agg.rx_ba_rsp_cnt,
|
||||
delta_tx->agg.rx_ba_rsp_cnt,
|
||||
max_tx->agg.rx_ba_rsp_cnt);
|
||||
|
||||
ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
|
||||
kfree(buf);
|
||||
return ret;
|
||||
if (priv->cfg->ops->lib->debugfs_ops.tx_stats_read)
|
||||
return priv->cfg->ops->lib->debugfs_ops.tx_stats_read(file,
|
||||
user_buf, count, ppos);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file,
|
||||
@ -1683,107 +1081,10 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct iwl_priv *priv = file->private_data;
|
||||
int pos = 0;
|
||||
char *buf;
|
||||
int bufsz = sizeof(struct statistics_general) * 10 + 300;
|
||||
ssize_t ret;
|
||||
struct statistics_general *general, *accum_general;
|
||||
struct statistics_general *delta_general, *max_general;
|
||||
struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg;
|
||||
struct statistics_div *div, *accum_div, *delta_div, *max_div;
|
||||
|
||||
if (!iwl_is_alive(priv))
|
||||
return -EAGAIN;
|
||||
|
||||
buf = kzalloc(bufsz, GFP_KERNEL);
|
||||
if (!buf) {
|
||||
IWL_ERR(priv, "Can not allocate Buffer\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* the statistic information display here is based on
|
||||
* the last statistics notification from uCode
|
||||
* might not reflect the current uCode activity
|
||||
*/
|
||||
general = &priv->statistics.general;
|
||||
dbg = &priv->statistics.general.dbg;
|
||||
div = &priv->statistics.general.div;
|
||||
accum_general = &priv->accum_statistics.general;
|
||||
delta_general = &priv->delta_statistics.general;
|
||||
max_general = &priv->max_delta.general;
|
||||
accum_dbg = &priv->accum_statistics.general.dbg;
|
||||
delta_dbg = &priv->delta_statistics.general.dbg;
|
||||
max_dbg = &priv->max_delta.general.dbg;
|
||||
accum_div = &priv->accum_statistics.general.div;
|
||||
delta_div = &priv->delta_statistics.general.div;
|
||||
max_div = &priv->max_delta.general.div;
|
||||
pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
|
||||
"Statistics_General:");
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_short_format,
|
||||
"temperature:",
|
||||
le32_to_cpu(general->temperature));
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_short_format,
|
||||
"temperature_m:",
|
||||
le32_to_cpu(general->temperature_m));
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"burst_check:",
|
||||
le32_to_cpu(dbg->burst_check),
|
||||
accum_dbg->burst_check,
|
||||
delta_dbg->burst_check, max_dbg->burst_check);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"burst_count:",
|
||||
le32_to_cpu(dbg->burst_count),
|
||||
accum_dbg->burst_count,
|
||||
delta_dbg->burst_count, max_dbg->burst_count);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"sleep_time:",
|
||||
le32_to_cpu(general->sleep_time),
|
||||
accum_general->sleep_time,
|
||||
delta_general->sleep_time, max_general->sleep_time);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"slots_out:",
|
||||
le32_to_cpu(general->slots_out),
|
||||
accum_general->slots_out,
|
||||
delta_general->slots_out, max_general->slots_out);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"slots_idle:",
|
||||
le32_to_cpu(general->slots_idle),
|
||||
accum_general->slots_idle,
|
||||
delta_general->slots_idle, max_general->slots_idle);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, "ttl_timestamp:\t\t\t%u\n",
|
||||
le32_to_cpu(general->ttl_timestamp));
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"tx_on_a:",
|
||||
le32_to_cpu(div->tx_on_a), accum_div->tx_on_a,
|
||||
delta_div->tx_on_a, max_div->tx_on_a);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"tx_on_b:",
|
||||
le32_to_cpu(div->tx_on_b), accum_div->tx_on_b,
|
||||
delta_div->tx_on_b, max_div->tx_on_b);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"exec_time:",
|
||||
le32_to_cpu(div->exec_time), accum_div->exec_time,
|
||||
delta_div->exec_time, max_div->exec_time);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"probe_time:",
|
||||
le32_to_cpu(div->probe_time), accum_div->probe_time,
|
||||
delta_div->probe_time, max_div->probe_time);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"rx_enable_counter:",
|
||||
le32_to_cpu(general->rx_enable_counter),
|
||||
accum_general->rx_enable_counter,
|
||||
delta_general->rx_enable_counter,
|
||||
max_general->rx_enable_counter);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
|
||||
"num_of_sos_states:",
|
||||
le32_to_cpu(general->num_of_sos_states),
|
||||
accum_general->num_of_sos_states,
|
||||
delta_general->num_of_sos_states,
|
||||
max_general->num_of_sos_states);
|
||||
ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
|
||||
kfree(buf);
|
||||
return ret;
|
||||
if (priv->cfg->ops->lib->debugfs_ops.general_stats_read)
|
||||
return priv->cfg->ops->lib->debugfs_ops.general_stats_read(file,
|
||||
user_buf, count, ppos);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t iwl_dbgfs_sensitivity_read(struct file *file,
|
||||
@ -2341,10 +1642,11 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
|
||||
DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR);
|
||||
DEBUGFS_ADD_FILE(plcp_delta, dir_debug, S_IWUSR | S_IRUSR);
|
||||
DEBUGFS_ADD_FILE(force_reset, dir_debug, S_IWUSR | S_IRUSR);
|
||||
DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR);
|
||||
DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR);
|
||||
DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR);
|
||||
|
||||
if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) {
|
||||
DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR);
|
||||
DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR);
|
||||
DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR);
|
||||
DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR);
|
||||
DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR);
|
||||
DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR);
|
||||
|
@ -58,7 +58,7 @@ extern struct iwl_cfg iwl5100_abg_cfg;
|
||||
extern struct iwl_cfg iwl5150_agn_cfg;
|
||||
extern struct iwl_cfg iwl5150_abg_cfg;
|
||||
extern struct iwl_cfg iwl6000i_2agn_cfg;
|
||||
extern struct iwl_cfg iwl6000i_g2_2agn_cfg;
|
||||
extern struct iwl_cfg iwl6000g2_2agn_cfg;
|
||||
extern struct iwl_cfg iwl6000i_2abg_cfg;
|
||||
extern struct iwl_cfg iwl6000i_2bg_cfg;
|
||||
extern struct iwl_cfg iwl6000_3agn_cfg;
|
||||
@ -1049,12 +1049,10 @@ struct iwl_priv {
|
||||
struct iwl_calib_result calib_results[IWL_CALIB_MAX];
|
||||
|
||||
/* Scan related variables */
|
||||
unsigned long next_scan_jiffies;
|
||||
unsigned long scan_start;
|
||||
unsigned long scan_pass_start;
|
||||
unsigned long scan_start_tsf;
|
||||
void *scan;
|
||||
int scan_bands;
|
||||
void *scan_cmd;
|
||||
enum ieee80211_band scan_band;
|
||||
struct cfg80211_scan_request *scan_request;
|
||||
bool is_internal_short_scan;
|
||||
u8 scan_tx_ant[IEEE80211_NUM_BANDS];
|
||||
@ -1259,7 +1257,6 @@ struct iwl_priv {
|
||||
struct work_struct scan_completed;
|
||||
struct work_struct rx_replenish;
|
||||
struct work_struct abort_scan;
|
||||
struct work_struct request_scan;
|
||||
struct work_struct beacon_update;
|
||||
struct work_struct tt_work;
|
||||
struct work_struct ct_enter;
|
||||
|
@ -172,22 +172,22 @@ struct iwl_eeprom_enhanced_txpwr {
|
||||
#define EEPROM_5000_TX_POWER_VERSION (4)
|
||||
#define EEPROM_5000_EEPROM_VERSION (0x11A)
|
||||
|
||||
/*5000 calibrations */
|
||||
#define EEPROM_5000_CALIB_ALL (INDIRECT_ADDRESS | INDIRECT_CALIBRATION)
|
||||
#define EEPROM_5000_XTAL ((2*0x128) | EEPROM_5000_CALIB_ALL)
|
||||
#define EEPROM_5000_TEMPERATURE ((2*0x12A) | EEPROM_5000_CALIB_ALL)
|
||||
/* 5000 and up calibration */
|
||||
#define EEPROM_CALIB_ALL (INDIRECT_ADDRESS | INDIRECT_CALIBRATION)
|
||||
#define EEPROM_XTAL ((2*0x128) | EEPROM_CALIB_ALL)
|
||||
|
||||
/* 5000 links */
|
||||
#define EEPROM_5000_LINK_HOST (2*0x64)
|
||||
#define EEPROM_5000_LINK_GENERAL (2*0x65)
|
||||
#define EEPROM_5000_LINK_REGULATORY (2*0x66)
|
||||
#define EEPROM_5000_LINK_CALIBRATION (2*0x67)
|
||||
#define EEPROM_5000_LINK_PROCESS_ADJST (2*0x68)
|
||||
#define EEPROM_5000_LINK_OTHERS (2*0x69)
|
||||
/* 5000 temperature */
|
||||
#define EEPROM_5000_TEMPERATURE ((2*0x12A) | EEPROM_CALIB_ALL)
|
||||
|
||||
/* 5000 regulatory - indirect access */
|
||||
#define EEPROM_5000_REG_SKU_ID ((0x02)\
|
||||
| INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 4 bytes */
|
||||
/* agn links */
|
||||
#define EEPROM_LINK_HOST (2*0x64)
|
||||
#define EEPROM_LINK_GENERAL (2*0x65)
|
||||
#define EEPROM_LINK_REGULATORY (2*0x66)
|
||||
#define EEPROM_LINK_CALIBRATION (2*0x67)
|
||||
#define EEPROM_LINK_PROCESS_ADJST (2*0x68)
|
||||
#define EEPROM_LINK_OTHERS (2*0x69)
|
||||
|
||||
/* agn regulatory - indirect access */
|
||||
#define EEPROM_REG_BAND_1_CHANNELS ((0x08)\
|
||||
| INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 28 bytes */
|
||||
#define EEPROM_REG_BAND_2_CHANNELS ((0x26)\
|
||||
@ -276,6 +276,10 @@ struct iwl_eeprom_enhanced_txpwr {
|
||||
#define EEPROM_6050_TX_POWER_VERSION (4)
|
||||
#define EEPROM_6050_EEPROM_VERSION (0x532)
|
||||
|
||||
/* 6x00g2 Specific */
|
||||
#define EEPROM_6000G2_TX_POWER_VERSION (6)
|
||||
#define EEPROM_6000G2_EEPROM_VERSION (0x709)
|
||||
|
||||
/* OTP */
|
||||
/* lower blocks contain EEPROM image and calibration data */
|
||||
#define OTP_LOW_IMAGE_SIZE (2 * 512 * sizeof(u16)) /* 2 KB */
|
||||
|
@ -529,48 +529,48 @@
|
||||
#define IWL_SCD_TXFIFO_POS_RA (4)
|
||||
#define IWL_SCD_QUEUE_RA_TID_MAP_RATID_MSK (0x01FF)
|
||||
|
||||
/* 5000 SCD */
|
||||
#define IWL50_SCD_QUEUE_STTS_REG_POS_TXF (0)
|
||||
#define IWL50_SCD_QUEUE_STTS_REG_POS_ACTIVE (3)
|
||||
#define IWL50_SCD_QUEUE_STTS_REG_POS_WSL (4)
|
||||
#define IWL50_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN (19)
|
||||
#define IWL50_SCD_QUEUE_STTS_REG_MSK (0x00FF0000)
|
||||
/* agn SCD */
|
||||
#define IWLAGN_SCD_QUEUE_STTS_REG_POS_TXF (0)
|
||||
#define IWLAGN_SCD_QUEUE_STTS_REG_POS_ACTIVE (3)
|
||||
#define IWLAGN_SCD_QUEUE_STTS_REG_POS_WSL (4)
|
||||
#define IWLAGN_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN (19)
|
||||
#define IWLAGN_SCD_QUEUE_STTS_REG_MSK (0x00FF0000)
|
||||
|
||||
#define IWL50_SCD_QUEUE_CTX_REG1_CREDIT_POS (8)
|
||||
#define IWL50_SCD_QUEUE_CTX_REG1_CREDIT_MSK (0x00FFFF00)
|
||||
#define IWL50_SCD_QUEUE_CTX_REG1_SUPER_CREDIT_POS (24)
|
||||
#define IWL50_SCD_QUEUE_CTX_REG1_SUPER_CREDIT_MSK (0xFF000000)
|
||||
#define IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS (0)
|
||||
#define IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK (0x0000007F)
|
||||
#define IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS (16)
|
||||
#define IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK (0x007F0000)
|
||||
#define IWLAGN_SCD_QUEUE_CTX_REG1_CREDIT_POS (8)
|
||||
#define IWLAGN_SCD_QUEUE_CTX_REG1_CREDIT_MSK (0x00FFFF00)
|
||||
#define IWLAGN_SCD_QUEUE_CTX_REG1_SUPER_CREDIT_POS (24)
|
||||
#define IWLAGN_SCD_QUEUE_CTX_REG1_SUPER_CREDIT_MSK (0xFF000000)
|
||||
#define IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS (0)
|
||||
#define IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK (0x0000007F)
|
||||
#define IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS (16)
|
||||
#define IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK (0x007F0000)
|
||||
|
||||
#define IWL50_SCD_CONTEXT_DATA_OFFSET (0x600)
|
||||
#define IWL50_SCD_TX_STTS_BITMAP_OFFSET (0x7B1)
|
||||
#define IWL50_SCD_TRANSLATE_TBL_OFFSET (0x7E0)
|
||||
#define IWLAGN_SCD_CONTEXT_DATA_OFFSET (0x600)
|
||||
#define IWLAGN_SCD_TX_STTS_BITMAP_OFFSET (0x7B1)
|
||||
#define IWLAGN_SCD_TRANSLATE_TBL_OFFSET (0x7E0)
|
||||
|
||||
#define IWL50_SCD_CONTEXT_QUEUE_OFFSET(x)\
|
||||
(IWL50_SCD_CONTEXT_DATA_OFFSET + ((x) * 8))
|
||||
#define IWLAGN_SCD_CONTEXT_QUEUE_OFFSET(x)\
|
||||
(IWLAGN_SCD_CONTEXT_DATA_OFFSET + ((x) * 8))
|
||||
|
||||
#define IWL50_SCD_TRANSLATE_TBL_OFFSET_QUEUE(x) \
|
||||
((IWL50_SCD_TRANSLATE_TBL_OFFSET + ((x) * 2)) & 0xfffc)
|
||||
#define IWLAGN_SCD_TRANSLATE_TBL_OFFSET_QUEUE(x) \
|
||||
((IWLAGN_SCD_TRANSLATE_TBL_OFFSET + ((x) * 2)) & 0xfffc)
|
||||
|
||||
#define IWL50_SCD_QUEUECHAIN_SEL_ALL(x) (((1<<(x)) - 1) &\
|
||||
#define IWLAGN_SCD_QUEUECHAIN_SEL_ALL(x) (((1<<(x)) - 1) &\
|
||||
(~(1<<IWL_CMD_QUEUE_NUM)))
|
||||
|
||||
#define IWL50_SCD_BASE (PRPH_BASE + 0xa02c00)
|
||||
#define IWLAGN_SCD_BASE (PRPH_BASE + 0xa02c00)
|
||||
|
||||
#define IWL50_SCD_SRAM_BASE_ADDR (IWL50_SCD_BASE + 0x0)
|
||||
#define IWL50_SCD_DRAM_BASE_ADDR (IWL50_SCD_BASE + 0x8)
|
||||
#define IWL50_SCD_AIT (IWL50_SCD_BASE + 0x0c)
|
||||
#define IWL50_SCD_TXFACT (IWL50_SCD_BASE + 0x10)
|
||||
#define IWL50_SCD_ACTIVE (IWL50_SCD_BASE + 0x14)
|
||||
#define IWL50_SCD_QUEUE_WRPTR(x) (IWL50_SCD_BASE + 0x18 + (x) * 4)
|
||||
#define IWL50_SCD_QUEUE_RDPTR(x) (IWL50_SCD_BASE + 0x68 + (x) * 4)
|
||||
#define IWL50_SCD_QUEUECHAIN_SEL (IWL50_SCD_BASE + 0xe8)
|
||||
#define IWL50_SCD_AGGR_SEL (IWL50_SCD_BASE + 0x248)
|
||||
#define IWL50_SCD_INTERRUPT_MASK (IWL50_SCD_BASE + 0x108)
|
||||
#define IWL50_SCD_QUEUE_STATUS_BITS(x) (IWL50_SCD_BASE + 0x10c + (x) * 4)
|
||||
#define IWLAGN_SCD_SRAM_BASE_ADDR (IWLAGN_SCD_BASE + 0x0)
|
||||
#define IWLAGN_SCD_DRAM_BASE_ADDR (IWLAGN_SCD_BASE + 0x8)
|
||||
#define IWLAGN_SCD_AIT (IWLAGN_SCD_BASE + 0x0c)
|
||||
#define IWLAGN_SCD_TXFACT (IWLAGN_SCD_BASE + 0x10)
|
||||
#define IWLAGN_SCD_ACTIVE (IWLAGN_SCD_BASE + 0x14)
|
||||
#define IWLAGN_SCD_QUEUE_WRPTR(x) (IWLAGN_SCD_BASE + 0x18 + (x) * 4)
|
||||
#define IWLAGN_SCD_QUEUE_RDPTR(x) (IWLAGN_SCD_BASE + 0x68 + (x) * 4)
|
||||
#define IWLAGN_SCD_QUEUECHAIN_SEL (IWLAGN_SCD_BASE + 0xe8)
|
||||
#define IWLAGN_SCD_AGGR_SEL (IWLAGN_SCD_BASE + 0x248)
|
||||
#define IWLAGN_SCD_INTERRUPT_MASK (IWLAGN_SCD_BASE + 0x108)
|
||||
#define IWLAGN_SCD_QUEUE_STATUS_BITS(x) (IWLAGN_SCD_BASE + 0x10c + (x) * 4)
|
||||
|
||||
/*********************** END TX SCHEDULER *************************************/
|
||||
|
||||
|
@ -69,9 +69,8 @@ int iwl_scan_cancel(struct iwl_priv *priv)
|
||||
}
|
||||
|
||||
if (test_bit(STATUS_SCANNING, &priv->status)) {
|
||||
if (!test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
|
||||
if (!test_and_set_bit(STATUS_SCAN_ABORTING, &priv->status)) {
|
||||
IWL_DEBUG_SCAN(priv, "Queuing scan abort.\n");
|
||||
set_bit(STATUS_SCAN_ABORTING, &priv->status);
|
||||
queue_work(priv->workqueue, &priv->abort_scan);
|
||||
|
||||
} else
|
||||
@ -201,9 +200,6 @@ static void iwl_rx_scan_results_notif(struct iwl_priv *priv,
|
||||
le32_to_cpu(notif->statistics[0]),
|
||||
le32_to_cpu(notif->tsf_low) - priv->scan_start_tsf);
|
||||
#endif
|
||||
|
||||
if (!priv->is_internal_short_scan)
|
||||
priv->next_scan_jiffies = 0;
|
||||
}
|
||||
|
||||
/* Service SCAN_COMPLETE_NOTIFICATION (0x84) */
|
||||
@ -223,49 +219,24 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
|
||||
/* The HW is no longer scanning */
|
||||
clear_bit(STATUS_SCAN_HW, &priv->status);
|
||||
|
||||
IWL_DEBUG_INFO(priv, "Scan pass on %sGHz took %dms\n",
|
||||
(priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) ?
|
||||
"2.4" : "5.2",
|
||||
IWL_DEBUG_INFO(priv, "Scan on %sGHz took %dms\n",
|
||||
(priv->scan_band == IEEE80211_BAND_2GHZ) ? "2.4" : "5.2",
|
||||
jiffies_to_msecs(elapsed_jiffies
|
||||
(priv->scan_pass_start, jiffies)));
|
||||
(priv->scan_start, jiffies)));
|
||||
|
||||
/* Remove this scanned band from the list of pending
|
||||
* bands to scan, band G precedes A in order of scanning
|
||||
* as seen in iwl_bg_request_scan */
|
||||
if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ))
|
||||
priv->scan_bands &= ~BIT(IEEE80211_BAND_2GHZ);
|
||||
else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ))
|
||||
priv->scan_bands &= ~BIT(IEEE80211_BAND_5GHZ);
|
||||
|
||||
/* If a request to abort was given, or the scan did not succeed
|
||||
/*
|
||||
* If a request to abort was given, or the scan did not succeed
|
||||
* then we reset the scan state machine and terminate,
|
||||
* re-queuing another scan if one has been requested */
|
||||
if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
|
||||
* re-queuing another scan if one has been requested
|
||||
*/
|
||||
if (test_and_clear_bit(STATUS_SCAN_ABORTING, &priv->status))
|
||||
IWL_DEBUG_INFO(priv, "Aborted scan completed.\n");
|
||||
clear_bit(STATUS_SCAN_ABORTING, &priv->status);
|
||||
} else {
|
||||
/* If there are more bands on this scan pass reschedule */
|
||||
if (priv->scan_bands)
|
||||
goto reschedule;
|
||||
}
|
||||
|
||||
if (!priv->is_internal_short_scan)
|
||||
priv->next_scan_jiffies = 0;
|
||||
|
||||
IWL_DEBUG_INFO(priv, "Setting scan to off\n");
|
||||
|
||||
clear_bit(STATUS_SCANNING, &priv->status);
|
||||
|
||||
IWL_DEBUG_INFO(priv, "Scan took %dms\n",
|
||||
jiffies_to_msecs(elapsed_jiffies(priv->scan_start, jiffies)));
|
||||
|
||||
queue_work(priv->workqueue, &priv->scan_completed);
|
||||
|
||||
return;
|
||||
|
||||
reschedule:
|
||||
priv->scan_pass_start = jiffies;
|
||||
queue_work(priv->workqueue, &priv->request_scan);
|
||||
}
|
||||
|
||||
void iwl_setup_rx_scan_handlers(struct iwl_priv *priv)
|
||||
@ -314,150 +285,6 @@ u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
|
||||
}
|
||||
EXPORT_SYMBOL(iwl_get_passive_dwell_time);
|
||||
|
||||
static int iwl_get_single_channel_for_scan(struct iwl_priv *priv,
|
||||
enum ieee80211_band band,
|
||||
struct iwl_scan_channel *scan_ch)
|
||||
{
|
||||
const struct ieee80211_supported_band *sband;
|
||||
const struct iwl_channel_info *ch_info;
|
||||
u16 passive_dwell = 0;
|
||||
u16 active_dwell = 0;
|
||||
int i, added = 0;
|
||||
u16 channel = 0;
|
||||
|
||||
sband = iwl_get_hw_mode(priv, band);
|
||||
if (!sband) {
|
||||
IWL_ERR(priv, "invalid band\n");
|
||||
return added;
|
||||
}
|
||||
|
||||
active_dwell = iwl_get_active_dwell_time(priv, band, 0);
|
||||
passive_dwell = iwl_get_passive_dwell_time(priv, band);
|
||||
|
||||
if (passive_dwell <= active_dwell)
|
||||
passive_dwell = active_dwell + 1;
|
||||
|
||||
/* only scan single channel, good enough to reset the RF */
|
||||
/* pick the first valid not in-use channel */
|
||||
if (band == IEEE80211_BAND_5GHZ) {
|
||||
for (i = 14; i < priv->channel_count; i++) {
|
||||
if (priv->channel_info[i].channel !=
|
||||
le16_to_cpu(priv->staging_rxon.channel)) {
|
||||
channel = priv->channel_info[i].channel;
|
||||
ch_info = iwl_get_channel_info(priv,
|
||||
band, channel);
|
||||
if (is_channel_valid(ch_info))
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < 14; i++) {
|
||||
if (priv->channel_info[i].channel !=
|
||||
le16_to_cpu(priv->staging_rxon.channel)) {
|
||||
channel =
|
||||
priv->channel_info[i].channel;
|
||||
ch_info = iwl_get_channel_info(priv,
|
||||
band, channel);
|
||||
if (is_channel_valid(ch_info))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (channel) {
|
||||
scan_ch->channel = cpu_to_le16(channel);
|
||||
scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
|
||||
scan_ch->active_dwell = cpu_to_le16(active_dwell);
|
||||
scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
|
||||
/* Set txpower levels to defaults */
|
||||
scan_ch->dsp_atten = 110;
|
||||
if (band == IEEE80211_BAND_5GHZ)
|
||||
scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
|
||||
else
|
||||
scan_ch->tx_gain = ((1 << 5) | (5 << 3));
|
||||
added++;
|
||||
} else
|
||||
IWL_ERR(priv, "no valid channel found\n");
|
||||
return added;
|
||||
}
|
||||
|
||||
static int iwl_get_channels_for_scan(struct iwl_priv *priv,
|
||||
enum ieee80211_band band,
|
||||
u8 is_active, u8 n_probes,
|
||||
struct iwl_scan_channel *scan_ch)
|
||||
{
|
||||
struct ieee80211_channel *chan;
|
||||
const struct ieee80211_supported_band *sband;
|
||||
const struct iwl_channel_info *ch_info;
|
||||
u16 passive_dwell = 0;
|
||||
u16 active_dwell = 0;
|
||||
int added, i;
|
||||
u16 channel;
|
||||
|
||||
sband = iwl_get_hw_mode(priv, band);
|
||||
if (!sband)
|
||||
return 0;
|
||||
|
||||
active_dwell = iwl_get_active_dwell_time(priv, band, n_probes);
|
||||
passive_dwell = iwl_get_passive_dwell_time(priv, band);
|
||||
|
||||
if (passive_dwell <= active_dwell)
|
||||
passive_dwell = active_dwell + 1;
|
||||
|
||||
for (i = 0, added = 0; i < priv->scan_request->n_channels; i++) {
|
||||
chan = priv->scan_request->channels[i];
|
||||
|
||||
if (chan->band != band)
|
||||
continue;
|
||||
|
||||
channel = ieee80211_frequency_to_channel(chan->center_freq);
|
||||
scan_ch->channel = cpu_to_le16(channel);
|
||||
|
||||
ch_info = iwl_get_channel_info(priv, band, channel);
|
||||
if (!is_channel_valid(ch_info)) {
|
||||
IWL_DEBUG_SCAN(priv, "Channel %d is INVALID for this band.\n",
|
||||
channel);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!is_active || is_channel_passive(ch_info) ||
|
||||
(chan->flags & IEEE80211_CHAN_PASSIVE_SCAN))
|
||||
scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
|
||||
else
|
||||
scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE;
|
||||
|
||||
if (n_probes)
|
||||
scan_ch->type |= IWL_SCAN_PROBE_MASK(n_probes);
|
||||
|
||||
scan_ch->active_dwell = cpu_to_le16(active_dwell);
|
||||
scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
|
||||
|
||||
/* Set txpower levels to defaults */
|
||||
scan_ch->dsp_atten = 110;
|
||||
|
||||
/* NOTE: if we were doing 6Mb OFDM for scans we'd use
|
||||
* power level:
|
||||
* scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3;
|
||||
*/
|
||||
if (band == IEEE80211_BAND_5GHZ)
|
||||
scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
|
||||
else
|
||||
scan_ch->tx_gain = ((1 << 5) | (5 << 3));
|
||||
|
||||
IWL_DEBUG_SCAN(priv, "Scanning ch=%d prob=0x%X [%s %d]\n",
|
||||
channel, le32_to_cpu(scan_ch->type),
|
||||
(scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) ?
|
||||
"ACTIVE" : "PASSIVE",
|
||||
(scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) ?
|
||||
active_dwell : passive_dwell);
|
||||
|
||||
scan_ch++;
|
||||
added++;
|
||||
}
|
||||
|
||||
IWL_DEBUG_SCAN(priv, "total channels to scan %d\n", added);
|
||||
return added;
|
||||
}
|
||||
|
||||
void iwl_init_scan_params(struct iwl_priv *priv)
|
||||
{
|
||||
u8 ant_idx = fls(priv->hw_params.valid_tx_ant) - 1;
|
||||
@ -476,26 +303,27 @@ static int iwl_scan_initiate(struct iwl_priv *priv)
|
||||
set_bit(STATUS_SCANNING, &priv->status);
|
||||
priv->is_internal_short_scan = false;
|
||||
priv->scan_start = jiffies;
|
||||
priv->scan_pass_start = priv->scan_start;
|
||||
|
||||
queue_work(priv->workqueue, &priv->request_scan);
|
||||
if (WARN_ON(!priv->cfg->ops->utils->request_scan))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
priv->cfg->ops->utils->request_scan(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define IWL_DELAY_NEXT_SCAN (HZ*2)
|
||||
|
||||
int iwl_mac_hw_scan(struct ieee80211_hw *hw,
|
||||
struct cfg80211_scan_request *req)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct iwl_priv *priv = hw->priv;
|
||||
int ret, i;
|
||||
int ret;
|
||||
|
||||
IWL_DEBUG_MAC80211(priv, "enter\n");
|
||||
|
||||
if (req->n_channels == 0)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
|
||||
if (!iwl_is_ready_rf(priv)) {
|
||||
ret = -EIO;
|
||||
@ -515,22 +343,8 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
/* We don't schedule scan within next_scan_jiffies period.
|
||||
* Avoid scanning during possible EAPOL exchange, return
|
||||
* success immediately.
|
||||
*/
|
||||
if (priv->next_scan_jiffies &&
|
||||
time_after(priv->next_scan_jiffies, jiffies)) {
|
||||
IWL_DEBUG_SCAN(priv, "scan rejected: within next scan period\n");
|
||||
queue_work(priv->workqueue, &priv->scan_completed);
|
||||
ret = 0;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
priv->scan_bands = 0;
|
||||
for (i = 0; i < req->n_channels; i++)
|
||||
priv->scan_bands |= BIT(req->channels[i]->band);
|
||||
|
||||
/* mac80211 will only ask for one band at a time */
|
||||
priv->scan_band = req->channels[0]->band;
|
||||
priv->scan_request = req;
|
||||
|
||||
ret = iwl_scan_initiate(priv);
|
||||
@ -538,7 +352,6 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
|
||||
IWL_DEBUG_MAC80211(priv, "leave\n");
|
||||
|
||||
out_unlock:
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
mutex_unlock(&priv->mutex);
|
||||
|
||||
return ret;
|
||||
@ -576,22 +389,20 @@ static void iwl_bg_start_internal_scan(struct work_struct *work)
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
priv->scan_bands = 0;
|
||||
if (priv->band == IEEE80211_BAND_5GHZ)
|
||||
priv->scan_bands |= BIT(IEEE80211_BAND_5GHZ);
|
||||
else
|
||||
priv->scan_bands |= BIT(IEEE80211_BAND_2GHZ);
|
||||
priv->scan_band = priv->band;
|
||||
|
||||
IWL_DEBUG_SCAN(priv, "Start internal short scan...\n");
|
||||
set_bit(STATUS_SCANNING, &priv->status);
|
||||
priv->is_internal_short_scan = true;
|
||||
queue_work(priv->workqueue, &priv->request_scan);
|
||||
|
||||
if (WARN_ON(!priv->cfg->ops->utils->request_scan))
|
||||
goto unlock;
|
||||
|
||||
priv->cfg->ops->utils->request_scan(priv);
|
||||
unlock:
|
||||
mutex_unlock(&priv->mutex);
|
||||
}
|
||||
|
||||
#define IWL_SCAN_CHECK_WATCHDOG (7 * HZ)
|
||||
|
||||
void iwl_bg_scan_check(struct work_struct *data)
|
||||
{
|
||||
struct iwl_priv *priv =
|
||||
@ -653,275 +464,15 @@ u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
|
||||
if (WARN_ON(left < ie_len))
|
||||
return len;
|
||||
|
||||
if (ies)
|
||||
if (ies && ie_len) {
|
||||
memcpy(pos, ies, ie_len);
|
||||
len += ie_len;
|
||||
left -= ie_len;
|
||||
len += ie_len;
|
||||
}
|
||||
|
||||
return (u16)len;
|
||||
}
|
||||
EXPORT_SYMBOL(iwl_fill_probe_req);
|
||||
|
||||
static void iwl_bg_request_scan(struct work_struct *data)
|
||||
{
|
||||
struct iwl_priv *priv =
|
||||
container_of(data, struct iwl_priv, request_scan);
|
||||
struct iwl_host_cmd cmd = {
|
||||
.id = REPLY_SCAN_CMD,
|
||||
.len = sizeof(struct iwl_scan_cmd),
|
||||
.flags = CMD_SIZE_HUGE,
|
||||
};
|
||||
struct iwl_scan_cmd *scan;
|
||||
struct ieee80211_conf *conf = NULL;
|
||||
u32 rate_flags = 0;
|
||||
u16 cmd_len;
|
||||
u16 rx_chain = 0;
|
||||
enum ieee80211_band band;
|
||||
u8 n_probes = 0;
|
||||
u8 rx_ant = priv->hw_params.valid_rx_ant;
|
||||
u8 rate;
|
||||
bool is_active = false;
|
||||
int chan_mod;
|
||||
u8 active_chains;
|
||||
|
||||
conf = ieee80211_get_hw_conf(priv->hw);
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
|
||||
cancel_delayed_work(&priv->scan_check);
|
||||
|
||||
if (!iwl_is_ready(priv)) {
|
||||
IWL_WARN(priv, "request scan called when driver not ready.\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Make sure the scan wasn't canceled before this queued work
|
||||
* was given the chance to run... */
|
||||
if (!test_bit(STATUS_SCANNING, &priv->status))
|
||||
goto done;
|
||||
|
||||
/* This should never be called or scheduled if there is currently
|
||||
* a scan active in the hardware. */
|
||||
if (test_bit(STATUS_SCAN_HW, &priv->status)) {
|
||||
IWL_DEBUG_INFO(priv, "Multiple concurrent scan requests in parallel. "
|
||||
"Ignoring second request.\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
|
||||
IWL_DEBUG_SCAN(priv, "Aborting scan due to device shutdown\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
|
||||
IWL_DEBUG_HC(priv, "Scan request while abort pending. Queuing.\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (iwl_is_rfkill(priv)) {
|
||||
IWL_DEBUG_HC(priv, "Aborting scan due to RF Kill activation\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!test_bit(STATUS_READY, &priv->status)) {
|
||||
IWL_DEBUG_HC(priv, "Scan request while uninitialized. Queuing.\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!priv->scan_bands) {
|
||||
IWL_DEBUG_HC(priv, "Aborting scan due to no requested bands\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!priv->scan) {
|
||||
priv->scan = kmalloc(sizeof(struct iwl_scan_cmd) +
|
||||
IWL_MAX_SCAN_SIZE, GFP_KERNEL);
|
||||
if (!priv->scan) {
|
||||
IWL_DEBUG_SCAN(priv,
|
||||
"fail to allocate memory for scan\n");
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
scan = priv->scan;
|
||||
memset(scan, 0, sizeof(struct iwl_scan_cmd) + IWL_MAX_SCAN_SIZE);
|
||||
|
||||
scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
|
||||
scan->quiet_time = IWL_ACTIVE_QUIET_TIME;
|
||||
|
||||
if (iwl_is_associated(priv)) {
|
||||
u16 interval = 0;
|
||||
u32 extra;
|
||||
u32 suspend_time = 100;
|
||||
u32 scan_suspend_time = 100;
|
||||
unsigned long flags;
|
||||
|
||||
IWL_DEBUG_INFO(priv, "Scanning while associated...\n");
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
interval = priv->beacon_int;
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
scan->suspend_time = 0;
|
||||
scan->max_out_time = cpu_to_le32(200 * 1024);
|
||||
if (!interval)
|
||||
interval = suspend_time;
|
||||
|
||||
extra = (suspend_time / interval) << 22;
|
||||
scan_suspend_time = (extra |
|
||||
((suspend_time % interval) * 1024));
|
||||
scan->suspend_time = cpu_to_le32(scan_suspend_time);
|
||||
IWL_DEBUG_SCAN(priv, "suspend_time 0x%X beacon interval %d\n",
|
||||
scan_suspend_time, interval);
|
||||
}
|
||||
|
||||
if (priv->is_internal_short_scan) {
|
||||
IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n");
|
||||
} else if (priv->scan_request->n_ssids) {
|
||||
int i, p = 0;
|
||||
IWL_DEBUG_SCAN(priv, "Kicking off active scan\n");
|
||||
for (i = 0; i < priv->scan_request->n_ssids; i++) {
|
||||
/* always does wildcard anyway */
|
||||
if (!priv->scan_request->ssids[i].ssid_len)
|
||||
continue;
|
||||
scan->direct_scan[p].id = WLAN_EID_SSID;
|
||||
scan->direct_scan[p].len =
|
||||
priv->scan_request->ssids[i].ssid_len;
|
||||
memcpy(scan->direct_scan[p].ssid,
|
||||
priv->scan_request->ssids[i].ssid,
|
||||
priv->scan_request->ssids[i].ssid_len);
|
||||
n_probes++;
|
||||
p++;
|
||||
}
|
||||
is_active = true;
|
||||
} else
|
||||
IWL_DEBUG_SCAN(priv, "Start passive scan.\n");
|
||||
|
||||
scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
|
||||
scan->tx_cmd.sta_id = priv->hw_params.bcast_sta_id;
|
||||
scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
|
||||
|
||||
|
||||
if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) {
|
||||
band = IEEE80211_BAND_2GHZ;
|
||||
scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
|
||||
chan_mod = le32_to_cpu(priv->active_rxon.flags & RXON_FLG_CHANNEL_MODE_MSK)
|
||||
>> RXON_FLG_CHANNEL_MODE_POS;
|
||||
if (chan_mod == CHANNEL_MODE_PURE_40) {
|
||||
rate = IWL_RATE_6M_PLCP;
|
||||
} else {
|
||||
rate = IWL_RATE_1M_PLCP;
|
||||
rate_flags = RATE_MCS_CCK_MSK;
|
||||
}
|
||||
scan->good_CRC_th = 0;
|
||||
} else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) {
|
||||
band = IEEE80211_BAND_5GHZ;
|
||||
rate = IWL_RATE_6M_PLCP;
|
||||
/*
|
||||
* If active scaning is requested but a certain channel
|
||||
* is marked passive, we can do active scanning if we
|
||||
* detect transmissions.
|
||||
*/
|
||||
scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH : 0;
|
||||
|
||||
/* Force use of chains B and C (0x6) for scan Rx
|
||||
* Avoid A (0x1) for the device has off-channel reception
|
||||
* on A-band.
|
||||
*/
|
||||
if (priv->cfg->off_channel_workaround)
|
||||
rx_ant = ANT_BC;
|
||||
} else {
|
||||
IWL_WARN(priv, "Invalid scan band count\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
priv->scan_tx_ant[band] =
|
||||
iwl_toggle_tx_ant(priv, priv->scan_tx_ant[band]);
|
||||
rate_flags |= iwl_ant_idx_to_flags(priv->scan_tx_ant[band]);
|
||||
scan->tx_cmd.rate_n_flags = iwl_hw_set_rate_n_flags(rate, rate_flags);
|
||||
|
||||
/* In power save mode use one chain, otherwise use all chains */
|
||||
if (test_bit(STATUS_POWER_PMI, &priv->status)) {
|
||||
/* rx_ant has been set to all valid chains previously */
|
||||
active_chains = rx_ant &
|
||||
((u8)(priv->chain_noise_data.active_chains));
|
||||
if (!active_chains)
|
||||
active_chains = rx_ant;
|
||||
|
||||
IWL_DEBUG_SCAN(priv, "chain_noise_data.active_chains: %u\n",
|
||||
priv->chain_noise_data.active_chains);
|
||||
|
||||
rx_ant = first_antenna(active_chains);
|
||||
}
|
||||
/* MIMO is not used here, but value is required */
|
||||
rx_chain |= priv->hw_params.valid_rx_ant << RXON_RX_CHAIN_VALID_POS;
|
||||
rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS;
|
||||
rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS;
|
||||
rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS;
|
||||
scan->rx_chain = cpu_to_le16(rx_chain);
|
||||
if (!priv->is_internal_short_scan) {
|
||||
cmd_len = iwl_fill_probe_req(priv,
|
||||
(struct ieee80211_mgmt *)scan->data,
|
||||
priv->scan_request->ie,
|
||||
priv->scan_request->ie_len,
|
||||
IWL_MAX_SCAN_SIZE - sizeof(*scan));
|
||||
} else {
|
||||
cmd_len = iwl_fill_probe_req(priv,
|
||||
(struct ieee80211_mgmt *)scan->data,
|
||||
NULL, 0,
|
||||
IWL_MAX_SCAN_SIZE - sizeof(*scan));
|
||||
|
||||
}
|
||||
scan->tx_cmd.len = cpu_to_le16(cmd_len);
|
||||
if (iwl_is_monitor_mode(priv))
|
||||
scan->filter_flags = RXON_FILTER_PROMISC_MSK;
|
||||
|
||||
scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK |
|
||||
RXON_FILTER_BCON_AWARE_MSK);
|
||||
|
||||
if (priv->is_internal_short_scan) {
|
||||
scan->channel_count =
|
||||
iwl_get_single_channel_for_scan(priv, band,
|
||||
(void *)&scan->data[le16_to_cpu(
|
||||
scan->tx_cmd.len)]);
|
||||
} else {
|
||||
scan->channel_count =
|
||||
iwl_get_channels_for_scan(priv, band,
|
||||
is_active, n_probes,
|
||||
(void *)&scan->data[le16_to_cpu(
|
||||
scan->tx_cmd.len)]);
|
||||
}
|
||||
if (scan->channel_count == 0) {
|
||||
IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count);
|
||||
goto done;
|
||||
}
|
||||
|
||||
cmd.len += le16_to_cpu(scan->tx_cmd.len) +
|
||||
scan->channel_count * sizeof(struct iwl_scan_channel);
|
||||
cmd.data = scan;
|
||||
scan->len = cpu_to_le16(cmd.len);
|
||||
|
||||
set_bit(STATUS_SCAN_HW, &priv->status);
|
||||
if (iwl_send_cmd_sync(priv, &cmd))
|
||||
goto done;
|
||||
|
||||
queue_delayed_work(priv->workqueue, &priv->scan_check,
|
||||
IWL_SCAN_CHECK_WATCHDOG);
|
||||
|
||||
mutex_unlock(&priv->mutex);
|
||||
return;
|
||||
|
||||
done:
|
||||
/* Cannot perform scan. Make sure we clear scanning
|
||||
* bits from status so next scan request can be performed.
|
||||
* If we don't clear scanning status bit here all next scan
|
||||
* will fail
|
||||
*/
|
||||
clear_bit(STATUS_SCAN_HW, &priv->status);
|
||||
clear_bit(STATUS_SCANNING, &priv->status);
|
||||
/* inform mac80211 scan aborted */
|
||||
queue_work(priv->workqueue, &priv->scan_completed);
|
||||
mutex_unlock(&priv->mutex);
|
||||
}
|
||||
|
||||
void iwl_bg_abort_scan(struct work_struct *work)
|
||||
{
|
||||
struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan);
|
||||
@ -969,7 +520,6 @@ EXPORT_SYMBOL(iwl_bg_scan_completed);
|
||||
void iwl_setup_scan_deferred_work(struct iwl_priv *priv)
|
||||
{
|
||||
INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed);
|
||||
INIT_WORK(&priv->request_scan, iwl_bg_request_scan);
|
||||
INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan);
|
||||
INIT_WORK(&priv->start_internal_scan, iwl_bg_start_internal_scan);
|
||||
INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check);
|
||||
|
@ -451,7 +451,17 @@ static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, bool is_ap)
|
||||
|
||||
link_cmd.general_params.single_stream_ant_msk =
|
||||
first_antenna(priv->hw_params.valid_tx_ant);
|
||||
link_cmd.general_params.dual_stream_ant_msk = 3;
|
||||
|
||||
link_cmd.general_params.dual_stream_ant_msk =
|
||||
priv->hw_params.valid_tx_ant &
|
||||
~first_antenna(priv->hw_params.valid_tx_ant);
|
||||
if (!link_cmd.general_params.dual_stream_ant_msk) {
|
||||
link_cmd.general_params.dual_stream_ant_msk = ANT_AB;
|
||||
} else if (num_of_ant(priv->hw_params.valid_tx_ant) == 2) {
|
||||
link_cmd.general_params.dual_stream_ant_msk =
|
||||
priv->hw_params.valid_tx_ant;
|
||||
}
|
||||
|
||||
link_cmd.agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
|
||||
link_cmd.agg_params.agg_time_limit =
|
||||
cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
|
||||
@ -1196,7 +1206,6 @@ int iwl_send_lq_cmd(struct iwl_priv *priv,
|
||||
iwl_dump_lq_cmd(priv, lq);
|
||||
BUG_ON(init && (cmd.flags & CMD_ASYNC));
|
||||
|
||||
iwl_dump_lq_cmd(priv, lq);
|
||||
ret = iwl_send_cmd(priv, &cmd);
|
||||
if (ret || (cmd.flags & CMD_ASYNC))
|
||||
return ret;
|
||||
|
@ -2527,7 +2527,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
|
||||
}
|
||||
|
||||
/* Configure Bluetooth device coexistence support */
|
||||
iwl_send_bt_config(priv);
|
||||
priv->cfg->ops->hcmd->send_bt_config(priv);
|
||||
|
||||
/* Configure the adapter for unassociated operation */
|
||||
iwlcore_commit_rxon(priv);
|
||||
@ -2791,11 +2791,8 @@ static void iwl3945_rfkill_poll(struct work_struct *data)
|
||||
|
||||
}
|
||||
|
||||
#define IWL_SCAN_CHECK_WATCHDOG (7 * HZ)
|
||||
static void iwl3945_bg_request_scan(struct work_struct *data)
|
||||
void iwl3945_request_scan(struct iwl_priv *priv)
|
||||
{
|
||||
struct iwl_priv *priv =
|
||||
container_of(data, struct iwl_priv, request_scan);
|
||||
struct iwl_host_cmd cmd = {
|
||||
.id = REPLY_SCAN_CMD,
|
||||
.len = sizeof(struct iwl3945_scan_cmd),
|
||||
@ -2809,8 +2806,6 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
|
||||
|
||||
conf = ieee80211_get_hw_conf(priv->hw);
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
|
||||
cancel_delayed_work(&priv->scan_check);
|
||||
|
||||
if (!iwl_is_ready(priv)) {
|
||||
@ -2853,20 +2848,15 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!priv->scan_bands) {
|
||||
IWL_DEBUG_HC(priv, "Aborting scan due to no requested bands\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!priv->scan) {
|
||||
priv->scan = kmalloc(sizeof(struct iwl3945_scan_cmd) +
|
||||
IWL_MAX_SCAN_SIZE, GFP_KERNEL);
|
||||
if (!priv->scan) {
|
||||
if (!priv->scan_cmd) {
|
||||
priv->scan_cmd = kmalloc(sizeof(struct iwl3945_scan_cmd) +
|
||||
IWL_MAX_SCAN_SIZE, GFP_KERNEL);
|
||||
if (!priv->scan_cmd) {
|
||||
IWL_DEBUG_SCAN(priv, "Fail to allocate scan memory\n");
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
scan = priv->scan;
|
||||
scan = priv->scan_cmd;
|
||||
memset(scan, 0, sizeof(struct iwl3945_scan_cmd) + IWL_MAX_SCAN_SIZE);
|
||||
|
||||
scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
|
||||
@ -2935,12 +2925,14 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
|
||||
|
||||
/* flags + rate selection */
|
||||
|
||||
if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) {
|
||||
switch (priv->scan_band) {
|
||||
case IEEE80211_BAND_2GHZ:
|
||||
scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
|
||||
scan->tx_cmd.rate = IWL_RATE_1M_PLCP;
|
||||
scan->good_CRC_th = 0;
|
||||
band = IEEE80211_BAND_2GHZ;
|
||||
} else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) {
|
||||
break;
|
||||
case IEEE80211_BAND_5GHZ:
|
||||
scan->tx_cmd.rate = IWL_RATE_6M_PLCP;
|
||||
/*
|
||||
* If active scaning is requested but a certain channel
|
||||
@ -2949,8 +2941,9 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
|
||||
*/
|
||||
scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH : 0;
|
||||
band = IEEE80211_BAND_5GHZ;
|
||||
} else {
|
||||
IWL_WARN(priv, "Invalid scan band count\n");
|
||||
break;
|
||||
default:
|
||||
IWL_WARN(priv, "Invalid scan band\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
@ -2971,9 +2964,6 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
|
||||
/* select Rx antennas */
|
||||
scan->flags |= iwl3945_get_antenna_flags(priv);
|
||||
|
||||
if (iwl_is_monitor_mode(priv))
|
||||
scan->filter_flags = RXON_FILTER_PROMISC_MSK;
|
||||
|
||||
scan->channel_count =
|
||||
iwl3945_get_channels_for_scan(priv, band, is_active, n_probes,
|
||||
(void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
|
||||
@ -2995,7 +2985,6 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
|
||||
queue_delayed_work(priv->workqueue, &priv->scan_check,
|
||||
IWL_SCAN_CHECK_WATCHDOG);
|
||||
|
||||
mutex_unlock(&priv->mutex);
|
||||
return;
|
||||
|
||||
done:
|
||||
@ -3009,7 +2998,6 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
|
||||
|
||||
/* inform mac80211 scan aborted */
|
||||
queue_work(priv->workqueue, &priv->scan_completed);
|
||||
mutex_unlock(&priv->mutex);
|
||||
}
|
||||
|
||||
static void iwl3945_bg_restart(struct work_struct *data)
|
||||
@ -3051,8 +3039,6 @@ static void iwl3945_bg_rx_replenish(struct work_struct *data)
|
||||
mutex_unlock(&priv->mutex);
|
||||
}
|
||||
|
||||
#define IWL_DELAY_NEXT_SCAN (HZ*2)
|
||||
|
||||
void iwl3945_post_associate(struct iwl_priv *priv)
|
||||
{
|
||||
int rc = 0;
|
||||
@ -3137,9 +3123,6 @@ void iwl3945_post_associate(struct iwl_priv *priv)
|
||||
__func__, priv->iw_mode);
|
||||
break;
|
||||
}
|
||||
|
||||
/* we have just associated, don't start scan too early */
|
||||
priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
@ -3672,44 +3655,6 @@ static ssize_t show_channels(struct device *d,
|
||||
|
||||
static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL);
|
||||
|
||||
static ssize_t show_statistics(struct device *d,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct iwl_priv *priv = dev_get_drvdata(d);
|
||||
u32 size = sizeof(struct iwl3945_notif_statistics);
|
||||
u32 len = 0, ofs = 0;
|
||||
u8 *data = (u8 *)&priv->_3945.statistics;
|
||||
int rc = 0;
|
||||
|
||||
if (!iwl_is_alive(priv))
|
||||
return -EAGAIN;
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
rc = iwl_send_statistics_request(priv, CMD_SYNC, false);
|
||||
mutex_unlock(&priv->mutex);
|
||||
|
||||
if (rc) {
|
||||
len = sprintf(buf,
|
||||
"Error sending statistics request: 0x%08X\n", rc);
|
||||
return len;
|
||||
}
|
||||
|
||||
while (size && (PAGE_SIZE - len)) {
|
||||
hex_dump_to_buffer(data + ofs, size, 16, 1, buf + len,
|
||||
PAGE_SIZE - len, 1);
|
||||
len = strlen(buf);
|
||||
if (PAGE_SIZE - len)
|
||||
buf[len++] = '\n';
|
||||
|
||||
ofs += 16;
|
||||
size -= min(size, 16U);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(statistics, S_IRUGO, show_statistics, NULL);
|
||||
|
||||
static ssize_t show_antenna(struct device *d,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
@ -3793,7 +3738,6 @@ static void iwl3945_setup_deferred_work(struct iwl_priv *priv)
|
||||
INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start);
|
||||
INIT_DELAYED_WORK(&priv->_3945.rfkill_poll, iwl3945_rfkill_poll);
|
||||
INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed);
|
||||
INIT_WORK(&priv->request_scan, iwl3945_bg_request_scan);
|
||||
INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan);
|
||||
INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check);
|
||||
|
||||
@ -3830,7 +3774,6 @@ static struct attribute *iwl3945_sysfs_entries[] = {
|
||||
&dev_attr_filter_flags.attr,
|
||||
&dev_attr_measurement.attr,
|
||||
&dev_attr_retry_rate.attr,
|
||||
&dev_attr_statistics.attr,
|
||||
&dev_attr_status.attr,
|
||||
&dev_attr_temperature.attr,
|
||||
&dev_attr_tx_power.attr,
|
||||
@ -4253,7 +4196,7 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
|
||||
|
||||
iwl_free_channel_map(priv);
|
||||
iwlcore_free_geos(priv);
|
||||
kfree(priv->scan);
|
||||
kfree(priv->scan_cmd);
|
||||
if (priv->ibss_beacon)
|
||||
dev_kfree_skb(priv->ibss_beacon);
|
||||
|
||||
|
@ -6,3 +6,5 @@ iwmc3200wifi-$(CONFIG_IWM_DEBUG) += debugfs.o
|
||||
iwmc3200wifi-$(CONFIG_IWM_TRACING) += trace.o
|
||||
|
||||
CFLAGS_trace.o := -I$(src)
|
||||
|
||||
ccflags-y += -D__CHECK_ENDIAN__
|
||||
|
@ -431,7 +431,8 @@ static int iwm_ntf_rx_ticket(struct iwm_priv *iwm, u8 *buf,
|
||||
return PTR_ERR(ticket_node);
|
||||
|
||||
IWM_DBG_RX(iwm, DBG, "TICKET %s(%d)\n",
|
||||
ticket->action == IWM_RX_TICKET_RELEASE ?
|
||||
__le16_to_cpu(ticket->action) ==
|
||||
IWM_RX_TICKET_RELEASE ?
|
||||
"RELEASE" : "DROP",
|
||||
ticket->id);
|
||||
spin_lock(&iwm->ticket_lock);
|
||||
|
@ -76,7 +76,7 @@ TRACE_EVENT(iwm_tx_wifi_cmd,
|
||||
IWM_ASSIGN;
|
||||
__entry->opcode = hdr->sw_hdr.cmd.cmd;
|
||||
__entry->lmac = 0;
|
||||
__entry->seq = hdr->sw_hdr.cmd.seq_num;
|
||||
__entry->seq = __le16_to_cpu(hdr->sw_hdr.cmd.seq_num);
|
||||
__entry->resp = GET_VAL8(hdr->sw_hdr.cmd.flags, UMAC_DEV_CMD_FLAGS_RESP_REQ);
|
||||
__entry->color = GET_VAL32(hdr->sw_hdr.meta_data, UMAC_FW_CMD_TX_STA_COLOR);
|
||||
__entry->eot = GET_VAL32(hdr->hw_hdr.cmd, UMAC_HDI_OUT_CMD_EOT);
|
||||
@ -123,7 +123,7 @@ TRACE_EVENT(iwm_tx_packets,
|
||||
__entry->ra_tid = GET_VAL32(hdr->hw_hdr.meta_data, UMAC_HDI_OUT_RATID);
|
||||
__entry->credit_group = GET_VAL32(hdr->hw_hdr.meta_data, UMAC_HDI_OUT_CREDIT_GRP);
|
||||
__entry->color = GET_VAL32(hdr->sw_hdr.meta_data, UMAC_FW_CMD_TX_STA_COLOR);
|
||||
__entry->seq = hdr->sw_hdr.cmd.seq_num;
|
||||
__entry->seq = __le16_to_cpu(hdr->sw_hdr.cmd.seq_num);
|
||||
__entry->npkt = 1;
|
||||
__entry->bytes = len;
|
||||
|
||||
|
@ -302,8 +302,8 @@ void iwm_tx_credit_init_pools(struct iwm_priv *iwm,
|
||||
|
||||
#define IWM_UDMA_HDR_LEN sizeof(struct iwm_umac_wifi_out_hdr)
|
||||
|
||||
static int iwm_tx_build_packet(struct iwm_priv *iwm, struct sk_buff *skb,
|
||||
int pool_id, u8 *buf)
|
||||
static __le16 iwm_tx_build_packet(struct iwm_priv *iwm, struct sk_buff *skb,
|
||||
int pool_id, u8 *buf)
|
||||
{
|
||||
struct iwm_umac_wifi_out_hdr *hdr = (struct iwm_umac_wifi_out_hdr *)buf;
|
||||
struct iwm_udma_wifi_cmd udma_cmd;
|
||||
|
@ -315,12 +315,28 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int if_sdio_wait_status(struct if_sdio_card *card, const u8 condition)
|
||||
{
|
||||
u8 status;
|
||||
unsigned long timeout;
|
||||
int ret = 0;
|
||||
|
||||
timeout = jiffies + HZ;
|
||||
while (1) {
|
||||
status = sdio_readb(card->func, IF_SDIO_STATUS, &ret);
|
||||
if (ret || (status & condition))
|
||||
break;
|
||||
if (time_after(jiffies, timeout))
|
||||
return -ETIMEDOUT;
|
||||
mdelay(1);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int if_sdio_card_to_host(struct if_sdio_card *card)
|
||||
{
|
||||
int ret;
|
||||
u8 status;
|
||||
u16 size, type, chunk;
|
||||
unsigned long timeout;
|
||||
|
||||
lbs_deb_enter(LBS_DEB_SDIO);
|
||||
|
||||
@ -335,19 +351,9 @@ static int if_sdio_card_to_host(struct if_sdio_card *card)
|
||||
goto out;
|
||||
}
|
||||
|
||||
timeout = jiffies + HZ;
|
||||
while (1) {
|
||||
status = sdio_readb(card->func, IF_SDIO_STATUS, &ret);
|
||||
if (ret)
|
||||
goto out;
|
||||
if (status & IF_SDIO_IO_RDY)
|
||||
break;
|
||||
if (time_after(jiffies, timeout)) {
|
||||
ret = -ETIMEDOUT;
|
||||
goto out;
|
||||
}
|
||||
mdelay(1);
|
||||
}
|
||||
ret = if_sdio_wait_status(card, IF_SDIO_IO_RDY);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* The transfer must be in one transaction or the firmware
|
||||
@ -414,8 +420,6 @@ static void if_sdio_host_to_card_worker(struct work_struct *work)
|
||||
{
|
||||
struct if_sdio_card *card;
|
||||
struct if_sdio_packet *packet;
|
||||
unsigned long timeout;
|
||||
u8 status;
|
||||
int ret;
|
||||
unsigned long flags;
|
||||
|
||||
@ -435,25 +439,15 @@ static void if_sdio_host_to_card_worker(struct work_struct *work)
|
||||
|
||||
sdio_claim_host(card->func);
|
||||
|
||||
timeout = jiffies + HZ;
|
||||
while (1) {
|
||||
status = sdio_readb(card->func, IF_SDIO_STATUS, &ret);
|
||||
if (ret)
|
||||
goto release;
|
||||
if (status & IF_SDIO_IO_RDY)
|
||||
break;
|
||||
if (time_after(jiffies, timeout)) {
|
||||
ret = -ETIMEDOUT;
|
||||
goto release;
|
||||
}
|
||||
mdelay(1);
|
||||
ret = if_sdio_wait_status(card, IF_SDIO_IO_RDY);
|
||||
if (ret == 0) {
|
||||
ret = sdio_writesb(card->func, card->ioport,
|
||||
packet->buffer, packet->nb);
|
||||
}
|
||||
|
||||
ret = sdio_writesb(card->func, card->ioport,
|
||||
packet->buffer, packet->nb);
|
||||
if (ret)
|
||||
goto release;
|
||||
release:
|
||||
lbs_pr_err("error %d sending packet to firmware\n", ret);
|
||||
|
||||
sdio_release_host(card->func);
|
||||
|
||||
kfree(packet);
|
||||
@ -466,10 +460,11 @@ release:
|
||||
/* Firmware */
|
||||
/********************************************************************/
|
||||
|
||||
#define FW_DL_READY_STATUS (IF_SDIO_IO_RDY | IF_SDIO_DL_RDY)
|
||||
|
||||
static int if_sdio_prog_helper(struct if_sdio_card *card)
|
||||
{
|
||||
int ret;
|
||||
u8 status;
|
||||
const struct firmware *fw;
|
||||
unsigned long timeout;
|
||||
u8 *chunk_buffer;
|
||||
@ -501,20 +496,14 @@ static int if_sdio_prog_helper(struct if_sdio_card *card)
|
||||
size = fw->size;
|
||||
|
||||
while (size) {
|
||||
timeout = jiffies + HZ;
|
||||
while (1) {
|
||||
status = sdio_readb(card->func, IF_SDIO_STATUS, &ret);
|
||||
if (ret)
|
||||
goto release;
|
||||
if ((status & IF_SDIO_IO_RDY) &&
|
||||
(status & IF_SDIO_DL_RDY))
|
||||
break;
|
||||
if (time_after(jiffies, timeout)) {
|
||||
ret = -ETIMEDOUT;
|
||||
goto release;
|
||||
}
|
||||
mdelay(1);
|
||||
}
|
||||
ret = if_sdio_wait_status(card, FW_DL_READY_STATUS);
|
||||
if (ret)
|
||||
goto release;
|
||||
|
||||
/* On some platforms (like Davinci) the chip needs more time
|
||||
* between helper blocks.
|
||||
*/
|
||||
mdelay(2);
|
||||
|
||||
chunk_size = min(size, (size_t)60);
|
||||
|
||||
@ -584,7 +573,6 @@ out:
|
||||
static int if_sdio_prog_real(struct if_sdio_card *card)
|
||||
{
|
||||
int ret;
|
||||
u8 status;
|
||||
const struct firmware *fw;
|
||||
unsigned long timeout;
|
||||
u8 *chunk_buffer;
|
||||
@ -616,20 +604,9 @@ static int if_sdio_prog_real(struct if_sdio_card *card)
|
||||
size = fw->size;
|
||||
|
||||
while (size) {
|
||||
timeout = jiffies + HZ;
|
||||
while (1) {
|
||||
status = sdio_readb(card->func, IF_SDIO_STATUS, &ret);
|
||||
if (ret)
|
||||
goto release;
|
||||
if ((status & IF_SDIO_IO_RDY) &&
|
||||
(status & IF_SDIO_DL_RDY))
|
||||
break;
|
||||
if (time_after(jiffies, timeout)) {
|
||||
ret = -ETIMEDOUT;
|
||||
goto release;
|
||||
}
|
||||
mdelay(1);
|
||||
}
|
||||
ret = if_sdio_wait_status(card, FW_DL_READY_STATUS);
|
||||
if (ret)
|
||||
goto release;
|
||||
|
||||
req_size = sdio_readb(card->func, IF_SDIO_RD_BASE, &ret);
|
||||
if (ret)
|
||||
|
@ -830,6 +830,33 @@ static int mac80211_hwsim_conf_tx(
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mac80211_hwsim_get_survey(
|
||||
struct ieee80211_hw *hw, int idx,
|
||||
struct survey_info *survey)
|
||||
{
|
||||
struct ieee80211_conf *conf = &hw->conf;
|
||||
|
||||
printk(KERN_DEBUG "%s:%s (idx=%d)\n",
|
||||
wiphy_name(hw->wiphy), __func__, idx);
|
||||
|
||||
if (idx != 0)
|
||||
return -ENOENT;
|
||||
|
||||
/* Current channel */
|
||||
survey->channel = conf->channel;
|
||||
|
||||
/*
|
||||
* Magically conjured noise level --- this is only ok for simulated hardware.
|
||||
*
|
||||
* A real driver which cannot determine the real channel noise MUST NOT
|
||||
* report any noise, especially not a magically conjured one :-)
|
||||
*/
|
||||
survey->filled = SURVEY_INFO_NOISE_DBM;
|
||||
survey->noise = -92;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NL80211_TESTMODE
|
||||
/*
|
||||
* This section contains example code for using netlink
|
||||
@ -1013,6 +1040,7 @@ static struct ieee80211_ops mac80211_hwsim_ops =
|
||||
.sta_notify = mac80211_hwsim_sta_notify,
|
||||
.set_tim = mac80211_hwsim_set_tim,
|
||||
.conf_tx = mac80211_hwsim_conf_tx,
|
||||
.get_survey = mac80211_hwsim_get_survey,
|
||||
CFG80211_TESTMODE_CMD(mac80211_hwsim_testmode_cmd)
|
||||
.ampdu_action = mac80211_hwsim_ampdu_action,
|
||||
.sw_scan_start = mac80211_hwsim_sw_scan,
|
||||
|
@ -11,3 +11,6 @@ obj-$(CONFIG_PCI_HERMES) += orinoco_pci.o
|
||||
obj-$(CONFIG_TMD_HERMES) += orinoco_tmd.o
|
||||
obj-$(CONFIG_NORTEL_HERMES) += orinoco_nortel.o
|
||||
obj-$(CONFIG_PCMCIA_SPECTRUM) += spectrum_cs.o
|
||||
|
||||
# Orinoco should be endian clean.
|
||||
ccflags-y += -D__CHECK_ENDIAN__
|
||||
|
@ -88,7 +88,9 @@ int orinoco_wiphy_register(struct wiphy *wiphy)
|
||||
|
||||
wiphy->rts_threshold = priv->rts_thresh;
|
||||
if (!priv->has_mwo)
|
||||
wiphy->frag_threshold = priv->frag_thresh;
|
||||
wiphy->frag_threshold = priv->frag_thresh + 1;
|
||||
wiphy->retry_short = priv->short_retry_limit;
|
||||
wiphy->retry_long = priv->long_retry_limit;
|
||||
|
||||
return wiphy_register(wiphy);
|
||||
}
|
||||
@ -196,8 +198,92 @@ static int orinoco_set_channel(struct wiphy *wiphy,
|
||||
return err;
|
||||
}
|
||||
|
||||
static int orinoco_set_wiphy_params(struct wiphy *wiphy, u32 changed)
|
||||
{
|
||||
struct orinoco_private *priv = wiphy_priv(wiphy);
|
||||
int frag_value = -1;
|
||||
int rts_value = -1;
|
||||
int err = 0;
|
||||
|
||||
if (changed & WIPHY_PARAM_RETRY_SHORT) {
|
||||
/* Setting short retry not supported */
|
||||
err = -EINVAL;
|
||||
}
|
||||
|
||||
if (changed & WIPHY_PARAM_RETRY_LONG) {
|
||||
/* Setting long retry not supported */
|
||||
err = -EINVAL;
|
||||
}
|
||||
|
||||
if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
|
||||
/* Set fragmentation */
|
||||
if (priv->has_mwo) {
|
||||
if (wiphy->frag_threshold < 0)
|
||||
frag_value = 0;
|
||||
else {
|
||||
printk(KERN_WARNING "%s: Fixed fragmentation "
|
||||
"is not supported on this firmware. "
|
||||
"Using MWO robust instead.\n",
|
||||
priv->ndev->name);
|
||||
frag_value = 1;
|
||||
}
|
||||
} else {
|
||||
if (wiphy->frag_threshold < 0)
|
||||
frag_value = 2346;
|
||||
else if ((wiphy->frag_threshold < 257) ||
|
||||
(wiphy->frag_threshold > 2347))
|
||||
err = -EINVAL;
|
||||
else
|
||||
/* cfg80211 value is 257-2347 (odd only)
|
||||
* orinoco rid has range 256-2346 (even only) */
|
||||
frag_value = wiphy->frag_threshold & ~0x1;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
|
||||
/* Set RTS.
|
||||
*
|
||||
* Prism documentation suggests default of 2432,
|
||||
* and a range of 0-3000.
|
||||
*
|
||||
* Current implementation uses 2347 as the default and
|
||||
* the upper limit.
|
||||
*/
|
||||
|
||||
if (wiphy->rts_threshold < 0)
|
||||
rts_value = 2347;
|
||||
else if (wiphy->rts_threshold > 2347)
|
||||
err = -EINVAL;
|
||||
else
|
||||
rts_value = wiphy->rts_threshold;
|
||||
}
|
||||
|
||||
if (!err) {
|
||||
unsigned long flags;
|
||||
|
||||
if (orinoco_lock(priv, &flags) != 0)
|
||||
return -EBUSY;
|
||||
|
||||
if (frag_value >= 0) {
|
||||
if (priv->has_mwo)
|
||||
priv->mwo_robust = frag_value;
|
||||
else
|
||||
priv->frag_thresh = frag_value;
|
||||
}
|
||||
if (rts_value >= 0)
|
||||
priv->rts_thresh = rts_value;
|
||||
|
||||
err = orinoco_commit(priv);
|
||||
|
||||
orinoco_unlock(priv, &flags);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
const struct cfg80211_ops orinoco_cfg_ops = {
|
||||
.change_virtual_intf = orinoco_change_vif,
|
||||
.set_channel = orinoco_set_channel,
|
||||
.scan = orinoco_scan,
|
||||
.set_wiphy_params = orinoco_set_wiphy_params,
|
||||
};
|
||||
|
@ -374,6 +374,32 @@ int orinoco_hw_read_card_settings(struct orinoco_private *priv, u8 *dev_addr)
|
||||
err = hermes_read_wordrec(hw, USER_BAP,
|
||||
HERMES_RID_CNFPREAMBLE_SYMBOL,
|
||||
&priv->preamble);
|
||||
if (err) {
|
||||
dev_err(dev, "Failed to read preamble setup\n");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* Retry settings */
|
||||
err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_SHORTRETRYLIMIT,
|
||||
&priv->short_retry_limit);
|
||||
if (err) {
|
||||
dev_err(dev, "Failed to read short retry limit\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_LONGRETRYLIMIT,
|
||||
&priv->long_retry_limit);
|
||||
if (err) {
|
||||
dev_err(dev, "Failed to read long retry limit\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_MAXTRANSMITLIFETIME,
|
||||
&priv->retry_lifetime);
|
||||
if (err) {
|
||||
dev_err(dev, "Failed to read max retry lifetime\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
|
@ -33,18 +33,6 @@ int orinoco_commit(struct orinoco_private *priv);
|
||||
void orinoco_reset(struct work_struct *work);
|
||||
|
||||
/* Information element helpers - find a home for these... */
|
||||
static inline u8 *orinoco_get_ie(u8 *data, size_t len,
|
||||
enum ieee80211_eid eid)
|
||||
{
|
||||
u8 *p = data;
|
||||
while ((p + 2) < (data + len)) {
|
||||
if (p[0] == eid)
|
||||
return p;
|
||||
p += p[1] + 2;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define WPA_OUI_TYPE "\x00\x50\xF2\x01"
|
||||
#define WPA_SELECTOR_LEN 4
|
||||
static inline u8 *orinoco_get_wpa_ie(u8 *data, size_t len)
|
||||
|
@ -131,6 +131,8 @@ struct orinoco_private {
|
||||
u16 ap_density, rts_thresh;
|
||||
u16 pm_on, pm_mcast, pm_period, pm_timeout;
|
||||
u16 preamble;
|
||||
u16 short_retry_limit, long_retry_limit;
|
||||
u16 retry_lifetime;
|
||||
#ifdef WIRELESS_SPY
|
||||
struct iw_spy_data spy_data; /* iwspy support */
|
||||
struct iw_public_data wireless_data;
|
||||
|
@ -127,7 +127,7 @@ void orinoco_add_extscan_result(struct orinoco_private *priv,
|
||||
{
|
||||
struct wiphy *wiphy = priv_to_wiphy(priv);
|
||||
struct ieee80211_channel *channel;
|
||||
u8 *ie;
|
||||
const u8 *ie;
|
||||
u64 timestamp;
|
||||
s32 signal;
|
||||
u16 capability;
|
||||
@ -136,7 +136,7 @@ void orinoco_add_extscan_result(struct orinoco_private *priv,
|
||||
int chan, freq;
|
||||
|
||||
ie_len = len - sizeof(*bss);
|
||||
ie = orinoco_get_ie(bss->data, ie_len, WLAN_EID_DS_PARAMS);
|
||||
ie = cfg80211_find_ie(WLAN_EID_DS_PARAMS, bss->data, ie_len);
|
||||
chan = ie ? ie[2] : 0;
|
||||
freq = ieee80211_dsss_chan_to_freq(chan);
|
||||
channel = ieee80211_get_channel(wiphy, freq);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user