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/driver-ops.h | |
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/driver-ops.h')
-rw-r--r-- | net/mac80211/driver-ops.h | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 4100c361a99d..d231c9323ad1 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
@@ -55,16 +55,32 @@ static inline void drv_bss_info_changed(struct ieee80211_local *local, | |||
55 | trace_drv_bss_info_changed(local, vif, info, changed); | 55 | trace_drv_bss_info_changed(local, vif, info, changed); |
56 | } | 56 | } |
57 | 57 | ||
58 | static inline u64 drv_prepare_multicast(struct ieee80211_local *local, | ||
59 | int mc_count, | ||
60 | struct dev_addr_list *mc_list) | ||
61 | { | ||
62 | u64 ret = 0; | ||
63 | |||
64 | if (local->ops->prepare_multicast) | ||
65 | ret = local->ops->prepare_multicast(&local->hw, mc_count, | ||
66 | mc_list); | ||
67 | |||
68 | trace_drv_prepare_multicast(local, mc_count, ret); | ||
69 | |||
70 | return ret; | ||
71 | } | ||
72 | |||
58 | static inline void drv_configure_filter(struct ieee80211_local *local, | 73 | static inline void drv_configure_filter(struct ieee80211_local *local, |
59 | unsigned int changed_flags, | 74 | unsigned int changed_flags, |
60 | unsigned int *total_flags, | 75 | unsigned int *total_flags, |
61 | int mc_count, | 76 | u64 multicast) |
62 | struct dev_addr_list *mc_list) | ||
63 | { | 77 | { |
78 | might_sleep(); | ||
79 | |||
64 | local->ops->configure_filter(&local->hw, changed_flags, total_flags, | 80 | local->ops->configure_filter(&local->hw, changed_flags, total_flags, |
65 | mc_count, mc_list); | 81 | multicast); |
66 | trace_drv_configure_filter(local, changed_flags, total_flags, | 82 | trace_drv_configure_filter(local, changed_flags, total_flags, |
67 | mc_count); | 83 | multicast); |
68 | } | 84 | } |
69 | 85 | ||
70 | static inline int drv_set_tim(struct ieee80211_local *local, | 86 | static inline int drv_set_tim(struct ieee80211_local *local, |