This is the mail archive of the ecos-discuss@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

cs8900a problem


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!

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);
}




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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]