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