diff options
author | Evan Lojewski <github@meklort.com> | 2020-02-08 08:50:42 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-02-08 08:50:42 -0700 |
commit | 2607cb167def8afa220e5b674b18bb6cb85c96d2 (patch) | |
tree | fadec03187bca51295d0716a028962cf692d6dad | |
parent | d4dba2b69e934189f3efd774e01cd29d5634e77e (diff) | |
download | bcm5719-ortega-2607cb167def8afa220e5b674b18bb6cb85c96d2.tar.gz bcm5719-ortega-2607cb167def8afa220e5b674b18bb6cb85c96d2.zip |
Network: Update network initialization code. (#27)
-rw-r--r-- | libs/Network/CMakeLists.txt | 4 | ||||
-rw-r--r-- | libs/Network/include/Network.h | 3 | ||||
-rw-r--r-- | libs/Network/ports.c | 140 |
3 files changed, 144 insertions, 3 deletions
diff --git a/libs/Network/CMakeLists.txt b/libs/Network/CMakeLists.txt index 63ccf88..67650c2 100644 --- a/libs/Network/CMakeLists.txt +++ b/libs/Network/CMakeLists.txt @@ -55,13 +55,13 @@ SET(SOURCES # Host Simulation library simulator_add_library(${PROJECT_NAME} STATIC ${SOURCES}) -target_link_libraries(${PROJECT_NAME} PRIVATE simulator NCSI) +target_link_libraries(${PROJECT_NAME} PRIVATE simulator NCSI MII) target_include_directories(${PROJECT_NAME} PUBLIC ../../include) target_include_directories(${PROJECT_NAME} PUBLIC include) # ARM Library arm_add_library(${PROJECT_NAME}-arm STATIC ${SOURCES}) -target_link_libraries(${PROJECT_NAME}-arm PRIVATE NCSI-arm printf-arm) +target_link_libraries(${PROJECT_NAME}-arm PRIVATE NCSI-arm printf-arm MII-arm) target_include_directories(${PROJECT_NAME}-arm PUBLIC ../../include) target_include_directories(${PROJECT_NAME}-arm PUBLIC include) diff --git a/libs/Network/include/Network.h b/libs/Network/include/Network.h index ac26f05..be92bd5 100644 --- a/libs/Network/include/Network.h +++ b/libs/Network/include/Network.h @@ -103,6 +103,9 @@ void Network_InitTxRx(void); void Network_resetTX(NetworkPort_t *port); void Network_resetRX(NetworkPort_t *port); +void Network_updatePortState(NetworkPort_t *port); + + uint32_t Network_TX_numBlocksNeeded(uint32_t frame_size); int32_t Network_TX_allocateBlock(NetworkPort_t *port); void Network_TX_releaseBlock(NetworkPort_t *port, int32_t block); diff --git a/libs/Network/ports.c b/libs/Network/ports.c index 1711c55..e9cea5a 100644 --- a/libs/Network/ports.c +++ b/libs/Network/ports.c @@ -59,6 +59,7 @@ #include <APE_TX_PORT2.h> #include <APE_TX_PORT3.h> #include <Network.h> +#include <MII.h> NetworkPort_t gPort0 = { .device = &DEVICE, @@ -781,8 +782,145 @@ void Network_InitPort(NetworkPort_t *port) RegDEVICEReceiveMacMode_t macMode; macMode = port->device->ReceiveMacMode; macMode.bits.Enable = 1; - macMode.bits.APEPromiscuousMode = 0; + macMode.bits.APEPromiscuousMode = 1; // When set, allows APE to RX without having to reset the network configuration after a power off port->device->ReceiveMacMode = macMode; + // Enable RX/TX + RegDEVICETransmitMacMode_t txMacMode; + txMacMode = port->device->TransmitMacMode; + txMacMode.bits.EnableTDE = 1; + // txMacMode.bits.EnableFlowControl = 1; + port->device->TransmitMacMode = txMacMode; + + RegDEVICEEeeMode_t eeeMode; + eeeMode = port->device->EeeMode; + eeeMode.bits.APETXDetectionEnable = 1; + eeeMode.bits.EEELinkIdleDetectionEnable = 1; + eeeMode.bits.SendIndexDetectionEnable = 1; + eeeMode.bits.TXLPIEnable = 1; + eeeMode.bits.RXLPIEnable = 1; + port->device->EeeMode = eeeMode; + + RegDEVICEBufferManagerMode_t bmm; + bmm.r32 = 0; + bmm.bits.Enable = 1; + bmm.bits.AttentionEnable = 1; + bmm.bits.ResetRXMBUFPointer = 1; + port->device->BufferManagerMode = bmm; + + RegDEVICEEmacMode_t emacMode; + emacMode = port->device->EmacMode; + emacMode.bits.EnableAPERXPath = 1; + emacMode.bits.EnableAPETXPath = 1; + + emacMode.bits.EnableFHDE = 1; + emacMode.bits.EnableTCE = 1; // Transmit DMA needed for APE to work properly + emacMode.bits.EnableRDE = 1; + + emacMode.bits.KeepFrameInWOL = 1; + emacMode.bits.MACLoopbackModeControl = 0; + port->device->EmacMode = emacMode; + + RegDEVICETransmitMacLengths_t txMacLengths; + txMacLengths = port->device->TransmitMacLengths; + txMacLengths.bits.SlotTimeLength = 0x21; + txMacLengths.bits.IPGLength = 0x6; + txMacLengths.bits.IPGCRSLength = 0x2; + port->device->TransmitMacLengths = txMacLengths; + + port->device->MiscellaneousConfig.bits.DisableGRCReset = 1; + port->device->LinkAwarePowerModeClockPolicy.bits.MACClockSwitch = DEVICE_LINK_AWARE_POWER_MODE_CLOCK_POLICY_MAC_CLOCK_SWITCH_6_25MHZ; + port->device->ClockSpeedOverridePolicy.r32 = 0; + + RegDEVICECpmuControl_t cmm; + cmm = port->device->CpmuControl; + cmm.bits.LinkIdlePowerModeEnable = 1; + cmm.bits.LinkAwarePowerModeEnable = 1; + 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 } + +void Network_updatePortState(NetworkPort_t *port) +{ + uint8_t phy = MII_getPhy(port->device); + RegMIIAuxiliaryStatusSummary_t status; + RegMIIControl_t control; + + control.r16 = MII_readRegister(port->device, phy, (mii_reg_t)REG_MII_CONTROL); + if(control.bits.RestartAutonegotiation) + { + // Link down, don't update mac mode. + } + else + { + status.r16 = MII_readRegister(port->device, phy, (mii_reg_t)REG_MII_AUXILIARY_STATUS_SUMMARY); + if(control.bits.AutoNegotiationEnable && !status.bits.AutoNegotiationComplete) + { + // Link down, don't update mac mode. + } + else + { + // Auto negotiation complete or mode forced. + RegDEVICEEmacMode_t emacMode, emacModeOrig; + emacModeOrig = emacMode = port->device->EmacMode; + + // Select full/half duplex mode. + switch((uint8_t)status.bits.AutoNegotiationHCD) + { + case MII_AUXILIARY_STATUS_SUMMARY_AUTO_NEGOTIATION_HCD_NO_HCD: + // Error + break; + + case MII_AUXILIARY_STATUS_SUMMARY_AUTO_NEGOTIATION_HCD_10BASE_T_HALF_DUPLEX: + case MII_AUXILIARY_STATUS_SUMMARY_AUTO_NEGOTIATION_HCD_100BASE_TX_HALF_DUPLEX: + case MII_AUXILIARY_STATUS_SUMMARY_AUTO_NEGOTIATION_HCD_1000BASE_T_HALF_DUPLEX: + emacMode.bits.HalfDuplex = 1; + break; + + case MII_AUXILIARY_STATUS_SUMMARY_AUTO_NEGOTIATION_HCD_100BASE_T4: + case MII_AUXILIARY_STATUS_SUMMARY_AUTO_NEGOTIATION_HCD_10BASE_T_FULL_DUPLEX: + case MII_AUXILIARY_STATUS_SUMMARY_AUTO_NEGOTIATION_HCD_100BASE_TX_FULL_DUPLEX: + case MII_AUXILIARY_STATUS_SUMMARY_AUTO_NEGOTIATION_HCD_1000BASE_T_FULL_DUPLEX: + emacMode.bits.HalfDuplex = 0; + break; + } + + // Select Speed + switch((uint8_t)status.bits.AutoNegotiationHCD) + { + case MII_AUXILIARY_STATUS_SUMMARY_AUTO_NEGOTIATION_HCD_NO_HCD: + // Error + break; + + case MII_AUXILIARY_STATUS_SUMMARY_AUTO_NEGOTIATION_HCD_10BASE_T_HALF_DUPLEX: + case MII_AUXILIARY_STATUS_SUMMARY_AUTO_NEGOTIATION_HCD_10BASE_T_FULL_DUPLEX: + case MII_AUXILIARY_STATUS_SUMMARY_AUTO_NEGOTIATION_HCD_100BASE_T4: + case MII_AUXILIARY_STATUS_SUMMARY_AUTO_NEGOTIATION_HCD_100BASE_TX_HALF_DUPLEX: + case MII_AUXILIARY_STATUS_SUMMARY_AUTO_NEGOTIATION_HCD_100BASE_TX_FULL_DUPLEX: + emacMode.bits.PortMode = DEVICE_EMAC_MODE_PORT_MODE_10_DIV_100; + break; + + case MII_AUXILIARY_STATUS_SUMMARY_AUTO_NEGOTIATION_HCD_1000BASE_T_HALF_DUPLEX: + case MII_AUXILIARY_STATUS_SUMMARY_AUTO_NEGOTIATION_HCD_1000BASE_T_FULL_DUPLEX: + emacMode.bits.PortMode = DEVICE_EMAC_MODE_PORT_MODE_1000; + break; + } + + if(emacMode.r32 != emacModeOrig.r32) + { + // Update emac mode to match current state. + port->device->EmacMode = emacMode; + } + + } + } +}
\ No newline at end of file |