diff options
author | Sujith Manoharan <c_manoha@qca.qualcomm.com> | 2014-12-10 10:56:11 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2014-12-12 07:48:43 -0500 |
commit | 5cf16616e152dd5c274a65954c77f64892d025a8 (patch) | |
tree | 1ce531ca046ecf90ae561df50ea14fed6da0eb9f /net | |
parent | 6b127c71fbdd3daacfd8b9f80b8e6ebfb70a889e (diff) |
mac80211: Fix accounting of multicast frames
Since multicast frames are marked as no-ack, using
IEEE80211_TX_STAT_ACK to check if they have been
successfully transmitted by the driver is incorrect
since a driver can choose to ignore transmission status
for no-ack frames. This results in incorrect accounting
for such frames.
To fix this issue, this patch introduces a new flag
that can be used by drivers to indicate error-free
transmission of no-ack frames.
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
[add a note about not setting the flag for non-no-ack frames]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/status.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/net/mac80211/status.c b/net/mac80211/status.c index bb146f377ee4..d64037c96729 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c | |||
@@ -664,13 +664,15 @@ void ieee80211_tx_status_noskb(struct ieee80211_hw *hw, | |||
664 | struct ieee80211_supported_band *sband; | 664 | struct ieee80211_supported_band *sband; |
665 | int retry_count; | 665 | int retry_count; |
666 | int rates_idx; | 666 | int rates_idx; |
667 | bool acked; | 667 | bool acked, noack_success; |
668 | 668 | ||
669 | rates_idx = ieee80211_tx_get_rates(hw, info, &retry_count); | 669 | rates_idx = ieee80211_tx_get_rates(hw, info, &retry_count); |
670 | 670 | ||
671 | sband = hw->wiphy->bands[info->band]; | 671 | sband = hw->wiphy->bands[info->band]; |
672 | 672 | ||
673 | acked = !!(info->flags & IEEE80211_TX_STAT_ACK); | 673 | acked = !!(info->flags & IEEE80211_TX_STAT_ACK); |
674 | noack_success = !!(info->flags & IEEE80211_TX_STAT_NOACK_TRANSMITTED); | ||
675 | |||
674 | if (pubsta) { | 676 | if (pubsta) { |
675 | struct sta_info *sta; | 677 | struct sta_info *sta; |
676 | 678 | ||
@@ -696,7 +698,7 @@ void ieee80211_tx_status_noskb(struct ieee80211_hw *hw, | |||
696 | rate_control_tx_status_noskb(local, sband, sta, info); | 698 | rate_control_tx_status_noskb(local, sband, sta, info); |
697 | } | 699 | } |
698 | 700 | ||
699 | if (acked) { | 701 | if (acked || noack_success) { |
700 | local->dot11TransmittedFrameCount++; | 702 | local->dot11TransmittedFrameCount++; |
701 | if (!pubsta) | 703 | if (!pubsta) |
702 | local->dot11MulticastTransmittedFrameCount++; | 704 | local->dot11MulticastTransmittedFrameCount++; |
@@ -856,7 +858,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
856 | * Fragments are passed to low-level drivers as separate skbs, so these | 858 | * Fragments are passed to low-level drivers as separate skbs, so these |
857 | * are actually fragments, not frames. Update frame counters only for | 859 | * are actually fragments, not frames. Update frame counters only for |
858 | * the first fragment of the frame. */ | 860 | * the first fragment of the frame. */ |
859 | if (info->flags & IEEE80211_TX_STAT_ACK) { | 861 | if ((info->flags & IEEE80211_TX_STAT_ACK) || |
862 | (info->flags & IEEE80211_TX_STAT_NOACK_TRANSMITTED)) { | ||
860 | if (ieee80211_is_first_frag(hdr->seq_ctrl)) { | 863 | if (ieee80211_is_first_frag(hdr->seq_ctrl)) { |
861 | local->dot11TransmittedFrameCount++; | 864 | local->dot11TransmittedFrameCount++; |
862 | if (is_multicast_ether_addr(hdr->addr1)) | 865 | if (is_multicast_ether_addr(hdr->addr1)) |