Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix rxtimeout workaround #365

Merged
merged 2 commits into from
Mar 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions arch/risc-v/src/mpfs/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -833,6 +833,14 @@ config MPFS_PHYINIT
---help---
call mpfs_phy_boardinitialize() on init

config MPFS_PHY_RX_TIMEOUT_WA
int "RX restart timeout workaround"
default 0
---help---
This is a workaround for LAN8742A rev A and B silicon errata.
Reset ETH interface in case no RX packets have been received
in configured time. Set to 0 to disable.

config MPFS_ETH0_PHY_KSZ9477
bool "Use ksz9477 switch as an SGMII PHY for ETH0"
default n
Expand Down
19 changes: 16 additions & 3 deletions arch/risc-v/src/mpfs/mpfs_ethernet.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,14 @@

#define MPFS_TXTIMEOUT (60 * CLK_TCK)

/* RX timeout = 30s */
/* RX timeout: Workaround for LAN8742A rev A and B silicon errata
* "Cable diagnostics incorrectly returns Open cable connection for
* terminated cable"
*/

#define MPFS_RXTIMEOUT (30 * CLK_TCK)
#if CONFIG_MPFS_PHY_RX_TIMEOUT_WA != 0
#define MPFS_RXTIMEOUT (CONFIG_MPFS_PHY_RX_TIMEOUT_WA * CLK_TCK)
#endif

/* PHY reset tim in loop counts */

Expand Down Expand Up @@ -269,7 +274,9 @@ struct mpfs_ethmac_s
uint8_t phyaddr; /* PHY address */
#endif
struct wdog_s txtimeout; /* TX timeout timer */
#ifdef MPFS_RXTIMEOUT
struct wdog_s rxtimeout; /* RX timeout timer */
#endif
struct work_s irqwork; /* For deferring interrupt work to the work queue */
struct work_s pollwork; /* For deferring poll work to the work queue */
struct work_s timeoutwork; /* For managing timeouts */
Expand Down Expand Up @@ -474,13 +481,15 @@ static int mpfs_interrupt_0(int irq, void *context, void *arg)
wd_cancel(&priv->txtimeout);
}

if ((isr & GEM_INT_RECEIVE_COMPLETE) != 0)
#ifdef MPFS_RXTIMEOUT
if ((isr & INT_RX) != 0)
{
/* If a RX transfer just completed, restart the timeout */

wd_start(&priv->rxtimeout, MPFS_RXTIMEOUT,
mpfs_txtimeout_expiry, (wdparm_t)priv);
}
#endif

/* Schedule to perform the interrupt processing on the worker thread. */

Expand Down Expand Up @@ -1570,12 +1579,14 @@ static int mpfs_ifup(struct net_driver_s *dev)
up_enable_irq(priv->mac_q_int[2]);
up_enable_irq(priv->mac_q_int[3]);

#ifdef MPFS_RXTIMEOUT
/* Set up the RX timeout. If we don't receive anything in time, try
* to re-initialize
*/

wd_start(&priv->rxtimeout, MPFS_RXTIMEOUT,
mpfs_txtimeout_expiry, (wdparm_t)priv);
#endif

return OK;
}
Expand Down Expand Up @@ -1620,9 +1631,11 @@ static int mpfs_ifdown(struct net_driver_s *dev)

wd_cancel(&priv->txtimeout);

#ifdef MPFS_RXTIMEOUT
/* Cancel the RX timeout timers */

wd_cancel(&priv->rxtimeout);
#endif

/* Put the MAC in its reset, non-operational state. This should be
* a known configuration that will guarantee the mpfs_ifup() always
Expand Down
Loading