forked from M-Labs/zynq-rs
libboard_zynq: wrap eth Buffer for alignment
This commit is contained in:
parent
ed52ead914
commit
46af38906e
@ -1,3 +1,4 @@
|
|||||||
|
use core::ops::{Deref, DerefMut};
|
||||||
use libregister::*;
|
use libregister::*;
|
||||||
use crate::println;
|
use crate::println;
|
||||||
use super::slcr;
|
use super::slcr;
|
||||||
@ -18,6 +19,29 @@ const TX_100: u32 = 25_000_000;
|
|||||||
/// Clock for GbE
|
/// Clock for GbE
|
||||||
const TX_1000: u32 = 125_000_000;
|
const TX_1000: u32 = 125_000_000;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
#[repr(C, align(0x08))]
|
||||||
|
pub struct Buffer(pub [u8; MTU]);
|
||||||
|
|
||||||
|
impl Buffer {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Buffer([0; MTU])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for Buffer {
|
||||||
|
type Target = [u8];
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DerefMut for Buffer {
|
||||||
|
fn deref_mut(&mut self) -> &mut <Self as Deref>::Target {
|
||||||
|
&mut self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Eth<'r, RX, TX> {
|
pub struct Eth<'r, RX, TX> {
|
||||||
rx: RX,
|
rx: RX,
|
||||||
tx: TX,
|
tx: TX,
|
||||||
@ -239,7 +263,7 @@ impl<'r, RX, TX> Eth<'r, RX, TX> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn start_rx<'rx>(self, rx_list: &'rx mut [rx::DescEntry], rx_buffers: &'rx mut [[u8; MTU]]) -> Eth<'r, rx::DescList<'rx>, TX> {
|
pub fn start_rx<'rx>(self, rx_list: &'rx mut [rx::DescEntry], rx_buffers: &'rx mut [Buffer]) -> Eth<'r, rx::DescList<'rx>, TX> {
|
||||||
let new_self = Eth {
|
let new_self = Eth {
|
||||||
rx: rx::DescList::new(rx_list, rx_buffers),
|
rx: rx::DescList::new(rx_list, rx_buffers),
|
||||||
tx: self.tx,
|
tx: self.tx,
|
||||||
@ -258,7 +282,7 @@ impl<'r, RX, TX> Eth<'r, RX, TX> {
|
|||||||
new_self
|
new_self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn start_tx<'tx>(self, tx_list: &'tx mut [tx::DescEntry], tx_buffers: &'tx mut [[u8; MTU]]) -> Eth<'r, RX, tx::DescList<'tx>> {
|
pub fn start_tx<'tx>(self, tx_list: &'tx mut [tx::DescEntry], tx_buffers: &'tx mut [Buffer]) -> Eth<'r, RX, tx::DescList<'tx>> {
|
||||||
let new_self = Eth {
|
let new_self = Eth {
|
||||||
rx: self.rx,
|
rx: self.rx,
|
||||||
tx: tx::DescList::new(tx_list, tx_buffers),
|
tx: tx::DescList::new(tx_list, tx_buffers),
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use core::ops::Deref;
|
use core::ops::Deref;
|
||||||
use libregister::*;
|
use libregister::*;
|
||||||
use super::MTU;
|
use super::Buffer;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
@ -55,16 +55,16 @@ register_bit!(desc_word1, global_broadcast, 31);
|
|||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct DescList<'a> {
|
pub struct DescList<'a> {
|
||||||
list: &'a mut [DescEntry],
|
list: &'a mut [DescEntry],
|
||||||
buffers: &'a mut [[u8; MTU]],
|
buffers: &'a mut [Buffer],
|
||||||
next: usize,
|
next: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> DescList<'a> {
|
impl<'a> DescList<'a> {
|
||||||
pub fn new(list: &'a mut [DescEntry], buffers: &'a mut [[u8; MTU]]) -> Self {
|
pub fn new(list: &'a mut [DescEntry], buffers: &'a mut [Buffer]) -> Self {
|
||||||
let last = list.len().min(buffers.len()) - 1;
|
let last = list.len().min(buffers.len()) - 1;
|
||||||
for (i, (entry, buffer)) in list.iter_mut().zip(buffers.iter_mut()).enumerate() {
|
for (i, (entry, buffer)) in list.iter_mut().zip(buffers.iter_mut()).enumerate() {
|
||||||
let is_last = i == last;
|
let is_last = i == last;
|
||||||
let buffer_addr = &mut buffer[0] as *mut _ as u32;
|
let buffer_addr = &mut buffer.0[0] as *mut _ as u32;
|
||||||
assert!(buffer_addr & 0b11 == 0);
|
assert!(buffer_addr & 0b11 == 0);
|
||||||
entry.word0.write(
|
entry.word0.write(
|
||||||
DescWord0::zeroed()
|
DescWord0::zeroed()
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use core::ops::{Deref, DerefMut};
|
use core::ops::{Deref, DerefMut};
|
||||||
use libregister::*;
|
use libregister::*;
|
||||||
use super::{MTU, regs};
|
use super::{Buffer, regs};
|
||||||
|
|
||||||
/// Descriptor entry
|
/// Descriptor entry
|
||||||
#[repr(C, align(0x08))]
|
#[repr(C, align(0x08))]
|
||||||
@ -42,12 +42,12 @@ pub const DESCS: usize = 8;
|
|||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct DescList<'a> {
|
pub struct DescList<'a> {
|
||||||
list: &'a mut [DescEntry],
|
list: &'a mut [DescEntry],
|
||||||
buffers: &'a mut [[u8; MTU]],
|
buffers: &'a mut [Buffer],
|
||||||
next: usize,
|
next: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> DescList<'a> {
|
impl<'a> DescList<'a> {
|
||||||
pub fn new(list: &'a mut [DescEntry], buffers: &'a mut [[u8; MTU]]) -> Self {
|
pub fn new(list: &'a mut [DescEntry], buffers: &'a mut [Buffer]) -> Self {
|
||||||
let last = list.len().min(buffers.len()) - 1;
|
let last = list.len().min(buffers.len()) - 1;
|
||||||
// Sending seems to not work properly with only one packet
|
// Sending seems to not work properly with only one packet
|
||||||
// buffer (two duplicates get send with every packet), so
|
// buffer (two duplicates get send with every packet), so
|
||||||
@ -57,7 +57,7 @@ impl<'a> DescList<'a> {
|
|||||||
|
|
||||||
for (i, (entry, buffer)) in list.iter_mut().zip(buffers.iter_mut()).enumerate() {
|
for (i, (entry, buffer)) in list.iter_mut().zip(buffers.iter_mut()).enumerate() {
|
||||||
let is_last = i == last;
|
let is_last = i == last;
|
||||||
let buffer_addr = &mut buffer[0] as *mut _ as u32;
|
let buffer_addr = &mut buffer.0[0] as *mut _ as u32;
|
||||||
assert!(buffer_addr & 0b11 == 0);
|
assert!(buffer_addr & 0b11 == 0);
|
||||||
entry.word0.write(
|
entry.word0.write(
|
||||||
DescWord0::zeroed()
|
DescWord0::zeroed()
|
||||||
|
Loading…
Reference in New Issue
Block a user