diff --git a/experiments/src/main.rs b/experiments/src/main.rs index fc754335..d0da50da 100644 --- a/experiments/src/main.rs +++ b/experiments/src/main.rs @@ -160,6 +160,7 @@ pub fn main_core0() { flash = flash_io.stop(); } + if false { let core1 = boot::Core1::start(false); let (mut core1_req, rx) = sync_channel!(usize, 10); @@ -174,20 +175,21 @@ pub fn main_core0() { } }); core1.disable(); + } let eth = zynq::eth::Eth::default(HWADDR.clone()); println!("Eth on"); - const RX_LEN: usize = 4096; + const RX_LEN: usize = 8192; // Number of transmission buffers (minimum is two because with // one, duplicate packet transmission occurs) - const TX_LEN: usize = 4096; + const TX_LEN: usize = 8192; let eth = eth.start_rx(RX_LEN); let mut eth = eth.start_tx(TX_LEN); let ethernet_addr = EthernetAddress(HWADDR); // IP stack - let local_addr = IpAddress::v4(192, 168, 1, 51); + let local_addr = IpAddress::v4(192, 168, 1, 54); let mut ip_addrs = [IpCidr::new(local_addr, 24)]; let routes = Routes::new(BTreeMap::new()); let neighbor_cache = NeighborCache::new(BTreeMap::new()); @@ -228,7 +230,7 @@ pub fn main_core0() { }); let stats_rx = stats.clone(); task::spawn(async move { - while let Ok(stream) = TcpStream::accept(TCP_PORT+1, 0x10_0000, 0x10_0000).await { + while let Ok(stream) = TcpStream::accept(TCP_PORT+1, 4096, 4096).await { let stats_rx = stats_rx.clone(); task::spawn(async move { loop { @@ -262,7 +264,16 @@ pub fn main_core0() { } }); - Sockets::run(&mut iface, || { + let mut last_stats_time = 0; + Sockets::run(&mut iface, |iface| { + let t = timer.get_time().0; + if t - last_stats_time >= 1000 { + let stats = &mut iface.device_mut().stats; + info!("eth stats: {:?}", stats); + stats.reset(); + last_stats_time = t; + } + Instant::from_millis(timer.get_time().0 as i64) }) } diff --git a/libasync/src/smoltcp/mod.rs b/libasync/src/smoltcp/mod.rs index fd5191e4..8aa3d9c2 100644 --- a/libasync/src/smoltcp/mod.rs +++ b/libasync/src/smoltcp/mod.rs @@ -43,11 +43,11 @@ impl Sockets { /// iface pub fn run<'b, 'c, 'e, D: for<'d> Device<'d>>( iface: &mut EthernetInterface<'b, 'c, 'e, D>, - mut get_time: impl FnMut() -> Instant, + mut get_time: impl FnMut(&mut EthernetInterface<'b, 'c, 'e, D>) -> Instant, ) -> ! { task::block_on(async { loop { - let instant = get_time(); + let instant = get_time(iface); Self::instance().poll(iface, instant); task::r#yield().await; } diff --git a/libboard_zynq/src/eth/mod.rs b/libboard_zynq/src/eth/mod.rs index 5bd49c3f..bc23c325 100644 --- a/libboard_zynq/src/eth/mod.rs +++ b/libboard_zynq/src/eth/mod.rs @@ -140,11 +140,43 @@ fn calculate_tx_divisors(tx_clock: u32) -> (u8, u8) { result } +#[derive(Debug)] +pub struct EthStats { + frame_recd: usize, + no_frame_recd: usize, + rx_idle: usize, + tx_send: usize, + tx_overflow: usize, +} + +impl EthStats { + pub fn new() -> Self { + EthStats { + frame_recd: 0, + no_frame_recd: 0, + rx_idle: 0, + tx_send: 0, + tx_overflow: 0, + } + } + + pub fn reset(&mut self) { + *self = EthStats { + frame_recd: 0, + no_frame_recd: 0, + rx_idle: 0, + tx_send: 0, + tx_overflow: 0, + }; + } +} + pub struct Eth { rx: RX, tx: TX, inner: EthInner, phy: Phy, + pub stats: EthStats, } impl Eth { @@ -303,6 +335,7 @@ impl Eth { inner.configure(macaddr); let phy = Phy::find(&mut inner).expect("phy"); + info!("Eth: found PHY {}", phy.name()); phy.reset(&mut inner); phy.restart_autoneg(&mut inner); @@ -311,6 +344,7 @@ impl Eth { tx: (), inner, phy, + stats: EthStats::new(), } } } @@ -322,6 +356,7 @@ impl Eth { tx: self.tx, inner: self.inner, phy: self.phy, + stats: self.stats, }; let list_addr = new_self.rx.list_addr(); assert!(list_addr & 0b11 == 0); @@ -341,6 +376,7 @@ impl Eth { tx: tx::DescList::new(tx_size), inner: self.inner, phy: self.phy, + stats: self.stats, }; let list_addr = &new_self.tx.list_addr(); assert!(list_addr & 0b11 == 0); @@ -387,16 +423,19 @@ impl Eth { let result = self.rx.recv_next(); match result { Ok(None) => { + self.stats.no_frame_recd += 1; // No packet, clear status bit GEM::regs().rx_status.write( regs::RxStatus::zeroed() .frame_recd(true) ); } + Ok(Some(_)) => self.stats.frame_recd += 1, _ => {} } result } else { + self.stats.rx_idle += 1; self.inner.check_link_change(&self.phy); Ok(None) } @@ -405,7 +444,13 @@ impl Eth { impl Eth { pub fn send<'s: 'p, 'p>(&'s mut self, length: usize) -> Option> { - self.tx.send(GEM::regs(), length) + let result = self.tx.send(GEM::regs(), length); + if result.is_some() { + self.stats.tx_send += 1; + } else { + self.stats.tx_overflow += 1; + } + result } } @@ -432,6 +477,7 @@ impl<'a, GEM: Gem> smoltcp::phy::Device<'a> for &mut Eth Option<(Self::RxToken, Self::TxToken)> { match self.rx.recv_next() { Ok(Some(pktref)) => { + self.stats.frame_recd += 1; let tx_token = tx::Token { regs: GEM::regs(), desc_list: &mut self.tx, @@ -439,6 +485,7 @@ impl<'a, GEM: Gem> smoltcp::phy::Device<'a> for &mut Eth { + self.stats.rx_idle += 1; self.inner.check_link_change(&self.phy); None }