Skip to content

Commit b2beffa

Browse files
Carl HuangKalle Valo
Carl Huang
authored and
Kalle Valo
committed
ath11k: enable 802.11 power save mode in station mode
To reduce power consumption enable 802.11 power save mode in station mode. This allows both radio and CPU to sleep more. Only enable the mode on QCA6390 and WCN6855, it's unknown how other hardware families support this feature. To test that power save mode is running run "iw dev wls1 set power_save off", check there is no NULL Data frame seen by a sniffer. And run "iw dev wls1 set power_save on" and check there is a NULL Data frame in sniffer. Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1 Signed-off-by: Carl Huang <[email protected]> Signed-off-by: Kalle Valo <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent af3d896 commit b2beffa

File tree

4 files changed

+94
-0
lines changed

4 files changed

+94
-0
lines changed

drivers/net/wireless/ath/ath11k/core.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
7676
.supports_monitor = true,
7777
.supports_shadow_regs = false,
7878
.idle_ps = false,
79+
.supports_sta_ps = false,
7980
.cold_boot_calib = true,
8081
.supports_suspend = false,
8182
.hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
@@ -126,6 +127,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
126127
.supports_monitor = true,
127128
.supports_shadow_regs = false,
128129
.idle_ps = false,
130+
.supports_sta_ps = false,
129131
.cold_boot_calib = true,
130132
.supports_suspend = false,
131133
.hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
@@ -175,6 +177,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
175177
.supports_monitor = false,
176178
.supports_shadow_regs = true,
177179
.idle_ps = true,
180+
.supports_sta_ps = true,
178181
.cold_boot_calib = false,
179182
.supports_suspend = true,
180183
.hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
@@ -224,6 +227,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
224227
.supports_monitor = true,
225228
.supports_shadow_regs = false,
226229
.idle_ps = false,
230+
.supports_sta_ps = false,
227231
.cold_boot_calib = false,
228232
.supports_suspend = false,
229233
.hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074),
@@ -273,6 +277,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
273277
.supports_monitor = false,
274278
.supports_shadow_regs = true,
275279
.idle_ps = true,
280+
.supports_sta_ps = true,
276281
.cold_boot_calib = false,
277282
.supports_suspend = true,
278283
.hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855),

drivers/net/wireless/ath/ath11k/core.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ struct ath11k_vif {
240240
bool is_started;
241241
bool is_up;
242242
bool spectral_enabled;
243+
bool ps;
243244
u32 aid;
244245
u8 bssid[ETH_ALEN];
245246
struct cfg80211_bitrate_mask bitrate_mask;

drivers/net/wireless/ath/ath11k/hw.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ struct ath11k_hw_params {
170170
bool supports_monitor;
171171
bool supports_shadow_regs;
172172
bool idle_ps;
173+
bool supports_sta_ps;
173174
bool cold_boot_calib;
174175
bool supports_suspend;
175176
u32 hal_desc_sz;

drivers/net/wireless/ath/ath11k/mac.c

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1049,6 +1049,83 @@ static int ath11k_mac_monitor_stop(struct ath11k *ar)
10491049
return 0;
10501050
}
10511051

1052+
static int ath11k_mac_vif_setup_ps(struct ath11k_vif *arvif)
1053+
{
1054+
struct ath11k *ar = arvif->ar;
1055+
struct ieee80211_vif *vif = arvif->vif;
1056+
struct ieee80211_conf *conf = &ar->hw->conf;
1057+
enum wmi_sta_powersave_param param;
1058+
enum wmi_sta_ps_mode psmode;
1059+
int ret;
1060+
int timeout;
1061+
bool enable_ps;
1062+
1063+
lockdep_assert_held(&arvif->ar->conf_mutex);
1064+
1065+
if (arvif->vif->type != NL80211_IFTYPE_STATION)
1066+
return 0;
1067+
1068+
enable_ps = arvif->ps;
1069+
1070+
if (!arvif->is_started) {
1071+
/* mac80211 can update vif powersave state while disconnected.
1072+
* Firmware doesn't behave nicely and consumes more power than
1073+
* necessary if PS is disabled on a non-started vdev. Hence
1074+
* force-enable PS for non-running vdevs.
1075+
*/
1076+
psmode = WMI_STA_PS_MODE_ENABLED;
1077+
} else if (enable_ps) {
1078+
psmode = WMI_STA_PS_MODE_ENABLED;
1079+
param = WMI_STA_PS_PARAM_INACTIVITY_TIME;
1080+
1081+
timeout = conf->dynamic_ps_timeout;
1082+
if (timeout == 0) {
1083+
/* firmware doesn't like 0 */
1084+
timeout = ieee80211_tu_to_usec(vif->bss_conf.beacon_int) / 1000;
1085+
}
1086+
1087+
ret = ath11k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param,
1088+
timeout);
1089+
if (ret) {
1090+
ath11k_warn(ar->ab, "failed to set inactivity time for vdev %d: %i\n",
1091+
arvif->vdev_id, ret);
1092+
return ret;
1093+
}
1094+
} else {
1095+
psmode = WMI_STA_PS_MODE_DISABLED;
1096+
}
1097+
1098+
ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac vdev %d psmode %s\n",
1099+
arvif->vdev_id, psmode ? "enable" : "disable");
1100+
1101+
ret = ath11k_wmi_pdev_set_ps_mode(ar, arvif->vdev_id, psmode);
1102+
if (ret) {
1103+
ath11k_warn(ar->ab, "failed to set sta power save mode %d for vdev %d: %d\n",
1104+
psmode, arvif->vdev_id, ret);
1105+
return ret;
1106+
}
1107+
1108+
return 0;
1109+
}
1110+
1111+
static int ath11k_mac_config_ps(struct ath11k *ar)
1112+
{
1113+
struct ath11k_vif *arvif;
1114+
int ret = 0;
1115+
1116+
lockdep_assert_held(&ar->conf_mutex);
1117+
1118+
list_for_each_entry(arvif, &ar->arvifs, list) {
1119+
ret = ath11k_mac_vif_setup_ps(arvif);
1120+
if (ret) {
1121+
ath11k_warn(ar->ab, "failed to setup powersave: %d\n", ret);
1122+
break;
1123+
}
1124+
}
1125+
1126+
return ret;
1127+
}
1128+
10521129
static int ath11k_mac_op_config(struct ieee80211_hw *hw, u32 changed)
10531130
{
10541131
struct ath11k *ar = hw->priv;
@@ -2942,6 +3019,16 @@ static void ath11k_mac_op_bss_info_changed(struct ieee80211_hw *hw,
29423019
ath11k_mac_txpower_recalc(ar);
29433020
}
29443021

3022+
if (changed & BSS_CHANGED_PS &&
3023+
ar->ab->hw_params.supports_sta_ps) {
3024+
arvif->ps = vif->bss_conf.ps;
3025+
3026+
ret = ath11k_mac_config_ps(ar);
3027+
if (ret)
3028+
ath11k_warn(ar->ab, "failed to setup ps on vdev %i: %d\n",
3029+
arvif->vdev_id, ret);
3030+
}
3031+
29453032
if (changed & BSS_CHANGED_MCAST_RATE &&
29463033
!ath11k_mac_vif_chan(arvif->vif, &def)) {
29473034
band = def.chan->band;

0 commit comments

Comments
 (0)