You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
119 lines
4.6 KiB
119 lines
4.6 KiB
From 62d593080703f536164d9840a9fd61fa0d41d607 Mon Sep 17 00:00:00 2001
|
|
From: Igor Russkikh <irusskik@redhat.com>
|
|
Date: Fri, 6 Nov 2020 18:37:14 -0500
|
|
Subject: [PATCH 057/139] [netdrv] net: atlantic: checksum compat issue
|
|
|
|
Message-id: <1604687916-15087-58-git-send-email-irusskik@redhat.com>
|
|
Patchwork-id: 338484
|
|
Patchwork-instance: patchwork
|
|
O-Subject: [RHEL8.4 BZ 1857861 057/139] net: atlantic: checksum compat issue
|
|
Bugzilla: 1857861
|
|
RH-Acked-by: David Arcari <darcari@redhat.com>
|
|
RH-Acked-by: John Linville <linville@redhat.com>
|
|
RH-Acked-by: Tony Camuso <tcamuso@redhat.com>
|
|
|
|
Bugzilla: http://bugzilla.redhat.com/1857861
|
|
|
|
commit 15beab0a9d797be1b7c67458da007a62269be29a
|
|
Author: Dmitry Bezrukov <dbezrukov@marvell.com>
|
|
Date: Fri Feb 14 18:44:51 2020 +0300
|
|
|
|
net: atlantic: checksum compat issue
|
|
|
|
Yet another checksum offload compatibility issue was found.
|
|
|
|
The known issue is that AQC HW marks tcp packets with 0xFFFF checksum
|
|
as invalid (1). This is workarounded in driver, passing all the suspicious
|
|
packets up to the stack for further csum validation.
|
|
|
|
Another HW problem (2) is that it hides invalid csum of LRO aggregated
|
|
packets inside of the individual descriptors. That was workarounded
|
|
by forced scan of all LRO descriptors for checksum errors.
|
|
|
|
However the scan logic was joint for both LRO and multi-descriptor
|
|
packets (jumbos). And this causes the issue.
|
|
|
|
We have to drop LRO packets with the detected bad checksum
|
|
because of (2), but we have to pass jumbo packets to stack because of (1).
|
|
|
|
When using windows tcp partner with jumbo frames but with LSO disabled
|
|
driver discards such frames as bad checksummed. But only LRO frames
|
|
should be dropped, not jumbos.
|
|
|
|
On such a configurations tcp stream have a chance of drops and stucks.
|
|
|
|
(1) 76f254d4afe2 ("net: aquantia: tcp checksum 0xffff being handled incorrectly")
|
|
(2) d08b9a0a3ebd ("net: aquantia: do not pass lro session with invalid tcp checksum")
|
|
|
|
Fixes: d08b9a0a3ebd ("net: aquantia: do not pass lro session with invalid tcp checksum")
|
|
Signed-off-by: Dmitry Bezrukov <dbezrukov@marvell.com>
|
|
Signed-off-by: Igor Russkikh <irusskikh@marvell.com>
|
|
Signed-off-by: Dmitry Bogdanov <dbogdanov@marvell.com>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
|
|
Signed-off-by: Igor Russkikh <irusskik@redhat.com>
|
|
|
|
Cc: David Arcari <darcari@redhat.com>
|
|
Cc: Igor Russkikh <irusskik@redhat.com>
|
|
Signed-off-by: Jan Stancek <jstancek@redhat.com>
|
|
---
|
|
drivers/net/ethernet/aquantia/atlantic/aq_ring.c | 3 ++-
|
|
drivers/net/ethernet/aquantia/atlantic/aq_ring.h | 3 ++-
|
|
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c | 5 +++--
|
|
3 files changed, 7 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
|
|
index 951d86f8b66e..6941999ae845 100644
|
|
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
|
|
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
|
|
@@ -351,7 +351,8 @@ int aq_ring_rx_clean(struct aq_ring_s *self,
|
|
err = 0;
|
|
goto err_exit;
|
|
}
|
|
- if (buff->is_error || buff->is_cso_err) {
|
|
+ if (buff->is_error ||
|
|
+ (buff->is_lro && buff->is_cso_err)) {
|
|
buff_ = buff;
|
|
do {
|
|
next_ = buff_->next,
|
|
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.h b/drivers/net/ethernet/aquantia/atlantic/aq_ring.h
|
|
index 991e4d31b094..2c96f20f6289 100644
|
|
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.h
|
|
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.h
|
|
@@ -78,7 +78,8 @@ struct __packed aq_ring_buff_s {
|
|
u32 is_cleaned:1;
|
|
u32 is_error:1;
|
|
u32 is_vlan:1;
|
|
- u32 rsvd3:4;
|
|
+ u32 is_lro:1;
|
|
+ u32 rsvd3:3;
|
|
u16 eop_index;
|
|
u16 rsvd4;
|
|
};
|
|
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
|
|
index ec041f78d063..5784da26f868 100644
|
|
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
|
|
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
|
|
@@ -823,6 +823,8 @@ static int hw_atl_b0_hw_ring_rx_receive(struct aq_hw_s *self,
|
|
}
|
|
}
|
|
|
|
+ buff->is_lro = !!(HW_ATL_B0_RXD_WB_STAT2_RSCCNT &
|
|
+ rxd_wb->status);
|
|
if (HW_ATL_B0_RXD_WB_STAT2_EOP & rxd_wb->status) {
|
|
buff->len = rxd_wb->pkt_len %
|
|
AQ_CFG_RX_FRAME_MAX;
|
|
@@ -835,8 +837,7 @@ static int hw_atl_b0_hw_ring_rx_receive(struct aq_hw_s *self,
|
|
rxd_wb->pkt_len > AQ_CFG_RX_FRAME_MAX ?
|
|
AQ_CFG_RX_FRAME_MAX : rxd_wb->pkt_len;
|
|
|
|
- if (HW_ATL_B0_RXD_WB_STAT2_RSCCNT &
|
|
- rxd_wb->status) {
|
|
+ if (buff->is_lro) {
|
|
/* LRO */
|
|
buff->next = rxd_wb->next_desc_ptr;
|
|
++ring->stats.rx.lro_packets;
|
|
--
|
|
2.13.6
|
|
|