nic: Fix incorrect wrap handling of RX circular buffer

nic: move other nic functions into the dedicated nic files
uip: alloc buffer multiple of 8 bytes

Signed-off-by: João Silva <jgc3silva@gmail.com>
This commit is contained in:
João Silva committed 2026-10-19 19:21:47 +01:00
1 parent 138acfadb1
commit 98369c37fe
18 files changed
+435 -117

No files matched your search

+90
View File
@@ -0,0 +1,90 @@
#include "rtl837x_common.h"
#include "rtl837x_regs.h"
#include "rtl837x_sfr.h"
#include "rtl837x_nic.h"
extern __xdata uint8_t rx_headers[16];
#ifndef RTLP_HOST_TEST
/* One RX DMA operation, starting inside the configured ring. The hardware
* wraps transfers that cross its end; the initial address must be normalized.
* Host tests supply a simulated DMA engine for this hardware boundary. */
bool nic_rx_dma(__xdata uint8_t *buffer, uint16_t ring_ptr, uint8_t words) __reentrant
{
uint16_t guard = 0;
SFR_NIC_DATA_U16LE = (uint16_t)buffer;
SFR_NIC_RING_U16LE = ring_ptr;
SFR_NIC_CTRL = words;
while (SFR_NIC_CTRL != 0) {
if (++guard == 0) {
print_string("NIC: RX transfer did not complete\n");
return false;
}
}
return true;
}
#endif
static bool nic_rx_copy(__xdata uint8_t *buffer, uint16_t ring_ptr, uint8_t words) __reentrant
{
if (ring_ptr > RTL837X_NIC_RX_RING_BYTES || (ring_ptr & 7))
return false;
if (ring_ptr == RTL837X_NIC_RX_RING_BYTES)
ring_ptr = 0;
return nic_rx_dma(buffer, ring_ptr, words);
}
bool nic_rx_header(uint16_t ring_ptr) __reentrant
{
if (ring_ptr >= RTL837X_NIC_RX_RING_BYTES)
return false;
return nic_rx_copy(rx_headers, ring_ptr, 1);
}
bool nic_rx_packet(__xdata uint8_t *buffer, uint16_t ring_ptr) __reentrant
{
uint16_t len = ((uint16_t)rx_headers[5] << 8) | rx_headers[4];
if (!len || len > UIP_CONF_BUFFER_SIZE)
return false;
return nic_rx_copy(buffer, ring_ptr, (len + 7) >> 3);
}
/*
* Transfers data in XMEM to the ASIC for transmission by the NIC
*/
void nic_tx_packet(__xdata uint8_t *buffer, uint16_t len, uint16_t ring_ptr)
{
uint16_t guard = 0;
SFR_NIC_DATA_U16LE = (uint16_t)(uintptr_t)buffer;
#ifdef RXTXDBG
print_string("TX: \n");
for (uint8_t i = 0; i < 100; i++) {
print_byte(uip_buf[i]);
write_char(' ');
}
write_char('\n');
#endif
ring_ptr <<= 3;
ring_ptr |= 0x8000;
SFR_NIC_RING_U16LE = ring_ptr;
len += 0xf;
len >>= 3;
SFR_NIC_CTRL = len;
while (SFR_NIC_CTRL != 0) {
if (++guard == 0) {
print_string("NIC: TX transfer did not complete\n");
return;
}
}
}