aboutsummaryrefslogtreecommitdiffstats
path: root/package/kernel/mac80211/patches/650-0010-rtl8xxxu-Add-support-for-aggregated-RX-packets-on-ge.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/kernel/mac80211/patches/650-0010-rtl8xxxu-Add-support-for-aggregated-RX-packets-on-ge.patch')
-rw-r--r--package/kernel/mac80211/patches/650-0010-rtl8xxxu-Add-support-for-aggregated-RX-packets-on-ge.patch140
1 files changed, 140 insertions, 0 deletions
diff --git a/package/kernel/mac80211/patches/650-0010-rtl8xxxu-Add-support-for-aggregated-RX-packets-on-ge.patch b/package/kernel/mac80211/patches/650-0010-rtl8xxxu-Add-support-for-aggregated-RX-packets-on-ge.patch
new file mode 100644
index 0000000000..6a6da06404
--- /dev/null
+++ b/package/kernel/mac80211/patches/650-0010-rtl8xxxu-Add-support-for-aggregated-RX-packets-on-ge.patch
@@ -0,0 +1,140 @@
+From 6cee81e9411abb9fc538308b06e75b4f2cdbde1c Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <Jes.Sorensen@redhat.com>
+Date: Fri, 20 May 2016 00:15:47 -0400
+Subject: [PATCH] rtl8xxxu: Add support for aggregated RX packets on gen1 parts
+
+This implements support for demuxing aggregated RX packets on gen1
+devices, using the rxdesc16 format.
+
+So far this has only been tested with rtl8723au devices.
+
+Signed-off-by: Jes Sorensen <Jes.Sorensen@redhat.com>
+---
+ .../net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 103 ++++++++++++++-------
+ 1 file changed, 69 insertions(+), 34 deletions(-)
+
+--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
+@@ -5093,53 +5093,88 @@ static void rtl8723bu_handle_c2h(struct
+ int rtl8xxxu_parse_rxdesc16(struct rtl8xxxu_priv *priv, struct sk_buff *skb)
+ {
+ struct ieee80211_hw *hw = priv->hw;
+- struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb);
+- struct rtl8xxxu_rxdesc16 *rx_desc =
+- (struct rtl8xxxu_rxdesc16 *)skb->data;
++ struct ieee80211_rx_status *rx_status;
++ struct rtl8xxxu_rxdesc16 *rx_desc;
+ struct rtl8723au_phy_stats *phy_stats;
+- __le32 *_rx_desc_le = (__le32 *)skb->data;
+- u32 *_rx_desc = (u32 *)skb->data;
++ struct sk_buff *next_skb = NULL;
++ __le32 *_rx_desc_le;
++ u32 *_rx_desc;
+ int drvinfo_sz, desc_shift;
+- int i;
++ int i, pkt_cnt, pkt_len, urb_len, pkt_offset;
+
+- for (i = 0; i < (sizeof(struct rtl8xxxu_rxdesc16) / sizeof(u32)); i++)
+- _rx_desc[i] = le32_to_cpu(_rx_desc_le[i]);
++ urb_len = skb->len;
++ pkt_cnt = 0;
+
+- memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
++ do {
++ rx_desc = (struct rtl8xxxu_rxdesc16 *)skb->data;
++ _rx_desc_le = (__le32 *)skb->data;
++ _rx_desc = (u32 *)skb->data;
+
+- skb_pull(skb, sizeof(struct rtl8xxxu_rxdesc16));
++ for (i = 0;
++ i < (sizeof(struct rtl8xxxu_rxdesc16) / sizeof(u32)); i++)
++ _rx_desc[i] = le32_to_cpu(_rx_desc_le[i]);
+
+- phy_stats = (struct rtl8723au_phy_stats *)skb->data;
++ /*
++ * Only read pkt_cnt from the header if we're parsing the
++ * first packet
++ */
++ if (!pkt_cnt)
++ pkt_cnt = rx_desc->pkt_cnt;
++ pkt_len = rx_desc->pktlen;
+
+- drvinfo_sz = rx_desc->drvinfo_sz * 8;
+- desc_shift = rx_desc->shift;
+- skb_pull(skb, drvinfo_sz + desc_shift);
++ drvinfo_sz = rx_desc->drvinfo_sz * 8;
++ desc_shift = rx_desc->shift;
++ pkt_offset = roundup(pkt_len + drvinfo_sz + desc_shift +
++ sizeof(struct rtl8xxxu_rxdesc16), 128);
+
+- if (rx_desc->phy_stats)
+- rtl8xxxu_rx_parse_phystats(priv, rx_status, phy_stats,
+- rx_desc->rxmcs);
++ if (pkt_cnt > 1)
++ next_skb = skb_clone(skb, GFP_ATOMIC);
+
+- rx_status->mactime = le32_to_cpu(rx_desc->tsfl);
+- rx_status->flag |= RX_FLAG_MACTIME_START;
++ rx_status = IEEE80211_SKB_RXCB(skb);
++ memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
+
+- if (!rx_desc->swdec)
+- rx_status->flag |= RX_FLAG_DECRYPTED;
+- if (rx_desc->crc32)
+- rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
+- if (rx_desc->bw)
+- rx_status->flag |= RX_FLAG_40MHZ;
++ skb_pull(skb, sizeof(struct rtl8xxxu_rxdesc16));
+
+- if (rx_desc->rxht) {
+- rx_status->flag |= RX_FLAG_HT;
+- rx_status->rate_idx = rx_desc->rxmcs - DESC_RATE_MCS0;
+- } else {
+- rx_status->rate_idx = rx_desc->rxmcs;
+- }
++ phy_stats = (struct rtl8723au_phy_stats *)skb->data;
+
+- rx_status->freq = hw->conf.chandef.chan->center_freq;
+- rx_status->band = hw->conf.chandef.chan->band;
++ skb_pull(skb, drvinfo_sz + desc_shift);
++
++ skb_trim(skb, pkt_len);
++
++ if (rx_desc->phy_stats)
++ rtl8xxxu_rx_parse_phystats(priv, rx_status, phy_stats,
++ rx_desc->rxmcs);
++
++ rx_status->mactime = le32_to_cpu(rx_desc->tsfl);
++ rx_status->flag |= RX_FLAG_MACTIME_START;
++
++ if (!rx_desc->swdec)
++ rx_status->flag |= RX_FLAG_DECRYPTED;
++ if (rx_desc->crc32)
++ rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
++ if (rx_desc->bw)
++ rx_status->flag |= RX_FLAG_40MHZ;
++
++ if (rx_desc->rxht) {
++ rx_status->flag |= RX_FLAG_HT;
++ rx_status->rate_idx = rx_desc->rxmcs - DESC_RATE_MCS0;
++ } else {
++ rx_status->rate_idx = rx_desc->rxmcs;
++ }
++
++ rx_status->freq = hw->conf.chandef.chan->center_freq;
++ rx_status->band = hw->conf.chandef.chan->band;
++
++ ieee80211_rx_irqsafe(hw, skb);
++
++ skb = next_skb;
++ if (skb)
++ skb_pull(next_skb, pkt_offset);
++
++ pkt_cnt--;
++ urb_len -= pkt_offset;
++ } while (skb && urb_len > 0 && pkt_cnt > 0);
+
+- ieee80211_rx_irqsafe(hw, skb);
+ return RX_TYPE_DATA_PKT;
+ }
+