1132: net: allow changing mac addr at runtime r=Dirbaio a=Dirbaio

bors r+

Co-authored-by: Dario Nieuwenhuis <dirbaio@dirbaio.net>
This commit is contained in:
bors[bot] 2022-12-27 00:14:16 +00:00 committed by GitHub
commit 3afb62d8d6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 37 deletions

View file

@ -34,24 +34,29 @@ impl<const MTU: usize, const N_RX: usize, const N_TX: usize> State<MTU, N_RX, N_
struct StateInner<'d, const MTU: usize> { struct StateInner<'d, const MTU: usize> {
rx: zerocopy_channel::Channel<'d, NoopRawMutex, PacketBuf<MTU>>, rx: zerocopy_channel::Channel<'d, NoopRawMutex, PacketBuf<MTU>>,
tx: zerocopy_channel::Channel<'d, NoopRawMutex, PacketBuf<MTU>>, tx: zerocopy_channel::Channel<'d, NoopRawMutex, PacketBuf<MTU>>,
link_state: Mutex<NoopRawMutex, RefCell<LinkStateState>>, shared: Mutex<NoopRawMutex, RefCell<Shared>>,
} }
/// State of the LinkState /// State of the LinkState
struct LinkStateState { struct Shared {
state: LinkState, link_state: LinkState,
waker: WakerRegistration, waker: WakerRegistration,
ethernet_address: [u8; 6],
} }
pub struct Runner<'d, const MTU: usize> { pub struct Runner<'d, const MTU: usize> {
tx_chan: zerocopy_channel::Receiver<'d, NoopRawMutex, PacketBuf<MTU>>, tx_chan: zerocopy_channel::Receiver<'d, NoopRawMutex, PacketBuf<MTU>>,
rx_chan: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf<MTU>>, rx_chan: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf<MTU>>,
link_state: &'d Mutex<NoopRawMutex, RefCell<LinkStateState>>, shared: &'d Mutex<NoopRawMutex, RefCell<Shared>>,
}
#[derive(Clone, Copy)]
pub struct StateRunner<'d> {
shared: &'d Mutex<NoopRawMutex, RefCell<Shared>>,
} }
pub struct RxRunner<'d, const MTU: usize> { pub struct RxRunner<'d, const MTU: usize> {
rx_chan: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf<MTU>>, rx_chan: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf<MTU>>,
link_state: &'d Mutex<NoopRawMutex, RefCell<LinkStateState>>,
} }
pub struct TxRunner<'d, const MTU: usize> { pub struct TxRunner<'d, const MTU: usize> {
@ -59,20 +64,30 @@ pub struct TxRunner<'d, const MTU: usize> {
} }
impl<'d, const MTU: usize> Runner<'d, MTU> { impl<'d, const MTU: usize> Runner<'d, MTU> {
pub fn split(self) -> (RxRunner<'d, MTU>, TxRunner<'d, MTU>) { pub fn split(self) -> (StateRunner<'d>, RxRunner<'d, MTU>, TxRunner<'d, MTU>) {
( (
RxRunner { StateRunner { shared: self.shared },
link_state: self.link_state, RxRunner { rx_chan: self.rx_chan },
rx_chan: self.rx_chan,
},
TxRunner { tx_chan: self.tx_chan }, TxRunner { tx_chan: self.tx_chan },
) )
} }
pub fn state_runner(&self) -> StateRunner<'d> {
StateRunner { shared: self.shared }
}
pub fn set_link_state(&mut self, state: LinkState) { pub fn set_link_state(&mut self, state: LinkState) {
self.link_state.lock(|s| { self.shared.lock(|s| {
let s = &mut *s.borrow_mut(); let s = &mut *s.borrow_mut();
s.state = state; s.link_state = state;
s.waker.wake();
});
}
pub fn set_ethernet_address(&mut self, address: [u8; 6]) {
self.shared.lock(|s| {
let s = &mut *s.borrow_mut();
s.ethernet_address = address;
s.waker.wake(); s.waker.wake();
}); });
} }
@ -122,15 +137,25 @@ impl<'d, const MTU: usize> Runner<'d, MTU> {
} }
} }
impl<'d, const MTU: usize> RxRunner<'d, MTU> { impl<'d> StateRunner<'d> {
pub fn set_link_state(&mut self, state: LinkState) { pub fn set_link_state(&self, state: LinkState) {
self.link_state.lock(|s| { self.shared.lock(|s| {
let s = &mut *s.borrow_mut(); let s = &mut *s.borrow_mut();
s.state = state; s.link_state = state;
s.waker.wake(); s.waker.wake();
}); });
} }
pub fn set_ethernet_address(&self, address: [u8; 6]) {
self.shared.lock(|s| {
let s = &mut *s.borrow_mut();
s.ethernet_address = address;
s.waker.wake();
});
}
}
impl<'d, const MTU: usize> RxRunner<'d, MTU> {
pub async fn rx_buf(&mut self) -> &mut [u8] { pub async fn rx_buf(&mut self) -> &mut [u8] {
let p = self.rx_chan.send().await; let p = self.rx_chan.send().await;
&mut p.buf &mut p.buf
@ -194,8 +219,9 @@ pub fn new<'d, const MTU: usize, const N_RX: usize, const N_TX: usize>(
let state = unsafe { &mut *state_uninit }.write(StateInner { let state = unsafe { &mut *state_uninit }.write(StateInner {
rx: zerocopy_channel::Channel::new(&mut state.rx[..]), rx: zerocopy_channel::Channel::new(&mut state.rx[..]),
tx: zerocopy_channel::Channel::new(&mut state.tx[..]), tx: zerocopy_channel::Channel::new(&mut state.tx[..]),
link_state: Mutex::new(RefCell::new(LinkStateState { shared: Mutex::new(RefCell::new(Shared {
state: LinkState::Down, link_state: LinkState::Down,
ethernet_address,
waker: WakerRegistration::new(), waker: WakerRegistration::new(),
})), })),
}); });
@ -207,12 +233,11 @@ pub fn new<'d, const MTU: usize, const N_RX: usize, const N_TX: usize>(
Runner { Runner {
tx_chan: tx_receiver, tx_chan: tx_receiver,
rx_chan: rx_sender, rx_chan: rx_sender,
link_state: &state.link_state, shared: &state.shared,
}, },
Device { Device {
caps, caps,
ethernet_address, shared: &state.shared,
link_state: &state.link_state,
rx: rx_receiver, rx: rx_receiver,
tx: tx_sender, tx: tx_sender,
}, },
@ -233,9 +258,8 @@ impl<const MTU: usize> PacketBuf<MTU> {
pub struct Device<'d, const MTU: usize> { pub struct Device<'d, const MTU: usize> {
rx: zerocopy_channel::Receiver<'d, NoopRawMutex, PacketBuf<MTU>>, rx: zerocopy_channel::Receiver<'d, NoopRawMutex, PacketBuf<MTU>>,
tx: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf<MTU>>, tx: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf<MTU>>,
link_state: &'d Mutex<NoopRawMutex, RefCell<LinkStateState>>, shared: &'d Mutex<NoopRawMutex, RefCell<Shared>>,
caps: Capabilities, caps: Capabilities,
ethernet_address: [u8; 6],
} }
impl<'d, const MTU: usize> embassy_net_driver::Driver for Device<'d, MTU> { impl<'d, const MTU: usize> embassy_net_driver::Driver for Device<'d, MTU> {
@ -265,14 +289,14 @@ impl<'d, const MTU: usize> embassy_net_driver::Driver for Device<'d, MTU> {
} }
fn ethernet_address(&self) -> [u8; 6] { fn ethernet_address(&self) -> [u8; 6] {
self.ethernet_address self.shared.lock(|s| s.borrow().ethernet_address)
} }
fn link_state(&mut self, cx: &mut Context) -> LinkState { fn link_state(&mut self, cx: &mut Context) -> LinkState {
self.link_state.lock(|s| { self.shared.lock(|s| {
let s = &mut *s.borrow_mut(); let s = &mut *s.borrow_mut();
s.waker.register(cx.waker()); s.waker.register(cx.waker());
s.state s.link_state
}) })
} }
} }

View file

@ -111,20 +111,13 @@ impl<D: Driver + 'static> Stack<D> {
#[cfg(feature = "medium-ethernet")] #[cfg(feature = "medium-ethernet")]
let medium = device.capabilities().medium; let medium = device.capabilities().medium;
#[cfg(feature = "medium-ethernet")]
let ethernet_addr = if medium == Medium::Ethernet {
device.ethernet_address()
} else {
[0, 0, 0, 0, 0, 0]
};
let mut b = InterfaceBuilder::new(); let mut b = InterfaceBuilder::new();
b = b.ip_addrs(&mut resources.addresses[..]); b = b.ip_addrs(&mut resources.addresses[..]);
b = b.random_seed(random_seed); b = b.random_seed(random_seed);
#[cfg(feature = "medium-ethernet")] #[cfg(feature = "medium-ethernet")]
if medium == Medium::Ethernet { if medium == Medium::Ethernet {
b = b.hardware_addr(HardwareAddress::Ethernet(EthernetAddress(ethernet_addr))); b = b.hardware_addr(HardwareAddress::Ethernet(EthernetAddress(device.ethernet_address())));
b = b.neighbor_cache(NeighborCache::new(&mut resources.neighbor_cache[..])); b = b.neighbor_cache(NeighborCache::new(&mut resources.neighbor_cache[..]));
b = b.routes(Routes::new(&mut resources.routes[..])); b = b.routes(Routes::new(&mut resources.routes[..]));
} }
@ -261,6 +254,13 @@ impl<D: Driver + 'static> Inner<D> {
fn poll(&mut self, cx: &mut Context<'_>, s: &mut SocketStack) { fn poll(&mut self, cx: &mut Context<'_>, s: &mut SocketStack) {
s.waker.register(cx.waker()); s.waker.register(cx.waker());
#[cfg(feature = "medium-ethernet")]
if self.device.capabilities().medium == Medium::Ethernet {
s.iface.set_hardware_addr(HardwareAddress::Ethernet(EthernetAddress(
self.device.ethernet_address(),
)));
}
let timestamp = instant_to_smoltcp(Instant::now()); let timestamp = instant_to_smoltcp(Instant::now());
let mut smoldev = DriverAdapter { let mut smoldev = DriverAdapter {
cx: Some(cx), cx: Some(cx),

View file

@ -25,16 +25,16 @@ pub struct Runner<'d, D: Driver<'d>, const MTU: usize> {
impl<'d, D: Driver<'d>, const MTU: usize> Runner<'d, D, MTU> { impl<'d, D: Driver<'d>, const MTU: usize> Runner<'d, D, MTU> {
pub async fn run(mut self) -> ! { pub async fn run(mut self) -> ! {
let (mut rx_chan, mut tx_chan) = self.ch.split(); let (state_chan, mut rx_chan, mut tx_chan) = self.ch.split();
let rx_fut = async move { let rx_fut = async move {
loop { loop {
trace!("WAITING for connection"); trace!("WAITING for connection");
rx_chan.set_link_state(LinkState::Down); state_chan.set_link_state(LinkState::Down);
self.rx_usb.wait_connection().await.unwrap(); self.rx_usb.wait_connection().await.unwrap();
trace!("Connected"); trace!("Connected");
rx_chan.set_link_state(LinkState::Up); state_chan.set_link_state(LinkState::Up);
loop { loop {
let p = rx_chan.rx_buf().await; let p = rx_chan.rx_buf().await;