Revision ced5296a hw/eepro100.c
b/hw/eepro100.c | ||
---|---|---|
172 | 172 |
char packet[MAX_ETH_FRAME_SIZE + 4]; |
173 | 173 |
} eepro100_rx_t; |
174 | 174 |
|
175 |
typedef enum { |
|
176 |
COMMAND_EL = BIT(15), |
|
177 |
COMMAND_S = BIT(14), |
|
178 |
COMMAND_I = BIT(13), |
|
179 |
COMMAND_NC = BIT(4), |
|
180 |
COMMAND_SF = BIT(3), |
|
181 |
COMMAND_CMD = BITS(2, 0), |
|
182 |
} scb_command_bit; |
|
183 |
|
|
184 |
typedef enum { |
|
185 |
STATUS_C = BIT(15), |
|
186 |
STATUS_OK = BIT(13), |
|
187 |
} scb_status_bit; |
|
188 |
|
|
175 | 189 |
typedef struct { |
176 | 190 |
uint32_t tx_good_frames, tx_max_collisions, tx_late_collisions, |
177 | 191 |
tx_underruns, tx_lost_crs, tx_deferred, tx_single_collisions, |
... | ... | |
753 | 767 |
|
754 | 768 |
static cu_state_t get_cu_state(EEPRO100State * s) |
755 | 769 |
{ |
756 |
return ((s->mem[SCBStatus] >> 6) & 0x03);
|
|
770 |
return ((s->mem[SCBStatus] & BITS(7, 6)) >> 6);
|
|
757 | 771 |
} |
758 | 772 |
|
759 | 773 |
static void set_cu_state(EEPRO100State * s, cu_state_t state) |
760 | 774 |
{ |
761 |
s->mem[SCBStatus] = (s->mem[SCBStatus] & 0x3f) + (state << 6);
|
|
775 |
s->mem[SCBStatus] = (s->mem[SCBStatus] & ~BITS(7, 6)) + (state << 6);
|
|
762 | 776 |
} |
763 | 777 |
|
764 | 778 |
static ru_state_t get_ru_state(EEPRO100State * s) |
765 | 779 |
{ |
766 |
return ((s->mem[SCBStatus] >> 2) & 0x0f);
|
|
780 |
return ((s->mem[SCBStatus] & BITS(5, 2)) >> 2);
|
|
767 | 781 |
} |
768 | 782 |
|
769 | 783 |
static void set_ru_state(EEPRO100State * s, ru_state_t state) |
770 | 784 |
{ |
771 |
s->mem[SCBStatus] = (s->mem[SCBStatus] & 0xc3) + (state << 2);
|
|
785 |
s->mem[SCBStatus] = (s->mem[SCBStatus] & ~BITS(5, 2)) + (state << 2);
|
|
772 | 786 |
} |
773 | 787 |
|
774 | 788 |
static void dump_statistics(EEPRO100State * s) |
... | ... | |
898 | 912 |
uint16_t command = le16_to_cpu(s->tx.command); |
899 | 913 |
logout("val=(cu start), status=0x%04x, command=0x%04x, link=0x%08x\n", |
900 | 914 |
status, command, s->tx.link); |
901 |
bool bit_el = ((command & 0x8000) != 0);
|
|
902 |
bool bit_s = ((command & 0x4000) != 0);
|
|
903 |
bool bit_i = ((command & 0x2000) != 0);
|
|
904 |
bool bit_nc = ((command & 0x0010) != 0);
|
|
915 |
bool bit_el = ((command & COMMAND_EL) != 0);
|
|
916 |
bool bit_s = ((command & COMMAND_S) != 0);
|
|
917 |
bool bit_i = ((command & COMMAND_I) != 0);
|
|
918 |
bool bit_nc = ((command & COMMAND_NC) != 0);
|
|
905 | 919 |
bool success = true; |
906 |
//~ bool bit_sf = ((command & 0x0008) != 0);
|
|
907 |
uint16_t cmd = command & 0x0007;
|
|
920 |
//~ bool bit_sf = ((command & COMMAND_SF) != 0);
|
|
921 |
uint16_t cmd = command & COMMAND_CMD;
|
|
908 | 922 |
s->cu_offset = le32_to_cpu(s->tx.link); |
909 | 923 |
switch (cmd) { |
910 | 924 |
case CmdNOp: |
... | ... | |
941 | 955 |
break; |
942 | 956 |
} |
943 | 957 |
/* Write new status. */ |
944 |
stw_phys(s->cb_address, status | 0x8000 | (success ? 0x2000 : 0));
|
|
958 |
stw_phys(s->cb_address, status | STATUS_C | (success ? STATUS_OK : 0));
|
|
945 | 959 |
if (bit_i) { |
946 | 960 |
/* CU completed action. */ |
947 | 961 |
eepro100_cx_interrupt(s); |
... | ... | |
1684 | 1698 |
/* CSMA is disabled. */ |
1685 | 1699 |
logout("%p received while CSMA is disabled\n", s); |
1686 | 1700 |
return -1; |
1687 |
} else if (size < 64 && (s->configuration[7] & 1)) {
|
|
1701 |
} else if (size < 64 && (s->configuration[7] & BIT(0))) {
|
|
1688 | 1702 |
/* Short frame and configuration byte 7/0 (discard short receive) set: |
1689 | 1703 |
* Short frame is discarded */ |
1690 | 1704 |
logout("%p received short frame (%zu byte)\n", s, size); |
1691 | 1705 |
s->statistics.rx_short_frame_errors++; |
1692 | 1706 |
//~ return -1; |
1693 |
} else if ((size > MAX_ETH_FRAME_SIZE + 4) && !(s->configuration[18] & 8)) {
|
|
1707 |
} else if ((size > MAX_ETH_FRAME_SIZE + 4) && !(s->configuration[18] & BIT(3))) {
|
|
1694 | 1708 |
/* Long frame and configuration byte 18/3 (long receive ok) not set: |
1695 | 1709 |
* Long frames are discarded. */ |
1696 | 1710 |
logout("%p received long frame (%zu byte), ignored\n", s, size); |
... | ... | |
1713 | 1727 |
assert(mcast_idx < 64); |
1714 | 1728 |
if (s->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7))) { |
1715 | 1729 |
/* Multicast frame is allowed in hash table. */ |
1716 |
} else if (s->configuration[15] & 1) {
|
|
1730 |
} else if (s->configuration[15] & BIT(0)) {
|
|
1717 | 1731 |
/* Promiscuous: receive all. */ |
1718 | 1732 |
rfd_status |= 0x0004; |
1719 | 1733 |
} else { |
... | ... | |
1723 | 1737 |
} |
1724 | 1738 |
/* TODO: Next not for promiscuous mode? */ |
1725 | 1739 |
rfd_status |= 0x0002; |
1726 |
} else if (s->configuration[15] & 1) {
|
|
1740 |
} else if (s->configuration[15] & BIT(0)) {
|
|
1727 | 1741 |
/* Promiscuous: receive all. */ |
1728 | 1742 |
TRACE(RXTX, logout("%p received frame in promiscuous mode, len=%zu\n", s, size)); |
1729 | 1743 |
rfd_status |= 0x0004; |
... | ... | |
1764 | 1778 |
/* Early receive interrupt not supported. */ |
1765 | 1779 |
//~ eepro100_er_interrupt(s); |
1766 | 1780 |
/* Receive CRC Transfer not supported. */ |
1767 |
if (s->configuration[18] & 4) {
|
|
1781 |
if (s->configuration[18] & BIT(2)) {
|
|
1768 | 1782 |
missing("Receive CRC Transfer"); |
1769 | 1783 |
return -1; |
1770 | 1784 |
} |
1771 | 1785 |
/* TODO: check stripping enable bit. */ |
1772 |
//~ assert(!(s->configuration[17] & 1));
|
|
1786 |
//~ assert(!(s->configuration[17] & BIT(0)));
|
|
1773 | 1787 |
cpu_physical_memory_write(s->ru_base + s->ru_offset + |
1774 | 1788 |
offsetof(eepro100_rx_t, packet), buf, size); |
1775 | 1789 |
s->statistics.rx_good_frames++; |
1776 | 1790 |
eepro100_fr_interrupt(s); |
1777 | 1791 |
s->ru_offset = le32_to_cpu(rx.link); |
1778 |
if (rfd_command & 0x8000) {
|
|
1792 |
if (rfd_command & COMMAND_EL) {
|
|
1779 | 1793 |
/* EL bit is set, so this was the last frame. */ |
1780 | 1794 |
logout("receive: Running out of frames\n"); |
1781 | 1795 |
set_ru_state(s, ru_suspended); |
1782 | 1796 |
} |
1783 |
if (rfd_command & 0x4000) {
|
|
1797 |
if (rfd_command & COMMAND_S) {
|
|
1784 | 1798 |
/* S bit is set. */ |
1785 | 1799 |
set_ru_state(s, ru_suspended); |
1786 | 1800 |
} |
Also available in: Unified diff