Revision 7f1e9d4e hw/eepro100.c
b/hw/eepro100.c | ||
---|---|---|
73 | 73 |
|
74 | 74 |
#define TRACE(flag, command) ((flag) ? (command) : (void)0) |
75 | 75 |
|
76 |
#define missing(text) assert(!"feature is missing in this emulation: " text)
|
|
76 |
#define missing(text) fprintf(stderr, "eepro100: feature is missing in this emulation: " text "\n")
|
|
77 | 77 |
|
78 | 78 |
#define MAX_ETH_FRAME_SIZE 1514 |
79 | 79 |
|
... | ... | |
672 | 672 |
bool bit_s = ((command & 0x4000) != 0); |
673 | 673 |
bool bit_i = ((command & 0x2000) != 0); |
674 | 674 |
bool bit_nc = ((command & 0x0010) != 0); |
675 |
bool success = true; |
|
675 | 676 |
//~ bool bit_sf = ((command & 0x0008) != 0); |
676 | 677 |
uint16_t cmd = command & 0x0007; |
677 | 678 |
s->cu_offset = le32_to_cpu(tx.link); |
... | ... | |
698 | 699 |
TRACE(RXTX, logout |
699 | 700 |
("transmit, TBD array address 0x%08x, TCB byte count 0x%04x, TBD count %u\n", |
700 | 701 |
tbd_array, tcb_bytes, tx.tbd_count)); |
701 |
assert(!bit_nc); |
|
702 |
|
|
703 |
if (bit_nc) { |
|
704 |
missing("CmdTx: NC = 0"); |
|
705 |
success = false; |
|
706 |
break; |
|
707 |
} |
|
702 | 708 |
//~ assert(!bit_sf); |
703 |
assert(tcb_bytes <= 2600); |
|
709 |
if (tcb_bytes > 2600) { |
|
710 |
logout("TCB byte count too large, using 2600\n"); |
|
711 |
tcb_bytes = 2600; |
|
712 |
} |
|
704 | 713 |
/* Next assertion fails for local configuration. */ |
705 | 714 |
//~ assert((tcb_bytes > 0) || (tbd_array != 0xffffffff)); |
706 | 715 |
if (!((tcb_bytes > 0) || (tbd_array != 0xffffffff))) { |
... | ... | |
732 | 741 |
uint8_t tbd_count = 0; |
733 | 742 |
if (device_supports_eTxCB(s) && !(s->configuration[6] & BIT(4))) { |
734 | 743 |
/* Extended Flexible TCB. */ |
735 |
assert(tcb_bytes == 0); |
|
736 | 744 |
for (; tbd_count < 2; tbd_count++) { |
737 | 745 |
uint32_t tx_buffer_address = ldl_phys(tbd_address); |
738 | 746 |
uint16_t tx_buffer_size = lduw_phys(tbd_address + 4); |
... | ... | |
782 | 790 |
break; |
783 | 791 |
default: |
784 | 792 |
missing("undefined command"); |
793 |
success = false; |
|
794 |
break; |
|
785 | 795 |
} |
786 |
/* Write new status (success). */
|
|
787 |
stw_phys(cb_address, status | 0x8000 | 0x2000);
|
|
796 |
/* Write new status. */ |
|
797 |
stw_phys(cb_address, status | 0x8000 | (success ? 0x2000 : 0));
|
|
788 | 798 |
if (bit_i) { |
789 | 799 |
/* CU completed action. */ |
790 | 800 |
eepro100_cx_interrupt(s); |
... | ... | |
1492 | 1502 |
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; |
1493 | 1503 |
|
1494 | 1504 |
/* TODO: check multiple IA bit. */ |
1495 |
assert(!(s->configuration[20] & BIT(6))); |
|
1505 |
if (s->configuration[20] & BIT(6)) { |
|
1506 |
missing("Multiple IA bit"); |
|
1507 |
return -1; |
|
1508 |
} |
|
1496 | 1509 |
|
1497 | 1510 |
if (s->configuration[8] & 0x80) { |
1498 | 1511 |
/* CSMA is disabled. */ |
... | ... | |
1521 | 1534 |
/* Multicast frame. */ |
1522 | 1535 |
TRACE(RXTX, logout("%p received multicast, len=%zu\n", s, size)); |
1523 | 1536 |
/* TODO: check multicast all bit. */ |
1524 |
assert(!(s->configuration[21] & BIT(3))); |
|
1537 |
if (s->configuration[21] & BIT(3)) { |
|
1538 |
missing("Multicast All bit"); |
|
1539 |
} |
|
1525 | 1540 |
int mcast_idx = compute_mcast_idx(buf); |
1526 | 1541 |
if (!(s->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7)))) { |
1527 | 1542 |
return size; |
... | ... | |
1551 | 1566 |
offsetof(eepro100_rx_t, packet)); |
1552 | 1567 |
uint16_t rfd_command = le16_to_cpu(rx.command); |
1553 | 1568 |
uint16_t rfd_size = le16_to_cpu(rx.size); |
1554 |
assert(size <= rfd_size); |
|
1569 |
|
|
1570 |
if (size > rfd_size) { |
|
1571 |
logout("Receive buffer (%" PRId16 " bytes) too small for data " |
|
1572 |
"(%zu bytes); data truncated\n", rfd_size, size); |
|
1573 |
size = rfd_size; |
|
1574 |
} |
|
1555 | 1575 |
if (size < 64) { |
1556 | 1576 |
rfd_status |= 0x0080; |
1557 | 1577 |
} |
... | ... | |
1563 | 1583 |
/* Early receive interrupt not supported. */ |
1564 | 1584 |
//~ eepro100_er_interrupt(s); |
1565 | 1585 |
/* Receive CRC Transfer not supported. */ |
1566 |
assert(!(s->configuration[18] & 4)); |
|
1586 |
if (s->configuration[18] & 4) { |
|
1587 |
missing("Receive CRC Transfer"); |
|
1588 |
return -1; |
|
1589 |
} |
|
1567 | 1590 |
/* TODO: check stripping enable bit. */ |
1568 | 1591 |
//~ assert(!(s->configuration[17] & 1)); |
1569 | 1592 |
cpu_physical_memory_write(s->ru_base + s->ru_offset + |
... | ... | |
1573 | 1596 |
s->ru_offset = le32_to_cpu(rx.link); |
1574 | 1597 |
if (rfd_command & 0x8000) { |
1575 | 1598 |
/* EL bit is set, so this was the last frame. */ |
1576 |
assert(0); |
|
1599 |
logout("receive: Running out of frames\n"); |
|
1600 |
set_ru_state(s, ru_suspended); |
|
1577 | 1601 |
} |
1578 | 1602 |
if (rfd_command & 0x4000) { |
1579 | 1603 |
/* S bit is set. */ |
Also available in: Unified diff