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>
This commit is contained in:
committed by
John W. Linville
parent
ea416a793d
commit
3ac64beecd
@ -227,9 +227,7 @@ static int ieee80211_open(struct net_device *dev)
|
||||
if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS)
|
||||
local->fif_other_bss++;
|
||||
|
||||
spin_lock_bh(&local->filter_lock);
|
||||
ieee80211_configure_filter(local);
|
||||
spin_unlock_bh(&local->filter_lock);
|
||||
break;
|
||||
default:
|
||||
conf.vif = &sdata->vif;
|
||||
@ -241,17 +239,13 @@ static int ieee80211_open(struct net_device *dev)
|
||||
|
||||
if (ieee80211_vif_is_mesh(&sdata->vif)) {
|
||||
local->fif_other_bss++;
|
||||
spin_lock_bh(&local->filter_lock);
|
||||
ieee80211_configure_filter(local);
|
||||
spin_unlock_bh(&local->filter_lock);
|
||||
|
||||
ieee80211_start_mesh(sdata);
|
||||
} else if (sdata->vif.type == NL80211_IFTYPE_AP) {
|
||||
local->fif_pspoll++;
|
||||
|
||||
spin_lock_bh(&local->filter_lock);
|
||||
ieee80211_configure_filter(local);
|
||||
spin_unlock_bh(&local->filter_lock);
|
||||
}
|
||||
|
||||
changed |= ieee80211_reset_erp_info(sdata);
|
||||
@ -404,10 +398,11 @@ static int ieee80211_stop(struct net_device *dev)
|
||||
spin_lock_bh(&local->filter_lock);
|
||||
__dev_addr_unsync(&local->mc_list, &local->mc_count,
|
||||
&dev->mc_list, &dev->mc_count);
|
||||
ieee80211_configure_filter(local);
|
||||
spin_unlock_bh(&local->filter_lock);
|
||||
netif_addr_unlock_bh(dev);
|
||||
|
||||
ieee80211_configure_filter(local);
|
||||
|
||||
del_timer_sync(&local->dynamic_ps_timer);
|
||||
cancel_work_sync(&local->dynamic_ps_enable_work);
|
||||
|
||||
@ -458,9 +453,7 @@ static int ieee80211_stop(struct net_device *dev)
|
||||
if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS)
|
||||
local->fif_other_bss--;
|
||||
|
||||
spin_lock_bh(&local->filter_lock);
|
||||
ieee80211_configure_filter(local);
|
||||
spin_unlock_bh(&local->filter_lock);
|
||||
break;
|
||||
case NL80211_IFTYPE_STATION:
|
||||
del_timer_sync(&sdata->u.mgd.chswitch_timer);
|
||||
@ -503,9 +496,7 @@ static int ieee80211_stop(struct net_device *dev)
|
||||
local->fif_other_bss--;
|
||||
atomic_dec(&local->iff_allmultis);
|
||||
|
||||
spin_lock_bh(&local->filter_lock);
|
||||
ieee80211_configure_filter(local);
|
||||
spin_unlock_bh(&local->filter_lock);
|
||||
|
||||
ieee80211_stop_mesh(sdata);
|
||||
}
|
||||
@ -622,8 +613,8 @@ static void ieee80211_set_multicast_list(struct net_device *dev)
|
||||
spin_lock_bh(&local->filter_lock);
|
||||
__dev_addr_sync(&local->mc_list, &local->mc_count,
|
||||
&dev->mc_list, &dev->mc_count);
|
||||
ieee80211_configure_filter(local);
|
||||
spin_unlock_bh(&local->filter_lock);
|
||||
ieee80211_queue_work(&local->hw, &local->reconfig_filter);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user