mirror of
https://github.com/openwrt/openwrt.git
synced 2025-01-04 04:54:18 +00:00
36f6d6ddcd
Backport support for RTL8812AU/RTL8821AU USB adapters Manually backported patch: 045-v6.13-wifi-rtw88-Enable-the-new-RTL8821AU-RTL8812AU-driver Patches from 046 to 051 are pending. Signed-off-by: Marty Jones <mj8263788@gmail.com> Link: https://github.com/openwrt/openwrt/pull/17079 [Move BPAUTO_WANT_DEV_COREDUMP to original patch] Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
119 lines
3.7 KiB
Diff
119 lines
3.7 KiB
Diff
From df3d8f463b1dfc7cb8f4fb52b1b81d290b850d03 Mon Sep 17 00:00:00 2001
|
|
From: Bitterblue Smith <rtl8821cerfe2@gmail.com>
|
|
Date: Thu, 8 Aug 2024 01:21:36 +0300
|
|
Subject: [PATCH] wifi: rtw88: usb: Support RX aggregation
|
|
|
|
The chips can be configured to aggregate several frames into a single
|
|
USB transfer. Modify rtw_usb_rx_handler() to support this case.
|
|
|
|
RX aggregation improves the RX speed of RTL8811CU on certain ARM
|
|
systems, like the NanoPi NEO Core2. It also improves the RX speed of
|
|
RTL8822CU on some x86_64 systems.
|
|
|
|
Currently none of the chips are configured to aggregate frames.
|
|
|
|
Tested with RTL8822CU, RTL8811CU, and RTL8723DU.
|
|
|
|
Reviewed-by: Sascha Hauer <s.hauer@pengutronix.de>
|
|
Tested-by: Sascha Hauer <s.hauer@pengutronix.de>
|
|
Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
|
|
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
|
|
Link: https://patch.msgid.link/f845826d-de71-492d-9a22-e48c07989a1f@gmail.com
|
|
---
|
|
drivers/net/wireless/realtek/rtw88/usb.c | 61 ++++++++++++++++--------
|
|
1 file changed, 40 insertions(+), 21 deletions(-)
|
|
|
|
--- a/drivers/net/wireless/realtek/rtw88/usb.c
|
|
+++ b/drivers/net/wireless/realtek/rtw88/usb.c
|
|
@@ -546,11 +546,12 @@ static void rtw_usb_rx_handler(struct wo
|
|
struct rtw_usb *rtwusb = container_of(work, struct rtw_usb, rx_work);
|
|
struct rtw_dev *rtwdev = rtwusb->rtwdev;
|
|
const struct rtw_chip_info *chip = rtwdev->chip;
|
|
- struct rtw_rx_pkt_stat pkt_stat;
|
|
+ u32 pkt_desc_sz = chip->rx_pkt_desc_sz;
|
|
struct ieee80211_rx_status rx_status;
|
|
+ u32 pkt_offset, next_pkt, urb_len;
|
|
+ struct rtw_rx_pkt_stat pkt_stat;
|
|
+ struct sk_buff *next_skb;
|
|
struct sk_buff *skb;
|
|
- u32 pkt_desc_sz = chip->rx_pkt_desc_sz;
|
|
- u32 pkt_offset;
|
|
u8 *rx_desc;
|
|
int limit;
|
|
|
|
@@ -559,31 +560,48 @@ static void rtw_usb_rx_handler(struct wo
|
|
if (!skb)
|
|
break;
|
|
|
|
- rx_desc = skb->data;
|
|
- chip->ops->query_rx_desc(rtwdev, rx_desc, &pkt_stat,
|
|
- &rx_status);
|
|
- pkt_offset = pkt_desc_sz + pkt_stat.drv_info_sz +
|
|
- pkt_stat.shift;
|
|
-
|
|
- if (pkt_stat.is_c2h) {
|
|
- skb_put(skb, pkt_stat.pkt_len + pkt_offset);
|
|
- rtw_fw_c2h_cmd_rx_irqsafe(rtwdev, pkt_offset, skb);
|
|
- continue;
|
|
- }
|
|
-
|
|
if (skb_queue_len(&rtwusb->rx_queue) >= RTW_USB_MAX_RXQ_LEN) {
|
|
dev_dbg_ratelimited(rtwdev->dev, "failed to get rx_queue, overflow\n");
|
|
dev_kfree_skb_any(skb);
|
|
continue;
|
|
}
|
|
|
|
- skb_put(skb, pkt_stat.pkt_len);
|
|
- skb_reserve(skb, pkt_offset);
|
|
+ urb_len = skb->len;
|
|
+
|
|
+ do {
|
|
+ rx_desc = skb->data;
|
|
+ chip->ops->query_rx_desc(rtwdev, rx_desc, &pkt_stat,
|
|
+ &rx_status);
|
|
+ pkt_offset = pkt_desc_sz + pkt_stat.drv_info_sz +
|
|
+ pkt_stat.shift;
|
|
+
|
|
+ next_pkt = round_up(pkt_stat.pkt_len + pkt_offset, 8);
|
|
+
|
|
+ if (urb_len >= next_pkt + pkt_desc_sz)
|
|
+ next_skb = skb_clone(skb, GFP_KERNEL);
|
|
+ else
|
|
+ next_skb = NULL;
|
|
+
|
|
+ if (pkt_stat.is_c2h) {
|
|
+ skb_trim(skb, pkt_stat.pkt_len + pkt_offset);
|
|
+ rtw_fw_c2h_cmd_rx_irqsafe(rtwdev, pkt_offset, skb);
|
|
+ } else {
|
|
+ skb_pull(skb, pkt_offset);
|
|
+ skb_trim(skb, pkt_stat.pkt_len);
|
|
+ rtw_update_rx_freq_for_invalid(rtwdev, skb,
|
|
+ &rx_status,
|
|
+ &pkt_stat);
|
|
+ rtw_rx_stats(rtwdev, pkt_stat.vif, skb);
|
|
+ memcpy(skb->cb, &rx_status, sizeof(rx_status));
|
|
+ ieee80211_rx_irqsafe(rtwdev->hw, skb);
|
|
+ }
|
|
+
|
|
+ skb = next_skb;
|
|
+ if (skb)
|
|
+ skb_pull(skb, next_pkt);
|
|
|
|
- rtw_update_rx_freq_for_invalid(rtwdev, skb, &rx_status, &pkt_stat);
|
|
- rtw_rx_stats(rtwdev, pkt_stat.vif, skb);
|
|
- memcpy(skb->cb, &rx_status, sizeof(rx_status));
|
|
- ieee80211_rx_irqsafe(rtwdev->hw, skb);
|
|
+ urb_len -= next_pkt;
|
|
+ } while (skb);
|
|
}
|
|
}
|
|
|
|
@@ -627,6 +645,7 @@ static void rtw_usb_read_port_complete(s
|
|
if (skb)
|
|
dev_kfree_skb_any(skb);
|
|
} else {
|
|
+ skb_put(skb, urb->actual_length);
|
|
skb_queue_tail(&rtwusb->rx_queue, skb);
|
|
queue_work(rtwusb->rxwq, &rtwusb->rx_work);
|
|
}
|