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}