From c74831a02c818f89d10f5475cd0fb9ba40bfb2a8 Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Thu, 17 Nov 2022 11:55:53 -0500 Subject: [PATCH] rtl8139: keep Tx command mode 0 and 1 separate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are two Tx Descriptor formats called mode 0 and mode 1. The mode is determined by the Large Send bit. CP_TX_IPCS (bit 18) is defined in mode 1 but the code checks the bit unconditionally. In mode 0 bit 18 is part of the Large Send MSS value. Explicitly check the Large Send bit to distinguish Tx command modes. This avoids bugs where modes are confused. Note that I didn't find any actual bugs aside from needlessly computing the IP checksum when the Large Send bit is enabled. Acked-by: Jason Wang Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Stefan Hajnoczi Message-Id: <20221117165554.1773409-3-stefanha@redhat.com> --- hw/net/rtl8139.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c index ffef3789b5..6dd7a8e6e0 100644 --- a/hw/net/rtl8139.c +++ b/hw/net/rtl8139.c @@ -2135,7 +2135,7 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) } ip_data_len -= hlen; - if (txdw0 & CP_TX_IPCS) + if (!(txdw0 & CP_TX_LGSEN) && (txdw0 & CP_TX_IPCS)) { DPRINTF("+++ C+ mode need IP checksum\n"); @@ -2268,7 +2268,7 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) /* Stop sending this frame */ saved_size = 0; } - else if (txdw0 & (CP_TX_TCPCS|CP_TX_UDPCS)) + else if (!(txdw0 & CP_TX_LGSEN) && (txdw0 & (CP_TX_TCPCS|CP_TX_UDPCS))) { DPRINTF("+++ C+ mode need TCP or UDP checksum\n");