public inbox for ecos-discuss@sourceware.org
 help / color / mirror / Atom feed
* [ECOS] cs8900a problem
@ 2004-05-05 21:42 Bob Koninckx
  2004-05-05 22:08 ` Gary Thomas
  0 siblings, 1 reply; 5+ messages in thread
From: Bob Koninckx @ 2004-05-05 21:42 UTC (permalink / raw)
  To: ecos-discuss

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

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [ECOS] cs8900a problem
  2004-05-05 21:42 [ECOS] cs8900a problem Bob Koninckx
@ 2004-05-05 22:08 ` Gary Thomas
  2004-05-06  5:18   ` Bob Koninckx
  0 siblings, 1 reply; 5+ messages in thread
From: Gary Thomas @ 2004-05-05 22:08 UTC (permalink / raw)
  To: bob.koninckx; +Cc: ecos-discuss

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

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [ECOS] cs8900a problem
  2004-05-05 22:08 ` Gary Thomas
@ 2004-05-06  5:18   ` Bob Koninckx
  2004-05-06 22:14     ` Bob Koninckx
  0 siblings, 1 reply; 5+ messages in thread
From: Bob Koninckx @ 2004-05-06  5:18 UTC (permalink / raw)
  To: Gary Thomas; +Cc: ecos-discuss

On Thu, 2004-05-06 at 00:08, Gary Thomas wrote:
> 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.
> > 
> > 
> > 
> > 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?
> 

stat always equals 0x04 (RxEvent without any flags set). I'll try and
see what happens if I ignore zero length frames.

Thanks,

Bob


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

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [ECOS] cs8900a problem
  2004-05-06  5:18   ` Bob Koninckx
@ 2004-05-06 22:14     ` Bob Koninckx
  2004-05-06 22:19       ` Gary Thomas
  0 siblings, 1 reply; 5+ messages in thread
From: Bob Koninckx @ 2004-05-06 22:14 UTC (permalink / raw)
  To: Gary Thomas; +Cc: ecos-discuss

Ignoring the frame seems to do the trick (at first sight). I suppose
that if ethernet frames would be lost, upper layers will take care of
that, right?

I do believe, however, that the real problem lies with the device
driver, which should not be delivering zero length frames in the first
place. According to the cs8900a datasheet, enabling interrupts in the
RxCFG register but leaving the corresponding acceptance bit unset in the
RxCTL register will result in the device reporting zero length frames. I
tried the following change in the cs8900_start function

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

Although this could have explained what happened, it didn't solve
anything. My observation that the zero length is always returned when
the main polling loop is entered three times has been confirmed today.
Don't know if it means anything, but it gives me the impression that it
could be a hardware overrun.

Bob

On Thu, 2004-05-06 at 07:17, Bob Koninckx wrote:
> On Thu, 2004-05-06 at 00:08, Gary Thomas wrote:
> > 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.
> > > 
> > > 
> > > 
> > > 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?
> > 
> 
> stat always equals 0x04 (RxEvent without any flags set). I'll try and
> see what happens if I ignore zero length frames.
> 
> Thanks,
> 
> Bob
> 


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

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [ECOS] cs8900a problem
  2004-05-06 22:14     ` Bob Koninckx
@ 2004-05-06 22:19       ` Gary Thomas
  0 siblings, 0 replies; 5+ messages in thread
From: Gary Thomas @ 2004-05-06 22:19 UTC (permalink / raw)
  To: bob.koninckx; +Cc: ecos-discuss

On Thu, 2004-05-06 at 16:13, Bob Koninckx wrote:
> Ignoring the frame seems to do the trick (at first sight). I suppose
> that if ethernet frames would be lost, upper layers will take care of
> that, right?
> 
> I do believe, however, that the real problem lies with the device
> driver, which should not be delivering zero length frames in the first
> place. According to the cs8900a datasheet, enabling interrupts in the
> RxCFG register but leaving the corresponding acceptance bit unset in the
> RxCTL register will result in the device reporting zero length frames. I
> tried the following change in the cs8900_start function
> 
> //    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);
> 
> Although this could have explained what happened, it didn't solve
> anything. My observation that the zero length is always returned when
> the main polling loop is entered three times has been confirmed today.
> Don't know if it means anything, but it gives me the impression that it
> could be a hardware overrun.

I've never seen this happen on any system with this chip, so I'm not
sure why it happens.  Of course this chip, like most others, has it's
own vulgarities and this is probably just another one, albeit freshly
discovered.

If ignoring zero length frames works, then by all means ignore them.
The rest (protocols, etc) should handle it just fine.
 
> 
> Bob
> 
> On Thu, 2004-05-06 at 07:17, Bob Koninckx wrote:
> > On Thu, 2004-05-06 at 00:08, Gary Thomas wrote:
> > > 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.
> > > > 
> > > > 
> > > > 
> > > > 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?
> > > 
> > 
> > stat always equals 0x04 (RxEvent without any flags set). I'll try and
> > see what happens if I ignore zero length frames.
> > 
> > Thanks,
> > 
> > Bob
> > 
-- 
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

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2004-05-06 22:19 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-05-05 21:42 [ECOS] cs8900a problem Bob Koninckx
2004-05-05 22:08 ` Gary Thomas
2004-05-06  5:18   ` Bob Koninckx
2004-05-06 22:14     ` Bob Koninckx
2004-05-06 22:19       ` Gary Thomas

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).