diff options
Diffstat (limited to 'libs')
-rw-r--r-- | libs/NCSI/include/NCSI.h | 8 | ||||
-rw-r--r-- | libs/NCSI/ncsi.c | 46 |
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++) |