1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
3 * Copyright (C) 2012-2014, 2018-2019 Intel Corporation
4 * Copyright (C) 2013-2014 Intel Mobile Communications GmbH
5 * Copyright (C) 2015-2017 Intel Deutschland GmbH
7 #include <linux/kernel.h>
8 #include <linux/module.h>
9 #include <linux/slab.h>
10 #include <linux/etherdevice.h>
12 #include <net/mac80211.h>
14 #include "iwl-debug.h"
16 #include "iwl-modparams.h"
17 #include "fw/api/power.h"
19 #define POWER_KEEP_ALIVE_PERIOD_SEC 25
22 int iwl_mvm_beacon_filter_send_cmd(struct iwl_mvm
*mvm
,
23 struct iwl_beacon_filter_cmd
*cmd
,
28 IWL_DEBUG_POWER(mvm
, "ba_enable_beacon_abort is: %d\n",
29 le32_to_cpu(cmd
->ba_enable_beacon_abort
));
30 IWL_DEBUG_POWER(mvm
, "ba_escape_timer is: %d\n",
31 le32_to_cpu(cmd
->ba_escape_timer
));
32 IWL_DEBUG_POWER(mvm
, "bf_debug_flag is: %d\n",
33 le32_to_cpu(cmd
->bf_debug_flag
));
34 IWL_DEBUG_POWER(mvm
, "bf_enable_beacon_filter is: %d\n",
35 le32_to_cpu(cmd
->bf_enable_beacon_filter
));
36 IWL_DEBUG_POWER(mvm
, "bf_energy_delta is: %d\n",
37 le32_to_cpu(cmd
->bf_energy_delta
));
38 IWL_DEBUG_POWER(mvm
, "bf_escape_timer is: %d\n",
39 le32_to_cpu(cmd
->bf_escape_timer
));
40 IWL_DEBUG_POWER(mvm
, "bf_roaming_energy_delta is: %d\n",
41 le32_to_cpu(cmd
->bf_roaming_energy_delta
));
42 IWL_DEBUG_POWER(mvm
, "bf_roaming_state is: %d\n",
43 le32_to_cpu(cmd
->bf_roaming_state
));
44 IWL_DEBUG_POWER(mvm
, "bf_temp_threshold is: %d\n",
45 le32_to_cpu(cmd
->bf_temp_threshold
));
46 IWL_DEBUG_POWER(mvm
, "bf_temp_fast_filter is: %d\n",
47 le32_to_cpu(cmd
->bf_temp_fast_filter
));
48 IWL_DEBUG_POWER(mvm
, "bf_temp_slow_filter is: %d\n",
49 le32_to_cpu(cmd
->bf_temp_slow_filter
));
50 IWL_DEBUG_POWER(mvm
, "bf_threshold_absolute_low is: %d, %d\n",
51 le32_to_cpu(cmd
->bf_threshold_absolute_low
[0]),
52 le32_to_cpu(cmd
->bf_threshold_absolute_low
[1]));
54 IWL_DEBUG_POWER(mvm
, "bf_threshold_absolute_high is: %d, %d\n",
55 le32_to_cpu(cmd
->bf_threshold_absolute_high
[0]),
56 le32_to_cpu(cmd
->bf_threshold_absolute_high
[1]));
58 if (fw_has_api(&mvm
->fw
->ucode_capa
,
59 IWL_UCODE_TLV_API_BEACON_FILTER_V4
))
60 len
= sizeof(struct iwl_beacon_filter_cmd
);
62 len
= offsetof(struct iwl_beacon_filter_cmd
,
63 bf_threshold_absolute_low
);
65 return iwl_mvm_send_cmd_pdu(mvm
, REPLY_BEACON_FILTERING_CMD
, flags
,
70 void iwl_mvm_beacon_filter_set_cqm_params(struct iwl_mvm
*mvm
,
71 struct ieee80211_vif
*vif
,
72 struct iwl_beacon_filter_cmd
*cmd
)
74 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
76 if (vif
->bss_conf
.cqm_rssi_thold
) {
77 cmd
->bf_energy_delta
=
78 cpu_to_le32(vif
->bss_conf
.cqm_rssi_hyst
);
79 /* fw uses an absolute value for this */
80 cmd
->bf_roaming_state
=
81 cpu_to_le32(-vif
->bss_conf
.cqm_rssi_thold
);
83 cmd
->ba_enable_beacon_abort
= cpu_to_le32(mvmvif
->bf_data
.ba_enabled
);
86 static void iwl_mvm_power_log(struct iwl_mvm
*mvm
,
87 struct iwl_mac_power_cmd
*cmd
)
90 "Sending power table command on mac id 0x%X for power level %d, flags = 0x%X\n",
91 cmd
->id_and_color
, iwlmvm_mod_params
.power_scheme
,
92 le16_to_cpu(cmd
->flags
));
93 IWL_DEBUG_POWER(mvm
, "Keep alive = %u sec\n",
94 le16_to_cpu(cmd
->keep_alive_seconds
));
96 if (!(cmd
->flags
& cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK
))) {
97 IWL_DEBUG_POWER(mvm
, "Disable power management\n");
101 IWL_DEBUG_POWER(mvm
, "Rx timeout = %u usec\n",
102 le32_to_cpu(cmd
->rx_data_timeout
));
103 IWL_DEBUG_POWER(mvm
, "Tx timeout = %u usec\n",
104 le32_to_cpu(cmd
->tx_data_timeout
));
105 if (cmd
->flags
& cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK
))
106 IWL_DEBUG_POWER(mvm
, "DTIM periods to skip = %u\n",
107 cmd
->skip_dtim_periods
);
108 if (cmd
->flags
& cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK
))
109 IWL_DEBUG_POWER(mvm
, "LP RX RSSI threshold = %u\n",
110 cmd
->lprx_rssi_threshold
);
111 if (cmd
->flags
& cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK
)) {
112 IWL_DEBUG_POWER(mvm
, "uAPSD enabled\n");
113 IWL_DEBUG_POWER(mvm
, "Rx timeout (uAPSD) = %u usec\n",
114 le32_to_cpu(cmd
->rx_data_timeout_uapsd
));
115 IWL_DEBUG_POWER(mvm
, "Tx timeout (uAPSD) = %u usec\n",
116 le32_to_cpu(cmd
->tx_data_timeout_uapsd
));
117 IWL_DEBUG_POWER(mvm
, "QNDP TID = %d\n", cmd
->qndp_tid
);
118 IWL_DEBUG_POWER(mvm
, "ACs flags = 0x%x\n", cmd
->uapsd_ac_flags
);
119 IWL_DEBUG_POWER(mvm
, "Max SP = %d\n", cmd
->uapsd_max_sp
);
123 static void iwl_mvm_power_configure_uapsd(struct iwl_mvm
*mvm
,
124 struct ieee80211_vif
*vif
,
125 struct iwl_mac_power_cmd
*cmd
)
127 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
128 enum ieee80211_ac_numbers ac
;
129 bool tid_found
= false;
131 #ifdef CONFIG_IWLWIFI_DEBUGFS
132 /* set advanced pm flag with no uapsd ACs to enable ps-poll */
133 if (mvmvif
->dbgfs_pm
.use_ps_poll
) {
134 cmd
->flags
|= cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK
);
139 for (ac
= IEEE80211_AC_VO
; ac
<= IEEE80211_AC_BK
; ac
++) {
140 if (!mvmvif
->queue_params
[ac
].uapsd
)
143 if (!test_bit(IWL_MVM_STATUS_IN_D3
, &mvm
->status
))
145 cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK
);
147 cmd
->uapsd_ac_flags
|= BIT(ac
);
149 /* QNDP TID - the highest TID with no admission control */
150 if (!tid_found
&& !mvmvif
->queue_params
[ac
].acm
) {
153 case IEEE80211_AC_VO
:
156 case IEEE80211_AC_VI
:
159 case IEEE80211_AC_BE
:
162 case IEEE80211_AC_BK
:
169 cmd
->flags
|= cpu_to_le16(POWER_FLAGS_UAPSD_MISBEHAVING_ENA_MSK
);
171 if (cmd
->uapsd_ac_flags
== (BIT(IEEE80211_AC_VO
) |
172 BIT(IEEE80211_AC_VI
) |
173 BIT(IEEE80211_AC_BE
) |
174 BIT(IEEE80211_AC_BK
))) {
175 cmd
->flags
|= cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK
);
176 cmd
->snooze_interval
= cpu_to_le16(IWL_MVM_PS_SNOOZE_INTERVAL
);
178 test_bit(IWL_MVM_STATUS_IN_D3
, &mvm
->status
) ?
179 cpu_to_le16(IWL_MVM_WOWLAN_PS_SNOOZE_WINDOW
) :
180 cpu_to_le16(IWL_MVM_PS_SNOOZE_WINDOW
);
183 cmd
->uapsd_max_sp
= mvm
->hw
->uapsd_max_sp_len
;
185 if (test_bit(IWL_MVM_STATUS_IN_D3
, &mvm
->status
) ||
186 cmd
->flags
& cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK
)) {
187 cmd
->rx_data_timeout_uapsd
=
188 cpu_to_le32(IWL_MVM_WOWLAN_PS_RX_DATA_TIMEOUT
);
189 cmd
->tx_data_timeout_uapsd
=
190 cpu_to_le32(IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT
);
192 cmd
->rx_data_timeout_uapsd
=
193 cpu_to_le32(IWL_MVM_UAPSD_RX_DATA_TIMEOUT
);
194 cmd
->tx_data_timeout_uapsd
=
195 cpu_to_le32(IWL_MVM_UAPSD_TX_DATA_TIMEOUT
);
198 if (cmd
->flags
& cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK
)) {
199 cmd
->heavy_tx_thld_packets
=
200 IWL_MVM_PS_SNOOZE_HEAVY_TX_THLD_PACKETS
;
201 cmd
->heavy_rx_thld_packets
=
202 IWL_MVM_PS_SNOOZE_HEAVY_RX_THLD_PACKETS
;
204 cmd
->heavy_tx_thld_packets
=
205 IWL_MVM_PS_HEAVY_TX_THLD_PACKETS
;
206 cmd
->heavy_rx_thld_packets
=
207 IWL_MVM_PS_HEAVY_RX_THLD_PACKETS
;
209 cmd
->heavy_tx_thld_percentage
=
210 IWL_MVM_PS_HEAVY_TX_THLD_PERCENT
;
211 cmd
->heavy_rx_thld_percentage
=
212 IWL_MVM_PS_HEAVY_RX_THLD_PERCENT
;
215 static void iwl_mvm_p2p_standalone_iterator(void *_data
, u8
*mac
,
216 struct ieee80211_vif
*vif
)
218 bool *is_p2p_standalone
= _data
;
220 switch (ieee80211_vif_type_p2p(vif
)) {
221 case NL80211_IFTYPE_P2P_GO
:
222 case NL80211_IFTYPE_AP
:
223 *is_p2p_standalone
= false;
225 case NL80211_IFTYPE_STATION
:
226 if (vif
->bss_conf
.assoc
)
227 *is_p2p_standalone
= false;
235 static bool iwl_mvm_power_allow_uapsd(struct iwl_mvm
*mvm
,
236 struct ieee80211_vif
*vif
)
238 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
240 if (!memcmp(mvmvif
->uapsd_misbehaving_bssid
, vif
->bss_conf
.bssid
,
245 * Avoid using uAPSD if P2P client is associated to GO that uses
246 * opportunistic power save. This is due to current FW limitation.
249 (vif
->bss_conf
.p2p_noa_attr
.oppps_ctwindow
&
250 IEEE80211_P2P_OPPPS_ENABLE_BIT
))
254 * Avoid using uAPSD if client is in DCM -
255 * low latency issue in Miracast
257 if (iwl_mvm_phy_ctx_count(mvm
) >= 2)
261 /* Allow U-APSD only if p2p is stand alone */
262 bool is_p2p_standalone
= true;
264 if (!iwl_mvm_is_p2p_scm_uapsd_supported(mvm
))
267 ieee80211_iterate_active_interfaces_atomic(mvm
->hw
,
268 IEEE80211_IFACE_ITER_NORMAL
,
269 iwl_mvm_p2p_standalone_iterator
,
272 if (!is_p2p_standalone
)
279 static bool iwl_mvm_power_is_radar(struct ieee80211_vif
*vif
)
281 struct ieee80211_chanctx_conf
*chanctx_conf
;
282 struct ieee80211_channel
*chan
;
283 bool radar_detect
= false;
286 chanctx_conf
= rcu_dereference(vif
->chanctx_conf
);
287 WARN_ON(!chanctx_conf
);
289 chan
= chanctx_conf
->def
.chan
;
290 radar_detect
= chan
->flags
& IEEE80211_CHAN_RADAR
;
297 static void iwl_mvm_power_config_skip_dtim(struct iwl_mvm
*mvm
,
298 struct ieee80211_vif
*vif
,
299 struct iwl_mac_power_cmd
*cmd
)
301 int dtimper
= vif
->bss_conf
.dtim_period
?: 1;
304 /* disable, in case we're supposed to override */
305 cmd
->skip_dtim_periods
= 0;
306 cmd
->flags
&= ~cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK
);
308 if (iwl_mvm_power_is_radar(vif
))
314 if (!test_bit(IWL_MVM_STATUS_IN_D3
, &mvm
->status
)) {
315 if (iwlmvm_mod_params
.power_scheme
!= IWL_POWER_SCHEME_LP
)
319 int dtimper_tu
= dtimper
* vif
->bss_conf
.beacon_int
;
321 if (WARN_ON(!dtimper_tu
))
323 /* configure skip over dtim up to 306TU - 314 msec */
324 skip
= max_t(u8
, 1, 306 / dtimper_tu
);
327 /* the firmware really expects "look at every X DTIMs", so add 1 */
328 cmd
->skip_dtim_periods
= 1 + skip
;
329 cmd
->flags
|= cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK
);
332 static void iwl_mvm_power_build_cmd(struct iwl_mvm
*mvm
,
333 struct ieee80211_vif
*vif
,
334 struct iwl_mac_power_cmd
*cmd
)
338 struct iwl_mvm_vif
*mvmvif __maybe_unused
=
339 iwl_mvm_vif_from_mac80211(vif
);
341 cmd
->id_and_color
= cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif
->id
,
343 dtimper
= vif
->bss_conf
.dtim_period
;
344 bi
= vif
->bss_conf
.beacon_int
;
347 * Regardless of power management state the driver must set
348 * keep alive period. FW will use it for sending keep alive NDPs
349 * immediately after association. Check that keep alive period
350 * is at least 3 * DTIM
352 keep_alive
= DIV_ROUND_UP(ieee80211_tu_to_usec(3 * dtimper
* bi
),
354 keep_alive
= max(keep_alive
, POWER_KEEP_ALIVE_PERIOD_SEC
);
355 cmd
->keep_alive_seconds
= cpu_to_le16(keep_alive
);
357 if (mvm
->ps_disabled
)
360 cmd
->flags
|= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK
);
362 if (!vif
->bss_conf
.ps
|| !mvmvif
->pm_enabled
)
365 if (iwl_mvm_vif_low_latency(mvmvif
) && vif
->p2p
&&
366 (!fw_has_capa(&mvm
->fw
->ucode_capa
,
367 IWL_UCODE_TLV_CAPA_SHORT_PM_TIMEOUTS
) ||
368 !IWL_MVM_P2P_LOWLATENCY_PS_ENABLE
))
371 cmd
->flags
|= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK
);
373 if (vif
->bss_conf
.beacon_rate
&&
374 (vif
->bss_conf
.beacon_rate
->bitrate
== 10 ||
375 vif
->bss_conf
.beacon_rate
->bitrate
== 60)) {
376 cmd
->flags
|= cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK
);
377 cmd
->lprx_rssi_threshold
= POWER_LPRX_RSSI_THRESHOLD
;
380 iwl_mvm_power_config_skip_dtim(mvm
, vif
, cmd
);
382 if (test_bit(IWL_MVM_STATUS_IN_D3
, &mvm
->status
)) {
383 cmd
->rx_data_timeout
=
384 cpu_to_le32(IWL_MVM_WOWLAN_PS_RX_DATA_TIMEOUT
);
385 cmd
->tx_data_timeout
=
386 cpu_to_le32(IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT
);
387 } else if (iwl_mvm_vif_low_latency(mvmvif
) && vif
->p2p
&&
388 fw_has_capa(&mvm
->fw
->ucode_capa
,
389 IWL_UCODE_TLV_CAPA_SHORT_PM_TIMEOUTS
)) {
390 cmd
->tx_data_timeout
=
391 cpu_to_le32(IWL_MVM_SHORT_PS_TX_DATA_TIMEOUT
);
392 cmd
->rx_data_timeout
=
393 cpu_to_le32(IWL_MVM_SHORT_PS_RX_DATA_TIMEOUT
);
395 cmd
->rx_data_timeout
=
396 cpu_to_le32(IWL_MVM_DEFAULT_PS_RX_DATA_TIMEOUT
);
397 cmd
->tx_data_timeout
=
398 cpu_to_le32(IWL_MVM_DEFAULT_PS_TX_DATA_TIMEOUT
);
401 if (iwl_mvm_power_allow_uapsd(mvm
, vif
))
402 iwl_mvm_power_configure_uapsd(mvm
, vif
, cmd
);
404 #ifdef CONFIG_IWLWIFI_DEBUGFS
405 if (mvmvif
->dbgfs_pm
.mask
& MVM_DEBUGFS_PM_KEEP_ALIVE
)
406 cmd
->keep_alive_seconds
=
407 cpu_to_le16(mvmvif
->dbgfs_pm
.keep_alive_seconds
);
408 if (mvmvif
->dbgfs_pm
.mask
& MVM_DEBUGFS_PM_SKIP_OVER_DTIM
) {
409 if (mvmvif
->dbgfs_pm
.skip_over_dtim
)
411 cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK
);
414 cpu_to_le16(~POWER_FLAGS_SKIP_OVER_DTIM_MSK
);
416 if (mvmvif
->dbgfs_pm
.mask
& MVM_DEBUGFS_PM_RX_DATA_TIMEOUT
)
417 cmd
->rx_data_timeout
=
418 cpu_to_le32(mvmvif
->dbgfs_pm
.rx_data_timeout
);
419 if (mvmvif
->dbgfs_pm
.mask
& MVM_DEBUGFS_PM_TX_DATA_TIMEOUT
)
420 cmd
->tx_data_timeout
=
421 cpu_to_le32(mvmvif
->dbgfs_pm
.tx_data_timeout
);
422 if (mvmvif
->dbgfs_pm
.mask
& MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS
)
423 cmd
->skip_dtim_periods
= mvmvif
->dbgfs_pm
.skip_dtim_periods
;
424 if (mvmvif
->dbgfs_pm
.mask
& MVM_DEBUGFS_PM_LPRX_ENA
) {
425 if (mvmvif
->dbgfs_pm
.lprx_ena
)
426 cmd
->flags
|= cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK
);
428 cmd
->flags
&= cpu_to_le16(~POWER_FLAGS_LPRX_ENA_MSK
);
430 if (mvmvif
->dbgfs_pm
.mask
& MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD
)
431 cmd
->lprx_rssi_threshold
= mvmvif
->dbgfs_pm
.lprx_rssi_threshold
;
432 if (mvmvif
->dbgfs_pm
.mask
& MVM_DEBUGFS_PM_SNOOZE_ENABLE
) {
433 if (mvmvif
->dbgfs_pm
.snooze_ena
)
435 cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK
);
438 cpu_to_le16(~POWER_FLAGS_SNOOZE_ENA_MSK
);
440 if (mvmvif
->dbgfs_pm
.mask
& MVM_DEBUGFS_PM_UAPSD_MISBEHAVING
) {
441 u16 flag
= POWER_FLAGS_UAPSD_MISBEHAVING_ENA_MSK
;
442 if (mvmvif
->dbgfs_pm
.uapsd_misbehaving
)
443 cmd
->flags
|= cpu_to_le16(flag
);
445 cmd
->flags
&= cpu_to_le16(flag
);
447 #endif /* CONFIG_IWLWIFI_DEBUGFS */
450 static int iwl_mvm_power_send_cmd(struct iwl_mvm
*mvm
,
451 struct ieee80211_vif
*vif
)
453 struct iwl_mac_power_cmd cmd
= {};
455 iwl_mvm_power_build_cmd(mvm
, vif
, &cmd
);
456 iwl_mvm_power_log(mvm
, &cmd
);
457 #ifdef CONFIG_IWLWIFI_DEBUGFS
458 memcpy(&iwl_mvm_vif_from_mac80211(vif
)->mac_pwr_cmd
, &cmd
, sizeof(cmd
));
461 return iwl_mvm_send_cmd_pdu(mvm
, MAC_PM_POWER_TABLE
, 0,
465 int iwl_mvm_power_update_device(struct iwl_mvm
*mvm
)
467 struct iwl_device_power_cmd cmd
= {
471 if (iwlmvm_mod_params
.power_scheme
== IWL_POWER_SCHEME_CAM
)
472 mvm
->ps_disabled
= true;
474 if (!mvm
->ps_disabled
)
475 cmd
.flags
|= cpu_to_le16(DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK
);
477 #ifdef CONFIG_IWLWIFI_DEBUGFS
478 if (test_bit(IWL_MVM_STATUS_IN_D3
, &mvm
->status
) ?
479 mvm
->disable_power_off_d3
: mvm
->disable_power_off
)
481 cpu_to_le16(~DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK
);
483 if (mvm
->ext_clock_valid
)
484 cmd
.flags
|= cpu_to_le16(DEVICE_POWER_FLAGS_32K_CLK_VALID_MSK
);
487 "Sending device power command with flags = 0x%X\n",
490 return iwl_mvm_send_cmd_pdu(mvm
, POWER_TABLE_CMD
, 0, sizeof(cmd
),
494 void iwl_mvm_power_vif_assoc(struct iwl_mvm
*mvm
, struct ieee80211_vif
*vif
)
496 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
498 if (memcmp(vif
->bss_conf
.bssid
, mvmvif
->uapsd_misbehaving_bssid
,
500 eth_zero_addr(mvmvif
->uapsd_misbehaving_bssid
);
503 static void iwl_mvm_power_uapsd_misbehav_ap_iterator(void *_data
, u8
*mac
,
504 struct ieee80211_vif
*vif
)
506 u8
*ap_sta_id
= _data
;
507 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
509 /* The ap_sta_id is not expected to change during current association
510 * so no explicit protection is needed
512 if (mvmvif
->ap_sta_id
== *ap_sta_id
)
513 memcpy(mvmvif
->uapsd_misbehaving_bssid
, vif
->bss_conf
.bssid
,
517 void iwl_mvm_power_uapsd_misbehaving_ap_notif(struct iwl_mvm
*mvm
,
518 struct iwl_rx_cmd_buffer
*rxb
)
520 struct iwl_rx_packet
*pkt
= rxb_addr(rxb
);
521 struct iwl_uapsd_misbehaving_ap_notif
*notif
= (void *)pkt
->data
;
522 u8 ap_sta_id
= le32_to_cpu(notif
->sta_id
);
524 ieee80211_iterate_active_interfaces_atomic(
525 mvm
->hw
, IEEE80211_IFACE_ITER_NORMAL
,
526 iwl_mvm_power_uapsd_misbehav_ap_iterator
, &ap_sta_id
);
529 struct iwl_power_vifs
{
531 struct ieee80211_vif
*bss_vif
;
532 struct ieee80211_vif
*p2p_vif
;
533 struct ieee80211_vif
*ap_vif
;
534 struct ieee80211_vif
*monitor_vif
;
541 static void iwl_mvm_power_disable_pm_iterator(void *_data
, u8
* mac
,
542 struct ieee80211_vif
*vif
)
544 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
546 mvmvif
->pm_enabled
= false;
549 static void iwl_mvm_power_ps_disabled_iterator(void *_data
, u8
* mac
,
550 struct ieee80211_vif
*vif
)
552 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
553 bool *disable_ps
= _data
;
555 if (mvmvif
->phy_ctxt
&& mvmvif
->phy_ctxt
->id
< NUM_PHY_CTX
)
556 *disable_ps
|= mvmvif
->ps_disabled
;
559 static void iwl_mvm_power_get_vifs_iterator(void *_data
, u8
*mac
,
560 struct ieee80211_vif
*vif
)
562 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
563 struct iwl_power_vifs
*power_iterator
= _data
;
564 bool active
= mvmvif
->phy_ctxt
&& mvmvif
->phy_ctxt
->id
< NUM_PHY_CTX
;
566 switch (ieee80211_vif_type_p2p(vif
)) {
567 case NL80211_IFTYPE_P2P_DEVICE
:
570 case NL80211_IFTYPE_P2P_GO
:
571 case NL80211_IFTYPE_AP
:
572 /* only a single MAC of the same type */
573 WARN_ON(power_iterator
->ap_vif
);
574 power_iterator
->ap_vif
= vif
;
576 power_iterator
->ap_active
= true;
579 case NL80211_IFTYPE_MONITOR
:
580 /* only a single MAC of the same type */
581 WARN_ON(power_iterator
->monitor_vif
);
582 power_iterator
->monitor_vif
= vif
;
584 power_iterator
->monitor_active
= true;
587 case NL80211_IFTYPE_P2P_CLIENT
:
588 /* only a single MAC of the same type */
589 WARN_ON(power_iterator
->p2p_vif
);
590 power_iterator
->p2p_vif
= vif
;
592 power_iterator
->p2p_active
= true;
595 case NL80211_IFTYPE_STATION
:
596 power_iterator
->bss_vif
= vif
;
598 power_iterator
->bss_active
= true;
606 static void iwl_mvm_power_set_pm(struct iwl_mvm
*mvm
,
607 struct iwl_power_vifs
*vifs
)
609 struct iwl_mvm_vif
*bss_mvmvif
= NULL
;
610 struct iwl_mvm_vif
*p2p_mvmvif
= NULL
;
611 struct iwl_mvm_vif
*ap_mvmvif
= NULL
;
612 bool client_same_channel
= false;
613 bool ap_same_channel
= false;
615 lockdep_assert_held(&mvm
->mutex
);
617 /* set pm_enable to false */
618 ieee80211_iterate_active_interfaces_atomic(mvm
->hw
,
619 IEEE80211_IFACE_ITER_NORMAL
,
620 iwl_mvm_power_disable_pm_iterator
,
624 bss_mvmvif
= iwl_mvm_vif_from_mac80211(vifs
->bss_vif
);
627 p2p_mvmvif
= iwl_mvm_vif_from_mac80211(vifs
->p2p_vif
);
630 ap_mvmvif
= iwl_mvm_vif_from_mac80211(vifs
->ap_vif
);
632 /* don't allow PM if any TDLS stations exist */
633 if (iwl_mvm_tdls_sta_count(mvm
, NULL
))
636 /* enable PM on bss if bss stand alone */
637 if (vifs
->bss_active
&& !vifs
->p2p_active
&& !vifs
->ap_active
) {
638 bss_mvmvif
->pm_enabled
= true;
642 /* enable PM on p2p if p2p stand alone */
643 if (vifs
->p2p_active
&& !vifs
->bss_active
&& !vifs
->ap_active
) {
644 p2p_mvmvif
->pm_enabled
= true;
648 if (vifs
->bss_active
&& vifs
->p2p_active
)
649 client_same_channel
= (bss_mvmvif
->phy_ctxt
->id
==
650 p2p_mvmvif
->phy_ctxt
->id
);
651 if (vifs
->bss_active
&& vifs
->ap_active
)
652 ap_same_channel
= (bss_mvmvif
->phy_ctxt
->id
==
653 ap_mvmvif
->phy_ctxt
->id
);
655 /* clients are not stand alone: enable PM if DCM */
656 if (!(client_same_channel
|| ap_same_channel
)) {
657 if (vifs
->bss_active
)
658 bss_mvmvif
->pm_enabled
= true;
659 if (vifs
->p2p_active
)
660 p2p_mvmvif
->pm_enabled
= true;
665 * There is only one channel in the system and there are only
666 * bss and p2p clients that share it
668 if (client_same_channel
&& !vifs
->ap_active
) {
669 /* share same channel*/
670 bss_mvmvif
->pm_enabled
= true;
671 p2p_mvmvif
->pm_enabled
= true;
675 #ifdef CONFIG_IWLWIFI_DEBUGFS
676 int iwl_mvm_power_mac_dbgfs_read(struct iwl_mvm
*mvm
,
677 struct ieee80211_vif
*vif
, char *buf
,
680 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
681 struct iwl_mac_power_cmd cmd
= {};
684 mutex_lock(&mvm
->mutex
);
685 memcpy(&cmd
, &mvmvif
->mac_pwr_cmd
, sizeof(cmd
));
686 mutex_unlock(&mvm
->mutex
);
688 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "power_scheme = %d\n",
689 iwlmvm_mod_params
.power_scheme
);
690 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "flags = 0x%x\n",
691 le16_to_cpu(cmd
.flags
));
692 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "keep_alive = %d\n",
693 le16_to_cpu(cmd
.keep_alive_seconds
));
695 if (!(cmd
.flags
& cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK
)))
698 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "skip_over_dtim = %d\n",
700 cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK
)) ? 1 : 0);
701 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "skip_dtim_periods = %d\n",
702 cmd
.skip_dtim_periods
);
703 if (!(cmd
.flags
& cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK
))) {
704 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "rx_data_timeout = %d\n",
705 le32_to_cpu(cmd
.rx_data_timeout
));
706 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "tx_data_timeout = %d\n",
707 le32_to_cpu(cmd
.tx_data_timeout
));
709 if (cmd
.flags
& cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK
))
710 pos
+= scnprintf(buf
+pos
, bufsz
-pos
,
711 "lprx_rssi_threshold = %d\n",
712 cmd
.lprx_rssi_threshold
);
714 if (!(cmd
.flags
& cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK
)))
717 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "rx_data_timeout_uapsd = %d\n",
718 le32_to_cpu(cmd
.rx_data_timeout_uapsd
));
719 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "tx_data_timeout_uapsd = %d\n",
720 le32_to_cpu(cmd
.tx_data_timeout_uapsd
));
721 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "qndp_tid = %d\n", cmd
.qndp_tid
);
722 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "uapsd_ac_flags = 0x%x\n",
724 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "uapsd_max_sp = %d\n",
726 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "heavy_tx_thld_packets = %d\n",
727 cmd
.heavy_tx_thld_packets
);
728 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "heavy_rx_thld_packets = %d\n",
729 cmd
.heavy_rx_thld_packets
);
730 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "heavy_tx_thld_percentage = %d\n",
731 cmd
.heavy_tx_thld_percentage
);
732 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "heavy_rx_thld_percentage = %d\n",
733 cmd
.heavy_rx_thld_percentage
);
734 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "uapsd_misbehaving_enable = %d\n",
736 cpu_to_le16(POWER_FLAGS_UAPSD_MISBEHAVING_ENA_MSK
)) ?
739 if (!(cmd
.flags
& cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK
)))
742 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "snooze_interval = %d\n",
743 cmd
.snooze_interval
);
744 pos
+= scnprintf(buf
+pos
, bufsz
-pos
, "snooze_window = %d\n",
751 iwl_mvm_beacon_filter_debugfs_parameters(struct ieee80211_vif
*vif
,
752 struct iwl_beacon_filter_cmd
*cmd
)
754 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
755 struct iwl_dbgfs_bf
*dbgfs_bf
= &mvmvif
->dbgfs_bf
;
757 if (dbgfs_bf
->mask
& MVM_DEBUGFS_BF_ENERGY_DELTA
)
758 cmd
->bf_energy_delta
= cpu_to_le32(dbgfs_bf
->bf_energy_delta
);
759 if (dbgfs_bf
->mask
& MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA
)
760 cmd
->bf_roaming_energy_delta
=
761 cpu_to_le32(dbgfs_bf
->bf_roaming_energy_delta
);
762 if (dbgfs_bf
->mask
& MVM_DEBUGFS_BF_ROAMING_STATE
)
763 cmd
->bf_roaming_state
= cpu_to_le32(dbgfs_bf
->bf_roaming_state
);
764 if (dbgfs_bf
->mask
& MVM_DEBUGFS_BF_TEMP_THRESHOLD
)
765 cmd
->bf_temp_threshold
=
766 cpu_to_le32(dbgfs_bf
->bf_temp_threshold
);
767 if (dbgfs_bf
->mask
& MVM_DEBUGFS_BF_TEMP_FAST_FILTER
)
768 cmd
->bf_temp_fast_filter
=
769 cpu_to_le32(dbgfs_bf
->bf_temp_fast_filter
);
770 if (dbgfs_bf
->mask
& MVM_DEBUGFS_BF_TEMP_SLOW_FILTER
)
771 cmd
->bf_temp_slow_filter
=
772 cpu_to_le32(dbgfs_bf
->bf_temp_slow_filter
);
773 if (dbgfs_bf
->mask
& MVM_DEBUGFS_BF_DEBUG_FLAG
)
774 cmd
->bf_debug_flag
= cpu_to_le32(dbgfs_bf
->bf_debug_flag
);
775 if (dbgfs_bf
->mask
& MVM_DEBUGFS_BF_ESCAPE_TIMER
)
776 cmd
->bf_escape_timer
= cpu_to_le32(dbgfs_bf
->bf_escape_timer
);
777 if (dbgfs_bf
->mask
& MVM_DEBUGFS_BA_ESCAPE_TIMER
)
778 cmd
->ba_escape_timer
= cpu_to_le32(dbgfs_bf
->ba_escape_timer
);
779 if (dbgfs_bf
->mask
& MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT
)
780 cmd
->ba_enable_beacon_abort
=
781 cpu_to_le32(dbgfs_bf
->ba_enable_beacon_abort
);
785 static int _iwl_mvm_enable_beacon_filter(struct iwl_mvm
*mvm
,
786 struct ieee80211_vif
*vif
,
787 struct iwl_beacon_filter_cmd
*cmd
,
790 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
793 if (mvmvif
!= mvm
->bf_allowed_vif
|| !vif
->bss_conf
.dtim_period
||
794 vif
->type
!= NL80211_IFTYPE_STATION
|| vif
->p2p
)
797 iwl_mvm_beacon_filter_set_cqm_params(mvm
, vif
, cmd
);
798 iwl_mvm_beacon_filter_debugfs_parameters(vif
, cmd
);
799 ret
= iwl_mvm_beacon_filter_send_cmd(mvm
, cmd
, cmd_flags
);
802 mvmvif
->bf_data
.bf_enabled
= true;
807 int iwl_mvm_enable_beacon_filter(struct iwl_mvm
*mvm
,
808 struct ieee80211_vif
*vif
,
811 struct iwl_beacon_filter_cmd cmd
= {
812 IWL_BF_CMD_CONFIG_DEFAULTS
,
813 .bf_enable_beacon_filter
= cpu_to_le32(1),
816 return _iwl_mvm_enable_beacon_filter(mvm
, vif
, &cmd
, flags
);
819 static int _iwl_mvm_disable_beacon_filter(struct iwl_mvm
*mvm
,
820 struct ieee80211_vif
*vif
,
823 struct iwl_beacon_filter_cmd cmd
= {};
824 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
827 if (vif
->type
!= NL80211_IFTYPE_STATION
|| vif
->p2p
)
830 ret
= iwl_mvm_beacon_filter_send_cmd(mvm
, &cmd
, flags
);
833 mvmvif
->bf_data
.bf_enabled
= false;
838 int iwl_mvm_disable_beacon_filter(struct iwl_mvm
*mvm
,
839 struct ieee80211_vif
*vif
,
842 return _iwl_mvm_disable_beacon_filter(mvm
, vif
, flags
);
845 static int iwl_mvm_power_set_ps(struct iwl_mvm
*mvm
)
850 /* disable PS if CAM */
851 disable_ps
= (iwlmvm_mod_params
.power_scheme
== IWL_POWER_SCHEME_CAM
);
852 /* ...or if any of the vifs require PS to be off */
853 ieee80211_iterate_active_interfaces_atomic(mvm
->hw
,
854 IEEE80211_IFACE_ITER_NORMAL
,
855 iwl_mvm_power_ps_disabled_iterator
,
858 /* update device power state if it has changed */
859 if (mvm
->ps_disabled
!= disable_ps
) {
860 bool old_ps_disabled
= mvm
->ps_disabled
;
862 mvm
->ps_disabled
= disable_ps
;
863 ret
= iwl_mvm_power_update_device(mvm
);
865 mvm
->ps_disabled
= old_ps_disabled
;
873 static int iwl_mvm_power_set_ba(struct iwl_mvm
*mvm
,
874 struct ieee80211_vif
*vif
)
876 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
877 struct iwl_beacon_filter_cmd cmd
= {
878 IWL_BF_CMD_CONFIG_DEFAULTS
,
879 .bf_enable_beacon_filter
= cpu_to_le32(1),
882 if (!mvmvif
->bf_data
.bf_enabled
)
885 if (test_bit(IWL_MVM_STATUS_IN_D3
, &mvm
->status
))
886 cmd
.ba_escape_timer
= cpu_to_le32(IWL_BA_ESCAPE_TIMER_D3
);
888 mvmvif
->bf_data
.ba_enabled
= !(!mvmvif
->pm_enabled
||
891 iwl_mvm_vif_low_latency(mvmvif
));
893 return _iwl_mvm_enable_beacon_filter(mvm
, vif
, &cmd
, 0);
896 int iwl_mvm_power_update_ps(struct iwl_mvm
*mvm
)
898 struct iwl_power_vifs vifs
= {
903 lockdep_assert_held(&mvm
->mutex
);
906 ieee80211_iterate_active_interfaces_atomic(mvm
->hw
,
907 IEEE80211_IFACE_ITER_NORMAL
,
908 iwl_mvm_power_get_vifs_iterator
, &vifs
);
910 ret
= iwl_mvm_power_set_ps(mvm
);
915 return iwl_mvm_power_set_ba(mvm
, vifs
.bss_vif
);
920 int iwl_mvm_power_update_mac(struct iwl_mvm
*mvm
)
922 struct iwl_power_vifs vifs
= {
927 lockdep_assert_held(&mvm
->mutex
);
930 ieee80211_iterate_active_interfaces_atomic(mvm
->hw
,
931 IEEE80211_IFACE_ITER_NORMAL
,
932 iwl_mvm_power_get_vifs_iterator
, &vifs
);
934 iwl_mvm_power_set_pm(mvm
, &vifs
);
936 ret
= iwl_mvm_power_set_ps(mvm
);
941 ret
= iwl_mvm_power_send_cmd(mvm
, vifs
.bss_vif
);
947 ret
= iwl_mvm_power_send_cmd(mvm
, vifs
.p2p_vif
);
953 return iwl_mvm_power_set_ba(mvm
, vifs
.bss_vif
);