Commit 040b97be authored by Jes Sorensen's avatar Jes Sorensen Committed by Kalle Valo

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: default avatarJes Sorensen <Jes.Sorensen@redhat.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 41892729
......@@ -5093,53 +5093,88 @@ static void rtl8723bu_handle_c2h(struct rtl8xxxu_priv *priv,
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;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment