1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
use crate::{rx::RxPacket, tx::TxError, EthernetDMA};
use core::intrinsics::transmute;
use smoltcp::phy::{ChecksumCapabilities, Device, DeviceCapabilities, RxToken, TxToken};
use smoltcp::time::Instant;
use smoltcp::Error;
impl<'a, 'rx, 'tx, 'b> Device<'a> for &'b mut EthernetDMA<'rx, 'tx> {
type RxToken = EthRxToken<'a>;
type TxToken = EthTxToken<'a>;
fn capabilities(&self) -> DeviceCapabilities {
let mut caps = DeviceCapabilities::default();
caps.max_transmission_unit = super::MTU;
caps.max_burst_size = Some(1);
caps.checksum = ChecksumCapabilities::ignored();
caps
}
fn receive(&mut self) -> Option<(Self::RxToken, Self::TxToken)> {
let self_ = unsafe {
transmute::<&mut EthernetDMA<'rx, 'tx>, &mut EthernetDMA<'a, 'a>>(*self)
};
let eth = self_ as *mut EthernetDMA<'a, 'a>;
match self_.recv_next() {
Ok(packet) => {
let rx = EthRxToken { packet };
let tx = EthTxToken { eth };
Some((rx, tx))
}
Err(_) => None,
}
}
fn transmit(&mut self) -> Option<Self::TxToken> {
let eth = unsafe {
transmute::<&mut EthernetDMA<'rx, 'tx>, &mut EthernetDMA<'a, 'a>>(*self)
as *mut EthernetDMA<'a, 'a>
};
Some(EthTxToken { eth })
}
}
pub struct EthRxToken<'a> {
packet: RxPacket<'a>,
}
impl<'a> RxToken for EthRxToken<'a> {
fn consume<R, F>(mut self, _timestamp: Instant, f: F) -> Result<R, Error>
where
F: FnOnce(&mut [u8]) -> Result<R, Error>,
{
let result = f(&mut self.packet);
self.packet.free();
result
}
}
pub struct EthTxToken<'a> {
eth: *mut EthernetDMA<'a, 'a>,
}
impl<'a> TxToken for EthTxToken<'a> {
fn consume<R, F>(self, _timestamp: Instant, len: usize, f: F) -> Result<R, Error>
where
F: FnOnce(&mut [u8]) -> Result<R, Error>,
{
let eth = unsafe { &mut *self.eth };
match eth.send(len, f) {
Err(TxError::WouldBlock) => Err(Error::Exhausted),
Ok(r) => r,
}
}
}