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>
This commit is contained in:
parent
6b127c71fb
commit
5cf16616e1
|
@ -505,6 +505,11 @@ struct ieee80211_bss_conf {
|
||||||
* @IEEE80211_TX_CTL_DONTFRAG: Don't fragment this packet even if it
|
* @IEEE80211_TX_CTL_DONTFRAG: Don't fragment this packet even if it
|
||||||
* would be fragmented by size (this is optional, only used for
|
* would be fragmented by size (this is optional, only used for
|
||||||
* monitor injection).
|
* monitor injection).
|
||||||
|
* @IEEE80211_TX_STAT_NOACK_TRANSMITTED: A frame that was marked with
|
||||||
|
* IEEE80211_TX_CTL_NO_ACK has been successfully transmitted without
|
||||||
|
* any errors (like issues specific to the driver/HW).
|
||||||
|
* This flag must not be set for frames that don't request no-ack
|
||||||
|
* behaviour with IEEE80211_TX_CTL_NO_ACK.
|
||||||
*
|
*
|
||||||
* Note: If you have to add new flags to the enumeration, then don't
|
* Note: If you have to add new flags to the enumeration, then don't
|
||||||
* forget to update %IEEE80211_TX_TEMPORARY_FLAGS when necessary.
|
* forget to update %IEEE80211_TX_TEMPORARY_FLAGS when necessary.
|
||||||
|
@ -540,6 +545,7 @@ enum mac80211_tx_info_flags {
|
||||||
IEEE80211_TX_STATUS_EOSP = BIT(28),
|
IEEE80211_TX_STATUS_EOSP = BIT(28),
|
||||||
IEEE80211_TX_CTL_USE_MINRATE = BIT(29),
|
IEEE80211_TX_CTL_USE_MINRATE = BIT(29),
|
||||||
IEEE80211_TX_CTL_DONTFRAG = BIT(30),
|
IEEE80211_TX_CTL_DONTFRAG = BIT(30),
|
||||||
|
IEEE80211_TX_STAT_NOACK_TRANSMITTED = BIT(31),
|
||||||
};
|
};
|
||||||
|
|
||||||
#define IEEE80211_TX_CTL_STBC_SHIFT 23
|
#define IEEE80211_TX_CTL_STBC_SHIFT 23
|
||||||
|
|
|
@ -664,13 +664,15 @@ void ieee80211_tx_status_noskb(struct ieee80211_hw *hw,
|
||||||
struct ieee80211_supported_band *sband;
|
struct ieee80211_supported_band *sband;
|
||||||
int retry_count;
|
int retry_count;
|
||||||
int rates_idx;
|
int rates_idx;
|
||||||
bool acked;
|
bool acked, noack_success;
|
||||||
|
|
||||||
rates_idx = ieee80211_tx_get_rates(hw, info, &retry_count);
|
rates_idx = ieee80211_tx_get_rates(hw, info, &retry_count);
|
||||||
|
|
||||||
sband = hw->wiphy->bands[info->band];
|
sband = hw->wiphy->bands[info->band];
|
||||||
|
|
||||||
acked = !!(info->flags & IEEE80211_TX_STAT_ACK);
|
acked = !!(info->flags & IEEE80211_TX_STAT_ACK);
|
||||||
|
noack_success = !!(info->flags & IEEE80211_TX_STAT_NOACK_TRANSMITTED);
|
||||||
|
|
||||||
if (pubsta) {
|
if (pubsta) {
|
||||||
struct sta_info *sta;
|
struct sta_info *sta;
|
||||||
|
|
||||||
|
@ -696,7 +698,7 @@ void ieee80211_tx_status_noskb(struct ieee80211_hw *hw,
|
||||||
rate_control_tx_status_noskb(local, sband, sta, info);
|
rate_control_tx_status_noskb(local, sband, sta, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (acked) {
|
if (acked || noack_success) {
|
||||||
local->dot11TransmittedFrameCount++;
|
local->dot11TransmittedFrameCount++;
|
||||||
if (!pubsta)
|
if (!pubsta)
|
||||||
local->dot11MulticastTransmittedFrameCount++;
|
local->dot11MulticastTransmittedFrameCount++;
|
||||||
|
@ -856,7 +858,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||||
* Fragments are passed to low-level drivers as separate skbs, so these
|
* Fragments are passed to low-level drivers as separate skbs, so these
|
||||||
* are actually fragments, not frames. Update frame counters only for
|
* are actually fragments, not frames. Update frame counters only for
|
||||||
* the first fragment of the frame. */
|
* the first fragment of the frame. */
|
||||||
if (info->flags & IEEE80211_TX_STAT_ACK) {
|
if ((info->flags & IEEE80211_TX_STAT_ACK) ||
|
||||||
|
(info->flags & IEEE80211_TX_STAT_NOACK_TRANSMITTED)) {
|
||||||
if (ieee80211_is_first_frag(hdr->seq_ctrl)) {
|
if (ieee80211_is_first_frag(hdr->seq_ctrl)) {
|
||||||
local->dot11TransmittedFrameCount++;
|
local->dot11TransmittedFrameCount++;
|
||||||
if (is_multicast_ether_addr(hdr->addr1))
|
if (is_multicast_ether_addr(hdr->addr1))
|
||||||
|
|
Loading…
Reference in New Issue