1 /* 2 * Copyright (c) 2014-2017 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 void ath10k_sta_update_extd_stats_rx_duration(struct ath10k *ar, 22 struct ath10k_fw_stats *stats) 23 { 24 struct ath10k_fw_extd_stats_peer *peer; 25 struct ieee80211_sta *sta; 26 struct ath10k_sta *arsta; 27 28 rcu_read_lock(); 29 list_for_each_entry(peer, &stats->peers_extd, list) { 30 sta = ieee80211_find_sta_by_ifaddr(ar->hw, peer->peer_macaddr, 31 NULL); 32 if (!sta) 33 continue; 34 arsta = (struct ath10k_sta *)sta->drv_priv; 35 arsta->rx_duration += (u64)peer->rx_duration; 36 } 37 rcu_read_unlock(); 38 } 39 40 static void ath10k_sta_update_stats_rx_duration(struct ath10k *ar, 41 struct ath10k_fw_stats *stats) 42 { 43 struct ath10k_fw_stats_peer *peer; 44 struct ieee80211_sta *sta; 45 struct ath10k_sta *arsta; 46 47 rcu_read_lock(); 48 list_for_each_entry(peer, &stats->peers, list) { 49 sta = ieee80211_find_sta_by_ifaddr(ar->hw, peer->peer_macaddr, 50 NULL); 51 if (!sta) 52 continue; 53 arsta = (struct ath10k_sta *)sta->drv_priv; 54 arsta->rx_duration += (u64)peer->rx_duration; 55 } 56 rcu_read_unlock(); 57 } 58 59 void ath10k_sta_update_rx_duration(struct ath10k *ar, 60 struct ath10k_fw_stats *stats) 61 { 62 if (stats->extended) 63 ath10k_sta_update_extd_stats_rx_duration(ar, stats); 64 else 65 ath10k_sta_update_stats_rx_duration(ar, stats); 66 } 67 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) 71 { 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; 75 char buf[32]; 76 int len = 0; 77 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) ? 81 "auto" : "manual"); 82 mutex_unlock(&ar->conf_mutex); 83 84 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 85 } 86 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) 90 { 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; 94 u32 aggr_mode; 95 int ret; 96 97 if (kstrtouint_from_user(user_buf, count, 0, &aggr_mode)) 98 return -EINVAL; 99 100 if (aggr_mode >= ATH10K_DBG_AGGR_MODE_MAX) 101 return -EINVAL; 102 103 mutex_lock(&ar->conf_mutex); 104 if ((ar->state != ATH10K_STATE_ON) || 105 (aggr_mode == arsta->aggr_mode)) { 106 ret = count; 107 goto out; 108 } 109 110 ret = ath10k_wmi_addba_clear_resp(ar, arsta->arvif->vdev_id, sta->addr); 111 if (ret) { 112 ath10k_warn(ar, "failed to clear addba session ret: %d\n", ret); 113 goto out; 114 } 115 116 arsta->aggr_mode = aggr_mode; 117 out: 118 mutex_unlock(&ar->conf_mutex); 119 return ret; 120 } 121 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, 125 .open = simple_open, 126 .owner = THIS_MODULE, 127 .llseek = default_llseek, 128 }; 129 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) 133 { 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; 137 u32 tid, buf_size; 138 int ret; 139 char buf[64]; 140 141 simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count); 142 143 /* make sure that buf is null terminated */ 144 buf[sizeof(buf) - 1] = '\0'; 145 146 ret = sscanf(buf, "%u %u", &tid, &buf_size); 147 if (ret != 2) 148 return -EINVAL; 149 150 /* Valid TID values are 0 through 15 */ 151 if (tid > HTT_DATA_TX_EXT_TID_MGMT - 2) 152 return -EINVAL; 153 154 mutex_lock(&ar->conf_mutex); 155 if ((ar->state != ATH10K_STATE_ON) || 156 (arsta->aggr_mode != ATH10K_DBG_AGGR_MODE_MANUAL)) { 157 ret = count; 158 goto out; 159 } 160 161 ret = ath10k_wmi_addba_send(ar, arsta->arvif->vdev_id, sta->addr, 162 tid, buf_size); 163 if (ret) { 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); 166 } 167 168 ret = count; 169 out: 170 mutex_unlock(&ar->conf_mutex); 171 return ret; 172 } 173 174 static const struct file_operations fops_addba = { 175 .write = ath10k_dbg_sta_write_addba, 176 .open = simple_open, 177 .owner = THIS_MODULE, 178 .llseek = default_llseek, 179 }; 180 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) 184 { 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; 188 u32 tid, status; 189 int ret; 190 char buf[64]; 191 192 simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count); 193 194 /* make sure that buf is null terminated */ 195 buf[sizeof(buf) - 1] = '\0'; 196 197 ret = sscanf(buf, "%u %u", &tid, &status); 198 if (ret != 2) 199 return -EINVAL; 200 201 /* Valid TID values are 0 through 15 */ 202 if (tid > HTT_DATA_TX_EXT_TID_MGMT - 2) 203 return -EINVAL; 204 205 mutex_lock(&ar->conf_mutex); 206 if ((ar->state != ATH10K_STATE_ON) || 207 (arsta->aggr_mode != ATH10K_DBG_AGGR_MODE_MANUAL)) { 208 ret = count; 209 goto out; 210 } 211 212 ret = ath10k_wmi_addba_set_resp(ar, arsta->arvif->vdev_id, sta->addr, 213 tid, status); 214 if (ret) { 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); 217 } 218 ret = count; 219 out: 220 mutex_unlock(&ar->conf_mutex); 221 return ret; 222 } 223 224 static const struct file_operations fops_addba_resp = { 225 .write = ath10k_dbg_sta_write_addba_resp, 226 .open = simple_open, 227 .owner = THIS_MODULE, 228 .llseek = default_llseek, 229 }; 230 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) 234 { 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; 239 int ret; 240 char buf[64]; 241 242 simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count); 243 244 /* make sure that buf is null terminated */ 245 buf[sizeof(buf) - 1] = '\0'; 246 247 ret = sscanf(buf, "%u %u %u", &tid, &initiator, &reason); 248 if (ret != 3) 249 return -EINVAL; 250 251 /* Valid TID values are 0 through 15 */ 252 if (tid > HTT_DATA_TX_EXT_TID_MGMT - 2) 253 return -EINVAL; 254 255 mutex_lock(&ar->conf_mutex); 256 if ((ar->state != ATH10K_STATE_ON) || 257 (arsta->aggr_mode != ATH10K_DBG_AGGR_MODE_MANUAL)) { 258 ret = count; 259 goto out; 260 } 261 262 ret = ath10k_wmi_delba_send(ar, arsta->arvif->vdev_id, sta->addr, 263 tid, initiator, reason); 264 if (ret) { 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, 267 reason); 268 } 269 ret = count; 270 out: 271 mutex_unlock(&ar->conf_mutex); 272 return ret; 273 } 274 275 static const struct file_operations fops_delba = { 276 .write = ath10k_dbg_sta_write_delba, 277 .open = simple_open, 278 .owner = THIS_MODULE, 279 .llseek = default_llseek, 280 }; 281 282 static ssize_t ath10k_dbg_sta_read_peer_debug_trigger(struct file *file, 283 char __user *user_buf, 284 size_t count, 285 loff_t *ppos) 286 { 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; 290 char buf[8]; 291 int len = 0; 292 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); 297 298 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 299 } 300 301 static ssize_t 302 ath10k_dbg_sta_write_peer_debug_trigger(struct file *file, 303 const char __user *user_buf, 304 size_t count, loff_t *ppos) 305 { 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; 310 int ret; 311 312 if (kstrtou8_from_user(user_buf, count, 0, &peer_debug_trigger)) 313 return -EINVAL; 314 315 if (peer_debug_trigger != 1) 316 return -EINVAL; 317 318 mutex_lock(&ar->conf_mutex); 319 320 if (ar->state != ATH10K_STATE_ON) { 321 ret = -ENETDOWN; 322 goto out; 323 } 324 325 ret = ath10k_wmi_peer_set_param(ar, arsta->arvif->vdev_id, sta->addr, 326 WMI_PEER_DEBUG, peer_debug_trigger); 327 if (ret) { 328 ath10k_warn(ar, "failed to set param to trigger peer tid logs for station ret: %d\n", 329 ret); 330 goto out; 331 } 332 out: 333 mutex_unlock(&ar->conf_mutex); 334 return count; 335 } 336 337 static const struct file_operations fops_peer_debug_trigger = { 338 .open = simple_open, 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, 343 }; 344 345 void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 346 struct ieee80211_sta *sta, struct dentry *dir) 347 { 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); 354 } 355