diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2009-08-17 10:16:53 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-08-20 11:35:58 -0400 |
commit | 3ac64beecd27400d12cc7afb4108eef26c499f6a (patch) | |
tree | da0220085f68e30fe61ba9b8833dc6311d6dc25e /net/mac80211/iface.c | |
parent | ea416a793d2b611f22b42ba094fd2e5bd30fff43 (diff) |
mac80211: allow configure_filter callback to sleep
Over time, a whole bunch of drivers have come up
with their own scheme to delay the configure_filter
operation to a workqueue. To be able to simplify
things, allow configure_filter to sleep, and add
a new prepare_multicast callback that drivers that
need the multicast address list implement. This new
callback must be atomic, but most drivers either
don't care or just calculate a hash which can be
done atomically and then uploaded to the hardware
non-atomically.
A cursory look suggests that at76c50x-usb, ar9170,
mwl8k (which is actually very broken now), rt2x00,
wl1251, wl1271 and zd1211 should make use of this
new capability.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/iface.c')
-rw-r--r-- | net/mac80211/iface.c | 15 |
1 files changed, 3 insertions, 12 deletions
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index e8fb03b91a44..b161301056df 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -227,9 +227,7 @@ static int ieee80211_open(struct net_device *dev) | |||
227 | if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) | 227 | if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) |
228 | local->fif_other_bss++; | 228 | local->fif_other_bss++; |
229 | 229 | ||
230 | spin_lock_bh(&local->filter_lock); | ||
231 | ieee80211_configure_filter(local); | 230 | ieee80211_configure_filter(local); |
232 | spin_unlock_bh(&local->filter_lock); | ||
233 | break; | 231 | break; |
234 | default: | 232 | default: |
235 | conf.vif = &sdata->vif; | 233 | conf.vif = &sdata->vif; |
@@ -241,17 +239,13 @@ static int ieee80211_open(struct net_device *dev) | |||
241 | 239 | ||
242 | if (ieee80211_vif_is_mesh(&sdata->vif)) { | 240 | if (ieee80211_vif_is_mesh(&sdata->vif)) { |
243 | local->fif_other_bss++; | 241 | local->fif_other_bss++; |
244 | spin_lock_bh(&local->filter_lock); | ||
245 | ieee80211_configure_filter(local); | 242 | ieee80211_configure_filter(local); |
246 | spin_unlock_bh(&local->filter_lock); | ||
247 | 243 | ||
248 | ieee80211_start_mesh(sdata); | 244 | ieee80211_start_mesh(sdata); |
249 | } else if (sdata->vif.type == NL80211_IFTYPE_AP) { | 245 | } else if (sdata->vif.type == NL80211_IFTYPE_AP) { |
250 | local->fif_pspoll++; | 246 | local->fif_pspoll++; |
251 | 247 | ||
252 | spin_lock_bh(&local->filter_lock); | ||
253 | ieee80211_configure_filter(local); | 248 | ieee80211_configure_filter(local); |
254 | spin_unlock_bh(&local->filter_lock); | ||
255 | } | 249 | } |
256 | 250 | ||
257 | changed |= ieee80211_reset_erp_info(sdata); | 251 | changed |= ieee80211_reset_erp_info(sdata); |
@@ -404,10 +398,11 @@ static int ieee80211_stop(struct net_device *dev) | |||
404 | spin_lock_bh(&local->filter_lock); | 398 | spin_lock_bh(&local->filter_lock); |
405 | __dev_addr_unsync(&local->mc_list, &local->mc_count, | 399 | __dev_addr_unsync(&local->mc_list, &local->mc_count, |
406 | &dev->mc_list, &dev->mc_count); | 400 | &dev->mc_list, &dev->mc_count); |
407 | ieee80211_configure_filter(local); | ||
408 | spin_unlock_bh(&local->filter_lock); | 401 | spin_unlock_bh(&local->filter_lock); |
409 | netif_addr_unlock_bh(dev); | 402 | netif_addr_unlock_bh(dev); |
410 | 403 | ||
404 | ieee80211_configure_filter(local); | ||
405 | |||
411 | del_timer_sync(&local->dynamic_ps_timer); | 406 | del_timer_sync(&local->dynamic_ps_timer); |
412 | cancel_work_sync(&local->dynamic_ps_enable_work); | 407 | cancel_work_sync(&local->dynamic_ps_enable_work); |
413 | 408 | ||
@@ -458,9 +453,7 @@ static int ieee80211_stop(struct net_device *dev) | |||
458 | if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) | 453 | if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) |
459 | local->fif_other_bss--; | 454 | local->fif_other_bss--; |
460 | 455 | ||
461 | spin_lock_bh(&local->filter_lock); | ||
462 | ieee80211_configure_filter(local); | 456 | ieee80211_configure_filter(local); |
463 | spin_unlock_bh(&local->filter_lock); | ||
464 | break; | 457 | break; |
465 | case NL80211_IFTYPE_STATION: | 458 | case NL80211_IFTYPE_STATION: |
466 | del_timer_sync(&sdata->u.mgd.chswitch_timer); | 459 | del_timer_sync(&sdata->u.mgd.chswitch_timer); |
@@ -503,9 +496,7 @@ static int ieee80211_stop(struct net_device *dev) | |||
503 | local->fif_other_bss--; | 496 | local->fif_other_bss--; |
504 | atomic_dec(&local->iff_allmultis); | 497 | atomic_dec(&local->iff_allmultis); |
505 | 498 | ||
506 | spin_lock_bh(&local->filter_lock); | ||
507 | ieee80211_configure_filter(local); | 499 | ieee80211_configure_filter(local); |
508 | spin_unlock_bh(&local->filter_lock); | ||
509 | 500 | ||
510 | ieee80211_stop_mesh(sdata); | 501 | ieee80211_stop_mesh(sdata); |
511 | } | 502 | } |
@@ -622,8 +613,8 @@ static void ieee80211_set_multicast_list(struct net_device *dev) | |||
622 | spin_lock_bh(&local->filter_lock); | 613 | spin_lock_bh(&local->filter_lock); |
623 | __dev_addr_sync(&local->mc_list, &local->mc_count, | 614 | __dev_addr_sync(&local->mc_list, &local->mc_count, |
624 | &dev->mc_list, &dev->mc_count); | 615 | &dev->mc_list, &dev->mc_count); |
625 | ieee80211_configure_filter(local); | ||
626 | spin_unlock_bh(&local->filter_lock); | 616 | spin_unlock_bh(&local->filter_lock); |
617 | ieee80211_queue_work(&local->hw, &local->reconfig_filter); | ||
627 | } | 618 | } |
628 | 619 | ||
629 | /* | 620 | /* |