diff --git a/kernel/driver/net/stmmac/src/lib.rs b/kernel/driver/net/stmmac/src/lib.rs index 12205d41..458b7a74 100644 --- a/kernel/driver/net/stmmac/src/lib.rs +++ b/kernel/driver/net/stmmac/src/lib.rs @@ -60,13 +60,25 @@ struct Stmmac { impl Inner { fn link_state(&self) -> LinkState { - // TODO read the link state properly, i.e., read from PHY's registers, I guess? I didn't - // find a nice way to read the link state from the MAC itself, it only seems to report - // the MAC<->PHY link state (which is always up, obviously) - LinkState::Ethernet(EthernetLinkState::Up( - EthernetSpeed::Unknown, - Duplex::Unknown, - )) + let status = self.regs.lock().MAC.MACPHYCSR.extract(); + let link = if status.matches_all(MACPHYCSR::LNKSTS::Up) { + let speed = match status.read_as_enum(MACPHYCSR::LNKSPEED) { + Some(MACPHYCSR::LNKSPEED::Value::Speed2_5MHz) => EthernetSpeed::Speed10, + Some(MACPHYCSR::LNKSPEED::Value::Speed25MHz) => EthernetSpeed::Speed100, + Some(MACPHYCSR::LNKSPEED::Value::Speed125MHz) => EthernetSpeed::Speed1000, + _ => EthernetSpeed::Unknown, + }; + let duplex = if status.matches_all(MACPHYCSR::LNKMOD::FullDuplex) { + Duplex::Full + } else { + Duplex::Half + }; + EthernetLinkState::Up(speed, duplex) + } else { + EthernetLinkState::Down + }; + + LinkState::Ethernet(link) } }