[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.
indeed
> 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() ->
/net/bsd_tcpip/current/src/ecos/timeout.c::ecos_synch_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 
context???

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,
Jürgen

> 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