From ab7b9b735583d6e7145167978d480e1083ab0685 Mon Sep 17 00:00:00 2001 From: Thales Fragoso Date: Thu, 20 Aug 2020 21:48:41 -0300 Subject: [PATCH] Make the creation of TxRingEntry and RxRingEntry const --- src/desc.rs | 10 +++++++--- src/lib.rs | 8 ++++---- src/ring.rs | 26 +++++++++++++++++++++----- src/rx.rs | 17 ++++++++++++----- src/tx.rs | 18 +++++++++++++----- 5 files changed, 57 insertions(+), 22 deletions(-) diff --git a/src/desc.rs b/src/desc.rs index fef0c2ae..56c3ca97 100644 --- a/src/desc.rs +++ b/src/desc.rs @@ -18,13 +18,17 @@ impl Clone for Descriptor { impl Default for Descriptor { fn default() -> Self { - Descriptor { - desc: Aligned([0; 4]), - } + Self::new() } } impl Descriptor { + pub const fn new() -> Self { + Self { + desc: Aligned([0; 4]), + } + } + fn r(&self, n: usize) -> &RO { let ro = &self.desc.deref()[n] as *const _ as *const RO; unsafe { &*ro } diff --git a/src/lib.rs b/src/lib.rs index 21858769..f16fd287 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -24,11 +24,11 @@ mod smi; pub use ring::RingEntry; mod desc; mod rx; -pub use rx::{RxDescriptor, RxError}; -use rx::{RxPacket, RxRing, RxRingEntry}; +pub use rx::{RxDescriptor, RxError, RxRingEntry}; +use rx::{RxPacket, RxRing}; mod tx; -pub use tx::{TxDescriptor, TxError}; -use tx::{TxRing, TxRingEntry}; +use tx::TxRing; +pub use tx::{TxDescriptor, TxError, TxRingEntry}; pub mod setup; pub use setup::EthPins; use setup::{ diff --git a/src/ring.rs b/src/ring.rs index 9062e439..5850da4e 100644 --- a/src/ring.rs +++ b/src/ring.rs @@ -1,7 +1,7 @@ use aligned::{Aligned, A8}; use core::ops::{Deref, DerefMut}; -use crate::MTU; +use crate::{RxDescriptor, TxDescriptor, MTU}; pub trait RingDescriptor { fn setup(&mut self, buffer: *const u8, len: usize, next: Option<&Self>); @@ -23,18 +23,34 @@ impl Clone for RingEntry { impl Default for RingEntry { fn default() -> Self { - Self::new() + RingEntry { + desc: Aligned([T::default()]), + buffer: Aligned([0; MTU]), + } } } -impl RingEntry { - pub fn new() -> Self { +impl RingEntry { + /// Creates a RingEntry with a TxDescriptor. + pub const fn new() -> Self { RingEntry { - desc: Aligned([T::default()]), + desc: Aligned([TxDescriptor::new()]), + buffer: Aligned([0; MTU]), + } + } +} + +impl RingEntry { + /// Creates a RingEntry with a RxDescriptor. + pub const fn new() -> Self { + RingEntry { + desc: Aligned([RxDescriptor::new()]), buffer: Aligned([0; MTU]), } } +} +impl RingEntry { pub(crate) fn setup(&mut self, next: Option<&Self>) { let buffer = self.buffer.as_ptr(); let len = self.buffer.len(); diff --git a/src/rx.rs b/src/rx.rs index 4264f809..a98cabc0 100644 --- a/src/rx.rs +++ b/src/rx.rs @@ -50,15 +50,18 @@ pub struct RxDescriptor { impl Default for RxDescriptor { fn default() -> Self { - let mut desc = Descriptor::default(); - unsafe { - desc.write(1, RXDESC_1_RCH); - } - RxDescriptor { desc } + Self::new() } } impl RxDescriptor { + /// Creates an zeroed RxDescriptor. + pub const fn new() -> Self { + Self { + desc: Descriptor::new(), + } + } + /// Is owned by the DMA engine? fn is_owned(&self) -> bool { (self.desc.read(0) & RXDESC_0_OWN) == RXDESC_0_OWN @@ -126,6 +129,10 @@ pub type RxRingEntry = RingEntry; impl RingDescriptor for RxDescriptor { fn setup(&mut self, buffer: *const u8, len: usize, next: Option<&Self>) { + // Defer this initialization to this function, so we can have `RingEntry` on bss. + unsafe { + self.desc.write(1, RXDESC_1_RCH); + } self.set_buffer1(buffer, len); match next { Some(next) => self.set_buffer2(&next.desc as *const Descriptor as *const u8), diff --git a/src/tx.rs b/src/tx.rs index ad79ec46..a72aa7a2 100644 --- a/src/tx.rs +++ b/src/tx.rs @@ -47,15 +47,18 @@ pub struct TxDescriptor { impl Default for TxDescriptor { fn default() -> Self { - let mut desc = Descriptor::default(); - unsafe { - desc.write(0, TXDESC_0_TCH | TXDESC_0_IC | TXDESC_0_FS | TXDESC_0_LS); - } - TxDescriptor { desc } + Self::new() } } impl TxDescriptor { + /// Creates an zeroed TxDescriptor. + pub const fn new() -> Self { + Self { + desc: Descriptor::new(), + } + } + /// Is owned by the DMA engine? fn is_owned(&self) -> bool { (self.desc.read(0) & TXDESC_0_OWN) == TXDESC_0_OWN @@ -115,6 +118,11 @@ pub type TxRingEntry = RingEntry; impl RingDescriptor for TxDescriptor { fn setup(&mut self, buffer: *const u8, _len: usize, next: Option<&Self>) { + // Defer this initialization to this function, so we can have `RingEntry` on bss. + unsafe { + self.desc + .write(0, TXDESC_0_TCH | TXDESC_0_IC | TXDESC_0_FS | TXDESC_0_LS); + } self.set_buffer1(buffer); match next { Some(next) => self.set_buffer2(&next.desc as *const Descriptor as *const u8),