This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM2431: Issues arise when receiving a large volume of Ethernet packets.

Part Number: AM2431
Other Parts Discussed in Thread: LP-AM243

Hi all TI experts,

My current product uses the AM2431 as the main chip, and the SDK I am using is mcu_plus_sdk_am243x_09_01_00_41. I referred to the enet_layer2_cpsw sample program and modified it for our application.

Recently, I encountered an issue where the system functions normally with only a few Ethernet packets, but when a large volume of packets is present, errors occur. I discovered that the issue is related to the configuration settings in Enet (CPSW) -> ENET RX DMA channel > Packet Pool Config. The maximum setting for the Large Pool Packet Count is 192, but my system sends 807 packets within 8 ms, each packet being 1461 bytes. After transmission, there's an idle period of about 20 ms, allowing the MCU to process the packets. Observations using Wireshark show that the data rate is approximately 125 Mbps, and given the AM2431's capability to handle gigabit Ethernet, it should theoretically manage this workload. However, it appears that the volume of packets is too great, and there isn't enough DMA space to handle them all. I am looking for any suggestions on how to resolve this issue. Thank you!

Best,

Larry

  • is anyone have idea?

  • Hi ,

    Thanks for your query.

    I am out of office this week.

    Will check on this next week.

    Regards

    Ashwani

  • Hi Ashwani,

    Thanks for your reply, hope get your feedback as soon as possible.

    Best,

    Larry

  • Hi ,

    Thanks for waiting patiently.

    As we can see you have described problem well.

    Can you help me step by step to follow to reproduce the issue faster?

    Meanwhile, can you please try the same steps on MCU-PLUS-SDK-AM243X Software development kit (SDK) | TI.com and confirm you are getting same results?

    Regards

    Ashwani

  • Hi Ashwani,

    Sure, based on your description, I upgraded the SDK version to 9.2.0.50, but I am still encountering issues. What information do you need from me to reproduce the problem step-by-step?

    Here is some information that I think is necessary to provide:

    1. My AM2431 communicates with another Ethernet switch IC via RGMII, thus the External Phy Management is enabled.
    2. Each packet size is 1461 bytes, with an interval of 2-3ms between packet transmissions. This interval might decrease, depending on my settings. There can be up to 1000 consecutive packets received, followed by a rest period of 10-20ms, which allows the AM2431 to process the recently received packets.

    What other information do you require?

    Best,
    Larry

  • Okay Larry,

    I will start with MCU SDK 9.2 on AM243x-EVM.

    AM2431

    This is AM243x-evm. correct?

    configuration settings in Enet (CPSW)

    Better to have screenshots of the changes you have locally done?

    Regards

    Ashwani

  • Hi Ashwani,

    This is AM243x-evm. correct?

     No, this is our product, where we use the AM2431 as our main chip. It is implemented on our custom board, not on a development kit.

    Better to have screenshots of the changes you have locally done?

    I can provide syscfg file content.

    /**
     * These arguments were used when this file was generated. They will be automatically applied on subsequent loads
     * via the GUI or CLI. Run CLI with '--help' for additional information on how to override these arguments.
     * @cliArgs --device "AM243x_ALX_beta" --package "ALX" --part "ALX" --context "r5fss0-0" --product "MCU_PLUS_SDK_AM243x@09.02.00"
     * @versions {"tool":"1.20.0+3587"}
     */
    
    /**
     * Import the modules used in this configuration.
     */
    const flash           = scripting.addModule("/board/flash/flash", {}, false);
    const flash1          = flash.addInstance();
    const bootloader      = scripting.addModule("/drivers/bootloader/bootloader", {}, false);
    const bootloader1     = bootloader.addInstance();
    const epwm            = scripting.addModule("/drivers/epwm/epwm", {}, false);
    const epwm1           = epwm.addInstance();
    const epwm2           = epwm.addInstance();
    const epwm3           = epwm.addInstance();
    const epwm4           = epwm.addInstance();
    const epwm5           = epwm.addInstance();
    const epwm6           = epwm.addInstance();
    const gpio            = scripting.addModule("/drivers/gpio/gpio", {}, false);
    const gpio1           = gpio.addInstance();
    const gpio2           = gpio.addInstance();
    const gpio3           = gpio.addInstance();
    const gpio4           = gpio.addInstance();
    const gpio5           = gpio.addInstance();
    const gpio6           = gpio.addInstance();
    const gpio7           = gpio.addInstance();
    const gpio8           = gpio.addInstance();
    const gpio9           = gpio.addInstance();
    const gpio10          = gpio.addInstance();
    const gpio11          = gpio.addInstance();
    const gpio12          = gpio.addInstance();
    const gpio13          = gpio.addInstance();
    const gpio14          = gpio.addInstance();
    const gpio15          = gpio.addInstance();
    const gpio16          = gpio.addInstance();
    const gpio17          = gpio.addInstance();
    const gpio18          = gpio.addInstance();
    const gpio19          = gpio.addInstance();
    const gpio20          = gpio.addInstance();
    const gpio21          = gpio.addInstance();
    const gpio22          = gpio.addInstance();
    const gpio23          = gpio.addInstance();
    const gpio24          = gpio.addInstance();
    const gpio25          = gpio.addInstance();
    const gpio26          = gpio.addInstance();
    const gpio27          = gpio.addInstance();
    const gpio28          = gpio.addInstance();
    const gpio29          = gpio.addInstance();
    const gpio30          = gpio.addInstance();
    const i2c             = scripting.addModule("/drivers/i2c/i2c", {}, false);
    const i2c1            = i2c.addInstance();
    const mcspi           = scripting.addModule("/drivers/mcspi/mcspi", {}, false);
    const mcspi1          = mcspi.addInstance();
    const pruicss         = scripting.addModule("/drivers/pruicss/pruicss", {}, false);
    const pruicss1        = pruicss.addInstance();
    const udma            = scripting.addModule("/drivers/udma/udma", {}, false);
    const udma1           = udma.addInstance();
    const udma2           = udma.addInstance();
    const addr_translate  = scripting.addModule("/kernel/dpl/addr_translate", {}, false);
    const addr_translate1 = addr_translate.addInstance();
    const clock           = scripting.addModule("/kernel/dpl/clock");
    const debug_log       = scripting.addModule("/kernel/dpl/debug_log");
    const mpu_armv7       = scripting.addModule("/kernel/dpl/mpu_armv7", {}, false);
    const mpu_armv71      = mpu_armv7.addInstance();
    const mpu_armv72      = mpu_armv7.addInstance();
    const mpu_armv73      = mpu_armv7.addInstance();
    const mpu_armv74      = mpu_armv7.addInstance();
    const mpu_armv75      = mpu_armv7.addInstance();
    const enet_cpsw       = scripting.addModule("/networking/enet_cpsw/enet_cpsw", {}, false);
    const enet_cpsw1      = enet_cpsw.addInstance();
    
    /**
     * Write custom configuration values to the imported modules.
     */
    bootloader1.$name = "CONFIG_BOOTLOADER_FLASH0";
    
    flash1.$name                              = "CONFIG_FLASH0";
    bootloader1.flashDriver                   = flash1;
    flash1.flashSize                          = 2097152;
    flash1.flashManfId                        = "0xEF";
    flash1.flashDeviceId                      = "0x4015";
    flash1.flashBlockSize                     = 65536;
    flash1.cmdBlockErase4B                    = "0xD8";
    flash1.cmdSectorErase4B                   = "0x20";
    flash1.dummy_isAddrReg                    = false;
    flash1.dummy_cfgReg                       = "0x00000000";
    flash1.dummy_mask                         = "0x00";
    flash1.dummy_bitP                         = 0;
    flash1.resetType                          = "0x30";
    flash1.addressByteSupport                 = "0";
    flash1.idNumBytes                         = 5;
    flash1.device                             = "CUSTOM_FLASH";
    flash1.fname                              = "W25Q16JV";
    flash1.dummyId8                           = 0;
    flash1.flashDeviceBusyTimeout             = 5120000;
    flash1.flashPageProgTimeout               = 704;
    flash1.dummyClksRd                        = 0;
    flash1.dummy_cmdRegRd                     = "0x00";
    flash1.dummy_cmdRegWr                     = "0x00";
    flash1.protocol                           = "1s_1s_1s";
    flash1.cmdRd                              = "0x03";
    flash1.modeClksRd                         = 0;
    flash1.fourByteEnableSeq                  = "0x80";
    flash1.flash444Seq                        = "0x00";
    flash1.peripheralDriver.$name             = "CONFIG_OSPI0";
    flash1.peripheralDriver.dmaEnable         = true;
    flash1.peripheralDriver.OSPI.$assign      = "OSPI0";
    flash1.peripheralDriver.OSPI.CLK.$assign  = "OSPI0_CLK";
    flash1.peripheralDriver.OSPI.CSn0.$assign = "OSPI0_CSn0";
    flash1.peripheralDriver.OSPI.D3.$assign   = "OSPI0_D3";
    flash1.peripheralDriver.OSPI.D2.$assign   = "OSPI0_D2";
    flash1.peripheralDriver.OSPI.D1.$assign   = "OSPI0_D1";
    flash1.peripheralDriver.OSPI.D0.$assign   = "OSPI0_D0";
    
    epwm1.$name            = "ADD0";
    epwm1.EPWM.$assign     = "EHRPWM5";
    epwm1.EPWM.A.$assign   = "GPMC0_BE1n";
    epwm1.EPWM.B.$used     = false;
    epwm1.EPWM.SYNCO.$used = false;
    epwm1.EPWM.SYNCI.rx    = false;
    epwm1.EPWM.SYNCI.$used = false;
    
    epwm2.$name            = "ADD1";
    epwm2.EPWM.$assign     = "EHRPWM3";
    epwm2.EPWM.A.$assign   = "GPMC0_AD13";
    epwm2.EPWM.B.$used     = false;
    epwm2.EPWM.SYNCO.$used = false;
    epwm2.EPWM.SYNCI.$used = false;
    
    epwm3.$name            = "ADD2";
    epwm3.EPWM.$assign     = "EHRPWM2";
    epwm3.EPWM.A.$assign   = "GPMC0_AD8";
    epwm3.EPWM.B.$used     = false;
    epwm3.EPWM.SYNCO.$used = false;
    epwm3.EPWM.SYNCI.$used = false;
    
    epwm4.$name            = "GCLK_GATE";
    epwm4.EPWM.$assign     = "EHRPWM0";
    epwm4.EPWM.A.$assign   = "GPMC0_AD3";
    epwm4.EPWM.B.$used     = false;
    epwm4.EPWM.SYNCO.$used = false;
    epwm4.EPWM.SYNCI.$used = false;
    
    epwm5.$name            = "GCLK_PWM";
    epwm5.EPWM.$assign     = "EHRPWM1";
    epwm5.EPWM.A.$assign   = "GPMC0_AD5";
    epwm5.EPWM.B.$used     = false;
    epwm5.EPWM.SYNCO.$used = false;
    epwm5.EPWM.SYNCI.$used = false;
    
    epwm6.$name            = "UTXD";
    epwm6.EPWM.$assign     = "EHRPWM8";
    epwm6.EPWM.A.$assign   = "GPMC0_AD7";
    epwm6.EPWM.B.$used     = false;
    epwm6.EPWM.SYNCO.$used = false;
    epwm6.EPWM.SYNCI.rx    = false;
    epwm6.EPWM.SYNCI.$used = false;
    
    gpio1.$name          = "UDB1_L";
    gpio1.pinDir         = "OUTPUT";
    gpio1.rx             = true;
    gpio1.GPIO_n.$assign = "PRG0_PRU0_GPO0";
    
    gpio2.$name          = "UDB2_L";
    gpio2.pinDir         = "OUTPUT";
    gpio2.rx             = true;
    gpio2.GPIO_n.$assign = "PRG0_PRU0_GPO1";
    
    gpio3.$name          = "UDGI2_L";
    gpio3.rx             = true;
    gpio3.GPIO_n.$assign = "PRG0_PRU0_GPO2";
    
    gpio4.$name          = "UDBI1_L";
    gpio4.rx             = true;
    gpio4.GPIO_n.$assign = "PRG0_PRU0_GPO3";
    
    gpio5.$name          = "UDG2_L";
    gpio5.pinDir         = "OUTPUT";
    gpio5.rx             = true;
    gpio5.GPIO_n.$assign = "PRG0_PRU0_GPO4";
    
    gpio6.$name          = "UDRI2_L";
    gpio6.rx             = true;
    gpio6.GPIO_n.$assign = "PRG0_PRU0_GPO5";
    
    gpio7.$name          = "UDBI2_L";
    gpio7.rx             = true;
    gpio7.GPIO_n.$assign = "PRG0_PRU0_GPO6";
    
    gpio8.$name          = "UDRI1_L";
    gpio8.rx             = true;
    gpio8.GPIO_n.$assign = "PRG0_PRU0_GPO7";
    
    gpio9.$name          = "UDR2_L";
    gpio9.pinDir         = "OUTPUT";
    gpio9.rx             = true;
    gpio9.GPIO_n.$assign = "PRG0_PRU0_GPO11";
    
    gpio10.$name          = "UDG1_L";
    gpio10.pinDir         = "OUTPUT";
    gpio10.rx             = true;
    gpio10.GPIO_n.$assign = "PRG0_PRU0_GPO12";
    
    gpio11.$name          = "UDR1_L";
    gpio11.pinDir         = "OUTPUT";
    gpio11.rx             = true;
    gpio11.GPIO_n.$assign = "PRG0_PRU0_GPO18";
    
    gpio12.$name          = "UDGI1_L";
    gpio12.rx             = true;
    gpio12.GPIO_n.$assign = "PRG0_PRU0_GPO19";
    
    gpio13.$name          = "ULAT";
    gpio13.pinDir         = "OUTPUT";
    gpio13.rx             = true;
    gpio13.GPIO_n.$assign = "PRG1_PRU1_GPO13";
    
    gpio14.$name          = "STATUS_R";
    gpio14.pinDir         = "OUTPUT";
    gpio14.rx             = true;
    gpio14.GPIO_n.$assign = "PRG0_PRU1_GPO2";
    
    gpio15.$name          = "STATUS_G";
    gpio15.pinDir         = "OUTPUT";
    gpio15.rx             = true;
    gpio15.GPIO_n.$assign = "PRG0_PRU1_GPO3";
    
    gpio16.$name          = "STATUS_B";
    gpio16.pinDir         = "OUTPUT";
    gpio16.rx             = true;
    gpio16.GPIO_n.$assign = "PRG0_PRU1_GPO4";
    
    gpio17.$name          = "UDR2_R";
    gpio17.pinDir         = "OUTPUT";
    gpio17.rx             = true;
    gpio17.GPIO_n.$assign = "PRG1_PRU0_GPO0";
    
    gpio18.$name          = "UDG1_R";
    gpio18.rx             = true;
    gpio18.GPIO_n.$assign = "PRG1_PRU0_GPO1";
    
    gpio19.$name          = "UDB1_R";
    gpio19.pinDir         = "OUTPUT";
    gpio19.rx             = true;
    gpio19.GPIO_n.$assign = "PRG1_PRU0_GPO2";
    
    gpio20.$name          = "UDRI2_R";
    gpio20.rx             = true;
    gpio20.GPIO_n.$assign = "PRG1_PRU0_GPO3";
    
    gpio21.$name          = "UDRI1_R";
    gpio21.rx             = true;
    gpio21.GPIO_n.$assign = "PRG1_PRU0_GPO4";
    
    gpio22.$name          = "UDR1_R";
    gpio22.rx             = true;
    gpio22.GPIO_n.$assign = "PRG1_PRU0_GPO6";
    
    gpio23.$name          = "UDB2_R";
    gpio23.pinDir         = "OUTPUT";
    gpio23.rx             = true;
    gpio23.GPIO_n.$assign = "PRG1_PRU0_GPO11";
    
    gpio24.$name          = "UDG2_R";
    gpio24.pinDir         = "OUTPUT";
    gpio24.rx             = true;
    gpio24.GPIO_n.$assign = "PRG1_PRU0_GPO12";
    
    gpio25.$name          = "UDBI2_R";
    gpio25.rx             = true;
    gpio25.GPIO_n.$assign = "PRG1_PRU0_GPO13";
    
    gpio26.$name          = "UDGI2_R";
    gpio26.rx             = true;
    gpio26.GPIO_n.$assign = "PRG1_PRU0_GPO14";
    
    gpio27.$name          = "UDGI1_R";
    gpio27.rx             = true;
    gpio27.GPIO_n.$assign = "PRG1_PRU0_GPO15";
    
    gpio28.$name          = "UDBI1_R";
    gpio28.rx             = true;
    gpio28.GPIO_n.$assign = "PRG1_PRU0_GPO16";
    
    gpio29.$name          = "UDCLK";
    gpio29.pinDir         = "OUTPUT";
    gpio29.rx             = true;
    gpio29.GPIO_n.$assign = "PRG0_PRU0_GPO10";
    
    gpio30.$name          = "URXD1";
    gpio30.trigType       = "BOTH_EDGE";
    gpio30.enableIntr     = true;
    gpio30.GPIO_n.$assign = "PRG1_PRU0_GPO19";
    
    i2c1.$name           = "CONFIG_I2C0";
    i2c1.I2C.$assign     = "I2C0";
    i2c1.I2C_child.$name = "drivers_i2c_v0_i2c_v0_template0";
    
    mcspi1.$name                       = "CONFIG_MCSPI0";
    mcspi1.dpe1                        = "ENABLE";
    mcspi1.dpe0                        = "DISABLE";
    mcspi1.inputSelect                 = "0";
    mcspi1.SPI.$assign                 = "SPI3";
    mcspi1.SPI.CLK.$assign             = "PRG0_PRU0_GPO16";
    mcspi1.SPI.D0.$assign              = "PRG0_PRU0_GPO13";
    mcspi1.SPI.D1.$assign              = "PRG0_PRU0_GPO14";
    mcspi1.mcspiChannel[0].$name       = "CONFIG_MCSPI_CH0";
    mcspi1.mcspiChannel[0].bitRate     = 100000;
    mcspi1.mcspiChannel[0].CSn.$assign = "PRG0_PRU0_GPO17";
    mcspi1.child.$name                 = "drivers_mcspi_v0_mcspi_v0_template0";
    
    pruicss1.$name                           = "CONFIG_PRU_ICSS0";
    pruicss1.AdditionalICSSSettings[0].$name = "CONFIG_PRU_ICSS_IO0";
    
    udma2.$name                        = "CONFIG_UDMA0";
    flash1.peripheralDriver.udmaDriver = udma2;
    
    addr_translate1.$name = "CONFIG_ADDR_TRANSLATE_REGION0";
    
    debug_log.enableUartLog            = true;
    debug_log.uartLog.$name            = "CONFIG_UART1";
    debug_log.uartLog.UART.$assign     = "USART0";
    debug_log.uartLog.UART.RXD.$assign = "UART0_RXD";
    debug_log.uartLog.UART.TXD.$assign = "UART0_TXD";
    
    const uart_v0_template  = scripting.addModule("/drivers/uart/v0/uart_v0_template", {}, false);
    const uart_v0_template1 = uart_v0_template.addInstance({}, false);
    uart_v0_template1.$name = "drivers_uart_v0_uart_v0_template0";
    debug_log.uartLog.child = uart_v0_template1;
    
    mpu_armv71.$name             = "CONFIG_MPU_REGION0";
    mpu_armv71.size              = 31;
    mpu_armv71.attributes        = "Device";
    mpu_armv71.accessPermissions = "Supervisor RD+WR, User RD";
    mpu_armv71.allowExecute      = false;
    
    mpu_armv72.$name             = "CONFIG_MPU_REGION1";
    mpu_armv72.size              = 15;
    mpu_armv72.accessPermissions = "Supervisor RD+WR, User RD";
    
    mpu_armv73.$name             = "CONFIG_MPU_REGION2";
    mpu_armv73.baseAddr          = 0x41010000;
    mpu_armv73.size              = 15;
    mpu_armv73.accessPermissions = "Supervisor RD+WR, User RD";
    
    mpu_armv74.$name             = "CONFIG_MPU_REGION3";
    mpu_armv74.baseAddr          = 0x70000000;
    mpu_armv74.accessPermissions = "Supervisor RD+WR, User RD";
    mpu_armv74.size              = 23;
    
    mpu_armv75.$name             = "CONFIG_MPU_REGION5";
    mpu_armv75.baseAddr          = 0xA5000000;
    mpu_armv75.size              = 23;
    mpu_armv75.attributes        = "NonCached";
    mpu_armv75.accessPermissions = "Supervisor RD+WR, User RD";
    
    enet_cpsw1.$name                           = "CONFIG_ENET_CPSW0";
    enet_cpsw1.customBoardEnable               = true;
    enet_cpsw1.mdioBusFreqHz                   = 200000;
    enet_cpsw1.ExternalPhyMgmtEnable           = true;
    enet_cpsw1.mdioMode                        = "MDIO_MODE_MANUAL";
    enet_cpsw1.macAddrConfig                   = "Manual Entry";
    enet_cpsw1.macAddrList                     = "E2:FF:0A:00:FF:FF,70:ff:76:1d:ec:e3";
    enet_cpsw1.hostportPadShortPacket          = false;
    enet_cpsw1.LargePoolPktCount               = 192;
    enet_cpsw1.txDmaChannel[0].$name           = "ENET_DMA_TX_CH0";
    enet_cpsw1.txDmaChannel[0].PacketsCount    = 2;
    enet_cpsw1.rxDmaChannel[0].$name           = "ENET_DMA_RX_CH0";
    enet_cpsw1.rxDmaChannel[0].sizeThreshEn    = 0x1;
    enet_cpsw1.rxDmaChannel[0].PacketsCount    = 190;
    enet_cpsw1.pinmux[0].$name                 = "ENET_CPSW_PINMUX0";
    enet_cpsw1.pinmux[0].enableRgmii2          = false;
    enet_cpsw1.pinmux[0].MDIO.$assign          = "MDIO0";
    enet_cpsw1.pinmux[0].MDIO.MDC.$assign      = "PRG1_MDIO0_MDC";
    enet_cpsw1.pinmux[0].MDIO.MDIO.$assign     = "PRG1_MDIO0_MDIO";
    enet_cpsw1.pinmux[0].RGMII1.$assign        = "RGMII1";
    enet_cpsw1.pinmux[0].RGMII1.RD0.$assign    = "PRG1_PRU1_GPO5";
    enet_cpsw1.pinmux[0].RGMII1.RD1.$assign    = "PRG1_PRU1_GPO8";
    enet_cpsw1.pinmux[0].RGMII1.RD2.$assign    = "PRG1_PRU1_GPO18";
    enet_cpsw1.pinmux[0].RGMII1.RD3.$assign    = "PRG1_PRU1_GPO19";
    enet_cpsw1.pinmux[0].RGMII1.RX_CTL.$assign = "PRG1_PRU0_GPO5";
    enet_cpsw1.pinmux[0].RGMII1.RXC.$assign    = "PRG1_PRU0_GPO8";
    enet_cpsw1.pinmux[0].RGMII1.TD0.$assign    = "PRG1_PRU1_GPO7";
    enet_cpsw1.pinmux[0].RGMII1.TD1.$assign    = "PRG1_PRU1_GPO9";
    enet_cpsw1.pinmux[0].RGMII1.TD2.$assign    = "PRG1_PRU1_GPO10";
    enet_cpsw1.pinmux[0].RGMII1.TD3.$assign    = "PRG1_PRU1_GPO17";
    enet_cpsw1.pinmux[0].RGMII1.TX_CTL.$assign = "PRG1_PRU0_GPO9";
    enet_cpsw1.pinmux[0].RGMII1.TXC.$assign    = "PRG1_PRU0_GPO10";
    
    udma1.$name        = "CONFIG_UDMA_PKTDMA_0";
    udma1.instance     = "PKTDMA_0";
    enet_cpsw1.udmaDrv = udma1;
    mcspi1.udmaDriver  = udma1;
    
    /**
     * Pinmux solution for unlocked pins/peripherals. This ensures that minor changes to the automatic solver in a future
     * version of the tool will not impact the pinmux you originally saw.  These lines can be completely deleted in order to
     * re-solve from scratch.
     */
    i2c1.I2C.SCL.$suggestSolution = "I2C0_SCL";
    i2c1.I2C.SDA.$suggestSolution = "I2C0_SDA";
    

    Best,

    Larry

  • No, this is our product, where we use the AM2431 as our main chip

    Okay. This is your custom board. Can you please try same test on AM243x-evm and provide steps and results for that.

    It will help us to reproduce the issue on our side on EVM.

    Regards

    Ashwani

  • Hi Ashwani,

    I'm sorry for the late reply, I've been handling other tasks recently.

    To clarify, the development board I am using is the LP-AM243, so all my upcoming tests will use this board. I have modified the example code of enet_l2_cpsw for testing purposes, and I made changes in two areas.

    First, I modified the packet pool configuration in Enet(CPSW), changing the Large Pool Packet Count to 192, the Number Of Packets for the ENET RX DMA channel to 124, and the Number Of Packets for the ENET TX DMA channel to 64.

    Second, I modified the contents of EnetApp_rxTask() in l2_cpsw_dataflow.c, so that packets are only returned when the first byte of the payload is not 0x21. Here are the modifications:

     

    void EnetApp_rxTask(void *args)
    {
        EnetApp_PerCtxt *perCtxt = (EnetApp_PerCtxt *)args;
        EnetDma_PktQ rxReadyQ;
        EnetDma_PktQ rxFreeQ;
        EnetDma_PktQ txSubmitQ;
        EnetDma_Pkt *rxPktInfo;
        EnetDma_Pkt *txPktInfo;
        EthFrame *rxFrame;
        EthFrame *txFrame;
        uint32_t totalLenReceived = 0U;
        uint32_t index = 0U,i = 0U;
        uint32_t totalRxCnt = 0U;
        int32_t status = ENET_SOK;
    
        while ((ENET_SOK == status) && (gEnetApp.run))
        {
            /* Wait for packet reception */
            SemaphoreP_pend(&perCtxt->rxSemObj, SystemP_WAIT_FOREVER);
    
            /* All peripherals have single hardware RX channel, so we only need to retrieve
             * packets from a single flow.*/
            EnetQueue_initQ(&rxReadyQ);
            EnetQueue_initQ(&rxFreeQ);
            EnetQueue_initQ(&txSubmitQ);
    
            /* Get the packets received so far */
            status = EnetDma_retrieveRxPktQ(perCtxt->hRxCh, &rxReadyQ);
            if (status != ENET_SOK)
            {
                /* Should we bail out here? */
                EnetAppUtils_print("Failed to retrieve RX pkt queue: %d\r\n", status);
                continue;
            }
    #if DEBUG
            EnetAppUtils_print("%s: Received %u packets\r\n", perCtxt->name, EnetQueue_getQCount(&rxReadyQ));
    #endif
            totalRxCnt += EnetQueue_getQCount(&rxReadyQ);
    
            /* Consume the received packets and send them back */
            rxPktInfo = (EnetDma_Pkt *)EnetQueue_deq(&rxReadyQ);
            while (rxPktInfo != NULL)
            {
                rxFrame = (EthFrame *)rxPktInfo->sgList.list[0].bufPtr;
                EnetDma_checkPktState(&rxPktInfo->pktState,
                                        ENET_PKTSTATE_MODULE_APP,
                                        ENET_PKTSTATE_APP_WITH_DRIVER,
                                        ENET_PKTSTATE_APP_WITH_READYQ);
                totalLenReceived = 0;
                for (i = 0; i < rxPktInfo->sgList.numScatterSegments; i++)
                {
                    totalLenReceived += rxPktInfo->sgList.list[i].segmentFilledLen;
                }
                EnetAppUtils_assert(totalLenReceived <= ENET_MEM_LARGE_POOL_PKT_SIZE);
    
                if(rxFrame->payload[0] != 0x21)
                {
                    TickType_t tickCount  = xTaskGetTickCount();
                    uint32_t current_time = tickCount * portTICK_PERIOD_MS;
                    static prev_time = 0;
    
                    EnetAppUtils_print("Recv 0x22: %d\r\n", current_time - prev_time);
                    prev_time = current_time;
    
                    /* Retrieve TX packets from driver and recycle them */
                    EnetApp_retrieveFreeTxPkts(perCtxt);
    
                    /* Dequeue one free TX Eth packet */
                    txPktInfo = (EnetDma_Pkt *)EnetQueue_deq(&gEnetApp.txFreePktInfoQ);
                    if (txPktInfo != NULL)
                    {
                        /* Fill the TX Eth frame with test content */
                        txFrame = (EthFrame *)txPktInfo->sgList.list[0].bufPtr;
                        memcpy(txFrame->hdr.dstMac, rxFrame->hdr.srcMac, ENET_MAC_ADDR_LEN);
                        memcpy(txFrame->hdr.srcMac, &perCtxt->macAddr[0U], ENET_MAC_ADDR_LEN);
                        txFrame->hdr.etherType = rxFrame->hdr.etherType;
    
                        txPktInfo->sgList.list[0].segmentFilledLen = totalLenReceived;
                        EnetAppUtils_assert(txPktInfo->sgList.list[0].segmentAllocLen >= txPktInfo->sgList.list[0].segmentFilledLen);
    
                        memcpy(&txFrame->payload[0U],
                               &rxFrame->payload[0U],
                               rxPktInfo->sgList.list[0].segmentFilledLen - sizeof(EthFrameHeader));
                        index = rxPktInfo->sgList.list[0].segmentFilledLen - sizeof(EthFrameHeader);
                        for (i = 1; i < rxPktInfo->sgList.numScatterSegments; i++)
                        {
                            memcpy(&txFrame->payload[index],
                                   rxPktInfo->sgList.list[i].bufPtr,
                                   rxPktInfo->sgList.list[i].segmentFilledLen);
                            index += rxPktInfo->sgList.list[i].segmentFilledLen;
                        }
    
                        txPktInfo->sgList.numScatterSegments = 1;
                        txPktInfo->chkSumInfo = 0U;
                        txPktInfo->appPriv = &gEnetApp;
                        txPktInfo->tsInfo.enableHostTxTs = false;
    
                        EnetDma_checkPktState(&txPktInfo->pktState,
                                                ENET_PKTSTATE_MODULE_APP,
                                                ENET_PKTSTATE_APP_WITH_FREEQ,
                                                ENET_PKTSTATE_APP_WITH_DRIVER);
    
                        /* Enqueue the packet for later transmission */
                        EnetQueue_enq(&txSubmitQ, &txPktInfo->node);
                    }
                    else
                    {
                        EnetAppUtils_print("%s: Drop due to TX pkt not available\r\n", perCtxt->name);
                    }
                }
    
                EnetDma_checkPktState(&rxPktInfo->pktState,
                                        ENET_PKTSTATE_MODULE_APP,
                                        ENET_PKTSTATE_APP_WITH_READYQ,
                                        ENET_PKTSTATE_APP_WITH_FREEQ);
    
                /* Release the received packet */
                EnetQueue_enq(&rxFreeQ, &rxPktInfo->node);
                rxPktInfo = (EnetDma_Pkt *)EnetQueue_deq(&rxReadyQ);
            }
    
            /* Transmit all enqueued packets */
            status = EnetDma_submitTxPktQ(perCtxt->hTxCh, &txSubmitQ);
            if (status != ENET_SOK)
            {
                EnetAppUtils_print("%s: Failed to submit TX pkt queue: %d\r\n", perCtxt->name, status);
            }
    
            EnetAppUtils_validatePacketState(&rxFreeQ,
                                                ENET_PKTSTATE_APP_WITH_FREEQ,
                                                ENET_PKTSTATE_APP_WITH_DRIVER);
    
            /* Submit now processed buffers */
            EnetDma_submitRxPktQ(perCtxt->hRxCh, &rxFreeQ);
            if (status != ENET_SOK)
            {
                EnetAppUtils_print("%s: Failed to submit RX pkt queue: %d\r\n", perCtxt->name, status);
            }
        }
    
        EnetAppUtils_print("%s: Received %u packets\r\n", perCtxt->name, totalRxCnt);
    
        SemaphoreP_post(&perCtxt->rxDoneSemObj);
        TaskP_exit();
    }

    The payload content of the packets sent by my program is distinguished by the first byte as the command type. My program will send a large number of 0x21 packets, which will undergo other processing. Only when a 0x22 packet is received will a response be required. Therefore, the modifications mentioned above are simulating the tasks that my firmware needs to perform.

    My program sends a 0x21 packet every 2-3 milliseconds, sending 200 packets in total, and finally sends a 0x22 packet. After sending the 0x22 packet, it stops sending for about 20 milliseconds, and then starts the next sending process. However, under these conditions, the LP-AM243 cannot correctly return the 0x22 packet each time. My goal is to send more than 1000 packets of 0x21, or even more. What else can be modified to achieve this?

    Best,

    Larry

  • Hi ,

    I am on travel this week.

    Please expect some response next week.

    Regards

    Ashwani

  • Hi Ashwani,

    Looking forward your response.

    Best,

    Larry

  • under these conditions, the LP-AM243 cannot correctly return the 0x22 packet each time

    Some data / stats of the miss ?

    Regards

    Ashwani 

  • Hi Ashwani,

    I captured some transmission data using Wireshark. The following link shows a state with a smaller amount of data. Please add frame[14] == 0x22 in the filter position. You can see that for every 0x22 packet sent by my transmitting end, a 0x22 packet is returned.

    https://drive.google.com/file/d/166aD-oyV_p6vm3LCOwW41a0NWHiF5SF9/view?usp=drive_link

    And in the following link, when I increase the amount of data transmitted to a certain extent, using the same filter command, you can see that the LP board is no longer able to return a packet after each 0x22 command is sent, as shown in the previous capture.

    https://drive.google.com/file/d/11_gku0VKEqp9sTVBE7mCmnL2Sxt3imYL/view?usp=drive_link

    Do you need any additional information?

    Best,

    Larry

  • Hi Ashwani,

    Additional information: According to the second file, "four_by_eight_panel_capture," the data rate calculated using Wireshark is only about 50 Mbit/sec. However, based on the SDK documentation "Ethernet Performance," the UDP throughput of the AM243 achieves 50 Mbps with a CPU loading of 16%. Theoretically, it should be more than sufficient to handle this data rate. Nonetheless, I tested the sample program "enet_lwip_cpsw" on the AM243-LP, and using the iperf command, the tested RX throughput was only around 10 Mbps. Could this be the underlying issue?

    Best,

    Larry

  • Hi Larry,

    "enet_lwip_cpsw" on the AM243-LP, and using the iperf command, the tested RX throughput was only around 10 Mbps.

    Are you referring below example ?

    Regards

    Ashwani

  • Hi Ashwani,

    Yes.

    Best,

    Larry

  • Thanks Larry for confirmation.

    I will discuss this internally and get back to you.

    Regards

    Ashwani

  • Hi Larry,

    You are using application / example Debug or release mode?

    You are using port in Switch mode or MAC mode?

    Packet coming to board have VLAN and priority enabled?

    If yes, what are the packet with what priority?

    Are you referring below example ?

    The screenshot I shared showing ~100M iperf performance with constant (non-bursty) traffic.

    Your case seems to have bursty traffic.

    Can you try shaping the traffic reaching to HOST by using below IOCTL?

    Regards

    Ashwani

  • Hi Ashwani,

    To correct, during my previous test of "enet_lwip_cpsw", my PC was connected to WiFi, which then connected to the switch, while the LP-AM243 was connected to the switch via RJ45. In this setup, the throughput I obtained through iperf was only 10Mbps. Last Friday, I corrected the test conditions by connecting both the PC and the LP-AM243 to the same switch via RJ45. Under these conditions, I achieved a throughput similar to the SDK documentation, around 50Mbps.

    Through this experiment, I have understood that the LP-AM243 can actually handle at least 50Mbps of data, and even up to 110Mbps under 100% CPU loading. However, why can "enet_lwip_cpsw" handle this data volume, but "enet_l2_cpsw" seems unable to handle around 50Mbps? Without lwIP, "enet_l2_cpsw" should be more efficient. What exactly is causing this difference?

    Best,

    Larry

  • I achieved a throughput similar to the SDK documentation, around 50Mbps.

    Thanks Lary for update.

    but "enet_l2_cpsw" seems unable to handle around 50Mbps?

    You are using application / example Debug or release mode?

    You are using port in Switch mode or MAC mode?

    If yes, what are the packet with what priority?

    Your case seems to have bursty traffic ?

    Can you try shaping the traffic reaching to HOST by using below IOCTL?

    Regards

    Ashwani

  • Hi Ashwani,

    You are using application / example Debug or release mode?

          I am using debug mode to test.

    You are using port in Switch mode or MAC mode?

         I am just using the example code "enet_l2_cpsw" to test, I think this is in the Switch mode?

    If yes, what are the packet with what priority?

        I don't have any priority for any packet.

    Can you try shaping the traffic reaching to HOST by using below IOCTL?

        How can I using IOCTL?  can you give me some step by step example?

    Best,

    Larry

     

        

  • I am using debug mode to test.

    You may try release mode for better results.

    How can I using IOCTL?  can you give me some step by step example?

    As of now, we do not have a test code for this.

    Regards

    Ashwani

  • Hi Ashwani,

    I want to confirm something. According to the documentation in the SDK, in the table under "Ethernet Performance" for UDP Throughput, when the Datagram Length is 1470B, in the best case scenario, the LP-AM243 can only handle 11Mbps of data per second, correct? Hardware-wise, Ethernet speeds can reach up to 1 gigabit per second, but the LP-AM243's processing capability is only 110Mbps. Is my understanding correct?

    Best,

    Larry

  • Hi Lary,

    I am working on this internally.

    Will get back to you as soon as I have some update.

    Can you check where packet drop is happening?

    At Host (R5F) or MAC level?

    Regards

    Ashwani