Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / 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 static ssize_t ath10k_dbg_sta_read_aggr_mode(struct file *file,
22                                              char __user *user_buf,
23                                              size_t count, loff_t *ppos)
24 {
25         struct ieee80211_sta *sta = file->private_data;
26         struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
27         struct ath10k *ar = arsta->arvif->ar;
28         char buf[32];
29         int len = 0;
30
31         mutex_lock(&ar->conf_mutex);
32         len = scnprintf(buf, sizeof(buf) - len, "aggregation mode: %s\n",
33                         (arsta->aggr_mode == ATH10K_DBG_AGGR_MODE_AUTO) ?
34                         "auto" : "manual");
35         mutex_unlock(&ar->conf_mutex);
36
37         return simple_read_from_buffer(user_buf, count, ppos, buf, len);
38 }
39
40 static ssize_t ath10k_dbg_sta_write_aggr_mode(struct file *file,
41                                               const char __user *user_buf,
42                                               size_t count, loff_t *ppos)
43 {
44         struct ieee80211_sta *sta = file->private_data;
45         struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
46         struct ath10k *ar = arsta->arvif->ar;
47         u32 aggr_mode;
48         int ret;
49
50         if (kstrtouint_from_user(user_buf, count, 0, &aggr_mode))
51                 return -EINVAL;
52
53         if (aggr_mode >= ATH10K_DBG_AGGR_MODE_MAX)
54                 return -EINVAL;
55
56         mutex_lock(&ar->conf_mutex);
57         if ((ar->state != ATH10K_STATE_ON) ||
58             (aggr_mode == arsta->aggr_mode)) {
59                 ret = count;
60                 goto out;
61         }
62
63         ret = ath10k_wmi_addba_clear_resp(ar, arsta->arvif->vdev_id, sta->addr);
64         if (ret) {
65                 ath10k_warn(ar, "failed to clear addba session ret: %d\n", ret);
66                 goto out;
67         }
68
69         arsta->aggr_mode = aggr_mode;
70 out:
71         mutex_unlock(&ar->conf_mutex);
72         return ret;
73 }
74
75 static const struct file_operations fops_aggr_mode = {
76         .read = ath10k_dbg_sta_read_aggr_mode,
77         .write = ath10k_dbg_sta_write_aggr_mode,
78         .open = simple_open,
79         .owner = THIS_MODULE,
80         .llseek = default_llseek,
81 };
82
83 static ssize_t ath10k_dbg_sta_write_addba(struct file *file,
84                                           const char __user *user_buf,
85                                           size_t count, loff_t *ppos)
86 {
87         struct ieee80211_sta *sta = file->private_data;
88         struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
89         struct ath10k *ar = arsta->arvif->ar;
90         u32 tid, buf_size;
91         int ret;
92         char buf[64];
93
94         simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
95
96         /* make sure that buf is null terminated */
97         buf[sizeof(buf) - 1] = '\0';
98
99         ret = sscanf(buf, "%u %u", &tid, &buf_size);
100         if (ret != 2)
101                 return -EINVAL;
102
103         /* Valid TID values are 0 through 15 */
104         if (tid > HTT_DATA_TX_EXT_TID_MGMT - 2)
105                 return -EINVAL;
106
107         mutex_lock(&ar->conf_mutex);
108         if ((ar->state != ATH10K_STATE_ON) ||
109             (arsta->aggr_mode != ATH10K_DBG_AGGR_MODE_MANUAL)) {
110                 ret = count;
111                 goto out;
112         }
113
114         ret = ath10k_wmi_addba_send(ar, arsta->arvif->vdev_id, sta->addr,
115                                     tid, buf_size);
116         if (ret) {
117                 ath10k_warn(ar, "failed to send addba request: vdev_id %u peer %pM tid %u buf_size %u\n",
118                             arsta->arvif->vdev_id, sta->addr, tid, buf_size);
119         }
120
121         ret = count;
122 out:
123         mutex_unlock(&ar->conf_mutex);
124         return ret;
125 }
126
127 static const struct file_operations fops_addba = {
128         .write = ath10k_dbg_sta_write_addba,
129         .open = simple_open,
130         .owner = THIS_MODULE,
131         .llseek = default_llseek,
132 };
133
134 static ssize_t ath10k_dbg_sta_write_addba_resp(struct file *file,
135                                                const char __user *user_buf,
136                                                size_t count, loff_t *ppos)
137 {
138         struct ieee80211_sta *sta = file->private_data;
139         struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
140         struct ath10k *ar = arsta->arvif->ar;
141         u32 tid, status;
142         int ret;
143         char buf[64];
144
145         simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
146
147         /* make sure that buf is null terminated */
148         buf[sizeof(buf) - 1] = '\0';
149
150         ret = sscanf(buf, "%u %u", &tid, &status);
151         if (ret != 2)
152                 return -EINVAL;
153
154         /* Valid TID values are 0 through 15 */
155         if (tid > HTT_DATA_TX_EXT_TID_MGMT - 2)
156                 return -EINVAL;
157
158         mutex_lock(&ar->conf_mutex);
159         if ((ar->state != ATH10K_STATE_ON) ||
160             (arsta->aggr_mode != ATH10K_DBG_AGGR_MODE_MANUAL)) {
161                 ret = count;
162                 goto out;
163         }
164
165         ret = ath10k_wmi_addba_set_resp(ar, arsta->arvif->vdev_id, sta->addr,
166                                         tid, status);
167         if (ret) {
168                 ath10k_warn(ar, "failed to send addba response: vdev_id %u peer %pM tid %u status%u\n",
169                             arsta->arvif->vdev_id, sta->addr, tid, status);
170         }
171         ret = count;
172 out:
173         mutex_unlock(&ar->conf_mutex);
174         return ret;
175 }
176
177 static const struct file_operations fops_addba_resp = {
178         .write = ath10k_dbg_sta_write_addba_resp,
179         .open = simple_open,
180         .owner = THIS_MODULE,
181         .llseek = default_llseek,
182 };
183
184 static ssize_t ath10k_dbg_sta_write_delba(struct file *file,
185                                           const char __user *user_buf,
186                                           size_t count, loff_t *ppos)
187 {
188         struct ieee80211_sta *sta = file->private_data;
189         struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
190         struct ath10k *ar = arsta->arvif->ar;
191         u32 tid, initiator, reason;
192         int ret;
193         char buf[64];
194
195         simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
196
197         /* make sure that buf is null terminated */
198         buf[sizeof(buf) - 1] = '\0';
199
200         ret = sscanf(buf, "%u %u %u", &tid, &initiator, &reason);
201         if (ret != 3)
202                 return -EINVAL;
203
204         /* Valid TID values are 0 through 15 */
205         if (tid > HTT_DATA_TX_EXT_TID_MGMT - 2)
206                 return -EINVAL;
207
208         mutex_lock(&ar->conf_mutex);
209         if ((ar->state != ATH10K_STATE_ON) ||
210             (arsta->aggr_mode != ATH10K_DBG_AGGR_MODE_MANUAL)) {
211                 ret = count;
212                 goto out;
213         }
214
215         ret = ath10k_wmi_delba_send(ar, arsta->arvif->vdev_id, sta->addr,
216                                     tid, initiator, reason);
217         if (ret) {
218                 ath10k_warn(ar, "failed to send delba: vdev_id %u peer %pM tid %u initiator %u reason %u\n",
219                             arsta->arvif->vdev_id, sta->addr, tid, initiator,
220                             reason);
221         }
222         ret = count;
223 out:
224         mutex_unlock(&ar->conf_mutex);
225         return ret;
226 }
227
228 static const struct file_operations fops_delba = {
229         .write = ath10k_dbg_sta_write_delba,
230         .open = simple_open,
231         .owner = THIS_MODULE,
232         .llseek = default_llseek,
233 };
234
235 void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
236                             struct ieee80211_sta *sta, struct dentry *dir)
237 {
238         debugfs_create_file("aggr_mode", S_IRUGO | S_IWUSR, dir, sta,
239                             &fops_aggr_mode);
240         debugfs_create_file("addba", S_IWUSR, dir, sta, &fops_addba);
241         debugfs_create_file("addba_resp", S_IWUSR, dir, sta, &fops_addba_resp);
242         debugfs_create_file("delba", S_IWUSR, dir, sta, &fops_delba);
243 }