From: Pavel Belous Date: Mon, 28 Aug 2017 18:52:10 +0000 (+0300) Subject: net:ethernet:aquantia: Workaround for HW checksum bug. X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=0a402e7b9725611069dad4c873d1516f8c805f38;p=GitHub%2Fmoto-9609%2Fandroid_kernel_motorola_exynos9610.git net:ethernet:aquantia: Workaround for HW checksum bug. 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 Signed-off-by: David S. Miller --- 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 faeb4935ef3e..c5a02df7a48b 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 1bceb7358e5c..21784cc39dab 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;