TEST(TDLS_PEER_AUTH));
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
-@@ -282,6 +282,8 @@ void ieee80211_send_delba(struct ieee802
+@@ -47,7 +47,9 @@ void ieee80211_apply_htcap_overrides(str
+ int i;
+
+ if (sdata->vif.type != NL80211_IFTYPE_STATION) {
+- WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION);
++ /* AP interfaces call this code when adding new stations,
++ * so just silently ignore non station interfaces.
++ */
+ return;
+ }
+
+@@ -282,6 +284,8 @@ void ieee80211_send_delba(struct ieee802
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;
case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
case cpu_to_le16(IEEE80211_STYPE_DISASSOC):
-@@ -2805,10 +2808,16 @@ static int prepare_for_handlers(struct i
+@@ -2796,19 +2799,32 @@ static int prepare_for_handlers(struct i
+ return 0;
+ } else if (!ieee80211_bssid_match(bssid,
+ sdata->vif.addr)) {
++ /*
++ * Accept public action frames even when the
++ * BSSID doesn't match, this is used for P2P
++ * and location updates. Note that mac80211
++ * itself never looks at these frames.
++ */
+ if (!(status->rx_flags & IEEE80211_RX_IN_SCAN) &&
+- !ieee80211_is_beacon(hdr->frame_control) &&
+- !(ieee80211_is_action(hdr->frame_control) &&
+- sdata->vif.p2p))
++ ieee80211_is_public_action(hdr, skb->len))
++ return 1;
++ if (!(status->rx_flags & IEEE80211_RX_IN_SCAN) &&
++ !ieee80211_is_beacon(hdr->frame_control))
+ return 0;
+ status->rx_flags &= ~IEEE80211_RX_RA_MATCH;
}
break;
case NL80211_IFTYPE_WDS:
ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
+--- a/include/linux/ieee80211.h
++++ b/include/linux/ieee80211.h
+@@ -1695,6 +1695,23 @@ static inline bool ieee80211_is_robust_m
+ }
+
+ /**
++ * ieee80211_is_public_action - check if frame is a public action frame
++ * @hdr: the frame
++ * @len: length of the frame
++ */
++static inline bool ieee80211_is_public_action(struct ieee80211_hdr *hdr,
++ size_t len)
++{
++ struct ieee80211_mgmt *mgmt = (void *)hdr;
++
++ if (len < 25)
++ return false;
++ if (!ieee80211_is_action(hdr->frame_control))
++ return false;
++ return mgmt->u.action.category == WLAN_CATEGORY_PUBLIC;
++}
++
++/**
+ * ieee80211_fhss_chan_to_freq - get channel frequency
+ * @channel: the FHSS channel
+ *
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -1332,8 +1332,11 @@ static int invoke_tx_handlers(struct iee
+ if (!(tx->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL))
+ CALL_TXH(ieee80211_tx_h_rate_ctrl);
+
+- if (unlikely(info->flags & IEEE80211_TX_INTFL_RETRANSMISSION))
++ if (unlikely(info->flags & IEEE80211_TX_INTFL_RETRANSMISSION)) {
++ __skb_queue_tail(&tx->skbs, tx->skb);
++ tx->skb = NULL;
+ goto txh_done;
++ }
+
+ CALL_TXH(ieee80211_tx_h_michael_mic_add);
+ CALL_TXH(ieee80211_tx_h_sequence);