+ struct sk_buff *skb = bf->bf_mpdu;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+@@ -2057,9 +2057,7 @@ static void ath_tx_rc_status(struct ath_
+ tx_rateindex = ts->ts_rateindex;
+ WARN_ON(tx_rateindex >= hw->max_rates);
+
+- if (ts->ts_status & ATH9K_TXERR_FILT)
+- tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
+- if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && update_rc) {
++ if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
+ tx_info->flags |= IEEE80211_TX_STAT_AMPDU;
+
+ BUG_ON(nbad > nframes);
+@@ -2069,7 +2067,7 @@ static void ath_tx_rc_status(struct ath_
+ }
+
+ if ((ts->ts_status & ATH9K_TXERR_FILT) == 0 &&
+- (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) {
++ (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) == 0) {
+ /*
+ * If an underrun error is seen assume it as an excessive
+ * retry only if max frame trigger level has been reached
+@@ -2082,9 +2080,9 @@ static void ath_tx_rc_status(struct ath_
+ * successfully by eventually preferring slower rates.
+ * This itself should also alleviate congestion on the bus.
+ */
+- if (ieee80211_is_data(hdr->frame_control) &&
+- (ts->ts_flags & (ATH9K_TX_DATA_UNDERRUN |
+- ATH9K_TX_DELIM_UNDERRUN)) &&
++ if (unlikely(ts->ts_flags & (ATH9K_TX_DATA_UNDERRUN |
++ ATH9K_TX_DELIM_UNDERRUN)) &&
++ ieee80211_is_data(hdr->frame_control) &&
+ ah->tx_trig_level >= sc->sc_ah->config.max_txtrig_level)
+ tx_info->status.rates[tx_rateindex].count =
+ hw->max_rate_tries;
+@@ -2115,13 +2113,7 @@ static void ath_tx_process_buffer(struct
+ spin_unlock_bh(&txq->axq_lock);
+
+ if (!bf_isampdu(bf)) {
+- /*
+- * This frame is sent out as a single frame.
+- * Use hardware retry status for this frame.
+- */
+- if (ts->ts_status & ATH9K_TXERR_XRETRY)
+- bf->bf_state.bf_type |= BUF_XRETRY;
+- ath_tx_rc_status(sc, bf, ts, 1, txok ? 0 : 1, txok, true);
++ ath_tx_rc_status(sc, bf, ts, 1, txok ? 0 : 1, txok);
+ ath_tx_complete_buf(sc, bf, txq, bf_head, ts, txok, 0);
+ } else
+ ath_tx_complete_aggr(sc, txq, bf, bf_head, ts, txok, true);
+--- a/net/mac80211/agg-rx.c
++++ b/net/mac80211/agg-rx.c
+@@ -180,6 +180,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);
++ else if (sdata->vif.type == NL80211_IFTYPE_WDS)
++ memcpy(mgmt->bssid, da, ETH_ALEN);
+
+ mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
+ IEEE80211_STYPE_ACTION);
+--- a/net/mac80211/agg-tx.c
++++ b/net/mac80211/agg-tx.c
+@@ -77,7 +77,8 @@ static void ieee80211_send_addba_request
+ memcpy(mgmt->da, da, ETH_ALEN);
+ memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
+ if (sdata->vif.type == NL80211_IFTYPE_AP ||
+- sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
++ sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
++ sdata->vif.type == NL80211_IFTYPE_WDS)
+ memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
+ else if (sdata->vif.type == NL80211_IFTYPE_STATION)
+ memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
+@@ -397,7 +398,8 @@ int ieee80211_start_tx_ba_session(struct
+ */
+ if (sdata->vif.type != NL80211_IFTYPE_STATION &&
+ sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
+- sdata->vif.type != NL80211_IFTYPE_AP)
++ sdata->vif.type != NL80211_IFTYPE_AP &&
++ sdata->vif.type != NL80211_IFTYPE_WDS)
+ return -EINVAL;
+
+ if (test_sta_flags(sta, WLAN_STA_BLOCK_BA)) {
+--- a/net/mac80211/debugfs_sta.c
++++ b/net/mac80211/debugfs_sta.c
+@@ -59,7 +59,7 @@ static ssize_t sta_flags_read(struct fil
+ char buf[100];
+ struct sta_info *sta = file->private_data;
+ u32 staflags = get_sta_flags(sta);
+- int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s",
++ int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s",
+ staflags & WLAN_STA_AUTH ? "AUTH\n" : "",
+ staflags & WLAN_STA_ASSOC ? "ASSOC\n" : "",
+ staflags & WLAN_STA_PS_STA ? "PS (sta)\n" : "",
+@@ -67,7 +67,6 @@ static ssize_t sta_flags_read(struct fil
+ staflags & WLAN_STA_AUTHORIZED ? "AUTHORIZED\n" : "",
+ staflags & WLAN_STA_SHORT_PREAMBLE ? "SHORT PREAMBLE\n" : "",
+ staflags & WLAN_STA_WME ? "WME\n" : "",
+- staflags & WLAN_STA_WDS ? "WDS\n" : "",
+ staflags & WLAN_STA_MFP ? "MFP\n" : "");
+ return simple_read_from_buffer(userbuf, count, ppos, buf, res);
+ }
+--- a/net/mac80211/iface.c
++++ b/net/mac80211/iface.c
+@@ -178,7 +178,6 @@ static int ieee80211_do_open(struct net_
+ {
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ struct ieee80211_local *local = sdata->local;
+- struct sta_info *sta;
+ u32 changed = 0;
+ int res;
+ u32 hw_reconf_flags = 0;
+@@ -290,27 +289,6 @@ static int ieee80211_do_open(struct net_
+
+ set_bit(SDATA_STATE_RUNNING, &sdata->state);
+
+- if (sdata->vif.type == NL80211_IFTYPE_WDS) {
+- /* Create STA entry for the WDS peer */
+- sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr,
+- GFP_KERNEL);
+- if (!sta) {
+- res = -ENOMEM;
+- goto err_del_interface;
+- }
+-
+- /* no locking required since STA is not live yet */
+- sta->flags |= WLAN_STA_AUTHORIZED;
+-
+- res = sta_info_insert(sta);
+- if (res) {
+- /* STA has been freed */
+- goto err_del_interface;
+- }
+-
+- rate_control_rate_init(sta);
+- }
+-
+ /*
+ * set_multicast_list will be invoked by the networking core
+ * which will check whether any increments here were done in
+@@ -344,8 +322,7 @@ static int ieee80211_do_open(struct net_
+ netif_tx_start_all_queues(dev);
+
+ return 0;
+- err_del_interface:
+- drv_remove_interface(local, &sdata->vif);
++
+ err_stop:
+ if (!local->open_count)
+ drv_stop(local);
+@@ -718,6 +695,70 @@ static void ieee80211_if_setup(struct ne
+ dev->destructor = free_netdev;
+ }
+
++static void ieee80211_wds_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
++ struct sk_buff *skb)
++{
++ struct ieee80211_local *local = sdata->local;
++ struct ieee80211_rx_status *rx_status;
++ struct ieee802_11_elems elems;
++ struct ieee80211_mgmt *mgmt;
++ struct sta_info *sta;
++ size_t baselen;
++ u32 rates = 0;
++ u16 stype;
++ bool new = false;
++ enum ieee80211_band band = local->hw.conf.channel->band;
++ struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
++
++ rx_status = IEEE80211_SKB_RXCB(skb);
++ mgmt = (struct ieee80211_mgmt *) skb->data;
++ stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE;
++
++ if (stype != IEEE80211_STYPE_BEACON)
++ return;
++
++ baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
++ if (baselen > skb->len)
++ return;
++
++ ieee802_11_parse_elems(mgmt->u.probe_resp.variable,
++ skb->len - baselen, &elems);
++
++ rates = ieee80211_sta_get_rates(local, &elems, band);
++
++ rcu_read_lock();
++
++ sta = sta_info_get(sdata, sdata->u.wds.remote_addr);
++
++ if (!sta) {
++ rcu_read_unlock();
++ sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr,
++ GFP_KERNEL);
++ if (!sta)
++ return;
++
++ new = true;
++ }
++
++ sta->last_rx = jiffies;
++ sta->sta.supp_rates[local->hw.conf.channel->band] = rates;
++
++ if (elems.ht_cap_elem)
++ ieee80211_ht_cap_ie_to_sta_ht_cap(sband,
++ elems.ht_cap_elem, &sta->sta.ht_cap);
++
++ if (elems.wmm_param)
++ set_sta_flags(sta, WLAN_STA_WME);
++
++ if (new) {
++ sta->flags = WLAN_STA_AUTHORIZED;
++ rate_control_rate_init(sta);
++ sta_info_insert_rcu(sta);
++ }
++
++ rcu_read_unlock();
++}
++
+ static void ieee80211_iface_work(struct work_struct *work)
+ {
+ struct ieee80211_sub_if_data *sdata =
+@@ -822,6 +863,9 @@ static void ieee80211_iface_work(struct
+ break;
+ ieee80211_mesh_rx_queued_mgmt(sdata, skb);
+ break;
++ case NL80211_IFTYPE_WDS:
++ ieee80211_wds_rx_queued_mgmt(sdata, skb);
++ break;
+ default:
+ WARN(1, "frame for unexpected interface type");
+ break;
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -2163,7 +2163,8 @@ ieee80211_rx_h_action(struct ieee80211_r
+ */
+ if (sdata->vif.type != NL80211_IFTYPE_STATION &&
+ sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
+- sdata->vif.type != NL80211_IFTYPE_AP)
++ sdata->vif.type != NL80211_IFTYPE_AP &&
++ sdata->vif.type != NL80211_IFTYPE_WDS)
+ break;
+
+ /* verify action_code is present */
+@@ -2378,13 +2379,14 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_
+
+ if (!ieee80211_vif_is_mesh(&sdata->vif) &&
+ sdata->vif.type != NL80211_IFTYPE_ADHOC &&
+- sdata->vif.type != NL80211_IFTYPE_STATION)
++ sdata->vif.type != NL80211_IFTYPE_STATION &&
++ sdata->vif.type != NL80211_IFTYPE_WDS)
+ return RX_DROP_MONITOR;
+
+ switch (stype) {
+ case cpu_to_le16(IEEE80211_STYPE_BEACON):
+ case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP):
+- /* process for all: mesh, mlme, ibss */
++ /* process for all: mesh, mlme, ibss, wds */
+ break;
+ case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
+ case cpu_to_le16(IEEE80211_STYPE_DISASSOC):
+@@ -2727,10 +2729,16 @@ static int prepare_for_handlers(struct i
+ }
+ break;
+ case NL80211_IFTYPE_WDS:
+- if (bssid || !ieee80211_is_data(hdr->frame_control))
+- return 0;
+ if (compare_ether_addr(sdata->u.wds.remote_addr, hdr->addr2))
+ return 0;
++
++ if (ieee80211_is_data(hdr->frame_control) ||
++ ieee80211_is_action(hdr->frame_control)) {
++ if (compare_ether_addr(sdata->vif.addr, hdr->addr1))
++ return 0;
++ } else if (!ieee80211_is_beacon(hdr->frame_control))
++ return 0;
++
+ break;
+ default:
+ /* should never get here */
+--- a/net/mac80211/sta_info.h
++++ b/net/mac80211/sta_info.h
+@@ -31,7 +31,6 @@
+ * frames.
+ * @WLAN_STA_ASSOC_AP: We're associated to that station, it is an AP.
+ * @WLAN_STA_WME: Station is a QoS-STA.
+- * @WLAN_STA_WDS: Station is one of our WDS peers.
+ * @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the
+ * IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next
+ * frame to this station is transmitted.
+@@ -54,7 +53,6 @@ enum ieee80211_sta_info_flags {
+ WLAN_STA_SHORT_PREAMBLE = 1<<4,
+ WLAN_STA_ASSOC_AP = 1<<5,
+ WLAN_STA_WME = 1<<6,
+- WLAN_STA_WDS = 1<<7,
+ WLAN_STA_CLEAR_PS_FILT = 1<<9,
+ WLAN_STA_MFP = 1<<10,
+ WLAN_STA_BLOCK_BA = 1<<11,
+--- a/net/mac80211/status.c
++++ b/net/mac80211/status.c
+@@ -278,17 +278,19 @@ void ieee80211_tx_status(struct ieee8021
+ }
+
+ if (!acked && ieee80211_is_back_req(fc)) {
++ u16 control;
++
+ /*
+- * BAR failed, let's tear down the BA session as a
+- * last resort as some STAs (Intel 5100 on Windows)
+- * can get stuck when the BA window isn't flushed
+- * correctly.
++ * BAR failed, store the last SSN and retry sending
++ * the BAR when the next unicast transmission on the
++ * same TID succeeds.
+ */
+ bar = (struct ieee80211_bar *) skb->data;
+- if (!(bar->control & IEEE80211_BAR_CTRL_MULTI_TID)) {
++ control = le16_to_cpu(bar->control);
++ if (!(control & IEEE80211_BAR_CTRL_MULTI_TID)) {
+ u16 ssn = le16_to_cpu(bar->start_seq_num);
+
+- tid = (bar->control &
++ tid = (control &
+ IEEE80211_BAR_CTRL_TID_INFO_MASK) >>
+ IEEE80211_BAR_CTRL_TID_INFO_SHIFT;
+
+--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
++++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+@@ -704,8 +704,10 @@ static void ar5008_hw_override_ini(struc
+ REG_WRITE(ah, AR_PCU_MISC_MODE2, val);
+ }
+
+- if (!AR_SREV_5416_20_OR_LATER(ah) ||
+- AR_SREV_9280_20_OR_LATER(ah))
++ REG_SET_BIT(ah, AR_PHY_CCK_DETECT,
++ AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
++
++ if (AR_SREV_9280_20_OR_LATER(ah))
+ return;
+ /*
+ * Disable BB clock gating
+@@ -802,7 +804,8 @@ static int ar5008_hw_process_ini(struct
+
+ /* Write ADDAC shifts */
+ REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO);
+- ah->eep_ops->set_addac(ah, chan);
++ if (ah->eep_ops->set_addac)
++ ah->eep_ops->set_addac(ah, chan);
+
+ if (AR_SREV_5416_22_OR_LATER(ah)) {
+ REG_WRITE_ARRAY(&ah->iniAddac, 1, regWrites);
+@@ -1007,24 +1010,6 @@ static void ar5008_restore_chainmask(str
+ }
+ }
+
+-static void ar5008_set_diversity(struct ath_hw *ah, bool value)
+-{
+- u32 v = REG_READ(ah, AR_PHY_CCK_DETECT);
+- if (value)
+- v |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
+- else
+- v &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
+- REG_WRITE(ah, AR_PHY_CCK_DETECT, v);
+-}
+-
+-static u32 ar9100_hw_compute_pll_control(struct ath_hw *ah,
+- struct ath9k_channel *chan)
+-{
+- if (chan && IS_CHAN_5GHZ(chan))
+- return 0x1450;
+- return 0x1458;
+-}
+-
+ static u32 ar9160_hw_compute_pll_control(struct ath_hw *ah,
+ struct ath9k_channel *chan)
+ {
+@@ -1654,7 +1639,6 @@ void ar5008_hw_attach_phy_ops(struct ath
+ priv_ops->rfbus_req = ar5008_hw_rfbus_req;
+ priv_ops->rfbus_done = ar5008_hw_rfbus_done;
+ priv_ops->restore_chainmask = ar5008_restore_chainmask;
+- priv_ops->set_diversity = ar5008_set_diversity;
+ priv_ops->do_getnf = ar5008_hw_do_getnf;
+ priv_ops->set_radar_params = ar5008_hw_set_radar_params;
+
+@@ -1664,9 +1648,7 @@ void ar5008_hw_attach_phy_ops(struct ath
+ } else
+ priv_ops->ani_control = ar5008_hw_ani_control_old;
+
+- if (AR_SREV_9100(ah))
+- priv_ops->compute_pll_control = ar9100_hw_compute_pll_control;
+- else if (AR_SREV_9160_10_OR_LATER(ah))
++ if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah))
+ priv_ops->compute_pll_control = ar9160_hw_compute_pll_control;
+ else
+ priv_ops->compute_pll_control = ar5008_hw_compute_pll_control;
+--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
++++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+@@ -592,6 +592,9 @@ static void ar9003_hw_override_ini(struc
+ val = REG_READ(ah, AR_PCU_MISC_MODE2) & (~AR_ADHOC_MCAST_KEYID_ENABLE);
+ REG_WRITE(ah, AR_PCU_MISC_MODE2,
+ val | AR_AGG_WEP_ENABLE_FIX | AR_AGG_WEP_ENABLE);
++
++ REG_SET_BIT(ah, AR_PHY_CCK_DETECT,
++ AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
+ }
+
+ static void ar9003_hw_prog_ini(struct ath_hw *ah,
+@@ -785,16 +788,6 @@ static void ar9003_hw_rfbus_done(struct
+ REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
+ }
+
+-static void ar9003_hw_set_diversity(struct ath_hw *ah, bool value)
+-{
+- u32 v = REG_READ(ah, AR_PHY_CCK_DETECT);
+- if (value)
+- v |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
+- else
+- v &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
+- REG_WRITE(ah, AR_PHY_CCK_DETECT, v);
+-}
+-
+ static bool ar9003_hw_ani_control(struct ath_hw *ah,
+ enum ath9k_ani_cmd cmd, int param)
+ {
+@@ -1277,7 +1270,6 @@ void ar9003_hw_attach_phy_ops(struct ath
+ priv_ops->set_delta_slope = ar9003_hw_set_delta_slope;
+ priv_ops->rfbus_req = ar9003_hw_rfbus_req;
+ priv_ops->rfbus_done = ar9003_hw_rfbus_done;
+- priv_ops->set_diversity = ar9003_hw_set_diversity;
+ priv_ops->ani_control = ar9003_hw_ani_control;
+ priv_ops->do_getnf = ar9003_hw_do_getnf;
+ priv_ops->ani_cache_ini_regs = ar9003_hw_ani_cache_ini_regs;
+--- a/drivers/net/wireless/ath/ath9k/eeprom.c
++++ b/drivers/net/wireless/ath/ath9k/eeprom.c
+@@ -456,12 +456,7 @@ void ath9k_hw_get_gain_boundaries_pdadcs
+ pPdGainBoundaries[i] =
+ min((u16)MAX_RATE_POWER, pPdGainBoundaries[i]);
+
+- if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) {
+- minDelta = pPdGainBoundaries[0] - 23;
+- pPdGainBoundaries[0] = 23;
+- } else {
+- minDelta = 0;
+- }
++ minDelta = 0;
+
+ if (i == 0) {
+ if (AR_SREV_9280_20_OR_LATER(ah))
+--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
++++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+@@ -405,12 +405,7 @@ static void ath9k_hw_set_4k_power_cal_ta
+ REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3, 0);
+
+ for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) {
+- if (AR_SREV_5416_20_OR_LATER(ah) &&
+- (ah->rxchainmask == 5 || ah->txchainmask == 5) &&
+- (i != 0)) {
+- regChainOffset = (i == 1) ? 0x2000 : 0x1000;
+- } else
+- regChainOffset = i * 0x1000;
++ regChainOffset = i * 0x1000;
+
+ if (pEepData->baseEepHeader.txMask & (1 << i)) {
+ pRawDataset = pEepData->calPierData2G[i];
+@@ -423,19 +418,17 @@ static void ath9k_hw_set_4k_power_cal_ta
+
+ ENABLE_REGWRITE_BUFFER(ah);
+
+- if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) {
+- REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset,
+- SM(pdGainOverlap_t2,
+- AR_PHY_TPCRG5_PD_GAIN_OVERLAP)
+- | SM(gainBoundaries[0],
+- AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)
+- | SM(gainBoundaries[1],
+- AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)
+- | SM(gainBoundaries[2],
+- AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)
+- | SM(gainBoundaries[3],
+- AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
+- }
++ REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset,
++ SM(pdGainOverlap_t2,
++ AR_PHY_TPCRG5_PD_GAIN_OVERLAP)
++ | SM(gainBoundaries[0],
++ AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)
++ | SM(gainBoundaries[1],
++ AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)
++ | SM(gainBoundaries[2],
++ AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)
++ | SM(gainBoundaries[3],
++ AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
+
+ regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
+ for (j = 0; j < 32; j++) {
+@@ -715,10 +708,8 @@ static void ath9k_hw_4k_set_txpower(stru
+ if (test)
+ return;
+
+- if (AR_SREV_9280_20_OR_LATER(ah)) {
+- for (i = 0; i < Ar5416RateSize; i++)
+- ratesArray[i] -= AR5416_PWR_TABLE_OFFSET_DB * 2;
+- }
++ for (i = 0; i < Ar5416RateSize; i++)
++ ratesArray[i] -= AR5416_PWR_TABLE_OFFSET_DB * 2;
+
+ ENABLE_REGWRITE_BUFFER(ah);
+
+@@ -788,28 +779,6 @@ static void ath9k_hw_4k_set_txpower(stru
+ REGWRITE_BUFFER_FLUSH(ah);
+ }
+
+-static void ath9k_hw_4k_set_addac(struct ath_hw *ah,
+- struct ath9k_channel *chan)
+-{
+- struct modal_eep_4k_header *pModal;
+- struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
+- u8 biaslevel;
+-
+- if (ah->hw_version.macVersion != AR_SREV_VERSION_9160)
+- return;
+-
+- if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7)
+- return;
+-
+- pModal = &eep->modalHeader;
+-
+- if (pModal->xpaBiasLvl != 0xff) {
+- biaslevel = pModal->xpaBiasLvl;
+- INI_RA(&ah->iniAddac, 7, 1) =
+- (INI_RA(&ah->iniAddac, 7, 1) & (~0x18)) | biaslevel << 3;
+- }
+-}
+-
+ static void ath9k_hw_4k_set_gain(struct ath_hw *ah,
+ struct modal_eep_4k_header *pModal,
+ struct ar5416_eeprom_4k *eep,
+@@ -877,6 +846,7 @@ static void ath9k_hw_4k_set_board_values
+ u8 txRxAttenLocal;
+ u8 ob[5], db1[5], db2[5];
+ u8 ant_div_control1, ant_div_control2;
++ u8 bb_desired_scale;
+ u32 regVal;
+
+ pModal = &eep->modalHeader;
+@@ -1096,30 +1066,29 @@ static void ath9k_hw_4k_set_board_values
+ AR_PHY_SETTLING_SWITCH,
+ pModal->swSettleHt40);
+ }
+- if (AR_SREV_9271(ah) || AR_SREV_9285(ah)) {
+- u8 bb_desired_scale = (pModal->bb_scale_smrt_antenna &
+- EEP_4K_BB_DESIRED_SCALE_MASK);
+- if ((pBase->txGainType == 0) && (bb_desired_scale != 0)) {
+- u32 pwrctrl, mask, clr;
+-
+- mask = BIT(0)|BIT(5)|BIT(10)|BIT(15)|BIT(20)|BIT(25);
+- pwrctrl = mask * bb_desired_scale;
+- clr = mask * 0x1f;
+- REG_RMW(ah, AR_PHY_TX_PWRCTRL8, pwrctrl, clr);
+- REG_RMW(ah, AR_PHY_TX_PWRCTRL10, pwrctrl, clr);
+- REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL12, pwrctrl, clr);
+-
+- mask = BIT(0)|BIT(5)|BIT(15);
+- pwrctrl = mask * bb_desired_scale;
+- clr = mask * 0x1f;
+- REG_RMW(ah, AR_PHY_TX_PWRCTRL9, pwrctrl, clr);
+-
+- mask = BIT(0)|BIT(5);
+- pwrctrl = mask * bb_desired_scale;
+- clr = mask * 0x1f;
+- REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL11, pwrctrl, clr);
+- REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL13, pwrctrl, clr);
+- }
++
++ bb_desired_scale = (pModal->bb_scale_smrt_antenna &
++ EEP_4K_BB_DESIRED_SCALE_MASK);
++ if ((pBase->txGainType == 0) && (bb_desired_scale != 0)) {
++ u32 pwrctrl, mask, clr;
++
++ mask = BIT(0)|BIT(5)|BIT(10)|BIT(15)|BIT(20)|BIT(25);
++ pwrctrl = mask * bb_desired_scale;
++ clr = mask * 0x1f;
++ REG_RMW(ah, AR_PHY_TX_PWRCTRL8, pwrctrl, clr);
++ REG_RMW(ah, AR_PHY_TX_PWRCTRL10, pwrctrl, clr);
++ REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL12, pwrctrl, clr);
++
++ mask = BIT(0)|BIT(5)|BIT(15);
++ pwrctrl = mask * bb_desired_scale;
++ clr = mask * 0x1f;
++ REG_RMW(ah, AR_PHY_TX_PWRCTRL9, pwrctrl, clr);
++
++ mask = BIT(0)|BIT(5);
++ pwrctrl = mask * bb_desired_scale;
++ clr = mask * 0x1f;
++ REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL11, pwrctrl, clr);
++ REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL13, pwrctrl, clr);
+ }
+ }
+
+@@ -1161,7 +1130,6 @@ const struct eeprom_ops eep_4k_ops = {
+ .get_eeprom_ver = ath9k_hw_4k_get_eeprom_ver,
+ .get_eeprom_rev = ath9k_hw_4k_get_eeprom_rev,
+ .set_board_values = ath9k_hw_4k_set_board_values,
+- .set_addac = ath9k_hw_4k_set_addac,
+ .set_txpower = ath9k_hw_4k_set_txpower,
+ .get_spur_channel = ath9k_hw_4k_get_spur_channel
+ };
+--- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c
++++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
+@@ -851,10 +851,8 @@ static void ath9k_hw_ar9287_set_txpower(
+ if (test)
+ return;
+
+- if (AR_SREV_9280_20_OR_LATER(ah)) {
+- for (i = 0; i < Ar5416RateSize; i++)
+- ratesArray[i] -= AR9287_PWR_TABLE_OFFSET_DB * 2;
+- }
++ for (i = 0; i < Ar5416RateSize; i++)
++ ratesArray[i] -= AR9287_PWR_TABLE_OFFSET_DB * 2;
+
+ ENABLE_REGWRITE_BUFFER(ah);
+
+@@ -944,11 +942,6 @@ static void ath9k_hw_ar9287_set_txpower(
+ REGWRITE_BUFFER_FLUSH(ah);
+ }
+
+-static void ath9k_hw_ar9287_set_addac(struct ath_hw *ah,
+- struct ath9k_channel *chan)
+-{
+-}
+-
+ static void ath9k_hw_ar9287_set_board_values(struct ath_hw *ah,
+ struct ath9k_channel *chan)
+ {
+@@ -1100,7 +1093,6 @@ const struct eeprom_ops eep_ar9287_ops =
+ .get_eeprom_ver = ath9k_hw_ar9287_get_eeprom_ver,
+ .get_eeprom_rev = ath9k_hw_ar9287_get_eeprom_rev,
+ .set_board_values = ath9k_hw_ar9287_set_board_values,
+- .set_addac = ath9k_hw_ar9287_set_addac,
+ .set_txpower = ath9k_hw_ar9287_set_txpower,
+ .get_spur_channel = ath9k_hw_ar9287_get_spur_channel
+ };
+--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
++++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
+@@ -547,8 +547,7 @@ static void ath9k_hw_def_set_board_value
+ break;
+ }
+
+- if (AR_SREV_5416_20_OR_LATER(ah) &&
+- (ah->rxchainmask == 5 || ah->txchainmask == 5) && (i != 0))
++ if ((ah->rxchainmask == 5 || ah->txchainmask == 5) && (i != 0))
+ regChainOffset = (i == 1) ? 0x2000 : 0x1000;
+ else
+ regChainOffset = i * 0x1000;
+@@ -565,9 +564,8 @@ static void ath9k_hw_def_set_board_value
+ SM(pModal->iqCalQCh[i],
+ AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
+
+- if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah))
+- ath9k_hw_def_set_gain(ah, pModal, eep, txRxAttenLocal,
+- regChainOffset, i);
++ ath9k_hw_def_set_gain(ah, pModal, eep, txRxAttenLocal,
++ regChainOffset, i);
+ }
+
+ if (AR_SREV_9280_20_OR_LATER(ah)) {
+@@ -893,8 +891,7 @@ static void ath9k_hw_set_def_power_cal_t
+ xpdGainValues[2]);
+
+ for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+- if (AR_SREV_5416_20_OR_LATER(ah) &&
+- (ah->rxchainmask == 5 || ah->txchainmask == 5) &&
++ if ((ah->rxchainmask == 5 || ah->txchainmask == 5) &&
+ (i != 0)) {
+ regChainOffset = (i == 1) ? 0x2000 : 0x1000;
+ } else
+@@ -935,27 +932,24 @@ static void ath9k_hw_set_def_power_cal_t
+
+ ENABLE_REGWRITE_BUFFER(ah);
+
+- if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) {
+- if (OLC_FOR_AR9280_20_LATER) {
+- REG_WRITE(ah,
+- AR_PHY_TPCRG5 + regChainOffset,
+- SM(0x6,
+- AR_PHY_TPCRG5_PD_GAIN_OVERLAP) |
+- SM_PD_GAIN(1) | SM_PD_GAIN(2) |
+- SM_PD_GAIN(3) | SM_PD_GAIN(4));
+- } else {
+- REG_WRITE(ah,
+- AR_PHY_TPCRG5 + regChainOffset,
+- SM(pdGainOverlap_t2,
+- AR_PHY_TPCRG5_PD_GAIN_OVERLAP)|
+- SM_PDGAIN_B(0, 1) |
+- SM_PDGAIN_B(1, 2) |
+- SM_PDGAIN_B(2, 3) |
+- SM_PDGAIN_B(3, 4));
+- }
++ if (OLC_FOR_AR9280_20_LATER) {
++ REG_WRITE(ah,
++ AR_PHY_TPCRG5 + regChainOffset,
++ SM(0x6,
++ AR_PHY_TPCRG5_PD_GAIN_OVERLAP) |
++ SM_PD_GAIN(1) | SM_PD_GAIN(2) |
++ SM_PD_GAIN(3) | SM_PD_GAIN(4));
++ } else {
++ REG_WRITE(ah,
++ AR_PHY_TPCRG5 + regChainOffset,
++ SM(pdGainOverlap_t2,
++ AR_PHY_TPCRG5_PD_GAIN_OVERLAP)|
++ SM_PDGAIN_B(0, 1) |
++ SM_PDGAIN_B(1, 2) |
++ SM_PDGAIN_B(2, 3) |
++ SM_PDGAIN_B(3, 4));
+ }
+
+-
+ ath9k_adjust_pdadc_values(ah, pwr_table_offset,
+ diff, pdadcValues);
+
+--- a/drivers/net/wireless/ath/ath9k/init.c
++++ b/drivers/net/wireless/ath/ath9k/init.c
+@@ -506,7 +506,6 @@ static void ath9k_init_misc(struct ath_s
+ sc->sc_flags |= SC_OP_RXAGGR;
+ }
+
+- ath9k_hw_set_diversity(sc->sc_ah, true);
+ sc->rx.defant = ath9k_hw_getdefantenna(sc->sc_ah);
+
+ memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN);
+--- a/drivers/net/wireless/ath/ath9k/reg.h
++++ b/drivers/net/wireless/ath/ath9k/reg.h
+@@ -800,10 +800,6 @@
+ #define AR_SREV_5416(_ah) \
+ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \
+ ((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE))
+-#define AR_SREV_5416_20_OR_LATER(_ah) \
+- (((AR_SREV_5416(_ah)) && \
+- ((_ah)->hw_version.macRev >= AR_SREV_REVISION_5416_20)) || \
+- ((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9100))
+ #define AR_SREV_5416_22_OR_LATER(_ah) \
+ (((AR_SREV_5416(_ah)) && \
+ ((_ah)->hw_version.macRev >= AR_SREV_REVISION_5416_22)) || \
+--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
++++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
+@@ -869,6 +869,7 @@ static bool ar9002_hw_init_cal(struct at
+ ar9002_hw_pa_cal(ah, true);
+
+ /* Do NF Calibration after DC offset and other calibrations */
++ ath9k_hw_loadnf(ah, chan);
+ ath9k_hw_start_nfcal(ah, true);
+
+ if (ah->caldata)
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -671,7 +671,6 @@ enum queue_stop_reason {
+ IEEE80211_QUEUE_STOP_REASON_AGGREGATION,
+ IEEE80211_QUEUE_STOP_REASON_SUSPEND,
+ IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
+- IEEE80211_QUEUE_STOP_REASON_CHTYPE_CHANGE,
+ };
+
+ #ifdef CONFIG_MAC80211_LEDS
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -1921,24 +1921,8 @@ static void ieee80211_rx_mgmt_beacon(str
+
+ rcu_read_unlock();
+
+- /*
+- * Whenever the AP announces the HT mode change that can be
+- * 40MHz intolerant or etc., it would be safer to stop tx
+- * queues before doing hw config to avoid buffer overflow.
+- */
+- ieee80211_stop_queues_by_reason(&sdata->local->hw,
+- IEEE80211_QUEUE_STOP_REASON_CHTYPE_CHANGE);
+-
+- /* flush out all packets */
+- synchronize_net();
+-
+- drv_flush(local, false);
+-
+ changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem,
+ bssid, ap_ht_cap_flags);
+-
+- ieee80211_wake_queues_by_reason(&sdata->local->hw,
+- IEEE80211_QUEUE_STOP_REASON_CHTYPE_CHANGE);
+ }
+
+ /* Note: country IE parsing is done for us by cfg80211 */
+--- a/drivers/net/wireless/b43/main.c
++++ b/drivers/net/wireless/b43/main.c
+@@ -1613,7 +1613,8 @@ static void handle_irq_beacon(struct b43
+ u32 cmd, beacon0_valid, beacon1_valid;
+
+ if (!b43_is_mode(wl, NL80211_IFTYPE_AP) &&
+- !b43_is_mode(wl, NL80211_IFTYPE_MESH_POINT))
++ !b43_is_mode(wl, NL80211_IFTYPE_MESH_POINT) &&
++ !b43_is_mode(wl, NL80211_IFTYPE_ADHOC))
+ return;
+
+ /* This is the bottom half of the asynchronous beacon update. */