This is the mail archive of the
ecos-bugs@sources.redhat.com
mailing list for the eCos project.
[Bug 1000097] New: cs8900a ethernet controller can generate zero length frames, which causes eCos to crash
- From: bugzilla at ecoscentric dot com
- To: ecos-bugs at sources dot redhat dot com
- Date: Thu, 10 Jun 2004 20:23:18 +0100 (BST)
- Subject: [Bug 1000097] New: cs8900a ethernet controller can generate zero length frames, which causes eCos to crash
http://bugs.ecos.sourceware.org/show_bug.cgi?id=1000097
Summary: cs8900a ethernet controller can generate zero length
frames, which causes eCos to crash
Product: eCos
Version: unknown
Platform: All
OS/Version: All
Status: UNCONFIRMED
Severity: critical
Priority: normal
Component: Ethernet drivers
AssignedTo: gary@mlbassoc.com
ReportedBy: shf@pfinc.com
QAContact: ecos-bugs@sources.redhat.com
In cs8900a_start (in if_cs8900a.c), the RxCFG register is set to generate
interrupts upon reception of runt frames, frames with bad CRC, and frames with
length greater than 1518 characters (the maximum length message buffered by the
cs8900a), as well as for valid frames. Under certain conditions a runt frame
causes the cs8900a to indicate that a frame is available with zero length.
Calling the eth_drv_recv function with a zero length causes eCos to crash.
Changing the RxCFG register to only allow an interrupt upon reception of a
valid frame (with good CRC) seems to fix my problem. Recently, someone
reported that the polling routine used by redboot can generate zero length
frames (probably by a different mechanism). Since the 8900a should never
receive a zero length frame, or a frame with length greater than 1518 byes, it
seems prudent to test for these limits in the cs8900a_RxEvent function, and
ignore those with invalid frame length.
Here is a diff of the current if_cs8900a.c and my modified file:
cvs -q diff -u5 -p
Index: if_cs8900a.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/eth/cl/cs8900a/current/src/if_cs8900a.c,v
retrieving revision 1.10
diff -u -5 -p -r1.10 if_cs8900a.c
--- if_cs8900a.c 27 May 2004 06:48:47 -0000 1.10
+++ if_cs8900a.c 10 Jun 2004 17:42:35 -0000
@@ -331,12 +331,11 @@ cs8900a_start(struct eth_drv_sc *sc, cyg
cs8900a_priv_data_t *cpd = (cs8900a_priv_data_t *)sc->driver_private;
cyg_addrword_t base = cpd->base;
put_reg(base, PP_BusCtl, PP_BusCtl_MemoryE); // Disable interrupts,
memory mode
put_reg(base, PP_IntReg, PP_IntReg_IRQ0); // Only possibility
- put_reg(base, PP_RxCFG, PP_RxCFG_RxOK | PP_RxCFG_CRC |
- PP_RxCFG_RUNT | PP_RxCFG_EXTRA);
+ put_reg(base, PP_RxCFG, PP_RxCFG_RxOK);
cpd->rxmode = PP_RxCTL_RxOK | PP_RxCTL_Broadcast | PP_RxCTL_IA;
put_reg(base, PP_RxCTL, cpd->rxmode);
put_reg(base, PP_TxCFG, PP_TxCFG_TxOK | PP_TxCFG_Collision |
PP_TxCFG_CRS | PP_TxCFG_SQE | PP_TxCFG_Late |
PP_TxCFG_Jabber | PP_TxCFG_16Collisions);
@@ -553,11 +552,13 @@ cs8900a_RxEvent(struct eth_drv_sc *sc, i
#ifdef CYGDBG_IO_ETH_DRIVERS_DEBUG
if (cyg_io_eth_net_debug) {
diag_printf("RxEvent - stat: %x, len: %d\n", stat, len);
}
#endif
- (sc->funs->eth_drv->recv)(sc, len);
+ if( (len > 0) && (len <= 1518) ) {
+ (sc->funs->eth_drv->recv)(sc, len);
+ }
}
}
// This function is called as a result of the "eth_drv_recv()" call above.
// It's job is to actually fetch data for a packet from the hardware once
------- You are receiving this mail because: -------
You are the QA contact for the bug, or are watching the QA contact.