Line 1... |
Line 1... |
/* ethernet.c -- Simulation of Ethernet MAC
|
/* ethernet.c -- Simulation of Ethernet MAC
|
|
|
Copyright (C) 2001 by Erez Volk, erez@opencores.org
|
Copyright (C) 2001 by Erez Volk, erez@opencores.org
|
Ivan Guzvinec, ivang@opencores.org
|
Ivan Guzvinec, ivang@opencores.org
|
Copyright (C) 2008 Embecosm Limited
|
Copyright (C) 2008 Embecosm Limited
|
|
Copyright (C) 2010 ORSoC
|
|
|
Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
|
Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
|
|
Contributor Julius Baxter <julius@orsoc.se>
|
|
|
This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
|
This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
|
|
|
This program is free software; you can redistribute it and/or modify it
|
This program is free software; you can redistribute it and/or modify it
|
under the terms of the GNU General Public License as published by the Free
|
under the terms of the GNU General Public License as published by the Free
|
Line 75... |
Line 77... |
unsigned rx_channel;
|
unsigned rx_channel;
|
|
|
/* Our address */
|
/* Our address */
|
unsigned char mac_address[ETHER_ADDR_LEN];
|
unsigned char mac_address[ETHER_ADDR_LEN];
|
|
|
/* interrupt line */
|
/* interrupt line number */
|
unsigned long mac_int;
|
unsigned long mac_int;
|
|
|
|
/* interrupt line status */
|
|
int int_line_stat;
|
|
|
/* VAPI ID */
|
/* VAPI ID */
|
unsigned long base_vapi_id;
|
unsigned long base_vapi_id;
|
|
|
/* Ethernet PHY address */
|
/* Ethernet PHY address */
|
unsigned long phy_addr;
|
unsigned long phy_addr;
|
Line 173... |
Line 178... |
static void eth_skip_rx_file (struct eth_device *, off_t);
|
static void eth_skip_rx_file (struct eth_device *, off_t);
|
static void eth_rx_next_packet (struct eth_device *);
|
static void eth_rx_next_packet (struct eth_device *);
|
static void eth_write_tx_bd_num (struct eth_device *, unsigned long value);
|
static void eth_write_tx_bd_num (struct eth_device *, unsigned long value);
|
static void eth_miim_trans (void *dat);
|
static void eth_miim_trans (void *dat);
|
|
|
|
#define ETH_DEBUG 0
|
|
|
|
|
/* ========================================================================== */
|
/* ========================================================================== */
|
/* Dummy socket routines. These are the points where we spoof an Ethernet */
|
/* Dummy socket routines. These are the points where we spoof an Ethernet */
|
/* network. */
|
/* network. */
|
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
Line 294... |
Line 301... |
{
|
{
|
case ETH_RTX_FILE:
|
case ETH_RTX_FILE:
|
nwritten = write (eth->txfd, eth->tx_buff, eth->tx.packet_length);
|
nwritten = write (eth->txfd, eth->tx_buff, eth->tx.packet_length);
|
break;
|
break;
|
case ETH_RTX_TAP:
|
case ETH_RTX_TAP:
|
/*
|
#if ETH_DEBUG
|
printf ("Writing TAP\n");
|
printf ("Writing TAP\n");
|
|
|
printf("packet %d bytes:",(int) eth->tx.packet_length );
|
printf("packet %d bytes:",(int) eth->tx.packet_length );
|
int j; for (j=0;j<eth->tx.packet_length;j++)
|
int j; for (j=0;j<eth->tx.packet_length;j++)
|
{ if (j%16==0)printf("\n");
|
{ if (j%16==0)printf("\n");
|
else if (j%8==0) printf(" ");
|
else if (j%8==0) printf(" ");
|
printf("%.2x ", eth->tx_buff[j]);
|
printf("%.2x ", eth->tx_buff[j]);
|
}
|
}
|
printf("\nend packet:\n");
|
printf("\nend packet:\n");
|
*/
|
#endif
|
nwritten = write (eth->rtx_fd, eth->tx_buff, eth->tx.packet_length);
|
nwritten = write (eth->rtx_fd, eth->tx_buff, eth->tx.packet_length);
|
break;
|
break;
|
}
|
}
|
|
|
/* set BD status */
|
/* set BD status */
|
Line 325... |
Line 332... |
CLEAR_FLAG (eth->tx.bd, ETH_TX_BD, READY);
|
CLEAR_FLAG (eth->tx.bd, ETH_TX_BD, READY);
|
CLEAR_FLAG (eth->tx.bd, ETH_TX_BD, COLLISION);
|
CLEAR_FLAG (eth->tx.bd, ETH_TX_BD, COLLISION);
|
SET_FLAG (eth->regs.int_source, ETH_INT_SOURCE, TXE);
|
SET_FLAG (eth->regs.int_source, ETH_INT_SOURCE, TXE);
|
|
|
eth->tx.state = ETH_TXSTATE_WAIT4BD;
|
eth->tx.state = ETH_TXSTATE_WAIT4BD;
|
|
|
}
|
}
|
|
|
eth->regs.bd_ram[eth->tx.bd_index] = eth->tx.bd;
|
eth->regs.bd_ram[eth->tx.bd_index] = eth->tx.bd;
|
|
|
|
SET_FLAG (eth->regs.int_source, ETH_INT_SOURCE, TXB);
|
|
|
/* generate OK interrupt */
|
/* generate OK interrupt */
|
if (TEST_FLAG (eth->regs.int_mask, ETH_INT_MASK, TXE_M) ||
|
if (TEST_FLAG (eth->regs.int_mask, ETH_INT_MASK, TXE_M) ||
|
TEST_FLAG (eth->regs.int_mask, ETH_INT_MASK, TXB_M))
|
TEST_FLAG (eth->regs.int_mask, ETH_INT_MASK, TXB_M))
|
{
|
{
|
if (TEST_FLAG (eth->tx.bd, ETH_TX_BD, IRQ))
|
if (TEST_FLAG (eth->tx.bd, ETH_TX_BD, IRQ) && !eth->int_line_stat)
|
{
|
{
|
//printf ("ETH_TXSTATE_TRANSMIT interrupt\n");
|
#if ETH_DEBUG
|
|
printf ("ETH_TXSTATE_TRANSMIT interrupt\n");
|
|
#endif
|
report_interrupt (eth->mac_int);
|
report_interrupt (eth->mac_int);
|
|
eth->int_line_stat = 1;
|
}
|
}
|
}
|
}
|
|
|
/* advance to next BD */
|
/* advance to next BD */
|
if (bAdvance)
|
if (bAdvance)
|
Line 354... |
Line 367... |
|
|
break;
|
break;
|
}
|
}
|
|
|
/* Reschedule */
|
/* Reschedule */
|
|
if (eth->tx.state == ETH_TXSTATE_WAIT4BD)
|
|
SCHED_ADD (eth_controller_tx_clock, dat, 10);
|
|
else
|
SCHED_ADD (eth_controller_tx_clock, dat, 1);
|
SCHED_ADD (eth_controller_tx_clock, dat, 1);
|
}
|
}
|
|
|
/* ========================================================================= */
|
/* ========================================================================= */
|
|
|
Line 413... |
Line 429... |
{
|
{
|
eth->rx.fd = eth->rxfd;
|
eth->rx.fd = eth->rxfd;
|
eth->rx.offset = 0;
|
eth->rx.offset = 0;
|
}
|
}
|
eth->rx.state = ETH_RXSTATE_RECV;
|
eth->rx.state = ETH_RXSTATE_RECV;
|
//printf("rx_clk: going to ETH_RXSTATE_RECV\n");
|
|
}
|
}
|
else if (!TEST_FLAG (eth->regs.moder, ETH_MODER, RXEN))
|
else if (!TEST_FLAG (eth->regs.moder, ETH_MODER, RXEN))
|
{
|
{
|
eth->rx.state = ETH_RXSTATE_IDLE;
|
eth->rx.state = ETH_RXSTATE_IDLE;
|
}
|
}
|
Line 449... |
Line 465... |
}
|
}
|
else if (nread > 0)
|
else if (nread > 0)
|
{
|
{
|
SET_FLAG (eth->regs.int_source, ETH_INT_SOURCE, BUSY);
|
SET_FLAG (eth->regs.int_source, ETH_INT_SOURCE, BUSY);
|
|
|
if (TEST_FLAG (eth->regs.int_mask, ETH_INT_MASK, BUSY_M))
|
if (TEST_FLAG (eth->regs.int_mask, ETH_INT_MASK, BUSY_M) &&
|
|
!eth->int_line_stat)
|
{
|
{
|
printf ("ETH_RXSTATE_WAIT4BD BUSY interrupt\n");
|
printf ("ETH_RXSTATE_WAIT4BD BUSY interrupt\n");
|
report_interrupt (eth->mac_int);
|
report_interrupt (eth->mac_int);
|
|
eth->int_line_stat = 1;
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
Line 519... |
Line 537... |
"Warning: Poll of RXTATE_RECV failed %s: ignored.\n",
|
"Warning: Poll of RXTATE_RECV failed %s: ignored.\n",
|
strerror (errno));
|
strerror (errno));
|
}
|
}
|
else if ((n > 0) && ((fds[0].revents & POLLIN) == POLLIN))
|
else if ((n > 0) && ((fds[0].revents & POLLIN) == POLLIN))
|
{
|
{
|
//printf ("Reading TAP. ");
|
#if ETH_DEBUG
|
|
printf ("Reading TAP. ");
|
|
#endif
|
nread = read (eth->rtx_fd, eth->rx_buff, ETH_MAXPL);
|
nread = read (eth->rtx_fd, eth->rx_buff, ETH_MAXPL);
|
//printf ("%d bytes read.\n",(int) nread);
|
#if ETH_DEBUG
|
|
printf ("%d bytes read.\n",(int) nread);
|
|
#endif
|
if (nread < 0)
|
if (nread < 0)
|
{
|
{
|
fprintf (stderr,
|
fprintf (stderr,
|
"Warning: Read of RXTATE_RECV failed %s: ignored\n",
|
"Warning: Read of RXTATE_RECV failed %s: ignored\n",
|
strerror (errno));
|
strerror (errno));
|
|
|
if (TEST_FLAG (eth->regs.int_mask, ETH_INT_MASK, RXE_M))
|
|
{
|
|
SET_FLAG (eth->regs.int_source, ETH_INT_SOURCE, RXE);
|
SET_FLAG (eth->regs.int_source, ETH_INT_SOURCE, RXE);
|
|
|
|
if (TEST_FLAG (eth->regs.int_mask, ETH_INT_MASK, RXE_M) &&
|
|
!eth->int_line_stat)
|
|
{
|
printf ("ETH_RXTATE_RECV RXE interrupt\n");
|
printf ("ETH_RXTATE_RECV RXE interrupt\n");
|
report_interrupt (eth->mac_int);
|
report_interrupt (eth->mac_int);
|
|
eth->int_line_stat = 1;
|
}
|
}
|
}
|
}
|
|
|
}
|
}
|
|
|
Line 562... |
Line 587... |
(eth->rx_buff[1] != 0xff) ) ||
|
(eth->rx_buff[1] != 0xff) ) ||
|
((eth->mac_address[0] != eth->rx_buff[5]) &&
|
((eth->mac_address[0] != eth->rx_buff[5]) &&
|
(eth->rx_buff[0] != 0xff)))
|
(eth->rx_buff[0] != 0xff)))
|
|
|
{
|
{
|
/*
|
#if ETH_DEBUG
|
printf("ETH_RXSTATE dropping packet for %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
|
printf("ETH_RXSTATE dropping packet for %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
|
eth->rx_buff[0],
|
eth->rx_buff[0],
|
eth->rx_buff[1],
|
eth->rx_buff[1],
|
eth->rx_buff[2],
|
eth->rx_buff[2],
|
eth->rx_buff[3],
|
eth->rx_buff[3],
|
eth->rx_buff[4],
|
eth->rx_buff[4],
|
eth->rx_buff[5]);
|
eth->rx_buff[5]);
|
*/
|
#endif
|
break;
|
break;
|
}
|
}
|
}
|
}
|
|
|
eth->rx.packet_length = nread;
|
eth->rx.packet_length = nread;
|
Line 589... |
Line 614... |
break;
|
break;
|
}
|
}
|
break;
|
break;
|
|
|
case ETH_RXSTATE_WRITEFIFO:
|
case ETH_RXSTATE_WRITEFIFO:
|
//printf("ETH_RXSTATE_WRITEFIFO: writing to %d bytes 0x%.8x\n",(int)eth->rx.bytes_left, (unsigned int)eth->rx.bd_addr);
|
#if ETH_DEBUG
|
|
printf("ETH_RXSTATE_WRITEFIFO: writing to RXBD%d: %d bytes @ 0x%.8x\n",
|
|
(int) eth->rx.bd_index/2, (int)eth->rx.bytes_left,
|
|
(unsigned int)eth->rx.bd_addr);
|
|
#endif
|
if (eth->rx.bytes_left > 0){
|
if (eth->rx.bytes_left > 0){
|
while((int) eth->rx.bytes_left){
|
while((int) eth->rx.bytes_left){
|
send_word = ((unsigned long) eth->rx_buff[eth->rx.bytes_read] << 24) |
|
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 + 1] << 16) |
|
((unsigned long) eth->rx_buff[eth->rx.bytes_read + 2] << 8) |
|
((unsigned long) eth->rx_buff[eth->rx.bytes_read + 2] << 8) |
|
Line 611... |
Line 640... |
eth->rx.bytes_left = 0;
|
eth->rx.bytes_left = 0;
|
}
|
}
|
}
|
}
|
|
|
}
|
}
|
//printf("ETH_RXSTATE_WRITEFIFO: bytes read: 0x%.8x\n",(unsigned int)eth->rx.bytes_read);
|
#if ETH_DEBUG
|
|
printf("ETH_RXSTATE_WRITEFIFO: bytes read: 0x%.8x\n",
|
|
(unsigned int)eth->rx.bytes_read);
|
|
#endif
|
if (eth->rx.bytes_left <= 0)
|
if (eth->rx.bytes_left <= 0)
|
{
|
{
|
/* Write result to bd */
|
/* Write result to bd */
|
SET_FIELD (eth->rx.bd, ETH_RX_BD, LENGTH, eth->rx.packet_length+4);
|
SET_FIELD (eth->rx.bd, ETH_RX_BD, LENGTH, eth->rx.packet_length+4);
|
CLEAR_FLAG (eth->rx.bd, ETH_RX_BD, READY);
|
CLEAR_FLAG (eth->rx.bd, ETH_RX_BD, READY);
|
Line 635... |
Line 667... |
|| eth->rx.bd_index >= ETH_BD_COUNT)
|
|| eth->rx.bd_index >= ETH_BD_COUNT)
|
eth->rx.bd_index = eth->regs.tx_bd_num << 1;
|
eth->rx.bd_index = eth->regs.tx_bd_num << 1;
|
else
|
else
|
eth->rx.bd_index += 2;
|
eth->rx.bd_index += 2;
|
|
|
|
SET_FLAG (eth->regs.int_source, ETH_INT_SOURCE, RXB);
|
|
|
if ((TEST_FLAG (eth->regs.int_mask, ETH_INT_MASK, RXB_M)) &&
|
if ((TEST_FLAG (eth->regs.int_mask, ETH_INT_MASK, RXB_M)) &&
|
(TEST_FLAG (eth->rx.bd, ETH_RX_BD, IRQ)))
|
(TEST_FLAG (eth->rx.bd, ETH_RX_BD, IRQ)) &&
|
|
!eth->int_line_stat)
|
{
|
{
|
//printf ("ETH_RXSTATE_WRITEFIFO interrupt\n");
|
#if ETH_DEBUG
|
|
printf ("ETH_RXSTATE_WRITEFIFO interrupt\n");
|
|
#endif
|
report_interrupt (eth->mac_int);
|
report_interrupt (eth->mac_int);
|
|
eth->int_line_stat = 1;
|
}
|
}
|
|
|
/* ready to receive next packet */
|
/* ready to receive next packet */
|
eth->rx.state = ETH_RXSTATE_IDLE;
|
eth->rx.state = ETH_RXSTATE_IDLE;
|
}
|
}
|
break;
|
break;
|
}
|
}
|
|
|
/* Reschedule */
|
/* Reschedule */
|
|
if (eth->rx.state == ETH_RXSTATE_RECV)
|
|
SCHED_ADD (eth_controller_rx_clock, dat, 10);
|
|
else
|
SCHED_ADD (eth_controller_rx_clock, dat, 1);
|
SCHED_ADD (eth_controller_rx_clock, dat, 1);
|
}
|
}
|
|
|
/* ========================================================================= */
|
/* ========================================================================= */
|
/* Move to next RX BD */
|
/* Move to next RX BD */
|
Line 715... |
Line 756... |
eth_reset (void *dat)
|
eth_reset (void *dat)
|
{
|
{
|
struct eth_device *eth = dat;
|
struct eth_device *eth = dat;
|
struct ifreq ifr;
|
struct ifreq ifr;
|
|
|
|
#if ETH_DEBUG
|
printf ("Resetting Ethernet\n");
|
printf ("Resetting Ethernet\n");
|
|
#endif
|
/* Nothing to do if we do not have a base address set.
|
/* Nothing to do if we do not have a base address set.
|
|
|
TODO: Surely this should test for being enabled? */
|
TODO: Surely this should test for being enabled? */
|
if (0 == eth->baseaddr)
|
if (0 == eth->baseaddr)
|
{
|
{
|
Line 798... |
Line 840... |
strerror (errno));
|
strerror (errno));
|
close (eth->rtx_fd);
|
close (eth->rtx_fd);
|
eth->rtx_fd = 0;
|
eth->rtx_fd = 0;
|
return;
|
return;
|
}
|
}
|
|
#if ETH_DEBUG
|
PRINTF ("Opened TAP %s\n", ifr.ifr_name);
|
PRINTF ("Opened TAP %s\n", ifr.ifr_name);
|
|
#endif
|
/* Do we need to flush any packets? */
|
/* Do we need to flush any packets? */
|
break;
|
break;
|
}
|
}
|
|
|
/* Set registers to default values */
|
/* Set registers to default values */
|
Line 825... |
Line 867... |
|
|
/* Reset TX/RX BD indexes */
|
/* Reset TX/RX BD indexes */
|
eth->tx.bd_index = 0;
|
eth->tx.bd_index = 0;
|
eth->rx.bd_index = eth->regs.tx_bd_num << 1;
|
eth->rx.bd_index = eth->regs.tx_bd_num << 1;
|
|
|
|
/* Reset IRQ line status */
|
|
eth->int_line_stat = 0;
|
|
|
/* Initialize VAPI */
|
/* Initialize VAPI */
|
if (eth->base_vapi_id)
|
if (eth->base_vapi_id)
|
{
|
{
|
vapi_install_multi_handler (eth->base_vapi_id, ETH_NUM_VAPI_IDS,
|
vapi_install_multi_handler (eth->base_vapi_id, ETH_NUM_VAPI_IDS,
|
eth_vapi_read, dat);
|
eth_vapi_read, dat);
|
Line 949... |
Line 994... |
struct eth_device *eth = dat;
|
struct eth_device *eth = dat;
|
|
|
switch (addr)
|
switch (addr)
|
{
|
{
|
case ETH_MODER:
|
case ETH_MODER:
|
|
#if ETH_DEBUG
|
|
printf("eth_write32: MODER 0x%x\n",value);
|
|
#endif
|
if (!TEST_FLAG (eth->regs.moder, ETH_MODER, RXEN) &&
|
if (!TEST_FLAG (eth->regs.moder, ETH_MODER, RXEN) &&
|
TEST_FLAG (value, ETH_MODER, RXEN))
|
TEST_FLAG (value, ETH_MODER, RXEN))
|
{
|
{
|
// Reset RX BD index
|
// Reset RX BD index
|
eth->rx.bd_index = eth->regs.tx_bd_num << 1;
|
eth->rx.bd_index = eth->regs.tx_bd_num << 1;
|
|
|
|
// Clear TAP
|
|
{
|
|
/* Poll to see if there is data to read */
|
|
struct pollfd fds[1];
|
|
int n;
|
|
int nread;
|
|
|
|
fds[0].fd = eth->rtx_fd;
|
|
fds[0].events = POLLIN;
|
|
|
|
do {
|
|
n = poll (fds, 1, 0);
|
|
if (n < 0)
|
|
{
|
|
fprintf (stderr, "Warning: Poll in while emptying TAP: %s: ignored.\n",
|
|
strerror (errno));
|
|
}
|
|
else if ((n > 0) && ((fds[0].revents & POLLIN) == POLLIN))
|
|
{
|
|
nread = read (eth->rtx_fd, eth->rx_buff, ETH_MAXPL);
|
|
|
|
if (nread < 0)
|
|
{
|
|
fprintf (stderr,
|
|
"Warning: Read failed %s: ignored\n",
|
|
strerror (errno));
|
|
}
|
|
}
|
|
} while (n > 0);
|
|
}
|
|
|
SCHED_ADD (eth_controller_rx_clock, dat, 1);
|
SCHED_ADD (eth_controller_rx_clock, dat, 1);
|
}
|
}
|
else if (!TEST_FLAG (value, ETH_MODER, RXEN))
|
else if (!TEST_FLAG (value, ETH_MODER, RXEN) &&
|
|
TEST_FLAG (eth->regs.moder, ETH_MODER, RXEN))
|
SCHED_FIND_REMOVE (eth_controller_rx_clock, dat);
|
SCHED_FIND_REMOVE (eth_controller_rx_clock, dat);
|
|
|
if (!TEST_FLAG (eth->regs.moder, ETH_MODER, TXEN) &&
|
if (!TEST_FLAG (eth->regs.moder, ETH_MODER, TXEN) &&
|
TEST_FLAG (value, ETH_MODER, TXEN))
|
TEST_FLAG (value, ETH_MODER, TXEN))
|
{
|
{
|
eth->tx.bd_index = 0;
|
eth->tx.bd_index = 0;
|
SCHED_ADD (eth_controller_tx_clock, dat, 1);
|
SCHED_ADD (eth_controller_tx_clock, dat, 1);
|
}
|
}
|
else if (!TEST_FLAG (value, ETH_MODER, TXEN))
|
else if (!TEST_FLAG (value, ETH_MODER, TXEN) &&
|
|
TEST_FLAG (eth->regs.moder, ETH_MODER, TXEN))
|
SCHED_FIND_REMOVE (eth_controller_tx_clock, dat);
|
SCHED_FIND_REMOVE (eth_controller_tx_clock, dat);
|
|
|
eth->regs.moder = value;
|
eth->regs.moder = value;
|
|
|
if (TEST_FLAG (value, ETH_MODER, RST))
|
if (TEST_FLAG (value, ETH_MODER, RST))
|
eth_reset (dat);
|
eth_reset (dat);
|
return;
|
return;
|
case ETH_INT_SOURCE:
|
case ETH_INT_SOURCE:
|
// Clear interrupt if all interrupt sources have been dealt with
|
#if ETH_DEBUG
|
|
printf("eth_write32: INT_SOURCE 0x%x\n",value);
|
|
#endif
|
eth->regs.int_source &= ~value;
|
eth->regs.int_source &= ~value;
|
if (!eth->regs.int_source)
|
|
|
// Clear IRQ line if all interrupt sources have been dealt with
|
|
if (!(eth->regs.int_source & eth->regs.int_mask) && eth->int_line_stat)
|
|
{
|
clear_interrupt (eth->mac_int);
|
clear_interrupt (eth->mac_int);
|
|
eth->int_line_stat = 0;
|
|
}
|
|
|
return;
|
return;
|
case ETH_INT_MASK:
|
case ETH_INT_MASK:
|
|
#if ETH_DEBUG
|
|
printf("eth_write32: INT_MASK 0x%x\n",value);
|
|
#endif
|
eth->regs.int_mask = value;
|
eth->regs.int_mask = value;
|
if (eth->regs.int_source & eth->regs.int_mask)
|
if ((eth->regs.int_source & eth->regs.int_mask) && !eth->int_line_stat)
|
report_interrupt (eth->mac_int);
|
report_interrupt (eth->mac_int);
|
else
|
else
|
|
if (eth->int_line_stat)
|
|
{
|
clear_interrupt (eth->mac_int);
|
clear_interrupt (eth->mac_int);
|
|
eth->int_line_stat = 0;
|
|
}
|
return;
|
return;
|
case ETH_IPGT:
|
case ETH_IPGT:
|
eth->regs.ipgt = value;
|
eth->regs.ipgt = value;
|
return;
|
return;
|
case ETH_IPGR1:
|
case ETH_IPGR1:
|
Line 1512... |
Line 1607... |
|
|
new->enabled = 1;
|
new->enabled = 1;
|
new->baseaddr = 0;
|
new->baseaddr = 0;
|
new->dma = 0;
|
new->dma = 0;
|
new->mac_int = 0;
|
new->mac_int = 0;
|
|
new->int_line_stat= 0;
|
new->rtx_type = ETH_RTX_FILE;
|
new->rtx_type = ETH_RTX_FILE;
|
new->rx_channel = 0;
|
new->rx_channel = 0;
|
new->tx_channel = 0;
|
new->tx_channel = 0;
|
new->rtx_fd = 0;
|
new->rtx_fd = 0;
|
new->rxfile = strdup ("eth_rx");
|
new->rxfile = strdup ("eth_rx");
|