Line 42... |
Line 42... |
#include <netinet/in.h>
|
#include <netinet/in.h>
|
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
#include <sys/socket.h>
|
#include <sys/socket.h>
|
#include <net/if.h>
|
#include <net/if.h>
|
|
|
#ifdef HAVE_ETH_PHY
|
#if HAVE_ETH_PHY
|
#include <netpacket/packet.h>
|
#include <netpacket/packet.h>
|
#endif /* HAVE_ETH_PHY */
|
#endif /* HAVE_ETH_PHY */
|
|
|
#ifdef HAVE_NET_ETHERNET_H
|
#if HAVE_NET_ETHERNET_H
|
# include <net/ethernet.h>
|
# include <net/ethernet.h>
|
#elif defined(HAVE_SYS_ETHERNET_H)
|
#elif defined(HAVE_SYS_ETHERNET_H)
|
# include <sys/ethernet.h>
|
# include <sys/ethernet.h>
|
#else /* !HAVE_NET_ETHERNET_H && !HAVE_SYS_ETHERNET_H - */
|
#else /* !HAVE_NET_ETHERNET_H && !HAVE_SYS_ETHERNET_H - */
|
#include <sys/types.h>
|
#include <sys/types.h>
|
Line 66... |
Line 66... |
#include "fields.h"
|
#include "fields.h"
|
#include "crc32.h"
|
#include "crc32.h"
|
#include "vapi.h"
|
#include "vapi.h"
|
#include "pic.h"
|
#include "pic.h"
|
#include "sched.h"
|
#include "sched.h"
|
#include "debug.h"
|
|
#include "toplevel-support.h"
|
#include "toplevel-support.h"
|
#include "sim-cmd.h"
|
#include "sim-cmd.h"
|
|
|
/* Address space required by one Ethernet MAC */
|
/* Address space required by one Ethernet MAC */
|
#define ETH_ADDR_SPACE 0x1000
|
#define ETH_ADDR_SPACE 0x1000
|
Line 402... |
Line 401... |
unsigned char tx_buff[ETH_MAXPL];
|
unsigned char tx_buff[ETH_MAXPL];
|
unsigned char lo_buff[ETH_MAXPL];
|
unsigned char lo_buff[ETH_MAXPL];
|
};
|
};
|
|
|
|
|
DEFAULT_DEBUG_CHANNEL (eth);
|
|
|
|
/* simulator interface */
|
/* simulator interface */
|
static void eth_vapi_read (unsigned long id, unsigned long data, void *dat);
|
static void eth_vapi_read (unsigned long id, unsigned long data, void *dat);
|
/* register interface */
|
/* register interface */
|
static void eth_write32 (oraddr_t addr, uint32_t value, void *dat);
|
static void eth_write32 (oraddr_t addr, uint32_t value, void *dat);
|
static uint32_t eth_read32 (oraddr_t addr, void *dat);
|
static uint32_t eth_read32 (oraddr_t addr, void *dat);
|
Line 439... |
Line 436... |
unsigned long read_word;
|
unsigned long read_word;
|
|
|
switch (eth->tx.state)
|
switch (eth->tx.state)
|
{
|
{
|
case ETH_TXSTATE_IDLE:
|
case ETH_TXSTATE_IDLE:
|
TRACE ("TX - entering state WAIT4BD (%ld)\n", eth->tx.bd_index);
|
|
eth->tx.state = ETH_TXSTATE_WAIT4BD;
|
eth->tx.state = ETH_TXSTATE_WAIT4BD;
|
break;
|
break;
|
case ETH_TXSTATE_WAIT4BD:
|
case ETH_TXSTATE_WAIT4BD:
|
/* Read buffer descriptor */
|
/* Read buffer descriptor */
|
eth->tx.bd = eth->regs.bd_ram[eth->tx.bd_index];
|
eth->tx.bd = eth->regs.bd_ram[eth->tx.bd_index];
|
Line 492... |
Line 488... |
eth->tx.crc_dly = 1;
|
eth->tx.crc_dly = 1;
|
else
|
else
|
eth->tx.crc_dly = 0;
|
eth->tx.crc_dly = 0;
|
/* XXX - For now we skip CRC calculation */
|
/* XXX - For now we skip CRC calculation */
|
|
|
TRACE ("Ethernet: Starting TX of %lu 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)
|
if (eth->rtx_type == ETH_RTX_FILE)
|
{
|
{
|
/* write packet length to file */
|
/* write packet length to file */
|
nwritten =
|
nwritten =
|
write (eth->txfd, &(eth->tx.packet_length),
|
write (eth->txfd, &(eth->tx.packet_length),
|
sizeof (eth->tx.packet_length));
|
sizeof (eth->tx.packet_length));
|
}
|
}
|
|
|
/************************************************/
|
/************************************************/
|
/* start transmit with reading packet into FIFO */
|
/* start transmit with reading packet into FIFO */
|
TRACE ("TX - entering state READFIFO\n");
|
|
eth->tx.state = ETH_TXSTATE_READFIFO;
|
eth->tx.state = ETH_TXSTATE_READFIFO;
|
}
|
}
|
|
|
/* stay in this state if (TXEN && !READY) */
|
/* stay in this state if (TXEN && !READY) */
|
break;
|
break;
|
Line 537... |
Line 528... |
eth->tx.bytes_sent += 1;
|
eth->tx.bytes_sent += 1;
|
}
|
}
|
#endif
|
#endif
|
else
|
else
|
{
|
{
|
TRACE ("TX - entering state TRANSMIT\n");
|
|
eth->tx.state = ETH_TXSTATE_TRANSMIT;
|
eth->tx.state = ETH_TXSTATE_TRANSMIT;
|
}
|
}
|
break;
|
break;
|
case ETH_TXSTATE_TRANSMIT:
|
case ETH_TXSTATE_TRANSMIT:
|
/* send packet */
|
/* send packet */
|
Line 563... |
Line 553... |
/* set BD status */
|
/* set BD status */
|
if (nwritten == eth->tx.packet_length)
|
if (nwritten == eth->tx.packet_length)
|
{
|
{
|
CLEAR_FLAG (eth->tx.bd, ETH_TX_BD, READY);
|
CLEAR_FLAG (eth->tx.bd, ETH_TX_BD, READY);
|
SET_FLAG (eth->regs.int_source, ETH_INT_SOURCE, TXB);
|
SET_FLAG (eth->regs.int_source, ETH_INT_SOURCE, TXB);
|
TRACE ("ETH_INT_SOURCE = %0lx\n", eth->regs.int_source);
|
|
|
|
TRACE ("TX - entering state WAIT4BD\n");
|
|
eth->tx.state = ETH_TXSTATE_WAIT4BD;
|
eth->tx.state = ETH_TXSTATE_WAIT4BD;
|
TRACE ("send (%ld)bytes OK\n", nwritten);
|
|
}
|
}
|
else
|
else
|
{
|
{
|
/* XXX - implement retry mechanism here! */
|
/* XXX - implement retry mechanism here! */
|
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);
|
TRACE ("ETH_INT_SOURCE = %0lx\n", eth->regs.int_source);
|
|
|
|
TRACE ("TX - entering state WAIT4BD\n");
|
|
eth->tx.state = ETH_TXSTATE_WAIT4BD;
|
eth->tx.state = ETH_TXSTATE_WAIT4BD;
|
TRACE ("send FAILED!\n");
|
|
}
|
}
|
|
|
eth->regs.bd_ram[eth->tx.bd_index] = eth->tx.bd;
|
eth->regs.bd_ram[eth->tx.bd_index] = eth->tx.bd;
|
|
|
/* generate OK interrupt */
|
/* generate OK interrupt */
|
Line 631... |
Line 615... |
|
|
|
|
switch (eth->rx.state)
|
switch (eth->rx.state)
|
{
|
{
|
case ETH_RXSTATE_IDLE:
|
case ETH_RXSTATE_IDLE:
|
TRACE ("RX - entering state WAIT4BD (%ld)\n", eth->rx.bd_index);
|
|
eth->rx.state = ETH_RXSTATE_WAIT4BD;
|
eth->rx.state = ETH_RXSTATE_WAIT4BD;
|
break;
|
break;
|
|
|
case ETH_RXSTATE_WAIT4BD:
|
case ETH_RXSTATE_WAIT4BD:
|
eth->rx.bd = eth->regs.bd_ram[eth->rx.bd_index];
|
eth->rx.bd = eth->regs.bd_ram[eth->rx.bd_index];
|
Line 651... |
Line 634... |
CLEAR_FLAG (eth->rx.bd, ETH_RX_BD, UVERRUN);
|
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, COLLISION);
|
CLEAR_FLAG (eth->rx.bd, ETH_RX_BD, TOOBIG);
|
CLEAR_FLAG (eth->rx.bd, ETH_RX_BD, TOOBIG);
|
CLEAR_FLAG (eth->rx.bd, ETH_RX_BD, TOOSHORT);
|
CLEAR_FLAG (eth->rx.bd, ETH_RX_BD, TOOSHORT);
|
|
|
TRACE ("Ethernet: Starting RX\n");
|
|
|
|
/* Setup file to read from */
|
/* Setup file to read from */
|
if (TEST_FLAG (eth->regs.moder, ETH_MODER, LOOPBCK))
|
if (TEST_FLAG (eth->regs.moder, ETH_MODER, LOOPBCK))
|
{
|
{
|
eth->rx.fd = eth->txfd;
|
eth->rx.fd = eth->txfd;
|
eth->rx.offset = &(eth->loopback_offset);
|
eth->rx.offset = &(eth->loopback_offset);
|
Line 664... |
Line 645... |
else
|
else
|
{
|
{
|
eth->rx.fd = eth->rxfd;
|
eth->rx.fd = eth->rxfd;
|
eth->rx.offset = 0;
|
eth->rx.offset = 0;
|
}
|
}
|
TRACE ("RX - entering state RECV\n");
|
|
eth->rx.state = ETH_RXSTATE_RECV;
|
eth->rx.state = ETH_RXSTATE_RECV;
|
}
|
}
|
else if (!TEST_FLAG (eth->regs.moder, ETH_MODER, RXEN))
|
else if (!TEST_FLAG (eth->regs.moder, ETH_MODER, RXEN))
|
{
|
{
|
TRACE ("RX - entering state IDLE\n");
|
|
eth->rx.state = ETH_RXSTATE_IDLE;
|
eth->rx.state = ETH_RXSTATE_IDLE;
|
}
|
}
|
else
|
else
|
{
|
{
|
nread =
|
nread =
|
Line 697... |
Line 676... |
(eth, &(eth->rx.packet_length),
|
(eth, &(eth->rx.packet_length),
|
sizeof (eth->rx.packet_length)) <
|
sizeof (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) */
|
/* TODO: just do what real ethernet would do (some kind of error state) */
|
TRACE
|
|
("eth_start_rx(): File does not have a packet ready for RX (len = %ld)\n",
|
|
eth->rx.packet_length);
|
|
sim_done ();
|
sim_done ();
|
break;
|
break;
|
}
|
}
|
|
|
/* Packet must be big enough to hold a header */
|
/* Packet must be big enough to hold a header */
|
if (eth->rx.packet_length < ETHER_HDR_LEN)
|
if (eth->rx.packet_length < ETHER_HDR_LEN)
|
{
|
{
|
TRACE ("eth_start_rx(): Packet too small\n");
|
|
eth_rx_next_packet (eth);
|
eth_rx_next_packet (eth);
|
|
|
TRACE ("RX - entering state WAIT4BD\n");
|
|
eth->rx.state = ETH_RXSTATE_WAIT4BD;
|
eth->rx.state = ETH_RXSTATE_WAIT4BD;
|
break;
|
break;
|
}
|
}
|
|
|
eth->rx.bytes_read = 0;
|
eth->rx.bytes_read = 0;
|
Line 722... |
Line 696... |
|
|
/* for now Read entire packet into memory */
|
/* for now Read entire packet into memory */
|
nread = eth_read_rx_file (eth, eth->rx_buff, eth->rx.bytes_left);
|
nread = eth_read_rx_file (eth, eth->rx_buff, eth->rx.bytes_left);
|
if (nread < eth->rx.bytes_left)
|
if (nread < eth->rx.bytes_left)
|
{
|
{
|
TRACE ("Read %ld from %ld. Error!\n", nread,
|
|
eth->rx.bytes_left);
|
|
eth->rx.error = 1;
|
eth->rx.error = 1;
|
break;
|
break;
|
}
|
}
|
|
|
eth->rx.packet_length = nread;
|
eth->rx.packet_length = nread;
|
eth->rx.bytes_left = nread;
|
eth->rx.bytes_left = nread;
|
eth->rx.bytes_read = 0;
|
eth->rx.bytes_read = 0;
|
|
|
TRACE ("RX - entering state WRITEFIFO\n");
|
|
eth->rx.state = ETH_RXSTATE_WRITEFIFO;
|
eth->rx.state = ETH_RXSTATE_WRITEFIFO;
|
|
|
break;
|
break;
|
|
|
case ETH_RTX_SOCK:
|
case ETH_RTX_SOCK:
|
nread = recv (eth->rtx_sock, eth->rx_buff, ETH_MAXPL, MSG_DONTWAIT);
|
nread = recv (eth->rtx_sock, eth->rx_buff, ETH_MAXPL, MSG_DONTWAIT);
|
|
|
if (nread == 0)
|
if (nread == 0)
|
{
|
{
|
TRACE ("No data read\n");
|
|
break;
|
break;
|
}
|
}
|
else if (nread < 0)
|
else if (nread < 0)
|
{
|
{
|
if (errno != EAGAIN)
|
if (errno != EAGAIN)
|
{
|
{
|
TRACE ("recv() FAILED!\n");
|
|
break;
|
break;
|
}
|
}
|
else
|
else
|
break;
|
break;
|
}
|
}
|
Line 777... |
Line 746... |
|
|
eth->rx.packet_length = nread;
|
eth->rx.packet_length = nread;
|
eth->rx.bytes_left = nread;
|
eth->rx.bytes_left = nread;
|
eth->rx.bytes_read = 0;
|
eth->rx.bytes_read = 0;
|
|
|
TRACE ("RX - entering state WRITEFIFO\n");
|
|
eth->rx.state = ETH_RXSTATE_WRITEFIFO;
|
eth->rx.state = ETH_RXSTATE_WRITEFIFO;
|
|
|
break;
|
break;
|
case ETH_RTX_VAPI:
|
case ETH_RTX_VAPI:
|
break;
|
break;
|
Line 794... |
Line 762... |
((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) |
|
((unsigned long) eth->rx_buff[eth->rx.bytes_read + 3]);
|
((unsigned long) eth->rx_buff[eth->rx.bytes_read + 3]);
|
set_direct32 (eth->rx.bd_addr + eth->rx.bytes_read, send_word, 0, 0);
|
set_direct32 (eth->rx.bd_addr + eth->rx.bytes_read, send_word, 0, 0);
|
/* update counters */
|
/* update counters */
|
TRACE ("Write %ld, left %ld - %08lXd\n", eth->rx.bytes_read,
|
|
eth->rx.bytes_left, send_word);
|
|
eth->rx.bytes_left -= 4;
|
eth->rx.bytes_left -= 4;
|
eth->rx.bytes_read += 4;
|
eth->rx.bytes_read += 4;
|
#else
|
#else
|
set_direct8 (eth->rx.bd_addr + eth->rx.bytes_read,
|
set_direct8 (eth->rx.bd_addr + eth->rx.bytes_read,
|
eth->rx_buff[eth->rx.bytes_read], 0, 0);
|
eth->rx_buff[eth->rx.bytes_read], 0, 0);
|
Line 811... |
Line 777... |
{
|
{
|
/* Write result to bd */
|
/* Write result to bd */
|
SET_FIELD (eth->rx.bd, ETH_RX_BD, LENGTH, eth->rx.packet_length);
|
SET_FIELD (eth->rx.bd, ETH_RX_BD, LENGTH, eth->rx.packet_length);
|
CLEAR_FLAG (eth->rx.bd, ETH_RX_BD, READY);
|
CLEAR_FLAG (eth->rx.bd, ETH_RX_BD, READY);
|
SET_FLAG (eth->regs.int_source, ETH_INT_SOURCE, RXB);
|
SET_FLAG (eth->regs.int_source, ETH_INT_SOURCE, RXB);
|
TRACE ("ETH_INT_SOURCE = %0lx\n", eth->regs.int_source);
|
|
|
|
if (eth->rx.packet_length <
|
if (eth->rx.packet_length <
|
(GET_FIELD (eth->regs.packetlen, ETH_PACKETLEN, MINFL) - 4))
|
(GET_FIELD (eth->regs.packetlen, ETH_PACKETLEN, MINFL) - 4))
|
SET_FLAG (eth->rx.bd, ETH_RX_BD, TOOSHORT);
|
SET_FLAG (eth->rx.bd, ETH_RX_BD, TOOSHORT);
|
if (eth->rx.packet_length >
|
if (eth->rx.packet_length >
|
Line 836... |
Line 801... |
{
|
{
|
report_interrupt (eth->mac_int);
|
report_interrupt (eth->mac_int);
|
}
|
}
|
|
|
/* ready to receive next packet */
|
/* ready to receive next packet */
|
TRACE ("RX - entering state IDLE\n");
|
|
eth->rx.state = ETH_RXSTATE_IDLE;
|
eth->rx.state = ETH_RXSTATE_IDLE;
|
}
|
}
|
break;
|
break;
|
}
|
}
|
|
|
Line 874... |
Line 838... |
{
|
{
|
ssize_t result;
|
ssize_t result;
|
|
|
if (eth->rx.fd <= 0)
|
if (eth->rx.fd <= 0)
|
{
|
{
|
TRACE ("Ethernet: No RX file\n");
|
|
return 0;
|
return 0;
|
}
|
}
|
|
|
if (eth->rx.offset)
|
if (eth->rx.offset)
|
if (lseek (eth->rx.fd, *(eth->rx.offset), SEEK_SET) == (off_t) - 1)
|
if (lseek (eth->rx.fd, *(eth->rx.offset), SEEK_SET) == (off_t) - 1)
|
{
|
{
|
TRACE ("Ethernet: Error seeking RX file\n");
|
|
return 0;
|
return 0;
|
}
|
}
|
|
|
result = read (eth->rx.fd, buf, count);
|
result = read (eth->rx.fd, buf, count);
|
TRACE ("Ethernet: read result = %d \n", result);
|
|
if (eth->rx.offset && result >= 0)
|
if (eth->rx.offset && result >= 0)
|
*(eth->rx.offset) += result;
|
*(eth->rx.offset) += result;
|
|
|
return result;
|
return result;
|
}
|
}
|
Line 940... |
Line 901... |
case ETH_RTX_SOCK:
|
case ETH_RTX_SOCK:
|
/* (Re-)open TX/RX sockets */
|
/* (Re-)open TX/RX sockets */
|
if (eth->rtx_sock != 0)
|
if (eth->rtx_sock != 0)
|
break;
|
break;
|
|
|
TRACE ("RTX opening socket...\n");
|
|
eth->rtx_sock = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL));
|
eth->rtx_sock = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL));
|
if (eth->rtx_sock == -1)
|
if (eth->rtx_sock == -1)
|
{
|
{
|
fprintf (stderr, "Cannot open rtx_sock.\n");
|
fprintf (stderr, "Cannot open rtx_sock.\n");
|
return;
|
return;
|
}
|
}
|
|
|
/* get interface index number */
|
/* get interface index number */
|
TRACE ("RTX getting interface...\n");
|
|
memset (&(eth->ifr), 0, sizeof (eth->ifr));
|
memset (&(eth->ifr), 0, sizeof (eth->ifr));
|
strncpy (eth->ifr.ifr_name, eth->sockif, IFNAMSIZ);
|
strncpy (eth->ifr.ifr_name, eth->sockif, IFNAMSIZ);
|
if (ioctl (eth->rtx_sock, SIOCGIFINDEX, &(eth->ifr)) == -1)
|
if (ioctl (eth->rtx_sock, SIOCGIFINDEX, &(eth->ifr)) == -1)
|
{
|
{
|
fprintf (stderr, "SIOCGIFINDEX failed!\n");
|
fprintf (stderr, "SIOCGIFINDEX failed!\n");
|
return;
|
return;
|
}
|
}
|
TRACE ("RTX Socket Interface : %d\n", eth->ifr.ifr_ifindex);
|
|
|
|
/* Bind to interface... */
|
/* Bind to interface... */
|
TRACE ("Binding to the interface ifindex=%d\n",
|
|
eth->ifr.ifr_ifindex);
|
|
memset (&sll, 0xff, sizeof (sll));
|
memset (&sll, 0xff, sizeof (sll));
|
sll.sll_family = AF_PACKET; /* allways AF_PACKET */
|
sll.sll_family = AF_PACKET; /* allways AF_PACKET */
|
sll.sll_protocol = htons (ETH_P_ALL);
|
sll.sll_protocol = htons (ETH_P_ALL);
|
sll.sll_ifindex = eth->ifr.ifr_ifindex;
|
sll.sll_ifindex = eth->ifr.ifr_ifindex;
|
if (bind (eth->rtx_sock, (struct sockaddr *) &sll, sizeof (sll)) ==
|
if (bind (eth->rtx_sock, (struct sockaddr *) &sll, sizeof (sll)) ==
|
Line 974... |
Line 930... |
fprintf (stderr, "Error bind().\n");
|
fprintf (stderr, "Error bind().\n");
|
return;
|
return;
|
}
|
}
|
|
|
/* first, flush all received packets. */
|
/* first, flush all received packets. */
|
TRACE ("Flush");
|
|
do
|
do
|
{
|
{
|
fd_set fds;
|
fd_set fds;
|
struct timeval t;
|
struct timeval t;
|
|
|
TRACE (".");
|
|
FD_ZERO (&fds);
|
FD_ZERO (&fds);
|
FD_SET (eth->rtx_sock, &fds);
|
FD_SET (eth->rtx_sock, &fds);
|
memset (&t, 0, sizeof (t));
|
memset (&t, 0, sizeof (t));
|
j = select (FD_SETSIZE, &fds, NULL, NULL, &t);
|
j = select (FD_SETSIZE, &fds, NULL, NULL, &t);
|
if (j > 0)
|
if (j > 0)
|
recv (eth->rtx_sock, eth->rx_buff, j, 0);
|
recv (eth->rtx_sock, eth->rx_buff, j, 0);
|
}
|
}
|
while (j);
|
while (j);
|
TRACE ("\n");
|
|
|
|
break;
|
break;
|
#else /* HAVE_ETH_PHY */
|
#else /* HAVE_ETH_PHY */
|
case ETH_RTX_SOCK:
|
case ETH_RTX_SOCK:
|
fprintf (stderr,
|
fprintf (stderr,
|
Line 1253... |
Line 1206... |
unsigned long which;
|
unsigned long which;
|
struct eth_device *eth = dat;
|
struct eth_device *eth = dat;
|
|
|
which = id - eth->base_vapi_id;
|
which = id - eth->base_vapi_id;
|
|
|
TRACE ("ETH: id %08lx, data %08lx\n", id, data);
|
|
|
|
if (!eth)
|
if (!eth)
|
{
|
{
|
TRACE ("ETH: VAPI ID %08lx is not ours!\n", id);
|
|
return;
|
return;
|
}
|
}
|
|
|
switch (which)
|
switch (which)
|
{
|
{
|