Hi again
I have been analyzing the fec_isr routine and have come across something that puzzles me.
In the receive logic section the isr first declares an rxpkt, then increments some fecstats counters. It then checks for receive errors. If there are no errors a new packet is declared for the receive ring and the variables:
int bd2, len;
BD *bdp2;
Then there is a check to see if the frame is spread over two buffers. In my case it isn't. So the consequent code is not executed. The next runable section checks to see if variable len is lilbufsiz to see whether to allocate a big or small buffer.
Where is variable len set?
Am I missing something?
Thanks
Kyle
see code below:
else /* we received a good BD */
{
PACKET pkt; /* new packet for receive ring */
int bd2, len;
BD *bdp2;
//putchar('*');
bd2 = next_rxbd;
if ((bdp->bd_cstatus & MCF_FEC_RxBD_L) == 0)
{
/* All frames should fit in a single BD. If they
* don't, i.e. RxBD_L is not set, the rest of the
* frame is in the next BD(s), so just combine them. */
do
{
putchar('2');
if ((bd2 = bd2 + 1) >= NUM_RXBDS)
bd2 -= NUM_RXBDS;
bdp2 = &RxBDs[bd2];
if ((bdp2->bd_cstatus & MCF_FEC_RxBD_E) == 0)
{
len = bdp2->bd_length;
/* last BD length is total frame length */
if (bdp2->bd_cstatus & MCF_FEC_RxBD_L)
len -= bdp->bd_length;
if (bdp->bd_length + len = MAX_ETH_PKT)
{
rx_copies++;
/* append the data to the first BD */
MEMCPY((void *)(bdp->bd_addr + bdp->bd_length),
(void *)bdp2->bd_addr, len);
bdp->bd_length += len;
bdp->bd_cstatus = (bdp2->bd_cstatus & ~MCF_FEC_RxBD_W) |
(bdp->bd_cstatus & MCF_FEC_RxBD_W);
bdp2->bd_cstatus |= 0x0400; /* unused bit */
}
else /* too much data to copy */
{
/* TODO: increment some error counter */
putchar('E');
goto next_recv;
}
}
else
{
/* TODO: increment some error counter */
putchar('e');
goto next_recv;
}
}
while ((bdp2->bd_cstatus & MCF_FEC_RxBD_L) == 0);
}
/* First, get a fresh packet for rx ring. If we can't get one then
* we have to dump the current packet by leaving it in the ring,
* since the FEC won't let us have an empty ring entry.
*/
/* If we can fit this packet into a little buffer, then get one
* and copy the packet. This slows performance a bit, but helps
* preserve big buffers in memory-tight systems.
*/
if ((len lilbufsiz) &&
((pkt = pk_alloc(bdp->bd_length)) != NULL))
{
/* copy received data into newly alloced small packet. Leave the
* big packet in the FEC ring BD, and plug the small packet's address
* into the rxpkt variable.
*/
putchar('l');
MEMCPY(pkt->nb_buff, (void*)bdp->bd_addr, bdp->bd_length);
rxpkt = pkt; /* put little pkt in local variable */
rxpkt->net = nets[fec_iface]; /* install net in rxpkt */
input_ippkt(rxpkt, bdp->bd_length); /* pass to IP stack */
}
Message Edited by wyliek on 2007-03-0201:29 PM
Message Edited by wyliek on 2007-03-0201:29 PM