eth: add smoltcp support

This commit is contained in:
Astro 2019-07-02 23:29:16 +02:00
parent 5603766c5d
commit 3a5ed0aac6
4 changed files with 70 additions and 0 deletions

View File

@ -22,3 +22,4 @@ r0 = "0.2"
volatile-register = "0.2"
bit_field = "0.10"
compiler_builtins = { git = "https://github.com/rust-lang-nursery/compiler-builtins", no-default-features = true, features = ["mem", "no-lang-items"]}
smoltcp = { version = "0.5", default-features = false, features = ["proto-ipv4", "socket-tcp"] }

View File

@ -494,3 +494,40 @@ impl<RX, TX> phy::PhyAccess for Eth<RX, TX> {
self.wait_phy_idle();
}
}
impl<'a, 'rx: 'a, 'tx: 'a> smoltcp::phy::Device<'a> for Eth<rx::DescList<'rx>, tx::DescList<'tx>> {
type RxToken = rx::PktRef<'a>;
type TxToken = tx::Token<'a, 'tx>;
fn capabilities(&self) -> smoltcp::phy::DeviceCapabilities {
let mut caps = smoltcp::phy::DeviceCapabilities::default();
caps.max_transmission_unit = MTU;
caps
}
fn receive(&'a mut self) -> Option<(Self::RxToken, Self::TxToken)> {
match self.rx.recv_next() {
Ok(Some(mut pktref)) => {
let tx_token = tx::Token {
regs: self.regs,
desc_list: &mut self.tx,
};
Some((pktref, tx_token))
}
Ok(None) =>
None,
Err(e) => {
println!("eth recv error: {:?}", e);
None
}
}
}
fn transmit(&'a mut self) -> Option<Self::TxToken> {
Some(tx::Token {
regs: self.regs,
desc_list: &mut self.tx,
})
}
}

View File

@ -122,3 +122,12 @@ impl<'a> Deref for PktRef<'a> {
self.buffer
}
}
impl<'a> smoltcp::phy::RxToken for PktRef<'a> {
fn consume<R, F>(mut self, _timestamp: smoltcp::time::Instant, f: F) -> smoltcp::Result<R>
where
F: FnOnce(&[u8]) -> smoltcp::Result<R>
{
f(self.buffer)
}
}

View File

@ -120,3 +120,26 @@ impl<'a> DerefMut for PktRef<'a> {
self.buffer
}
}
/// TxToken for smoltcp support
pub struct Token<'a, 'tx> {
pub regs: &'a mut regs::RegisterBlock,
pub desc_list: &'a mut DescList<'tx>,
}
impl<'a, 'tx: 'a> smoltcp::phy::TxToken for Token<'a, 'tx> {
fn consume<R, F>(self, _timestamp: smoltcp::time::Instant, len: usize, f: F) -> smoltcp::Result<R>
where F: FnOnce(&mut [u8]) -> smoltcp::Result<R>
{
match self.desc_list.send(self.regs, len) {
None =>
Err(smoltcp::Error::Exhausted),
Some(mut pktref) => {
let result = f(pktref.deref_mut());
// TODO: on result.is_err() don;t send
drop(pktref);
result
}
}
}
}