mac80211: add stations after AP start on reconfig
authorArik Nemtsov <arik@wizery.com>
Sun, 3 Jun 2012 20:31:56 +0000 (23:31 +0300)
committerJohn W. Linville <linville@tuxdriver.com>
Wed, 6 Jun 2012 19:20:23 +0000 (15:20 -0400)
When performing a HW restart for an AP mode interface, add stations back
only after the AP is beaconing. This mimics the normal flow of STA
addition on AP.

Some devices (wlcore) do not support adding stations before beaconing,
so this has the added benefit of making recovery work for them.

Signed-off-by: Arik Nemtsov <arik@wizery.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
net/mac80211/util.c

index b007c686103217533dd984b8f463996ecf574583..1df4019f294b6206f45222160be1e4c193e76e30 100644 (file)
@@ -1279,14 +1279,19 @@ int ieee80211_reconfig(struct ieee80211_local *local)
        /* add STAs back */
        mutex_lock(&local->sta_mtx);
        list_for_each_entry(sta, &local->sta_list, list) {
-               if (sta->uploaded) {
-                       enum ieee80211_sta_state state;
+               enum ieee80211_sta_state state;
 
-                       for (state = IEEE80211_STA_NOTEXIST;
-                            state < sta->sta_state; state++)
-                               WARN_ON(drv_sta_state(local, sta->sdata, sta,
-                                                     state, state + 1));
-               }
+               if (!sta->uploaded)
+                       continue;
+
+               /* AP-mode stations will be added later */
+               if (sta->sdata->vif.type == NL80211_IFTYPE_AP)
+                       continue;
+
+               for (state = IEEE80211_STA_NOTEXIST;
+                    state < sta->sta_state; state++)
+                       WARN_ON(drv_sta_state(local, sta->sdata, sta, state,
+                                             state + 1));
        }
        mutex_unlock(&local->sta_mtx);
 
@@ -1383,6 +1388,24 @@ int ieee80211_reconfig(struct ieee80211_local *local)
                }
        }
 
+       /* APs are now beaconing, add back stations */
+       mutex_lock(&local->sta_mtx);
+       list_for_each_entry(sta, &local->sta_list, list) {
+               enum ieee80211_sta_state state;
+
+               if (!sta->uploaded)
+                       continue;
+
+               if (sta->sdata->vif.type != NL80211_IFTYPE_AP)
+                       continue;
+
+               for (state = IEEE80211_STA_NOTEXIST;
+                    state < sta->sta_state; state++)
+                       WARN_ON(drv_sta_state(local, sta->sdata, sta, state,
+                                             state + 1));
+       }
+       mutex_unlock(&local->sta_mtx);
+
        /* add back keys */
        list_for_each_entry(sdata, &local->interfaces, list)
                if (ieee80211_sdata_running(sdata))