aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt2x00mac.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00mac.c')
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c57
1 files changed, 55 insertions, 2 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 0a11c27d603b..17b6bb034ebf 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -380,6 +380,50 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw,
380} 380}
381EXPORT_SYMBOL_GPL(rt2x00mac_config_interface); 381EXPORT_SYMBOL_GPL(rt2x00mac_config_interface);
382 382
383void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
384 unsigned int changed_flags,
385 unsigned int *total_flags,
386 int mc_count, struct dev_addr_list *mc_list)
387{
388 struct rt2x00_dev *rt2x00dev = hw->priv;
389
390 /*
391 * Mask off any flags we are going to ignore
392 * from the total_flags field.
393 */
394 *total_flags &=
395 FIF_ALLMULTI |
396 FIF_FCSFAIL |
397 FIF_PLCPFAIL |
398 FIF_CONTROL |
399 FIF_OTHER_BSS |
400 FIF_PROMISC_IN_BSS;
401
402 /*
403 * Apply some rules to the filters:
404 * - Some filters imply different filters to be set.
405 * - Some things we can't filter out at all.
406 * - Multicast filter seems to kill broadcast traffic so never use it.
407 */
408 *total_flags |= FIF_ALLMULTI;
409 if (*total_flags & FIF_OTHER_BSS ||
410 *total_flags & FIF_PROMISC_IN_BSS)
411 *total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS;
412
413 /*
414 * Check if there is any work left for us.
415 */
416 if (rt2x00dev->packet_filter == *total_flags)
417 return;
418 rt2x00dev->packet_filter = *total_flags;
419
420 if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags))
421 queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->filter_work);
422 else
423 rt2x00dev->ops->lib->config_filter(rt2x00dev, *total_flags);
424}
425EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter);
426
383int rt2x00mac_get_stats(struct ieee80211_hw *hw, 427int rt2x00mac_get_stats(struct ieee80211_hw *hw,
384 struct ieee80211_low_level_stats *stats) 428 struct ieee80211_low_level_stats *stats)
385{ 429{
@@ -419,6 +463,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
419{ 463{
420 struct rt2x00_dev *rt2x00dev = hw->priv; 464 struct rt2x00_dev *rt2x00dev = hw->priv;
421 struct rt2x00_intf *intf = vif_to_intf(vif); 465 struct rt2x00_intf *intf = vif_to_intf(vif);
466 unsigned int delayed = 0;
422 467
423 /* 468 /*
424 * When the association status has changed we must reset the link 469 * When the association status has changed we must reset the link
@@ -439,11 +484,19 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
439 * When the erp information has changed, we should perform 484 * When the erp information has changed, we should perform
440 * additional configuration steps. For all other changes we are done. 485 * additional configuration steps. For all other changes we are done.
441 */ 486 */
442 if (changes & BSS_CHANGED_ERP_PREAMBLE) 487 if (changes & BSS_CHANGED_ERP_PREAMBLE) {
443 rt2x00lib_config_erp(rt2x00dev, intf, bss_conf); 488 if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags))
489 rt2x00lib_config_erp(rt2x00dev, intf, bss_conf);
490 else
491 delayed |= DELAYED_CONFIG_ERP;
492 }
444 493
445 spin_lock(&intf->lock); 494 spin_lock(&intf->lock);
446 memcpy(&intf->conf, bss_conf, sizeof(*bss_conf)); 495 memcpy(&intf->conf, bss_conf, sizeof(*bss_conf));
496 if (delayed) {
497 intf->delayed_flags |= delayed;
498 queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work);
499 }
447 spin_unlock(&intf->lock); 500 spin_unlock(&intf->lock);
448} 501}
449EXPORT_SYMBOL_GPL(rt2x00mac_bss_info_changed); 502EXPORT_SYMBOL_GPL(rt2x00mac_bss_info_changed);