mirror of
https://github.com/apache/nuttx.git
synced 2026-05-27 19:36:35 +08:00
Most Ethernet drviers: Check if the poll timer is running before restarting it at the end of each TX.
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* arch/arm/src/lpc17xx/lpc17_ethernet.c
|
* arch/arm/src/lpc17xx/lpc17_ethernet.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010-2015 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2010-2015, 2017 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -1262,6 +1262,8 @@ static int lpc17_interrupt(int irq, void *context)
|
|||||||
|
|
||||||
if ((status & ETH_INT_TXDONE) != 0)
|
if ((status & ETH_INT_TXDONE) != 0)
|
||||||
{
|
{
|
||||||
|
int delay;
|
||||||
|
|
||||||
NETDEV_TXDONE(&priv->lp_dev);
|
NETDEV_TXDONE(&priv->lp_dev);
|
||||||
|
|
||||||
/* A packet transmission just completed */
|
/* A packet transmission just completed */
|
||||||
@@ -1283,14 +1285,28 @@ static int lpc17_interrupt(int irq, void *context)
|
|||||||
|
|
||||||
work_cancel(ETHWORK, &priv->lp_txwork);
|
work_cancel(ETHWORK, &priv->lp_txwork);
|
||||||
|
|
||||||
/* Then make sure that the TX poll timer is running (if it is
|
/* Check if the poll timer is running. If it is not, then
|
||||||
* already running, the following would restart it). This is
|
* start it now. There is a race condition here: We may test
|
||||||
* necessary to avoid certain race conditions where the polling
|
* the time remaining on the poll timer and determine that it
|
||||||
* sequence can be interrupted.
|
* is still running, but then the timer expires immiately.
|
||||||
|
* That should not be problem, however, the poll timer is
|
||||||
|
* queued for processing should be in the work queue and
|
||||||
|
* should execute immediately after we complete the TX poll.
|
||||||
|
* Inefficient, but not fatal.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(void)wd_start(priv->lp_txpoll, LPC17_WDDELAY, lpc17_poll_expiry,
|
delay = wd_gettime(priv->lp_txpoll);
|
||||||
1, priv);
|
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->lp_txpoll, LPC17_WDDELAY,
|
||||||
|
lpc17_poll_expiry, 1, priv);
|
||||||
|
}
|
||||||
|
|
||||||
/* Schedule TX-related work to be performed on the work thread */
|
/* Schedule TX-related work to be performed on the work thread */
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* arch/arm/src/lpc43/lpc43_eth.c
|
* arch/arm/src/lpc43/lpc43_eth.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2011-2015 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2011-2015, 2017 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -1862,17 +1862,32 @@ static void lpc43_txdone(FAR struct lpc43_ethmac_s *priv)
|
|||||||
|
|
||||||
if (priv->inflight <= 0)
|
if (priv->inflight <= 0)
|
||||||
{
|
{
|
||||||
|
int delay;
|
||||||
|
|
||||||
/* Cancel the TX timeout */
|
/* Cancel the TX timeout */
|
||||||
|
|
||||||
wd_cancel(priv->txtimeout);
|
wd_cancel(priv->txtimeout);
|
||||||
|
|
||||||
/* Then make sure that the TX poll timer is running (if it is already
|
/* Check if the poll timer is running. If it is not, then start it
|
||||||
* running, the following would restart it). This is necessary to
|
* now. There is a race condition here: We may test the time
|
||||||
* avoid certain race conditions where the polling sequence can be
|
* remaining on the poll timer and determine that it is still running,
|
||||||
* interrupted.
|
* but then the timer expires immiately. That should not be problem,
|
||||||
|
* however, the poll timer processing should be in the work queue and
|
||||||
|
* should execute immediately after we complete the TX poll.
|
||||||
|
* Inefficient, but not fatal.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(void)wd_start(priv->txpoll, LPC43_WDDELAY, lpc43_poll_expiry, 1, priv);
|
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, LPC43_WDDELAY, lpc43_poll_expiry,
|
||||||
|
1, priv);
|
||||||
|
}
|
||||||
|
|
||||||
/* And disable further TX interrupts. */
|
/* And disable further TX interrupts. */
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* arch/arm/src/sam34/sam_emac.c
|
* arch/arm/src/sam34/sam_emac.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2014-2015 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2014-2015, 2017 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* This logic derives from the SAM34D3 Ethernet driver.
|
* This logic derives from the SAM34D3 Ethernet driver.
|
||||||
@@ -1638,6 +1638,8 @@ static int sam_emac_interrupt(int irq, void *context)
|
|||||||
tsr = sam_getreg(priv, SAM_EMAC_TSR);
|
tsr = sam_getreg(priv, SAM_EMAC_TSR);
|
||||||
if ((tsr & EMAC_TSR_TXCOMP) != 0)
|
if ((tsr & EMAC_TSR_TXCOMP) != 0)
|
||||||
{
|
{
|
||||||
|
int delay;
|
||||||
|
|
||||||
/* If a TX transfer just completed, then cancel the TX timeout so
|
/* If a TX transfer just completed, then cancel the TX timeout so
|
||||||
* there will be do race condition between any subsequent timeout
|
* there will be do race condition between any subsequent timeout
|
||||||
* expiration and the deferred interrupt processing.
|
* expiration and the deferred interrupt processing.
|
||||||
@@ -1645,13 +1647,26 @@ static int sam_emac_interrupt(int irq, void *context)
|
|||||||
|
|
||||||
wd_cancel(priv->txtimeout);
|
wd_cancel(priv->txtimeout);
|
||||||
|
|
||||||
/* Make sure that the TX poll timer is running (if it is already
|
/* Check if the poll timer is running. If it is not, then start it
|
||||||
* running, the following would restart it). This is necessary to
|
* now. There is a race condition here: We may test the time
|
||||||
* avoid certain race conditions where the polling sequence can be
|
* remaining on the poll timer and determine that it is still running,
|
||||||
* interrupted.
|
* but then the timer expires immiately. That should not be problem,
|
||||||
|
* however, the poll timer processing should be in the work queue and
|
||||||
|
* should execute immediately after we complete the TX poll.
|
||||||
|
* Inefficient, but not fatal.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(void)wd_start(priv->txpoll, SAM_WDDELAY, sam_poll_expiry, 1, priv);
|
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, SAM_WDDELAY, sam_poll_expiry,
|
||||||
|
1, priv);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cancel any pending poll work */
|
/* Cancel any pending poll work */
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
* 10/100 Base-T Ethernet driver for the SAMA5D3. Denoted as 'A' to
|
* 10/100 Base-T Ethernet driver for the SAMA5D3. Denoted as 'A' to
|
||||||
* distinguish it from the SAMA5D4 EMAC driver.
|
* distinguish it from the SAMA5D4 EMAC driver.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013-2016 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2013-2017 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* References:
|
* References:
|
||||||
@@ -1676,6 +1676,8 @@ static int sam_emac_interrupt(int irq, void *context)
|
|||||||
tsr = sam_getreg(priv, SAM_EMAC_TSR_OFFSET);
|
tsr = sam_getreg(priv, SAM_EMAC_TSR_OFFSET);
|
||||||
if ((tsr & EMAC_TSR_COMP) != 0)
|
if ((tsr & EMAC_TSR_COMP) != 0)
|
||||||
{
|
{
|
||||||
|
int delay;
|
||||||
|
|
||||||
/* If a TX transfer just completed, then cancel the TX timeout so
|
/* If a TX transfer just completed, then cancel the TX timeout so
|
||||||
* there will be do race condition between any subsequent timeout
|
* there will be do race condition between any subsequent timeout
|
||||||
* expiration and the deferred interrupt processing.
|
* expiration and the deferred interrupt processing.
|
||||||
@@ -1683,13 +1685,26 @@ static int sam_emac_interrupt(int irq, void *context)
|
|||||||
|
|
||||||
wd_cancel(priv->txtimeout);
|
wd_cancel(priv->txtimeout);
|
||||||
|
|
||||||
/* Make sure that the TX poll timer is running (if it is already
|
/* Check if the poll timer is running. If it is not, then start it
|
||||||
* running, the following would restart it). This is necessary to
|
* now. There is a race condition here: We may test the time
|
||||||
* avoid certain race conditions where the polling sequence can be
|
* remaining on the poll timer and determine that it is still running,
|
||||||
* interrupted.
|
* but then the timer expires immiately. That should not be problem,
|
||||||
|
* however, the poll timer processing should be in the work queue and
|
||||||
|
* should execute immediately after we complete the TX poll.
|
||||||
|
* Inefficient, but not fatal.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(void)wd_start(priv->txpoll, SAM_WDDELAY, sam_poll_expiry, 1, priv);
|
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, SAM_WDDELAY, sam_poll_expiry,
|
||||||
|
1, priv);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cancel any pending poll work */
|
/* Cancel any pending poll work */
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
* separate (mostly because the 'B' driver needs to support two EMAC blocks.
|
* separate (mostly because the 'B' driver needs to support two EMAC blocks.
|
||||||
* But the 'B' driver should replace the 'A' driver someday.
|
* But the 'B' driver should replace the 'A' driver someday.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2014-2015 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2014-2015, 2017 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* This logic derives from the SAM4E Ethernet driver which, in turn, derived
|
* This logic derives from the SAM4E Ethernet driver which, in turn, derived
|
||||||
@@ -2043,6 +2043,8 @@ static int sam_emac_interrupt(struct sam_emac_s *priv)
|
|||||||
tsr = sam_getreg(priv, SAM_EMAC_TSR_OFFSET);
|
tsr = sam_getreg(priv, SAM_EMAC_TSR_OFFSET);
|
||||||
if ((tsr & EMAC_TSR_TXCOMP) != 0)
|
if ((tsr & EMAC_TSR_TXCOMP) != 0)
|
||||||
{
|
{
|
||||||
|
int delay;
|
||||||
|
|
||||||
/* If a TX transfer just completed, then cancel the TX timeout so
|
/* If a TX transfer just completed, then cancel the TX timeout so
|
||||||
* there will be do race condition between any subsequent timeout
|
* there will be do race condition between any subsequent timeout
|
||||||
* expiration and the deferred interrupt processing.
|
* expiration and the deferred interrupt processing.
|
||||||
@@ -2050,13 +2052,26 @@ static int sam_emac_interrupt(struct sam_emac_s *priv)
|
|||||||
|
|
||||||
wd_cancel(priv->txtimeout);
|
wd_cancel(priv->txtimeout);
|
||||||
|
|
||||||
/* Make sure that the TX poll timer is running (if it is already
|
/* Check if the poll timer is running. If it is not, then start it
|
||||||
* running, the following would restart it). This is necessary to
|
* now. There is a race condition here: We may test the time
|
||||||
* avoid certain race conditions where the polling sequence can be
|
* remaining on the poll timer and determine that it is still running,
|
||||||
* interrupted.
|
* but then the timer expires immiately. That should not be problem,
|
||||||
|
* however, the poll timer processing should be in the work queue and
|
||||||
|
* should execute immediately after we complete the TX poll.
|
||||||
|
* Inefficient, but not fatal.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(void)wd_start(priv->txpoll, SAM_WDDELAY, sam_poll_expiry, 1, priv);
|
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, SAM_WDDELAY, sam_poll_expiry,
|
||||||
|
1, priv);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cancel any pending poll work */
|
/* Cancel any pending poll work */
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* arch/arm/src/sama5/sam_gmac.c
|
* arch/arm/src/sama5/sam_gmac.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013-2016 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2013-2017 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* References:
|
* References:
|
||||||
@@ -1628,6 +1628,8 @@ static int sam_gmac_interrupt(int irq, void *context)
|
|||||||
tsr = sam_getreg(priv, SAM_GMAC_TSR_OFFSET);
|
tsr = sam_getreg(priv, SAM_GMAC_TSR_OFFSET);
|
||||||
if ((tsr & GMAC_TSR_TXCOMP) != 0)
|
if ((tsr & GMAC_TSR_TXCOMP) != 0)
|
||||||
{
|
{
|
||||||
|
int delay;
|
||||||
|
|
||||||
/* If a TX transfer just completed, then cancel the TX timeout so
|
/* If a TX transfer just completed, then cancel the TX timeout so
|
||||||
* there will be do race condition between any subsequent timeout
|
* there will be do race condition between any subsequent timeout
|
||||||
* expiration and the deferred interrupt processing.
|
* expiration and the deferred interrupt processing.
|
||||||
@@ -1635,13 +1637,25 @@ static int sam_gmac_interrupt(int irq, void *context)
|
|||||||
|
|
||||||
wd_cancel(priv->txtimeout);
|
wd_cancel(priv->txtimeout);
|
||||||
|
|
||||||
/* Make sure that the TX poll timer is running (if it is already
|
/* Check if the poll timer is running. If it is not, then start it
|
||||||
* running, the following would restart it). This is necessary to
|
* now. There is a race condition here: We may test the time
|
||||||
* avoid certain race conditions where the polling sequence can be
|
* remaining on the poll timer and determine that it is still running,
|
||||||
* interrupted.
|
* but then the timer expires immiately. That should not be problem,
|
||||||
|
* however, the poll timer processing should be in the work queue and
|
||||||
|
* should execute immediately after we complete the TX poll.
|
||||||
|
* Inefficient, but not fatal.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(void)wd_start(priv->txpoll, SAM_WDDELAY, sam_poll_expiry, 1, priv);
|
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, SAM_WDDELAY, sam_poll_expiry, 1, priv);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cancel any pending poll work */
|
/* Cancel any pending poll work */
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* arch/arm/src/samv7/sam_emac.c
|
* arch/arm/src/samv7/sam_emac.c
|
||||||
* 10/100 Base-T Ethernet driver for the SAMV71.
|
* 10/100 Base-T Ethernet driver for the SAMV71.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2015, 2017 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* This logic derives from the SAMA5 Ethernet driver which, in turn, derived
|
* This logic derives from the SAMA5 Ethernet driver which, in turn, derived
|
||||||
@@ -2489,6 +2489,8 @@ static int sam_emac_interrupt(struct sam_emac_s *priv)
|
|||||||
tsr = sam_getreg(priv, SAM_EMAC_TSR_OFFSET);
|
tsr = sam_getreg(priv, SAM_EMAC_TSR_OFFSET);
|
||||||
if ((tsr & EMAC_TSR_TXCOMP) != 0)
|
if ((tsr & EMAC_TSR_TXCOMP) != 0)
|
||||||
{
|
{
|
||||||
|
int delay;
|
||||||
|
|
||||||
/* If a TX transfer just completed, then cancel the TX timeout so
|
/* If a TX transfer just completed, then cancel the TX timeout so
|
||||||
* there will be do race condition between any subsequent timeout
|
* there will be do race condition between any subsequent timeout
|
||||||
* expiration and the deferred interrupt processing.
|
* expiration and the deferred interrupt processing.
|
||||||
@@ -2496,13 +2498,26 @@ static int sam_emac_interrupt(struct sam_emac_s *priv)
|
|||||||
|
|
||||||
wd_cancel(priv->txtimeout);
|
wd_cancel(priv->txtimeout);
|
||||||
|
|
||||||
/* Make sure that the TX poll timer is running (if it is already
|
/* Check if the poll timer is running. If it is not, then start it
|
||||||
* running, the following would restart it). This is necessary to
|
* now. There is a race condition here: We may test the time
|
||||||
* avoid certain race conditions where the polling sequence can be
|
* remaining on the poll timer and determine that it is still running,
|
||||||
* interrupted.
|
* but then the timer expires immiately. That should not be problem,
|
||||||
|
* however, the poll timer processing should be in the work queue and
|
||||||
|
* should execute immediately after we complete the TX poll.
|
||||||
|
* Inefficient, but not fatal.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(void)wd_start(priv->txpoll, SAM_WDDELAY, sam_poll_expiry, 1, priv);
|
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, SAM_WDDELAY, sam_poll_expiry,
|
||||||
|
1, priv);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cancel any pending poll work */
|
/* Cancel any pending poll work */
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* arch/arm/src/stm32/stm32_eth.c
|
* arch/arm/src/stm32/stm32_eth.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2011-2012, 2014, 2016 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2011-2012, 2014, 2016-2017 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -1927,17 +1927,32 @@ static void stm32_txdone(FAR struct stm32_ethmac_s *priv)
|
|||||||
|
|
||||||
if (priv->inflight <= 0)
|
if (priv->inflight <= 0)
|
||||||
{
|
{
|
||||||
|
int delay;
|
||||||
|
|
||||||
/* Cancel the TX timeout */
|
/* Cancel the TX timeout */
|
||||||
|
|
||||||
wd_cancel(priv->txtimeout);
|
wd_cancel(priv->txtimeout);
|
||||||
|
|
||||||
/* Then make sure that the TX poll timer is running (if it is already
|
/* Check if the poll timer is running. If it is not, then start it
|
||||||
* running, the following would restart it). This is necessary to
|
* now. There is a race condition here: We may test the time
|
||||||
* avoid certain race conditions where the polling sequence can be
|
* remaining on the poll timer and determine that it is still running,
|
||||||
* interrupted.
|
* 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.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(void)wd_start(priv->txpoll, STM32_WDDELAY, stm32_poll_expiry, 1, priv);
|
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. */
|
/* And disable further TX interrupts. */
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* arch/arm/src/stm32f7/stm32_ethernet.c
|
* arch/arm/src/stm32f7/stm32_ethernet.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015-2016 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2015-2017 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -2040,17 +2040,32 @@ static void stm32_txdone(struct stm32_ethmac_s *priv)
|
|||||||
|
|
||||||
if (priv->inflight <= 0)
|
if (priv->inflight <= 0)
|
||||||
{
|
{
|
||||||
|
int delay;
|
||||||
|
|
||||||
/* Cancel the TX timeout */
|
/* Cancel the TX timeout */
|
||||||
|
|
||||||
wd_cancel(priv->txtimeout);
|
wd_cancel(priv->txtimeout);
|
||||||
|
|
||||||
/* Then make sure that the TX poll timer is running (if it is already
|
/* Check if the poll timer is running. If it is not, then start it
|
||||||
* running, the following would restart it). This is necessary to
|
* now. There is a race condition here: We may test the time
|
||||||
* avoid certain race conditions where the polling sequence can be
|
* remaining on the poll timer and determine that it is still running,
|
||||||
* interrupted.
|
* but then the timer expires immiately. That should not be problem,
|
||||||
|
* however, the poll timer processing should be in the work queue and
|
||||||
|
* should execute immediately after we complete the TX poll.
|
||||||
|
* Inefficient, but not fatal.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(void)wd_start(priv->txpoll, STM32_WDDELAY, stm32_poll_expiry, 1, priv);
|
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. */
|
/* And disable further TX interrupts. */
|
||||||
|
|
||||||
|
|||||||
@@ -1272,7 +1272,8 @@ static void tiva_poll_expiry(int argc, wdparm_t arg, ...)
|
|||||||
* cycle.
|
* cycle.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(void)wd_start(priv->ld_txpoll, TIVA_WDDELAY, tiva_poll_expiry, 1, arg);
|
(void)wd_start(priv->ld_txpoll, TIVA_WDDELAY, tiva_poll_expiry,
|
||||||
|
1, arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1425,7 +1426,8 @@ static int tiva_ifup(struct net_driver_s *dev)
|
|||||||
|
|
||||||
/* Set and activate a timer process */
|
/* Set and activate a timer process */
|
||||||
|
|
||||||
(void)wd_start(priv->ld_txpoll, TIVA_WDDELAY, tiva_poll_expiry, 1, (uint32_t)priv);
|
(void)wd_start(priv->ld_txpoll, TIVA_WDDELAY, tiva_poll_expiry,
|
||||||
|
1, (uint32_t)priv);
|
||||||
|
|
||||||
priv->ld_bifup = true;
|
priv->ld_bifup = true;
|
||||||
leave_critical_section(flags);
|
leave_critical_section(flags);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* arch/arm/src/tiva/tm4c_ethernet.c
|
* arch/arm/src/tiva/tm4c_ethernet.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2014-2015 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2014-2015, 2017 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -1955,17 +1955,32 @@ static void tiva_txdone(FAR struct tiva_ethmac_s *priv)
|
|||||||
|
|
||||||
if (priv->inflight <= 0)
|
if (priv->inflight <= 0)
|
||||||
{
|
{
|
||||||
|
int delay;
|
||||||
|
|
||||||
/* Cancel the TX timeout */
|
/* Cancel the TX timeout */
|
||||||
|
|
||||||
wd_cancel(priv->txtimeout);
|
wd_cancel(priv->txtimeout);
|
||||||
|
|
||||||
/* Then make sure that the TX poll timer is running (if it is already
|
/* Check if the poll timer is running. If it is not, then start it
|
||||||
* running, the following would restart it). This is necessary to
|
* now. There is a race condition here: We may test the time
|
||||||
* avoid certain race conditions where the polling sequence can be
|
* remaining on the poll timer and determine that it is still running,
|
||||||
* interrupted.
|
* but then the timer expires immiately. That should not be problem,
|
||||||
|
* however, the poll timer processing should be in the work queue and
|
||||||
|
* should execute immediately after we complete the TX poll.
|
||||||
|
* Inefficient, but not fatal.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(void)wd_start(priv->txpoll, TIVA_WDDELAY, tiva_poll_expiry, 1, (uint32_t)priv);
|
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, TIVA_WDDELAY, tiva_poll_expiry,
|
||||||
|
1, (uint32_t)priv);
|
||||||
|
}
|
||||||
|
|
||||||
/* And disable further TX interrupts. */
|
/* And disable further TX interrupts. */
|
||||||
|
|
||||||
@@ -2306,7 +2321,8 @@ static void tiva_poll_work(FAR void *arg)
|
|||||||
|
|
||||||
/* Setup the watchdog poll timer again */
|
/* Setup the watchdog poll timer again */
|
||||||
|
|
||||||
(void)wd_start(priv->txpoll, TIVA_WDDELAY, tiva_poll_expiry, 1, (uint32_t)priv);
|
(void)wd_start(priv->txpoll, TIVA_WDDELAY, tiva_poll_expiry,
|
||||||
|
1, (uint32_t)priv);
|
||||||
net_unlock();
|
net_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2348,7 +2364,8 @@ static void tiva_poll_expiry(int argc, uint32_t arg, ...)
|
|||||||
* cycle.
|
* cycle.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(void)wd_start(priv->txpoll, TIVA_WDDELAY, tiva_poll_expiry, 1, (uint32_t)priv);
|
(void)wd_start(priv->txpoll, TIVA_WDDELAY, tiva_poll_expiry,
|
||||||
|
1, (uint32_t)priv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2396,7 +2413,8 @@ static int tiva_ifup(struct net_driver_s *dev)
|
|||||||
|
|
||||||
/* Set and activate a timer process */
|
/* Set and activate a timer process */
|
||||||
|
|
||||||
(void)wd_start(priv->txpoll, TIVA_WDDELAY, tiva_poll_expiry, 1, (uint32_t)priv);
|
(void)wd_start(priv->txpoll, TIVA_WDDELAY, tiva_poll_expiry,
|
||||||
|
1, (uint32_t)priv);
|
||||||
|
|
||||||
/* Enable the Ethernet interrupt */
|
/* Enable the Ethernet interrupt */
|
||||||
|
|
||||||
|
|||||||
@@ -2097,7 +2097,8 @@ static void pic32mz_poll_expiry(int argc, wdparm_t arg, ...)
|
|||||||
* cycle.
|
* cycle.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(void)wd_start(priv->pd_txpoll, PIC32MZ_WDDELAY, pic32mz_poll_expiry, 1, arg);
|
(void)wd_start(priv->pd_txpoll, PIC32MZ_WDDELAY, pic32mz_poll_expiry,
|
||||||
|
1, arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* arch/misoc/src/commong/misoc_net_net.c
|
* arch/misoc/src/commong/misoc_net_net.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2016-2017 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
* Ramtin Amin <keytwo@gmail.com>
|
* Ramtin Amin <keytwo@gmail.com>
|
||||||
*
|
*
|
||||||
@@ -542,6 +542,8 @@ static void misoc_net_receive(FAR struct misoc_net_driver_s *priv)
|
|||||||
|
|
||||||
static void misoc_net_txdone(FAR struct misoc_net_driver_s *priv)
|
static void misoc_net_txdone(FAR struct misoc_net_driver_s *priv)
|
||||||
{
|
{
|
||||||
|
int delay;
|
||||||
|
|
||||||
/* Check for errors and update statistics */
|
/* Check for errors and update statistics */
|
||||||
|
|
||||||
NETDEV_TXDONE(priv->misoc_net_dev);
|
NETDEV_TXDONE(priv->misoc_net_dev);
|
||||||
@@ -554,14 +556,25 @@ static void misoc_net_txdone(FAR struct misoc_net_driver_s *priv)
|
|||||||
|
|
||||||
wd_cancel(priv->misoc_net_txtimeout);
|
wd_cancel(priv->misoc_net_txtimeout);
|
||||||
|
|
||||||
/* Then make sure that the TX poll timer is running (if it is already
|
/* Check if the poll timer is running. If it is not, then start it now.
|
||||||
* running, the following would restart it). This is necessary to
|
* There is a race condition here: We may test the time remaining on the
|
||||||
* avoid certain race conditions where the polling sequence can be
|
* poll timer and determine that it is still running, but then the timer
|
||||||
* interrupted.
|
* expires immiately. That should not be problem, however, the poll timer
|
||||||
|
* processing should be in the work queue and should execute immediately
|
||||||
|
* after we complete the TX poll. Inefficient, but not fatal.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(void)wd_start(priv->misoc_net_txpoll, MISOC_NET_WDDELAY,
|
delay = wd_gettime(priv->misoc_net_txpoll);
|
||||||
misoc_net_poll_expiry, 1, (wdparm_t)priv);
|
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->misoc_net_txpoll, MISOC_NET_WDDELAY,
|
||||||
|
misoc_net_poll_expiry, 1, (wdparm_t)priv);
|
||||||
|
}
|
||||||
|
|
||||||
/* And disable further TX interrupts. */
|
/* And disable further TX interrupts. */
|
||||||
|
|
||||||
|
|||||||
@@ -1980,7 +1980,8 @@ static void ez80emac_poll_expiry(int argc, wdparm_t arg, ...)
|
|||||||
* cycle.
|
* cycle.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(void)wd_start(priv->txpoll, EMAC_WDDELAY, ez80emac_poll_expiry, 1, arg);
|
(void)wd_start(priv->txpoll, EMAC_WDDELAY, ez80emac_poll_expiry,
|
||||||
|
1, arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1453,7 +1453,8 @@ static void dm9x_poll_expiry(int argc, wdparm_t arg, ...)
|
|||||||
* cycle.
|
* cycle.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(void)wd_start(priv->dm_txpoll, DM9X_WDDELAY, dm9x_poll_expiry, 1, arg);
|
(void)wd_start(priv->dm_txpoll, DM9X_WDDELAY, dm9x_poll_expiry,
|
||||||
|
1, arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+20
-7
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* drivers/net/enc28j60.c
|
* drivers/net/enc28j60.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010-2012, 2014-2016 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2010-2012, 2014-2017 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* References:
|
* References:
|
||||||
@@ -1275,6 +1275,8 @@ static void enc_linkstatus(FAR struct enc_driver_s *priv)
|
|||||||
|
|
||||||
static void enc_txif(FAR struct enc_driver_s *priv)
|
static void enc_txif(FAR struct enc_driver_s *priv)
|
||||||
{
|
{
|
||||||
|
int delay;
|
||||||
|
|
||||||
/* Update statistics */
|
/* Update statistics */
|
||||||
|
|
||||||
NETDEV_TXDONE(&priv->dev);
|
NETDEV_TXDONE(&priv->dev);
|
||||||
@@ -1287,14 +1289,25 @@ static void enc_txif(FAR struct enc_driver_s *priv)
|
|||||||
|
|
||||||
wd_cancel(priv->txtimeout);
|
wd_cancel(priv->txtimeout);
|
||||||
|
|
||||||
/* Then make sure that the TX poll timer is running (if it is already
|
/* Check if the poll timer is running. If it is not, then start it now.
|
||||||
* running, the following would restart it). This is necessary to
|
* There is a race condition here: We may test the time remaining on the
|
||||||
* avoid certain race conditions where the polling sequence can be
|
* poll timer and determine that it is still running, but then the timer
|
||||||
* interrupted.
|
* expires immiately. That should not be problem, however, the poll timer
|
||||||
|
* processing should be in the work queue and should execute immediately
|
||||||
|
* after we complete the TX poll. Inefficient, but not fatal.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(void)wd_start(priv->txpoll, ENC_WDDELAY, enc_polltimer, 1,
|
delay = wd_gettime(priv->txpoll);
|
||||||
(wdparm_t)priv);
|
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, ENC_WDDELAY, enc_polltimer, 1,
|
||||||
|
(wdparm_t)priv);
|
||||||
|
}
|
||||||
|
|
||||||
/* Then poll the network for new XMIT data */
|
/* Then poll the network for new XMIT data */
|
||||||
|
|
||||||
|
|||||||
@@ -1291,18 +1291,32 @@ static void enc_txif(FAR struct enc_driver_s *priv)
|
|||||||
|
|
||||||
if (sq_empty(&priv->txqueue))
|
if (sq_empty(&priv->txqueue))
|
||||||
{
|
{
|
||||||
|
int delay;
|
||||||
|
|
||||||
/* If no further xmits are pending, then cancel the TX timeout */
|
/* If no further xmits are pending, then cancel the TX timeout */
|
||||||
|
|
||||||
wd_cancel(priv->txtimeout);
|
wd_cancel(priv->txtimeout);
|
||||||
|
|
||||||
/* Then make sure that the TX poll timer is running (if it is already
|
/* Check if the poll timer is running. If it is not, then start it
|
||||||
* running, the following would restart it). This is necessary to
|
* now. There is a race condition here: We may test the time
|
||||||
* avoid certain race conditions where the polling sequence can be
|
* remaining on the poll timer and determine that it is still running,
|
||||||
* interrupted.
|
* but then the timer expires immiately. That should not be problem,
|
||||||
|
* however, the poll timer processing should be in the work queue and
|
||||||
|
* should execute immediately after we complete the TX poll.
|
||||||
|
* Inefficient, but not fatal.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(void)wd_start(priv->txpoll, ENC_WDDELAY, enc_polltimer, 1,
|
delay = wd_gettime(priv->txpoll);
|
||||||
(wdparm_t)priv);
|
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, ENC_WDDELAY, enc_polltimer, 1,
|
||||||
|
(wdparm_t)priv);
|
||||||
|
}
|
||||||
|
|
||||||
/* Poll for TX packets from the networking layer */
|
/* Poll for TX packets from the networking layer */
|
||||||
|
|
||||||
|
|||||||
+18
-5
@@ -805,6 +805,7 @@ static void ftmac100_receive(FAR struct ftmac100_driver_s *priv)
|
|||||||
static void ftmac100_txdone(FAR struct ftmac100_driver_s *priv)
|
static void ftmac100_txdone(FAR struct ftmac100_driver_s *priv)
|
||||||
{
|
{
|
||||||
FAR struct ftmac100_txdes_s *txdes;
|
FAR struct ftmac100_txdes_s *txdes;
|
||||||
|
int delay;
|
||||||
|
|
||||||
/* Check if a Tx was pending */
|
/* Check if a Tx was pending */
|
||||||
|
|
||||||
@@ -843,13 +844,25 @@ static void ftmac100_txdone(FAR struct ftmac100_driver_s *priv)
|
|||||||
|
|
||||||
wd_cancel(priv->ft_txtimeout);
|
wd_cancel(priv->ft_txtimeout);
|
||||||
|
|
||||||
/* Then make sure that the TX poll timer is running (if it is already
|
/* Check if the poll timer is running. If it is not, then start it now.
|
||||||
* running, the following would restart it). This is necessary to avoid
|
* There is a race condition here: We may test the time remaining on the
|
||||||
* certain race conditions where the polling sequence can be interrupted.
|
* poll timer and determine that it is still running, but then the timer
|
||||||
|
* expires immiately. That should not be problem, however, the poll timer
|
||||||
|
* processing should be in the work queue and should execute immediately
|
||||||
|
* after we complete the TX poll. Inefficient, but not fatal.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(void)wd_start(priv->ft_txpoll, FTMAC100_WDDELAY, ftmac100_poll_expiry, 1,
|
delay = wd_gettime(priv->ft_txpoll);
|
||||||
(wdparm_t)priv);
|
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->ft_txpoll, FTMAC100_WDDELAY, ftmac100_poll_expiry,
|
||||||
|
1, (wdparm_t)priv);
|
||||||
|
}
|
||||||
|
|
||||||
/* Then poll the network for new XMIT data */
|
/* Then poll the network for new XMIT data */
|
||||||
|
|
||||||
|
|||||||
@@ -338,7 +338,8 @@ static int lo_ifup(FAR struct net_driver_s *dev)
|
|||||||
|
|
||||||
/* Set and activate a timer process */
|
/* Set and activate a timer process */
|
||||||
|
|
||||||
(void)wd_start(priv->lo_polldog, LO_WDDELAY, lo_poll_expiry, 1, (wdparm_t)priv);
|
(void)wd_start(priv->lo_polldog, LO_WDDELAY, lo_poll_expiry,
|
||||||
|
1, (wdparm_t)priv);
|
||||||
|
|
||||||
priv->lo_bifup = true;
|
priv->lo_bifup = true;
|
||||||
return OK;
|
return OK;
|
||||||
|
|||||||
+20
-7
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* drivers/net/skeleton.c
|
* drivers/net/skeleton.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -463,6 +463,8 @@ static void skel_receive(FAR struct skel_driver_s *priv)
|
|||||||
|
|
||||||
static void skel_txdone(FAR struct skel_driver_s *priv)
|
static void skel_txdone(FAR struct skel_driver_s *priv)
|
||||||
{
|
{
|
||||||
|
int delay;
|
||||||
|
|
||||||
/* Check for errors and update statistics */
|
/* Check for errors and update statistics */
|
||||||
|
|
||||||
NETDEV_TXDONE(priv->sk_dev);
|
NETDEV_TXDONE(priv->sk_dev);
|
||||||
@@ -475,14 +477,25 @@ static void skel_txdone(FAR struct skel_driver_s *priv)
|
|||||||
|
|
||||||
wd_cancel(priv->sk_txtimeout);
|
wd_cancel(priv->sk_txtimeout);
|
||||||
|
|
||||||
/* Then make sure that the TX poll timer is running (if it is already
|
/* Check if the poll timer is running. If it is not, then start it now.
|
||||||
* running, the following would restart it). This is necessary to
|
* There is a race condition here: We may test the time remaining on the
|
||||||
* avoid certain race conditions where the polling sequence can be
|
* poll timer and determine that it is still running, but then the timer
|
||||||
* interrupted.
|
* expires immiately. That should not be problem, however, the poll timer
|
||||||
|
* processing should be in the work queue and should execute immediately
|
||||||
|
* after we complete the TX poll. Inefficient, but not fatal.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(void)wd_start(priv->sk_txpoll, skeleton_WDDELAY, skel_poll_expiry, 1,
|
delay = wd_gettime(priv->sk_txpoll);
|
||||||
(wdparm_t)priv);
|
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->sk_txpoll, skeleton_WDDELAY, skel_poll_expiry,
|
||||||
|
1, (wdparm_t)priv);
|
||||||
|
}
|
||||||
|
|
||||||
/* And disable further TX interrupts. */
|
/* And disable further TX interrupts. */
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -656,7 +656,8 @@ static int tun_ifup(struct net_driver_s *dev)
|
|||||||
|
|
||||||
/* Set and activate a timer process */
|
/* Set and activate a timer process */
|
||||||
|
|
||||||
(void)wd_start(priv->txpoll, TUN_WDDELAY, tun_poll_expiry, 1, (wdparm_t)priv);
|
(void)wd_start(priv->txpoll, TUN_WDDELAY, tun_poll_expiry,
|
||||||
|
1, (wdparm_t)priv);
|
||||||
|
|
||||||
priv->bifup = true;
|
priv->bifup = true;
|
||||||
return OK;
|
return OK;
|
||||||
|
|||||||
Reference in New Issue
Block a user