113776c11Slogin use core::{ 213776c11Slogin cell::UnsafeCell, 313776c11Slogin fmt::Debug, 413776c11Slogin ops::{Deref, DerefMut}, 513776c11Slogin }; 613776c11Slogin 713776c11Slogin use alloc::{string::String, sync::Arc}; 813776c11Slogin use smoltcp::{phy, wire}; 913776c11Slogin use virtio_drivers::{device::net::VirtIONet, transport::Transport}; 1013776c11Slogin 1113776c11Slogin use crate::{ 1213776c11Slogin driver::{virtio::virtio_impl::HalImpl, Driver}, 1313776c11Slogin kdebug, kerror, kinfo, 1413776c11Slogin libs::spinlock::SpinLock, 1513776c11Slogin net::{generate_iface_id, NET_DRIVERS}, 1613776c11Slogin syscall::SystemError, 1713776c11Slogin time::Instant, 1813776c11Slogin }; 1913776c11Slogin 2013776c11Slogin use super::NetDriver; 2113776c11Slogin 2213776c11Slogin /// @brief Virtio网络设备驱动(加锁) 2313776c11Slogin pub struct VirtioNICDriver<T: Transport> { 2413776c11Slogin pub inner: Arc<SpinLock<VirtIONet<HalImpl, T, 2>>>, 2513776c11Slogin } 2613776c11Slogin 2713776c11Slogin impl<T: Transport> Clone for VirtioNICDriver<T> { 2813776c11Slogin fn clone(&self) -> Self { 2913776c11Slogin return VirtioNICDriver { 3013776c11Slogin inner: self.inner.clone(), 3113776c11Slogin }; 3213776c11Slogin } 3313776c11Slogin } 3413776c11Slogin 3513776c11Slogin /// @brief 网卡驱动的包裹器,这是为了获取网卡驱动的可变引用而设计的。 3613776c11Slogin /// 由于smoltcp的设计,导致需要在poll的时候获取网卡驱动的可变引用, 3713776c11Slogin /// 同时需要在token的consume里面获取可变引用。为了避免双重加锁,所以需要这个包裹器。 3813776c11Slogin struct VirtioNICDriverWrapper<T: Transport>(UnsafeCell<VirtioNICDriver<T>>); 3913776c11Slogin unsafe impl<T: Transport> Send for VirtioNICDriverWrapper<T> {} 4013776c11Slogin unsafe impl<T: Transport> Sync for VirtioNICDriverWrapper<T> {} 4113776c11Slogin 4213776c11Slogin impl<T: Transport> Deref for VirtioNICDriverWrapper<T> { 4313776c11Slogin type Target = VirtioNICDriver<T>; 4413776c11Slogin fn deref(&self) -> &Self::Target { 4513776c11Slogin unsafe { &*self.0.get() } 4613776c11Slogin } 4713776c11Slogin } 4813776c11Slogin impl<T: Transport> DerefMut for VirtioNICDriverWrapper<T> { 4913776c11Slogin fn deref_mut(&mut self) -> &mut Self::Target { 5013776c11Slogin unsafe { &mut *self.0.get() } 5113776c11Slogin } 5213776c11Slogin } 5313776c11Slogin 5413776c11Slogin impl<T: Transport> VirtioNICDriverWrapper<T> { 5513776c11Slogin fn force_get_mut(&self) -> &mut VirtioNICDriver<T> { 5613776c11Slogin unsafe { &mut *self.0.get() } 5713776c11Slogin } 5813776c11Slogin } 5913776c11Slogin 6013776c11Slogin impl<T: Transport> Debug for VirtioNICDriver<T> { 6113776c11Slogin fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 6213776c11Slogin f.debug_struct("VirtioNICDriver").finish() 6313776c11Slogin } 6413776c11Slogin } 6513776c11Slogin 6613776c11Slogin pub struct VirtioInterface<T: Transport> { 6713776c11Slogin driver: VirtioNICDriverWrapper<T>, 6813776c11Slogin iface_id: usize, 6913776c11Slogin iface: SpinLock<smoltcp::iface::Interface>, 7013776c11Slogin name: String, 7113776c11Slogin } 7213776c11Slogin 7313776c11Slogin impl<T: Transport> Debug for VirtioInterface<T> { 7413776c11Slogin fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 7513776c11Slogin f.debug_struct("VirtioInterface") 7613776c11Slogin .field("driver", self.driver.deref()) 7713776c11Slogin .field("iface_id", &self.iface_id) 7813776c11Slogin .field("iface", &"smoltcp::iface::Interface") 7913776c11Slogin .field("name", &self.name) 8013776c11Slogin .finish() 8113776c11Slogin } 8213776c11Slogin } 8313776c11Slogin 8413776c11Slogin impl<T: Transport> VirtioInterface<T> { 8513776c11Slogin pub fn new(mut driver: VirtioNICDriver<T>) -> Arc<Self> { 8613776c11Slogin let iface_id = generate_iface_id(); 8713776c11Slogin let mut iface_config = smoltcp::iface::Config::new(); 8813776c11Slogin 8913776c11Slogin // todo: 随机设定这个值。 9013776c11Slogin // 参见 https://docs.rs/smoltcp/latest/smoltcp/iface/struct.Config.html#structfield.random_seed 9113776c11Slogin iface_config.random_seed = 12345; 9213776c11Slogin 9313776c11Slogin iface_config.hardware_addr = Some(wire::HardwareAddress::Ethernet( 9413776c11Slogin smoltcp::wire::EthernetAddress(driver.inner.lock().mac_address()), 9513776c11Slogin )); 9613776c11Slogin let iface = smoltcp::iface::Interface::new(iface_config, &mut driver); 9713776c11Slogin 9813776c11Slogin let driver: VirtioNICDriverWrapper<T> = VirtioNICDriverWrapper(UnsafeCell::new(driver)); 9913776c11Slogin let result = Arc::new(VirtioInterface { 10013776c11Slogin driver, 10113776c11Slogin iface_id, 10213776c11Slogin iface: SpinLock::new(iface), 10313776c11Slogin name: format!("eth{}", iface_id), 10413776c11Slogin }); 10513776c11Slogin 10613776c11Slogin return result; 10713776c11Slogin } 10813776c11Slogin } 10913776c11Slogin 11013776c11Slogin impl<T: 'static + Transport> VirtioNICDriver<T> { 11113776c11Slogin pub fn new(driver_net: VirtIONet<HalImpl, T, 2>) -> Self { 11213776c11Slogin let mut iface_config = smoltcp::iface::Config::new(); 11313776c11Slogin 11413776c11Slogin // todo: 随机设定这个值。 11513776c11Slogin // 参见 https://docs.rs/smoltcp/latest/smoltcp/iface/struct.Config.html#structfield.random_seed 11613776c11Slogin iface_config.random_seed = 12345; 11713776c11Slogin 11813776c11Slogin iface_config.hardware_addr = Some(wire::HardwareAddress::Ethernet( 11913776c11Slogin smoltcp::wire::EthernetAddress(driver_net.mac_address()), 12013776c11Slogin )); 12113776c11Slogin 12213776c11Slogin let inner: Arc<SpinLock<VirtIONet<HalImpl, T, 2>>> = Arc::new(SpinLock::new(driver_net)); 12313776c11Slogin let result = VirtioNICDriver { inner }; 12413776c11Slogin return result; 12513776c11Slogin } 12613776c11Slogin } 12713776c11Slogin 12813776c11Slogin pub struct VirtioNetToken<T: Transport> { 12913776c11Slogin driver: VirtioNICDriver<T>, 13013776c11Slogin rx_buffer: Option<virtio_drivers::device::net::RxBuffer>, 13113776c11Slogin } 13213776c11Slogin 13313776c11Slogin impl<'a, T: Transport> VirtioNetToken<T> { 13413776c11Slogin pub fn new( 13513776c11Slogin driver: VirtioNICDriver<T>, 13613776c11Slogin rx_buffer: Option<virtio_drivers::device::net::RxBuffer>, 13713776c11Slogin ) -> Self { 13813776c11Slogin return Self { driver, rx_buffer }; 13913776c11Slogin } 14013776c11Slogin } 14113776c11Slogin 14213776c11Slogin impl<T: Transport> phy::Device for VirtioNICDriver<T> { 14313776c11Slogin type RxToken<'a> = VirtioNetToken<T> where Self: 'a; 14413776c11Slogin type TxToken<'a> = VirtioNetToken<T> where Self: 'a; 14513776c11Slogin 14613776c11Slogin fn receive( 14713776c11Slogin &mut self, 14813776c11Slogin _timestamp: smoltcp::time::Instant, 14913776c11Slogin ) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> { 15013776c11Slogin match self.inner.lock().receive() { 15113776c11Slogin Ok(buf) => Some(( 15213776c11Slogin VirtioNetToken::new(self.clone(), Some(buf)), 15313776c11Slogin VirtioNetToken::new(self.clone(), None), 15413776c11Slogin )), 15513776c11Slogin Err(virtio_drivers::Error::NotReady) => None, 15613776c11Slogin Err(err) => panic!("VirtIO receive failed: {}", err), 15713776c11Slogin } 15813776c11Slogin } 15913776c11Slogin 16013776c11Slogin fn transmit(&mut self, _timestamp: smoltcp::time::Instant) -> Option<Self::TxToken<'_>> { 16113776c11Slogin // kdebug!("VirtioNet: transmit"); 16213776c11Slogin if self.inner.lock().can_send() { 16313776c11Slogin // kdebug!("VirtioNet: can send"); 16413776c11Slogin return Some(VirtioNetToken::new(self.clone(), None)); 16513776c11Slogin } else { 16613776c11Slogin // kdebug!("VirtioNet: can not send"); 16713776c11Slogin return None; 16813776c11Slogin } 16913776c11Slogin } 17013776c11Slogin 17113776c11Slogin fn capabilities(&self) -> phy::DeviceCapabilities { 17213776c11Slogin let mut caps = phy::DeviceCapabilities::default(); 17313776c11Slogin // 网卡的最大传输单元. 请与IP层的MTU进行区分。这个值应当是网卡的最大传输单元,而不是IP层的MTU。 17413776c11Slogin caps.max_transmission_unit = 2000; 17513776c11Slogin /* 17613776c11Slogin Maximum burst size, in terms of MTU. 17713776c11Slogin The network device is unable to send or receive bursts large than the value returned by this function. 17813776c11Slogin If None, there is no fixed limit on burst size, e.g. if network buffers are dynamically allocated. 17913776c11Slogin */ 18013776c11Slogin caps.max_burst_size = Some(1); 18113776c11Slogin return caps; 18213776c11Slogin } 18313776c11Slogin } 18413776c11Slogin 18513776c11Slogin impl<T: Transport> phy::TxToken for VirtioNetToken<T> { 18613776c11Slogin fn consume<R, F>(self, len: usize, f: F) -> R 18713776c11Slogin where 18813776c11Slogin F: FnOnce(&mut [u8]) -> R, 18913776c11Slogin { 19013776c11Slogin // // 为了线程安全,这里需要对VirtioNet进行加【写锁】,以保证对设备的互斥访问。 19113776c11Slogin 19213776c11Slogin let mut driver_net = self.driver.inner.lock(); 19313776c11Slogin let mut tx_buf = driver_net.new_tx_buffer(len); 19413776c11Slogin let result = f(tx_buf.packet_mut()); 19513776c11Slogin driver_net.send(tx_buf).expect("virtio_net send failed"); 19613776c11Slogin return result; 19713776c11Slogin } 19813776c11Slogin } 19913776c11Slogin 20013776c11Slogin impl<T: Transport> phy::RxToken for VirtioNetToken<T> { 20113776c11Slogin fn consume<R, F>(self, f: F) -> R 20213776c11Slogin where 20313776c11Slogin F: FnOnce(&mut [u8]) -> R, 20413776c11Slogin { 20513776c11Slogin // 为了线程安全,这里需要对VirtioNet进行加【写锁】,以保证对设备的互斥访问。 20613776c11Slogin let mut rx_buf = self.rx_buffer.unwrap(); 20713776c11Slogin let result = f(rx_buf.packet_mut()); 20813776c11Slogin self.driver 20913776c11Slogin .inner 21013776c11Slogin .lock() 21113776c11Slogin .recycle_rx_buffer(rx_buf) 21213776c11Slogin .expect("virtio_net recv failed"); 21313776c11Slogin result 21413776c11Slogin } 21513776c11Slogin } 21613776c11Slogin 21713776c11Slogin /// @brief virtio-net 驱动的初始化与测试 21813776c11Slogin pub fn virtio_net<T: Transport + 'static>(transport: T) { 21913776c11Slogin let driver_net: VirtIONet<HalImpl, T, 2> = 22013776c11Slogin match VirtIONet::<HalImpl, T, 2>::new(transport, 4096) { 22113776c11Slogin Ok(net) => net, 22213776c11Slogin Err(_) => { 22313776c11Slogin kerror!("VirtIONet init failed"); 22413776c11Slogin return; 22513776c11Slogin } 22613776c11Slogin }; 22713776c11Slogin let mac = smoltcp::wire::EthernetAddress::from_bytes(&driver_net.mac_address()); 22813776c11Slogin let driver: VirtioNICDriver<T> = VirtioNICDriver::new(driver_net); 22913776c11Slogin let iface = VirtioInterface::new(driver); 23013776c11Slogin // 将网卡的接口信息注册到全局的网卡接口信息表中 23113776c11Slogin NET_DRIVERS.write().insert(iface.nic_id(), iface.clone()); 23213776c11Slogin kinfo!( 23313776c11Slogin "Virtio-net driver init successfully!\tNetDevID: [{}], MAC: [{}]", 23413776c11Slogin iface.name(), 23513776c11Slogin mac 23613776c11Slogin ); 23713776c11Slogin } 23813776c11Slogin 23913776c11Slogin impl<T: Transport> Driver for VirtioInterface<T> { 24013776c11Slogin fn as_any_ref(&'static self) -> &'static dyn core::any::Any { 24113776c11Slogin self 24213776c11Slogin } 24313776c11Slogin } 24413776c11Slogin 24513776c11Slogin impl<T: Transport> NetDriver for VirtioInterface<T> { 24613776c11Slogin fn mac(&self) -> smoltcp::wire::EthernetAddress { 24713776c11Slogin let mac: [u8; 6] = self.driver.inner.lock().mac_address(); 24813776c11Slogin return smoltcp::wire::EthernetAddress::from_bytes(&mac); 24913776c11Slogin } 25013776c11Slogin 25113776c11Slogin #[inline] 25213776c11Slogin fn nic_id(&self) -> usize { 25313776c11Slogin return self.iface_id; 25413776c11Slogin } 25513776c11Slogin 25613776c11Slogin #[inline] 25713776c11Slogin fn name(&self) -> String { 25813776c11Slogin return self.name.clone(); 25913776c11Slogin } 26013776c11Slogin 26113776c11Slogin fn update_ip_addrs(&self, ip_addrs: &[wire::IpCidr]) -> Result<(), SystemError> { 26213776c11Slogin if ip_addrs.len() != 1 { 26313776c11Slogin return Err(SystemError::EINVAL); 26413776c11Slogin } 26513776c11Slogin 26613776c11Slogin self.iface.lock().update_ip_addrs(|addrs| { 26713776c11Slogin let dest = addrs.iter_mut().next(); 26813776c11Slogin if let None = dest { 26913776c11Slogin addrs.push(ip_addrs[0]).expect("Push ipCidr failed: full"); 27013776c11Slogin } else { 27113776c11Slogin let dest = dest.unwrap(); 27213776c11Slogin *dest = ip_addrs[0]; 27313776c11Slogin } 27413776c11Slogin }); 27513776c11Slogin return Ok(()); 27613776c11Slogin } 27713776c11Slogin 27813776c11Slogin fn poll( 27913776c11Slogin &self, 28013776c11Slogin sockets: &mut smoltcp::iface::SocketSet, 28113776c11Slogin ) -> Result<(), crate::syscall::SystemError> { 28213776c11Slogin let timestamp: smoltcp::time::Instant = Instant::now().into(); 28313776c11Slogin let mut guard = self.iface.lock(); 28413776c11Slogin let poll_res = guard.poll(timestamp, self.driver.force_get_mut(), sockets); 28513776c11Slogin // todo: notify!!! 28613776c11Slogin // kdebug!("Virtio Interface poll:{poll_res}"); 28713776c11Slogin if poll_res { 28813776c11Slogin return Ok(()); 28913776c11Slogin } 290*79a452ceShoumkh return Err(SystemError::EAGAIN_OR_EWOULDBLOCK); 29113776c11Slogin } 29213776c11Slogin 29313776c11Slogin #[inline(always)] 29413776c11Slogin fn inner_iface(&self) -> &SpinLock<smoltcp::iface::Interface> { 29513776c11Slogin return &self.iface; 29613776c11Slogin } 29713776c11Slogin // fn as_any_ref(&'static self) -> &'static dyn core::any::Any { 29813776c11Slogin // return self; 29913776c11Slogin // } 30013776c11Slogin } 30113776c11Slogin 30213776c11Slogin // 向编译器保证,VirtioNICDriver在线程之间是安全的. 30313776c11Slogin // 由于smoltcp只会在token内真正操作网卡设备,并且在VirtioNetToken的consume 30413776c11Slogin // 方法内,会对VirtioNet进行加【写锁】,因此,能够保证对设备操作的的互斥访问, 30513776c11Slogin // 因此VirtioNICDriver在线程之间是安全的。 30613776c11Slogin // unsafe impl<T: Transport> Sync for VirtioNICDriver<T> {} 30713776c11Slogin // unsafe impl<T: Transport> Send for VirtioNICDriver<T> {} 308