0001
0002
0003
0004
0005
0006
0007 #include "core.h"
0008 #include "wmi-ops.h"
0009 #include "txrx.h"
0010 #include "debug.h"
0011
0012 static void ath10k_rx_stats_update_amsdu_subfrm(struct ath10k *ar,
0013 struct ath10k_sta_tid_stats *stats,
0014 u32 msdu_count)
0015 {
0016 if (msdu_count == 1)
0017 stats->rx_pkt_amsdu[ATH10K_AMSDU_SUBFRM_NUM_1]++;
0018 else if (msdu_count == 2)
0019 stats->rx_pkt_amsdu[ATH10K_AMSDU_SUBFRM_NUM_2]++;
0020 else if (msdu_count == 3)
0021 stats->rx_pkt_amsdu[ATH10K_AMSDU_SUBFRM_NUM_3]++;
0022 else if (msdu_count == 4)
0023 stats->rx_pkt_amsdu[ATH10K_AMSDU_SUBFRM_NUM_4]++;
0024 else if (msdu_count > 4)
0025 stats->rx_pkt_amsdu[ATH10K_AMSDU_SUBFRM_NUM_MORE]++;
0026 }
0027
0028 static void ath10k_rx_stats_update_ampdu_subfrm(struct ath10k *ar,
0029 struct ath10k_sta_tid_stats *stats,
0030 u32 mpdu_count)
0031 {
0032 if (mpdu_count <= 10)
0033 stats->rx_pkt_ampdu[ATH10K_AMPDU_SUBFRM_NUM_10]++;
0034 else if (mpdu_count <= 20)
0035 stats->rx_pkt_ampdu[ATH10K_AMPDU_SUBFRM_NUM_20]++;
0036 else if (mpdu_count <= 30)
0037 stats->rx_pkt_ampdu[ATH10K_AMPDU_SUBFRM_NUM_30]++;
0038 else if (mpdu_count <= 40)
0039 stats->rx_pkt_ampdu[ATH10K_AMPDU_SUBFRM_NUM_40]++;
0040 else if (mpdu_count <= 50)
0041 stats->rx_pkt_ampdu[ATH10K_AMPDU_SUBFRM_NUM_50]++;
0042 else if (mpdu_count <= 60)
0043 stats->rx_pkt_ampdu[ATH10K_AMPDU_SUBFRM_NUM_60]++;
0044 else if (mpdu_count > 60)
0045 stats->rx_pkt_ampdu[ATH10K_AMPDU_SUBFRM_NUM_MORE]++;
0046 }
0047
0048 void ath10k_sta_update_rx_tid_stats_ampdu(struct ath10k *ar, u16 peer_id, u8 tid,
0049 struct htt_rx_indication_mpdu_range *ranges,
0050 int num_ranges)
0051 {
0052 struct ath10k_sta *arsta;
0053 struct ath10k_peer *peer;
0054 int i;
0055
0056 if (tid > IEEE80211_NUM_TIDS || !(ar->sta_tid_stats_mask & BIT(tid)))
0057 return;
0058
0059 rcu_read_lock();
0060 spin_lock_bh(&ar->data_lock);
0061
0062 peer = ath10k_peer_find_by_id(ar, peer_id);
0063 if (!peer || !peer->sta)
0064 goto out;
0065
0066 arsta = (struct ath10k_sta *)peer->sta->drv_priv;
0067
0068 for (i = 0; i < num_ranges; i++)
0069 ath10k_rx_stats_update_ampdu_subfrm(ar,
0070 &arsta->tid_stats[tid],
0071 ranges[i].mpdu_count);
0072
0073 out:
0074 spin_unlock_bh(&ar->data_lock);
0075 rcu_read_unlock();
0076 }
0077
0078 void ath10k_sta_update_rx_tid_stats(struct ath10k *ar, u8 *first_hdr,
0079 unsigned long num_msdus,
0080 enum ath10k_pkt_rx_err err,
0081 unsigned long unchain_cnt,
0082 unsigned long drop_cnt,
0083 unsigned long drop_cnt_filter,
0084 unsigned long queued_msdus)
0085 {
0086 struct ieee80211_sta *sta;
0087 struct ath10k_sta *arsta;
0088 struct ieee80211_hdr *hdr;
0089 struct ath10k_sta_tid_stats *stats;
0090 u8 tid = IEEE80211_NUM_TIDS;
0091 bool non_data_frm = false;
0092
0093 hdr = (struct ieee80211_hdr *)first_hdr;
0094 if (!ieee80211_is_data(hdr->frame_control))
0095 non_data_frm = true;
0096
0097 if (ieee80211_is_data_qos(hdr->frame_control))
0098 tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
0099
0100 if (!(ar->sta_tid_stats_mask & BIT(tid)) || non_data_frm)
0101 return;
0102
0103 rcu_read_lock();
0104
0105 sta = ieee80211_find_sta_by_ifaddr(ar->hw, hdr->addr2, NULL);
0106 if (!sta)
0107 goto exit;
0108
0109 arsta = (struct ath10k_sta *)sta->drv_priv;
0110
0111 spin_lock_bh(&ar->data_lock);
0112 stats = &arsta->tid_stats[tid];
0113 stats->rx_pkt_from_fw += num_msdus;
0114 stats->rx_pkt_unchained += unchain_cnt;
0115 stats->rx_pkt_drop_chained += drop_cnt;
0116 stats->rx_pkt_drop_filter += drop_cnt_filter;
0117 if (err != ATH10K_PKT_RX_ERR_MAX)
0118 stats->rx_pkt_err[err] += queued_msdus;
0119 stats->rx_pkt_queued_for_mac += queued_msdus;
0120 ath10k_rx_stats_update_amsdu_subfrm(ar, &arsta->tid_stats[tid],
0121 num_msdus);
0122 spin_unlock_bh(&ar->data_lock);
0123
0124 exit:
0125 rcu_read_unlock();
0126 }
0127
0128 static void ath10k_sta_update_extd_stats_rx_duration(struct ath10k *ar,
0129 struct ath10k_fw_stats *stats)
0130 {
0131 struct ath10k_fw_extd_stats_peer *peer;
0132 struct ieee80211_sta *sta;
0133 struct ath10k_sta *arsta;
0134
0135 rcu_read_lock();
0136 list_for_each_entry(peer, &stats->peers_extd, list) {
0137 sta = ieee80211_find_sta_by_ifaddr(ar->hw, peer->peer_macaddr,
0138 NULL);
0139 if (!sta)
0140 continue;
0141 arsta = (struct ath10k_sta *)sta->drv_priv;
0142 arsta->rx_duration += (u64)peer->rx_duration;
0143 }
0144 rcu_read_unlock();
0145 }
0146
0147 static void ath10k_sta_update_stats_rx_duration(struct ath10k *ar,
0148 struct ath10k_fw_stats *stats)
0149 {
0150 struct ath10k_fw_stats_peer *peer;
0151 struct ieee80211_sta *sta;
0152 struct ath10k_sta *arsta;
0153
0154 rcu_read_lock();
0155 list_for_each_entry(peer, &stats->peers, list) {
0156 sta = ieee80211_find_sta_by_ifaddr(ar->hw, peer->peer_macaddr,
0157 NULL);
0158 if (!sta)
0159 continue;
0160 arsta = (struct ath10k_sta *)sta->drv_priv;
0161 arsta->rx_duration += (u64)peer->rx_duration;
0162 }
0163 rcu_read_unlock();
0164 }
0165
0166 void ath10k_sta_update_rx_duration(struct ath10k *ar,
0167 struct ath10k_fw_stats *stats)
0168 {
0169 if (stats->extended)
0170 ath10k_sta_update_extd_stats_rx_duration(ar, stats);
0171 else
0172 ath10k_sta_update_stats_rx_duration(ar, stats);
0173 }
0174
0175 static ssize_t ath10k_dbg_sta_read_aggr_mode(struct file *file,
0176 char __user *user_buf,
0177 size_t count, loff_t *ppos)
0178 {
0179 struct ieee80211_sta *sta = file->private_data;
0180 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
0181 struct ath10k *ar = arsta->arvif->ar;
0182 char buf[32];
0183 int len = 0;
0184
0185 mutex_lock(&ar->conf_mutex);
0186 len = scnprintf(buf, sizeof(buf) - len, "aggregation mode: %s\n",
0187 (arsta->aggr_mode == ATH10K_DBG_AGGR_MODE_AUTO) ?
0188 "auto" : "manual");
0189 mutex_unlock(&ar->conf_mutex);
0190
0191 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
0192 }
0193
0194 static ssize_t ath10k_dbg_sta_write_aggr_mode(struct file *file,
0195 const char __user *user_buf,
0196 size_t count, loff_t *ppos)
0197 {
0198 struct ieee80211_sta *sta = file->private_data;
0199 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
0200 struct ath10k *ar = arsta->arvif->ar;
0201 u32 aggr_mode;
0202 int ret;
0203
0204 if (kstrtouint_from_user(user_buf, count, 0, &aggr_mode))
0205 return -EINVAL;
0206
0207 if (aggr_mode >= ATH10K_DBG_AGGR_MODE_MAX)
0208 return -EINVAL;
0209
0210 mutex_lock(&ar->conf_mutex);
0211 if ((ar->state != ATH10K_STATE_ON) ||
0212 (aggr_mode == arsta->aggr_mode)) {
0213 ret = count;
0214 goto out;
0215 }
0216
0217 ret = ath10k_wmi_addba_clear_resp(ar, arsta->arvif->vdev_id, sta->addr);
0218 if (ret) {
0219 ath10k_warn(ar, "failed to clear addba session ret: %d\n", ret);
0220 goto out;
0221 }
0222
0223 arsta->aggr_mode = aggr_mode;
0224 out:
0225 mutex_unlock(&ar->conf_mutex);
0226 return ret;
0227 }
0228
0229 static const struct file_operations fops_aggr_mode = {
0230 .read = ath10k_dbg_sta_read_aggr_mode,
0231 .write = ath10k_dbg_sta_write_aggr_mode,
0232 .open = simple_open,
0233 .owner = THIS_MODULE,
0234 .llseek = default_llseek,
0235 };
0236
0237 static ssize_t ath10k_dbg_sta_write_addba(struct file *file,
0238 const char __user *user_buf,
0239 size_t count, loff_t *ppos)
0240 {
0241 struct ieee80211_sta *sta = file->private_data;
0242 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
0243 struct ath10k *ar = arsta->arvif->ar;
0244 u32 tid, buf_size;
0245 int ret;
0246 char buf[64] = {0};
0247
0248 ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos,
0249 user_buf, count);
0250 if (ret <= 0)
0251 return ret;
0252
0253 ret = sscanf(buf, "%u %u", &tid, &buf_size);
0254 if (ret != 2)
0255 return -EINVAL;
0256
0257
0258 if (tid > HTT_DATA_TX_EXT_TID_MGMT - 2)
0259 return -EINVAL;
0260
0261 mutex_lock(&ar->conf_mutex);
0262 if ((ar->state != ATH10K_STATE_ON) ||
0263 (arsta->aggr_mode != ATH10K_DBG_AGGR_MODE_MANUAL)) {
0264 ret = count;
0265 goto out;
0266 }
0267
0268 ret = ath10k_wmi_addba_send(ar, arsta->arvif->vdev_id, sta->addr,
0269 tid, buf_size);
0270 if (ret) {
0271 ath10k_warn(ar, "failed to send addba request: vdev_id %u peer %pM tid %u buf_size %u\n",
0272 arsta->arvif->vdev_id, sta->addr, tid, buf_size);
0273 }
0274
0275 ret = count;
0276 out:
0277 mutex_unlock(&ar->conf_mutex);
0278 return ret;
0279 }
0280
0281 static const struct file_operations fops_addba = {
0282 .write = ath10k_dbg_sta_write_addba,
0283 .open = simple_open,
0284 .owner = THIS_MODULE,
0285 .llseek = default_llseek,
0286 };
0287
0288 static ssize_t ath10k_dbg_sta_write_addba_resp(struct file *file,
0289 const char __user *user_buf,
0290 size_t count, loff_t *ppos)
0291 {
0292 struct ieee80211_sta *sta = file->private_data;
0293 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
0294 struct ath10k *ar = arsta->arvif->ar;
0295 u32 tid, status;
0296 int ret;
0297 char buf[64] = {0};
0298
0299 ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos,
0300 user_buf, count);
0301 if (ret <= 0)
0302 return ret;
0303
0304 ret = sscanf(buf, "%u %u", &tid, &status);
0305 if (ret != 2)
0306 return -EINVAL;
0307
0308
0309 if (tid > HTT_DATA_TX_EXT_TID_MGMT - 2)
0310 return -EINVAL;
0311
0312 mutex_lock(&ar->conf_mutex);
0313 if ((ar->state != ATH10K_STATE_ON) ||
0314 (arsta->aggr_mode != ATH10K_DBG_AGGR_MODE_MANUAL)) {
0315 ret = count;
0316 goto out;
0317 }
0318
0319 ret = ath10k_wmi_addba_set_resp(ar, arsta->arvif->vdev_id, sta->addr,
0320 tid, status);
0321 if (ret) {
0322 ath10k_warn(ar, "failed to send addba response: vdev_id %u peer %pM tid %u status%u\n",
0323 arsta->arvif->vdev_id, sta->addr, tid, status);
0324 }
0325 ret = count;
0326 out:
0327 mutex_unlock(&ar->conf_mutex);
0328 return ret;
0329 }
0330
0331 static const struct file_operations fops_addba_resp = {
0332 .write = ath10k_dbg_sta_write_addba_resp,
0333 .open = simple_open,
0334 .owner = THIS_MODULE,
0335 .llseek = default_llseek,
0336 };
0337
0338 static ssize_t ath10k_dbg_sta_write_delba(struct file *file,
0339 const char __user *user_buf,
0340 size_t count, loff_t *ppos)
0341 {
0342 struct ieee80211_sta *sta = file->private_data;
0343 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
0344 struct ath10k *ar = arsta->arvif->ar;
0345 u32 tid, initiator, reason;
0346 int ret;
0347 char buf[64] = {0};
0348
0349 ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos,
0350 user_buf, count);
0351 if (ret <= 0)
0352 return ret;
0353
0354 ret = sscanf(buf, "%u %u %u", &tid, &initiator, &reason);
0355 if (ret != 3)
0356 return -EINVAL;
0357
0358
0359 if (tid > HTT_DATA_TX_EXT_TID_MGMT - 2)
0360 return -EINVAL;
0361
0362 mutex_lock(&ar->conf_mutex);
0363 if ((ar->state != ATH10K_STATE_ON) ||
0364 (arsta->aggr_mode != ATH10K_DBG_AGGR_MODE_MANUAL)) {
0365 ret = count;
0366 goto out;
0367 }
0368
0369 ret = ath10k_wmi_delba_send(ar, arsta->arvif->vdev_id, sta->addr,
0370 tid, initiator, reason);
0371 if (ret) {
0372 ath10k_warn(ar, "failed to send delba: vdev_id %u peer %pM tid %u initiator %u reason %u\n",
0373 arsta->arvif->vdev_id, sta->addr, tid, initiator,
0374 reason);
0375 }
0376 ret = count;
0377 out:
0378 mutex_unlock(&ar->conf_mutex);
0379 return ret;
0380 }
0381
0382 static const struct file_operations fops_delba = {
0383 .write = ath10k_dbg_sta_write_delba,
0384 .open = simple_open,
0385 .owner = THIS_MODULE,
0386 .llseek = default_llseek,
0387 };
0388
0389 static ssize_t ath10k_dbg_sta_read_peer_debug_trigger(struct file *file,
0390 char __user *user_buf,
0391 size_t count,
0392 loff_t *ppos)
0393 {
0394 struct ieee80211_sta *sta = file->private_data;
0395 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
0396 struct ath10k *ar = arsta->arvif->ar;
0397 char buf[8];
0398 int len = 0;
0399
0400 mutex_lock(&ar->conf_mutex);
0401 len = scnprintf(buf, sizeof(buf) - len,
0402 "Write 1 to once trigger the debug logs\n");
0403 mutex_unlock(&ar->conf_mutex);
0404
0405 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
0406 }
0407
0408 static ssize_t
0409 ath10k_dbg_sta_write_peer_debug_trigger(struct file *file,
0410 const char __user *user_buf,
0411 size_t count, loff_t *ppos)
0412 {
0413 struct ieee80211_sta *sta = file->private_data;
0414 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
0415 struct ath10k *ar = arsta->arvif->ar;
0416 u8 peer_debug_trigger;
0417 int ret;
0418
0419 if (kstrtou8_from_user(user_buf, count, 0, &peer_debug_trigger))
0420 return -EINVAL;
0421
0422 if (peer_debug_trigger != 1)
0423 return -EINVAL;
0424
0425 mutex_lock(&ar->conf_mutex);
0426
0427 if (ar->state != ATH10K_STATE_ON) {
0428 ret = -ENETDOWN;
0429 goto out;
0430 }
0431
0432 ret = ath10k_wmi_peer_set_param(ar, arsta->arvif->vdev_id, sta->addr,
0433 ar->wmi.peer_param->debug, peer_debug_trigger);
0434 if (ret) {
0435 ath10k_warn(ar, "failed to set param to trigger peer tid logs for station ret: %d\n",
0436 ret);
0437 goto out;
0438 }
0439 out:
0440 mutex_unlock(&ar->conf_mutex);
0441 return count;
0442 }
0443
0444 static const struct file_operations fops_peer_debug_trigger = {
0445 .open = simple_open,
0446 .read = ath10k_dbg_sta_read_peer_debug_trigger,
0447 .write = ath10k_dbg_sta_write_peer_debug_trigger,
0448 .owner = THIS_MODULE,
0449 .llseek = default_llseek,
0450 };
0451
0452 static ssize_t ath10k_dbg_sta_read_peer_ps_state(struct file *file,
0453 char __user *user_buf,
0454 size_t count, loff_t *ppos)
0455 {
0456 struct ieee80211_sta *sta = file->private_data;
0457 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
0458 struct ath10k *ar = arsta->arvif->ar;
0459 char buf[20];
0460 int len = 0;
0461
0462 spin_lock_bh(&ar->data_lock);
0463
0464 len = scnprintf(buf, sizeof(buf) - len, "%d\n",
0465 arsta->peer_ps_state);
0466
0467 spin_unlock_bh(&ar->data_lock);
0468
0469 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
0470 }
0471
0472 static const struct file_operations fops_peer_ps_state = {
0473 .open = simple_open,
0474 .read = ath10k_dbg_sta_read_peer_ps_state,
0475 .owner = THIS_MODULE,
0476 .llseek = default_llseek,
0477 };
0478
0479 static char *get_err_str(enum ath10k_pkt_rx_err i)
0480 {
0481 switch (i) {
0482 case ATH10K_PKT_RX_ERR_FCS:
0483 return "fcs_err";
0484 case ATH10K_PKT_RX_ERR_TKIP:
0485 return "tkip_err";
0486 case ATH10K_PKT_RX_ERR_CRYPT:
0487 return "crypt_err";
0488 case ATH10K_PKT_RX_ERR_PEER_IDX_INVAL:
0489 return "peer_idx_inval";
0490 case ATH10K_PKT_RX_ERR_MAX:
0491 return "unknown";
0492 }
0493
0494 return "unknown";
0495 }
0496
0497 static char *get_num_ampdu_subfrm_str(enum ath10k_ampdu_subfrm_num i)
0498 {
0499 switch (i) {
0500 case ATH10K_AMPDU_SUBFRM_NUM_10:
0501 return "upto 10";
0502 case ATH10K_AMPDU_SUBFRM_NUM_20:
0503 return "11-20";
0504 case ATH10K_AMPDU_SUBFRM_NUM_30:
0505 return "21-30";
0506 case ATH10K_AMPDU_SUBFRM_NUM_40:
0507 return "31-40";
0508 case ATH10K_AMPDU_SUBFRM_NUM_50:
0509 return "41-50";
0510 case ATH10K_AMPDU_SUBFRM_NUM_60:
0511 return "51-60";
0512 case ATH10K_AMPDU_SUBFRM_NUM_MORE:
0513 return ">60";
0514 case ATH10K_AMPDU_SUBFRM_NUM_MAX:
0515 return "0";
0516 }
0517
0518 return "0";
0519 }
0520
0521 static char *get_num_amsdu_subfrm_str(enum ath10k_amsdu_subfrm_num i)
0522 {
0523 switch (i) {
0524 case ATH10K_AMSDU_SUBFRM_NUM_1:
0525 return "1";
0526 case ATH10K_AMSDU_SUBFRM_NUM_2:
0527 return "2";
0528 case ATH10K_AMSDU_SUBFRM_NUM_3:
0529 return "3";
0530 case ATH10K_AMSDU_SUBFRM_NUM_4:
0531 return "4";
0532 case ATH10K_AMSDU_SUBFRM_NUM_MORE:
0533 return ">4";
0534 case ATH10K_AMSDU_SUBFRM_NUM_MAX:
0535 return "0";
0536 }
0537
0538 return "0";
0539 }
0540
0541 #define PRINT_TID_STATS(_field, _tabs) \
0542 do { \
0543 int k = 0; \
0544 for (j = 0; j <= IEEE80211_NUM_TIDS; j++) { \
0545 if (ar->sta_tid_stats_mask & BIT(j)) { \
0546 len += scnprintf(buf + len, buf_len - len, \
0547 "[%02d] %-10lu ", \
0548 j, stats[j]._field); \
0549 k++; \
0550 if (k % 8 == 0) { \
0551 len += scnprintf(buf + len, \
0552 buf_len - len, "\n"); \
0553 len += scnprintf(buf + len, \
0554 buf_len - len, \
0555 _tabs); \
0556 } \
0557 } \
0558 } \
0559 len += scnprintf(buf + len, buf_len - len, "\n"); \
0560 } while (0)
0561
0562 static ssize_t ath10k_dbg_sta_read_tid_stats(struct file *file,
0563 char __user *user_buf,
0564 size_t count, loff_t *ppos)
0565 {
0566 struct ieee80211_sta *sta = file->private_data;
0567 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
0568 struct ath10k *ar = arsta->arvif->ar;
0569 struct ath10k_sta_tid_stats *stats = arsta->tid_stats;
0570 size_t len = 0, buf_len = 1048 * IEEE80211_NUM_TIDS;
0571 char *buf;
0572 int i, j;
0573 ssize_t ret;
0574
0575 buf = kzalloc(buf_len, GFP_KERNEL);
0576 if (!buf)
0577 return -ENOMEM;
0578
0579 mutex_lock(&ar->conf_mutex);
0580
0581 spin_lock_bh(&ar->data_lock);
0582
0583 len += scnprintf(buf + len, buf_len - len,
0584 "\n\t\tDriver Rx pkt stats per tid, ([tid] count)\n");
0585 len += scnprintf(buf + len, buf_len - len,
0586 "\t\t------------------------------------------\n");
0587 len += scnprintf(buf + len, buf_len - len, "MSDUs from FW\t\t\t");
0588 PRINT_TID_STATS(rx_pkt_from_fw, "\t\t\t\t");
0589
0590 len += scnprintf(buf + len, buf_len - len, "MSDUs unchained\t\t\t");
0591 PRINT_TID_STATS(rx_pkt_unchained, "\t\t\t\t");
0592
0593 len += scnprintf(buf + len, buf_len - len,
0594 "MSDUs locally dropped:chained\t");
0595 PRINT_TID_STATS(rx_pkt_drop_chained, "\t\t\t\t");
0596
0597 len += scnprintf(buf + len, buf_len - len,
0598 "MSDUs locally dropped:filtered\t");
0599 PRINT_TID_STATS(rx_pkt_drop_filter, "\t\t\t\t");
0600
0601 len += scnprintf(buf + len, buf_len - len,
0602 "MSDUs queued for mac80211\t");
0603 PRINT_TID_STATS(rx_pkt_queued_for_mac, "\t\t\t\t");
0604
0605 for (i = 0; i < ATH10K_PKT_RX_ERR_MAX; i++) {
0606 len += scnprintf(buf + len, buf_len - len,
0607 "MSDUs with error:%s\t", get_err_str(i));
0608 PRINT_TID_STATS(rx_pkt_err[i], "\t\t\t\t");
0609 }
0610
0611 len += scnprintf(buf + len, buf_len - len, "\n");
0612 for (i = 0; i < ATH10K_AMPDU_SUBFRM_NUM_MAX; i++) {
0613 len += scnprintf(buf + len, buf_len - len,
0614 "A-MPDU num subframes %s\t",
0615 get_num_ampdu_subfrm_str(i));
0616 PRINT_TID_STATS(rx_pkt_ampdu[i], "\t\t\t\t");
0617 }
0618
0619 len += scnprintf(buf + len, buf_len - len, "\n");
0620 for (i = 0; i < ATH10K_AMSDU_SUBFRM_NUM_MAX; i++) {
0621 len += scnprintf(buf + len, buf_len - len,
0622 "A-MSDU num subframes %s\t\t",
0623 get_num_amsdu_subfrm_str(i));
0624 PRINT_TID_STATS(rx_pkt_amsdu[i], "\t\t\t\t");
0625 }
0626
0627 spin_unlock_bh(&ar->data_lock);
0628
0629 ret = simple_read_from_buffer(user_buf, count, ppos, buf, len);
0630
0631 kfree(buf);
0632
0633 mutex_unlock(&ar->conf_mutex);
0634
0635 return ret;
0636 }
0637
0638 static const struct file_operations fops_tid_stats_dump = {
0639 .open = simple_open,
0640 .read = ath10k_dbg_sta_read_tid_stats,
0641 .owner = THIS_MODULE,
0642 .llseek = default_llseek,
0643 };
0644
0645 static ssize_t ath10k_dbg_sta_dump_tx_stats(struct file *file,
0646 char __user *user_buf,
0647 size_t count, loff_t *ppos)
0648 {
0649 struct ieee80211_sta *sta = file->private_data;
0650 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
0651 struct ath10k *ar = arsta->arvif->ar;
0652 struct ath10k_htt_data_stats *stats;
0653 const char *str_name[ATH10K_STATS_TYPE_MAX] = {"succ", "fail",
0654 "retry", "ampdu"};
0655 const char *str[ATH10K_COUNTER_TYPE_MAX] = {"bytes", "packets"};
0656 int len = 0, i, j, k, retval = 0;
0657 const int size = 16 * 4096;
0658 char *buf;
0659
0660 buf = kzalloc(size, GFP_KERNEL);
0661 if (!buf)
0662 return -ENOMEM;
0663
0664 mutex_lock(&ar->conf_mutex);
0665
0666 if (!arsta->tx_stats) {
0667 ath10k_warn(ar, "failed to get tx stats");
0668 mutex_unlock(&ar->conf_mutex);
0669 kfree(buf);
0670 return 0;
0671 }
0672
0673 spin_lock_bh(&ar->data_lock);
0674 for (k = 0; k < ATH10K_STATS_TYPE_MAX; k++) {
0675 for (j = 0; j < ATH10K_COUNTER_TYPE_MAX; j++) {
0676 stats = &arsta->tx_stats->stats[k];
0677 len += scnprintf(buf + len, size - len, "%s_%s\n",
0678 str_name[k],
0679 str[j]);
0680 len += scnprintf(buf + len, size - len,
0681 " VHT MCS %s\n",
0682 str[j]);
0683 for (i = 0; i < ATH10K_VHT_MCS_NUM; i++)
0684 len += scnprintf(buf + len, size - len,
0685 " %llu ",
0686 stats->vht[j][i]);
0687 len += scnprintf(buf + len, size - len, "\n");
0688 len += scnprintf(buf + len, size - len, " HT MCS %s\n",
0689 str[j]);
0690 for (i = 0; i < ATH10K_HT_MCS_NUM; i++)
0691 len += scnprintf(buf + len, size - len,
0692 " %llu ", stats->ht[j][i]);
0693 len += scnprintf(buf + len, size - len, "\n");
0694 len += scnprintf(buf + len, size - len,
0695 " BW %s (20,5,10,40,80,160 MHz)\n", str[j]);
0696 len += scnprintf(buf + len, size - len,
0697 " %llu %llu %llu %llu %llu %llu\n",
0698 stats->bw[j][0], stats->bw[j][1],
0699 stats->bw[j][2], stats->bw[j][3],
0700 stats->bw[j][4], stats->bw[j][5]);
0701 len += scnprintf(buf + len, size - len,
0702 " NSS %s (1x1,2x2,3x3,4x4)\n", str[j]);
0703 len += scnprintf(buf + len, size - len,
0704 " %llu %llu %llu %llu\n",
0705 stats->nss[j][0], stats->nss[j][1],
0706 stats->nss[j][2], stats->nss[j][3]);
0707 len += scnprintf(buf + len, size - len,
0708 " GI %s (LGI,SGI)\n",
0709 str[j]);
0710 len += scnprintf(buf + len, size - len, " %llu %llu\n",
0711 stats->gi[j][0], stats->gi[j][1]);
0712 len += scnprintf(buf + len, size - len,
0713 " legacy rate %s (1,2 ... Mbps)\n ",
0714 str[j]);
0715 for (i = 0; i < ATH10K_LEGACY_NUM; i++)
0716 len += scnprintf(buf + len, size - len, "%llu ",
0717 stats->legacy[j][i]);
0718 len += scnprintf(buf + len, size - len, "\n");
0719 len += scnprintf(buf + len, size - len,
0720 " Rate table %s (1,2 ... Mbps)\n ",
0721 str[j]);
0722 for (i = 0; i < ATH10K_RATE_TABLE_NUM; i++) {
0723 len += scnprintf(buf + len, size - len, "%llu ",
0724 stats->rate_table[j][i]);
0725 if (!((i + 1) % 8))
0726 len +=
0727 scnprintf(buf + len, size - len, "\n ");
0728 }
0729 }
0730 }
0731
0732 len += scnprintf(buf + len, size - len,
0733 "\nTX duration\n %llu usecs\n",
0734 arsta->tx_stats->tx_duration);
0735 len += scnprintf(buf + len, size - len,
0736 "BA fails\n %llu\n", arsta->tx_stats->ba_fails);
0737 len += scnprintf(buf + len, size - len,
0738 "ack fails\n %llu\n", arsta->tx_stats->ack_fails);
0739 spin_unlock_bh(&ar->data_lock);
0740
0741 if (len > size)
0742 len = size;
0743 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
0744 kfree(buf);
0745
0746 mutex_unlock(&ar->conf_mutex);
0747 return retval;
0748 }
0749
0750 static const struct file_operations fops_tx_stats = {
0751 .read = ath10k_dbg_sta_dump_tx_stats,
0752 .open = simple_open,
0753 .owner = THIS_MODULE,
0754 .llseek = default_llseek,
0755 };
0756
0757 void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
0758 struct ieee80211_sta *sta, struct dentry *dir)
0759 {
0760 struct ath10k *ar = hw->priv;
0761
0762 debugfs_create_file("aggr_mode", 0644, dir, sta, &fops_aggr_mode);
0763 debugfs_create_file("addba", 0200, dir, sta, &fops_addba);
0764 debugfs_create_file("addba_resp", 0200, dir, sta, &fops_addba_resp);
0765 debugfs_create_file("delba", 0200, dir, sta, &fops_delba);
0766 debugfs_create_file("peer_debug_trigger", 0600, dir, sta,
0767 &fops_peer_debug_trigger);
0768 debugfs_create_file("dump_tid_stats", 0400, dir, sta,
0769 &fops_tid_stats_dump);
0770
0771 if (ath10k_peer_stats_enabled(ar) &&
0772 ath10k_debug_is_extd_tx_stats_enabled(ar))
0773 debugfs_create_file("tx_stats", 0400, dir, sta,
0774 &fops_tx_stats);
0775 debugfs_create_file("peer_ps_state", 0400, dir, sta,
0776 &fops_peer_ps_state);
0777 }