@@ -107,7 +107,7 @@ static ssize_t sta_stats_read(struct file *file, char __user *userbuf,
{
struct sta_info *sta = file->private_data;
unsigned int len = 0;
- const int buf_len = 8000;
+ const int buf_len = 12000;
char *buf = kzalloc(buf_len, GFP_KERNEL);
unsigned long sum;
char tmp[60];
@@ -186,6 +186,7 @@ static ssize_t sta_stats_read(struct file *file, char __user *userbuf,
PRINT_MY_STATS("rx-bw-40", rx_stats.msdu_40);
PRINT_MY_STATS("rx-bw-80", rx_stats.msdu_80);
PRINT_MY_STATS("rx-bw-160", rx_stats.msdu_160);
+ PRINT_MY_STATS("rx-bw-he-ru", rx_stats.msdu_he_ru);
PRINT_MY_STATS("rx-he-total", rx_stats.msdu_he_tot);
PRINT_MY_STATS("rx-he-su", rx_stats.msdu_he_su);
@@ -213,6 +214,27 @@ static ssize_t sta_stats_read(struct file *file, char __user *userbuf,
sprintf(tmp, "rx-rate-idx[%3i]", i);
PRINT_MY_STATS(tmp, rx_stats.msdu_rate_idx[i]);
}
+
+ len += scnprintf(buf + len, buf_len - len, "\n");
+ PRINT_MY_STATS("tx-bw-20", sta->tx_stats.msdu_20);
+ PRINT_MY_STATS("tx-bw-40", sta->tx_stats.msdu_40);
+ PRINT_MY_STATS("tx-bw-80", sta->tx_stats.msdu_80);
+ PRINT_MY_STATS("tx-bw-160", sta->tx_stats.msdu_160);
+ PRINT_MY_STATS("tx-bw-he-ru", sta->tx_stats.msdu_he_ru);
+
+ PRINT_MY_STATS("tx-vht", sta->tx_stats.msdu_vht);
+ PRINT_MY_STATS("tx-ht", sta->tx_stats.msdu_ht);
+ PRINT_MY_STATS("tx-legacy", sta->tx_stats.msdu_legacy);
+
+ for (i = 0; i < ARRAY_SIZE(sta->tx_stats.msdu_nss); i++) {
+ sprintf(tmp, "tx-msdu-nss[%i]", i);
+ PRINT_MY_STATS(tmp, sta->tx_stats.msdu_nss[i]);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(sta->tx_stats.msdu_rate_idx); i++) {
+ sprintf(tmp, "tx-rate-idx[%3i]", i);
+ PRINT_MY_STATS(tmp, sta->tx_stats.msdu_rate_idx[i]);
+ }
#endif
#undef PRINT_MY_STATS
@@ -1767,6 +1767,7 @@ static void ieee80211_update_data_rx_stats(struct ieee80211_rx_data *rx,
stats->msdu_160++;
break;
case RATE_INFO_BW_HE_RU:
+ stats->msdu_he_ru++;
stats->msdu_he_ru_alloc[status->he_ru]++;
break;
};
@@ -445,6 +445,7 @@ struct ieee80211_sta_rx_stats {
u32 msdu_40;
u32 msdu_80;
u32 msdu_160;
+ u32 msdu_he_ru;
u32 msdu_he_ru_alloc[NL80211_RATE_INFO_HE_RU_ALLOC_LAST];
u32 msdu_he_tot;
u32 msdu_he_su;
@@ -636,6 +637,21 @@ struct sta_info {
struct ieee80211_tx_rate last_rate;
struct rate_info last_rate_info;
u64 msdu[IEEE80211_NUM_TIDS + 1];
+#ifdef CONFIG_MAC80211_DEBUG_STA_COUNTERS
+ /* these take liberty with how things are defined, and are
+ * designed to give a rough idea of how things are going.
+ */
+ u32 msdu_20;
+ u32 msdu_40;
+ u32 msdu_80;
+ u32 msdu_160;
+ u32 msdu_he_ru;
+ u32 msdu_vht;
+ u32 msdu_ht;
+ u32 msdu_legacy;
+ u32 msdu_nss[8];
+ u32 msdu_rate_idx[13];
+#endif
} tx_stats;
u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1];
@@ -1112,6 +1112,9 @@ void ieee80211_tx_status_ext(struct ieee80211_hw *hw,
if (pubsta) {
struct ieee80211_sub_if_data *sdata = sta->sdata;
+#ifdef CONFIG_MAC80211_DEBUG_STA_COUNTERS
+ bool do_stats = false;
+#endif
if (!acked && !noack_success)
sta->status_stats.retry_failed++;
@@ -1124,6 +1127,9 @@ void ieee80211_tx_status_ext(struct ieee80211_hw *hw,
acked, info->status.tx_time);
if (acked) {
+#ifdef CONFIG_MAC80211_DEBUG_STA_COUNTERS
+ do_stats = true;
+#endif
sta->status_stats.last_ack = jiffies;
if (sta->status_stats.lost_packets)
@@ -1154,11 +1160,52 @@ void ieee80211_tx_status_ext(struct ieee80211_hw *hw,
return;
} else if (noack_success) {
/* nothing to do here, do not account as lost */
+#ifdef CONFIG_MAC80211_DEBUG_STA_COUNTERS
+ do_stats = true;
+#endif
} else {
ieee80211_lost_packet(sta, info);
}
}
+#ifdef CONFIG_MAC80211_DEBUG_STA_COUNTERS
+ if (do_stats && (rates_idx != -1)) {
+ u8 nss = 0;
+ u8 mcs = 0;
+ struct ieee80211_tx_rate *txrt = &(info->status.rates[rates_idx]);
+ if (txrt->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+ sta->tx_stats.msdu_40++;
+ else if (txrt->flags & IEEE80211_TX_RC_80_MHZ_WIDTH)
+ sta->tx_stats.msdu_80++;
+ else if (txrt->flags & IEEE80211_TX_RC_160_MHZ_WIDTH)
+ sta->tx_stats.msdu_160++;
+ else
+ sta->tx_stats.msdu_20++;
+
+ if (txrt->flags & IEEE80211_TX_RC_MCS) {
+ nss = (txrt->idx / 8);
+ mcs = txrt->idx - (nss * 8);
+ sta->tx_stats.msdu_ht++;
+ }
+ else if (txrt->flags & IEEE80211_TX_RC_VHT_MCS) {
+ mcs = ieee80211_rate_get_vht_mcs(txrt);
+ nss = ieee80211_rate_get_vht_nss(txrt);
+ nss -= 1;
+ sta->tx_stats.msdu_vht++;
+ }
+ else {
+ mcs = txrt->idx;
+ sta->tx_stats.msdu_legacy++;
+ }
+
+ if (nss > (ARRAY_SIZE(sta->tx_stats.msdu_nss) - 1))
+ nss = ARRAY_SIZE(sta->tx_stats.msdu_nss) - 1;
+ if (mcs > (ARRAY_SIZE(sta->tx_stats.msdu_rate_idx) - 1))
+ mcs = ARRAY_SIZE(sta->tx_stats.msdu_rate_idx) - 1;
+ sta->tx_stats.msdu_nss[nss]++;
+ sta->tx_stats.msdu_rate_idx[mcs]++;
+ }
+#endif
rate_control_tx_status(local, sband, status);
if (ieee80211_vif_is_mesh(&sta->sdata->vif))
ieee80211s_update_metric(local, sta, status);