sel4_shared_ring_buffer_smoltcp/
lib.rs
1#![no_std]
8
9extern crate alloc;
10
11use lock_api::{Mutex, RawMutex};
12use one_shot_mutex::unsync::RawOneShotMutex;
13use smoltcp::phy::{self, Device, DeviceCapabilities};
14use smoltcp::time::Instant;
15
16use sel4_abstract_allocator::AbstractAllocator;
17use sel4_abstract_rc::{AbstractRcT, RcT};
18use sel4_shared_memory::SharedMemoryRef;
19use sel4_shared_ring_buffer::{roles::Provide, RingBuffers};
20
21mod inner;
22
23pub use inner::{Error, PeerMisbehaviorError};
24use inner::{Inner, RxBufferIndex, TxBufferIndex};
25
26pub struct DeviceImpl<A: AbstractAllocator, R: RawMutex = RawOneShotMutex, P: AbstractRcT = RcT> {
27 inner: P::Rc<Mutex<R, Inner<A>>>,
28}
29
30impl<A: AbstractAllocator, R: RawMutex, P: AbstractRcT> Clone for DeviceImpl<A, R, P> {
31 fn clone(&self) -> Self {
32 Self {
33 inner: self.inner.clone(),
34 }
35 }
36}
37
38impl<A: AbstractAllocator, R: RawMutex, P: AbstractRcT> DeviceImpl<A, R, P> {
39 #[allow(clippy::too_many_arguments)]
40 pub fn new(
41 raw_mutex: R,
42 dma_region: SharedMemoryRef<'static, [u8]>,
43 bounce_buffer_allocator: A,
44 rx_ring_buffers: RingBuffers<'static, Provide, fn()>,
45 tx_ring_buffers: RingBuffers<'static, Provide, fn()>,
46 num_rx_buffers: usize,
47 rx_buffer_size: usize,
48 caps: DeviceCapabilities,
49 ) -> Result<Self, Error> {
50 Ok(Self {
51 inner: P::Rc::from(Mutex::from_raw(
52 raw_mutex,
53 Inner::new(
54 dma_region,
55 bounce_buffer_allocator,
56 rx_ring_buffers,
57 tx_ring_buffers,
58 num_rx_buffers,
59 rx_buffer_size,
60 caps,
61 )?,
62 )),
63 })
64 }
65
66 fn inner(&self) -> &P::Rc<Mutex<R, Inner<A>>> {
67 &self.inner
68 }
69
70 pub fn poll(&self) -> bool {
71 self.inner().lock().poll().unwrap()
72 }
73
74 pub fn can_receive(&self) -> bool {
75 self.inner().lock().can_receive()
76 }
77
78 pub fn can_transmit(&self) -> bool {
79 self.inner().lock().can_transmit()
80 }
81
82 fn new_rx_token(&self, rx_buffer: RxBufferIndex) -> RxToken<A, R, P> {
83 RxToken {
84 buffer: rx_buffer,
85 shared: self.clone(),
86 }
87 }
88
89 fn new_tx_token(&self, tx_buffer: TxBufferIndex) -> TxToken<A, R, P> {
90 TxToken {
91 buffer: tx_buffer,
92 shared: self.clone(),
93 }
94 }
95}
96
97impl<A: AbstractAllocator, R: RawMutex, P: AbstractRcT> Device for DeviceImpl<A, R, P> {
98 type RxToken<'a>
99 = RxToken<A, R, P>
100 where
101 A: 'a,
102 R: 'a,
103 P: 'a;
104 type TxToken<'a>
105 = TxToken<A, R, P>
106 where
107 A: 'a,
108 R: 'a,
109 P: 'a;
110
111 fn capabilities(&self) -> DeviceCapabilities {
112 self.inner().lock().caps().clone()
113 }
114
115 fn receive(&mut self, _timestamp: Instant) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
116 self.inner()
117 .lock()
118 .receive()
119 .map(|(rx_ix, tx_ix)| (self.new_rx_token(rx_ix), self.new_tx_token(tx_ix)))
120 }
121
122 fn transmit(&mut self, _timestamp: Instant) -> Option<Self::TxToken<'_>> {
123 self.inner()
124 .lock()
125 .transmit()
126 .map(|ix| self.new_tx_token(ix))
127 }
128}
129
130pub struct RxToken<A: AbstractAllocator, R: RawMutex, P: AbstractRcT> {
131 buffer: RxBufferIndex,
132 shared: DeviceImpl<A, R, P>,
133}
134
135impl<A: AbstractAllocator, R: RawMutex, P: AbstractRcT> phy::RxToken for RxToken<A, R, P> {
136 fn consume<T, F>(self, f: F) -> T
137 where
138 F: FnOnce(&mut [u8]) -> T,
139 {
140 let mut ptr = self.shared.inner().lock().consume_rx_start(self.buffer);
141 let r = f(unsafe { ptr.as_mut() });
142 self.shared.inner().lock().consume_rx_finish(self.buffer);
143 r
144 }
145}
146
147impl<A: AbstractAllocator, R: RawMutex, P: AbstractRcT> Drop for RxToken<A, R, P> {
148 fn drop(&mut self) {
149 self.shared.inner().lock().drop_rx(self.buffer).unwrap()
150 }
151}
152
153pub struct TxToken<A: AbstractAllocator, R: RawMutex, P: AbstractRcT> {
154 buffer: TxBufferIndex,
155 shared: DeviceImpl<A, R, P>,
156}
157
158impl<A: AbstractAllocator, R: RawMutex, P: AbstractRcT> phy::TxToken for TxToken<A, R, P> {
159 fn consume<T, F>(self, len: usize, f: F) -> T
160 where
161 F: FnOnce(&mut [u8]) -> T,
162 {
163 self.shared
164 .inner()
165 .lock()
166 .consume_tx(self.buffer, len, f)
167 .unwrap()
168 }
169}
170
171impl<A: AbstractAllocator, R: RawMutex, P: AbstractRcT> Drop for TxToken<A, R, P> {
172 fn drop(&mut self) {
173 self.shared.inner().lock().drop_tx(self.buffer)
174 }
175}