Hardware IPv4 checksum on an STM32F407 is not working, though all the proper settings are set. (Works on rare occasions, oddly)
I'm debugging a legacy application on an STM32F407 that uses the std peripheral libraries and LwIP 1.4.1, and except on rare occasions, hardware IPv4 checksums don't work; they all get sent out as zeroes. When I disable hardware checksums in lwipopts.h, I get correct checksums (but at a performance penalty). The application works reliably in all other respects, and we've previously ignored the checksum issue.
My development IDE is Keil MDK 5.36.0.0
Ethernet link is 100BaseT, fixed IPv4 addressing (no DHCP), with two different PHY chips on different target systems (both systems use the same Ethernet stack code and exhibit the same bug).
There are a number of settings that need to be used for this, and after many searches, much reading, and a number of debug sessions, I'm confident I have set them all to the right settings. (I've gone as far as breakpointing the Ethernet transmission when it is about to hand over the Ethernet DMA TX descriptor, and checking the descriptor fields and Ethernet registers at that time.)
- CHECKSUM_BY_HARDWARE defined in lwipopts.h
- USE_ENHANCED_DMA_DESCRIPTORS defined in stm32f4x7_eth_conf.h
- Extended Tx descriptors are used, and are initialized with CIC bits set to ETH_DMATxDesc_CIC_TCPUDPICMP_Full
- ETH_DMAMBR EDFE bit set to 1
- ETH_MACCR IPCO bit set to 1
- IPv4 ethertype used for transmit
The fact that I have had ONE debug session that did return nonzero checksums with hardware calculation enabled leads me to suspect that I'm configuring the registers and descriptors correctly, but some subtle interference is happening. I'm aware of the IPv6 erratum, but I don't think it applies here.
Where else should I look for the cause of this?
Thanks,
Steve Hersey
