]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.19.54/net-aquantia-fix-lro-with-fcs-error.patch
Linux 4.19.54
[thirdparty/kernel/stable-queue.git] / releases / 4.19.54 / net-aquantia-fix-lro-with-fcs-error.patch
CommitLineData
a15a8890
SL
1From 6460d4530b9adde94834f3a53920739b80a1e6d7 Mon Sep 17 00:00:00 2001
2From: Dmitry Bogdanov <dmitry.bogdanov@aquantia.com>
3Date: Sat, 25 May 2019 09:58:03 +0000
4Subject: net: aquantia: fix LRO with FCS error
5
6[ Upstream commit eaeb3b7494ba9159323814a8ce8af06a9277d99b ]
7
8Driver stops producing skbs on ring if a packet with FCS error
9was coalesced into LRO session. Ring gets hang forever.
10
11Thats a logical error in driver processing descriptors:
12When rx_stat indicates MAC Error, next pointer and eop flags
13are not filled. This confuses driver so it waits for descriptor 0
14to be filled by HW.
15
16Solution is fill next pointer and eop flag even for packets with FCS error.
17
18Fixes: bab6de8fd180b ("net: ethernet: aquantia: Atlantic A0 and B0 specific functions.")
19Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
20Signed-off-by: Dmitry Bogdanov <dmitry.bogdanov@aquantia.com>
21Signed-off-by: David S. Miller <davem@davemloft.net>
22Signed-off-by: Sasha Levin <sashal@kernel.org>
23---
24 .../aquantia/atlantic/hw_atl/hw_atl_b0.c | 61 ++++++++++---------
25 1 file changed, 32 insertions(+), 29 deletions(-)
26
27diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
28index 56363ff5c891..51cd1f98bcf0 100644
29--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
30+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
31@@ -695,38 +695,41 @@ static int hw_atl_b0_hw_ring_rx_receive(struct aq_hw_s *self,
32 if ((rx_stat & BIT(0)) || rxd_wb->type & 0x1000U) {
33 /* MAC error or DMA error */
34 buff->is_error = 1U;
35- } else {
36- if (self->aq_nic_cfg->is_rss) {
37- /* last 4 byte */
38- u16 rss_type = rxd_wb->type & 0xFU;
39-
40- if (rss_type && rss_type < 0x8U) {
41- buff->is_hash_l4 = (rss_type == 0x4 ||
42- rss_type == 0x5);
43- buff->rss_hash = rxd_wb->rss_hash;
44- }
45+ }
46+ if (self->aq_nic_cfg->is_rss) {
47+ /* last 4 byte */
48+ u16 rss_type = rxd_wb->type & 0xFU;
49+
50+ if (rss_type && rss_type < 0x8U) {
51+ buff->is_hash_l4 = (rss_type == 0x4 ||
52+ rss_type == 0x5);
53+ buff->rss_hash = rxd_wb->rss_hash;
54 }
55+ }
56
57- if (HW_ATL_B0_RXD_WB_STAT2_EOP & rxd_wb->status) {
58- buff->len = rxd_wb->pkt_len %
59- AQ_CFG_RX_FRAME_MAX;
60- buff->len = buff->len ?
61- buff->len : AQ_CFG_RX_FRAME_MAX;
62- buff->next = 0U;
63- buff->is_eop = 1U;
64+ if (HW_ATL_B0_RXD_WB_STAT2_EOP & rxd_wb->status) {
65+ buff->len = rxd_wb->pkt_len %
66+ AQ_CFG_RX_FRAME_MAX;
67+ buff->len = buff->len ?
68+ buff->len : AQ_CFG_RX_FRAME_MAX;
69+ buff->next = 0U;
70+ buff->is_eop = 1U;
71+ } else {
72+ buff->len =
73+ rxd_wb->pkt_len > AQ_CFG_RX_FRAME_MAX ?
74+ AQ_CFG_RX_FRAME_MAX : rxd_wb->pkt_len;
75+
76+ if (HW_ATL_B0_RXD_WB_STAT2_RSCCNT &
77+ rxd_wb->status) {
78+ /* LRO */
79+ buff->next = rxd_wb->next_desc_ptr;
80+ ++ring->stats.rx.lro_packets;
81 } else {
82- if (HW_ATL_B0_RXD_WB_STAT2_RSCCNT &
83- rxd_wb->status) {
84- /* LRO */
85- buff->next = rxd_wb->next_desc_ptr;
86- ++ring->stats.rx.lro_packets;
87- } else {
88- /* jumbo */
89- buff->next =
90- aq_ring_next_dx(ring,
91- ring->hw_head);
92- ++ring->stats.rx.jumbo_packets;
93- }
94+ /* jumbo */
95+ buff->next =
96+ aq_ring_next_dx(ring,
97+ ring->hw_head);
98+ ++ring->stats.rx.jumbo_packets;
99 }
100 }
101 }
102--
1032.20.1
104