From: Sasha Levin Date: Fri, 30 Aug 2019 14:53:15 +0000 (-0400) Subject: fixes for 5.2 X-Git-Tag: v4.4.191~58 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3f740c3323de26da676acd7ae33398d5f0a0ac32;p=thirdparty%2Fkernel%2Fstable-queue.git fixes for 5.2 Signed-off-by: Sasha Levin --- diff --git a/queue-5.2/mt76-usb-fix-rx-a-msdu-support.patch b/queue-5.2/mt76-usb-fix-rx-a-msdu-support.patch new file mode 100644 index 00000000000..fed1a6025d5 --- /dev/null +++ b/queue-5.2/mt76-usb-fix-rx-a-msdu-support.patch @@ -0,0 +1,107 @@ +From 7e00c8d6c543e69fd04591e249a92613c1c9008e Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Sat, 15 Jun 2019 16:03:32 +0200 +Subject: mt76: usb: fix rx A-MSDU support + +[ Upstream commit 2a92b08b18553c101115423bd34963b1a59a45a3 ] + +Commit f8f527b16db5 ("mt76: usb: use EP max packet aligned buffer sizes +for rx") breaks A-MSDU support. When A-MSDU is enable the device can +receive frames up to q->buf_size but they will be discarded in +mt76u_process_rx_entry since there is no enough room for +skb_shared_info. Fix the issue reallocating the skb and copying in the +linear area the first 128B of the received frames and in the frag_list +the remaining part + +Fixes: f8f527b16db5 ("mt76: usb: use EP max packet aligned buffer sizes for rx") +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Kalle Valo +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt76.h | 1 + + drivers/net/wireless/mediatek/mt76/usb.c | 46 ++++++++++++++++++----- + 2 files changed, 38 insertions(+), 9 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h +index 8ecbf81a906f5..889b76deb7037 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt76.h ++++ b/drivers/net/wireless/mediatek/mt76/mt76.h +@@ -30,6 +30,7 @@ + #define MT_TX_RING_SIZE 256 + #define MT_MCU_RING_SIZE 32 + #define MT_RX_BUF_SIZE 2048 ++#define MT_SKB_HEAD_LEN 128 + + struct mt76_dev; + struct mt76_wcid; +diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c +index bbaa1365bbda2..dd90427b2d672 100644 +--- a/drivers/net/wireless/mediatek/mt76/usb.c ++++ b/drivers/net/wireless/mediatek/mt76/usb.c +@@ -429,6 +429,42 @@ static int mt76u_get_rx_entry_len(u8 *data, u32 data_len) + return dma_len; + } + ++static struct sk_buff * ++mt76u_build_rx_skb(void *data, int len, int buf_size) ++{ ++ struct sk_buff *skb; ++ ++ if (SKB_WITH_OVERHEAD(buf_size) < MT_DMA_HDR_LEN + len) { ++ struct page *page; ++ ++ /* slow path, not enough space for data and ++ * skb_shared_info ++ */ ++ skb = alloc_skb(MT_SKB_HEAD_LEN, GFP_ATOMIC); ++ if (!skb) ++ return NULL; ++ ++ skb_put_data(skb, data + MT_DMA_HDR_LEN, MT_SKB_HEAD_LEN); ++ data += (MT_DMA_HDR_LEN + MT_SKB_HEAD_LEN); ++ page = virt_to_head_page(data); ++ skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, ++ page, data - page_address(page), ++ len - MT_SKB_HEAD_LEN, buf_size); ++ ++ return skb; ++ } ++ ++ /* fast path */ ++ skb = build_skb(data, buf_size); ++ if (!skb) ++ return NULL; ++ ++ skb_reserve(skb, MT_DMA_HDR_LEN); ++ __skb_put(skb, len); ++ ++ return skb; ++} ++ + static int + mt76u_process_rx_entry(struct mt76_dev *dev, struct urb *urb) + { +@@ -446,19 +482,11 @@ mt76u_process_rx_entry(struct mt76_dev *dev, struct urb *urb) + return 0; + + data_len = min_t(int, len, data_len - MT_DMA_HDR_LEN); +- if (MT_DMA_HDR_LEN + data_len > SKB_WITH_OVERHEAD(q->buf_size)) { +- dev_err_ratelimited(dev->dev, "rx data too big %d\n", data_len); +- return 0; +- } +- +- skb = build_skb(data, q->buf_size); ++ skb = mt76u_build_rx_skb(data, data_len, q->buf_size); + if (!skb) + return 0; + +- skb_reserve(skb, MT_DMA_HDR_LEN); +- __skb_put(skb, data_len); + len -= data_len; +- + while (len > 0 && nsgs < urb->num_sgs) { + data_len = min_t(int, len, urb->sg[nsgs].length); + skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, +-- +2.20.1 + diff --git a/queue-5.2/series b/queue-5.2/series index e325a9209bb..c65a6ba1c93 100644 --- a/queue-5.2/series +++ b/queue-5.2/series @@ -45,3 +45,4 @@ lcoking-rwsem-add-missing-acquire-to-read_slowpath-s.patch watchdog-bcm2835_wdt-fix-module-autoload.patch selftests-bpf-install-files-test_xdp_vlan.sh.patch drm-bridge-tfp410-fix-memleak-in-get_modes.patch +mt76-usb-fix-rx-a-msdu-support.patch