aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2014-11-21 08:26:31 -0500
committerJohannes Berg <johannes.berg@intel.com>2015-01-08 09:28:20 -0500
commit79c892b85027d5074dfa670dd451c14ee649fb88 (patch)
treeb01b5e649d3d0256e5e84c886eda587b73ace6e1
parent6de39808cf1dd7b02bf42e7d8695d80f5eaf645d (diff)
mac80211: provide per-TID RX/TX MSDU counters
Implement the new counters cfg80211 can now advertise to userspace. The TX code is in the sequence number handler, which is a bit odd, but that place already knows the TID and frame type, so it was easiest and least impact there. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--net/mac80211/rx.c9
-rw-r--r--net/mac80211/sta_info.c31
-rw-r--r--net/mac80211/sta_info.h12
-rw-r--r--net/mac80211/status.c15
-rw-r--r--net/mac80211/tx.c3
5 files changed, 68 insertions, 2 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index fa5d870655a9..3a1a3ba40bd8 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2314,6 +2314,15 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
2314 if (unlikely(!ieee80211_is_data_present(hdr->frame_control))) 2314 if (unlikely(!ieee80211_is_data_present(hdr->frame_control)))
2315 return RX_DROP_MONITOR; 2315 return RX_DROP_MONITOR;
2316 2316
2317 if (rx->sta) {
2318 /* The security index has the same property as needed
2319 * for the rx_msdu field, i.e. it is IEEE80211_NUM_TIDS
2320 * for non-QoS-data frames. Here we know it's a data
2321 * frame, so count MSDUs.
2322 */
2323 rx->sta->rx_msdu[rx->security_idx]++;
2324 }
2325
2317 /* 2326 /*
2318 * Send unexpected-4addr-frame event to hostapd. For older versions, 2327 * Send unexpected-4addr-frame event to hostapd. For older versions,
2319 * also drop the frame to cooked monitor interfaces. 2328 * also drop the frame to cooked monitor interfaces.
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 64b53b943d98..dc352fcdd469 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -1843,6 +1843,37 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
1843 sinfo->filled |= BIT(NL80211_STA_INFO_RX_BITRATE); 1843 sinfo->filled |= BIT(NL80211_STA_INFO_RX_BITRATE);
1844 } 1844 }
1845 1845
1846 sinfo->filled |= BIT(NL80211_STA_INFO_TID_STATS);
1847 for (i = 0; i < IEEE80211_NUM_TIDS + 1; i++) {
1848 struct cfg80211_tid_stats *tidstats = &sinfo->pertid[i];
1849
1850 if (!(tidstats->filled & BIT(NL80211_TID_STATS_RX_MSDU))) {
1851 tidstats->filled |= BIT(NL80211_TID_STATS_RX_MSDU);
1852 tidstats->rx_msdu = sta->rx_msdu[i];
1853 }
1854
1855 if (!(tidstats->filled & BIT(NL80211_TID_STATS_TX_MSDU))) {
1856 tidstats->filled |= BIT(NL80211_TID_STATS_TX_MSDU);
1857 tidstats->tx_msdu = sta->tx_msdu[i];
1858 }
1859
1860 if (!(tidstats->filled &
1861 BIT(NL80211_TID_STATS_TX_MSDU_RETRIES)) &&
1862 local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) {
1863 tidstats->filled |=
1864 BIT(NL80211_TID_STATS_TX_MSDU_RETRIES);
1865 tidstats->tx_msdu_retries = sta->tx_msdu_retries[i];
1866 }
1867
1868 if (!(tidstats->filled &
1869 BIT(NL80211_TID_STATS_TX_MSDU_FAILED)) &&
1870 local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) {
1871 tidstats->filled |=
1872 BIT(NL80211_TID_STATS_TX_MSDU_FAILED);
1873 tidstats->tx_msdu_failed = sta->tx_msdu_failed[i];
1874 }
1875 }
1876
1846 if (ieee80211_vif_is_mesh(&sdata->vif)) { 1877 if (ieee80211_vif_is_mesh(&sdata->vif)) {
1847#ifdef CONFIG_MAC80211_MESH 1878#ifdef CONFIG_MAC80211_MESH
1848 sinfo->filled |= BIT(NL80211_STA_INFO_LLID) | 1879 sinfo->filled |= BIT(NL80211_STA_INFO_LLID) |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 4f052bb2a5ad..925e68fe64c7 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -346,6 +346,14 @@ struct ieee80211_tx_latency_stat {
346 * @cipher_scheme: optional cipher scheme for this station 346 * @cipher_scheme: optional cipher scheme for this station
347 * @last_tdls_pkt_time: holds the time in jiffies of last TDLS pkt ACKed 347 * @last_tdls_pkt_time: holds the time in jiffies of last TDLS pkt ACKed
348 * @reserved_tid: reserved TID (if any, otherwise IEEE80211_TID_UNRESERVED) 348 * @reserved_tid: reserved TID (if any, otherwise IEEE80211_TID_UNRESERVED)
349 * @tx_msdu: MSDUs transmitted to this station, using IEEE80211_NUM_TID
350 * entry for non-QoS frames
351 * @tx_msdu_retries: MSDU retries for transmissions to to this station,
352 * using IEEE80211_NUM_TID entry for non-QoS frames
353 * @tx_msdu_failed: MSDU failures for transmissions to to this station,
354 * using IEEE80211_NUM_TID entry for non-QoS frames
355 * @rx_msdu: MSDUs received from this station, using IEEE80211_NUM_TID
356 * entry for non-QoS frames
349 */ 357 */
350struct sta_info { 358struct sta_info {
351 /* General information, mostly static */ 359 /* General information, mostly static */
@@ -416,6 +424,10 @@ struct sta_info {
416 u32 last_rx_rate_vht_flag; 424 u32 last_rx_rate_vht_flag;
417 u8 last_rx_rate_vht_nss; 425 u8 last_rx_rate_vht_nss;
418 u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1]; 426 u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1];
427 u64 tx_msdu[IEEE80211_NUM_TIDS + 1];
428 u64 tx_msdu_retries[IEEE80211_NUM_TIDS + 1];
429 u64 tx_msdu_failed[IEEE80211_NUM_TIDS + 1];
430 u64 rx_msdu[IEEE80211_NUM_TIDS + 1];
419 431
420 /* 432 /*
421 * Aggregation information, locked with lock. 433 * Aggregation information, locked with lock.
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 7d4e9307164c..788707f05516 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -730,6 +730,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
730 struct ieee80211_bar *bar; 730 struct ieee80211_bar *bar;
731 int rtap_len; 731 int rtap_len;
732 int shift = 0; 732 int shift = 0;
733 int tid = IEEE80211_NUM_TIDS;;
733 734
734 rates_idx = ieee80211_tx_get_rates(hw, info, &retry_count); 735 rates_idx = ieee80211_tx_get_rates(hw, info, &retry_count);
735 736
@@ -773,7 +774,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
773 774
774 if ((info->flags & IEEE80211_TX_STAT_AMPDU_NO_BACK) && 775 if ((info->flags & IEEE80211_TX_STAT_AMPDU_NO_BACK) &&
775 (ieee80211_is_data_qos(fc))) { 776 (ieee80211_is_data_qos(fc))) {
776 u16 tid, ssn; 777 u16 ssn;
777 u8 *qc; 778 u8 *qc;
778 779
779 qc = ieee80211_get_qos_ctl(hdr); 780 qc = ieee80211_get_qos_ctl(hdr);
@@ -782,10 +783,14 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
782 & IEEE80211_SCTL_SEQ); 783 & IEEE80211_SCTL_SEQ);
783 ieee80211_send_bar(&sta->sdata->vif, hdr->addr1, 784 ieee80211_send_bar(&sta->sdata->vif, hdr->addr1,
784 tid, ssn); 785 tid, ssn);
786 } else if (ieee80211_is_data_qos(fc)) {
787 u8 *qc = ieee80211_get_qos_ctl(hdr);
788
789 tid = qc[0] & 0xf;
785 } 790 }
786 791
787 if (!acked && ieee80211_is_back_req(fc)) { 792 if (!acked && ieee80211_is_back_req(fc)) {
788 u16 tid, control; 793 u16 control;
789 794
790 /* 795 /*
791 * BAR failed, store the last SSN and retry sending 796 * BAR failed, store the last SSN and retry sending
@@ -813,6 +818,12 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
813 if (!acked) 818 if (!acked)
814 sta->tx_retry_failed++; 819 sta->tx_retry_failed++;
815 sta->tx_retry_count += retry_count; 820 sta->tx_retry_count += retry_count;
821
822 if (ieee80211_is_data_present(fc)) {
823 if (!acked)
824 sta->tx_msdu_failed[tid]++;
825 sta->tx_msdu_retries[tid] += retry_count;
826 }
816 } 827 }
817 828
818 rate_control_tx_status(local, sband, sta, skb); 829 rate_control_tx_status(local, sband, sta, skb);
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 058686a721a1..da7f352a2b16 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -815,6 +815,8 @@ ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx)
815 /* for pure STA mode without beacons, we can do it */ 815 /* for pure STA mode without beacons, we can do it */
816 hdr->seq_ctrl = cpu_to_le16(tx->sdata->sequence_number); 816 hdr->seq_ctrl = cpu_to_le16(tx->sdata->sequence_number);
817 tx->sdata->sequence_number += 0x10; 817 tx->sdata->sequence_number += 0x10;
818 if (tx->sta)
819 tx->sta->tx_msdu[IEEE80211_NUM_TIDS]++;
818 return TX_CONTINUE; 820 return TX_CONTINUE;
819 } 821 }
820 822
@@ -831,6 +833,7 @@ ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx)
831 qc = ieee80211_get_qos_ctl(hdr); 833 qc = ieee80211_get_qos_ctl(hdr);
832 tid = *qc & IEEE80211_QOS_CTL_TID_MASK; 834 tid = *qc & IEEE80211_QOS_CTL_TID_MASK;
833 seq = &tx->sta->tid_seq[tid]; 835 seq = &tx->sta->tid_seq[tid];
836 tx->sta->tx_msdu[tid]++;
834 837
835 hdr->seq_ctrl = cpu_to_le16(*seq); 838 hdr->seq_ctrl = cpu_to_le16(*seq);
836 839