Revert "DHCP support for core device firmware"

This reverts commit 6ffb1f83ee.
This commit is contained in:
Sebastien Bourdeauducq 2022-07-08 17:58:00 +08:00
parent c4a9fa78ee
commit d622fb8db7
6 changed files with 30 additions and 168 deletions

View File

@ -1,15 +1,12 @@
use core::fmt; use core::fmt;
use smoltcp::wire::{EthernetAddress, IpAddress, Ipv4Address}; use smoltcp::wire::{EthernetAddress, IpAddress};
use config; use config;
#[cfg(soc_platform = "kasli")] #[cfg(soc_platform = "kasli")]
use i2c_eeprom; use i2c_eeprom;
pub const USE_DHCP: IpAddress = IpAddress::Ipv4(Ipv4Address::UNSPECIFIED);
pub struct NetAddresses { pub struct NetAddresses {
pub hardware_addr: EthernetAddress, pub hardware_addr: EthernetAddress,
pub ipv4_addr: IpAddress, pub ipv4_addr: IpAddress,
@ -52,13 +49,7 @@ pub fn get_adresses() -> NetAddresses {
} }
let ipv4_addr; let ipv4_addr;
match config::read_str("ip", |r| r.map(|s| { match config::read_str("ip", |r| r.map(|s| s.parse())) {
if s == "use_dhcp" {
Ok(USE_DHCP)
} else {
s.parse()
}
})) {
Ok(Ok(addr)) => ipv4_addr = addr, Ok(Ok(addr)) => ipv4_addr = addr,
_ => { _ => {
#[cfg(soc_platform = "kasli")] #[cfg(soc_platform = "kasli")]

View File

@ -27,13 +27,9 @@ board_misoc = { path = "../libboard_misoc", features = ["uart_console", "smoltcp
logger_artiq = { path = "../liblogger_artiq" } logger_artiq = { path = "../liblogger_artiq" }
board_artiq = { path = "../libboard_artiq" } board_artiq = { path = "../libboard_artiq" }
proto_artiq = { path = "../libproto_artiq", features = ["log", "alloc"] } proto_artiq = { path = "../libproto_artiq", features = ["log", "alloc"] }
smoltcp = { version = "0.8.0", default-features = false, features = ["alloc", "medium-ethernet", "proto-ipv4", "proto-ipv6", "socket-tcp"] }
riscv = { version = "0.6.0", features = ["inline-asm"] } riscv = { version = "0.6.0", features = ["inline-asm"] }
[dependencies.smoltcp]
version = "0.8.0"
default-features = false
features = ["alloc", "medium-ethernet", "proto-ipv4", "proto-ipv6", "socket-tcp", "socket-dhcpv4"]
[dependencies.fringe] [dependencies.fringe]
git = "https://git.m-labs.hk/M-Labs/libfringe.git" git = "https://git.m-labs.hk/M-Labs/libfringe.git"
rev = "3ecbe5" rev = "3ecbe5"

View File

@ -1,59 +0,0 @@
use board_misoc::clock;
use sched;
use sched::Dhcpv4Socket;
use smoltcp::socket::Dhcpv4Event;
use smoltcp::wire::{Ipv4Address, Ipv4Cidr};
pub fn dhcp_thread(io: sched::Io) {
let mut socket = Dhcpv4Socket::new(&io);
let mut last_ip: Option<Ipv4Cidr> = None;
let mut done_reset = false;
let start_time = clock::get_ms();
loop {
// A significant amount of the time our first discover isn't received
// by the server. This is likely to be because the ethernet device isn't quite
// ready at the point that it is sent. The following makes recovery from
// that faster.
if !done_reset && last_ip.is_none() && start_time + 1000 < clock::get_ms() {
info!("Didn't get initial IP in first second. Assuming packet loss, trying a reset.");
socket.reset();
done_reset = true;
}
if let Some(event) = socket.poll() {
match event {
Dhcpv4Event::Configured(config) => {
// Only compare the ip address in the config with previous config because we
// ignore the rest of the config i.e. we don't do any DNS or require a default
// gateway.
let changed = if let Some(last_ip) = last_ip {
if config.address != last_ip {
info!("IP address changed {} -> {}", last_ip, config.address);
true
} else {
false
}
} else {
info!("Acquired IP address: None -> {}", config.address);
true
};
if changed {
last_ip = Some(config.address);
io.set_ipv4_address(&config.address);
}
}
Dhcpv4Event::Deconfigured => {
if let Some(ip) = last_ip {
info!("Lost IP address {} -> None", ip);
io.set_ipv4_address(&Ipv4Cidr::new(Ipv4Address::UNSPECIFIED, 0));
last_ip = None;
}
// We always get one of these events at the start, ignore that one
}
}
}
// We want to poll after every poll of the interface. So we need to
// do a minimal yield here.
io.relinquish().unwrap();
}
}

View File

@ -27,12 +27,11 @@ extern crate riscv;
use core::cell::RefCell; use core::cell::RefCell;
use core::convert::TryFrom; use core::convert::TryFrom;
use smoltcp::wire::{HardwareAddress, IpAddress, IpCidr, Ipv4Address}; use smoltcp::wire::{IpCidr, HardwareAddress};
use board_misoc::{csr, ident, clock, spiflash, config, net_settings, pmp, boot}; use board_misoc::{csr, ident, clock, spiflash, config, net_settings, pmp, boot};
#[cfg(has_ethmac)] #[cfg(has_ethmac)]
use board_misoc::ethmac; use board_misoc::ethmac;
use board_misoc::net_settings::{NetAddresses, USE_DHCP};
#[cfg(has_drtio)] #[cfg(has_drtio)]
use board_artiq::drtioaux; use board_artiq::drtioaux;
use board_artiq::drtio_routing; use board_artiq::drtio_routing;
@ -59,14 +58,6 @@ mod session;
mod moninj; mod moninj;
#[cfg(has_rtio_analyzer)] #[cfg(has_rtio_analyzer)]
mod analyzer; mod analyzer;
mod dhcp;
// Fixed indexes for the IP addresses so that they can be modified with some
// semblance of confidence
pub const IPV4_INDEX: usize = 0;
pub const IPV6_LL_INDEX: usize = 1;
pub const IPV6_INDEX: usize = 2;
const IP_ADDRESS_STORAGE_SIZE: usize = 3;
#[cfg(has_grabber)] #[cfg(has_grabber)]
fn grabber_thread(io: sched::Io) { fn grabber_thread(io: sched::Io) {
@ -96,18 +87,6 @@ fn setup_log_levels() {
} }
} }
pub fn get_ip_addrs(net_addresses: &NetAddresses) -> [IpCidr; IP_ADDRESS_STORAGE_SIZE] {
let mut storage = [
IpCidr::new(IpAddress::Ipv4(Ipv4Address::UNSPECIFIED), 0); IP_ADDRESS_STORAGE_SIZE
];
storage[IPV4_INDEX] = IpCidr::new(net_addresses.ipv4_addr, 0);
storage[IPV6_LL_INDEX] = IpCidr::new(net_addresses.ipv6_ll_addr, 0);
if let Some(ipv6) = net_addresses.ipv6_addr {
storage[IPV6_INDEX] = IpCidr::new(ipv6, 0);
}
storage
}
fn startup() { fn startup() {
clock::init(); clock::init();
info!("ARTIQ runtime starting..."); info!("ARTIQ runtime starting...");
@ -162,17 +141,31 @@ fn startup() {
smoltcp::iface::NeighborCache::new(alloc::collections::btree_map::BTreeMap::new()); smoltcp::iface::NeighborCache::new(alloc::collections::btree_map::BTreeMap::new());
let net_addresses = net_settings::get_adresses(); let net_addresses = net_settings::get_adresses();
info!("network addresses: {}", net_addresses); info!("network addresses: {}", net_addresses);
let use_dhcp = if net_addresses.ipv4_addr == USE_DHCP { let interface = match net_addresses.ipv6_addr {
info!("Will try to acquire an IPv4 address with DHCP"); Some(addr) => {
true let ip_addrs = [
} else { IpCidr::new(net_addresses.ipv4_addr, 0),
false IpCidr::new(net_addresses.ipv6_ll_addr, 0),
IpCidr::new(addr, 0)
];
smoltcp::iface::InterfaceBuilder::new(net_device, vec![])
.hardware_addr(HardwareAddress::Ethernet(net_addresses.hardware_addr))
.ip_addrs(ip_addrs)
.neighbor_cache(neighbor_cache)
.finalize()
}
None => {
let ip_addrs = [
IpCidr::new(net_addresses.ipv4_addr, 0),
IpCidr::new(net_addresses.ipv6_ll_addr, 0)
];
smoltcp::iface::InterfaceBuilder::new(net_device, vec![])
.hardware_addr(HardwareAddress::Ethernet(net_addresses.hardware_addr))
.ip_addrs(ip_addrs)
.neighbor_cache(neighbor_cache)
.finalize()
}
}; };
let interface = smoltcp::iface::InterfaceBuilder::new(net_device, vec![])
.hardware_addr(HardwareAddress::Ethernet(net_addresses.hardware_addr))
.ip_addrs(get_ip_addrs(&net_addresses))
.neighbor_cache(neighbor_cache)
.finalize();
#[cfg(has_drtio)] #[cfg(has_drtio)]
let drtio_routing_table = urc::Urc::new(RefCell::new( let drtio_routing_table = urc::Urc::new(RefCell::new(
@ -189,10 +182,6 @@ fn startup() {
let mut scheduler = sched::Scheduler::new(interface); let mut scheduler = sched::Scheduler::new(interface);
let io = scheduler.io(); let io = scheduler.io();
if use_dhcp {
io.spawn(4096, dhcp::dhcp_thread);
}
rtio_mgt::startup(&io, &aux_mutex, &drtio_routing_table, &up_destinations); rtio_mgt::startup(&io, &aux_mutex, &drtio_routing_table, &up_destinations);
io.spawn(4096, mgmt::thread); io.spawn(4096, mgmt::thread);

View File

@ -2,13 +2,13 @@
use core::mem; use core::mem;
use core::result; use core::result;
use core::cell::{Cell, RefCell, RefMut}; use core::cell::{Cell, RefCell};
use alloc::vec::Vec; use alloc::vec::Vec;
use fringe::OwnedStack; use fringe::OwnedStack;
use fringe::generator::{Generator, Yielder, State as GeneratorState}; use fringe::generator::{Generator, Yielder, State as GeneratorState};
use smoltcp::time::Duration; use smoltcp::time::Duration;
use smoltcp::Error as NetworkError; use smoltcp::Error as NetworkError;
use smoltcp::wire::{IpEndpoint, Ipv4Cidr, IpCidr}; use smoltcp::wire::IpEndpoint;
use smoltcp::iface::{Interface, SocketHandle}; use smoltcp::iface::{Interface, SocketHandle};
use io::{Read, Write}; use io::{Read, Write};
@ -16,7 +16,6 @@ use board_misoc::clock;
use urc::Urc; use urc::Urc;
use board_misoc::ethmac::EthernetDevice; use board_misoc::ethmac::EthernetDevice;
use smoltcp::phy::Tracer; use smoltcp::phy::Tracer;
use IPV4_INDEX;
#[derive(Fail, Debug)] #[derive(Fail, Debug)]
pub enum Error { pub enum Error {
@ -274,12 +273,6 @@ impl<'a> Io<'a> {
pub fn join(&self, handle: ThreadHandle) -> Result<(), Error> { pub fn join(&self, handle: ThreadHandle) -> Result<(), Error> {
self.until(move || handle.terminated()) self.until(move || handle.terminated())
} }
pub fn set_ipv4_address(&self, addr: &Ipv4Cidr) {
self.network.borrow_mut().update_ip_addrs(|addrs| {
addrs.as_mut()[IPV4_INDEX] = IpCidr::Ipv4(*addr);
})
}
} }
#[derive(Clone)] #[derive(Clone)]
@ -570,45 +563,3 @@ impl<'a> Drop for TcpStream<'a> {
self.io.network.borrow_mut().remove_socket(self.handle); self.io.network.borrow_mut().remove_socket(self.handle);
} }
} }
pub struct Dhcpv4Socket<'a> {
io: &'a Io<'a>,
handle: SocketHandle,
}
impl<'a> Dhcpv4Socket<'a> {
fn new_lower(io: &'a Io<'a>) -> SocketHandle {
let socket = smoltcp::socket::Dhcpv4Socket::new();
io.network.borrow_mut().add_socket(socket)
}
pub fn new(io: &'a Io<'a>) -> Self {
Self {
io,
handle: Self::new_lower(io)
}
}
fn lower(&mut self) -> RefMut<smoltcp::socket::Dhcpv4Socket> {
RefMut::map(
self.io.network.borrow_mut(),
|network| network.get_socket::<smoltcp::socket::Dhcpv4Socket>(self.handle),
)
}
pub fn poll(&mut self) -> Option<smoltcp::socket::Dhcpv4Event> {
self.lower().poll()
}
pub fn reset(&mut self) {
self.lower().reset()
}
}
impl<'a> Drop for Dhcpv4Socket<'a> {
fn drop(&mut self) {
let mut network = self.io.network.borrow_mut();
network.remove_socket(self.handle);
}
}

View File

@ -268,12 +268,6 @@ In other cases, install OpenOCD as before, and flash the IP (and, if necessary,
For Kasli devices, flashing a MAC address is not necessary as they can obtain it from their EEPROM. For Kasli devices, flashing a MAC address is not necessary as they can obtain it from their EEPROM.
Alternatively you can set the "ip" config field to "use_dhcp" to have the device use DHCP to obtain an IP address on
boot. e.g. ::
$ artiq_mkfs flash_storage.img -s ip use_dhcp
$ artiq_flash -t [board] -V [variant] -f flash_storage.img storage start
Check that you can ping the device. If ping fails, check that the Ethernet link LED is ON - on Kasli, it is the LED next to the SFP0 connector. As a next step, look at the messages emitted on the UART during boot. Use a program such as flterm or PuTTY to connect to the device's serial port at 115200bps 8-N-1 and reboot the device. On Kasli, the serial port is on FTDI channel 2 with v1.1 hardware (with channel 0 being JTAG) and on FTDI channel 1 with v1.0 hardware. Check that you can ping the device. If ping fails, check that the Ethernet link LED is ON - on Kasli, it is the LED next to the SFP0 connector. As a next step, look at the messages emitted on the UART during boot. Use a program such as flterm or PuTTY to connect to the device's serial port at 115200bps 8-N-1 and reboot the device. On Kasli, the serial port is on FTDI channel 2 with v1.1 hardware (with channel 0 being JTAG) and on FTDI channel 1 with v1.0 hardware.
If you want to use IPv6, the device also has a link-local address that corresponds to its EUI-64, and an additional arbitrary IPv6 address can be defined by using the ``ip6`` configuration key. All IPv4 and IPv6 addresses can be used at the same time. If you want to use IPv6, the device also has a link-local address that corresponds to its EUI-64, and an additional arbitrary IPv6 address can be defined by using the ``ip6`` configuration key. All IPv4 and IPv6 addresses can be used at the same time.