Commit 0cfcefef authored by Michal Kazior's avatar Michal Kazior Committed by Johannes Berg
Browse files

mac80211: support reporting A-MSDU subframes individually

Some devices may not be able to report A-MSDUs in
single buffers. Drivers for such devices were
forced to re-assemble A-MSDUs which would then
be eventually disassembled by mac80211. This could
lead to CPU cache thrashing and poor performance.

Since A-MSDU has a single sequence number all
subframes share it. This was in conflict with
retransmission/duplication recovery

Patch introduces a new flag that is meant to be
set for all individually reported A-MSDU subframes
except the last one. This ensures the
last_seq_ctrl is updated after the last subframe
is processed. If an A-MSDU is actually a duplicate
transmission all reported subframes will be
properly discarded.
Signed-off-by: default avatarMichal Kazior <>
[johannes: add braces that were missing even before]
Signed-off-by: default avatarJohannes Berg <>
parent 15e230ab
......@@ -829,6 +829,15 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
* @RX_FLAG_STBC_MASK: STBC 2 bit bitmask. 1 - Nss=1, 2 - Nss=2, 3 - Nss=3
* @RX_FLAG_10MHZ: 10 MHz (half channel) was used
* @RX_FLAG_5MHZ: 5 MHz (quarter channel) was used
* @RX_FLAG_AMSDU_MORE: Some drivers may prefer to report separate A-MSDU
* subframes instead of a one huge frame for performance reasons.
* All, but the last MSDU from an A-MSDU should have this flag set. E.g.
* if an A-MSDU has 3 frames, the first 2 must have the flag set, while
* the 3rd (last) one must not have this flag set. The flag is used to
* deal with retransmission/duplication recovery properly since A-MSDU
* subframes share the same sequence number. Reported subframes can be
* either regular MSDU or singly A-MSDUs. Subframes must not be
* interleaved with other frames.
enum mac80211_rx_flags {
......@@ -859,6 +868,7 @@ enum mac80211_rx_flags {
RX_FLAG_10MHZ = BIT(28),
......@@ -995,8 +995,9 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
} else
} else if (!(status->flag & RX_FLAG_AMSDU_MORE)) {
rx->sta->last_seq_ctrl[rx->seqno_idx] = hdr->seq_ctrl;
if (unlikely(rx->skb->len < 16)) {
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment