root/drivers/net/wireless/ath/ath10k/debugfs_sta.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ath10k_rx_stats_update_amsdu_subfrm
  2. ath10k_rx_stats_update_ampdu_subfrm
  3. ath10k_sta_update_rx_tid_stats_ampdu
  4. ath10k_sta_update_rx_tid_stats
  5. ath10k_sta_update_extd_stats_rx_duration
  6. ath10k_sta_update_stats_rx_duration
  7. ath10k_sta_update_rx_duration
  8. ath10k_dbg_sta_read_aggr_mode
  9. ath10k_dbg_sta_write_aggr_mode
  10. ath10k_dbg_sta_write_addba
  11. ath10k_dbg_sta_write_addba_resp
  12. ath10k_dbg_sta_write_delba
  13. ath10k_dbg_sta_read_peer_debug_trigger
  14. ath10k_dbg_sta_write_peer_debug_trigger
  15. ath10k_dbg_sta_read_peer_ps_state
  16. get_err_str
  17. get_num_ampdu_subfrm_str
  18. get_num_amsdu_subfrm_str
  19. ath10k_dbg_sta_read_tid_stats
  20. ath10k_dbg_sta_dump_tx_stats
  21. ath10k_sta_add_debugfs

   1 // SPDX-License-Identifier: ISC
   2 /*
   3  * Copyright (c) 2014-2017 Qualcomm Atheros, Inc.
   4  * Copyright (c) 2018, The Linux Foundation. All rights reserved.
   5  */
   6 
   7 #include "core.h"
   8 #include "wmi-ops.h"
   9 #include "txrx.h"
  10 #include "debug.h"
  11 
  12 static void ath10k_rx_stats_update_amsdu_subfrm(struct ath10k *ar,
  13                                                 struct ath10k_sta_tid_stats *stats,
  14                                                 u32 msdu_count)
  15 {
  16         if (msdu_count == 1)
  17                 stats->rx_pkt_amsdu[ATH10K_AMSDU_SUBFRM_NUM_1]++;
  18         else if (msdu_count == 2)
  19                 stats->rx_pkt_amsdu[ATH10K_AMSDU_SUBFRM_NUM_2]++;
  20         else if (msdu_count == 3)
  21                 stats->rx_pkt_amsdu[ATH10K_AMSDU_SUBFRM_NUM_3]++;
  22         else if (msdu_count == 4)
  23                 stats->rx_pkt_amsdu[ATH10K_AMSDU_SUBFRM_NUM_4]++;
  24         else if (msdu_count > 4)
  25                 stats->rx_pkt_amsdu[ATH10K_AMSDU_SUBFRM_NUM_MORE]++;
  26 }
  27 
  28 static void ath10k_rx_stats_update_ampdu_subfrm(struct ath10k *ar,
  29                                                 struct ath10k_sta_tid_stats *stats,
  30                                                 u32 mpdu_count)
  31 {
  32         if (mpdu_count <= 10)
  33                 stats->rx_pkt_ampdu[ATH10K_AMPDU_SUBFRM_NUM_10]++;
  34         else if (mpdu_count <= 20)
  35                 stats->rx_pkt_ampdu[ATH10K_AMPDU_SUBFRM_NUM_20]++;
  36         else if (mpdu_count <= 30)
  37                 stats->rx_pkt_ampdu[ATH10K_AMPDU_SUBFRM_NUM_30]++;
  38         else if (mpdu_count <= 40)
  39                 stats->rx_pkt_ampdu[ATH10K_AMPDU_SUBFRM_NUM_40]++;
  40         else if (mpdu_count <= 50)
  41                 stats->rx_pkt_ampdu[ATH10K_AMPDU_SUBFRM_NUM_50]++;
  42         else if (mpdu_count <= 60)
  43                 stats->rx_pkt_ampdu[ATH10K_AMPDU_SUBFRM_NUM_60]++;
  44         else if (mpdu_count > 60)
  45                 stats->rx_pkt_ampdu[ATH10K_AMPDU_SUBFRM_NUM_MORE]++;
  46 }
  47 
  48 void ath10k_sta_update_rx_tid_stats_ampdu(struct ath10k *ar, u16 peer_id, u8 tid,
  49                                           struct htt_rx_indication_mpdu_range *ranges,
  50                                           int num_ranges)
  51 {
  52         struct ath10k_sta *arsta;
  53         struct ath10k_peer *peer;
  54         int i;
  55 
  56         if (tid > IEEE80211_NUM_TIDS || !(ar->sta_tid_stats_mask & BIT(tid)))
  57                 return;
  58 
  59         rcu_read_lock();
  60         spin_lock_bh(&ar->data_lock);
  61 
  62         peer = ath10k_peer_find_by_id(ar, peer_id);
  63         if (!peer || !peer->sta)
  64                 goto out;
  65 
  66         arsta = (struct ath10k_sta *)peer->sta->drv_priv;
  67 
  68         for (i = 0; i < num_ranges; i++)
  69                 ath10k_rx_stats_update_ampdu_subfrm(ar,
  70                                                     &arsta->tid_stats[tid],
  71                                                     ranges[i].mpdu_count);
  72 
  73 out:
  74         spin_unlock_bh(&ar->data_lock);
  75         rcu_read_unlock();
  76 }
  77 
  78 void ath10k_sta_update_rx_tid_stats(struct ath10k *ar, u8 *first_hdr,
  79                                     unsigned long num_msdus,
  80                                     enum ath10k_pkt_rx_err err,
  81                                     unsigned long unchain_cnt,
  82                                     unsigned long drop_cnt,
  83                                     unsigned long drop_cnt_filter,
  84                                     unsigned long queued_msdus)
  85 {
  86         struct ieee80211_sta *sta;
  87         struct ath10k_sta *arsta;
  88         struct ieee80211_hdr *hdr;
  89         struct ath10k_sta_tid_stats *stats;
  90         u8 tid = IEEE80211_NUM_TIDS;
  91         bool non_data_frm = false;
  92 
  93         hdr = (struct ieee80211_hdr *)first_hdr;
  94         if (!ieee80211_is_data(hdr->frame_control))
  95                 non_data_frm = true;
  96 
  97         if (ieee80211_is_data_qos(hdr->frame_control))
  98                 tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
  99 
 100         if (!(ar->sta_tid_stats_mask & BIT(tid)) || non_data_frm)
 101                 return;
 102 
 103         rcu_read_lock();
 104 
 105         sta = ieee80211_find_sta_by_ifaddr(ar->hw, hdr->addr2, NULL);
 106         if (!sta)
 107                 goto exit;
 108 
 109         arsta = (struct ath10k_sta *)sta->drv_priv;
 110 
 111         spin_lock_bh(&ar->data_lock);
 112         stats = &arsta->tid_stats[tid];
 113         stats->rx_pkt_from_fw += num_msdus;
 114         stats->rx_pkt_unchained += unchain_cnt;
 115         stats->rx_pkt_drop_chained += drop_cnt;
 116         stats->rx_pkt_drop_filter += drop_cnt_filter;
 117         if (err != ATH10K_PKT_RX_ERR_MAX)
 118                 stats->rx_pkt_err[err] += queued_msdus;
 119         stats->rx_pkt_queued_for_mac += queued_msdus;
 120         ath10k_rx_stats_update_amsdu_subfrm(ar, &arsta->tid_stats[tid],
 121                                             num_msdus);
 122         spin_unlock_bh(&ar->data_lock);
 123 
 124 exit:
 125         rcu_read_unlock();
 126 }
 127 
 128 static void ath10k_sta_update_extd_stats_rx_duration(struct ath10k *ar,
 129                                                      struct ath10k_fw_stats *stats)
 130 {
 131         struct ath10k_fw_extd_stats_peer *peer;
 132         struct ieee80211_sta *sta;
 133         struct ath10k_sta *arsta;
 134 
 135         rcu_read_lock();
 136         list_for_each_entry(peer, &stats->peers_extd, list) {
 137                 sta = ieee80211_find_sta_by_ifaddr(ar->hw, peer->peer_macaddr,
 138                                                    NULL);
 139                 if (!sta)
 140                         continue;
 141                 arsta = (struct ath10k_sta *)sta->drv_priv;
 142                 arsta->rx_duration += (u64)peer->rx_duration;
 143         }
 144         rcu_read_unlock();
 145 }
 146 
 147 static void ath10k_sta_update_stats_rx_duration(struct ath10k *ar,
 148                                                 struct ath10k_fw_stats *stats)
 149 {
 150         struct ath10k_fw_stats_peer *peer;
 151         struct ieee80211_sta *sta;
 152         struct ath10k_sta *arsta;
 153 
 154         rcu_read_lock();
 155         list_for_each_entry(peer, &stats->peers, list) {
 156                 sta = ieee80211_find_sta_by_ifaddr(ar->hw, peer->peer_macaddr,
 157                                                    NULL);
 158                 if (!sta)
 159                         continue;
 160                 arsta = (struct ath10k_sta *)sta->drv_priv;
 161                 arsta->rx_duration += (u64)peer->rx_duration;
 162         }
 163         rcu_read_unlock();
 164 }
 165 
 166 void ath10k_sta_update_rx_duration(struct ath10k *ar,
 167                                    struct ath10k_fw_stats *stats)
 168 {
 169         if (stats->extended)
 170                 ath10k_sta_update_extd_stats_rx_duration(ar, stats);
 171         else
 172                 ath10k_sta_update_stats_rx_duration(ar, stats);
 173 }
 174 
 175 static ssize_t ath10k_dbg_sta_read_aggr_mode(struct file *file,
 176                                              char __user *user_buf,
 177                                              size_t count, loff_t *ppos)
 178 {
 179         struct ieee80211_sta *sta = file->private_data;
 180         struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
 181         struct ath10k *ar = arsta->arvif->ar;
 182         char buf[32];
 183         int len = 0;
 184 
 185         mutex_lock(&ar->conf_mutex);
 186         len = scnprintf(buf, sizeof(buf) - len, "aggregation mode: %s\n",
 187                         (arsta->aggr_mode == ATH10K_DBG_AGGR_MODE_AUTO) ?
 188                         "auto" : "manual");
 189         mutex_unlock(&ar->conf_mutex);
 190 
 191         return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 192 }
 193 
 194 static ssize_t ath10k_dbg_sta_write_aggr_mode(struct file *file,
 195                                               const char __user *user_buf,
 196                                               size_t count, loff_t *ppos)
 197 {
 198         struct ieee80211_sta *sta = file->private_data;
 199         struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
 200         struct ath10k *ar = arsta->arvif->ar;
 201         u32 aggr_mode;
 202         int ret;
 203 
 204         if (kstrtouint_from_user(user_buf, count, 0, &aggr_mode))
 205                 return -EINVAL;
 206 
 207         if (aggr_mode >= ATH10K_DBG_AGGR_MODE_MAX)
 208                 return -EINVAL;
 209 
 210         mutex_lock(&ar->conf_mutex);
 211         if ((ar->state != ATH10K_STATE_ON) ||
 212             (aggr_mode == arsta->aggr_mode)) {
 213                 ret = count;
 214                 goto out;
 215         }
 216 
 217         ret = ath10k_wmi_addba_clear_resp(ar, arsta->arvif->vdev_id, sta->addr);
 218         if (ret) {
 219                 ath10k_warn(ar, "failed to clear addba session ret: %d\n", ret);
 220                 goto out;
 221         }
 222 
 223         arsta->aggr_mode = aggr_mode;
 224 out:
 225         mutex_unlock(&ar->conf_mutex);
 226         return ret;
 227 }
 228 
 229 static const struct file_operations fops_aggr_mode = {
 230         .read = ath10k_dbg_sta_read_aggr_mode,
 231         .write = ath10k_dbg_sta_write_aggr_mode,
 232         .open = simple_open,
 233         .owner = THIS_MODULE,
 234         .llseek = default_llseek,
 235 };
 236 
 237 static ssize_t ath10k_dbg_sta_write_addba(struct file *file,
 238                                           const char __user *user_buf,
 239                                           size_t count, loff_t *ppos)
 240 {
 241         struct ieee80211_sta *sta = file->private_data;
 242         struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
 243         struct ath10k *ar = arsta->arvif->ar;
 244         u32 tid, buf_size;
 245         int ret;
 246         char buf[64] = {0};
 247 
 248         ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos,
 249                                      user_buf, count);
 250         if (ret <= 0)
 251                 return ret;
 252 
 253         ret = sscanf(buf, "%u %u", &tid, &buf_size);
 254         if (ret != 2)
 255                 return -EINVAL;
 256 
 257         /* Valid TID values are 0 through 15 */
 258         if (tid > HTT_DATA_TX_EXT_TID_MGMT - 2)
 259                 return -EINVAL;
 260 
 261         mutex_lock(&ar->conf_mutex);
 262         if ((ar->state != ATH10K_STATE_ON) ||
 263             (arsta->aggr_mode != ATH10K_DBG_AGGR_MODE_MANUAL)) {
 264                 ret = count;
 265                 goto out;
 266         }
 267 
 268         ret = ath10k_wmi_addba_send(ar, arsta->arvif->vdev_id, sta->addr,
 269                                     tid, buf_size);
 270         if (ret) {
 271                 ath10k_warn(ar, "failed to send addba request: vdev_id %u peer %pM tid %u buf_size %u\n",
 272                             arsta->arvif->vdev_id, sta->addr, tid, buf_size);
 273         }
 274 
 275         ret = count;
 276 out:
 277         mutex_unlock(&ar->conf_mutex);
 278         return ret;
 279 }
 280 
 281 static const struct file_operations fops_addba = {
 282         .write = ath10k_dbg_sta_write_addba,
 283         .open = simple_open,
 284         .owner = THIS_MODULE,
 285         .llseek = default_llseek,
 286 };
 287 
 288 static ssize_t ath10k_dbg_sta_write_addba_resp(struct file *file,
 289                                                const char __user *user_buf,
 290                                                size_t count, loff_t *ppos)
 291 {
 292         struct ieee80211_sta *sta = file->private_data;
 293         struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
 294         struct ath10k *ar = arsta->arvif->ar;
 295         u32 tid, status;
 296         int ret;
 297         char buf[64] = {0};
 298 
 299         ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos,
 300                                      user_buf, count);
 301         if (ret <= 0)
 302                 return ret;
 303 
 304         ret = sscanf(buf, "%u %u", &tid, &status);
 305         if (ret != 2)
 306                 return -EINVAL;
 307 
 308         /* Valid TID values are 0 through 15 */
 309         if (tid > HTT_DATA_TX_EXT_TID_MGMT - 2)
 310                 return -EINVAL;
 311 
 312         mutex_lock(&ar->conf_mutex);
 313         if ((ar->state != ATH10K_STATE_ON) ||
 314             (arsta->aggr_mode != ATH10K_DBG_AGGR_MODE_MANUAL)) {
 315                 ret = count;
 316                 goto out;
 317         }
 318 
 319         ret = ath10k_wmi_addba_set_resp(ar, arsta->arvif->vdev_id, sta->addr,
 320                                         tid, status);
 321         if (ret) {
 322                 ath10k_warn(ar, "failed to send addba response: vdev_id %u peer %pM tid %u status%u\n",
 323                             arsta->arvif->vdev_id, sta->addr, tid, status);
 324         }
 325         ret = count;
 326 out:
 327         mutex_unlock(&ar->conf_mutex);
 328         return ret;
 329 }
 330 
 331 static const struct file_operations fops_addba_resp = {
 332         .write = ath10k_dbg_sta_write_addba_resp,
 333         .open = simple_open,
 334         .owner = THIS_MODULE,
 335         .llseek = default_llseek,
 336 };
 337 
 338 static ssize_t ath10k_dbg_sta_write_delba(struct file *file,
 339                                           const char __user *user_buf,
 340                                           size_t count, loff_t *ppos)
 341 {
 342         struct ieee80211_sta *sta = file->private_data;
 343         struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
 344         struct ath10k *ar = arsta->arvif->ar;
 345         u32 tid, initiator, reason;
 346         int ret;
 347         char buf[64] = {0};
 348 
 349         ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos,
 350                                      user_buf, count);
 351         if (ret <= 0)
 352                 return ret;
 353 
 354         ret = sscanf(buf, "%u %u %u", &tid, &initiator, &reason);
 355         if (ret != 3)
 356                 return -EINVAL;
 357 
 358         /* Valid TID values are 0 through 15 */
 359         if (tid > HTT_DATA_TX_EXT_TID_MGMT - 2)
 360                 return -EINVAL;
 361 
 362         mutex_lock(&ar->conf_mutex);
 363         if ((ar->state != ATH10K_STATE_ON) ||
 364             (arsta->aggr_mode != ATH10K_DBG_AGGR_MODE_MANUAL)) {
 365                 ret = count;
 366                 goto out;
 367         }
 368 
 369         ret = ath10k_wmi_delba_send(ar, arsta->arvif->vdev_id, sta->addr,
 370                                     tid, initiator, reason);
 371         if (ret) {
 372                 ath10k_warn(ar, "failed to send delba: vdev_id %u peer %pM tid %u initiator %u reason %u\n",
 373                             arsta->arvif->vdev_id, sta->addr, tid, initiator,
 374                             reason);
 375         }
 376         ret = count;
 377 out:
 378         mutex_unlock(&ar->conf_mutex);
 379         return ret;
 380 }
 381 
 382 static const struct file_operations fops_delba = {
 383         .write = ath10k_dbg_sta_write_delba,
 384         .open = simple_open,
 385         .owner = THIS_MODULE,
 386         .llseek = default_llseek,
 387 };
 388 
 389 static ssize_t ath10k_dbg_sta_read_peer_debug_trigger(struct file *file,
 390                                                       char __user *user_buf,
 391                                                       size_t count,
 392                                                       loff_t *ppos)
 393 {
 394         struct ieee80211_sta *sta = file->private_data;
 395         struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
 396         struct ath10k *ar = arsta->arvif->ar;
 397         char buf[8];
 398         int len = 0;
 399 
 400         mutex_lock(&ar->conf_mutex);
 401         len = scnprintf(buf, sizeof(buf) - len,
 402                         "Write 1 to once trigger the debug logs\n");
 403         mutex_unlock(&ar->conf_mutex);
 404 
 405         return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 406 }
 407 
 408 static ssize_t
 409 ath10k_dbg_sta_write_peer_debug_trigger(struct file *file,
 410                                         const char __user *user_buf,
 411                                         size_t count, loff_t *ppos)
 412 {
 413         struct ieee80211_sta *sta = file->private_data;
 414         struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
 415         struct ath10k *ar = arsta->arvif->ar;
 416         u8 peer_debug_trigger;
 417         int ret;
 418 
 419         if (kstrtou8_from_user(user_buf, count, 0, &peer_debug_trigger))
 420                 return -EINVAL;
 421 
 422         if (peer_debug_trigger != 1)
 423                 return -EINVAL;
 424 
 425         mutex_lock(&ar->conf_mutex);
 426 
 427         if (ar->state != ATH10K_STATE_ON) {
 428                 ret = -ENETDOWN;
 429                 goto out;
 430         }
 431 
 432         ret = ath10k_wmi_peer_set_param(ar, arsta->arvif->vdev_id, sta->addr,
 433                                         WMI_PEER_DEBUG, peer_debug_trigger);
 434         if (ret) {
 435                 ath10k_warn(ar, "failed to set param to trigger peer tid logs for station ret: %d\n",
 436                             ret);
 437                 goto out;
 438         }
 439 out:
 440         mutex_unlock(&ar->conf_mutex);
 441         return count;
 442 }
 443 
 444 static const struct file_operations fops_peer_debug_trigger = {
 445         .open = simple_open,
 446         .read = ath10k_dbg_sta_read_peer_debug_trigger,
 447         .write = ath10k_dbg_sta_write_peer_debug_trigger,
 448         .owner = THIS_MODULE,
 449         .llseek = default_llseek,
 450 };
 451 
 452 static ssize_t ath10k_dbg_sta_read_peer_ps_state(struct file *file,
 453                                                  char __user *user_buf,
 454                                                  size_t count, loff_t *ppos)
 455 {
 456         struct ieee80211_sta *sta = file->private_data;
 457         struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
 458         struct ath10k *ar = arsta->arvif->ar;
 459         char buf[20];
 460         int len = 0;
 461 
 462         spin_lock_bh(&ar->data_lock);
 463 
 464         len = scnprintf(buf, sizeof(buf) - len, "%d\n",
 465                         arsta->peer_ps_state);
 466 
 467         spin_unlock_bh(&ar->data_lock);
 468 
 469         return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 470 }
 471 
 472 static const struct file_operations fops_peer_ps_state = {
 473         .open = simple_open,
 474         .read = ath10k_dbg_sta_read_peer_ps_state,
 475         .owner = THIS_MODULE,
 476         .llseek = default_llseek,
 477 };
 478 
 479 static char *get_err_str(enum ath10k_pkt_rx_err i)
 480 {
 481         switch (i) {
 482         case ATH10K_PKT_RX_ERR_FCS:
 483                 return "fcs_err";
 484         case ATH10K_PKT_RX_ERR_TKIP:
 485                 return "tkip_err";
 486         case ATH10K_PKT_RX_ERR_CRYPT:
 487                 return "crypt_err";
 488         case ATH10K_PKT_RX_ERR_PEER_IDX_INVAL:
 489                 return "peer_idx_inval";
 490         case ATH10K_PKT_RX_ERR_MAX:
 491                 return "unknown";
 492         }
 493 
 494         return "unknown";
 495 }
 496 
 497 static char *get_num_ampdu_subfrm_str(enum ath10k_ampdu_subfrm_num i)
 498 {
 499         switch (i) {
 500         case ATH10K_AMPDU_SUBFRM_NUM_10:
 501                 return "upto 10";
 502         case ATH10K_AMPDU_SUBFRM_NUM_20:
 503                 return "11-20";
 504         case ATH10K_AMPDU_SUBFRM_NUM_30:
 505                 return "21-30";
 506         case ATH10K_AMPDU_SUBFRM_NUM_40:
 507                 return "31-40";
 508         case ATH10K_AMPDU_SUBFRM_NUM_50:
 509                 return "41-50";
 510         case ATH10K_AMPDU_SUBFRM_NUM_60:
 511                 return "51-60";
 512         case ATH10K_AMPDU_SUBFRM_NUM_MORE:
 513                 return ">60";
 514         case ATH10K_AMPDU_SUBFRM_NUM_MAX:
 515                 return "0";
 516         }
 517 
 518         return "0";
 519 }
 520 
 521 static char *get_num_amsdu_subfrm_str(enum ath10k_amsdu_subfrm_num i)
 522 {
 523         switch (i) {
 524         case ATH10K_AMSDU_SUBFRM_NUM_1:
 525                 return "1";
 526         case ATH10K_AMSDU_SUBFRM_NUM_2:
 527                 return "2";
 528         case ATH10K_AMSDU_SUBFRM_NUM_3:
 529                 return "3";
 530         case ATH10K_AMSDU_SUBFRM_NUM_4:
 531                 return "4";
 532         case ATH10K_AMSDU_SUBFRM_NUM_MORE:
 533                 return ">4";
 534         case ATH10K_AMSDU_SUBFRM_NUM_MAX:
 535                 return "0";
 536         }
 537 
 538         return "0";
 539 }
 540 
 541 #define PRINT_TID_STATS(_field, _tabs) \
 542         do { \
 543                 int k = 0; \
 544                 for (j = 0; j <= IEEE80211_NUM_TIDS; j++) { \
 545                         if (ar->sta_tid_stats_mask & BIT(j))  { \
 546                                 len += scnprintf(buf + len, buf_len - len, \
 547                                                  "[%02d] %-10lu  ", \
 548                                                  j, stats[j]._field); \
 549                                 k++; \
 550                                 if (k % 8 == 0)  { \
 551                                         len += scnprintf(buf + len, \
 552                                                          buf_len - len, "\n"); \
 553                                         len += scnprintf(buf + len, \
 554                                                          buf_len - len, \
 555                                                          _tabs); \
 556                                 } \
 557                         } \
 558                 } \
 559                 len += scnprintf(buf + len, buf_len - len, "\n"); \
 560         } while (0)
 561 
 562 static ssize_t ath10k_dbg_sta_read_tid_stats(struct file *file,
 563                                              char __user *user_buf,
 564                                              size_t count, loff_t *ppos)
 565 {
 566         struct ieee80211_sta *sta = file->private_data;
 567         struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
 568         struct ath10k *ar = arsta->arvif->ar;
 569         struct ath10k_sta_tid_stats *stats = arsta->tid_stats;
 570         size_t len = 0, buf_len = 1048 * IEEE80211_NUM_TIDS;
 571         char *buf;
 572         int i, j;
 573         ssize_t ret;
 574 
 575         buf = kzalloc(buf_len, GFP_KERNEL);
 576         if (!buf)
 577                 return -ENOMEM;
 578 
 579         mutex_lock(&ar->conf_mutex);
 580 
 581         spin_lock_bh(&ar->data_lock);
 582 
 583         len += scnprintf(buf + len, buf_len - len,
 584                          "\n\t\tDriver Rx pkt stats per tid, ([tid] count)\n");
 585         len += scnprintf(buf + len, buf_len - len,
 586                          "\t\t------------------------------------------\n");
 587         len += scnprintf(buf + len, buf_len - len, "MSDUs from FW\t\t\t");
 588         PRINT_TID_STATS(rx_pkt_from_fw, "\t\t\t\t");
 589 
 590         len += scnprintf(buf + len, buf_len - len, "MSDUs unchained\t\t\t");
 591         PRINT_TID_STATS(rx_pkt_unchained, "\t\t\t\t");
 592 
 593         len += scnprintf(buf + len, buf_len - len,
 594                          "MSDUs locally dropped:chained\t");
 595         PRINT_TID_STATS(rx_pkt_drop_chained, "\t\t\t\t");
 596 
 597         len += scnprintf(buf + len, buf_len - len,
 598                          "MSDUs locally dropped:filtered\t");
 599         PRINT_TID_STATS(rx_pkt_drop_filter, "\t\t\t\t");
 600 
 601         len += scnprintf(buf + len, buf_len - len,
 602                          "MSDUs queued for mac80211\t");
 603         PRINT_TID_STATS(rx_pkt_queued_for_mac, "\t\t\t\t");
 604 
 605         for (i = 0; i < ATH10K_PKT_RX_ERR_MAX; i++) {
 606                 len += scnprintf(buf + len, buf_len - len,
 607                                  "MSDUs with error:%s\t", get_err_str(i));
 608                 PRINT_TID_STATS(rx_pkt_err[i], "\t\t\t\t");
 609         }
 610 
 611         len += scnprintf(buf + len, buf_len - len, "\n");
 612         for (i = 0; i < ATH10K_AMPDU_SUBFRM_NUM_MAX; i++) {
 613                 len += scnprintf(buf + len, buf_len - len,
 614                                  "A-MPDU num subframes %s\t",
 615                                  get_num_ampdu_subfrm_str(i));
 616                 PRINT_TID_STATS(rx_pkt_ampdu[i], "\t\t\t\t");
 617         }
 618 
 619         len += scnprintf(buf + len, buf_len - len, "\n");
 620         for (i = 0; i < ATH10K_AMSDU_SUBFRM_NUM_MAX; i++) {
 621                 len += scnprintf(buf + len, buf_len - len,
 622                                  "A-MSDU num subframes %s\t\t",
 623                                  get_num_amsdu_subfrm_str(i));
 624                 PRINT_TID_STATS(rx_pkt_amsdu[i], "\t\t\t\t");
 625         }
 626 
 627         spin_unlock_bh(&ar->data_lock);
 628 
 629         ret = simple_read_from_buffer(user_buf, count, ppos, buf, len);
 630 
 631         kfree(buf);
 632 
 633         mutex_unlock(&ar->conf_mutex);
 634 
 635         return ret;
 636 }
 637 
 638 static const struct file_operations fops_tid_stats_dump = {
 639         .open = simple_open,
 640         .read = ath10k_dbg_sta_read_tid_stats,
 641         .owner = THIS_MODULE,
 642         .llseek = default_llseek,
 643 };
 644 
 645 static ssize_t ath10k_dbg_sta_dump_tx_stats(struct file *file,
 646                                             char __user *user_buf,
 647                                             size_t count, loff_t *ppos)
 648 {
 649         struct ieee80211_sta *sta = file->private_data;
 650         struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
 651         struct ath10k *ar = arsta->arvif->ar;
 652         struct ath10k_htt_data_stats *stats;
 653         const char *str_name[ATH10K_STATS_TYPE_MAX] = {"succ", "fail",
 654                                                        "retry", "ampdu"};
 655         const char *str[ATH10K_COUNTER_TYPE_MAX] = {"bytes", "packets"};
 656         int len = 0, i, j, k, retval = 0;
 657         const int size = 16 * 4096;
 658         char *buf;
 659 
 660         buf = kzalloc(size, GFP_KERNEL);
 661         if (!buf)
 662                 return -ENOMEM;
 663 
 664         mutex_lock(&ar->conf_mutex);
 665 
 666         if (!arsta->tx_stats) {
 667                 ath10k_warn(ar, "failed to get tx stats");
 668                 mutex_unlock(&ar->conf_mutex);
 669                 kfree(buf);
 670                 return 0;
 671         }
 672 
 673         spin_lock_bh(&ar->data_lock);
 674         for (k = 0; k < ATH10K_STATS_TYPE_MAX; k++) {
 675                 for (j = 0; j < ATH10K_COUNTER_TYPE_MAX; j++) {
 676                         stats = &arsta->tx_stats->stats[k];
 677                         len += scnprintf(buf + len, size - len, "%s_%s\n",
 678                                          str_name[k],
 679                                          str[j]);
 680                         len += scnprintf(buf + len, size - len,
 681                                          " VHT MCS %s\n",
 682                                          str[j]);
 683                         for (i = 0; i < ATH10K_VHT_MCS_NUM; i++)
 684                                 len += scnprintf(buf + len, size - len,
 685                                                  "  %llu ",
 686                                                  stats->vht[j][i]);
 687                         len += scnprintf(buf + len, size - len, "\n");
 688                         len += scnprintf(buf + len, size - len, " HT MCS %s\n",
 689                                          str[j]);
 690                         for (i = 0; i < ATH10K_HT_MCS_NUM; i++)
 691                                 len += scnprintf(buf + len, size - len,
 692                                                  "  %llu ", stats->ht[j][i]);
 693                         len += scnprintf(buf + len, size - len, "\n");
 694                         len += scnprintf(buf + len, size - len,
 695                                         " BW %s (20,5,10,40,80,160 MHz)\n", str[j]);
 696                         len += scnprintf(buf + len, size - len,
 697                                          "  %llu %llu %llu %llu %llu %llu\n",
 698                                          stats->bw[j][0], stats->bw[j][1],
 699                                          stats->bw[j][2], stats->bw[j][3],
 700                                          stats->bw[j][4], stats->bw[j][5]);
 701                         len += scnprintf(buf + len, size - len,
 702                                          " NSS %s (1x1,2x2,3x3,4x4)\n", str[j]);
 703                         len += scnprintf(buf + len, size - len,
 704                                          "  %llu %llu %llu %llu\n",
 705                                          stats->nss[j][0], stats->nss[j][1],
 706                                          stats->nss[j][2], stats->nss[j][3]);
 707                         len += scnprintf(buf + len, size - len,
 708                                          " GI %s (LGI,SGI)\n",
 709                                          str[j]);
 710                         len += scnprintf(buf + len, size - len, "  %llu %llu\n",
 711                                          stats->gi[j][0], stats->gi[j][1]);
 712                         len += scnprintf(buf + len, size - len,
 713                                          " legacy rate %s (1,2 ... Mbps)\n  ",
 714                                          str[j]);
 715                         for (i = 0; i < ATH10K_LEGACY_NUM; i++)
 716                                 len += scnprintf(buf + len, size - len, "%llu ",
 717                                                  stats->legacy[j][i]);
 718                         len += scnprintf(buf + len, size - len, "\n");
 719                         len += scnprintf(buf + len, size - len,
 720                                          " Rate table %s (1,2 ... Mbps)\n  ",
 721                                          str[j]);
 722                         for (i = 0; i < ATH10K_RATE_TABLE_NUM; i++) {
 723                                 len += scnprintf(buf + len, size - len, "%llu ",
 724                                                  stats->rate_table[j][i]);
 725                                 if (!((i + 1) % 8))
 726                                         len +=
 727                                         scnprintf(buf + len, size - len, "\n  ");
 728                         }
 729                 }
 730         }
 731 
 732         len += scnprintf(buf + len, size - len,
 733                          "\nTX duration\n %llu usecs\n",
 734                          arsta->tx_stats->tx_duration);
 735         len += scnprintf(buf + len, size - len,
 736                         "BA fails\n %llu\n", arsta->tx_stats->ba_fails);
 737         len += scnprintf(buf + len, size - len,
 738                         "ack fails\n %llu\n", arsta->tx_stats->ack_fails);
 739         spin_unlock_bh(&ar->data_lock);
 740 
 741         if (len > size)
 742                 len = size;
 743         retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
 744         kfree(buf);
 745 
 746         mutex_unlock(&ar->conf_mutex);
 747         return retval;
 748 }
 749 
 750 static const struct file_operations fops_tx_stats = {
 751         .read = ath10k_dbg_sta_dump_tx_stats,
 752         .open = simple_open,
 753         .owner = THIS_MODULE,
 754         .llseek = default_llseek,
 755 };
 756 
 757 void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 758                             struct ieee80211_sta *sta, struct dentry *dir)
 759 {
 760         struct ath10k *ar = hw->priv;
 761 
 762         debugfs_create_file("aggr_mode", 0644, dir, sta, &fops_aggr_mode);
 763         debugfs_create_file("addba", 0200, dir, sta, &fops_addba);
 764         debugfs_create_file("addba_resp", 0200, dir, sta, &fops_addba_resp);
 765         debugfs_create_file("delba", 0200, dir, sta, &fops_delba);
 766         debugfs_create_file("peer_debug_trigger", 0600, dir, sta,
 767                             &fops_peer_debug_trigger);
 768         debugfs_create_file("dump_tid_stats", 0400, dir, sta,
 769                             &fops_tid_stats_dump);
 770 
 771         if (ath10k_peer_stats_enabled(ar) &&
 772             ath10k_debug_is_extd_tx_stats_enabled(ar))
 773                 debugfs_create_file("tx_stats", 0400, dir, sta,
 774                                     &fops_tx_stats);
 775         debugfs_create_file("peer_ps_state", 0400, dir, sta,
 776                             &fops_peer_ps_state);
 777 }

/* [<][>][^][v][top][bottom][index][help] */