]>
Commit | Line | Data |
---|---|---|
2a2a4ae2 SL |
1 | From bdeef54f3b4489428521046205246070bc3b57bc 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 f4b3554b0b67..236325f48ec9 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 | @@ -683,38 +683,41 @@ static int hw_atl_b0_hw_ring_rx_receive(struct aq_hw_s *self, | |
32 | if (is_err || rxd_wb->type & 0x1000U) { | |
33 | /* status 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 |