diff --git a/arch/arm/src/lpc17xx/lpc17_ethernet.c b/arch/arm/src/lpc17xx/lpc17_ethernet.c index 54574021bde..dc03f96e256 100644 --- a/arch/arm/src/lpc17xx/lpc17_ethernet.c +++ b/arch/arm/src/lpc17xx/lpc17_ethernet.c @@ -1326,6 +1326,14 @@ static int lpc17_interrupt(int irq, void *context) work_cancel(HPWORK, &priv->lp_txwork); + /* Then make sure that the TX poll timer is running (if it is + * already running, the following would 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 */ work_queue(HPWORK, &priv->lp_txwork, (worker_t)lpc17_txdone_work, diff --git a/arch/arm/src/lpc43xx/lpc43_ethernet.c b/arch/arm/src/lpc43xx/lpc43_ethernet.c index c36c87f9c0c..52f535f0179 100644 --- a/arch/arm/src/lpc43xx/lpc43_ethernet.c +++ b/arch/arm/src/lpc43xx/lpc43_ethernet.c @@ -1218,8 +1218,13 @@ static int lpc43_txpoll(struct net_driver_s *dev) * Function: lpc43_dopoll * * Description: - * The function is called when a frame is received using the DMA receive - * interrupt. It scans the RX descriptors to the received frame. + * The function is called in order to perform an out-of-sequence TX poll. + * This is done: + * + * 1. After completion of a transmission (lpc43_txdone), + * 2. When new TX data is available (lpc43_txavail_process), and + * 3. After a TX timeout to restart the sending process + * (lpc43_txtimeout_process). * * Parameters: * priv - Reference to the driver state structure @@ -1864,8 +1869,18 @@ static void lpc43_txdone(FAR struct lpc43_ethmac_s *priv) if (priv->inflight <= 0) { + /* Cancel the TX timeout */ + wd_cancel(priv->txtimeout); + /* Then make sure that the TX poll timer is running (if it is already + * running, the following would 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. */ lpc43_disableint(priv, ETH_DMAINT_TI); diff --git a/arch/arm/src/sam34/sam_emac.c b/arch/arm/src/sam34/sam_emac.c index afb7406c88f..882603221b5 100644 --- a/arch/arm/src/sam34/sam_emac.c +++ b/arch/arm/src/sam34/sam_emac.c @@ -923,7 +923,13 @@ static int sam_txpoll(struct net_driver_s *dev) * Function: sam_dopoll * * Description: - * Perform the uIP poll. + * The function is called in order to perform an out-of-sequence TX poll. + * This is done: + * + * 1. After completion of a transmission (sam_txdone), + * 2. When new TX data is available (sam_txavail_process), and + * 3. After a TX timeout to restart the sending process + * (sam_txtimeout_process). * * Parameters: * priv - Reference to the driver state structure @@ -1671,6 +1677,14 @@ static int sam_emac_interrupt(int irq, void *context) */ wd_cancel(priv->txtimeout); + + /* Make sure that the TX poll timer is running (if it is already + * running, the following would 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 */ diff --git a/arch/arm/src/sama5/sam_emaca.c b/arch/arm/src/sama5/sam_emaca.c index a6b01eb8d33..4d2e61b3fe0 100644 --- a/arch/arm/src/sama5/sam_emaca.c +++ b/arch/arm/src/sama5/sam_emaca.c @@ -899,7 +899,12 @@ static int sam_txpoll(struct net_driver_s *dev) * Function: sam_dopoll * * Description: - * Perform the uIP poll. + * The function is called in order to perform an out-of-sequence TX poll. + * This is done: + * + * 1. After completion of a transmission (sam_txdone), + * 2. When new TX data is available (sam_txavail), and + * 3. After a TX timeout to restart the sending process (sam_txtimeout). * * Parameters: * priv - Reference to the driver state structure diff --git a/arch/arm/src/sama5/sam_emacb.c b/arch/arm/src/sama5/sam_emacb.c index a84f3bf2e70..154f241f1f4 100644 --- a/arch/arm/src/sama5/sam_emacb.c +++ b/arch/arm/src/sama5/sam_emacb.c @@ -1262,7 +1262,13 @@ static int sam_txpoll(struct net_driver_s *dev) * Function: sam_dopoll * * Description: - * Perform the uIP poll. + * The function is called in order to perform an out-of-sequence TX poll. + * This is done: + * + * 1. After completion of a transmission (sam_txdone), + * 2. When new TX data is available (sam_txavail_process), and + * 3. After a TX timeout to restart the sending process + * (sam_txtimeout_process). * * Parameters: * priv - Reference to the driver state structure @@ -2062,6 +2068,14 @@ static int sam_emac_interrupt(struct sam_emac_s *priv) */ wd_cancel(priv->txtimeout); + + /* Make sure that the TX poll timer is running (if it is already + * running, the following would 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 */ diff --git a/arch/arm/src/sama5/sam_gmac.c b/arch/arm/src/sama5/sam_gmac.c index 0313f5b6bbe..0129d8e549d 100644 --- a/arch/arm/src/sama5/sam_gmac.c +++ b/arch/arm/src/sama5/sam_gmac.c @@ -831,7 +831,12 @@ static int sam_txpoll(struct net_driver_s *dev) * Function: sam_dopoll * * Description: - * Perform the uIP poll. + * The function is called in order to perform an out-of-sequence TX poll. + * This is done: + * + * 1. After completion of a transmission (sam_txdone), + * 2. When new TX data is available (sam_txavail), and + * 3. After a TX timeout to restart the sending process (sam_txtimeout). * * Parameters: * priv - Reference to the driver state structure diff --git a/arch/arm/src/samv7/sam_emac.c b/arch/arm/src/samv7/sam_emac.c index d617e0c4059..d493b3ecb9b 100644 --- a/arch/arm/src/samv7/sam_emac.c +++ b/arch/arm/src/samv7/sam_emac.c @@ -1554,7 +1554,14 @@ static int sam_txpoll(struct net_driver_s *dev) * Function: sam_dopoll * * Description: - * Perform the network poll. + * The function is called in order to perform an out-of-sequence TX poll. + * This is done: + * + * 1. After completion of a transmission (sam_txdone), + * 2. When new TX data is available (sam_txavail_process), + * 3. For certain TX errors (sam_txerr_interrupt), and + * 4. After a TX timeout to restart the sending process + * (sam_txtimeout_process). * * Parameters: * priv - Reference to the driver state structure @@ -2507,6 +2514,14 @@ static int sam_emac_interrupt(struct sam_emac_s *priv) */ wd_cancel(priv->txtimeout); + + /* Make sure that the TX poll timer is running (if it is already + * running, the following would 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 */ diff --git a/arch/arm/src/stm32/stm32_eth.c b/arch/arm/src/stm32/stm32_eth.c index 3838f79cdb1..c534a01f7be 100644 --- a/arch/arm/src/stm32/stm32_eth.c +++ b/arch/arm/src/stm32/stm32_eth.c @@ -1286,8 +1286,13 @@ static int stm32_txpoll(struct net_driver_s *dev) * Function: stm32_dopoll * * Description: - * The function is called when a frame is received using the DMA receive - * interrupt. It scans the RX descriptors to the received frame. + * The function is called in order to perform an out-of-sequence TX poll. + * This is done: + * + * 1. After completion of a transmission (stm32_txdone), + * 2. When new TX data is available (stm32_txavail_process), and + * 3. After a TX timeout to restart the sending process + * (stm32_txtimeout_process). * * Parameters: * priv - Reference to the driver state structure @@ -1909,7 +1914,7 @@ static void stm32_freeframe(FAR struct stm32_ethmac_s *priv) * * Description: * An interrupt was received indicating that the last TX packet - * transfer(s) are complete. + * transfer(s) are complete. * * Parameters: * priv - Reference to the driver state structure @@ -1939,7 +1944,9 @@ static void stm32_txdone(FAR struct stm32_ethmac_s *priv) wd_cancel(priv->txtimeout); /* Then make sure that the TX poll timer is running (if it is already - * running, the following would restart it). + * running, the following would 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); @@ -2549,7 +2556,6 @@ static inline void stm32_txavail_process(FAR struct stm32_ethmac_s *priv) stm32_dopoll(priv); } - } /**************************************************************************** diff --git a/arch/arm/src/stm32f7/stm32_ethernet.c b/arch/arm/src/stm32f7/stm32_ethernet.c index 768a79979db..6d4e388b3d3 100644 --- a/arch/arm/src/stm32f7/stm32_ethernet.c +++ b/arch/arm/src/stm32f7/stm32_ethernet.c @@ -1356,8 +1356,13 @@ static int stm32_txpoll(struct net_driver_s *dev) * Function: stm32_dopoll * * Description: - * The function is called when a frame is received using the DMA receive - * interrupt. It scans the RX descriptors to the received frame. + * The function is called in order to perform an out-of-sequence TX poll. + * This is done: + * + * 1. After completion of a transmission (stm32_txdone), + * 2. When new TX data is available (stm32_txavail_process), and + * 3. After a TX timeout to restart the sending process + * (stm32_txtimeout_process). * * Parameters: * priv - Reference to the driver state structure @@ -2051,8 +2056,18 @@ static void stm32_txdone(struct stm32_ethmac_s *priv) if (priv->inflight <= 0) { + /* Cancel the TX timeout */ + wd_cancel(priv->txtimeout); + /* Then make sure that the TX poll timer is running (if it is already + * running, the following would 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); diff --git a/arch/arm/src/tiva/tm4c_ethernet.c b/arch/arm/src/tiva/tm4c_ethernet.c index 1a61f16672d..465d695c9d6 100644 --- a/arch/arm/src/tiva/tm4c_ethernet.c +++ b/arch/arm/src/tiva/tm4c_ethernet.c @@ -1325,8 +1325,13 @@ static int tiva_txpoll(struct net_driver_s *dev) * Function: tiva_dopoll * * Description: - * The function is called when a frame is received using the DMA receive - * interrupt. It scans the RX descriptors to the received frame. + * The function is called in order to perform an out-of-sequence TX poll. + * This is done: + * + * 1. After completion of a transmission (tiva_txdone), + * 2. When new TX data is available (tiva_txavail_process), and + * 3. After a TX timeout to restart the sending process + * (tiva_txtimeout_process). * * Parameters: * priv - Reference to the driver state structure @@ -1959,8 +1964,18 @@ static void tiva_txdone(FAR struct tiva_ethmac_s *priv) if (priv->inflight <= 0) { + /* Cancel the TX timeout */ + wd_cancel(priv->txtimeout); + /* Then make sure that the TX poll timer is running (if it is already + * running, the following would 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. */ tiva_disableint(priv, EMAC_DMAINT_TI);