rx: PktRef

This commit is contained in:
Astro 2019-06-21 01:19:04 +02:00
parent 80f003b2c6
commit a4be03bee9
2 changed files with 33 additions and 10 deletions

View File

@ -333,7 +333,7 @@ impl<RX, TX> Eth<RX, TX> {
} }
impl<'rx, TX> Eth<rx::DescList<'rx>, TX> { impl<'rx, TX> Eth<rx::DescList<'rx>, TX> {
pub fn recv_next(&mut self) -> Option<&[u8]> { pub fn recv_next(&mut self) -> Option<rx::PktRef> {
self.rx.recv_next() self.rx.recv_next()
} }
} }

View File

@ -1,4 +1,4 @@
use core::mem::uninitialized; use core::ops::Deref;
use crate::{register, register_bit, register_bits, register_bits_typed, regs::*}; use crate::{register, register_bit, register_bits, register_bits_typed, regs::*};
/// Descriptor entry /// Descriptor entry
@ -69,19 +69,42 @@ impl<'a> DescList<'a> {
&self.list[0] as *const _ as u32 &self.list[0] as *const _ as u32
} }
pub fn recv_next(&mut self) -> Option<&[u8]> { pub fn recv_next<'s: 'p, 'p>(&'s mut self) -> Option<PktRef<'p>> {
if self.list[self.next].word0.read().used() { let list_len = self.list.len();
let len = self.list[self.next].word1 let entry = &mut self.list[self.next];
.read().frame_length_lsbs() if entry.word0.read().used() {
.into(); let len = entry.word1.read()
let pkt = &self.buffers[self.next][0..len]; .frame_length_lsbs().into();
// TODO: check no split pkt across multiple buffers
let buffer = &self.buffers[self.next][0..len];
self.next += 1; self.next += 1;
if self.next >= self.list.len() { if self.next >= list_len {
self.next = 0; self.next = 0;
} }
Some(pkt)
Some(PktRef { entry, buffer })
} else { } else {
None 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
}
}