ath9k/ath5k: fix driver load issues with mesh support compiled out
[openwrt.git] / package / mac80211 / patches / 300-pending_work.patch
index adf59f6..23b992d 100644 (file)
+--- a/drivers/net/wireless/ath/ath5k/base.c
++++ b/drivers/net/wireless/ath/ath5k/base.c
+@@ -1171,7 +1171,7 @@ ath5k_check_ibss_tsf(struct ath5k_hw *ah
+       if (ieee80211_is_beacon(mgmt->frame_control) &&
+           le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS &&
+-          memcmp(mgmt->bssid, common->curbssid, ETH_ALEN) == 0) {
++          compare_ether_addr(mgmt->bssid, common->curbssid) == 0) {
+               /*
+                * Received an IBSS beacon with the same BSSID. Hardware *must*
+                * have updated the local TSF. We have to work around various
+@@ -1235,7 +1235,7 @@ ath5k_update_beacon_rssi(struct ath5k_hw
+       /* only beacons from our BSSID */
+       if (!ieee80211_is_beacon(mgmt->frame_control) ||
+-          memcmp(mgmt->bssid, common->curbssid, ETH_ALEN) != 0)
++          compare_ether_addr(mgmt->bssid, common->curbssid) != 0)
+               return;
+       ewma_add(&ah->ah_beacon_rssi_avg, rssi);
+@@ -2416,6 +2416,22 @@ ath5k_tx_complete_poll_work(struct work_
+ * Initialization routines *
+ \*************************/
++static const struct ieee80211_iface_limit if_limits[] = {
++      { .max = 2048,  .types = BIT(NL80211_IFTYPE_STATION) },
++      { .max = 4,     .types =
++#ifdef CONFIG_MAC80211_MESH
++                               BIT(NL80211_IFTYPE_MESH_POINT) |
++#endif
++                               BIT(NL80211_IFTYPE_AP) },
++};
++
++static const struct ieee80211_iface_combination if_comb = {
++      .limits = if_limits,
++      .n_limits = ARRAY_SIZE(if_limits),
++      .max_interfaces = 2048,
++      .num_different_channels = 1,
++};
++
+ int __devinit
+ ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops)
+ {
+@@ -2437,6 +2453,9 @@ ath5k_init_ah(struct ath5k_hw *ah, const
+               BIT(NL80211_IFTYPE_ADHOC) |
+               BIT(NL80211_IFTYPE_MESH_POINT);
++      hw->wiphy->iface_combinations = &if_comb;
++      hw->wiphy->n_iface_combinations = 1;
++
+       /* SW support for IBSS_RSN is provided by mac80211 */
+       hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
+--- a/drivers/net/wireless/ath/ath9k/ani.c
++++ b/drivers/net/wireless/ath/ath9k/ani.c
+@@ -274,7 +274,9 @@ static void ath9k_hw_set_ofdm_nil(struct
+               aniState->rssiThrLow, aniState->rssiThrHigh);
+       if (aniState->update_ani)
+-              aniState->ofdmNoiseImmunityLevel = immunityLevel;
++              aniState->ofdmNoiseImmunityLevel =
++                      (immunityLevel > ATH9K_ANI_OFDM_DEF_LEVEL) ?
++                      immunityLevel : ATH9K_ANI_OFDM_DEF_LEVEL;
+       entry_ofdm = &ofdm_level_table[aniState->ofdmNoiseImmunityLevel];
+       entry_cck = &cck_level_table[aniState->cckNoiseImmunityLevel];
+@@ -340,7 +342,9 @@ static void ath9k_hw_set_cck_nil(struct 
+               immunityLevel = ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI;
+       if (aniState->update_ani)
+-              aniState->cckNoiseImmunityLevel = immunityLevel;
++              aniState->cckNoiseImmunityLevel =
++                      (immunityLevel > ATH9K_ANI_CCK_DEF_LEVEL) ?
++                      immunityLevel : ATH9K_ANI_CCK_DEF_LEVEL;
+       entry_ofdm = &ofdm_level_table[aniState->ofdmNoiseImmunityLevel];
+       entry_cck = &cck_level_table[aniState->cckNoiseImmunityLevel];
+--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
++++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+@@ -618,19 +618,10 @@ static void ar5008_hw_init_bb(struct ath
+       u32 synthDelay;
+       synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
+-      if (IS_CHAN_B(chan))
+-              synthDelay = (4 * synthDelay) / 22;
+-      else
+-              synthDelay /= 10;
+-
+-      if (IS_CHAN_HALF_RATE(chan))
+-              synthDelay *= 2;
+-      else if (IS_CHAN_QUARTER_RATE(chan))
+-              synthDelay *= 4;
+       REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
+-      udelay(synthDelay + BASE_ACTIVATE_DELAY);
++      ath9k_hw_synth_delay(ah, chan, synthDelay);
+ }
+ static void ar5008_hw_init_chain_masks(struct ath_hw *ah)
+@@ -868,7 +859,7 @@ static int ar5008_hw_process_ini(struct 
+       ar5008_hw_set_channel_regs(ah, chan);
+       ar5008_hw_init_chain_masks(ah);
+       ath9k_olc_init(ah);
+-      ath9k_hw_apply_txpower(ah, chan);
++      ath9k_hw_apply_txpower(ah, chan, false);
+       /* Write analog registers */
+       if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
+@@ -948,12 +939,8 @@ static bool ar5008_hw_rfbus_req(struct a
+ static void ar5008_hw_rfbus_done(struct ath_hw *ah)
+ {
+       u32 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
+-      if (IS_CHAN_B(ah->curchan))
+-              synthDelay = (4 * synthDelay) / 22;
+-      else
+-              synthDelay /= 10;
+-      udelay(synthDelay + BASE_ACTIVATE_DELAY);
++      ath9k_hw_synth_delay(ah, ah->curchan, synthDelay);
+       REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
+ }
+--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
++++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+@@ -1000,10 +1000,12 @@ static bool ar9003_hw_init_cal(struct at
+       if (mci && IS_CHAN_2GHZ(chan) && run_agc_cal)
+               ar9003_mci_init_cal_req(ah, &is_reusable);
+-      txiqcal_done = ar9003_hw_tx_iq_cal_run(ah);
+-      REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
+-      udelay(5);
+-      REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
++      if (!(IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan))) {
++              txiqcal_done = ar9003_hw_tx_iq_cal_run(ah);
++              REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
++              udelay(5);
++              REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
++      }
+ skip_tx_iqcal:
+       if (run_agc_cal || !(ah->ah_flags & AH_FASTCC)) {
+--- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
++++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
+@@ -54,7 +54,7 @@ void ar9003_paprd_enable(struct ath_hw *
+       if (val) {
+               ah->paprd_table_write_done = true;
+-              ath9k_hw_apply_txpower(ah, chan);
++              ath9k_hw_apply_txpower(ah, chan, false);
+       }
+       REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B0,
+--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
++++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+@@ -524,22 +524,10 @@ static void ar9003_hw_init_bb(struct ath
+        * Value is in 100ns increments.
+        */
+       synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
+-      if (IS_CHAN_B(chan))
+-              synthDelay = (4 * synthDelay) / 22;
+-      else
+-              synthDelay /= 10;
+       /* Activate the PHY (includes baseband activate + synthesizer on) */
+       REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
+-
+-      /*
+-       * There is an issue if the AP starts the calibration before
+-       * the base band timeout completes.  This could result in the
+-       * rx_clear false triggering.  As a workaround we add delay an
+-       * extra BASE_ACTIVATE_DELAY usecs to ensure this condition
+-       * does not happen.
+-       */
+-      udelay(synthDelay + BASE_ACTIVATE_DELAY);
++      ath9k_hw_synth_delay(ah, chan, synthDelay);
+ }
+ static void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx)
+@@ -690,7 +678,7 @@ static int ar9003_hw_process_ini(struct 
+       ar9003_hw_override_ini(ah);
+       ar9003_hw_set_channel_regs(ah, chan);
+       ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
+-      ath9k_hw_apply_txpower(ah, chan);
++      ath9k_hw_apply_txpower(ah, chan, false);
+       if (AR_SREV_9462(ah)) {
+               if (REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_0,
+@@ -721,6 +709,14 @@ 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,
++                            AR_PHY_FRAME_CTL_CF_OVERLAP_WINDOW, 3);
+       REG_WRITE(ah, AR_PHY_MODE, rfMode);
+ }
+@@ -791,12 +787,8 @@ static bool ar9003_hw_rfbus_req(struct a
+ static void ar9003_hw_rfbus_done(struct ath_hw *ah)
+ {
+       u32 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
+-      if (IS_CHAN_B(ah->curchan))
+-              synthDelay = (4 * synthDelay) / 22;
+-      else
+-              synthDelay /= 10;
+-      udelay(synthDelay + BASE_ACTIVATE_DELAY);
++      ath9k_hw_synth_delay(ah, ah->curchan, synthDelay);
+       REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
+ }
+--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h
++++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
+@@ -468,6 +468,9 @@
+ #define AR_PHY_ADDAC_PARA_CTL    (AR_SM_BASE + 0x150)
+ #define AR_PHY_XPA_CFG           (AR_SM_BASE + 0x158)
++#define AR_PHY_FRAME_CTL_CF_OVERLAP_WINDOW  3
++#define AR_PHY_FRAME_CTL_CF_OVERLAP_WINDOW_S    0
++
+ #define AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A           0x0001FC00
+ #define AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A_S         10
+ #define AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A                       0x3FF
+--- a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h
++++ b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h
+@@ -1115,9 +1115,9 @@ static const u32 ar9462_2p0_mac_core[][2
+       {0x000081f8, 0x00000000},
+       {0x000081fc, 0x00000000},
+       {0x00008240, 0x00100000},
+-      {0x00008244, 0x0010f400},
++      {0x00008244, 0x0010f424},
+       {0x00008248, 0x00000800},
+-      {0x0000824c, 0x0001e800},
++      {0x0000824c, 0x0001e848},
+       {0x00008250, 0x00000000},
+       {0x00008254, 0x00000000},
+       {0x00008258, 0x00000000},
+--- a/drivers/net/wireless/ath/ath9k/ath9k.h
++++ b/drivers/net/wireless/ath/ath9k/ath9k.h
+@@ -370,7 +370,7 @@ struct ath_vif {
+  * number of beacon intervals, the game's up.
+  */
+ #define BSTUCK_THRESH                 9
+-#define       ATH_BCBUF                       4
++#define       ATH_BCBUF                       8
+ #define ATH_DEFAULT_BINTVAL           100 /* TU */
+ #define ATH_DEFAULT_BMISS_LIMIT       10
+ #define IEEE80211_MS_TO_TU(x)           (((x) * 1000) / 1024)
+--- a/drivers/net/wireless/ath/ath9k/beacon.c
++++ b/drivers/net/wireless/ath/ath9k/beacon.c
+@@ -91,7 +91,7 @@ static void ath_beacon_setup(struct ath_
+       info.txpower = MAX_RATE_POWER;
+       info.keyix = ATH9K_TXKEYIX_INVALID;
+       info.keytype = ATH9K_KEY_TYPE_CLEAR;
+-      info.flags = ATH9K_TXDESC_NOACK | ATH9K_TXDESC_INTREQ;
++      info.flags = ATH9K_TXDESC_NOACK | ATH9K_TXDESC_CLRDMASK;
+       info.buf_addr[0] = bf->bf_buf_addr;
+       info.buf_len[0] = roundup(skb->len, 4);
+@@ -359,6 +359,11 @@ void ath_beacon_tasklet(unsigned long da
+       int slot;
+       u32 bfaddr, bc = 0;
++      if (work_pending(&sc->hw_reset_work)) {
++              ath_dbg(common, RESET,
++                      "reset work is pending, skip beaconing now\n");
++              return;
++      }
+       /*
+        * Check if the previous beacon has gone out.  If
+        * not don't try to post another, skip this period
+@@ -369,6 +374,9 @@ void ath_beacon_tasklet(unsigned long da
+       if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0) {
+               sc->beacon.bmisscnt++;
++              if (!ath9k_hw_check_alive(ah))
++                      ieee80211_queue_work(sc->hw, &sc->hw_check_work);
++
+               if (sc->beacon.bmisscnt < BSTUCK_THRESH * sc->nbcnvifs) {
+                       ath_dbg(common, BSTUCK,
+                               "missed %u consecutive beacons\n",
+@@ -378,6 +386,7 @@ void ath_beacon_tasklet(unsigned long da
+                               ath9k_hw_bstuck_nfcal(ah);
+               } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) {
+                       ath_dbg(common, BSTUCK, "beacon is officially stuck\n");
++                      sc->beacon.bmisscnt = 0;
+                       sc->sc_flags |= SC_OP_TSF_RESET;
+                       ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
+               }
+@@ -650,6 +659,8 @@ static void ath_beacon_config_adhoc(stru
+       u32 tsf, intval, nexttbtt;
+       ath9k_reset_beacon_status(sc);
++      if (!(sc->sc_flags & SC_OP_BEACONS))
++              ath9k_hw_settsf64(ah, sc->beacon.bc_tstamp);
+       intval = TU_TO_USEC(conf->beacon_interval);
+       tsf = roundup(ath9k_hw_gettsf32(ah) + TU_TO_USEC(FUDGE), intval);
+--- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c
++++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
+@@ -824,6 +824,8 @@ static void ath9k_hw_ar9287_set_txpower(
+                       regulatory->max_power_level = ratesArray[i];
+       }
++      ath9k_hw_update_regulatory_maxpower(ah);
++
+       if (test)
+               return;
+--- a/drivers/net/wireless/ath/ath9k/gpio.c
++++ b/drivers/net/wireless/ath/ath9k/gpio.c
+@@ -41,6 +41,9 @@ void ath_init_leds(struct ath_softc *sc)
+ {
+       int ret;
++      if (AR_SREV_9100(sc->sc_ah))
++              return;
++
+       if (sc->sc_ah->led_pin < 0) {
+               if (AR_SREV_9287(sc->sc_ah))
+                       sc->sc_ah->led_pin = ATH_LED_PIN_9287;
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -142,6 +142,22 @@ bool ath9k_hw_wait(struct ath_hw *ah, u3
+ }
+ EXPORT_SYMBOL(ath9k_hw_wait);
++void ath9k_hw_synth_delay(struct ath_hw *ah, struct ath9k_channel *chan,
++                        int hw_delay)
++{
++      if (IS_CHAN_B(chan))
++              hw_delay = (4 * hw_delay) / 22;
++      else
++              hw_delay /= 10;
++
++      if (IS_CHAN_HALF_RATE(chan))
++              hw_delay *= 2;
++      else if (IS_CHAN_QUARTER_RATE(chan))
++              hw_delay *= 4;
++
++      udelay(hw_delay + BASE_ACTIVATE_DELAY);
++}
++
+ void ath9k_hw_write_array(struct ath_hw *ah, struct ar5416IniArray *array,
+                         int column, unsigned int *writecnt)
+ {
+@@ -388,8 +404,8 @@ static void ath9k_hw_init_config(struct 
+ {
+       int i;
+-      ah->config.dma_beacon_response_time = 2;
+-      ah->config.sw_beacon_response_time = 10;
++      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;
+@@ -971,7 +987,7 @@ void ath9k_hw_init_global_settings(struc
+       struct ath_common *common = ath9k_hw_common(ah);
+       struct ieee80211_conf *conf = &common->hw->conf;
+       const struct ath9k_channel *chan = ah->curchan;
+-      int acktimeout, ctstimeout;
++      int acktimeout, ctstimeout, ack_offset = 0;
+       int slottime;
+       int sifstime;
+       int rx_lat = 0, tx_lat = 0, eifs = 0;
+@@ -992,6 +1008,11 @@ void ath9k_hw_init_global_settings(struc
+               rx_lat = 37;
+       tx_lat = 54;
++      if (IS_CHAN_5GHZ(chan))
++              sifstime = 16;
++      else
++              sifstime = 10;
++
+       if (IS_CHAN_HALF_RATE(chan)) {
+               eifs = 175;
+               rx_lat *= 2;
+@@ -999,8 +1020,9 @@ void ath9k_hw_init_global_settings(struc
+               if (IS_CHAN_A_FAST_CLOCK(ah, chan))
+                   tx_lat += 11;
++              sifstime *= 2;
++              ack_offset = 16;
+               slottime = 13;
+-              sifstime = 32;
+       } else if (IS_CHAN_QUARTER_RATE(chan)) {
+               eifs = 340;
+               rx_lat = (rx_lat * 4) - 1;
+@@ -1008,8 +1030,9 @@ void ath9k_hw_init_global_settings(struc
+               if (IS_CHAN_A_FAST_CLOCK(ah, chan))
+                   tx_lat += 22;
++              sifstime *= 4;
++              ack_offset = 32;
+               slottime = 21;
+-              sifstime = 64;
+       } else {
+               if (AR_SREV_9287(ah) && AR_SREV_9287_13_OR_LATER(ah)) {
+                       eifs = AR_D_GBL_IFS_EIFS_ASYNC_FIFO;
+@@ -1023,14 +1046,10 @@ void ath9k_hw_init_global_settings(struc
+               tx_lat = MS(reg, AR_USEC_TX_LAT);
+               slottime = ah->slottime;
+-              if (IS_CHAN_5GHZ(chan))
+-                      sifstime = 16;
+-              else
+-                      sifstime = 10;
+       }
+       /* As defined by IEEE 802.11-2007 17.3.8.6 */
+-      acktimeout = slottime + sifstime + 3 * ah->coverage_class;
++      acktimeout = slottime + sifstime + 3 * ah->coverage_class + ack_offset;
+       ctstimeout = acktimeout;
+       /*
+@@ -1040,7 +1059,8 @@ void ath9k_hw_init_global_settings(struc
+        * BA frames in some implementations, but it has been found to fix ACK
+        * timeout issues in other cases as well.
+        */
+-      if (conf->channel && conf->channel->band == IEEE80211_BAND_2GHZ) {
++      if (conf->channel && conf->channel->band == IEEE80211_BAND_2GHZ &&
++          !IS_CHAN_HALF_RATE(chan) && !IS_CHAN_QUARTER_RATE(chan)) {
+               acktimeout += 64 - sifstime - ah->slottime;
+               ctstimeout += 48 - sifstime - ah->slottime;
+       }
+@@ -1420,6 +1440,10 @@ static bool ath9k_hw_channel_change(stru
+                                                   CHANNEL_5GHZ));
+       mode_diff = (chan->chanmode != ah->curchan->chanmode);
++      if ((ah->curchan->channelFlags | chan->channelFlags) &
++          (CHANNEL_HALF | CHANNEL_QUARTER))
++              return false;
++
+       for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
+               if (ath9k_hw_numtxpending(ah, qnum)) {
+                       ath_dbg(common, QUEUE,
+@@ -1453,7 +1477,7 @@ static bool ath9k_hw_channel_change(stru
+               return false;
+       }
+       ath9k_hw_set_clockrate(ah);
+-      ath9k_hw_apply_txpower(ah, chan);
++      ath9k_hw_apply_txpower(ah, chan, false);
+       ath9k_hw_rfbus_done(ah);
+       if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
+@@ -2724,7 +2748,8 @@ static int get_antenna_gain(struct ath_h
+       return ah->eep_ops->get_eeprom(ah, gain_param);
+ }
+-void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan)
++void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan,
++                          bool test)
+ {
+       struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
+       struct ieee80211_channel *channel;
+@@ -2745,7 +2770,7 @@ void ath9k_hw_apply_txpower(struct ath_h
+       ah->eep_ops->set_txpower(ah, chan,
+                                ath9k_regd_get_ctl(reg, chan),
+-                               ant_reduction, new_pwr, false);
++                               ant_reduction, new_pwr, test);
+ }
+ void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test)
+@@ -2758,7 +2783,7 @@ void ath9k_hw_set_txpowerlimit(struct at
+       if (test)
+               channel->max_power = MAX_RATE_POWER / 2;
+-      ath9k_hw_apply_txpower(ah, chan);
++      ath9k_hw_apply_txpower(ah, chan, test);
+       if (test)
+               channel->max_power = DIV_ROUND_UP(reg->max_power_level, 2);
+--- a/drivers/net/wireless/ath/ath9k/hw.h
++++ b/drivers/net/wireless/ath/ath9k/hw.h
+@@ -923,6 +923,8 @@ void ath9k_hw_set_gpio(struct ath_hw *ah
+ void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna);
+ /* General Operation */
++void ath9k_hw_synth_delay(struct ath_hw *ah, struct ath9k_channel *chan,
++                        int hw_delay);
+ bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout);
+ void ath9k_hw_write_array(struct ath_hw *ah, struct ar5416IniArray *array,
+                         int column, unsigned int *writecnt);
+@@ -976,7 +978,8 @@ void ath9k_hw_name(struct ath_hw *ah, ch
+ /* PHY */
+ void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled,
+                                  u32 *coef_mantissa, u32 *coef_exponent);
+-void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan);
++void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan,
++                          bool test);
+ /*
+  * Code Specific to AR5008, AR9001 or AR9002,
+--- a/drivers/net/wireless/ath/ath9k/mac.c
++++ b/drivers/net/wireless/ath/ath9k/mac.c
+@@ -133,8 +133,16 @@ EXPORT_SYMBOL(ath9k_hw_updatetxtriglevel
+ void ath9k_hw_abort_tx_dma(struct ath_hw *ah)
+ {
++      int maxdelay = 1000;
+       int i, q;
++      if (ah->curchan) {
++              if (IS_CHAN_HALF_RATE(ah->curchan))
++                      maxdelay *= 2;
++              else if (IS_CHAN_QUARTER_RATE(ah->curchan))
++                      maxdelay *= 4;
++      }
++
+       REG_WRITE(ah, AR_Q_TXD, AR_Q_TXD_M);
+       REG_SET_BIT(ah, AR_PCU_MISC, AR_PCU_FORCE_QUIET_COLL | AR_PCU_CLEAR_VMF);
+@@ -142,7 +150,7 @@ void ath9k_hw_abort_tx_dma(struct ath_hw
+       REG_SET_BIT(ah, AR_D_GBL_IFS_MISC, AR_D_GBL_IFS_MISC_IGNORE_BACKOFF);
+       for (q = 0; q < AR_NUM_QCU; q++) {
+-              for (i = 0; i < 1000; i++) {
++              for (i = 0; i < maxdelay; i++) {
+                       if (i)
+                               udelay(5);
+--- a/drivers/net/wireless/ath/ath9k/main.c
++++ b/drivers/net/wireless/ath/ath9k/main.c
+@@ -692,17 +692,6 @@ void ath9k_tasklet(unsigned long data)
+               goto out;
+       }
+-      /*
+-       * Only run the baseband hang check if beacons stop working in AP or
+-       * IBSS mode, because it has a high false positive rate. For station
+-       * mode it should not be necessary, since the upper layers will detect
+-       * this through a beacon miss automatically and the following channel
+-       * change will trigger a hardware reset anyway
+-       */
+-      if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0 &&
+-          !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
 --- a/net/mac80211/agg-rx.c
 +++ b/net/mac80211/agg-rx.c
-@@ -176,6 +176,8 @@ static void ieee80211_send_addba_resp(st
-               memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
-       else if (sdata->vif.type == NL80211_IFTYPE_STATION)
+@@ -200,6 +200,8 @@ static void ieee80211_send_addba_resp(st
                memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
+       else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
+               memcpy(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN);
 +      else if (sdata->vif.type == NL80211_IFTYPE_WDS)
 +              memcpy(mgmt->bssid, da, ETH_ALEN);
  
        mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
                                          IEEE80211_STYPE_ACTION);
-@@ -262,7 +264,11 @@ void ieee80211_process_addba_request(str
-                               "%pM on tid %u\n",
-                               mgmt->sa, tid);
- #endif /* CONFIG_MAC80211_HT_DEBUG */
--              goto end;
-+
-+              /* delete existing Rx BA session on the same tid */
-+              ___ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_RECIPIENT,
-+                                              WLAN_STATUS_UNSPECIFIED_QOS,
-+                                              false);
-       }
-       /* prepare A-MPDU MLME for Rx aggregation */
 --- a/net/mac80211/agg-tx.c
 +++ b/net/mac80211/agg-tx.c
-@@ -79,7 +79,8 @@ static void ieee80211_send_addba_request
-       memcpy(mgmt->da, da, ETH_ALEN);
+@@ -81,7 +81,8 @@ static void ieee80211_send_addba_request
        memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
        if (sdata->vif.type == NL80211_IFTYPE_AP ||
--          sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
-+          sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
+           sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
+-          sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
++          sdata->vif.type == NL80211_IFTYPE_MESH_POINT ||
 +          sdata->vif.type == NL80211_IFTYPE_WDS)
                memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
        else if (sdata->vif.type == NL80211_IFTYPE_STATION)
                memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
-@@ -398,7 +399,8 @@ int ieee80211_start_tx_ba_session(struct
-        */
-       if (sdata->vif.type != NL80211_IFTYPE_STATION &&
+@@ -484,6 +485,7 @@ int ieee80211_start_tx_ba_session(struct
+           sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
            sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
--          sdata->vif.type != NL80211_IFTYPE_AP)
-+          sdata->vif.type != NL80211_IFTYPE_AP &&
-+          sdata->vif.type != NL80211_IFTYPE_WDS)
+           sdata->vif.type != NL80211_IFTYPE_AP &&
++          sdata->vif.type != NL80211_IFTYPE_WDS &&
+           sdata->vif.type != NL80211_IFTYPE_ADHOC)
                return -EINVAL;
  
-       if (test_sta_flags(sta, WLAN_STA_BLOCK_BA)) {
 --- a/net/mac80211/debugfs_sta.c
 +++ b/net/mac80211/debugfs_sta.c
-@@ -59,7 +59,7 @@ static ssize_t sta_flags_read(struct fil
-       char buf[100];
-       struct sta_info *sta = file->private_data;
-       u32 staflags = get_sta_flags(sta);
--      int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s",
-+      int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s",
-               staflags & WLAN_STA_AUTH ? "AUTH\n" : "",
-               staflags & WLAN_STA_ASSOC ? "ASSOC\n" : "",
-               staflags & WLAN_STA_PS_STA ? "PS (sta)\n" : "",
-@@ -67,7 +67,6 @@ static ssize_t sta_flags_read(struct fil
-               staflags & WLAN_STA_AUTHORIZED ? "AUTHORIZED\n" : "",
-               staflags & WLAN_STA_SHORT_PREAMBLE ? "SHORT PREAMBLE\n" : "",
-               staflags & WLAN_STA_WME ? "WME\n" : "",
--              staflags & WLAN_STA_WDS ? "WDS\n" : "",
-               staflags & WLAN_STA_MFP ? "MFP\n" : "");
-       return simple_read_from_buffer(userbuf, count, ppos, buf, res);
- }
+@@ -63,11 +63,11 @@ static ssize_t sta_flags_read(struct fil
+       test_sta_flag(sta, WLAN_STA_##flg) ? #flg "\n" : ""
+       int res = scnprintf(buf, sizeof(buf),
+-                          "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
++                          "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+                           TEST(AUTH), TEST(ASSOC), TEST(PS_STA),
+                           TEST(PS_DRIVER), TEST(AUTHORIZED),
+                           TEST(SHORT_PREAMBLE),
+-                          TEST(WME), TEST(WDS), TEST(CLEAR_PS_FILT),
++                          TEST(WME), TEST(CLEAR_PS_FILT),
+                           TEST(MFP), TEST(BLOCK_BA), TEST(PSPOLL),
+                           TEST(UAPSD), TEST(SP), TEST(TDLS_PEER),
+                           TEST(TDLS_PEER_AUTH), TEST(4ADDR_EVENT),
 --- a/net/mac80211/iface.c
 +++ b/net/mac80211/iface.c
-@@ -178,7 +178,6 @@ static int ieee80211_do_open(struct net_
+@@ -163,7 +163,8 @@ static int ieee80211_check_queues(struct
+                       return -EINVAL;
+       }
+-      if (sdata->vif.type != NL80211_IFTYPE_AP) {
++      if ((sdata->vif.type != NL80211_IFTYPE_AP) ||
++          !(sdata->local->hw.flags & IEEE80211_HW_QUEUE_CONTROL)) {
+               sdata->vif.cab_queue = IEEE80211_INVAL_HW_QUEUE;
+               return 0;
+       }
+@@ -281,7 +282,6 @@ static int ieee80211_do_open(struct net_
  {
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        struct ieee80211_local *local = sdata->local;
        u32 changed = 0;
        int res;
        u32 hw_reconf_flags = 0;
-@@ -290,27 +289,6 @@ static int ieee80211_do_open(struct net_
+@@ -427,28 +427,6 @@ static int ieee80211_do_open(struct net_
  
        set_bit(SDATA_STATE_RUNNING, &sdata->state);
  
 -                      goto err_del_interface;
 -              }
 -
--              /* no locking required since STA is not live yet */
--              sta->flags |= WLAN_STA_AUTHORIZED;
+-              sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
+-              sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC);
+-              sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED);
 -
 -              res = sta_info_insert(sta);
 -              if (res) {
        /*
         * set_multicast_list will be invoked by the networking core
         * which will check whether any increments here were done in
-@@ -344,8 +322,7 @@ static int ieee80211_do_open(struct net_
-       netif_tx_start_all_queues(dev);
-       return 0;
-- err_del_interface:
--      drv_remove_interface(local, &sdata->vif);
-+
-  err_stop:
-       if (!local->open_count)
-               drv_stop(local);
-@@ -718,6 +695,70 @@ static void ieee80211_if_setup(struct ne
+@@ -845,6 +823,70 @@ static void ieee80211_if_setup(struct ne
        dev->destructor = free_netdev;
  }
  
 +      ieee802_11_parse_elems(mgmt->u.probe_resp.variable,
 +                             skb->len - baselen, &elems);
 +
-+      rates = ieee80211_sta_get_rates(local, &elems, band);
++      rates = ieee80211_sta_get_rates(local, &elems, band, NULL);
 +
 +      rcu_read_lock();
 +
 +      sta->sta.supp_rates[local->hw.conf.channel->band] = rates;
 +
 +      if (elems.ht_cap_elem)
-+              ieee80211_ht_cap_ie_to_sta_ht_cap(sband,
++              ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
 +                              elems.ht_cap_elem, &sta->sta.ht_cap);
 +
 +      if (elems.wmm_param)
-+              set_sta_flags(sta, WLAN_STA_WME);
++              set_sta_flag(sta, WLAN_STA_WME);
 +
 +      if (new) {
-+              sta->flags = WLAN_STA_AUTHORIZED;
++              set_sta_flag(sta, WLAN_STA_AUTHORIZED);
 +              rate_control_rate_init(sta);
 +              sta_info_insert_rcu(sta);
 +      }
  static void ieee80211_iface_work(struct work_struct *work)
  {
        struct ieee80211_sub_if_data *sdata =
-@@ -822,6 +863,9 @@ static void ieee80211_iface_work(struct 
+@@ -949,6 +991,9 @@ static void ieee80211_iface_work(struct 
                                break;
                        ieee80211_mesh_rx_queued_mgmt(sdata, skb);
                        break;
                        break;
 --- a/net/mac80211/rx.c
 +++ b/net/mac80211/rx.c
-@@ -2137,7 +2137,8 @@ ieee80211_rx_h_action(struct ieee80211_r
-                */
-               if (sdata->vif.type != NL80211_IFTYPE_STATION &&
+@@ -103,7 +103,7 @@ static void
+ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
+                                struct sk_buff *skb,
+                                struct ieee80211_rate *rate,
+-                               int rtap_len)
++                               int rtap_len, bool has_fcs)
+ {
+       struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
+       struct ieee80211_radiotap_header *rthdr;
+@@ -134,7 +134,7 @@ ieee80211_add_rx_radiotap_header(struct 
+       }
+       /* IEEE80211_RADIOTAP_FLAGS */
+-      if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS)
++      if (has_fcs && (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS))
+               *pos |= IEEE80211_RADIOTAP_F_FCS;
+       if (status->flag & (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC))
+               *pos |= IEEE80211_RADIOTAP_F_BADFCS;
+@@ -294,7 +294,8 @@ ieee80211_rx_monitor(struct ieee80211_lo
+       }
+       /* prepend radiotap information */
+-      ieee80211_add_rx_radiotap_header(local, skb, rate, needed_headroom);
++      ieee80211_add_rx_radiotap_header(local, skb, rate, needed_headroom,
++                                       true);
+       skb_reset_mac_header(skb);
+       skb->ip_summed = CHECKSUM_UNNECESSARY;
+@@ -2282,6 +2283,7 @@ ieee80211_rx_h_action(struct ieee80211_r
+                   sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
                    sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
--                  sdata->vif.type != NL80211_IFTYPE_AP)
-+                  sdata->vif.type != NL80211_IFTYPE_AP &&
-+                  sdata->vif.type != NL80211_IFTYPE_WDS)
+                   sdata->vif.type != NL80211_IFTYPE_AP &&
++                  sdata->vif.type != NL80211_IFTYPE_WDS &&
+                   sdata->vif.type != NL80211_IFTYPE_ADHOC)
                        break;
  
-               /* verify action_code is present */
-@@ -2335,13 +2336,14 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_
+@@ -2496,14 +2498,15 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_
  
        if (!ieee80211_vif_is_mesh(&sdata->vif) &&
            sdata->vif.type != NL80211_IFTYPE_ADHOC &&
                return RX_DROP_MONITOR;
  
        switch (stype) {
+       case cpu_to_le16(IEEE80211_STYPE_AUTH):
        case cpu_to_le16(IEEE80211_STYPE_BEACON):
        case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP):
 -              /* process for all: mesh, mlme, ibss */
 +              /* process for all: mesh, mlme, ibss, wds */
                break;
-       case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
-       case cpu_to_le16(IEEE80211_STYPE_DISASSOC):
-@@ -2680,10 +2682,16 @@ static int prepare_for_handlers(struct i
+       case cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP):
+       case cpu_to_le16(IEEE80211_STYPE_REASSOC_RESP):
+@@ -2567,7 +2570,8 @@ static void ieee80211_rx_cooked_monitor(
+               goto out_free_skb;
+       /* prepend radiotap information */
+-      ieee80211_add_rx_radiotap_header(local, skb, rate, needed_headroom);
++      ieee80211_add_rx_radiotap_header(local, skb, rate, needed_headroom,
++                                       false);
+       skb_set_mac_header(skb, 0);
+       skb->ip_summed = CHECKSUM_UNNECESSARY;
+@@ -2836,10 +2840,16 @@ static int prepare_for_handlers(struct i
                }
                break;
        case NL80211_IFTYPE_WDS:
                /* should never get here */
 --- a/net/mac80211/sta_info.h
 +++ b/net/mac80211/sta_info.h
-@@ -31,7 +31,6 @@
+@@ -32,7 +32,6 @@
+  * @WLAN_STA_SHORT_PREAMBLE: Station is capable of receiving short-preamble
   *    frames.
-  * @WLAN_STA_ASSOC_AP: We're associated to that station, it is an AP.
   * @WLAN_STA_WME: Station is a QoS-STA.
 - * @WLAN_STA_WDS: Station is one of our WDS peers.
   * @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the
   *    IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next
   *    frame to this station is transmitted.
-@@ -54,7 +53,6 @@ enum ieee80211_sta_info_flags {
-       WLAN_STA_SHORT_PREAMBLE = 1<<4,
-       WLAN_STA_ASSOC_AP       = 1<<5,
-       WLAN_STA_WME            = 1<<6,
--      WLAN_STA_WDS            = 1<<7,
-       WLAN_STA_CLEAR_PS_FILT  = 1<<9,
-       WLAN_STA_MFP            = 1<<10,
-       WLAN_STA_BLOCK_BA       = 1<<11,
---- a/drivers/net/wireless/ath/ath9k/beacon.c
-+++ b/drivers/net/wireless/ath/ath9k/beacon.c
-@@ -360,6 +360,7 @@ void ath_beacon_tasklet(unsigned long da
-       struct ath_common *common = ath9k_hw_common(ah);
-       struct ath_buf *bf = NULL;
-       struct ieee80211_vif *vif;
-+      struct ath_tx_status ts;
-       int slot;
-       u32 bfaddr, bc = 0;
-@@ -384,7 +385,9 @@ void ath_beacon_tasklet(unsigned long da
-                       ath_dbg(common, ATH_DBG_BSTUCK,
-                               "beacon is officially stuck\n");
-                       sc->sc_flags |= SC_OP_TSF_RESET;
-+                      spin_lock(&sc->sc_pcu_lock);
-                       ath_reset(sc, true);
-+                      spin_unlock(&sc->sc_pcu_lock);
-               }
-               return;
-@@ -464,6 +467,11 @@ void ath_beacon_tasklet(unsigned long da
-               ath9k_hw_txstart(ah, sc->beacon.beaconq);
-               sc->beacon.ast_be_xmit += bc;     /* XXX per-vif? */
-+              if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
-+                      spin_lock_bh(&sc->sc_pcu_lock);
-+                      ath9k_hw_txprocdesc(ah, bf->bf_desc, (void *)&ts);
-+                      spin_unlock_bh(&sc->sc_pcu_lock);
-+              }
-       }
+@@ -64,7 +63,6 @@ enum ieee80211_sta_info_flags {
+       WLAN_STA_AUTHORIZED,
+       WLAN_STA_SHORT_PREAMBLE,
+       WLAN_STA_WME,
+-      WLAN_STA_WDS,
+       WLAN_STA_CLEAR_PS_FILT,
+       WLAN_STA_MFP,
+       WLAN_STA_BLOCK_BA,
+--- a/drivers/net/wireless/ath/ath9k/init.c
++++ b/drivers/net/wireless/ath/ath9k/init.c
+@@ -647,6 +647,24 @@ void ath9k_reload_chainmask_settings(str
+               setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap);
  }
  
---- a/drivers/net/wireless/ath/ath9k/main.c
-+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -617,8 +617,11 @@ void ath_hw_check(struct work_struct *wo
-       ath_dbg(common, ATH_DBG_RESET, "Possible baseband hang, "
-               "busy=%d (try %d)\n", busy, sc->hw_busy_count + 1);
-       if (busy >= 99) {
--              if (++sc->hw_busy_count >= 3)
-+              if (++sc->hw_busy_count >= 3) {
-+                      spin_lock_bh(&sc->sc_pcu_lock);
-                       ath_reset(sc, true);
-+                      spin_unlock_bh(&sc->sc_pcu_lock);
-+              }
-       } else if (busy >= 0)
-               sc->hw_busy_count = 0;
-@@ -637,7 +640,9 @@ static void ath_hw_pll_rx_hang_check(str
-                       /* Rx is hung for more than 500ms. Reset it */
-                       ath_dbg(common, ATH_DBG_RESET,
-                               "Possible RX hang, resetting");
-+                      spin_lock_bh(&sc->sc_pcu_lock);
-                       ath_reset(sc, true);
-+                      spin_unlock_bh(&sc->sc_pcu_lock);
-                       count = 0;
-               }
-       } else
-@@ -674,7 +679,9 @@ void ath9k_tasklet(unsigned long data)
-       if ((status & ATH9K_INT_FATAL) ||
-           (status & ATH9K_INT_BB_WATCHDOG)) {
-+              spin_lock(&sc->sc_pcu_lock);
-               ath_reset(sc, true);
-+              spin_unlock(&sc->sc_pcu_lock);
-               return;
-       }
-@@ -980,7 +987,6 @@ int ath_reset(struct ath_softc *sc, bool
-       del_timer_sync(&common->ani.timer);
-       ath9k_ps_wakeup(sc);
--      spin_lock_bh(&sc->sc_pcu_lock);
-       ieee80211_stop_queues(hw);
-@@ -1023,7 +1029,6 @@ int ath_reset(struct ath_softc *sc, bool
-       }
-       ieee80211_wake_queues(hw);
--      spin_unlock_bh(&sc->sc_pcu_lock);
-       /* Start ANI */
-       if (!common->disable_ani)
-@@ -2326,9 +2331,9 @@ static void ath9k_flush(struct ieee80211
-       ath9k_ps_wakeup(sc);
-       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);
-+      spin_unlock_bh(&sc->sc_pcu_lock);
-       ath9k_ps_restore(sc);
-       ieee80211_wake_queues(hw);
---- a/drivers/net/wireless/ath/ath9k/xmit.c
-+++ b/drivers/net/wireless/ath/ath9k/xmit.c
-@@ -565,11 +565,8 @@ static void ath_tx_complete_aggr(struct 
-       rcu_read_unlock();
--      if (needreset) {
--              spin_unlock_bh(&sc->sc_pcu_lock);
-+      if (needreset)
-               ath_reset(sc, false);
--              spin_lock_bh(&sc->sc_pcu_lock);
--      }
- }
- static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
-@@ -664,7 +661,8 @@ static int ath_compute_num_delims(struct
-        * TODO - this could be improved to be dependent on the rate.
-        *      The hardware can keep up at lower rates, but not higher rates
-        */
--      if (fi->keyix != ATH9K_TXKEYIX_INVALID)
-+      if ((fi->keyix != ATH9K_TXKEYIX_INVALID) &&
-+          !(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA))
-               ndelim += ATH_AGGR_ENCRYPTDELIM;
-       /*
-@@ -2169,7 +2167,9 @@ static void ath_tx_complete_poll_work(st
-       if (needreset) {
-               ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_RESET,
-                       "tx hung, resetting the chip\n");
-+              spin_lock_bh(&sc->sc_pcu_lock);
-               ath_reset(sc, true);
-+              spin_unlock_bh(&sc->sc_pcu_lock);
-       }
-       ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work,
---- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
-+++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
-@@ -236,7 +236,7 @@ static void ar9003_paprd_get_gain_table(
-       memset(entry, 0, sizeof(ah->paprd_gain_table_entries));
-       memset(index, 0, sizeof(ah->paprd_gain_table_index));
--      for (i = 0; i < 32; i++) {
-+      for (i = 0; i < PAPRD_GAIN_TABLE_ENTRIES; i++) {
-               entry[i] = REG_READ(ah, reg);
-               index[i] = (entry[i] >> 24) & 0xff;
-               reg += 4;
-@@ -246,13 +246,13 @@ static void ar9003_paprd_get_gain_table(
- static unsigned int ar9003_get_desired_gain(struct ath_hw *ah, int chain,
-                                           int target_power)
- {
--      int olpc_gain_delta = 0;
-+      int olpc_gain_delta = 0, cl_gain_mod;
-       int alpha_therm, alpha_volt;
-       int therm_cal_value, volt_cal_value;
-       int therm_value, volt_value;
-       int thermal_gain_corr, voltage_gain_corr;
-       int desired_scale, desired_gain = 0;
--      u32 reg;
-+      u32 reg_olpc  = 0, reg_cl_gain  = 0;
-       REG_CLR_BIT(ah, AR_PHY_PAPRD_TRAINER_STAT1,
-                   AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE);
-@@ -271,15 +271,29 @@ static unsigned int ar9003_get_desired_g
-       volt_value = REG_READ_FIELD(ah, AR_PHY_BB_THERM_ADC_4,
-                                   AR_PHY_BB_THERM_ADC_4_LATEST_VOLT_VALUE);
--      if (chain == 0)
--              reg = AR_PHY_TPC_11_B0;
--      else if (chain == 1)
--              reg = AR_PHY_TPC_11_B1;
--      else
--              reg = AR_PHY_TPC_11_B2;
-+      switch (chain) {
-+      case 0:
-+              reg_olpc = AR_PHY_TPC_11_B0;
-+              reg_cl_gain = AR_PHY_CL_TAB_0;
-+              break;
-+      case 1:
-+              reg_olpc = AR_PHY_TPC_11_B1;
-+              reg_cl_gain = AR_PHY_CL_TAB_1;
-+              break;
-+      case 2:
-+              reg_olpc = AR_PHY_TPC_11_B2;
-+              reg_cl_gain = AR_PHY_CL_TAB_2;
-+              break;
-+      default:
-+              ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
-+              "Invalid chainmask: %d\n", chain);
-+              break;
-+      }
--      olpc_gain_delta = REG_READ_FIELD(ah, reg,
-+      olpc_gain_delta = REG_READ_FIELD(ah, reg_olpc,
-                                        AR_PHY_TPC_11_OLPC_GAIN_DELTA);
-+      cl_gain_mod = REG_READ_FIELD(ah, reg_cl_gain,
-+                                       AR_PHY_CL_TAB_CL_GAIN_MOD);
-       if (olpc_gain_delta >= 128)
-               olpc_gain_delta = olpc_gain_delta - 256;
-@@ -289,7 +303,7 @@ static unsigned int ar9003_get_desired_g
-       voltage_gain_corr = (alpha_volt * (volt_value - volt_cal_value) +
-                            (128 / 2)) / 128;
-       desired_gain = target_power - olpc_gain_delta - thermal_gain_corr -
--          voltage_gain_corr + desired_scale;
-+          voltage_gain_corr + desired_scale + cl_gain_mod;
-       return desired_gain;
- }
-@@ -727,7 +741,7 @@ int ar9003_paprd_setup_gain_table(struct
-       desired_gain = ar9003_get_desired_gain(ah, chain, train_power);
-       gain_index = 0;
--      for (i = 0; i < 32; i++) {
-+      for (i = 0; i < PAPRD_GAIN_TABLE_ENTRIES; i++) {
-               if (ah->paprd_gain_table_index[i] >= desired_gain)
-                       break;
-               gain_index++;
---- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h
-+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
-@@ -1121,6 +1121,9 @@
- #define AR_PHY_POWERTX_RATE8_POWERTXHT40_5    0x3F00
- #define AR_PHY_POWERTX_RATE8_POWERTXHT40_5_S  8
-+#define AR_PHY_CL_TAB_CL_GAIN_MOD             0x1f
-+#define AR_PHY_CL_TAB_CL_GAIN_MOD_S           0
++static const struct ieee80211_iface_limit if_limits[] = {
++      { .max = 2048,  .types = BIT(NL80211_IFTYPE_STATION) |
++                               BIT(NL80211_IFTYPE_P2P_CLIENT) |
++                               BIT(NL80211_IFTYPE_WDS) },
++      { .max = 8,     .types =
++#ifdef CONFIG_MAC80211_MESH
++                               BIT(NL80211_IFTYPE_MESH_POINT) |
++#endif
++                               BIT(NL80211_IFTYPE_AP) |
++                               BIT(NL80211_IFTYPE_P2P_GO) },
++};
 +
- void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx);
- #endif  /* AR9003_PHY_H */
---- a/drivers/net/wireless/ath/ath5k/eeprom.c
-+++ b/drivers/net/wireless/ath/ath5k/eeprom.c
-@@ -691,14 +691,12 @@ ath5k_eeprom_free_pcal_info(struct ath5k
-               if (!chinfo[pier].pd_curves)
-                       continue;
--              for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
-+              for (pdg = 0; pdg < AR5K_EEPROM_N_PD_CURVES; pdg++) {
-                       struct ath5k_pdgain_info *pd =
-                                       &chinfo[pier].pd_curves[pdg];
--                      if (pd != NULL) {
--                              kfree(pd->pd_step);
--                              kfree(pd->pd_pwr);
--                      }
-+                      kfree(pd->pd_step);
-+                      kfree(pd->pd_pwr);
-               }
-               kfree(chinfo[pier].pd_curves);
---- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
-+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
-@@ -229,6 +229,7 @@ static void ar9003_hw_fill_txdesc(struct
- static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
-                                struct ath_tx_status *ts)
++static const struct ieee80211_iface_combination if_comb = {
++      .limits = if_limits,
++      .n_limits = ARRAY_SIZE(if_limits),
++      .max_interfaces = 2048,
++      .num_different_channels = 1,
++};
+ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
  {
-+      struct ar9003_txc *txc = (struct ar9003_txc *) ds;
-       struct ar9003_txs *ads;
-       u32 status;
-@@ -238,7 +239,11 @@ static int ar9003_hw_proc_txdesc(struct 
-       if ((status & AR_TxDone) == 0)
-               return -EINPROGRESS;
--      ah->ts_tail = (ah->ts_tail + 1) % ah->ts_size;
-+      ts->qid = MS(ads->ds_info, AR_TxQcuNum);
-+      if (!txc || (MS(txc->info, AR_TxQcuNum) == ts->qid))
-+              ah->ts_tail = (ah->ts_tail + 1) % ah->ts_size;
-+      else
-+              return -ENOENT;
-       if ((MS(ads->ds_info, AR_DescId) != ATHEROS_VENDOR_ID) ||
-           (MS(ads->ds_info, AR_TxRxDesc) != 1)) {
-@@ -254,7 +259,6 @@ static int ar9003_hw_proc_txdesc(struct 
-       ts->ts_seqnum = MS(status, AR_SeqNum);
-       ts->tid = MS(status, AR_TxTid);
--      ts->qid = MS(ads->ds_info, AR_TxQcuNum);
-       ts->desc_id = MS(ads->status1, AR_TxDescId);
-       ts->ts_tstamp = ads->status4;
-       ts->ts_status = 0;
---- a/net/mac80211/wpa.c
-+++ b/net/mac80211/wpa.c
-@@ -15,6 +15,7 @@
- #include <linux/gfp.h>
- #include <asm/unaligned.h>
- #include <net/mac80211.h>
-+#include <crypto/aes.h>
- #include "ieee80211_i.h"
- #include "michael.h"
-@@ -86,6 +87,11 @@ ieee80211_rx_h_michael_mic_verify(struct
-       struct sk_buff *skb = rx->skb;
-       struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-+      int queue = rx->queue;
-+
-+      /* otherwise, TKIP is vulnerable to TID 0 vs. non-QoS replays */
-+      if (rx->queue == NUM_RX_DATA_QUEUES - 1)
-+              queue = 0;
-       /*
-        * it makes no sense to check for MIC errors on anything other
-@@ -148,8 +154,8 @@ ieee80211_rx_h_michael_mic_verify(struct
- update_iv:
-       /* update IV in key information to be able to detect replays */
--      rx->key->u.tkip.rx[rx->queue].iv32 = rx->tkip_iv32;
--      rx->key->u.tkip.rx[rx->queue].iv16 = rx->tkip_iv16;
-+      rx->key->u.tkip.rx[queue].iv32 = rx->tkip_iv32;
-+      rx->key->u.tkip.rx[queue].iv16 = rx->tkip_iv16;
-       return RX_CONTINUE;
-@@ -165,6 +171,7 @@ static int tkip_encrypt_skb(struct ieee8
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
-       struct ieee80211_key *key = tx->key;
-       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-+      unsigned long flags;
-       unsigned int hdrlen;
-       int len, tail;
-       u8 *pos;
-@@ -192,11 +199,12 @@ static int tkip_encrypt_skb(struct ieee8
-       pos += hdrlen;
-       /* Increase IV for the frame */
-+      spin_lock_irqsave(&key->u.tkip.txlock, flags);
-       key->u.tkip.tx.iv16++;
-       if (key->u.tkip.tx.iv16 == 0)
-               key->u.tkip.tx.iv32++;
--
--      pos = ieee80211_tkip_add_iv(pos, key, key->u.tkip.tx.iv16);
-+      pos = ieee80211_tkip_add_iv(pos, key);
-+      spin_unlock_irqrestore(&key->u.tkip.txlock, flags);
-       /* hwaccel - with software IV */
-       if (info->control.hw_key)
-@@ -205,9 +213,8 @@ static int tkip_encrypt_skb(struct ieee8
-       /* Add room for ICV */
-       skb_put(skb, TKIP_ICV_LEN);
--      hdr = (struct ieee80211_hdr *) skb->data;
-       return ieee80211_tkip_encrypt_data(tx->local->wep_tx_tfm,
--                                         key, pos, len, hdr->addr2);
-+                                         key, skb, pos, len);
- }
+@@ -676,6 +694,9 @@ void ath9k_set_hw_capab(struct ath_softc
+               BIT(NL80211_IFTYPE_ADHOC) |
+               BIT(NL80211_IFTYPE_MESH_POINT);
  
-@@ -235,6 +242,11 @@ ieee80211_crypto_tkip_decrypt(struct iee
-       struct ieee80211_key *key = rx->key;
-       struct sk_buff *skb = rx->skb;
-       struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
-+      int queue = rx->queue;
++      hw->wiphy->iface_combinations = &if_comb;
++      hw->wiphy->n_iface_combinations = 1;
 +
-+      /* otherwise, TKIP is vulnerable to TID 0 vs. non-QoS replays */
-+      if (rx->queue == NUM_RX_DATA_QUEUES - 1)
-+              queue = 0;
-       hdrlen = ieee80211_hdrlen(hdr->frame_control);
-@@ -255,7 +267,7 @@ ieee80211_crypto_tkip_decrypt(struct iee
-       res = ieee80211_tkip_decrypt_data(rx->local->wep_rx_tfm,
-                                         key, skb->data + hdrlen,
-                                         skb->len - hdrlen, rx->sta->sta.addr,
--                                        hdr->addr1, hwaccel, rx->queue,
-+                                        hdr->addr1, hwaccel, queue,
-                                         &rx->tkip_iv32,
-                                         &rx->tkip_iv16);
-       if (res != TKIP_DECRYPT_OK)
-@@ -283,6 +295,8 @@ static void ccmp_special_blocks(struct s
-       unsigned int hdrlen;
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-+      memset(scratch, 0, 6 * AES_BLOCK_LEN);
-+
-       b_0 = scratch + 3 * AES_BLOCK_LEN;
-       aad = scratch + 4 * AES_BLOCK_LEN;
-@@ -373,8 +387,10 @@ static int ccmp_encrypt_skb(struct ieee8
-       struct ieee80211_key *key = tx->key;
-       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       int hdrlen, len, tail;
--      u8 *pos, *pn;
--      int i;
-+      u8 *pos;
-+      u8 pn[6];
-+      u64 pn64;
-+      u8 scratch[6 * AES_BLOCK_LEN];
-       if (info->control.hw_key &&
-           !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
-@@ -402,14 +418,14 @@ static int ccmp_encrypt_skb(struct ieee8
-       hdr = (struct ieee80211_hdr *) pos;
-       pos += hdrlen;
--      /* PN = PN + 1 */
--      pn = key->u.ccmp.tx_pn;
-+      pn64 = atomic64_inc_return(&key->u.ccmp.tx_pn);
--      for (i = CCMP_PN_LEN - 1; i >= 0; i--) {
--              pn[i]++;
--              if (pn[i])
--                      break;
--      }
-+      pn[5] = pn64;
-+      pn[4] = pn64 >> 8;
-+      pn[3] = pn64 >> 16;
-+      pn[2] = pn64 >> 24;
-+      pn[1] = pn64 >> 32;
-+      pn[0] = pn64 >> 40;
-       ccmp_pn2hdr(pos, pn, key->conf.keyidx);
-@@ -418,8 +434,8 @@ static int ccmp_encrypt_skb(struct ieee8
-               return 0;
-       pos += CCMP_HDR_LEN;
--      ccmp_special_blocks(skb, pn, key->u.ccmp.tx_crypto_buf, 0);
--      ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, key->u.ccmp.tx_crypto_buf, pos, len,
-+      ccmp_special_blocks(skb, pn, scratch, 0);
-+      ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, scratch, pos, len,
-                                 pos, skb_put(skb, CCMP_MIC_LEN));
-       return 0;
-@@ -475,11 +491,12 @@ ieee80211_crypto_ccmp_decrypt(struct iee
-       }
-       if (!(status->flag & RX_FLAG_DECRYPTED)) {
-+              u8 scratch[6 * AES_BLOCK_LEN];
-               /* hardware didn't decrypt/verify MIC */
--              ccmp_special_blocks(skb, pn, key->u.ccmp.rx_crypto_buf, 1);
-+              ccmp_special_blocks(skb, pn, scratch, 1);
-               if (ieee80211_aes_ccm_decrypt(
--                          key->u.ccmp.tfm, key->u.ccmp.rx_crypto_buf,
-+                          key->u.ccmp.tfm, scratch,
-                           skb->data + hdrlen + CCMP_HDR_LEN, data_len,
-                           skb->data + skb->len - CCMP_MIC_LEN,
-                           skb->data + hdrlen + CCMP_HDR_LEN))
---- a/drivers/net/wireless/b43/xmit.c
-+++ b/drivers/net/wireless/b43/xmit.c
-@@ -323,8 +323,7 @@ int b43_generate_txhdr(struct b43_wldev 
-                       /* we give the phase1key and iv16 here, the key is stored in
-                        * shm. With that the hardware can do phase 2 and encryption.
+       if (AR_SREV_5416(sc->sc_ah))
+               hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
+--- a/net/mac80211/ibss.c
++++ b/net/mac80211/ibss.c
+@@ -455,8 +455,8 @@ static void ieee80211_rx_bss_info(struct
+                        * fall back to HT20 if we don't use or use
+                        * the other extension channel
                         */
--                      ieee80211_get_tkip_key(info->control.hw_key, skb_frag,
--                                      IEEE80211_TKIP_P1_KEY, (u8*)phase1key);
-+                      ieee80211_get_tkip_p1k(info->control.hw_key, skb_frag, phase1key);
-                       /* phase1key is in host endian. Copy to little-endian txhdr->iv. */
-                       for (i = 0; i < 5; i++) {
-                               txhdr->iv[i * 2 + 0] = phase1key[i];
---- a/drivers/net/wireless/iwlegacy/iwl-4965-tx.c
-+++ b/drivers/net/wireless/iwlegacy/iwl-4965-tx.c
-@@ -240,8 +240,7 @@ static void iwl4965_tx_cmd_build_hwcrypt
-       case WLAN_CIPHER_SUITE_TKIP:
-               tx_cmd->sec_ctl = TX_CMD_SEC_TKIP;
--              ieee80211_get_tkip_key(keyconf, skb_frag,
--                      IEEE80211_TKIP_P2_KEY, tx_cmd->key);
-+              ieee80211_get_tkip_p2k(keyconf, skb_frag, tx_cmd->key);
-               IWL_DEBUG_TX(priv, "tx_cmd with tkip hwcrypto\n");
-               break;
---- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
-+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
-@@ -497,8 +497,7 @@ static void iwlagn_tx_cmd_build_hwcrypto
-       case WLAN_CIPHER_SUITE_TKIP:
-               tx_cmd->sec_ctl = TX_CMD_SEC_TKIP;
--              ieee80211_get_tkip_key(keyconf, skb_frag,
--                      IEEE80211_TKIP_P2_KEY, tx_cmd->key);
-+              ieee80211_get_tkip_p2k(keyconf, skb_frag, tx_cmd->key);
-               IWL_DEBUG_TX(priv, "tx_cmd with tkip hwcrypto\n");
-               break;
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -960,21 +960,6 @@ enum sta_notify_cmd {
- };
- /**
-- * enum ieee80211_tkip_key_type - get tkip key
-- *
-- * Used by drivers which need to get a tkip key for skb. Some drivers need a
-- * phase 1 key, others need a phase 2 key. A single function allows the driver
-- * to get the key, this enum indicates what type of key is required.
-- *
-- * @IEEE80211_TKIP_P1_KEY: the driver needs a phase 1 key
-- * @IEEE80211_TKIP_P2_KEY: the driver needs a phase 2 key
-- */
--enum ieee80211_tkip_key_type {
--      IEEE80211_TKIP_P1_KEY,
--      IEEE80211_TKIP_P2_KEY,
--};
--
--/**
-  * enum ieee80211_hw_flags - hardware flags
-  *
-  * These flags are used to indicate hardware capabilities to
-@@ -2568,21 +2553,33 @@ struct sk_buff *
- ieee80211_get_buffered_bc(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
- /**
-- * ieee80211_get_tkip_key - get a TKIP rc4 for skb
-+ * ieee80211_get_tkip_p1k - get a TKIP phase 1 key
-+ *
-+ * This function returns the TKIP phase 1 key for the IV32 taken
-+ * from the given packet.
-+ *
-+ * @keyconf: the parameter passed with the set key
-+ * @skb: the packet to take the IV32 value from that will be encrypted
-+ *    with this P1K
-+ * @p1k: a buffer to which the key will be written, as 5 u16 values
-+ */
-+void ieee80211_get_tkip_p1k(struct ieee80211_key_conf *keyconf,
-+                          struct sk_buff *skb, u16 *p1k);
-+
-+/**
-+ * ieee80211_get_tkip_p2k - get a TKIP phase 2 key
-  *
-- * This function computes a TKIP rc4 key for an skb. It computes
-- * a phase 1 key if needed (iv16 wraps around). This function is to
-- * be used by drivers which can do HW encryption but need to compute
-- * to phase 1/2 key in SW.
-+ * This function computes the TKIP RC4 key for the IV values
-+ * in the packet.
-  *
-  * @keyconf: the parameter passed with the set key
-- * @skb: the skb for which the key is needed
-- * @type: TBD
-- * @key: a buffer to which the key will be written
-- */
--void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf,
--                              struct sk_buff *skb,
--                              enum ieee80211_tkip_key_type type, u8 *key);
-+ * @skb: the packet to take the IV32/IV16 values from that will be
-+ *    encrypted with this key
-+ * @p2k: a buffer to which the key will be written, 16 bytes
-+ */
-+void ieee80211_get_tkip_p2k(struct ieee80211_key_conf *keyconf,
-+                          struct sk_buff *skb, u8 *p2k);
-+
- /**
-  * ieee80211_wake_queue - wake specific queue
-  * @hw: pointer as obtained from ieee80211_alloc_hw().
---- a/net/mac80211/key.c
-+++ b/net/mac80211/key.c
-@@ -333,6 +333,7 @@ struct ieee80211_key *ieee80211_key_allo
-                                       get_unaligned_le16(seq);
-                       }
-               }
-+              spin_lock_init(&key->u.tkip.txlock);
-               break;
-       case WLAN_CIPHER_SUITE_CCMP:
-               key->conf.iv_len = CCMP_HDR_LEN;
---- a/net/mac80211/key.h
-+++ b/net/mac80211/key.h
-@@ -52,9 +52,10 @@ enum ieee80211_internal_tkip_state {
- };
- struct tkip_ctx {
--      u32 iv32;
--      u16 iv16;
--      u16 p1k[5];
-+      u32 iv32;       /* current iv32 */
-+      u16 iv16;       /* current iv16 */
-+      u16 p1k[5];     /* p1k cache */
-+      u32 p1k_iv32;   /* iv32 for which p1k computed */
-       enum ieee80211_internal_tkip_state state;
- };
-@@ -71,6 +72,9 @@ struct ieee80211_key {
-       union {
-               struct {
-+                      /* protects tx context */
-+                      spinlock_t txlock;
-+
-                       /* last used TSC */
-                       struct tkip_ctx tx;
-@@ -78,7 +82,7 @@ struct ieee80211_key {
-                       struct tkip_ctx rx[NUM_RX_DATA_QUEUES];
-               } tkip;
-               struct {
--                      u8 tx_pn[6];
-+                      atomic64_t tx_pn;
-                       /*
-                        * Last received packet number. The first
-                        * NUM_RX_DATA_QUEUES counters are used with Data
-@@ -88,12 +92,9 @@ struct ieee80211_key {
-                       u8 rx_pn[NUM_RX_DATA_QUEUES + 1][6];
-                       struct crypto_cipher *tfm;
-                       u32 replays; /* dot11RSNAStatsCCMPReplays */
--                      /* scratch buffers for virt_to_page() (crypto API) */
- #ifndef AES_BLOCK_LEN
- #define AES_BLOCK_LEN 16
- #endif
--                      u8 tx_crypto_buf[6 * AES_BLOCK_LEN];
--                      u8 rx_crypto_buf[6 * AES_BLOCK_LEN];
-               } ccmp;
-               struct {
-                       u8 tx_pn[6];
---- a/net/mac80211/tkip.c
-+++ b/net/mac80211/tkip.c
-@@ -101,6 +101,7 @@ static void tkip_mixing_phase1(const u8 
-               p1k[4] += tkipS(p1k[3] ^ get_unaligned_le16(tk + 0 + j)) + i;
-       }
-       ctx->state = TKIP_STATE_PHASE1_DONE;
-+      ctx->p1k_iv32 = tsc_IV32;
- }
- static void tkip_mixing_phase2(const u8 *tk, struct tkip_ctx *ctx,
-@@ -140,60 +141,72 @@ static void tkip_mixing_phase2(const u8 
- /* Add TKIP IV and Ext. IV at @pos. @iv0, @iv1, and @iv2 are the first octets
-  * of the IV. Returns pointer to the octet following IVs (i.e., beginning of
-  * the packet payload). */
--u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, u16 iv16)
-+u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key)
- {
--      pos = write_tkip_iv(pos, iv16);
-+      lockdep_assert_held(&key->u.tkip.txlock);
-+
-+      pos = write_tkip_iv(pos, key->u.tkip.tx.iv16);
-       *pos++ = (key->conf.keyidx << 6) | (1 << 5) /* Ext IV */;
-       put_unaligned_le32(key->u.tkip.tx.iv32, pos);
-       return pos + 4;
- }
--void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf,
--                      struct sk_buff *skb, enum ieee80211_tkip_key_type type,
--                      u8 *outkey)
-+static void ieee80211_compute_tkip_p1k(struct ieee80211_key *key, u32 iv32)
- {
--      struct ieee80211_key *key = (struct ieee80211_key *)
--                      container_of(keyconf, struct ieee80211_key, conf);
--      struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
--      u8 *data;
--      const u8 *tk;
--      struct tkip_ctx *ctx;
--      u16 iv16;
--      u32 iv32;
--
--      data = (u8 *)hdr + ieee80211_hdrlen(hdr->frame_control);
--      iv16 = data[2] | (data[0] << 8);
--      iv32 = get_unaligned_le32(&data[4]);
--
--      tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY];
--      ctx = &key->u.tkip.tx;
--
--#ifdef CONFIG_MAC80211_TKIP_DEBUG
--      printk(KERN_DEBUG "TKIP encrypt: iv16 = 0x%04x, iv32 = 0x%08x\n",
--                      iv16, iv32);
-+      struct ieee80211_sub_if_data *sdata = key->sdata;
-+      struct tkip_ctx *ctx = &key->u.tkip.tx;
-+      const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY];
--      if (iv32 != ctx->iv32) {
--              printk(KERN_DEBUG "skb: iv32 = 0x%08x key: iv32 = 0x%08x\n",
--                      iv32, ctx->iv32);
--              printk(KERN_DEBUG "Wrap around of iv16 in the middle of a "
--                      "fragmented packet\n");
--      }
--#endif
-+      lockdep_assert_held(&key->u.tkip.txlock);
--      /* Update the p1k only when the iv16 in the packet wraps around, this
--       * might occur after the wrap around of iv16 in the key in case of
--       * fragmented packets. */
--      if (iv16 == 0 || ctx->state == TKIP_STATE_NOT_INIT)
--              tkip_mixing_phase1(tk, ctx, hdr->addr2, iv32);
-+      /*
-+       * Update the P1K when the IV32 is different from the value it
-+       * had when we last computed it (or when not initialised yet).
-+       * This might flip-flop back and forth if packets are processed
-+       * out-of-order due to the different ACs, but then we have to
-+       * just compute the P1K more often.
-+       */
-+      if (ctx->p1k_iv32 != iv32 || ctx->state == TKIP_STATE_NOT_INIT)
-+              tkip_mixing_phase1(tk, ctx, sdata->vif.addr, iv32);
-+}
--      if (type == IEEE80211_TKIP_P1_KEY) {
--              memcpy(outkey, ctx->p1k, sizeof(u16) * 5);
--              return;
--      }
-+void ieee80211_get_tkip_p1k(struct ieee80211_key_conf *keyconf,
-+                          struct sk_buff *skb, u16 *p1k)
-+{
-+      struct ieee80211_key *key = (struct ieee80211_key *)
-+                      container_of(keyconf, struct ieee80211_key, conf);
-+      struct tkip_ctx *ctx = &key->u.tkip.tx;
-+      struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-+      const u8 *data = (u8 *)hdr + ieee80211_hdrlen(hdr->frame_control);
-+      u32 iv32 = get_unaligned_le32(&data[4]);
-+      unsigned long flags;
-+
-+      spin_lock_irqsave(&key->u.tkip.txlock, flags);
-+      ieee80211_compute_tkip_p1k(key, iv32);
-+      memcpy(p1k, ctx->p1k, sizeof(ctx->p1k));
-+      spin_unlock_irqrestore(&key->u.tkip.txlock, flags);
-+}
-+EXPORT_SYMBOL(ieee80211_get_tkip_p1k);
--      tkip_mixing_phase2(tk, ctx, iv16, outkey);
-+void ieee80211_get_tkip_p2k(struct ieee80211_key_conf *keyconf,
-+                          struct sk_buff *skb, u8 *p2k)
-+{
-+      struct ieee80211_key *key = (struct ieee80211_key *)
-+                      container_of(keyconf, struct ieee80211_key, conf);
-+      const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY];
-+      struct tkip_ctx *ctx = &key->u.tkip.tx;
-+      struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-+      const u8 *data = (u8 *)hdr + ieee80211_hdrlen(hdr->frame_control);
-+      u32 iv32 = get_unaligned_le32(&data[4]);
-+      u16 iv16 = data[2] | (data[0] << 8);
-+      unsigned long flags;
-+
-+      spin_lock_irqsave(&key->u.tkip.txlock, flags);
-+      ieee80211_compute_tkip_p1k(key, iv32);
-+      tkip_mixing_phase2(tk, ctx, iv16, p2k);
-+      spin_unlock_irqrestore(&key->u.tkip.txlock, flags);
- }
--EXPORT_SYMBOL(ieee80211_get_tkip_key);
-+EXPORT_SYMBOL(ieee80211_get_tkip_p2k);
- /*
-  * Encrypt packet payload with TKIP using @key. @pos is a pointer to the
-@@ -204,19 +217,15 @@ EXPORT_SYMBOL(ieee80211_get_tkip_key);
-  */
- int ieee80211_tkip_encrypt_data(struct crypto_cipher *tfm,
-                               struct ieee80211_key *key,
--                              u8 *pos, size_t payload_len, u8 *ta)
-+                              struct sk_buff *skb,
-+                              u8 *payload, size_t payload_len)
- {
-       u8 rc4key[16];
--      struct tkip_ctx *ctx = &key->u.tkip.tx;
--      const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY];
--
--      /* Calculate per-packet key */
--      if (ctx->iv16 == 0 || ctx->state == TKIP_STATE_NOT_INIT)
--              tkip_mixing_phase1(tk, ctx, ta, ctx->iv32);
--      tkip_mixing_phase2(tk, ctx, ctx->iv16, rc4key);
-+      ieee80211_get_tkip_p2k(&key->conf, skb, rc4key);
--      return ieee80211_wep_encrypt_data(tfm, rc4key, 16, pos, payload_len);
-+      return ieee80211_wep_encrypt_data(tfm, rc4key, 16,
-+                                        payload, payload_len);
- }
- /* Decrypt packet payload with TKIP using @key. @pos is a pointer to the
---- a/net/mac80211/tkip.h
-+++ b/net/mac80211/tkip.h
-@@ -13,11 +13,13 @@
- #include <linux/crypto.h>
- #include "key.h"
--u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, u16 iv16);
-+u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key);
- int ieee80211_tkip_encrypt_data(struct crypto_cipher *tfm,
--                               struct ieee80211_key *key,
--                               u8 *pos, size_t payload_len, u8 *ta);
-+                              struct ieee80211_key *key,
-+                              struct sk_buff *skb,
-+                              u8 *payload, size_t payload_len);
-+
- enum {
-       TKIP_DECRYPT_OK = 0,
-       TKIP_DECRYPT_NO_EXT_IV = -1,
---- a/net/mac80211/cfg.c
-+++ b/net/mac80211/cfg.c
-@@ -209,6 +209,7 @@ static int ieee80211_get_key(struct wiph
-       u8 seq[6] = {0};
-       struct key_params params;
-       struct ieee80211_key *key = NULL;
-+      u64 pn64;
-       u32 iv32;
-       u16 iv16;
-       int err = -ENOENT;
-@@ -256,12 +257,13 @@ static int ieee80211_get_key(struct wiph
-               params.seq_len = 6;
-               break;
-       case WLAN_CIPHER_SUITE_CCMP:
--              seq[0] = key->u.ccmp.tx_pn[5];
--              seq[1] = key->u.ccmp.tx_pn[4];
--              seq[2] = key->u.ccmp.tx_pn[3];
--              seq[3] = key->u.ccmp.tx_pn[2];
--              seq[4] = key->u.ccmp.tx_pn[1];
--              seq[5] = key->u.ccmp.tx_pn[0];
-+              pn64 = atomic64_read(&key->u.ccmp.tx_pn);
-+              seq[0] = pn64;
-+              seq[1] = pn64 >> 8;
-+              seq[2] = pn64 >> 16;
-+              seq[3] = pn64 >> 24;
-+              seq[4] = pn64 >> 32;
-+              seq[5] = pn64 >> 40;
-               params.seq = seq;
-               params.seq_len = 6;
-               break;
---- a/net/mac80211/debugfs_key.c
-+++ b/net/mac80211/debugfs_key.c
-@@ -79,6 +79,7 @@ static ssize_t key_tx_spec_read(struct f
-                               size_t count, loff_t *ppos)
- {
-       const u8 *tpn;
-+      u64 pn;
-       char buf[20];
-       int len;
-       struct ieee80211_key *key = file->private_data;
-@@ -94,9 +95,10 @@ static ssize_t key_tx_spec_read(struct f
-                               key->u.tkip.tx.iv16);
-               break;
-       case WLAN_CIPHER_SUITE_CCMP:
--              tpn = key->u.ccmp.tx_pn;
-+              pn = atomic64_read(&key->u.ccmp.tx_pn);
-               len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n",
--                              tpn[0], tpn[1], tpn[2], tpn[3], tpn[4], tpn[5]);
-+                              (u8)(pn >> 40), (u8)(pn >> 32), (u8)(pn >> 24),
-+                              (u8)(pn >> 16), (u8)(pn >> 8), (u8)pn);
-               break;
-       case WLAN_CIPHER_SUITE_AES_CMAC:
-               tpn = key->u.aes_cmac.tx_pn;
+-                      if ((channel_type == NL80211_CHAN_HT40MINUS ||
+-                           channel_type == NL80211_CHAN_HT40PLUS) &&
++                      if (!(channel_type == NL80211_CHAN_HT40MINUS ||
++                            channel_type == NL80211_CHAN_HT40PLUS) ||
+                           channel_type != sdata->u.ibss.channel_type)
+                               sta_ht_cap_new.cap &=
+                                       ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;