Hi there,
I am using FreeRTOS+TCP 4.2.0 on a NXP i.MXRT1170.
First steps are completed, obtaining an IP address with DHCP works however I noticed some issues with sending ICMP packet responses.
- When the FreeRTOS IP stack is providing the checksums, everything works as expected
- When the checksum calculation is offloaded to the CPU (and disabled in FreeRTOS) by using the TX accelerator of the CPU by providing two settings to the enet_config_t struct
/*!< Insert IP header checksum and protocol checksum. */
config.txAccelerConfig = kENET_TxAccelIpCheckEnabled |
kENET_TxAccelProtoCheckEnabled;
then DHCP works as expected, ICMP packets are received, responses are sent however the responses are disregarded by the server due to a wrong IP header checksum.
The ICMP checksum in that case is correctly calculated but the IP header checksum (only in ICMP packets) is always 0xffff. I thought that this would be the case when the checksum is calculated twice, so I added a line in FreeRTOS_ICMP.c which zeros not only the ICMP header checksum but also the IP header checksum like this
#if ( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 0 )
{
/* calculate the IP header checksum, in case the driver won't do that. */
pxIPHeader->usHeaderChecksum = 0x00U;
pxIPHeader->usHeaderChecksum = usGenerateChecksum( 0U, ( uint8_t * ) &( pxIPHeader->ucVersionHeaderLength ), uxIPHeaderSizePacket( pxNetworkBuffer ) );
pxIPHeader->usHeaderChecksum = ( uint16_t ) ~FreeRTOS_htons( pxIPHeader->usHeaderChecksum );
/* calculate the ICMP checksum for an outgoing packet. */
( void ) usGenerateProtocolChecksum( ( uint8_t * ) pxICMPPacket, pxNetworkBuffer->xDataLength, pdTRUE );
}
#else
{
/* Just to prevent compiler warnings about unused parameters. */
( void ) pxNetworkBuffer;
/* Many EMAC peripherals will only calculate the ICMP checksum
* correctly if the field is nulled beforehand. */
pxICMPHeader->usChecksum = 0U;
/* mod: also setting ip header checksum to zero*/
pxIPHeader->usHeaderChecksum = 0x00U;
}
#endif /* if ( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 0 ) */
With this modification, everything works as expected when offloading the checksum calculation to the CPU.
I don’t know if this causes any side effects for other CPUs.
Best regards,
Rainer