67ef75b60567e95476e5d8344903f36694a740e2
[cascardo/linux.git] / drivers / net / wireless / ath / ath10k / debugfs_sta.c
1 /*
2  * Copyright (c) 2014 Qualcomm Atheros, Inc.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16
17 #include "core.h"
18 #include "wmi-ops.h"
19 #include "debug.h"
20
21 void ath10k_sta_update_rx_duration(struct ath10k *ar, struct list_head *head)
22 {       struct ieee80211_sta *sta;
23         struct ath10k_fw_stats_peer *peer;
24         struct ath10k_sta *arsta;
25
26         rcu_read_lock();
27         list_for_each_entry(peer, head, list) {
28                 sta = ieee80211_find_sta_by_ifaddr(ar->hw, peer->peer_macaddr,
29                                                    NULL);
30                 if (!sta)
31                         continue;
32                 arsta = (struct ath10k_sta *)sta->drv_priv;
33                 arsta->rx_duration += (u64)peer->rx_duration;
34         }
35         rcu_read_unlock();
36 }
37
38 static ssize_t ath10k_dbg_sta_read_aggr_mode(struct file *file,
39                                              char __user *user_buf,
40                                              size_t count, loff_t *ppos)
41 {
42         struct ieee80211_sta *sta = file->private_data;
43         struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
44         struct ath10k *ar = arsta->arvif->ar;
45         char buf[32];
46         int len = 0;
47
48         mutex_lock(&ar->conf_mutex);
49         len = scnprintf(buf, sizeof(buf) - len, "aggregation mode: %s\n",
50                         (arsta->aggr_mode == ATH10K_DBG_AGGR_MODE_AUTO) ?
51                         "auto" : "manual");
52         mutex_unlock(&ar->conf_mutex);
53
54         return simple_read_from_buffer(user_buf, count, ppos, buf, len);
55 }
56
57 static ssize_t ath10k_dbg_sta_write_aggr_mode(struct file *file,
58                                               const char __user *user_buf,
59                                               size_t count, loff_t *ppos)
60 {
61         struct ieee80211_sta *sta = file->private_data;
62         struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
63         struct ath10k *ar = arsta->arvif->ar;
64         u32 aggr_mode;
65         int ret;
66
67         if (kstrtouint_from_user(user_buf, count, 0, &aggr_mode))
68                 return -EINVAL;
69
70         if (aggr_mode >= ATH10K_DBG_AGGR_MODE_MAX)
71                 return -EINVAL;
72
73         mutex_lock(&ar->conf_mutex);
74         if ((ar->state != ATH10K_STATE_ON) ||
75             (aggr_mode == arsta->aggr_mode)) {
76                 ret = count;
77                 goto out;
78         }
79
80         ret = ath10k_wmi_addba_clear_resp(ar, arsta->arvif->vdev_id, sta->addr);
81         if (ret) {
82                 ath10k_warn(ar, "failed to clear addba session ret: %d\n", ret);
83                 goto out;
84         }
85
86         arsta->aggr_mode = aggr_mode;
87 out:
88         mutex_unlock(&ar->conf_mutex);
89         return ret;
90 }
91
92 static const struct file_operations fops_aggr_mode = {
93         .read = ath10k_dbg_sta_read_aggr_mode,
94         .write = ath10k_dbg_sta_write_aggr_mode,
95         .open = simple_open,
96         .owner = THIS_MODULE,
97         .llseek = default_llseek,
98 };
99
100 static ssize_t ath10k_dbg_sta_write_addba(struct file *file,
101                                           const char __user *user_buf,
102                                           size_t count, loff_t *ppos)
103 {
104         struct ieee80211_sta *sta = file->private_data;
105         struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
106         struct ath10k *ar = arsta->arvif->ar;
107         u32 tid, buf_size;
108         int ret;
109         char buf[64];
110
111         simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
112
113         /* make sure that buf is null terminated */
114         buf[sizeof(buf) - 1] = '\0';
115
116         ret = sscanf(buf, "%u %u", &tid, &buf_size);
117         if (ret != 2)
118                 return -EINVAL;
119
120         /* Valid TID values are 0 through 15 */
121         if (tid > HTT_DATA_TX_EXT_TID_MGMT - 2)
122                 return -EINVAL;
123
124         mutex_lock(&ar->conf_mutex);
125         if ((ar->state != ATH10K_STATE_ON) ||
126             (arsta->aggr_mode != ATH10K_DBG_AGGR_MODE_MANUAL)) {
127                 ret = count;
128                 goto out;
129         }
130
131         ret = ath10k_wmi_addba_send(ar, arsta->arvif->vdev_id, sta->addr,
132                                     tid, buf_size);
133         if (ret) {
134                 ath10k_warn(ar, "failed to send addba request: vdev_id %u peer %pM tid %u buf_size %u\n",
135                             arsta->arvif->vdev_id, sta->addr, tid, buf_size);
136         }
137
138         ret = count;
139 out:
140         mutex_unlock(&ar->conf_mutex);
141         return ret;
142 }
143
144 static const struct file_operations fops_addba = {
145         .write = ath10k_dbg_sta_write_addba,
146         .open = simple_open,
147         .owner = THIS_MODULE,
148         .llseek = default_llseek,
149 };
150
151 static ssize_t ath10k_dbg_sta_write_addba_resp(struct file *file,
152                                                const char __user *user_buf,
153                                                size_t count, loff_t *ppos)
154 {
155         struct ieee80211_sta *sta = file->private_data;
156         struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
157         struct ath10k *ar = arsta->arvif->ar;
158         u32 tid, status;
159         int ret;
160         char buf[64];
161
162         simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
163
164         /* make sure that buf is null terminated */
165         buf[sizeof(buf) - 1] = '\0';
166
167         ret = sscanf(buf, "%u %u", &tid, &status);
168         if (ret != 2)
169                 return -EINVAL;
170
171         /* Valid TID values are 0 through 15 */
172         if (tid > HTT_DATA_TX_EXT_TID_MGMT - 2)
173                 return -EINVAL;
174
175         mutex_lock(&ar->conf_mutex);
176         if ((ar->state != ATH10K_STATE_ON) ||
177             (arsta->aggr_mode != ATH10K_DBG_AGGR_MODE_MANUAL)) {
178                 ret = count;
179                 goto out;
180         }
181
182         ret = ath10k_wmi_addba_set_resp(ar, arsta->arvif->vdev_id, sta->addr,
183                                         tid, status);
184         if (ret) {
185                 ath10k_warn(ar, "failed to send addba response: vdev_id %u peer %pM tid %u status%u\n",
186                             arsta->arvif->vdev_id, sta->addr, tid, status);
187         }
188         ret = count;
189 out:
190         mutex_unlock(&ar->conf_mutex);
191         return ret;
192 }
193
194 static const struct file_operations fops_addba_resp = {
195         .write = ath10k_dbg_sta_write_addba_resp,
196         .open = simple_open,
197         .owner = THIS_MODULE,
198         .llseek = default_llseek,
199 };
200
201 static ssize_t ath10k_dbg_sta_write_delba(struct file *file,
202                                           const char __user *user_buf,
203                                           size_t count, loff_t *ppos)
204 {
205         struct ieee80211_sta *sta = file->private_data;
206         struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
207         struct ath10k *ar = arsta->arvif->ar;
208         u32 tid, initiator, reason;
209         int ret;
210         char buf[64];
211
212         simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
213
214         /* make sure that buf is null terminated */
215         buf[sizeof(buf) - 1] = '\0';
216
217         ret = sscanf(buf, "%u %u %u", &tid, &initiator, &reason);
218         if (ret != 3)
219                 return -EINVAL;
220
221         /* Valid TID values are 0 through 15 */
222         if (tid > HTT_DATA_TX_EXT_TID_MGMT - 2)
223                 return -EINVAL;
224
225         mutex_lock(&ar->conf_mutex);
226         if ((ar->state != ATH10K_STATE_ON) ||
227             (arsta->aggr_mode != ATH10K_DBG_AGGR_MODE_MANUAL)) {
228                 ret = count;
229                 goto out;
230         }
231
232         ret = ath10k_wmi_delba_send(ar, arsta->arvif->vdev_id, sta->addr,
233                                     tid, initiator, reason);
234         if (ret) {
235                 ath10k_warn(ar, "failed to send delba: vdev_id %u peer %pM tid %u initiator %u reason %u\n",
236                             arsta->arvif->vdev_id, sta->addr, tid, initiator,
237                             reason);
238         }
239         ret = count;
240 out:
241         mutex_unlock(&ar->conf_mutex);
242         return ret;
243 }
244
245 static const struct file_operations fops_delba = {
246         .write = ath10k_dbg_sta_write_delba,
247         .open = simple_open,
248         .owner = THIS_MODULE,
249         .llseek = default_llseek,
250 };
251
252 static ssize_t ath10k_dbg_sta_read_rx_duration(struct file *file,
253                                                char __user *user_buf,
254                                                size_t count, loff_t *ppos)
255 {
256         struct ieee80211_sta *sta = file->private_data;
257         struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
258         char buf[100];
259         int len = 0;
260
261         len = scnprintf(buf, sizeof(buf),
262                         "%llu usecs\n", arsta->rx_duration);
263
264         return simple_read_from_buffer(user_buf, count, ppos, buf, len);
265 }
266
267 static const struct file_operations fops_rx_duration = {
268         .read = ath10k_dbg_sta_read_rx_duration,
269         .open = simple_open,
270         .owner = THIS_MODULE,
271         .llseek = default_llseek,
272 };
273
274 void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
275                             struct ieee80211_sta *sta, struct dentry *dir)
276 {
277         debugfs_create_file("aggr_mode", S_IRUGO | S_IWUSR, dir, sta,
278                             &fops_aggr_mode);
279         debugfs_create_file("addba", S_IWUSR, dir, sta, &fops_addba);
280         debugfs_create_file("addba_resp", S_IWUSR, dir, sta, &fops_addba_resp);
281         debugfs_create_file("delba", S_IWUSR, dir, sta, &fops_delba);
282         debugfs_create_file("rx_duration", S_IRUGO, dir, sta,
283                             &fops_rx_duration);
284 }