forked from M-Labs/zynq-rs
Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
4158906122 |
@ -160,6 +160,7 @@ pub fn main_core0() {
|
|||||||
flash = flash_io.stop();
|
flash = flash_io.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if false {
|
||||||
let core1 = boot::Core1::start(false);
|
let core1 = boot::Core1::start(false);
|
||||||
|
|
||||||
let (mut core1_req, rx) = sync_channel!(usize, 10);
|
let (mut core1_req, rx) = sync_channel!(usize, 10);
|
||||||
@ -174,20 +175,21 @@ pub fn main_core0() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
core1.disable();
|
core1.disable();
|
||||||
|
}
|
||||||
|
|
||||||
let eth = zynq::eth::Eth::default(HWADDR.clone());
|
let eth = zynq::eth::Eth::default(HWADDR.clone());
|
||||||
println!("Eth on");
|
println!("Eth on");
|
||||||
|
|
||||||
const RX_LEN: usize = 4096;
|
const RX_LEN: usize = 8192;
|
||||||
// Number of transmission buffers (minimum is two because with
|
// Number of transmission buffers (minimum is two because with
|
||||||
// one, duplicate packet transmission occurs)
|
// one, duplicate packet transmission occurs)
|
||||||
const TX_LEN: usize = 4096;
|
const TX_LEN: usize = 8192;
|
||||||
let eth = eth.start_rx(RX_LEN);
|
let eth = eth.start_rx(RX_LEN);
|
||||||
let mut eth = eth.start_tx(TX_LEN);
|
let mut eth = eth.start_tx(TX_LEN);
|
||||||
|
|
||||||
let ethernet_addr = EthernetAddress(HWADDR);
|
let ethernet_addr = EthernetAddress(HWADDR);
|
||||||
// IP stack
|
// 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 mut ip_addrs = [IpCidr::new(local_addr, 24)];
|
||||||
let routes = Routes::new(BTreeMap::new());
|
let routes = Routes::new(BTreeMap::new());
|
||||||
let neighbor_cache = NeighborCache::new(BTreeMap::new());
|
let neighbor_cache = NeighborCache::new(BTreeMap::new());
|
||||||
@ -228,7 +230,7 @@ pub fn main_core0() {
|
|||||||
});
|
});
|
||||||
let stats_rx = stats.clone();
|
let stats_rx = stats.clone();
|
||||||
task::spawn(async move {
|
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();
|
let stats_rx = stats_rx.clone();
|
||||||
task::spawn(async move {
|
task::spawn(async move {
|
||||||
loop {
|
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)
|
Instant::from_millis(timer.get_time().0 as i64)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -43,11 +43,11 @@ impl Sockets {
|
|||||||
/// iface
|
/// iface
|
||||||
pub fn run<'b, 'c, 'e, D: for<'d> Device<'d>>(
|
pub fn run<'b, 'c, 'e, D: for<'d> Device<'d>>(
|
||||||
iface: &mut EthernetInterface<'b, 'c, 'e, 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 {
|
task::block_on(async {
|
||||||
loop {
|
loop {
|
||||||
let instant = get_time();
|
let instant = get_time(iface);
|
||||||
Self::instance().poll(iface, instant);
|
Self::instance().poll(iface, instant);
|
||||||
task::r#yield().await;
|
task::r#yield().await;
|
||||||
}
|
}
|
||||||
|
@ -140,11 +140,43 @@ fn calculate_tx_divisors(tx_clock: u32) -> (u8, u8) {
|
|||||||
result
|
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<GEM: Gem, RX, TX> {
|
pub struct Eth<GEM: Gem, RX, TX> {
|
||||||
rx: RX,
|
rx: RX,
|
||||||
tx: TX,
|
tx: TX,
|
||||||
inner: EthInner<GEM>,
|
inner: EthInner<GEM>,
|
||||||
phy: Phy,
|
phy: Phy,
|
||||||
|
pub stats: EthStats,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Eth<Gem0, (), ()> {
|
impl Eth<Gem0, (), ()> {
|
||||||
@ -303,6 +335,7 @@ impl<GEM: Gem> Eth<GEM, (), ()> {
|
|||||||
inner.configure(macaddr);
|
inner.configure(macaddr);
|
||||||
|
|
||||||
let phy = Phy::find(&mut inner).expect("phy");
|
let phy = Phy::find(&mut inner).expect("phy");
|
||||||
|
info!("Eth: found PHY {}", phy.name());
|
||||||
phy.reset(&mut inner);
|
phy.reset(&mut inner);
|
||||||
phy.restart_autoneg(&mut inner);
|
phy.restart_autoneg(&mut inner);
|
||||||
|
|
||||||
@ -311,6 +344,7 @@ impl<GEM: Gem> Eth<GEM, (), ()> {
|
|||||||
tx: (),
|
tx: (),
|
||||||
inner,
|
inner,
|
||||||
phy,
|
phy,
|
||||||
|
stats: EthStats::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -322,6 +356,7 @@ impl<GEM: Gem, RX, TX> Eth<GEM, RX, TX> {
|
|||||||
tx: self.tx,
|
tx: self.tx,
|
||||||
inner: self.inner,
|
inner: self.inner,
|
||||||
phy: self.phy,
|
phy: self.phy,
|
||||||
|
stats: self.stats,
|
||||||
};
|
};
|
||||||
let list_addr = new_self.rx.list_addr();
|
let list_addr = new_self.rx.list_addr();
|
||||||
assert!(list_addr & 0b11 == 0);
|
assert!(list_addr & 0b11 == 0);
|
||||||
@ -341,6 +376,7 @@ impl<GEM: Gem, RX, TX> Eth<GEM, RX, TX> {
|
|||||||
tx: tx::DescList::new(tx_size),
|
tx: tx::DescList::new(tx_size),
|
||||||
inner: self.inner,
|
inner: self.inner,
|
||||||
phy: self.phy,
|
phy: self.phy,
|
||||||
|
stats: self.stats,
|
||||||
};
|
};
|
||||||
let list_addr = &new_self.tx.list_addr();
|
let list_addr = &new_self.tx.list_addr();
|
||||||
assert!(list_addr & 0b11 == 0);
|
assert!(list_addr & 0b11 == 0);
|
||||||
@ -387,16 +423,19 @@ impl<GEM: Gem, TX> Eth<GEM, rx::DescList, TX> {
|
|||||||
let result = self.rx.recv_next();
|
let result = self.rx.recv_next();
|
||||||
match result {
|
match result {
|
||||||
Ok(None) => {
|
Ok(None) => {
|
||||||
|
self.stats.no_frame_recd += 1;
|
||||||
// No packet, clear status bit
|
// No packet, clear status bit
|
||||||
GEM::regs().rx_status.write(
|
GEM::regs().rx_status.write(
|
||||||
regs::RxStatus::zeroed()
|
regs::RxStatus::zeroed()
|
||||||
.frame_recd(true)
|
.frame_recd(true)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Ok(Some(_)) => self.stats.frame_recd += 1,
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
} else {
|
} else {
|
||||||
|
self.stats.rx_idle += 1;
|
||||||
self.inner.check_link_change(&self.phy);
|
self.inner.check_link_change(&self.phy);
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
@ -405,7 +444,13 @@ impl<GEM: Gem, TX> Eth<GEM, rx::DescList, TX> {
|
|||||||
|
|
||||||
impl<GEM: Gem, RX> Eth<GEM, RX, tx::DescList> {
|
impl<GEM: Gem, RX> Eth<GEM, RX, tx::DescList> {
|
||||||
pub fn send<'s: 'p, 'p>(&'s mut self, length: usize) -> Option<tx::PktRef<'p>> {
|
pub fn send<'s: 'p, 'p>(&'s mut self, length: usize) -> Option<tx::PktRef<'p>> {
|
||||||
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<GEM, rx::DescList, tx::
|
|||||||
fn receive(&'a mut self) -> Option<(Self::RxToken, Self::TxToken)> {
|
fn receive(&'a mut self) -> Option<(Self::RxToken, Self::TxToken)> {
|
||||||
match self.rx.recv_next() {
|
match self.rx.recv_next() {
|
||||||
Ok(Some(pktref)) => {
|
Ok(Some(pktref)) => {
|
||||||
|
self.stats.frame_recd += 1;
|
||||||
let tx_token = tx::Token {
|
let tx_token = tx::Token {
|
||||||
regs: GEM::regs(),
|
regs: GEM::regs(),
|
||||||
desc_list: &mut self.tx,
|
desc_list: &mut self.tx,
|
||||||
@ -439,6 +485,7 @@ impl<'a, GEM: Gem> smoltcp::phy::Device<'a> for &mut Eth<GEM, rx::DescList, tx::
|
|||||||
Some((pktref, tx_token))
|
Some((pktref, tx_token))
|
||||||
}
|
}
|
||||||
Ok(None) => {
|
Ok(None) => {
|
||||||
|
self.stats.rx_idle += 1;
|
||||||
self.inner.check_link_change(&self.phy);
|
self.inner.check_link_change(&self.phy);
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user