]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - 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
1 From 6460d4530b9adde94834f3a53920739b80a1e6d7 Mon Sep 17 00:00:00 2001
2 From: Dmitry Bogdanov <dmitry.bogdanov@aquantia.com>
3 Date: Sat, 25 May 2019 09:58:03 +0000
4 Subject: net: aquantia: fix LRO with FCS error
5
6 [ Upstream commit eaeb3b7494ba9159323814a8ce8af06a9277d99b ]
7
8 Driver stops producing skbs on ring if a packet with FCS error
9 was coalesced into LRO session. Ring gets hang forever.
10
11 Thats a logical error in driver processing descriptors:
12 When rx_stat indicates MAC Error, next pointer and eop flags
13 are not filled. This confuses driver so it waits for descriptor 0
14 to be filled by HW.
15
16 Solution is fill next pointer and eop flag even for packets with FCS error.
17
18 Fixes: bab6de8fd180b ("net: ethernet: aquantia: Atlantic A0 and B0 specific functions.")
19 Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
20 Signed-off-by: Dmitry Bogdanov <dmitry.bogdanov@aquantia.com>
21 Signed-off-by: David S. Miller <davem@davemloft.net>
22 Signed-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
27 diff --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
28 index 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 --
103 2.20.1
104