OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 701 to Rev 702
    Reverse comparison

Rev 701 → Rev 702

/trunk/or1ksim/sim.cfg
110,7 → 110,7
name = "FLASH"
ce = 0
baseaddr = 0x00000000
size = 0x000200000
size = 0x00200000
delayr = 10
delayw = -1
enddevice
118,8 → 118,8
device 1
name = "RAM"
ce = 1
baseaddr = 0x04000000
size = 0x04000000
baseaddr = 0x40000000
size = 0x00200000
delayr = 2
delayw = 4
enddevice
354,7 → 354,7
 
section sim
/* verbose = 1 */
debug = 0
debug = 3
profile = 0
prof_fn = "sim.profile"
mprofile = 0
513,7 → 513,7
*/
 
section debug
enabled = 0
enabled = 1
gdb_enabled = 0
server_port = 9999
vapi_id = 0xFFFF
535,7 → 535,7
*/
 
section mc
enabled = 1
enabled = 0
baseaddr = 0x60000000
POC = 0x00000008 /* Power on configuration register */
end
647,9 → 647,9
*/
 
section ethernet
nethernets = 0
nethernets = 1
 
/*
 
device 0
baseaddr = 0x88000000
dma = 0
658,7 → 658,7
rxfile = "/tmp/eth0.rx"
txfile = "/tmp/eth0.tx"
enddevice
*/
 
end
 
/* GPIO SECTION
/trunk/or1ksim/cpu/common/stats.c
76,7 → 76,7
{
int i = 0;
debug(3,"adddstats start\n");
debug(7,"adddstats start\n");
 
while((dstats[i].insn1 != item1 || dstats[i].insn2 != item2) && (i < DSTATS_LEN) && dstats[i].insn1 >= 0) i++;
 
/trunk/or1ksim/testbench/eth.c
1,20 → 1,20
/* Ethernet test */
 
#include "spr_defs.h"
#include "support.h"
 
typedef long off_t;
 
#include "../peripheral/fields.h"
#include "../peripheral/dma.h"
#include "../peripheral/ethernet.h"
 
#define ETH_BASE 0x88000000LU
#define DMA_BASE 0x90000000LU
#define ETH_INT_LINE 0x15
 
typedef volatile unsigned long *REGISTER;
 
REGISTER
eth_moder = (unsigned long *)(ETH_BASE + ETH_MODER),
eth_moder = (unsigned long *)(ETH_BASE + ETH_MODER),
eth_int_source = (unsigned long *)(ETH_BASE + ETH_INT_SOURCE),
eth_int_mask = (unsigned long *)(ETH_BASE + ETH_INT_MASK),
eth_ipgt = (unsigned long *)(ETH_BASE + ETH_IPGT),
32,27 → 32,30
eth_miistatus = (unsigned long *)(ETH_BASE + ETH_MIISTATUS),
eth_mac_addr0 = (unsigned long *)(ETH_BASE + ETH_MAC_ADDR0),
eth_mac_addr1 = (unsigned long *)(ETH_BASE + ETH_MAC_ADDR1),
eth_bd_base = (unsigned long *)(ETH_BASE + ETH_BD_BASE),
dma_csr = (unsigned long *)(DMA_BASE + DMA_CSR),
dma_int_msk_a = (unsigned long *)(DMA_BASE + DMA_INT_MSK_A),
dma_int_msk_b = (unsigned long *)(DMA_BASE + DMA_INT_MSK_B),
dma_int_src_a = (unsigned long *)(DMA_BASE + DMA_INT_SRC_A),
dma_int_src_b = (unsigned long *)(DMA_BASE + DMA_INT_SRC_B),
dma_ch0_csr = (unsigned long *)(DMA_BASE + DMA_CH_BASE + DMA_CH_CSR),
dma_ch0_sz = (unsigned long *)(DMA_BASE + DMA_CH_BASE + DMA_CH_SZ),
dma_ch0_a0 = (unsigned long *)(DMA_BASE + DMA_CH_BASE + DMA_CH_A0),
dma_ch0_am0 = (unsigned long *)(DMA_BASE + DMA_CH_BASE + DMA_CH_AM0),
dma_ch0_a1 = (unsigned long *)(DMA_BASE + DMA_CH_BASE + DMA_CH_A1),
dma_ch0_am1 = (unsigned long *)(DMA_BASE + DMA_CH_BASE + DMA_CH_AM1),
dma_ch0_desc = (unsigned long *)(DMA_BASE + DMA_CH_BASE + DMA_CH_DESC);
eth_bd_base = (unsigned long *)(ETH_BASE + ETH_BD_BASE);
 
struct DMA_DESCRIPTOR
unsigned int_happend;
unsigned char r_packet[0x1000];
unsigned char s_packet[1003];
 
 
void interrupt_handler()
{
unsigned long csr;
unsigned long adr0;
unsigned long adr1;
unsigned long next;
};
unsigned x;
printf ("Int\n");
switch (*eth_int_source & 0xf) {
case 0x1: printf ("Transmit Error.\n"); break;
case 0x2: printf ("Receive Buffer\n");break;
case 0x4: printf ("Receive Frame\n");break;
case 0x8: printf ("Busy\n"); break;
case 0x0: printf ("Modem Status.\n"); break;
default:
printf ("Invalid iir @ %i\n", __LINE__);
exit (1);
}
mtspr(SPR_PICSR, 0);
int_happend = 1;
}
 
