mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-10-29 17:54:14 +08:00
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:
18 files changed
+435
-117
No files matched your search
+10
-108
@@ -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;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user