New ENET assert occurs after porting from SDK v2.7.0 to v2.9.0

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

New ENET assert occurs after porting from SDK v2.7.0 to v2.9.0

1,240 Views
lh_dan
Contributor III

After porting existing K65 code from SDKv2.7.0 to SDKv2.9.0 (verified the issue with SDKv2.8.2 as well), I now am seeing asserts when operating my device on an extremely busy network. The assert being seen (ENET_GetRxBuffer() status != kStatus_Success) is found in the new function ethernetif_drop_frame() of enet_ethernetif_kinetis.c:

static void ethernetif_drop_frame(struct ethernetif *ethernetif)
{
    status_t status;
    void *buffer;
    uint32_t len;
    uint32_t ts;
    bool isLastBuff;

    do
    {
#if 0 /* Error statisctics */
        enet_data_error_stats_t eErrStatic;
        /* Get the error information of the received g_frame. */
        ENET_GetRxErrBeforeReadFrame(&ethernetif->handle, &eErrStatic);
#endif
        status = ENET_GetRxBuffer(ethernetif->base, &ethernetif->handle, &buffer, &len, 0, &isLastBuff, &ts);
        LWIP_UNUSED_ARG(status); /* for LWIP_NOASSERT */
        LWIP_ASSERT("ENET_GetRxBuffer() status != kStatus_Success", status == kStatus_Success);
        ENET_ReleaseRxBuffer(ethernetif->base, &ethernetif->handle, buffer, 0);
    } while (!isLastBuff);

    LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_linkinput: RxFrameError\n"));

    LINK_STATS_INC(link.drop);
    MIB2_STATS_NETIF_INC(netif, ifindiscards);
}

The asserts occur when receive descriptors are being dropped because of frame errors found by ENET_GetRxFrameSize when the length of the descriptor buffer is zero:

            /* Add check for abnormal case. */
            if (curBuffDescrip->length == 0U)
            {
                isReturn = true;
                result   = kStatus_ENET_RxFrameError;
                break;
            }

When this is the case, it seems that the last flag (ENET_BUFFDESCRIPTOR_RX_LAST_MASK) on the descriptor in error is not set, resulting in the ethernetif_drop_frame() function attempting to drop multiple descriptors. It is when this function is attempting to drop the second descriptor that this error/assert occurs.

Setting the last flag in the descriptor in error seems to solve the issue as this stops the drop frame function from dropping multiple descriptors. Though I am unsure if this is the correct solution. 

Does anyone have any thoughts on what is going on here and what the proper solution might be? 

Labels (1)
0 Kudos
5 Replies

1,108 Views
sagar_prajapati
Contributor II

Hello @Alexis_A ,

 

Is there any update on this isssue?

I am also facing same problem.

 

Regards,

Sagar

0 Kudos

1,187 Views
Alexis_A
NXP TechSupport
NXP TechSupport

Hello @lh_dan,

After analyzing this problem, I'm not entirely sure that setting the flag, in the length section, would be the best option, since is possible that after a frame fails, all the frame is not discarded and this could cause corruption in the following ones.

Could you try adding this flag in the ENET_SetRxBufferDescriptors in the following section?

Alexis_A_0-1615596120285.png

Best Regards,

Alexis Andalon

 

0 Kudos

1,167 Views
lh_dan
Contributor III

Hi Alexis,

Thanks for looking into this issue for me. I am working from home today but when I get back to the office later this week I should be able to test this out. I'll let you know if it fixes my issue.

So does this only set the last flag on the last buffer descriptor (the bd with the wrap bit set)?

-Dan

0 Kudos

1,148 Views
lh_dan
Contributor III

Alexis, 

I tested out the code change that you suggested (and removed my previous change). It did not fix the issue that I am seeing. 

Looking at the fix you suggested, wouldn't this just set the last flag at initialization but not on any later transaction? When ENET_ReleaseRxBuffer() releases the buffer it will always clear the last flag. 

            /* Clears status including the owner flag. */
            blockBuffDescrip->control &= ENET_BUFFDESCRIPTOR_RX_WRAP_MASK;
            /* Sets the receive buffer descriptor with the empty flag. */
            blockBuffDescrip->control |= ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK;

One interesting thing that I noticed is that the comments for ENET_GetRxBuffer show that ENET_GetRxBuffer & ENET_ReleaseRxBuffer should not be called when when length is zero. However the actual code does exactly this.

lh_dan_0-1615991183866.png

 

0 Kudos

1,199 Views
Alexis_A
NXP TechSupport
NXP TechSupport

Hello @lh_dan,

My first impression is that your workaround seems OK, but let me investigate a little more to see if I can find a more suitable workaround.

Best Regards,

Alexis Andalon

0 Kudos