[ECOS] cs8900a problem

Gary Thomas gary@mlbassoc.com
Wed May 5 22:08:00 GMT 2004


On Wed, 2004-05-05 at 15:41, Bob Koninckx wrote:
> After some (a lot) digging, I've come closer to my ethernet redboot
> problem.
> 
> Problem seems to originate from the following function
> 
> static void
> cs8900a_RxEvent(struct eth_drv_sc *sc)
> {
>     cs8900a_priv_data_t *cpd = (cs8900a_priv_data_t*)sc->driver_private;
>     cyg_addrword_t base = cpd->base;
>     cyg_uint16 stat, len;
> 
>     HAL_READ_UINT16(base+CS8900A_RTDATA, stat);
>     HAL_READ_UINT16(base+CS8900A_RTDATA, len);
> 
> #ifdef CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED
>     len = CYG_SWAP16(len);
> #endif
> 
> #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);
> }
> 
> sometimes a frame length of zero is read (status is always four in this
> case). Further in the stack this value is diminished by 14, cast to an
> unsigned (resulting in a huge number) and the result is then used as a
> length for copying the buffer. 
> Consequently, most or even the whole ram gets overwritten and redboot
> crashes ... so far for what's happening.
> 
> 
> I further noticed that this zero length frame is only seen if the while
> loop in the main polling function gets entered at least three times. I
> have no idea what could be wrong, Hints or tips are welcome here!

What happens if you just ignore frames with a zero length?
What's the status (stat) value when the length is zero?

> 
> Thanks,
> Bob
> 
> static void
> cs8900a_poll(struct eth_drv_sc *sc)
> {
>     cyg_uint16 event;
>     cs8900a_priv_data_t *cpd = (cs8900a_priv_data_t*)sc->driver_private;
>     cyg_addrword_t base = cpd->base;
> 
>     HAL_READ_UINT16(base+CS8900A_ISQ, event);
>     while (event != 0) {
>         switch (event & ISQ_EventMask) {
>         case ISQ_RxEvent:
>             if(event & 0xf000)
>               diag_printf("RxEvent, %d\n", event);
>             cs8900a_RxEvent(sc); <<--third RxEvent on a row causes
> problems
>             break;
>         case ISQ_TxEvent:
>             cs8900a_TxEvent(sc, event);
>             break;
>         case ISQ_BufEvent:
>             cs8900a_BufEvent(sc, event);
>             break;
>         case ISQ_RxMissEvent:
>             diag_printf("ISQ_RxMissEvent\n");
>             // Receive miss counter has overflowed
>             break;
>         case ISQ_TxColEvent:
>             diag_printf("ISQ_TxColEvent\n");
>             // Transmit collision counter has overflowed
>             break;
>         default:
> #if DEBUG & 1
>             diag_printf("%s: Unknown event: %x\n", __FUNCTION__, event);
> #endif
>             break;
>         }
>         HAL_READ_UINT16(base+CS8900A_ISQ, event);
>     }
>                                                                                                                                                
>     CYGHWR_CL_CS8900A_PLF_INT_CLEAR(cpd);
> }
-- 
Gary Thomas <gary@mlbassoc.com>
MLB Associates


-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss



More information about the Ecos-discuss mailing list