aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorStefan Hajnoczi <stefanha@redhat.com>2022-11-17 11:55:53 -0500
committerStefan Hajnoczi <stefanha@redhat.com>2022-11-21 09:28:43 -0500
commitc74831a02c818f89d10f5475cd0fb9ba40bfb2a8 (patch)
treecb95ede0c6e62a64870ba113d70ecbfa17b6a905 /hw
parentbd142b2391a4369f39f9f4e8c48b15ed18280446 (diff)
downloadqemu-c74831a02c818f89d10f5475cd0fb9ba40bfb2a8.zip
qemu-c74831a02c818f89d10f5475cd0fb9ba40bfb2a8.tar.gz
qemu-c74831a02c818f89d10f5475cd0fb9ba40bfb2a8.tar.bz2
rtl8139: keep Tx command mode 0 and 1 separate
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 <jasowang@redhat.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Message-Id: <20221117165554.1773409-3-stefanha@redhat.com>
Diffstat (limited to 'hw')
-rw-r--r--hw/net/rtl8139.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
index ffef378..6dd7a8e 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");