aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/iface.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2010-08-05 11:02:38 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-08-16 15:26:40 -0400
commit7da7cc1d42d8ce02cca16df8c021e6d657f1f8fd (patch)
tree3d18e0b36edfcc015d27f66890cf4a8d60c45bda /net/mac80211/iface.c
parent1fdaa46e9f26ccbab5e0eb8c4d4f8e1fbf32c7df (diff)
mac80211: per interface idle notification
Sometimes we don't just need to know whether or not the device is idle, but also per interface. This adds that reporting capability to mac80211. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/iface.c')
-rw-r--r--net/mac80211/iface.c53
1 files changed, 45 insertions, 8 deletions
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index c1008a9d7bfb..9459aeee0ddc 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -309,7 +309,9 @@ static int ieee80211_open(struct net_device *dev)
309 if (sdata->flags & IEEE80211_SDATA_PROMISC) 309 if (sdata->flags & IEEE80211_SDATA_PROMISC)
310 atomic_inc(&local->iff_promiscs); 310 atomic_inc(&local->iff_promiscs);
311 311
312 mutex_lock(&local->mtx);
312 hw_reconf_flags |= __ieee80211_recalc_idle(local); 313 hw_reconf_flags |= __ieee80211_recalc_idle(local);
314 mutex_unlock(&local->mtx);
313 315
314 local->open_count++; 316 local->open_count++;
315 if (hw_reconf_flags) { 317 if (hw_reconf_flags) {
@@ -516,7 +518,9 @@ static int ieee80211_stop(struct net_device *dev)
516 518
517 sdata->bss = NULL; 519 sdata->bss = NULL;
518 520
521 mutex_lock(&local->mtx);
519 hw_reconf_flags |= __ieee80211_recalc_idle(local); 522 hw_reconf_flags |= __ieee80211_recalc_idle(local);
523 mutex_unlock(&local->mtx);
520 524
521 ieee80211_recalc_ps(local, -1); 525 ieee80211_recalc_ps(local, -1);
522 526
@@ -1199,28 +1203,61 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local)
1199{ 1203{
1200 struct ieee80211_sub_if_data *sdata; 1204 struct ieee80211_sub_if_data *sdata;
1201 int count = 0; 1205 int count = 0;
1206 bool working = false, scanning = false;
1207 struct ieee80211_work *wk;
1202 1208
1203 if (!list_empty(&local->work_list)) 1209#ifdef CONFIG_PROVE_LOCKING
1204 return ieee80211_idle_off(local, "working"); 1210 WARN_ON(debug_locks && !lockdep_rtnl_is_held() &&
1205 1211 !lockdep_is_held(&local->iflist_mtx));
1206 if (local->scanning) 1212#endif
1207 return ieee80211_idle_off(local, "scanning"); 1213 lockdep_assert_held(&local->mtx);
1208 1214
1209 list_for_each_entry(sdata, &local->interfaces, list) { 1215 list_for_each_entry(sdata, &local->interfaces, list) {
1210 if (!ieee80211_sdata_running(sdata)) 1216 if (!ieee80211_sdata_running(sdata)) {
1217 sdata->vif.bss_conf.idle = true;
1211 continue; 1218 continue;
1219 }
1220
1221 sdata->old_idle = sdata->vif.bss_conf.idle;
1222
1212 /* do not count disabled managed interfaces */ 1223 /* do not count disabled managed interfaces */
1213 if (sdata->vif.type == NL80211_IFTYPE_STATION && 1224 if (sdata->vif.type == NL80211_IFTYPE_STATION &&
1214 !sdata->u.mgd.associated) 1225 !sdata->u.mgd.associated) {
1226 sdata->vif.bss_conf.idle = true;
1215 continue; 1227 continue;
1228 }
1216 /* do not count unused IBSS interfaces */ 1229 /* do not count unused IBSS interfaces */
1217 if (sdata->vif.type == NL80211_IFTYPE_ADHOC && 1230 if (sdata->vif.type == NL80211_IFTYPE_ADHOC &&
1218 !sdata->u.ibss.ssid_len) 1231 !sdata->u.ibss.ssid_len) {
1232 sdata->vif.bss_conf.idle = true;
1219 continue; 1233 continue;
1234 }
1220 /* count everything else */ 1235 /* count everything else */
1221 count++; 1236 count++;
1222 } 1237 }
1223 1238
1239 list_for_each_entry(wk, &local->work_list, list) {
1240 working = true;
1241 wk->sdata->vif.bss_conf.idle = false;
1242 }
1243
1244 if (local->scan_sdata) {
1245 scanning = true;
1246 local->scan_sdata->vif.bss_conf.idle = false;
1247 }
1248
1249 list_for_each_entry(sdata, &local->interfaces, list) {
1250 if (sdata->old_idle == sdata->vif.bss_conf.idle)
1251 continue;
1252 if (!ieee80211_sdata_running(sdata))
1253 continue;
1254 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE);
1255 }
1256
1257 if (working)
1258 return ieee80211_idle_off(local, "working");
1259 if (scanning)
1260 return ieee80211_idle_off(local, "scanning");
1224 if (!count) 1261 if (!count)
1225 return ieee80211_idle_on(local); 1262 return ieee80211_idle_on(local);
1226 else 1263 else