From a4be03bee967d4c3a2b17d8ba4d9b2a2fc3e5794 Mon Sep 17 00:00:00 2001 From: Astro Date: Fri, 21 Jun 2019 01:19:04 +0200 Subject: [PATCH] rx: PktRef --- src/eth/mod.rs | 2 +- src/eth/rx.rs | 41 ++++++++++++++++++++++++++++++++--------- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/src/eth/mod.rs b/src/eth/mod.rs index 5dc0fd5..5d108f9 100644 --- a/src/eth/mod.rs +++ b/src/eth/mod.rs @@ -333,7 +333,7 @@ impl Eth { } impl<'rx, TX> Eth, TX> { - pub fn recv_next(&mut self) -> Option<&[u8]> { + pub fn recv_next(&mut self) -> Option { self.rx.recv_next() } } diff --git a/src/eth/rx.rs b/src/eth/rx.rs index cc7f9f0..896c0ec 100644 --- a/src/eth/rx.rs +++ b/src/eth/rx.rs @@ -1,4 +1,4 @@ -use core::mem::uninitialized; +use core::ops::Deref; use crate::{register, register_bit, register_bits, register_bits_typed, regs::*}; /// Descriptor entry @@ -69,19 +69,42 @@ impl<'a> DescList<'a> { &self.list[0] as *const _ as u32 } - pub fn recv_next(&mut self) -> Option<&[u8]> { - if self.list[self.next].word0.read().used() { - let len = self.list[self.next].word1 - .read().frame_length_lsbs() - .into(); - let pkt = &self.buffers[self.next][0..len]; + pub fn recv_next<'s: 'p, 'p>(&'s mut self) -> Option> { + let list_len = self.list.len(); + let entry = &mut self.list[self.next]; + if entry.word0.read().used() { + let len = entry.word1.read() + .frame_length_lsbs().into(); + // TODO: check no split pkt across multiple buffers + let buffer = &self.buffers[self.next][0..len]; + self.next += 1; - if self.next >= self.list.len() { + if self.next >= list_len { self.next = 0; } - Some(pkt) + + Some(PktRef { entry, buffer }) } else { None } } } + +/// Releases a buffer back to the HW upon Drop +pub struct PktRef<'a> { + entry: &'a mut DescEntry, + buffer: &'a [u8], +} + +impl<'a> Drop for PktRef<'a> { + fn drop(&mut self) { + self.entry.word0.modify(|_, w| w.used(false)); + } +} + +impl<'a> Deref for PktRef<'a> { + type Target = [u8]; + fn deref(&self) -> &Self::Target { + self.buffer + } +}