LCOV - code coverage report
Current view: top level - drivers/net/wireless/ath/ath10k - debugfs_sta.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 321 0.0 %
Date: 2022-03-28 15:32:58 Functions: 0 14 0.0 %
Branches: 0 162 0.0 %

           Branch data     Line data    Source code
       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                 :          0 : 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                 :          0 :         struct ath10k_sta *arsta;
      53                 :          0 :         struct ath10k_peer *peer;
      54                 :          0 :         int i;
      55                 :            : 
      56   [ #  #  #  # ]:          0 :         if (tid > IEEE80211_NUM_TIDS || !(ar->sta_tid_stats_mask & BIT(tid)))
      57                 :            :                 return;
      58                 :            : 
      59                 :          0 :         rcu_read_lock();
      60                 :          0 :         spin_lock_bh(&ar->data_lock);
      61                 :            : 
      62                 :          0 :         peer = ath10k_peer_find_by_id(ar, peer_id);
      63   [ #  #  #  # ]:          0 :         if (!peer || !peer->sta)
      64                 :          0 :                 goto out;
      65                 :            : 
      66                 :            :         arsta = (struct ath10k_sta *)peer->sta->drv_priv;
      67                 :            : 
      68         [ #  # ]:          0 :         for (i = 0; i < num_ranges; i++)
      69                 :          0 :                 ath10k_rx_stats_update_ampdu_subfrm(ar,
      70                 :            :                                                     &arsta->tid_stats[tid],
      71                 :          0 :                                                     ranges[i].mpdu_count);
      72                 :            : 
      73                 :          0 : out:
      74                 :          0 :         spin_unlock_bh(&ar->data_lock);
      75                 :          0 :         rcu_read_unlock();
      76                 :            : }
      77                 :            : 
      78                 :          0 : 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                 :          0 :         struct ieee80211_sta *sta;
      87                 :          0 :         struct ath10k_sta *arsta;
      88                 :          0 :         struct ieee80211_hdr *hdr;
      89                 :          0 :         struct ath10k_sta_tid_stats *stats;
      90                 :          0 :         u8 tid = IEEE80211_NUM_TIDS;
      91                 :          0 :         bool non_data_frm = false;
      92                 :            : 
      93                 :          0 :         hdr = (struct ieee80211_hdr *)first_hdr;
      94         [ #  # ]:          0 :         if (!ieee80211_is_data(hdr->frame_control))
      95                 :          0 :                 non_data_frm = true;
      96                 :            : 
      97         [ #  # ]:          0 :         if (ieee80211_is_data_qos(hdr->frame_control))
      98         [ #  # ]:          0 :                 tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
      99                 :            : 
     100   [ #  #  #  # ]:          0 :         if (!(ar->sta_tid_stats_mask & BIT(tid)) || non_data_frm)
     101                 :            :                 return;
     102                 :            : 
     103                 :          0 :         rcu_read_lock();
     104                 :            : 
     105                 :          0 :         sta = ieee80211_find_sta_by_ifaddr(ar->hw, hdr->addr2, NULL);
     106         [ #  # ]:          0 :         if (!sta)
     107                 :          0 :                 goto exit;
     108                 :            : 
     109                 :          0 :         arsta = (struct ath10k_sta *)sta->drv_priv;
     110                 :            : 
     111                 :          0 :         spin_lock_bh(&ar->data_lock);
     112                 :          0 :         stats = &arsta->tid_stats[tid];
     113                 :          0 :         stats->rx_pkt_from_fw += num_msdus;
     114                 :          0 :         stats->rx_pkt_unchained += unchain_cnt;
     115                 :          0 :         stats->rx_pkt_drop_chained += drop_cnt;
     116                 :          0 :         stats->rx_pkt_drop_filter += drop_cnt_filter;
     117         [ #  # ]:          0 :         if (err != ATH10K_PKT_RX_ERR_MAX)
     118                 :          0 :                 stats->rx_pkt_err[err] += queued_msdus;
     119                 :          0 :         stats->rx_pkt_queued_for_mac += queued_msdus;
     120                 :          0 :         ath10k_rx_stats_update_amsdu_subfrm(ar, &arsta->tid_stats[tid],
     121                 :            :                                             num_msdus);
     122                 :          0 :         spin_unlock_bh(&ar->data_lock);
     123                 :            : 
     124                 :          0 : exit:
     125                 :          0 :         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                 :          0 : void ath10k_sta_update_rx_duration(struct ath10k *ar,
     167                 :            :                                    struct ath10k_fw_stats *stats)
     168                 :            : {
     169         [ #  # ]:          0 :         if (stats->extended)
     170                 :          0 :                 ath10k_sta_update_extd_stats_rx_duration(ar, stats);
     171                 :            :         else
     172                 :          0 :                 ath10k_sta_update_stats_rx_duration(ar, stats);
     173                 :          0 : }
     174                 :            : 
     175                 :          0 : 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                 :          0 :         struct ieee80211_sta *sta = file->private_data;
     180                 :          0 :         struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
     181                 :          0 :         struct ath10k *ar = arsta->arvif->ar;
     182                 :          0 :         char buf[32];
     183                 :          0 :         int len = 0;
     184                 :            : 
     185                 :          0 :         mutex_lock(&ar->conf_mutex);
     186                 :          0 :         len = scnprintf(buf, sizeof(buf) - len, "aggregation mode: %s\n",
     187         [ #  # ]:          0 :                         (arsta->aggr_mode == ATH10K_DBG_AGGR_MODE_AUTO) ?
     188                 :            :                         "auto" : "manual");
     189                 :          0 :         mutex_unlock(&ar->conf_mutex);
     190                 :            : 
     191                 :          0 :         return simple_read_from_buffer(user_buf, count, ppos, buf, len);
     192                 :            : }
     193                 :            : 
     194                 :          0 : 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                 :          0 :         struct ieee80211_sta *sta = file->private_data;
     199                 :          0 :         struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
     200                 :          0 :         struct ath10k *ar = arsta->arvif->ar;
     201                 :          0 :         u32 aggr_mode;
     202                 :          0 :         int ret;
     203                 :            : 
     204         [ #  # ]:          0 :         if (kstrtouint_from_user(user_buf, count, 0, &aggr_mode))
     205                 :            :                 return -EINVAL;
     206                 :            : 
     207         [ #  # ]:          0 :         if (aggr_mode >= ATH10K_DBG_AGGR_MODE_MAX)
     208                 :            :                 return -EINVAL;
     209                 :            : 
     210                 :          0 :         mutex_lock(&ar->conf_mutex);
     211         [ #  # ]:          0 :         if ((ar->state != ATH10K_STATE_ON) ||
     212         [ #  # ]:          0 :             (aggr_mode == arsta->aggr_mode)) {
     213                 :          0 :                 ret = count;
     214                 :          0 :                 goto out;
     215                 :            :         }
     216                 :            : 
     217                 :          0 :         ret = ath10k_wmi_addba_clear_resp(ar, arsta->arvif->vdev_id, sta->addr);
     218         [ #  # ]:          0 :         if (ret) {
     219                 :          0 :                 ath10k_warn(ar, "failed to clear addba session ret: %d\n", ret);
     220                 :          0 :                 goto out;
     221                 :            :         }
     222                 :            : 
     223                 :          0 :         arsta->aggr_mode = aggr_mode;
     224                 :          0 : out:
     225                 :          0 :         mutex_unlock(&ar->conf_mutex);
     226                 :          0 :         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                 :          0 : 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                 :          0 :         struct ieee80211_sta *sta = file->private_data;
     242                 :          0 :         struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
     243                 :          0 :         struct ath10k *ar = arsta->arvif->ar;
     244                 :          0 :         u32 tid, buf_size;
     245                 :          0 :         int ret;
     246                 :          0 :         char buf[64] = {0};
     247                 :            : 
     248                 :          0 :         ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos,
     249                 :            :                                      user_buf, count);
     250         [ #  # ]:          0 :         if (ret <= 0)
     251                 :          0 :                 return ret;
     252                 :            : 
     253                 :          0 :         ret = sscanf(buf, "%u %u", &tid, &buf_size);
     254         [ #  # ]:          0 :         if (ret != 2)
     255                 :            :                 return -EINVAL;
     256                 :            : 
     257                 :            :         /* Valid TID values are 0 through 15 */
     258         [ #  # ]:          0 :         if (tid > HTT_DATA_TX_EXT_TID_MGMT - 2)
     259                 :            :                 return -EINVAL;
     260                 :            : 
     261                 :          0 :         mutex_lock(&ar->conf_mutex);
     262         [ #  # ]:          0 :         if ((ar->state != ATH10K_STATE_ON) ||
     263         [ #  # ]:          0 :             (arsta->aggr_mode != ATH10K_DBG_AGGR_MODE_MANUAL)) {
     264                 :          0 :                 ret = count;
     265                 :          0 :                 goto out;
     266                 :            :         }
     267                 :            : 
     268                 :          0 :         ret = ath10k_wmi_addba_send(ar, arsta->arvif->vdev_id, sta->addr,
     269                 :            :                                     tid, buf_size);
     270         [ #  # ]:          0 :         if (ret) {
     271                 :          0 :                 ath10k_warn(ar, "failed to send addba request: vdev_id %u peer %pM tid %u buf_size %u\n",
     272                 :          0 :                             arsta->arvif->vdev_id, sta->addr, tid, buf_size);
     273                 :            :         }
     274                 :            : 
     275                 :          0 :         ret = count;
     276                 :          0 : out:
     277                 :          0 :         mutex_unlock(&ar->conf_mutex);
     278                 :          0 :         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                 :          0 : 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                 :          0 :         struct ieee80211_sta *sta = file->private_data;
     293                 :          0 :         struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
     294                 :          0 :         struct ath10k *ar = arsta->arvif->ar;
     295                 :          0 :         u32 tid, status;
     296                 :          0 :         int ret;
     297                 :          0 :         char buf[64] = {0};
     298                 :            : 
     299                 :          0 :         ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos,
     300                 :            :                                      user_buf, count);
     301         [ #  # ]:          0 :         if (ret <= 0)
     302                 :          0 :                 return ret;
     303                 :            : 
     304                 :          0 :         ret = sscanf(buf, "%u %u", &tid, &status);
     305         [ #  # ]:          0 :         if (ret != 2)
     306                 :            :                 return -EINVAL;
     307                 :            : 
     308                 :            :         /* Valid TID values are 0 through 15 */
     309         [ #  # ]:          0 :         if (tid > HTT_DATA_TX_EXT_TID_MGMT - 2)
     310                 :            :                 return -EINVAL;
     311                 :            : 
     312                 :          0 :         mutex_lock(&ar->conf_mutex);
     313         [ #  # ]:          0 :         if ((ar->state != ATH10K_STATE_ON) ||
     314         [ #  # ]:          0 :             (arsta->aggr_mode != ATH10K_DBG_AGGR_MODE_MANUAL)) {
     315                 :          0 :                 ret = count;
     316                 :          0 :                 goto out;
     317                 :            :         }
     318                 :            : 
     319                 :          0 :         ret = ath10k_wmi_addba_set_resp(ar, arsta->arvif->vdev_id, sta->addr,
     320                 :            :                                         tid, status);
     321         [ #  # ]:          0 :         if (ret) {
     322                 :          0 :                 ath10k_warn(ar, "failed to send addba response: vdev_id %u peer %pM tid %u status%u\n",
     323                 :          0 :                             arsta->arvif->vdev_id, sta->addr, tid, status);
     324                 :            :         }
     325                 :          0 :         ret = count;
     326                 :          0 : out:
     327                 :          0 :         mutex_unlock(&ar->conf_mutex);
     328                 :          0 :         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                 :          0 : 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                 :          0 :         struct ieee80211_sta *sta = file->private_data;
     343                 :          0 :         struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
     344                 :          0 :         struct ath10k *ar = arsta->arvif->ar;
     345                 :          0 :         u32 tid, initiator, reason;
     346                 :          0 :         int ret;
     347                 :          0 :         char buf[64] = {0};
     348                 :            : 
     349                 :          0 :         ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos,
     350                 :            :                                      user_buf, count);
     351         [ #  # ]:          0 :         if (ret <= 0)
     352                 :          0 :                 return ret;
     353                 :            : 
     354                 :          0 :         ret = sscanf(buf, "%u %u %u", &tid, &initiator, &reason);
     355         [ #  # ]:          0 :         if (ret != 3)
     356                 :            :                 return -EINVAL;
     357                 :            : 
     358                 :            :         /* Valid TID values are 0 through 15 */
     359         [ #  # ]:          0 :         if (tid > HTT_DATA_TX_EXT_TID_MGMT - 2)
     360                 :            :                 return -EINVAL;
     361                 :            : 
     362                 :          0 :         mutex_lock(&ar->conf_mutex);
     363         [ #  # ]:          0 :         if ((ar->state != ATH10K_STATE_ON) ||
     364         [ #  # ]:          0 :             (arsta->aggr_mode != ATH10K_DBG_AGGR_MODE_MANUAL)) {
     365                 :          0 :                 ret = count;
     366                 :          0 :                 goto out;
     367                 :            :         }
     368                 :            : 
     369                 :          0 :         ret = ath10k_wmi_delba_send(ar, arsta->arvif->vdev_id, sta->addr,
     370                 :            :                                     tid, initiator, reason);
     371         [ #  # ]:          0 :         if (ret) {
     372                 :          0 :                 ath10k_warn(ar, "failed to send delba: vdev_id %u peer %pM tid %u initiator %u reason %u\n",
     373                 :          0 :                             arsta->arvif->vdev_id, sta->addr, tid, initiator,
     374                 :            :                             reason);
     375                 :            :         }
     376                 :          0 :         ret = count;
     377                 :          0 : out:
     378                 :          0 :         mutex_unlock(&ar->conf_mutex);
     379                 :          0 :         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                 :          0 : 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                 :          0 :         struct ieee80211_sta *sta = file->private_data;
     395                 :          0 :         struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
     396                 :          0 :         struct ath10k *ar = arsta->arvif->ar;
     397                 :          0 :         char buf[8];
     398                 :          0 :         int len = 0;
     399                 :            : 
     400                 :          0 :         mutex_lock(&ar->conf_mutex);
     401                 :          0 :         len = scnprintf(buf, sizeof(buf) - len,
     402                 :            :                         "Write 1 to once trigger the debug logs\n");
     403                 :          0 :         mutex_unlock(&ar->conf_mutex);
     404                 :            : 
     405                 :          0 :         return simple_read_from_buffer(user_buf, count, ppos, buf, len);
     406                 :            : }
     407                 :            : 
     408                 :            : static ssize_t
     409                 :          0 : 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                 :          0 :         struct ieee80211_sta *sta = file->private_data;
     414                 :          0 :         struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
     415                 :          0 :         struct ath10k *ar = arsta->arvif->ar;
     416                 :          0 :         u8 peer_debug_trigger;
     417                 :          0 :         int ret;
     418                 :            : 
     419         [ #  # ]:          0 :         if (kstrtou8_from_user(user_buf, count, 0, &peer_debug_trigger))
     420                 :            :                 return -EINVAL;
     421                 :            : 
     422         [ #  # ]:          0 :         if (peer_debug_trigger != 1)
     423                 :            :                 return -EINVAL;
     424                 :            : 
     425                 :          0 :         mutex_lock(&ar->conf_mutex);
     426                 :            : 
     427         [ #  # ]:          0 :         if (ar->state != ATH10K_STATE_ON) {
     428                 :          0 :                 ret = -ENETDOWN;
     429                 :          0 :                 goto out;
     430                 :            :         }
     431                 :            : 
     432                 :          0 :         ret = ath10k_wmi_peer_set_param(ar, arsta->arvif->vdev_id, sta->addr,
     433                 :          0 :                                         ar->wmi.peer_param->debug, peer_debug_trigger);
     434         [ #  # ]:          0 :         if (ret) {
     435                 :          0 :                 ath10k_warn(ar, "failed to set param to trigger peer tid logs for station ret: %d\n",
     436                 :            :                             ret);
     437                 :          0 :                 goto out;
     438                 :            :         }
     439                 :          0 : out:
     440                 :          0 :         mutex_unlock(&ar->conf_mutex);
     441                 :          0 :         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                 :          0 : 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                 :          0 :         struct ieee80211_sta *sta = file->private_data;
     457                 :          0 :         struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
     458                 :          0 :         struct ath10k *ar = arsta->arvif->ar;
     459                 :          0 :         char buf[20];
     460                 :          0 :         int len = 0;
     461                 :            : 
     462                 :          0 :         spin_lock_bh(&ar->data_lock);
     463                 :            : 
     464                 :          0 :         len = scnprintf(buf, sizeof(buf) - len, "%d\n",
     465                 :            :                         arsta->peer_ps_state);
     466                 :            : 
     467                 :          0 :         spin_unlock_bh(&ar->data_lock);
     468                 :            : 
     469                 :          0 :         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                 :          0 : static char *get_err_str(enum ath10k_pkt_rx_err i)
     480                 :            : {
     481                 :          0 :         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                 :          0 : static char *get_num_ampdu_subfrm_str(enum ath10k_ampdu_subfrm_num i)
     498                 :            : {
     499                 :          0 :         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                 :          0 : static char *get_num_amsdu_subfrm_str(enum ath10k_amsdu_subfrm_num i)
     522                 :            : {
     523                 :          0 :         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                 :          0 : 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                 :          0 :         struct ieee80211_sta *sta = file->private_data;
     567                 :          0 :         struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
     568                 :          0 :         struct ath10k *ar = arsta->arvif->ar;
     569                 :          0 :         struct ath10k_sta_tid_stats *stats = arsta->tid_stats;
     570                 :          0 :         size_t len = 0, buf_len = 1048 * IEEE80211_NUM_TIDS;
     571                 :          0 :         char *buf;
     572                 :          0 :         int i, j;
     573                 :          0 :         ssize_t ret;
     574                 :            : 
     575                 :          0 :         buf = kzalloc(buf_len, GFP_KERNEL);
     576         [ #  # ]:          0 :         if (!buf)
     577                 :            :                 return -ENOMEM;
     578                 :            : 
     579                 :          0 :         mutex_lock(&ar->conf_mutex);
     580                 :            : 
     581                 :          0 :         spin_lock_bh(&ar->data_lock);
     582                 :            : 
     583                 :          0 :         len += scnprintf(buf + len, buf_len - len,
     584                 :            :                          "\n\t\tDriver Rx pkt stats per tid, ([tid] count)\n");
     585                 :          0 :         len += scnprintf(buf + len, buf_len - len,
     586                 :            :                          "\t\t------------------------------------------\n");
     587                 :          0 :         len += scnprintf(buf + len, buf_len - len, "MSDUs from FW\t\t\t");
     588   [ #  #  #  #  :          0 :         PRINT_TID_STATS(rx_pkt_from_fw, "\t\t\t\t");
                   #  # ]
     589                 :            : 
     590                 :          0 :         len += scnprintf(buf + len, buf_len - len, "MSDUs unchained\t\t\t");
     591   [ #  #  #  #  :          0 :         PRINT_TID_STATS(rx_pkt_unchained, "\t\t\t\t");
                   #  # ]
     592                 :            : 
     593                 :          0 :         len += scnprintf(buf + len, buf_len - len,
     594                 :            :                          "MSDUs locally dropped:chained\t");
     595   [ #  #  #  #  :          0 :         PRINT_TID_STATS(rx_pkt_drop_chained, "\t\t\t\t");
                   #  # ]
     596                 :            : 
     597                 :          0 :         len += scnprintf(buf + len, buf_len - len,
     598                 :            :                          "MSDUs locally dropped:filtered\t");
     599   [ #  #  #  #  :          0 :         PRINT_TID_STATS(rx_pkt_drop_filter, "\t\t\t\t");
                   #  # ]
     600                 :            : 
     601                 :          0 :         len += scnprintf(buf + len, buf_len - len,
     602                 :            :                          "MSDUs queued for mac80211\t");
     603   [ #  #  #  #  :          0 :         PRINT_TID_STATS(rx_pkt_queued_for_mac, "\t\t\t\t");
                   #  # ]
     604                 :            : 
     605         [ #  # ]:          0 :         for (i = 0; i < ATH10K_PKT_RX_ERR_MAX; i++) {
     606                 :          0 :                 len += scnprintf(buf + len, buf_len - len,
     607                 :            :                                  "MSDUs with error:%s\t", get_err_str(i));
     608   [ #  #  #  #  :          0 :                 PRINT_TID_STATS(rx_pkt_err[i], "\t\t\t\t");
                   #  # ]
     609                 :            :         }
     610                 :            : 
     611                 :          0 :         len += scnprintf(buf + len, buf_len - len, "\n");
     612         [ #  # ]:          0 :         for (i = 0; i < ATH10K_AMPDU_SUBFRM_NUM_MAX; i++) {
     613                 :          0 :                 len += scnprintf(buf + len, buf_len - len,
     614                 :            :                                  "A-MPDU num subframes %s\t",
     615                 :            :                                  get_num_ampdu_subfrm_str(i));
     616   [ #  #  #  #  :          0 :                 PRINT_TID_STATS(rx_pkt_ampdu[i], "\t\t\t\t");
                   #  # ]
     617                 :            :         }
     618                 :            : 
     619                 :          0 :         len += scnprintf(buf + len, buf_len - len, "\n");
     620         [ #  # ]:          0 :         for (i = 0; i < ATH10K_AMSDU_SUBFRM_NUM_MAX; i++) {
     621                 :          0 :                 len += scnprintf(buf + len, buf_len - len,
     622                 :            :                                  "A-MSDU num subframes %s\t\t",
     623                 :            :                                  get_num_amsdu_subfrm_str(i));
     624   [ #  #  #  #  :          0 :                 PRINT_TID_STATS(rx_pkt_amsdu[i], "\t\t\t\t");
                   #  # ]
     625                 :            :         }
     626                 :            : 
     627                 :          0 :         spin_unlock_bh(&ar->data_lock);
     628                 :            : 
     629                 :          0 :         ret = simple_read_from_buffer(user_buf, count, ppos, buf, len);
     630                 :            : 
     631                 :          0 :         kfree(buf);
     632                 :            : 
     633                 :          0 :         mutex_unlock(&ar->conf_mutex);
     634                 :            : 
     635                 :          0 :         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                 :          0 : 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                 :          0 :         struct ieee80211_sta *sta = file->private_data;
     650                 :          0 :         struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
     651                 :          0 :         struct ath10k *ar = arsta->arvif->ar;
     652                 :          0 :         struct ath10k_htt_data_stats *stats;
     653                 :          0 :         const char *str_name[ATH10K_STATS_TYPE_MAX] = {"succ", "fail",
     654                 :            :                                                        "retry", "ampdu"};
     655                 :          0 :         const char *str[ATH10K_COUNTER_TYPE_MAX] = {"bytes", "packets"};
     656                 :          0 :         int len = 0, i, j, k, retval = 0;
     657                 :          0 :         const int size = 16 * 4096;
     658                 :          0 :         char *buf;
     659                 :            : 
     660                 :          0 :         buf = kzalloc(size, GFP_KERNEL);
     661         [ #  # ]:          0 :         if (!buf)
     662                 :            :                 return -ENOMEM;
     663                 :            : 
     664                 :          0 :         mutex_lock(&ar->conf_mutex);
     665                 :            : 
     666         [ #  # ]:          0 :         if (!arsta->tx_stats) {
     667                 :          0 :                 ath10k_warn(ar, "failed to get tx stats");
     668                 :          0 :                 mutex_unlock(&ar->conf_mutex);
     669                 :          0 :                 kfree(buf);
     670                 :          0 :                 return 0;
     671                 :            :         }
     672                 :            : 
     673                 :          0 :         spin_lock_bh(&ar->data_lock);
     674         [ #  # ]:          0 :         for (k = 0; k < ATH10K_STATS_TYPE_MAX; k++) {
     675         [ #  # ]:          0 :                 for (j = 0; j < ATH10K_COUNTER_TYPE_MAX; j++) {
     676                 :          0 :                         stats = &arsta->tx_stats->stats[k];
     677                 :          0 :                         len += scnprintf(buf + len, size - len, "%s_%s\n",
     678                 :            :                                          str_name[k],
     679                 :            :                                          str[j]);
     680                 :          0 :                         len += scnprintf(buf + len, size - len,
     681                 :            :                                          " VHT MCS %s\n",
     682                 :            :                                          str[j]);
     683         [ #  # ]:          0 :                         for (i = 0; i < ATH10K_VHT_MCS_NUM; i++)
     684                 :          0 :                                 len += scnprintf(buf + len, size - len,
     685                 :            :                                                  "  %llu ",
     686                 :            :                                                  stats->vht[j][i]);
     687                 :          0 :                         len += scnprintf(buf + len, size - len, "\n");
     688                 :          0 :                         len += scnprintf(buf + len, size - len, " HT MCS %s\n",
     689                 :            :                                          str[j]);
     690         [ #  # ]:          0 :                         for (i = 0; i < ATH10K_HT_MCS_NUM; i++)
     691                 :          0 :                                 len += scnprintf(buf + len, size - len,
     692                 :            :                                                  "  %llu ", stats->ht[j][i]);
     693                 :          0 :                         len += scnprintf(buf + len, size - len, "\n");
     694                 :          0 :                         len += scnprintf(buf + len, size - len,
     695                 :            :                                         " BW %s (20,5,10,40,80,160 MHz)\n", str[j]);
     696                 :          0 :                         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                 :          0 :                         len += scnprintf(buf + len, size - len,
     702                 :            :                                          " NSS %s (1x1,2x2,3x3,4x4)\n", str[j]);
     703                 :          0 :                         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                 :          0 :                         len += scnprintf(buf + len, size - len,
     708                 :            :                                          " GI %s (LGI,SGI)\n",
     709                 :            :                                          str[j]);
     710                 :          0 :                         len += scnprintf(buf + len, size - len, "  %llu %llu\n",
     711                 :            :                                          stats->gi[j][0], stats->gi[j][1]);
     712                 :          0 :                         len += scnprintf(buf + len, size - len,
     713                 :            :                                          " legacy rate %s (1,2 ... Mbps)\n  ",
     714                 :            :                                          str[j]);
     715         [ #  # ]:          0 :                         for (i = 0; i < ATH10K_LEGACY_NUM; i++)
     716                 :          0 :                                 len += scnprintf(buf + len, size - len, "%llu ",
     717                 :            :                                                  stats->legacy[j][i]);
     718                 :          0 :                         len += scnprintf(buf + len, size - len, "\n");
     719                 :          0 :                         len += scnprintf(buf + len, size - len,
     720                 :            :                                          " Rate table %s (1,2 ... Mbps)\n  ",
     721                 :            :                                          str[j]);
     722         [ #  # ]:          0 :                         for (i = 0; i < ATH10K_RATE_TABLE_NUM; i++) {
     723                 :          0 :                                 len += scnprintf(buf + len, size - len, "%llu ",
     724                 :            :                                                  stats->rate_table[j][i]);
     725         [ #  # ]:          0 :                                 if (!((i + 1) % 8))
     726                 :          0 :                                         len +=
     727                 :          0 :                                         scnprintf(buf + len, size - len, "\n  ");
     728                 :            :                         }
     729                 :            :                 }
     730                 :            :         }
     731                 :            : 
     732                 :          0 :         len += scnprintf(buf + len, size - len,
     733                 :            :                          "\nTX duration\n %llu usecs\n",
     734                 :          0 :                          arsta->tx_stats->tx_duration);
     735                 :          0 :         len += scnprintf(buf + len, size - len,
     736                 :          0 :                         "BA fails\n %llu\n", arsta->tx_stats->ba_fails);
     737                 :          0 :         len += scnprintf(buf + len, size - len,
     738                 :          0 :                         "ack fails\n %llu\n", arsta->tx_stats->ack_fails);
     739                 :          0 :         spin_unlock_bh(&ar->data_lock);
     740                 :            : 
     741                 :          0 :         if (len > size)
     742                 :            :                 len = size;
     743                 :          0 :         retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
     744                 :          0 :         kfree(buf);
     745                 :            : 
     746                 :          0 :         mutex_unlock(&ar->conf_mutex);
     747                 :          0 :         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                 :          0 : void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
     758                 :            :                             struct ieee80211_sta *sta, struct dentry *dir)
     759                 :            : {
     760                 :          0 :         struct ath10k *ar = hw->priv;
     761                 :            : 
     762                 :          0 :         debugfs_create_file("aggr_mode", 0644, dir, sta, &fops_aggr_mode);
     763                 :          0 :         debugfs_create_file("addba", 0200, dir, sta, &fops_addba);
     764                 :          0 :         debugfs_create_file("addba_resp", 0200, dir, sta, &fops_addba_resp);
     765                 :          0 :         debugfs_create_file("delba", 0200, dir, sta, &fops_delba);
     766                 :          0 :         debugfs_create_file("peer_debug_trigger", 0600, dir, sta,
     767                 :            :                             &fops_peer_debug_trigger);
     768                 :          0 :         debugfs_create_file("dump_tid_stats", 0400, dir, sta,
     769                 :            :                             &fops_tid_stats_dump);
     770                 :            : 
     771   [ #  #  #  # ]:          0 :         if (ath10k_peer_stats_enabled(ar) &&
     772         [ #  # ]:          0 :             ath10k_debug_is_extd_tx_stats_enabled(ar))
     773                 :          0 :                 debugfs_create_file("tx_stats", 0400, dir, sta,
     774                 :            :                                     &fops_tx_stats);
     775                 :          0 :         debugfs_create_file("peer_ps_state", 0400, dir, sta,
     776                 :            :                             &fops_peer_ps_state);
     777                 :          0 : }

Generated by: LCOV version 1.14