2021-05-06 18:33:07 +08:00
|
|
|
///! Task to process network hardware.
|
|
|
|
///!
|
|
|
|
///! # Design
|
|
|
|
///! The network processir is a small taks to regularly process incoming data over ethernet, handle
|
|
|
|
///! the ethernet PHY state, and reset the network as appropriate.
|
2021-05-05 21:39:33 +08:00
|
|
|
use super::{NetworkReference, UpdateState};
|
|
|
|
use crate::hardware::{CycleCounter, EthernetPhy};
|
2021-05-05 01:52:41 +08:00
|
|
|
|
2021-05-06 18:33:07 +08:00
|
|
|
/// Processor for managing network hardware.
|
2021-05-05 01:52:41 +08:00
|
|
|
pub struct NetworkProcessor {
|
|
|
|
stack: NetworkReference,
|
|
|
|
phy: EthernetPhy,
|
|
|
|
clock: CycleCounter,
|
|
|
|
network_was_reset: bool,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl NetworkProcessor {
|
2021-05-06 18:33:07 +08:00
|
|
|
/// Construct a new network processor.
|
|
|
|
///
|
|
|
|
/// # Args
|
|
|
|
/// * `stack` - A reference to the shared network stack
|
|
|
|
/// * `phy` - The ethernet PHY used for the network.
|
|
|
|
/// * `clock` - The clock used for providing time to the network.
|
|
|
|
///
|
|
|
|
/// # Returns
|
|
|
|
/// The newly constructed processor.
|
2021-05-05 21:39:33 +08:00
|
|
|
pub fn new(
|
|
|
|
stack: NetworkReference,
|
|
|
|
phy: EthernetPhy,
|
|
|
|
clock: CycleCounter,
|
|
|
|
) -> Self {
|
|
|
|
Self {
|
|
|
|
stack,
|
|
|
|
phy,
|
|
|
|
clock,
|
|
|
|
network_was_reset: false,
|
|
|
|
}
|
2021-05-05 01:52:41 +08:00
|
|
|
}
|
|
|
|
|
2021-05-26 21:02:50 +08:00
|
|
|
pub fn egress(&mut self) {
|
|
|
|
let now = self.clock.current_ms();
|
|
|
|
self.stack.lock(|stack| stack.poll(now)).ok();
|
|
|
|
}
|
|
|
|
|
2021-05-06 18:33:07 +08:00
|
|
|
/// Process and update the state of the network.
|
|
|
|
///
|
|
|
|
/// # Note
|
|
|
|
/// This function should be called regularly before other network tasks to update the state of
|
|
|
|
/// all relevant network sockets.
|
|
|
|
///
|
|
|
|
/// # Returns
|
|
|
|
/// An update state corresponding with any changes in the underlying network.
|
2021-05-05 01:52:41 +08:00
|
|
|
pub fn update(&mut self) -> UpdateState {
|
|
|
|
// Service the network stack to process any inbound and outbound traffic.
|
2021-05-05 21:39:33 +08:00
|
|
|
let now = self.clock.current_ms();
|
|
|
|
|
|
|
|
let result = match self.stack.lock(|stack| stack.poll(now)) {
|
2021-05-05 01:52:41 +08:00
|
|
|
Ok(true) => UpdateState::Updated,
|
|
|
|
Ok(false) => UpdateState::NoChange,
|
|
|
|
Err(err) => {
|
|
|
|
log::info!("Network error: {:?}", err);
|
|
|
|
UpdateState::Updated
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// If the PHY indicates there's no more ethernet link, reset the DHCP server in the network
|
|
|
|
// stack.
|
2021-05-26 23:56:44 +08:00
|
|
|
// TODO: Poll the link state in a task and handle resets. Polling this often is slow and
|
|
|
|
// uses necessary CPU time.
|
|
|
|
//match self.phy.poll_link() {
|
|
|
|
// true => self.network_was_reset = false,
|
2021-05-05 01:52:41 +08:00
|
|
|
|
2021-05-26 23:56:44 +08:00
|
|
|
// // Only reset the network stack once per link reconnection. This prevents us from
|
|
|
|
// // sending an excessive number of DHCP requests.
|
|
|
|
// false if !self.network_was_reset => {
|
|
|
|
// self.network_was_reset = true;
|
|
|
|
// self.stack.lock(|stack| stack.handle_link_reset());
|
|
|
|
// }
|
|
|
|
// _ => {}
|
|
|
|
//};
|
2021-05-05 01:52:41 +08:00
|
|
|
|
|
|
|
result
|
|
|
|
}
|
|
|
|
}
|