diff options
author | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2014-01-27 01:09:23 -0500 |
---|---|---|
committer | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2014-02-03 15:43:55 -0500 |
commit | 06280a2ba9050cd8bc15a03aa22b24698a3ea742 (patch) | |
tree | 8891704fabbeda14e44dfa60bf6f3e034de1f72d /drivers/net/wireless/iwlwifi | |
parent | dcefeec05be5821a82f9ee66f6fcb9849d3f7568 (diff) |
iwlwifi: mvm: don't send the beacon filtering command from iterator
The firmware doesn't allow per-vif beacon filtering: we can
use beacon filtering for one vif only. So remember which
vif has beacon filtering enabled in the iterator, and send
the command outside the iterator.
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/power.c | 58 |
1 files changed, 49 insertions, 9 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c index 20bc37648faf..15c9c780323b 100644 --- a/drivers/net/wireless/iwlwifi/mvm/power.c +++ b/drivers/net/wireless/iwlwifi/mvm/power.c | |||
@@ -417,13 +417,10 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, | |||
417 | #endif /* CONFIG_IWLWIFI_DEBUGFS */ | 417 | #endif /* CONFIG_IWLWIFI_DEBUGFS */ |
418 | } | 418 | } |
419 | 419 | ||
420 | static int iwl_mvm_power_mac_update_mode(struct iwl_mvm *mvm, | 420 | static int _iwl_mvm_power_mac_update_mode(struct iwl_mvm *mvm, |
421 | struct ieee80211_vif *vif) | 421 | struct ieee80211_vif *vif) |
422 | { | 422 | { |
423 | int ret; | ||
424 | bool ba_enable; | ||
425 | struct iwl_mac_power_cmd cmd = {}; | 423 | struct iwl_mac_power_cmd cmd = {}; |
426 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
427 | 424 | ||
428 | if (vif->type != NL80211_IFTYPE_STATION) | 425 | if (vif->type != NL80211_IFTYPE_STATION) |
429 | return 0; | 426 | return 0; |
@@ -435,8 +432,19 @@ static int iwl_mvm_power_mac_update_mode(struct iwl_mvm *mvm, | |||
435 | iwl_mvm_power_build_cmd(mvm, vif, &cmd); | 432 | iwl_mvm_power_build_cmd(mvm, vif, &cmd); |
436 | iwl_mvm_power_log(mvm, &cmd); | 433 | iwl_mvm_power_log(mvm, &cmd); |
437 | 434 | ||
438 | ret = iwl_mvm_send_cmd_pdu(mvm, MAC_PM_POWER_TABLE, CMD_SYNC, | 435 | return iwl_mvm_send_cmd_pdu(mvm, MAC_PM_POWER_TABLE, CMD_SYNC, |
439 | sizeof(cmd), &cmd); | 436 | sizeof(cmd), &cmd); |
437 | } | ||
438 | |||
439 | static int iwl_mvm_power_mac_update_mode(struct iwl_mvm *mvm, | ||
440 | struct ieee80211_vif *vif) | ||
441 | |||
442 | { | ||
443 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
444 | bool ba_enable; | ||
445 | int ret; | ||
446 | |||
447 | ret = _iwl_mvm_power_mac_update_mode(mvm, vif); | ||
440 | if (ret) | 448 | if (ret) |
441 | return ret; | 449 | return ret; |
442 | 450 | ||
@@ -544,13 +552,24 @@ int iwl_mvm_power_uapsd_misbehaving_ap_notif(struct iwl_mvm *mvm, | |||
544 | return 0; | 552 | return 0; |
545 | } | 553 | } |
546 | 554 | ||
555 | struct iwl_mvm_power_iterator { | ||
556 | struct iwl_mvm *mvm; | ||
557 | struct ieee80211_vif *bf_vif; | ||
558 | }; | ||
559 | |||
547 | static void iwl_mvm_power_binding_iterator(void *_data, u8 *mac, | 560 | static void iwl_mvm_power_binding_iterator(void *_data, u8 *mac, |
548 | struct ieee80211_vif *vif) | 561 | struct ieee80211_vif *vif) |
549 | { | 562 | { |
550 | struct iwl_mvm *mvm = _data; | 563 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
564 | struct iwl_mvm_power_iterator *power_iterator = _data; | ||
565 | struct iwl_mvm *mvm = power_iterator->mvm; | ||
551 | int ret; | 566 | int ret; |
552 | 567 | ||
553 | ret = iwl_mvm_power_mac_update_mode(mvm, vif); | 568 | ret = _iwl_mvm_power_mac_update_mode(mvm, vif); |
569 | |||
570 | if (mvmvif->bf_data.bf_enabled && !WARN_ON(power_iterator->bf_vif)) | ||
571 | power_iterator->bf_vif = vif; | ||
572 | |||
554 | WARN_ONCE(ret, "Failed to update power parameters on a specific vif\n"); | 573 | WARN_ONCE(ret, "Failed to update power parameters on a specific vif\n"); |
555 | } | 574 | } |
556 | 575 | ||
@@ -558,6 +577,14 @@ static void _iwl_mvm_power_update_binding(struct iwl_mvm *mvm, | |||
558 | struct ieee80211_vif *vif, | 577 | struct ieee80211_vif *vif, |
559 | bool assign) | 578 | bool assign) |
560 | { | 579 | { |
580 | bool ba_enable; | ||
581 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
582 | struct iwl_mvm_power_iterator power_it = { | ||
583 | .mvm = mvm, | ||
584 | }; | ||
585 | |||
586 | lockdep_assert_held(&mvm->mutex); | ||
587 | |||
561 | if (vif->type == NL80211_IFTYPE_MONITOR) { | 588 | if (vif->type == NL80211_IFTYPE_MONITOR) { |
562 | int ret = _iwl_mvm_power_update_device(mvm, assign); | 589 | int ret = _iwl_mvm_power_update_device(mvm, assign); |
563 | mvm->ps_prevented = assign; | 590 | mvm->ps_prevented = assign; |
@@ -567,7 +594,20 @@ static void _iwl_mvm_power_update_binding(struct iwl_mvm *mvm, | |||
567 | ieee80211_iterate_active_interfaces(mvm->hw, | 594 | ieee80211_iterate_active_interfaces(mvm->hw, |
568 | IEEE80211_IFACE_ITER_NORMAL, | 595 | IEEE80211_IFACE_ITER_NORMAL, |
569 | iwl_mvm_power_binding_iterator, | 596 | iwl_mvm_power_binding_iterator, |
570 | mvm); | 597 | &power_it); |
598 | |||
599 | if (!power_it.bf_vif) | ||
600 | return; | ||
601 | |||
602 | vif = power_it.bf_vif; | ||
603 | mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
604 | |||
605 | ba_enable = !(iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM || | ||
606 | mvm->ps_prevented || mvm->bound_vif_cnt > 1 || | ||
607 | !vif->bss_conf.ps || iwl_mvm_vif_low_latency(mvmvif)); | ||
608 | |||
609 | WARN_ON_ONCE(iwl_mvm_update_beacon_abort(mvm, power_it.bf_vif, | ||
610 | ba_enable)); | ||
571 | } | 611 | } |
572 | 612 | ||
573 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 613 | #ifdef CONFIG_IWLWIFI_DEBUGFS |