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 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 void ath10k_sta_statistics(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 69 struct ieee80211_sta *sta, 70 struct station_info *sinfo) 71 { 72 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv; 73 struct ath10k *ar = arsta->arvif->ar; 74 75 if (!ath10k_peer_stats_enabled(ar)) 76 return; 77 78 sinfo->rx_duration = arsta->rx_duration; 79 sinfo->filled |= 1ULL << NL80211_STA_INFO_RX_DURATION; 80 81 if (!arsta->txrate.legacy && !arsta->txrate.nss) 82 return; 83 84 if (arsta->txrate.legacy) { 85 sinfo->txrate.legacy = arsta->txrate.legacy; 86 } else { 87 sinfo->txrate.mcs = arsta->txrate.mcs; 88 sinfo->txrate.nss = arsta->txrate.nss; 89 sinfo->txrate.bw = arsta->txrate.bw; 90 } 91 sinfo->txrate.flags = arsta->txrate.flags; 92 sinfo->filled |= 1ULL << NL80211_STA_INFO_TX_BITRATE; 93 } 94 95 static ssize_t ath10k_dbg_sta_read_aggr_mode(struct file *file, 96 char __user *user_buf, 97 size_t count, loff_t *ppos) 98 { 99 struct ieee80211_sta *sta = file->private_data; 100 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv; 101 struct ath10k *ar = arsta->arvif->ar; 102 char buf[32]; 103 int len = 0; 104 105 mutex_lock(&ar->conf_mutex); 106 len = scnprintf(buf, sizeof(buf) - len, "aggregation mode: %s\n", 107 (arsta->aggr_mode == ATH10K_DBG_AGGR_MODE_AUTO) ? 108 "auto" : "manual"); 109 mutex_unlock(&ar->conf_mutex); 110 111 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 112 } 113 114 static ssize_t ath10k_dbg_sta_write_aggr_mode(struct file *file, 115 const char __user *user_buf, 116 size_t count, loff_t *ppos) 117 { 118 struct ieee80211_sta *sta = file->private_data; 119 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv; 120 struct ath10k *ar = arsta->arvif->ar; 121 u32 aggr_mode; 122 int ret; 123 124 if (kstrtouint_from_user(user_buf, count, 0, &aggr_mode)) 125 return -EINVAL; 126 127 if (aggr_mode >= ATH10K_DBG_AGGR_MODE_MAX) 128 return -EINVAL; 129 130 mutex_lock(&ar->conf_mutex); 131 if ((ar->state != ATH10K_STATE_ON) || 132 (aggr_mode == arsta->aggr_mode)) { 133 ret = count; 134 goto out; 135 } 136 137 ret = ath10k_wmi_addba_clear_resp(ar, arsta->arvif->vdev_id, sta->addr); 138 if (ret) { 139 ath10k_warn(ar, "failed to clear addba session ret: %d\n", ret); 140 goto out; 141 } 142 143 arsta->aggr_mode = aggr_mode; 144 out: 145 mutex_unlock(&ar->conf_mutex); 146 return ret; 147 } 148 149 static const struct file_operations fops_aggr_mode = { 150 .read = ath10k_dbg_sta_read_aggr_mode, 151 .write = ath10k_dbg_sta_write_aggr_mode, 152 .open = simple_open, 153 .owner = THIS_MODULE, 154 .llseek = default_llseek, 155 }; 156 157 static ssize_t ath10k_dbg_sta_write_addba(struct file *file, 158 const char __user *user_buf, 159 size_t count, loff_t *ppos) 160 { 161 struct ieee80211_sta *sta = file->private_data; 162 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv; 163 struct ath10k *ar = arsta->arvif->ar; 164 u32 tid, buf_size; 165 int ret; 166 char buf[64]; 167 168 simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count); 169 170 /* make sure that buf is null terminated */ 171 buf[sizeof(buf) - 1] = '\0'; 172 173 ret = sscanf(buf, "%u %u", &tid, &buf_size); 174 if (ret != 2) 175 return -EINVAL; 176 177 /* Valid TID values are 0 through 15 */ 178 if (tid > HTT_DATA_TX_EXT_TID_MGMT - 2) 179 return -EINVAL; 180 181 mutex_lock(&ar->conf_mutex); 182 if ((ar->state != ATH10K_STATE_ON) || 183 (arsta->aggr_mode != ATH10K_DBG_AGGR_MODE_MANUAL)) { 184 ret = count; 185 goto out; 186 } 187 188 ret = ath10k_wmi_addba_send(ar, arsta->arvif->vdev_id, sta->addr, 189 tid, buf_size); 190 if (ret) { 191 ath10k_warn(ar, "failed to send addba request: vdev_id %u peer %pM tid %u buf_size %u\n", 192 arsta->arvif->vdev_id, sta->addr, tid, buf_size); 193 } 194 195 ret = count; 196 out: 197 mutex_unlock(&ar->conf_mutex); 198 return ret; 199 } 200 201 static const struct file_operations fops_addba = { 202 .write = ath10k_dbg_sta_write_addba, 203 .open = simple_open, 204 .owner = THIS_MODULE, 205 .llseek = default_llseek, 206 }; 207 208 static ssize_t ath10k_dbg_sta_write_addba_resp(struct file *file, 209 const char __user *user_buf, 210 size_t count, loff_t *ppos) 211 { 212 struct ieee80211_sta *sta = file->private_data; 213 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv; 214 struct ath10k *ar = arsta->arvif->ar; 215 u32 tid, status; 216 int ret; 217 char buf[64]; 218 219 simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count); 220 221 /* make sure that buf is null terminated */ 222 buf[sizeof(buf) - 1] = '\0'; 223 224 ret = sscanf(buf, "%u %u", &tid, &status); 225 if (ret != 2) 226 return -EINVAL; 227 228 /* Valid TID values are 0 through 15 */ 229 if (tid > HTT_DATA_TX_EXT_TID_MGMT - 2) 230 return -EINVAL; 231 232 mutex_lock(&ar->conf_mutex); 233 if ((ar->state != ATH10K_STATE_ON) || 234 (arsta->aggr_mode != ATH10K_DBG_AGGR_MODE_MANUAL)) { 235 ret = count; 236 goto out; 237 } 238 239 ret = ath10k_wmi_addba_set_resp(ar, arsta->arvif->vdev_id, sta->addr, 240 tid, status); 241 if (ret) { 242 ath10k_warn(ar, "failed to send addba response: vdev_id %u peer %pM tid %u status%u\n", 243 arsta->arvif->vdev_id, sta->addr, tid, status); 244 } 245 ret = count; 246 out: 247 mutex_unlock(&ar->conf_mutex); 248 return ret; 249 } 250 251 static const struct file_operations fops_addba_resp = { 252 .write = ath10k_dbg_sta_write_addba_resp, 253 .open = simple_open, 254 .owner = THIS_MODULE, 255 .llseek = default_llseek, 256 }; 257 258 static ssize_t ath10k_dbg_sta_write_delba(struct file *file, 259 const char __user *user_buf, 260 size_t count, loff_t *ppos) 261 { 262 struct ieee80211_sta *sta = file->private_data; 263 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv; 264 struct ath10k *ar = arsta->arvif->ar; 265 u32 tid, initiator, reason; 266 int ret; 267 char buf[64]; 268 269 simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count); 270 271 /* make sure that buf is null terminated */ 272 buf[sizeof(buf) - 1] = '\0'; 273 274 ret = sscanf(buf, "%u %u %u", &tid, &initiator, &reason); 275 if (ret != 3) 276 return -EINVAL; 277 278 /* Valid TID values are 0 through 15 */ 279 if (tid > HTT_DATA_TX_EXT_TID_MGMT - 2) 280 return -EINVAL; 281 282 mutex_lock(&ar->conf_mutex); 283 if ((ar->state != ATH10K_STATE_ON) || 284 (arsta->aggr_mode != ATH10K_DBG_AGGR_MODE_MANUAL)) { 285 ret = count; 286 goto out; 287 } 288 289 ret = ath10k_wmi_delba_send(ar, arsta->arvif->vdev_id, sta->addr, 290 tid, initiator, reason); 291 if (ret) { 292 ath10k_warn(ar, "failed to send delba: vdev_id %u peer %pM tid %u initiator %u reason %u\n", 293 arsta->arvif->vdev_id, sta->addr, tid, initiator, 294 reason); 295 } 296 ret = count; 297 out: 298 mutex_unlock(&ar->conf_mutex); 299 return ret; 300 } 301 302 static const struct file_operations fops_delba = { 303 .write = ath10k_dbg_sta_write_delba, 304 .open = simple_open, 305 .owner = THIS_MODULE, 306 .llseek = default_llseek, 307 }; 308 309 static ssize_t ath10k_dbg_sta_read_peer_debug_trigger(struct file *file, 310 char __user *user_buf, 311 size_t count, 312 loff_t *ppos) 313 { 314 struct ieee80211_sta *sta = file->private_data; 315 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv; 316 struct ath10k *ar = arsta->arvif->ar; 317 char buf[8]; 318 int len = 0; 319 320 mutex_lock(&ar->conf_mutex); 321 len = scnprintf(buf, sizeof(buf) - len, 322 "Write 1 to once trigger the debug logs\n"); 323 mutex_unlock(&ar->conf_mutex); 324 325 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 326 } 327 328 static ssize_t 329 ath10k_dbg_sta_write_peer_debug_trigger(struct file *file, 330 const char __user *user_buf, 331 size_t count, loff_t *ppos) 332 { 333 struct ieee80211_sta *sta = file->private_data; 334 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv; 335 struct ath10k *ar = arsta->arvif->ar; 336 u8 peer_debug_trigger; 337 int ret; 338 339 if (kstrtou8_from_user(user_buf, count, 0, &peer_debug_trigger)) 340 return -EINVAL; 341 342 if (peer_debug_trigger != 1) 343 return -EINVAL; 344 345 mutex_lock(&ar->conf_mutex); 346 347 if (ar->state != ATH10K_STATE_ON) { 348 ret = -ENETDOWN; 349 goto out; 350 } 351 352 ret = ath10k_wmi_peer_set_param(ar, arsta->arvif->vdev_id, sta->addr, 353 WMI_PEER_DEBUG, peer_debug_trigger); 354 if (ret) { 355 ath10k_warn(ar, "failed to set param to trigger peer tid logs for station ret: %d\n", 356 ret); 357 goto out; 358 } 359 out: 360 mutex_unlock(&ar->conf_mutex); 361 return count; 362 } 363 364 static const struct file_operations fops_peer_debug_trigger = { 365 .open = simple_open, 366 .read = ath10k_dbg_sta_read_peer_debug_trigger, 367 .write = ath10k_dbg_sta_write_peer_debug_trigger, 368 .owner = THIS_MODULE, 369 .llseek = default_llseek, 370 }; 371 372 void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 373 struct ieee80211_sta *sta, struct dentry *dir) 374 { 375 debugfs_create_file("aggr_mode", S_IRUGO | S_IWUSR, dir, sta, 376 &fops_aggr_mode); 377 debugfs_create_file("addba", S_IWUSR, dir, sta, &fops_addba); 378 debugfs_create_file("addba_resp", S_IWUSR, dir, sta, &fops_addba_resp); 379 debugfs_create_file("delba", S_IWUSR, dir, sta, &fops_delba); 380 debugfs_create_file("peer_debug_trigger", 0600, dir, sta, 381 &fops_peer_debug_trigger); 382 } 383