Hi again,

Marco Cavallini wrote:
>Hi Claude,
>I had similar problems on a MCF5282, which seems being solved with
>modifications to cache setting code, I'd like to try your patch as soon
>as I have some spare time (I hope this week).
>Feel free to contact me privately to discuss your patch and other things
>I've done to work this board properly.

I had already disabled the CACHE completely but FEC problem persisted.
In order to let people having older driver versions I'd like to make a summary of the changes here:


First, since FEC driver only processes buffers holding entire packets, it is not necessary to enable interrupts for RXB and TXB events (rx buffer and tx buffer), but only for RXF and TXF events (rx and tx frames). This may produce unnecessary interrupts to CPU. Interrupts are enabled in fec_enet_init() and fec_restart() functions. If you take a look to the patch, only necessary int's are enabled:


  fecp->fec_imask = (FEC_ENET_TXF | /*FEC_ENET_TXB |*/
            FEC_ENET_RXF /*| FEC_ENET_RXB */ | FEC_ENET_MII);


Commented lines have been left for convenience. They should be removed, however, to clean up code.

On the other hand, other changes affected the interrupt service routine. In my opinion, it's fine that, in order to process all packets waiting in the queue, the ring should be entirely processed when an interrupt is raised when receiving a packet (see the loop in fec_enet_rx(), which is called from the ISR). But I don't agree with making a loop in the ISR to handle all different events (tx, rx and mii events) that are waiting, since they should be acknowledge in a different manner.
The old FEC driver does the following, in the ISR:

while ("pending interrupts"){
        acknowledge all interrupts
        if RX event, then process RX event
        if TX event, then process TX event
        if MII event, then process MII event
}

The fixed code (the patch's one) does this, instead:

if ("pending interrupts") {
if RX event, then process RX event and then acknowledge RX event (clearing the corresponding flag) if TX event, then process TX event and then acknowledge TX event (clearing the corresponding flag) if MII event, then process MII event and then acknowledge MII event (clearing the corresponding flag)
}

I saw that the first solution produced, after some time, a lost of synchronization when processing the ring. It seems that acknowledging the RX event before processing the ring makes the FEC to allow entering more packets till produce a ring overflow.

Finally, the "pending interrupts" condition above, was implemented as follows (in the old FEC driver):
        ((int_events = fecp->ievent) != 0)

The fixed code does:
((int_events = (fecp->ievent & (FEC_ENET_RXF | FEC_ENET_TXF | FEC_ENET_MII))) != 0)

This avoids the ISR (after receiving a RX,TX or MII event) to keep running if other flag in the fecp->ievent register is raised for any reason (error flag, for example). However, the replacement of "while" for "if" implicitly avoids it.


Well, I hope this solution could help someone. At least it has helped me!!

Claude










_______________________________________________
uClinux-dev mailing list
uClinux-dev@uclinux.org
http://mailman.uclinux.org/mailman/listinfo/uclinux-dev
This message was resent by uclinux-dev@uclinux.org
To unsubscribe see:
http://mailman.uclinux.org/mailman/options/uclinux-dev

Reply via email to