From: Pavel Belous <pavel.bel...@aquantia.com>

The hardware has the HW Checksum Offload bug when small
TCP patckets (with length <= 60 bytes) has wrong "checksum valid" bit.

The solution is - ignore checksum valid bit for small packets
(with length <= 60 bytes) and mark this as CHECKSUM_NONE to allow
network stack recalculate checksum itself.

Fixes: ccf9a5ed14be ("net: ethernet: aquantia: Atlantic A0 and B0 specific 
functions.")
Signed-off-by: Pavel Belous <pavel.bel...@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c | 6 ++++++
 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c | 6 ++++++
 2 files changed, 12 insertions(+)

diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
index faeb493..c5a02df 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
@@ -629,6 +629,12 @@ static int hw_atl_a0_hw_ring_rx_receive(struct aq_hw_s 
*self,
                                buff->is_udp_cso = (is_err & 0x10U) ? 0 : 1;
                        else if (0x0U == (pkt_type & 0x1CU))
                                buff->is_tcp_cso = (is_err & 0x10U) ? 0 : 1;
+
+                       /* Checksum offload workaround for small packets */
+                       if (rxd_wb->pkt_len <= 60) {
+                               buff->is_ip_cso = 0U;
+                               buff->is_cso_err = 0U;
+                       }
                }
 
                is_err &= ~0x18U;
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 1bceb73..21784cc 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
@@ -645,6 +645,12 @@ static int hw_atl_b0_hw_ring_rx_receive(struct aq_hw_s 
*self,
                                buff->is_udp_cso = buff->is_cso_err ? 0U : 1U;
                        else if (0x0U == (pkt_type & 0x1CU))
                                buff->is_tcp_cso = buff->is_cso_err ? 0U : 1U;
+
+                       /* Checksum offload workaround for small packets */
+                       if (rxd_wb->pkt_len <= 60) {
+                               buff->is_ip_cso = 0U;
+                               buff->is_cso_err = 0U;
+                       }
                }
 
                is_err &= ~0x18U;
-- 
2.7.4

Reply via email to