|
@@ -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;
|
|
|
|
|
@@ -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.
|
|
@@ -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;
|
|
@@ -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);
|
|
@@ -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)
|