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

+10 -108
View File
@@ -2,7 +2,6 @@
#include <stdint.h>
// #define REGDBG 1
// #define RXTXDBG 1
#include "rtl837x_sfr.h"
#include "rtl837x_regs.h"
@@ -12,6 +11,7 @@
#include "rtl837x_phy.h"
#include "rtl837x_port.h"
#include "rtl837x_trap.h"
#include "rtl837x_nic.h"
#include "rtl837x_stp.h"
#include "rtl837x_lacp.h"
#include "rtl837x_igmp.h"
@@ -123,8 +123,8 @@ __code const uint8_t * __code const hex = "0123456789abcdef";
__xdata uint8_t flash_buf[FLASH_BUF_SIZE];
// NIC buffers for packet RX/TX
__xdata uint8_t rx_headers[16]; // Packet header(s) on RX
__xdata uint8_t uip_buf[UIP_CONF_BUFFER_SIZE+2];
__xdata uint8_t rx_headers[16]; // RX descriptor
__xdata uint8_t uip_buf[UIP_CONF_BUFFER_ALLOC_SIZE];
__xdata uint16_t rx_packet_vlan;
__xdata uint16_t management_vlan;
@@ -714,108 +714,6 @@ void get_random_32(void)
}
/*
* Transfer Network Interface RX data from the ASIC to the 8051 XMEM
* data will be stored in the rx_header structure
* len is the length of data to be transferred
*/
bool nic_rx_header(uint16_t ring_ptr)
{
uint16_t buffer = (uint16_t) &rx_headers[0];
uint16_t guard = 0;
SFR_NIC_DATA_U16LE = buffer;
SFR_NIC_RING_U16LE = ring_ptr;
SFR_NIC_CTRL = 1;
while (SFR_NIC_CTRL != 0) {
if (++guard == 0) {
print_string("NIC: RX header transfer did not complete\n");
return false;
}
}
return true;
}
/*
* Transfer Network Interface RX data from the ASIC to the 8051 XMEM
* the description of the packet must be in the rx_headers data structure
* data will be returned in the xmem buffer points to
* ring_ptr is the current position of the RX Ring on the ASIC side
*/
bool nic_rx_packet(uint16_t buffer, uint16_t ring_ptr)
{
uint16_t guard = 0;
SFR_NIC_DATA_U16LE = buffer;
SFR_NIC_RING_U16LE = ring_ptr;
uint16_t len = (((uint16_t)rx_headers[5]) << 8) | rx_headers[4];
len += 7;
len >>= 3;
#ifdef RXTXDBG
print_string(" len: ");
print_short(len);
#endif
SFR_NIC_CTRL = len;
while (SFR_NIC_CTRL != 0) {
if (++guard == 0) {
print_string("NIC: RX transfer did not complete\n");
return false;
}
}
return true;
}
/*
* Transfers data in XMEM to the ASIC for transmission by the nic
*/
void nic_tx_packet(uint16_t ring_ptr)
{
uint16_t len;
uint16_t guard = 0;
/* A frame that got a dot1Q tag was shifted forward over its padding, so it
* starts at uip_buf and carries the q_frame layout. One that did not keeps
* the padding in front and the nonq_frame layout, so the padding is skipped.
*/
if (frame_tagged) {
SFR_NIC_DATA_U16LE = (uint16_t) uip_buf;
len = FRAME_Q->len;
/*
(__xdata struct rtl_dot1q_frame *)uip_buf
#define FRAME (((__xdata struct rtl_dot1q_frame *)&uip_buf[0]).nonq_frame)*/
} else {
SFR_NIC_DATA_U16LE = (uint16_t) uip_buf + VLAN_TAG_SIZE;
len = FRAME->len;
}
#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;
}
}
}
/* Read flash using the MMIO capabilities of the DW8051 core
* Bank is < 0x3f and is the MSB
* addr gives the address in the bank
@@ -999,8 +897,12 @@ void tcpip_output(void)
uint16_t ring_ptr = ((uint16_t)sfr_data[2]) << 8;
ring_ptr |= sfr_data[3];
// Move data over from xmem buffer to ASIC side using DMA
nic_tx_packet(ring_ptr);
// Move data over from xmem buffer to ASIC side using DMA. A VLAN-tagged
// frame starts at uip_buf; an untagged frame retains four bytes of padding.
if (frame_tagged)
nic_tx_packet(uip_buf, FRAME_Q->len, ring_ptr);
else
nic_tx_packet(uip_buf + VLAN_TAG_SIZE, FRAME->len, ring_ptr);
// New position of the ring-pointer on the NIC-side indicates number of bytes transmitted
reg_read_m(RTL837X_REG_NIC_TX_CURR_PKT);
@@ -1037,7 +939,7 @@ void handle_rx(void)
write_char(' ');
}
#endif
if (!nic_rx_packet((uint16_t) &uip_buf[0], ring_ptr + 8)) {
if (!nic_rx_packet(uip_buf, ring_ptr + 8)) {
REG_SET(RTL837X_REG_NIC_RXCMD, 1);
return;
}