1.. _net_l2_interface: 2 3L2 Layer Management 4################### 5 6.. contents:: 7 :local: 8 :depth: 2 9 10Overview 11******** 12 13The L2 stack is designed to hide the whole networking link-layer part 14and the related device drivers from the upper network stack. This is made 15through a :c:struct:`net_if` declared in 16:zephyr_file:`include/net/net_if.h`. 17 18The upper layers are unaware of implementation details beyond the net_if 19object and the generic API provided by the L2 layer in 20:zephyr_file:`include/net/net_l2.h` as :c:struct:`net_l2`. 21 22Only the L2 layer can talk to the device driver, linked to the net_if 23object. The L2 layer dictates the API provided by the device driver, 24specific for that device, and optimized for working together. 25 26Currently, there are L2 layers for :ref:`Ethernet <ethernet_interface>`, 27:ref:`IEEE 802.15.4 Soft-MAC <ieee802154_interface>`, 28:ref:`Bluetooth IPSP <bluetooth-ipsp-sample>`, :ref:`CANBUS <can_api>`, 29:ref:`OpenThread <thread_protocol_interface>`, Wi-Fi, and a dummy layer 30example that can be used as a template for writing a new one. 31 32L2 layer API 33************ 34 35In order to create an L2 layer, or a driver for a specific L2 layer, 36one needs to understand how the L3 layer interacts with it and 37how the L2 layer is supposed to behave. 38See also :ref:`network stack architecture <network_stack_architecture>` for 39more details. The generic L2 API has these functions: 40 41- ``recv()``: All device drivers, once they receive a packet which they put 42 into a :c:type:`net_pkt`, will push this buffer to the network 43 stack via :c:func:`net_recv_data`. At this point, the network 44 stack does not know what to do with it. Instead, it passes the 45 buffer along to the L2 stack's ``recv()`` function for handling. 46 The L2 stack does what it needs to do with the packet, for example, parsing 47 the link layer header, or handling link-layer only packets. The ``recv()`` 48 function will return ``NET_DROP`` in case of an erroneous packet, 49 ``NET_OK`` if the packet was fully consumed by the L2, or ``NET_CONTINUE`` 50 if the network stack should then handle it. 51 52- ``send()``: Similar to receive function, the network stack will call this 53 function to actually send a network packet. All relevant link-layer content 54 will be generated and added by this function. 55 The ``send()`` function returns the number of bytes sent, or a negative 56 error code if there was a failure sending the network packet. 57 58- ``enable()``: This function is used to enable/disable traffic over a network 59 interface. The function returns ``<0`` if error and ``>=0`` if no error. 60 61- ``get_flags()``: This function will return the capabilities of an L2 driver, 62 for example whether the L2 supports multicast or promiscuous mode. 63 64Network Device drivers 65********************** 66 67Network device drivers fully follows Zephyr device driver model as a 68basis. Please refer to :ref:`device_model_api`. 69 70There are, however, two differences: 71 72- The driver_api pointer must point to a valid :c:struct:`net_if_api` 73 pointer. 74 75- The network device driver must use :c:macro:`NET_DEVICE_INIT_INSTANCE()` 76 or :c:macro:`ETH_NET_DEVICE_INIT()` for Ethernet devices. These 77 macros will call the :c:macro:`DEVICE_DEFINE()` macro, and also 78 instantiate a unique :c:struct:`net_if` related to the created 79 device driver instance. 80 81Implementing a network device driver depends on the L2 stack it 82belongs to: :ref:`Ethernet <ethernet_interface>`, 83:ref:`IEEE 802.15.4 <ieee802154_interface>`, etc. 84In the next section, we will describe how a device driver should behave when 85receiving or sending a network packet. The rest is hardware dependent 86and is not detailed here. 87 88Ethernet device driver 89====================== 90 91On reception, it is up to the device driver to fill-in the network packet with 92as many data buffers as required. The network packet itself is a 93:c:type:`net_pkt` and should be allocated through 94:c:func:`net_pkt_rx_alloc_with_buffer`. Then all data buffers will be 95automatically allocated and filled by :c:func:`net_pkt_write`. 96 97After all the network data has been received, the device driver needs to 98call :c:func:`net_recv_data`. If that call fails, it will be up to the 99device driver to unreference the buffer via :c:func:`net_pkt_unref`. 100 101On sending, the device driver send function will be called, and it is up to 102the device driver to send the network packet all at once, with all the buffers. 103 104Each Ethernet device driver will need, in the end, to call 105``ETH_NET_DEVICE_INIT()`` like this: 106 107.. code-block:: c 108 109 ETH_NET_DEVICE_INIT(..., CONFIG_ETH_INIT_PRIORITY, 110 &the_valid_net_if_api_instance, 1500); 111 112IEEE 802.15.4 device driver 113=========================== 114 115Device drivers for IEEE 802.15.4 L2 work basically the same as for 116Ethernet. What has been described above, especially for ``recv()``, applies 117here as well. There are two specific differences however: 118 119- It requires a dedicated device driver API: :c:struct:`ieee802154_radio_api`, 120 which overloads :c:struct:`net_if_api`. This is because 802.15.4 L2 needs more from the device 121 driver than just ``send()`` and ``recv()`` functions. This dedicated API is 122 declared in :zephyr_file:`include/net/ieee802154_radio.h`. Each and every 123 IEEE 802.15.4 device driver must provide a valid pointer on such 124 relevantly filled-in API structure. 125 126- Sending a packet is slightly different than in Ethernet. IEEE 802.15.4 sends 127 relatively small frames, 127 bytes all inclusive: frame header, 128 payload and frame checksum. Buffers are meant to fit such 129 frame size limitation. But a buffer containing an IPv6/UDP packet 130 might have more than one fragment. IEEE 802.15.4 drivers 131 handle only one buffer at a time. This is why the 132 :c:struct:`ieee802154_radio_api` requires a tx function pointer which differs 133 from the :c:struct:`net_if_api` send function pointer. 134 Instead, the IEEE 802.15.4 L2, provides a generic 135 :c:func:`ieee802154_radio_send` meant to be given as 136 :c:type:`net_if` send function. It turn, the implementation 137 of :c:func:`ieee802154_radio_send` will ensure the same behavior: 138 sending one buffer at a time through :c:type:`ieee802154_radio_api` tx 139 function, and unreferencing the network packet 140 only when all the transmission were successful. 141 142Each IEEE 802.15.4 device driver, in the end, will need to call 143``NET_DEVICE_INIT_INSTANCE()`` that way: 144 145.. code-block:: c 146 147 NET_DEVICE_INIT_INSTANCE(..., 148 the_device_init_prio, 149 &the_valid_ieee802154_radio_api_instance, 150 IEEE802154_L2, 151 NET_L2_GET_CTX_TYPE(IEEE802154_L2), 125); 152 153API Reference 154************* 155 156.. doxygengroup:: net_l2 157