apache / apache/nuttx

NuttX Net & IOB DMA incompatiblity

Open
#6,835 6 comments 0 reactions 0 assignees View on GitHub
Dominant language
C
Stars
4k
Forks
1.7k
Avg merge
1d 17h
Merged PRs (30d)
237

Description

Currently almost all Ethernet MAC with DMA roughly work in the following manner
```mermaid
sequenceDiagram
participant DMA
participant MAC driver
MAC driver->>MAC driver: Allocate rxbuffer[N * (MTU + DESC + PAD)]
MAC driver->>DMA: Setup DMA Engine
DMA ->>MAC driver: IRQ Event packet received
and copied to rxbuffer[]
MAC driver ->>Workqueue: Schedule workqueue
to handle packet
Workqueue ->>Net: Process packet
(TCP Assembly, Checksum etc)
send to network stack
Net ->> IOB: Push packet data to IOB buffer
and notify socket listener
IOB ->> App : App executes write(s, buffer[])
copy data from IOB to local buffer
```

As result the same packet data will be in
```
MAC: rxbuffer
IOB: buffer
App: local buffer
```
Ideally we want the MAC DMA Engine to directly copy the packet to the having the following scheme.
```mermaid
sequenceDiagram
participant DMA
participant MAC driver
participant Workqueue
participant Net
MAC driver->>DMA: Setup DMA Engine
DMA ->> IOB : Copy Packet to IOB
DMA ->>MAC driver: IRQ Event packet received
and copied to iob
MAC driver ->>Workqueue: Schedule workqueue
to handle packet
Workqueue ->>Net: Send to network stack
Net ->> MAC driver: Since data is in MAC specific DMA format
Callback to MAC to parse received data
alt CRC Done by MAC
Net->>MAC driver: Request bit to check CRC is correct
else CRC Done in software
Net->>Net: Calculate CRC and verify
end
Net ->> App: Notify socket listener
IOB ->> App : App executes write(s, buffer[])
copy data from IOB to local buffer
```

The biggest problem is though that MAC has it's own representation of the DMA descriptor + buffer.
IMXRT
https://github.com/apache/incubator-nuttx/blob/5d12e350da31324e632ee7da3a3062b05212b74c/arch/arm/src/imxrt/hardware/imxrt_enet.h#L650-L662
STM32H7
https://github.com/apache/incubator-nuttx/blob/5d12e350da31324e632ee7da3a3062b05212b74c/arch/arm/src/stm32h7/hardware/stm32_ethernet.h#L662-L670

PR #6834 is trying to address this, however on system with mixed interfaces utilizing the NET stack & IOB.
For example
| Interface | MTU |
|----------|------|
| Ethernet | 1518 |
| WIFI | 576 |
| CAN2.0B | 13 |

When adding the DMA Descriptor to the IOB as proposed in #6834 each IOB in the case of IMXRT would by grow by 29bytes.

I can think of some solutions but I'm not sure what would be best:

1. Make the IOB buffer peripheral specific, hence for the example above we will get 3 separate IOB buffer pools
2. Create a 2nd DMA aware IOB `iob_dma` that has metadata of the DMA descriptor and pheripheral. Where the Network stack can invoke callbacks to the pheripheral to parse the received metadata (also nice to check for HW offloading and then fallback to the SW method)
3. Create IOB buffer pool that supports variable data length, a good example could be https://github.com/pavel-kirienko/o1heap

Another thing I want to address is to support the HW offloading bits, there are ethernet MAC's that have IP offloading features such as checksum calculation done by MAC and simply indicate using a bit that the CRC in the DMA descriptor, or indicate that an automatic ARP response has been send.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.