debugfs_sta.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  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. #include "core.h"
  17. #include "wmi-ops.h"
  18. #include "debug.h"
  19. static void ath10k_sta_update_extd_stats_rx_duration(struct ath10k *ar,
  20. struct ath10k_fw_stats *stats)
  21. {
  22. struct ath10k_fw_extd_stats_peer *peer;
  23. struct ieee80211_sta *sta;
  24. struct ath10k_sta *arsta;
  25. rcu_read_lock();
  26. list_for_each_entry(peer, &stats->peers_extd, list) {
  27. sta = ieee80211_find_sta_by_ifaddr(ar->hw, peer->peer_macaddr,
  28. NULL);
  29. if (!sta)
  30. continue;
  31. arsta = (struct ath10k_sta *)sta->drv_priv;
  32. arsta->rx_duration += (u64)peer->rx_duration;
  33. }
  34. rcu_read_unlock();
  35. }
  36. static void ath10k_sta_update_stats_rx_duration(struct ath10k *ar,
  37. struct ath10k_fw_stats *stats)
  38. {
  39. struct ath10k_fw_stats_peer *peer;
  40. struct ieee80211_sta *sta;
  41. struct ath10k_sta *arsta;
  42. rcu_read_lock();
  43. list_for_each_entry(peer, &stats->peers, list) {
  44. sta = ieee80211_find_sta_by_ifaddr(ar->hw, peer->peer_macaddr,
  45. NULL);
  46. if (!sta)
  47. continue;
  48. arsta = (struct ath10k_sta *)sta->drv_priv;
  49. arsta->rx_duration += (u64)peer->rx_duration;
  50. }
  51. rcu_read_unlock();
  52. }
  53. void ath10k_sta_update_rx_duration(struct ath10k *ar,
  54. struct ath10k_fw_stats *stats)
  55. {
  56. if (stats->extended)
  57. ath10k_sta_update_extd_stats_rx_duration(ar, stats);
  58. else
  59. ath10k_sta_update_stats_rx_duration(ar, stats);
  60. }
  61. void ath10k_sta_statistics(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  62. struct ieee80211_sta *sta,
  63. struct station_info *sinfo)
  64. {
  65. struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
  66. struct ath10k *ar = arsta->arvif->ar;
  67. if (!ath10k_peer_stats_enabled(ar))
  68. return;
  69. sinfo->rx_duration = arsta->rx_duration;
  70. sinfo->filled |= 1ULL << NL80211_STA_INFO_RX_DURATION;
  71. if (!arsta->txrate.legacy && !arsta->txrate.nss)
  72. return;
  73. if (arsta->txrate.legacy) {
  74. sinfo->txrate.legacy = arsta->txrate.legacy;
  75. } else {
  76. sinfo->txrate.mcs = arsta->txrate.mcs;
  77. sinfo->txrate.nss = arsta->txrate.nss;
  78. sinfo->txrate.bw = arsta->txrate.bw;
  79. }
  80. sinfo->txrate.flags = arsta->txrate.flags;
  81. sinfo->filled |= 1ULL << NL80211_STA_INFO_TX_BITRATE;
  82. }
  83. static ssize_t ath10k_dbg_sta_read_aggr_mode(struct file *file,
  84. char __user *user_buf,
  85. size_t count, loff_t *ppos)
  86. {
  87. struct ieee80211_sta *sta = file->private_data;
  88. struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
  89. struct ath10k *ar = arsta->arvif->ar;
  90. char buf[32];
  91. int len = 0;
  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) ?
  95. "auto" : "manual");
  96. mutex_unlock(&ar->conf_mutex);
  97. return simple_read_from_buffer(user_buf, count, ppos, buf, len);
  98. }
  99. static ssize_t ath10k_dbg_sta_write_aggr_mode(struct file *file,
  100. const char __user *user_buf,
  101. size_t count, loff_t *ppos)
  102. {
  103. struct ieee80211_sta *sta = file->private_data;
  104. struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
  105. struct ath10k *ar = arsta->arvif->ar;
  106. u32 aggr_mode;
  107. int ret;
  108. if (kstrtouint_from_user(user_buf, count, 0, &aggr_mode))
  109. return -EINVAL;
  110. if (aggr_mode >= ATH10K_DBG_AGGR_MODE_MAX)
  111. return -EINVAL;
  112. mutex_lock(&ar->conf_mutex);
  113. if ((ar->state != ATH10K_STATE_ON) ||
  114. (aggr_mode == arsta->aggr_mode)) {
  115. ret = count;
  116. goto out;
  117. }
  118. ret = ath10k_wmi_addba_clear_resp(ar, arsta->arvif->vdev_id, sta->addr);
  119. if (ret) {
  120. ath10k_warn(ar, "failed to clear addba session ret: %d\n", ret);
  121. goto out;
  122. }
  123. arsta->aggr_mode = aggr_mode;
  124. out:
  125. mutex_unlock(&ar->conf_mutex);
  126. return ret;
  127. }
  128. static const struct file_operations fops_aggr_mode = {
  129. .read = ath10k_dbg_sta_read_aggr_mode,
  130. .write = ath10k_dbg_sta_write_aggr_mode,
  131. .open = simple_open,
  132. .owner = THIS_MODULE,
  133. .llseek = default_llseek,
  134. };
  135. static ssize_t ath10k_dbg_sta_write_addba(struct file *file,
  136. const char __user *user_buf,
  137. size_t count, loff_t *ppos)
  138. {
  139. struct ieee80211_sta *sta = file->private_data;
  140. struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
  141. struct ath10k *ar = arsta->arvif->ar;
  142. u32 tid, buf_size;
  143. int ret;
  144. char buf[64];
  145. simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
  146. /* make sure that buf is null terminated */
  147. buf[sizeof(buf) - 1] = '\0';
  148. ret = sscanf(buf, "%u %u", &tid, &buf_size);
  149. if (ret != 2)
  150. return -EINVAL;
  151. /* Valid TID values are 0 through 15 */
  152. if (tid > HTT_DATA_TX_EXT_TID_MGMT - 2)
  153. return -EINVAL;
  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. ret = ath10k_wmi_addba_send(ar, arsta->arvif->vdev_id, sta->addr,
  161. tid, buf_size);
  162. if (ret) {
  163. ath10k_warn(ar, "failed to send addba request: vdev_id %u peer %pM tid %u buf_size %u\n",
  164. arsta->arvif->vdev_id, sta->addr, tid, buf_size);
  165. }
  166. ret = count;
  167. out:
  168. mutex_unlock(&ar->conf_mutex);
  169. return ret;
  170. }
  171. static const struct file_operations fops_addba = {
  172. .write = ath10k_dbg_sta_write_addba,
  173. .open = simple_open,
  174. .owner = THIS_MODULE,
  175. .llseek = default_llseek,
  176. };
  177. static ssize_t ath10k_dbg_sta_write_addba_resp(struct file *file,
  178. const char __user *user_buf,
  179. size_t count, loff_t *ppos)
  180. {
  181. struct ieee80211_sta *sta = file->private_data;
  182. struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
  183. struct ath10k *ar = arsta->arvif->ar;
  184. u32 tid, status;
  185. int ret;
  186. char buf[64];
  187. simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
  188. /* make sure that buf is null terminated */
  189. buf[sizeof(buf) - 1] = '\0';
  190. ret = sscanf(buf, "%u %u", &tid, &status);
  191. if (ret != 2)
  192. return -EINVAL;
  193. /* Valid TID values are 0 through 15 */
  194. if (tid > HTT_DATA_TX_EXT_TID_MGMT - 2)
  195. return -EINVAL;
  196. mutex_lock(&ar->conf_mutex);
  197. if ((ar->state != ATH10K_STATE_ON) ||
  198. (arsta->aggr_mode != ATH10K_DBG_AGGR_MODE_MANUAL)) {
  199. ret = count;
  200. goto out;
  201. }
  202. ret = ath10k_wmi_addba_set_resp(ar, arsta->arvif->vdev_id, sta->addr,
  203. tid, status);
  204. if (ret) {
  205. ath10k_warn(ar, "failed to send addba response: vdev_id %u peer %pM tid %u status%u\n",
  206. arsta->arvif->vdev_id, sta->addr, tid, status);
  207. }
  208. ret = count;
  209. out:
  210. mutex_unlock(&ar->conf_mutex);
  211. return ret;
  212. }
  213. static const struct file_operations fops_addba_resp = {
  214. .write = ath10k_dbg_sta_write_addba_resp,
  215. .open = simple_open,
  216. .owner = THIS_MODULE,
  217. .llseek = default_llseek,
  218. };
  219. static ssize_t ath10k_dbg_sta_write_delba(struct file *file,
  220. const char __user *user_buf,
  221. size_t count, loff_t *ppos)
  222. {
  223. struct ieee80211_sta *sta = file->private_data;
  224. struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
  225. struct ath10k *ar = arsta->arvif->ar;
  226. u32 tid, initiator, reason;
  227. int ret;
  228. char buf[64];
  229. simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
  230. /* make sure that buf is null terminated */
  231. buf[sizeof(buf) - 1] = '\0';
  232. ret = sscanf(buf, "%u %u %u", &tid, &initiator, &reason);
  233. if (ret != 3)
  234. return -EINVAL;
  235. /* Valid TID values are 0 through 15 */
  236. if (tid > HTT_DATA_TX_EXT_TID_MGMT - 2)
  237. return -EINVAL;
  238. mutex_lock(&ar->conf_mutex);
  239. if ((ar->state != ATH10K_STATE_ON) ||
  240. (arsta->aggr_mode != ATH10K_DBG_AGGR_MODE_MANUAL)) {
  241. ret = count;
  242. goto out;
  243. }
  244. ret = ath10k_wmi_delba_send(ar, arsta->arvif->vdev_id, sta->addr,
  245. tid, initiator, reason);
  246. if (ret) {
  247. ath10k_warn(ar, "failed to send delba: vdev_id %u peer %pM tid %u initiator %u reason %u\n",
  248. arsta->arvif->vdev_id, sta->addr, tid, initiator,
  249. reason);
  250. }
  251. ret = count;
  252. out:
  253. mutex_unlock(&ar->conf_mutex);
  254. return ret;
  255. }
  256. static const struct file_operations fops_delba = {
  257. .write = ath10k_dbg_sta_write_delba,
  258. .open = simple_open,
  259. .owner = THIS_MODULE,
  260. .llseek = default_llseek,
  261. };
  262. static ssize_t ath10k_dbg_sta_read_peer_debug_trigger(struct file *file,
  263. char __user *user_buf,
  264. size_t count,
  265. loff_t *ppos)
  266. {
  267. struct ieee80211_sta *sta = file->private_data;
  268. struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
  269. struct ath10k *ar = arsta->arvif->ar;
  270. char buf[8];
  271. int len = 0;
  272. mutex_lock(&ar->conf_mutex);
  273. len = scnprintf(buf, sizeof(buf) - len,
  274. "Write 1 to once trigger the debug logs\n");
  275. mutex_unlock(&ar->conf_mutex);
  276. return simple_read_from_buffer(user_buf, count, ppos, buf, len);
  277. }
  278. static ssize_t
  279. ath10k_dbg_sta_write_peer_debug_trigger(struct file *file,
  280. const char __user *user_buf,
  281. size_t count, loff_t *ppos)
  282. {
  283. struct ieee80211_sta *sta = file->private_data;
  284. struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
  285. struct ath10k *ar = arsta->arvif->ar;
  286. u8 peer_debug_trigger;
  287. int ret;
  288. if (kstrtou8_from_user(user_buf, count, 0, &peer_debug_trigger))
  289. return -EINVAL;
  290. if (peer_debug_trigger != 1)
  291. return -EINVAL;
  292. mutex_lock(&ar->conf_mutex);
  293. if (ar->state != ATH10K_STATE_ON) {
  294. ret = -ENETDOWN;
  295. goto out;
  296. }
  297. ret = ath10k_wmi_peer_set_param(ar, arsta->arvif->vdev_id, sta->addr,
  298. WMI_PEER_DEBUG, peer_debug_trigger);
  299. if (ret) {
  300. ath10k_warn(ar, "failed to set param to trigger peer tid logs for station ret: %d\n",
  301. ret);
  302. goto out;
  303. }
  304. out:
  305. mutex_unlock(&ar->conf_mutex);
  306. return count;
  307. }
  308. static const struct file_operations fops_peer_debug_trigger = {
  309. .open = simple_open,
  310. .read = ath10k_dbg_sta_read_peer_debug_trigger,
  311. .write = ath10k_dbg_sta_write_peer_debug_trigger,
  312. .owner = THIS_MODULE,
  313. .llseek = default_llseek,
  314. };
  315. void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  316. struct ieee80211_sta *sta, struct dentry *dir)
  317. {
  318. debugfs_create_file("aggr_mode", 0644, dir, sta, &fops_aggr_mode);
  319. debugfs_create_file("addba", 0200, dir, sta, &fops_addba);
  320. debugfs_create_file("addba_resp", 0200, dir, sta, &fops_addba_resp);
  321. debugfs_create_file("delba", 0200, dir, sta, &fops_delba);
  322. debugfs_create_file("peer_debug_trigger", 0600, dir, sta,
  323. &fops_peer_debug_trigger);
  324. }