This is the mail archive of the ecos-discuss@sourceware.org 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]

`


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


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