summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvan Lojewski <github@meklort.com>2020-02-26 20:52:35 -0700
committerGitHub <noreply@github.com>2020-02-26 20:52:35 -0700
commitb82cd4c280bbe92012213cc2c8856546f74d6723 (patch)
tree353f84d9316ec632a812b3ca24d58db220d81ecb
parent4b0ee4127869a8ae640c940866d87d267405cdb9 (diff)
downloadbcm5719-ortega-b82cd4c280bbe92012213cc2c8856546f74d6723.tar.gz
bcm5719-ortega-b82cd4c280bbe92012213cc2c8856546f74d6723.zip
ncsi: Add a reload API to reload current configuration without disconnecting the BMC. (#44)
-rw-r--r--libs/NCSI/include/NCSI.h8
-rw-r--r--libs/NCSI/ncsi.c46
2 files changed, 54 insertions, 0 deletions
diff --git a/libs/NCSI/include/NCSI.h b/libs/NCSI/include/NCSI.h
index 2e9223d..fc1a557 100644
--- a/libs/NCSI/include/NCSI.h
+++ b/libs/NCSI/include/NCSI.h
@@ -70,4 +70,12 @@ void NCSI_handlePassthrough(void);
void NCSI_init(void);
+
+typedef enum {
+ NEVER_RESET, /* Host up, do not reset the PHY */
+ AS_NEEDED, /* Reset the phy if no link */
+ ALWAYS_RESET /* Host was just turned off, reset phy */
+} reload_type_t;
+void NCSI_reload(reload_type_t reset_phy);
+
#endif /* NCSI_H */ \ No newline at end of file
diff --git a/libs/NCSI/ncsi.c b/libs/NCSI/ncsi.c
index 3e27755..43e3cc8 100644
--- a/libs/NCSI/ncsi.c
+++ b/libs/NCSI/ncsi.c
@@ -678,6 +678,44 @@ void resetChannel(int ch)
APE_releaseLock();
}
+void reloadChannel(int ch, reload_type_t reset_phy)
+{
+ NetworkPort_t *port = gPackageState.port[ch];
+
+ uint32_t low = port->shm_channel->NcsiChannelMac0Mid.r32 << 16 | port->shm_channel->NcsiChannelMac0Low.r32;
+ uint16_t high = port->shm_channel->NcsiChannelMac0High.r32;
+ Network_SetMACAddr(port, high, low, /* TBD */ 0, 1);
+
+ if (gPackageState.port[ch]->shm_channel->NcsiChannelInfo.bits.Enabled)
+ {
+ printf("[ch %d] Reusing MAC: 0x%02X%04X\n", ch, high, low);
+
+ bool reset;
+ switch (reset_phy)
+ {
+ case NEVER_RESET:
+ reset = false;
+ break;
+ case AS_NEEDED:
+ reset = !Network_isLinkUp(port);
+ break;
+ case ALWAYS_RESET:
+ reset = true;
+ break;
+ }
+
+ if (reset)
+ {
+ uint8_t phy = MII_getPhy(port->device);
+ APE_aquireLock();
+ MII_writeRegister(port->device, phy, (mii_reg_t)REG_MII_CONTROL, MII_CONTROL_RESET_MASK);
+ APE_releaseLock();
+ }
+
+ Network_InitPort(gPackageState.port[ch]);
+ }
+}
+
void NCSI_TxPacket(uint32_t *packet, uint32_t packet_len)
{
uint32_t packetWords = DIVIDE_RND_UP(packet_len, sizeof(uint32_t));
@@ -751,6 +789,14 @@ void NCSI_init(void)
SHM.SegSig.r32 = 0; // (1 << command);
}
+void NCSI_reload(reload_type_t reset_phy)
+{
+ for (int i = 0; i < ARRAY_ELEMENTS(gPackageState.port); i++)
+ {
+ reloadChannel(i, reset_phy);
+ }
+}
+
void NCSI_handlePassthrough(void)
{
for (int ch = 0; ch < ARRAY_ELEMENTS(gPackageState.port); ch++)
OpenPOWER on IntegriCloud