kernel/hil/
ethernet.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Leon Schuermann <leon@is.currently.online> 2023.
4// Copyright Tock Contributors 2023.
5
6//! Raw Ethernet Adapter HIL for devices transporting IEEE 802.3 Ethernet
7//! frames.
8//!
9//! This HIL currently only encompasses the raw datapath for IEEE 802.3 Ethernet
10//! frames. It expects frames to be fully formed with an Ethernet header
11//! containing source and destination address. Frames should not include the FCS
12//! (Frame Check Sequence) trailer.
13//!
14//! This HIL is not stable and will be extended by subsequent contributions
15//! building out a more fully-featured in-kernel network stack. However, it is
16//! sufficient to bridge Ethernet MACs / adapters into userspace, where another
17//! network stack can be used.
18
19use crate::ErrorCode;
20
21/// Ethernet adapter datapath client HIL
22pub trait EthernetAdapterDatapathClient {
23    /// An Ethernet frame was transmitted, or an error occurred during
24    /// transmission.
25    ///
26    /// Arguments:
27    ///
28    /// 1. `err`: `Ok(())` if no error occurred, `Err(e)` otherwise.
29    ///
30    ///    Possible error codes:
31    ///    - [`ErrorCode::FAIL`]: an internal error occurred. The frame may or
32    ///      may not have been sent, and the Ethernet MAC may or may not be able
33    ///      to send further frames.
34    ///
35    ///    - [`ErrorCode::BUSY`]: the Ethernet MAC is current busy processing
36    ///      another operation and could not enqueue this frame. A client may
37    ///      try again later.
38    ///
39    ///    - [`ErrorCode::OFF`]: the Ethernet MAC is not enabled or initialized
40    ///      and cannot send this frame.
41    ///
42    ///    - [`ErrorCode::NODEVICE`]: the Ethernet MAC does not have an active
43    ///      link and cannot send this frame.
44    ///
45    /// 2. `frame_buffer`: the buffer initially supplied to `transmit`. Ethernet
46    ///    MACs will retain the sent frame data (from the start of this buffer,
47    ///    up to `len`) in the buffer for inspection by the client.
48    ///
49    /// 3. `len`: the length of the raw frame that was transmitted, including
50    ///    the Ethernet header and excluding the FCS trailer. This value must be
51    ///    identical to the one supplied in
52    ///    [`EthernetAdapterDatapath::transmit_frame`].
53    ///
54    ///    This value imposes a maximum frame size of `u16::MAX` bytes. While
55    ///    Ethernet II frames do not contain an explicit length parameter
56    ///    (instead using the 16-bit length parameter reserved in IEEE 802.3 as
57    ///    an Ethertype parameter), the largest MTUs for Ethernet frames
58    ///    (including various Jumbo-frame options) are all below 65535 bytes and
59    ///    hence fit into a 16-bit integer value.
60    ///
61    /// 4. `transmission_identifier`: an opaque identifier of this transmission
62    ///    operation. This value will be identical to the one supplied in the
63    ///    call to [`EthernetAdapterDatapath::transmit_frame`].
64    ///
65    /// 5. `timestamp`: optional timestamp of the transmission time of this
66    ///    frame, if frame timestamping is enabled (such as for IEEE 1588 PTP).
67    ///    The value of this field is opaque, users of this interface must refer
68    ///    to the [`EthernetAdapterDatapath`] MAC implementation to interpret
69    ///    this value and convert it to a proper timestamp.
70    ///
71    ///    Because the transmit timestamp of a packet is ultimately tied to a
72    ///    particular packet, this value is transported alongside the datapath
73    ///    and not in another, independent callback.
74    fn transmit_frame_done(
75        &self,
76        err: Result<(), ErrorCode>,
77        frame_buffer: &'static mut [u8],
78        len: u16,
79        transmission_identifier: usize,
80        timestamp: Option<u64>,
81    );
82
83    /// An Ethernet frame was received.
84    ///
85    /// Arguments:
86    ///
87    /// 1. `frame`: a buffer containing the frame data, including the Ethernet
88    ///    header and excluding the FCS trailer.
89    ///
90    /// 2. `timestamp`: optional timestamp of the reception time of this frame,
91    ///    if frame timestamping is enabled (such as for IEEE 1588 PTP).  The
92    ///    value of this field is opaque, users of this interface must refer to
93    ///    the [`EthernetAdapterDatapath`] MAC implementation to interpret this
94    ///    value and convert it to a proper timestamp.
95    ///
96    ///    Because the receive timestamp of a packet is ultimately tied to a
97    ///    particular packet, this value is transported alongside the datapath
98    ///    and not in another, independent callback.
99    fn received_frame(&self, frame: &[u8], timestamp: Option<u64>);
100}
101
102/// Ethernet adapter datapath HIL
103pub trait EthernetAdapterDatapath<'a> {
104    /// Set the Ethernet adapter client for this peripheral.
105    fn set_client(&self, client: &'a dyn EthernetAdapterDatapathClient);
106
107    /// Enable reception of Ethernet frames.
108    ///
109    /// Ethernet adapters must not invoke any
110    /// [`EthernetAdapaterClient::received_frame`] client methods before this
111    /// function is called, and not after [`EthernetAdapater::disable_receive`]
112    /// is called.
113    fn enable_receive(&self);
114
115    /// Disable reception of Ethernet frames.
116    ///
117    /// Ethernet adapters must not invoke any
118    /// [`EthernetAdapaterClient::received_frame`] client methods after this
119    /// function is called, until a subsequent call to
120    /// [`EthernetAdapater::enable_receive`].
121    fn disable_receive(&self);
122
123    /// Transmit an Ethernet frame / enqueue a frame for transmission.
124    ///
125    /// Arguments:
126    ///
127    /// 1. `frame`: buffer holding the raw Ethernet frame to be transmitted. The
128    ///    frame must be located at offset `0` in this buffer, including the
129    ///    Ethernet header with source and destination address set, but
130    ///    excluding the FCS trailer. The buffer may be larger than the Ethernet
131    ///    frame. The frame length is set in the `len` argument. The
132    ///    [`EthernetAdapterDatapath`] implementation will return this buffer
133    ///    with its original length in a call to
134    ///    [`EthernetAdapterDatapathClient::transmit_frame_done`], or in the
135    ///    return value of this function.
136    ///
137    /// 2. `len`: the length of the raw frame, including the Ethernet header and
138    ///    excluding the FCS trailer.
139    ///
140    ///    This value imposes a maximum frame size of `u16::MAX` bytes. While
141    ///    Ethernet II frames do not contain an explicit length parameter
142    ///    (instead using the 16-bit length parameter reserved in IEEE 802.3 as
143    ///    an Ethertype parameter), the largest MTUs for Ethernet frames
144    ///    (including various Jumbo-frame options) are all below 65535 bytes and
145    ///    hence fit into a 16-bit integer value.
146    ///
147    /// 3. `transmission_identifier`: an opaque identifier of this transmission
148    ///    operation. This value will be identical to the one supplied in the
149    ///    subsequent call to
150    ///    [`EthernetAdapterDatapathClient::transmit_frame_done`], which will be
151    ///    issued once this frame has been transmitted or an asynchronous error
152    ///    occurred during transmission.
153    ///
154    /// Return value: This function will return with `Ok(())` when a frame has
155    /// successfully been enqueued for transmission. In this case, the currently
156    /// registered client will receive a call to
157    /// [`EthernetAdapterDatapathClient::transmit_frame_done`] containing this
158    /// function call's `transmission_identifier`. In case of a synchronous
159    /// error when enqueueing a frame for transmission, the following errors may
160    /// be returned alongside the passed `frame_buffer`:
161    ///
162    /// - [`ErrorCode::FAIL`]: an internal error occurred. The frame may or may
163    ///   not have been sent, and the Ethernet MAC may or may not be able to
164    ///   send further frames.
165    ///
166    /// - [`ErrorCode::BUSY`]: the Ethernet MAC is currently busy processing
167    ///   another operation and could not enqueue this frame. A client may try
168    ///   again later.
169    ///
170    /// - [`ErrorCode::OFF`]: the Ethernet MAC is not enabled or initialized and
171    ///   cannot send this frame.
172    ///
173    /// - [`ErrorCode::NODEVICE`]: the Ethernet MAC does not have an active link
174    ///   and cannot send this frame.
175    ///
176    /// When this function returns with a synchronous error, it will not also
177    /// raise a callback for this transmit operation.
178    ///
179    /// Ethernet adapters may or may not support multiple outstanding / pending
180    /// transmissions. When they do not, they will return `Err(ErrorCode::BUSY)`
181    /// when trying to transmit a frame while another transmission is pending or
182    /// in progress.
183    fn transmit_frame(
184        &self,
185        frame_buffer: &'static mut [u8],
186        len: u16,
187        transmission_identifier: usize,
188    ) -> Result<(), (ErrorCode, &'static mut [u8])>;
189}