Revision 1b0009db hw/e1000.c
b/hw/e1000.c | ||
---|---|---|
105 | 105 |
char tse; |
106 | 106 |
char ip; |
107 | 107 |
char tcp; |
108 |
char cptse; // current packet tse bit |
|
108 | 109 |
} tx; |
109 | 110 |
|
110 | 111 |
struct { |
... | ... | |
308 | 309 |
unsigned int frames = s->tx.tso_frames, css, sofar, n; |
309 | 310 |
struct e1000_tx *tp = &s->tx; |
310 | 311 |
|
311 |
if (tp->tse) { |
|
312 |
if (tp->tse && tp->cptse) {
|
|
312 | 313 |
css = tp->ipcss; |
313 | 314 |
DBGOUT(TXSUM, "frames %d size %d ipcss %d\n", |
314 | 315 |
frames, tp->size, css); |
... | ... | |
382 | 383 |
tp->tucso = tp->tucss + (tp->tcp ? 16 : 6); |
383 | 384 |
} |
384 | 385 |
return; |
385 |
} else if (dtype == (E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D)) |
|
386 |
} else if (dtype == (E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D)) { |
|
387 |
// data descriptor |
|
386 | 388 |
tp->sum_needed = le32_to_cpu(dp->upper.data) >> 8; |
389 |
tp->cptse = ( txd_lower & E1000_TXD_CMD_TSE ) ? 1 : 0; |
|
390 |
} else |
|
391 |
// legacy descriptor |
|
392 |
tp->cptse = 0; |
|
387 | 393 |
|
388 | 394 |
addr = le64_to_cpu(dp->buffer_addr); |
389 |
if (tp->tse) { |
|
395 |
if (tp->tse && tp->cptse) {
|
|
390 | 396 |
hdr = tp->hdr_len; |
391 | 397 |
msh = hdr + tp->mss; |
398 |
do { |
|
399 |
bytes = split_size; |
|
400 |
if (tp->size + bytes > msh) |
|
401 |
bytes = msh - tp->size; |
|
402 |
cpu_physical_memory_read(addr, tp->data + tp->size, bytes); |
|
403 |
if ((sz = tp->size + bytes) >= hdr && tp->size < hdr) |
|
404 |
memmove(tp->header, tp->data, hdr); |
|
405 |
tp->size = sz; |
|
406 |
addr += bytes; |
|
407 |
if (sz == msh) { |
|
408 |
xmit_seg(s); |
|
409 |
memmove(tp->data, tp->header, hdr); |
|
410 |
tp->size = hdr; |
|
411 |
} |
|
412 |
} while (split_size -= bytes); |
|
413 |
} else if (!tp->tse && tp->cptse) { |
|
414 |
// context descriptor TSE is not set, while data descriptor TSE is set |
|
415 |
DBGOUT(TXERR, "TCP segmentaion Error\n"); |
|
416 |
} else { |
|
417 |
cpu_physical_memory_read(addr, tp->data + tp->size, split_size); |
|
418 |
tp->size += split_size; |
|
392 | 419 |
} |
393 |
do { |
|
394 |
bytes = split_size; |
|
395 |
if (tp->size + bytes > msh) |
|
396 |
bytes = msh - tp->size; |
|
397 |
cpu_physical_memory_read(addr, tp->data + tp->size, bytes); |
|
398 |
if ((sz = tp->size + bytes) >= hdr && tp->size < hdr) |
|
399 |
memmove(tp->header, tp->data, hdr); |
|
400 |
tp->size = sz; |
|
401 |
addr += bytes; |
|
402 |
if (sz == msh) { |
|
403 |
xmit_seg(s); |
|
404 |
memmove(tp->data, tp->header, hdr); |
|
405 |
tp->size = hdr; |
|
406 |
} |
|
407 |
} while (split_size -= bytes); |
|
408 | 420 |
|
409 | 421 |
if (!(txd_lower & E1000_TXD_CMD_EOP)) |
410 | 422 |
return; |
411 |
if (tp->size > hdr)
|
|
423 |
if (!(tp->tse && tp->cptse && tp->size < hdr))
|
|
412 | 424 |
xmit_seg(s); |
413 | 425 |
tp->tso_frames = 0; |
414 | 426 |
tp->sum_needed = 0; |
415 | 427 |
tp->size = 0; |
428 |
tp->cptse = 0; |
|
416 | 429 |
} |
417 | 430 |
|
418 | 431 |
static uint32_t |
Also available in: Unified diff