From: ljsebald <ljs...@us...> - 2024-02-04 16:27:22
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "A pseudo Operating System for the Dreamcast.". The branch, master has been updated via a6ac69842f75a75a1e16c481dd76d17186f8f477 (commit) from d059b922625b6fd1f05dac4381b48d0ba571650b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a6ac69842f75a75a1e16c481dd76d17186f8f477 Author: Donald Haase <qu...@ya...> Date: Sun Feb 4 11:26:33 2024 -0500 BBA Driver Cleanup (#278) * Correct leaving read without unlocking * Adding register values for RX config, minor cleanups. * Shift RX Config register defines to header file. Minor cleanups. Refactoring and bugfixing of link change state. * Testing to see if the whole idea of forcing ARN on initial link change was bunk. This happens in bba_hw_init and on any link change. * Replace magic values with register defines. Remove comments with 0x00000e0a as that is identical to the RX_CONFIG_DEFAULT | RT_RXC_APM | RT_RXC_AB * Last pass of removing magic numbers. * A deeper cleaning of the driver, maybe too far * Re-add RX_NOWRAP, as it is checked for optional wrapping behavior * Last change, just update some other magic numbers * Correct buffer offsets ----------------------------------------------------------------------- Summary of changes: .../dreamcast/hardware/network/broadband_adapter.c | 219 +++++++-------------- .../dreamcast/include/dc/net/broadband_adapter.h | 50 +++-- 2 files changed, 108 insertions(+), 161 deletions(-) diff --git a/kernel/arch/dreamcast/hardware/network/broadband_adapter.c b/kernel/arch/dreamcast/hardware/network/broadband_adapter.c index 9eda6d8f..1140cd29 100644 --- a/kernel/arch/dreamcast/hardware/network/broadband_adapter.c +++ b/kernel/arch/dreamcast/hardware/network/broadband_adapter.c @@ -18,31 +18,26 @@ #include <dc/flashrom.h> #include <arch/irq.h> #include <arch/cache.h> +#include <arch/memory.h> #include <kos/net.h> #include <kos/thread.h> #include <kos/sem.h> -//#define vid_border_color(r, g, b) (void)0 /* nothing */ - /* Configuration definitions */ #define RTL_MEM (0x1840000) -#define RX_NOWRAP 1 /* 1 for no wrapping or 0 to use wrapping mode (Ignored for 64Kb buffer length) */ -#define RX_MAX_DMA_BURST 6 /* 2^(4+n) bytes from 0-6 (16b - 1Kb) or 7 for unlimited */ -#define RX_BUFFER_LEN_SHIFT 1 /* 0 : 8Kb, 1 : 16Kb, 2 : 32Kb, 3 : 64Kb */ -#define RX_FIFO_THRESHOLD 0 /* 2^(4+n) bytes from 0-6 (16b - 1Kb) or 7 for none */ -#define RX_EARLY_THRESHOLD 0 /* Early RX Threshold multiplier n/16 or 0 for none */ +#define RX_NOWRAP RT_RXC_WRAP /* Default to no wrapping */ +#define RX_BUFFER_SHIFT 1 /* 0 : 8Kb, 1 : 16Kb, 2 : 32Kb, 3 : 64Kb */ + +#define RX_CONFIG_DEFAULT (RT_ERTH(0) | RT_RXC_RXFTH(0) | \ + RT_RXC_RBLEN(RX_BUFFER_SHIFT) | RT_RXC_MXDMA(6) | RX_NOWRAP) -#define RX_CONFIG (RX_EARLY_THRESHOLD<<24) | (RX_FIFO_THRESHOLD<<13) | \ - (RX_BUFFER_LEN_SHIFT<<11) | (RX_MAX_DMA_BURST<<8) | \ - (RX_NOWRAP<<7) +#define RX_BUFFER_LEN (0x2000 << RX_BUFFER_SHIFT) #define TX_MAX_DMA_BURST 6 /* 2^(4+n) bytes from 0-7 (16b - 2Kb) */ #define TX_CONFIG (TX_MAX_DMA_BURST<<8) -#define RX_BUFFER_LEN (0x2000<<RX_BUFFER_LEN_SHIFT) - #define TX_BUFFER_OFFSET (RX_BUFFER_LEN + 0x2000) #define TX_BUFFER_LEN (0x800) #define TX_NB_BUFFERS 4 @@ -50,9 +45,6 @@ /* This was originally set as ASIC_IRQB */ #define BBA_ASIC_IRQ ASIC_IRQ_DEFAULT -/* Use a customized g2_read_block function */ -#define FAST_G2_READ - /* DMA transfer will be used only if the amount of bytes exceeds that threshold */ #define DMA_THRESHOLD 128 // looks like a good value @@ -220,18 +212,18 @@ struct { #define NIC(ADDR) (GAPS_BASE + 0x1700 + (ADDR)) /* 8 and 32 bit access to the PCI MEMMAP space (configured by GAPS) */ -static uint32 const rtl_mem = 0xa0000000 + RTL_MEM; +static uint32 const rtl_mem = MEM_AREA_P2_BASE + RTL_MEM; /* TX buffer pointers */ -static uint32 const txdesc[4] = { - 0xa0000000 + RTL_MEM + TX_BUFFER_OFFSET, - 0xa0000800 + RTL_MEM + TX_BUFFER_OFFSET, - 0xa0001000 + RTL_MEM + TX_BUFFER_OFFSET, - 0xa0001800 + RTL_MEM + TX_BUFFER_OFFSET, +static uint32 const txdesc[TX_NB_BUFFERS] = { + MEM_AREA_P2_BASE + (TX_BUFFER_LEN * 0) + RTL_MEM + TX_BUFFER_OFFSET, + MEM_AREA_P2_BASE + (TX_BUFFER_LEN * 1) + RTL_MEM + TX_BUFFER_OFFSET, + MEM_AREA_P2_BASE + (TX_BUFFER_LEN * 2) + RTL_MEM + TX_BUFFER_OFFSET, + MEM_AREA_P2_BASE + (TX_BUFFER_LEN * 3) + RTL_MEM + TX_BUFFER_OFFSET, }; /* Is the link stabilized? */ -static volatile int link_stable, link_initial; +static volatile int link_stable; /* Receive callback */ static eth_rx_callback_t eth_rx_callback; @@ -277,7 +269,6 @@ static int bba_hw_init(void) { uint32 tmp; link_stable = 0; - link_initial = 0; /* Initialize GAPS */ if(gaps_init() < 0) @@ -343,7 +334,7 @@ static int bba_hw_init(void) { g2_write_8(NIC(RT_CHIPCMD), RT_CMD_RX_ENABLE | RT_CMD_TX_ENABLE); /* Set Rx FIFO threshold to 1K, Rx size to 16k+16, 1024 byte DMA burst */ - g2_write_32(NIC(RT_RXCONFIG), RX_CONFIG); + g2_write_32(NIC(RT_RXCONFIG), RX_CONFIG_DEFAULT); /* Set Tx 1024 byte DMA burst */ g2_write_32(NIC(RT_TXCONFIG), TX_CONFIG); @@ -402,7 +393,7 @@ static int bba_hw_init(void) { rtl.cur_rx = 0; /* Enable receiving broadcast and physical match packets */ - g2_write_32(NIC(RT_RXCONFIG), g2_read_32(NIC(RT_RXCONFIG)) | 0x0000000a); + g2_write_32(NIC(RT_RXCONFIG), g2_read_32(NIC(RT_RXCONFIG)) | RT_RXC_APM | RT_RXC_AB); return 0; } @@ -414,14 +405,12 @@ static void rx_reset(void) { rtl.cur_rx = 0; g2_write_8(NIC(RT_CHIPCMD), RT_CMD_TX_ENABLE); - //g2_write_32(NIC(RT_RXCONFIG), 0x00000e0a); - g2_write_32(NIC(RT_RXCONFIG), RX_CONFIG | 0x0000000a); + g2_write_32(NIC(RT_RXCONFIG), RX_CONFIG_DEFAULT | RT_RXC_APM | RT_RXC_AB); while(!(g2_read_8(NIC(RT_CHIPCMD)) & RT_CMD_RX_ENABLE)) g2_write_8(NIC(RT_CHIPCMD), RT_CMD_TX_ENABLE | RT_CMD_RX_ENABLE); - //g2_write_32(NIC(RT_RXCONFIG), 0x00000e0a); - g2_write_32(NIC(RT_RXCONFIG), RX_CONFIG | 0x0000000a); + g2_write_32(NIC(RT_RXCONFIG), RX_CONFIG_DEFAULT | RT_RXC_APM | RT_RXC_AB); g2_write_16(NIC(RT_INTRSTATUS), 0xffff); } @@ -434,15 +423,7 @@ static void bba_hw_shutdown(void) { asic_evt_set_handler(ASIC_EVT_EXP_PCI, NULL); } - -//#define g2_read_block_8(a, b, len) memcpy(a, b, len) -//#define g2_read_block_8(a, b, len) memcpy4(a, b, (len) + 3) -//#define g2_read_block_8(a, b, len) sq_cpy(a, b, (len) + 31) -//#define g2_read_block_8(a, b, len) g2_read_block_32(a, b, ((len)+3) >> 2) -#ifdef FAST_G2_READ -#define g2_read_block_8 my_g2_read_block_8 - -static void g2_read_block_8(uint8 *dst, uint8 *src, int len) { +static void g2_read_block_8_fast(uint8 *dst, uint8 *src, int len) { if(len <= 0) return; @@ -450,13 +431,6 @@ static void g2_read_block_8(uint8 *dst, uint8 *src, int len) { ctx = g2_lock(); - /* This is in case dst is not multiple of 4, which never happens here */ - /* while( (((uint32)dst)&3) ) { */ - /* *dst++ = *src++; */ - /* if(!--len) */ - /* return; */ - /* } */ - uint32 * d = (uint32 *) dst; uint32 * s = (uint32 *) src; len = (len + 3) >> 2; @@ -466,27 +440,26 @@ static void g2_read_block_8(uint8 *dst, uint8 *src, int len) { --len; } - if(!len) - return; + if(len > 0) { - len >>= 3; - - do { - d[0] = *s++; - d[1] = *s++; - d[2] = *s++; - d[3] = *s++; - d[4] = *s++; - d[5] = *s++; - d[6] = *s++; - d[7] = *s++; - d += 8; + len >>= 3; + + do { + d[0] = *s++; + d[1] = *s++; + d[2] = *s++; + d[3] = *s++; + d[4] = *s++; + d[5] = *s++; + d[6] = *s++; + d[7] = *s++; + d += 8; + } + while(--len); } - while(--len); g2_unlock(ctx); } -#endif #define RXBSZ (64*1024) /* must be a power of two */ @@ -496,10 +469,7 @@ static struct pkt { uint8 * rxbuff; } rx_pkt[MAX_PKTS]; -#define BEFORE 0 // 32*1024 -#define AFTER 0 // (BEFORE + 32*1024) - -static uint8 rxbuff[RXBSZ + 2 * 1600 + AFTER] __attribute__((aligned(32))); +static uint8 rxbuff[RXBSZ + 2 * 1600] __attribute__((aligned(32))); static uint32 rxbuff_pos; static int rxin; static int rxout; @@ -596,11 +566,10 @@ static int bba_copy_dma(uint8 * dst, uint32 s, int len) { return 0; } else { - g2_read_block_8(dst, src, len); + g2_read_block_8_fast(dst, src, len); return !dma_used; } } -#undef g2_read_block_8 /* Utility function to copy out a some data from the ring buffer into an SH-4 buffer. This is done to make sure the buffers don't overflow. */ @@ -630,19 +599,16 @@ static int rx_enq(int ring_offset, size_t pkt_size) { /* If there's no one to receive it, don't bother. */ if(eth_rx_callback) { if(rxin != rxout && - (((rx_pkt[rxout].rxbuff - (rxbuff + 32 + BEFORE)) - rxbuff_pos) & (RXBSZ - 1)) < pkt_size + 2048) { - /* printf("diff %d, %d\n", (( (rx_pkt[rxout].rxbuff - rxbuff) - rxbuff_pos ) & (RXBSZ-1)), */ - /* pkt_size); */ - //dbglog(DBG_KDEBUG, "rx_enq: lagging\n"); + (((rx_pkt[rxout].rxbuff - (rxbuff + 32)) - rxbuff_pos) & (RXBSZ - 1)) < pkt_size + 2048) { return -1; } /* Receive buffer: temporary space to copy out received data */ #ifdef USE_P2_AREA - rx_pkt[rxin].rxbuff = rxbuff + 32 + BEFORE + (rxbuff_pos | 0xa0000000) + (ring_offset & 31); + rx_pkt[rxin].rxbuff = rxbuff + 32 + (rxbuff_pos | MEM_AREA_P2_BASE) + (ring_offset & 31); #else - rx_pkt[rxin].rxbuff = rxbuff + 32 + BEFORE + rxbuff_pos + (ring_offset & 31); + rx_pkt[rxin].rxbuff = rxbuff + 32 + rxbuff_pos + (ring_offset & 31); #endif @@ -662,19 +628,6 @@ static int bba_rtx(const uint8 * pkt, int len, int wait) static int bba_tx(const uint8 * pkt, int len, int wait) #endif { - /* - int i; - - dbglog(DBG_KDEBUG,"Transmitting packet:\r\n"); - for(i=0; i<len; i++) { - dbglog(DBG_KDEBUG,"%02x ", pkt[i]); - if(i && !(i % 16)) - printf("\r\n"); - } - dbglog(DBG_KDEBUG,"\r\n"); - */ - - //wait = BBA_TX_WAIT; if(!link_stable) { if(wait == BBA_TX_WAIT) { while(!link_stable) @@ -686,14 +639,14 @@ static int bba_tx(const uint8 * pkt, int len, int wait) /* Wait till it's clear to transmit */ if(wait == BBA_TX_WAIT) { - while(!(g2_read_32(NIC(RT_TXSTATUS0 + 4 * rtl.cur_tx)) & 0x2000)) { - if(g2_read_32(NIC(RT_TXSTATUS0 + 4 * rtl.cur_tx)) & 0x40000000) + while(!(g2_read_32(NIC(RT_TXSTATUS0 + 4 * rtl.cur_tx)) & RT_TX_HOST_OWNS)) { + if(g2_read_32(NIC(RT_TXSTATUS0 + 4 * rtl.cur_tx)) & RT_TX_ABORTED) g2_write_32(NIC(RT_TXSTATUS0 + 4 * rtl.cur_tx), g2_read_32(NIC(RT_TXSTATUS0 + 4 * rtl.cur_tx)) | 1); } } else { - if(!(g2_read_32(NIC(RT_TXSTATUS0 + 4 * rtl.cur_tx)) & 0x2000)) { + if(!(g2_read_32(NIC(RT_TXSTATUS0 + 4 * rtl.cur_tx)) & RT_TX_HOST_OWNS)) { return BBA_TX_AGAIN; } } @@ -737,9 +690,6 @@ int bba_tx(const uint8 * pkt, int len, int wait) { int res; if(irq_inside_int()) { - /* printf("bba_tx called from an irq !\n"); */ - /* return 0; */ - //return bba_rtx(pkt, len, wait); if(sem_trywait(&tx_sema)) { //printf("bba_tx called from an irq while a thread was running it !\n"); return BBA_TX_OK; /* sorry guys ... */ @@ -765,7 +715,6 @@ void bba_unlock(void) { //sem_signal(&bba_rx_sema2); } -static int bcolor; static void *bba_rx_threadfunc(void *dummy) { (void)dummy; @@ -776,8 +725,6 @@ static void *bba_rx_threadfunc(void *dummy) { if(bba_rx_exit_thread) break; - bcolor = 255; - //vid_border_color(255, 255, 0); bba_lock(); if(rxout != rxin) { @@ -788,8 +735,6 @@ static void *bba_rx_threadfunc(void *dummy) { rxout = (rxout + 1) % MAX_PKTS; } - bcolor = 0; - //vid_border_color(0, 0, 0); bba_unlock(); } @@ -803,8 +748,7 @@ static void bba_rx(void) { uint32 rx_status; size_t pkt_size, ring_offset; - //vid_border_color(255, 0, 255); - while(!(g2_read_8(NIC(RT_CHIPCMD)) & 1)) { + while(!(g2_read_8(NIC(RT_CHIPCMD)) & RT_CMD_RX_BUF_EMPTY)) { /* Get frame size and status */ ring_offset = rtl.cur_rx % RX_BUFFER_LEN; rx_status = g2_read_32(rtl_mem + ring_offset); @@ -816,12 +760,6 @@ static void bba_rx(void) { break; } - /* if( ( ( g2_read_16(NIC(RT_RXBUFHEAD)) - ring_offset ) & (RX_BUFFER_LEN-1)) < */ - /* ( (rx_size+4+3) & (RX_BUFFER_LEN-3-1) )) { */ - /* //dbglog(DBG_KDEBUG, "bba: oops\n"); */ - /* break; */ - /* } */ - if((rx_status & 1) && (pkt_size <= 1514)) { /* Add it to the rx queue */ int res = rx_enq(ring_offset + 4, pkt_size); @@ -841,8 +779,32 @@ static void bba_rx(void) { break; } } +} + +static void bba_link_change(void) { + // This should really be a bit more complete, but this + // should be sufficient. - //vid_border_color(bcolor, bcolor, 0); + // Is our link there? + if(g2_read_16(NIC(RT_MII_BMSR)) & RT_MII_LINK) { + // We must have just finished an auto-negotiation. + dbglog(DBG_INFO, "bba: link stable\n"); + + // The link is back. + link_stable = 1; + } + else { + dbglog(DBG_INFO, "bba: link lost\n"); + + // Do an auto-negotiation. + g2_write_16(NIC(RT_MII_BMCR), + RT_MII_RESET | + RT_MII_AN_ENABLE | + RT_MII_AN_START); + + // The link is gone. + link_stable = 0; + } } /* Ethernet IRQ handler */ @@ -851,7 +813,6 @@ static void bba_irq_hnd(uint32 code) { (void)code; - //vid_border_color(0, 255, 0); /* Acknowledge 8193 interrupt, except RX ACK bits. We'll handle those in the RX int handler. */ intr = g2_read_16(NIC(RT_INTRSTATUS)); @@ -877,43 +838,7 @@ static void bba_irq_hnd(uint32 code) { } if(intr & RT_INT_LINK_CHANGE) { - // Get the MII media status reg. - uint32 bmsr = g2_read_16(NIC(RT_MII_BMSR)); - - // If this is the first time, force a renegotiation. - if(!link_initial) { - bmsr &= ~(RT_MII_LINK | RT_MII_AN_COMPLETE); - dbglog(DBG_INFO, "bba: initial link change, redoing auto-neg\n"); - } - - // This should really be a bit more complete, but this - // should be sufficient. - - // Is our link there? - if(bmsr & RT_MII_LINK) { - // We must have just finished an auto-negotiation. - dbglog(DBG_INFO, "bba: link stable\n"); - - // The link is back. - link_stable = 1; - } - else { - if(link_initial) - dbglog(DBG_INFO, "bba: link lost\n"); - - // Do an auto-negotiation. - g2_write_16(NIC(RT_MII_BMCR), - RT_MII_RESET | - RT_MII_AN_ENABLE | - RT_MII_AN_START); - - // The link is gone. - link_stable = 0; - } - - // We've done our initial link interrupt now. - link_initial = 1; - + bba_link_change(); hnd = 1; } @@ -931,8 +856,6 @@ static void bba_irq_hnd(uint32 code) { if(!hnd) { dbglog(DBG_KDEBUG, "bba: spurious interrupt, status is %08x\n", intr); } - - //vid_border_color(0, 0, 0); } /****************************************************************************/ @@ -1117,7 +1040,7 @@ static int bba_if_set_mc(netif_t *self, const uint8 *list, int count) { /* Disable multicast reception */ old = g2_read_32(NIC(RT_RXCONFIG)); - g2_write_32(NIC(RT_RXCONFIG), old & ~0x00000004); + g2_write_32(NIC(RT_RXCONFIG), old & ~RT_RXC_AM); } else { int i, pos; @@ -1136,7 +1059,7 @@ static int bba_if_set_mc(netif_t *self, const uint8 *list, int count) { /* Enable multicast reception */ old = g2_read_32(NIC(RT_RXCONFIG)); - g2_write_32(NIC(RT_RXCONFIG), old | 0x00000004); + g2_write_32(NIC(RT_RXCONFIG), old | RT_RXC_AM); } return 0; diff --git a/kernel/arch/dreamcast/include/dc/net/broadband_adapter.h b/kernel/arch/dreamcast/include/dc/net/broadband_adapter.h index d2710220..2b0b4727 100644 --- a/kernel/arch/dreamcast/include/dc/net/broadband_adapter.h +++ b/kernel/arch/dreamcast/include/dc/net/broadband_adapter.h @@ -165,7 +165,7 @@ __BEGIN_DECLS #define RT_INT_RX_ACK (RT_INT_RXFIFO_OVERFLOW | RT_INT_RXBUF_OVERFLOW | RT_INT_RX_OK) /** @} */ -/** \defgroup bba_tbits Transmit Status Bits +/** \defgroup bba_tbits RTL8139C Transmit Status Bits \brief BBA transmit status register fields @{ */ @@ -182,18 +182,42 @@ __BEGIN_DECLS \brief BBA receive status register fields @{ */ -#define RT_RX_MULTICAST 0x00008000 /**< \brief Multicast packet */ -#define RT_RX_PAM 0x00004000 /**< \brief Physical address matched */ -#define RT_RX_BROADCAST 0x00002000 /**< \brief Broadcast address matched */ -#define RT_RX_BAD_SYMBOL 0x00000020 /**< \brief Invalid symbol in 100TX packet */ -#define RT_RX_RUNT 0x00000010 /**< \brief Packet size is <64 bytes */ -#define RT_RX_TOO_LONG 0x00000008 /**< \brief Packet size is >4K bytes */ -#define RT_RX_CRC_ERR 0x00000004 /**< \brief CRC error */ -#define RT_RX_FRAME_ALIGN 0x00000002 /**< \brief Frame alignment error */ -#define RT_RX_STATUS_OK 0x00000001 /**< \brief Status ok: a good packet was received */ +#define RT_RX_MULTICAST 0x8000 /**< \brief Multicast packet */ +#define RT_RX_PAM 0x4000 /**< \brief Physical address matched */ +#define RT_RX_BROADCAST 0x2000 /**< \brief Broadcast address matched */ +#define RT_RX_BAD_SYMBOL 0x0020 /**< \brief Invalid symbol in 100TX packet */ +#define RT_RX_RUNT 0x0010 /**< \brief Packet size is <64 bytes */ +#define RT_RX_TOO_LONG 0x0008 /**< \brief Packet size is >4K bytes */ +#define RT_RX_CRC_ERR 0x0004 /**< \brief CRC error */ +#define RT_RX_FRAME_ALIGN 0x0002 /**< \brief Frame alignment error */ +#define RT_RX_STATUS_OK 0x0001 /**< \brief Status ok: a good packet was received */ /** @} */ -/** \defgroup bba_config1bits Config Register 1 Bits +/** \defgroup bba_config5bits RTL8139C RX Config Register (RT_RXCONFIG) bits + + From RTL8139C(L) datasheet v1.4. + + @{ +*/ +#define RT_ERTH(n) ((n) <<24) /**< \brief Early RX Threshold multiplier n/16 or 0 for none */ + +#define RT_RXC_MulERINT 0x00020000 /**< \brief 0 for Early Receive Interrupt only on familiar protocols 1 for any */ +#define RT_RXC_RER8 0x00010000 /**< \brief 1 sets the acceptance of runt error packets */ +#define RT_RXC_RXFTH(n) ((n) <<13) /**< \brief 2^(4+n) bytes from 0-6 (16b - 1Kb) or 7 for none */ +#define RT_RXC_RBLEN(n) ((n) <<11) /**< \brief Set Rx ring buffer len to 16b + 2^(3+n) kb. */ +#define RT_RXC_MXDMA(n) ((n) << 8) /**< \brief 2^(4+n) bytes from 0-6 (16b - 1Kb) or 7 for unlimited */ + +#define RT_RXC_WRAP 0x00000080 /**< \brief 0 to use wrapping mode or 1 to not (Ignored for 64Kb buffer length) */ ...<truncated>... hooks/post-receive -- A pseudo Operating System for the Dreamcast. |