diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/mvm/power.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/power.c | 198 |
1 files changed, 134 insertions, 64 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c index e7ca965a89b8..4e7c9f245846 100644 --- a/drivers/net/wireless/iwlwifi/mvm/power.c +++ b/drivers/net/wireless/iwlwifi/mvm/power.c | |||
@@ -75,8 +75,8 @@ | |||
75 | 75 | ||
76 | #define POWER_KEEP_ALIVE_PERIOD_SEC 25 | 76 | #define POWER_KEEP_ALIVE_PERIOD_SEC 25 |
77 | 77 | ||
78 | static int iwl_mvm_beacon_filter_send_cmd(struct iwl_mvm *mvm, | 78 | int iwl_mvm_beacon_filter_send_cmd(struct iwl_mvm *mvm, |
79 | struct iwl_beacon_filter_cmd *cmd) | 79 | struct iwl_beacon_filter_cmd *cmd) |
80 | { | 80 | { |
81 | int ret; | 81 | int ret; |
82 | 82 | ||
@@ -85,52 +85,60 @@ static int iwl_mvm_beacon_filter_send_cmd(struct iwl_mvm *mvm, | |||
85 | 85 | ||
86 | if (!ret) { | 86 | if (!ret) { |
87 | IWL_DEBUG_POWER(mvm, "ba_enable_beacon_abort is: %d\n", | 87 | IWL_DEBUG_POWER(mvm, "ba_enable_beacon_abort is: %d\n", |
88 | cmd->ba_enable_beacon_abort); | 88 | le32_to_cpu(cmd->ba_enable_beacon_abort)); |
89 | IWL_DEBUG_POWER(mvm, "ba_escape_timer is: %d\n", | 89 | IWL_DEBUG_POWER(mvm, "ba_escape_timer is: %d\n", |
90 | cmd->ba_escape_timer); | 90 | le32_to_cpu(cmd->ba_escape_timer)); |
91 | IWL_DEBUG_POWER(mvm, "bf_debug_flag is: %d\n", | 91 | IWL_DEBUG_POWER(mvm, "bf_debug_flag is: %d\n", |
92 | cmd->bf_debug_flag); | 92 | le32_to_cpu(cmd->bf_debug_flag)); |
93 | IWL_DEBUG_POWER(mvm, "bf_enable_beacon_filter is: %d\n", | 93 | IWL_DEBUG_POWER(mvm, "bf_enable_beacon_filter is: %d\n", |
94 | cmd->bf_enable_beacon_filter); | 94 | le32_to_cpu(cmd->bf_enable_beacon_filter)); |
95 | IWL_DEBUG_POWER(mvm, "bf_energy_delta is: %d\n", | 95 | IWL_DEBUG_POWER(mvm, "bf_energy_delta is: %d\n", |
96 | cmd->bf_energy_delta); | 96 | le32_to_cpu(cmd->bf_energy_delta)); |
97 | IWL_DEBUG_POWER(mvm, "bf_escape_timer is: %d\n", | 97 | IWL_DEBUG_POWER(mvm, "bf_escape_timer is: %d\n", |
98 | cmd->bf_escape_timer); | 98 | le32_to_cpu(cmd->bf_escape_timer)); |
99 | IWL_DEBUG_POWER(mvm, "bf_roaming_energy_delta is: %d\n", | 99 | IWL_DEBUG_POWER(mvm, "bf_roaming_energy_delta is: %d\n", |
100 | cmd->bf_roaming_energy_delta); | 100 | le32_to_cpu(cmd->bf_roaming_energy_delta)); |
101 | IWL_DEBUG_POWER(mvm, "bf_roaming_state is: %d\n", | 101 | IWL_DEBUG_POWER(mvm, "bf_roaming_state is: %d\n", |
102 | cmd->bf_roaming_state); | 102 | le32_to_cpu(cmd->bf_roaming_state)); |
103 | IWL_DEBUG_POWER(mvm, "bf_temperature_delta is: %d\n", | 103 | IWL_DEBUG_POWER(mvm, "bf_temp_threshold is: %d\n", |
104 | cmd->bf_temperature_delta); | 104 | le32_to_cpu(cmd->bf_temp_threshold)); |
105 | IWL_DEBUG_POWER(mvm, "bf_temp_fast_filter is: %d\n", | ||
106 | le32_to_cpu(cmd->bf_temp_fast_filter)); | ||
107 | IWL_DEBUG_POWER(mvm, "bf_temp_slow_filter is: %d\n", | ||
108 | le32_to_cpu(cmd->bf_temp_slow_filter)); | ||
105 | } | 109 | } |
106 | return ret; | 110 | return ret; |
107 | } | 111 | } |
108 | 112 | ||
109 | static int iwl_mvm_update_beacon_abort(struct iwl_mvm *mvm, | 113 | int iwl_mvm_update_beacon_abort(struct iwl_mvm *mvm, |
110 | struct ieee80211_vif *vif, bool enable) | 114 | struct ieee80211_vif *vif, bool enable) |
111 | { | 115 | { |
112 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 116 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
113 | struct iwl_beacon_filter_cmd cmd = { | 117 | struct iwl_beacon_filter_cmd cmd = { |
114 | IWL_BF_CMD_CONFIG_DEFAULTS, | 118 | IWL_BF_CMD_CONFIG_DEFAULTS, |
115 | .bf_enable_beacon_filter = 1, | 119 | .bf_enable_beacon_filter = cpu_to_le32(1), |
116 | .ba_enable_beacon_abort = enable, | 120 | .ba_enable_beacon_abort = cpu_to_le32(enable), |
117 | }; | 121 | }; |
118 | 122 | ||
119 | if (!mvmvif->bf_enabled) | 123 | if (!mvmvif->bf_enabled) |
120 | return 0; | 124 | return 0; |
121 | 125 | ||
126 | if (mvm->cur_ucode == IWL_UCODE_WOWLAN) | ||
127 | cmd.ba_escape_timer = cpu_to_le32(IWL_BA_ESCAPE_TIMER_D3); | ||
128 | |||
122 | iwl_mvm_beacon_filter_debugfs_parameters(vif, &cmd); | 129 | iwl_mvm_beacon_filter_debugfs_parameters(vif, &cmd); |
123 | return iwl_mvm_beacon_filter_send_cmd(mvm, &cmd); | 130 | return iwl_mvm_beacon_filter_send_cmd(mvm, &cmd); |
124 | } | 131 | } |
125 | 132 | ||
126 | static void iwl_mvm_power_log(struct iwl_mvm *mvm, | 133 | static void iwl_mvm_power_log(struct iwl_mvm *mvm, |
127 | struct iwl_powertable_cmd *cmd) | 134 | struct iwl_mac_power_cmd *cmd) |
128 | { | 135 | { |
129 | IWL_DEBUG_POWER(mvm, | 136 | IWL_DEBUG_POWER(mvm, |
130 | "Sending power table command for power level %d, flags = 0x%X\n", | 137 | "Sending power table command on mac id 0x%X for power level %d, flags = 0x%X\n", |
131 | iwlmvm_mod_params.power_scheme, | 138 | cmd->id_and_color, iwlmvm_mod_params.power_scheme, |
132 | le16_to_cpu(cmd->flags)); | 139 | le16_to_cpu(cmd->flags)); |
133 | IWL_DEBUG_POWER(mvm, "Keep alive = %u sec\n", cmd->keep_alive_seconds); | 140 | IWL_DEBUG_POWER(mvm, "Keep alive = %u sec\n", |
141 | le16_to_cpu(cmd->keep_alive_seconds)); | ||
134 | 142 | ||
135 | if (cmd->flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)) { | 143 | if (cmd->flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)) { |
136 | IWL_DEBUG_POWER(mvm, "Rx timeout = %u usec\n", | 144 | IWL_DEBUG_POWER(mvm, "Rx timeout = %u usec\n", |
@@ -139,15 +147,16 @@ static void iwl_mvm_power_log(struct iwl_mvm *mvm, | |||
139 | le32_to_cpu(cmd->tx_data_timeout)); | 147 | le32_to_cpu(cmd->tx_data_timeout)); |
140 | if (cmd->flags & cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK)) | 148 | if (cmd->flags & cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK)) |
141 | IWL_DEBUG_POWER(mvm, "DTIM periods to skip = %u\n", | 149 | IWL_DEBUG_POWER(mvm, "DTIM periods to skip = %u\n", |
142 | le32_to_cpu(cmd->skip_dtim_periods)); | 150 | cmd->skip_dtim_periods); |
143 | if (cmd->flags & cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK)) | 151 | if (cmd->flags & cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK)) |
144 | IWL_DEBUG_POWER(mvm, "LP RX RSSI threshold = %u\n", | 152 | IWL_DEBUG_POWER(mvm, "LP RX RSSI threshold = %u\n", |
145 | le32_to_cpu(cmd->lprx_rssi_threshold)); | 153 | cmd->lprx_rssi_threshold); |
146 | } | 154 | } |
147 | } | 155 | } |
148 | 156 | ||
149 | void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | 157 | static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, |
150 | struct iwl_powertable_cmd *cmd) | 158 | struct ieee80211_vif *vif, |
159 | struct iwl_mac_power_cmd *cmd) | ||
151 | { | 160 | { |
152 | struct ieee80211_hw *hw = mvm->hw; | 161 | struct ieee80211_hw *hw = mvm->hw; |
153 | struct ieee80211_chanctx_conf *chanctx_conf; | 162 | struct ieee80211_chanctx_conf *chanctx_conf; |
@@ -158,19 +167,26 @@ void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
158 | struct iwl_mvm_vif *mvmvif __maybe_unused = | 167 | struct iwl_mvm_vif *mvmvif __maybe_unused = |
159 | iwl_mvm_vif_from_mac80211(vif); | 168 | iwl_mvm_vif_from_mac80211(vif); |
160 | 169 | ||
170 | cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, | ||
171 | mvmvif->color)); | ||
172 | dtimper = hw->conf.ps_dtim_period ?: 1; | ||
173 | |||
161 | /* | 174 | /* |
162 | * Regardless of power management state the driver must set | 175 | * Regardless of power management state the driver must set |
163 | * keep alive period. FW will use it for sending keep alive NDPs | 176 | * keep alive period. FW will use it for sending keep alive NDPs |
164 | * immediately after association. | 177 | * immediately after association. Check that keep alive period |
178 | * is at least 3 * DTIM | ||
165 | */ | 179 | */ |
166 | cmd->keep_alive_seconds = POWER_KEEP_ALIVE_PERIOD_SEC; | 180 | dtimper_msec = dtimper * vif->bss_conf.beacon_int; |
181 | keep_alive = max_t(int, 3 * dtimper_msec, | ||
182 | MSEC_PER_SEC * POWER_KEEP_ALIVE_PERIOD_SEC); | ||
183 | keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC); | ||
184 | cmd->keep_alive_seconds = cpu_to_le16(keep_alive); | ||
167 | 185 | ||
168 | if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM) | 186 | if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM) |
169 | return; | 187 | return; |
170 | 188 | ||
171 | cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); | 189 | cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); |
172 | if (!vif->bss_conf.assoc) | ||
173 | cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK); | ||
174 | 190 | ||
175 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 191 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
176 | if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_DISABLE_POWER_OFF && | 192 | if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_DISABLE_POWER_OFF && |
@@ -186,12 +202,9 @@ void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
186 | (vif->bss_conf.beacon_rate->bitrate == 10 || | 202 | (vif->bss_conf.beacon_rate->bitrate == 10 || |
187 | vif->bss_conf.beacon_rate->bitrate == 60)) { | 203 | vif->bss_conf.beacon_rate->bitrate == 60)) { |
188 | cmd->flags |= cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK); | 204 | cmd->flags |= cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK); |
189 | cmd->lprx_rssi_threshold = | 205 | cmd->lprx_rssi_threshold = POWER_LPRX_RSSI_THRESHOLD; |
190 | cpu_to_le32(POWER_LPRX_RSSI_THRESHOLD); | ||
191 | } | 206 | } |
192 | 207 | ||
193 | dtimper = hw->conf.ps_dtim_period ?: 1; | ||
194 | |||
195 | /* Check if radar detection is required on current channel */ | 208 | /* Check if radar detection is required on current channel */ |
196 | rcu_read_lock(); | 209 | rcu_read_lock(); |
197 | chanctx_conf = rcu_dereference(vif->chanctx_conf); | 210 | chanctx_conf = rcu_dereference(vif->chanctx_conf); |
@@ -207,27 +220,25 @@ void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
207 | (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP || | 220 | (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP || |
208 | mvm->cur_ucode == IWL_UCODE_WOWLAN)) { | 221 | mvm->cur_ucode == IWL_UCODE_WOWLAN)) { |
209 | cmd->flags |= cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK); | 222 | cmd->flags |= cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK); |
210 | cmd->skip_dtim_periods = cpu_to_le32(3); | 223 | cmd->skip_dtim_periods = 3; |
211 | } | 224 | } |
212 | 225 | ||
213 | /* Check that keep alive period is at least 3 * DTIM */ | ||
214 | dtimper_msec = dtimper * vif->bss_conf.beacon_int; | ||
215 | keep_alive = max_t(int, 3 * dtimper_msec, | ||
216 | MSEC_PER_SEC * cmd->keep_alive_seconds); | ||
217 | keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC); | ||
218 | cmd->keep_alive_seconds = keep_alive; | ||
219 | |||
220 | if (mvm->cur_ucode != IWL_UCODE_WOWLAN) { | 226 | if (mvm->cur_ucode != IWL_UCODE_WOWLAN) { |
221 | cmd->rx_data_timeout = cpu_to_le32(100 * USEC_PER_MSEC); | 227 | cmd->rx_data_timeout = |
222 | cmd->tx_data_timeout = cpu_to_le32(100 * USEC_PER_MSEC); | 228 | cpu_to_le32(IWL_MVM_DEFAULT_PS_RX_DATA_TIMEOUT); |
229 | cmd->tx_data_timeout = | ||
230 | cpu_to_le32(IWL_MVM_DEFAULT_PS_TX_DATA_TIMEOUT); | ||
223 | } else { | 231 | } else { |
224 | cmd->rx_data_timeout = cpu_to_le32(10 * USEC_PER_MSEC); | 232 | cmd->rx_data_timeout = |
225 | cmd->tx_data_timeout = cpu_to_le32(10 * USEC_PER_MSEC); | 233 | cpu_to_le32(IWL_MVM_WOWLAN_PS_RX_DATA_TIMEOUT); |
234 | cmd->tx_data_timeout = | ||
235 | cpu_to_le32(IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT); | ||
226 | } | 236 | } |
227 | 237 | ||
228 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 238 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
229 | if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_KEEP_ALIVE) | 239 | if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_KEEP_ALIVE) |
230 | cmd->keep_alive_seconds = mvmvif->dbgfs_pm.keep_alive_seconds; | 240 | cmd->keep_alive_seconds = |
241 | cpu_to_le16(mvmvif->dbgfs_pm.keep_alive_seconds); | ||
231 | if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_SKIP_OVER_DTIM) { | 242 | if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_SKIP_OVER_DTIM) { |
232 | if (mvmvif->dbgfs_pm.skip_over_dtim) | 243 | if (mvmvif->dbgfs_pm.skip_over_dtim) |
233 | cmd->flags |= | 244 | cmd->flags |= |
@@ -243,8 +254,7 @@ void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
243 | cmd->tx_data_timeout = | 254 | cmd->tx_data_timeout = |
244 | cpu_to_le32(mvmvif->dbgfs_pm.tx_data_timeout); | 255 | cpu_to_le32(mvmvif->dbgfs_pm.tx_data_timeout); |
245 | if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS) | 256 | if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS) |
246 | cmd->skip_dtim_periods = | 257 | cmd->skip_dtim_periods = mvmvif->dbgfs_pm.skip_dtim_periods; |
247 | cpu_to_le32(mvmvif->dbgfs_pm.skip_dtim_periods); | ||
248 | if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_LPRX_ENA) { | 258 | if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_LPRX_ENA) { |
249 | if (mvmvif->dbgfs_pm.lprx_ena) | 259 | if (mvmvif->dbgfs_pm.lprx_ena) |
250 | cmd->flags |= cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK); | 260 | cmd->flags |= cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK); |
@@ -252,16 +262,16 @@ void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
252 | cmd->flags &= cpu_to_le16(~POWER_FLAGS_LPRX_ENA_MSK); | 262 | cmd->flags &= cpu_to_le16(~POWER_FLAGS_LPRX_ENA_MSK); |
253 | } | 263 | } |
254 | if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD) | 264 | if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD) |
255 | cmd->lprx_rssi_threshold = | 265 | cmd->lprx_rssi_threshold = mvmvif->dbgfs_pm.lprx_rssi_threshold; |
256 | cpu_to_le32(mvmvif->dbgfs_pm.lprx_rssi_threshold); | ||
257 | #endif /* CONFIG_IWLWIFI_DEBUGFS */ | 266 | #endif /* CONFIG_IWLWIFI_DEBUGFS */ |
258 | } | 267 | } |
259 | 268 | ||
260 | int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | 269 | static int iwl_mvm_power_mac_update_mode(struct iwl_mvm *mvm, |
270 | struct ieee80211_vif *vif) | ||
261 | { | 271 | { |
262 | int ret; | 272 | int ret; |
263 | bool ba_enable; | 273 | bool ba_enable; |
264 | struct iwl_powertable_cmd cmd = {}; | 274 | struct iwl_mac_power_cmd cmd = {}; |
265 | 275 | ||
266 | if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) | 276 | if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) |
267 | return 0; | 277 | return 0; |
@@ -280,7 +290,7 @@ int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | |||
280 | iwl_mvm_power_build_cmd(mvm, vif, &cmd); | 290 | iwl_mvm_power_build_cmd(mvm, vif, &cmd); |
281 | iwl_mvm_power_log(mvm, &cmd); | 291 | iwl_mvm_power_log(mvm, &cmd); |
282 | 292 | ||
283 | ret = iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_SYNC, | 293 | ret = iwl_mvm_send_cmd_pdu(mvm, MAC_PM_POWER_TABLE, CMD_SYNC, |
284 | sizeof(cmd), &cmd); | 294 | sizeof(cmd), &cmd); |
285 | if (ret) | 295 | if (ret) |
286 | return ret; | 296 | return ret; |
@@ -291,15 +301,19 @@ int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | |||
291 | return iwl_mvm_update_beacon_abort(mvm, vif, ba_enable); | 301 | return iwl_mvm_update_beacon_abort(mvm, vif, ba_enable); |
292 | } | 302 | } |
293 | 303 | ||
294 | int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | 304 | static int iwl_mvm_power_mac_disable(struct iwl_mvm *mvm, |
305 | struct ieee80211_vif *vif) | ||
295 | { | 306 | { |
296 | struct iwl_powertable_cmd cmd = {}; | 307 | struct iwl_mac_power_cmd cmd = {}; |
297 | struct iwl_mvm_vif *mvmvif __maybe_unused = | 308 | struct iwl_mvm_vif *mvmvif __maybe_unused = |
298 | iwl_mvm_vif_from_mac80211(vif); | 309 | iwl_mvm_vif_from_mac80211(vif); |
299 | 310 | ||
300 | if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) | 311 | if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) |
301 | return 0; | 312 | return 0; |
302 | 313 | ||
314 | cmd.id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, | ||
315 | mvmvif->color)); | ||
316 | |||
303 | if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM) | 317 | if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM) |
304 | cmd.flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); | 318 | cmd.flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); |
305 | 319 | ||
@@ -310,11 +324,50 @@ int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | |||
310 | #endif | 324 | #endif |
311 | iwl_mvm_power_log(mvm, &cmd); | 325 | iwl_mvm_power_log(mvm, &cmd); |
312 | 326 | ||
313 | return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_ASYNC, | 327 | return iwl_mvm_send_cmd_pdu(mvm, MAC_PM_POWER_TABLE, CMD_ASYNC, |
314 | sizeof(cmd), &cmd); | 328 | sizeof(cmd), &cmd); |
315 | } | 329 | } |
316 | 330 | ||
317 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 331 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
332 | static int iwl_mvm_power_mac_dbgfs_read(struct iwl_mvm *mvm, | ||
333 | struct ieee80211_vif *vif, char *buf, | ||
334 | int bufsz) | ||
335 | { | ||
336 | struct iwl_mac_power_cmd cmd = {}; | ||
337 | int pos = 0; | ||
338 | |||
339 | iwl_mvm_power_build_cmd(mvm, vif, &cmd); | ||
340 | |||
341 | pos += scnprintf(buf+pos, bufsz-pos, "disable_power_off = %d\n", | ||
342 | (cmd.flags & | ||
343 | cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK)) ? | ||
344 | 0 : 1); | ||
345 | pos += scnprintf(buf+pos, bufsz-pos, "skip_dtim_periods = %d\n", | ||
346 | cmd.skip_dtim_periods); | ||
347 | pos += scnprintf(buf+pos, bufsz-pos, "power_scheme = %d\n", | ||
348 | iwlmvm_mod_params.power_scheme); | ||
349 | pos += scnprintf(buf+pos, bufsz-pos, "flags = 0x%x\n", | ||
350 | le16_to_cpu(cmd.flags)); | ||
351 | pos += scnprintf(buf+pos, bufsz-pos, "keep_alive = %d\n", | ||
352 | le16_to_cpu(cmd.keep_alive_seconds)); | ||
353 | |||
354 | if (cmd.flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)) { | ||
355 | pos += scnprintf(buf+pos, bufsz-pos, "skip_over_dtim = %d\n", | ||
356 | (cmd.flags & | ||
357 | cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK)) ? | ||
358 | 1 : 0); | ||
359 | pos += scnprintf(buf+pos, bufsz-pos, "rx_data_timeout = %d\n", | ||
360 | le32_to_cpu(cmd.rx_data_timeout)); | ||
361 | pos += scnprintf(buf+pos, bufsz-pos, "tx_data_timeout = %d\n", | ||
362 | le32_to_cpu(cmd.tx_data_timeout)); | ||
363 | if (cmd.flags & cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK)) | ||
364 | pos += scnprintf(buf+pos, bufsz-pos, | ||
365 | "lprx_rssi_threshold = %d\n", | ||
366 | cmd.lprx_rssi_threshold); | ||
367 | } | ||
368 | return pos; | ||
369 | } | ||
370 | |||
318 | void | 371 | void |
319 | iwl_mvm_beacon_filter_debugfs_parameters(struct ieee80211_vif *vif, | 372 | iwl_mvm_beacon_filter_debugfs_parameters(struct ieee80211_vif *vif, |
320 | struct iwl_beacon_filter_cmd *cmd) | 373 | struct iwl_beacon_filter_cmd *cmd) |
@@ -323,22 +376,30 @@ iwl_mvm_beacon_filter_debugfs_parameters(struct ieee80211_vif *vif, | |||
323 | struct iwl_dbgfs_bf *dbgfs_bf = &mvmvif->dbgfs_bf; | 376 | struct iwl_dbgfs_bf *dbgfs_bf = &mvmvif->dbgfs_bf; |
324 | 377 | ||
325 | if (dbgfs_bf->mask & MVM_DEBUGFS_BF_ENERGY_DELTA) | 378 | if (dbgfs_bf->mask & MVM_DEBUGFS_BF_ENERGY_DELTA) |
326 | cmd->bf_energy_delta = dbgfs_bf->bf_energy_delta; | 379 | cmd->bf_energy_delta = cpu_to_le32(dbgfs_bf->bf_energy_delta); |
327 | if (dbgfs_bf->mask & MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA) | 380 | if (dbgfs_bf->mask & MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA) |
328 | cmd->bf_roaming_energy_delta = | 381 | cmd->bf_roaming_energy_delta = |
329 | dbgfs_bf->bf_roaming_energy_delta; | 382 | cpu_to_le32(dbgfs_bf->bf_roaming_energy_delta); |
330 | if (dbgfs_bf->mask & MVM_DEBUGFS_BF_ROAMING_STATE) | 383 | if (dbgfs_bf->mask & MVM_DEBUGFS_BF_ROAMING_STATE) |
331 | cmd->bf_roaming_state = dbgfs_bf->bf_roaming_state; | 384 | cmd->bf_roaming_state = cpu_to_le32(dbgfs_bf->bf_roaming_state); |
332 | if (dbgfs_bf->mask & MVM_DEBUGFS_BF_TEMPERATURE_DELTA) | 385 | if (dbgfs_bf->mask & MVM_DEBUGFS_BF_TEMP_THRESHOLD) |
333 | cmd->bf_temperature_delta = dbgfs_bf->bf_temperature_delta; | 386 | cmd->bf_temp_threshold = |
387 | cpu_to_le32(dbgfs_bf->bf_temp_threshold); | ||
388 | if (dbgfs_bf->mask & MVM_DEBUGFS_BF_TEMP_FAST_FILTER) | ||
389 | cmd->bf_temp_fast_filter = | ||
390 | cpu_to_le32(dbgfs_bf->bf_temp_fast_filter); | ||
391 | if (dbgfs_bf->mask & MVM_DEBUGFS_BF_TEMP_SLOW_FILTER) | ||
392 | cmd->bf_temp_slow_filter = | ||
393 | cpu_to_le32(dbgfs_bf->bf_temp_slow_filter); | ||
334 | if (dbgfs_bf->mask & MVM_DEBUGFS_BF_DEBUG_FLAG) | 394 | if (dbgfs_bf->mask & MVM_DEBUGFS_BF_DEBUG_FLAG) |
335 | cmd->bf_debug_flag = dbgfs_bf->bf_debug_flag; | 395 | cmd->bf_debug_flag = cpu_to_le32(dbgfs_bf->bf_debug_flag); |
336 | if (dbgfs_bf->mask & MVM_DEBUGFS_BF_ESCAPE_TIMER) | 396 | if (dbgfs_bf->mask & MVM_DEBUGFS_BF_ESCAPE_TIMER) |
337 | cmd->bf_escape_timer = cpu_to_le32(dbgfs_bf->bf_escape_timer); | 397 | cmd->bf_escape_timer = cpu_to_le32(dbgfs_bf->bf_escape_timer); |
338 | if (dbgfs_bf->mask & MVM_DEBUGFS_BA_ESCAPE_TIMER) | 398 | if (dbgfs_bf->mask & MVM_DEBUGFS_BA_ESCAPE_TIMER) |
339 | cmd->ba_escape_timer = cpu_to_le32(dbgfs_bf->ba_escape_timer); | 399 | cmd->ba_escape_timer = cpu_to_le32(dbgfs_bf->ba_escape_timer); |
340 | if (dbgfs_bf->mask & MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT) | 400 | if (dbgfs_bf->mask & MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT) |
341 | cmd->ba_enable_beacon_abort = dbgfs_bf->ba_enable_beacon_abort; | 401 | cmd->ba_enable_beacon_abort = |
402 | cpu_to_le32(dbgfs_bf->ba_enable_beacon_abort); | ||
342 | } | 403 | } |
343 | #endif | 404 | #endif |
344 | 405 | ||
@@ -348,7 +409,7 @@ int iwl_mvm_enable_beacon_filter(struct iwl_mvm *mvm, | |||
348 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 409 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
349 | struct iwl_beacon_filter_cmd cmd = { | 410 | struct iwl_beacon_filter_cmd cmd = { |
350 | IWL_BF_CMD_CONFIG_DEFAULTS, | 411 | IWL_BF_CMD_CONFIG_DEFAULTS, |
351 | .bf_enable_beacon_filter = 1, | 412 | .bf_enable_beacon_filter = cpu_to_le32(1), |
352 | }; | 413 | }; |
353 | int ret; | 414 | int ret; |
354 | 415 | ||
@@ -372,7 +433,8 @@ int iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm, | |||
372 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 433 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
373 | int ret; | 434 | int ret; |
374 | 435 | ||
375 | if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) | 436 | if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BF_UPDATED) || |
437 | vif->type != NL80211_IFTYPE_STATION || vif->p2p) | ||
376 | return 0; | 438 | return 0; |
377 | 439 | ||
378 | ret = iwl_mvm_beacon_filter_send_cmd(mvm, &cmd); | 440 | ret = iwl_mvm_beacon_filter_send_cmd(mvm, &cmd); |
@@ -382,3 +444,11 @@ int iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm, | |||
382 | 444 | ||
383 | return ret; | 445 | return ret; |
384 | } | 446 | } |
447 | |||
448 | const struct iwl_mvm_power_ops pm_mac_ops = { | ||
449 | .power_update_mode = iwl_mvm_power_mac_update_mode, | ||
450 | .power_disable = iwl_mvm_power_mac_disable, | ||
451 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
452 | .power_dbgfs_read = iwl_mvm_power_mac_dbgfs_read, | ||
453 | #endif | ||
454 | }; | ||