rx->sdata->vif.type != NL80211_IFTYPE_ADHOC &&
                     rx->sdata->vif.type != NL80211_IFTYPE_WDS &&
                     (!rx->sta || !test_sta_flag(rx->sta, WLAN_STA_ASSOC)))) {
-               if (rx->sta && rx->sta->dummy &&
+               /*
+                * accept port control frames from the AP even when it's not
+                * yet marked ASSOC to prevent a race where we don't set the
+                * assoc bit quickly enough before it sends the first frame
+                */
+               if (rx->sta && rx->sdata->vif.type == NL80211_IFTYPE_STATION &&
                    ieee80211_is_data_present(hdr->frame_control)) {
                        u16 ethertype;
                        u8 *payload;
        if (ieee80211_is_data(fc)) {
                prev_sta = NULL;
 
-               for_each_sta_info_rx(local, hdr->addr2, sta, tmp) {
+               for_each_sta_info(local, hdr->addr2, sta, tmp) {
                        if (!prev_sta) {
                                prev_sta = sta;
                                continue;
                        continue;
                }
 
-               rx.sta = sta_info_get_bss_rx(prev, hdr->addr2);
+               rx.sta = sta_info_get_bss(prev, hdr->addr2);
                rx.sdata = prev;
                ieee80211_prepare_and_rx_handle(&rx, skb, false);
 
        }
 
        if (prev) {
-               rx.sta = sta_info_get_bss_rx(prev, hdr->addr2);
+               rx.sta = sta_info_get_bss(prev, hdr->addr2);
                rx.sdata = prev;
 
                if (ieee80211_prepare_and_rx_handle(&rx, skb, true))
 
        struct ieee80211_local *local = sdata->local;
        struct sta_info *sta;
 
-       sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)],
-                                   lockdep_is_held(&local->sta_mtx));
-       while (sta) {
-               if (sta->sdata == sdata && !sta->dummy &&
-                   memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
-                       break;
-               sta = rcu_dereference_check(sta->hnext,
-                                           lockdep_is_held(&local->sta_mtx));
-       }
-       return sta;
-}
-
-/* get a station info entry even if it is a dummy station*/
-struct sta_info *sta_info_get_rx(struct ieee80211_sub_if_data *sdata,
-                             const u8 *addr)
-{
-       struct ieee80211_local *local = sdata->local;
-       struct sta_info *sta;
-
        sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)],
                                    lockdep_is_held(&local->sta_mtx));
        while (sta) {
        struct ieee80211_local *local = sdata->local;
        struct sta_info *sta;
 
-       sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)],
-                                   lockdep_is_held(&local->sta_mtx));
-       while (sta) {
-               if ((sta->sdata == sdata ||
-                    (sta->sdata->bss && sta->sdata->bss == sdata->bss)) &&
-                   !sta->dummy &&
-                   memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
-                       break;
-               sta = rcu_dereference_check(sta->hnext,
-                                           lockdep_is_held(&local->sta_mtx));
-       }
-       return sta;
-}
-
-/*
- * Get sta info either from the specified interface
- * or from one of its vlans (including dummy stations)
- */
-struct sta_info *sta_info_get_bss_rx(struct ieee80211_sub_if_data *sdata,
-                                 const u8 *addr)
-{
-       struct ieee80211_local *local = sdata->local;
-       struct sta_info *sta;
-
        sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)],
                                    lockdep_is_held(&local->sta_mtx));
        while (sta) {
 {
        struct ieee80211_local *local = sta->local;
        struct ieee80211_sub_if_data *sdata = sta->sdata;
-       struct sta_info *exist_sta;
-       bool dummy_reinsert = false;
+       struct station_info sinfo;
        int err = 0;
 
        lockdep_assert_held(&local->sta_mtx);
 
-       /*
-        * check if STA exists already.
-        * only accept a scenario of a second call to sta_info_insert_finish
-        * with a dummy station entry that was inserted earlier
-        * in that case - assume that the dummy station flag should
-        * be removed.
-        */
-       exist_sta = sta_info_get_bss_rx(sdata, sta->sta.addr);
-       if (exist_sta) {
-               if (exist_sta == sta && sta->dummy) {
-                       dummy_reinsert = true;
-               } else {
-                       err = -EEXIST;
-                       goto out_err;
-               }
-       }
-
-       if (!sta->dummy || dummy_reinsert) {
-               /* notify driver */
-               err = sta_info_insert_drv_state(local, sdata, sta);
-               if (err)
-                       goto out_err;
+       /* check if STA exists already */
+       if (sta_info_get_bss(sdata, sta->sta.addr)) {
+               err = -EEXIST;
+               goto out_err;
        }
 
-       if (!dummy_reinsert) {
-               local->num_sta++;
-               local->sta_generation++;
-               smp_mb();
+       /* notify driver */
+       err = sta_info_insert_drv_state(local, sdata, sta);
+       if (err)
+               goto out_err;
 
-               /* make the station visible */
-               sta_info_hash_add(local, sta);
+       local->num_sta++;
+       local->sta_generation++;
+       smp_mb();
 
-               list_add(&sta->list, &local->sta_list);
+       /* make the station visible */
+       sta_info_hash_add(local, sta);
 
-               set_sta_flag(sta, WLAN_STA_INSERTED);
-       } else {
-               sta->dummy = false;
-       }
+       list_add(&sta->list, &local->sta_list);
 
-       if (!sta->dummy) {
-               struct station_info sinfo;
+       set_sta_flag(sta, WLAN_STA_INSERTED);
 
-               ieee80211_sta_debugfs_add(sta);
-               rate_control_add_sta_debugfs(sta);
+       ieee80211_sta_debugfs_add(sta);
+       rate_control_add_sta_debugfs(sta);
 
-               memset(&sinfo, 0, sizeof(sinfo));
-               sinfo.filled = 0;
-               sinfo.generation = local->sta_generation;
-               cfg80211_new_sta(sdata->dev, sta->sta.addr, &sinfo, GFP_KERNEL);
-       }
+       memset(&sinfo, 0, sizeof(sinfo));
+       sinfo.filled = 0;
+       sinfo.generation = local->sta_generation;
+       cfg80211_new_sta(sdata->dev, sta->sta.addr, &sinfo, GFP_KERNEL);
 
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
-       wiphy_debug(local->hw.wiphy, "Inserted %sSTA %pM\n",
-                       sta->dummy ? "dummy " : "", sta->sta.addr);
+       wiphy_debug(local->hw.wiphy, "Inserted STA %pM\n", sta->sta.addr);
 #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
 
        /* move reference to rcu-protected */
        return err;
 }
 
-/* Caller must hold sta->local->sta_mtx */
-int sta_info_reinsert(struct sta_info *sta)
-{
-       struct ieee80211_local *local = sta->local;
-       int err = 0;
-
-       err = sta_info_insert_check(sta);
-       if (err) {
-               mutex_unlock(&local->sta_mtx);
-               return err;
-       }
-
-       might_sleep();
-
-       err = sta_info_insert_finish(sta);
-       rcu_read_unlock();
-       return err;
-}
-
 static inline void __bss_tim_set(struct ieee80211_if_ap *bss, u16 aid)
 {
        /*
        int ret;
 
        mutex_lock(&sdata->local->sta_mtx);
-       sta = sta_info_get_rx(sdata, addr);
+       sta = sta_info_get(sdata, addr);
        ret = __sta_info_destroy(sta);
        mutex_unlock(&sdata->local->sta_mtx);
 
        int ret;
 
        mutex_lock(&sdata->local->sta_mtx);
-       sta = sta_info_get_bss_rx(sdata, addr);
+       sta = sta_info_get_bss(sdata, addr);
        ret = __sta_info_destroy(sta);
        mutex_unlock(&sdata->local->sta_mtx);
 
 
  * @dead: set to true when sta is unlinked
  * @uploaded: set to true when sta is uploaded to the driver
  * @lost_packets: number of consecutive lost packets
- * @dummy: indicate a dummy station created for receiving
- *     EAP frames before association
  * @sta: station information we share with the driver
  * @sta_state: duplicates information about station state (for debug)
  * @beacon_loss_count: number of times beacon loss has triggered
        unsigned int lost_packets;
        unsigned int beacon_loss_count;
 
-       /* should be right in front of sta to be in the same cache line */
-       bool dummy;
-
        /* keep last! */
        struct ieee80211_sta sta;
 };
 struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata,
                              const u8 *addr);
 
-struct sta_info *sta_info_get_rx(struct ieee80211_sub_if_data *sdata,
-                             const u8 *addr);
-
 struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata,
                                  const u8 *addr);
 
