* [Qemu-devel] [4878] e1000: only use TSE if enabled for current packet (Anthony Xu).
@ 2008-07-16 12:39 Andrzej Zaborowski
0 siblings, 0 replies; only message in thread
From: Andrzej Zaborowski @ 2008-07-16 12:39 UTC (permalink / raw)
To: qemu-devel
Revision: 4878
http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=4878
Author: balrog
Date: 2008-07-16 12:39:45 +0000 (Wed, 16 Jul 2008)
Log Message:
-----------
e1000: only use TSE if enabled for current packet (Anthony Xu).
Previously, all data descriptors used TSE context descriptor by default,
It's not correct, per spec, data descriptor uses TSE bit to indicate
whether use TSE,
Legacy data descripter never use TSE.
This patch fixed this bug.
Modified Paths:
--------------
trunk/hw/e1000.c
Modified: trunk/hw/e1000.c
===================================================================
--- trunk/hw/e1000.c 2008-07-16 12:13:52 UTC (rev 4877)
+++ trunk/hw/e1000.c 2008-07-16 12:39:45 UTC (rev 4878)
@@ -105,6 +105,7 @@
char tse;
char ip;
char tcp;
+ char cptse; // current packet tse bit
} tx;
struct {
@@ -308,7 +309,7 @@
unsigned int frames = s->tx.tso_frames, css, sofar, n;
struct e1000_tx *tp = &s->tx;
- if (tp->tse) {
+ if (tp->tse && tp->cptse) {
css = tp->ipcss;
DBGOUT(TXSUM, "frames %d size %d ipcss %d\n",
frames, tp->size, css);
@@ -382,37 +383,49 @@
tp->tucso = tp->tucss + (tp->tcp ? 16 : 6);
}
return;
- } else if (dtype == (E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D))
+ } else if (dtype == (E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D)) {
+ // data descriptor
tp->sum_needed = le32_to_cpu(dp->upper.data) >> 8;
+ tp->cptse = ( txd_lower & E1000_TXD_CMD_TSE ) ? 1 : 0;
+ } else
+ // legacy descriptor
+ tp->cptse = 0;
addr = le64_to_cpu(dp->buffer_addr);
- if (tp->tse) {
+ if (tp->tse && tp->cptse) {
hdr = tp->hdr_len;
msh = hdr + tp->mss;
+ do {
+ bytes = split_size;
+ if (tp->size + bytes > msh)
+ bytes = msh - tp->size;
+ cpu_physical_memory_read(addr, tp->data + tp->size, bytes);
+ if ((sz = tp->size + bytes) >= hdr && tp->size < hdr)
+ memmove(tp->header, tp->data, hdr);
+ tp->size = sz;
+ addr += bytes;
+ if (sz == msh) {
+ xmit_seg(s);
+ memmove(tp->data, tp->header, hdr);
+ tp->size = hdr;
+ }
+ } while (split_size -= bytes);
+ } else if (!tp->tse && tp->cptse) {
+ // context descriptor TSE is not set, while data descriptor TSE is set
+ DBGOUT(TXERR, "TCP segmentaion Error\n");
+ } else {
+ cpu_physical_memory_read(addr, tp->data + tp->size, split_size);
+ tp->size += split_size;
}
- do {
- bytes = split_size;
- if (tp->size + bytes > msh)
- bytes = msh - tp->size;
- cpu_physical_memory_read(addr, tp->data + tp->size, bytes);
- if ((sz = tp->size + bytes) >= hdr && tp->size < hdr)
- memmove(tp->header, tp->data, hdr);
- tp->size = sz;
- addr += bytes;
- if (sz == msh) {
- xmit_seg(s);
- memmove(tp->data, tp->header, hdr);
- tp->size = hdr;
- }
- } while (split_size -= bytes);
if (!(txd_lower & E1000_TXD_CMD_EOP))
return;
- if (tp->size > hdr)
+ if (!(tp->tse && tp->cptse && tp->size < hdr))
xmit_seg(s);
tp->tso_frames = 0;
tp->sum_needed = 0;
tp->size = 0;
+ tp->cptse = 0;
}
static uint32_t
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2008-07-16 12:39 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-07-16 12:39 [Qemu-devel] [4878] e1000: only use TSE if enabled for current packet (Anthony Xu) Andrzej Zaborowski
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).