2 * Copyright (c) 2014 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 void ath10k_sta_statistics(struct ieee80211_hw
*hw
, struct ieee80211_vif
*vif
,
69 struct ieee80211_sta
*sta
,
70 struct station_info
*sinfo
)
72 struct ath10k_sta
*arsta
= (struct ath10k_sta
*)sta
->drv_priv
;
73 struct ath10k
*ar
= arsta
->arvif
->ar
;
75 if (!ath10k_peer_stats_enabled(ar
))
78 sinfo
->rx_duration
= arsta
->rx_duration
;
79 sinfo
->filled
|= 1ULL << NL80211_STA_INFO_RX_DURATION
;
82 static ssize_t
ath10k_dbg_sta_read_aggr_mode(struct file
*file
,
83 char __user
*user_buf
,
84 size_t count
, loff_t
*ppos
)
86 struct ieee80211_sta
*sta
= file
->private_data
;
87 struct ath10k_sta
*arsta
= (struct ath10k_sta
*)sta
->drv_priv
;
88 struct ath10k
*ar
= arsta
->arvif
->ar
;
92 mutex_lock(&ar
->conf_mutex
);
93 len
= scnprintf(buf
, sizeof(buf
) - len
, "aggregation mode: %s\n",
94 (arsta
->aggr_mode
== ATH10K_DBG_AGGR_MODE_AUTO
) ?
96 mutex_unlock(&ar
->conf_mutex
);
98 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, len
);
101 static ssize_t
ath10k_dbg_sta_write_aggr_mode(struct file
*file
,
102 const char __user
*user_buf
,
103 size_t count
, loff_t
*ppos
)
105 struct ieee80211_sta
*sta
= file
->private_data
;
106 struct ath10k_sta
*arsta
= (struct ath10k_sta
*)sta
->drv_priv
;
107 struct ath10k
*ar
= arsta
->arvif
->ar
;
111 if (kstrtouint_from_user(user_buf
, count
, 0, &aggr_mode
))
114 if (aggr_mode
>= ATH10K_DBG_AGGR_MODE_MAX
)
117 mutex_lock(&ar
->conf_mutex
);
118 if ((ar
->state
!= ATH10K_STATE_ON
) ||
119 (aggr_mode
== arsta
->aggr_mode
)) {
124 ret
= ath10k_wmi_addba_clear_resp(ar
, arsta
->arvif
->vdev_id
, sta
->addr
);
126 ath10k_warn(ar
, "failed to clear addba session ret: %d\n", ret
);
130 arsta
->aggr_mode
= aggr_mode
;
132 mutex_unlock(&ar
->conf_mutex
);
136 static const struct file_operations fops_aggr_mode
= {
137 .read
= ath10k_dbg_sta_read_aggr_mode
,
138 .write
= ath10k_dbg_sta_write_aggr_mode
,
140 .owner
= THIS_MODULE
,
141 .llseek
= default_llseek
,
144 static ssize_t
ath10k_dbg_sta_write_addba(struct file
*file
,
145 const char __user
*user_buf
,
146 size_t count
, loff_t
*ppos
)
148 struct ieee80211_sta
*sta
= file
->private_data
;
149 struct ath10k_sta
*arsta
= (struct ath10k_sta
*)sta
->drv_priv
;
150 struct ath10k
*ar
= arsta
->arvif
->ar
;
155 simple_write_to_buffer(buf
, sizeof(buf
) - 1, ppos
, user_buf
, count
);
157 /* make sure that buf is null terminated */
158 buf
[sizeof(buf
) - 1] = '\0';
160 ret
= sscanf(buf
, "%u %u", &tid
, &buf_size
);
164 /* Valid TID values are 0 through 15 */
165 if (tid
> HTT_DATA_TX_EXT_TID_MGMT
- 2)
168 mutex_lock(&ar
->conf_mutex
);
169 if ((ar
->state
!= ATH10K_STATE_ON
) ||
170 (arsta
->aggr_mode
!= ATH10K_DBG_AGGR_MODE_MANUAL
)) {
175 ret
= ath10k_wmi_addba_send(ar
, arsta
->arvif
->vdev_id
, sta
->addr
,
178 ath10k_warn(ar
, "failed to send addba request: vdev_id %u peer %pM tid %u buf_size %u\n",
179 arsta
->arvif
->vdev_id
, sta
->addr
, tid
, buf_size
);
184 mutex_unlock(&ar
->conf_mutex
);
188 static const struct file_operations fops_addba
= {
189 .write
= ath10k_dbg_sta_write_addba
,
191 .owner
= THIS_MODULE
,
192 .llseek
= default_llseek
,
195 static ssize_t
ath10k_dbg_sta_write_addba_resp(struct file
*file
,
196 const char __user
*user_buf
,
197 size_t count
, loff_t
*ppos
)
199 struct ieee80211_sta
*sta
= file
->private_data
;
200 struct ath10k_sta
*arsta
= (struct ath10k_sta
*)sta
->drv_priv
;
201 struct ath10k
*ar
= arsta
->arvif
->ar
;
206 simple_write_to_buffer(buf
, sizeof(buf
) - 1, ppos
, user_buf
, count
);
208 /* make sure that buf is null terminated */
209 buf
[sizeof(buf
) - 1] = '\0';
211 ret
= sscanf(buf
, "%u %u", &tid
, &status
);
215 /* Valid TID values are 0 through 15 */
216 if (tid
> HTT_DATA_TX_EXT_TID_MGMT
- 2)
219 mutex_lock(&ar
->conf_mutex
);
220 if ((ar
->state
!= ATH10K_STATE_ON
) ||
221 (arsta
->aggr_mode
!= ATH10K_DBG_AGGR_MODE_MANUAL
)) {
226 ret
= ath10k_wmi_addba_set_resp(ar
, arsta
->arvif
->vdev_id
, sta
->addr
,
229 ath10k_warn(ar
, "failed to send addba response: vdev_id %u peer %pM tid %u status%u\n",
230 arsta
->arvif
->vdev_id
, sta
->addr
, tid
, status
);
234 mutex_unlock(&ar
->conf_mutex
);
238 static const struct file_operations fops_addba_resp
= {
239 .write
= ath10k_dbg_sta_write_addba_resp
,
241 .owner
= THIS_MODULE
,
242 .llseek
= default_llseek
,
245 static ssize_t
ath10k_dbg_sta_write_delba(struct file
*file
,
246 const char __user
*user_buf
,
247 size_t count
, loff_t
*ppos
)
249 struct ieee80211_sta
*sta
= file
->private_data
;
250 struct ath10k_sta
*arsta
= (struct ath10k_sta
*)sta
->drv_priv
;
251 struct ath10k
*ar
= arsta
->arvif
->ar
;
252 u32 tid
, initiator
, reason
;
256 simple_write_to_buffer(buf
, sizeof(buf
) - 1, ppos
, user_buf
, count
);
258 /* make sure that buf is null terminated */
259 buf
[sizeof(buf
) - 1] = '\0';
261 ret
= sscanf(buf
, "%u %u %u", &tid
, &initiator
, &reason
);
265 /* Valid TID values are 0 through 15 */
266 if (tid
> HTT_DATA_TX_EXT_TID_MGMT
- 2)
269 mutex_lock(&ar
->conf_mutex
);
270 if ((ar
->state
!= ATH10K_STATE_ON
) ||
271 (arsta
->aggr_mode
!= ATH10K_DBG_AGGR_MODE_MANUAL
)) {
276 ret
= ath10k_wmi_delba_send(ar
, arsta
->arvif
->vdev_id
, sta
->addr
,
277 tid
, initiator
, reason
);
279 ath10k_warn(ar
, "failed to send delba: vdev_id %u peer %pM tid %u initiator %u reason %u\n",
280 arsta
->arvif
->vdev_id
, sta
->addr
, tid
, initiator
,
285 mutex_unlock(&ar
->conf_mutex
);
289 static const struct file_operations fops_delba
= {
290 .write
= ath10k_dbg_sta_write_delba
,
292 .owner
= THIS_MODULE
,
293 .llseek
= default_llseek
,
296 void ath10k_sta_add_debugfs(struct ieee80211_hw
*hw
, struct ieee80211_vif
*vif
,
297 struct ieee80211_sta
*sta
, struct dentry
*dir
)
299 debugfs_create_file("aggr_mode", S_IRUGO
| S_IWUSR
, dir
, sta
,
301 debugfs_create_file("addba", S_IWUSR
, dir
, sta
, &fops_addba
);
302 debugfs_create_file("addba_resp", S_IWUSR
, dir
, sta
, &fops_addba_resp
);
303 debugfs_create_file("delba", S_IWUSR
, dir
, sta
, &fops_delba
);