-struct sta_info *sta_info_get_bss_rx(struct ieee80211_sub_if_data *sdata,
-                                 const u8 *addr);
-
 static inline
 void for_each_sta_info_type_check(struct ieee80211_local *local,
                                  const u8 *addr,
 {
 }
 
-#define for_each_sta_info(local, _addr, _sta, nxt)                     \
-       for (   /* initialise loop */                                   \
-               _sta = rcu_dereference(local->sta_hash[STA_HASH(_addr)]),\
-               nxt = _sta ? rcu_dereference(_sta->hnext) : NULL;       \
-               /* typecheck */                                         \
-               for_each_sta_info_type_check(local, (_addr), _sta, nxt),\
-               /* continue condition */                                \
-               _sta;                                                   \
-               /* advance loop */                                      \
-               _sta = nxt,                                             \
-               nxt = _sta ? rcu_dereference(_sta->hnext) : NULL        \
-            )                                                          \
-       /* run code only if address matches and it's not a dummy sta */ \
-       if (memcmp(_sta->sta.addr, (_addr), ETH_ALEN) == 0 &&           \
-               !_sta->dummy)
-
-#define for_each_sta_info_rx(local, _addr, _sta, nxt)                  \
+#define for_each_sta_info(local, _addr, _sta, nxt)                     \
        for (   /* initialise loop */                                   \
                _sta = rcu_dereference(local->sta_hash[STA_HASH(_addr)]),\
                nxt = _sta ? rcu_dereference(_sta->hnext) : NULL;       \
  */
 int sta_info_insert(struct sta_info *sta);
 int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU);
-int sta_info_reinsert(struct sta_info *sta);
 
 int __must_check __sta_info_destroy(struct sta_info *sta);
 int sta_info_destroy_addr(struct ieee80211_sub_if_data *sdata,