xref: /linux/drivers/net/wireless/ath/ath10k/debugfs_sta.c (revision fbc872c38c8fed31948c85683b5326ee5ab9fccc)
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 }
285