+--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
++++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+@@ -23,10 +23,11 @@
+ #define MAX_MEASUREMENT MAX_IQCAL_MEASUREMENT
+ #define MAX_MAG_DELTA 11
+ #define MAX_PHS_DELTA 10
++#define MAXIQCAL 3
+
+ struct coeff {
+- int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT];
+- int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT];
++ int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MAXIQCAL];
++ int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MAXIQCAL];
+ int iqc_coeff[2];
+ };
+
+@@ -800,7 +801,7 @@ static bool ar9003_hw_calc_iq_corr(struc
+ if (q_q_coff > 63)
+ q_q_coff = 63;
+
+- iqc_coeff[0] = (q_q_coff * 128) + q_i_coff;
++ iqc_coeff[0] = (q_q_coff * 128) + (0x7f & q_i_coff);
+
+ ath_dbg(common, CALIBRATE, "tx chain %d: iq corr coeff=%x\n",
+ chain_idx, iqc_coeff[0]);
+@@ -831,7 +832,7 @@ static bool ar9003_hw_calc_iq_corr(struc
+ if (q_q_coff > 63)
+ q_q_coff = 63;
+
+- iqc_coeff[1] = (q_q_coff * 128) + q_i_coff;
++ iqc_coeff[1] = (q_q_coff * 128) + (0x7f & q_i_coff);
+
+ ath_dbg(common, CALIBRATE, "rx chain %d: iq corr coeff=%x\n",
+ chain_idx, iqc_coeff[1]);
+@@ -839,7 +840,8 @@ static bool ar9003_hw_calc_iq_corr(struc
+ return true;
+ }
+
+-static void ar9003_hw_detect_outlier(int *mp_coeff, int nmeasurement,
++static void ar9003_hw_detect_outlier(int mp_coeff[][MAXIQCAL],
++ int nmeasurement,
+ int max_delta)
+ {
+ int mp_max = -64, max_idx = 0;
+@@ -848,20 +850,20 @@ static void ar9003_hw_detect_outlier(int
+
+ /* find min/max mismatch across all calibrated gains */
+ for (i = 0; i < nmeasurement; i++) {
+- if (mp_coeff[i] > mp_max) {
+- mp_max = mp_coeff[i];
++ if (mp_coeff[i][0] > mp_max) {
++ mp_max = mp_coeff[i][0];
+ max_idx = i;
+- } else if (mp_coeff[i] < mp_min) {
+- mp_min = mp_coeff[i];
++ } else if (mp_coeff[i][0] < mp_min) {
++ mp_min = mp_coeff[i][0];
+ min_idx = i;
+ }
+ }
+
+ /* find average (exclude max abs value) */
+ for (i = 0; i < nmeasurement; i++) {
+- if ((abs(mp_coeff[i]) < abs(mp_max)) ||
+- (abs(mp_coeff[i]) < abs(mp_min))) {
+- mp_avg += mp_coeff[i];
++ if ((abs(mp_coeff[i][0]) < abs(mp_max)) ||
++ (abs(mp_coeff[i][0]) < abs(mp_min))) {
++ mp_avg += mp_coeff[i][0];
+ mp_count++;
+ }
+ }
+@@ -873,7 +875,7 @@ static void ar9003_hw_detect_outlier(int
+ if (mp_count)
+ mp_avg /= mp_count;
+ else
+- mp_avg = mp_coeff[nmeasurement - 1];
++ mp_avg = mp_coeff[nmeasurement - 1][0];
+
+ /* detect outlier */
+ if (abs(mp_max - mp_min) > max_delta) {
+@@ -882,15 +884,16 @@ static void ar9003_hw_detect_outlier(int
+ else
+ outlier_idx = min_idx;
+
+- mp_coeff[outlier_idx] = mp_avg;
++ mp_coeff[outlier_idx][0] = mp_avg;
+ }
+ }
+
+-static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah,
+- struct coeff *coeff,
+- bool is_reusable)
++static void ar9003_hw_tx_iq_cal_outlier_detection(struct ath_hw *ah,
++ struct coeff *coeff,
++ bool is_reusable)
+ {
+ int i, im, nmeasurement;
++ int magnitude, phase;
+ u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS];
+ struct ath9k_hw_cal_data *caldata = ah->caldata;
+
+@@ -920,21 +923,30 @@ static void ar9003_hw_tx_iqcal_load_avg_
+ if (nmeasurement > MAX_MEASUREMENT)
+ nmeasurement = MAX_MEASUREMENT;
+
+- /* detect outlier only if nmeasurement > 1 */
+- if (nmeasurement > 1) {
+- /* Detect magnitude outlier */
+- ar9003_hw_detect_outlier(coeff->mag_coeff[i],
+- nmeasurement, MAX_MAG_DELTA);
+-
+- /* Detect phase outlier */
+- ar9003_hw_detect_outlier(coeff->phs_coeff[i],
+- nmeasurement, MAX_PHS_DELTA);
++ /*
++ * Skip normal outlier detection for AR9550.
++ */
++ if (!AR_SREV_9550(ah)) {
++ /* detect outlier only if nmeasurement > 1 */
++ if (nmeasurement > 1) {
++ /* Detect magnitude outlier */
++ ar9003_hw_detect_outlier(coeff->mag_coeff[i],
++ nmeasurement,
++ MAX_MAG_DELTA);
++
++ /* Detect phase outlier */
++ ar9003_hw_detect_outlier(coeff->phs_coeff[i],
++ nmeasurement,
++ MAX_PHS_DELTA);
++ }
+ }
+
+ for (im = 0; im < nmeasurement; im++) {
++ magnitude = coeff->mag_coeff[i][im][0];
++ phase = coeff->phs_coeff[i][im][0];
+
+- coeff->iqc_coeff[0] = (coeff->mag_coeff[i][im] & 0x7f) |
+- ((coeff->phs_coeff[i][im] & 0x7f) << 7);
++ coeff->iqc_coeff[0] =
++ (phase & 0x7f) | ((magnitude & 0x7f) << 7);
+
+ if ((im % 2) == 0)
+ REG_RMW_FIELD(ah, tx_corr_coeff[im][i],
+@@ -991,7 +1003,63 @@ static bool ar9003_hw_tx_iq_cal_run(stru
+ return true;
+ }
+
+-static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah, bool is_reusable)
++static void __ar955x_tx_iq_cal_sort(struct ath_hw *ah,
++ struct coeff *coeff,
++ int i, int nmeasurement)
++{
++ struct ath_common *common = ath9k_hw_common(ah);
++ int im, ix, iy, temp;
++
++ for (im = 0; im < nmeasurement; im++) {
++ for (ix = 0; ix < MAXIQCAL - 1; ix++) {
++ for (iy = ix + 1; iy <= MAXIQCAL - 1; iy++) {
++ if (coeff->mag_coeff[i][im][iy] <
++ coeff->mag_coeff[i][im][ix]) {
++ temp = coeff->mag_coeff[i][im][ix];
++ coeff->mag_coeff[i][im][ix] =
++ coeff->mag_coeff[i][im][iy];
++ coeff->mag_coeff[i][im][iy] = temp;
++ }
++ if (coeff->phs_coeff[i][im][iy] <
++ coeff->phs_coeff[i][im][ix]) {
++ temp = coeff->phs_coeff[i][im][ix];
++ coeff->phs_coeff[i][im][ix] =
++ coeff->phs_coeff[i][im][iy];
++ coeff->phs_coeff[i][im][iy] = temp;
++ }
++ }
++ }
++ coeff->mag_coeff[i][im][0] = coeff->mag_coeff[i][im][MAXIQCAL / 2];
++ coeff->phs_coeff[i][im][0] = coeff->phs_coeff[i][im][MAXIQCAL / 2];
++
++ ath_dbg(common, CALIBRATE,
++ "IQCAL: Median [ch%d][gain%d]: mag = %d phase = %d\n",
++ i, im,
++ coeff->mag_coeff[i][im][0],
++ coeff->phs_coeff[i][im][0]);
++ }
++}
++
++static bool ar955x_tx_iq_cal_median(struct ath_hw *ah,
++ struct coeff *coeff,
++ int iqcal_idx,
++ int nmeasurement)
++{
++ int i;
++
++ if ((iqcal_idx + 1) != MAXIQCAL)
++ return false;
++
++ for (i = 0; i < AR9300_MAX_CHAINS; i++) {
++ __ar955x_tx_iq_cal_sort(ah, coeff, i, nmeasurement);
++ }
++
++ return true;
++}
++
++static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah,
++ int iqcal_idx,
++ bool is_reusable)
+ {
+ struct ath_common *common = ath9k_hw_common(ah);
+ const u32 txiqcal_status[AR9300_MAX_CHAINS] = {
+@@ -1004,10 +1072,11 @@ static void ar9003_hw_tx_iq_cal_post_pro
+ AR_PHY_CHAN_INFO_TAB_1,
+ AR_PHY_CHAN_INFO_TAB_2,
+ };
+- struct coeff coeff;
++ static struct coeff coeff;
+ s32 iq_res[6];
+ int i, im, j;
+- int nmeasurement;
++ int nmeasurement = 0;
++ bool outlier_detect = true;
+
+ for (i = 0; i < AR9300_MAX_CHAINS; i++) {
+ if (!(ah->txchainmask & (1 << i)))
+@@ -1065,17 +1134,23 @@ static void ar9003_hw_tx_iq_cal_post_pro
+ goto tx_iqcal_fail;
+ }
+
+- coeff.mag_coeff[i][im] = coeff.iqc_coeff[0] & 0x7f;
+- coeff.phs_coeff[i][im] =
++ coeff.phs_coeff[i][im][iqcal_idx] =
++ coeff.iqc_coeff[0] & 0x7f;
++ coeff.mag_coeff[i][im][iqcal_idx] =
+ (coeff.iqc_coeff[0] >> 7) & 0x7f;
+
+- if (coeff.mag_coeff[i][im] > 63)
+- coeff.mag_coeff[i][im] -= 128;
+- if (coeff.phs_coeff[i][im] > 63)
+- coeff.phs_coeff[i][im] -= 128;
++ if (coeff.mag_coeff[i][im][iqcal_idx] > 63)
++ coeff.mag_coeff[i][im][iqcal_idx] -= 128;
++ if (coeff.phs_coeff[i][im][iqcal_idx] > 63)
++ coeff.phs_coeff[i][im][iqcal_idx] -= 128;
+ }
+ }
+- ar9003_hw_tx_iqcal_load_avg_2_passes(ah, &coeff, is_reusable);
++
++ if (AR_SREV_9550(ah))
++ outlier_detect = ar955x_tx_iq_cal_median(ah, &coeff,
++ iqcal_idx, nmeasurement);
++ if (outlier_detect)
++ ar9003_hw_tx_iq_cal_outlier_detection(ah, &coeff, is_reusable);
+
+ return;
+
+@@ -1409,7 +1484,7 @@ skip_tx_iqcal:
+ }
+
+ if (txiqcal_done)
+- ar9003_hw_tx_iq_cal_post_proc(ah, is_reusable);
++ ar9003_hw_tx_iq_cal_post_proc(ah, 0, is_reusable);
+ else if (caldata && test_bit(TXIQCAL_DONE, &caldata->cal_flags))
+ ar9003_hw_tx_iq_cal_reload(ah);
+
+@@ -1455,14 +1530,38 @@ skip_tx_iqcal:
+ return true;
+ }
+
++static bool do_ar9003_agc_cal(struct ath_hw *ah)
++{
++ struct ath_common *common = ath9k_hw_common(ah);
++ bool status;
++
++ REG_WRITE(ah, AR_PHY_AGC_CONTROL,
++ REG_READ(ah, AR_PHY_AGC_CONTROL) |
++ AR_PHY_AGC_CONTROL_CAL);
++
++ status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
++ AR_PHY_AGC_CONTROL_CAL,
++ 0, AH_WAIT_TIMEOUT);
++ if (!status) {
++ ath_dbg(common, CALIBRATE,
++ "offset calibration failed to complete in %d ms,"
++ "noisy environment?\n",
++ AH_WAIT_TIMEOUT / 1000);
++ return false;
++ }
++
++ return true;
++}
++
+ static bool ar9003_hw_init_cal_soc(struct ath_hw *ah,
+ struct ath9k_channel *chan)
+ {
+ struct ath_common *common = ath9k_hw_common(ah);
+ struct ath9k_hw_cal_data *caldata = ah->caldata;
+ bool txiqcal_done = false;
+- bool is_reusable = true, status = true;
++ bool status = true;
+ bool run_agc_cal = false, sep_iq_cal = false;
++ int i = 0;
+
+ /* Use chip chainmask only for calibration */
+ ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask);
+@@ -1485,7 +1584,12 @@ static bool ar9003_hw_init_cal_soc(struc
+ * AGC calibration. Specifically, AR9550 in SoC chips.
+ */
+ if (ah->enabled_cals & TX_IQ_ON_AGC_CAL) {
+- txiqcal_done = true;
++ if (REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_0,
++ AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL)) {
++ txiqcal_done = true;
++ } else {
++ txiqcal_done = false;
++ }
+ run_agc_cal = true;
+ } else {
+ sep_iq_cal = true;
+@@ -1512,27 +1616,37 @@ skip_tx_iqcal:
+ if (AR_SREV_9330_11(ah))
+ ar9003_hw_manual_peak_cal(ah, 0, IS_CHAN_2GHZ(chan));
+
+- /* 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 */
+- status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
+- AR_PHY_AGC_CONTROL_CAL,
+- 0, AH_WAIT_TIMEOUT);
+- }
++ /*
++ * For non-AR9550 chips, we just trigger AGC calibration
++ * in the HW, poll for completion and then process
++ * the results.
++ *
++ * For AR955x, we run it multiple times and use
++ * median IQ correction.
++ */
++ if (!AR_SREV_9550(ah)) {
++ status = do_ar9003_agc_cal(ah);
++ if (!status)
++ return false;
+
+- if (!status) {
+- ath_dbg(common, CALIBRATE,
+- "offset calibration failed to complete in %d ms; noisy environment?\n",
+- AH_WAIT_TIMEOUT / 1000);
+- return false;
++ if (txiqcal_done)
++ ar9003_hw_tx_iq_cal_post_proc(ah, 0, false);
++ } else {
++ if (!txiqcal_done) {
++ status = do_ar9003_agc_cal(ah);
++ if (!status)
++ return false;
++ } else {
++ for (i = 0; i < MAXIQCAL; i++) {
++ status = do_ar9003_agc_cal(ah);
++ if (!status)
++ return false;
++ ar9003_hw_tx_iq_cal_post_proc(ah, i, false);
++ }
++ }
++ }
+ }
+
+- if (txiqcal_done)
+- ar9003_hw_tx_iq_cal_post_proc(ah, is_reusable);
+-
+ /* Revert chainmask to runtime parameters */
+ ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
+
+--- a/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h
++++ b/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h
+@@ -15,6 +15,8 @@
+ #ifndef RTL8187_H
+ #define RTL8187_H
+
++#include <linux/cache.h>
++
+ #include "rtl818x.h"
+ #include "leds.h"
+
+@@ -139,7 +141,10 @@ struct rtl8187_priv {
+ u8 aifsn[4];
+ u8 rfkill_mask;
+ struct {
+- __le64 buf;
++ union {
++ __le64 buf;
++ u8 dummy1[L1_CACHE_BYTES];
++ } ____cacheline_aligned;
+ struct sk_buff_head queue;
+ } b_tx_status; /* This queue is used by both -b and non-b devices */
+ struct mutex io_mutex;
+@@ -147,7 +152,8 @@ struct rtl8187_priv {
+ u8 bits8;
+ __le16 bits16;
+ __le32 bits32;
+- } *io_dmabuf;
++ u8 dummy2[L1_CACHE_BYTES];
++ } *io_dmabuf ____cacheline_aligned;
+ bool rfkill_off;
+ u16 seqno;
+ };
+--- a/net/mac80211/wme.c
++++ b/net/mac80211/wme.c
+@@ -154,6 +154,11 @@ u16 ieee80211_select_queue(struct ieee80
+ return IEEE80211_AC_BE;
+ }
+
++ if (skb->protocol == sdata->control_port_protocol) {
++ skb->priority = 7;
++ return ieee80211_downgrade_queue(sdata, skb);
++ }
++
+ /* use the data classifier to determine what 802.1d tag the
+ * data frame has */
+ rcu_read_lock();
+--- a/drivers/net/wireless/ath/ath9k/xmit.c
++++ b/drivers/net/wireless/ath/ath9k/xmit.c
+@@ -1444,14 +1444,16 @@ void ath_tx_aggr_sleep(struct ieee80211_
+ for (tidno = 0, tid = &an->tid[tidno];
+ tidno < IEEE80211_NUM_TIDS; tidno++, tid++) {
+
+- if (!tid->sched)
+- continue;
+-
+ ac = tid->ac;
+ txq = ac->txq;
+
+ ath_txq_lock(sc, txq);
+
++ if (!tid->sched) {
++ ath_txq_unlock(sc, txq);
++ continue;
++ }
++
+ buffered = ath_tid_has_buffered(tid);
+
+ tid->sched = false;
+@@ -1696,7 +1698,7 @@ int ath_cabq_update(struct ath_softc *sc
+
+ ath9k_hw_get_txq_props(sc->sc_ah, qnum, &qi);
+
+- qi.tqi_readyTime = (cur_conf->beacon_interval *
++ qi.tqi_readyTime = (TU_TO_USEC(cur_conf->beacon_interval) *
+ ATH_CABQ_READY_TIME) / 100;
+ ath_txq_update(sc, qnum, &qi);
+
+@@ -2184,14 +2186,15 @@ int ath_tx_start(struct ieee80211_hw *hw
+ txq->stopped = true;
+ }
+
++ if (txctl->an)
++ tid = ath_get_skb_tid(sc, txctl->an, skb);
++
+ if (info->flags & IEEE80211_TX_CTL_PS_RESPONSE) {
+ ath_txq_unlock(sc, txq);
+ txq = sc->tx.uapsdq;
+ ath_txq_lock(sc, txq);
+ } else if (txctl->an &&
+ ieee80211_is_data_present(hdr->frame_control)) {
+- tid = ath_get_skb_tid(sc, txctl->an, skb);
+-
+ WARN_ON(tid->ac->txq != txctl->txq);
+
+ if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT)
+--- a/drivers/net/wireless/ath/ath9k/init.c
++++ b/drivers/net/wireless/ath/ath9k/init.c
+@@ -943,6 +943,7 @@ static void ath9k_set_hw_capab(struct at
+ hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
+ hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_5_10_MHZ;
+ hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
++ hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
+
+ hw->queues = 4;
+ hw->max_rates = 4;
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -1700,14 +1700,8 @@ void ieee80211_stop_queue_by_reason(stru
+ void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue);
+ void ieee80211_add_pending_skb(struct ieee80211_local *local,
+ struct sk_buff *skb);
+-void ieee80211_add_pending_skbs_fn(struct ieee80211_local *local,
+- struct sk_buff_head *skbs,
+- void (*fn)(void *data), void *data);
+-static inline void ieee80211_add_pending_skbs(struct ieee80211_local *local,
+- struct sk_buff_head *skbs)
+-{
+- ieee80211_add_pending_skbs_fn(local, skbs, NULL, NULL);
+-}
++void ieee80211_add_pending_skbs(struct ieee80211_local *local,
++ struct sk_buff_head *skbs);
+ void ieee80211_flush_queues(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata);
+
+--- a/net/mac80211/sta_info.c
++++ b/net/mac80211/sta_info.c
+@@ -91,7 +91,7 @@ static int sta_info_hash_del(struct ieee
+ return -ENOENT;
+ }
+
+-static void cleanup_single_sta(struct sta_info *sta)
++static void __cleanup_single_sta(struct sta_info *sta)
+ {
+ int ac, i;
+ struct tid_ampdu_tx *tid_tx;
+@@ -99,7 +99,8 @@ static void cleanup_single_sta(struct st
+ struct ieee80211_local *local = sdata->local;
+ struct ps_data *ps;
+
+- if (test_sta_flag(sta, WLAN_STA_PS_STA)) {
++ if (test_sta_flag(sta, WLAN_STA_PS_STA) ||
++ test_sta_flag(sta, WLAN_STA_PS_DRIVER)) {
+ if (sta->sdata->vif.type == NL80211_IFTYPE_AP ||
+ sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
+ ps = &sdata->bss->ps;
+@@ -109,6 +110,7 @@ static void cleanup_single_sta(struct st
+ return;
+
+ clear_sta_flag(sta, WLAN_STA_PS_STA);
++ clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
+
+ atomic_dec(&ps->num_sta_ps);
+ sta_info_recalc_tim(sta);
+@@ -139,7 +141,14 @@ static void cleanup_single_sta(struct st
+ ieee80211_purge_tx_queue(&local->hw, &tid_tx->pending);
+ kfree(tid_tx);
+ }
++}
+
++static void cleanup_single_sta(struct sta_info *sta)
++{
++ struct ieee80211_sub_if_data *sdata = sta->sdata;
++ struct ieee80211_local *local = sdata->local;
++
++ __cleanup_single_sta(sta);
+ sta_info_free(local, sta);
+ }
+
+@@ -330,6 +339,7 @@ struct sta_info *sta_info_alloc(struct i
+ rcu_read_unlock();
+
+ spin_lock_init(&sta->lock);
++ spin_lock_init(&sta->ps_lock);
+ INIT_WORK(&sta->drv_unblock_wk, sta_unblock);
+ INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work);
+ mutex_init(&sta->ampdu_mlme.mtx);
+@@ -487,21 +497,26 @@ static int sta_info_insert_finish(struct
+ goto out_err;
+ }
+
+- /* notify driver */
+- err = sta_info_insert_drv_state(local, sdata, sta);
+- if (err)
+- goto out_err;
+-
+ local->num_sta++;
+ local->sta_generation++;
+ smp_mb();
+
++ /* simplify things and don't accept BA sessions yet */
++ set_sta_flag(sta, WLAN_STA_BLOCK_BA);
++
+ /* make the station visible */
+ sta_info_hash_add(local, sta);
+
+ list_add_rcu(&sta->list, &local->sta_list);
+
++ /* notify driver */
++ err = sta_info_insert_drv_state(local, sdata, sta);
++ if (err)
++ goto out_remove;
++
+ set_sta_flag(sta, WLAN_STA_INSERTED);
++ /* accept BA sessions now */
++ clear_sta_flag(sta, WLAN_STA_BLOCK_BA);
+
+ ieee80211_recalc_min_chandef(sdata);
+ ieee80211_sta_debugfs_add(sta);
+@@ -522,6 +537,12 @@ static int sta_info_insert_finish(struct
+ mesh_accept_plinks_update(sdata);
+
+ return 0;
++ out_remove:
++ sta_info_hash_del(local, sta);
++ list_del_rcu(&sta->list);
++ local->num_sta--;
++ synchronize_net();
++ __cleanup_single_sta(sta);
+ out_err:
+ mutex_unlock(&local->sta_mtx);
+ rcu_read_lock();
+@@ -1071,10 +1092,14 @@ struct ieee80211_sta *ieee80211_find_sta
+ }
+ EXPORT_SYMBOL(ieee80211_find_sta);
+
+-static void clear_sta_ps_flags(void *_sta)
++/* powersave support code */
++void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
+ {
+- struct sta_info *sta = _sta;
+ struct ieee80211_sub_if_data *sdata = sta->sdata;
++ struct ieee80211_local *local = sdata->local;
++ struct sk_buff_head pending;
++ int filtered = 0, buffered = 0, ac;
++ unsigned long flags;
+ struct ps_data *ps;
+
+ if (sdata->vif.type == NL80211_IFTYPE_AP ||
+@@ -1085,20 +1110,6 @@ static void clear_sta_ps_flags(void *_st
+ else
+ return;
+
+- clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
+- if (test_and_clear_sta_flag(sta, WLAN_STA_PS_STA))
+- atomic_dec(&ps->num_sta_ps);
+-}
+-
+-/* powersave support code */
+-void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
+-{
+- struct ieee80211_sub_if_data *sdata = sta->sdata;
+- struct ieee80211_local *local = sdata->local;
+- struct sk_buff_head pending;
+- int filtered = 0, buffered = 0, ac;
+- unsigned long flags;
+-
+ clear_sta_flag(sta, WLAN_STA_SP);
+
+ BUILD_BUG_ON(BITS_TO_LONGS(IEEE80211_NUM_TIDS) > 1);
+@@ -1109,6 +1120,8 @@ void ieee80211_sta_ps_deliver_wakeup(str
+
+ skb_queue_head_init(&pending);
+
++ /* sync with ieee80211_tx_h_unicast_ps_buf */
++ spin_lock(&sta->ps_lock);
+ /* Send all buffered frames to the station */
+ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
+ int count = skb_queue_len(&pending), tmp;
+@@ -1127,7 +1140,12 @@ void ieee80211_sta_ps_deliver_wakeup(str
+ buffered += tmp - count;
+ }
+
+- ieee80211_add_pending_skbs_fn(local, &pending, clear_sta_ps_flags, sta);
++ ieee80211_add_pending_skbs(local, &pending);
++ clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
++ clear_sta_flag(sta, WLAN_STA_PS_STA);
++ spin_unlock(&sta->ps_lock);
++
++ atomic_dec(&ps->num_sta_ps);
+
+ /* This station just woke up and isn't aware of our SMPS state */
+ if (!ieee80211_smps_is_restrictive(sta->known_smps_mode,
+--- a/net/mac80211/sta_info.h
++++ b/net/mac80211/sta_info.h
+@@ -267,6 +267,7 @@ struct ieee80211_tx_latency_stat {
+ * @drv_unblock_wk: used for driver PS unblocking
+ * @listen_interval: listen interval of this station, when we're acting as AP
+ * @_flags: STA flags, see &enum ieee80211_sta_info_flags, do not use directly
++ * @ps_lock: used for powersave (when mac80211 is the AP) related locking
+ * @ps_tx_buf: buffers (per AC) of frames to transmit to this station
+ * when it leaves power saving state or polls
+ * @tx_filtered: buffers (per AC) of frames we already tried to
+@@ -356,10 +357,8 @@ struct sta_info {
+ /* use the accessors defined below */
+ unsigned long _flags;
+
+- /*
+- * STA powersave frame queues, no more than the internal
+- * locking required.
+- */
++ /* STA powersave lock and frame queues */
++ spinlock_t ps_lock;
+ struct sk_buff_head ps_tx_buf[IEEE80211_NUM_ACS];
+ struct sk_buff_head tx_filtered[IEEE80211_NUM_ACS];
+ unsigned long driver_buffered_tids;
+--- a/net/mac80211/util.c
++++ b/net/mac80211/util.c
+@@ -435,9 +435,8 @@ void ieee80211_add_pending_skb(struct ie
+ spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
+ }
+
+-void ieee80211_add_pending_skbs_fn(struct ieee80211_local *local,
+- struct sk_buff_head *skbs,
+- void (*fn)(void *data), void *data)
++void ieee80211_add_pending_skbs(struct ieee80211_local *local,
++ struct sk_buff_head *skbs)
+ {
+ struct ieee80211_hw *hw = &local->hw;
+ struct sk_buff *skb;
+@@ -461,9 +460,6 @@ void ieee80211_add_pending_skbs_fn(struc
+ __skb_queue_tail(&local->pending[queue], skb);
+ }
+
+- if (fn)
+- fn(data);
+-
+ for (i = 0; i < hw->queues; i++)
+ __ieee80211_wake_queue(hw, i,
+ IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
+--- a/net/wireless/reg.c
++++ b/net/wireless/reg.c
+@@ -1700,7 +1700,7 @@ static void reg_process_hint(struct regu
+ return;
+ case NL80211_REGDOM_SET_BY_USER:
+ treatment = reg_process_hint_user(reg_request);
+- if (treatment == REG_REQ_OK ||
++ if (treatment == REG_REQ_IGNORE ||
+ treatment == REG_REQ_ALREADY_SET)
+ return;
+ schedule_delayed_work(®_timeout, msecs_to_jiffies(3142));
+--- a/drivers/net/wireless/ath/ath9k/debug.c
++++ b/drivers/net/wireless/ath/ath9k/debug.c
+@@ -866,6 +866,12 @@ static ssize_t read_file_reset(struct fi
+ "%17s: %2d\n", "PLL RX Hang",
+ sc->debug.stats.reset[RESET_TYPE_PLL_HANG]);
+ len += scnprintf(buf + len, sizeof(buf) - len,
++ "%17s: %2d\n", "MAC Hang",
++ sc->debug.stats.reset[RESET_TYPE_MAC_HANG]);
++ len += scnprintf(buf + len, sizeof(buf) - len,
++ "%17s: %2d\n", "Stuck Beacon",
++ sc->debug.stats.reset[RESET_TYPE_BEACON_STUCK]);
++ len += scnprintf(buf + len, sizeof(buf) - len,
+ "%17s: %2d\n", "MCI Reset",
+ sc->debug.stats.reset[RESET_TYPE_MCI]);
+
+--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
++++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+@@ -868,10 +868,6 @@ static void ar9003_hw_set_rfmode(struct
+
+ if (IS_CHAN_A_FAST_CLOCK(ah, chan))
+ rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE);
+- if (IS_CHAN_QUARTER_RATE(chan))
+- rfMode |= AR_PHY_MODE_QUARTER;
+- if (IS_CHAN_HALF_RATE(chan))
+- rfMode |= AR_PHY_MODE_HALF;
+
+ if (rfMode & (AR_PHY_MODE_QUARTER | AR_PHY_MODE_HALF))
+ REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL,
+--- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c
++++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
+@@ -706,6 +706,7 @@ ath5k_get_survey(struct ieee80211_hw *hw
+ survey->channel = conf->chandef.chan;
+ survey->noise = ah->ah_noise_floor;
+ survey->filled = SURVEY_INFO_NOISE_DBM |
++ SURVEY_INFO_IN_USE |
+ SURVEY_INFO_CHANNEL_TIME |
+ SURVEY_INFO_CHANNEL_TIME_BUSY |
+ SURVEY_INFO_CHANNEL_TIME_RX |
+--- a/drivers/net/wireless/ath/ath9k/recv.c
++++ b/drivers/net/wireless/ath/ath9k/recv.c
+@@ -732,11 +732,18 @@ static struct ath_rxbuf *ath_get_next_rx
+ return NULL;
+
+ /*
+- * mark descriptor as zero-length and set the 'more'
+- * flag to ensure that both buffers get discarded
++ * Re-check previous descriptor, in case it has been filled
++ * in the mean time.
+ */
+- rs->rs_datalen = 0;
+- rs->rs_more = true;
++ ret = ath9k_hw_rxprocdesc(ah, ds, rs);
++ if (ret == -EINPROGRESS) {
++ /*
++ * mark descriptor as zero-length and set the 'more'
++ * flag to ensure that both buffers get discarded
++ */
++ rs->rs_datalen = 0;
++ rs->rs_more = true;
++ }
+ }
+
+ list_del(&bf->list);
+@@ -985,32 +992,32 @@ static int ath9k_rx_skb_preprocess(struc
+ struct ath_common *common = ath9k_hw_common(ah);
+ struct ieee80211_hdr *hdr;
+ bool discard_current = sc->rx.discard_next;
+- int ret = 0;
+
+ /*
+ * Discard corrupt descriptors which are marked in
+ * ath_get_next_rx_buf().
+ */
+- sc->rx.discard_next = rx_stats->rs_more;
+ if (discard_current)
+- return -EINVAL;
++ goto corrupt;
++
++ sc->rx.discard_next = false;
+
+ /*
+ * Discard zero-length packets.
+ */
+ if (!rx_stats->rs_datalen) {
+ RX_STAT_INC(rx_len_err);
+- return -EINVAL;
++ goto corrupt;
+ }
+
+- /*
+- * rs_status follows rs_datalen so if rs_datalen is too large
+- * we can take a hint that hardware corrupted it, so ignore
+- * those frames.
+- */
++ /*
++ * rs_status follows rs_datalen so if rs_datalen is too large
++ * we can take a hint that hardware corrupted it, so ignore
++ * those frames.
++ */
+ if (rx_stats->rs_datalen > (common->rx_bufsize - ah->caps.rx_status_len)) {
+ RX_STAT_INC(rx_len_err);
+- return -EINVAL;
++ goto corrupt;
+ }
+
+ /* Only use status info from the last fragment */
+@@ -1024,10 +1031,8 @@ static int ath9k_rx_skb_preprocess(struc
+ * This is different from the other corrupt descriptor
+ * condition handled above.
+ */
+- if (rx_stats->rs_status & ATH9K_RXERR_CORRUPT_DESC) {
+- ret = -EINVAL;
+- goto exit;
+- }
++ if (rx_stats->rs_status & ATH9K_RXERR_CORRUPT_DESC)
++ goto corrupt;
+
+ hdr = (struct ieee80211_hdr *) (skb->data + ah->caps.rx_status_len);
+
+@@ -1043,18 +1048,15 @@ static int ath9k_rx_skb_preprocess(struc
+ if (ath_process_fft(sc, hdr, rx_stats, rx_status->mactime))
+ RX_STAT_INC(rx_spectral);
+
+- ret = -EINVAL;
+- goto exit;
++ return -EINVAL;
+ }
+
+ /*
+ * everything but the rate is checked here, the rate check is done
+ * separately to avoid doing two lookups for a rate for each frame.
+ */
+- if (!ath9k_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error)) {
+- ret = -EINVAL;
+- goto exit;
+- }
++ if (!ath9k_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error))
++ return -EINVAL;
+
+ if (ath_is_mybeacon(common, hdr)) {
+ RX_STAT_INC(rx_beacons);
+@@ -1064,15 +1066,11 @@ static int ath9k_rx_skb_preprocess(struc
+ /*
+ * This shouldn't happen, but have a safety check anyway.
+ */
+- if (WARN_ON(!ah->curchan)) {
+- ret = -EINVAL;
+- goto exit;
+- }
++ if (WARN_ON(!ah->curchan))
++ return -EINVAL;
+
+- if (ath9k_process_rate(common, hw, rx_stats, rx_status)) {
+- ret =-EINVAL;
+- goto exit;
+- }
++ if (ath9k_process_rate(common, hw, rx_stats, rx_status))
++ return -EINVAL;
+
+ ath9k_process_rssi(common, hw, rx_stats, rx_status);
+
+@@ -1087,9 +1085,11 @@ static int ath9k_rx_skb_preprocess(struc
+ sc->rx.num_pkts++;
+ #endif
+
+-exit:
+- sc->rx.discard_next = false;
+- return ret;
++ return 0;
++
++corrupt:
++ sc->rx.discard_next = rx_stats->rs_more;
++ return -EINVAL;
+ }
+
+ static void ath9k_rx_skb_postprocess(struct ath_common *common,
+--- a/drivers/net/wireless/ath/ath9k/ani.c
++++ b/drivers/net/wireless/ath/ath9k/ani.c
+@@ -176,16 +176,26 @@ static void ath9k_hw_set_ofdm_nil(struct
+ if (ah->opmode == NL80211_IFTYPE_STATION &&
+ BEACON_RSSI(ah) <= ATH9K_ANI_RSSI_THR_HIGH)
+ weak_sig = true;
+-
+ /*
+- * OFDM Weak signal detection is always enabled for AP mode.
++ * Newer chipsets are better at dealing with high PHY error counts -
++ * keep weak signal detection enabled when no RSSI threshold is
++ * available to determine if it is needed (mode != STA)
+ */
+- if (ah->opmode != NL80211_IFTYPE_AP &&
+- aniState->ofdmWeakSigDetect != weak_sig) {
+- ath9k_hw_ani_control(ah,
+- ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
+- entry_ofdm->ofdm_weak_signal_on);
+- }
++ else if (AR_SREV_9300_20_OR_LATER(ah) &&
++ ah->opmode != NL80211_IFTYPE_STATION)
++ weak_sig = true;
++
++ /* Older chipsets are more sensitive to high PHY error counts */
++ else if (!AR_SREV_9300_20_OR_LATER(ah) &&
++ aniState->ofdmNoiseImmunityLevel >= 8)
++ weak_sig = false;
++
++ if (aniState->ofdmWeakSigDetect != weak_sig)
++ ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
++ weak_sig);
++
++ if (!AR_SREV_9300_20_OR_LATER(ah))
++ return;
+
+ if (aniState->ofdmNoiseImmunityLevel >= ATH9K_ANI_OFDM_DEF_LEVEL) {
+ ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH;
+@@ -483,10 +493,17 @@ void ath9k_hw_ani_init(struct ath_hw *ah
+
+ ath_dbg(common, ANI, "Initialize ANI\n");
+
+- ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH;
+- ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW;
+- ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH;
+- ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW;
++ if (AR_SREV_9300_20_OR_LATER(ah)) {
++ ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH;
++ ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW;
++ ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH;
++ ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW;
++ } else {
++ ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_OLD;
++ ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_OLD;
++ ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH_OLD;
++ ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW_OLD;
++ }
+
+ ani->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
+ ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
+--- a/drivers/net/wireless/ath/ath9k/ani.h
++++ b/drivers/net/wireless/ath/ath9k/ani.h
+@@ -22,12 +22,16 @@
+ /* units are errors per second */
+ #define ATH9K_ANI_OFDM_TRIG_HIGH 3500
+ #define ATH9K_ANI_OFDM_TRIG_HIGH_BELOW_INI 1000
++#define ATH9K_ANI_OFDM_TRIG_HIGH_OLD 500
+
+ #define ATH9K_ANI_OFDM_TRIG_LOW 400
+ #define ATH9K_ANI_OFDM_TRIG_LOW_ABOVE_INI 900
++#define ATH9K_ANI_OFDM_TRIG_LOW_OLD 200
+
+ #define ATH9K_ANI_CCK_TRIG_HIGH 600
++#define ATH9K_ANI_CCK_TRIG_HIGH_OLD 200
+ #define ATH9K_ANI_CCK_TRIG_LOW 300
++#define ATH9K_ANI_CCK_TRIG_LOW_OLD 100
+
+ #define ATH9K_ANI_SPUR_IMMUNE_LVL 3
+ #define ATH9K_ANI_FIRSTEP_LVL 2