blob: 67ef75b60567e95476e5d8344903f36694a740e2 [file] [log] [blame]
Rajkumar Manoharanf5045982015-01-12 14:07:27 +02001/*
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
Mohammed Shafi Shajakhan856e7c32016-01-13 21:16:34 +053021void 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
Rajkumar Manoharanf5045982015-01-12 14:07:27 +020038static 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
57static 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;
87out:
88 mutex_unlock(&ar->conf_mutex);
89 return ret;
90}
91
92static 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
Rajkumar Manoharan8bf8f192015-01-12 14:07:27 +0200100static 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;
139out:
140 mutex_unlock(&ar->conf_mutex);
141 return ret;
142}
143
144static 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
Rajkumar Manoharan8e68d552015-01-12 14:07:27 +0200151static 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;
189out:
190 mutex_unlock(&ar->conf_mutex);
191 return ret;
192}
193
194static 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
Rajkumar Manoharanda2aedc2015-01-12 14:07:28 +0200201static 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;
240out:
241 mutex_unlock(&ar->conf_mutex);
242 return ret;
243}
244
245static 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
Mohammed Shafi Shajakhan856e7c32016-01-13 21:16:34 +0530252static 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
267static 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
Rajkumar Manoharanf5045982015-01-12 14:07:27 +0200274void 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);
Rajkumar Manoharan8bf8f192015-01-12 14:07:27 +0200279 debugfs_create_file("addba", S_IWUSR, dir, sta, &fops_addba);
Rajkumar Manoharan8e68d552015-01-12 14:07:27 +0200280 debugfs_create_file("addba_resp", S_IWUSR, dir, sta, &fops_addba_resp);
Rajkumar Manoharanda2aedc2015-01-12 14:07:28 +0200281 debugfs_create_file("delba", S_IWUSR, dir, sta, &fops_delba);
Mohammed Shafi Shajakhan856e7c32016-01-13 21:16:34 +0530282 debugfs_create_file("rx_duration", S_IRUGO, dir, sta,
283 &fops_rx_duration);
Rajkumar Manoharanf5045982015-01-12 14:07:27 +0200284}