diff options
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.patch | 140 |
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; + } + |