diff options
-rw-r--r-- | drivers/net/wireless/ath/ath12k/core.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath12k/hw.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath12k/hw.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath12k/mac.c | 54 |
4 files changed, 63 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index a984171e4a08..97e5a0ccd233 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -266,6 +266,7 @@ struct ath12k_vif { u8 tx_encap_type; u8 vdev_stats_id; u32 punct_bitmap; + bool ps; }; struct ath12k_vif_iter { diff --git a/drivers/net/wireless/ath/ath12k/hw.c b/drivers/net/wireless/ath/ath12k/hw.c index a9adb547c83d..6e2242a79a2f 100644 --- a/drivers/net/wireless/ath/ath12k/hw.c +++ b/drivers/net/wireless/ath/ath12k/hw.c @@ -918,6 +918,8 @@ static const struct ath12k_hw_params ath12k_hw_params[] = { .max_mlo_peer = 256, .otp_board_id_register = QCN9274_QFPROM_RAW_RFA_PDET_ROW13_LSB, + + .supports_sta_ps = false, }, { .name = "wcn7850 hw2.0", @@ -986,6 +988,8 @@ static const struct ath12k_hw_params ath12k_hw_params[] = { .max_mlo_peer = 32, .otp_board_id_register = 0, + + .supports_sta_ps = true, }, { .name = "qcn9274 hw2.0", @@ -1052,6 +1056,8 @@ static const struct ath12k_hw_params ath12k_hw_params[] = { .max_mlo_peer = 256, .otp_board_id_register = QCN9274_QFPROM_RAW_RFA_PDET_ROW13_LSB, + + .supports_sta_ps = false, }, }; diff --git a/drivers/net/wireless/ath/ath12k/hw.h b/drivers/net/wireless/ath/ath12k/hw.h index 2e9c3b05d75a..87965980b938 100644 --- a/drivers/net/wireless/ath/ath12k/hw.h +++ b/drivers/net/wireless/ath/ath12k/hw.h @@ -209,6 +209,8 @@ struct ath12k_hw_params { u16 max_mlo_peer; u32 otp_board_id_register; + + bool supports_sta_ps; }; struct ath12k_hw_ops { diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 6ef55876e7df..fb5bf500ed87 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -2510,12 +2510,60 @@ static int ath12k_mac_fils_discovery(struct ath12k_vif *arvif, return ret; } +static void ath12k_mac_vif_setup_ps(struct ath12k_vif *arvif) +{ + struct ath12k *ar = arvif->ar; + struct ieee80211_vif *vif = arvif->vif; + struct ieee80211_conf *conf = &ath12k_ar_to_hw(ar)->conf; + enum wmi_sta_powersave_param param; + enum wmi_sta_ps_mode psmode; + int ret; + int timeout; + bool enable_ps; + + lockdep_assert_held(&ar->conf_mutex); + + if (vif->type != NL80211_IFTYPE_STATION) + return; + + enable_ps = arvif->ps; + if (enable_ps) { + psmode = WMI_STA_PS_MODE_ENABLED; + param = WMI_STA_PS_PARAM_INACTIVITY_TIME; + + timeout = conf->dynamic_ps_timeout; + if (timeout == 0) { + /* firmware doesn't like 0 */ + timeout = ieee80211_tu_to_usec(vif->bss_conf.beacon_int) / 1000; + } + + ret = ath12k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param, + timeout); + if (ret) { + ath12k_warn(ar->ab, "failed to set inactivity time for vdev %d: %i\n", + arvif->vdev_id, ret); + return; + } + } else { + psmode = WMI_STA_PS_MODE_DISABLED; + } + + ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac vdev %d psmode %s\n", + arvif->vdev_id, psmode ? "enable" : "disable"); + + ret = ath12k_wmi_pdev_set_ps_mode(ar, arvif->vdev_id, psmode); + if (ret) + ath12k_warn(ar->ab, "failed to set sta power save mode %d for vdev %d: %d\n", + psmode, arvif->vdev_id, ret); +} + static void ath12k_mac_bss_info_changed(struct ath12k *ar, struct ath12k_vif *arvif, struct ieee80211_bss_conf *info, u64 changed) { struct ieee80211_vif *vif = arvif->vif; + struct ieee80211_vif_cfg *vif_cfg = &vif->cfg; struct cfg80211_chan_def def; u32 param_id, param_value; enum nl80211_band band; @@ -2788,6 +2836,12 @@ static void ath12k_mac_bss_info_changed(struct ath12k *ar, if (changed & BSS_CHANGED_EHT_PUNCTURING) arvif->punct_bitmap = info->eht_puncturing; + + if (changed & BSS_CHANGED_PS && + ar->ab->hw_params->supports_sta_ps) { + arvif->ps = vif_cfg->ps; + ath12k_mac_vif_setup_ps(arvif); + } } static void ath12k_mac_op_bss_info_changed(struct ieee80211_hw *hw, |