From a07beb2a4570f65ead5b94ad25d84d981c2b6fae Mon Sep 17 00:00:00 2001 From: Astro Date: Tue, 2 Jul 2019 23:29:16 +0200 Subject: [PATCH] eth: add smoltcp support --- Cargo.toml | 1 + src/eth/mod.rs | 37 +++++++++++++++++++++++++++++++++++++ src/eth/rx.rs | 9 +++++++++ src/eth/tx.rs | 23 +++++++++++++++++++++++ 4 files changed, 70 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 274bb580..fa584d66 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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"] } diff --git a/src/eth/mod.rs b/src/eth/mod.rs index e84c4899..e46b0690 100644 --- a/src/eth/mod.rs +++ b/src/eth/mod.rs @@ -486,3 +486,40 @@ impl phy::PhyAccess for Eth { self.wait_phy_idle(); } } + +impl<'a, 'rx: 'a, 'tx: 'a> smoltcp::phy::Device<'a> for Eth, 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 { + Some(tx::Token { + regs: self.regs, + desc_list: &mut self.tx, + }) + } + +} diff --git a/src/eth/rx.rs b/src/eth/rx.rs index 516ea80e..e2716581 100644 --- a/src/eth/rx.rs +++ b/src/eth/rx.rs @@ -120,3 +120,12 @@ impl<'a> Deref for PktRef<'a> { self.buffer } } + +impl<'a> smoltcp::phy::RxToken for PktRef<'a> { + fn consume(mut self, _timestamp: smoltcp::time::Instant, f: F) -> smoltcp::Result + where + F: FnOnce(&[u8]) -> smoltcp::Result + { + f(self.buffer) + } +} diff --git a/src/eth/tx.rs b/src/eth/tx.rs index 45fedf7c..0bb72019 100644 --- a/src/eth/tx.rs +++ b/src/eth/tx.rs @@ -118,3 +118,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(self, _timestamp: smoltcp::time::Instant, len: usize, f: F) -> smoltcp::Result + where F: FnOnce(&mut [u8]) -> smoltcp::Result + { + 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 + } + } + } +}