stm32f4/f7/h7_eth: Improvements in Ethernet DMA error handling.

* Error handling for abnormal interrupts and DMA errors is now
enabled for all builds, regardless of any DEBUG configuration.

* Error handling resets the MAC for the specific errors that
may halt the Ethernet operation, instead of everything as it
was before.
This commit is contained in:
Fotis Panagiotopoulos 2023-08-03 19:05:18 +03:00 committed by Alan Carvalho de Assis
parent 9e4a9fe32b
commit f3945560c0
3 changed files with 57 additions and 51 deletions

View File

@ -587,11 +587,7 @@
#define ETH_DMAINT_XMIT_ENABLE (ETH_DMAINT_NIS | ETH_DMAINT_TI) #define ETH_DMAINT_XMIT_ENABLE (ETH_DMAINT_NIS | ETH_DMAINT_TI)
#define ETH_DMAINT_XMIT_DISABLE (ETH_DMAINT_TI) #define ETH_DMAINT_XMIT_DISABLE (ETH_DMAINT_TI)
#ifdef CONFIG_DEBUG_NET #define ETH_DMAINT_ERROR_ENABLE (ETH_DMAINT_AIS | ETH_DMAINT_ABNORMAL)
# define ETH_DMAINT_ERROR_ENABLE (ETH_DMAINT_AIS | ETH_DMAINT_ABNORMAL)
#else
# define ETH_DMAINT_ERROR_ENABLE (0)
#endif
/* Helpers ******************************************************************/ /* Helpers ******************************************************************/
@ -2043,21 +2039,27 @@ static void stm32_interrupt_work(void *arg)
stm32_putreg(ETH_DMAINT_AIS, STM32_ETH_DMASR); stm32_putreg(ETH_DMAINT_AIS, STM32_ETH_DMASR);
/* As per the datasheet's recommendation, the MAC /* In case of any error that stops the DMA, reset the MAC. */
* needs to be reset for all abnormal events. The
* scheduled job will take the interface down and
* up again.
*/
work_queue(ETHWORK, &priv->irqwork, stm32_txtimeout_work, priv, 0); if (dmasr & (ETH_DMAINT_FBEI | ETH_DMAINT_RPSI |
ETH_DMAINT_TJTI | ETH_DMAINT_TPSI))
{
/* As per the datasheet's recommendation, the MAC
* needs to be reset for all fatal errors. The
* scheduled job will take the interface down and
* up again.
*/
/* Interrupts need to remain disabled, no other work_queue(ETHWORK, &priv->irqwork, stm32_txtimeout_work, priv, 0);
* processing will take place. After reset
* everything will be restored.
*/
net_unlock(); /* Interrupts need to remain disabled, no other
return; * processing will take place. After reset
* everything will be restored.
*/
net_unlock();
return;
}
} }
net_unlock(); net_unlock();

View File

@ -572,11 +572,7 @@
#define ETH_DMAINT_XMIT_ENABLE (ETH_DMAINT_NIS | ETH_DMAINT_TI) #define ETH_DMAINT_XMIT_ENABLE (ETH_DMAINT_NIS | ETH_DMAINT_TI)
#define ETH_DMAINT_XMIT_DISABLE (ETH_DMAINT_TI) #define ETH_DMAINT_XMIT_DISABLE (ETH_DMAINT_TI)
#ifdef CONFIG_DEBUG_NET #define ETH_DMAINT_ERROR_ENABLE (ETH_DMAINT_AIS | ETH_DMAINT_ABNORMAL)
# define ETH_DMAINT_ERROR_ENABLE (ETH_DMAINT_AIS | ETH_DMAINT_ABNORMAL)
#else
# define ETH_DMAINT_ERROR_ENABLE (0)
#endif
/* Helpers ******************************************************************/ /* Helpers ******************************************************************/
@ -2133,21 +2129,27 @@ static void stm32_interrupt_work(void *arg)
stm32_putreg(ETH_DMAINT_AIS, STM32_ETH_DMASR); stm32_putreg(ETH_DMAINT_AIS, STM32_ETH_DMASR);
/* As per the datasheet's recommendation, the MAC /* In case of any error that stops the DMA, reset the MAC. */
* needs to be reset for all abnormal events. The
* scheduled job will take the interface down and
* up again.
*/
work_queue(ETHWORK, &priv->irqwork, stm32_txtimeout_work, priv, 0); if (dmasr & (ETH_DMAINT_FBEI | ETH_DMAINT_RPSI |
ETH_DMAINT_TJTI | ETH_DMAINT_TPSI))
{
/* As per the datasheet's recommendation, the MAC
* needs to be reset for all fatal errors. The
* scheduled job will take the interface down and
* up again.
*/
/* Interrupts need to remain disabled, no other work_queue(ETHWORK, &priv->irqwork, stm32_txtimeout_work, priv, 0);
* processing will take place. After reset
* everything will be restored.
*/
net_unlock(); /* Interrupts need to remain disabled, no other
return; * processing will take place. After reset
* everything will be restored.
*/
net_unlock();
return;
}
} }
net_unlock(); net_unlock();

View File

@ -578,11 +578,7 @@
#define ETH_DMAINT_XMIT_ENABLE (ETH_DMACIER_NIE | ETH_DMACIER_TIE) #define ETH_DMAINT_XMIT_ENABLE (ETH_DMACIER_NIE | ETH_DMACIER_TIE)
#define ETH_DMAINT_XMIT_DISABLE (ETH_DMACIER_TIE) #define ETH_DMAINT_XMIT_DISABLE (ETH_DMACIER_TIE)
#ifdef CONFIG_DEBUG_NET #define ETH_DMAINT_ERROR_ENABLE (ETH_DMACIER_AIE | ETH_DMAINT_ABNORMAL)
# define ETH_DMAINT_ERROR_ENABLE (ETH_DMACIER_AIE | ETH_DMAINT_ABNORMAL)
#else
# define ETH_DMAINT_ERROR_ENABLE (0)
#endif
/* Helpers ******************************************************************/ /* Helpers ******************************************************************/
@ -2246,21 +2242,27 @@ static void stm32_interrupt_work(void *arg)
stm32_putreg(ETH_DMACSR_AIS, STM32_ETH_DMACSR); stm32_putreg(ETH_DMACSR_AIS, STM32_ETH_DMACSR);
/* As per the datasheet's recommendation, the MAC /* In case of any error that stops the DMA, reset the MAC. */
* needs to be reset for all abnormal events. The
* scheduled job will take the interface down and
* up again.
*/
work_queue(ETHWORK, &priv->irqwork, stm32_txtimeout_work, priv, 0); if (dmasr & (ETH_DMACIER_CDEE | ETH_DMACSR_FBE |
ETH_DMACSR_RPS | ETH_DMACSR_TPS))
{
/* As per the datasheet's recommendation, the MAC
* needs to be reset for all fatal errors. The
* scheduled job will take the interface down and
* up again.
*/
/* Interrupts need to remain disabled, no other work_queue(ETHWORK, &priv->irqwork, stm32_txtimeout_work, priv, 0);
* processing will take place. After reset
* everything will be restored.
*/
net_unlock(); /* Interrupts need to remain disabled, no other
return; * processing will take place. After reset
* everything will be restored.
*/
net_unlock();
return;
}
} }
net_unlock(); net_unlock();