From 388f0dce16f9847e8a9368569639f4c60c1bf3be Mon Sep 17 00:00:00 2001 From: Evan Lojewski Date: Sun, 13 Jun 2021 20:04:55 -0600 Subject: ape: Fix a possible race condition where MII contention could exist. (#220) This ensure the APE locks the MII interface before accessing it to avoid collisions with the host. --- libs/Network/include/Network.h | 1 + libs/Network/ports.c | 21 +++++++++++++-------- 2 files changed, 14 insertions(+), 8 deletions(-) (limited to 'libs') diff --git a/libs/Network/include/Network.h b/libs/Network/include/Network.h index ec57a17..dadc2e8 100644 --- a/libs/Network/include/Network.h +++ b/libs/Network/include/Network.h @@ -112,6 +112,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); +void Network_setEnableState(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 92391f5..cde3f18 100644 --- a/libs/Network/ports.c +++ b/libs/Network/ports.c @@ -863,6 +863,12 @@ bool Network_checkEnableState(NetworkPort_t *port) return true; } +void Network_setEnableState(NetworkPort_t *port) +{ + APE.Mode.r32 |= port->APEModeEnable.r32; + APE.Mode2.r32 |= port->APEMode2Enable.r32; +} + void Network_InitPort(NetworkPort_t *port, reload_type_t reset_phy) { RegMIIStatus_t stat; @@ -870,20 +876,18 @@ void Network_InitPort(NetworkPort_t *port, reload_type_t reset_phy) RegSHM_CHANNELNcsiChannelStatus_t linkStatus; uint8_t phy = MII_getPhy(port->device); + APE_aquireLock(); + if ((ALWAYS_RESET == reset_phy) || (AS_NEEDED == reset_phy && !Network_isLinkUp(port))) { - APE_aquireLock(); MII_reset(port->device, phy); - APE_releaseLock(); } else { bool updated; // Ensure the PHY is advertising all capabilities and updating if needed. - APE_aquireLock(); updated = MII_UpdateAdvertisement(port->device, phy); - APE_releaseLock(); if (updated) { @@ -900,8 +904,7 @@ void Network_InitPort(NetworkPort_t *port, reload_type_t reset_phy) Network_resetTX(port, reset_phy); Network_resetRX(port, reset_phy); - APE.Mode.r32 |= port->APEModeEnable.r32; - APE.Mode2.r32 |= port->APEMode2Enable.r32; + Network_setEnableState(port); // Ensure REG_RECEIVE_MAC_MODE has ENABLE set. // I recommend also setting APE_PROMISCUOUS_MODE and PROMISCUOUS_MODE, @@ -993,8 +996,6 @@ void Network_InitPort(NetworkPort_t *port, reload_type_t reset_phy) port->device->GrcModeControl.bits.HostStackUp = 1; // Enable packet RX - APE_aquireLock(); - Network_updatePortState(port); uint16_t status_value = MII_readRegister(port->device, phy, (mii_reg_t)REG_MII_STATUS); @@ -1032,6 +1033,8 @@ void Network_checkPortState(NetworkPort_t *port) port->link_state_printed = true; } + APE_aquireLock(); + // Update state to match latest. if (Network_updatePortState(port)) { @@ -1046,6 +1049,8 @@ void Network_checkPortState(NetworkPort_t *port) printf("Link Status Updated\n"); port->link_state_printed = false; } + + APE_releaseLock(); } } -- cgit v1.2.1