Enet Migration Guide
Introduction
Enet LLD Migration guide explains the rationale for syscfg integration and the associated changes needed in application.
Need for Sysconfig
Enet LLD enables syscfg based module configuration. This impacts applications using the enet driver that are migrating from previous releases. The rationale for deep sysconfig integration with enet driver is listed:
The Enet LLD driver contains core specific, board specific code. However in MCU+SDK all module libraries can only be SOC+ISA specific. There is no option to have core specific or board specific options when building a library. This required user of enet library to modify enet source code that is not built for the default core/board combo and recompile the enet library. This issue has been addressed by ensuring portions that are core or board specific are part of syscfg template that are compiled as part of application.
Migrating open params of a module from C based to Sysconfig generated has other advantages:
Range check for all values at config time instead of runtime parameter checks
This reduces code size on target by eliminating error checks and minimizes erroneous configuration
Validation checks based on external module configuration like Clock config
Avoid uninitialized members in open params structure
Syscfg generated code will correctly initialize all members of openParams.
Allows easier migration to new versions and maintain backward compatibility without requiring application code change.
Although the same is typically done in C code by means of Enet_InitCfg API, the syscfg approach reduces target side code and ensure member initialization even if app fails to invoke Enet_InitCfg API
Allows creation of external module instances needed by enet lld without requiring application integrator to understand enet module external dependency. This simplifies system integration and reduces errors
UDMA instance is created as shared instance by Enet Module
I2C instances needed for board config can be created as shared instance by Enet Module
PRU instance interrupt configuration for ICSSG can be done by Enet Syscfg Module
Allows sizing of data structures in enet driver based on application config
The number of tx dma channels, rx dma channels, number of enet phy instances, enet resource manager configuration, number of packet buffers etc can be sized correctly based on application usecase rather than sizing them for a worst case if their allocation is determined by syscfg configuration
Enet LLD Driver library is built with close to zero r/w memory footprint
All data structures needed by EnetLLD drivers are sysconfig generated and sized correctly
For example:
Enet_memInit(Enet LLD function) invokesEnet_memGetCfg(Sysconfig generated code) which returns data structure with number of packets, rings, desc and associated memory that is generated based on application configuration and is right sized
Syscfg GUI allows presenting options in a scalable manner, showing only relevant options based on config and enables descriptive error msgs for wrong configuration.
Example of using syscfg GUI to scalably present config options:
If Enable Packet Pool Allocation option is not selected none of the other packet pool configuration options which are irrelevant are presented to the user

If Enable Packet Pool Allocation option is enabled the other packet pool configuration options are presented to the user

