Skip to content

Commit

Permalink
carl9170: report A-MPDU status
Browse files Browse the repository at this point in the history
Because the hardware reports whenever an frame
was either at the start, in the middle or at
the end of a A-MPDU, we can easily report the
information for radiotap.

Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Christian Lamparter authored and John W. Linville committed Aug 21, 2012
1 parent 6957802 commit 33dd769
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 4 deletions.
1 change: 1 addition & 0 deletions drivers/net/wireless/ath/carl9170/carl9170.h
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,7 @@ struct ar9170 {
bool rx_has_plcp;
struct sk_buff *rx_failover;
int rx_failover_missing;
u32 ampdu_ref;

/* FIFO for collecting outstanding BlockAckRequest */
struct list_head bar_list[__AR9170_NUM_TXQ];
Expand Down
15 changes: 11 additions & 4 deletions drivers/net/wireless/ath/carl9170/rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -624,7 +624,8 @@ static void carl9170_ba_check(struct ar9170 *ar, void *data, unsigned int len)
#undef TID_CHECK
}

static bool carl9170_ampdu_check(struct ar9170 *ar, u8 *buf, u8 ms)
static bool carl9170_ampdu_check(struct ar9170 *ar, u8 *buf, u8 ms,
struct ieee80211_rx_status *rx_status)
{
__le16 fc;

Expand All @@ -637,6 +638,9 @@ static bool carl9170_ampdu_check(struct ar9170 *ar, u8 *buf, u8 ms)
return true;
}

rx_status->flag |= RX_FLAG_AMPDU_DETAILS | RX_FLAG_AMPDU_LAST_KNOWN;
rx_status->ampdu_reference = ar->ampdu_ref;

/*
* "802.11n - 7.4a.3 A-MPDU contents" describes in which contexts
* certain frame types can be part of an aMPDU.
Expand Down Expand Up @@ -685,12 +689,15 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
if (unlikely(len < sizeof(*mac)))
goto drop;

memset(&status, 0, sizeof(status));

mpdu_len = len - sizeof(*mac);

mac = (void *)(buf + mpdu_len);
mac_status = mac->status;
switch (mac_status & AR9170_RX_STATUS_MPDU) {
case AR9170_RX_STATUS_MPDU_FIRST:
ar->ampdu_ref++;
/* Aggregated MPDUs start with an PLCP header */
if (likely(mpdu_len >= sizeof(struct ar9170_rx_head))) {
head = (void *) buf;
Expand Down Expand Up @@ -721,12 +728,13 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
break;

case AR9170_RX_STATUS_MPDU_LAST:
status.flag |= RX_FLAG_AMPDU_IS_LAST;

/*
* The last frame of an A-MPDU has an extra tail
* which does contain the phy status of the whole
* aggregate.
*/

if (likely(mpdu_len >= sizeof(struct ar9170_rx_phystatus))) {
mpdu_len -= sizeof(struct ar9170_rx_phystatus);
phy = (void *)(buf + mpdu_len);
Expand Down Expand Up @@ -774,11 +782,10 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
if (unlikely(mpdu_len < (2 + 2 + ETH_ALEN + FCS_LEN)))
goto drop;

memset(&status, 0, sizeof(status));
if (unlikely(carl9170_rx_mac_status(ar, head, mac, &status)))
goto drop;

if (!carl9170_ampdu_check(ar, buf, mac_status))
if (!carl9170_ampdu_check(ar, buf, mac_status, &status))
goto drop;

if (phy)
Expand Down

0 comments on commit 33dd769

Please sign in to comment.