return false;
 }
 
+/**
+ * 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 < IEEE80211_MIN_ACTION_SIZE)
+               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
 
                                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_public_action(hdr, skb->len))
+                               return 1;
                        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_beacon(hdr->frame_control))
                                return 0;
                        status->rx_flags &= ~IEEE80211_RX_RA_MATCH;
                }