nxp-mcuxpresso/mcux-sdk

[BUG]ENET_QOS:Unstable packet reception

Closed this issue · 2 comments

Since the reception of Ethernet packets was unstable, I checked the source code.
In fsl_enet_qos.c:
In ENET_QOS_DropFrame() like this... :

        if (tsAvailable && ((rxDesc->control & ENET_QOS_RXDESCRIP_WR_CTXT_MASK) != 0U))
         {
             if (!handle->doubleBuffEnable)
             {
                 buff1Addr = handle->rxBufferStartAddr[channel][rxBdRing->rxGenIdx];
                 ENET_QOS_UpdateRxDescriptor(rxDesc, (void *)(uint8_t *)buff1Addr, NULL, handle->rxintEnable,
                                             handle->doubleBuffEnable);
             }
             else
             {
                 buff1Addr = handle->rxBufferStartAddr[channel][2U * rxBdRing->rxGenIdx];
                 buff2Addr = handle->rxBufferStartAddr[channel][2U * rxBdRing->rxGenIdx + 1U];
                 ENET_QOS_UpdateRxDescriptor(rxDesc, (void *)(uint8_t *)buff1Addr, (void *)(uint8_t *)buff2Addr,
                                             handle->rxintEnable, handle->doubleBuffEnable);
             }
             rxBdRing->rxGenIdx = ENET_QOS_IncreaseIndex(rxBdRing->rxGenIdx, rxBdRing->rxRingLen);
         }

Skipping descriptors with the TSA bit set...

In ENET_QOS_ReadFrame() like this... :

             if (tsAvailable)
             {
                 uint8_t retryTimes = 10;

                 while (((control & ENET_QOS_RXDESCRIP_WR_OWN_MASK) != 0U) ||
                        ((control & ENET_QOS_RXDESCRIP_WR_CTXT_MASK) == 0U))
                 {
                     SDK_DelayAtLeastUs(1U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
                     if (0U == retryTimes--)
                     {
                         assert(false);
                     }
                     control = rxDesc->control;
                 }
             }

             /* Reinit for the context descriptor which has been updated by DMA.
             if ((control & ENET_QOS_RXDESCRIP_WR_CTXT_MASK) != 0U)
             {
                 if (tsAvailable && (NULL != ts))
                 {
                     ENET_QOS_StoreRxFrameTime(base, handle, rxDesc, ts);
                 }

                 if (!handle->doubleBuffEnable)
                 {
                     buff1Addr = handle->rxBufferStartAddr[channel][rxBdRing->rxGenIdx];
                     ENET_QOS_UpdateRxDescriptor(rxDesc, (void *)(uint8_t *)buff1Addr, NULL, handle->rxintEnable,
                                                 handle->doubleBuffEnable);
                 }
                 else
                 {
                     buff1Addr = handle->rxBufferStartAddr[channel][2U * rxBdRing->rxGenIdx];
                     buff2Addr = handle->rxBufferStartAddr[channel][2U * rxBdRing->rxGenIdx + 1U];
                     ENET_QOS_UpdateRxDescriptor(rxDesc, (void *)(uint8_t *)buff1Addr, (void *)(uint8_t *)buff2Addr,
                                                 handle->rxintEnable, handle->doubleBuffEnable);
                 }
                 rxBdRing->rxGenIdx = ENET_QOS_IncreaseIndex(rxBdRing->rxGenIdx, rxBdRing->rxRingLen);
             }

Descriptors are updated with or without the TSA bit.

I referenced the logic of ENET_QOS_DropFrame() and modified ENET_QOS_ReadFrame() to similarly update the descriptor when the TSA bit is set.

As a result, reception has improved.

Thanks for reporting the issue, already forwarded the issue to internal team, feedback could be delayed.

Thank you for fixing the problem.

I have confirmed the contents of your source code modification.
The modification was the same as mine, so I was able to confirm that my modification of the source code was correct.

thank you.