Line 14... |
Line 14... |
int tx_full;
|
int tx_full;
|
int rx_next; /* Next buffer to be checked for new packet and given to the user */
|
int rx_next; /* Next buffer to be checked for new packet and given to the user */
|
void (*receive)(volatile unsigned char *add, int len); /* Pointer to function to be called
|
void (*receive)(volatile unsigned char *add, int len); /* Pointer to function to be called
|
when frame is received */
|
when frame is received */
|
|
|
|
unsigned long eth_data[((ETH_TXBD_NUM + ETH_RXBD_NUM) * ETH_MAXBUF_LEN)/4] = {0};
|
|
#undef ETH_DATA_BASE
|
|
#define ETH_DATA_BASE ((unsigned long)eth_data)
|
|
|
static void
|
static void
|
print_packet(unsigned long add, int len)
|
print_packet(unsigned long add, int len)
|
{
|
{
|
int i;
|
int i;
|
|
|
Line 38... |
Line 42... |
bd = (eth_bd *)ETH_BD_BASE;
|
bd = (eth_bd *)ETH_BD_BASE;
|
|
|
for(i = 0; i < ETH_TXBD_NUM; i++){
|
for(i = 0; i < ETH_TXBD_NUM; i++){
|
|
|
/* Set Tx BD status */
|
/* Set Tx BD status */
|
bd[i].status = ETH_TX_BD_PAD | ETH_TX_BD_CRC | ETH_RX_BD_IRQ;
|
bd[i].len_status = 0 << 16 | ETH_TX_BD_PAD | ETH_TX_BD_CRC | ETH_RX_BD_IRQ;
|
|
|
/* Initialize Tx buffer pointer */
|
/* Initialize Tx buffer pointer */
|
bd[i].addr = ETH_DATA_BASE + (i * ETH_MAXBUF_LEN);
|
bd[i].addr = ETH_DATA_BASE + (i * ETH_MAXBUF_LEN);
|
}
|
}
|
|
|
bd[i-1].status |= ETH_TX_BD_WRAP; // Last Tx BD - Wrap
|
bd[i-1].len_status |= ETH_TX_BD_WRAP; // Last Tx BD - Wrap
|
}
|
}
|
|
|
void init_rx_bd_pool(void)
|
void init_rx_bd_pool(void)
|
{
|
{
|
eth_bd *bd;
|
eth_bd *bd;
|
Line 57... |
Line 61... |
bd = (eth_bd *)ETH_BD_BASE + ETH_TXBD_NUM;
|
bd = (eth_bd *)ETH_BD_BASE + ETH_TXBD_NUM;
|
|
|
for(i = 0; i < ETH_RXBD_NUM; i++){
|
for(i = 0; i < ETH_RXBD_NUM; i++){
|
|
|
/* Set Rx BD status */
|
/* Set Rx BD status */
|
bd[i].status = ETH_RX_BD_EMPTY | ETH_RX_BD_IRQ;
|
bd[i].len_status = 0 << 16 | ETH_RX_BD_EMPTY | ETH_RX_BD_IRQ;
|
|
|
/* Initialize Rx buffer pointer */
|
/* Initialize Rx buffer pointer */
|
bd[i].addr = ETH_DATA_BASE + ((ETH_TXBD_NUM + i) * ETH_MAXBUF_LEN);
|
bd[i].addr = ETH_DATA_BASE + ((ETH_TXBD_NUM + i) * ETH_MAXBUF_LEN);
|
}
|
}
|
|
|
bd[i-1].status |= ETH_TX_BD_WRAP; // Last Rx BD - Wrap
|
bd[i-1].len_status |= ETH_TX_BD_WRAP; // Last Rx BD - Wrap
|
}
|
}
|
|
|
void eth_init (void (*rec)(volatile unsigned char *, int))
|
void eth_init (void (*rec)(volatile unsigned char *, int))
|
{
|
{
|
|
|
Line 153... |
Line 157... |
if(tx_full)
|
if(tx_full)
|
return (void *)0;
|
return (void *)0;
|
|
|
bd = (eth_bd *)ETH_BD_BASE;
|
bd = (eth_bd *)ETH_BD_BASE;
|
|
|
if(bd[tx_next].status & ETH_TX_BD_READY)
|
if(bd[tx_next].len_status & ETH_TX_BD_READY)
|
return (void *)0;
|
return (void *)0;
|
|
|
add = bd[tx_next].addr;
|
add = bd[tx_next].addr;
|
|
|
tx_next = (tx_next + 1) & ETH_TXBD_NUM_MASK;
|
tx_next = (tx_next + 1) & ETH_TXBD_NUM_MASK;
|
Line 174... |
Line 178... |
eth_bd *bd;
|
eth_bd *bd;
|
|
|
bd = (eth_bd *)ETH_BD_BASE;
|
bd = (eth_bd *)ETH_BD_BASE;
|
|
|
bd[tx_last].addr = (unsigned long)buf;
|
bd[tx_last].addr = (unsigned long)buf;
|
bd[tx_last].len = len;
|
bd[tx_last].len_status &= 0x0000ffff & ~ETH_TX_BD_STATS;
|
|
bd[tx_last].len_status |= len << 16 | ETH_TX_BD_READY;
|
bd[tx_last].status &= ~ETH_TX_BD_STATS;
|
|
bd[tx_last].status |= ETH_TX_BD_READY;
|
|
|
|
tx_last = (tx_last + 1) & ETH_TXBD_NUM_MASK;
|
tx_last = (tx_last + 1) & ETH_TXBD_NUM_MASK;
|
tx_full = 0;
|
tx_full = 0;
|
}
|
}
|
|
|
Line 195... |
Line 197... |
|
|
while(1) {
|
while(1) {
|
|
|
int bad = 0;
|
int bad = 0;
|
|
|
if(bd[rx_next].status & ETH_RX_BD_EMPTY)
|
if(bd[rx_next].len_status & ETH_RX_BD_EMPTY)
|
return len;
|
return len;
|
|
|
if(bd[rx_next].status & ETH_RX_BD_OVERRUN) {
|
if(bd[rx_next].len_status & ETH_RX_BD_OVERRUN) {
|
printf("eth rx: ETH_RX_BD_OVERRUN\n");
|
printf("eth rx: ETH_RX_BD_OVERRUN\n");
|
bad = 1;
|
bad = 1;
|
}
|
}
|
if(bd[rx_next].status & ETH_RX_BD_INVSIMB) {
|
if(bd[rx_next].len_status & ETH_RX_BD_INVSIMB) {
|
printf("eth rx: ETH_RX_BD_INVSIMB\n");
|
printf("eth rx: ETH_RX_BD_INVSIMB\n");
|
bad = 1;
|
bad = 1;
|
}
|
}
|
if(bd[rx_next].status & ETH_RX_BD_DRIBBLE) {
|
if(bd[rx_next].len_status & ETH_RX_BD_DRIBBLE) {
|
printf("eth rx: ETH_RX_BD_DRIBBLE\n");
|
printf("eth rx: ETH_RX_BD_DRIBBLE\n");
|
bad = 1;
|
bad = 1;
|
}
|
}
|
if(bd[rx_next].status & ETH_RX_BD_TOOLONG) {
|
if(bd[rx_next].len_status & ETH_RX_BD_TOOLONG) {
|
printf("eth rx: ETH_RX_BD_TOOLONG\n");
|
printf("eth rx: ETH_RX_BD_TOOLONG\n");
|
bad = 1;
|
bad = 1;
|
}
|
}
|
if(bd[rx_next].status & ETH_RX_BD_SHORT) {
|
if(bd[rx_next].len_status & ETH_RX_BD_SHORT) {
|
printf("eth rx: ETH_RX_BD_SHORT\n");
|
printf("eth rx: ETH_RX_BD_SHORT\n");
|
bad = 1;
|
bad = 1;
|
}
|
}
|
if(bd[rx_next].status & ETH_RX_BD_CRCERR) {
|
if(bd[rx_next].len_status & ETH_RX_BD_CRCERR) {
|
printf("eth rx: ETH_RX_BD_CRCERR\n");
|
printf("eth rx: ETH_RX_BD_CRCERR\n");
|
bad = 1;
|
bad = 1;
|
}
|
}
|
if(bd[rx_next].status & ETH_RX_BD_LATECOL) {
|
if(bd[rx_next].len_status & ETH_RX_BD_LATECOL) {
|
printf("eth rx: ETH_RX_BD_LATECOL\n");
|
printf("eth rx: ETH_RX_BD_LATECOL\n");
|
bad = 1;
|
bad = 1;
|
}
|
}
|
|
|
if(!bad) {
|
if(!bad) {
|
receive((void *)bd[rx_next].addr, bd[rx_next].len);
|
receive((void *)bd[rx_next].addr, bd[rx_next].len_status >> 16);
|
len += bd[rx_next].len;
|
len += bd[rx_next].len_status >> 16;
|
}
|
}
|
|
|
bd[rx_next].status &= ~ETH_RX_BD_STATS;
|
bd[rx_next].len_status &= ~ETH_RX_BD_STATS;
|
bd[rx_next].status |= ETH_RX_BD_EMPTY;
|
bd[rx_next].len_status |= ETH_RX_BD_EMPTY;
|
|
|
rx_next = (rx_next + 1) & ETH_RXBD_NUM_MASK;
|
rx_next = (rx_next + 1) & ETH_RXBD_NUM_MASK;
|
}
|
}
|
}
|
}
|
|
|