56 lines
2.3 KiB
Diff
56 lines
2.3 KiB
Diff
|
From: "Michael S. Tsirkin" <mst@redhat.com>
|
|||
|
Date: Tue, 15 Feb 2011 18:27:52 +0200
|
|||
|
Subject: e1000: clear EOP for multi-buffer descriptors
|
|||
|
MIME-Version: 1.0
|
|||
|
Content-Type: text/plain; charset=UTF-8
|
|||
|
Content-Transfer-Encoding: 8bit
|
|||
|
Patch-mainline: v0.15.0-rc0
|
|||
|
Git-commit: ee912ccfa007351a62ba42bd60499769f6c02c1e
|
|||
|
References: bnc#840196
|
|||
|
|
|||
|
The e1000 spec says: if software statically allocates
|
|||
|
buffers, and uses memory read to check for completed descriptors, it
|
|||
|
simply has to zero the status byte in the descriptor to make it ready
|
|||
|
for reuse by hardware. This is not a hardware requirement (moving the
|
|||
|
hardware tail pointer is), but is necessary for performing an in–memory
|
|||
|
scan.
|
|||
|
|
|||
|
Thus the guest does not have to clear the status byte. In case it
|
|||
|
doesn't we need to clear EOP for all descriptors
|
|||
|
except the last. While I don't know of any such guests,
|
|||
|
it's probably a good idea to stick to the spec.
|
|||
|
|
|||
|
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
|||
|
Reported-by: Juan Quintela <quintela@redhat.com>
|
|||
|
Acked-by: Alex Williamson <alex.williamson@redhat.com>
|
|||
|
Acked-by: Kevin Wolf <kwolf@redhat.com>
|
|||
|
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
|||
|
Acked-by: Michal Kubecek <mkubecek@suse.cz>
|
|||
|
---
|
|||
|
tools/qemu-xen-traditional-dir-remote/hw/e1000.c | 6 ++++--
|
|||
|
1 file changed, 4 insertions(+), 2 deletions(-)
|
|||
|
|
|||
|
diff --git a/tools/qemu-xen-traditional-dir-remote/hw/e1000.c b/tools/qemu-xen-traditional-dir-remote/hw/e1000.c
|
|||
|
index 34818e0..7e791dc 100644
|
|||
|
--- a/tools/qemu-xen-traditional-dir-remote/hw/e1000.c
|
|||
|
+++ b/tools/qemu-xen-traditional-dir-remote/hw/e1000.c
|
|||
|
@@ -694,11 +694,13 @@ e1000_receive(void *opaque, const uint8_t *buf, int size)
|
|||
|
copy_size);
|
|||
|
}
|
|||
|
desc_offset += desc_size;
|
|||
|
+ desc.length = cpu_to_le16(desc_size);
|
|||
|
if (desc_offset >= total_size) {
|
|||
|
- desc.length = cpu_to_le16(desc_size);
|
|||
|
desc.status |= E1000_RXD_STAT_EOP | E1000_RXD_STAT_IXSM;
|
|||
|
} else {
|
|||
|
- desc.length = cpu_to_le16(desc_size);
|
|||
|
+ /* Guest zeroing out status is not a hardware requirement.
|
|||
|
+ Clear EOP in case guest didn't do it. */
|
|||
|
+ desc.status &= ~E1000_RXD_STAT_EOP;
|
|||
|
}
|
|||
|
} else // as per intel docs; skip descriptors with null buf addr
|
|||
|
DBGOUT(RX, "Null RX descriptor!!\n");
|
|||
|
--
|
|||
|
1.8.1.4
|
|||
|
|