mac80211: assume 2-byte aligning for 802.11 packets, slightly improves code size...
[openwrt.git] / package / mac80211 / patches / 300-pending_work.patch
index 1fec1b4..4033139 100644 (file)
---- a/drivers/net/wireless/ath/ath9k/ath9k.h
-+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -360,7 +360,7 @@ void ath_tx_aggr_sleep(struct ieee80211_
- struct ath_vif {
-       int av_bslot;
--      bool is_bslot_active, primary_sta_vif;
-+      bool primary_sta_vif;
-       __le64 tsf_adjust; /* TSF adjustment for staggered beacons */
-       struct ath_buf *av_bcbuf;
- };
-@@ -386,6 +386,7 @@ struct ath_beacon_config {
-       u16 dtim_period;
-       u16 bmiss_timeout;
-       u8 dtim_count;
-+      bool enable_beacon;
- };
- struct ath_beacon {
-@@ -397,7 +398,6 @@ struct ath_beacon {
-       u32 beaconq;
-       u32 bmisscnt;
--      u32 ast_be_xmit;
-       u32 bc_tstamp;
-       struct ieee80211_vif *bslot[ATH_BCBUF];
-       int slottime;
-@@ -411,12 +411,14 @@ struct ath_beacon {
-       bool tx_last;
- };
--void ath_beacon_tasklet(unsigned long data);
--void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif);
--int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif);
--void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp);
--int ath_beaconq_config(struct ath_softc *sc);
--void ath_set_beacon(struct ath_softc *sc);
-+void ath9k_beacon_tasklet(unsigned long data);
-+bool ath9k_allow_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif);
-+void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif,
-+                       u32 changed);
-+void ath9k_beacon_assign_slot(struct ath_softc *sc, struct ieee80211_vif *vif);
-+void ath9k_beacon_remove_slot(struct ath_softc *sc, struct ieee80211_vif *vif);
-+void ath9k_set_tsfadjust(struct ath_softc *sc, struct ieee80211_vif *vif);
-+void ath9k_set_beacon(struct ath_softc *sc);
- void ath9k_set_beaconing_status(struct ath_softc *sc, bool status);
- /*******************/
-@@ -442,9 +444,12 @@ void ath_rx_poll(unsigned long data);
- void ath_start_rx_poll(struct ath_softc *sc, u8 nbeacon);
- void ath_paprd_calibrate(struct work_struct *work);
- void ath_ani_calibrate(unsigned long data);
--void ath_start_ani(struct ath_common *common);
-+void ath_start_ani(struct ath_softc *sc);
-+void ath_stop_ani(struct ath_softc *sc);
-+void ath_check_ani(struct ath_softc *sc);
- int ath_update_survey_stats(struct ath_softc *sc);
- void ath_update_survey_nf(struct ath_softc *sc, int channel);
-+void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type);
- /**********/
- /* BTCOEX */
-@@ -613,7 +618,6 @@ enum sc_op_flags {
-       SC_OP_INVALID,
-       SC_OP_BEACONS,
-       SC_OP_RXFLUSH,
--      SC_OP_TSF_RESET,
-       SC_OP_ANI_RUN,
-       SC_OP_PRIM_STA_VIF,
-       SC_OP_HW_RESET,
---- a/drivers/net/wireless/ath/ath9k/beacon.c
-+++ b/drivers/net/wireless/ath/ath9k/beacon.c
-@@ -30,7 +30,7 @@ static void ath9k_reset_beacon_status(st
-  *  the operating mode of the station (AP or AdHoc).  Parameters are AIFS
-  *  settings and channel width min/max
- */
--int ath_beaconq_config(struct ath_softc *sc)
-+static void ath9k_beaconq_config(struct ath_softc *sc)
- {
-       struct ath_hw *ah = sc->sc_ah;
-       struct ath_common *common = ath9k_hw_common(ah);
-@@ -38,6 +38,7 @@ int ath_beaconq_config(struct ath_softc 
-       struct ath_txq *txq;
-       ath9k_hw_get_txq_props(ah, sc->beacon.beaconq, &qi);
-+
-       if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
-               /* Always burst out beacon and CAB traffic. */
-               qi.tqi_aifs = 1;
-@@ -56,12 +57,9 @@ int ath_beaconq_config(struct ath_softc 
-       }
-       if (!ath9k_hw_set_txq_props(ah, sc->beacon.beaconq, &qi)) {
--              ath_err(common,
--                      "Unable to update h/w beacon queue parameters\n");
--              return 0;
-+              ath_err(common, "Unable to update h/w beacon queue parameters\n");
-       } else {
-               ath9k_hw_resettxqueue(ah, sc->beacon.beaconq);
--              return 1;
-       }
- }
-@@ -70,7 +68,7 @@ int ath_beaconq_config(struct ath_softc 
-  *  up rate codes, and channel flags. Beacons are always sent out at the
-  *  lowest rate, and are not retried.
- */
--static void ath_beacon_setup(struct ath_softc *sc, struct ieee80211_vif *vif,
-+static void ath9k_beacon_setup(struct ath_softc *sc, struct ieee80211_vif *vif,
-                            struct ath_buf *bf, int rateidx)
- {
-       struct sk_buff *skb = bf->bf_mpdu;
-@@ -81,8 +79,6 @@ static void ath_beacon_setup(struct ath_
-       u8 chainmask = ah->txchainmask;
-       u8 rate = 0;
--      ath9k_reset_beacon_status(sc);
--
-       sband = &sc->sbands[common->hw->conf.channel->band];
-       rate = sband->bitrates[rateidx].hw_value;
-       if (vif->bss_conf.use_short_preamble)
-@@ -111,7 +107,7 @@ static void ath_beacon_setup(struct ath_
-       ath9k_hw_set_txdesc(ah, bf->bf_desc, &info);
- }
--static void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb)
-+static void ath9k_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb)
- {
-       struct ath_softc *sc = hw->priv;
-       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-@@ -128,28 +124,22 @@ static void ath_tx_cabq(struct ieee80211
-       }
- }
--static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
--                                         struct ieee80211_vif *vif)
-+static struct ath_buf *ath9k_beacon_generate(struct ieee80211_hw *hw,
-+                                           struct ieee80211_vif *vif)
- {
-       struct ath_softc *sc = hw->priv;
-       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-       struct ath_buf *bf;
--      struct ath_vif *avp;
-+      struct ath_vif *avp = (void *)vif->drv_priv;
-       struct sk_buff *skb;
--      struct ath_txq *cabq;
-+      struct ath_txq *cabq = sc->beacon.cabq;
-       struct ieee80211_tx_info *info;
-+      struct ieee80211_mgmt *mgmt_hdr;
-       int cabq_depth;
--      ath9k_reset_beacon_status(sc);
--
--      avp = (void *)vif->drv_priv;
--      cabq = sc->beacon.cabq;
--
--      if ((avp->av_bcbuf == NULL) || !avp->is_bslot_active)
-+      if (avp->av_bcbuf == NULL)
-               return NULL;
--      /* Release the old beacon first */
--
-       bf = avp->av_bcbuf;
-       skb = bf->bf_mpdu;
-       if (skb) {
-@@ -159,14 +149,14 @@ static struct ath_buf *ath_beacon_genera
-               bf->bf_buf_addr = 0;
-       }
--      /* Get a new beacon from mac80211 */
--
-       skb = ieee80211_beacon_get(hw, vif);
--      bf->bf_mpdu = skb;
-       if (skb == NULL)
-               return NULL;
--      ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp =
--              avp->tsf_adjust;
-+
-+      bf->bf_mpdu = skb;
-+
-+      mgmt_hdr = (struct ieee80211_mgmt *)skb->data;
-+      mgmt_hdr->u.beacon.timestamp = avp->tsf_adjust;
-       info = IEEE80211_SKB_CB(skb);
-       if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
-@@ -212,61 +202,52 @@ static struct ath_buf *ath_beacon_genera
-               }
-       }
--      ath_beacon_setup(sc, vif, bf, info->control.rates[0].idx);
-+      ath9k_beacon_setup(sc, vif, bf, info->control.rates[0].idx);
-       while (skb) {
--              ath_tx_cabq(hw, skb);
-+              ath9k_tx_cabq(hw, skb);
-               skb = ieee80211_get_buffered_bc(hw, vif);
-       }
-       return bf;
- }
--int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif)
-+void ath9k_beacon_assign_slot(struct ath_softc *sc, struct ieee80211_vif *vif)
- {
-       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
--      struct ath_vif *avp;
--      struct ath_buf *bf;
--      struct sk_buff *skb;
--      struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
--      __le64 tstamp;
-+      struct ath_vif *avp = (void *)vif->drv_priv;
-+      int slot;
--      avp = (void *)vif->drv_priv;
-+      avp->av_bcbuf = list_first_entry(&sc->beacon.bbuf, struct ath_buf, list);
-+      list_del(&avp->av_bcbuf->list);
--      /* Allocate a beacon descriptor if we haven't done so. */
--      if (!avp->av_bcbuf) {
--              /* Allocate beacon state for hostap/ibss.  We know
--               * a buffer is available. */
--              avp->av_bcbuf = list_first_entry(&sc->beacon.bbuf,
--                                               struct ath_buf, list);
--              list_del(&avp->av_bcbuf->list);
--
--              if (ath9k_uses_beacons(vif->type)) {
--                      int slot;
--                      /*
--                       * Assign the vif to a beacon xmit slot. As
--                       * above, this cannot fail to find one.
--                       */
--                      avp->av_bslot = 0;
--                      for (slot = 0; slot < ATH_BCBUF; slot++)
--                              if (sc->beacon.bslot[slot] == NULL) {
--                                      avp->av_bslot = slot;
--                                      avp->is_bslot_active = false;
--
--                                      /* NB: keep looking for a double slot */
--                                      if (slot == 0 || !sc->beacon.bslot[slot-1])
--                                              break;
--                              }
--                      BUG_ON(sc->beacon.bslot[avp->av_bslot] != NULL);
--                      sc->beacon.bslot[avp->av_bslot] = vif;
--                      sc->nbcnvifs++;
-+      for (slot = 0; slot < ATH_BCBUF; slot++) {
-+              if (sc->beacon.bslot[slot] == NULL) {
-+                      avp->av_bslot = slot;
-+                      break;
-               }
-       }
--      /* release the previous beacon frame, if it already exists. */
--      bf = avp->av_bcbuf;
--      if (bf->bf_mpdu != NULL) {
--              skb = bf->bf_mpdu;
-+      sc->beacon.bslot[avp->av_bslot] = vif;
-+      sc->nbcnvifs++;
-+
-+      ath_dbg(common, CONFIG, "Added interface at beacon slot: %d\n",
-+              avp->av_bslot);
-+}
-+
-+void ath9k_beacon_remove_slot(struct ath_softc *sc, struct ieee80211_vif *vif)
-+{
-+      struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-+      struct ath_vif *avp = (void *)vif->drv_priv;
-+      struct ath_buf *bf = avp->av_bcbuf;
-+
-+      ath_dbg(common, CONFIG, "Removing interface at beacon slot: %d\n",
-+              avp->av_bslot);
-+
-+      tasklet_disable(&sc->bcon_tasklet);
-+
-+      if (bf && bf->bf_mpdu) {
-+              struct sk_buff *skb = bf->bf_mpdu;
-               dma_unmap_single(sc->dev, bf->bf_buf_addr,
-                                skb->len, DMA_TO_DEVICE);
-               dev_kfree_skb_any(skb);
-@@ -274,99 +255,74 @@ int ath_beacon_alloc(struct ath_softc *s
-               bf->bf_buf_addr = 0;
-       }
--      /* NB: the beacon data buffer must be 32-bit aligned. */
--      skb = ieee80211_beacon_get(sc->hw, vif);
--      if (skb == NULL)
--              return -ENOMEM;
--
--      tstamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
--      sc->beacon.bc_tstamp = (u32) le64_to_cpu(tstamp);
--      /* Calculate a TSF adjustment factor required for staggered beacons. */
--      if (avp->av_bslot > 0) {
--              u64 tsfadjust;
--              int intval;
-+      avp->av_bcbuf = NULL;
-+      sc->beacon.bslot[avp->av_bslot] = NULL;
-+      sc->nbcnvifs--;
-+      list_add_tail(&bf->list, &sc->beacon.bbuf);
--              intval = cur_conf->beacon_interval ? : ATH_DEFAULT_BINTVAL;
-+      tasklet_enable(&sc->bcon_tasklet);
-+}
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -5090,7 +5090,8 @@ static int rt2800_probe_hw_mode(struct r
+           IEEE80211_HW_SUPPORTS_PS |
+           IEEE80211_HW_PS_NULLFUNC_STACK |
+           IEEE80211_HW_AMPDU_AGGREGATION |
+-          IEEE80211_HW_REPORTS_TX_ACK_STATUS;
++          IEEE80211_HW_REPORTS_TX_ACK_STATUS |
++          IEEE80211_HW_TEARDOWN_AGGR_ON_BAR_FAIL;
  
+       /*
+        * Don't set IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING for USB devices
+--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
++++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
+@@ -392,10 +392,9 @@ void rt2x00lib_txdone(struct queue_entry
+               tx_info->flags |= IEEE80211_TX_STAT_AMPDU;
+               tx_info->status.ampdu_len = 1;
+               tx_info->status.ampdu_ack_len = success ? 1 : 0;
 -              /*
--               * Calculate the TSF offset for this beacon slot, i.e., the
--               * number of usecs that need to be added to the timestamp field
--               * in Beacon and Probe Response frames. Beacon slot 0 is
--               * processed at the correct offset, so it does not require TSF
--               * adjustment. Other slots are adjusted to get the timestamp
--               * close to the TBTT for the BSS.
+-               * TODO: Need to tear down BA session here
+-               * if not successful.
 -               */
--              tsfadjust = TU_TO_USEC(intval * avp->av_bslot) / ATH_BCBUF;
--              avp->tsf_adjust = cpu_to_le64(tsfadjust);
-+static int ath9k_beacon_choose_slot(struct ath_softc *sc)
-+{
-+      struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-+      struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
-+      u16 intval;
-+      u32 tsftu;
-+      u64 tsf;
-+      int slot;
--              ath_dbg(common, BEACON,
--                      "stagger beacons, bslot %d intval %u tsfadjust %llu\n",
--                      avp->av_bslot, intval, (unsigned long long)tsfadjust);
-+      if (sc->sc_ah->opmode != NL80211_IFTYPE_AP) {
-+              ath_dbg(common, BEACON, "slot 0, tsf: %llu\n",
-+                      ath9k_hw_gettsf64(sc->sc_ah));
-+              return 0;
-+      }
--              ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp =
--                      avp->tsf_adjust;
--      } else
--              avp->tsf_adjust = cpu_to_le64(0);
-+      intval = cur_conf->beacon_interval ? : ATH_DEFAULT_BINTVAL;
-+      tsf = ath9k_hw_gettsf64(sc->sc_ah);
-+      tsf += TU_TO_USEC(sc->sc_ah->config.sw_beacon_response_time);
-+      tsftu = TSF_TO_TU((tsf * ATH_BCBUF) >>32, tsf * ATH_BCBUF);
-+      slot = (tsftu % (intval * ATH_BCBUF)) / intval;
--      bf->bf_mpdu = skb;
--      bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
--                                       skb->len, DMA_TO_DEVICE);
--      if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) {
--              dev_kfree_skb_any(skb);
--              bf->bf_mpdu = NULL;
--              bf->bf_buf_addr = 0;
--              ath_err(common, "dma_mapping_error on beacon alloc\n");
--              return -ENOMEM;
--      }
--      avp->is_bslot_active = true;
-+      ath_dbg(common, BEACON, "slot: %d tsf: %llu tsftu: %u\n",
-+              slot, tsf, tsftu / ATH_BCBUF);
--      return 0;
-+      return slot;
- }
--void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp)
-+void ath9k_set_tsfadjust(struct ath_softc *sc, struct ieee80211_vif *vif)
- {
--      if (avp->av_bcbuf != NULL) {
--              struct ath_buf *bf;
-+      struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-+      struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
-+      struct ath_vif *avp = (void *)vif->drv_priv;
-+      u64 tsfadjust;
--              avp->is_bslot_active = false;
--              if (avp->av_bslot != -1) {
--                      sc->beacon.bslot[avp->av_bslot] = NULL;
--                      sc->nbcnvifs--;
--                      avp->av_bslot = -1;
--              }
-+      if (avp->av_bslot == 0)
-+              return;
--              bf = avp->av_bcbuf;
--              if (bf->bf_mpdu != NULL) {
--                      struct sk_buff *skb = bf->bf_mpdu;
--                      dma_unmap_single(sc->dev, bf->bf_buf_addr,
--                                       skb->len, DMA_TO_DEVICE);
--                      dev_kfree_skb_any(skb);
--                      bf->bf_mpdu = NULL;
--                      bf->bf_buf_addr = 0;
--              }
--              list_add_tail(&bf->list, &sc->beacon.bbuf);
-+      tsfadjust = cur_conf->beacon_interval * avp->av_bslot / ATH_BCBUF;
-+      avp->tsf_adjust = cpu_to_le64(TU_TO_USEC(tsfadjust));
--              avp->av_bcbuf = NULL;
--      }
-+      ath_dbg(common, CONFIG, "tsfadjust is: %llu for bslot: %d\n",
-+              (unsigned long long)tsfadjust, avp->av_bslot);
- }
--void ath_beacon_tasklet(unsigned long data)
-+void ath9k_beacon_tasklet(unsigned long data)
- {
-       struct ath_softc *sc = (struct ath_softc *)data;
--      struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
-       struct ath_hw *ah = sc->sc_ah;
-       struct ath_common *common = ath9k_hw_common(ah);
-       struct ath_buf *bf = NULL;
-       struct ieee80211_vif *vif;
-       bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA);
-       int slot;
--      u32 bfaddr, bc = 0;
--      if (work_pending(&sc->hw_reset_work)) {
-+      if (test_bit(SC_OP_HW_RESET, &sc->sc_flags)) {
-               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
-@@ -390,55 +346,25 @@ void ath_beacon_tasklet(unsigned long da
-               } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) {
-                       ath_dbg(common, BSTUCK, "beacon is officially stuck\n");
-                       sc->beacon.bmisscnt = 0;
--                      set_bit(SC_OP_TSF_RESET, &sc->sc_flags);
--                      ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
-+                      ath9k_queue_reset(sc, RESET_TYPE_BEACON_STUCK);
-               }
-               return;
++              if (!success)
++                      tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
        }
  
--      /*
--       * Generate beacon frames. we are sending frames
--       * staggered so calculate the slot for this frame based
--       * on the tsf to safeguard against missing an swba.
--       */
--
--
--      if (ah->opmode == NL80211_IFTYPE_AP) {
--              u16 intval;
--              u32 tsftu;
--              u64 tsf;
--
--              intval = cur_conf->beacon_interval ? : ATH_DEFAULT_BINTVAL;
--              tsf = ath9k_hw_gettsf64(ah);
--              tsf += TU_TO_USEC(ah->config.sw_beacon_response_time);
--              tsftu = TSF_TO_TU((tsf * ATH_BCBUF) >>32, tsf * ATH_BCBUF);
--              slot = (tsftu % (intval * ATH_BCBUF)) / intval;
--              vif = sc->beacon.bslot[slot];
--
--              ath_dbg(common, BEACON,
--                      "slot %d [tsf %llu tsftu %u intval %u] vif %p\n",
--                      slot, tsf, tsftu / ATH_BCBUF, intval, vif);
--      } else {
--              slot = 0;
--              vif = sc->beacon.bslot[slot];
--      }
-+      slot = ath9k_beacon_choose_slot(sc);
-+      vif = sc->beacon.bslot[slot];
-+      if (!vif || !vif->bss_conf.enable_beacon)
-+              return;
--      bfaddr = 0;
--      if (vif) {
--              bf = ath_beacon_generate(sc->hw, vif);
--              if (bf != NULL) {
--                      bfaddr = bf->bf_daddr;
--                      bc = 1;
--              }
-+      bf = ath9k_beacon_generate(sc->hw, vif);
-+      WARN_ON(!bf);
--              if (sc->beacon.bmisscnt != 0) {
--                      ath_dbg(common, BSTUCK,
--                              "resume beacon xmit after %u misses\n",
--                              sc->beacon.bmisscnt);
--                      sc->beacon.bmisscnt = 0;
--              }
-+      if (sc->beacon.bmisscnt != 0) {
-+              ath_dbg(common, BSTUCK, "resume beacon xmit after %u misses\n",
-+                      sc->beacon.bmisscnt);
-+              sc->beacon.bmisscnt = 0;
-       }
-       /*
-@@ -458,39 +384,37 @@ void ath_beacon_tasklet(unsigned long da
-        *     set to ATH_BCBUF so this check is a noop.
-        */
-       if (sc->beacon.updateslot == UPDATE) {
--              sc->beacon.updateslot = COMMIT; /* commit next beacon */
-+              sc->beacon.updateslot = COMMIT;
-               sc->beacon.slotupdate = slot;
--      } else if (sc->beacon.updateslot == COMMIT && sc->beacon.slotupdate == slot) {
-+      } else if (sc->beacon.updateslot == COMMIT &&
-+                 sc->beacon.slotupdate == slot) {
-               ah->slottime = sc->beacon.slottime;
-               ath9k_hw_init_global_settings(ah);
-               sc->beacon.updateslot = OK;
-       }
--      if (bfaddr != 0) {
-+
-+      if (bf) {
-+              ath9k_reset_beacon_status(sc);
-+
-               /* NB: cabq traffic should already be queued and primed */
--              ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bfaddr);
-+              ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bf->bf_daddr);
-               if (!edma)
-                       ath9k_hw_txstart(ah, sc->beacon.beaconq);
--
--              sc->beacon.ast_be_xmit += bc;     /* XXX per-vif? */
-       }
- }
--static void ath9k_beacon_init(struct ath_softc *sc,
--                            u32 next_beacon,
--                            u32 beacon_period)
-+static void ath9k_beacon_init(struct ath_softc *sc, u32 nexttbtt, u32 intval)
- {
--      if (test_bit(SC_OP_TSF_RESET, &sc->sc_flags)) {
--              ath9k_ps_wakeup(sc);
--              ath9k_hw_reset_tsf(sc->sc_ah);
--      }
--
--      ath9k_hw_beaconinit(sc->sc_ah, next_beacon, beacon_period);
-+      struct ath_hw *ah = sc->sc_ah;
--      if (test_bit(SC_OP_TSF_RESET, &sc->sc_flags)) {
--              ath9k_ps_restore(sc);
--              clear_bit(SC_OP_TSF_RESET, &sc->sc_flags);
--      }
-+      ath9k_hw_disable_interrupts(ah);
-+      ath9k_hw_reset_tsf(ah);
-+      ath9k_beaconq_config(sc);
-+      ath9k_hw_beaconinit(ah, nexttbtt, intval);
-+      sc->beacon.bmisscnt = 0;
-+      ath9k_hw_set_interrupts(ah);
-+      ath9k_hw_enable_interrupts(ah);
- }
- /*
-@@ -498,32 +422,27 @@ static void ath9k_beacon_init(struct ath
-  * burst together.  For the former arrange for the SWBA to be delivered for each
-  * slot. Slots that are not occupied will generate nothing.
-  */
--static void ath_beacon_config_ap(struct ath_softc *sc,
--                               struct ath_beacon_config *conf)
-+static void ath9k_beacon_config_ap(struct ath_softc *sc,
-+                                 struct ath_beacon_config *conf)
- {
-       struct ath_hw *ah = sc->sc_ah;
-+      struct ath_common *common = ath9k_hw_common(ah);
-       u32 nexttbtt, intval;
-       /* NB: the beacon interval is kept internally in TU's */
-       intval = TU_TO_USEC(conf->beacon_interval);
--      intval /= ATH_BCBUF;    /* for staggered beacons */
-+      intval /= ATH_BCBUF;
-       nexttbtt = intval;
--      /*
--       * In AP mode we enable the beacon timers and SWBA interrupts to
--       * prepare beacon frames.
--       */
--      ah->imask |= ATH9K_INT_SWBA;
--      ath_beaconq_config(sc);
-+      if (conf->enable_beacon)
-+              ah->imask |= ATH9K_INT_SWBA;
-+      else
-+              ah->imask &= ~ATH9K_INT_SWBA;
--      /* Set the computed AP beacon timers */
-+      ath_dbg(common, BEACON, "AP nexttbtt: %u intval: %u conf_intval: %u\n",
-+              nexttbtt, intval, conf->beacon_interval);
--      ath9k_hw_disable_interrupts(ah);
--      set_bit(SC_OP_TSF_RESET, &sc->sc_flags);
-       ath9k_beacon_init(sc, nexttbtt, intval);
--      sc->beacon.bmisscnt = 0;
--      ath9k_hw_set_interrupts(ah);
--      ath9k_hw_enable_interrupts(ah);
- }
- /*
-@@ -534,8 +453,8 @@ static void ath_beacon_config_ap(struct 
-  * we'll receive a BMISS interrupt when we stop seeing beacons from the AP
-  * we've associated with.
-  */
--static void ath_beacon_config_sta(struct ath_softc *sc,
--                                struct ath_beacon_config *conf)
-+static void ath9k_beacon_config_sta(struct ath_softc *sc,
-+                                  struct ath_beacon_config *conf)
- {
-       struct ath_hw *ah = sc->sc_ah;
-       struct ath_common *common = ath9k_hw_common(ah);
-@@ -654,8 +573,8 @@ static void ath_beacon_config_sta(struct
-       ath9k_hw_enable_interrupts(ah);
- }
--static void ath_beacon_config_adhoc(struct ath_softc *sc,
--                                  struct ath_beacon_config *conf)
-+static void ath9k_beacon_config_adhoc(struct ath_softc *sc,
-+                                    struct ath_beacon_config *conf)
- {
-       struct ath_hw *ah = sc->sc_ah;
-       struct ath_common *common = ath9k_hw_common(ah);
-@@ -669,82 +588,53 @@ static void ath_beacon_config_adhoc(stru
-       tsf = roundup(ath9k_hw_gettsf32(ah) + TU_TO_USEC(FUDGE), intval);
-       nexttbtt = tsf + intval;
--      ath_dbg(common, BEACON, "IBSS nexttbtt %u intval %u (%u)\n",
--              nexttbtt, intval, conf->beacon_interval);
--
--      /*
--       * In IBSS mode enable the beacon timers but only enable SWBA interrupts
--       * if we need to manually prepare beacon frames.  Otherwise we use a
--       * self-linked tx descriptor and let the hardware deal with things.
--       */
--      ah->imask |= ATH9K_INT_SWBA;
--
--      ath_beaconq_config(sc);
-+      if (conf->enable_beacon)
-+              ah->imask |= ATH9K_INT_SWBA;
-+      else
-+              ah->imask &= ~ATH9K_INT_SWBA;
--      /* Set the computed ADHOC beacon timers */
-+      ath_dbg(common, BEACON, "IBSS nexttbtt: %u intval: %u conf_intval: %u\n",
-+              nexttbtt, intval, conf->beacon_interval);
--      ath9k_hw_disable_interrupts(ah);
-       ath9k_beacon_init(sc, nexttbtt, intval);
--      sc->beacon.bmisscnt = 0;
--
--      ath9k_hw_set_interrupts(ah);
--      ath9k_hw_enable_interrupts(ah);
- }
+       if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -173,7 +173,7 @@ struct ieee80211_chanctx_conf {
  
--static bool ath9k_allow_beacon_config(struct ath_softc *sc,
--                                    struct ieee80211_vif *vif)
-+bool ath9k_allow_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
- {
--      struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
-       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
--      struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
-       struct ath_vif *avp = (void *)vif->drv_priv;
--      /*
--       * Can not have different beacon interval on multiple
--       * AP interface case
--       */
--      if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) &&
--          (sc->nbcnvifs > 1) &&
--          (vif->type == NL80211_IFTYPE_AP) &&
--          (cur_conf->beacon_interval != bss_conf->beacon_int)) {
--              ath_dbg(common, CONFIG,
--                      "Changing beacon interval of multiple AP interfaces !\n");
--              return false;
--      }
--      /*
--       * Can not configure station vif's beacon config
--       * while on AP opmode
--       */
--      if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) &&
--          (vif->type != NL80211_IFTYPE_AP)) {
--              ath_dbg(common, CONFIG,
--                      "STA vif's beacon not allowed on AP mode\n");
--              return false;
-+      if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
-+              if ((vif->type != NL80211_IFTYPE_AP) ||
-+                  (sc->nbcnvifs > 1)) {
-+                      ath_dbg(common, CONFIG,
-+                              "An AP interface is already present !\n");
-+                      return false;
-+              }
-       }
--      /*
--       * Do not allow beacon config if HW was already configured
--       * with another STA vif
--       */
--      if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) &&
--          (vif->type == NL80211_IFTYPE_STATION) &&
--          test_bit(SC_OP_BEACONS, &sc->sc_flags) &&
--          !avp->primary_sta_vif) {
--              ath_dbg(common, CONFIG,
--                      "Beacon already configured for a station interface\n");
--              return false;
-+
-+      if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION) {
-+              if ((vif->type == NL80211_IFTYPE_STATION) &&
-+                  test_bit(SC_OP_BEACONS, &sc->sc_flags) &&
-+                  !avp->primary_sta_vif) {
-+                      ath_dbg(common, CONFIG,
-+                              "Beacon already configured for a station interface\n");
-+                      return false;
-+              }
-       }
-+
-       return true;
- }
+       u8 rx_chains_static, rx_chains_dynamic;
  
