aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwl8k.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-08-17 10:16:53 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-08-20 11:35:58 -0400
commit3ac64beecd27400d12cc7afb4108eef26c499f6a (patch)
treeda0220085f68e30fe61ba9b8833dc6311d6dc25e /drivers/net/wireless/mwl8k.c
parentea416a793d2b611f22b42ba094fd2e5bd30fff43 (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 'drivers/net/wireless/mwl8k.c')
-rw-r--r--drivers/net/wireless/mwl8k.c34
1 files changed, 27 insertions, 7 deletions
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 8a6d3afe4122..f84387083e73 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -3251,31 +3251,50 @@ mwl8k_configure_filter_exit:
3251 return rc; 3251 return rc;
3252} 3252}
3253 3253
3254static u64 mwl8k_prepare_multicast(struct ieee80211_hw *hw,
3255 int mc_count, struct dev_addr_list *mclist)
3256{
3257 struct mwl8k_configure_filter_worker *worker;
3258
3259 worker = kzalloc(sizeof(*worker), GFP_ATOMIC);
3260
3261 if (!worker)
3262 return 0;
3263
3264 /*
3265 * XXX: This is _HORRIBLY_ broken!!
3266 *
3267 * No locking, the mclist pointer might be invalid as soon as this
3268 * function returns, something in the list might be invalidated
3269 * once we get to the worker, etc...
3270 */
3271 worker->mc_count = mc_count;
3272 worker->mclist = mclist;
3273
3274 return (u64)worker;
3275}
3276
3254static void mwl8k_configure_filter(struct ieee80211_hw *hw, 3277static void mwl8k_configure_filter(struct ieee80211_hw *hw,
3255 unsigned int changed_flags, 3278 unsigned int changed_flags,
3256 unsigned int *total_flags, 3279 unsigned int *total_flags,
3257 int mc_count, 3280 u64 multicast)
3258 struct dev_addr_list *mclist)
3259{ 3281{
3260 3282
3261 struct mwl8k_configure_filter_worker *worker; 3283 struct mwl8k_configure_filter_worker *worker = (void *)multicast;
3262 struct mwl8k_priv *priv = hw->priv; 3284 struct mwl8k_priv *priv = hw->priv;
3263 3285
3264 /* Clear unsupported feature flags */ 3286 /* Clear unsupported feature flags */
3265 *total_flags &= MWL8K_SUPPORTED_IF_FLAGS; 3287 *total_flags &= MWL8K_SUPPORTED_IF_FLAGS;
3266 3288
3267 if (!(changed_flags & MWL8K_SUPPORTED_IF_FLAGS) && !mc_count) 3289 if (!(changed_flags & MWL8K_SUPPORTED_IF_FLAGS))
3268 return; 3290 return;
3269 3291
3270 worker = kzalloc(sizeof(*worker), GFP_ATOMIC);
3271 if (worker == NULL) 3292 if (worker == NULL)
3272 return; 3293 return;
3273 3294
3274 worker->header.options = MWL8K_WQ_QUEUE_ONLY | MWL8K_WQ_TX_WAIT_EMPTY; 3295 worker->header.options = MWL8K_WQ_QUEUE_ONLY | MWL8K_WQ_TX_WAIT_EMPTY;
3275 worker->changed_flags = changed_flags; 3296 worker->changed_flags = changed_flags;
3276 worker->total_flags = total_flags; 3297 worker->total_flags = total_flags;
3277 worker->mc_count = mc_count;
3278 worker->mclist = mclist;
3279 3298
3280 mwl8k_queue_work(hw, &worker->header, priv->config_wq, 3299 mwl8k_queue_work(hw, &worker->header, priv->config_wq,
3281 mwl8k_configure_filter_wt); 3300 mwl8k_configure_filter_wt);
@@ -3441,6 +3460,7 @@ static const struct ieee80211_ops mwl8k_ops = {
3441 .remove_interface = mwl8k_remove_interface, 3460 .remove_interface = mwl8k_remove_interface,
3442 .config = mwl8k_config, 3461 .config = mwl8k_config,
3443 .bss_info_changed = mwl8k_bss_info_changed, 3462 .bss_info_changed = mwl8k_bss_info_changed,
3463 .prepare_multicast = mwl8k_prepare_multicast,
3444 .configure_filter = mwl8k_configure_filter, 3464 .configure_filter = mwl8k_configure_filter,
3445 .set_rts_threshold = mwl8k_set_rts_threshold, 3465 .set_rts_threshold = mwl8k_set_rts_threshold,
3446 .conf_tx = mwl8k_conf_tx, 3466 .conf_tx = mwl8k_conf_tx,