.. | .. |
---|
8 | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
---|
9 | 9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH |
---|
10 | 10 | * Copyright(c) 2015 - 2017 Intel Deutschland GmbH |
---|
| 11 | + * Copyright (C) 2018 - 2019 Intel Corporation |
---|
11 | 12 | * |
---|
12 | 13 | * This program is free software; you can redistribute it and/or modify |
---|
13 | 14 | * it under the terms of version 2 of the GNU General Public License as |
---|
.. | .. |
---|
17 | 18 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
18 | 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
---|
19 | 20 | * General Public License for more details. |
---|
20 | | - * |
---|
21 | | - * You should have received a copy of the GNU General Public License |
---|
22 | | - * along with this program; if not, write to the Free Software |
---|
23 | | - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, |
---|
24 | | - * USA |
---|
25 | 21 | * |
---|
26 | 22 | * The full GNU General Public License is included in this distribution |
---|
27 | 23 | * in the file called COPYING. |
---|
.. | .. |
---|
35 | 31 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
---|
36 | 32 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH |
---|
37 | 33 | * Copyright(c) 2015 - 2017 Intel Deutschland GmbH |
---|
| 34 | + * Copyright (C) 2018 - 2019 Intel Corporation |
---|
38 | 35 | * All rights reserved. |
---|
39 | 36 | * |
---|
40 | 37 | * Redistribution and use in source and binary forms, with or without |
---|
.. | .. |
---|
84 | 81 | struct iwl_beacon_filter_cmd *cmd, |
---|
85 | 82 | u32 flags) |
---|
86 | 83 | { |
---|
| 84 | + u16 len; |
---|
| 85 | + |
---|
87 | 86 | IWL_DEBUG_POWER(mvm, "ba_enable_beacon_abort is: %d\n", |
---|
88 | 87 | le32_to_cpu(cmd->ba_enable_beacon_abort)); |
---|
89 | 88 | IWL_DEBUG_POWER(mvm, "ba_escape_timer is: %d\n", |
---|
.. | .. |
---|
106 | 105 | le32_to_cpu(cmd->bf_temp_fast_filter)); |
---|
107 | 106 | IWL_DEBUG_POWER(mvm, "bf_temp_slow_filter is: %d\n", |
---|
108 | 107 | le32_to_cpu(cmd->bf_temp_slow_filter)); |
---|
| 108 | + IWL_DEBUG_POWER(mvm, "bf_threshold_absolute_low is: %d, %d\n", |
---|
| 109 | + le32_to_cpu(cmd->bf_threshold_absolute_low[0]), |
---|
| 110 | + le32_to_cpu(cmd->bf_threshold_absolute_low[1])); |
---|
| 111 | + |
---|
| 112 | + IWL_DEBUG_POWER(mvm, "bf_threshold_absolute_high is: %d, %d\n", |
---|
| 113 | + le32_to_cpu(cmd->bf_threshold_absolute_high[0]), |
---|
| 114 | + le32_to_cpu(cmd->bf_threshold_absolute_high[1])); |
---|
| 115 | + |
---|
| 116 | + if (fw_has_api(&mvm->fw->ucode_capa, |
---|
| 117 | + IWL_UCODE_TLV_API_BEACON_FILTER_V4)) |
---|
| 118 | + len = sizeof(struct iwl_beacon_filter_cmd); |
---|
| 119 | + else |
---|
| 120 | + len = offsetof(struct iwl_beacon_filter_cmd, |
---|
| 121 | + bf_threshold_absolute_low); |
---|
109 | 122 | |
---|
110 | 123 | return iwl_mvm_send_cmd_pdu(mvm, REPLY_BEACON_FILTERING_CMD, flags, |
---|
111 | | - sizeof(struct iwl_beacon_filter_cmd), cmd); |
---|
| 124 | + len, cmd); |
---|
112 | 125 | } |
---|
113 | 126 | |
---|
114 | 127 | static |
---|
115 | 128 | void iwl_mvm_beacon_filter_set_cqm_params(struct iwl_mvm *mvm, |
---|
116 | 129 | struct ieee80211_vif *vif, |
---|
117 | | - struct iwl_beacon_filter_cmd *cmd, |
---|
118 | | - bool d0i3) |
---|
| 130 | + struct iwl_beacon_filter_cmd *cmd) |
---|
119 | 131 | { |
---|
120 | 132 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
---|
121 | 133 | |
---|
122 | | - if (vif->bss_conf.cqm_rssi_thold && !d0i3) { |
---|
| 134 | + if (vif->bss_conf.cqm_rssi_thold) { |
---|
123 | 135 | cmd->bf_energy_delta = |
---|
124 | 136 | cpu_to_le32(vif->bss_conf.cqm_rssi_hyst); |
---|
125 | 137 | /* fw uses an absolute value for this */ |
---|
.. | .. |
---|
186 | 198 | if (!mvmvif->queue_params[ac].uapsd) |
---|
187 | 199 | continue; |
---|
188 | 200 | |
---|
189 | | - if (mvm->fwrt.cur_fw_img != IWL_UCODE_WOWLAN) |
---|
| 201 | + if (!test_bit(IWL_MVM_STATUS_IN_D3, &mvm->status)) |
---|
190 | 202 | cmd->flags |= |
---|
191 | 203 | cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK); |
---|
192 | 204 | |
---|
.. | .. |
---|
221 | 233 | cmd->flags |= cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK); |
---|
222 | 234 | cmd->snooze_interval = cpu_to_le16(IWL_MVM_PS_SNOOZE_INTERVAL); |
---|
223 | 235 | cmd->snooze_window = |
---|
224 | | - (mvm->fwrt.cur_fw_img == IWL_UCODE_WOWLAN) ? |
---|
| 236 | + test_bit(IWL_MVM_STATUS_IN_D3, &mvm->status) ? |
---|
225 | 237 | cpu_to_le16(IWL_MVM_WOWLAN_PS_SNOOZE_WINDOW) : |
---|
226 | 238 | cpu_to_le16(IWL_MVM_PS_SNOOZE_WINDOW); |
---|
227 | 239 | } |
---|
228 | 240 | |
---|
229 | 241 | cmd->uapsd_max_sp = mvm->hw->uapsd_max_sp_len; |
---|
230 | 242 | |
---|
231 | | - if (mvm->fwrt.cur_fw_img == IWL_UCODE_WOWLAN || cmd->flags & |
---|
232 | | - cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) { |
---|
| 243 | + if (test_bit(IWL_MVM_STATUS_IN_D3, &mvm->status) || |
---|
| 244 | + cmd->flags & cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) { |
---|
233 | 245 | cmd->rx_data_timeout_uapsd = |
---|
234 | 246 | cpu_to_le32(IWL_MVM_WOWLAN_PS_RX_DATA_TIMEOUT); |
---|
235 | 247 | cmd->tx_data_timeout_uapsd = |
---|
.. | .. |
---|
342 | 354 | |
---|
343 | 355 | static void iwl_mvm_power_config_skip_dtim(struct iwl_mvm *mvm, |
---|
344 | 356 | struct ieee80211_vif *vif, |
---|
345 | | - struct iwl_mac_power_cmd *cmd, |
---|
346 | | - bool host_awake) |
---|
| 357 | + struct iwl_mac_power_cmd *cmd) |
---|
347 | 358 | { |
---|
348 | 359 | int dtimper = vif->bss_conf.dtim_period ?: 1; |
---|
349 | 360 | int skip; |
---|
.. | .. |
---|
358 | 369 | if (dtimper >= 10) |
---|
359 | 370 | return; |
---|
360 | 371 | |
---|
361 | | - /* TODO: check that multicast wake lock is off */ |
---|
362 | | - |
---|
363 | | - if (host_awake) { |
---|
| 372 | + if (!test_bit(IWL_MVM_STATUS_IN_D3, &mvm->status)) { |
---|
364 | 373 | if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_LP) |
---|
365 | 374 | return; |
---|
366 | 375 | skip = 2; |
---|
.. | .. |
---|
380 | 389 | |
---|
381 | 390 | static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, |
---|
382 | 391 | struct ieee80211_vif *vif, |
---|
383 | | - struct iwl_mac_power_cmd *cmd, |
---|
384 | | - bool host_awake) |
---|
| 392 | + struct iwl_mac_power_cmd *cmd) |
---|
385 | 393 | { |
---|
386 | 394 | int dtimper, bi; |
---|
387 | 395 | int keep_alive; |
---|
.. | .. |
---|
427 | 435 | cmd->lprx_rssi_threshold = POWER_LPRX_RSSI_THRESHOLD; |
---|
428 | 436 | } |
---|
429 | 437 | |
---|
430 | | - iwl_mvm_power_config_skip_dtim(mvm, vif, cmd, host_awake); |
---|
| 438 | + iwl_mvm_power_config_skip_dtim(mvm, vif, cmd); |
---|
431 | 439 | |
---|
432 | | - if (!host_awake) { |
---|
| 440 | + if (test_bit(IWL_MVM_STATUS_IN_D3, &mvm->status)) { |
---|
433 | 441 | cmd->rx_data_timeout = |
---|
434 | 442 | cpu_to_le32(IWL_MVM_WOWLAN_PS_RX_DATA_TIMEOUT); |
---|
435 | 443 | cmd->tx_data_timeout = |
---|
.. | .. |
---|
502 | 510 | { |
---|
503 | 511 | struct iwl_mac_power_cmd cmd = {}; |
---|
504 | 512 | |
---|
505 | | - iwl_mvm_power_build_cmd(mvm, vif, &cmd, |
---|
506 | | - mvm->fwrt.cur_fw_img != IWL_UCODE_WOWLAN); |
---|
| 513 | + iwl_mvm_power_build_cmd(mvm, vif, &cmd); |
---|
507 | 514 | iwl_mvm_power_log(mvm, &cmd); |
---|
508 | 515 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
---|
509 | 516 | memcpy(&iwl_mvm_vif_from_mac80211(vif)->mac_pwr_cmd, &cmd, sizeof(cmd)); |
---|
.. | .. |
---|
526 | 533 | cmd.flags |= cpu_to_le16(DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK); |
---|
527 | 534 | |
---|
528 | 535 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
---|
529 | | - if ((mvm->fwrt.cur_fw_img == IWL_UCODE_WOWLAN) ? |
---|
| 536 | + if (test_bit(IWL_MVM_STATUS_IN_D3, &mvm->status) ? |
---|
530 | 537 | mvm->disable_power_off_d3 : mvm->disable_power_off) |
---|
531 | 538 | cmd.flags &= |
---|
532 | 539 | cpu_to_le16(~DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK); |
---|
533 | 540 | #endif |
---|
| 541 | + if (mvm->ext_clock_valid) |
---|
| 542 | + cmd.flags |= cpu_to_le16(DEVICE_POWER_FLAGS_32K_CLK_VALID_MSK); |
---|
| 543 | + |
---|
534 | 544 | IWL_DEBUG_POWER(mvm, |
---|
535 | 545 | "Sending device power command with flags = 0x%X\n", |
---|
536 | 546 | cmd.flags); |
---|
.. | .. |
---|
610 | 620 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
---|
611 | 621 | struct iwl_power_vifs *power_iterator = _data; |
---|
612 | 622 | bool active = mvmvif->phy_ctxt && mvmvif->phy_ctxt->id < NUM_PHY_CTX; |
---|
| 623 | + |
---|
| 624 | + if (!mvmvif->uploaded) |
---|
| 625 | + return; |
---|
613 | 626 | |
---|
614 | 627 | switch (ieee80211_vif_type_p2p(vif)) { |
---|
615 | 628 | case NL80211_IFTYPE_P2P_DEVICE: |
---|
.. | .. |
---|
833 | 846 | static int _iwl_mvm_enable_beacon_filter(struct iwl_mvm *mvm, |
---|
834 | 847 | struct ieee80211_vif *vif, |
---|
835 | 848 | struct iwl_beacon_filter_cmd *cmd, |
---|
836 | | - u32 cmd_flags, |
---|
837 | | - bool d0i3) |
---|
| 849 | + u32 cmd_flags) |
---|
838 | 850 | { |
---|
839 | 851 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
---|
840 | 852 | int ret; |
---|
.. | .. |
---|
843 | 855 | vif->type != NL80211_IFTYPE_STATION || vif->p2p) |
---|
844 | 856 | return 0; |
---|
845 | 857 | |
---|
846 | | - iwl_mvm_beacon_filter_set_cqm_params(mvm, vif, cmd, d0i3); |
---|
847 | | - if (!d0i3) |
---|
848 | | - iwl_mvm_beacon_filter_debugfs_parameters(vif, cmd); |
---|
| 858 | + iwl_mvm_beacon_filter_set_cqm_params(mvm, vif, cmd); |
---|
| 859 | + iwl_mvm_beacon_filter_debugfs_parameters(vif, cmd); |
---|
849 | 860 | ret = iwl_mvm_beacon_filter_send_cmd(mvm, cmd, cmd_flags); |
---|
850 | 861 | |
---|
851 | | - /* don't change bf_enabled in case of temporary d0i3 configuration */ |
---|
852 | | - if (!ret && !d0i3) |
---|
| 862 | + if (!ret) |
---|
853 | 863 | mvmvif->bf_data.bf_enabled = true; |
---|
854 | 864 | |
---|
855 | 865 | return ret; |
---|
.. | .. |
---|
864 | 874 | .bf_enable_beacon_filter = cpu_to_le32(1), |
---|
865 | 875 | }; |
---|
866 | 876 | |
---|
867 | | - return _iwl_mvm_enable_beacon_filter(mvm, vif, &cmd, flags, false); |
---|
| 877 | + return _iwl_mvm_enable_beacon_filter(mvm, vif, &cmd, flags); |
---|
868 | 878 | } |
---|
869 | 879 | |
---|
870 | 880 | static int _iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm, |
---|
871 | 881 | struct ieee80211_vif *vif, |
---|
872 | | - u32 flags, bool d0i3) |
---|
| 882 | + u32 flags) |
---|
873 | 883 | { |
---|
874 | 884 | struct iwl_beacon_filter_cmd cmd = {}; |
---|
875 | 885 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
---|
.. | .. |
---|
880 | 890 | |
---|
881 | 891 | ret = iwl_mvm_beacon_filter_send_cmd(mvm, &cmd, flags); |
---|
882 | 892 | |
---|
883 | | - /* don't change bf_enabled in case of temporary d0i3 configuration */ |
---|
884 | | - if (!ret && !d0i3) |
---|
| 893 | + if (!ret) |
---|
885 | 894 | mvmvif->bf_data.bf_enabled = false; |
---|
886 | 895 | |
---|
887 | 896 | return ret; |
---|
.. | .. |
---|
891 | 900 | struct ieee80211_vif *vif, |
---|
892 | 901 | u32 flags) |
---|
893 | 902 | { |
---|
894 | | - return _iwl_mvm_disable_beacon_filter(mvm, vif, flags, false); |
---|
| 903 | + return _iwl_mvm_disable_beacon_filter(mvm, vif, flags); |
---|
895 | 904 | } |
---|
896 | 905 | |
---|
897 | 906 | static int iwl_mvm_power_set_ps(struct iwl_mvm *mvm) |
---|
.. | .. |
---|
934 | 943 | if (!mvmvif->bf_data.bf_enabled) |
---|
935 | 944 | return 0; |
---|
936 | 945 | |
---|
937 | | - if (mvm->fwrt.cur_fw_img == IWL_UCODE_WOWLAN) |
---|
| 946 | + if (test_bit(IWL_MVM_STATUS_IN_D3, &mvm->status)) |
---|
938 | 947 | cmd.ba_escape_timer = cpu_to_le32(IWL_BA_ESCAPE_TIMER_D3); |
---|
939 | 948 | |
---|
940 | 949 | mvmvif->bf_data.ba_enabled = !(!mvmvif->pm_enabled || |
---|
.. | .. |
---|
942 | 951 | !vif->bss_conf.ps || |
---|
943 | 952 | iwl_mvm_vif_low_latency(mvmvif)); |
---|
944 | 953 | |
---|
945 | | - return _iwl_mvm_enable_beacon_filter(mvm, vif, &cmd, 0, false); |
---|
| 954 | + return _iwl_mvm_enable_beacon_filter(mvm, vif, &cmd, 0); |
---|
946 | 955 | } |
---|
947 | 956 | |
---|
948 | 957 | int iwl_mvm_power_update_ps(struct iwl_mvm *mvm) |
---|
.. | .. |
---|
1005 | 1014 | return iwl_mvm_power_set_ba(mvm, vifs.bss_vif); |
---|
1006 | 1015 | |
---|
1007 | 1016 | return 0; |
---|
1008 | | -} |
---|
1009 | | - |
---|
1010 | | -int iwl_mvm_update_d0i3_power_mode(struct iwl_mvm *mvm, |
---|
1011 | | - struct ieee80211_vif *vif, |
---|
1012 | | - bool enable, u32 flags) |
---|
1013 | | -{ |
---|
1014 | | - int ret; |
---|
1015 | | - struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
---|
1016 | | - struct iwl_mac_power_cmd cmd = {}; |
---|
1017 | | - |
---|
1018 | | - if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) |
---|
1019 | | - return 0; |
---|
1020 | | - |
---|
1021 | | - if (!vif->bss_conf.assoc) |
---|
1022 | | - return 0; |
---|
1023 | | - |
---|
1024 | | - iwl_mvm_power_build_cmd(mvm, vif, &cmd, !enable); |
---|
1025 | | - |
---|
1026 | | - iwl_mvm_power_log(mvm, &cmd); |
---|
1027 | | -#ifdef CONFIG_IWLWIFI_DEBUGFS |
---|
1028 | | - memcpy(&mvmvif->mac_pwr_cmd, &cmd, sizeof(cmd)); |
---|
1029 | | -#endif |
---|
1030 | | - ret = iwl_mvm_send_cmd_pdu(mvm, MAC_PM_POWER_TABLE, flags, |
---|
1031 | | - sizeof(cmd), &cmd); |
---|
1032 | | - if (ret) |
---|
1033 | | - return ret; |
---|
1034 | | - |
---|
1035 | | - /* configure beacon filtering */ |
---|
1036 | | - if (mvmvif != mvm->bf_allowed_vif) |
---|
1037 | | - return 0; |
---|
1038 | | - |
---|
1039 | | - if (enable) { |
---|
1040 | | - struct iwl_beacon_filter_cmd cmd_bf = { |
---|
1041 | | - IWL_BF_CMD_CONFIG_D0I3, |
---|
1042 | | - .bf_enable_beacon_filter = cpu_to_le32(1), |
---|
1043 | | - }; |
---|
1044 | | - /* |
---|
1045 | | - * When beacon storing is supported - disable beacon filtering |
---|
1046 | | - * altogether - the latest beacon will be sent when exiting d0i3 |
---|
1047 | | - */ |
---|
1048 | | - if (fw_has_capa(&mvm->fw->ucode_capa, |
---|
1049 | | - IWL_UCODE_TLV_CAPA_BEACON_STORING)) |
---|
1050 | | - ret = _iwl_mvm_disable_beacon_filter(mvm, vif, flags, |
---|
1051 | | - true); |
---|
1052 | | - else |
---|
1053 | | - ret = _iwl_mvm_enable_beacon_filter(mvm, vif, &cmd_bf, |
---|
1054 | | - flags, true); |
---|
1055 | | - } else { |
---|
1056 | | - if (mvmvif->bf_data.bf_enabled) |
---|
1057 | | - ret = iwl_mvm_enable_beacon_filter(mvm, vif, flags); |
---|
1058 | | - else |
---|
1059 | | - ret = iwl_mvm_disable_beacon_filter(mvm, vif, flags); |
---|
1060 | | - } |
---|
1061 | | - |
---|
1062 | | - return ret; |
---|
1063 | 1017 | } |
---|