summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/ath/ath9k
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2011-05-16 14:55:42 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-05-16 19:32:19 -0400
commite00cf3b9eb7839b952e434a75bff6b99e47337ac (patch)
treeef583ab8ac09bf703026650d4bc7777e6a3864d3 /drivers/net/wireless/ath/ath9k
parent1a8218e96271790a07dd7065a2ef173e0f67e328 (diff)
parent3b8ab88acaceb505aa06ef3bbf3a73b92470ae78 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Conflicts: drivers/net/wireless/iwlwifi/iwl-agn-tx.c net/mac80211/sta_info.h
Diffstat (limited to 'drivers/net/wireless/ath/ath9k')
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_mac.c10
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_phy.c44
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.c78
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.c11
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c46
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.h22
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h3
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c15
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.c21
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/hw-ops.h16
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c16
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h15
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.c9
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c47
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c215
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c11
17 files changed, 428 insertions, 152 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
index c338efbccf40..7a332f16b79a 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
@@ -415,15 +415,6 @@ static void ar9002_hw_clr11n_aggr(struct ath_hw *ah, void *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);
-}
-
void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
u32 size, u32 flags)
{
@@ -456,6 +447,5 @@ void ar9002_hw_attach_mac_ops(struct ath_hw *ah)
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->set_clrdmask = ar9002_hw_set_clrdmask;
}
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
index 7d68d61e406b..a57e963cf0dc 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
@@ -517,23 +517,7 @@ static void ar9002_hw_set_nf_limits(struct ath_hw *ah)
}
}
-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;
-
- ar9002_hw_set_nf_limits(ah);
-}
-
-void ath9k_hw_antdiv_comb_conf_get(struct ath_hw *ah,
+static void ar9002_hw_antdiv_comb_conf_get(struct ath_hw *ah,
struct ath_hw_antcomb_conf *antconf)
{
u32 regval;
@@ -545,10 +529,11 @@ void ath9k_hw_antdiv_comb_conf_get(struct ath_hw *ah,
AR_PHY_9285_ANT_DIV_ALT_LNACONF_S;
antconf->fast_div_bias = (regval & AR_PHY_9285_FAST_DIV_BIAS) >>
AR_PHY_9285_FAST_DIV_BIAS_S;
+ antconf->lna1_lna2_delta = -3;
+ antconf->div_group = 0;
}
-EXPORT_SYMBOL(ath9k_hw_antdiv_comb_conf_get);
-void ath9k_hw_antdiv_comb_conf_set(struct ath_hw *ah,
+static void ar9002_hw_antdiv_comb_conf_set(struct ath_hw *ah,
struct ath_hw_antcomb_conf *antconf)
{
u32 regval;
@@ -566,4 +551,23 @@ void ath9k_hw_antdiv_comb_conf_set(struct ath_hw *ah,
REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regval);
}
-EXPORT_SYMBOL(ath9k_hw_antdiv_comb_conf_set);
+
+void ar9002_hw_attach_phy_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->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;
+
+ ops->antdiv_comb_conf_get = ar9002_hw_antdiv_comb_conf_get;
+ ops->antdiv_comb_conf_set = ar9002_hw_antdiv_comb_conf_set;
+
+ ar9002_hw_set_nf_limits(ah);
+}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index fb892e5d141a..1e220354e4be 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -652,7 +652,7 @@ static const struct ar9300_eeprom ar9300_x113 = {
.regDmn = { LE16(0), LE16(0x1f) },
.txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
.opCapFlags = {
- .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
+ .opFlags = AR5416_OPFLAGS_11A,
.eepMisc = 0,
},
.rfSilent = 0,
@@ -922,7 +922,7 @@ static const struct ar9300_eeprom ar9300_x113 = {
.db_stage2 = {3, 3, 3}, /* 3 chain */
.db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */
.db_stage4 = {3, 3, 3}, /* don't exist for 2G */
- .xpaBiasLvl = 0,
+ .xpaBiasLvl = 0xf,
.txFrameToDataStart = 0x0e,
.txFrameToPaOn = 0x0e,
.txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
@@ -3442,17 +3442,15 @@ static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
{
int bias = ar9003_hw_xpa_bias_level_get(ah, is2ghz);
- if (AR_SREV_9485(ah))
+ if (AR_SREV_9485(ah) || AR_SREV_9340(ah))
REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias);
else {
REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
- if (!AR_SREV_9340(ah)) {
- REG_RMW_FIELD(ah, AR_CH0_THERM,
- AR_CH0_THERM_XPABIASLVL_MSB,
- bias >> 2);
- REG_RMW_FIELD(ah, AR_CH0_THERM,
- AR_CH0_THERM_XPASHORT2GND, 1);
- }
+ REG_RMW_FIELD(ah, AR_CH0_THERM,
+ AR_CH0_THERM_XPABIASLVL_MSB,
+ bias >> 2);
+ REG_RMW_FIELD(ah, AR_CH0_THERM,
+ AR_CH0_THERM_XPASHORT2GND, 1);
}
}
@@ -3500,6 +3498,8 @@ static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah,
static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
{
int chain;
+ u32 regval;
+ u32 ant_div_ctl1;
static const u32 switch_chain_reg[AR9300_MAX_CHAINS] = {
AR_PHY_SWITCH_CHAIN_0,
AR_PHY_SWITCH_CHAIN_1,
@@ -3525,13 +3525,49 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
if (AR_SREV_9485(ah)) {
value = ath9k_hw_ar9300_get_eeprom(ah, EEP_ANT_DIV_CTL1);
- REG_RMW_FIELD(ah, AR_PHY_MC_GAIN_CTRL, AR_ANT_DIV_CTRL_ALL,
- value);
- REG_RMW_FIELD(ah, AR_PHY_MC_GAIN_CTRL, AR_ANT_DIV_ENABLE,
- value >> 6);
- REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT, AR_FAST_DIV_ENABLE,
- value >> 7);
+ /*
+ * main_lnaconf, alt_lnaconf, main_tb, alt_tb
+ * are the fields present
+ */
+ regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
+ regval &= (~AR_ANT_DIV_CTRL_ALL);
+ regval |= (value & 0x3f) << AR_ANT_DIV_CTRL_ALL_S;
+ /* enable_lnadiv */
+ regval &= (~AR_PHY_9485_ANT_DIV_LNADIV);
+ regval |= ((value >> 6) & 0x1) <<
+ AR_PHY_9485_ANT_DIV_LNADIV_S;
+ REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
+
+ /*enable fast_div */
+ regval = REG_READ(ah, AR_PHY_CCK_DETECT);
+ regval &= (~AR_FAST_DIV_ENABLE);
+ regval |= ((value >> 7) & 0x1) <<
+ AR_FAST_DIV_ENABLE_S;
+ REG_WRITE(ah, AR_PHY_CCK_DETECT, regval);
+ ant_div_ctl1 =
+ ah->eep_ops->get_eeprom(ah, EEP_ANT_DIV_CTL1);
+ /* check whether antenna diversity is enabled */
+ if ((ant_div_ctl1 >> 0x6) == 0x3) {
+ regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
+ /*
+ * clear bits 25-30 main_lnaconf, alt_lnaconf,
+ * main_tb, alt_tb
+ */
+ regval &= (~(AR_PHY_9485_ANT_DIV_MAIN_LNACONF |
+ AR_PHY_9485_ANT_DIV_ALT_LNACONF |
+ AR_PHY_9485_ANT_DIV_ALT_GAINTB |
+ AR_PHY_9485_ANT_DIV_MAIN_GAINTB));
+ /* by default use LNA1 for the main antenna */
+ regval |= (AR_PHY_9485_ANT_DIV_LNA1 <<
+ AR_PHY_9485_ANT_DIV_MAIN_LNACONF_S);
+ regval |= (AR_PHY_9485_ANT_DIV_LNA2 <<
+ AR_PHY_9485_ANT_DIV_ALT_LNACONF_S);
+ REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
+ }
+
+
}
+
}
static void ar9003_hw_drive_strength_apply(struct ath_hw *ah)
@@ -4005,6 +4041,16 @@ static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray)
POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
);
+ /* Write the power for duplicated frames - HT40 */
+
+ /* dup40_cck (LSB), dup40_ofdm, ext20_cck, ext20_ofdm (MSB) */
+ REG_WRITE(ah, 0xa3e0,
+ POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
+ POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
+ POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) |
+ POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
+ );
+
/* Write the HT20 power per rate set */
/* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index c1264d60c499..be6adec33ddb 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -484,16 +484,6 @@ static void ar9003_hw_clr11n_aggr(struct ath_hw *ah, void *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);
-
-}
-
void ar9003_hw_set_paprd_txdesc(struct ath_hw *ah, void *ds, u8 chains)
{
struct ar9003_txc *ads = ds;
@@ -518,7 +508,6 @@ void ar9003_hw_attach_mac_ops(struct ath_hw *hw)
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->set_clrdmask = ar9003_hw_set_clrdmask;
}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index c83be2dd5718..25f3c2fdf2bc 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -1184,9 +1184,52 @@ static void ar9003_hw_set_radar_conf(struct ath_hw *ah)
conf->radar_inband = 8;
}
+static void ar9003_hw_antdiv_comb_conf_get(struct ath_hw *ah,
+ struct ath_hw_antcomb_conf *antconf)
+{
+ u32 regval;
+
+ regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
+ antconf->main_lna_conf = (regval & AR_PHY_9485_ANT_DIV_MAIN_LNACONF) >>
+ AR_PHY_9485_ANT_DIV_MAIN_LNACONF_S;
+ antconf->alt_lna_conf = (regval & AR_PHY_9485_ANT_DIV_ALT_LNACONF) >>
+ AR_PHY_9485_ANT_DIV_ALT_LNACONF_S;
+ antconf->fast_div_bias = (regval & AR_PHY_9485_ANT_FAST_DIV_BIAS) >>
+ AR_PHY_9485_ANT_FAST_DIV_BIAS_S;
+ antconf->lna1_lna2_delta = -9;
+ antconf->div_group = 2;
+}
+
+static void ar9003_hw_antdiv_comb_conf_set(struct ath_hw *ah,
+ struct ath_hw_antcomb_conf *antconf)
+{
+ u32 regval;
+
+ regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
+ regval &= ~(AR_PHY_9485_ANT_DIV_MAIN_LNACONF |
+ AR_PHY_9485_ANT_DIV_ALT_LNACONF |
+ AR_PHY_9485_ANT_FAST_DIV_BIAS |
+ AR_PHY_9485_ANT_DIV_MAIN_GAINTB |
+ AR_PHY_9485_ANT_DIV_ALT_GAINTB);
+ regval |= ((antconf->main_lna_conf <<
+ AR_PHY_9485_ANT_DIV_MAIN_LNACONF_S)
+ & AR_PHY_9485_ANT_DIV_MAIN_LNACONF);
+ regval |= ((antconf->alt_lna_conf << AR_PHY_9485_ANT_DIV_ALT_LNACONF_S)
+ & AR_PHY_9485_ANT_DIV_ALT_LNACONF);
+ regval |= ((antconf->fast_div_bias << AR_PHY_9485_ANT_FAST_DIV_BIAS_S)
+ & AR_PHY_9485_ANT_FAST_DIV_BIAS);
+ regval |= ((antconf->main_gaintb << AR_PHY_9485_ANT_DIV_MAIN_GAINTB_S)
+ & AR_PHY_9485_ANT_DIV_MAIN_GAINTB);
+ regval |= ((antconf->alt_gaintb << AR_PHY_9485_ANT_DIV_ALT_GAINTB_S)
+ & AR_PHY_9485_ANT_DIV_ALT_GAINTB);
+
+ REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
+}
+
void ar9003_hw_attach_phy_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);
static const u32 ar9300_cca_regs[6] = {
AR_PHY_CCA_0,
AR_PHY_CCA_1,
@@ -1213,6 +1256,9 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
priv_ops->ani_cache_ini_regs = ar9003_hw_ani_cache_ini_regs;
priv_ops->set_radar_params = ar9003_hw_set_radar_params;
+ ops->antdiv_comb_conf_get = ar9003_hw_antdiv_comb_conf_get;
+ ops->antdiv_comb_conf_set = ar9003_hw_antdiv_comb_conf_set;
+
ar9003_hw_set_nf_limits(ah);
ar9003_hw_set_radar_conf(ah);
memcpy(ah->nf_regs, ar9300_cca_regs, sizeof(ah->nf_regs));
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
index 2a0d5cbb7e76..c7505b48e5c0 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
@@ -261,12 +261,34 @@
#define AR_PHY_EXT_CCA0 (AR_AGC_BASE + 0x20)
#define AR_PHY_RESTART (AR_AGC_BASE + 0x24)
+/*
+ * Antenna Diversity settings
+ */
#define AR_PHY_MC_GAIN_CTRL (AR_AGC_BASE + 0x28)
#define AR_ANT_DIV_CTRL_ALL 0x7e000000
#define AR_ANT_DIV_CTRL_ALL_S 25
#define AR_ANT_DIV_ENABLE 0x1000000
#define AR_ANT_DIV_ENABLE_S 24
+
+#define AR_PHY_9485_ANT_FAST_DIV_BIAS 0x00007e00
+#define AR_PHY_9485_ANT_FAST_DIV_BIAS_S 9
+#define AR_PHY_9485_ANT_DIV_LNADIV 0x01000000
+#define AR_PHY_9485_ANT_DIV_LNADIV_S 24
+#define AR_PHY_9485_ANT_DIV_ALT_LNACONF 0x06000000
+#define AR_PHY_9485_ANT_DIV_ALT_LNACONF_S 25
+#define AR_PHY_9485_ANT_DIV_MAIN_LNACONF 0x18000000
+#define AR_PHY_9485_ANT_DIV_MAIN_LNACONF_S 27
+#define AR_PHY_9485_ANT_DIV_ALT_GAINTB 0x20000000
+#define AR_PHY_9485_ANT_DIV_ALT_GAINTB_S 29
+#define AR_PHY_9485_ANT_DIV_MAIN_GAINTB 0x40000000
+#define AR_PHY_9485_ANT_DIV_MAIN_GAINTB_S 30
+
+#define AR_PHY_9485_ANT_DIV_LNA1_MINUS_LNA2 0x0
+#define AR_PHY_9485_ANT_DIV_LNA2 0x1
+#define AR_PHY_9485_ANT_DIV_LNA1 0x2
+#define AR_PHY_9485_ANT_DIV_LNA1_PLUS_LNA2 0x3
+
#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)
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 0312aa091807..03b37d7be1c3 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -62,7 +62,6 @@ struct ath_node;
#define ATH_TXQ_SETUP(sc, i) ((sc)->tx.txqsetup & (1<<i))
struct ath_config {
- u32 ath_aggr_prot;
u16 txpowlimit;
u8 cabqReadytime;
};
@@ -484,7 +483,6 @@ static inline void ath_deinit_leds(struct ath_softc *sc)
#define ATH_ANT_DIV_COMB_ALT_ANT_RATIO 30
#define ATH_ANT_DIV_COMB_ALT_ANT_RATIO2 20
-#define ATH_ANT_DIV_COMB_LNA1_LNA2_DELTA -3
#define ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA -1
#define ATH_ANT_DIV_COMB_LNA1_DELTA_HI -4
#define ATH_ANT_DIV_COMB_LNA1_DELTA_MID -2
@@ -565,6 +563,7 @@ struct ath_ant_comb {
#define PS_WAIT_FOR_PSPOLL_DATA BIT(2)
#define PS_WAIT_FOR_TX_ACK BIT(3)
#define PS_BEACON_SYNC BIT(4)
+#define PS_TSFOOR_SYNC BIT(5)
struct ath_rate_table;
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 22cd241a098b..637dbc5f7b67 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -620,7 +620,13 @@ static void ath_beacon_config_sta(struct ath_softc *sc,
ath9k_hw_disable_interrupts(ah);
ath9k_hw_set_sta_beacon_timers(ah, &bs);
ah->imask |= ATH9K_INT_BMISS;
- ath9k_hw_set_interrupts(ah, ah->imask);
+
+ /*
+ * If the beacon config is called beacause of TSFOOR,
+ * Interrupts will be enabled back at the end of ath9k_tasklet
+ */
+ if (!(sc->ps_flags & PS_TSFOOR_SYNC))
+ ath9k_hw_set_interrupts(ah, ah->imask);
}
static void ath_beacon_config_adhoc(struct ath_softc *sc,
@@ -661,7 +667,12 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
ath9k_hw_disable_interrupts(ah);
ath9k_beacon_init(sc, nexttbtt, intval);
sc->beacon.bmisscnt = 0;
- ath9k_hw_set_interrupts(ah, ah->imask);
+ /*
+ * If the beacon config is called beacause of TSFOOR,
+ * Interrupts will be enabled back at the end of ath9k_tasklet
+ */
+ if (!(sc->ps_flags & PS_TSFOOR_SYNC))
+ ath9k_hw_set_interrupts(ah, ah->imask);
}
static bool ath9k_allow_beacon_config(struct ath_softc *sc,
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index 8649581fa4dd..558b228a717f 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -69,15 +69,21 @@ static void ath9k_hw_update_nfcal_hist_buffer(struct ath_hw *ah,
int16_t *nfarray)
{
struct ath_common *common = ath9k_hw_common(ah);
+ struct ieee80211_conf *conf = &common->hw->conf;
struct ath_nf_limits *limit;
struct ath9k_nfcal_hist *h;
bool high_nf_mid = false;
+ u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
int i;
h = cal->nfCalHist;
limit = ath9k_hw_get_nf_limits(ah, ah->curchan);
for (i = 0; i < NUM_NF_READINGS; i++) {
+ if (!(chainmask & (1 << i)) ||
+ ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf)))
+ continue;
+
h[i].nfCalBuffer[h[i].currIndex] = nfarray[i];
if (++h[i].currIndex >= ATH9K_NF_CAL_HIST_MAX)
@@ -225,6 +231,7 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
int32_t val;
u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
struct ath_common *common = ath9k_hw_common(ah);
+ struct ieee80211_conf *conf = &common->hw->conf;
s16 default_nf = ath9k_hw_get_default_nf(ah, chan);
if (ah->caldata)
@@ -234,6 +241,9 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
if (chainmask & (1 << i)) {
s16 nfval;
+ if ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf))
+ continue;
+
if (h)
nfval = h[i].privNF;
else
@@ -293,6 +303,9 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
ENABLE_REGWRITE_BUFFER(ah);
for (i = 0; i < NUM_NF_READINGS; i++) {
if (chainmask & (1 << i)) {
+ if ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf))
+ continue;
+
val = REG_READ(ah, ah->nf_regs[i]);
val &= 0xFFFFFE00;
val |= (((u32) (-50) << 1) & 0x1ff);
@@ -396,14 +409,6 @@ void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,
}
}
-s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan)
-{
- if (!ah->curchan || !ah->curchan->noisefloor)
- return ath9k_hw_get_default_nf(ah, chan);
-
- return ah->curchan->noisefloor;
-}
-EXPORT_SYMBOL(ath9k_hw_getchan_noise);
void ath9k_hw_bstuck_nfcal(struct ath_hw *ah)
{
diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h
index b8973eb8d858..4420780fa3b8 100644
--- a/drivers/net/wireless/ath/ath9k/calib.h
+++ b/drivers/net/wireless/ath/ath9k/calib.h
@@ -106,7 +106,6 @@ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan);
void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,
struct ath9k_channel *chan);
void ath9k_hw_bstuck_nfcal(struct ath_hw *ah);
-s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan);
void ath9k_hw_reset_calibration(struct ath_hw *ah,
struct ath9k_cal_list *currCal);
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h
index 9dd90a85ad63..8b8f0445aef8 100644
--- a/drivers/net/wireless/ath/ath9k/hw-ops.h
+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
@@ -116,15 +116,21 @@ 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)
+static inline void ath9k_hw_set_clrdmask(struct ath_hw *ah, void *ds, bool val)
{
- ath9k_hw_ops(ah)->set11n_burstduration(ah, ds, burstDuration);
+ ath9k_hw_ops(ah)->set_clrdmask(ah, ds, val);
}
-static inline void ath9k_hw_set_clrdmask(struct ath_hw *ah, void *ds, bool val)
+static inline void ath9k_hw_antdiv_comb_conf_get(struct ath_hw *ah,
+ struct ath_hw_antcomb_conf *antconf)
{
- ath9k_hw_ops(ah)->set_clrdmask(ah, ds, val);
+ ath9k_hw_ops(ah)->antdiv_comb_conf_get(ah, antconf);
+}
+
+static inline void ath9k_hw_antdiv_comb_conf_set(struct ath_hw *ah,
+ struct ath_hw_antcomb_conf *antconf)
+{
+ ath9k_hw_ops(ah)->antdiv_comb_conf_set(ah, antconf);
}
/* Private hardware call ops */
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 58f3d4210338..b75b5dca4e29 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2022,6 +2022,22 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
}
+ if (AR_SREV_9485(ah)) {
+ ant_div_ctl1 = ah->eep_ops->get_eeprom(ah, EEP_ANT_DIV_CTL1);
+ /*
+ * enable the diversity-combining algorithm only when
+ * both enable_lna_div and enable_fast_div are set
+ * Table for Diversity
+ * ant_div_alt_lnaconf bit 0-1
+ * ant_div_main_lnaconf bit 2-3
+ * ant_div_alt_gaintb bit 4
+ * ant_div_main_gaintb bit 5
+ * enable_ant_div_lnadiv bit 6
+ * enable_ant_fast_div bit 7
+ */
+ if ((ant_div_ctl1 >> 0x6) == 0x3)
+ pCap->hw_caps |= ATH9K_HW_CAP_ANT_DIV_COMB;
+ }
if (AR_SREV_9485_10(ah)) {
pCap->pcie_lcr_extsync_en = true;
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 34ed1bd0e855..7af2773d2bfc 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -479,6 +479,10 @@ struct ath_hw_antcomb_conf {
u8 main_lna_conf;
u8 alt_lna_conf;
u8 fast_div_bias;
+ u8 main_gaintb;
+ u8 alt_gaintb;
+ int lna1_lna2_delta;
+ u8 div_group;
};
/**
@@ -628,9 +632,12 @@ struct ath_hw_ops {
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 (*set_clrdmask)(struct ath_hw *ah, void *ds, bool val);
+ void (*antdiv_comb_conf_get)(struct ath_hw *ah,
+ struct ath_hw_antcomb_conf *antconf);
+ void (*antdiv_comb_conf_set)(struct ath_hw *ah,
+ struct ath_hw_antcomb_conf *antconf);
+
};
struct ath_nf_limits {
@@ -906,10 +913,6 @@ void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio,
void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val);
u32 ath9k_hw_getdefantenna(struct ath_hw *ah);
void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna);
-void ath9k_hw_antdiv_comb_conf_get(struct ath_hw *ah,
- struct ath_hw_antcomb_conf *antconf);
-void ath9k_hw_antdiv_comb_conf_set(struct ath_hw *ah,
- struct ath_hw_antcomb_conf *antconf);
/* General Operation */
bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout);
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index 9cf7a7d0e118..bd6d2b9d736f 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -430,8 +430,13 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH));
REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ);
- REG_WRITE(ah, AR_DMISC(q),
- AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
+
+ if (AR_SREV_9340(ah))
+ REG_WRITE(ah, AR_DMISC(q),
+ AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x1);
+ else
+ REG_WRITE(ah, AR_DMISC(q),
+ AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
if (qi->tqi_cbrPeriod) {
REG_WRITE(ah, AR_QCBRCFG(q),
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index c3dbf2661a3f..45303bdbc465 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -689,6 +689,17 @@ void ath9k_tasklet(unsigned long data)
!ath9k_hw_check_alive(ah))
ieee80211_queue_work(sc->hw, &sc->hw_check_work);
+ if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) {
+ /*
+ * TSF sync does not look correct; remain awake to sync with
+ * the next Beacon.
+ */
+ ath_dbg(common, ATH_DBG_PS,
+ "TSFOOR - Sync with next Beacon\n");
+ sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC |
+ PS_TSFOOR_SYNC;
+ }
+
if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
rxmask = (ATH9K_INT_RXHP | ATH9K_INT_RXLP | ATH9K_INT_RXEOL |
ATH9K_INT_RXORN);
@@ -711,16 +722,6 @@ void ath9k_tasklet(unsigned long data)
ath_tx_tasklet(sc);
}
- if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) {
- /*
- * TSF sync does not look correct; remain awake to sync with
- * the next Beacon.
- */
- ath_dbg(common, ATH_DBG_PS,
- "TSFOOR - Sync with next Beacon\n");
- sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC;
- }
-
if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
if (status & ATH9K_INT_GENTIMER)
ath_gen_timer_isr(sc->sc_ah);
@@ -1384,7 +1385,9 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw,
ath9k_hw_set_tsfadjust(ah, 0);
sc->sc_flags &= ~SC_OP_TSF_RESET;
- if (iter_data.nwds + iter_data.nmeshes)
+ if (iter_data.nmeshes)
+ ah->opmode = NL80211_IFTYPE_MESH_POINT;
+ else if (iter_data.nwds)
ah->opmode = NL80211_IFTYPE_AP;
else if (iter_data.nadhocs)
ah->opmode = NL80211_IFTYPE_ADHOC;
@@ -1408,6 +1411,7 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw,
/* Set up ANI */
if ((iter_data.naps + iter_data.nadhocs) > 0) {
+ sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
sc->sc_flags |= SC_OP_ANI_RUN;
ath_start_ani(common);
} else {
@@ -1778,6 +1782,11 @@ static int ath9k_sta_add(struct ieee80211_hw *hw,
struct ieee80211_key_conf ps_key = { };
ath_node_attach(sc, sta);
+
+ if (vif->type != NL80211_IFTYPE_AP &&
+ vif->type != NL80211_IFTYPE_AP_VLAN)
+ return 0;
+
an->ps_key = ath_key_config(common, vif, sta, &ps_key);
return 0;
@@ -2039,9 +2048,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
if (changed & BSS_CHANGED_BSSID) {
ath9k_config_bss(sc, vif);
- /* Set aggregation protection mode parameters */
- sc->config.ath_aggr_prot = 0;
-
ath_dbg(common, ATH_DBG_CONFIG, "BSSID: %pM aid: 0x%x\n",
common->curbssid, common->curaid);
}
@@ -2261,6 +2267,7 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop)
struct ath_softc *sc = hw->priv;
int timeout = 200; /* ms */
int i, j;
+ bool drain_txq;
mutex_lock(&sc->mutex);
cancel_delayed_work_sync(&sc->tx_complete_work);
@@ -2269,7 +2276,7 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop)
timeout = 1;
for (j = 0; j < timeout; j++) {
- int npend = 0;
+ bool npend = false;
if (j)
usleep_range(1000, 2000);
@@ -2278,7 +2285,10 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop)
if (!ATH_TXQ_SETUP(sc, i))
continue;
- npend += ath9k_has_pending_frames(sc, &sc->tx.txq[i]);
+ npend = ath9k_has_pending_frames(sc, &sc->tx.txq[i]);
+
+ if (npend)
+ break;
}
if (!npend)
@@ -2286,7 +2296,10 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop)
}
ath9k_ps_wakeup(sc);
- if (!ath_drain_all_txq(sc, false))
+ spin_lock_bh(&sc->sc_pcu_lock);
+ drain_txq = ath_drain_all_txq(sc, false);
+ spin_unlock_bh(&sc->sc_pcu_lock);
+ if (!drain_txq)
ath_reset(sc, false);
ath9k_ps_restore(sc);
ieee80211_wake_queues(hw);
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index c5b7cbe59bfa..4f52e0429f99 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -28,6 +28,33 @@ static inline bool ath_is_alt_ant_ratio_better(int alt_ratio, int maxdelta,
(alt_rssi_avg > main_rssi_avg + mindelta)) && (pkt_count > 50);
}
+static inline bool ath_ant_div_comb_alt_check(u8 div_group, int alt_ratio,
+ int curr_main_set, int curr_alt_set,
+ int alt_rssi_avg, int main_rssi_avg)
+{
+ bool result = false;
+ switch (div_group) {
+ case 0:
+ if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)
+ result = true;
+ break;
+ case 1:
+ if ((((curr_main_set == ATH_ANT_DIV_COMB_LNA2) &&
+ (curr_alt_set == ATH_ANT_DIV_COMB_LNA1) &&
+ (alt_rssi_avg >= (main_rssi_avg - 5))) ||
+ ((curr_main_set == ATH_ANT_DIV_COMB_LNA1) &&
+ (curr_alt_set == ATH_ANT_DIV_COMB_LNA2) &&
+ (alt_rssi_avg >= (main_rssi_avg - 2)))) &&
+ (alt_rssi_avg >= 4))
+ result = true;
+ else
+ result = false;
+ break;
+ }
+
+ return result;
+}
+
static inline bool ath9k_check_auto_sleep(struct ath_softc *sc)
{
return sc->ps_enabled &&
@@ -572,6 +599,7 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
ath_dbg(common, ATH_DBG_PS,
"Reconfigure Beacon timers based on timestamp from the AP\n");
ath_set_beacon(sc);
+ sc->ps_flags &= ~PS_TSFOOR_SYNC;
}
if (ath_beacon_dtim_pending_cab(skb)) {
@@ -916,7 +944,8 @@ static void ath9k_process_rssi(struct ath_common *common,
int last_rssi;
__le16 fc;
- if (ah->opmode != NL80211_IFTYPE_STATION)
+ if ((ah->opmode != NL80211_IFTYPE_STATION) &&
+ (ah->opmode != NL80211_IFTYPE_ADHOC))
return;
fc = hdr->frame_control;
@@ -1288,49 +1317,138 @@ static void ath_select_ant_div_from_quick_scan(struct ath_ant_comb *antcomb,
}
}
-static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf)
+static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf,
+ struct ath_ant_comb *antcomb, int alt_ratio)
{
- /* Adjust the fast_div_bias based on main and alt lna conf */
- switch ((ant_conf->main_lna_conf << 4) | ant_conf->alt_lna_conf) {
- case (0x01): /* A-B LNA2 */
- ant_conf->fast_div_bias = 0x3b;
- break;
- case (0x02): /* A-B LNA1 */
- ant_conf->fast_div_bias = 0x3d;
- break;
- case (0x03): /* A-B A+B */
- ant_conf->fast_div_bias = 0x1;
- break;
- case (0x10): /* LNA2 A-B */
- ant_conf->fast_div_bias = 0x7;
- break;
- case (0x12): /* LNA2 LNA1 */
- ant_conf->fast_div_bias = 0x2;
- break;
- case (0x13): /* LNA2 A+B */
- ant_conf->fast_div_bias = 0x7;
- break;
- case (0x20): /* LNA1 A-B */
- ant_conf->fast_div_bias = 0x6;
- break;
- case (0x21): /* LNA1 LNA2 */
- ant_conf->fast_div_bias = 0x0;
- break;
- case (0x23): /* LNA1 A+B */
- ant_conf->fast_div_bias = 0x6;
- break;
- case (0x30): /* A+B A-B */
- ant_conf->fast_div_bias = 0x1;
- break;
- case (0x31): /* A+B LNA2 */
- ant_conf->fast_div_bias = 0x3b;
- break;
- case (0x32): /* A+B LNA1 */
- ant_conf->fast_div_bias = 0x3d;
- break;
- default:
- break;
+ if (ant_conf->div_group == 0) {
+ /* Adjust the fast_div_bias based on main and alt lna conf */
+ switch ((ant_conf->main_lna_conf << 4) |
+ ant_conf->alt_lna_conf) {
+ case (0x01): /* A-B LNA2 */
+ ant_conf->fast_div_bias = 0x3b;
+ break;
+ case (0x02): /* A-B LNA1 */
+ ant_conf->fast_div_bias = 0x3d;
+ break;
+ case (0x03): /* A-B A+B */
+ ant_conf->fast_div_bias = 0x1;
+ break;
+ case (0x10): /* LNA2 A-B */
+ ant_conf->fast_div_bias = 0x7;
+ break;
+ case (0x12): /* LNA2 LNA1 */
+ ant_conf->fast_div_bias = 0x2;
+ break;
+ case (0x13): /* LNA2 A+B */
+ ant_conf->fast_div_bias = 0x7;
+ break;
+ case (0x20): /* LNA1 A-B */
+ ant_conf->fast_div_bias = 0x6;
+ break;
+ case (0x21): /* LNA1 LNA2 */
+ ant_conf->fast_div_bias = 0x0;
+ break;
+ case (0x23): /* LNA1 A+B */
+ ant_conf->fast_div_bias = 0x6;
+ break;
+ case (0x30): /* A+B A-B */
+ ant_conf->fast_div_bias = 0x1;
+ break;
+ case (0x31): /* A+B LNA2 */
+ ant_conf->fast_div_bias = 0x3b;
+ break;
+ case (0x32): /* A+B LNA1 */
+ ant_conf->fast_div_bias = 0x3d;
+ break;
+ default:
+ break;
+ }
+ } else if (ant_conf->div_group == 2) {
+ /* Adjust the fast_div_bias based on main and alt_lna_conf */
+ switch ((ant_conf->main_lna_conf << 4) |
+ ant_conf->alt_lna_conf) {
+ case (0x01): /* A-B LNA2 */
+ ant_conf->fast_div_bias = 0x1;
+ ant_conf->main_gaintb = 0;
+ ant_conf->alt_gaintb = 0;
+ break;
+ case (0x02): /* A-B LNA1 */
+ ant_conf->fast_div_bias = 0x1;
+ ant_conf->main_gaintb = 0;
+ ant_conf->alt_gaintb = 0;
+ break;
+ case (0x03): /* A-B A+B */
+ ant_conf->fast_div_bias = 0x1;
+ ant_conf->main_gaintb = 0;
+ ant_conf->alt_gaintb = 0;
+ break;
+ case (0x10): /* LNA2 A-B */
+ if (!(antcomb->scan) &&
+ (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
+ ant_conf->fast_div_bias = 0x1;
+ else
+ ant_conf->fast_div_bias = 0x2;
+ ant_conf->main_gaintb = 0;
+ ant_conf->alt_gaintb = 0;
+ break;
+ case (0x12): /* LNA2 LNA1 */
+ ant_conf->fast_div_bias = 0x1;
+ ant_conf->main_gaintb = 0;
+ ant_conf->alt_gaintb = 0;
+ break;
+ case (0x13): /* LNA2 A+B */
+ if (!(antcomb->scan) &&
+ (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
+ ant_conf->fast_div_bias = 0x1;
+ else
+ ant_conf->fast_div_bias = 0x2;
+ ant_conf->main_gaintb = 0;
+ ant_conf->alt_gaintb = 0;
+ break;
+ case (0x20): /* LNA1 A-B */
+ if (!(antcomb->scan) &&
+ (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
+ ant_conf->fast_div_bias = 0x1;
+ else
+ ant_conf->fast_div_bias = 0x2;
+ ant_conf->main_gaintb = 0;
+ ant_conf->alt_gaintb = 0;
+ break;
+ case (0x21): /* LNA1 LNA2 */
+ ant_conf->fast_div_bias = 0x1;
+ ant_conf->main_gaintb = 0;
+ ant_conf->alt_gaintb = 0;
+ break;
+ case (0x23): /* LNA1 A+B */
+ if (!(antcomb->scan) &&
+ (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
+ ant_conf->fast_div_bias = 0x1;
+ else
+ ant_conf->fast_div_bias = 0x2;
+ ant_conf->main_gaintb = 0;
+ ant_conf->alt_gaintb = 0;
+ break;
+ case (0x30): /* A+B A-B */
+ ant_conf->fast_div_bias = 0x1;
+ ant_conf->main_gaintb = 0;
+ ant_conf->alt_gaintb = 0;
+ break;
+ case (0x31): /* A+B LNA2 */
+ ant_conf->fast_div_bias = 0x1;
+ ant_conf->main_gaintb = 0;
+ ant_conf->alt_gaintb = 0;
+ break;
+ case (0x32): /* A+B LNA1 */
+ ant_conf->fast_div_bias = 0x1;
+ ant_conf->main_gaintb = 0;
+ ant_conf->alt_gaintb = 0;
+ break;
+ default:
+ break;
+ }
+
}
+
}
/* Antenna diversity and combining */
@@ -1350,8 +1468,8 @@ static void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs)
main_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_MAIN_SHIFT) &
ATH_ANT_RX_MASK;
- /* Record packet only when alt_rssi is positive */
- if (alt_rssi > 0) {
+ /* Record packet only when both main_rssi and alt_rssi is positive */
+ if (main_rssi > 0 && alt_rssi > 0) {
antcomb->total_pkt_count++;
antcomb->main_total_rssi += main_rssi;
antcomb->alt_total_rssi += alt_rssi;
@@ -1411,7 +1529,9 @@ static void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs)
}
if (!antcomb->scan) {
- if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO) {
+ if (ath_ant_div_comb_alt_check(div_ant_conf.div_group,
+ alt_ratio, curr_main_set, curr_alt_set,
+ alt_rssi_avg, main_rssi_avg)) {
if (curr_alt_set == ATH_ANT_DIV_COMB_LNA2) {
/* Switch main and alt LNA */
div_ant_conf.main_lna_conf =
@@ -1440,7 +1560,7 @@ static void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs)
}
if ((alt_rssi_avg < (main_rssi_avg +
- ATH_ANT_DIV_COMB_LNA1_LNA2_DELTA)))
+ div_ant_conf.lna1_lna2_delta)))
goto div_comb_done;
}
@@ -1554,8 +1674,7 @@ static void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs)
antcomb->quick_scan_cnt++;
div_comb_done:
- ath_ant_div_conf_fast_divbias(&div_ant_conf);
-
+ ath_ant_div_conf_fast_divbias(&div_ant_conf, antcomb, alt_ratio);
ath9k_hw_antdiv_comb_conf_set(sc->sc_ah, &div_ant_conf);
antcomb->scan_start_time = jiffies;
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 7b91b2aa6240..97dd1fac98b6 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1663,8 +1663,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len)
rix = rates[i].idx;
series[i].Tries = rates[i].count;
- if ((sc->config.ath_aggr_prot && bf_isaggr(bf)) ||
- (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS)) {
+ if (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS) {
series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
flags |= ATH9K_TXDESC_RTSENA;
} else if (rates[i].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
@@ -1733,8 +1732,6 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len)
!is_pspoll, ctsrate,
0, series, 4, flags);
- if (sc->config.ath_aggr_prot && flags)
- ath9k_hw_set11n_burstduration(sc->sc_ah, bf->bf_desc, 8192);
}
static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw,
@@ -1848,6 +1845,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_sta *sta = info->control.sta;
+ struct ieee80211_vif *vif = info->control.vif;
struct ath_softc *sc = hw->priv;
struct ath_txq *txq = txctl->txq;
struct ath_buf *bf;
@@ -1885,6 +1883,11 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
memmove(skb->data, skb->data + padsize, padpos);
}
+ if ((vif && vif->type != NL80211_IFTYPE_AP &&
+ vif->type != NL80211_IFTYPE_AP_VLAN) ||
+ !ieee80211_is_data(hdr->frame_control))
+ info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
+
setup_frame_info(hw, skb, frmlen);
/*