CHERIoT RTOS
A compartmentalised RTOS for CHERIoT hardware
Loading...
Searching...
No Matches
ethernet.hh
1#pragma once
2#include <array>
3#include <concepts>
4#include <cstdint>
5
6/**
7 * Helper concept for the type returned by `receive_frame`. This must provide a
8 * buffer and a length. It may also be an RAII type that handles any cleanup
9 * when it is destroyed.
10 *
11 * This is not required to be copyable.
12 */
13template<typename T>
14concept ReceivedEthernetFrame = requires(T frame) {
15 { frame->length } -> std::convertible_to<uint16_t>;
16 { frame->buffer } -> std::convertible_to<const uint8_t *>;
17 { frame->buffer } -> std::convertible_to<bool>;
18};
19
20/**
21 * Concept for an Ethernet adaptor.
22 */
23template<typename T>
24concept EthernetAdaptor = requires(T adaptor,
25 const uint8_t *buffer,
26 uint16_t length,
27 std::array<uint8_t, 6> macAddress) {
28 /**
29 * The default MAC address for this adaptor. Must return a 6-byte array.
30 */
31 { T::mac_address_default() } -> std::same_as<std::array<uint8_t, 6>>;
32 /**
33 * Is the default MAC address unique? If the device (e.g. soft MAC)
34 * doesn't have its own hardware MAC address then callers may prefer to
35 * generate a locally administered MAC address randomly.
36 */
37 { T::has_unique_mac_address() } -> std::convertible_to<bool>;
38 /**
39 * Set the MAC address of this adaptor.
40 */
41 { adaptor.mac_address_set(macAddress) };
42 /**
43 * Set the MAC address of this adaptor to the default value.
44 */
45 { adaptor.mac_address_set() };
46
47 /**
48 * Check if PHY link is up.
49 */
50 { adaptor.phy_link_status() } -> std::convertible_to<bool>;
51
52 /**
53 * Receive a frame. Returns an optional value (convertible to bool) that
54 * has a length and a buffer. The return value owns the buffer for its
55 * lifetime.
56 */
57 { adaptor.receive_frame() } -> ReceivedEthernetFrame;
58
59 /**
60 * Send a frame identified by a base and length. Returns true if the frame
61 * was sent successfully, false otherwise.
62 *
63 * The third argument is a hook that allows the caller to validate the
64 * packet after it's been buffered but before it's sent. This avoids
65 * time-of-check-to-time-of-use issues in egress filtering.
66 */
67 {
68 adaptor.send_frame(
69 buffer, length, [](const uint8_t *buffer, uint16_t length) {
70 return true;
71 })
72 } -> std::same_as<bool>;
73
74 /**
75 * Read the current interrupt counter for receive interrupts. If this
76 * device doesn't support interrupts then this can return some other value.
77 * This is used only with `receive_interrupt_complete`.
78 */
79 { adaptor.receive_interrupt_value() } -> std::same_as<uint32_t>;
80
81 /**
82 * Called after `receive_frame` fails to return new frames to block until a
83 * new frame is ready to receive.
84 *
85 * TODO: This currently blocks on a single value, this may later be
86 * augmented with an interface that sets up a multiwaiter.
87 */
88 { adaptor.receive_interrupt_complete(nullptr, 0) } -> std::same_as<int>;
89};
Concept for an Ethernet adaptor.
Definition ethernet.hh:24
Helper concept for the type returned by receive_frame.
Definition ethernet.hh:14