mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-10-29 17:54:14 +08:00
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>
91 lines
2.0 KiB
C
91 lines
2.0 KiB
C
#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;
|
|
}
|
|
}
|
|
}
|