STM32 Ethernet: Need two work structures so that pending poll work is not lost when an interrupt occurs.
This commit is contained in:
parent
34a2839244
commit
c7943586d8
@ -583,7 +583,8 @@ struct stm32_ethmac_s
|
||||
uint8_t fduplex : 1; /* Full (vs. half) duplex */
|
||||
WDOG_ID txpoll; /* TX poll timer */
|
||||
WDOG_ID txtimeout; /* TX timeout timer */
|
||||
struct work_s work; /* For deferring work to the work queue */
|
||||
struct work_s irqwork; /* For deferring interrupt work to the work queue */
|
||||
struct work_s pollwork; /* For deferring poll work to the work queue */
|
||||
|
||||
/* This holds the information visible to the NuttX network */
|
||||
|
||||
@ -1933,27 +1934,6 @@ static void stm32_txdone(FAR struct stm32_ethmac_s *priv)
|
||||
|
||||
wd_cancel(priv->txtimeout);
|
||||
|
||||
/* Check if the poll timer is running. If it is not, then start it
|
||||
* now. There is a race condition here: We may test the time
|
||||
* remaining on the poll timer and determine that it is still running,
|
||||
* but then the timer expires immiately. That should not be problem,
|
||||
* however, the poll timer is queued processing should be in the work
|
||||
* queue and should execute immediately after we complete the TX poll.
|
||||
* Inefficient, but not fatal.
|
||||
*/
|
||||
|
||||
delay = wd_gettime(priv->txpoll);
|
||||
if (delay <= 0)
|
||||
{
|
||||
/* The poll timer is not running .. restart it. This is necessary
|
||||
* to avoid certain race conditions where the polling sequence can
|
||||
* be interrupted.
|
||||
*/
|
||||
|
||||
(void)wd_start(priv->txpoll, STM32_WDDELAY, stm32_poll_expiry,
|
||||
1, priv);
|
||||
}
|
||||
|
||||
/* And disable further TX interrupts. */
|
||||
|
||||
stm32_disableint(priv, ETH_DMAINT_TI);
|
||||
@ -2117,13 +2097,9 @@ static int stm32_interrupt(int irq, FAR void *context, FAR void *arg)
|
||||
wd_cancel(priv->txtimeout);
|
||||
}
|
||||
|
||||
/* Cancel any pending poll work */
|
||||
|
||||
work_cancel(ETHWORK, &priv->work);
|
||||
|
||||
/* Schedule to perform the interrupt processing on the worker thread. */
|
||||
|
||||
work_queue(ETHWORK, &priv->work, stm32_interrupt_work, priv, 0);
|
||||
work_queue(ETHWORK, &priv->irqwork, stm32_interrupt_work, priv, 0);
|
||||
}
|
||||
|
||||
return OK;
|
||||
@ -2196,15 +2172,15 @@ static void stm32_txtimeout_expiry(int argc, uint32_t arg, ...)
|
||||
|
||||
up_disable_irq(STM32_IRQ_ETH);
|
||||
|
||||
/* Cancel any pending poll or interrupt work. This will have no effect
|
||||
* on work that has already been started.
|
||||
/* Cancel any pending interrupt work. This will have no effect on work that
|
||||
* has already been started.
|
||||
*/
|
||||
|
||||
work_cancel(ETHWORK, &priv->work);
|
||||
work_cancel(ETHWORK, &priv->irqwork);
|
||||
|
||||
/* Schedule to perform the TX timeout processing on the worker thread. */
|
||||
|
||||
work_queue(ETHWORK, &priv->work, stm32_txtimeout_work, priv, 0);
|
||||
work_queue(ETHWORK, &priv->irqwork, stm32_txtimeout_work, priv, 0);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -2305,11 +2281,11 @@ static void stm32_poll_expiry(int argc, uint32_t arg, ...)
|
||||
* pending interrupt actions.
|
||||
*/
|
||||
|
||||
if (work_available(&priv->work))
|
||||
if (work_available(&priv->pollwork))
|
||||
{
|
||||
/* Schedule to perform the interrupt processing on the worker thread. */
|
||||
|
||||
work_queue(ETHWORK, &priv->work, stm32_poll_work, priv, 0);
|
||||
work_queue(ETHWORK, &priv->pollwork, stm32_poll_work, priv, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2487,11 +2463,11 @@ static int stm32_txavail(struct net_driver_s *dev)
|
||||
* availability action.
|
||||
*/
|
||||
|
||||
if (work_available(&priv->work))
|
||||
if (work_available(&priv->pollwork))
|
||||
{
|
||||
/* Schedule to serialize the poll on the worker thread. */
|
||||
|
||||
work_queue(ETHWORK, &priv->work, stm32_txavail_work, priv, 0);
|
||||
work_queue(ETHWORK, &priv->pollwork, stm32_txavail_work, priv, 0);
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
Loading…
Reference in New Issue
Block a user