zephyr/drivers/ethernet
Aurelien Jarno 87cf468959 drivers: eth: gmac: fix TX descriptor write process
The SAM E70 Ethernet driver uses scatter gather DMA to transmit data.
Each fragment of a network packet is mapped from a set of descriptors
that is used by the controller to do the DMA transfer. Each descriptor
contain an address and a length/status. The important status bits are
GMAC_TXW1_LASTBUFFER to indicate the last fragment of a packet and
GMAC_TXW1_USED to indicate that a descriptor has been processed by the
controller.

When starting a transmission, the controller start at the descriptor
after the last one that has been processed. If the descriptor is NOT
flagged by GMAC_TXW1_USED, it sends a first packet by sending all the
fragments up to a descriptor flagged with GMAC_TXW1_LASTBUFFER. The
first descriptor of a packet *and only the first descriptor of a packet*
is then modified to flag it with GMAC_TXW1_USED and to provide a status
(mostly related to errors and checksum offloading). It then continues
with the next packet and so on and only stops if the next descriptor
after GMAC_TXW1_LASTBUFFER is flagged with GMAC_TXW1_USED.

Therefore in order for the controller to stop processing descriptors,
the strategy is to flag the next descriptor after the last fragment to
be sent with GMAC_TXW1_USED. When the next packet has to be queued, the
flag can be removed before starting a transmission.

This is what is currently done in the current driver. However there is a
small race condition in the implementation: if packets are queued fast
enough, the controller is still sending the fragment of the previous
packet when the descriptor are written. When writing the first
descriptor, the GMAC_TXW1_USED flag is removed. This is done after
writing the address (with a memory barrier) so that looks safe. However
given that the GMAC_TXW1_USED flag is only added by the controller to
the first descriptor of a packet it means the next descriptor might
have it cleared. In that case the descriptor is processed, and a junk
packet is sent. That also desynchronize eth_tx and tx_complete as one
or more packets than expected are transmitted.

In order to fix that the strategy is slightly changed to initially write
the first descriptor with the GMAC_TXW1_USED flag set. Once all the
descriptors from the packet are written the bit is cleared (after a
memory barrier). Then the transmission can be started safely.

The patch also does a small optimization writing the next descriptor
with only the GMAC_TXW1_USED bit set instead of setting this bit. As
this will be a non-cached area, it's better avoiding a read followed
by a write if not necessary.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
2019-01-22 15:40:05 +02:00
..
CMakeLists.txt drivers: eth_smsc911x: Add driver for SMSC9118 aka LAN9118 chip 2019-01-19 11:59:29 -05:00
eth_dw_priv.h
eth_dw.c
eth_e1000_priv.h
eth_e1000.c
eth_enc28j60_priv.h
eth_enc28j60.c drivers: eth_enc28j60: moved to dts 2019-01-16 21:28:23 -05:00
eth_mcux.c
eth_native_posix_adapt.c
eth_native_posix_priv.h
eth_native_posix.c
eth_sam_gmac_priv.h drivers: eth: gmac: conservatively compute the number of descriptors 2019-01-22 15:40:05 +02:00
eth_sam_gmac.c drivers: eth: gmac: fix TX descriptor write process 2019-01-22 15:40:05 +02:00
eth_smsc911x_priv.h drivers: eth_smsc911x: Add driver for SMSC9118 aka LAN9118 chip 2019-01-19 11:59:29 -05:00
eth_smsc911x.c drivers: eth_smsc911x: Add driver for SMSC9118 aka LAN9118 chip 2019-01-19 11:59:29 -05:00
eth_stellaris_priv.h
eth_stellaris.c
eth_stm32_hal_priv.h
eth_stm32_hal.c
Kconfig drivers: eth_smsc911x: Add driver for SMSC9118 aka LAN9118 chip 2019-01-19 11:59:29 -05:00
Kconfig.dw kconfig: Refactor the dependency on 'NET_L2_ETHERNET' 2018-12-30 16:24:50 -05:00
Kconfig.e1000
Kconfig.enc28j60 drivers: eth_enc28j60: moved to dts 2019-01-16 21:28:23 -05:00
Kconfig.mcux drivers: eth_mcux: By default use 1 buffer each for hardware RX/TX 2019-01-21 12:40:33 +02:00
Kconfig.native_posix kconfig: Refactor the dependency on 'NET_L2_ETHERNET' 2018-12-30 16:24:50 -05:00
Kconfig.sam_gmac kconfig: Refactor the dependency on 'NET_L2_ETHERNET' 2018-12-30 16:24:50 -05:00
Kconfig.smsc911x drivers: eth_smsc911x: Add driver for SMSC9118 aka LAN9118 chip 2019-01-19 11:59:29 -05:00
Kconfig.stellaris drivers: eth: stellaris: Enable automatic Ethernet support in QEMU 2019-01-11 09:48:27 +02:00
Kconfig.stm32_hal kconfig: Refactor the dependency on 'NET_L2_ETHERNET' 2018-12-30 16:24:50 -05:00
phy_sam_gmac.c
phy_sam_gmac.h