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 11*91e9d4abSLoGin use super::NetDriver; 1213776c11Slogin use crate::{ 13b087521eSChiichen driver::{ 1406d5e247SLoGin base::{ 15a03c4f9dSLoGin device::{bus::Bus, driver::Driver, Device, IdTable}, 16a03c4f9dSLoGin kobject::{KObjType, KObject, KObjectState}, 1706d5e247SLoGin }, 18b087521eSChiichen virtio::virtio_impl::HalImpl, 19d470019bSLoGin }, 20d470019bSLoGin kerror, kinfo, 2113776c11Slogin libs::spinlock::SpinLock, 2213776c11Slogin net::{generate_iface_id, NET_DRIVERS}, 2313776c11Slogin time::Instant, 2413776c11Slogin }; 25*91e9d4abSLoGin use system_error::SystemError; 2613776c11Slogin 2713776c11Slogin /// @brief Virtio网络设备驱动(加锁) 2813776c11Slogin pub struct VirtioNICDriver<T: Transport> { 2913776c11Slogin pub inner: Arc<SpinLock<VirtIONet<HalImpl, T, 2>>>, 3013776c11Slogin } 3113776c11Slogin 3213776c11Slogin impl<T: Transport> Clone for VirtioNICDriver<T> { 3313776c11Slogin fn clone(&self) -> Self { 3413776c11Slogin return VirtioNICDriver { 3513776c11Slogin inner: self.inner.clone(), 3613776c11Slogin }; 3713776c11Slogin } 3813776c11Slogin } 3913776c11Slogin 4013776c11Slogin /// @brief 网卡驱动的包裹器,这是为了获取网卡驱动的可变引用而设计的。 4113776c11Slogin /// 由于smoltcp的设计,导致需要在poll的时候获取网卡驱动的可变引用, 4213776c11Slogin /// 同时需要在token的consume里面获取可变引用。为了避免双重加锁,所以需要这个包裹器。 4313776c11Slogin struct VirtioNICDriverWrapper<T: Transport>(UnsafeCell<VirtioNICDriver<T>>); 4413776c11Slogin unsafe impl<T: Transport> Send for VirtioNICDriverWrapper<T> {} 4513776c11Slogin unsafe impl<T: Transport> Sync for VirtioNICDriverWrapper<T> {} 4613776c11Slogin 4713776c11Slogin impl<T: Transport> Deref for VirtioNICDriverWrapper<T> { 4813776c11Slogin type Target = VirtioNICDriver<T>; 4913776c11Slogin fn deref(&self) -> &Self::Target { 5013776c11Slogin unsafe { &*self.0.get() } 5113776c11Slogin } 5213776c11Slogin } 5313776c11Slogin impl<T: Transport> DerefMut for VirtioNICDriverWrapper<T> { 5413776c11Slogin fn deref_mut(&mut self) -> &mut Self::Target { 5513776c11Slogin unsafe { &mut *self.0.get() } 5613776c11Slogin } 5713776c11Slogin } 5813776c11Slogin 5913776c11Slogin impl<T: Transport> VirtioNICDriverWrapper<T> { 6013776c11Slogin fn force_get_mut(&self) -> &mut VirtioNICDriver<T> { 6113776c11Slogin unsafe { &mut *self.0.get() } 6213776c11Slogin } 6313776c11Slogin } 6413776c11Slogin 6513776c11Slogin impl<T: Transport> Debug for VirtioNICDriver<T> { 6613776c11Slogin fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 6713776c11Slogin f.debug_struct("VirtioNICDriver").finish() 6813776c11Slogin } 6913776c11Slogin } 7013776c11Slogin 7113776c11Slogin pub struct VirtioInterface<T: Transport> { 7213776c11Slogin driver: VirtioNICDriverWrapper<T>, 7313776c11Slogin iface_id: usize, 7413776c11Slogin iface: SpinLock<smoltcp::iface::Interface>, 7513776c11Slogin name: String, 7613776c11Slogin } 7713776c11Slogin 7813776c11Slogin impl<T: Transport> Debug for VirtioInterface<T> { 7913776c11Slogin fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 8013776c11Slogin f.debug_struct("VirtioInterface") 8113776c11Slogin .field("driver", self.driver.deref()) 8213776c11Slogin .field("iface_id", &self.iface_id) 8313776c11Slogin .field("iface", &"smoltcp::iface::Interface") 8413776c11Slogin .field("name", &self.name) 8513776c11Slogin .finish() 8613776c11Slogin } 8713776c11Slogin } 8813776c11Slogin 8913776c11Slogin impl<T: Transport> VirtioInterface<T> { 9013776c11Slogin pub fn new(mut driver: VirtioNICDriver<T>) -> Arc<Self> { 9113776c11Slogin let iface_id = generate_iface_id(); 9213776c11Slogin let mut iface_config = smoltcp::iface::Config::new(); 9313776c11Slogin 9413776c11Slogin // todo: 随机设定这个值。 9513776c11Slogin // 参见 https://docs.rs/smoltcp/latest/smoltcp/iface/struct.Config.html#structfield.random_seed 9613776c11Slogin iface_config.random_seed = 12345; 9713776c11Slogin 9813776c11Slogin iface_config.hardware_addr = Some(wire::HardwareAddress::Ethernet( 9913776c11Slogin smoltcp::wire::EthernetAddress(driver.inner.lock().mac_address()), 10013776c11Slogin )); 10113776c11Slogin let iface = smoltcp::iface::Interface::new(iface_config, &mut driver); 10213776c11Slogin 10313776c11Slogin let driver: VirtioNICDriverWrapper<T> = VirtioNICDriverWrapper(UnsafeCell::new(driver)); 10413776c11Slogin let result = Arc::new(VirtioInterface { 10513776c11Slogin driver, 10613776c11Slogin iface_id, 10713776c11Slogin iface: SpinLock::new(iface), 10813776c11Slogin name: format!("eth{}", iface_id), 10913776c11Slogin }); 11013776c11Slogin 11113776c11Slogin return result; 11213776c11Slogin } 11313776c11Slogin } 11413776c11Slogin 11513776c11Slogin impl<T: 'static + Transport> VirtioNICDriver<T> { 11613776c11Slogin pub fn new(driver_net: VirtIONet<HalImpl, T, 2>) -> Self { 11713776c11Slogin let mut iface_config = smoltcp::iface::Config::new(); 11813776c11Slogin 11913776c11Slogin // todo: 随机设定这个值。 12013776c11Slogin // 参见 https://docs.rs/smoltcp/latest/smoltcp/iface/struct.Config.html#structfield.random_seed 12113776c11Slogin iface_config.random_seed = 12345; 12213776c11Slogin 12313776c11Slogin iface_config.hardware_addr = Some(wire::HardwareAddress::Ethernet( 12413776c11Slogin smoltcp::wire::EthernetAddress(driver_net.mac_address()), 12513776c11Slogin )); 12613776c11Slogin 12713776c11Slogin let inner: Arc<SpinLock<VirtIONet<HalImpl, T, 2>>> = Arc::new(SpinLock::new(driver_net)); 12813776c11Slogin let result = VirtioNICDriver { inner }; 12913776c11Slogin return result; 13013776c11Slogin } 13113776c11Slogin } 13213776c11Slogin 13313776c11Slogin pub struct VirtioNetToken<T: Transport> { 13413776c11Slogin driver: VirtioNICDriver<T>, 13513776c11Slogin rx_buffer: Option<virtio_drivers::device::net::RxBuffer>, 13613776c11Slogin } 13713776c11Slogin 13813776c11Slogin impl<'a, T: Transport> VirtioNetToken<T> { 13913776c11Slogin pub fn new( 14013776c11Slogin driver: VirtioNICDriver<T>, 14113776c11Slogin rx_buffer: Option<virtio_drivers::device::net::RxBuffer>, 14213776c11Slogin ) -> Self { 14313776c11Slogin return Self { driver, rx_buffer }; 14413776c11Slogin } 14513776c11Slogin } 14613776c11Slogin 14713776c11Slogin impl<T: Transport> phy::Device for VirtioNICDriver<T> { 14813776c11Slogin type RxToken<'a> = VirtioNetToken<T> where Self: 'a; 14913776c11Slogin type TxToken<'a> = VirtioNetToken<T> where Self: 'a; 15013776c11Slogin 15113776c11Slogin fn receive( 15213776c11Slogin &mut self, 15313776c11Slogin _timestamp: smoltcp::time::Instant, 15413776c11Slogin ) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> { 15513776c11Slogin match self.inner.lock().receive() { 15613776c11Slogin Ok(buf) => Some(( 15713776c11Slogin VirtioNetToken::new(self.clone(), Some(buf)), 15813776c11Slogin VirtioNetToken::new(self.clone(), None), 15913776c11Slogin )), 16013776c11Slogin Err(virtio_drivers::Error::NotReady) => None, 16113776c11Slogin Err(err) => panic!("VirtIO receive failed: {}", err), 16213776c11Slogin } 16313776c11Slogin } 16413776c11Slogin 16513776c11Slogin fn transmit(&mut self, _timestamp: smoltcp::time::Instant) -> Option<Self::TxToken<'_>> { 16613776c11Slogin // kdebug!("VirtioNet: transmit"); 16740609970SGnoCiYeH if self.inner.lock_irqsave().can_send() { 16813776c11Slogin // kdebug!("VirtioNet: can send"); 16913776c11Slogin return Some(VirtioNetToken::new(self.clone(), None)); 17013776c11Slogin } else { 17113776c11Slogin // kdebug!("VirtioNet: can not send"); 17213776c11Slogin return None; 17313776c11Slogin } 17413776c11Slogin } 17513776c11Slogin 17613776c11Slogin fn capabilities(&self) -> phy::DeviceCapabilities { 17713776c11Slogin let mut caps = phy::DeviceCapabilities::default(); 17813776c11Slogin // 网卡的最大传输单元. 请与IP层的MTU进行区分。这个值应当是网卡的最大传输单元,而不是IP层的MTU。 17913776c11Slogin caps.max_transmission_unit = 2000; 18013776c11Slogin /* 18113776c11Slogin Maximum burst size, in terms of MTU. 18213776c11Slogin The network device is unable to send or receive bursts large than the value returned by this function. 18313776c11Slogin If None, there is no fixed limit on burst size, e.g. if network buffers are dynamically allocated. 18413776c11Slogin */ 18513776c11Slogin caps.max_burst_size = Some(1); 18613776c11Slogin return caps; 18713776c11Slogin } 18813776c11Slogin } 18913776c11Slogin 19013776c11Slogin impl<T: Transport> phy::TxToken for VirtioNetToken<T> { 19113776c11Slogin fn consume<R, F>(self, len: usize, f: F) -> R 19213776c11Slogin where 19313776c11Slogin F: FnOnce(&mut [u8]) -> R, 19413776c11Slogin { 19513776c11Slogin // // 为了线程安全,这里需要对VirtioNet进行加【写锁】,以保证对设备的互斥访问。 19613776c11Slogin 19713776c11Slogin let mut driver_net = self.driver.inner.lock(); 19813776c11Slogin let mut tx_buf = driver_net.new_tx_buffer(len); 19913776c11Slogin let result = f(tx_buf.packet_mut()); 20013776c11Slogin driver_net.send(tx_buf).expect("virtio_net send failed"); 20113776c11Slogin return result; 20213776c11Slogin } 20313776c11Slogin } 20413776c11Slogin 20513776c11Slogin impl<T: Transport> phy::RxToken for VirtioNetToken<T> { 20613776c11Slogin fn consume<R, F>(self, f: F) -> R 20713776c11Slogin where 20813776c11Slogin F: FnOnce(&mut [u8]) -> R, 20913776c11Slogin { 21013776c11Slogin // 为了线程安全,这里需要对VirtioNet进行加【写锁】,以保证对设备的互斥访问。 21113776c11Slogin let mut rx_buf = self.rx_buffer.unwrap(); 21213776c11Slogin let result = f(rx_buf.packet_mut()); 21313776c11Slogin self.driver 21413776c11Slogin .inner 21513776c11Slogin .lock() 21613776c11Slogin .recycle_rx_buffer(rx_buf) 21713776c11Slogin .expect("virtio_net recv failed"); 21813776c11Slogin result 21913776c11Slogin } 22013776c11Slogin } 22113776c11Slogin 22213776c11Slogin /// @brief virtio-net 驱动的初始化与测试 22313776c11Slogin pub fn virtio_net<T: Transport + 'static>(transport: T) { 22413776c11Slogin let driver_net: VirtIONet<HalImpl, T, 2> = 22513776c11Slogin match VirtIONet::<HalImpl, T, 2>::new(transport, 4096) { 22613776c11Slogin Ok(net) => net, 22713776c11Slogin Err(_) => { 22813776c11Slogin kerror!("VirtIONet init failed"); 22913776c11Slogin return; 23013776c11Slogin } 23113776c11Slogin }; 23213776c11Slogin let mac = smoltcp::wire::EthernetAddress::from_bytes(&driver_net.mac_address()); 23313776c11Slogin let driver: VirtioNICDriver<T> = VirtioNICDriver::new(driver_net); 23413776c11Slogin let iface = VirtioInterface::new(driver); 23506d5e247SLoGin let name = iface.name.clone(); 23613776c11Slogin // 将网卡的接口信息注册到全局的网卡接口信息表中 23713776c11Slogin NET_DRIVERS.write().insert(iface.nic_id(), iface.clone()); 23813776c11Slogin kinfo!( 23913776c11Slogin "Virtio-net driver init successfully!\tNetDevID: [{}], MAC: [{}]", 24006d5e247SLoGin name, 24113776c11Slogin mac 24213776c11Slogin ); 24313776c11Slogin } 24413776c11Slogin 24506d5e247SLoGin impl<T: Transport + 'static> Driver for VirtioInterface<T> { 246a03c4f9dSLoGin fn id_table(&self) -> Option<IdTable> { 247b087521eSChiichen todo!() 248b087521eSChiichen } 249b087521eSChiichen 250a03c4f9dSLoGin fn add_device(&self, _device: Arc<dyn Device>) { 251b087521eSChiichen todo!() 252b087521eSChiichen } 253b087521eSChiichen 254a03c4f9dSLoGin fn delete_device(&self, _device: &Arc<dyn Device>) { 255a03c4f9dSLoGin todo!() 256a03c4f9dSLoGin } 257a03c4f9dSLoGin 258a03c4f9dSLoGin fn devices(&self) -> alloc::vec::Vec<Arc<dyn Device>> { 259a03c4f9dSLoGin todo!() 260a03c4f9dSLoGin } 261a03c4f9dSLoGin 262a03c4f9dSLoGin fn bus(&self) -> Option<Arc<dyn Bus>> { 263a03c4f9dSLoGin todo!() 264a03c4f9dSLoGin } 265a03c4f9dSLoGin 266a03c4f9dSLoGin fn set_bus(&self, _bus: Option<Arc<dyn Bus>>) { 267b087521eSChiichen todo!() 268b087521eSChiichen } 269b087521eSChiichen } 270b087521eSChiichen 27106d5e247SLoGin impl<T: Transport + 'static> NetDriver for VirtioInterface<T> { 27213776c11Slogin fn mac(&self) -> smoltcp::wire::EthernetAddress { 27313776c11Slogin let mac: [u8; 6] = self.driver.inner.lock().mac_address(); 27413776c11Slogin return smoltcp::wire::EthernetAddress::from_bytes(&mac); 27513776c11Slogin } 27613776c11Slogin 27713776c11Slogin #[inline] 27813776c11Slogin fn nic_id(&self) -> usize { 27913776c11Slogin return self.iface_id; 28013776c11Slogin } 28113776c11Slogin 28213776c11Slogin #[inline] 28313776c11Slogin fn name(&self) -> String { 28413776c11Slogin return self.name.clone(); 28513776c11Slogin } 28613776c11Slogin 28713776c11Slogin fn update_ip_addrs(&self, ip_addrs: &[wire::IpCidr]) -> Result<(), SystemError> { 28813776c11Slogin if ip_addrs.len() != 1 { 28913776c11Slogin return Err(SystemError::EINVAL); 29013776c11Slogin } 29113776c11Slogin 29213776c11Slogin self.iface.lock().update_ip_addrs(|addrs| { 29313776c11Slogin let dest = addrs.iter_mut().next(); 29413776c11Slogin if let None = dest { 29513776c11Slogin addrs.push(ip_addrs[0]).expect("Push ipCidr failed: full"); 29613776c11Slogin } else { 29713776c11Slogin let dest = dest.unwrap(); 29813776c11Slogin *dest = ip_addrs[0]; 29913776c11Slogin } 30013776c11Slogin }); 30113776c11Slogin return Ok(()); 30213776c11Slogin } 30313776c11Slogin 304*91e9d4abSLoGin fn poll(&self, sockets: &mut smoltcp::iface::SocketSet) -> Result<(), SystemError> { 30513776c11Slogin let timestamp: smoltcp::time::Instant = Instant::now().into(); 30613776c11Slogin let mut guard = self.iface.lock(); 30713776c11Slogin let poll_res = guard.poll(timestamp, self.driver.force_get_mut(), sockets); 30813776c11Slogin // todo: notify!!! 309971462beSGnoCiYeH // kdebug!("Virtio Interface poll:{poll_res}"); 31013776c11Slogin if poll_res { 31113776c11Slogin return Ok(()); 31213776c11Slogin } 31379a452ceShoumkh return Err(SystemError::EAGAIN_OR_EWOULDBLOCK); 31413776c11Slogin } 31513776c11Slogin 31613776c11Slogin #[inline(always)] 31713776c11Slogin fn inner_iface(&self) -> &SpinLock<smoltcp::iface::Interface> { 31813776c11Slogin return &self.iface; 31913776c11Slogin } 32013776c11Slogin // fn as_any_ref(&'static self) -> &'static dyn core::any::Any { 32113776c11Slogin // return self; 32213776c11Slogin // } 32313776c11Slogin } 32413776c11Slogin 32506d5e247SLoGin impl<T: Transport + 'static> KObject for VirtioInterface<T> { 32606d5e247SLoGin fn as_any_ref(&self) -> &dyn core::any::Any { 32706d5e247SLoGin self 32806d5e247SLoGin } 32906d5e247SLoGin 33006d5e247SLoGin fn set_inode(&self, _inode: Option<Arc<crate::filesystem::kernfs::KernFSInode>>) { 33106d5e247SLoGin todo!() 33206d5e247SLoGin } 33306d5e247SLoGin 33406d5e247SLoGin fn inode(&self) -> Option<Arc<crate::filesystem::kernfs::KernFSInode>> { 33506d5e247SLoGin todo!() 33606d5e247SLoGin } 33706d5e247SLoGin 33806d5e247SLoGin fn parent(&self) -> Option<alloc::sync::Weak<dyn KObject>> { 33906d5e247SLoGin todo!() 34006d5e247SLoGin } 34106d5e247SLoGin 34206d5e247SLoGin fn set_parent(&self, _parent: Option<alloc::sync::Weak<dyn KObject>>) { 34306d5e247SLoGin todo!() 34406d5e247SLoGin } 34506d5e247SLoGin 34606d5e247SLoGin fn kset(&self) -> Option<Arc<crate::driver::base::kset::KSet>> { 34706d5e247SLoGin todo!() 34806d5e247SLoGin } 34906d5e247SLoGin 35006d5e247SLoGin fn set_kset(&self, _kset: Option<Arc<crate::driver::base::kset::KSet>>) { 35106d5e247SLoGin todo!() 35206d5e247SLoGin } 35306d5e247SLoGin 35406d5e247SLoGin fn kobj_type(&self) -> Option<&'static dyn crate::driver::base::kobject::KObjType> { 35506d5e247SLoGin todo!() 35606d5e247SLoGin } 35706d5e247SLoGin 35806d5e247SLoGin fn name(&self) -> String { 35906d5e247SLoGin self.name.clone() 36006d5e247SLoGin } 36106d5e247SLoGin 36206d5e247SLoGin fn set_name(&self, _name: String) { 36306d5e247SLoGin todo!() 36406d5e247SLoGin } 36506d5e247SLoGin 36606d5e247SLoGin fn kobj_state( 36706d5e247SLoGin &self, 36806d5e247SLoGin ) -> crate::libs::rwlock::RwLockReadGuard<crate::driver::base::kobject::KObjectState> { 36906d5e247SLoGin todo!() 37006d5e247SLoGin } 37106d5e247SLoGin 37206d5e247SLoGin fn kobj_state_mut( 37306d5e247SLoGin &self, 37406d5e247SLoGin ) -> crate::libs::rwlock::RwLockWriteGuard<crate::driver::base::kobject::KObjectState> { 37506d5e247SLoGin todo!() 37606d5e247SLoGin } 37706d5e247SLoGin 378a03c4f9dSLoGin fn set_kobj_state(&self, _state: KObjectState) { 379a03c4f9dSLoGin todo!() 380a03c4f9dSLoGin } 381a03c4f9dSLoGin 382a03c4f9dSLoGin fn set_kobj_type(&self, _ktype: Option<&'static dyn KObjType>) { 38306d5e247SLoGin todo!() 38406d5e247SLoGin } 38506d5e247SLoGin } 38606d5e247SLoGin 38713776c11Slogin // 向编译器保证,VirtioNICDriver在线程之间是安全的. 38813776c11Slogin // 由于smoltcp只会在token内真正操作网卡设备,并且在VirtioNetToken的consume 38913776c11Slogin // 方法内,会对VirtioNet进行加【写锁】,因此,能够保证对设备操作的的互斥访问, 39013776c11Slogin // 因此VirtioNICDriver在线程之间是安全的。 39113776c11Slogin // unsafe impl<T: Transport> Sync for VirtioNICDriver<T> {} 39213776c11Slogin // unsafe impl<T: Transport> Send for VirtioNICDriver<T> {} 393