[riot-notifications] [RIOT-OS/RIOT] [RFC] netdev: change receive mechanism (#11652)

José Alamos notifications at github.com
Fri Jun 7 17:24:05 CEST 2019

> Moreover, for link layers with smaller packet sizes this might be fine, but e.g. all Ethernet devices would require an extra 1500 B of RAM with that. This is IMHO a no-go, especially if it is not necessarily required.

Indeed for Ethernet is a different story. In fact, most OS's allocate memory for LLs with huge MTU.
This is usually not the case for LLs like IEEE802.15.4 (in fact, some OSs receive the packet in stack variables and then directly call the phy_indication function). See for instance [this](https://github.com/contiki-os/contiki/blob/bc2e445817aa546c0bb93a9900093ec276005e2a/dev/cc1200/cc1200.c#L2211) and [this](https://github.com/ARMmbed/mbed-os/blob/4a2985a5c34f6e97bf9767545df29665c1b274ff/components/802.15.4_RF/atmel-rf-driver/source/NanostackRfPhyAtmel.cpp#L1771)

> Yeah, allocations are slow.  ;)

Yes, indeed, but the graphs doesn't show the effect of allocation because in both setups I'm calling `gnrc_pktbuf_add` . The only difference is an extra rx_buf I defined in the second case, so there's a an extra memcpy (but still faster than calling `netdev->driver->recv` twice).

I have the impression if I do all the MAC logic without allocation, the time difference would be even bigger (I might try to find some time to show some results there).

> This doesn't need to be changed in netdev. The (admittedly somewhat complicated) recv logic especially allows leaving the buffer handling to the stack. Somewhere up, gnrc should maybe use static input buffers instead of dynamic packet snips.

I agree it's possible to do both with netdev.

(Sorry for the long explanation, but I need to present some context)

Slightly out of the scope of this issue, but while working for some months in PHY/MAC layer rework, I've noticed a generic network abstraction with a southbound API to network devices might not be the best idea:
1. Below the MAC layer, most PHY and network devices (RF, ethernet) work in a completely different way. The MAC<->PHY interface for IEEE802.15.4 looks totally different than the one for Ethernet or LoRaWAN. Same for the PHY<->network device interface. Trying to make a generic interface in these layers doesn't make too much sense considering they are usually well defined and not interchangeable (an Ethernet MAC shouldn't talk to a LoRaWAN PHY in most cases)

A concrete example is the NETOPT_PRELOADING option. It was added for keeping a frame in the transceiver's framebuffer before calling tx_exec. This is a native operation of a IEEE802.15.4 transceiver, and a IEEEE802.15.4 PHY layer already knows how to "prepare" and "transmit" without needing to add [this logic](https://github.com/RIOT-OS/RIOT/blob/master/drivers/at86rf2xx/at86rf2xx_netdev.c#L231)

Another example: transceivers are not aware of PAN ID, short address, long address, etc. Some devices (at86rf2xx) include some helpers to deal with common MAC layer operations (hw address filtering, etc), and have some functions to load the hw address. But still, the driver is not aware of the addresses. This means there's a specific MAC<->device interface for setting hw filter addresses, that won't be present in other PHY/MAC layers

Usually the convergence layer goes on top of the MAC. See how Linux "net_dev" diverges on top of mac80211 and the Ethernet driver (from Linux.com):

These lack of several interfaces between MAC, PHY and transceivers is one of the reasons why we have MAC/PHY components scattered everywhere (RF, netdev, gnrc_netif) and why we don't have more complex MAC layers (although we can send IEEE802.15.4 frame, we don't have a IEEE802.1.54 MAC layer with security, commisioning, coordinators, beacons, etc).

The `netdev` interface can work OK with a southbound API to MAC layers (or directly on top of devices with very simple MAC/PHY). I drew this picture some time ago to show how the netdev interface can work on top of SoftMAC (software MAC) and FullMAC (MAC implemented in the device, e.g CA8210):


2. There are well defined and stable northbound and southbound API's for MAC/PHY. Check for instance https://github.com/RIOT-OS/RIOT/issues/11324. We are reinventing the wheel each if we try to run glue code there.

3. In practice, the API on top of the network device is not sufficient for properly sending packets, doing CSMA, etc. In order to send data, it's required to be on top of the MAC layer, not on top of the device. Since we use `netdev` directly on top of the network device, we have to write part of the MAC layer each time we want to send data (see [gnrc_netif](https://github.com/RIOT-OS/RIOT/blob/master/sys/net/gnrc/netif/ieee802154/gnrc_netif_ieee802154.c#L232 and [AT86RF2xx test driver](https://github.com/RIOT-OS/RIOT/blob/f2754a4dfc15854b37fd37f2ff018ff30c81937f/tests/driver_at86rf2xx/cmd.c#L277)). The semantic of "send", "recv", "get" and "set" is not the best for an API for a transceiver (but can be on top of a MAC layer).

Maybe it's not the smartest idea to open the discussion here, I can open an issue if you want.

Going back to the original discussion and the points mentioned above, it could be possible to have different receive procedures depending on the MAC layer (it makes a lot of sense to allocate 1500 byte for Ethernet, but maybe not 127 bytes for IEEE802.15.4).


You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.riot-os.org/pipermail/notifications/attachments/20190607/d9ece9f2/attachment.html>

More information about the notifications mailing list