summaryrefslogtreecommitdiff
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2014-01-27 08:09:23 +0200
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2014-02-03 22:43:55 +0200
commit06280a2ba9050cd8bc15a03aa22b24698a3ea742 (patch)
tree8891704fabbeda14e44dfa60bf6f3e034de1f72d /drivers/net/wireless
parentdcefeec05be5821a82f9ee66f6fcb9849d3f7568 (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')
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/power.c58
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,
#endif /* CONFIG_IWLWIFI_DEBUGFS */
}
-static int iwl_mvm_power_mac_update_mode(struct iwl_mvm *mvm,
+static int _iwl_mvm_power_mac_update_mode(struct iwl_mvm *mvm,
struct ieee80211_vif *vif)
{
- int ret;
- bool ba_enable;
struct iwl_mac_power_cmd cmd = {};
- struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
if (vif->type != NL80211_IFTYPE_STATION)
return 0;
@@ -435,8 +432,19 @@ static int iwl_mvm_power_mac_update_mode(struct iwl_mvm *mvm,
iwl_mvm_power_build_cmd(mvm, vif, &cmd);
iwl_mvm_power_log(mvm, &cmd);
- ret = iwl_mvm_send_cmd_pdu(mvm, MAC_PM_POWER_TABLE, CMD_SYNC,
- sizeof(cmd), &cmd);
+ return iwl_mvm_send_cmd_pdu(mvm, MAC_PM_POWER_TABLE, CMD_SYNC,
+ sizeof(cmd), &cmd);
+}
+
+static int iwl_mvm_power_mac_update_mode(struct iwl_mvm *mvm,
+ struct ieee80211_vif *vif)
+
+{
+ struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+ bool ba_enable;
+ int ret;
+
+ ret = _iwl_mvm_power_mac_update_mode(mvm, vif);
if (ret)
return ret;
@@ -544,13 +552,24 @@ int iwl_mvm_power_uapsd_misbehaving_ap_notif(struct iwl_mvm *mvm,
return 0;
}
+struct iwl_mvm_power_iterator {
+ struct iwl_mvm *mvm;
+ struct ieee80211_vif *bf_vif;
+};
+
static void iwl_mvm_power_binding_iterator(void *_data, u8 *mac,
struct ieee80211_vif *vif)
{
- struct iwl_mvm *mvm = _data;
+ struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+ struct iwl_mvm_power_iterator *power_iterator = _data;
+ struct iwl_mvm *mvm = power_iterator->mvm;
int ret;
- ret = iwl_mvm_power_mac_update_mode(mvm, vif);
+ ret = _iwl_mvm_power_mac_update_mode(mvm, vif);
+
+ if (mvmvif->bf_data.bf_enabled && !WARN_ON(power_iterator->bf_vif))
+ power_iterator->bf_vif = vif;
+
WARN_ONCE(ret, "Failed to update power parameters on a specific vif\n");
}
@@ -558,6 +577,14 @@ static void _iwl_mvm_power_update_binding(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
bool assign)
{
+ bool ba_enable;
+ struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+ struct iwl_mvm_power_iterator power_it = {
+ .mvm = mvm,
+ };
+
+ lockdep_assert_held(&mvm->mutex);
+
if (vif->type == NL80211_IFTYPE_MONITOR) {
int ret = _iwl_mvm_power_update_device(mvm, assign);
mvm->ps_prevented = assign;
@@ -567,7 +594,20 @@ static void _iwl_mvm_power_update_binding(struct iwl_mvm *mvm,
ieee80211_iterate_active_interfaces(mvm->hw,
IEEE80211_IFACE_ITER_NORMAL,
iwl_mvm_power_binding_iterator,
- mvm);
+ &power_it);
+
+ if (!power_it.bf_vif)
+ return;
+
+ vif = power_it.bf_vif;
+ mvmvif = iwl_mvm_vif_from_mac80211(vif);
+
+ ba_enable = !(iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM ||
+ mvm->ps_prevented || mvm->bound_vif_cnt > 1 ||
+ !vif->bss_conf.ps || iwl_mvm_vif_low_latency(mvmvif));
+
+ WARN_ON_ONCE(iwl_mvm_update_beacon_abort(mvm, power_it.bf_vif,
+ ba_enable));
}
#ifdef CONFIG_IWLWIFI_DEBUGFS