|
|
@@ -856,7 +856,31 @@
|
|
|
|
|
|
/**********/
|
|
|
/* BTCOEX */
|
|
|
-@@ -570,6 +571,34 @@ static inline void ath_fill_led_pin(stru
|
|
|
+@@ -476,20 +477,19 @@ enum bt_op_flags {
|
|
|
+ };
|
|
|
+
|
|
|
+ struct ath_btcoex {
|
|
|
+- bool hw_timer_enabled;
|
|
|
+ spinlock_t btcoex_lock;
|
|
|
+ struct timer_list period_timer; /* Timer for BT period */
|
|
|
++ struct timer_list no_stomp_timer;
|
|
|
+ u32 bt_priority_cnt;
|
|
|
+ unsigned long bt_priority_time;
|
|
|
+ unsigned long op_flags;
|
|
|
+ int bt_stomp_type; /* Types of BT stomping */
|
|
|
+- u32 btcoex_no_stomp; /* in usec */
|
|
|
++ u32 btcoex_no_stomp; /* in msec */
|
|
|
+ u32 btcoex_period; /* in msec */
|
|
|
+- u32 btscan_no_stomp; /* in usec */
|
|
|
++ u32 btscan_no_stomp; /* in msec */
|
|
|
+ u32 duty_cycle;
|
|
|
+ u32 bt_wait_time;
|
|
|
+ int rssi_count;
|
|
|
+- struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */
|
|
|
+ struct ath_mci_profile mci;
|
|
|
+ u8 stomp_audio;
|
|
|
+ };
|
|
|
+@@ -570,6 +570,34 @@ static inline void ath_fill_led_pin(stru
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
@@ -891,7 +915,7 @@
|
|
|
/*******************************/
|
|
|
/* Antenna diversity/combining */
|
|
|
/*******************************/
|
|
|
-@@ -632,15 +661,16 @@ void ath_ant_comb_scan(struct ath_softc
|
|
|
+@@ -632,15 +660,16 @@ void ath_ant_comb_scan(struct ath_softc
|
|
|
/* Main driver core */
|
|
|
/********************/
|
|
|
|
|
|
@@ -917,7 +941,7 @@
|
|
|
|
|
|
/*
|
|
|
* Default cache line size, in bytes.
|
|
|
-@@ -723,6 +753,7 @@ struct ath_softc {
|
|
|
+@@ -723,6 +752,7 @@ struct ath_softc {
|
|
|
struct work_struct hw_check_work;
|
|
|
struct work_struct hw_reset_work;
|
|
|
struct completion paprd_complete;
|
|
|
@@ -925,7 +949,7 @@
|
|
|
|
|
|
unsigned int hw_busy_count;
|
|
|
unsigned long sc_flags;
|
|
|
-@@ -759,6 +790,7 @@ struct ath_softc {
|
|
|
+@@ -759,6 +789,7 @@ struct ath_softc {
|
|
|
struct delayed_work tx_complete_work;
|
|
|
struct delayed_work hw_pll_work;
|
|
|
struct timer_list rx_poll_timer;
|
|
|
@@ -933,7 +957,7 @@
|
|
|
|
|
|
#ifdef CPTCFG_ATH9K_BTCOEX_SUPPORT
|
|
|
struct ath_btcoex btcoex;
|
|
|
-@@ -783,7 +815,7 @@ struct ath_softc {
|
|
|
+@@ -783,7 +814,7 @@ struct ath_softc {
|
|
|
bool tx99_state;
|
|
|
s16 tx99_power;
|
|
|
|
|
|
@@ -942,7 +966,7 @@
|
|
|
atomic_t wow_got_bmiss_intr;
|
|
|
atomic_t wow_sleep_proc_intr; /* in the middle of WoW sleep ? */
|
|
|
u32 wow_intr_before_sleep;
|
|
|
-@@ -946,10 +978,25 @@ struct fft_sample_ht20_40 {
|
|
|
+@@ -946,10 +977,25 @@ struct fft_sample_ht20_40 {
|
|
|
u8 data[SPECTRAL_HT20_40_NUM_BINS];
|
|
|
} __packed;
|
|
|
|
|
|
@@ -970,7 +994,7 @@
|
|
|
|
|
|
void ath9k_tasklet(unsigned long data);
|
|
|
int ath_cabq_update(struct ath_softc *);
|
|
|
-@@ -966,6 +1013,9 @@ extern bool is_ath9k_unloaded;
|
|
|
+@@ -966,6 +1012,9 @@ extern bool is_ath9k_unloaded;
|
|
|
|
|
|
u8 ath9k_parse_mpdudensity(u8 mpdudensity);
|
|
|
irqreturn_t ath_isr(int irq, void *dev);
|
|
|
@@ -1120,23 +1144,48 @@
|
|
|
}
|
|
|
--- a/drivers/net/wireless/ath/ath9k/hw.c
|
|
|
+++ b/drivers/net/wireless/ath/ath9k/hw.c
|
|
|
-@@ -17,6 +17,7 @@
|
|
|
+@@ -17,6 +17,8 @@
|
|
|
#include <linux/io.h>
|
|
|
#include <linux/slab.h>
|
|
|
#include <linux/module.h>
|
|
|
+#include <linux/time.h>
|
|
|
++#include <linux/bitops.h>
|
|
|
#include <asm/unaligned.h>
|
|
|
|
|
|
#include "hw.h"
|
|
|
-@@ -454,7 +455,6 @@ static void ath9k_hw_init_config(struct
|
|
|
- }
|
|
|
+@@ -438,23 +440,13 @@ static bool ath9k_hw_chip_test(struct at
|
|
|
|
|
|
+ static void ath9k_hw_init_config(struct ath_hw *ah)
|
|
|
+ {
|
|
|
+- int i;
|
|
|
+-
|
|
|
+ ah->config.dma_beacon_response_time = 1;
|
|
|
+ ah->config.sw_beacon_response_time = 6;
|
|
|
+- ah->config.additional_swba_backoff = 0;
|
|
|
+ ah->config.ack_6mb = 0x0;
|
|
|
+ ah->config.cwm_ignore_extcca = 0;
|
|
|
+- ah->config.pcie_clock_req = 0;
|
|
|
+ ah->config.analog_shiftreg = 1;
|
|
|
+
|
|
|
+- for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
|
|
|
+- ah->config.spurchans[i][0] = AR_NO_SPUR;
|
|
|
+- ah->config.spurchans[i][1] = AR_NO_SPUR;
|
|
|
+- }
|
|
|
+-
|
|
|
ah->config.rx_intr_mitigation = true;
|
|
|
- ah->config.pcieSerDesWrite = true;
|
|
|
|
|
|
/*
|
|
|
* We need this for PCI devices only (Cardbus, PCI, miniPCI)
|
|
|
-@@ -549,11 +549,11 @@ static int ath9k_hw_post_init(struct ath
|
|
|
+@@ -486,7 +478,6 @@ static void ath9k_hw_init_defaults(struc
|
|
|
+ ah->hw_version.magic = AR5416_MAGIC;
|
|
|
+ ah->hw_version.subvendorid = 0;
|
|
|
+
|
|
|
+- ah->atim_window = 0;
|
|
|
+ ah->sta_id1_defaults =
|
|
|
+ AR_STA_ID1_CRPT_MIC_ENABLE |
|
|
|
+ AR_STA_ID1_MCAST_KSRCH;
|
|
|
+@@ -549,11 +540,11 @@ static int ath9k_hw_post_init(struct ath
|
|
|
* EEPROM needs to be initialized before we do this.
|
|
|
* This is required for regulatory compliance.
|
|
|
*/
|
|
|
@@ -1151,7 +1200,7 @@
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-@@ -1502,8 +1502,9 @@ static bool ath9k_hw_channel_change(stru
|
|
|
+@@ -1502,8 +1493,9 @@ static bool ath9k_hw_channel_change(stru
|
|
|
int r;
|
|
|
|
|
|
if (pCap->hw_caps & ATH9K_HW_CAP_FCC_BAND_SWITCH) {
|
|
|
@@ -1163,7 +1212,7 @@
|
|
|
}
|
|
|
|
|
|
for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
|
|
|
-@@ -1815,7 +1816,7 @@ static int ath9k_hw_do_fastcc(struct ath
|
|
|
+@@ -1815,7 +1807,7 @@ static int ath9k_hw_do_fastcc(struct ath
|
|
|
* If cross-band fcc is not supoprted, bail out if channelFlags differ.
|
|
|
*/
|
|
|
if (!(pCap->hw_caps & ATH9K_HW_CAP_FCC_BAND_SWITCH) &&
|
|
|
@@ -1172,7 +1221,7 @@
|
|
|
goto fail;
|
|
|
|
|
|
if (!ath9k_hw_check_alive(ah))
|
|
|
-@@ -1856,10 +1857,12 @@ int ath9k_hw_reset(struct ath_hw *ah, st
|
|
|
+@@ -1856,10 +1848,12 @@ int ath9k_hw_reset(struct ath_hw *ah, st
|
|
|
struct ath9k_hw_cal_data *caldata, bool fastcc)
|
|
|
{
|
|
|
struct ath_common *common = ath9k_hw_common(ah);
|
|
|
@@ -1185,7 +1234,7 @@
|
|
|
int r;
|
|
|
bool start_mci_reset = false;
|
|
|
bool save_fullsleep = ah->chip_fullsleep;
|
|
|
-@@ -1902,10 +1905,10 @@ int ath9k_hw_reset(struct ath_hw *ah, st
|
|
|
+@@ -1902,10 +1896,10 @@ int ath9k_hw_reset(struct ath_hw *ah, st
|
|
|
|
|
|
macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B;
|
|
|
|
|
|
@@ -1200,7 +1249,7 @@
|
|
|
|
|
|
saveLedState = REG_READ(ah, AR_CFG_LED) &
|
|
|
(AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL |
|
|
|
-@@ -1938,8 +1941,9 @@ int ath9k_hw_reset(struct ath_hw *ah, st
|
|
|
+@@ -1938,8 +1932,9 @@ int ath9k_hw_reset(struct ath_hw *ah, st
|
|
|
}
|
|
|
|
|
|
/* Restore TSF */
|
|
|
@@ -1212,17 +1261,262 @@
|
|
|
|
|
|
if (AR_SREV_9280_20_OR_LATER(ah))
|
|
|
REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE);
|
|
|
+@@ -2261,9 +2256,6 @@ void ath9k_hw_beaconinit(struct ath_hw *
|
|
|
+ case NL80211_IFTYPE_ADHOC:
|
|
|
+ REG_SET_BIT(ah, AR_TXCFG,
|
|
|
+ AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY);
|
|
|
+- REG_WRITE(ah, AR_NEXT_NDP_TIMER, next_beacon +
|
|
|
+- TU_TO_USEC(ah->atim_window ? ah->atim_window : 1));
|
|
|
+- flags |= AR_NDP_TIMER_EN;
|
|
|
+ case NL80211_IFTYPE_MESH_POINT:
|
|
|
+ case NL80211_IFTYPE_AP:
|
|
|
+ REG_WRITE(ah, AR_NEXT_TBTT_TIMER, next_beacon);
|
|
|
+@@ -2284,7 +2276,6 @@ void ath9k_hw_beaconinit(struct ath_hw *
|
|
|
+ REG_WRITE(ah, AR_BEACON_PERIOD, beacon_period);
|
|
|
+ REG_WRITE(ah, AR_DMA_BEACON_PERIOD, beacon_period);
|
|
|
+ REG_WRITE(ah, AR_SWBA_PERIOD, beacon_period);
|
|
|
+- REG_WRITE(ah, AR_NDP_PERIOD, beacon_period);
|
|
|
+
|
|
|
+ REGWRITE_BUFFER_FLUSH(ah);
|
|
|
+
|
|
|
+@@ -2301,12 +2292,9 @@ void ath9k_hw_set_sta_beacon_timers(stru
|
|
|
+
|
|
|
+ ENABLE_REGWRITE_BUFFER(ah);
|
|
|
+
|
|
|
+- REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt));
|
|
|
+-
|
|
|
+- REG_WRITE(ah, AR_BEACON_PERIOD,
|
|
|
+- TU_TO_USEC(bs->bs_intval));
|
|
|
+- REG_WRITE(ah, AR_DMA_BEACON_PERIOD,
|
|
|
+- TU_TO_USEC(bs->bs_intval));
|
|
|
++ REG_WRITE(ah, AR_NEXT_TBTT_TIMER, bs->bs_nexttbtt);
|
|
|
++ REG_WRITE(ah, AR_BEACON_PERIOD, bs->bs_intval);
|
|
|
++ REG_WRITE(ah, AR_DMA_BEACON_PERIOD, bs->bs_intval);
|
|
|
+
|
|
|
+ REGWRITE_BUFFER_FLUSH(ah);
|
|
|
+
|
|
|
+@@ -2334,9 +2322,8 @@ void ath9k_hw_set_sta_beacon_timers(stru
|
|
|
+
|
|
|
+ ENABLE_REGWRITE_BUFFER(ah);
|
|
|
+
|
|
|
+- REG_WRITE(ah, AR_NEXT_DTIM,
|
|
|
+- TU_TO_USEC(bs->bs_nextdtim - SLEEP_SLOP));
|
|
|
+- REG_WRITE(ah, AR_NEXT_TIM, TU_TO_USEC(nextTbtt - SLEEP_SLOP));
|
|
|
++ REG_WRITE(ah, AR_NEXT_DTIM, bs->bs_nextdtim - SLEEP_SLOP);
|
|
|
++ REG_WRITE(ah, AR_NEXT_TIM, nextTbtt - SLEEP_SLOP);
|
|
|
+
|
|
|
+ REG_WRITE(ah, AR_SLEEP1,
|
|
|
+ SM((CAB_TIMEOUT_VAL << 3), AR_SLEEP1_CAB_TIMEOUT)
|
|
|
+@@ -2350,8 +2337,8 @@ void ath9k_hw_set_sta_beacon_timers(stru
|
|
|
+ REG_WRITE(ah, AR_SLEEP2,
|
|
|
+ SM(beacontimeout, AR_SLEEP2_BEACON_TIMEOUT));
|
|
|
+
|
|
|
+- REG_WRITE(ah, AR_TIM_PERIOD, TU_TO_USEC(beaconintval));
|
|
|
+- REG_WRITE(ah, AR_DTIM_PERIOD, TU_TO_USEC(dtimperiod));
|
|
|
++ REG_WRITE(ah, AR_TIM_PERIOD, beaconintval);
|
|
|
++ REG_WRITE(ah, AR_DTIM_PERIOD, dtimperiod);
|
|
|
+
|
|
|
+ REGWRITE_BUFFER_FLUSH(ah);
|
|
|
+
|
|
|
+@@ -2987,20 +2974,6 @@ static const struct ath_gen_timer_config
|
|
|
+
|
|
|
+ /* HW generic timer primitives */
|
|
|
+
|
|
|
+-/* compute and clear index of rightmost 1 */
|
|
|
+-static u32 rightmost_index(struct ath_gen_timer_table *timer_table, u32 *mask)
|
|
|
+-{
|
|
|
+- u32 b;
|
|
|
+-
|
|
|
+- b = *mask;
|
|
|
+- b &= (0-b);
|
|
|
+- *mask &= ~b;
|
|
|
+- b *= debruijn32;
|
|
|
+- b >>= 27;
|
|
|
+-
|
|
|
+- return timer_table->gen_timer_index[b];
|
|
|
+-}
|
|
|
+-
|
|
|
+ u32 ath9k_hw_gettsf32(struct ath_hw *ah)
|
|
|
+ {
|
|
|
+ return REG_READ(ah, AR_TSF_L32);
|
|
|
+@@ -3016,6 +2989,10 @@ struct ath_gen_timer *ath_gen_timer_allo
|
|
|
+ struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;
|
|
|
+ struct ath_gen_timer *timer;
|
|
|
+
|
|
|
++ if ((timer_index < AR_FIRST_NDP_TIMER) ||
|
|
|
++ (timer_index >= ATH_MAX_GEN_TIMER))
|
|
|
++ return NULL;
|
|
|
++
|
|
|
+ timer = kzalloc(sizeof(struct ath_gen_timer), GFP_KERNEL);
|
|
|
+ if (timer == NULL)
|
|
|
+ return NULL;
|
|
|
+@@ -3033,23 +3010,13 @@ EXPORT_SYMBOL(ath_gen_timer_alloc);
|
|
|
+
|
|
|
+ void ath9k_hw_gen_timer_start(struct ath_hw *ah,
|
|
|
+ struct ath_gen_timer *timer,
|
|
|
+- u32 trig_timeout,
|
|
|
++ u32 timer_next,
|
|
|
+ u32 timer_period)
|
|
|
+ {
|
|
|
+ struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;
|
|
|
+- u32 tsf, timer_next;
|
|
|
+-
|
|
|
+- BUG_ON(!timer_period);
|
|
|
+-
|
|
|
+- set_bit(timer->index, &timer_table->timer_mask.timer_bits);
|
|
|
+-
|
|
|
+- tsf = ath9k_hw_gettsf32(ah);
|
|
|
++ u32 mask = 0;
|
|
|
+
|
|
|
+- timer_next = tsf + trig_timeout;
|
|
|
+-
|
|
|
+- ath_dbg(ath9k_hw_common(ah), BTCOEX,
|
|
|
+- "current tsf %x period %x timer_next %x\n",
|
|
|
+- tsf, timer_period, timer_next);
|
|
|
++ timer_table->timer_mask |= BIT(timer->index);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Program generic timer registers
|
|
|
+@@ -3075,10 +3042,19 @@ void ath9k_hw_gen_timer_start(struct ath
|
|
|
+ (1 << timer->index));
|
|
|
+ }
|
|
|
+
|
|
|
+- /* Enable both trigger and thresh interrupt masks */
|
|
|
+- REG_SET_BIT(ah, AR_IMR_S5,
|
|
|
+- (SM(AR_GENTMR_BIT(timer->index), AR_IMR_S5_GENTIMER_THRESH) |
|
|
|
+- SM(AR_GENTMR_BIT(timer->index), AR_IMR_S5_GENTIMER_TRIG)));
|
|
|
++ if (timer->trigger)
|
|
|
++ mask |= SM(AR_GENTMR_BIT(timer->index),
|
|
|
++ AR_IMR_S5_GENTIMER_TRIG);
|
|
|
++ if (timer->overflow)
|
|
|
++ mask |= SM(AR_GENTMR_BIT(timer->index),
|
|
|
++ AR_IMR_S5_GENTIMER_THRESH);
|
|
|
++
|
|
|
++ REG_SET_BIT(ah, AR_IMR_S5, mask);
|
|
|
++
|
|
|
++ if ((ah->imask & ATH9K_INT_GENTIMER) == 0) {
|
|
|
++ ah->imask |= ATH9K_INT_GENTIMER;
|
|
|
++ ath9k_hw_set_interrupts(ah);
|
|
|
++ }
|
|
|
+ }
|
|
|
+ EXPORT_SYMBOL(ath9k_hw_gen_timer_start);
|
|
|
+
|
|
|
+@@ -3086,11 +3062,6 @@ void ath9k_hw_gen_timer_stop(struct ath_
|
|
|
+ {
|
|
|
+ struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;
|
|
|
+
|
|
|
+- if ((timer->index < AR_FIRST_NDP_TIMER) ||
|
|
|
+- (timer->index >= ATH_MAX_GEN_TIMER)) {
|
|
|
+- return;
|
|
|
+- }
|
|
|
+-
|
|
|
+ /* Clear generic timer enable bits. */
|
|
|
+ REG_CLR_BIT(ah, gen_tmr_configuration[timer->index].mode_addr,
|
|
|
+ gen_tmr_configuration[timer->index].mode_mask);
|
|
|
+@@ -3110,7 +3081,12 @@ void ath9k_hw_gen_timer_stop(struct ath_
|
|
|
+ (SM(AR_GENTMR_BIT(timer->index), AR_IMR_S5_GENTIMER_THRESH) |
|
|
|
+ SM(AR_GENTMR_BIT(timer->index), AR_IMR_S5_GENTIMER_TRIG)));
|
|
|
+
|
|
|
+- clear_bit(timer->index, &timer_table->timer_mask.timer_bits);
|
|
|
++ timer_table->timer_mask &= ~BIT(timer->index);
|
|
|
++
|
|
|
++ if (timer_table->timer_mask == 0) {
|
|
|
++ ah->imask &= ~ATH9K_INT_GENTIMER;
|
|
|
++ ath9k_hw_set_interrupts(ah);
|
|
|
++ }
|
|
|
+ }
|
|
|
+ EXPORT_SYMBOL(ath9k_hw_gen_timer_stop);
|
|
|
+
|
|
|
+@@ -3131,32 +3107,32 @@ void ath_gen_timer_isr(struct ath_hw *ah
|
|
|
+ {
|
|
|
+ struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;
|
|
|
+ struct ath_gen_timer *timer;
|
|
|
+- struct ath_common *common = ath9k_hw_common(ah);
|
|
|
+- u32 trigger_mask, thresh_mask, index;
|
|
|
++ unsigned long trigger_mask, thresh_mask;
|
|
|
++ unsigned int index;
|
|
|
+
|
|
|
+ /* get hardware generic timer interrupt status */
|
|
|
+ trigger_mask = ah->intr_gen_timer_trigger;
|
|
|
+ thresh_mask = ah->intr_gen_timer_thresh;
|
|
|
+- trigger_mask &= timer_table->timer_mask.val;
|
|
|
+- thresh_mask &= timer_table->timer_mask.val;
|
|
|
++ trigger_mask &= timer_table->timer_mask;
|
|
|
++ thresh_mask &= timer_table->timer_mask;
|
|
|
+
|
|
|
+ trigger_mask &= ~thresh_mask;
|
|
|
+
|
|
|
+- while (thresh_mask) {
|
|
|
+- index = rightmost_index(timer_table, &thresh_mask);
|
|
|
++ for_each_set_bit(index, &thresh_mask, ARRAY_SIZE(timer_table->timers)) {
|
|
|
+ timer = timer_table->timers[index];
|
|
|
+- BUG_ON(!timer);
|
|
|
+- ath_dbg(common, BTCOEX, "TSF overflow for Gen timer %d\n",
|
|
|
+- index);
|
|
|
++ if (!timer)
|
|
|
++ continue;
|
|
|
++ if (!timer->overflow)
|
|
|
++ continue;
|
|
|
+ timer->overflow(timer->arg);
|
|
|
+ }
|
|
|
+
|
|
|
+- while (trigger_mask) {
|
|
|
+- index = rightmost_index(timer_table, &trigger_mask);
|
|
|
++ for_each_set_bit(index, &trigger_mask, ARRAY_SIZE(timer_table->timers)) {
|
|
|
+ timer = timer_table->timers[index];
|
|
|
+- BUG_ON(!timer);
|
|
|
+- ath_dbg(common, BTCOEX,
|
|
|
+- "Gen timer[%d] trigger\n", index);
|
|
|
++ if (!timer)
|
|
|
++ continue;
|
|
|
++ if (!timer->trigger)
|
|
|
++ continue;
|
|
|
+ timer->trigger(timer->arg);
|
|
|
+ }
|
|
|
+ }
|
|
|
--- a/drivers/net/wireless/ath/ath9k/hw.h
|
|
|
+++ b/drivers/net/wireless/ath/ath9k/hw.h
|
|
|
-@@ -283,7 +283,6 @@ struct ath9k_ops_config {
|
|
|
- int additional_swba_backoff;
|
|
|
+@@ -168,7 +168,7 @@
|
|
|
+ #define CAB_TIMEOUT_VAL 10
|
|
|
+ #define BEACON_TIMEOUT_VAL 10
|
|
|
+ #define MIN_BEACON_TIMEOUT_VAL 1
|
|
|
+-#define SLEEP_SLOP 3
|
|
|
++#define SLEEP_SLOP TU_TO_USEC(3)
|
|
|
+
|
|
|
+ #define INIT_CONFIG_STATUS 0x00000000
|
|
|
+ #define INIT_RSSI_THR 0x00000700
|
|
|
+@@ -280,11 +280,8 @@ struct ath9k_hw_capabilities {
|
|
|
+ struct ath9k_ops_config {
|
|
|
+ int dma_beacon_response_time;
|
|
|
+ int sw_beacon_response_time;
|
|
|
+- int additional_swba_backoff;
|
|
|
int ack_6mb;
|
|
|
u32 cwm_ignore_extcca;
|
|
|
- bool pcieSerDesWrite;
|
|
|
- u8 pcie_clock_req;
|
|
|
+- u8 pcie_clock_req;
|
|
|
u32 pcie_waen;
|
|
|
u8 analog_shiftreg;
|
|
|
-@@ -316,6 +315,8 @@ struct ath9k_ops_config {
|
|
|
+ u32 ofdm_trig_low;
|
|
|
+@@ -295,18 +292,11 @@ struct ath9k_ops_config {
|
|
|
+ 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
|
|
|
+-#define AR_SPUR_5413_1 1640
|
|
|
+-#define AR_SPUR_5413_2 1200
|
|
|
+ #define AR_NO_SPUR 0x8000
|
|
|
+ #define AR_BASE_FREQ_2GHZ 2300
|
|
|
+ #define AR_BASE_FREQ_5GHZ 4900
|
|
|
+ #define AR_SPUR_FEEQ_BOUND_HT40 19
|
|
|
+ #define AR_SPUR_FEEQ_BOUND_HT20 10
|
|
|
+- int spurmode;
|
|
|
+- u16 spurchans[AR_EEPROM_MODAL_SPURS][2];
|
|
|
+ u8 max_txtrig_level;
|
|
|
+ u16 ani_poll_interval; /* ANI poll interval in ms */
|
|
|
+
|
|
|
+@@ -316,6 +306,8 @@ struct ath9k_ops_config {
|
|
|
u32 ant_ctrl_comm2g_switch_enable;
|
|
|
bool xatten_margin_cfg;
|
|
|
bool alt_mingainidx;
|
|
|
@@ -1231,7 +1525,53 @@
|
|
|
};
|
|
|
|
|
|
enum ath9k_int {
|
|
|
-@@ -864,6 +865,7 @@ struct ath_hw {
|
|
|
+@@ -459,10 +451,6 @@ struct ath9k_beacon_state {
|
|
|
+ u32 bs_intval;
|
|
|
+ #define ATH9K_TSFOOR_THRESHOLD 0x00004240 /* 16k us */
|
|
|
+ u32 bs_dtimperiod;
|
|
|
+- u16 bs_cfpperiod;
|
|
|
+- u16 bs_cfpmaxduration;
|
|
|
+- u32 bs_cfpnext;
|
|
|
+- u16 bs_timoffset;
|
|
|
+ u16 bs_bmissthreshold;
|
|
|
+ u32 bs_sleepduration;
|
|
|
+ u32 bs_tsfoor_threshold;
|
|
|
+@@ -498,12 +486,6 @@ struct ath9k_hw_version {
|
|
|
+
|
|
|
+ #define AR_GENTMR_BIT(_index) (1 << (_index))
|
|
|
+
|
|
|
+-/*
|
|
|
+- * Using de Bruijin sequence to look up 1's index in a 32 bit number
|
|
|
+- * debruijn32 = 0000 0111 0111 1100 1011 0101 0011 0001
|
|
|
+- */
|
|
|
+-#define debruijn32 0x077CB531U
|
|
|
+-
|
|
|
+ struct ath_gen_timer_configuration {
|
|
|
+ u32 next_addr;
|
|
|
+ u32 period_addr;
|
|
|
+@@ -519,12 +501,8 @@ struct ath_gen_timer {
|
|
|
+ };
|
|
|
+
|
|
|
+ struct ath_gen_timer_table {
|
|
|
+- u32 gen_timer_index[32];
|
|
|
+ struct ath_gen_timer *timers[ATH_MAX_GEN_TIMER];
|
|
|
+- union {
|
|
|
+- unsigned long timer_bits;
|
|
|
+- u16 val;
|
|
|
+- } timer_mask;
|
|
|
++ u16 timer_mask;
|
|
|
+ };
|
|
|
+
|
|
|
+ struct ath_hw_antcomb_conf {
|
|
|
+@@ -785,7 +763,6 @@ struct ath_hw {
|
|
|
+ u32 txurn_interrupt_mask;
|
|
|
+ atomic_t intr_ref_cnt;
|
|
|
+ bool chip_fullsleep;
|
|
|
+- u32 atim_window;
|
|
|
+ u32 modes_index;
|
|
|
+
|
|
|
+ /* Calibration */
|
|
|
+@@ -864,6 +841,7 @@ struct ath_hw {
|
|
|
u32 gpio_mask;
|
|
|
u32 gpio_val;
|
|
|
|
|
|
@@ -1239,7 +1579,7 @@
|
|
|
struct ar5416IniArray iniModes;
|
|
|
struct ar5416IniArray iniCommon;
|
|
|
struct ar5416IniArray iniBB_RfGain;
|
|
|
-@@ -920,7 +922,7 @@ struct ath_hw {
|
|
|
+@@ -920,7 +898,7 @@ struct ath_hw {
|
|
|
/* Enterprise mode cap */
|
|
|
u32 ent_mode;
|
|
|
|
|
|
@@ -1248,7 +1588,7 @@
|
|
|
u32 wow_event_mask;
|
|
|
#endif
|
|
|
bool is_clk_25mhz;
|
|
|
-@@ -1126,7 +1128,7 @@ ath9k_hw_get_btcoex_scheme(struct ath_hw
|
|
|
+@@ -1126,7 +1104,7 @@ ath9k_hw_get_btcoex_scheme(struct ath_hw
|
|
|
#endif /* CPTCFG_ATH9K_BTCOEX_SUPPORT */
|
|
|
|
|
|
|
|
|
@@ -1496,7 +1836,7 @@
|
|
|
{
|
|
|
ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
|
|
|
|
|
|
-@@ -487,6 +504,8 @@ void ath9k_tasklet(unsigned long data)
|
|
|
+@@ -487,8 +504,13 @@ void ath9k_tasklet(unsigned long data)
|
|
|
ath_tx_edma_tasklet(sc);
|
|
|
else
|
|
|
ath_tx_tasklet(sc);
|
|
|
@@ -1504,8 +1844,13 @@
|
|
|
+ wake_up(&sc->tx_wait);
|
|
|
}
|
|
|
|
|
|
++ if (status & ATH9K_INT_GENTIMER)
|
|
|
++ ath_gen_timer_isr(sc->sc_ah);
|
|
|
++
|
|
|
ath9k_btcoex_handle_interrupt(sc, status);
|
|
|
-@@ -579,7 +598,8 @@ irqreturn_t ath_isr(int irq, void *dev)
|
|
|
+
|
|
|
+ /* re-enable hardware interrupt */
|
|
|
+@@ -579,7 +601,8 @@ irqreturn_t ath_isr(int irq, void *dev)
|
|
|
|
|
|
goto chip_reset;
|
|
|
}
|
|
|
@@ -1515,7 +1860,7 @@
|
|
|
if (status & ATH9K_INT_BMISS) {
|
|
|
if (atomic_read(&sc->wow_sleep_proc_intr) == 0) {
|
|
|
ath_dbg(common, ANY, "during WoW we got a BMISS\n");
|
|
|
-@@ -588,6 +608,8 @@ irqreturn_t ath_isr(int irq, void *dev)
|
|
|
+@@ -588,6 +611,8 @@ irqreturn_t ath_isr(int irq, void *dev)
|
|
|
}
|
|
|
}
|
|
|
#endif
|
|
|
@@ -1524,7 +1869,7 @@
|
|
|
if (status & ATH9K_INT_SWBA)
|
|
|
tasklet_schedule(&sc->bcon_tasklet);
|
|
|
|
|
|
-@@ -627,7 +649,7 @@ chip_reset:
|
|
|
+@@ -627,7 +652,7 @@ chip_reset:
|
|
|
#undef SCHED_INTR
|
|
|
}
|
|
|
|
|
|
@@ -1533,7 +1878,16 @@
|
|
|
{
|
|
|
int r;
|
|
|
|
|
|
-@@ -1817,13 +1839,31 @@ static void ath9k_set_coverage_class(str
|
|
|
+@@ -735,6 +760,8 @@ static int ath9k_start(struct ieee80211_
|
|
|
+ */
|
|
|
+ ath9k_cmn_init_crypto(sc->sc_ah);
|
|
|
+
|
|
|
++ ath9k_hw_reset_tsf(ah);
|
|
|
++
|
|
|
+ spin_unlock_bh(&sc->sc_pcu_lock);
|
|
|
+
|
|
|
+ mutex_unlock(&sc->mutex);
|
|
|
+@@ -1817,13 +1844,31 @@ static void ath9k_set_coverage_class(str
|
|
|
mutex_unlock(&sc->mutex);
|
|
|
}
|
|
|
|
|
|
@@ -1567,7 +1921,7 @@
|
|
|
bool drain_txq;
|
|
|
|
|
|
mutex_lock(&sc->mutex);
|
|
|
-@@ -1841,25 +1881,9 @@ static void ath9k_flush(struct ieee80211
|
|
|
+@@ -1841,25 +1886,9 @@ static void ath9k_flush(struct ieee80211
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
@@ -1596,7 +1950,7 @@
|
|
|
|
|
|
if (drop) {
|
|
|
ath9k_ps_wakeup(sc);
|
|
|
-@@ -2021,333 +2045,6 @@ static int ath9k_get_antenna(struct ieee
|
|
|
+@@ -2021,333 +2050,6 @@ static int ath9k_get_antenna(struct ieee
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
@@ -1930,7 +2284,7 @@
|
|
|
static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
|
|
|
{
|
|
|
struct ath_softc *sc = hw->priv;
|
|
|
-@@ -2373,134 +2070,6 @@ static void ath9k_channel_switch_beacon(
|
|
|
+@@ -2373,134 +2075,6 @@ static void ath9k_channel_switch_beacon(
|
|
|
sc->csa_vif = vif;
|
|
|
}
|
|
|
|
|
|
@@ -2065,7 +2419,7 @@
|
|
|
struct ieee80211_ops ath9k_ops = {
|
|
|
.tx = ath9k_tx,
|
|
|
.start = ath9k_start,
|
|
|
-@@ -2531,7 +2100,7 @@ struct ieee80211_ops ath9k_ops = {
|
|
|
+@@ -2531,7 +2105,7 @@ struct ieee80211_ops ath9k_ops = {
|
|
|
.set_antenna = ath9k_set_antenna,
|
|
|
.get_antenna = ath9k_get_antenna,
|
|
|
|
|
|
@@ -11533,3 +11887,794 @@
|
|
|
}
|
|
|
|
|
|
if (sync_cause) {
|
|
|
+--- a/drivers/net/wireless/ath/ath9k/antenna.c
|
|
|
++++ b/drivers/net/wireless/ath/ath9k/antenna.c
|
|
|
+@@ -724,14 +724,14 @@ void ath_ant_comb_scan(struct ath_softc
|
|
|
+ struct ath_ant_comb *antcomb = &sc->ant_comb;
|
|
|
+ int alt_ratio = 0, alt_rssi_avg = 0, main_rssi_avg = 0, curr_alt_set;
|
|
|
+ int curr_main_set;
|
|
|
+- int main_rssi = rs->rs_rssi_ctl0;
|
|
|
+- int alt_rssi = rs->rs_rssi_ctl1;
|
|
|
++ int main_rssi = rs->rs_rssi_ctl[0];
|
|
|
++ int alt_rssi = rs->rs_rssi_ctl[1];
|
|
|
+ int rx_ant_conf, main_ant_conf;
|
|
|
+ bool short_scan = false, ret;
|
|
|
+
|
|
|
+- rx_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_CURRENT_SHIFT) &
|
|
|
++ rx_ant_conf = (rs->rs_rssi_ctl[2] >> ATH_ANT_RX_CURRENT_SHIFT) &
|
|
|
+ ATH_ANT_RX_MASK;
|
|
|
+- main_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_MAIN_SHIFT) &
|
|
|
++ main_ant_conf = (rs->rs_rssi_ctl[2] >> ATH_ANT_RX_MAIN_SHIFT) &
|
|
|
+ ATH_ANT_RX_MASK;
|
|
|
+
|
|
|
+ if (alt_rssi >= antcomb->low_rssi_thresh) {
|
|
|
+--- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c
|
|
|
++++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
|
|
|
+@@ -32,12 +32,8 @@ static int ar9002_hw_init_mode_regs(stru
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+- if (ah->config.pcie_clock_req)
|
|
|
+- INIT_INI_ARRAY(&ah->iniPcieSerdes,
|
|
|
+- ar9280PciePhy_clkreq_off_L1_9280);
|
|
|
+- else
|
|
|
+- INIT_INI_ARRAY(&ah->iniPcieSerdes,
|
|
|
+- ar9280PciePhy_clkreq_always_on_L1_9280);
|
|
|
++ INIT_INI_ARRAY(&ah->iniPcieSerdes,
|
|
|
++ ar9280PciePhy_clkreq_always_on_L1_9280);
|
|
|
+
|
|
|
+ if (AR_SREV_9287_11_OR_LATER(ah)) {
|
|
|
+ INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1);
|
|
|
+--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c
|
|
|
++++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
|
|
|
+@@ -201,7 +201,6 @@ static void ar9002_hw_spur_mitigate(stru
|
|
|
+ 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);
|
|
|
+
|
|
|
+--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
|
|
|
++++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
|
|
|
+@@ -476,12 +476,12 @@ int ath9k_hw_process_rxdesc_edma(struct
|
|
|
+
|
|
|
+ /* 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);
|
|
|
++ rxs->rs_rssi_ctl[0] = MS(rxsp->status1, AR_RxRSSIAnt00);
|
|
|
++ rxs->rs_rssi_ctl[1] = MS(rxsp->status1, AR_RxRSSIAnt01);
|
|
|
++ rxs->rs_rssi_ctl[2] = MS(rxsp->status1, AR_RxRSSIAnt02);
|
|
|
++ rxs->rs_rssi_ext[0] = MS(rxsp->status5, AR_RxRSSIAnt10);
|
|
|
++ rxs->rs_rssi_ext[1] = MS(rxsp->status5, AR_RxRSSIAnt11);
|
|
|
++ rxs->rs_rssi_ext[2] = MS(rxsp->status5, AR_RxRSSIAnt12);
|
|
|
+
|
|
|
+ if (rxsp->status11 & AR_RxKeyIdxValid)
|
|
|
+ rxs->rs_keyix = MS(rxsp->status11, AR_KeyIdx);
|
|
|
+--- a/drivers/net/wireless/ath/ath9k/beacon.c
|
|
|
++++ b/drivers/net/wireless/ath/ath9k/beacon.c
|
|
|
+@@ -431,6 +431,33 @@ static void ath9k_beacon_init(struct ath
|
|
|
+ ath9k_hw_enable_interrupts(ah);
|
|
|
+ }
|
|
|
+
|
|
|
++/* Calculate the modulo of a 64 bit TSF snapshot with a TU divisor */
|
|
|
++static u32 ath9k_mod_tsf64_tu(u64 tsf, u32 div_tu)
|
|
|
++{
|
|
|
++ u32 tsf_mod, tsf_hi, tsf_lo, mod_hi, mod_lo;
|
|
|
++
|
|
|
++ tsf_mod = tsf & (BIT(10) - 1);
|
|
|
++ tsf_hi = tsf >> 32;
|
|
|
++ tsf_lo = ((u32) tsf) >> 10;
|
|
|
++
|
|
|
++ mod_hi = tsf_hi % div_tu;
|
|
|
++ mod_lo = ((mod_hi << 22) + tsf_lo) % div_tu;
|
|
|
++
|
|
|
++ return (mod_lo << 10) | tsf_mod;
|
|
|
++}
|
|
|
++
|
|
|
++static u32 ath9k_get_next_tbtt(struct ath_softc *sc, u64 tsf,
|
|
|
++ unsigned int interval)
|
|
|
++{
|
|
|
++ struct ath_hw *ah = sc->sc_ah;
|
|
|
++ unsigned int offset;
|
|
|
++
|
|
|
++ tsf += TU_TO_USEC(FUDGE + ah->config.sw_beacon_response_time);
|
|
|
++ offset = ath9k_mod_tsf64_tu(tsf, interval);
|
|
|
++
|
|
|
++ return (u32) tsf + TU_TO_USEC(interval) - offset;
|
|
|
++}
|
|
|
++
|
|
|
+ /*
|
|
|
+ * For multi-bss ap support beacons are either staggered evenly over N slots or
|
|
|
+ * burst together. For the former arrange for the SWBA to be delivered for each
|
|
|
+@@ -446,7 +473,8 @@ static void ath9k_beacon_config_ap(struc
|
|
|
+ /* NB: the beacon interval is kept internally in TU's */
|
|
|
+ intval = TU_TO_USEC(conf->beacon_interval);
|
|
|
+ intval /= ATH_BCBUF;
|
|
|
+- nexttbtt = intval;
|
|
|
++ nexttbtt = ath9k_get_next_tbtt(sc, ath9k_hw_gettsf64(ah),
|
|
|
++ conf->beacon_interval);
|
|
|
+
|
|
|
+ if (conf->enable_beacon)
|
|
|
+ ah->imask |= ATH9K_INT_SWBA;
|
|
|
+@@ -458,7 +486,7 @@ static void ath9k_beacon_config_ap(struc
|
|
|
+ (conf->enable_beacon) ? "Enable" : "Disable",
|
|
|
+ nexttbtt, intval, conf->beacon_interval);
|
|
|
+
|
|
|
+- ath9k_beacon_init(sc, nexttbtt, intval, true);
|
|
|
++ ath9k_beacon_init(sc, nexttbtt, intval, false);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+@@ -475,11 +503,9 @@ static void ath9k_beacon_config_sta(stru
|
|
|
+ struct ath_hw *ah = sc->sc_ah;
|
|
|
+ struct ath_common *common = ath9k_hw_common(ah);
|
|
|
+ struct ath9k_beacon_state bs;
|
|
|
+- int dtimperiod, dtimcount, sleepduration;
|
|
|
+- int cfpperiod, cfpcount;
|
|
|
+- u32 nexttbtt = 0, intval, tsftu;
|
|
|
++ int dtim_intval, sleepduration;
|
|
|
++ u32 nexttbtt = 0, intval;
|
|
|
+ u64 tsf;
|
|
|
+- int num_beacons, offset, dtim_dec_count, cfp_dec_count;
|
|
|
+
|
|
|
+ /* No need to configure beacon if we are not associated */
|
|
|
+ if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) {
|
|
|
+@@ -492,53 +518,25 @@ static void ath9k_beacon_config_sta(stru
|
|
|
+ intval = conf->beacon_interval;
|
|
|
+
|
|
|
+ /*
|
|
|
+- * Setup dtim and cfp parameters according to
|
|
|
++ * Setup dtim parameters according to
|
|
|
+ * last beacon we received (which may be none).
|
|
|
+ */
|
|
|
+- dtimperiod = conf->dtim_period;
|
|
|
+- dtimcount = conf->dtim_count;
|
|
|
+- if (dtimcount >= dtimperiod) /* NB: sanity check */
|
|
|
+- dtimcount = 0;
|
|
|
+- cfpperiod = 1; /* NB: no PCF support yet */
|
|
|
+- cfpcount = 0;
|
|
|
+-
|
|
|
++ dtim_intval = intval * conf->dtim_period;
|
|
|
+ sleepduration = conf->listen_interval * intval;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Pull nexttbtt forward to reflect the current
|
|
|
+- * TSF and calculate dtim+cfp state for the result.
|
|
|
++ * TSF and calculate dtim state for the result.
|
|
|
+ */
|
|
|
+ tsf = ath9k_hw_gettsf64(ah);
|
|
|
+- tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE;
|
|
|
+-
|
|
|
+- num_beacons = tsftu / intval + 1;
|
|
|
+- offset = tsftu % intval;
|
|
|
+- nexttbtt = tsftu - offset;
|
|
|
+- if (offset)
|
|
|
+- nexttbtt += intval;
|
|
|
+-
|
|
|
+- /* DTIM Beacon every dtimperiod Beacon */
|
|
|
+- dtim_dec_count = num_beacons % dtimperiod;
|
|
|
+- /* CFP every cfpperiod DTIM Beacon */
|
|
|
+- cfp_dec_count = (num_beacons / dtimperiod) % cfpperiod;
|
|
|
+- if (dtim_dec_count)
|
|
|
+- cfp_dec_count++;
|
|
|
+-
|
|
|
+- dtimcount -= dtim_dec_count;
|
|
|
+- if (dtimcount < 0)
|
|
|
+- dtimcount += dtimperiod;
|
|
|
+-
|
|
|
+- cfpcount -= cfp_dec_count;
|
|
|
+- if (cfpcount < 0)
|
|
|
+- cfpcount += cfpperiod;
|
|
|
++ nexttbtt = ath9k_get_next_tbtt(sc, tsf, intval);
|
|
|
+
|
|
|
+- bs.bs_intval = intval;
|
|
|
++ bs.bs_intval = TU_TO_USEC(intval);
|
|
|
++ bs.bs_dtimperiod = conf->dtim_period * bs.bs_intval;
|
|
|
+ bs.bs_nexttbtt = nexttbtt;
|
|
|
+- bs.bs_dtimperiod = dtimperiod*intval;
|
|
|
+- bs.bs_nextdtim = bs.bs_nexttbtt + dtimcount*intval;
|
|
|
+- bs.bs_cfpperiod = cfpperiod*bs.bs_dtimperiod;
|
|
|
+- bs.bs_cfpnext = bs.bs_nextdtim + cfpcount*bs.bs_dtimperiod;
|
|
|
+- bs.bs_cfpmaxduration = 0;
|
|
|
++ bs.bs_nextdtim = nexttbtt;
|
|
|
++ if (conf->dtim_period > 1)
|
|
|
++ bs.bs_nextdtim = ath9k_get_next_tbtt(sc, tsf, dtim_intval);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Calculate the number of consecutive beacons to miss* before taking
|
|
|
+@@ -566,18 +564,16 @@ static void ath9k_beacon_config_sta(stru
|
|
|
+ * XXX fixed at 100ms
|
|
|
+ */
|
|
|
+
|
|
|
+- bs.bs_sleepduration = roundup(IEEE80211_MS_TO_TU(100), sleepduration);
|
|
|
++ bs.bs_sleepduration = TU_TO_USEC(roundup(IEEE80211_MS_TO_TU(100),
|
|
|
++ sleepduration));
|
|
|
+ if (bs.bs_sleepduration > bs.bs_dtimperiod)
|
|
|
+ bs.bs_sleepduration = bs.bs_dtimperiod;
|
|
|
+
|
|
|
+ /* TSF out of range threshold fixed at 1 second */
|
|
|
+ bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD;
|
|
|
+
|
|
|
+- ath_dbg(common, BEACON, "tsf: %llu tsftu: %u\n", tsf, tsftu);
|
|
|
+- ath_dbg(common, BEACON,
|
|
|
+- "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n",
|
|
|
+- bs.bs_bmissthreshold, bs.bs_sleepduration,
|
|
|
+- bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext);
|
|
|
++ ath_dbg(common, BEACON, "bmiss: %u sleep: %u\n",
|
|
|
++ bs.bs_bmissthreshold, bs.bs_sleepduration);
|
|
|
+
|
|
|
+ /* Set the computed STA beacon timers */
|
|
|
+
|
|
|
+@@ -600,25 +596,11 @@ static void ath9k_beacon_config_adhoc(st
|
|
|
+
|
|
|
+ intval = TU_TO_USEC(conf->beacon_interval);
|
|
|
+
|
|
|
+- if (conf->ibss_creator) {
|
|
|
++ if (conf->ibss_creator)
|
|
|
+ nexttbtt = intval;
|
|
|
+- } else {
|
|
|
+- u32 tbtt, offset, tsftu;
|
|
|
+- u64 tsf;
|
|
|
+-
|
|
|
+- /*
|
|
|
+- * Pull nexttbtt forward to reflect the current
|
|
|
+- * sync'd TSF.
|
|
|
+- */
|
|
|
+- tsf = ath9k_hw_gettsf64(ah);
|
|
|
+- tsftu = TSF_TO_TU(tsf >> 32, tsf) + FUDGE;
|
|
|
+- offset = tsftu % conf->beacon_interval;
|
|
|
+- tbtt = tsftu - offset;
|
|
|
+- if (offset)
|
|
|
+- tbtt += conf->beacon_interval;
|
|
|
+-
|
|
|
+- nexttbtt = TU_TO_USEC(tbtt);
|
|
|
+- }
|
|
|
++ else
|
|
|
++ nexttbtt = ath9k_get_next_tbtt(sc, ath9k_hw_gettsf64(ah),
|
|
|
++ conf->beacon_interval);
|
|
|
+
|
|
|
+ if (conf->enable_beacon)
|
|
|
+ ah->imask |= ATH9K_INT_SWBA;
|
|
|
+--- a/drivers/net/wireless/ath/ath9k/btcoex.c
|
|
|
++++ b/drivers/net/wireless/ath/ath9k/btcoex.c
|
|
|
+@@ -66,7 +66,6 @@ void ath9k_hw_init_btcoex_hw(struct ath_
|
|
|
+ .bt_first_slot_time = 5,
|
|
|
+ .bt_hold_rx_clear = true,
|
|
|
+ };
|
|
|
+- u32 i, idx;
|
|
|
+ bool rxclear_polarity = ath_bt_config.bt_rxclear_polarity;
|
|
|
+
|
|
|
+ if (AR_SREV_9300_20_OR_LATER(ah))
|
|
|
+@@ -88,11 +87,6 @@ void ath9k_hw_init_btcoex_hw(struct ath_
|
|
|
+ SM(ath_bt_config.bt_hold_rx_clear, AR_BT_HOLD_RX_CLEAR) |
|
|
|
+ SM(ATH_BTCOEX_BMISS_THRESH, AR_BT_BCN_MISS_THRESH) |
|
|
|
+ AR_BT_DISABLE_BT_ANT;
|
|
|
+-
|
|
|
+- for (i = 0; i < 32; i++) {
|
|
|
+- idx = (debruijn32 << i) >> 27;
|
|
|
+- ah->hw_gen_timers.gen_timer_index[idx] = i;
|
|
|
+- }
|
|
|
+ }
|
|
|
+ EXPORT_SYMBOL(ath9k_hw_init_btcoex_hw);
|
|
|
+
|
|
|
+--- a/drivers/net/wireless/ath/ath9k/dfs.c
|
|
|
++++ b/drivers/net/wireless/ath/ath9k/dfs.c
|
|
|
+@@ -158,8 +158,8 @@ void ath9k_dfs_process_phyerr(struct ath
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+- ard.rssi = rs->rs_rssi_ctl0;
|
|
|
+- ard.ext_rssi = rs->rs_rssi_ext0;
|
|
|
++ ard.rssi = rs->rs_rssi_ctl[0];
|
|
|
++ ard.ext_rssi = rs->rs_rssi_ext[0];
|
|
|
+
|
|
|
+ /*
|
|
|
+ * hardware stores this as 8 bit signed value.
|
|
|
+--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
|
|
|
++++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
|
|
|
+@@ -1085,31 +1085,7 @@ static void ath9k_hw_4k_set_board_values
|
|
|
+
|
|
|
+ static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
|
|
|
+ {
|
|
|
+-#define EEP_MAP4K_SPURCHAN \
|
|
|
+- (ah->eeprom.map4k.modalHeader.spurChans[i].spurChan)
|
|
|
+- struct ath_common *common = ath9k_hw_common(ah);
|
|
|
+-
|
|
|
+- u16 spur_val = AR_NO_SPUR;
|
|
|
+-
|
|
|
+- ath_dbg(common, ANI, "Getting spur idx:%d is2Ghz:%d val:%x\n",
|
|
|
+- i, is2GHz, ah->config.spurchans[i][is2GHz]);
|
|
|
+-
|
|
|
+- switch (ah->config.spurmode) {
|
|
|
+- case SPUR_DISABLE:
|
|
|
+- break;
|
|
|
+- case SPUR_ENABLE_IOCTL:
|
|
|
+- spur_val = ah->config.spurchans[i][is2GHz];
|
|
|
+- ath_dbg(common, ANI, "Getting spur val from new loc. %d\n",
|
|
|
+- spur_val);
|
|
|
+- break;
|
|
|
+- case SPUR_ENABLE_EEPROM:
|
|
|
+- spur_val = EEP_MAP4K_SPURCHAN;
|
|
|
+- break;
|
|
|
+- }
|
|
|
+-
|
|
|
+- return spur_val;
|
|
|
+-
|
|
|
+-#undef EEP_MAP4K_SPURCHAN
|
|
|
++ return ah->eeprom.map4k.modalHeader.spurChans[i].spurChan;
|
|
|
+ }
|
|
|
+
|
|
|
+ const struct eeprom_ops eep_4k_ops = {
|
|
|
+--- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c
|
|
|
++++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
|
|
|
+@@ -1004,31 +1004,7 @@ static void ath9k_hw_ar9287_set_board_va
|
|
|
+ static u16 ath9k_hw_ar9287_get_spur_channel(struct ath_hw *ah,
|
|
|
+ u16 i, bool is2GHz)
|
|
|
+ {
|
|
|
+-#define EEP_MAP9287_SPURCHAN \
|
|
|
+- (ah->eeprom.map9287.modalHeader.spurChans[i].spurChan)
|
|
|
+-
|
|
|
+- struct ath_common *common = ath9k_hw_common(ah);
|
|
|
+- u16 spur_val = AR_NO_SPUR;
|
|
|
+-
|
|
|
+- ath_dbg(common, ANI, "Getting spur idx:%d is2Ghz:%d val:%x\n",
|
|
|
+- i, is2GHz, ah->config.spurchans[i][is2GHz]);
|
|
|
+-
|
|
|
+- switch (ah->config.spurmode) {
|
|
|
+- case SPUR_DISABLE:
|
|
|
+- break;
|
|
|
+- case SPUR_ENABLE_IOCTL:
|
|
|
+- spur_val = ah->config.spurchans[i][is2GHz];
|
|
|
+- ath_dbg(common, ANI, "Getting spur val from new loc. %d\n",
|
|
|
+- spur_val);
|
|
|
+- break;
|
|
|
+- case SPUR_ENABLE_EEPROM:
|
|
|
+- spur_val = EEP_MAP9287_SPURCHAN;
|
|
|
+- break;
|
|
|
+- }
|
|
|
+-
|
|
|
+- return spur_val;
|
|
|
+-
|
|
|
+-#undef EEP_MAP9287_SPURCHAN
|
|
|
++ return ah->eeprom.map9287.modalHeader.spurChans[i].spurChan;
|
|
|
+ }
|
|
|
+
|
|
|
+ const struct eeprom_ops eep_ar9287_ops = {
|
|
|
+--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
|
|
|
++++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
|
|
|
+@@ -1348,31 +1348,7 @@ static void ath9k_hw_def_set_txpower(str
|
|
|
+
|
|
|
+ static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
|
|
|
+ {
|
|
|
+-#define EEP_DEF_SPURCHAN \
|
|
|
+- (ah->eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan)
|
|
|
+- struct ath_common *common = ath9k_hw_common(ah);
|
|
|
+-
|
|
|
+- u16 spur_val = AR_NO_SPUR;
|
|
|
+-
|
|
|
+- ath_dbg(common, ANI, "Getting spur idx:%d is2Ghz:%d val:%x\n",
|
|
|
+- i, is2GHz, ah->config.spurchans[i][is2GHz]);
|
|
|
+-
|
|
|
+- switch (ah->config.spurmode) {
|
|
|
+- case SPUR_DISABLE:
|
|
|
+- break;
|
|
|
+- case SPUR_ENABLE_IOCTL:
|
|
|
+- spur_val = ah->config.spurchans[i][is2GHz];
|
|
|
+- ath_dbg(common, ANI, "Getting spur val from new loc. %d\n",
|
|
|
+- spur_val);
|
|
|
+- break;
|
|
|
+- case SPUR_ENABLE_EEPROM:
|
|
|
+- spur_val = EEP_DEF_SPURCHAN;
|
|
|
+- break;
|
|
|
+- }
|
|
|
+-
|
|
|
+- return spur_val;
|
|
|
+-
|
|
|
+-#undef EEP_DEF_SPURCHAN
|
|
|
++ return ah->eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan;
|
|
|
+ }
|
|
|
+
|
|
|
+ const struct eeprom_ops eep_def_ops = {
|
|
|
+--- a/drivers/net/wireless/ath/ath9k/gpio.c
|
|
|
++++ b/drivers/net/wireless/ath/ath9k/gpio.c
|
|
|
+@@ -157,36 +157,6 @@ static void ath_detect_bt_priority(struc
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+-static void ath9k_gen_timer_start(struct ath_hw *ah,
|
|
|
+- struct ath_gen_timer *timer,
|
|
|
+- u32 trig_timeout,
|
|
|
+- u32 timer_period)
|
|
|
+-{
|
|
|
+- ath9k_hw_gen_timer_start(ah, timer, trig_timeout, timer_period);
|
|
|
+-
|
|
|
+- if ((ah->imask & ATH9K_INT_GENTIMER) == 0) {
|
|
|
+- ath9k_hw_disable_interrupts(ah);
|
|
|
+- ah->imask |= ATH9K_INT_GENTIMER;
|
|
|
+- ath9k_hw_set_interrupts(ah);
|
|
|
+- ath9k_hw_enable_interrupts(ah);
|
|
|
+- }
|
|
|
+-}
|
|
|
+-
|
|
|
+-static void ath9k_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer)
|
|
|
+-{
|
|
|
+- struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;
|
|
|
+-
|
|
|
+- ath9k_hw_gen_timer_stop(ah, timer);
|
|
|
+-
|
|
|
+- /* if no timer is enabled, turn off interrupt mask */
|
|
|
+- if (timer_table->timer_mask.val == 0) {
|
|
|
+- ath9k_hw_disable_interrupts(ah);
|
|
|
+- ah->imask &= ~ATH9K_INT_GENTIMER;
|
|
|
+- ath9k_hw_set_interrupts(ah);
|
|
|
+- ath9k_hw_enable_interrupts(ah);
|
|
|
+- }
|
|
|
+-}
|
|
|
+-
|
|
|
+ static void ath_mci_ftp_adjust(struct ath_softc *sc)
|
|
|
+ {
|
|
|
+ struct ath_btcoex *btcoex = &sc->btcoex;
|
|
|
+@@ -257,19 +227,9 @@ static void ath_btcoex_period_timer(unsi
|
|
|
+
|
|
|
+ spin_unlock_bh(&btcoex->btcoex_lock);
|
|
|
+
|
|
|
+- /*
|
|
|
+- * btcoex_period is in msec while (btocex/btscan_)no_stomp are in usec,
|
|
|
+- * ensure that we properly convert btcoex_period to usec
|
|
|
+- * for any comparision with (btcoex/btscan_)no_stomp.
|
|
|
+- */
|
|
|
+- if (btcoex->btcoex_period * 1000 != btcoex->btcoex_no_stomp) {
|
|
|
+- if (btcoex->hw_timer_enabled)
|
|
|
+- ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer);
|
|
|
+-
|
|
|
+- ath9k_gen_timer_start(ah, btcoex->no_stomp_timer, timer_period,
|
|
|
+- timer_period * 10);
|
|
|
+- btcoex->hw_timer_enabled = true;
|
|
|
+- }
|
|
|
++ if (btcoex->btcoex_period != btcoex->btcoex_no_stomp)
|
|
|
++ mod_timer(&btcoex->no_stomp_timer,
|
|
|
++ jiffies + msecs_to_jiffies(timer_period));
|
|
|
+
|
|
|
+ ath9k_ps_restore(sc);
|
|
|
+
|
|
|
+@@ -282,7 +242,7 @@ skip_hw_wakeup:
|
|
|
+ * Generic tsf based hw timer which configures weight
|
|
|
+ * registers to time slice between wlan and bt traffic
|
|
|
+ */
|
|
|
+-static void ath_btcoex_no_stomp_timer(void *arg)
|
|
|
++static void ath_btcoex_no_stomp_timer(unsigned long arg)
|
|
|
+ {
|
|
|
+ struct ath_softc *sc = (struct ath_softc *)arg;
|
|
|
+ struct ath_hw *ah = sc->sc_ah;
|
|
|
+@@ -311,24 +271,18 @@ static int ath_init_btcoex_timer(struct
|
|
|
+ struct ath_btcoex *btcoex = &sc->btcoex;
|
|
|
+
|
|
|
+ btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD;
|
|
|
+- btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) * 1000 *
|
|
|
++ btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) *
|
|
|
+ btcoex->btcoex_period / 100;
|
|
|
+- btcoex->btscan_no_stomp = (100 - ATH_BTCOEX_BTSCAN_DUTY_CYCLE) * 1000 *
|
|
|
++ btcoex->btscan_no_stomp = (100 - ATH_BTCOEX_BTSCAN_DUTY_CYCLE) *
|
|
|
+ btcoex->btcoex_period / 100;
|
|
|
+
|
|
|
+ setup_timer(&btcoex->period_timer, ath_btcoex_period_timer,
|
|
|
+ (unsigned long) sc);
|
|
|
++ setup_timer(&btcoex->no_stomp_timer, ath_btcoex_no_stomp_timer,
|
|
|
++ (unsigned long) sc);
|
|
|
+
|
|
|
+ spin_lock_init(&btcoex->btcoex_lock);
|
|
|
+
|
|
|
+- btcoex->no_stomp_timer = ath_gen_timer_alloc(sc->sc_ah,
|
|
|
+- ath_btcoex_no_stomp_timer,
|
|
|
+- ath_btcoex_no_stomp_timer,
|
|
|
+- (void *) sc, AR_FIRST_NDP_TIMER);
|
|
|
+-
|
|
|
+- if (!btcoex->no_stomp_timer)
|
|
|
+- return -ENOMEM;
|
|
|
+-
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+@@ -343,10 +297,7 @@ void ath9k_btcoex_timer_resume(struct at
|
|
|
+ ath_dbg(ath9k_hw_common(ah), BTCOEX, "Starting btcoex timers\n");
|
|
|
+
|
|
|
+ /* make sure duty cycle timer is also stopped when resuming */
|
|
|
+- if (btcoex->hw_timer_enabled) {
|
|
|
+- ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer);
|
|
|
+- btcoex->hw_timer_enabled = false;
|
|
|
+- }
|
|
|
++ del_timer_sync(&btcoex->no_stomp_timer);
|
|
|
+
|
|
|
+ btcoex->bt_priority_cnt = 0;
|
|
|
+ btcoex->bt_priority_time = jiffies;
|
|
|
+@@ -363,24 +314,16 @@ void ath9k_btcoex_timer_resume(struct at
|
|
|
+ void ath9k_btcoex_timer_pause(struct ath_softc *sc)
|
|
|
+ {
|
|
|
+ struct ath_btcoex *btcoex = &sc->btcoex;
|
|
|
+- struct ath_hw *ah = sc->sc_ah;
|
|
|
+
|
|
|
+ del_timer_sync(&btcoex->period_timer);
|
|
|
+-
|
|
|
+- if (btcoex->hw_timer_enabled) {
|
|
|
+- ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer);
|
|
|
+- btcoex->hw_timer_enabled = false;
|
|
|
+- }
|
|
|
++ del_timer_sync(&btcoex->no_stomp_timer);
|
|
|
+ }
|
|
|
+
|
|
|
+ void ath9k_btcoex_stop_gen_timer(struct ath_softc *sc)
|
|
|
+ {
|
|
|
+ struct ath_btcoex *btcoex = &sc->btcoex;
|
|
|
+
|
|
|
+- if (btcoex->hw_timer_enabled) {
|
|
|
+- ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer);
|
|
|
+- btcoex->hw_timer_enabled = false;
|
|
|
+- }
|
|
|
++ del_timer_sync(&btcoex->no_stomp_timer);
|
|
|
+ }
|
|
|
+
|
|
|
+ u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen)
|
|
|
+@@ -400,12 +343,6 @@ u16 ath9k_btcoex_aggr_limit(struct ath_s
|
|
|
+
|
|
|
+ void ath9k_btcoex_handle_interrupt(struct ath_softc *sc, u32 status)
|
|
|
+ {
|
|
|
+- struct ath_hw *ah = sc->sc_ah;
|
|
|
+-
|
|
|
+- if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE)
|
|
|
+- if (status & ATH9K_INT_GENTIMER)
|
|
|
+- ath_gen_timer_isr(sc->sc_ah);
|
|
|
+-
|
|
|
+ if (status & ATH9K_INT_MCI)
|
|
|
+ ath_mci_intr(sc);
|
|
|
+ }
|
|
|
+@@ -447,10 +384,6 @@ void ath9k_deinit_btcoex(struct ath_soft
|
|
|
+ {
|
|
|
+ struct ath_hw *ah = sc->sc_ah;
|
|
|
+
|
|
|
+- if ((sc->btcoex.no_stomp_timer) &&
|
|
|
+- ath9k_hw_get_btcoex_scheme(sc->sc_ah) == ATH_BTCOEX_CFG_3WIRE)
|
|
|
+- ath_gen_timer_free(sc->sc_ah, sc->btcoex.no_stomp_timer);
|
|
|
+-
|
|
|
+ if (ath9k_hw_mci_is_enabled(ah))
|
|
|
+ ath_mci_cleanup(sc);
|
|
|
+ }
|
|
|
+--- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
|
|
|
++++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
|
|
|
+@@ -70,11 +70,11 @@ static void ath9k_htc_beacon_config_sta(
|
|
|
+ struct ath9k_beacon_state bs;
|
|
|
+ enum ath9k_int imask = 0;
|
|
|
+ int dtimperiod, dtimcount, sleepduration;
|
|
|
+- int cfpperiod, cfpcount, bmiss_timeout;
|
|
|
++ int bmiss_timeout;
|
|
|
+ u32 nexttbtt = 0, intval, tsftu;
|
|
|
+ __be32 htc_imask = 0;
|
|
|
+ u64 tsf;
|
|
|
+- int num_beacons, offset, dtim_dec_count, cfp_dec_count;
|
|
|
++ int num_beacons, offset, dtim_dec_count;
|
|
|
+ int ret __attribute__ ((unused));
|
|
|
+ u8 cmd_rsp;
|
|
|
+
|
|
|
+@@ -84,7 +84,7 @@ static void ath9k_htc_beacon_config_sta(
|
|
|
+ bmiss_timeout = (ATH_DEFAULT_BMISS_LIMIT * bss_conf->beacon_interval);
|
|
|
+
|
|
|
+ /*
|
|
|
+- * Setup dtim and cfp parameters according to
|
|
|
++ * Setup dtim parameters according to
|
|
|
+ * last beacon we received (which may be none).
|
|
|
+ */
|
|
|
+ dtimperiod = bss_conf->dtim_period;
|
|
|
+@@ -93,8 +93,6 @@ static void ath9k_htc_beacon_config_sta(
|
|
|
+ dtimcount = 1;
|
|
|
+ if (dtimcount >= dtimperiod) /* NB: sanity check */
|
|
|
+ dtimcount = 0;
|
|
|
+- cfpperiod = 1; /* NB: no PCF support yet */
|
|
|
+- cfpcount = 0;
|
|
|
+
|
|
|
+ sleepduration = intval;
|
|
|
+ if (sleepduration <= 0)
|
|
|
+@@ -102,7 +100,7 @@ static void ath9k_htc_beacon_config_sta(
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Pull nexttbtt forward to reflect the current
|
|
|
+- * TSF and calculate dtim+cfp state for the result.
|
|
|
++ * TSF and calculate dtim state for the result.
|
|
|
+ */
|
|
|
+ tsf = ath9k_hw_gettsf64(priv->ah);
|
|
|
+ tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE;
|
|
|
+@@ -115,26 +113,14 @@ static void ath9k_htc_beacon_config_sta(
|
|
|
+
|
|
|
+ /* DTIM Beacon every dtimperiod Beacon */
|
|
|
+ dtim_dec_count = num_beacons % dtimperiod;
|
|
|
+- /* CFP every cfpperiod DTIM Beacon */
|
|
|
+- cfp_dec_count = (num_beacons / dtimperiod) % cfpperiod;
|
|
|
+- if (dtim_dec_count)
|
|
|
+- cfp_dec_count++;
|
|
|
+-
|
|
|
+ dtimcount -= dtim_dec_count;
|
|
|
+ if (dtimcount < 0)
|
|
|
+ dtimcount += dtimperiod;
|
|
|
+
|
|
|
+- cfpcount -= cfp_dec_count;
|
|
|
+- if (cfpcount < 0)
|
|
|
+- cfpcount += cfpperiod;
|
|
|
+-
|
|
|
+- bs.bs_intval = intval;
|
|
|
+- bs.bs_nexttbtt = nexttbtt;
|
|
|
+- bs.bs_dtimperiod = dtimperiod*intval;
|
|
|
+- bs.bs_nextdtim = bs.bs_nexttbtt + dtimcount*intval;
|
|
|
+- bs.bs_cfpperiod = cfpperiod*bs.bs_dtimperiod;
|
|
|
+- bs.bs_cfpnext = bs.bs_nextdtim + cfpcount*bs.bs_dtimperiod;
|
|
|
+- bs.bs_cfpmaxduration = 0;
|
|
|
++ bs.bs_intval = TU_TO_USEC(intval);
|
|
|
++ bs.bs_nexttbtt = TU_TO_USEC(nexttbtt);
|
|
|
++ bs.bs_dtimperiod = dtimperiod * bs.bs_intval;
|
|
|
++ bs.bs_nextdtim = bs.bs_nexttbtt + dtimcount * bs.bs_intval;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Calculate the number of consecutive beacons to miss* before taking
|
|
|
+@@ -161,7 +147,8 @@ static void ath9k_htc_beacon_config_sta(
|
|
|
+ * XXX fixed at 100ms
|
|
|
+ */
|
|
|
+
|
|
|
+- bs.bs_sleepduration = roundup(IEEE80211_MS_TO_TU(100), sleepduration);
|
|
|
++ bs.bs_sleepduration = TU_TO_USEC(roundup(IEEE80211_MS_TO_TU(100),
|
|
|
++ sleepduration));
|
|
|
+ if (bs.bs_sleepduration > bs.bs_dtimperiod)
|
|
|
+ bs.bs_sleepduration = bs.bs_dtimperiod;
|
|
|
+
|
|
|
+@@ -170,10 +157,8 @@ static void ath9k_htc_beacon_config_sta(
|
|
|
+
|
|
|
+ ath_dbg(common, CONFIG, "intval: %u tsf: %llu tsftu: %u\n",
|
|
|
+ intval, tsf, tsftu);
|
|
|
+- ath_dbg(common, CONFIG,
|
|
|
+- "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n",
|
|
|
+- bs.bs_bmissthreshold, bs.bs_sleepduration,
|
|
|
+- bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext);
|
|
|
++ ath_dbg(common, CONFIG, "bmiss: %u sleep: %u\n",
|
|
|
++ bs.bs_bmissthreshold, bs.bs_sleepduration);
|
|
|
+
|
|
|
+ /* Set the computed STA beacon timers */
|
|
|
+
|
|
|
+--- a/drivers/net/wireless/ath/ath9k/mac.c
|
|
|
++++ b/drivers/net/wireless/ath/ath9k/mac.c
|
|
|
+@@ -481,8 +481,7 @@ bool ath9k_hw_resettxqueue(struct ath_hw
|
|
|
+ | AR_Q_MISC_CBR_INCR_DIS0);
|
|
|
+ value = (qi->tqi_readyTime -
|
|
|
+ (ah->config.sw_beacon_response_time -
|
|
|
+- ah->config.dma_beacon_response_time) -
|
|
|
+- ah->config.additional_swba_backoff) * 1024;
|
|
|
++ ah->config.dma_beacon_response_time)) * 1024;
|
|
|
+ REG_WRITE(ah, AR_QRDYTIMECFG(q),
|
|
|
+ value | AR_Q_RDYTIMECFG_EN);
|
|
|
+ REG_SET_BIT(ah, AR_DMISC(q),
|
|
|
+@@ -550,25 +549,25 @@ int ath9k_hw_rxprocdesc(struct ath_hw *a
|
|
|
+
|
|
|
+ if (ads.ds_rxstatus8 & AR_PostDelimCRCErr) {
|
|
|
+ rs->rs_rssi = ATH9K_RSSI_BAD;
|
|
|
+- rs->rs_rssi_ctl0 = ATH9K_RSSI_BAD;
|
|
|
+- rs->rs_rssi_ctl1 = ATH9K_RSSI_BAD;
|
|
|
+- rs->rs_rssi_ctl2 = ATH9K_RSSI_BAD;
|
|
|
+- rs->rs_rssi_ext0 = ATH9K_RSSI_BAD;
|
|
|
+- rs->rs_rssi_ext1 = ATH9K_RSSI_BAD;
|
|
|
+- rs->rs_rssi_ext2 = ATH9K_RSSI_BAD;
|
|
|
++ rs->rs_rssi_ctl[0] = ATH9K_RSSI_BAD;
|
|
|
++ rs->rs_rssi_ctl[1] = ATH9K_RSSI_BAD;
|
|
|
++ rs->rs_rssi_ctl[2] = ATH9K_RSSI_BAD;
|
|
|
++ rs->rs_rssi_ext[0] = ATH9K_RSSI_BAD;
|
|
|
++ rs->rs_rssi_ext[1] = ATH9K_RSSI_BAD;
|
|
|
++ rs->rs_rssi_ext[2] = ATH9K_RSSI_BAD;
|
|
|
+ } else {
|
|
|
+ rs->rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
|
|
|
+- rs->rs_rssi_ctl0 = MS(ads.ds_rxstatus0,
|
|
|
++ rs->rs_rssi_ctl[0] = MS(ads.ds_rxstatus0,
|
|
|
+ AR_RxRSSIAnt00);
|
|
|
+- rs->rs_rssi_ctl1 = MS(ads.ds_rxstatus0,
|
|
|
++ rs->rs_rssi_ctl[1] = MS(ads.ds_rxstatus0,
|
|
|
+ AR_RxRSSIAnt01);
|
|
|
+- rs->rs_rssi_ctl2 = MS(ads.ds_rxstatus0,
|
|
|
++ rs->rs_rssi_ctl[2] = MS(ads.ds_rxstatus0,
|
|
|
+ AR_RxRSSIAnt02);
|
|
|
+- rs->rs_rssi_ext0 = MS(ads.ds_rxstatus4,
|
|
|
++ rs->rs_rssi_ext[0] = MS(ads.ds_rxstatus4,
|
|
|
+ AR_RxRSSIAnt10);
|
|
|
+- rs->rs_rssi_ext1 = MS(ads.ds_rxstatus4,
|
|
|
++ rs->rs_rssi_ext[1] = MS(ads.ds_rxstatus4,
|
|
|
+ AR_RxRSSIAnt11);
|
|
|
+- rs->rs_rssi_ext2 = MS(ads.ds_rxstatus4,
|
|
|
++ rs->rs_rssi_ext[2] = MS(ads.ds_rxstatus4,
|
|
|
+ AR_RxRSSIAnt12);
|
|
|
+ }
|
|
|
+ if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
|
|
|
+--- a/drivers/net/wireless/ath/ath9k/mac.h
|
|
|
++++ b/drivers/net/wireless/ath/ath9k/mac.h
|
|
|
+@@ -133,12 +133,8 @@ struct ath_rx_status {
|
|
|
+ u8 rs_rate;
|
|
|
+ u8 rs_antenna;
|
|
|
+ u8 rs_more;
|
|
|
+- int8_t rs_rssi_ctl0;
|
|
|
+- int8_t rs_rssi_ctl1;
|
|
|
+- int8_t rs_rssi_ctl2;
|
|
|
+- int8_t rs_rssi_ext0;
|
|
|
+- int8_t rs_rssi_ext1;
|
|
|
+- int8_t rs_rssi_ext2;
|
|
|
++ int8_t rs_rssi_ctl[3];
|
|
|
++ int8_t rs_rssi_ext[3];
|
|
|
+ u8 rs_isaggr;
|
|
|
+ u8 rs_firstaggr;
|
|
|
+ u8 rs_moreaggr;
|
|
|
+--- a/drivers/net/wireless/ath/ath9k/mci.c
|
|
|
++++ b/drivers/net/wireless/ath/ath9k/mci.c
|
|
|
+@@ -200,7 +200,7 @@ skip_tuning:
|
|
|
+ if (btcoex->duty_cycle > ATH_MCI_MAX_DUTY_CYCLE)
|
|
|
+ btcoex->duty_cycle = ATH_MCI_MAX_DUTY_CYCLE;
|
|
|
+
|
|
|
+- btcoex->btcoex_no_stomp = btcoex->btcoex_period * 1000 *
|
|
|
++ btcoex->btcoex_no_stomp = btcoex->btcoex_period *
|
|
|
+ (100 - btcoex->duty_cycle) / 100;
|
|
|
+
|
|
|
+ ath9k_hw_btcoex_enable(sc->sc_ah);
|
|
|
+--- a/drivers/net/wireless/ath/ath9k/recv.c
|
|
|
++++ b/drivers/net/wireless/ath/ath9k/recv.c
|
|
|
+@@ -906,6 +906,7 @@ static void ath9k_process_rssi(struct at
|
|
|
+ struct ath_hw *ah = common->ah;
|
|
|
+ int last_rssi;
|
|
|
+ int rssi = rx_stats->rs_rssi;
|
|
|
++ int i, j;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * RSSI is not available for subframes in an A-MPDU.
|
|
|
+@@ -924,6 +925,20 @@ static void ath9k_process_rssi(struct at
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
++ for (i = 0, j = 0; i < ARRAY_SIZE(rx_stats->rs_rssi_ctl); i++) {
|
|
|
++ s8 rssi;
|
|
|
++
|
|
|
++ if (!(ah->rxchainmask & BIT(i)))
|
|
|
++ continue;
|
|
|
++
|
|
|
++ rssi = rx_stats->rs_rssi_ctl[i];
|
|
|
++ if (rssi != ATH9K_RSSI_BAD) {
|
|
|
++ rxs->chains |= BIT(j);
|
|
|
++ rxs->chain_signal[j] = ah->noise + rssi;
|
|
|
++ }
|
|
|
++ j++;
|
|
|
++ }
|
|
|
++
|
|
|
+ /*
|
|
|
+ * Update Beacon RSSI, this is used by ANI.
|
|
|
+ */
|
|
|
+@@ -1073,14 +1088,14 @@ static int ath_process_fft(struct ath_so
|
|
|
+ fft_sample_40.channel_type = chan_type;
|
|
|
+
|
|
|
+ if (chan_type == NL80211_CHAN_HT40PLUS) {
|
|
|
+- lower_rssi = fix_rssi_inv_only(rs->rs_rssi_ctl0);
|
|
|
+- upper_rssi = fix_rssi_inv_only(rs->rs_rssi_ext0);
|
|
|
++ lower_rssi = fix_rssi_inv_only(rs->rs_rssi_ctl[0]);
|
|
|
++ upper_rssi = fix_rssi_inv_only(rs->rs_rssi_ext[0]);
|
|
|
+
|
|
|
+ fft_sample_40.lower_noise = ah->noise;
|
|
|
+ fft_sample_40.upper_noise = ext_nf;
|
|
|
+ } else {
|
|
|
+- lower_rssi = fix_rssi_inv_only(rs->rs_rssi_ext0);
|
|
|
+- upper_rssi = fix_rssi_inv_only(rs->rs_rssi_ctl0);
|
|
|
++ lower_rssi = fix_rssi_inv_only(rs->rs_rssi_ext[0]);
|
|
|
++ upper_rssi = fix_rssi_inv_only(rs->rs_rssi_ctl[0]);
|
|
|
+
|
|
|
+ fft_sample_40.lower_noise = ext_nf;
|
|
|
+ fft_sample_40.upper_noise = ah->noise;
|
|
|
+@@ -1116,7 +1131,7 @@ static int ath_process_fft(struct ath_so
|
|
|
+ fft_sample_20.tlv.length = __cpu_to_be16(length);
|
|
|
+ fft_sample_20.freq = __cpu_to_be16(freq);
|
|
|
+
|
|
|
+- fft_sample_20.rssi = fix_rssi_inv_only(rs->rs_rssi_ctl0);
|
|
|
++ fft_sample_20.rssi = fix_rssi_inv_only(rs->rs_rssi_ctl[0]);
|
|
|
+ fft_sample_20.noise = ah->noise;
|
|
|
+
|
|
|
+ mag_info = ((struct ath_ht20_mag_info *)radar_info) - 1;
|