summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorEvan Lojewski <github@meklort.com>2020-02-24 20:31:12 -0700
committerGitHub <noreply@github.com>2020-02-24 20:31:12 -0700
commitc3087a309398c6e83bb26e336f3955f004efb0f8 (patch)
tree693583fb9652b576633ce30acb625e57d5760354 /libs
parent8364552c917490bb7b284413577fcbeb953368c3 (diff)
downloadbcm5719-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.h5
-rw-r--r--libs/Network/ports.c78
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;
+}
OpenPOWER on IntegriCloud