Hi there, I am _still_ working on an uClinux Ethernet driver on the NiosII on a Cyclone2. It is similar to the DM9000 driver.
I have finally got the receive function working correctly, but it seems to have an intermittent problem, after receiving a number of frames successfully, the kernel crashes.
If I remove "netif_rx(skb)" the error does not occur. Are the upper layers not handling my frames properly? Are my frames some how malformed and therefore creating a problem when the reach the higher layers of the TCP/IP stack?
In the last few trials I did, when it crashes it happens after 3, 20, 143, 14, 2, 10 packets were received. I then get the error:
Quote:
Bad page state in process 'swapper'
page:48be64e2 flags:0x41fd0000 mapping:00000000 mapcount:12477673 count:0
Trying to fix it up, but a reboot is needed
Backtrace:
Stack from 009bfe6c:<0>
<0> 00000001<0> 00840c90<0> 41fd0000<0> 00000000<0> 00be64e9<0> 00000000<0> 48be64e2<0> 00843a18<0>
<0> 00000400<0> 00c25000<0> 009af7b4<0> 00ed7a00<0> 48be64e2<0> 00843ae0<0> 00847280<0> 00000305<0>
<0> 009093e8<0> 00ed7a00<0> 009af79c<0> 009091ac<0> 00ed7a00<0> 009091cc<0> 00ed7a00<0> 009092ac<0>
<0> 00912e10<0> 009b6594<0> 009af780<0> 00000040<0> ffffe282<0> 009af768<0> 00000001<0> 009af768<0>
<0> 00912ed4<0> 009b6594<0> ffffe282<0> 009af774<0> 009af788<0> 0000012c<0> 00000000<0> 00000040<0>
<0> 009af780<0> 009130b8<0> deadbeef<0> deadbeef<0> 009ab3e8<0> 0000000a<0> 00000001<0> 009b7810<0>
Call Trace:<0>
<0> [<00815dd8>]<0> [<00815ebc>]<0> [<008161b8>]<0> [<008014a4>]<0>
<0> [<008009cc>]<0> [<00801bf4>]<0> [<00801bfc>]<0> [<009872ac>]<0>
<0> [<008000a4>]<0>
Bad page state in process 'swapper'
page:98bb0681 flags:0x00000018 mapping:00cc8408 mapcount:0 count:0
Trying to fix it up, but a reboot is needed
Backtrace:
Stack from 009bfe6c:<0>
<0> 00000001<0> 00840c90<0> 00000018<0> 00cc8408<0> 00000000<0> 00000000<0> 98bb0681<0> 00843a18<0>
<0> 00000400<0> 00c25000<0> 009af7b4<0> 00ed7a00<0> 98bb0681<0> 00843ae0<0> 00847280<0> 00000382<0>
<0> 009093e8<0> 00ed7a00<0> 009af79c<0> 009091ac<0> 00ed7a00<0> 009091cc<0> 00ed7a00<0> 009092ac<0>
<0> 00912e10<0> 009b6594<0> 009af780<0> 00000040<0> ffffe282<0> 009af768<0> 00000001<0> 009af768<0>
<0> 00912ed4<0> 009b6594<0> ffffe282<0> 009af774<0> 009af788<0> 0000012c<0> 00000000<0> 00000040
|
This is the basic code for my receive function with the hardware specific code removed.
Code:
void hw_rx2(struct net_device *dev)
{
struct sk_buff *skb;
uint8_t *rdptr;
...
/* Recieve frame header */
...
if ((skb = dev_alloc_skb(rxLen+2)) == NULL) {
printk("Cannot allocate socket buffer\n");
goto ERROR;
}
skb_reserve(skb, 2);
rdptr = (uint8_t *) skb_put(skb, rxLen+2);
/* Recieve Ethernet frame */
while (1) { /* break based on frame length, will always be in valid range */
for (i=0;i<4;i++) { /* Read 8 bytes of Ethernet frame. */
/* READ WORD */
rxWord = ...
count++;
if (count > rxLen) { /* if at end of frame */
goto FCS;
}
else {
memcpy(rdptr, &rxWord, 16); /* copy 2 bytes to socket buffer */
rdptr += 2; /* increment pointer by 2 bytes */
}
}
while (/* Poll status register until data ready to read */)
}
FCS:
/* READ FRAME CHECK SEQUENCE */
...
skb->csum = FCS1 + FCS2;
dev->stats.rx_bytes += rxLen;
/* pass to upper layer */
skb->protocol = eth_type_trans(skb, dev);
netif_rx(skb);
dev->stats.rx_packets++;
DONE:
/* Write to CMD_STATUS_REG to indicate the end of the frame. */
...
return;
}
Any ideas?
Cheers,
Austin.