static void set_mac( void )
{
63,51 → 66,113
static void transmit_one_packet( void )
{
unsigned i;
unsigned char packet[1003];
struct DMA_DESCRIPTOR desc;
 
/* Initialize packet */
for ( i = 0; i < sizeof(packet); ++ i )
packet[i] = (unsigned char)i;
for ( i = 0; i < sizeof(s_packet); ++ i )
s_packet[i] = (unsigned char)i;
 
/* Set Ethernet BD size */
*eth_bd_base = sizeof(packet) << ETH_TX_BD_LENGTH_OFFSET;
/* Set Ethernet BD */
SET_FIELD(eth_bd_base[0], ETH_TX_BD, LENGTH, sizeof(s_packet));
eth_bd_base[1] = (unsigned long)s_packet;
 
/* Set dma stuff */
desc.csr = 1600; /* transfer size; Ethernet will stop the DMA after packet is sent */
desc.adr0 = (unsigned long)packet;
desc.adr1 = ETH_BASE + ETH_DMA_RX_TX;
desc.csr |= FLAG_MASK( DMA_DESC_CSR, EOL ) | FLAG_MASK( DMA_DESC_CSR, INC_SRC );
desc.next = 0xDEADDEADUL; /* just to help debugging */
*dma_ch0_sz = 1UL << DMA_CH_SZ_CHK_SZ_OFFSET; /* Chunk size = 1 word */
*dma_ch0_desc = (unsigned long)&desc; /* Tell DMA channel where the descriptor is */
/* Start Ethernet */
SET_FLAG(eth_bd_base[0], ETH_TX_BD, READY);
SET_FLAG(*eth_moder, ETH_MODER, TXEN);
/* Now wait till sent */
while ( TEST_FLAG( eth_bd_base[0], ETH_TX_BD, READY ) );
CLEAR_FLAG(*eth_moder, ETH_MODER, TXEN);
}
 
/* Start DMA (it will wait for request from Ethernet) */
*dma_ch0_csr = FLAG_MASK( DMA_CH_CSR, CH_EN ) /* Enable channel */ |
FLAG_MASK( DMA_CH_CSR, USE_ED ) /* Use linked lists */ |
FLAG_MASK( DMA_CH_CSR, MODE ) /* Wait for HW handshake */ |
FLAG_MASK( DMA_CH_CSR, DST_SEL ) /* Interface 1 is the destination (meaningless for simulation) */;
static void transmit_one_packet_int( void )
{
unsigned i;
/* Initialize packet */
for ( i = 0; i < sizeof(s_packet); ++ i )
s_packet[i] = (unsigned char)i;
 
/* Set Ethernet BD */
SET_FIELD(eth_bd_base[2], ETH_TX_BD, LENGTH, sizeof(s_packet));
eth_bd_base[3] = (unsigned long)s_packet;
 
/* Start Ethernet */
*eth_bd_base |= FLAG_MASK( ETH_TX_BD, READY ); /* signal BD as ready */
*eth_moder |= FLAG_MASK( ETH_MODER, TXEN ) | FLAG_MASK( ETH_MODER, DMAEN );
SET_FLAG(eth_bd_base[2], ETH_TX_BD, READY);
SET_FLAG(*eth_moder, ETH_MODER, TXEN);
}
 
/* Now wait till DMA finishes */
while ( TEST_FLAG( *dma_ch0_csr, DMA_CH_CSR, BUSY ) )
;
 
static void receive_one_packet(void)
{
unsigned int i;
unsigned int len;
eth_bd_base[*eth_tx_bd_num + 1] = (unsigned long)r_packet;
SET_FLAG(eth_bd_base[*eth_tx_bd_num], ETH_RX_BD, READY);
SET_FLAG(*eth_moder, ETH_MODER, RXEN);
 
while ( TEST_FLAG( eth_bd_base[*eth_tx_bd_num], ETH_RX_BD, READY ) );
CLEAR_FLAG(*eth_moder, ETH_MODER, RXEN);
len = GET_FIELD(eth_bd_base[*eth_tx_bd_num], ETH_RX_BD, LENGTH);
for (i=0; i<len; i++)
if (r_packet[i] != (unsigned char)i)
{
printf("Failed at byte %d. expect %d, received %d\n", i, i, r_packet[i]);
exit(1);
}
}
 
static void receive_one_packet_int(void)
{
unsigned int i;
unsigned int len;
eth_bd_base[*eth_tx_bd_num + 3] = (unsigned long)r_packet;
SET_FLAG(eth_bd_base[*eth_tx_bd_num + 2], ETH_RX_BD, READY);
SET_FLAG(*eth_moder, ETH_MODER, RXEN);
 
while ( TEST_FLAG( eth_bd_base[*eth_tx_bd_num + 2], ETH_RX_BD, READY ) );
CLEAR_FLAG(*eth_moder, ETH_MODER, RXEN);
len = GET_FIELD(eth_bd_base[*eth_tx_bd_num + 2], ETH_RX_BD, LENGTH);
for (i=0; i<len; i++)
if (r_packet[i] != (unsigned char)i)
{
printf("Failed at byte %d. expect %d, received %d\n", i, i, r_packet[i]);
exit(1);
}
}
 
int main()
{
printf( "Starting Ethernet test\n" );
 
set_mac();
transmit_one_packet();
/* non iterrupt test */
transmit_one_packet();
receive_one_packet();
/* interrupt test */
excpt_int = (unsigned long)interrupt_handler;
/* Enable interrupts */
mtspr (SPR_SR, mfspr(SPR_SR) | SPR_SR_IEE);
mtspr (SPR_PICMR, mfspr(SPR_PICMR) | (0x00000001L << ETH_INT_LINE));
transmit_one_packet_int();
/*
while (!int_happend);
receive_one_packet_int();
while (!int_happend);
*/
printf( "Ending Ethernet test\n" );
report (0xdeaddead);
report (0xdeaddead);
return 0;
}
 
/trunk/or1ksim/peripheral/Makefile.in
105,7 → 105,7
host_os = @host_os@
 
noinst_LIBRARIES = libperipheral.a
libperipheral_a_SOURCES = 16450.c dma.c mc.c ethernet.c crc32.c gpio.c vga.c fb.c ps2kbd.c
libperipheral_a_SOURCES = 16450.c dma.c mc.c eth.c crc32.c gpio.c vga.c fb.c ps2kbd.c
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = ../config.h
CONFIG_CLEAN_FILES =
117,8 → 117,8
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
libperipheral_a_LIBADD =
libperipheral_a_OBJECTS = 16450.o dma.o mc.o ethernet.o crc32.o gpio.o \
vga.o fb.o ps2kbd.o
libperipheral_a_OBJECTS = 16450.o dma.o mc.o eth.o crc32.o gpio.o vga.o \
fb.o ps2kbd.o
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
129,7 → 129,7
 
TAR = gtar
GZIP_ENV = --best
DEP_FILES = .deps/16450.P .deps/crc32.P .deps/dma.P .deps/ethernet.P \
DEP_FILES = .deps/16450.P .deps/crc32.P .deps/dma.P .deps/eth.P \
.deps/fb.P .deps/gpio.P .deps/mc.P .deps/ps2kbd.P .deps/vga.P
SOURCES = $(libperipheral_a_SOURCES)
OBJECTS = $(libperipheral_a_OBJECTS)
/trunk/or1ksim/peripheral/eth.c
23,7 → 23,6
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/poll.h>
38,9 → 37,10
#include "fields.h"
#include "crc32.h"
 
 
static struct eth_device eths[MAX_ETHERNETS];
 
/* simulator interface */
static void eth_reset_controller( struct eth_device *eth);
/* register interface */
static void eth_write32( unsigned long addr, unsigned long value );
static unsigned long eth_read32( unsigned long addr );
49,9 → 49,13
static void eth_controller_rx_clock( struct eth_device * );
/* utility functions */
static int eth_find_controller( unsigned long addr, struct eth_device **eth, unsigned long *reladdr );
 
static ssize_t eth_read_rx_file( struct eth_device *, void *, size_t );
static void eth_skip_rx_file( struct eth_device *, off_t );
static void eth_rewind_rx_file( struct eth_device *, off_t );
static void eth_rx_next_packet( struct eth_device * );
static void eth_write_tx_bd_num( struct eth_device *, unsigned long value );
/* ========================================================================= */
/* TX LOGIC */
/* TX LOGIC */
/*---------------------------------------------------------------------------*/
 
/*
60,88 → 64,155
*/
void eth_controller_tx_clock( struct eth_device *eth )
{
unsigned long breakpoint = 0;
int breakpoint = 0;
int bAdvance = 1;
struct sockaddr_ll sll;
long nwritten;
unsigned long read_word;
 
switch (eth->tx.state) {
case ETH_TXSTATE_IDLE:
if ( TEST_FLAG( eth->regs.moder, ETH_MODER, TXEN ) || (eth->txfd <= 0) ) {
 
/* wait for TxBuffer to be ready */
eth->tx.state = ETH_TXSTATE_WAIT4BD;
}
break;
case ETH_TXSTATE_IDLE:
if ( TEST_FLAG( eth->regs.moder, ETH_MODER, TXEN ) ) {
/* wait for TxBuffer to be ready */
debug (3, "TX - entering state WAIT4BD\n");
eth->tx.state = ETH_TXSTATE_WAIT4BD;
}
break;
case ETH_TXSTATE_WAIT4BD:
/* Read buffer descriptor */
eth->tx.bd = eth->regs.bd_ram[eth->tx.bd_index];
eth->tx.bd_addr = eth->regs.bd_ram[eth->tx.bd_index + 1];
 
if ( TEST_FLAG( eth->tx.bd, ETH_TX_BD, READY ) ) {
/*****************/
/* initialize TX */
eth->tx.bytes_left = eth->tx.packet_length = GET_FIELD( eth->tx.bd, ETH_TX_BD, LENGTH );
eth->tx.bytes_sent = 0;
 
/* Initialize error status bits */
CLEAR_FLAG( eth->tx.bd, ETH_TX_BD, DEFER );
CLEAR_FLAG( eth->tx.bd, ETH_TX_BD, COLLISION );
CLEAR_FLAG( eth->tx.bd, ETH_TX_BD, RETRANSMIT );
CLEAR_FLAG( eth->tx.bd, ETH_TX_BD, UNDERRUN );
CLEAR_FLAG( eth->tx.bd, ETH_TX_BD, NO_CARRIER );
SET_FIELD( eth->tx.bd, ETH_TX_BD, RETRY, 0 );
/* Find out minimum length */
if ( TEST_FLAG( eth->tx.bd, ETH_TX_BD, PAD ) ||
TEST_FLAG( eth->regs.moder, ETH_MODER, PAD ) )
eth->tx.minimum_length = GET_FIELD( eth->regs.packetlen, ETH_PACKETLEN, MINFL );
else
eth->tx.minimum_length = eth->tx.packet_length;
/* Find out maximum length */
if ( TEST_FLAG( eth->regs.moder, ETH_MODER, HUGEN ) )
eth->tx.maximum_length = eth->tx.packet_length;
else
eth->tx.maximum_length = GET_FIELD( eth->regs.packetlen, ETH_PACKETLEN, MAXFL );
/* Do we need CRC on this packet? */
if ( TEST_FLAG( eth->regs.moder, ETH_MODER, CRCEN ) ||
(TEST_FLAG( eth->tx.bd, ETH_TX_BD, CRC) &&
TEST_FLAG( eth->tx.bd, ETH_TX_BD, LAST)) )
eth->tx.add_crc = 1;
else
eth->tx.add_crc = 0;
eth_initialize_tx_crc( eth );
debug( 3, "Ethernet: Starting TX of %u bytes (min. %u, max. %u)\n", eth->tx.packet_length,
eth->tx.minimum_length, eth->tx.maximum_length );
/* Write "header" to file */
length_with_crc = eth->tx.add_crc ? (eth->tx.packet_length + 4) : eth->tx.packet_length;
write( eth->txfd, &length_with_crc, sizeof(length_with_crc) );
/************************************************/
/* start transmit with reading packet into FIFO */
eth->tx.state = ETH_TXSTATE_READFIFO;
}
else if ( !TEST_FLAG( eth->regs.moder, ETH_MODER, TXEN ) ) {
/* stop TX logic */
eth->tx.state = ETH_TXSTATE_IDLE;
}
 
/* stay in this state if (TXEN && !READY) */
break;
/* Read buffer descriptor */
eth->tx.bd = eth->regs.bd_ram[eth->tx.bd_index];
eth->tx.bd_addr = eth->regs.bd_ram[eth->tx.bd_index + 1];
if ( TEST_FLAG( eth->tx.bd, ETH_TX_BD, READY ) ) {
/*****************/
/* initialize TX */
eth->tx.bytes_left = eth->tx.packet_length = GET_FIELD( eth->tx.bd, ETH_TX_BD, LENGTH );
eth->tx.bytes_sent = 0;
/* Initialize error status bits */
CLEAR_FLAG( eth->tx.bd, ETH_TX_BD, DEFER );
CLEAR_FLAG( eth->tx.bd, ETH_TX_BD, COLLISION );
CLEAR_FLAG( eth->tx.bd, ETH_TX_BD, RETRANSMIT );
CLEAR_FLAG( eth->tx.bd, ETH_TX_BD, UNDERRUN );
CLEAR_FLAG( eth->tx.bd, ETH_TX_BD, NO_CARRIER );
SET_FIELD ( eth->tx.bd, ETH_TX_BD, RETRY, 0 );
/* Find out minimum length */
if ( TEST_FLAG( eth->tx.bd, ETH_TX_BD, PAD ) ||
TEST_FLAG( eth->regs.moder, ETH_MODER, PAD ) )
eth->tx.minimum_length = GET_FIELD( eth->regs.packetlen, ETH_PACKETLEN, MINFL );
else
eth->tx.minimum_length = eth->tx.packet_length;
/* Find out maximum length */
if ( TEST_FLAG( eth->regs.moder, ETH_MODER, HUGEN ) )
eth->tx.maximum_length = eth->tx.packet_length;
else
eth->tx.maximum_length = GET_FIELD( eth->regs.packetlen, ETH_PACKETLEN, MAXFL );
/* Do we need CRC on this packet? */
if ( TEST_FLAG( eth->regs.moder, ETH_MODER, CRCEN ) ||
(TEST_FLAG( eth->tx.bd, ETH_TX_BD, CRC) &&
TEST_FLAG( eth->tx.bd, ETH_TX_BD, LAST)) )
eth->tx.add_crc = 1;
else
eth->tx.add_crc = 0;
if ( TEST_FLAG( eth->regs.moder, ETH_MODER, DLYCRCEN ) )
eth->tx.crc_dly = 1;
else
eth->tx.crc_dly = 0;
/* XXX - For now we skip CRC calculation */
debug( 3, "Ethernet: Starting TX of %u bytes (min. %u, max. %u)\n", eth->tx.packet_length,
eth->tx.minimum_length, eth->tx.maximum_length );
if (eth->rtx_type == ETH_RTX_FILE) {
/* write packet length to file */
nwritten = write( eth->txfd, &(eth->tx.packet_length), sizeof(eth->tx.packet_length) );
}
/************************************************/
/* start transmit with reading packet into FIFO */
debug (3, "TX - entering state READFIFO\n");
eth->tx.state = ETH_TXSTATE_READFIFO;
}
else if ( !TEST_FLAG( eth->regs.moder, ETH_MODER, TXEN ) ) {
/* stop TX logic */
debug (3, "TX - entering state IDLE\n");
eth->tx.state = ETH_TXSTATE_IDLE;
}
/* stay in this state if (TXEN && !READY) */
break;
case ETH_TXSTATE_READFIFO:
if ( eth->tx.bytes_sent < eth->tx.packet_length ) {
eth->tx_buff[eth->tx.bytes_sent\4] = eval_mem32(eth->tx.bytes_sent + eth->tx.bd_addr, &breakpoint)
eth->tx.bytes_sent += 4;
}
else {
eth->tx.state = ETH_TXSTATE_TRANSMIT;
}
break;
if ( eth->tx.bytes_sent < eth->tx.packet_length ) {
read_word = eval_mem32(eth->tx.bytes_sent + eth->tx.bd_addr, &breakpoint);
eth->tx_buff[eth->tx.bytes_sent] = (unsigned char)(read_word >> 24);
eth->tx_buff[eth->tx.bytes_sent+1] = (unsigned char)(read_word >> 16);
eth->tx_buff[eth->tx.bytes_sent+2] = (unsigned char)(read_word >> 8);
eth->tx_buff[eth->tx.bytes_sent+3] = (unsigned char)(read_word);
eth->tx.bytes_sent += 4;
}
else {
debug (3, "TX - entering state TRANSMIT\n");
eth->tx.state = ETH_TXSTATE_TRANSMIT;
}
break;
case ETH_TXSTATE_TRANSMIT:
write( eth->txfd, eth->tx_buff, eth->tx.packet_length );
eth->tx.state = ETH_TXSTATE_IDLE;
break;
/* send packet */
switch (eth->rtx_type) {
case ETH_RTX_FILE:
nwritten = write( eth->txfd, eth->tx_buff, eth->tx.packet_length );
break;
case ETH_RTX_SOCK:
memset(&sll, 0, sizeof(sll));
sll.sll_ifindex = eth->ifr.ifr_ifindex;
nwritten = sendto(eth->rtx_sock, eth->tx_buff, eth->tx.packet_length, 0, (struct sockaddr *)&sll, sizeof(sll));
break;
}
/* set BD status */
if (nwritten == eth->tx.packet_length) {
CLEAR_FLAG (eth->tx.bd, ETH_TX_BD, READY);
SET_FLAG (eth->regs.int_source, ETH_INT_SOURCE, TXB);
debug (3, "TX - entering state IDLE\n");
eth->tx.state = ETH_TXSTATE_IDLE;
debug (3, "send (%d)bytes OK\n", nwritten);
}
else {
/* XXX - implement retry mechanism here! */
CLEAR_FLAG (eth->tx.bd, ETH_TX_BD, READY);
CLEAR_FLAG (eth->tx.bd, ETH_TX_BD, COLLISION);
SET_FLAG (eth->regs.int_source, ETH_INT_SOURCE, TXE);
debug (3, "TX - entering state IDLE\n");
eth->tx.state = ETH_TXSTATE_IDLE;
debug (3, "send FAILED!\n");
}
eth->regs.bd_ram[eth->tx.bd_index] = eth->tx.bd;
/* advance to next BD */
if (bAdvance) {
if ( TEST_FLAG( eth->tx.bd, ETH_TX_BD, WRAP ) ||
eth->tx.bd_index >= ETH_BD_COUNT )
eth->tx.bd_index = 0;
else
eth->tx.bd_index += 2;
}
/* generate OK interrupt */
if ( TEST_FLAG(eth->regs.int_mask, ETH_INT_MASK, TXE_M) ||
TEST_FLAG(eth->regs.int_mask, ETH_INT_MASK, TXB_M) )
{
report_interrupt( eth->mac_int );
}
break;
}
}
/* ========================================================================= */
148,7 → 219,7
 
 
/* ========================================================================= */
/* RX LOGIC */
/* RX LOGIC */
/*---------------------------------------------------------------------------*/
 
/*
157,23 → 228,203
*/
void eth_controller_rx_clock( struct eth_device *eth )
{
int i;
int breakpoint = 0;
long nread;
unsigned long send_word;
fd_set rfds;
switch (eth->rx.state) {
case ETH_RXSTATE_IDLE:
break;
if ( TEST_FLAG( eth->regs.moder, ETH_MODER, RXEN) ) {
debug (3, "RX - entering state WAIT4BD\n");
eth->rx.state = ETH_RXSTATE_WAIT4BD;
}
break;
case ETH_RXSTATE_WAIT4BD:
break;
eth->rx.bd = eth->regs.bd_ram[eth->rx.bd_index];
eth->rx.bd_addr = eth->regs.bd_ram[eth->rx.bd_index + 1];
if ( TEST_FLAG( eth->rx.bd, ETH_RX_BD, READY ) ) {
/*****************/
/* Initialize RX */
CLEAR_FLAG( eth->rx.bd, ETH_RX_BD, MISS );
CLEAR_FLAG( eth->rx.bd, ETH_RX_BD, INVALID );
CLEAR_FLAG( eth->rx.bd, ETH_RX_BD, DRIBBLE );
CLEAR_FLAG( eth->rx.bd, ETH_RX_BD, UVERRUN );
CLEAR_FLAG( eth->rx.bd, ETH_RX_BD, COLLISION );
CLEAR_FLAG( eth->rx.bd, ETH_RX_BD, TOOBIG );
CLEAR_FLAG( eth->rx.bd, ETH_RX_BD, TOOSHORT );
debug( 3, "Ethernet: Starting RX\n" );
/* Setup file to read from */
if ( TEST_FLAG( eth->regs.moder, ETH_MODER, LOOPBCK ) ) {
eth->rx.fd = eth->txfd;
eth->rx.offset = &(eth->loopback_offset);
} else {
eth->rx.fd = eth->rxfd;
eth->rx.offset = 0;
}
debug (3, "RX - entering state RECV\n");
eth->rx.state = ETH_RXSTATE_RECV;
}
else {
nread = recv(eth->rtx_sock, eth->rx_buff, ETH_MAXPL, MSG_PEEK);
if (nread > 0) {
SET_FLAG (eth->regs.int_source, ETH_INT_SOURCE, BUSY);
}
}
break;
case ETH_RXSTATE_RECV:
break;
switch (eth->rtx_type) {
case ETH_RTX_FILE:
/* Read packet length */
if ( eth_read_rx_file( eth, &(eth->rx.packet_length), sizeof(eth->rx.packet_length) )
< sizeof(eth->rx.packet_length) ) {
/* TODO: just do what real ethernet would do (some kind of error state) */
debug (4, "eth_start_rx(): File does not have a packet ready for RX\n" );
cont_run = 0;
break;
}
 
/* Packet must be big enough to hold a header */
if ( eth->rx.packet_length < ETH_HLEN ){
debug( 3, "eth_start_rx(): Packet too small\n" );
eth_rx_next_packet( eth );
 
debug (3, "RX - entering state IDLE\n");
eth->rx.state = ETH_RXSTATE_IDLE;
break;
}
eth->rx.bytes_read = 0;
eth->rx.bytes_left = eth->rx.packet_length;
/* for now Read entire packet into memory */
nread = eth_read_rx_file( eth, eth->rx_buff, eth->rx.bytes_left );
if ( nread < eth->rx.bytes_left )
debug (3, "Read %d from %d. Error!\n", nread, eth->rx.bytes_left);
eth->rx.error = 1;
break;
case ETH_RTX_SOCK:
nread = recv(eth->rtx_sock, eth->rx_buff, ETH_MAXPL, MSG_DONTWAIT);
if (nread < 0) {
if ( errno != EAGAIN ) {
debug (3, "recv() FAILED!\n");
break;
}
else {
break;
}
}
eth->rx.bytes_left = nread;
eth->rx.bytes_read = 0;
debug (3, "RX - entering state WRITEFIFO\n");
eth->rx.state = ETH_RXSTATE_WRITEFIFO;
break;
}
break;
case ETH_RXSTATE_WRITEFIFO:
break;
send_word = ((unsigned long)eth->rx_buff[eth->rx.bytes_read] << 24) |
((unsigned long)eth->rx_buff[eth->rx.bytes_read+1] << 16) |
((unsigned long)eth->rx_buff[eth->rx.bytes_read+2] << 8) |
((unsigned long)eth->rx_buff[eth->rx.bytes_read+3] );
set_mem32( eth->rx.bd_addr + eth->rx.bytes_read, send_word, &breakpoint);
/* update counters */
debug (3, "Write %d, left %d - %08lXd\n", eth->rx.bytes_read, eth->rx.bytes_left, send_word);
eth->rx.bytes_left -= 4;
eth->rx.bytes_read += 4;
if ( eth->rx.bytes_left <= 0 ) {
/* Write result to bd */
SET_FIELD( eth->rx.bd, ETH_RX_BD, LENGTH, eth->rx.packet_length );
CLEAR_FLAG( eth->rx.bd, ETH_RX_BD, READY);
SET_FLAG( eth->regs.int_source, ETH_INT_SOURCE, RXF);
if ( eth->rx.packet_length < GET_FIELD( eth->regs.packetlen, ETH_PACKETLEN, MINFL ) )
SET_FLAG( eth->rx.bd, ETH_RX_BD, TOOBIG);
if ( eth->rx.packet_length > GET_FIELD( eth->regs.packetlen, ETH_PACKETLEN, MAXFL ) )
SET_FLAG( eth->rx.bd, ETH_RX_BD, TOOSHORT);
eth->regs.bd_ram[eth->rx.bd_index] = eth->rx.bd;
/* advance to next BD */
if ( TEST_FLAG( eth->rx.bd, ETH_RX_BD, WRAP ) || eth->rx.bd_index >= ETH_BD_COUNT )
eth->tx.bd_index = eth->regs.tx_bd_num;
else
eth->tx.bd_index += 2;
if ( TEST_FLAG(eth->regs.int_mask, ETH_INT_MASK, RXF_M) ) {
report_interrupt( eth->mac_int );
}
/* ready to receive next packet */
debug (3, "RX - entering state IDLE\n");
eth->rx.state = ETH_RXSTATE_IDLE;
}
break;
}
}
 
/* ========================================================================= */
/* Move to next RX BD */
void eth_rx_next_packet( struct eth_device *eth )
{
/* Skip any possible leftovers */
if ( eth->rx.bytes_left )
eth_skip_rx_file( eth, eth->rx.bytes_left );
}
/* "Skip" bytes in RX file */
void eth_skip_rx_file( struct eth_device *eth, off_t count )
{
eth->rx.offset += count;
}
 
/* Move RX file position back */
void eth_rewind_rx_file( struct eth_device *eth, off_t count )
{
eth->rx.offset -= count;
}
/*
* Utility function to read from the ethernet RX file
* This function moves the file pointer to the current place in the packet before reading
*/
ssize_t eth_read_rx_file( struct eth_device *eth, void *buf, size_t count )
{
ssize_t result;
if ( eth->rx.fd <= 0 ) {
debug( 3, "Ethernet: No RX file\n" );
return 0;
}
if ( eth->rx.offset )
if ( lseek( eth->rx.fd, *(eth->rx.offset), SEEK_SET ) == (off_t)-1 ) {
debug( 3, "Ethernet: Error seeking RX file\n" );
return 0;
}
 
result = read( eth->rx.fd, buf, count );
if ( eth->rx.offset && result >= 0 )
*(eth->rx.offset) += result;
return result;
}
 
/* ========================================================================= */
 
/*
Reset. Initializes all registers to default and places devices in
memory address space.
Reset. Initializes all registers to default and places devices in
memory address space.
*/
void eth_reset()
{
181,61 → 432,134
unsigned i;
if (!config.nethernets)
return;
return;
if ( first_time ) {
memset( eths, 0, sizeof(eths) );
first_time = 0;
memset( eths, 0, sizeof(eths) );
first_time = 0;
}
for ( i = 0; i < MAX_ETHERNETS; ++ i ) {
struct eth_device *eth = &(eths[i]);
eth->eth_number = i;
eth->baseaddr = config.ethernets[i].baseaddr;
if ( eth->baseaddr != 0 ) {
/* Mark which DMA controller and channels */
eth->dma = config.ethernets[i].dma;
eth->tx_channel = config.ethernets[i].tx_channel;
eth->rx_channel = config.ethernets[i].rx_channel;
/* (Re-)open TX/RX files */
eth->rxfile = config.ethernets[i].rxfile;
eth->txfile = config.ethernets[i].txfile;
eth_close_files( eth );
if ( (eth->rxfd = open( eth->rxfile, O_RDONLY )) < 0 )
fprintf( stderr, "Cannot open Ethernet RX file \"%s\"\n", eth->rxfile );
if ( (eth->txfd = open( eth->txfile,
O_RDWR | O_CREAT | O_APPEND | O_SYNC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH )) < 0 )
fprintf( stderr, "Cannot open Ethernet TX file \"%s\"\n", eth->txfile );
eth->loopback_offset = lseek( eth->txfd, 0, SEEK_END );
/* Set registers to default values */
memset( &(eth->regs), 0, sizeof(eth->regs) );
eth->regs.moder = 0x0000A000;
eth->regs.ipgt = 0x00000012;
eth->regs.ipgr1 = 0x0000000C;
eth->regs.ipgr2 = 0x00000012;
eth->regs.packetlen = 0x003C0600;
eth->regs.collconf = 0x000F003F;
eth->regs.miimoder = 0x00000064;
eth->regs.tx_tb_num = 0x00000080;
/* Initialize TX/RX status */
memset( &(eth->tx), 0, sizeof(eth->tx) );
memset( &(eth->rx), 0, sizeof(eth->rx) );
eth->rx.bd_index = eth->regs.tx_bd_num;
/* Register memory range */
register_memoryarea( eth->baseaddr, ETH_ADDR_SPACE, 4, eth_read32, eth_write32 );
}
struct eth_device *eth = &(eths[i]);
eth->eth_number = i;
eth_reset_controller( eth );
}
}
/* ========================================================================= */
 
 
static void eth_reset_controller(struct eth_device *eth)
{
int i = eth->eth_number;
int j;
struct sockaddr_ll sll;
eth->baseaddr = config.ethernets[i].baseaddr;
if ( eth->baseaddr != 0 ) {
/* Mark which DMA controller and channels */
eth->dma = config.ethernets[i].dma;
eth->tx_channel = config.ethernets[i].tx_channel;
eth->rx_channel = config.ethernets[i].rx_channel;
eth->rtx_type = ETH_RTX_SOCK/*config.ethernets[i].rtx_type*/;
switch (eth->rtx_type) {
case ETH_RTX_FILE:
/* (Re-)open TX/RX files */
eth->rxfile = config.ethernets[i].rxfile;
eth->txfile = config.ethernets[i].txfile;
if ( eth->rxfd > 0 )
close( eth->rxfd );
if ( eth->txfd > 0 )
close( eth->txfd );
eth->rxfd = eth->txfd = -1;
if ( (eth->rxfd = open( eth->rxfile, O_RDONLY )) < 0 )
fprintf( stderr, "Cannot open Ethernet RX file \"%s\"\n", eth->rxfile );
if ( (eth->txfd = open( eth->txfile,
O_RDWR | O_CREAT | O_APPEND | O_SYNC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH )) < 0 )
fprintf( stderr, "Cannot open Ethernet TX file \"%s\"\n", eth->txfile );
eth->loopback_offset = lseek( eth->txfd, 0, SEEK_END );
break;
case ETH_RTX_SOCK:
/* (Re-)open TX/RX sockets */
if (eth->rtx_sock != 0)
break;
debug (3, "RTX oppening socket...\n");
eth->rtx_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
if (eth->rtx_sock == -1) {
fprintf( stderr, "Cannot open rtx_sock.\n");
return;
}
/* get interface index number */
debug (3, "RTX getting interface...\n");
memset(&(eth->ifr), 0, sizeof(eth->ifr));
strncpy(eth->ifr.ifr_name, "lo"/*config.ethernets[i].sock_interface*/, IFNAMSIZ);
if (ioctl(eth->rtx_sock, SIOCGIFINDEX, &(eth->ifr)) == -1) {
fprintf( stderr, "SIOCGIFINDEX failed!\n");
return;
}
debug (3, "RTX Socket Interface : %d\n", eth->ifr.ifr_ifindex);
/* Bind to interface... */
debug (3, "Binding to the interface ifindex=%d\n", eth->ifr.ifr_ifindex);
memset(&sll, 0xff, sizeof(sll));
sll.sll_family = AF_PACKET; /* allways AF_PACKET */
sll.sll_protocol = htons(ETH_P_ALL);
sll.sll_ifindex = eth->ifr.ifr_ifindex;
if (bind(eth->rtx_sock, (struct sockaddr *)&sll, sizeof(sll)) == -1) {
fprintf( stderr, "Error bind().\n");
return;
}
/* first, flush all received packets. */
debug (3, "Flush");
do {
fd_set fds;
struct timeval t;
debug( 3, ".");
FD_ZERO(&fds);
FD_SET(eth->rtx_sock, &fds);
memset(&t, 0, sizeof(t));
j = select(FD_SETSIZE, &fds, NULL, NULL, &t);
if (j > 0)
recv(eth->rtx_sock, eth->rx_buff, j, 0);
} while (j);
debug (3, "\n");
break;
}
/* Set registers to default values */
memset( &(eth->regs), 0, sizeof(eth->regs) );
eth->regs.moder = 0x0000A000;
eth->regs.ipgt = 0x00000012;
eth->regs.ipgr1 = 0x0000000C;
eth->regs.ipgr2 = 0x00000012;
eth->regs.packetlen = 0x003C0600;
eth->regs.collconf = 0x000F003F;
eth->regs.miimoder = 0x00000064;
eth->regs.tx_bd_num = 0x00000080;
/* Initialize TX/RX status */
memset( &(eth->tx), 0, sizeof(eth->tx) );
memset( &(eth->rx), 0, sizeof(eth->rx) );
eth->rx.bd_index = eth->regs.tx_bd_num;
/* Register memory range */
register_memoryarea( eth->baseaddr, ETH_ADDR_SPACE, 4, eth_read32, eth_write32 );
}
}
/* ========================================================================= */
 
 
/*
Print register values on stdout
*/
244,31 → 568,31
unsigned i;
for ( i = 0; i < MAX_ETHERNETS; ++ i ) {
struct eth_device *eth = &(eths[i]);
if ( eth->baseaddr == 0 )
continue;
printf( "\nEthernet MAC %u at 0x%08X:\n", i, eth->baseaddr );
printf( "MODER : 0x%08lX\n", eth->regs.moder );
printf( "INT_SOURCE : 0x%08lX\n", eth->regs.int_source );
printf( "INT_MASK : 0x%08lX\n", eth->regs.int_mask );
printf( "IPGT : 0x%08lX\n", eth->regs.ipgt );
printf( "IPGR1 : 0x%08lX\n", eth->regs.ipgr1 );
printf( "IPGR2 : 0x%08lX\n", eth->regs.ipgr2 );
printf( "PACKETLEN : 0x%08lX\n", eth->regs.packetlen );
printf( "COLLCONF : 0x%08lX\n", eth->regs.collconf );
printf( "TX_BD_NUM : 0x%08lX\n", eth->regs.tx_bd_num );
printf( "CTRLMODER : 0x%08lX\n", eth->regs.controlmoder );
printf( "MIIMODER : 0x%08lX\n", eth->regs.miimoder );
printf( "MIICOMMAND : 0x%08lX\n", eth->regs.miicommand );
printf( "MIIADDRESS : 0x%08lX\n", eth->regs.miiaddress );
printf( "MIITX_DATA : 0x%08lX\n", eth->regs.miitx_data );
printf( "MIIRX_DATA : 0x%08lX\n", eth->regs.miirx_data );
printf( "MIISTATUS : 0x%08lX\n", eth->regs.miistatus );
printf( "MAC Address : %02X:%02X:%02X:%02X:%02X:%02X\n",
eth->mac_address[0], eth->mac_address[1], eth->mac_address[2],
eth->mac_address[3], eth->mac_address[4], eth->mac_address[5] );
struct eth_device *eth = &(eths[i]);
if ( eth->baseaddr == 0 )
continue;
printf( "\nEthernet MAC %u at 0x%08X:\n", i, eth->baseaddr );
printf( "MODER : 0x%08lX\n", eth->regs.moder );
printf( "INT_SOURCE : 0x%08lX\n", eth->regs.int_source );
printf( "INT_MASK : 0x%08lX\n", eth->regs.int_mask );
printf( "IPGT : 0x%08lX\n", eth->regs.ipgt );
printf( "IPGR1 : 0x%08lX\n", eth->regs.ipgr1 );
printf( "IPGR2 : 0x%08lX\n", eth->regs.ipgr2 );
printf( "PACKETLEN : 0x%08lX\n", eth->regs.packetlen );
printf( "COLLCONF : 0x%08lX\n", eth->regs.collconf );
printf( "TX_BD_NUM : 0x%08lX\n", eth->regs.tx_bd_num );
printf( "CTRLMODER : 0x%08lX\n", eth->regs.controlmoder );
printf( "MIIMODER : 0x%08lX\n", eth->regs.miimoder );
printf( "MIICOMMAND : 0x%08lX\n", eth->regs.miicommand );
printf( "MIIADDRESS : 0x%08lX\n", eth->regs.miiaddress );
printf( "MIITX_DATA : 0x%08lX\n", eth->regs.miitx_data );
printf( "MIIRX_DATA : 0x%08lX\n", eth->regs.miirx_data );
printf( "MIISTATUS : 0x%08lX\n", eth->regs.miistatus );
printf( "MAC Address : %02X:%02X:%02X:%02X:%02X:%02X\n",
eth->mac_address[0], eth->mac_address[1], eth->mac_address[2],
eth->mac_address[3], eth->mac_address[4], eth->mac_address[5] );
}
}
/* ========================================================================= */
282,8 → 606,8
unsigned i;
for ( i = 0; i < config.nethernets; ++ i ) {
eth_controller_tx_clock( &(eths[i]) );
eth_controller_rx_clock( &(eths[i]) );
eth_controller_tx_clock( &(eths[i]) );
eth_controller_rx_clock( &(eths[i]) );
}
}
/* ========================================================================= */
295,9 → 619,9
unsigned long eth_read32( unsigned long addr )
{
struct eth_device *eth;
if ( !eth_find_controller( addr, &eth, &addr ) ) {
printf( "eth_read32( 0x%08lX ): Not in registered range(s)\n", addr );
return 0;
if ( !eth_find_controller( addr, &eth, &addr ) ) {
printf( "eth_read32( 0x%08lX ): Not in registered range(s)\n", addr );
return 0;
}
 
switch( addr ) {
318,16 → 642,16
case ETH_MIIRX_DATA: return eth->regs.miirx_data;
case ETH_MIISTATUS: return eth->regs.miistatus;
case ETH_MAC_ADDR0: return (((unsigned long)eth->mac_address[3]) << 24) |
(((unsigned long)eth->mac_address[2]) << 16) |
(((unsigned long)eth->mac_address[1]) << 8) |
(unsigned long)eth->mac_address[0];
(((unsigned long)eth->mac_address[2]) << 16) |
(((unsigned long)eth->mac_address[1]) << 8) |
(unsigned long)eth->mac_address[0];
case ETH_MAC_ADDR1: return (((unsigned long)eth->mac_address[5]) << 8) |
(unsigned long)eth->mac_address[4];
case ETH_DMA_RX_TX: return eth_rx( eth );
(unsigned long)eth->mac_address[4];
/*case ETH_DMA_RX_TX: return eth_rx( eth );*/
}
 
if ( (addr >= ETH_BD_BASE) && (addr < ETH_BD_BASE + ETH_BD_SPACE) )
return eth->regs.bd_ram[(addr - ETH_BD_BASE) / 4];
return eth->regs.bd_ram[(addr - ETH_BD_BASE) / 4];
printf( "eth_read32( 0x%08lX ): Illegal address\n", addr + eth->baseaddr );
cont_run = 0;
342,9 → 666,9
void eth_write32( unsigned long addr, unsigned long value )
{
struct eth_device *eth;
if ( !eth_find_controller( addr, &eth, &addr ) ) {
printf( "eth_write32( 0x%08lX ): Not in registered range(s)\n", addr );
return;
if ( !eth_find_controller( addr, &eth, &addr ) ) {
printf( "eth_write32( 0x%08lX ): Not in registered range(s)\n", addr );
return;
}
switch( addr ) {
365,22 → 689,22
case ETH_MIIRX_DATA: eth->regs.miirx_data = value; return;
case ETH_MIISTATUS: eth->regs.miistatus = value; return;
case ETH_MAC_ADDR0:
eth->mac_address[0] = value & 0xFF;
eth->mac_address[1] = (value >> 8) & 0xFF;
eth->mac_address[2] = (value >> 16) & 0xFF;
eth->mac_address[3] = (value >> 24) & 0xFF;
return;
eth->mac_address[0] = value & 0xFF;
eth->mac_address[1] = (value >> 8) & 0xFF;
eth->mac_address[2] = (value >> 16) & 0xFF;
eth->mac_address[3] = (value >> 24) & 0xFF;
return;
case ETH_MAC_ADDR1:
eth->mac_address[4] = value & 0xFF;
eth->mac_address[5] = (value >> 8) & 0xFF;
return;
case ETH_DMA_RX_TX: eth_tx( eth, value ); return;
eth->mac_address[4] = value & 0xFF;
eth->mac_address[5] = (value >> 8) & 0xFF;
return;
/*case ETH_DMA_RX_TX: eth_tx( eth, value ); return;*/
}
 
if ( (addr >= ETH_BD_BASE) && (addr < ETH_BD_BASE + ETH_BD_SPACE) ) {
eth->regs.bd_ram[(addr - ETH_BD_BASE) / 4] = value;
return;
eth->regs.bd_ram[(addr - ETH_BD_BASE) / 4] = value;
return;
}
printf( "eth_write32( 0x%08lX ): Illegal address\n", addr + eth->baseaddr );
390,6 → 714,14
/* ========================================================================= */
 
 
/* When TX_BD_NUM is written, also reset current RX BD index */
void eth_write_tx_bd_num( struct eth_device *eth, unsigned long value )
{
eth->rx.bd_index = eth->regs.tx_bd_num = value & 0xFF;
}
/* ========================================================================= */
 
 
/*
Convert a memory address to a oontroller struct and relative address.
Return nonzero on success
400,17 → 732,17
*eth = NULL;
for ( i = 0; i < MAX_ETHERNETS && *eth == NULL; ++ i ) {
if ( (addr >= eths[i].baseaddr) && (addr < eths[i].baseaddr + ETH_ADDR_SPACE) )
*eth = &(eths[i]);
}
if ( (addr >= eths[i].baseaddr) && (addr < eths[i].baseaddr + ETH_ADDR_SPACE) )
*eth = &(eths[i]);
}
/* verify we found a controller */
if ( *eth == NULL )
return 0;
return 0;
/* Verify legal address */
if ( (addr - (*eth)->baseaddr) % 4 != 0 )
return 0;
return 0;
*reladdr = addr - (*eth)->baseaddr;
return 1;
/trunk/or1ksim/peripheral/ethernet.h
153,7 → 153,7
/* Field definitions for RX buffer descriptors */
#define ETH_RX_BD_LENGTH_OFFSET 16
#define ETH_RX_BD_LENGTH_WIDTH 16
#define ETH_RX_BD_EMPTY_OFFSET 15
#define ETH_RX_BD_READY_OFFSET 15
#define ETH_RX_BD_INTERRUPT_OFFSET 14
#define ETH_RX_BD_WRAP_OFFSET 13
#define ETH_RX_BD_MISS_OFFSET 7
163,6 → 163,6
#define ETH_RX_BD_TOOBIG_OFFSET 3
#define ETH_RX_BD_TOOSHORT_OFFSET 2
#define ETH_RX_BD_CRC_OFFSET 1
#define ETH_RX_BD_LATECOLL_OFFSET 0
#define ETH_RX_BD_COLLISION_OFFSET 0
 
#endif /* __OR1KSIM_PERIPHERAL_ETHERNET_H */
/trunk/or1ksim/peripheral/Makefile.am
19,4 → 19,4
#
 
noinst_LIBRARIES = libperipheral.a
libperipheral_a_SOURCES = 16450.c dma.c mc.c ethernet.c crc32.c gpio.c vga.c fb.c ps2kbd.c
libperipheral_a_SOURCES = 16450.c dma.c mc.c eth.c crc32.c gpio.c vga.c fb.c ps2kbd.c
/trunk/or1ksim/peripheral/ethernet_i.h
23,6 → 23,10
 
#include "ethernet.h"
#include "config.h"
#include <netpacket/packet.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
 
/*
* Ethernet protocol definitions
33,7 → 37,7
 
#include <sys/types.h>
 
#define ETH_ALEN 6
#define ETH_ALEN 6
 
struct ether_addr
{
90,6 → 94,12
#define ETH_RXSTATE_WAIT4BD 10
#define ETH_RXSTATE_RECV 20
#define ETH_RXSTATE_WRITEFIFO 30
 
#define ETH_RTX_FILE 0
#define ETH_RTX_SOCK 1
 
#define ETH_MAXPL 0x10000
 
struct eth_device
{
/* Base address in memory */
103,8 → 113,11
unsigned tx_channel;
unsigned rx_channel;
 
/* Our address */
unsigned char mac_address[ETH_ALEN];
/* Our address */
unsigned char mac_address[ETH_ALEN];
/* interrupt line */
unsigned long mac_int;
 
/* RX and TX file names and handles */
const char *rxfile, *txfile;
112,6 → 125,11
int rxfd;
off_t loopback_offset;
 
int rtx_sock;
int rtx_type;
struct ifreq ifr;
fd_set rfds, wfds;
/* Current TX state */
struct
{
120,11 → 138,12
unsigned long bd;
unsigned long bd_addr;
unsigned working, waiting_for_dma, error;
unsigned packet_length;
long packet_length;
unsigned minimum_length, maximum_length;
unsigned add_crc;
unsigned crc_dly;
unsigned long crc_value;
unsigned bytes_left, bytes_sent;
long bytes_left, bytes_sent;
} tx;
 
/* Current RX state */
133,10 → 152,11
unsigned long state;
unsigned long bd_index;
unsigned long bd;
unsigned long bd_addr;
int fd;
off_t *offset;
unsigned working, error, waiting_for_dma;
unsigned packet_length, bytes_read, bytes_left;
long packet_length, bytes_read, bytes_left;
} rx;
 
/* Visible registers */
163,9 → 183,9
unsigned long bd_ram[ETH_BD_SPACE / 4];
} regs;
 
unsigned long rx_buff[0x10000];
unsigned long tx_buff[0x10000];
unsigned long lo_buff[0x10000];
unsigned char rx_buff[ETH_MAXPL];
unsigned char tx_buff[ETH_MAXPL];
unsigned char lo_buff[ETH_MAXPL];
};
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.