That is an interesting solution, it also works for me. It is 3 percent faster than my solution with the extra mutex.
It looks like a silicon problem: as soon as the CPU fills all transmission descriptors , the peripheral “forgets” to call the transmit-complete-interrupt GMAC_ISR_TCOMP.
Solution:
When there are GMAC_TX_BUFFERS descriptors, we will make sure that there is always one descriptor free. That seems to do the trick.
The counting semaphore xTXDescriptorSemaphore will have a maximum count of GMAC_TX_BUFFERS-1.
While testing I saw that sometimes 2 TX descriptors were occupied, and both transmissions were completed with a GMAC_ISR_TCOMP interrupt.
I cleaned the sources and uploaded them to my branch IPv4_single_SAM_EMAC_race_condition.
Note that for the SAME70, we don’t have to calculate the checksum for transmission. Not calling vGMACGenerateChecksum() makes sending a lot faster.
Testing:
- I tested both
GMAC_TX_BUFFERS=2and6. - Also I varied the
ipconfigNETWORK_MTU, between586and1500.
Optimal settings for a IPERF3 TCP test:
#define GMAC_RX_BUFFERS 4
#define GMAC_TX_BUFFERS 6
#define ipconfigNETWORK_MTU 1500
#define ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS 24
#define ipconfigIPERF_TX_BUFSIZE ( 6 * ipconfigTCP_MSS ) /* Units of bytes. */
#define ipconfigIPERF_TX_WINSIZE ( 4 ) /* Size in units of MSS */
#define ipconfigIPERF_RX_BUFSIZE ( 6 * ipconfigTCP_MSS ) /* Units of bytes. */
#define ipconfigIPERF_RX_WINSIZE ( 4 ); /* Size in units of MSS */
Would you be so kind to test the above driver from Github?
I will also keep my test with IPERF running here and transmit 1 TB ![]()