We need very fast Wi-Fi transfer rates at times. I have been able to tune the code and Wi-Fi driver settings to get up to 30-35 Mbps which is great. But if I don't throttle the transmission then the faster the packets are sent, the higher the percentage are thrown out by the Wi-Fi driver.
The application level zsock_send(sock, packet, size, 0) function blocks, so I would think that would automatically throttle how fast the data is sent from the application so that it doesn't overflow any downstream buffers such as in the Wi-Fi driver. But that is not the case. If the data is sent too quickly, then a large percentage of packets are lost. I traced it down to the Wi-Fi driver:
If the queue is full then it just silently discards any additional packets. This does not block the application, so it just keeps sending without knowing that 10-25% (depending on the sending speed) of the packets are being ignored and never sent.
So if the queue being full doesn't bubble up and cause the zsock_send() call to block, how do I know when I'm sending too fast and the driver queue is overflowing? I tried increasing the queue size with CONFIG_NRF700X_MAX_TX_PENDING_QLEN, but that doesn't really help since we have sustained high speeds for a few seconds. If the queue is being filled faster than it is being emptied, no matter how big it is it will overflow. So I need some way to automatically slow the sending of the packets to avoid the overflow.
- Is there a function to call to get the low level driver queue state?
- Is there a way to get a count of how many packets the tx_enqueue or tx_process functions are discarding? Maybe I could poll that as a way to infer when overflow is occurring. But I'd rather not have any overflow at all, because that means lost packets and I won't know which ones.
- Is there maybe a callback or something that can send an event when the queue is getting close to full?
- Is there a way to make zsock_send() truly block if the downstream queue is full?
The zperf speed test has a loop that generates successive packets and calls zsock_send() to send them. If the loop time is too short for the target data rate it is trying to get then it will insert delays with k_sleep() to slow things down. But if the target speed is set too high, the Wi-Fi driver starts throwing out packets. And if the delay is removed completely so the loop runs as fast as the zsock_send() blocking allows, then even more packets get thrown out.
There has to be a way to send as fast as possible, but wait when the Wi-Fi Tx queue gets full so it can catch up. How can I do this?