--void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
-+static void ath9k_cache_beacon_config(struct ath_softc *sc,
-+                                    struct ieee80211_bss_conf *bss_conf)
- {
-+      struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-       struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
--      struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
--      if (!ath9k_allow_beacon_config(sc, vif))
--              return;
-+      ath_dbg(common, BEACON,
-+              "Caching beacon data for BSS: %pM\n", bss_conf->bssid);
--      /* Setup the beacon configuration parameters */
-       cur_conf->beacon_interval = bss_conf->beacon_int;
-       cur_conf->dtim_period = bss_conf->dtim_period;
-       cur_conf->listen_interval = 1;
-@@ -769,73 +659,59 @@ void ath_beacon_config(struct ath_softc 
-       if (cur_conf->dtim_period == 0)
-               cur_conf->dtim_period = 1;
--      ath_set_beacon(sc);
- }
+-      u8 drv_priv[0] __attribute__((__aligned__(sizeof(void *))));
++      u8 drv_priv[0] __aligned(sizeof(void *));
+ };
  
--static bool ath_has_valid_bslot(struct ath_softc *sc)
-+void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif,
-+                       u32 changed)
- {
--      struct ath_vif *avp;
--      int slot;
--      bool found = false;
-+      struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
-+      struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
--      for (slot = 0; slot < ATH_BCBUF; slot++) {
--              if (sc->beacon.bslot[slot]) {
--                      avp = (void *)sc->beacon.bslot[slot]->drv_priv;
--                      if (avp->is_bslot_active) {
--                              found = true;
--                              break;
--                      }
-+      ath9k_cache_beacon_config(sc, bss_conf);
-+
-+      if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION) {
-+              ath9k_set_beacon(sc);
-+              set_bit(SC_OP_BEACONS, &sc->sc_flags);
-+      } else {
-+              /*
-+               * Take care of multiple interfaces when
-+               * enabling/disabling SWBA.
-+               */
-+              if (changed & BSS_CHANGED_BEACON_ENABLED) {
-+                      if (!bss_conf->enable_beacon &&
-+                          (sc->nbcnvifs <= 1))
-+                              cur_conf->enable_beacon = false;
-+                      else if (bss_conf->enable_beacon)
-+                              cur_conf->enable_beacon = true;
-               }
-+
-+              ath9k_set_beacon(sc);
-+
-+              if (cur_conf->enable_beacon)
-+                      set_bit(SC_OP_BEACONS, &sc->sc_flags);
-+              else
-+                      clear_bit(SC_OP_BEACONS, &sc->sc_flags);
-       }
--      return found;
- }
+ /**
+@@ -1059,7 +1059,7 @@ struct ieee80211_vif {
+       u32 driver_flags;
  
--
--void ath_set_beacon(struct ath_softc *sc)
-+void ath9k_set_beacon(struct ath_softc *sc)
- {
-       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-       struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
-       switch (sc->sc_ah->opmode) {
-       case NL80211_IFTYPE_AP:
--              if (ath_has_valid_bslot(sc))
--                      ath_beacon_config_ap(sc, cur_conf);
-+              ath9k_beacon_config_ap(sc, cur_conf);
-               break;
-       case NL80211_IFTYPE_ADHOC:
-       case NL80211_IFTYPE_MESH_POINT:
--              ath_beacon_config_adhoc(sc, cur_conf);
-+              ath9k_beacon_config_adhoc(sc, cur_conf);
-               break;
-       case NL80211_IFTYPE_STATION:
--              ath_beacon_config_sta(sc, cur_conf);
-+              ath9k_beacon_config_sta(sc, cur_conf);
-               break;
-       default:
-               ath_dbg(common, CONFIG, "Unsupported beaconing mode\n");
-               return;
-       }
--
--      set_bit(SC_OP_BEACONS, &sc->sc_flags);
--}
--
--void ath9k_set_beaconing_status(struct ath_softc *sc, bool status)
--{
--      struct ath_hw *ah = sc->sc_ah;
--
--      if (!ath_has_valid_bslot(sc)) {
--              clear_bit(SC_OP_BEACONS, &sc->sc_flags);
--              return;
--      }
--
--      ath9k_ps_wakeup(sc);
--      if (status) {
--              /* Re-enable beaconing */
--              ah->imask |= ATH9K_INT_SWBA;
--              ath9k_hw_set_interrupts(ah);
--      } else {
--              /* Disable SWBA interrupt */
--              ah->imask &= ~ATH9K_INT_SWBA;
--              ath9k_hw_set_interrupts(ah);
--              tasklet_kill(&sc->bcon_tasklet);
--              ath9k_hw_stop_dma_queue(ah, sc->beacon.beaconq);
--      }
--      ath9k_ps_restore(sc);
- }
---- a/drivers/net/wireless/ath/ath9k/debug.c
-+++ b/drivers/net/wireless/ath/ath9k/debug.c
-@@ -206,10 +206,9 @@ static ssize_t write_file_disable_ani(st
-       if (disable_ani) {
-               clear_bit(SC_OP_ANI_RUN, &sc->sc_flags);
--              del_timer_sync(&common->ani.timer);
-+              ath_stop_ani(sc);
-       } else {
--              set_bit(SC_OP_ANI_RUN, &sc->sc_flags);
--              ath_start_ani(common);
-+              ath_check_ani(sc);
-       }
+       /* must be last */
+-      u8 drv_priv[0] __attribute__((__aligned__(sizeof(void *))));
++      u8 drv_priv[0] __aligned(sizeof(void *));
+ };
  
