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
6 [ Upstream commit eaeb3b7494ba9159323814a8ce8af06a9277d99b ]
8 Driver stops producing skbs on ring if a packet with FCS error
9 was coalesced into LRO session. Ring gets hang forever.
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
16 Solution is fill next pointer and eop flag even for packets with FCS error.
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>
24 .../aquantia/atlantic/hw_atl/hw_atl_b0.c | 61 ++++++++++---------
25 1 file changed, 32 insertions(+), 29 deletions(-)
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 */
36 - if (self->aq_nic_cfg->is_rss) {
38 - u16 rss_type = rxd_wb->type & 0xFU;
40 - if (rss_type && rss_type < 0x8U) {
41 - buff->is_hash_l4 = (rss_type == 0x4 ||
43 - buff->rss_hash = rxd_wb->rss_hash;
46 + if (self->aq_nic_cfg->is_rss) {
48 + u16 rss_type = rxd_wb->type & 0xFU;
50 + if (rss_type && rss_type < 0x8U) {
51 + buff->is_hash_l4 = (rss_type == 0x4 ||
53 + buff->rss_hash = rxd_wb->rss_hash;
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;
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;
73 + rxd_wb->pkt_len > AQ_CFG_RX_FRAME_MAX ?
74 + AQ_CFG_RX_FRAME_MAX : rxd_wb->pkt_len;
76 + if (HW_ATL_B0_RXD_WB_STAT2_RSCCNT &
79 + buff->next = rxd_wb->next_desc_ptr;
80 + ++ring->stats.rx.lro_packets;
82 - if (HW_ATL_B0_RXD_WB_STAT2_RSCCNT &
85 - buff->next = rxd_wb->next_desc_ptr;
86 - ++ring->stats.rx.lro_packets;
90 - aq_ring_next_dx(ring,
92 - ++ring->stats.rx.jumbo_packets;
96 + aq_ring_next_dx(ring,
98 + ++ring->stats.rx.jumbo_packets;