diff options
author | Maharaja Kennadyrajan <mkenna@codeaurora.org> | 2018-09-18 09:34:27 +0300 |
---|---|---|
committer | Kalle Valo <kvalo@codeaurora.org> | 2018-10-01 17:02:08 +0300 |
commit | d70c0d463f9dd67037426bad243f647efec527d3 (patch) | |
tree | 9b0d98ede7b7e6c3d4307174776e489be3aaaf66 /drivers/net/wireless/ath/ath10k/debug.c | |
parent | 4be3b05e7a83c6820095005e794432ca1711fa7f (diff) | |
download | linux-d70c0d463f9dd67037426bad243f647efec527d3.tar.xz |
ath10k: add debugfs support to get power save state change of STA
This patch helps to get the power save state change of each peer
connected to the AP. With WMI_10_4_PEER_STA_PS_STATECHG_EVENTID
event, ps state of each peer is reported to user space via
debugfs.
Use the below command to get the ps state of each sta:
cat /sys/kernel/debug/ieee80211/phyX/netdev::wlanX/stations/
XX:XX:XX:XX:XX:XX/peer_ps_state
If STA is in power save state, we get the peer_ps_state value as 1.
if STA is not in power save state, we get the peer_ps_state value as 0.
If ps_state event is disabled, we get the peer_ps_state value as 2.
We can enable/disable the ps_state events using the debugfs flag
"ps_state_enable"
echo Y > /sys/kernel/debug/ieee80211/phyX/ath10k/ps_state_enable
Y = 1 to enable and Y = 0 to disable
Tested in QCA4019 with firmware ver 10.4-3.2.1.1-00011
Signed-off-by: Maharaja Kennadyrajan <mkenna@codeaurora.org>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Diffstat (limited to 'drivers/net/wireless/ath/ath10k/debug.c')
-rw-r--r-- | drivers/net/wireless/ath/ath10k/debug.c | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index ada29a4cc9c8..2c0cb6757fc6 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c @@ -2398,6 +2398,85 @@ static const struct file_operations fops_warm_hw_reset = { .llseek = default_llseek, }; +static void ath10k_peer_ps_state_disable(void *data, + struct ieee80211_sta *sta) +{ + struct ath10k *ar = data; + struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv; + + spin_lock_bh(&ar->data_lock); + arsta->peer_ps_state = WMI_PEER_PS_STATE_DISABLED; + spin_unlock_bh(&ar->data_lock); +} + +static ssize_t ath10k_write_ps_state_enable(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath10k *ar = file->private_data; + int ret; + u32 param; + u8 ps_state_enable; + + if (kstrtou8_from_user(user_buf, count, 0, &ps_state_enable)) + return -EINVAL; + + if (ps_state_enable > 1 || ps_state_enable < 0) + return -EINVAL; + + mutex_lock(&ar->conf_mutex); + + if (ar->ps_state_enable == ps_state_enable) { + ret = count; + goto exit; + } + + param = ar->wmi.pdev_param->peer_sta_ps_statechg_enable; + ret = ath10k_wmi_pdev_set_param(ar, param, ps_state_enable); + if (ret) { + ath10k_warn(ar, "failed to enable ps_state_enable: %d\n", + ret); + goto exit; + } + ar->ps_state_enable = ps_state_enable; + + if (!ar->ps_state_enable) + ieee80211_iterate_stations_atomic(ar->hw, + ath10k_peer_ps_state_disable, + ar); + + ret = count; + +exit: + mutex_unlock(&ar->conf_mutex); + + return ret; +} + +static ssize_t ath10k_read_ps_state_enable(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath10k *ar = file->private_data; + int len = 0; + char buf[32]; + + mutex_lock(&ar->conf_mutex); + len = scnprintf(buf, sizeof(buf) - len, "%d\n", + ar->ps_state_enable); + mutex_unlock(&ar->conf_mutex); + + return simple_read_from_buffer(user_buf, count, ppos, buf, len); +} + +static const struct file_operations fops_ps_state_enable = { + .read = ath10k_read_ps_state_enable, + .write = ath10k_write_ps_state_enable, + .open = simple_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + int ath10k_debug_create(struct ath10k *ar) { ar->debug.cal_data = vzalloc(ATH10K_DEBUG_CAL_DATA_LEN); @@ -2534,6 +2613,9 @@ int ath10k_debug_register(struct ath10k *ar) debugfs_create_file("warm_hw_reset", 0600, ar->debug.debugfs_phy, ar, &fops_warm_hw_reset); + debugfs_create_file("ps_state_enable", 0600, ar->debug.debugfs_phy, ar, + &fops_ps_state_enable); + return 0; } |