-       return count;
---- a/drivers/net/wireless/ath/ath9k/debug.h
-+++ b/drivers/net/wireless/ath/ath9k/debug.h
-@@ -32,6 +32,19 @@ struct ath_buf;
- #define RESET_STAT_INC(sc, type) do { } while (0)
- #endif
+ static inline bool ieee80211_vif_is_mesh(struct ieee80211_vif *vif)
+@@ -1209,7 +1209,7 @@ struct ieee80211_sta {
+       u8 max_sp;
  
-+enum ath_reset_type {
-+      RESET_TYPE_BB_HANG,
-+      RESET_TYPE_BB_WATCHDOG,
-+      RESET_TYPE_FATAL_INT,
-+      RESET_TYPE_TX_ERROR,
-+      RESET_TYPE_TX_HANG,
-+      RESET_TYPE_PLL_HANG,
-+      RESET_TYPE_MAC_HANG,
-+      RESET_TYPE_BEACON_STUCK,
-+      RESET_TYPE_MCI,
-+      __RESET_TYPE_MAX
-+};
-+
- #ifdef CONFIG_ATH9K_DEBUGFS
+       /* must be last */
+-      u8 drv_priv[0] __attribute__((__aligned__(sizeof(void *))));
++      u8 drv_priv[0] __aligned(sizeof(void *));
+ };
  
  /**
-@@ -209,17 +222,6 @@ struct ath_rx_stats {
-       u32 rx_frags;
+@@ -1369,6 +1369,10 @@ struct ieee80211_tx_control {
+  * @IEEE80211_HW_P2P_DEV_ADDR_FOR_INTF: Use the P2P Device address for any
+  *    P2P Interface. This will be honoured even if more than one interface
+  *    is supported.
++ *
++ * @IEEE80211_HW_TEARDOWN_AGGR_ON_BAR_FAIL: On this hardware TX BA session
++ *    should be tear down once BAR frame will not be acked.
++ *
+  */
+ enum ieee80211_hw_flags {
+       IEEE80211_HW_HAS_RATE_CONTROL                   = 1<<0,
+@@ -1397,6 +1401,7 @@ enum ieee80211_hw_flags {
+       IEEE80211_HW_TX_AMPDU_SETUP_IN_HW               = 1<<23,
+       IEEE80211_HW_SCAN_WHILE_IDLE                    = 1<<24,
+       IEEE80211_HW_P2P_DEV_ADDR_FOR_INTF              = 1<<25,
++      IEEE80211_HW_TEARDOWN_AGGR_ON_BAR_FAIL          = 1<<26,
  };
  
--enum ath_reset_type {
--      RESET_TYPE_BB_HANG,
--      RESET_TYPE_BB_WATCHDOG,
--      RESET_TYPE_FATAL_INT,
--      RESET_TYPE_TX_ERROR,
--      RESET_TYPE_TX_HANG,
--      RESET_TYPE_PLL_HANG,
--      RESET_TYPE_MAC_HANG,
--      __RESET_TYPE_MAX
--};
--
- struct ath_stats {
-       struct ath_interrupt_stats istats;
-       struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES];
---- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
-+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
-@@ -1111,7 +1111,7 @@ static int ath9k_htc_add_interface(struc
-       if ((priv->ah->opmode == NL80211_IFTYPE_AP) &&
-           !test_bit(OP_ANI_RUNNING, &priv->op_flags)) {
--              ath9k_hw_set_tsfadjust(priv->ah, 1);
-+              ath9k_hw_set_tsfadjust(priv->ah, true);
-               ath9k_htc_start_ani(priv);
-       }
---- a/drivers/net/wireless/ath/ath9k/hw.c
-+++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -2908,9 +2908,9 @@ void ath9k_hw_reset_tsf(struct ath_hw *a
- }
- EXPORT_SYMBOL(ath9k_hw_reset_tsf);
--void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting)
-+void ath9k_hw_set_tsfadjust(struct ath_hw *ah, bool set)
- {
--      if (setting)
-+      if (set)
-               ah->misc_mode |= AR_PCU_TX_ADD_TSF;
-       else
-               ah->misc_mode &= ~AR_PCU_TX_ADD_TSF;
---- a/drivers/net/wireless/ath/ath9k/hw.h
-+++ b/drivers/net/wireless/ath/ath9k/hw.h
-@@ -943,7 +943,7 @@ u32 ath9k_hw_gettsf32(struct ath_hw *ah)
- u64 ath9k_hw_gettsf64(struct ath_hw *ah);
- void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64);
- void ath9k_hw_reset_tsf(struct ath_hw *ah);
--void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting);
-+void ath9k_hw_set_tsfadjust(struct ath_hw *ah, bool set);
- void ath9k_hw_init_global_settings(struct ath_hw *ah);
- u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah);
- void ath9k_hw_set11nmac2040(struct ath_hw *ah);
---- a/drivers/net/wireless/ath/ath9k/init.c
-+++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -560,7 +560,7 @@ static int ath9k_init_softc(u16 devid, s
-       spin_lock_init(&sc->debug.samp_lock);
- #endif
-       tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
--      tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet,
-+      tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet,
-                    (unsigned long)sc);
-       INIT_WORK(&sc->hw_reset_work, ath_reset_work);
---- a/drivers/net/wireless/ath/ath9k/link.c
-+++ b/drivers/net/wireless/ath/ath9k/link.c
-@@ -50,8 +50,7 @@ void ath_tx_complete_poll_work(struct wo
-       if (needreset) {
-               ath_dbg(ath9k_hw_common(sc->sc_ah), RESET,
-                       "tx hung, resetting the chip\n");
--              RESET_STAT_INC(sc, RESET_TYPE_TX_HANG);
--              ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
-+              ath9k_queue_reset(sc, RESET_TYPE_TX_HANG);
-               return;
-       }
-@@ -69,6 +68,7 @@ void ath_hw_check(struct work_struct *wo
-       unsigned long flags;
-       int busy;
-       u8 is_alive, nbeacon = 1;
-+      enum ath_reset_type type;
-       ath9k_ps_wakeup(sc);
-       is_alive = ath9k_hw_check_alive(sc->sc_ah);
-@@ -78,7 +78,7 @@ void ath_hw_check(struct work_struct *wo
-       else if (!is_alive && AR_SREV_9300(sc->sc_ah)) {
-               ath_dbg(common, RESET,
-                       "DCU stuck is detected. Schedule chip reset\n");
--              RESET_STAT_INC(sc, RESET_TYPE_MAC_HANG);
-+              type = RESET_TYPE_MAC_HANG;
-               goto sched_reset;
-       }
-@@ -90,7 +90,7 @@ void ath_hw_check(struct work_struct *wo
-               busy, sc->hw_busy_count + 1);
-       if (busy >= 99) {
-               if (++sc->hw_busy_count >= 3) {
--                      RESET_STAT_INC(sc, RESET_TYPE_BB_HANG);
-+                      type = RESET_TYPE_BB_HANG;
-                       goto sched_reset;
-               }
-       } else if (busy >= 0) {
-@@ -102,7 +102,7 @@ void ath_hw_check(struct work_struct *wo
-       goto out;
- sched_reset:
--      ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
-+      ath9k_queue_reset(sc, type);
- out:
-       ath9k_ps_restore(sc);
- }
-@@ -119,8 +119,7 @@ static bool ath_hw_pll_rx_hang_check(str
-               count++;
-               if (count == 3) {
-                       ath_dbg(common, RESET, "PLL WAR, resetting the chip\n");
--                      RESET_STAT_INC(sc, RESET_TYPE_PLL_HANG);
--                      ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
-+                      ath9k_queue_reset(sc, RESET_TYPE_PLL_HANG);
-                       count = 0;
-                       return true;
-               }
-@@ -432,26 +431,69 @@ set_timer:
-       }
- }
--void ath_start_ani(struct ath_common *common)
-+void ath_start_ani(struct ath_softc *sc)
- {
--      struct ath_hw *ah = common->ah;
-+      struct ath_hw *ah = sc->sc_ah;
-+      struct ath_common *common = ath9k_hw_common(ah);
-       unsigned long timestamp = jiffies_to_msecs(jiffies);
--      struct ath_softc *sc = (struct ath_softc *) common->priv;
--      if (!test_bit(SC_OP_ANI_RUN, &sc->sc_flags))
--              return;
--
--      if (sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)
-+      if (common->disable_ani ||
-+          !test_bit(SC_OP_ANI_RUN, &sc->sc_flags) ||
-+          (sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL))
-               return;
-       common->ani.longcal_timer = timestamp;
-       common->ani.shortcal_timer = timestamp;
-       common->ani.checkani_timer = timestamp;
-+      ath_dbg(common, ANI, "Starting ANI\n");
-       mod_timer(&common->ani.timer,
-                 jiffies + msecs_to_jiffies((u32)ah->config.ani_poll_interval));
- }
-+void ath_stop_ani(struct ath_softc *sc)
-+{
-+      struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-+
-+      ath_dbg(common, ANI, "Stopping ANI\n");
-+      del_timer_sync(&common->ani.timer);
-+}
-+
-+void ath_check_ani(struct ath_softc *sc)
-+{
-+      struct ath_hw *ah = sc->sc_ah;
-+      struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
-+
-+      /*
-+       * Check for the various conditions in which ANI has to
-+       * be stopped.
-+       */
-+      if (ah->opmode == NL80211_IFTYPE_ADHOC) {
-+              if (!cur_conf->enable_beacon)
-+                      goto stop_ani;
-+      } else if (ah->opmode == NL80211_IFTYPE_AP) {
-+              if (!cur_conf->enable_beacon) {
-+                      /*
-+                       * Disable ANI only when there are no
-+                       * associated stations.
-+                       */
-+                      if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags))
-+                              goto stop_ani;
-+              }
-+      } else if (ah->opmode == NL80211_IFTYPE_STATION) {
-+              if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags))
-+                      goto stop_ani;
-+      }
-+
-+      set_bit(SC_OP_ANI_RUN, &sc->sc_flags);
-+      ath_start_ani(sc);
-+      return;
-+
-+stop_ani:
-+      clear_bit(SC_OP_ANI_RUN, &sc->sc_flags);
-+      ath_stop_ani(sc);
-+}
-+
- void ath_update_survey_nf(struct ath_softc *sc, int channel)
- {
-       struct ath_hw *ah = sc->sc_ah;
---- a/drivers/net/wireless/ath/ath9k/main.c
-+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -167,8 +167,6 @@ static void ath_cancel_work(struct ath_s
- static void ath_restart_work(struct ath_softc *sc)
- {
--      struct ath_common *common = ath9k_hw_common(sc->sc_ah);
--
-       ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
-       if (AR_SREV_9340(sc->sc_ah) || AR_SREV_9485(sc->sc_ah) ||
-@@ -177,21 +175,18 @@ static void ath_restart_work(struct ath_
-                                    msecs_to_jiffies(ATH_PLL_WORK_INTERVAL));
-       ath_start_rx_poll(sc, 3);
--
--      if (!common->disable_ani)
--              ath_start_ani(common);
-+      ath_start_ani(sc);
- }
- static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush)
- {
-       struct ath_hw *ah = sc->sc_ah;
--      struct ath_common *common = ath9k_hw_common(ah);
-       bool ret = true;
-       ieee80211_stop_queues(sc->hw);
-       sc->hw_busy_count = 0;
--      del_timer_sync(&common->ani.timer);
-+      ath_stop_ani(sc);
-       del_timer_sync(&sc->rx_poll_timer);
-       ath9k_debug_samp_bb_mac(sc);
-@@ -236,7 +231,7 @@ static bool ath_complete_reset(struct at
-               if (!test_bit(SC_OP_BEACONS, &sc->sc_flags))
-                       goto work;
--              ath_set_beacon(sc);
-+              ath9k_set_beacon(sc);
-               if (ah->opmode == NL80211_IFTYPE_STATION &&
-                   test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) {
-@@ -365,6 +360,7 @@ void ath9k_tasklet(unsigned long data)
-       struct ath_softc *sc = (struct ath_softc *)data;
-       struct ath_hw *ah = sc->sc_ah;
-       struct ath_common *common = ath9k_hw_common(ah);
-+      enum ath_reset_type type;
-       unsigned long flags;
-       u32 status = sc->intrstatus;
-       u32 rxmask;
-@@ -374,18 +370,13 @@ void ath9k_tasklet(unsigned long data)
-       if ((status & ATH9K_INT_FATAL) ||
-           (status & ATH9K_INT_BB_WATCHDOG)) {
--#ifdef CONFIG_ATH9K_DEBUGFS
--              enum ath_reset_type type;
-               if (status & ATH9K_INT_FATAL)
-                       type = RESET_TYPE_FATAL_INT;
-               else
-                       type = RESET_TYPE_BB_WATCHDOG;
--              RESET_STAT_INC(sc, type);
--#endif
--              set_bit(SC_OP_HW_RESET, &sc->sc_flags);
--              ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
-+              ath9k_queue_reset(sc, type);
-               goto out;
-       }
-@@ -575,6 +566,15 @@ static int ath_reset(struct ath_softc *s
-       return r;
- }
-+void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type)
-+{
-+#ifdef CONFIG_ATH9K_DEBUGFS
-+      RESET_STAT_INC(sc, type);
-+#endif
-+      set_bit(SC_OP_HW_RESET, &sc->sc_flags);
-+      ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
-+}
-+
- void ath_reset_work(struct work_struct *work)
- {
-       struct ath_softc *sc = container_of(work, struct ath_softc, hw_reset_work);
-@@ -841,16 +841,6 @@ bool ath9k_uses_beacons(int type)
-       }
- }
--static void ath9k_reclaim_beacon(struct ath_softc *sc,
--                               struct ieee80211_vif *vif)
--{
--      struct ath_vif *avp = (void *)vif->drv_priv;
--
--      ath9k_set_beaconing_status(sc, false);
--      ath_beacon_return(sc, avp);
--      ath9k_set_beaconing_status(sc, true);
--}
--
- static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
- {
-       struct ath9k_vif_iter_data *iter_data = data;
-@@ -918,18 +908,14 @@ static void ath9k_calculate_summary_stat
-       ath9k_calculate_iter_data(hw, vif, &iter_data);
--      /* Set BSSID mask. */
-       memcpy(common->bssidmask, iter_data.mask, ETH_ALEN);
-       ath_hw_setbssidmask(common);
--      /* Set op-mode & TSF */
-       if (iter_data.naps > 0) {
--              ath9k_hw_set_tsfadjust(ah, 1);
--              set_bit(SC_OP_TSF_RESET, &sc->sc_flags);
-+              ath9k_hw_set_tsfadjust(ah, true);
-               ah->opmode = NL80211_IFTYPE_AP;
-       } else {
--              ath9k_hw_set_tsfadjust(ah, 0);
--              clear_bit(SC_OP_TSF_RESET, &sc->sc_flags);
-+              ath9k_hw_set_tsfadjust(ah, false);
-               if (iter_data.nmeshes)
-                       ah->opmode = NL80211_IFTYPE_MESH_POINT;
-@@ -941,45 +927,14 @@ static void ath9k_calculate_summary_stat
-                       ah->opmode = NL80211_IFTYPE_STATION;
-       }
--      /*
--       * Enable MIB interrupts when there are hardware phy counters.
--       */
-+      ath9k_hw_setopmode(ah);
-+
-       if ((iter_data.nstations + iter_data.nadhocs + iter_data.nmeshes) > 0)
-               ah->imask |= ATH9K_INT_TSFOOR;
-       else
-               ah->imask &= ~ATH9K_INT_TSFOOR;
-       ath9k_hw_set_interrupts(ah);
--
--      /* Set up ANI */
--      if (iter_data.naps > 0) {
--              sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
--
--              if (!common->disable_ani) {
--                      set_bit(SC_OP_ANI_RUN, &sc->sc_flags);
--                      ath_start_ani(common);
--              }
--
--      } else {
--              clear_bit(SC_OP_ANI_RUN, &sc->sc_flags);
--              del_timer_sync(&common->ani.timer);
--      }
--}
--
--/* Called with sc->mutex held, vif counts set up properly. */
--static void ath9k_do_vif_add_setup(struct ieee80211_hw *hw,
--                                 struct ieee80211_vif *vif)
--{
--      struct ath_softc *sc = hw->priv;
--
--      ath9k_calculate_summary_state(hw, vif);
--
--      if (ath9k_uses_beacons(vif->type)) {
--              /* Reserve a beacon slot for the vif */
--              ath9k_set_beaconing_status(sc, false);
--              ath_beacon_alloc(sc, vif);
--              ath9k_set_beaconing_status(sc, true);
--      }
- }
- static int ath9k_add_interface(struct ieee80211_hw *hw,
-@@ -1021,7 +976,10 @@ static int ath9k_add_interface(struct ie
-       sc->nvifs++;
--      ath9k_do_vif_add_setup(hw, vif);
-+      ath9k_calculate_summary_state(hw, vif);
-+      if (ath9k_uses_beacons(vif->type))
-+              ath9k_beacon_assign_slot(sc, vif);
-+
- out:
-       mutex_unlock(&sc->mutex);
-       ath9k_ps_restore(sc);
-@@ -1038,6 +996,7 @@ static int ath9k_change_interface(struct
-       int ret = 0;
-       ath_dbg(common, CONFIG, "Change Interface\n");
-+
-       mutex_lock(&sc->mutex);
-       ath9k_ps_wakeup(sc);
-@@ -1050,15 +1009,16 @@ static int ath9k_change_interface(struct
-               }
-       }
--      /* Clean up old vif stuff */
-       if (ath9k_uses_beacons(vif->type))
--              ath9k_reclaim_beacon(sc, vif);
-+              ath9k_beacon_remove_slot(sc, vif);
--      /* Add new settings */
-       vif->type = new_type;
-       vif->p2p = p2p;
--      ath9k_do_vif_add_setup(hw, vif);
-+      ath9k_calculate_summary_state(hw, vif);
-+      if (ath9k_uses_beacons(vif->type))
-+              ath9k_beacon_assign_slot(sc, vif);
-+
- out:
-       ath9k_ps_restore(sc);
-       mutex_unlock(&sc->mutex);
-@@ -1078,9 +1038,8 @@ static void ath9k_remove_interface(struc
-       sc->nvifs--;
--      /* Reclaim beacon resources */
-       if (ath9k_uses_beacons(vif->type))
--              ath9k_reclaim_beacon(sc, vif);
-+              ath9k_beacon_remove_slot(sc, vif);
-       ath9k_calculate_summary_state(hw, NULL);
-@@ -1388,10 +1347,6 @@ static int ath9k_conf_tx(struct ieee8021
-       if (ret)
-               ath_err(common, "TXQ Update failed\n");
--      if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)
--              if (queue == WME_AC_BE && !ret)
--                      ath_beaconq_config(sc);
--
-       mutex_unlock(&sc->mutex);
-       ath9k_ps_restore(sc);
-@@ -1460,85 +1415,36 @@ static int ath9k_set_key(struct ieee8021
-       return ret;
- }
--static void ath9k_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
-+
-+static void ath9k_bss_assoc_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
- {
-       struct ath_softc *sc = data;
-       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
--      struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
-       struct ath_vif *avp = (void *)vif->drv_priv;
-+      struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
-       unsigned long flags;
--      /*
--       * Skip iteration if primary station vif's bss info
--       * was not changed
--       */
-+
-       if (test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags))
-               return;
-       if (bss_conf->assoc) {
-               set_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags);
-               avp->primary_sta_vif = true;
-+
-               memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
-               common->curaid = bss_conf->aid;
-               ath9k_hw_write_associd(sc->sc_ah);
--              ath_dbg(common, CONFIG, "Bss Info ASSOC %d, bssid: %pM\n",
--                      bss_conf->aid, common->curbssid);
--              ath_beacon_config(sc, vif);
--              /*
--               * Request a re-configuration of Beacon related timers
--               * on the receipt of the first Beacon frame (i.e.,
--               * after time sync with the AP).
--               */
--              spin_lock_irqsave(&sc->sc_pm_lock, flags);
--              sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON;
--              spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
--              /* Reset rssi stats */
-               sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
-               sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
--              ath_start_rx_poll(sc, 3);
--
--              if (!common->disable_ani) {
--                      set_bit(SC_OP_ANI_RUN, &sc->sc_flags);
--                      ath_start_ani(common);
--              }
--
--      }
--}
--
--static void ath9k_config_bss(struct ath_softc *sc, struct ieee80211_vif *vif)
--{
--      struct ath_common *common = ath9k_hw_common(sc->sc_ah);
--      struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
--      struct ath_vif *avp = (void *)vif->drv_priv;
--
--      if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION)
--              return;
--
--      /* Reconfigure bss info */
--      if (avp->primary_sta_vif && !bss_conf->assoc) {
--              ath_dbg(common, CONFIG, "Bss Info DISASSOC %d, bssid %pM\n",
--                      common->curaid, common->curbssid);
--              clear_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags);
--              clear_bit(SC_OP_BEACONS, &sc->sc_flags);
--              avp->primary_sta_vif = false;
--              memset(common->curbssid, 0, ETH_ALEN);
--              common->curaid = 0;
--      }
--
--      ieee80211_iterate_active_interfaces_atomic(
--                      sc->hw, ath9k_bss_iter, sc);
-+              spin_lock_irqsave(&sc->sc_pm_lock, flags);
-+              sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON;
-+              spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
--      /*
--       * None of station vifs are associated.
--       * Clear bssid & aid
--       */
--      if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) {
--              ath9k_hw_write_associd(sc->sc_ah);
--              clear_bit(SC_OP_ANI_RUN, &sc->sc_flags);
--              del_timer_sync(&common->ani.timer);
--              del_timer_sync(&sc->rx_poll_timer);
--              memset(&sc->caldata, 0, sizeof(sc->caldata));
-+              ath_dbg(common, CONFIG,
-+                      "Primary Station interface: %pM, BSSID: %pM\n",
-+                      vif->addr, common->curbssid);
-       }
- }
-@@ -1547,6 +1453,11 @@ static void ath9k_bss_info_changed(struc
-                                  struct ieee80211_bss_conf *bss_conf,
-                                  u32 changed)
- {
-+#define CHECK_ANI                             \
-+      (BSS_CHANGED_ASSOC |                    \
-+       BSS_CHANGED_IBSS |                     \
-+       BSS_CHANGED_BEACON_ENABLED)
-+
-       struct ath_softc *sc = hw->priv;
-       struct ath_hw *ah = sc->sc_ah;
-       struct ath_common *common = ath9k_hw_common(ah);
-@@ -1557,53 +1468,43 @@ static void ath9k_bss_info_changed(struc
-       mutex_lock(&sc->mutex);
-       if (changed & BSS_CHANGED_ASSOC) {
--              ath9k_config_bss(sc, vif);
-+              ath_dbg(common, CONFIG, "BSSID %pM Changed ASSOC %d\n",
-+                      bss_conf->bssid, bss_conf->assoc);
--              ath_dbg(common, CONFIG, "BSSID: %pM aid: 0x%x\n",
--                      common->curbssid, common->curaid);
-+              /*
-+               * Do not do anything when the opmode is not STATION.
-+               */
-+              if (ah->opmode == NL80211_IFTYPE_STATION) {
-+                      if (avp->primary_sta_vif && !bss_conf->assoc) {
-+                              clear_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags);
-+                              clear_bit(SC_OP_BEACONS, &sc->sc_flags);
-+                              avp->primary_sta_vif = false;
-+                      }
-+
-+                      ieee80211_iterate_active_interfaces_atomic(sc->hw,
-+                                                 ath9k_bss_assoc_iter, sc);
-+
-+                      if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) {
-+                              memset(common->curbssid, 0, ETH_ALEN);
-+                              common->curaid = 0;
-+                              ath9k_hw_write_associd(sc->sc_ah);
-+                      }
-+              }
-       }
-       if (changed & BSS_CHANGED_IBSS) {
--              /* There can be only one vif available */
-               memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
-               common->curaid = bss_conf->aid;
-               ath9k_hw_write_associd(sc->sc_ah);
--
--              if (bss_conf->ibss_joined) {
--                      sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
--
--                      if (!common->disable_ani) {
--                              set_bit(SC_OP_ANI_RUN, &sc->sc_flags);
--                              ath_start_ani(common);
--                      }
--
--              } else {
--                      clear_bit(SC_OP_ANI_RUN, &sc->sc_flags);
--                      del_timer_sync(&common->ani.timer);
--                      del_timer_sync(&sc->rx_poll_timer);
--              }
-       }
--      /*
--       * In case of AP mode, the HW TSF has to be reset
--       * when the beacon interval changes.
--       */
--      if ((changed & BSS_CHANGED_BEACON_INT) &&
--          (vif->type == NL80211_IFTYPE_AP))
--              set_bit(SC_OP_TSF_RESET, &sc->sc_flags);
--
--      /* Configure beaconing (AP, IBSS, MESH) */
--      if (ath9k_uses_beacons(vif->type) &&
--          ((changed & BSS_CHANGED_BEACON) ||
--           (changed & BSS_CHANGED_BEACON_ENABLED) ||
--           (changed & BSS_CHANGED_BEACON_INT))) {
--              ath9k_set_beaconing_status(sc, false);
--              if (bss_conf->enable_beacon)
--                      ath_beacon_alloc(sc, vif);
--              else
--                      avp->is_bslot_active = false;
--              ath_beacon_config(sc, vif);
--              ath9k_set_beaconing_status(sc, true);
-+      if ((changed & BSS_CHANGED_BEACON) ||
-+          (changed & BSS_CHANGED_BEACON_ENABLED) ||
-+          (changed & BSS_CHANGED_BEACON_INT)) {
-+              if (ah->opmode == NL80211_IFTYPE_AP)
-+                      ath9k_set_tsfadjust(sc, vif);
-+              if (ath9k_allow_beacon_config(sc, vif))
-+                      ath9k_beacon_config(sc, vif, changed);
-       }
-       if (changed & BSS_CHANGED_ERP_SLOT) {
-@@ -1625,8 +1526,13 @@ static void ath9k_bss_info_changed(struc
-               }
-       }
-+      if (changed & CHECK_ANI)
-+              ath_check_ani(sc);
-+
-       mutex_unlock(&sc->mutex);
-       ath9k_ps_restore(sc);
-+
-+#undef CHECK_ANI
- }
- static u64 ath9k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
-@@ -1855,10 +1761,11 @@ static int ath9k_tx_last_beacon(struct i
-       if (!vif)
-               return 0;
--      avp = (void *)vif->drv_priv;
--      if (!avp->is_bslot_active)
-+      if (!vif->bss_conf.enable_beacon)
-               return 0;
-+      avp = (void *)vif->drv_priv;
-+
-       if (!sc->beacon.tx_processed && !edma) {
-               tasklet_disable(&sc->bcon_tasklet);
---- a/drivers/net/wireless/ath/ath9k/mci.c
-+++ b/drivers/net/wireless/ath/ath9k/mci.c
-@@ -202,7 +202,7 @@ static void ath_mci_cal_msg(struct ath_s
-       case MCI_GPM_BT_CAL_REQ:
-               if (mci_hw->bt_state == MCI_BT_AWAKE) {
-                       ar9003_mci_state(ah, MCI_STATE_SET_BT_CAL_START);
--                      ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
-+                      ath9k_queue_reset(sc, RESET_TYPE_MCI);
-               }
-               ath_dbg(common, MCI, "MCI State : %d\n", mci_hw->bt_state);
-               break;
---- a/drivers/net/wireless/ath/ath9k/recv.c
-+++ b/drivers/net/wireless/ath/ath9k/recv.c
-@@ -553,7 +553,7 @@ static void ath_rx_ps_beacon(struct ath_
-               sc->ps_flags &= ~PS_BEACON_SYNC;
-               ath_dbg(common, PS,
-                       "Reconfigure Beacon timers based on timestamp from the AP\n");
--              ath_set_beacon(sc);
-+              ath9k_set_beacon(sc);
-       }
-       if (ath_beacon_dtim_pending_cab(skb)) {
---- a/drivers/net/wireless/ath/ath9k/xmit.c
-+++ b/drivers/net/wireless/ath/ath9k/xmit.c
-@@ -614,10 +614,8 @@ static void ath_tx_complete_aggr(struct 
-       rcu_read_unlock();
--      if (needreset) {
--              RESET_STAT_INC(sc, RESET_TYPE_TX_ERROR);
--              ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
--      }
-+      if (needreset)
-+              ath9k_queue_reset(sc, RESET_TYPE_TX_ERROR);
- }
- static bool ath_lookup_legacy(struct ath_buf *bf)
-@@ -1586,7 +1584,8 @@ void ath_txq_schedule(struct ath_softc *
-       struct ath_atx_ac *ac, *ac_tmp, *last_ac;
-       struct ath_atx_tid *tid, *last_tid;
--      if (work_pending(&sc->hw_reset_work) || list_empty(&txq->axq_acq) ||
-+      if (test_bit(SC_OP_HW_RESET, &sc->sc_flags) ||
-+          list_empty(&txq->axq_acq) ||
-           txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH)
-               return;
-@@ -2191,7 +2190,7 @@ static void ath_tx_processq(struct ath_s
-       ath_txq_lock(sc, txq);
-       for (;;) {
--              if (work_pending(&sc->hw_reset_work))
-+              if (test_bit(SC_OP_HW_RESET, &sc->sc_flags))
-                       break;
-               if (list_empty(&txq->axq_q)) {
-@@ -2274,7 +2273,7 @@ void ath_tx_edma_tasklet(struct ath_soft
-       int status;
-       for (;;) {
--              if (work_pending(&sc->hw_reset_work))
-+              if (test_bit(SC_OP_HW_RESET, &sc->sc_flags))
-                       break;
-               status = ath9k_hw_txprocdesc(ah, NULL, (void *)&ts);
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -3596,22 +3596,6 @@ void ieee80211_request_smps(struct ieee8
-                           enum ieee80211_smps_mode smps_mode);
  /**
-- * ieee80211_key_removed - disable hw acceleration for key
-- * @key_conf: The key hw acceleration should be disabled for
-- *
-- * This allows drivers to indicate that the given key has been
-- * removed from hardware acceleration, due to a new key that
-- * was added. Don't use this if the key can continue to be used
-- * for TX, if the key restriction is on RX only it is permitted
-- * to keep the key for TX only and not call this function.
-- *
-- * Due to locking constraints, it may only be called during
-- * @set_key. This function must be allowed to sleep, and the
-- * key it tries to disable may still be used until it returns.
-- */
--void ieee80211_key_removed(struct ieee80211_key_conf *key_conf);
--
--/**
-  * ieee80211_ready_on_channel - notification of remain-on-channel start
-  * @hw: pointer as obtained from ieee80211_alloc_hw()
-  */
 --- a/net/mac80211/agg-rx.c
 +++ b/net/mac80211/agg-rx.c
 @@ -203,6 +203,8 @@ static void ieee80211_send_addba_resp(st
                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);
-@@ -459,6 +460,7 @@ int ieee80211_start_tx_ba_session(struct
+@@ -460,6 +461,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_ADHOC)
                return -EINVAL;
  
---- a/net/mac80211/cfg.c
-+++ b/net/mac80211/cfg.c
-@@ -1741,6 +1741,8 @@ static int ieee80211_set_txq_params(stru
-               return -EINVAL;
-       }
-+      ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_QOS);
-+
-       return 0;
- }
 --- a/net/mac80211/debugfs_sta.c
 +++ b/net/mac80211/debugfs_sta.c
-@@ -63,11 +63,11 @@ static ssize_t sta_flags_read(struct fil
+@@ -65,11 +65,11 @@ static ssize_t sta_flags_read(struct fil
        test_sta_flag(sta, WLAN_STA_##flg) ? #flg "\n" : ""
  
        int res = scnprintf(buf, sizeof(buf),
                            TEST(MFP), TEST(BLOCK_BA), TEST(PSPOLL),
                            TEST(UAPSD), TEST(SP), TEST(TDLS_PEER),
                            TEST(TDLS_PEER_AUTH), TEST(4ADDR_EVENT),
+--- a/net/mac80211/ibss.c
++++ b/net/mac80211/ibss.c
+@@ -201,6 +201,20 @@ static void __ieee80211_sta_join_ibss(st
+       bss_change |= BSS_CHANGED_BASIC_RATES;
+       bss_change |= BSS_CHANGED_HT;
+       bss_change |= BSS_CHANGED_IBSS;
++
++      /*
++       * In 5 GHz/802.11a, we can always use short slot time.
++       * (IEEE 802.11-2012 18.3.8.7)
++       *
++       * In 2.4GHz, we must always use long slots in IBSS for compatibility
++       * reasons.
++       * (IEEE 802.11-2012 19.4.5)
++       *
++       * HT follows these specifications (IEEE 802.11-2012 20.3.18)
++       */
++      sdata->vif.bss_conf.use_short_slot = chan->band == IEEE80211_BAND_5GHZ;
++      bss_change |= BSS_CHANGED_ERP_SLOT;
++
+       sdata->vif.bss_conf.ibss_joined = true;
+       sdata->vif.bss_conf.ibss_creator = creator;
+       ieee80211_bss_info_change_notify(sdata, bss_change);
 --- a/net/mac80211/iface.c
 +++ b/net/mac80211/iface.c
-@@ -400,7 +400,6 @@ static int ieee80211_do_open(struct net_
+@@ -508,9 +508,9 @@ static void ieee80211_del_virtual_monito
+ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
  {
-       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+       struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
++      struct ieee80211_sub_if_data *ap_sdata;
+       struct net_device *dev = wdev->netdev;
        struct ieee80211_local *local = sdata->local;
 -      struct sta_info *sta;
        u32 changed = 0;
        int res;
        u32 hw_reconf_flags = 0;
-@@ -538,28 +537,6 @@ static int ieee80211_do_open(struct net_
+@@ -587,10 +587,14 @@ int ieee80211_do_open(struct wireless_de
+       switch (sdata->vif.type) {
+       case NL80211_IFTYPE_AP_VLAN:
+               /* no need to tell driver, but set carrier */
+-              if (rtnl_dereference(sdata->bss->beacon))
+-                      netif_carrier_on(dev);
+-              else
++              if (!rtnl_dereference(sdata->bss->beacon)) {
+                       netif_carrier_off(dev);
++                      break;
++              }
++
++              ap_sdata = get_bss_sdata(sdata);
++              ieee80211_vif_copy_channel(sdata, ap_sdata);
++              netif_carrier_on(dev);
+               break;
+       case NL80211_IFTYPE_MONITOR:
+               if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) {
+@@ -665,30 +669,8 @@ int ieee80211_do_open(struct wireless_de
  
        set_bit(SDATA_STATE_RUNNING, &sdata->state);
  
 -              }
 -
 -              rate_control_rate_init(sta);
+-              netif_carrier_on(dev);
+-      } else if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) {
++      if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE)
+               rcu_assign_pointer(local->p2p_sdata, sdata);
 -      }
--
        /*
         * set_multicast_list will be invoked by the networking core
-        * which will check whether any increments here were done in
-@@ -949,6 +926,72 @@ static void ieee80211_if_setup(struct ne
+@@ -844,6 +826,8 @@ static void ieee80211_do_stop(struct iee
+       switch (sdata->vif.type) {
+       case NL80211_IFTYPE_AP_VLAN:
+               list_del(&sdata->u.vlan.list);
++              netif_carrier_off(sdata->dev);
++              ieee80211_vif_release_channel(sdata);
+               /* no need to tell driver */
+               break;
+       case NL80211_IFTYPE_MONITOR:
+@@ -1072,6 +1056,72 @@ static void ieee80211_if_setup(struct ne
        dev->destructor = free_netdev;
  }
  
  static void ieee80211_iface_work(struct work_struct *work)
  {
        struct ieee80211_sub_if_data *sdata =
-@@ -1053,6 +1096,9 @@ static void ieee80211_iface_work(struct 
+@@ -1176,6 +1226,9 @@ static void ieee80211_iface_work(struct 
                                break;
                        ieee80211_mesh_rx_queued_mgmt(sdata, skb);
                        break;
                default:
                        WARN(1, "frame for unexpected interface type");
                        break;
---- a/net/mac80211/key.c
-+++ b/net/mac80211/key.c
-@@ -197,26 +197,6 @@ static void ieee80211_key_disable_hw_acc
-       key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
- }
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -378,9 +378,6 @@ ieee80211_rx_monitor(struct ieee80211_lo
+        * the SKB because it has a bad FCS/PLCP checksum.
+        */
  
--void ieee80211_key_removed(struct ieee80211_key_conf *key_conf)
--{
--      struct ieee80211_key *key;
--
--      key = container_of(key_conf, struct ieee80211_key, conf);
--
--      might_sleep();
--      assert_key_lock(key->local);
--
--      key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
+-      /* room for the radiotap header based on driver features */
+-      needed_headroom = ieee80211_rx_radiotap_space(local, status);
 -
--      /*
--       * Flush TX path to avoid attempts to use this key
--       * after this function returns. Until then, drivers
--       * must be prepared to handle the key.
--       */
--      synchronize_rcu();
--}
--EXPORT_SYMBOL_GPL(ieee80211_key_removed);
--
- static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata,
-                                       int idx, bool uni, bool multi)
- {
---- a/net/mac80211/mlme.c
-+++ b/net/mac80211/mlme.c
-@@ -1108,7 +1108,7 @@ void ieee80211_dynamic_ps_timer(unsigned
- }
- /* MLME */
--static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
-+static bool ieee80211_sta_wmm_params(struct ieee80211_local *local,
-                                    struct ieee80211_sub_if_data *sdata,
-                                    u8 *wmm_param, size_t wmm_param_len)
- {
-@@ -1119,23 +1119,23 @@ static void ieee80211_sta_wmm_params(str
-       u8 *pos, uapsd_queues = 0;
-       if (!local->ops->conf_tx)
--              return;
-+              return false;
-       if (local->hw.queues < IEEE80211_NUM_ACS)
--              return;
-+              return false;
-       if (!wmm_param)
--              return;
-+              return false;
+       if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS)
+               present_fcs_len = FCS_LEN;
  
-       if (wmm_param_len < 8 || wmm_param[5] /* version */ != 1)
--              return;
-+              return false;
-       if (ifmgd->flags & IEEE80211_STA_UAPSD_ENABLED)
-               uapsd_queues = ifmgd->uapsd_queues;
-       count = wmm_param[6] & 0x0f;
-       if (count == ifmgd->wmm_last_param_set)
--              return;
-+              return false;
-       ifmgd->wmm_last_param_set = count;
-       pos = wmm_param + 8;
-@@ -1202,6 +1202,7 @@ static void ieee80211_sta_wmm_params(str
-       /* enable WMM or activate new settings */
-       sdata->vif.bss_conf.qos = true;
-+      return true;
- }
- static void __ieee80211_stop_poll(struct ieee80211_sub_if_data *sdata)
-@@ -2435,14 +2436,6 @@ static void ieee80211_rx_mgmt_beacon(str
-               directed_tim = ieee80211_check_tim(elems.tim, elems.tim_len,
-                                                  ifmgd->aid);
+@@ -399,6 +396,9 @@ ieee80211_rx_monitor(struct ieee80211_lo
+               return remove_monitor_info(local, origskb);
+       }
  
--      if (ncrc != ifmgd->beacon_crc || !ifmgd->beacon_crc_valid) {
--              ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems,
--                                    true);
--
--              ieee80211_sta_wmm_params(local, sdata, elems.wmm_param,
--                                       elems.wmm_param_len);
--      }
--
-       if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) {
-               if (directed_tim) {
-                       if (local->hw.conf.dynamic_ps_timeout > 0) {
-@@ -2473,6 +2466,13 @@ static void ieee80211_rx_mgmt_beacon(str
-       ifmgd->beacon_crc = ncrc;
-       ifmgd->beacon_crc_valid = true;
-+      ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems,
-+                            true);
++      /* room for the radiotap header based on driver features */
++      needed_headroom = ieee80211_rx_radiotap_space(local, status);
 +
-+      if (ieee80211_sta_wmm_params(local, sdata, elems.wmm_param,
-+                                   elems.wmm_param_len))
-+              changed |= BSS_CHANGED_QOS;
-+
-       if (elems.erp_info && elems.erp_info_len >= 1) {
-               erp_valid = true;
-               erp_value = elems.erp_info[0];
---- a/net/mac80211/rc80211_minstrel_ht.c
-+++ b/net/mac80211/rc80211_minstrel_ht.c
-@@ -626,8 +626,12 @@ minstrel_ht_get_rate(void *priv, struct 
- #ifdef CONFIG_MAC80211_DEBUGFS
-       /* use fixed index if set */
--      if (mp->fixed_rate_idx != -1)
--              sample_idx = mp->fixed_rate_idx;
-+      if (mp->fixed_rate_idx != -1) {
-+              mi->max_tp_rate = mp->fixed_rate_idx;
-+              mi->max_tp_rate2 = mp->fixed_rate_idx;
-+              mi->max_prob_rate = mp->fixed_rate_idx;
-+              sample_idx = -1;
-+      }
- #endif
-       if (sample_idx >= 0) {
---- a/net/mac80211/rx.c
-+++ b/net/mac80211/rx.c
-@@ -2262,6 +2262,7 @@ ieee80211_rx_h_action(struct ieee80211_r
+       if (should_drop_frame(origskb, present_fcs_len)) {
+               /* only need to expand headroom if necessary */
+               skb = origskb;
+@@ -2333,7 +2333,8 @@ ieee80211_rx_h_action(struct ieee80211_r
+       if (len < IEEE80211_MIN_ACTION_SIZE)
+               return RX_DROP_UNUSABLE;
+-      if (!rx->sta && mgmt->u.action.category != WLAN_CATEGORY_PUBLIC)
++      if (!rx->sta && mgmt->u.action.category != WLAN_CATEGORY_PUBLIC &&
++          mgmt->u.action.category != WLAN_CATEGORY_SELF_PROTECTED)
+               return RX_DROP_UNUSABLE;
+       if (!(status->rx_flags & IEEE80211_RX_RA_MATCH))
+@@ -2349,6 +2350,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_ADHOC)
                        break;
  
-@@ -2479,14 +2480,15 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_
+@@ -2625,14 +2627,15 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_
  
        if (!ieee80211_vif_is_mesh(&sdata->vif) &&
            sdata->vif.type != NL80211_IFTYPE_ADHOC &&
                break;
        case cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP):
        case cpu_to_le16(IEEE80211_STYPE_REASSOC_RESP):
-@@ -2817,10 +2819,16 @@ static int prepare_for_handlers(struct i
+@@ -2957,10 +2960,16 @@ static int prepare_for_handlers(struct i
                }
                break;
        case NL80211_IFTYPE_WDS:
 +                      return 0;
 +
                break;
-       default:
-               /* should never get here */
+       case NL80211_IFTYPE_P2P_DEVICE:
+               if (!ieee80211_is_public_action(hdr, skb->len) &&
 --- a/net/mac80211/sta_info.h
 +++ b/net/mac80211/sta_info.h
 @@ -32,7 +32,6 @@
        WLAN_STA_CLEAR_PS_FILT,
        WLAN_STA_MFP,
        WLAN_STA_BLOCK_BA,
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -2716,7 +2716,7 @@ EXPORT_SYMBOL(ieee80211_get_buffered_bc)
- void ieee80211_tx_skb_tid(struct ieee80211_sub_if_data *sdata,
-                         struct sk_buff *skb, int tid)
+--- a/net/mac80211/status.c
++++ b/net/mac80211/status.c
+@@ -502,7 +502,11 @@ void ieee80211_tx_status(struct ieee8021
+                                      IEEE80211_BAR_CTRL_TID_INFO_MASK) >>
+                                     IEEE80211_BAR_CTRL_TID_INFO_SHIFT;
+-                              ieee80211_set_bar_pending(sta, tid, ssn);
++                              if (local->hw.flags &
++                                  IEEE80211_HW_TEARDOWN_AGGR_ON_BAR_FAIL)
++                                      ieee80211_stop_tx_ba_session(&sta->sta, tid);
++                              else
++                                      ieee80211_set_bar_pending(sta, tid, ssn);
+                       }
+               }
+--- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
++++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
+@@ -534,98 +534,98 @@ static const u32 ar9300_2p2_baseband_cor
+ static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = {
+       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+-      {0x0000a2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
+-      {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
+-      {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
++      {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
++      {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
++      {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
+       {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+-      {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
+-      {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+-      {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
+-      {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
+-      {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
+-      {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
+-      {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400},
+-      {0x0000a518, 0x21002220, 0x21002220, 0x16000402, 0x16000402},
+-      {0x0000a51c, 0x27002223, 0x27002223, 0x19000404, 0x19000404},
+-      {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603},
+-      {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02},
+-      {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04},
+-      {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20},
+-      {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20},
+-      {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22},
+-      {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
+-      {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
+-      {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
+-      {0x0000a544, 0x52022470, 0x52022470, 0x3f001861, 0x3f001861},
+-      {0x0000a548, 0x55022490, 0x55022490, 0x43001a81, 0x43001a81},
+-      {0x0000a54c, 0x59022492, 0x59022492, 0x47001a83, 0x47001a83},
+-      {0x0000a550, 0x5d022692, 0x5d022692, 0x4a001c84, 0x4a001c84},
+-      {0x0000a554, 0x61022892, 0x61022892, 0x4e001ce3, 0x4e001ce3},
+-      {0x0000a558, 0x65024890, 0x65024890, 0x52001ce5, 0x52001ce5},
+-      {0x0000a55c, 0x69024892, 0x69024892, 0x56001ce9, 0x56001ce9},
+-      {0x0000a560, 0x6e024c92, 0x6e024c92, 0x5a001ceb, 0x5a001ceb},
+-      {0x0000a564, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+-      {0x0000a568, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+-      {0x0000a56c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+-      {0x0000a570, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+-      {0x0000a574, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+-      {0x0000a578, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+-      {0x0000a57c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+-      {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
+-      {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
+-      {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
+-      {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
+-      {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202},
+-      {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400},
+-      {0x0000a598, 0x21802220, 0x21802220, 0x16800402, 0x16800402},
+-      {0x0000a59c, 0x27802223, 0x27802223, 0x19800404, 0x19800404},
+-      {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603},
+-      {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02},
+-      {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04},
+-      {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20},
+-      {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20},
+-      {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22},
+-      {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24},
+-      {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640},
+-      {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660},
+-      {0x0000a5c4, 0x52822470, 0x52822470, 0x3f801861, 0x3f801861},
+-      {0x0000a5c8, 0x55822490, 0x55822490, 0x43801a81, 0x43801a81},
+-      {0x0000a5cc, 0x59822492, 0x59822492, 0x47801a83, 0x47801a83},
+-      {0x0000a5d0, 0x5d822692, 0x5d822692, 0x4a801c84, 0x4a801c84},
+-      {0x0000a5d4, 0x61822892, 0x61822892, 0x4e801ce3, 0x4e801ce3},
+-      {0x0000a5d8, 0x65824890, 0x65824890, 0x52801ce5, 0x52801ce5},
+-      {0x0000a5dc, 0x69824892, 0x69824892, 0x56801ce9, 0x56801ce9},
+-      {0x0000a5e0, 0x6e824c92, 0x6e824c92, 0x5a801ceb, 0x5a801ceb},
+-      {0x0000a5e4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+-      {0x0000a5e8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+-      {0x0000a5ec, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+-      {0x0000a5f0, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+-      {0x0000a5f4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+-      {0x0000a5f8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+-      {0x0000a5fc, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
++      {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
++      {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
++      {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002},
++      {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004},
++      {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200},
++      {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202},
++      {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400},
++      {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402},
++      {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404},
++      {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603},
++      {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02},
++      {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04},
++      {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20},
++      {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20},
++      {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22},
++      {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24},
++      {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640},
++      {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660},
++      {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861},
++      {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81},
++      {0x0000a54c, 0x59025eb2, 0x59025eb2, 0x42001a83, 0x42001a83},
++      {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84},
++      {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3},
++      {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5},
++      {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9},
++      {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb},
++      {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
++      {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
++      {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
++      {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
++      {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
++      {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
++      {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
++      {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000},
++      {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002},
++      {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004},
++      {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200},
++      {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202},
++      {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400},
++      {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402},
++      {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404},
++      {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603},
++      {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02},
++      {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04},
++      {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20},
++      {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20},
++      {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22},
++      {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24},
++      {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640},
++      {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660},
++      {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861},
++      {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81},
++      {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83},
++      {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84},
++      {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3},
++      {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5},
++      {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9},
++      {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb},
++      {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
++      {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
++      {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
++      {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
++      {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
++      {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
++      {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+-      {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+-      {0x0000a614, 0x02004000, 0x02004000, 0x01404000, 0x01404000},
+-      {0x0000a618, 0x02004801, 0x02004801, 0x01404501, 0x01404501},
+-      {0x0000a61c, 0x02808a02, 0x02808a02, 0x02008501, 0x02008501},
+-      {0x0000a620, 0x0380ce03, 0x0380ce03, 0x0280ca03, 0x0280ca03},
+-      {0x0000a624, 0x04411104, 0x04411104, 0x03010c04, 0x03010c04},
+-      {0x0000a628, 0x04411104, 0x04411104, 0x04014c04, 0x04014c04},
+-      {0x0000a62c, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+-      {0x0000a630, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+-      {0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+-      {0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+-      {0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+-      {0x0000b2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
+-      {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
+-      {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
++      {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000},
++      {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000},
++      {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501},
++      {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501},
++      {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03},
++      {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04},
++      {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04},
++      {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
++      {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
++      {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
++      {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
++      {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
++      {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
++      {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
++      {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
+       {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+-      {0x0000c2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
+-      {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
+-      {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
++      {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
++      {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
++      {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
+       {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+       {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
+       {0x00016048, 0x66480001, 0x66480001, 0x66480001, 0x66480001},
+--- a/drivers/net/wireless/ath/ath9k/debug.h
++++ b/drivers/net/wireless/ath/ath9k/debug.h
+@@ -242,7 +242,7 @@ struct ath_rx_stats {
+ struct ath_stats {
+       struct ath_interrupt_stats istats;
+-      struct ath_tx_stats txstats[IEEE80211_NUM_ACS];
++      struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES];
+       struct ath_rx_stats rxstats;
+       struct ath_dfs_stats dfs_stats;
+       u32 reset[__RESET_TYPE_MAX];
+--- a/drivers/net/wireless/ath/carl9170/rx.c
++++ b/drivers/net/wireless/ath/carl9170/rx.c
+@@ -684,7 +684,7 @@ static int carl9170_handle_mpdu(struct a
+       if (!skb)
+               return -ENOMEM;
+-      memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
++      memcpy(IEEE80211_SKB_RXCB(skb), status, sizeof(*status));
+       ieee80211_rx(ar->hw, skb);
+       return 0;
+ }
+--- a/drivers/net/wireless/ath/ath9k/calib.c
++++ b/drivers/net/wireless/ath/ath9k/calib.c
+@@ -69,6 +69,7 @@ s16 ath9k_hw_getchan_noise(struct ath_hw
+       if (chan && chan->noisefloor) {
+               s8 delta = chan->noisefloor -
++                         ATH9K_NF_CAL_NOISE_THRESH -
+                          ath9k_hw_get_default_nf(ah, chan);
+               if (delta > 0)
+                       noise += delta;
+--- a/drivers/net/wireless/ath/ath9k/calib.h
++++ b/drivers/net/wireless/ath/ath9k/calib.h
+@@ -21,6 +21,9 @@
+ #define AR_PHY_CCA_FILTERWINDOW_LENGTH          5
++/* Internal noise floor can vary by about 6db depending on the frequency */
++#define ATH9K_NF_CAL_NOISE_THRESH             6
++
+ #define NUM_NF_READINGS       6
+ #define ATH9K_NF_CAL_HIST_MAX 5
+--- a/drivers/net/wireless/ath/ath5k/base.c
++++ b/drivers/net/wireless/ath/ath5k/base.c
+@@ -851,7 +851,7 @@ ath5k_txbuf_free_skb(struct ath5k_hw *ah
+               return;
+       dma_unmap_single(ah->dev, bf->skbaddr, bf->skb->len,
+                       DMA_TO_DEVICE);
+-      dev_kfree_skb_any(bf->skb);
++      ieee80211_free_txskb(ah->hw, bf->skb);
+       bf->skb = NULL;
+       bf->skbaddr = 0;
+       bf->desc->ds_data = 0;
+@@ -1578,7 +1578,7 @@ ath5k_tx_queue(struct ieee80211_hw *hw, 
+       return;
+ drop_packet:
+-      dev_kfree_skb_any(skb);
++      ieee80211_free_txskb(hw, skb);
+ }
+ static void
+--- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c
++++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
+@@ -65,7 +65,7 @@ ath5k_tx(struct ieee80211_hw *hw, struct
+       u16 qnum = skb_get_queue_mapping(skb);
+       if (WARN_ON(qnum >= ah->ah_capabilities.cap_queues.q_tx_num)) {
+-              dev_kfree_skb_any(skb);
++              ieee80211_free_txskb(hw, skb);
+               return;
+       }
+--- a/drivers/net/wireless/b43/dma.c
++++ b/drivers/net/wireless/b43/dma.c
+@@ -409,7 +409,10 @@ static inline
+                               struct b43_dmadesc_meta *meta)
  {
--      int ac = ieee802_1d_to_ac[tid];
-+      int ac = ieee802_1d_to_ac[tid & 7];
-       skb_set_mac_header(skb, 0);
-       skb_set_network_header(skb, 0);
---- a/net/wireless/chan.c
-+++ b/net/wireless/chan.c
-@@ -136,9 +136,16 @@ cfg80211_get_chan_state(struct cfg80211_
-               break;
-       case NL80211_IFTYPE_AP:
-       case NL80211_IFTYPE_P2P_GO:
-+              if (wdev->beacon_interval) {
-+                      *chan = wdev->channel;
-+                      *chanmode = CHAN_MODE_SHARED;
-+              }
-+              return;
-       case NL80211_IFTYPE_MESH_POINT:
--              *chan = wdev->channel;
--              *chanmode = CHAN_MODE_SHARED;
-+              if (wdev->mesh_id_len) {
-+                      *chan = wdev->channel;
-+                      *chanmode = CHAN_MODE_SHARED;
-+              }
+       if (meta->skb) {
+-              dev_kfree_skb_any(meta->skb);
++              if (ring->tx)
++                      ieee80211_free_txskb(ring->dev->wl->hw, meta->skb);
++              else
++                      dev_kfree_skb_any(meta->skb);
+               meta->skb = NULL;
+       }
+ }
+@@ -1454,7 +1457,7 @@ int b43_dma_tx(struct b43_wldev *dev, st
+       if (unlikely(err == -ENOKEY)) {
+               /* Drop this packet, as we don't have the encryption key
+                * anymore and must not transmit it unencrypted. */
+-              dev_kfree_skb_any(skb);
++              ieee80211_free_txskb(dev->wl->hw, skb);
+               err = 0;
+               goto out;
+       }
+--- a/drivers/net/wireless/b43/main.c
++++ b/drivers/net/wireless/b43/main.c
+@@ -3397,7 +3397,7 @@ static void b43_tx_work(struct work_stru
+                               break;
+                       }
+                       if (unlikely(err))
+-                              dev_kfree_skb(skb); /* Drop it */
++                              ieee80211_free_txskb(wl->hw, skb);
+                       err = 0;
+               }
+@@ -3419,7 +3419,7 @@ static void b43_op_tx(struct ieee80211_h
+       if (unlikely(skb->len < 2 + 2 + 6)) {
+               /* Too short, this can't be a valid frame. */
+-              dev_kfree_skb_any(skb);
++              ieee80211_free_txskb(hw, skb);
                return;
-       case NL80211_IFTYPE_MONITOR:
-       case NL80211_IFTYPE_AP_VLAN:
+       }
+       B43_WARN_ON(skb_shinfo(skb)->nr_frags);
+@@ -4234,8 +4234,12 @@ redo:
+       /* Drain all TX queues. */
+       for (queue_num = 0; queue_num < B43_QOS_QUEUE_NUM; queue_num++) {
+-              while (skb_queue_len(&wl->tx_queue[queue_num]))
+-                      dev_kfree_skb(skb_dequeue(&wl->tx_queue[queue_num]));
++              while (skb_queue_len(&wl->tx_queue[queue_num])) {
++                      struct sk_buff *skb;
++
++                      skb = skb_dequeue(&wl->tx_queue[queue_num]);
++                      ieee80211_free_txskb(wl->hw, skb);
++              }
+       }
+       b43_mac_suspend(dev);
+--- a/drivers/net/wireless/b43/pio.c
++++ b/drivers/net/wireless/b43/pio.c
+@@ -196,7 +196,7 @@ static void b43_pio_cancel_tx_packets(st
+       for (i = 0; i < ARRAY_SIZE(q->packets); i++) {
+               pack = &(q->packets[i]);
+               if (pack->skb) {
+-                      dev_kfree_skb_any(pack->skb);
++                      ieee80211_free_txskb(q->dev->wl->hw, pack->skb);
+                       pack->skb = NULL;
+               }
+       }
+@@ -552,7 +552,7 @@ int b43_pio_tx(struct b43_wldev *dev, st
+       if (unlikely(err == -ENOKEY)) {
+               /* Drop this packet, as we don't have the encryption key
+                * anymore and must not transmit it unencrypted. */
+-              dev_kfree_skb_any(skb);
++              ieee80211_free_txskb(dev->wl->hw, skb);
+               err = 0;
+               goto out;
+       }
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -915,6 +915,12 @@ static int ieee80211_start_ap(struct wip
+       if (err)
+               return err;
++      list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) {
++              err = ieee80211_vif_copy_channel(vlan, sdata);
++              if (err)
++                      return err;
++      }
++
+       /*
+        * Apply control port protocol, this allows us to
+        * not encrypt dynamic WEP control frames.
+@@ -998,8 +1004,11 @@ static int ieee80211_stop_ap(struct wiph
+       old_probe_resp = rtnl_dereference(sdata->u.ap.probe_resp);
+       /* turn off carrier for this interface and dependent VLANs */
+-      list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
++      list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) {
++              sta_info_flush(local, vlan);
+               netif_carrier_off(vlan->dev);
++              ieee80211_vif_release_channel(vlan);
++      }
+       netif_carrier_off(dev);
+       /* remove beacon and probe response */
+--- a/net/mac80211/chan.c
++++ b/net/mac80211/chan.c
+@@ -119,14 +119,17 @@ static int ieee80211_assign_vif_chanctx(
+       lockdep_assert_held(&local->chanctx_mtx);
+-      ret = drv_assign_vif_chanctx(local, sdata, ctx);
+-      if (ret)
+-              return ret;
++      if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN) {
++              ret = drv_assign_vif_chanctx(local, sdata, ctx);
++              if (ret)
++                      return ret;
++      }
+       rcu_assign_pointer(sdata->vif.chanctx_conf, &ctx->conf);
+       ctx->refcount++;
+-      ieee80211_recalc_txpower(sdata);
++      if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN)
++              ieee80211_recalc_txpower(sdata);
+       return 0;
+ }
+@@ -174,7 +177,8 @@ static void ieee80211_unassign_vif_chanc
+       ctx->refcount--;
+       rcu_assign_pointer(sdata->vif.chanctx_conf, NULL);
+-      drv_unassign_vif_chanctx(local, sdata, ctx);
++      if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN)
++              drv_unassign_vif_chanctx(local, sdata, ctx);
+       if (ctx->refcount > 0) {
+               ieee80211_recalc_chanctx_chantype(sdata->local, ctx);
+@@ -285,6 +289,30 @@ void ieee80211_recalc_smps_chanctx(struc
+       drv_change_chanctx(local, chanctx, IEEE80211_CHANCTX_CHANGE_RX_CHAINS);
+ }
++int ieee80211_vif_copy_channel(struct ieee80211_sub_if_data *sdata,
++                             struct ieee80211_sub_if_data *parent)
++{
++      struct ieee80211_local *local = sdata->local;
++      struct ieee80211_chanctx_conf *conf;
++      struct ieee80211_chanctx *ctx;
++
++      int ret;
++
++      mutex_lock(&local->chanctx_mtx);
++      conf = rcu_dereference_protected(parent->vif.chanctx_conf,
++                                       lockdep_is_held(&local->chanctx_mtx));
++      if (!conf) {
++              ret = -ENOENT;
++              goto out;
++      }
++
++      ctx = container_of(conf, struct ieee80211_chanctx, conf);
++      ret = ieee80211_assign_vif_chanctx(sdata, ctx);
++out:
++      mutex_unlock(&local->chanctx_mtx);
++      return ret;
++}
++
+ int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
+                             const struct cfg80211_chan_def *chandef,
+                             enum ieee80211_chanctx_mode mode)
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -1633,6 +1633,8 @@ ieee80211_vif_use_channel(struct ieee802
+                         const struct cfg80211_chan_def *chandef,
+                         enum ieee80211_chanctx_mode mode);
+ void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata);
++int ieee80211_vif_copy_channel(struct ieee80211_sub_if_data *sdata,
++                             struct ieee80211_sub_if_data *parent);
+ void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local,
+                                  struct ieee80211_chanctx *chanctx);
+--- a/include/linux/ieee80211.h
++++ b/include/linux/ieee80211.h
+@@ -180,7 +180,7 @@ struct ieee80211_hdr {
+       u8 addr3[6];
+       __le16 seq_ctrl;
+       u8 addr4[6];
+-} __attribute__ ((packed));
++} __packed;
+ struct ieee80211_hdr_3addr {
+       __le16 frame_control;
+@@ -189,7 +189,7 @@ struct ieee80211_hdr_3addr {
+       u8 addr2[6];
+       u8 addr3[6];
+       __le16 seq_ctrl;
+-} __attribute__ ((packed));
++} __packed;
+ struct ieee80211_qos_hdr {
+       __le16 frame_control;
+@@ -199,7 +199,7 @@ struct ieee80211_qos_hdr {
+       u8 addr3[6];
+       __le16 seq_ctrl;
+       __le16 qos_ctrl;
+-} __attribute__ ((packed));
++} __packed;
+ /**
+  * ieee80211_has_tods - check if IEEE80211_FCTL_TODS is set
+@@ -576,7 +576,7 @@ struct ieee80211s_hdr {
+       __le32 seqnum;
+       u8 eaddr1[6];
+       u8 eaddr2[6];
+-} __attribute__ ((packed));
++} __packed;
+ /* Mesh flags */
+ #define MESH_FLAGS_AE_A4      0x1
+@@ -614,7 +614,7 @@ struct ieee80211_quiet_ie {
+       u8 period;
+       __le16 duration;
+       __le16 offset;
+-} __attribute__ ((packed));
++} __packed;
+ /**
+  * struct ieee80211_msrment_ie
+@@ -626,7 +626,7 @@ struct ieee80211_msrment_ie {
+       u8 mode;
+       u8 type;
+       u8 request[0];
+-} __attribute__ ((packed));
++} __packed;
+ /**
+  * struct ieee80211_channel_sw_ie
+@@ -637,7 +637,7 @@ struct ieee80211_channel_sw_ie {
+       u8 mode;
+       u8 new_ch_num;
+       u8 count;
+-} __attribute__ ((packed));
++} __packed;
+ /**
+  * struct ieee80211_tim
+@@ -650,7 +650,7 @@ struct ieee80211_tim_ie {
+       u8 bitmap_ctrl;
+       /* variable size: 1 - 251 bytes */
+       u8 virtual_map[1];
+-} __attribute__ ((packed));
++} __packed;
+ /**
+  * struct ieee80211_meshconf_ie
+@@ -665,7 +665,7 @@ struct ieee80211_meshconf_ie {
+       u8 meshconf_auth;
+       u8 meshconf_form;
+       u8 meshconf_cap;
+-} __attribute__ ((packed));
++} __packed;
+ /**
+  * enum mesh_config_capab_flags - Mesh Configuration IE capability field flags
+@@ -695,7 +695,7 @@ struct ieee80211_rann_ie {
+       __le32 rann_seq;
+       __le32 rann_interval;
+       __le32 rann_metric;
+-} __attribute__ ((packed));
++} __packed;
+ enum ieee80211_rann_flags {
+       RANN_FLAG_IS_GATE = 1 << 0,
+@@ -717,33 +717,33 @@ struct ieee80211_mgmt {
+                       __le16 status_code;
+                       /* possibly followed by Challenge text */
+                       u8 variable[0];
+-              } __attribute__ ((packed)) auth;
++              } __packed auth;
+               struct {
+                       __le16 reason_code;
+-              } __attribute__ ((packed)) deauth;
++              } __packed deauth;
+               struct {
+                       __le16 capab_info;
+                       __le16 listen_interval;
+                       /* followed by SSID and Supported rates */
+                       u8 variable[0];
+-              } __attribute__ ((packed)) assoc_req;
++              } __packed assoc_req;
+               struct {
+                       __le16 capab_info;
+                       __le16 status_code;
+                       __le16 aid;
+                       /* followed by Supported rates */
+                       u8 variable[0];
+-              } __attribute__ ((packed)) assoc_resp, reassoc_resp;
++              } __packed assoc_resp, reassoc_resp;
+               struct {
+                       __le16 capab_info;
+                       __le16 listen_interval;
+                       u8 current_ap[6];
+                       /* followed by SSID and Supported rates */
+                       u8 variable[0];
+-              } __attribute__ ((packed)) reassoc_req;
++              } __packed reassoc_req;
+               struct {
+                       __le16 reason_code;
+-              } __attribute__ ((packed)) disassoc;
++              } __packed disassoc;
+               struct {
+                       __le64 timestamp;
+                       __le16 beacon_int;
+@@ -751,11 +751,11 @@ struct ieee80211_mgmt {
+                       /* followed by some of SSID, Supported rates,
+                        * FH Params, DS Params, CF Params, IBSS Params, TIM */
+                       u8 variable[0];
+-              } __attribute__ ((packed)) beacon;
++              } __packed beacon;
+               struct {
+                       /* only variable items: SSID, Supported rates */
+                       u8 variable[0];
+-              } __attribute__ ((packed)) probe_req;
++              } __packed probe_req;
+               struct {
+                       __le64 timestamp;
+                       __le16 beacon_int;
+@@ -763,7 +763,7 @@ struct ieee80211_mgmt {
+                       /* followed by some of SSID, Supported rates,
+                        * FH Params, DS Params, CF Params, IBSS Params */
+                       u8 variable[0];
+-              } __attribute__ ((packed)) probe_resp;
++              } __packed probe_resp;
+               struct {
+                       u8 category;
+                       union {
+@@ -772,55 +772,55 @@ struct ieee80211_mgmt {
+                                       u8 dialog_token;
+                                       u8 status_code;
+                                       u8 variable[0];
+-                              } __attribute__ ((packed)) wme_action;
++                              } __packed wme_action;
+                               struct{
+                                       u8 action_code;
+                                       u8 element_id;
+                                       u8 length;
+                                       struct ieee80211_channel_sw_ie sw_elem;
+-                              } __attribute__((packed)) chan_switch;
++                              } __packed chan_switch;
+                               struct{
+                                       u8 action_code;
+                                       u8 dialog_token;
+                                       u8 element_id;
+                                       u8 length;
+                                       struct ieee80211_msrment_ie msr_elem;
+-                              } __attribute__((packed)) measurement;
++                              } __packed measurement;
+                               struct{
+                                       u8 action_code;
+                                       u8 dialog_token;
+                                       __le16 capab;
+                                       __le16 timeout;
+                                       __le16 start_seq_num;
+-                              } __attribute__((packed)) addba_req;
++                              } __packed addba_req;
+                               struct{
+                                       u8 action_code;
+                                       u8 dialog_token;
+                                       __le16 status;
+                                       __le16 capab;
+                                       __le16 timeout;
+-                              } __attribute__((packed)) addba_resp;
++                              } __packed addba_resp;
+                               struct{
+                                       u8 action_code;
+                                       __le16 params;
+                                       __le16 reason_code;
+-                              } __attribute__((packed)) delba;
++                              } __packed delba;
+                               struct {
+                                       u8 action_code;
+                                       u8 variable[0];
+-                              } __attribute__((packed)) self_prot;
++                              } __packed self_prot;
+                               struct{
+                                       u8 action_code;
+                                       u8 variable[0];
+-                              } __attribute__((packed)) mesh_action;
++                              } __packed mesh_action;
+                               struct {
+                                       u8 action;
+                                       u8 trans_id[WLAN_SA_QUERY_TR_ID_LEN];
+-                              } __attribute__ ((packed)) sa_query;
++                              } __packed sa_query;
+                               struct {
+                                       u8 action;
+                                       u8 smps_control;
+-                              } __attribute__ ((packed)) ht_smps;
++                              } __packed ht_smps;
+                               struct {
+                                       u8 action_code;
+                                       u8 dialog_token;
+@@ -828,9 +828,9 @@ struct ieee80211_mgmt {
+                                       u8 variable[0];
+                               } __packed tdls_discover_resp;
+                       } u;
+-              } __attribute__ ((packed)) action;
++              } __packed action;
+       } u;
+-} __attribute__ ((packed));
++} __packed;
+ /* Supported Rates value encodings in 802.11n-2009 7.3.2.2 */
+ #define BSS_MEMBERSHIP_SELECTOR_HT_PHY        127
+@@ -846,7 +846,7 @@ struct ieee80211_mmie {
+       __le16 key_id;
+       u8 sequence_number[6];
+       u8 mic[8];
+-} __attribute__ ((packed));
++} __packed;
+ struct ieee80211_vendor_ie {
+       u8 element_id;
+@@ -861,20 +861,20 @@ struct ieee80211_rts {
+       __le16 duration;
+       u8 ra[6];
+       u8 ta[6];
+-} __attribute__ ((packed));
++} __packed;
+ struct ieee80211_cts {
+       __le16 frame_control;
+       __le16 duration;
+       u8 ra[6];
+-} __attribute__ ((packed));
++} __packed;
+ struct ieee80211_pspoll {
+       __le16 frame_control;
+       __le16 aid;
+       u8 bssid[6];
+       u8 ta[6];
+-} __attribute__ ((packed));
++} __packed;
+ /* TDLS */
+@@ -967,7 +967,7 @@ struct ieee80211_bar {
+       __u8 ta[6];
+       __le16 control;
+       __le16 start_seq_num;
+-} __attribute__((packed));
++} __packed;
+ /* 802.11 BAR control masks */
+ #define IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL  0x0000
+@@ -992,7 +992,7 @@ struct ieee80211_mcs_info {
+       __le16 rx_highest;
+       u8 tx_params;
+       u8 reserved[3];
+-} __attribute__((packed));
++} __packed;
+ /* 802.11n HT capability MSC set */
+ #define IEEE80211_HT_MCS_RX_HIGHEST_MASK      0x3ff
+@@ -1031,7 +1031,7 @@ struct ieee80211_ht_cap {
+       __le16 extended_ht_cap_info;
+       __le32 tx_BF_cap_info;
+       u8 antenna_selection_info;
+-} __attribute__ ((packed));
++} __packed;
+ /* 802.11n HT capabilities masks (for cap_info) */
+ #define IEEE80211_HT_CAP_LDPC_CODING          0x0001
+@@ -1102,7 +1102,7 @@ struct ieee80211_ht_operation {
+       __le16 operation_mode;
+       __le16 stbc_param;
+       u8 basic_set[16];
+-} __attribute__ ((packed));
++} __packed;
+ /* for ht_param */
+ #define IEEE80211_HT_PARAM_CHA_SEC_OFFSET             0x03
+@@ -1832,14 +1832,14 @@ struct ieee80211_country_ie_triplet {
+                       u8 first_channel;
+                       u8 num_channels;
+                       s8 max_power;
+-              } __attribute__ ((packed)) chans;
++              } __packed chans;
+               struct {
+                       u8 reg_extension_id;
+                       u8 reg_class;
+                       u8 coverage_class;
+-              } __attribute__ ((packed)) ext;
++              } __packed ext;
+       };
+-} __attribute__ ((packed));
++} __packed;
+ enum ieee80211_timeout_interval_type {
+       WLAN_TIMEOUT_REASSOC_DEADLINE = 1 /* 802.11r */,
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -1256,7 +1256,7 @@ struct cfg80211_bss {
+       u8 bssid[ETH_ALEN];
+-      u8 priv[0] __attribute__((__aligned__(sizeof(void *))));
++      u8 priv[0] __aligned(sizeof(void *));
+ };
+ /**
+@@ -2395,7 +2395,7 @@ struct wiphy {
+       const struct iw_handler_def *wext;
+ #endif
+-      char priv[0] __attribute__((__aligned__(NETDEV_ALIGN)));
++      char priv[0] __aligned(NETDEV_ALIGN);
+ };
+ static inline struct net *wiphy_net(struct wiphy *wiphy)
+--- a/net/wireless/core.h
++++ b/net/wireless/core.h
+@@ -86,7 +86,7 @@ struct cfg80211_registered_device {
+       /* must be last because of the way we do wiphy_priv(),
+        * and it should at least be aligned to NETDEV_ALIGN */
+-      struct wiphy wiphy __attribute__((__aligned__(NETDEV_ALIGN)));
++      struct wiphy wiphy __aligned(NETDEV_ALIGN);
+ };
+ static inline