From e5881a14add959f887f2b11af8879c640c7d3187 Mon Sep 17 00:00:00 2001 From: Astro Date: Fri, 21 Jun 2019 00:58:18 +0200 Subject: [PATCH] eth rx: descriptors/buffers as refs avoid moving these after their addresses have been written to the qbar --- src/eth/mod.rs | 28 +++++++--------------------- src/eth/regs.rs | 4 +++- src/eth/rx.rs | 33 ++++++++++++++++++--------------- src/main.rs | 11 +++-------- 4 files changed, 31 insertions(+), 45 deletions(-) diff --git a/src/eth/mod.rs b/src/eth/mod.rs index 4af77b9..5dc0fd5 100644 --- a/src/eth/mod.rs +++ b/src/eth/mod.rs @@ -290,8 +290,8 @@ impl Eth { self.regs.dma_cfg.write( regs::DmaCfg::zeroed() - // 1600 bytes - .ahb_mem_rx_buf_size(0x19) + // 1536 bytes + .ahb_mem_rx_buf_size(0x18) // 8 KB .rx_pktbuf_memsz_sel(0x3) // 4 KB @@ -306,37 +306,23 @@ impl Eth { self.regs.net_ctrl.write( regs::NetCtrl::zeroed() .mgmt_port_en(true) - .tx_en(true) - .rx_en(true) ); } - pub fn start_rx<'rx>(self, rx_buffers: [&'rx mut [u8]; rx::DESCS]) -> Eth, TX> { + pub fn start_rx<'rx>(self, list: &'rx mut [rx::DescEntry], rx_buffers: &'rx mut [[u8; 1536]]) -> Eth, TX> { let new_self = Eth { regs: self.regs, - rx: rx::DescList::new(rx_buffers), + rx: rx::DescList::new(list, rx_buffers), tx: self.tx, }; - let list_addr = &new_self.rx as *const _ as u32; + let list_addr = new_self.rx.list_addr(); assert!(list_addr & 0b11 == 0); new_self.regs.rx_qbar.write( regs::RxQbar::zeroed() .rx_q_baseaddr(list_addr >> 2) ); - new_self - } - - pub fn start_tx<'tx>(self, tx_buffers: [&'tx [u8]; tx::DESCS]) -> Eth> { - let new_self = Eth { - regs: self.regs, - rx: self.rx, - tx: tx::DescList::new(tx_buffers), - }; - let list_addr = &new_self.tx as *const _ as u32; - assert!(list_addr & 0b11 == 0); - new_self.regs.tx_qbar.write( - regs::TxQbar::zeroed() - .tx_q_baseaddr(list_addr >> 2) + new_self.regs.net_ctrl.modify(|_, w| + w.rx_en(true) ); new_self } diff --git a/src/eth/regs.rs b/src/eth/regs.rs index a136770..b7b16b7 100644 --- a/src/eth/regs.rs +++ b/src/eth/regs.rs @@ -240,7 +240,9 @@ register_bit!(dma_cfg, ahb_endian_swp_pkt_en, 7); register_bits!(dma_cfg, rx_pktbuf_memsz_sel, u8, 8, 9); register_bit!(dma_cfg, tx_pktbuf_memsz_sel, 10); register_bit!(dma_cfg, csum_gen_offload_en, 11); -register_bits!(dma_cfg, ahb_mem_rx_buf_size, u8, 16, 23); +register_bits!(dma_cfg, + /// 64 bytes unit + ahb_mem_rx_buf_size, u8, 16, 23); register_bit!(dma_cfg, disc_when_no_ahb, 24); register!(tx_status, TxStatus, RW, u32); diff --git a/src/eth/rx.rs b/src/eth/rx.rs index c850a40..cc7f9f0 100644 --- a/src/eth/rx.rs +++ b/src/eth/rx.rs @@ -3,7 +3,7 @@ use crate::{register, register_bit, register_bits, register_bits_typed, regs::*} /// Descriptor entry #[repr(C)] -struct DescEntry { +pub struct DescEntry { word0: DescWord0, word1: DescWord1, } @@ -32,40 +32,43 @@ register_bit!(desc_word1, uni_hash_match, 29); register_bit!(desc_word1, multi_hash_match, 30); register_bit!(desc_word1, global_broadcast, 31); -/// Number of descriptors -pub const DESCS: usize = 8; - #[repr(C)] pub struct DescList<'a> { - list: [DescEntry; DESCS], - buffers: [&'a mut [u8]; DESCS], + list: &'a mut [DescEntry], + buffers: &'a mut [[u8; 1536]], next: usize, } impl<'a> DescList<'a> { - pub fn new(buffers: [&'a mut [u8]; DESCS]) -> Self { - let mut list: [DescEntry; DESCS] = unsafe { uninitialized() }; - for i in 0..DESCS { - assert!(buffers[i].len() >= 1536); - let buffer_addr = &mut buffers[i][0] as *mut _ as u32; + pub fn new(list: &'a mut [DescEntry], buffers: &'a mut [[u8; 1536]]) -> Self { + let last = list.len().min(buffers.len()) - 1; + for (i, (entry, buffer)) in list.iter_mut().zip(buffers.iter_mut()).enumerate() { + let is_last = i == last; + assert!(buffer.len() >= 1536); + let buffer_addr = &mut buffer[0] as *mut _ as u32; assert!(buffer_addr & 0b11 == 0); - list[i].word0.write( + entry.word0.write( DescWord0::zeroed() .used(false) - .wrap(i == DESCS - 1) + .wrap(is_last) .address(buffer_addr >> 2) ); - list[i].word1.write( + entry.word1.write( DescWord1::zeroed() ); } DescList { - list, buffers, + list, + buffers, next: 0, } } + pub fn list_addr(&self) -> u32 { + &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 diff --git a/src/main.rs b/src/main.rs index 87e8fdf..c585a7a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -92,14 +92,9 @@ fn main() { } } - let mut rx_buffers = [[0u8; 1536]; eth::rx::DESCS]; - let mut rx_buffer_ptrs: [&mut [u8]; eth::rx::DESCS] = unsafe { - uninitialized() - }; - for (i, (ptr, buf)) in rx_buffer_ptrs.iter_mut().zip(rx_buffers.iter_mut()).enumerate() { - *ptr = buf; - } - let mut eth = eth.start_rx(rx_buffer_ptrs); + let mut rx_descs: [eth::rx::DescEntry; 8] = unsafe { uninitialized() }; + let mut rx_buffers = [[0u8; 1536]; 8]; + let mut eth = eth.start_rx(&mut rx_descs, &mut rx_buffers); loop { match eth.recv_next() {