[ECOS] `

Jürgen Lambrecht J.Lambrecht@televic.com
Wed Jun 11 10:12:00 GMT 2008

I-Yanaslov wrote:
> ----- Original Message ----- From: "Jürgen Lambrecht" 
> <J.Lambrecht@televic.com>
> To: <ecos-discuss@ecos.sourceware.org>
> Cc: "Andrew Lunn" <andrew@lunn.ch>; "I-Yanaslov" 
> <yanaslov_iv@ic-bresler.ru>
> Sent: Tuesday, June 10, 2008 8:11 PM
> Subject: Re: [ECOS] "packets eaten" with AT91 EMAC Ethernet driver
>> Lambrecht Jürgen wrote:
>> Indeed, that was the problem:
>> Wrong code in at91_eth_deliver():
>>   if (tsr&AT91_EMAC_TSR_COMP) //5
>>   {
>>      at91_reset_tbd(priv);
>>      _eth_drv_tx_done(sc,priv->curr_tx_key,0);
>>      priv->tx_busy = false;
>>   }
>> Correct code:
>>   {
>>      at91_reset_tbd(priv, b_reset_tbd_idx);
>>      priv->tx_busy = false;
>>      _eth_drv_tx_done(sc,priv->curr_tx_key,0);
>>   }
>> If the low-level driver is available (can_send() returns not zero) 
>> then the first packet is sent.
>> If the low-level driver is not available it stops here. It is 
>> supposed that the low-level driver will inform then the middleware 
>> when it is ready by calling tx_done.
>> eth_drv_tx_done on its turn calls eth_drv_send() which then checks 
>> again can_send()
>> The AT91 driver first called tx_done, calling send calling can_send 
>> which returns 0 of course.
>> And afterwards - too late - busy is set to true, so that can_send can 
>> return 1...
> "priv->tx_busy = false;" is not consumes many time.
> So, ISR is better place to do it.
> Than, TX driver becomes to ready (can_send() returns 1 ) just at 
> moment whan a HW becomes to ready, even if DSR and __eth_drv_tx_done() 
> is still running.
Yes, that could be a good idea.
I can only think of 1 problem:

The moment you set "priv->tx_busy = false;", packets can be sent. And if 
the TCP/IP stack has new data to send (e.g. because of a new RX), it 
will call send(), and then finally the transmit status bits in the TSR 
register can be overwritten before at91_eth_deliver() has read out the 
TSR register for the previous packet.
This should not be possible, if at91_eth_deliver() runs in DSR context, 
because a DSR will always run before "normal" functions.
But I don't think at91_eth_deliver() is called under DSR context.

This is the call stack:
The DSR is /io/eth/current/src/net/eth_drv.c::eth_drv_dsr() ->
{cyg_flag_setbits( &alarm_flag, 2 ); }
This flags the alarm-flag of the alarm_thread() (cyg_flag_wait(..)) ->
/io/eth/current/src/net/eth_drv_run_deliveries() -> at91_eth_deliver()

When the alarm-flag is flagged by the DSR function, the scheduler wakes 
up the alarm thread, but is this alarm_thread() still run under DSR 

I don't think so.
deliver() is meant to run under thread context and not DSR context, 
because all the copying and buffer handling takes too long for DSR 
context (?).

Kind regards,

> Ivan.

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