Enet Driver Initialization Sequence Change
Impact: The init sequence change impacts both ICSSG and CPSW peripherals on all SoCs.
Old Init Sequence |
New Init Sequence |
|---|---|
|
|
1. Set default enet osal configuration: Enet_initOsalCfg() |
1. Implement function EnetApp_updateCpswOpenParams() or EnetApp_updateIcssgOpenParams() depending on peripheral type. This function allows application to set any Enet openParams as per application requirement. |
2. Set default enet utils configuration: Enet_initUtilsCfg() |
2. Implement function EnetApp_initLinkArgs which allows application to set mac and phy params for each macPort enabled. |
3. Init Enet: Enet_init(osalCfg, utilsCfg) |
3. Invoke EnetApp_driverOpen(enetType, instId). Return value of EnetApp_driverOpen is status indicating success/failure. |
4. Set default Enet_openParams: Enet_initCfg() |
4. Application can get handle to Enet driver by invoking EnetApp_acquirehandleInfo() function. |
| 5. Update Enet open params with app specific configuration | |
6. Invoke Enet_open and get handle to Enet driver: hEnet = Enet_open(..openParams) |
|
| 7. For each macPort: init mac and phy link params, open macPort | |
8. Create PHY state machine task which will periodically invoke Enet_periodicTick |
|
| txsg_test_initseq_original.c | txsg_test_initseq_modified.c |
Compare txsg_test_initseq_original.c vs txsg_test_initseq_modified.c in a source code comparison tool to see the differences.
Enet DMA Channel Open Changes
Impact: The DMA channel open change impacts both ICSSG and CPSW peripherals on all SoCs. Only applications that directly invoke Enet driver packet transmit and receive APIs are impacted (LwIP based applications are not impacted).
The EnetDma_openRxCh() and EnetDma_openTxCh() DMA channel open was previously application callable APIs. Applications typically use EnetAppUtils wrapper APIs to open Tx and Rx DMA channels:
EnetAppUtils_openTxCh()EnetAppUtils_openRxCh()EnetAppUtils_openRxFlow()EnetAppUtils_openRxFlowForChIdx()
Supporting application invocable APIs for Tx and Rx DMA channel open required enet driver to support worst case number for Tx and Rx channels and associated rings, descriptors irrespective of actual number of channels used by application.
Most application typically use 1 Tx and 1 Rx channel but the default enet library was built to support up to 8 Tx and 8 Rx channels resulting in wastage of memory.
To ensure the DMA channel and associated rings are sized to correct value based on application usecase, DMA channel configuration is now supported via syscfg.
Sysconfig DMA channel config for AM263x/AWR294x/AM273x |
Sysconfig DMA channel config for AM243x/AM64x |
|---|---|
|
|
All application configurable DMA channel open params that were configurable via APIs EnetAppUtils_openTxCh/EnetAppUtils_openRxCh are now configurable via syscfg GUI.
One Tx and Rx channel are created by default.
If application needs additional Tx and Rx channels it should instantiate additional channels via syscfg.
Refer
mcu_plus_sdk/examples/networking/enet_layer2_multi_channel/<soc-platform>/r5fss0-0_freertos/example.syscfg
The syscfg generated EnetApp_driverOpen function internally opens all configured DMA channels.
Application can no longer open DMA channels directly.
Application gets handle to DMA channel by passing the DMA channel instance identifier used in example.syscfg:
enet_cpsw1.txDmaChannel[0].$name = "ENET_DMA_TX_CH0"(Instance identifier for Tx Dma channel 0)enet_cpsw1.rxDmaChannel[0].$name = "ENET_DMA_RX_CH0"(Instance identifier for Rx Dma channel 0)
To get DMA channel handle application invokes:
EnetApp_getTxDmaHandle(ENET_DMA_TX_CH0, &txInArgs, &txChInfo);EnetApp_getRxDmaHandle(ENET_DMA_RX_CH0, &rxInArgs, &rxChInfo);
Compare txsg_test_dma_original.c vs txsg_test_dma_modified.c in a source code comparison tool to see the differences:
Runtime Control API (Enet_ioctl) Change
Impact: The init sequence change impacts both ICSSG and CPSW peripherals on all SoCs.
Rationale for change:
Runtime control for Enet driver is supported via
Enet_ioctlAPI call.The
Enet_ioctlAPI takes a CMD and associated params.Internally the
Enet_ioctlwas implemented as a switch..case statement.
As all supported IOCTL cmds are implemented as a case statement, the linker will link in code associated with all supported IOCTLs cmd (~300 cmd) irrespective of whether the IOCTL cmd was invoked by application.
This results in large code size in the final application even though the application may not be using all the IOCTL cmds.
To resolve this issue, the Enet library has been modified to move to a model that ensures only IOCTL cmds invoked by application are linked into the final executable.
Old Method |
New Method |
|---|---|
|
|
Note:
Do not invoke Enet_ioctl API directly from application.
It should result in compilation error due to missing prototype unless application is wrongly including some enet private header files.
If
Enet_ioctlAPI is invoked directly you will get a cmd failure.
The
IOCTL_CMDhas to be anENET_IOCTLcmd enum and cannot be a variable.You will face linker error about undefined symbol if you use a variable instead of enum for the IOCTL cmd param.
Compare txsg_test_ioctl_original.c vs txsg_test_ioctl_modified.c in a source code comparison tool to see the differences:
Custom Board Support
The MCU+SDK enet driver supports a set of boards for each SoC out of the box.
Refer MCU+SDK release notes for platforms/boards supported for each SoC.
The board specific portion of the enet code is auto generated in the file ti_board_config.c for supported boards.
For porting enet based applications to a custom board the following need to be done:
Enable “Custom Board” syscfg option:

Enabling “Custom Board” will prevent auto generation of board specific code.
A C file will have to be then written that is specific to the board.
Board Config C File
The board specific file should contain the following:
const EnetPhy_DrvInfoTbl gEnetPhyDrvTbl: This is a table of ENET PHY drivers supported on the board. Refer the Enet custom PHY integration guide for details on how to populate this table.EnetBoard_setupPorts(): This function should setup any board level muxes and configure any SoC level RGMII internal delay/RMII configuration for the specific port.Refer API documentation for
mcu_plus_sdk/source/networking/enet/utils/include/enet_board.hfor details of function and arguments.
EnetBoard_getPhyCfg(): This function should return the ETHPHY specific configuration for a given port including any extended phy configuration.Refer API documentation for
mcu_plus_sdk/source/networking/enet/utils/include/enet_board.hfor details of function and arguments.
EnetBoard_getMacAddrList(): This function should populate any board specific MAC addresses that are available on board eeprom. If the board does not have any board specific macAddresses this function should set argument*pAvailMacEntries = 0.EnetBoard_getId(): This function should return the board id. This is not used anywhere outside this file so the board id returned will depend on the implementation ofEnetBoard_setupPorts()/EnetBoard_getPhyCfg()for the custom board if it refers the boardId to determine PHY config/setup ports.Refer
mcu_plus_sdk/examples/networking/enet_layer2_multi_channelenet_custom_board_config.cfor example illustrating custom board integration.
Ethernet MAC Address Management
Typically, one unique MAC address is burnt into efuse during device fabrication. Furthermore, additional MAC addresses are programmed in EEPROM on evaluation boards (EVM and launchpads) that are supported by TI.
There are two ways by which you can set the custom MAC address.
1. Using Syscfg GUI tool:
An option is provided in Syscfg GUI tool to force custom MAC address instead of taking from EEPROM/EFUSE.
To use this option:
Open syscfg GUI tool.
Go to “TI” -> “ENET(CPSW)” (or “ENET(ICSS)”) -> “System integration config”.
Change “MAC Address Assignment Method” to “Manual Entry” and fill the mac address in “MAC Address List” option.

