Merge pull request #5766 from 86Box/tc1995

Actually fix Loopback interrupt.
This commit is contained in:
Miran Grča
2025-07-09 21:37:24 +02:00
committed by GitHub
5 changed files with 64 additions and 62 deletions

View File

@@ -41,89 +41,89 @@ typedef struct dp8390_t {
/* Command Register - 00h read/write */ /* Command Register - 00h read/write */
struct CR_t { struct CR_t {
int stop; /* STP - Software Reset command */ bool stop; /* STP - Software Reset command */
int start; /* START - start the NIC */ bool start; /* START - start the NIC */
int tx_packet; /* TXP - initiate packet transmission */ bool tx_packet; /* TXP - initiate packet transmission */
uint8_t rdma_cmd; /* RD0,RD1,RD2 - Remote DMA command */ uint8_t rdma_cmd; /* RD0,RD1,RD2 - Remote DMA command */
uint8_t pgsel; /* PS0,PS1 - Page select */ uint8_t pgsel; /* PS0,PS1 - Page select */
} CR; } CR;
/* Interrupt Status Register - 07h read/write */ /* Interrupt Status Register - 07h read/write */
struct ISR_t { struct ISR_t {
int pkt_rx; /* PRX - packet received with no errors */ bool pkt_rx; /* PRX - packet received with no errors */
int pkt_tx; /* PTX - packet txed with no errors */ bool pkt_tx; /* PTX - packet txed with no errors */
int rx_err; /* RXE - packet rxed with 1 or more errors */ bool rx_err; /* RXE - packet rxed with 1 or more errors */
int tx_err; /* TXE - packet txed " " " " " */ bool tx_err; /* TXE - packet txed " " " " " */
int overwrite; /* OVW - rx buffer resources exhausted */ bool overwrite; /* OVW - rx buffer resources exhausted */
int cnt_oflow; /* CNT - network tally counter MSB's set */ bool cnt_oflow; /* CNT - network tally counter MSB's set */
int rdma_done; /* RDC - remote DMA complete */ bool rdma_done; /* RDC - remote DMA complete */
int reset; /* RST - reset status */ bool reset; /* RST - reset status */
} ISR; } ISR;
/* Interrupt Mask Register - 0fh write */ /* Interrupt Mask Register - 0fh write */
struct IMR_t { struct IMR_t {
int rx_inte; /* PRXE - packet rx interrupt enable */ bool rx_inte; /* PRXE - packet rx interrupt enable */
int tx_inte; /* PTXE - packet tx interrput enable */ bool tx_inte; /* PTXE - packet tx interrput enable */
int rxerr_inte; /* RXEE - rx error interrupt enable */ bool rxerr_inte; /* RXEE - rx error interrupt enable */
int txerr_inte; /* TXEE - tx error interrupt enable */ bool txerr_inte; /* TXEE - tx error interrupt enable */
int overw_inte; /* OVWE - overwrite warn int enable */ bool overw_inte; /* OVWE - overwrite warn int enable */
int cofl_inte; /* CNTE - counter o'flow int enable */ bool cofl_inte; /* CNTE - counter o'flow int enable */
int rdma_inte; /* RDCE - remote DMA complete int enable */ bool rdma_inte; /* RDCE - remote DMA complete int enable */
int reserved; /* D7 - reserved */ bool reserved; /* D7 - reserved */
} IMR; } IMR;
/* Data Configuration Register - 0eh write */ /* Data Configuration Register - 0eh write */
struct DCR_t { struct DCR_t {
int wdsize; /* WTS - 8/16-bit select */ bool wdsize; /* WTS - 8/16-bit select */
int endian; /* BOS - byte-order select */ bool endian; /* BOS - byte-order select */
int longaddr; /* LAS - long-address select */ bool longaddr; /* LAS - long-address select */
int loop; /* LS - loopback select */ bool loop; /* LS - loopback select */
int auto_rx; /* AR - auto-remove rx pkts with remote DMA */ bool auto_rx; /* AR - auto-remove rx pkts with remote DMA */
uint8_t fifo_size; /* FT0,FT1 - fifo threshold */ uint8_t fifo_size; /* FT0,FT1 - fifo threshold */
} DCR; } DCR;
/* Transmit Configuration Register - 0dh write */ /* Transmit Configuration Register - 0dh write */
struct TCR_t { struct TCR_t {
int crc_disable; /* CRC - inhibit tx CRC */ bool crc_disable; /* CRC - inhibit tx CRC */
uint8_t loop_cntl; /* LB0,LB1 - loopback control */ uint8_t loop_cntl; /* LB0,LB1 - loopback control */
int ext_stoptx; /* ATD - allow tx disable by external mcast */ bool ext_stoptx; /* ATD - allow tx disable by external mcast */
int coll_prio; /* OFST - backoff algorithm select */ bool coll_prio; /* OFST - backoff algorithm select */
uint8_t reserved; /* D5,D6,D7 - reserved */ uint8_t reserved; /* D5,D6,D7 - reserved */
} TCR; } TCR;
/* Transmit Status Register - 04h read */ /* Transmit Status Register - 04h read */
struct TSR_t { struct TSR_t {
int tx_ok; /* PTX - tx complete without error */ bool tx_ok; /* PTX - tx complete without error */
int reserved; /* D1 - reserved */ bool reserved; /* D1 - reserved */
int collided; /* COL - tx collided >= 1 times */ bool collided; /* COL - tx collided >= 1 times */
int aborted; /* ABT - aborted due to excessive collisions */ bool aborted; /* ABT - aborted due to excessive collisions */
int no_carrier; /* CRS - carrier-sense lost */ bool no_carrier; /* CRS - carrier-sense lost */
int fifo_ur; /* FU - FIFO underrun */ bool fifo_ur; /* FU - FIFO underrun */
int cd_hbeat; /* CDH - no tx cd-heartbeat from transceiver */ bool cd_hbeat; /* CDH - no tx cd-heartbeat from transceiver */
int ow_coll; /* OWC - out-of-window collision */ bool ow_coll; /* OWC - out-of-window collision */
} TSR; } TSR;
/* Receive Configuration Register - 0ch write */ /* Receive Configuration Register - 0ch write */
struct RCR_t { struct RCR_t {
int errors_ok; /* SEP - accept pkts with rx errors */ bool errors_ok; /* SEP - accept pkts with rx errors */
int runts_ok; /* AR - accept < 64-byte runts */ bool runts_ok; /* AR - accept < 64-byte runts */
int broadcast; /* AB - accept eth broadcast address */ bool broadcast; /* AB - accept eth broadcast address */
int multicast; /* AM - check mcast hash array */ bool multicast; /* AM - check mcast hash array */
int promisc; /* PRO - accept all packets */ bool promisc; /* PRO - accept all packets */
int monitor; /* MON - check pkts, but don't rx */ bool monitor; /* MON - check pkts, but don't rx */
uint8_t reserved; /* D6,D7 - reserved */ uint8_t reserved; /* D6,D7 - reserved */
} RCR; } RCR;
/* Receive Status Register - 0ch read */ /* Receive Status Register - 0ch read */
struct RSR_t { struct RSR_t {
int rx_ok; /* PRX - rx complete without error */ bool rx_ok; /* PRX - rx complete without error */
int bad_crc; /* CRC - Bad CRC detected */ bool bad_crc; /* CRC - Bad CRC detected */
int bad_falign; /* FAE - frame alignment error */ bool bad_falign; /* FAE - frame alignment error */
int fifo_or; /* FO - FIFO overrun */ bool fifo_or; /* FO - FIFO overrun */
int rx_missed; /* MPA - missed packet error */ bool rx_missed; /* MPA - missed packet error */
int rx_mbit; /* PHY - unicast or mcast/bcast address match */ bool rx_mbit; /* PHY - unicast or mcast/bcast address match */
int rx_disabled; /* DIS - set when in monitor mode */ bool rx_disabled; /* DIS - set when in monitor mode */
int deferred; /* DFR - collision active */ bool deferred; /* DFR - collision active */
} RSR; } RSR;
uint16_t local_dma; /* 01,02h read ; current local DMA addr */ uint16_t local_dma; /* 01,02h read ; current local DMA addr */

View File

@@ -45,6 +45,7 @@
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h>
#include <stdarg.h> #include <stdarg.h>
#include <wchar.h> #include <wchar.h>
#include <time.h> #include <time.h>

View File

@@ -19,6 +19,7 @@
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h>
#include <stdarg.h> #include <stdarg.h>
#include <wchar.h> #include <wchar.h>
#include <time.h> #include <time.h>
@@ -198,6 +199,11 @@ dp8390_write_cr(dp8390_t *dev, uint32_t val)
if (dev->TCR.loop_cntl) { if (dev->TCR.loop_cntl) {
dp8390_rx_common(dev, &dev->mem[((dev->tx_page_start * 256) - dev->mem_start) & dev->mem_wrap], dp8390_rx_common(dev, &dev->mem[((dev->tx_page_start * 256) - dev->mem_start) & dev->mem_wrap],
dev->tx_bytes); dev->tx_bytes);
if (dev->IMR.rx_inte && !dev->ISR.pkt_tx && dev->interrupt)
dev->interrupt(dev->priv, 1);
dev->ISR.pkt_tx = 1;
} }
} else if (val & 0x04) { } else if (val & 0x04) {
if (dev->CR.stop || (!dev->CR.start && (dev->flags & DP8390_FLAG_CHECK_CR))) { if (dev->CR.stop || (!dev->CR.start && (dev->flags & DP8390_FLAG_CHECK_CR))) {
@@ -220,12 +226,6 @@ dp8390_write_cr(dp8390_t *dev, uint32_t val)
if (!(dev->card->link_state & NET_LINK_DOWN)) if (!(dev->card->link_state & NET_LINK_DOWN))
network_tx(dev->card, &dev->mem[((dev->tx_page_start * 256) - dev->mem_start) & dev->mem_wrap], dev->tx_bytes); network_tx(dev->card, &dev->mem[((dev->tx_page_start * 256) - dev->mem_start) & dev->mem_wrap], dev->tx_bytes);
/* some more debug */
#ifdef ENABLE_DP8390_LOG
if (dev->tx_timer_active)
dp8390_log("DP8390: CR write, tx timer still active\n");
#endif
dp8390_tx(dev, val); dp8390_tx(dev, val);
} }
@@ -247,12 +247,12 @@ dp8390_tx(dp8390_t *dev, UNUSED(uint32_t val))
{ {
dev->CR.tx_packet = 0; dev->CR.tx_packet = 0;
dev->TSR.tx_ok = 1; dev->TSR.tx_ok = 1;
dev->ISR.pkt_tx = 1;
/* Generate an interrupt if not masked */ /* Generate an interrupt if not masked */
if (dev->IMR.tx_inte && dev->interrupt) if (dev->IMR.tx_inte && !dev->ISR.pkt_tx && dev->interrupt)
dev->interrupt(dev->priv, 1); dev->interrupt(dev->priv, 1);
dev->tx_timer_active = 0;
dev->ISR.pkt_tx = 1;
} }
/* /*
@@ -960,7 +960,6 @@ dp8390_reset(dp8390_t *dev)
memset(&dev->TCR, 0x00, sizeof(dev->TCR)); memset(&dev->TCR, 0x00, sizeof(dev->TCR));
memset(&dev->TSR, 0x00, sizeof(dev->TSR)); memset(&dev->TSR, 0x00, sizeof(dev->TSR));
memset(&dev->RSR, 0x00, sizeof(dev->RSR)); memset(&dev->RSR, 0x00, sizeof(dev->RSR));
dev->tx_timer_active = 0;
dev->local_dma = 0; dev->local_dma = 0;
dev->page_start = 0; dev->page_start = 0;
dev->page_stop = 0; dev->page_stop = 0;

View File

@@ -48,6 +48,7 @@
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h>
#include <stdarg.h> #include <stdarg.h>
#include <wchar.h> #include <wchar.h>
#include <time.h> #include <time.h>
@@ -933,7 +934,7 @@ nic_init(const device_t *info)
if (dev->board != NE2K_ETHERNEXT_MC) { if (dev->board != NE2K_ETHERNEXT_MC) {
dev->base_address = device_get_config_hex16("base"); dev->base_address = device_get_config_hex16("base");
dev->base_irq = device_get_config_int("irq"); dev->base_irq = device_get_config_int("irq");
if ((dev->board == NE2K_NE2000) || (dev->board == NE2K_NE2000_COMPAT) || if ((dev->board == NE2K_NE2000) || (dev->board == NE2K_NE2000_COMPAT) ||
(dev->board == NE2K_NE2000_COMPAT_8BIT) ) { (dev->board == NE2K_NE2000_COMPAT_8BIT) ) {
dev->bios_addr = device_get_config_hex20("bios_addr"); dev->bios_addr = device_get_config_hex20("bios_addr");
dev->has_bios = !!dev->bios_addr; dev->has_bios = !!dev->bios_addr;
@@ -1061,7 +1062,7 @@ nic_init(const device_t *info)
break; break;
} }
if (set_oui) { if (set_oui) {
/* See if we have a local MAC address configured. */ /* See if we have a local MAC address configured. */
mac_oui = device_get_config_mac("mac_oui", -1); mac_oui = device_get_config_mac("mac_oui", -1);
@@ -1742,7 +1743,7 @@ const device_t ne2000_compat_device = {
const device_t ne2000_compat_8bit_device = { const device_t ne2000_compat_8bit_device = {
.name = "NE2000 Compatible 8-bit", .name = "NE2000 Compatible 8-bit",
.internal_name = "ne2k8", .internal_name = "ne2k8",
.flags = DEVICE_ISA, .flags = DEVICE_ISA,
.local = NE2K_NE2000_COMPAT_8BIT, .local = NE2K_NE2000_COMPAT_8BIT,
.init = nic_init, .init = nic_init,
.close = nic_close, .close = nic_close,

View File

@@ -44,6 +44,7 @@
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h>
#include <stdarg.h> #include <stdarg.h>
#include <wchar.h> #include <wchar.h>
#include <time.h> #include <time.h>