aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorSachin Kulkarni <Sachin.Kulkarni@imgtec.com>2016-01-12 04:00:19 -0500
committerJohannes Berg <johannes.berg@intel.com>2016-01-26 05:27:39 -0500
commit4fa11ec726a32ea6dd768dbb2e2af3453a98ec0a (patch)
treea60f4e7a0cb0af3e062bef209da12d4b6f2b86a1 /net
parentda629cf111a2b9a182d1b43f03f2cb0d3f258af4 (diff)
mac80211: Requeue work after scan complete for all VIF types.
During a sw scan ieee80211_iface_work ignores work items for all vifs. However after the scan complete work is requeued only for STA, ADHOC and MESH iftypes. This occasionally results in event processing getting delayed/not processed for iftype AP when it coexists with a STA. This can result in data halt and eventually disconnection on the AP interface. Cc: stable@vger.kernel.org Signed-off-by: Sachin Kulkarni <Sachin.Kulkarni@imgtec.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/ibss.c1
-rw-r--r--net/mac80211/mesh.c11
-rw-r--r--net/mac80211/mesh.h4
-rw-r--r--net/mac80211/mlme.c2
-rw-r--r--net/mac80211/scan.c12
5 files changed, 11 insertions, 19 deletions
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index f7fc0e00497f..978d3bc31df7 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -1733,7 +1733,6 @@ void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local)
1733 if (sdata->vif.type != NL80211_IFTYPE_ADHOC) 1733 if (sdata->vif.type != NL80211_IFTYPE_ADHOC)
1734 continue; 1734 continue;
1735 sdata->u.ibss.last_scan_completed = jiffies; 1735 sdata->u.ibss.last_scan_completed = jiffies;
1736 ieee80211_queue_work(&local->hw, &sdata->work);
1737 } 1736 }
1738 mutex_unlock(&local->iflist_mtx); 1737 mutex_unlock(&local->iflist_mtx);
1739} 1738}
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index fa28500f28fd..6f85b6ab8e51 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -1370,17 +1370,6 @@ out:
1370 sdata_unlock(sdata); 1370 sdata_unlock(sdata);
1371} 1371}
1372 1372
1373void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local)
1374{
1375 struct ieee80211_sub_if_data *sdata;
1376
1377 rcu_read_lock();
1378 list_for_each_entry_rcu(sdata, &local->interfaces, list)
1379 if (ieee80211_vif_is_mesh(&sdata->vif) &&
1380 ieee80211_sdata_running(sdata))
1381 ieee80211_queue_work(&local->hw, &sdata->work);
1382 rcu_read_unlock();
1383}
1384 1373
1385void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata) 1374void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
1386{ 1375{
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index a1596344c3ba..4a8019f79fb2 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -362,14 +362,10 @@ static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata)
362 return sdata->u.mesh.mesh_pp_id == IEEE80211_PATH_PROTOCOL_HWMP; 362 return sdata->u.mesh.mesh_pp_id == IEEE80211_PATH_PROTOCOL_HWMP;
363} 363}
364 364
365void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local);
366
367void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata); 365void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata);
368void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata); 366void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata);
369void ieee80211s_stop(void); 367void ieee80211s_stop(void);
370#else 368#else
371static inline void
372ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local) {}
373static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata) 369static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata)
374{ return false; } 370{ return false; }
375static inline void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata) 371static inline void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata)
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 1c342e2592c4..bfbb1acafdd1 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -4005,8 +4005,6 @@ static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata)
4005 if (!ieee80211_hw_check(&sdata->local->hw, CONNECTION_MONITOR)) 4005 if (!ieee80211_hw_check(&sdata->local->hw, CONNECTION_MONITOR))
4006 ieee80211_queue_work(&sdata->local->hw, 4006 ieee80211_queue_work(&sdata->local->hw,
4007 &sdata->u.mgd.monitor_work); 4007 &sdata->u.mgd.monitor_work);
4008 /* and do all the other regular work too */
4009 ieee80211_queue_work(&sdata->local->hw, &sdata->work);
4010 } 4008 }
4011} 4009}
4012 4010
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 8eb68ef42e8c..ae980ce8daff 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -314,6 +314,7 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
314 bool was_scanning = local->scanning; 314 bool was_scanning = local->scanning;
315 struct cfg80211_scan_request *scan_req; 315 struct cfg80211_scan_request *scan_req;
316 struct ieee80211_sub_if_data *scan_sdata; 316 struct ieee80211_sub_if_data *scan_sdata;
317 struct ieee80211_sub_if_data *sdata;
317 318
318 lockdep_assert_held(&local->mtx); 319 lockdep_assert_held(&local->mtx);
319 320
@@ -373,7 +374,16 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
373 374
374 ieee80211_mlme_notify_scan_completed(local); 375 ieee80211_mlme_notify_scan_completed(local);
375 ieee80211_ibss_notify_scan_completed(local); 376 ieee80211_ibss_notify_scan_completed(local);
376 ieee80211_mesh_notify_scan_completed(local); 377
378 /* Requeue all the work that might have been ignored while
379 * the scan was in progress; if there was none this will
380 * just be a no-op for the particular interface.
381 */
382 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
383 if (ieee80211_sdata_running(sdata))
384 ieee80211_queue_work(&sdata->local->hw, &sdata->work);
385 }
386
377 if (was_scanning) 387 if (was_scanning)
378 ieee80211_start_next_roc(local); 388 ieee80211_start_next_roc(local);
379} 389}