2 * Copyright (c) 2014-2017 Qualcomm Atheros, Inc.
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.
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.
21 static void ath10k_sta_update_extd_stats_rx_duration(struct ath10k
*ar
,
22 struct ath10k_fw_stats
*stats
)
24 struct ath10k_fw_extd_stats_peer
*peer
;
25 struct ieee80211_sta
*sta
;
26 struct ath10k_sta
*arsta
;
29 list_for_each_entry(peer
, &stats
->peers_extd
, list
) {
30 sta
= ieee80211_find_sta_by_ifaddr(ar
->hw
, peer
->peer_macaddr
,
34 arsta
= (struct ath10k_sta
*)sta
->drv_priv
;
35 arsta
->rx_duration
+= (u64
)peer
->rx_duration
;
40 static void ath10k_sta_update_stats_rx_duration(struct ath10k
*ar
,
41 struct ath10k_fw_stats
*stats
)
43 struct ath10k_fw_stats_peer
*peer
;
44 struct ieee80211_sta
*sta
;
45 struct ath10k_sta
*arsta
;
48 list_for_each_entry(peer
, &stats
->peers
, list
) {
49 sta
= ieee80211_find_sta_by_ifaddr(ar
->hw
, peer
->peer_macaddr
,
53 arsta
= (struct ath10k_sta
*)sta
->drv_priv
;
54 arsta
->rx_duration
+= (u64
)peer
->rx_duration
;
59 void ath10k_sta_update_rx_duration(struct ath10k
*ar
,
60 struct ath10k_fw_stats
*stats
)
63 ath10k_sta_update_extd_stats_rx_duration(ar
, stats
);
65 ath10k_sta_update_stats_rx_duration(ar
, stats
);
68 static ssize_t
ath10k_dbg_sta_read_aggr_mode(struct file
*file
,
69 char __user
*user_buf
,
70 size_t count
, loff_t
*ppos
)
72 struct ieee80211_sta
*sta
= file
->private_data
;
73 struct ath10k_sta
*arsta
= (struct ath10k_sta
*)sta
->drv_priv
;
74 struct ath10k
*ar
= arsta
->arvif
->ar
;
78 mutex_lock(&ar
->conf_mutex
);
79 len
= scnprintf(buf
, sizeof(buf
) - len
, "aggregation mode: %s\n",
80 (arsta
->aggr_mode
== ATH10K_DBG_AGGR_MODE_AUTO
) ?
82 mutex_unlock(&ar
->conf_mutex
);
84 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, len
);
87 static ssize_t
ath10k_dbg_sta_write_aggr_mode(struct file
*file
,
88 const char __user
*user_buf
,
89 size_t count
, loff_t
*ppos
)
91 struct ieee80211_sta
*sta
= file
->private_data
;
92 struct ath10k_sta
*arsta
= (struct ath10k_sta
*)sta
->drv_priv
;
93 struct ath10k
*ar
= arsta
->arvif
->ar
;
97 if (kstrtouint_from_user(user_buf
, count
, 0, &aggr_mode
))
100 if (aggr_mode
>= ATH10K_DBG_AGGR_MODE_MAX
)
103 mutex_lock(&ar
->conf_mutex
);
104 if ((ar
->state
!= ATH10K_STATE_ON
) ||
105 (aggr_mode
== arsta
->aggr_mode
)) {
110 ret
= ath10k_wmi_addba_clear_resp(ar
, arsta
->arvif
->vdev_id
, sta
->addr
);
112 ath10k_warn(ar
, "failed to clear addba session ret: %d\n", ret
);
116 arsta
->aggr_mode
= aggr_mode
;
118 mutex_unlock(&ar
->conf_mutex
);
122 static const struct file_operations fops_aggr_mode
= {
123 .read
= ath10k_dbg_sta_read_aggr_mode
,
124 .write
= ath10k_dbg_sta_write_aggr_mode
,
126 .owner
= THIS_MODULE
,
127 .llseek
= default_llseek
,
130 static ssize_t
ath10k_dbg_sta_write_addba(struct file
*file
,
131 const char __user
*user_buf
,
132 size_t count
, loff_t
*ppos
)
134 struct ieee80211_sta
*sta
= file
->private_data
;
135 struct ath10k_sta
*arsta
= (struct ath10k_sta
*)sta
->drv_priv
;
136 struct ath10k
*ar
= arsta
->arvif
->ar
;
141 simple_write_to_buffer(buf
, sizeof(buf
) - 1, ppos
, user_buf
, count
);
143 /* make sure that buf is null terminated */
144 buf
[sizeof(buf
) - 1] = '\0';
146 ret
= sscanf(buf
, "%u %u", &tid
, &buf_size
);
150 /* Valid TID values are 0 through 15 */
151 if (tid
> HTT_DATA_TX_EXT_TID_MGMT
- 2)
154 mutex_lock(&ar
->conf_mutex
);
155 if ((ar
->state
!= ATH10K_STATE_ON
) ||
156 (arsta
->aggr_mode
!= ATH10K_DBG_AGGR_MODE_MANUAL
)) {
161 ret
= ath10k_wmi_addba_send(ar
, arsta
->arvif
->vdev_id
, sta
->addr
,
164 ath10k_warn(ar
, "failed to send addba request: vdev_id %u peer %pM tid %u buf_size %u\n",
165 arsta
->arvif
->vdev_id
, sta
->addr
, tid
, buf_size
);
170 mutex_unlock(&ar
->conf_mutex
);
174 static const struct file_operations fops_addba
= {
175 .write
= ath10k_dbg_sta_write_addba
,
177 .owner
= THIS_MODULE
,
178 .llseek
= default_llseek
,
181 static ssize_t
ath10k_dbg_sta_write_addba_resp(struct file
*file
,
182 const char __user
*user_buf
,
183 size_t count
, loff_t
*ppos
)
185 struct ieee80211_sta
*sta
= file
->private_data
;
186 struct ath10k_sta
*arsta
= (struct ath10k_sta
*)sta
->drv_priv
;
187 struct ath10k
*ar
= arsta
->arvif
->ar
;
192 simple_write_to_buffer(buf
, sizeof(buf
) - 1, ppos
, user_buf
, count
);
194 /* make sure that buf is null terminated */
195 buf
[sizeof(buf
) - 1] = '\0';
197 ret
= sscanf(buf
, "%u %u", &tid
, &status
);
201 /* Valid TID values are 0 through 15 */
202 if (tid
> HTT_DATA_TX_EXT_TID_MGMT
- 2)
205 mutex_lock(&ar
->conf_mutex
);
206 if ((ar
->state
!= ATH10K_STATE_ON
) ||
207 (arsta
->aggr_mode
!= ATH10K_DBG_AGGR_MODE_MANUAL
)) {
212 ret
= ath10k_wmi_addba_set_resp(ar
, arsta
->arvif
->vdev_id
, sta
->addr
,
215 ath10k_warn(ar
, "failed to send addba response: vdev_id %u peer %pM tid %u status%u\n",
216 arsta
->arvif
->vdev_id
, sta
->addr
, tid
, status
);
220 mutex_unlock(&ar
->conf_mutex
);
224 static const struct file_operations fops_addba_resp
= {
225 .write
= ath10k_dbg_sta_write_addba_resp
,
227 .owner
= THIS_MODULE
,
228 .llseek
= default_llseek
,
231 static ssize_t
ath10k_dbg_sta_write_delba(struct file
*file
,
232 const char __user
*user_buf
,
233 size_t count
, loff_t
*ppos
)
235 struct ieee80211_sta
*sta
= file
->private_data
;
236 struct ath10k_sta
*arsta
= (struct ath10k_sta
*)sta
->drv_priv
;
237 struct ath10k
*ar
= arsta
->arvif
->ar
;
238 u32 tid
, initiator
, reason
;
242 simple_write_to_buffer(buf
, sizeof(buf
) - 1, ppos
, user_buf
, count
);
244 /* make sure that buf is null terminated */
245 buf
[sizeof(buf
) - 1] = '\0';
247 ret
= sscanf(buf
, "%u %u %u", &tid
, &initiator
, &reason
);
251 /* Valid TID values are 0 through 15 */
252 if (tid
> HTT_DATA_TX_EXT_TID_MGMT
- 2)
255 mutex_lock(&ar
->conf_mutex
);
256 if ((ar
->state
!= ATH10K_STATE_ON
) ||
257 (arsta
->aggr_mode
!= ATH10K_DBG_AGGR_MODE_MANUAL
)) {
262 ret
= ath10k_wmi_delba_send(ar
, arsta
->arvif
->vdev_id
, sta
->addr
,
263 tid
, initiator
, reason
);
265 ath10k_warn(ar
, "failed to send delba: vdev_id %u peer %pM tid %u initiator %u reason %u\n",
266 arsta
->arvif
->vdev_id
, sta
->addr
, tid
, initiator
,
271 mutex_unlock(&ar
->conf_mutex
);
275 static const struct file_operations fops_delba
= {
276 .write
= ath10k_dbg_sta_write_delba
,
278 .owner
= THIS_MODULE
,
279 .llseek
= default_llseek
,
282 static ssize_t
ath10k_dbg_sta_read_peer_debug_trigger(struct file
*file
,
283 char __user
*user_buf
,
287 struct ieee80211_sta
*sta
= file
->private_data
;
288 struct ath10k_sta
*arsta
= (struct ath10k_sta
*)sta
->drv_priv
;
289 struct ath10k
*ar
= arsta
->arvif
->ar
;
293 mutex_lock(&ar
->conf_mutex
);
294 len
= scnprintf(buf
, sizeof(buf
) - len
,
295 "Write 1 to once trigger the debug logs\n");
296 mutex_unlock(&ar
->conf_mutex
);
298 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, len
);
302 ath10k_dbg_sta_write_peer_debug_trigger(struct file
*file
,
303 const char __user
*user_buf
,
304 size_t count
, loff_t
*ppos
)
306 struct ieee80211_sta
*sta
= file
->private_data
;
307 struct ath10k_sta
*arsta
= (struct ath10k_sta
*)sta
->drv_priv
;
308 struct ath10k
*ar
= arsta
->arvif
->ar
;
309 u8 peer_debug_trigger
;
312 if (kstrtou8_from_user(user_buf
, count
, 0, &peer_debug_trigger
))
315 if (peer_debug_trigger
!= 1)
318 mutex_lock(&ar
->conf_mutex
);
320 if (ar
->state
!= ATH10K_STATE_ON
) {
325 ret
= ath10k_wmi_peer_set_param(ar
, arsta
->arvif
->vdev_id
, sta
->addr
,
326 WMI_PEER_DEBUG
, peer_debug_trigger
);
328 ath10k_warn(ar
, "failed to set param to trigger peer tid logs for station ret: %d\n",
333 mutex_unlock(&ar
->conf_mutex
);
337 static const struct file_operations fops_peer_debug_trigger
= {
339 .read
= ath10k_dbg_sta_read_peer_debug_trigger
,
340 .write
= ath10k_dbg_sta_write_peer_debug_trigger
,
341 .owner
= THIS_MODULE
,
342 .llseek
= default_llseek
,
345 void ath10k_sta_add_debugfs(struct ieee80211_hw
*hw
, struct ieee80211_vif
*vif
,
346 struct ieee80211_sta
*sta
, struct dentry
*dir
)
348 debugfs_create_file("aggr_mode", 0644, dir
, sta
, &fops_aggr_mode
);
349 debugfs_create_file("addba", 0200, dir
, sta
, &fops_addba
);
350 debugfs_create_file("addba_resp", 0200, dir
, sta
, &fops_addba_resp
);
351 debugfs_create_file("delba", 0200, dir
, sta
, &fops_delba
);
352 debugfs_create_file("peer_debug_trigger", 0600, dir
, sta
,
353 &fops_peer_debug_trigger
);