diff options
author | Evan Lojewski <github@meklort.com> | 2020-11-19 19:23:06 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-19 19:23:06 -0700 |
commit | d2a90411c94cc8ea175b879d16a30705d206ae84 (patch) | |
tree | 8efef70894947fae30970aaa2cbcd63882014c50 | |
parent | 5520cf3dff14b3805fafafbfc05853a03aeafcfc (diff) | |
download | bcm5719-ortega-d2a90411c94cc8ea175b879d16a30705d206ae84.tar.gz bcm5719-ortega-d2a90411c94cc8ea175b879d16a30705d206ae84.zip |
ape: Reset the network interface any time the APE mode is incorrect. (#173)
In certain situations, such as a driver unload, the APE mode can be reset.
This adds APE.mode to the current state change check to enable early recovery
from events such as a driver unload.
-rw-r--r-- | ape/main.c | 10 | ||||
-rw-r--r-- | libs/Network/include/Network.h | 1 | ||||
-rw-r--r-- | libs/Network/ports.c | 17 |
3 files changed, 28 insertions, 0 deletions
@@ -327,6 +327,16 @@ void __attribute__((noreturn)) loaderLoop(void) } } } + else if (!Network_checkEnableState(gPort)) + { + printf("APE mode change, resetting.\n"); + wait_for_all_rx(); + RMU_init(); + NCSI_reload(ALWAYS_RESET); + + // Update host state to make sure we don't reset twice if it's changed. + host_state = SHM.HostDriverState.bits.State; + } Network_checkPortState(gPort); } diff --git a/libs/Network/include/Network.h b/libs/Network/include/Network.h index 0d13a90..ec57a17 100644 --- a/libs/Network/include/Network.h +++ b/libs/Network/include/Network.h @@ -111,6 +111,7 @@ void Network_resetRX(NetworkPort_t *port, reload_type_t reset_phy); void Network_checkPortState(NetworkPort_t *port); bool Network_updatePortState(NetworkPort_t *port); +bool Network_checkEnableState(NetworkPort_t *port); bool Network_isLinkUp(NetworkPort_t *port); void Network_resetLink(NetworkPort_t *port); diff --git a/libs/Network/ports.c b/libs/Network/ports.c index 0e93bf9..460d2d4 100644 --- a/libs/Network/ports.c +++ b/libs/Network/ports.c @@ -846,6 +846,23 @@ void Network_resetRX(NetworkPort_t *port, reload_type_t reset_phy) } } +bool Network_checkEnableState(NetworkPort_t *port) +{ + // Ensure APE mode is set properly + if ((APE.Mode.r32 & port->APEModeEnable.r32) != port->APEModeEnable.r32) + { + return false; + } + + // Ensure APE mode2 is set properly + if ((APE.Mode2.r32 & port->APEMode2Enable.r32) != port->APEMode2Enable.r32) + { + return false; + } + + return true; +} + void Network_InitPort(NetworkPort_t *port, reload_type_t reset_phy) { RegMIIStatus_t stat; |