[RFT/RFC 4/5] ath10k: report amsdu as a skb list
Janusz Dziedzic
janusz.dziedzic at tieto.com
Thu Jul 10 04:45:13 PDT 2014
Signed-off-by: Janusz Dziedzic <janusz.dziedzic at tieto.com>
---
drivers/net/wireless/ath/ath10k/htt_rx.c | 48 +++++++++++-------------------
1 file changed, 18 insertions(+), 30 deletions(-)
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 2a0526b..702653e 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -874,15 +874,14 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt,
{
struct htt_rx_desc *rxd;
struct sk_buff *skb = skb_in;
- struct sk_buff *first, *frame = NULL, *tmp;
+ struct sk_buff *first;
enum rx_msdu_decap_format fmt;
enum htt_rx_mpdu_encrypt_type enctype;
struct ieee80211_hdr *hdr;
u8 hdr_buf[64], addr[ETH_ALEN];
unsigned int hdr_len;
struct amsdu_subframe_hdr subframe_hdr;
- unsigned int size = 0;
- u8 padding;
+ struct ieee80211_rx_status *status;
rxd = (void *)skb->data - sizeof(*rxd);
enctype = MS(__le32_to_cpu(rxd->mpdu_start.info0),
@@ -893,21 +892,6 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt,
memcpy(hdr_buf, hdr, hdr_len);
hdr = (struct ieee80211_hdr *)hdr_buf;
- /* Check size we will need */
- tmp = skb_in;
- while (tmp) {
- size = size + tmp->len;
- tmp = tmp->next;
- }
-
- frame = dev_alloc_skb(size + skb_headroom(skb_in));
- if (!frame) {
- dev_kfree_skb_any(skb_in);
- return;
- }
-
- skb_reserve(frame, skb_headroom(skb_in));
-
first = skb;
while (skb) {
void *decap_hdr;
@@ -940,10 +924,6 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt,
memcpy(addr, ieee80211_get_DA(hdr), ETH_ALEN);
skb_pull(skb, hdr_len);
- /* cfg80211 expect this padding */
- padding = (4 - (skb->len + sizeof(subframe_hdr))) & 0x3;
- skb_put(skb, padding);
-
/* build amsdu subframe header */
memcpy(&subframe_hdr.dst, addr, ETH_ALEN);
memcpy(&subframe_hdr.src, ieee80211_get_SA(hdr), ETH_ALEN);
@@ -984,20 +964,26 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt,
skb_in = skb;
- if (skb_in == first)
- ath10k_htt_rx_h_protected(htt, rx_status, skb_in,
+ if (skb == first) {
+ ath10k_htt_rx_h_protected(htt, rx_status, skb,
enctype, fmt, false);
+ if (skb->next)
+ rx_status->flag |= RX_FLAG_AMSDU_LIST;
+ else
+ rx_status->flag &= ~RX_FLAG_AMSDU_LIST;
+ }
- memcpy(skb_put(frame, skb_in->len), skb_in->data, skb_in->len);
+ /* Setup AMSDU flag in skb->next ... subframes */
+ status = IEEE80211_SKB_RXCB(skb);
+ memset(status, 0, sizeof(*status));
- skb = skb->next;
- skb_in->next = NULL;
+ if (skb->next)
+ status->flag |= RX_FLAG_AMSDU_LIST;
- /* We don't need this skb anymore */
- dev_kfree_skb(skb_in);
+ skb = skb->next;
}
- ath10k_process_rx(htt->ar, rx_status, frame);
+ ath10k_process_rx(htt->ar, rx_status, first);
/* FIXME: It might be nice to re-assemble the A-MSDU when there's a
* monitor interface active for sniffing purposes. */
}
@@ -1307,6 +1293,8 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
else
rx_status->flag &= ~RX_FLAG_MMIC_ERROR;
+ rx_status->flag &= ~RX_FLAG_AMSDU_LIST;
+
hdr = ath10k_htt_rx_skb_get_hdr(msdu_head);
if (ath10k_htt_rx_hdr_is_amsdu(hdr))
--
1.7.9.5
More information about the ath10k
mailing list