ASIX driver sends a ZLP after every completed OUT request
ilyapas opened this issue · 0 comments
What target device are you using?
STM32H7B3
Which version of Azure RTOS?
6.2.0
What toolchain and environment?
arm-none-eabi
Hi,
we are using a STM32H7B3 controller in combination with a USB Ethernet Adapter based on the ASIX AX88772B chip.
We have DMA enabled for the USB Host Controller.
We noticed that after a successful transmission of the network packet to the ASIX chip the driver generates an extra zero-length packet. ASIX seems to not expect the ZLP and the network packet is never sent via Ethernet.
Here is the code responsible for the ZLP generation.
ux_host_class_asix_transmission_callback.c:
/* Check if a ZLP is needed. */
if ((transfer_request -> ux_transfer_request_actual_length > 0) &&
((transfer_request -> ux_transfer_request_actual_length %
transfer_request -> ux_transfer_request_packet_length) == 0))
{
transfer_request -> ux_transfer_request_requested_length = 0;
_ux_host_stack_transfer_request(transfer_request);
return;
}
Here is the 346-byte DHCP Discover packet as seen on the USB bus:
The ZLP is generated because after the 346-byte transfer ux_host_class_asix_transmission_callback function is entered with:
- ux_transfer_request_actual_length = 346
- ux_transfer_request_packet_length = 346
-> ZLP condition is true -> ZLP is sent
This only happens if DMA is enabled. With DMA disabled the values are different:
- ux_transfer_request_actual_length = 26 (which is the size of the last USB packet)
- ux_transfer_request_packet_length = 346
-> the ZLP condition is false -> no ZLP is sent.
We have tried sending ZLPs only if the last USB packet is equal to wMaxPacketSize of the endpoint (64 bytes), which is what ASIX does when sending packets to the USB Host, but even this seems to not be what ASIX chip is expecting, resulting in no generated Ethernet packets.
The only solution that has worked reliably for us is to remove the code above altogether and thus to never send ZLPs at all, which is what effectively happens when DMA is disabled.
The code above looks obviously wrong. Or are we missing something here?
Kind regards
Ilya