aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi
diff options
context:
space:
mode:
authorAlexander Bondar <alexander.bondar@intel.com>2013-10-23 05:50:34 -0400
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2013-12-17 12:39:42 -0500
commit92d8556250c81bd6d4df522926a2cb3711dd01e2 (patch)
tree5c1dcec1aa2344f2dc7299e713371f59508d2db3 /drivers/net/wireless/iwlwifi
parent1c2abf724b3397830e60596a6a41e2d9f870d1a6 (diff)
iwlwifi: mvm: Disable power save for monitor interface
When monitor interface is activated device power save needs to be disabled. Re-consider power management status on other active interfaces when monitor interface is bound or unbound. Signed-off-by: Alexander Bondar <alexander.bondar@intel.com> 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/mac80211.c15
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h10
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/power.c22
3 files changed, 35 insertions, 12 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index e1c379a61d83..d36105fa4bf6 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -1610,7 +1610,13 @@ static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
1610 goto out_unlock; 1610 goto out_unlock;
1611 1611
1612 /* 1612 /*
1613 * Setting the quota at this stage is only required for monitor 1613 * Power state must be updated before quotas,
1614 * otherwise fw will complain.
1615 */
1616 mvm->bound_vif_cnt++;
1617 iwl_mvm_power_update_binding(mvm, vif, true);
1618
1619 /* Setting the quota at this stage is only required for monitor
1614 * interfaces. For the other types, the bss_info changed flow 1620 * interfaces. For the other types, the bss_info changed flow
1615 * will handle quota settings. 1621 * will handle quota settings.
1616 */ 1622 */
@@ -1621,13 +1627,12 @@ static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
1621 goto out_remove_binding; 1627 goto out_remove_binding;
1622 } 1628 }
1623 1629
1624 mvm->bound_vif_cnt++;
1625 iwl_mvm_power_update_binding(mvm, vif);
1626
1627 goto out_unlock; 1630 goto out_unlock;
1628 1631
1629 out_remove_binding: 1632 out_remove_binding:
1630 iwl_mvm_binding_remove_vif(mvm, vif); 1633 iwl_mvm_binding_remove_vif(mvm, vif);
1634 mvm->bound_vif_cnt--;
1635 iwl_mvm_power_update_binding(mvm, vif, false);
1631 out_unlock: 1636 out_unlock:
1632 mutex_unlock(&mvm->mutex); 1637 mutex_unlock(&mvm->mutex);
1633 if (ret) 1638 if (ret)
@@ -1662,7 +1667,7 @@ static void iwl_mvm_unassign_vif_chanctx(struct ieee80211_hw *hw,
1662out_unlock: 1667out_unlock:
1663 mvmvif->phy_ctxt = NULL; 1668 mvmvif->phy_ctxt = NULL;
1664 mvm->bound_vif_cnt--; 1669 mvm->bound_vif_cnt--;
1665 iwl_mvm_power_update_binding(mvm, vif); 1670 iwl_mvm_power_update_binding(mvm, vif, false);
1666 1671
1667 mutex_unlock(&mvm->mutex); 1672 mutex_unlock(&mvm->mutex);
1668} 1673}
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index 51b0e9a4883f..7295f8e42f3e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -164,7 +164,7 @@ struct iwl_mvm_power_ops {
164 int (*power_update_device_mode)(struct iwl_mvm *mvm); 164 int (*power_update_device_mode)(struct iwl_mvm *mvm);
165 int (*power_disable)(struct iwl_mvm *mvm, struct ieee80211_vif *vif); 165 int (*power_disable)(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
166 void (*power_update_binding)(struct iwl_mvm *mvm, 166 void (*power_update_binding)(struct iwl_mvm *mvm,
167 struct ieee80211_vif *vif); 167 struct ieee80211_vif *vif, bool assign);
168#ifdef CONFIG_IWLWIFI_DEBUGFS 168#ifdef CONFIG_IWLWIFI_DEBUGFS
169 int (*power_dbgfs_read)(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 169 int (*power_dbgfs_read)(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
170 char *buf, int bufsz); 170 char *buf, int bufsz);
@@ -568,6 +568,9 @@ struct iwl_mvm {
568 u8 last_agg_queue; 568 u8 last_agg_queue;
569 569
570 u8 bound_vif_cnt; 570 u8 bound_vif_cnt;
571
572 /* Indicate if device power save is allowed */
573 bool ps_prevented;
571}; 574};
572 575
573/* Extract MVM priv from op_mode and _hw */ 576/* Extract MVM priv from op_mode and _hw */
@@ -787,10 +790,11 @@ static inline int iwl_mvm_power_update_device_mode(struct iwl_mvm *mvm)
787} 790}
788 791
789static inline void iwl_mvm_power_update_binding(struct iwl_mvm *mvm, 792static inline void iwl_mvm_power_update_binding(struct iwl_mvm *mvm,
790 struct ieee80211_vif *vif) 793 struct ieee80211_vif *vif,
794 bool assign)
791{ 795{
792 if (mvm->pm_ops->power_update_binding) 796 if (mvm->pm_ops->power_update_binding)
793 mvm->pm_ops->power_update_binding(mvm, vif); 797 mvm->pm_ops->power_update_binding(mvm, vif, assign);
794} 798}
795 799
796void iwl_mvm_power_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif); 800void iwl_mvm_power_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c
index d5d4935bc0e9..cfed105b28b2 100644
--- a/drivers/net/wireless/iwlwifi/mvm/power.c
+++ b/drivers/net/wireless/iwlwifi/mvm/power.c
@@ -301,7 +301,8 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
301 keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC); 301 keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC);
302 cmd->keep_alive_seconds = cpu_to_le16(keep_alive); 302 cmd->keep_alive_seconds = cpu_to_le16(keep_alive);
303 303
304 if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM) 304 if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM ||
305 mvm->ps_prevented)
305 return; 306 return;
306 307
307 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); 308 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK);
@@ -447,7 +448,7 @@ static int iwl_mvm_power_mac_disable(struct iwl_mvm *mvm,
447 sizeof(cmd), &cmd); 448 sizeof(cmd), &cmd);
448} 449}
449 450
450static int iwl_mvm_power_update_device(struct iwl_mvm *mvm) 451static int _iwl_mvm_power_update_device(struct iwl_mvm *mvm, bool force_disable)
451{ 452{
452 struct iwl_device_power_cmd cmd = { 453 struct iwl_device_power_cmd cmd = {
453 .flags = cpu_to_le16(DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK), 454 .flags = cpu_to_le16(DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK),
@@ -456,7 +457,8 @@ static int iwl_mvm_power_update_device(struct iwl_mvm *mvm)
456 if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD)) 457 if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD))
457 return 0; 458 return 0;
458 459
459 if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM) 460 if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM ||
461 force_disable)
460 cmd.flags |= cpu_to_le16(DEVICE_POWER_FLAGS_CAM_MSK); 462 cmd.flags |= cpu_to_le16(DEVICE_POWER_FLAGS_CAM_MSK);
461 463
462#ifdef CONFIG_IWLWIFI_DEBUGFS 464#ifdef CONFIG_IWLWIFI_DEBUGFS
@@ -473,6 +475,11 @@ static int iwl_mvm_power_update_device(struct iwl_mvm *mvm)
473 &cmd); 475 &cmd);
474} 476}
475 477
478static int iwl_mvm_power_update_device(struct iwl_mvm *mvm)
479{
480 return _iwl_mvm_power_update_device(mvm, false);
481}
482
476void iwl_mvm_power_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif) 483void iwl_mvm_power_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
477{ 484{
478 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 485 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
@@ -525,8 +532,15 @@ static void iwl_mvm_power_binding_iterator(void *_data, u8 *mac,
525} 532}
526 533
527static void _iwl_mvm_power_update_binding(struct iwl_mvm *mvm, 534static void _iwl_mvm_power_update_binding(struct iwl_mvm *mvm,
528 struct ieee80211_vif *vif) 535 struct ieee80211_vif *vif,
536 bool assign)
529{ 537{
538 if (vif->type == NL80211_IFTYPE_MONITOR) {
539 int ret = _iwl_mvm_power_update_device(mvm, assign);
540 mvm->ps_prevented = assign;
541 WARN_ONCE(ret, "Failed to update power device state\n");
542 }
543
530 ieee80211_iterate_active_interfaces(mvm->hw, 544 ieee80211_iterate_active_interfaces(mvm->hw,
531 IEEE80211_IFACE_ITER_NORMAL, 545 IEEE80211_IFACE_ITER_NORMAL,
532 iwl_mvm_power_binding_iterator, 546 iwl_mvm_power_binding_iterator,