Keeping “MAC Address Assignment Method” to “Auto Assign”, shall use the MAC address from EEPROM and EFUSE.

Please note that “Auto Assign” is not supported on AM273x and AWR294x due to EVM limitation.
2. Using Custom Board Option:
On your custom board EEPROM may not be available or it is not used to keep MAC address, then please follow the below steps to set MAC address:
Select custom board as per the Custom Board Support section above.
In your specific custom board specific
.cfile (e.g.enet_custom_board_config.c), implementEnetBoard_getMacAddrList():
void EnetBoard_getMacAddrList(uint8_t macAddr[][ENET_MAC_ADDR_LEN],
uint32_t maxMacEntries,
uint32_t *pAvailMacEntries)
{
int32_t status = ENET_SOK;
uint32_t macAddrCnt;
uint32_t i;
uint8_t macAddrBuf[ENET_BOARD_NUM_MACADDR_MAX * ENET_MAC_ADDR_LEN];
uint8_t numMacMax = 0;
/* Fill the MAC Address */
macAddrBuf[ENET_MAC_ADDR_LEN*0] = {0xF4, 0x84, 0x4C, 0xFB, 0xC0, 0x5C};
macAddrBuf[ENET_MAC_ADDR_LEN*1] = {0xF4, 0x84, 0x4C, 0xFB, 0xC0, 0x5D};
numMacMax = 2;
macAddrCnt = EnetUtils_min(numMacMax, maxMacEntries);
EnetAppUtils_assert(pAvailMacEntries != NULL);
for (i = 0U; i < macAddrCnt; i++)
{
memcpy(macAddr[i], &macAddrBuf[i * ENET_MAC_ADDR_LEN], ENET_MAC_ADDR_LEN);
}
*pAvailMacEntries = macAddrCnt;
if (macAddrCnt == 0U)
{
EnetAppUtils_print("EnetBoard_getMacAddrList Failed - IDK not present\n");
EnetAppUtils_assert(false);
}
}
External PHY Management
External PHY management allows application plugging in its own PHY state machine and managing PHY drivers outside of Enet LLD.
PHY control and PHY statemachine handling is disabled in Ethernet driver.
MDIO is still owned by Ethernet Driver and MDIO IOCTLs should be used to access the PHYs.
mcu_plus_sdk/examples/networking/lwip/enet_lwip_cpsw/extPhyMgmt/enetextphy_phymdio_dflt.c
External PHY management is enabled via syscfg option:

Application should register for MDIO link event interrupt if MDIO manual mode is not enabled.
Application should create a periodic polling task to check link state if MDIO manual mode is enabled.
This is because MDIO link event interrupt is not supported in MDIO manual mode (bitbanging mode).
Application should invoke below IOCTLs to inform Enet driver of link up/down events:
ENET_PER_IOCTL_HANDLE_EXTPHY_LINKUP_EVENTENET_PER_IOCTL_HANDLE_EXTPHY_LINKDOWN_EVENT
Refer example application for extphy demonstration:
mcu_plus_sdk/examples/networking/lwip/enet_lwip_cpsw
Note: The external PHY sample example does not implement a real state machine. Intention is to show Enet driver interaction with externally managed PHY and not implement a full featured external PHY.
Tuning Memory Usage for Non-LwIP Apps
Syscfg integration allows the enet driver rwdata memory footprint to be sized based on application configuration.
Key params that are useful for tuning the rw data memory:
Maximum number of packets for Tx and Rx DMA channel (configurable via syscfg).
For non-lwip application, the enet library packet pool allocation can be enabled via syscfg to configure the size of large, medium and small pools and the number of packets in each pool.

Tuning Memory Usage for LwIP Apps
This release does not support similar syscfg based configuration of packet pools for lwip based examples. This will be addressed in future releases. In the current release for lwip based application to tune memory the following option exists:
Set maximum number of packets for Tx and Rx DMA channel (configurable via syscfg).
Update
mcu_plus_sdk/source/networking/lwip/lwip-config/<soc>/lwippools.has per application requirement.Update
mcu_plus_sdk/source/networking/lwip/lwip-config/<soc>/lwipopts.h:PBUF_POOL_SIZE- determines number of Rx packets. The Rx DMA channel max number of packets should be updated if this value is modified.
Changes to lwipopts.h and lwippools require recompilation of library:
gmake -s -f makefile.<soc> libs-scrub(clean all libraries)gmake -s -f makefile.<soc> libs PROFILE:=debug/release(rebuild all libraries)



