--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
-@@ -176,6 +176,8 @@ static void ieee80211_send_addba_resp(st
+@@ -184,6 +184,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);
break;
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
-@@ -2137,7 +2137,8 @@ ieee80211_rx_h_action(struct ieee80211_r
+@@ -2160,7 +2160,8 @@ ieee80211_rx_h_action(struct ieee80211_r
*/
if (sdata->vif.type != NL80211_IFTYPE_STATION &&
sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
break;
/* verify action_code is present */
-@@ -2335,13 +2336,14 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_
+@@ -2375,13 +2376,14 @@ 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_DEAUTH):
case cpu_to_le16(IEEE80211_STYPE_DISASSOC):
-@@ -2680,10 +2682,16 @@ static int prepare_for_handlers(struct i
+@@ -2724,10 +2726,16 @@ static int prepare_for_handlers(struct i
}
break;
case NL80211_IFTYPE_WDS:
WLAN_STA_CLEAR_PS_FILT = 1<<9,
WLAN_STA_MFP = 1<<10,
WLAN_STA_BLOCK_BA = 1<<11,
+--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
++++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+@@ -671,7 +671,7 @@ static int ar9003_hw_process_ini(struct
+ REG_WRITE_ARRAY(&ah->iniModesAdditional,
+ modesIndex, regWrites);
+
+- if (AR_SREV_9300(ah))
++ if (AR_SREV_9330(ah))
+ REG_WRITE_ARRAY(&ah->iniModesAdditional, 1, regWrites);
+
+ if (AR_SREV_9340(ah) && !ah->is_clk_25mhz)
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -997,8 +997,14 @@ void ath9k_hw_init_global_settings(struc
+ slottime = 21;
+ sifstime = 64;
+ } else {
+- eifs = REG_READ(ah, AR_D_GBL_IFS_EIFS)/common->clockrate;
+- reg = REG_READ(ah, AR_USEC);
++ if (AR_SREV_9287(ah) && AR_SREV_9287_13_OR_LATER(ah)) {
++ eifs = AR_D_GBL_IFS_EIFS_ASYNC_FIFO;
++ reg = AR_USEC_ASYNC_FIFO;
++ } else {
++ eifs = REG_READ(ah, AR_D_GBL_IFS_EIFS)/
++ common->clockrate;
++ reg = REG_READ(ah, AR_USEC);
++ }
+ rx_lat = MS(reg, AR_USEC_RX_LAT);
+ tx_lat = MS(reg, AR_USEC_TX_LAT);
+
+--- a/drivers/net/wireless/ath/ath9k/reg.h
++++ b/drivers/net/wireless/ath/ath9k/reg.h
+@@ -619,6 +619,7 @@
+ #define AR_D_GBL_IFS_EIFS 0x10b0
+ #define AR_D_GBL_IFS_EIFS_M 0x0000FFFF
+ #define AR_D_GBL_IFS_EIFS_RESV0 0xFFFF0000
++#define AR_D_GBL_IFS_EIFS_ASYNC_FIFO 363
+
+ #define AR_D_GBL_IFS_MISC 0x10f0
+ #define AR_D_GBL_IFS_MISC_LFSR_SLICE_SEL 0x00000007
+@@ -1503,6 +1504,7 @@ enum {
+ #define AR_USEC_TX_LAT_S 14
+ #define AR_USEC_RX_LAT 0x1F800000
+ #define AR_USEC_RX_LAT_S 23
++#define AR_USEC_ASYNC_FIFO 0x12E00074
+
+ #define AR_RESET_TSF 0x8020
+ #define AR_RESET_TSF_ONCE 0x01000000
+--- a/drivers/net/wireless/ath/ath9k/xmit.c
++++ b/drivers/net/wireless/ath/ath9k/xmit.c
+@@ -582,7 +582,10 @@ static bool ath_lookup_legacy(struct ath
+ tx_info = IEEE80211_SKB_CB(skb);
+ rates = tx_info->control.rates;
+
+- for (i = 3; i >= 0; i--) {
++ for (i = 0; i < 4; i++) {
++ if (!rates[i].count || rates[i].idx < 0)
++ break;
++
+ if (!(rates[i].flags & IEEE80211_TX_RC_MCS))
+ return true;
+ }