From 743dfcf9bd1757d3bdae50a04158605dff502109 Mon Sep 17 00:00:00 2001 From: Patrick Mackinlay Date: Tue, 1 Jun 2021 19:27:34 +0700 Subject: i82586: various fixes * send fcs in loopback mode * don't store fcs in memory * don't consume descriptors for bad frames --- src/devices/machine/i82586.cpp | 91 ++++++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 43 deletions(-) diff --git a/src/devices/machine/i82586.cpp b/src/devices/machine/i82586.cpp index 4cad2244d35..e52c2ff8389 100644 --- a/src/devices/machine/i82586.cpp +++ b/src/devices/machine/i82586.cpp @@ -96,7 +96,7 @@ CFG_PARAMS[] = { "number of retries", "maximum number of retries", 15, 7, 0xf0, 4, true }, { "no crc insertion", "crc appended to frame", 0, 8, 0x10, 4, false }, { "prefetch bit in rbd", "disabled (valid only in new modes)", 0, 0, 0x80, 7, false }, - { "preamble length", "bytes", 7, 3, 0x30, 4, true }, + { "preamble length", "2^(n+1) bytes", 2, 3, 0x30, 4, true }, { "preamble until crs", "disabled", 1, 11, 0x01, 0, false }, { "promiscuous mode", "address filter on", 0, 8, 0x01, 0, false }, { "padding", "no padding", 0, 8, 0x80, 7, false }, @@ -201,6 +201,7 @@ void i82586_base_device::device_reset() m_ru_state = RU_IDLE; m_scp_address = SCP_ADDRESS; + m_mac_multi = 0; } void i82586_base_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) @@ -1000,7 +1001,7 @@ bool i82586_device::cu_transmit(u32 command) } // optionally compute/insert ethernet frame check sequence (4 bytes) - if (!cfg_no_crc_insertion() && !cfg_loopback_mode()) + if (!cfg_no_crc_insertion()) { LOG("cu_transmit inserting frame check sequence\n"); @@ -1092,8 +1093,8 @@ u16 i82586_device::ru_execute(u8 *buf, int length) u32 rfd_cs = m_space->read_dword(m_rfd); u16 status = 0; - // current buffer position and bytes remaining - int position = 0, remaining = length; + // current buffer position and bytes remaining (excluding fcs) + int position = 0, remaining = length - 4; // set busy status m_space->write_dword(m_rfd, rfd_cs | RFD_B); @@ -1105,7 +1106,7 @@ u16 i82586_device::ru_execute(u8 *buf, int length) status |= RFD_S_SHORT; // set crc status - if (!cfg_loopback_mode() && ~compute_crc(buf, length, cfg_crc16()) != FCS_RESIDUE) + if (~compute_crc(buf, length, cfg_crc16()) != FCS_RESIDUE) { LOGMASKED(LOG_FRAMES, "ru_execute crc error computed 0x%08x stored 0x%08x\n", compute_crc(buf, length - 4, cfg_crc16()), *(u32 *)&buf[length - 4]); @@ -1187,18 +1188,18 @@ u16 i82586_device::ru_execute(u8 *buf, int length) void i82586_device::ru_complete(const u16 status) { - if (status & RFD_OK) - LOG("ru_complete frame received without error\n"); - else - LOG("ru_complete frame received with errors status 0x%04x\n", status); - - // update receive frame descriptor status - u32 rfd_cs = m_space->read_dword(m_rfd); - m_space->write_dword(m_rfd, (rfd_cs & ~0xffffU) | status); - // if we received without error, or we're saving bad frames, advance to the next rfd if ((status & RFD_OK) || cfg_save_bad_frames()) { + if (status & RFD_OK) + LOG("ru_complete frame received without error\n"); + else + LOG("ru_complete frame received with errors status 0x%04x\n", status); + + // update receive frame descriptor status + u32 rfd_cs = m_space->read_dword(m_rfd); + m_space->write_dword(m_rfd, (rfd_cs & ~0xffffU) | status); + if (!(rfd_cs & RFD_EL)) { // advance to next rfd @@ -1216,17 +1217,19 @@ void i82586_device::ru_complete(const u16 status) // set frame received status m_fr = true; - } - // suspend on completion - if (rfd_cs & RFD_S) - { - m_ru_state = RU_SUSPENDED; - m_rnr = true; - } + // suspend on completion + if (rfd_cs & RFD_S) + { + m_ru_state = RU_SUSPENDED; + m_rnr = true; + } - static const char *const RU_STATE_NAME[] = { "IDLE", "SUSPENDED", "NO RESOURCES", nullptr, "READY" }; - LOG("ru_complete complete state %s\n", RU_STATE_NAME[m_ru_state]); + static const char *const RU_STATE_NAME[] = { "IDLE", "SUSPENDED", "NO RESOURCES", nullptr, "READY" }; + LOG("ru_complete complete state %s\n", RU_STATE_NAME[m_ru_state]); + } + else + LOG("ru_complete discarded frame with errors status 0x%04x\n", status); } u32 i82586_device::address(u32 base, int offset, int address, u16 empty) @@ -1827,7 +1830,7 @@ u16 i82596_device::ru_execute(u8 *buf, int length) } // set crc status - if (!cfg_loopback_mode() && ~compute_crc(buf, length, cfg_crc16()) != FCS_RESIDUE) + if (~compute_crc(buf, length, cfg_crc16()) != FCS_RESIDUE) { LOGMASKED(LOG_FRAMES, "ru_execute crc error computed 0x%08x stored 0x%08x\n", compute_crc(buf, length - 4, cfg_crc16()), *(u32 *)&buf[length - 4]); @@ -1970,18 +1973,18 @@ u16 i82596_device::ru_execute(u8 *buf, int length) void i82596_device::ru_complete(const u16 status) { - if (status & RFD_OK) - LOG("ru_complete frame received without error\n"); - else - LOG("ru_complete frame received with errors status 0x%04x\n", status); - - // store status - const u32 rfd_cs = m_space->read_dword(m_rfd); - m_space->write_dword(m_rfd, (rfd_cs & ~0xffffU) | status); - // if we received without error, or we're saving bad frames, advance to the next rfd - if ((rfd_cs & RFD_OK) || cfg_save_bad_frames()) + if ((status & RFD_OK) || cfg_save_bad_frames()) { + if (status & RFD_OK) + LOG("ru_complete frame received without error\n"); + else + LOG("ru_complete frame received with errors status 0x%04x\n", status); + + // update receive frame descriptor status + const u32 rfd_cs = m_space->read_dword(m_rfd); + m_space->write_dword(m_rfd, (rfd_cs & ~0xffffU) | status); + if (!(rfd_cs & RFD_EL)) { // advance to next rfd @@ -2004,17 +2007,19 @@ void i82596_device::ru_complete(const u16 status) // set frame received status m_fr = true; - } - // suspend on completion - if (rfd_cs & RFD_S) - { - m_ru_state = RU_SUSPENDED; - m_rnr = true; - } + // suspend on completion + if (rfd_cs & RFD_S) + { + m_ru_state = RU_SUSPENDED; + m_rnr = true; + } - static const char *const RU_STATE_NAME[] = { "IDLE", "SUSPENDED", "NO RESOURCES", nullptr, "READY", nullptr, nullptr, nullptr, nullptr, nullptr, "NO RESOURCES (RFD)", nullptr, "NO RESOURCES (RBD)" }; - LOG("ru_complete complete state %s\n", RU_STATE_NAME[m_ru_state]); + static const char *const RU_STATE_NAME[] = { "IDLE", "SUSPENDED", "NO RESOURCES", nullptr, "READY", nullptr, nullptr, nullptr, nullptr, nullptr, "NO RESOURCES (RFD)", nullptr, "NO RESOURCES (RBD)" }; + LOG("ru_complete complete state %s\n", RU_STATE_NAME[m_ru_state]); + } + else + LOG("ru_complete discarded frame with errors status 0x%04x\n", status); } u32 i82596_device::address(u32 base, int offset, int address, u16 empty) -- cgit v1.2.3