diff options
| -rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/Makefile | 2 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/d3.c | 4 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c | 7 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/debugfs.c | 2 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/fw.c | 8 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/mac80211.c | 31 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/mvm.h | 62 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/ops.c | 5 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/power.c | 54 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/power_legacy.c | 319 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/utils.c | 2 |
11 files changed, 62 insertions, 434 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/Makefile b/drivers/net/wireless/iwlwifi/mvm/Makefile index f98ec2b23898..41d390fd2ac8 100644 --- a/drivers/net/wireless/iwlwifi/mvm/Makefile +++ b/drivers/net/wireless/iwlwifi/mvm/Makefile | |||
| @@ -2,7 +2,7 @@ obj-$(CONFIG_IWLMVM) += iwlmvm.o | |||
| 2 | iwlmvm-y += fw.o mac80211.o nvm.o ops.o phy-ctxt.o mac-ctxt.o | 2 | iwlmvm-y += fw.o mac80211.o nvm.o ops.o phy-ctxt.o mac-ctxt.o |
| 3 | iwlmvm-y += utils.o rx.o tx.o binding.o quota.o sta.o sf.o | 3 | iwlmvm-y += utils.o rx.o tx.o binding.o quota.o sta.o sf.o |
| 4 | iwlmvm-y += scan.o time-event.o rs.o | 4 | iwlmvm-y += scan.o time-event.o rs.o |
| 5 | iwlmvm-y += power.o power_legacy.o bt-coex.o | 5 | iwlmvm-y += power.o bt-coex.o |
| 6 | iwlmvm-y += led.o tt.o | 6 | iwlmvm-y += led.o tt.o |
| 7 | iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o debugfs-vif.o | 7 | iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o debugfs-vif.o |
| 8 | iwlmvm-$(CONFIG_PM_SLEEP) += d3.o | 8 | iwlmvm-$(CONFIG_PM_SLEEP) += d3.o |
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c index f36a7ee0267f..a9850aa909d8 100644 --- a/drivers/net/wireless/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/iwlwifi/mvm/d3.c | |||
| @@ -1191,11 +1191,11 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, | |||
| 1191 | if (ret) | 1191 | if (ret) |
| 1192 | goto out; | 1192 | goto out; |
| 1193 | 1193 | ||
| 1194 | ret = iwl_mvm_power_update_device_mode(mvm); | 1194 | ret = iwl_mvm_power_update_device(mvm); |
| 1195 | if (ret) | 1195 | if (ret) |
| 1196 | goto out; | 1196 | goto out; |
| 1197 | 1197 | ||
| 1198 | ret = iwl_mvm_power_update_mode(mvm, vif); | 1198 | ret = iwl_mvm_power_mac_update_mode(mvm, vif); |
| 1199 | if (ret) | 1199 | if (ret) |
| 1200 | goto out; | 1200 | goto out; |
| 1201 | 1201 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c b/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c index a46895eaa374..9c0708eb540c 100644 --- a/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c +++ b/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c | |||
| @@ -185,7 +185,7 @@ static ssize_t iwl_dbgfs_pm_params_write(struct ieee80211_vif *vif, char *buf, | |||
| 185 | 185 | ||
| 186 | mutex_lock(&mvm->mutex); | 186 | mutex_lock(&mvm->mutex); |
| 187 | iwl_dbgfs_update_pm(mvm, vif, param, val); | 187 | iwl_dbgfs_update_pm(mvm, vif, param, val); |
| 188 | ret = iwl_mvm_power_update_mode(mvm, vif); | 188 | ret = iwl_mvm_power_mac_update_mode(mvm, vif); |
| 189 | mutex_unlock(&mvm->mutex); | 189 | mutex_unlock(&mvm->mutex); |
| 190 | 190 | ||
| 191 | return ret ?: count; | 191 | return ret ?: count; |
| @@ -202,7 +202,7 @@ static ssize_t iwl_dbgfs_pm_params_read(struct file *file, | |||
| 202 | int bufsz = sizeof(buf); | 202 | int bufsz = sizeof(buf); |
| 203 | int pos; | 203 | int pos; |
| 204 | 204 | ||
| 205 | pos = iwl_mvm_power_dbgfs_read(mvm, vif, buf, bufsz); | 205 | pos = iwl_mvm_power_mac_dbgfs_read(mvm, vif, buf, bufsz); |
| 206 | 206 | ||
| 207 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 207 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
| 208 | } | 208 | } |
| @@ -587,7 +587,8 @@ void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | |||
| 587 | return; | 587 | return; |
| 588 | } | 588 | } |
| 589 | 589 | ||
| 590 | if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM && | 590 | if ((mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PM_CMD_SUPPORT) && |
| 591 | iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM && | ||
| 591 | ((vif->type == NL80211_IFTYPE_STATION && !vif->p2p) || | 592 | ((vif->type == NL80211_IFTYPE_STATION && !vif->p2p) || |
| 592 | (vif->type == NL80211_IFTYPE_STATION && vif->p2p && | 593 | (vif->type == NL80211_IFTYPE_STATION && vif->p2p && |
| 593 | mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_P2P_PS))) | 594 | mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_P2P_PS))) |
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c index c116765ebe42..6853e5efe522 100644 --- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c | |||
| @@ -250,7 +250,7 @@ static ssize_t iwl_dbgfs_disable_power_off_write(struct iwl_mvm *mvm, char *buf, | |||
| 250 | } | 250 | } |
| 251 | 251 | ||
| 252 | mutex_lock(&mvm->mutex); | 252 | mutex_lock(&mvm->mutex); |
| 253 | ret = iwl_mvm_power_update_device_mode(mvm); | 253 | ret = iwl_mvm_power_update_device(mvm); |
| 254 | mutex_unlock(&mvm->mutex); | 254 | mutex_unlock(&mvm->mutex); |
| 255 | 255 | ||
| 256 | return ret ?: count; | 256 | return ret ?: count; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c index 212ffecf038b..155bb20519c2 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/iwlwifi/mvm/fw.c | |||
| @@ -442,7 +442,13 @@ int iwl_mvm_up(struct iwl_mvm *mvm) | |||
| 442 | /* Initialize tx backoffs to the minimal possible */ | 442 | /* Initialize tx backoffs to the minimal possible */ |
| 443 | iwl_mvm_tt_tx_backoff(mvm, 0); | 443 | iwl_mvm_tt_tx_backoff(mvm, 0); |
| 444 | 444 | ||
| 445 | ret = iwl_mvm_power_update_device_mode(mvm); | 445 | if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PM_CMD_SUPPORT)) { |
| 446 | ret = iwl_power_legacy_set_cam_mode(mvm); | ||
| 447 | if (ret) | ||
| 448 | goto error; | ||
| 449 | } | ||
| 450 | |||
| 451 | ret = iwl_mvm_power_update_device(mvm); | ||
| 446 | if (ret) | 452 | if (ret) |
| 447 | goto error; | 453 | goto error; |
| 448 | 454 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 43dd64409fc5..01b450039106 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c | |||
| @@ -636,14 +636,6 @@ static void iwl_mvm_mac_stop(struct ieee80211_hw *hw) | |||
| 636 | cancel_work_sync(&mvm->async_handlers_wk); | 636 | cancel_work_sync(&mvm->async_handlers_wk); |
| 637 | } | 637 | } |
| 638 | 638 | ||
| 639 | static void iwl_mvm_power_update_iterator(void *data, u8 *mac, | ||
| 640 | struct ieee80211_vif *vif) | ||
| 641 | { | ||
| 642 | struct iwl_mvm *mvm = data; | ||
| 643 | |||
| 644 | iwl_mvm_power_update_mode(mvm, vif); | ||
| 645 | } | ||
| 646 | |||
| 647 | static struct iwl_mvm_phy_ctxt *iwl_mvm_get_free_phy_ctxt(struct iwl_mvm *mvm) | 639 | static struct iwl_mvm_phy_ctxt *iwl_mvm_get_free_phy_ctxt(struct iwl_mvm *mvm) |
| 648 | { | 640 | { |
| 649 | u16 i; | 641 | u16 i; |
| @@ -725,7 +717,7 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, | |||
| 725 | if (ret) | 717 | if (ret) |
| 726 | goto out_release; | 718 | goto out_release; |
| 727 | 719 | ||
| 728 | iwl_mvm_power_disable(mvm, vif); | 720 | iwl_mvm_power_mac_disable(mvm, vif); |
| 729 | 721 | ||
| 730 | /* beacon filtering */ | 722 | /* beacon filtering */ |
| 731 | ret = iwl_mvm_disable_beacon_filter(mvm, vif, CMD_SYNC); | 723 | ret = iwl_mvm_disable_beacon_filter(mvm, vif, CMD_SYNC); |
| @@ -787,11 +779,6 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, | |||
| 787 | if (vif->type != NL80211_IFTYPE_P2P_DEVICE) | 779 | if (vif->type != NL80211_IFTYPE_P2P_DEVICE) |
| 788 | mvm->vif_count--; | 780 | mvm->vif_count--; |
| 789 | 781 | ||
| 790 | /* TODO: remove this when legacy PM will be discarded */ | ||
| 791 | ieee80211_iterate_active_interfaces( | ||
| 792 | mvm->hw, IEEE80211_IFACE_ITER_NORMAL, | ||
| 793 | iwl_mvm_power_update_iterator, mvm); | ||
| 794 | |||
| 795 | iwl_mvm_mac_ctxt_release(mvm, vif); | 782 | iwl_mvm_mac_ctxt_release(mvm, vif); |
| 796 | out_unlock: | 783 | out_unlock: |
| 797 | mutex_unlock(&mvm->mutex); | 784 | mutex_unlock(&mvm->mutex); |
| @@ -880,11 +867,6 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw, | |||
| 880 | if (mvm->vif_count && vif->type != NL80211_IFTYPE_P2P_DEVICE) | 867 | if (mvm->vif_count && vif->type != NL80211_IFTYPE_P2P_DEVICE) |
| 881 | mvm->vif_count--; | 868 | mvm->vif_count--; |
| 882 | 869 | ||
| 883 | /* TODO: remove this when legacy PM will be discarded */ | ||
| 884 | ieee80211_iterate_active_interfaces( | ||
| 885 | mvm->hw, IEEE80211_IFACE_ITER_NORMAL, | ||
| 886 | iwl_mvm_power_update_iterator, mvm); | ||
| 887 | |||
| 888 | iwl_mvm_mac_ctxt_remove(mvm, vif); | 870 | iwl_mvm_mac_ctxt_remove(mvm, vif); |
| 889 | 871 | ||
| 890 | out_release: | 872 | out_release: |
| @@ -1237,15 +1219,6 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, | |||
| 1237 | /* reset rssi values */ | 1219 | /* reset rssi values */ |
| 1238 | mvmvif->bf_data.ave_beacon_signal = 0; | 1220 | mvmvif->bf_data.ave_beacon_signal = 0; |
| 1239 | 1221 | ||
| 1240 | if (!(mvm->fw->ucode_capa.flags & | ||
| 1241 | IWL_UCODE_TLV_FLAGS_PM_CMD_SUPPORT)) { | ||
| 1242 | /* Workaround for FW bug, otherwise FW disables device | ||
| 1243 | * power save upon disassociation | ||
| 1244 | */ | ||
| 1245 | ret = iwl_mvm_power_update_mode(mvm, vif); | ||
| 1246 | if (ret) | ||
| 1247 | IWL_ERR(mvm, "failed to update power mode\n"); | ||
| 1248 | } | ||
| 1249 | iwl_mvm_bt_coex_vif_change(mvm); | 1222 | iwl_mvm_bt_coex_vif_change(mvm); |
| 1250 | iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_TT, | 1223 | iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_TT, |
| 1251 | IEEE80211_SMPS_AUTOMATIC); | 1224 | IEEE80211_SMPS_AUTOMATIC); |
| @@ -1258,7 +1231,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, | |||
| 1258 | &mvmvif->time_event_data); | 1231 | &mvmvif->time_event_data); |
| 1259 | } else if (changes & (BSS_CHANGED_PS | BSS_CHANGED_P2P_PS | | 1232 | } else if (changes & (BSS_CHANGED_PS | BSS_CHANGED_P2P_PS | |
| 1260 | BSS_CHANGED_QOS)) { | 1233 | BSS_CHANGED_QOS)) { |
| 1261 | ret = iwl_mvm_power_update_mode(mvm, vif); | 1234 | ret = iwl_mvm_power_mac_update_mode(mvm, vif); |
| 1262 | if (ret) | 1235 | if (ret) |
| 1263 | IWL_ERR(mvm, "failed to update power mode\n"); | 1236 | IWL_ERR(mvm, "failed to update power mode\n"); |
| 1264 | } | 1237 | } |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 2d76e228c1cb..0c12c322eb89 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h | |||
| @@ -92,7 +92,6 @@ enum iwl_mvm_tx_fifo { | |||
| 92 | }; | 92 | }; |
| 93 | 93 | ||
| 94 | extern struct ieee80211_ops iwl_mvm_hw_ops; | 94 | extern struct ieee80211_ops iwl_mvm_hw_ops; |
| 95 | extern const struct iwl_mvm_power_ops pm_legacy_ops; | ||
| 96 | extern const struct iwl_mvm_power_ops pm_mac_ops; | 95 | extern const struct iwl_mvm_power_ops pm_mac_ops; |
| 97 | 96 | ||
| 98 | /** | 97 | /** |
| @@ -159,20 +158,6 @@ enum iwl_power_scheme { | |||
| 159 | IEEE80211_WMM_IE_STA_QOSINFO_AC_BE) | 158 | IEEE80211_WMM_IE_STA_QOSINFO_AC_BE) |
| 160 | #define IWL_UAPSD_MAX_SP IEEE80211_WMM_IE_STA_QOSINFO_SP_2 | 159 | #define IWL_UAPSD_MAX_SP IEEE80211_WMM_IE_STA_QOSINFO_SP_2 |
| 161 | 160 | ||
| 162 | struct iwl_mvm_power_ops { | ||
| 163 | int (*power_update_mode)(struct iwl_mvm *mvm, | ||
| 164 | struct ieee80211_vif *vif); | ||
| 165 | int (*power_update_device_mode)(struct iwl_mvm *mvm); | ||
| 166 | int (*power_disable)(struct iwl_mvm *mvm, struct ieee80211_vif *vif); | ||
| 167 | void (*power_update_binding)(struct iwl_mvm *mvm, | ||
| 168 | struct ieee80211_vif *vif, bool assign); | ||
| 169 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
| 170 | int (*power_dbgfs_read)(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | ||
| 171 | char *buf, int bufsz); | ||
| 172 | #endif | ||
| 173 | }; | ||
| 174 | |||
| 175 | |||
| 176 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 161 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
| 177 | enum iwl_dbgfs_pm_mask { | 162 | enum iwl_dbgfs_pm_mask { |
| 178 | MVM_DEBUGFS_PM_KEEP_ALIVE = BIT(0), | 163 | MVM_DEBUGFS_PM_KEEP_ALIVE = BIT(0), |
| @@ -590,8 +575,6 @@ struct iwl_mvm { | |||
| 590 | struct iwl_mvm_tt_mgmt thermal_throttle; | 575 | struct iwl_mvm_tt_mgmt thermal_throttle; |
| 591 | s32 temperature; /* Celsius */ | 576 | s32 temperature; /* Celsius */ |
| 592 | 577 | ||
| 593 | const struct iwl_mvm_power_ops *pm_ops; | ||
| 594 | |||
| 595 | #ifdef CONFIG_NL80211_TESTMODE | 578 | #ifdef CONFIG_NL80211_TESTMODE |
| 596 | u32 noa_duration; | 579 | u32 noa_duration; |
| 597 | struct ieee80211_vif *noa_vif; | 580 | struct ieee80211_vif *noa_vif; |
| @@ -826,48 +809,23 @@ iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | |||
| 826 | /* rate scaling */ | 809 | /* rate scaling */ |
| 827 | int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, bool init); | 810 | int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, bool init); |
| 828 | 811 | ||
| 829 | /* power managment */ | 812 | /* power management */ |
| 830 | static inline int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, | 813 | int iwl_power_legacy_set_cam_mode(struct iwl_mvm *mvm); |
| 831 | struct ieee80211_vif *vif) | ||
| 832 | { | ||
| 833 | return mvm->pm_ops->power_update_mode(mvm, vif); | ||
| 834 | } | ||
| 835 | 814 | ||
| 836 | static inline int iwl_mvm_power_disable(struct iwl_mvm *mvm, | 815 | int iwl_mvm_power_mac_update_mode(struct iwl_mvm *mvm, |
| 837 | struct ieee80211_vif *vif) | 816 | struct ieee80211_vif *vif); |
| 838 | { | 817 | int iwl_mvm_power_mac_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif); |
| 839 | return mvm->pm_ops->power_disable(mvm, vif); | 818 | int iwl_mvm_power_update_device(struct iwl_mvm *mvm); |
| 840 | } | 819 | void iwl_mvm_power_update_binding(struct iwl_mvm *mvm, |
| 841 | 820 | struct ieee80211_vif *vif, bool assign); | |
| 842 | static inline int iwl_mvm_power_update_device_mode(struct iwl_mvm *mvm) | 821 | int iwl_mvm_power_mac_dbgfs_read(struct iwl_mvm *mvm, struct ieee80211_vif *vif, |
| 843 | { | 822 | char *buf, int bufsz); |
| 844 | if (mvm->pm_ops->power_update_device_mode) | ||
| 845 | return mvm->pm_ops->power_update_device_mode(mvm); | ||
| 846 | return 0; | ||
| 847 | } | ||
| 848 | |||
| 849 | static inline void iwl_mvm_power_update_binding(struct iwl_mvm *mvm, | ||
| 850 | struct ieee80211_vif *vif, | ||
| 851 | bool assign) | ||
| 852 | { | ||
| 853 | if (mvm->pm_ops->power_update_binding) | ||
| 854 | mvm->pm_ops->power_update_binding(mvm, vif, assign); | ||
| 855 | } | ||
| 856 | 823 | ||
| 857 | void iwl_mvm_power_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif); | 824 | void iwl_mvm_power_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif); |
| 858 | int iwl_mvm_power_uapsd_misbehaving_ap_notif(struct iwl_mvm *mvm, | 825 | int iwl_mvm_power_uapsd_misbehaving_ap_notif(struct iwl_mvm *mvm, |
| 859 | struct iwl_rx_cmd_buffer *rxb, | 826 | struct iwl_rx_cmd_buffer *rxb, |
| 860 | struct iwl_device_cmd *cmd); | 827 | struct iwl_device_cmd *cmd); |
| 861 | 828 | ||
| 862 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
| 863 | static inline int iwl_mvm_power_dbgfs_read(struct iwl_mvm *mvm, | ||
| 864 | struct ieee80211_vif *vif, | ||
| 865 | char *buf, int bufsz) | ||
| 866 | { | ||
| 867 | return mvm->pm_ops->power_dbgfs_read(mvm, vif, buf, bufsz); | ||
| 868 | } | ||
| 869 | #endif | ||
| 870 | |||
| 871 | int iwl_mvm_leds_init(struct iwl_mvm *mvm); | 829 | int iwl_mvm_leds_init(struct iwl_mvm *mvm); |
| 872 | void iwl_mvm_leds_exit(struct iwl_mvm *mvm); | 830 | void iwl_mvm_leds_exit(struct iwl_mvm *mvm); |
| 873 | 831 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index e268c15e5fea..a46f0b8b0870 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c | |||
| @@ -496,11 +496,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, | |||
| 496 | if (err) | 496 | if (err) |
| 497 | goto out_unregister; | 497 | goto out_unregister; |
| 498 | 498 | ||
| 499 | if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PM_CMD_SUPPORT) | ||
| 500 | mvm->pm_ops = &pm_mac_ops; | ||
| 501 | else | ||
| 502 | mvm->pm_ops = &pm_legacy_ops; | ||
| 503 | |||
| 504 | memset(&mvm->rx_stats, 0, sizeof(struct mvm_statistics_rx)); | 499 | memset(&mvm->rx_stats, 0, sizeof(struct mvm_statistics_rx)); |
| 505 | 500 | ||
| 506 | /* rpm starts with a taken ref. only set the appropriate bit here. */ | 501 | /* rpm starts with a taken ref. only set the appropriate bit here. */ |
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c index ac6d2c86e75c..2eea5b374ece 100644 --- a/drivers/net/wireless/iwlwifi/mvm/power.c +++ b/drivers/net/wireless/iwlwifi/mvm/power.c | |||
| @@ -439,14 +439,17 @@ static int _iwl_mvm_power_mac_update_mode(struct iwl_mvm *mvm, | |||
| 439 | sizeof(cmd), &cmd); | 439 | sizeof(cmd), &cmd); |
| 440 | } | 440 | } |
| 441 | 441 | ||
| 442 | static int iwl_mvm_power_mac_update_mode(struct iwl_mvm *mvm, | 442 | int iwl_mvm_power_mac_update_mode(struct iwl_mvm *mvm, |
| 443 | struct ieee80211_vif *vif) | 443 | struct ieee80211_vif *vif) |
| 444 | 444 | ||
| 445 | { | 445 | { |
| 446 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 446 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
| 447 | bool ba_enable; | 447 | bool ba_enable; |
| 448 | int ret; | 448 | int ret; |
| 449 | 449 | ||
| 450 | if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PM_CMD_SUPPORT)) | ||
| 451 | return 0; | ||
| 452 | |||
| 450 | ret = _iwl_mvm_power_mac_update_mode(mvm, vif); | 453 | ret = _iwl_mvm_power_mac_update_mode(mvm, vif); |
| 451 | if (ret) | 454 | if (ret) |
| 452 | return ret; | 455 | return ret; |
| @@ -458,13 +461,15 @@ static int iwl_mvm_power_mac_update_mode(struct iwl_mvm *mvm, | |||
| 458 | return iwl_mvm_update_beacon_abort(mvm, vif, ba_enable); | 461 | return iwl_mvm_update_beacon_abort(mvm, vif, ba_enable); |
| 459 | } | 462 | } |
| 460 | 463 | ||
| 461 | static int iwl_mvm_power_mac_disable(struct iwl_mvm *mvm, | 464 | int iwl_mvm_power_mac_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif) |
| 462 | struct ieee80211_vif *vif) | ||
| 463 | { | 465 | { |
| 464 | struct iwl_mac_power_cmd cmd = {}; | 466 | struct iwl_mac_power_cmd cmd = {}; |
| 465 | struct iwl_mvm_vif *mvmvif __maybe_unused = | 467 | struct iwl_mvm_vif *mvmvif __maybe_unused = |
| 466 | iwl_mvm_vif_from_mac80211(vif); | 468 | iwl_mvm_vif_from_mac80211(vif); |
| 467 | 469 | ||
| 470 | if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PM_CMD_SUPPORT)) | ||
| 471 | return 0; | ||
| 472 | |||
| 468 | if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) | 473 | if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) |
| 469 | return 0; | 474 | return 0; |
| 470 | 475 | ||
| @@ -513,8 +518,11 @@ static int _iwl_mvm_power_update_device(struct iwl_mvm *mvm, bool force_disable) | |||
| 513 | &cmd); | 518 | &cmd); |
| 514 | } | 519 | } |
| 515 | 520 | ||
| 516 | static int iwl_mvm_power_update_device(struct iwl_mvm *mvm) | 521 | int iwl_mvm_power_update_device(struct iwl_mvm *mvm) |
| 517 | { | 522 | { |
| 523 | if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PM_CMD_SUPPORT)) | ||
| 524 | return 0; | ||
| 525 | |||
| 518 | return _iwl_mvm_power_update_device(mvm, false); | 526 | return _iwl_mvm_power_update_device(mvm, false); |
| 519 | } | 527 | } |
| 520 | 528 | ||
| @@ -577,9 +585,8 @@ static void iwl_mvm_power_binding_iterator(void *_data, u8 *mac, | |||
| 577 | WARN_ONCE(ret, "Failed to update power parameters on a specific vif\n"); | 585 | WARN_ONCE(ret, "Failed to update power parameters on a specific vif\n"); |
| 578 | } | 586 | } |
| 579 | 587 | ||
| 580 | static void _iwl_mvm_power_update_binding(struct iwl_mvm *mvm, | 588 | void iwl_mvm_power_update_binding(struct iwl_mvm *mvm, |
| 581 | struct ieee80211_vif *vif, | 589 | struct ieee80211_vif *vif, bool assign) |
| 582 | bool assign) | ||
| 583 | { | 590 | { |
| 584 | bool ba_enable; | 591 | bool ba_enable; |
| 585 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 592 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
| @@ -589,6 +596,9 @@ static void _iwl_mvm_power_update_binding(struct iwl_mvm *mvm, | |||
| 589 | 596 | ||
| 590 | lockdep_assert_held(&mvm->mutex); | 597 | lockdep_assert_held(&mvm->mutex); |
| 591 | 598 | ||
| 599 | if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PM_CMD_SUPPORT)) | ||
| 600 | return; | ||
| 601 | |||
| 592 | if (vif->type == NL80211_IFTYPE_MONITOR) { | 602 | if (vif->type == NL80211_IFTYPE_MONITOR) { |
| 593 | int ret = _iwl_mvm_power_update_device(mvm, assign); | 603 | int ret = _iwl_mvm_power_update_device(mvm, assign); |
| 594 | mvm->ps_prevented = assign; | 604 | mvm->ps_prevented = assign; |
| @@ -615,14 +625,18 @@ static void _iwl_mvm_power_update_binding(struct iwl_mvm *mvm, | |||
| 615 | } | 625 | } |
| 616 | 626 | ||
| 617 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 627 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
| 618 | static int iwl_mvm_power_mac_dbgfs_read(struct iwl_mvm *mvm, | 628 | int iwl_mvm_power_mac_dbgfs_read(struct iwl_mvm *mvm, |
| 619 | struct ieee80211_vif *vif, char *buf, | 629 | struct ieee80211_vif *vif, char *buf, |
| 620 | int bufsz) | 630 | int bufsz) |
| 621 | { | 631 | { |
| 622 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 632 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
| 623 | struct iwl_mac_power_cmd cmd = {}; | 633 | struct iwl_mac_power_cmd cmd = {}; |
| 624 | int pos = 0; | 634 | int pos = 0; |
| 625 | 635 | ||
| 636 | if (WARN_ON(!(mvm->fw->ucode_capa.flags & | ||
| 637 | IWL_UCODE_TLV_FLAGS_PM_CMD_SUPPORT))) | ||
| 638 | return 0; | ||
| 639 | |||
| 626 | mutex_lock(&mvm->mutex); | 640 | mutex_lock(&mvm->mutex); |
| 627 | memcpy(&cmd, &mvmvif->mac_pwr_cmd, sizeof(cmd)); | 641 | memcpy(&cmd, &mvmvif->mac_pwr_cmd, sizeof(cmd)); |
| 628 | mutex_unlock(&mvm->mutex); | 642 | mutex_unlock(&mvm->mutex); |
| @@ -863,12 +877,12 @@ int iwl_mvm_update_beacon_filter(struct iwl_mvm *mvm, | |||
| 863 | return iwl_mvm_enable_beacon_filter(mvm, vif, flags); | 877 | return iwl_mvm_enable_beacon_filter(mvm, vif, flags); |
| 864 | } | 878 | } |
| 865 | 879 | ||
| 866 | const struct iwl_mvm_power_ops pm_mac_ops = { | 880 | int iwl_power_legacy_set_cam_mode(struct iwl_mvm *mvm) |
| 867 | .power_update_mode = iwl_mvm_power_mac_update_mode, | 881 | { |
| 868 | .power_update_device_mode = iwl_mvm_power_update_device, | 882 | struct iwl_powertable_cmd cmd = { |
| 869 | .power_disable = iwl_mvm_power_mac_disable, | 883 | .keep_alive_seconds = POWER_KEEP_ALIVE_PERIOD_SEC, |
| 870 | .power_update_binding = _iwl_mvm_power_update_binding, | 884 | }; |
| 871 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 885 | |
| 872 | .power_dbgfs_read = iwl_mvm_power_mac_dbgfs_read, | 886 | return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_SYNC, |
| 873 | #endif | 887 | sizeof(cmd), &cmd); |
| 874 | }; | 888 | } |
diff --git a/drivers/net/wireless/iwlwifi/mvm/power_legacy.c b/drivers/net/wireless/iwlwifi/mvm/power_legacy.c deleted file mode 100644 index ef712ae5bc62..000000000000 --- a/drivers/net/wireless/iwlwifi/mvm/power_legacy.c +++ /dev/null | |||
| @@ -1,319 +0,0 @@ | |||
| 1 | /****************************************************************************** | ||
| 2 | * | ||
| 3 | * This file is provided under a dual BSD/GPLv2 license. When using or | ||
| 4 | * redistributing this file, you may do so under either license. | ||
| 5 | * | ||
| 6 | * GPL LICENSE SUMMARY | ||
| 7 | * | ||
| 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of version 2 of the GNU General Public License as | ||
| 12 | * published by the Free Software Foundation. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope that it will be useful, but | ||
| 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 17 | * General Public License for more details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU General Public License | ||
| 20 | * along with this program; if not, write to the Free Software | ||
| 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, | ||
| 22 | * USA | ||
| 23 | * | ||
| 24 | * The full GNU General Public License is included in this distribution | ||
| 25 | * in the file called COPYING. | ||
| 26 | * | ||
| 27 | * Contact Information: | ||
| 28 | * Intel Linux Wireless <ilw@linux.intel.com> | ||
| 29 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
| 30 | * | ||
| 31 | * BSD LICENSE | ||
| 32 | * | ||
| 33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | ||
| 34 | * All rights reserved. | ||
| 35 | * | ||
| 36 | * Redistribution and use in source and binary forms, with or without | ||
| 37 | * modification, are permitted provided that the following conditions | ||
| 38 | * are met: | ||
| 39 | * | ||
| 40 | * * Redistributions of source code must retain the above copyright | ||
| 41 | * notice, this list of conditions and the following disclaimer. | ||
| 42 | * * Redistributions in binary form must reproduce the above copyright | ||
| 43 | * notice, this list of conditions and the following disclaimer in | ||
| 44 | * the documentation and/or other materials provided with the | ||
| 45 | * distribution. | ||
| 46 | * * Neither the name Intel Corporation nor the names of its | ||
| 47 | * contributors may be used to endorse or promote products derived | ||
| 48 | * from this software without specific prior written permission. | ||
| 49 | * | ||
| 50 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 51 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 52 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| 53 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| 54 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| 55 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
| 56 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| 57 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| 58 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| 59 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
| 60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 61 | * | ||
| 62 | *****************************************************************************/ | ||
| 63 | |||
| 64 | #include <linux/kernel.h> | ||
| 65 | #include <linux/module.h> | ||
| 66 | #include <linux/slab.h> | ||
| 67 | #include <linux/init.h> | ||
| 68 | |||
| 69 | #include <net/mac80211.h> | ||
| 70 | |||
| 71 | #include "iwl-debug.h" | ||
| 72 | #include "mvm.h" | ||
| 73 | #include "iwl-modparams.h" | ||
| 74 | #include "fw-api-power.h" | ||
| 75 | |||
| 76 | #define POWER_KEEP_ALIVE_PERIOD_SEC 25 | ||
| 77 | |||
| 78 | static void iwl_mvm_power_log(struct iwl_mvm *mvm, | ||
| 79 | struct iwl_powertable_cmd *cmd) | ||
| 80 | { | ||
| 81 | IWL_DEBUG_POWER(mvm, | ||
| 82 | "Sending power table command for power level %d, flags = 0x%X\n", | ||
| 83 | iwlmvm_mod_params.power_scheme, | ||
| 84 | le16_to_cpu(cmd->flags)); | ||
| 85 | IWL_DEBUG_POWER(mvm, "Keep alive = %u sec\n", cmd->keep_alive_seconds); | ||
| 86 | |||
| 87 | if (cmd->flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)) { | ||
| 88 | IWL_DEBUG_POWER(mvm, "Rx timeout = %u usec\n", | ||
| 89 | le32_to_cpu(cmd->rx_data_timeout)); | ||
| 90 | IWL_DEBUG_POWER(mvm, "Tx timeout = %u usec\n", | ||
| 91 | le32_to_cpu(cmd->tx_data_timeout)); | ||
| 92 | if (cmd->flags & cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK)) | ||
| 93 | IWL_DEBUG_POWER(mvm, "DTIM periods to skip = %u\n", | ||
| 94 | le32_to_cpu(cmd->skip_dtim_periods)); | ||
| 95 | if (cmd->flags & cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK)) | ||
| 96 | IWL_DEBUG_POWER(mvm, "LP RX RSSI threshold = %u\n", | ||
| 97 | le32_to_cpu(cmd->lprx_rssi_threshold)); | ||
| 98 | } | ||
| 99 | } | ||
| 100 | |||
| 101 | static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, | ||
| 102 | struct ieee80211_vif *vif, | ||
| 103 | struct iwl_powertable_cmd *cmd) | ||
| 104 | { | ||
| 105 | struct ieee80211_hw *hw = mvm->hw; | ||
| 106 | struct ieee80211_chanctx_conf *chanctx_conf; | ||
| 107 | struct ieee80211_channel *chan; | ||
| 108 | int dtimper, dtimper_msec; | ||
| 109 | int keep_alive; | ||
| 110 | bool radar_detect = false; | ||
| 111 | struct iwl_mvm_vif *mvmvif __maybe_unused = | ||
| 112 | iwl_mvm_vif_from_mac80211(vif); | ||
| 113 | |||
| 114 | /* | ||
| 115 | * Regardless of power management state the driver must set | ||
| 116 | * keep alive period. FW will use it for sending keep alive NDPs | ||
| 117 | * immediately after association. | ||
| 118 | */ | ||
| 119 | cmd->keep_alive_seconds = POWER_KEEP_ALIVE_PERIOD_SEC; | ||
| 120 | |||
| 121 | if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM) | ||
| 122 | return; | ||
| 123 | |||
| 124 | cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); | ||
| 125 | if (!vif->bss_conf.assoc) | ||
| 126 | cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK); | ||
| 127 | |||
| 128 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
| 129 | if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_DISABLE_POWER_OFF && | ||
| 130 | mvmvif->dbgfs_pm.disable_power_off) | ||
| 131 | cmd->flags &= cpu_to_le16(~POWER_FLAGS_POWER_SAVE_ENA_MSK); | ||
| 132 | #endif | ||
| 133 | if (!vif->bss_conf.ps) | ||
| 134 | return; | ||
| 135 | |||
| 136 | cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK); | ||
| 137 | |||
| 138 | if (vif->bss_conf.beacon_rate && | ||
| 139 | (vif->bss_conf.beacon_rate->bitrate == 10 || | ||
| 140 | vif->bss_conf.beacon_rate->bitrate == 60)) { | ||
| 141 | cmd->flags |= cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK); | ||
| 142 | cmd->lprx_rssi_threshold = | ||
| 143 | cpu_to_le32(POWER_LPRX_RSSI_THRESHOLD); | ||
| 144 | } | ||
| 145 | |||
| 146 | dtimper = hw->conf.ps_dtim_period ?: 1; | ||
| 147 | |||
| 148 | /* Check if radar detection is required on current channel */ | ||
| 149 | rcu_read_lock(); | ||
| 150 | chanctx_conf = rcu_dereference(vif->chanctx_conf); | ||
| 151 | WARN_ON(!chanctx_conf); | ||
| 152 | if (chanctx_conf) { | ||
| 153 | chan = chanctx_conf->def.chan; | ||
| 154 | radar_detect = chan->flags & IEEE80211_CHAN_RADAR; | ||
| 155 | } | ||
| 156 | rcu_read_unlock(); | ||
| 157 | |||
| 158 | /* Check skip over DTIM conditions */ | ||
| 159 | if (!radar_detect && (dtimper <= 10) && | ||
| 160 | (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP || | ||
| 161 | mvm->cur_ucode == IWL_UCODE_WOWLAN)) { | ||
| 162 | cmd->flags |= cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK); | ||
| 163 | cmd->skip_dtim_periods = cpu_to_le32(3); | ||
| 164 | } | ||
| 165 | |||
| 166 | /* Check that keep alive period is at least 3 * DTIM */ | ||
| 167 | dtimper_msec = dtimper * vif->bss_conf.beacon_int; | ||
| 168 | keep_alive = max_t(int, 3 * dtimper_msec, | ||
| 169 | MSEC_PER_SEC * cmd->keep_alive_seconds); | ||
| 170 | keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC); | ||
| 171 | cmd->keep_alive_seconds = keep_alive; | ||
| 172 | |||
| 173 | if (mvm->cur_ucode != IWL_UCODE_WOWLAN) { | ||
| 174 | cmd->rx_data_timeout = cpu_to_le32(100 * USEC_PER_MSEC); | ||
| 175 | cmd->tx_data_timeout = cpu_to_le32(100 * USEC_PER_MSEC); | ||
| 176 | } else { | ||
| 177 | cmd->rx_data_timeout = cpu_to_le32(10 * USEC_PER_MSEC); | ||
| 178 | cmd->tx_data_timeout = cpu_to_le32(10 * USEC_PER_MSEC); | ||
| 179 | } | ||
| 180 | |||
| 181 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
| 182 | if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_KEEP_ALIVE) | ||
| 183 | cmd->keep_alive_seconds = mvmvif->dbgfs_pm.keep_alive_seconds; | ||
| 184 | if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_SKIP_OVER_DTIM) { | ||
| 185 | if (mvmvif->dbgfs_pm.skip_over_dtim) | ||
| 186 | cmd->flags |= | ||
| 187 | cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK); | ||
| 188 | else | ||
| 189 | cmd->flags &= | ||
| 190 | cpu_to_le16(~POWER_FLAGS_SKIP_OVER_DTIM_MSK); | ||
| 191 | } | ||
| 192 | if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_RX_DATA_TIMEOUT) | ||
| 193 | cmd->rx_data_timeout = | ||
| 194 | cpu_to_le32(mvmvif->dbgfs_pm.rx_data_timeout); | ||
| 195 | if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_TX_DATA_TIMEOUT) | ||
| 196 | cmd->tx_data_timeout = | ||
| 197 | cpu_to_le32(mvmvif->dbgfs_pm.tx_data_timeout); | ||
| 198 | if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS) | ||
| 199 | cmd->skip_dtim_periods = | ||
| 200 | cpu_to_le32(mvmvif->dbgfs_pm.skip_dtim_periods); | ||
| 201 | if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_LPRX_ENA) { | ||
| 202 | if (mvmvif->dbgfs_pm.lprx_ena) | ||
| 203 | cmd->flags |= cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK); | ||
| 204 | else | ||
| 205 | cmd->flags &= cpu_to_le16(~POWER_FLAGS_LPRX_ENA_MSK); | ||
| 206 | } | ||
| 207 | if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD) | ||
| 208 | cmd->lprx_rssi_threshold = | ||
| 209 | cpu_to_le32(mvmvif->dbgfs_pm.lprx_rssi_threshold); | ||
| 210 | #endif /* CONFIG_IWLWIFI_DEBUGFS */ | ||
| 211 | } | ||
| 212 | |||
| 213 | static int iwl_mvm_power_legacy_update_mode(struct iwl_mvm *mvm, | ||
| 214 | struct ieee80211_vif *vif) | ||
| 215 | { | ||
| 216 | int ret; | ||
| 217 | bool ba_enable; | ||
| 218 | struct iwl_powertable_cmd cmd = {}; | ||
| 219 | |||
| 220 | if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) | ||
| 221 | return 0; | ||
| 222 | |||
| 223 | /* | ||
| 224 | * TODO: The following vif_count verification is temporary condition. | ||
| 225 | * Avoid power mode update if more than one interface is currently | ||
| 226 | * active. Remove this condition when FW will support power management | ||
| 227 | * on multiple MACs. | ||
| 228 | */ | ||
| 229 | IWL_DEBUG_POWER(mvm, "Currently %d interfaces active\n", | ||
| 230 | mvm->vif_count); | ||
| 231 | if (mvm->vif_count > 1) | ||
| 232 | return 0; | ||
| 233 | |||
| 234 | iwl_mvm_power_build_cmd(mvm, vif, &cmd); | ||
| 235 | iwl_mvm_power_log(mvm, &cmd); | ||
| 236 | |||
| 237 | ret = iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_SYNC, | ||
| 238 | sizeof(cmd), &cmd); | ||
| 239 | if (ret) | ||
| 240 | return ret; | ||
| 241 | |||
| 242 | ba_enable = !!(cmd.flags & | ||
| 243 | cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)); | ||
| 244 | |||
| 245 | return iwl_mvm_update_beacon_abort(mvm, vif, ba_enable); | ||
| 246 | } | ||
| 247 | |||
| 248 | static int iwl_mvm_power_legacy_disable(struct iwl_mvm *mvm, | ||
| 249 | struct ieee80211_vif *vif) | ||
| 250 | { | ||
| 251 | struct iwl_powertable_cmd cmd = {}; | ||
| 252 | struct iwl_mvm_vif *mvmvif __maybe_unused = | ||
| 253 | iwl_mvm_vif_from_mac80211(vif); | ||
| 254 | |||
| 255 | if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) | ||
| 256 | return 0; | ||
| 257 | |||
| 258 | if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM) | ||
| 259 | cmd.flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); | ||
| 260 | |||
| 261 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
| 262 | if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_DISABLE_POWER_OFF && | ||
| 263 | mvmvif->dbgfs_pm.disable_power_off) | ||
| 264 | cmd.flags &= cpu_to_le16(~POWER_FLAGS_POWER_SAVE_ENA_MSK); | ||
| 265 | #endif | ||
| 266 | iwl_mvm_power_log(mvm, &cmd); | ||
| 267 | |||
| 268 | return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_ASYNC, | ||
| 269 | sizeof(cmd), &cmd); | ||
| 270 | } | ||
| 271 | |||
| 272 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
| 273 | static int iwl_mvm_power_legacy_dbgfs_read(struct iwl_mvm *mvm, | ||
| 274 | struct ieee80211_vif *vif, char *buf, | ||
| 275 | int bufsz) | ||
| 276 | { | ||
| 277 | struct iwl_powertable_cmd cmd = {}; | ||
| 278 | int pos = 0; | ||
| 279 | |||
| 280 | iwl_mvm_power_build_cmd(mvm, vif, &cmd); | ||
| 281 | |||
| 282 | pos += scnprintf(buf+pos, bufsz-pos, "disable_power_off = %d\n", | ||
| 283 | (cmd.flags & | ||
| 284 | cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK)) ? | ||
| 285 | 0 : 1); | ||
| 286 | pos += scnprintf(buf+pos, bufsz-pos, "skip_dtim_periods = %d\n", | ||
| 287 | le32_to_cpu(cmd.skip_dtim_periods)); | ||
| 288 | pos += scnprintf(buf+pos, bufsz-pos, "power_scheme = %d\n", | ||
| 289 | iwlmvm_mod_params.power_scheme); | ||
| 290 | pos += scnprintf(buf+pos, bufsz-pos, "flags = 0x%x\n", | ||
| 291 | le16_to_cpu(cmd.flags)); | ||
| 292 | pos += scnprintf(buf+pos, bufsz-pos, "keep_alive = %d\n", | ||
| 293 | cmd.keep_alive_seconds); | ||
| 294 | |||
| 295 | if (cmd.flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)) { | ||
| 296 | pos += scnprintf(buf+pos, bufsz-pos, "skip_over_dtim = %d\n", | ||
| 297 | (cmd.flags & | ||
| 298 | cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK)) ? | ||
| 299 | 1 : 0); | ||
| 300 | pos += scnprintf(buf+pos, bufsz-pos, "rx_data_timeout = %d\n", | ||
| 301 | le32_to_cpu(cmd.rx_data_timeout)); | ||
| 302 | pos += scnprintf(buf+pos, bufsz-pos, "tx_data_timeout = %d\n", | ||
| 303 | le32_to_cpu(cmd.tx_data_timeout)); | ||
| 304 | if (cmd.flags & cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK)) | ||
| 305 | pos += scnprintf(buf+pos, bufsz-pos, | ||
| 306 | "lprx_rssi_threshold = %d\n", | ||
| 307 | le32_to_cpu(cmd.lprx_rssi_threshold)); | ||
| 308 | } | ||
| 309 | return pos; | ||
| 310 | } | ||
| 311 | #endif | ||
| 312 | |||
| 313 | const struct iwl_mvm_power_ops pm_legacy_ops = { | ||
| 314 | .power_update_mode = iwl_mvm_power_legacy_update_mode, | ||
| 315 | .power_disable = iwl_mvm_power_legacy_disable, | ||
| 316 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
| 317 | .power_dbgfs_read = iwl_mvm_power_legacy_dbgfs_read, | ||
| 318 | #endif | ||
| 319 | }; | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c index b2162328ac96..d4d901068e90 100644 --- a/drivers/net/wireless/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/iwlwifi/mvm/utils.c | |||
| @@ -564,5 +564,5 @@ int iwl_mvm_update_low_latency(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
| 564 | 564 | ||
| 565 | iwl_mvm_bt_coex_vif_change(mvm); | 565 | iwl_mvm_bt_coex_vif_change(mvm); |
| 566 | 566 | ||
| 567 | return iwl_mvm_power_update_mode(mvm, vif); | 567 | return iwl_mvm_power_mac_update_mode(mvm, vif); |
| 568 | } | 568 | } |
