diff options
author | Johannes Berg <johannes.berg@intel.com> | 2010-08-05 11:02:38 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-08-16 15:26:40 -0400 |
commit | 7da7cc1d42d8ce02cca16df8c021e6d657f1f8fd (patch) | |
tree | 3d18e0b36edfcc015d27f66890cf4a8d60c45bda /net/mac80211/iface.c | |
parent | 1fdaa46e9f26ccbab5e0eb8c4d4f8e1fbf32c7df (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.c | 53 |
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 |