Skip to content

Commit 5b98fd2

Browse files
22: Make the creation of TxRingEntry and RxRingEntry const r=adamgreig a=thalesfragoso This allow for people to create `RingEntry` on a const context, which saves a considerable amount of stack during initialization if having them in a `static`. I also left the non const `Default` implementations for compatibility and also because of rust-lang/rust#49147, which causes the creation of entries a bit cumbersome since `Aligned` isn't `Copy`, so users can use `default` on non const contexts if they want to. CC @adamgreig Co-authored-by: Thales Fragoso <[email protected]>
2 parents ea65a55 + ab7b9b7 commit 5b98fd2

File tree

5 files changed

+57
-22
lines changed

5 files changed

+57
-22
lines changed

src/desc.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,17 @@ impl Clone for Descriptor {
1818

1919
impl Default for Descriptor {
2020
fn default() -> Self {
21-
Descriptor {
22-
desc: Aligned([0; 4]),
23-
}
21+
Self::new()
2422
}
2523
}
2624

2725
impl Descriptor {
26+
pub const fn new() -> Self {
27+
Self {
28+
desc: Aligned([0; 4]),
29+
}
30+
}
31+
2832
fn r(&self, n: usize) -> &RO<u32> {
2933
let ro = &self.desc.deref()[n] as *const _ as *const RO<u32>;
3034
unsafe { &*ro }

src/lib.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@ mod smi;
2424
pub use ring::RingEntry;
2525
mod desc;
2626
mod rx;
27-
pub use rx::{RxDescriptor, RxError};
28-
use rx::{RxPacket, RxRing, RxRingEntry};
27+
pub use rx::{RxDescriptor, RxError, RxRingEntry};
28+
use rx::{RxPacket, RxRing};
2929
mod tx;
30-
pub use tx::{TxDescriptor, TxError};
31-
use tx::{TxRing, TxRingEntry};
30+
use tx::TxRing;
31+
pub use tx::{TxDescriptor, TxError, TxRingEntry};
3232
pub mod setup;
3333
pub use setup::EthPins;
3434
use setup::{

src/ring.rs

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use aligned::{Aligned, A8};
22
use core::ops::{Deref, DerefMut};
33

4-
use crate::MTU;
4+
use crate::{RxDescriptor, TxDescriptor, MTU};
55

66
pub trait RingDescriptor {
77
fn setup(&mut self, buffer: *const u8, len: usize, next: Option<&Self>);
@@ -23,18 +23,34 @@ impl<T: Clone + RingDescriptor> Clone for RingEntry<T> {
2323

2424
impl<T: Clone + RingDescriptor + Default> Default for RingEntry<T> {
2525
fn default() -> Self {
26-
Self::new()
26+
RingEntry {
27+
desc: Aligned([T::default()]),
28+
buffer: Aligned([0; MTU]),
29+
}
2730
}
2831
}
2932

30-
impl<T: Clone + RingDescriptor + Default> RingEntry<T> {
31-
pub fn new() -> Self {
33+
impl RingEntry<TxDescriptor> {
34+
/// Creates a RingEntry with a TxDescriptor.
35+
pub const fn new() -> Self {
3236
RingEntry {
33-
desc: Aligned([T::default()]),
37+
desc: Aligned([TxDescriptor::new()]),
38+
buffer: Aligned([0; MTU]),
39+
}
40+
}
41+
}
42+
43+
impl RingEntry<RxDescriptor> {
44+
/// Creates a RingEntry with a RxDescriptor.
45+
pub const fn new() -> Self {
46+
RingEntry {
47+
desc: Aligned([RxDescriptor::new()]),
3448
buffer: Aligned([0; MTU]),
3549
}
3650
}
51+
}
3752

53+
impl<T: Clone + RingDescriptor> RingEntry<T> {
3854
pub(crate) fn setup(&mut self, next: Option<&Self>) {
3955
let buffer = self.buffer.as_ptr();
4056
let len = self.buffer.len();

src/rx.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,18 @@ pub struct RxDescriptor {
5050

5151
impl Default for RxDescriptor {
5252
fn default() -> Self {
53-
let mut desc = Descriptor::default();
54-
unsafe {
55-
desc.write(1, RXDESC_1_RCH);
56-
}
57-
RxDescriptor { desc }
53+
Self::new()
5854
}
5955
}
6056

6157
impl RxDescriptor {
58+
/// Creates an zeroed RxDescriptor.
59+
pub const fn new() -> Self {
60+
Self {
61+
desc: Descriptor::new(),
62+
}
63+
}
64+
6265
/// Is owned by the DMA engine?
6366
fn is_owned(&self) -> bool {
6467
(self.desc.read(0) & RXDESC_0_OWN) == RXDESC_0_OWN
@@ -126,6 +129,10 @@ pub type RxRingEntry = RingEntry<RxDescriptor>;
126129

127130
impl RingDescriptor for RxDescriptor {
128131
fn setup(&mut self, buffer: *const u8, len: usize, next: Option<&Self>) {
132+
// Defer this initialization to this function, so we can have `RingEntry` on bss.
133+
unsafe {
134+
self.desc.write(1, RXDESC_1_RCH);
135+
}
129136
self.set_buffer1(buffer, len);
130137
match next {
131138
Some(next) => self.set_buffer2(&next.desc as *const Descriptor as *const u8),

src/tx.rs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,18 @@ pub struct TxDescriptor {
4747

4848
impl Default for TxDescriptor {
4949
fn default() -> Self {
50-
let mut desc = Descriptor::default();
51-
unsafe {
52-
desc.write(0, TXDESC_0_TCH | TXDESC_0_IC | TXDESC_0_FS | TXDESC_0_LS);
53-
}
54-
TxDescriptor { desc }
50+
Self::new()
5551
}
5652
}
5753

5854
impl TxDescriptor {
55+
/// Creates an zeroed TxDescriptor.
56+
pub const fn new() -> Self {
57+
Self {
58+
desc: Descriptor::new(),
59+
}
60+
}
61+
5962
/// Is owned by the DMA engine?
6063
fn is_owned(&self) -> bool {
6164
(self.desc.read(0) & TXDESC_0_OWN) == TXDESC_0_OWN
@@ -115,6 +118,11 @@ pub type TxRingEntry = RingEntry<TxDescriptor>;
115118

116119
impl RingDescriptor for TxDescriptor {
117120
fn setup(&mut self, buffer: *const u8, _len: usize, next: Option<&Self>) {
121+
// Defer this initialization to this function, so we can have `RingEntry` on bss.
122+
unsafe {
123+
self.desc
124+
.write(0, TXDESC_0_TCH | TXDESC_0_IC | TXDESC_0_FS | TXDESC_0_LS);
125+
}
118126
self.set_buffer1(buffer);
119127
match next {
120128
Some(next) => self.set_buffer2(&next.desc as *const Descriptor as *const u8),

0 commit comments

Comments
 (0)