diff options
author | Evan Lojewski <github@meklort.com> | 2020-02-24 20:31:12 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-02-24 20:31:12 -0700 |
commit | c3087a309398c6e83bb26e336f3955f004efb0f8 (patch) | |
tree | 693583fb9652b576633ce30acb625e57d5760354 /libs | |
parent | 8364552c917490bb7b284413577fcbeb953368c3 (diff) | |
download | bcm5719-ortega-c3087a309398c6e83bb26e336f3955f004efb0f8.tar.gz bcm5719-ortega-c3087a309398c6e83bb26e336f3955f004efb0f8.zip |
Network: Add APIs for checking and updating link/port state. (#42)
Diffstat (limited to 'libs')
-rw-r--r-- | libs/Network/include/Network.h | 5 | ||||
-rw-r--r-- | libs/Network/ports.c | 78 |
2 files changed, 78 insertions, 5 deletions
diff --git a/libs/Network/include/Network.h b/libs/Network/include/Network.h index be92bd5..059e04c 100644 --- a/libs/Network/include/Network.h +++ b/libs/Network/include/Network.h @@ -103,7 +103,10 @@ void Network_InitTxRx(void); void Network_resetTX(NetworkPort_t *port); void Network_resetRX(NetworkPort_t *port); -void Network_updatePortState(NetworkPort_t *port); +void Network_checkPortState(NetworkPort_t *port); +bool Network_updatePortState(NetworkPort_t *port); + +bool Network_isLinkUp(NetworkPort_t *port); uint32_t Network_TX_numBlocksNeeded(uint32_t frame_size); diff --git a/libs/Network/ports.c b/libs/Network/ports.c index c2622aa..fad9d30 100644 --- a/libs/Network/ports.c +++ b/libs/Network/ports.c @@ -61,6 +61,12 @@ #include <MII.h> #include <Network.h> +#ifdef CXX_SIMULATOR +#include <stdio.h> +#else +#include <printf.h> +#endif + NetworkPort_t gPort0 = { .device = &DEVICE, .filters = &FILTERS0, @@ -839,21 +845,42 @@ void Network_InitPort(NetworkPort_t *port) cmm.bits.LinkSpeedPowerModeEnable = 1; port->device->CpmuControl = cmm; - Network_SetMACAddr(port, 0, 0, 1, true); - if (port->device->EmacMode.bits.EnableFHDE || port->device->EmacMode.bits.EnableRDE) { port->device->ReceiveListPlacementMode.bits.Enable = 1; } port->device->GrcModeControl.bits.HostStackUp = 1; // Enable packet RX + + Network_updatePortState(port); +} + +void Network_checkPortState(NetworkPort_t *port) +{ + if (port->device->EmacStatus.bits.LinkStateChanged) + { + printf("LinkStatusChanged\n"); + + // Update state to match latest. + if (Network_updatePortState(port)) + { + RegDEVICEEmacStatus_t clearState; + clearState.r32 = 0; + clearState.bits.LinkStateChanged = 1; + clearState.bits.ConfigurationChanged = 1; + clearState.bits.SyncChanged = 1; + clearState.bits.MICompletion = 1; + port->device->EmacStatus.r32 = clearState.r32; + } + } } -void Network_updatePortState(NetworkPort_t *port) +bool Network_updatePortState(NetworkPort_t *port) { uint8_t phy = MII_getPhy(port->device); RegMIIAuxiliaryStatusSummary_t status; RegMIIControl_t control; + bool updated = false; control.r16 = MII_readRegister(port->device, phy, (mii_reg_t)REG_MII_CONTROL); if (control.bits.RestartAutonegotiation) @@ -920,6 +947,49 @@ void Network_updatePortState(NetworkPort_t *port) // Update emac mode to match current state. port->device->EmacMode = emacMode; } + + updated = true; } } -}
\ No newline at end of file + + return updated; +} + +bool Network_isLinkUp(NetworkPort_t *port) +{ + uint8_t phy = MII_getPhy(port->device); + RegMIIAuxiliaryStatusSummary_t status; + RegMIIControl_t control; + bool linkup; + + control.r16 = MII_readRegister(port->device, phy, (mii_reg_t)REG_MII_CONTROL); + if (control.bits.RestartAutonegotiation) + { + // Renegotiating, link not yet up. + linkup = false; + } + else + { + status.r16 = MII_readRegister(port->device, phy, (mii_reg_t)REG_MII_AUXILIARY_STATUS_SUMMARY); + if (control.bits.AutoNegotiationEnable && !status.bits.AutoNegotiationComplete) + { + // Renegotiating, link not yet up. + linkup = false; + } + else + { + if (MII_AUXILIARY_STATUS_SUMMARY_AUTO_NEGOTIATION_HCD_NO_HCD == status.bits.AutoNegotiationHCD) + { + // Autoneg failed, link not up. + linkup = false; + } + else + { + // Autoneg passed. + linkup = true; + } + } + } + + return linkup; +} |