113776c11Slogin use core::{ 213776c11Slogin cell::UnsafeCell, 313776c11Slogin fmt::Debug, 413776c11Slogin ops::{Deref, DerefMut}, 513776c11Slogin }; 613776c11Slogin 7c566df45SLoGin use alloc::{ 8c566df45SLoGin string::String, 9c566df45SLoGin sync::{Arc, Weak}, 10c566df45SLoGin }; 1113776c11Slogin use smoltcp::{phy, wire}; 1213776c11Slogin use virtio_drivers::{device::net::VirtIONet, transport::Transport}; 1313776c11Slogin 1491e9d4abSLoGin use super::NetDriver; 1513776c11Slogin use crate::{ 16b087521eSChiichen driver::{ 1706d5e247SLoGin base::{ 18*e2841179SLoGin device::{bus::Bus, driver::Driver, Device, DeviceId, IdTable}, 19a03c4f9dSLoGin kobject::{KObjType, KObject, KObjectState}, 2006d5e247SLoGin }, 21*e2841179SLoGin virtio::{irq::virtio_irq_manager, virtio_impl::HalImpl, VirtIODevice}, 22d470019bSLoGin }, 23*e2841179SLoGin exception::{irqdesc::IrqReturn, IrqNumber}, 24d470019bSLoGin kerror, kinfo, 2513776c11Slogin libs::spinlock::SpinLock, 26*e2841179SLoGin net::{generate_iface_id, net_core::poll_ifaces_try_lock_onetime, NET_DRIVERS}, 2713776c11Slogin time::Instant, 2813776c11Slogin }; 2991e9d4abSLoGin use system_error::SystemError; 3013776c11Slogin 3113776c11Slogin /// @brief Virtio网络设备驱动(加锁) 3213776c11Slogin pub struct VirtioNICDriver<T: Transport> { 3313776c11Slogin pub inner: Arc<SpinLock<VirtIONet<HalImpl, T, 2>>>, 3413776c11Slogin } 3513776c11Slogin 3613776c11Slogin impl<T: Transport> Clone for VirtioNICDriver<T> { 3713776c11Slogin fn clone(&self) -> Self { 3813776c11Slogin return VirtioNICDriver { 3913776c11Slogin inner: self.inner.clone(), 4013776c11Slogin }; 4113776c11Slogin } 4213776c11Slogin } 4313776c11Slogin 44*e2841179SLoGin /// 网卡驱动的包裹器,这是为了获取网卡驱动的可变引用而设计的。 45*e2841179SLoGin /// 4613776c11Slogin /// 由于smoltcp的设计,导致需要在poll的时候获取网卡驱动的可变引用, 4713776c11Slogin /// 同时需要在token的consume里面获取可变引用。为了避免双重加锁,所以需要这个包裹器。 4813776c11Slogin struct VirtioNICDriverWrapper<T: Transport>(UnsafeCell<VirtioNICDriver<T>>); 4913776c11Slogin unsafe impl<T: Transport> Send for VirtioNICDriverWrapper<T> {} 5013776c11Slogin unsafe impl<T: Transport> Sync for VirtioNICDriverWrapper<T> {} 5113776c11Slogin 5213776c11Slogin impl<T: Transport> Deref for VirtioNICDriverWrapper<T> { 5313776c11Slogin type Target = VirtioNICDriver<T>; 5413776c11Slogin fn deref(&self) -> &Self::Target { 5513776c11Slogin unsafe { &*self.0.get() } 5613776c11Slogin } 5713776c11Slogin } 5813776c11Slogin impl<T: Transport> DerefMut for VirtioNICDriverWrapper<T> { 5913776c11Slogin fn deref_mut(&mut self) -> &mut Self::Target { 6013776c11Slogin unsafe { &mut *self.0.get() } 6113776c11Slogin } 6213776c11Slogin } 6313776c11Slogin 6413776c11Slogin impl<T: Transport> VirtioNICDriverWrapper<T> { 6513776c11Slogin fn force_get_mut(&self) -> &mut VirtioNICDriver<T> { 6613776c11Slogin unsafe { &mut *self.0.get() } 6713776c11Slogin } 6813776c11Slogin } 6913776c11Slogin 7013776c11Slogin impl<T: Transport> Debug for VirtioNICDriver<T> { 7113776c11Slogin fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 7213776c11Slogin f.debug_struct("VirtioNICDriver").finish() 7313776c11Slogin } 7413776c11Slogin } 7513776c11Slogin 7613776c11Slogin pub struct VirtioInterface<T: Transport> { 7713776c11Slogin driver: VirtioNICDriverWrapper<T>, 7813776c11Slogin iface_id: usize, 7913776c11Slogin iface: SpinLock<smoltcp::iface::Interface>, 8013776c11Slogin name: String, 81*e2841179SLoGin dev_id: Arc<DeviceId>, 8213776c11Slogin } 8313776c11Slogin 8413776c11Slogin impl<T: Transport> Debug for VirtioInterface<T> { 8513776c11Slogin fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 8613776c11Slogin f.debug_struct("VirtioInterface") 8713776c11Slogin .field("driver", self.driver.deref()) 8813776c11Slogin .field("iface_id", &self.iface_id) 8913776c11Slogin .field("iface", &"smoltcp::iface::Interface") 9013776c11Slogin .field("name", &self.name) 9113776c11Slogin .finish() 9213776c11Slogin } 9313776c11Slogin } 9413776c11Slogin 9513776c11Slogin impl<T: Transport> VirtioInterface<T> { 96*e2841179SLoGin pub fn new(mut driver: VirtioNICDriver<T>, dev_id: Arc<DeviceId>) -> Arc<Self> { 9713776c11Slogin let iface_id = generate_iface_id(); 9813776c11Slogin let mut iface_config = smoltcp::iface::Config::new(); 9913776c11Slogin 10013776c11Slogin // todo: 随机设定这个值。 10113776c11Slogin // 参见 https://docs.rs/smoltcp/latest/smoltcp/iface/struct.Config.html#structfield.random_seed 10213776c11Slogin iface_config.random_seed = 12345; 10313776c11Slogin 10413776c11Slogin iface_config.hardware_addr = Some(wire::HardwareAddress::Ethernet( 10513776c11Slogin smoltcp::wire::EthernetAddress(driver.inner.lock().mac_address()), 10613776c11Slogin )); 10713776c11Slogin let iface = smoltcp::iface::Interface::new(iface_config, &mut driver); 10813776c11Slogin 10913776c11Slogin let driver: VirtioNICDriverWrapper<T> = VirtioNICDriverWrapper(UnsafeCell::new(driver)); 11013776c11Slogin let result = Arc::new(VirtioInterface { 11113776c11Slogin driver, 11213776c11Slogin iface_id, 11313776c11Slogin iface: SpinLock::new(iface), 11413776c11Slogin name: format!("eth{}", iface_id), 115*e2841179SLoGin dev_id, 11613776c11Slogin }); 11713776c11Slogin 11813776c11Slogin return result; 11913776c11Slogin } 12013776c11Slogin } 12113776c11Slogin 122*e2841179SLoGin impl<T: Transport + 'static> VirtIODevice for VirtioInterface<T> { 123*e2841179SLoGin fn handle_irq(&self, _irq: IrqNumber) -> Result<IrqReturn, SystemError> { 124*e2841179SLoGin poll_ifaces_try_lock_onetime().ok(); 125*e2841179SLoGin return Ok(IrqReturn::Handled); 126*e2841179SLoGin } 127*e2841179SLoGin 128*e2841179SLoGin fn dev_id(&self) -> &Arc<DeviceId> { 129*e2841179SLoGin return &self.dev_id; 130*e2841179SLoGin } 131*e2841179SLoGin } 132*e2841179SLoGin 133*e2841179SLoGin impl<T: Transport> Drop for VirtioInterface<T> { 134*e2841179SLoGin fn drop(&mut self) { 135*e2841179SLoGin // 从全局的网卡接口信息表中删除这个网卡的接口信息 136*e2841179SLoGin NET_DRIVERS.write_irqsave().remove(&self.iface_id); 137*e2841179SLoGin } 138*e2841179SLoGin } 139*e2841179SLoGin 14013776c11Slogin impl<T: 'static + Transport> VirtioNICDriver<T> { 14113776c11Slogin pub fn new(driver_net: VirtIONet<HalImpl, T, 2>) -> Self { 14213776c11Slogin let mut iface_config = smoltcp::iface::Config::new(); 14313776c11Slogin 14413776c11Slogin // todo: 随机设定这个值。 14513776c11Slogin // 参见 https://docs.rs/smoltcp/latest/smoltcp/iface/struct.Config.html#structfield.random_seed 14613776c11Slogin iface_config.random_seed = 12345; 14713776c11Slogin 14813776c11Slogin iface_config.hardware_addr = Some(wire::HardwareAddress::Ethernet( 14913776c11Slogin smoltcp::wire::EthernetAddress(driver_net.mac_address()), 15013776c11Slogin )); 15113776c11Slogin 15213776c11Slogin let inner: Arc<SpinLock<VirtIONet<HalImpl, T, 2>>> = Arc::new(SpinLock::new(driver_net)); 15313776c11Slogin let result = VirtioNICDriver { inner }; 15413776c11Slogin return result; 15513776c11Slogin } 15613776c11Slogin } 15713776c11Slogin 15813776c11Slogin pub struct VirtioNetToken<T: Transport> { 15913776c11Slogin driver: VirtioNICDriver<T>, 16013776c11Slogin rx_buffer: Option<virtio_drivers::device::net::RxBuffer>, 16113776c11Slogin } 16213776c11Slogin 16313776c11Slogin impl<'a, T: Transport> VirtioNetToken<T> { 16413776c11Slogin pub fn new( 16513776c11Slogin driver: VirtioNICDriver<T>, 16613776c11Slogin rx_buffer: Option<virtio_drivers::device::net::RxBuffer>, 16713776c11Slogin ) -> Self { 16813776c11Slogin return Self { driver, rx_buffer }; 16913776c11Slogin } 17013776c11Slogin } 17113776c11Slogin 17213776c11Slogin impl<T: Transport> phy::Device for VirtioNICDriver<T> { 17313776c11Slogin type RxToken<'a> = VirtioNetToken<T> where Self: 'a; 17413776c11Slogin type TxToken<'a> = VirtioNetToken<T> where Self: 'a; 17513776c11Slogin 17613776c11Slogin fn receive( 17713776c11Slogin &mut self, 17813776c11Slogin _timestamp: smoltcp::time::Instant, 17913776c11Slogin ) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> { 18013776c11Slogin match self.inner.lock().receive() { 18113776c11Slogin Ok(buf) => Some(( 18213776c11Slogin VirtioNetToken::new(self.clone(), Some(buf)), 18313776c11Slogin VirtioNetToken::new(self.clone(), None), 18413776c11Slogin )), 18513776c11Slogin Err(virtio_drivers::Error::NotReady) => None, 18613776c11Slogin Err(err) => panic!("VirtIO receive failed: {}", err), 18713776c11Slogin } 18813776c11Slogin } 18913776c11Slogin 19013776c11Slogin fn transmit(&mut self, _timestamp: smoltcp::time::Instant) -> Option<Self::TxToken<'_>> { 19113776c11Slogin // kdebug!("VirtioNet: transmit"); 19240609970SGnoCiYeH if self.inner.lock_irqsave().can_send() { 19313776c11Slogin // kdebug!("VirtioNet: can send"); 19413776c11Slogin return Some(VirtioNetToken::new(self.clone(), None)); 19513776c11Slogin } else { 19613776c11Slogin // kdebug!("VirtioNet: can not send"); 19713776c11Slogin return None; 19813776c11Slogin } 19913776c11Slogin } 20013776c11Slogin 20113776c11Slogin fn capabilities(&self) -> phy::DeviceCapabilities { 20213776c11Slogin let mut caps = phy::DeviceCapabilities::default(); 20313776c11Slogin // 网卡的最大传输单元. 请与IP层的MTU进行区分。这个值应当是网卡的最大传输单元,而不是IP层的MTU。 20413776c11Slogin caps.max_transmission_unit = 2000; 20513776c11Slogin /* 20613776c11Slogin Maximum burst size, in terms of MTU. 20713776c11Slogin The network device is unable to send or receive bursts large than the value returned by this function. 20813776c11Slogin If None, there is no fixed limit on burst size, e.g. if network buffers are dynamically allocated. 20913776c11Slogin */ 21013776c11Slogin caps.max_burst_size = Some(1); 21113776c11Slogin return caps; 21213776c11Slogin } 21313776c11Slogin } 21413776c11Slogin 21513776c11Slogin impl<T: Transport> phy::TxToken for VirtioNetToken<T> { 21613776c11Slogin fn consume<R, F>(self, len: usize, f: F) -> R 21713776c11Slogin where 21813776c11Slogin F: FnOnce(&mut [u8]) -> R, 21913776c11Slogin { 22013776c11Slogin // // 为了线程安全,这里需要对VirtioNet进行加【写锁】,以保证对设备的互斥访问。 22113776c11Slogin 22213776c11Slogin let mut driver_net = self.driver.inner.lock(); 22313776c11Slogin let mut tx_buf = driver_net.new_tx_buffer(len); 22413776c11Slogin let result = f(tx_buf.packet_mut()); 22513776c11Slogin driver_net.send(tx_buf).expect("virtio_net send failed"); 22613776c11Slogin return result; 22713776c11Slogin } 22813776c11Slogin } 22913776c11Slogin 23013776c11Slogin impl<T: Transport> phy::RxToken for VirtioNetToken<T> { 23113776c11Slogin fn consume<R, F>(self, f: F) -> R 23213776c11Slogin where 23313776c11Slogin F: FnOnce(&mut [u8]) -> R, 23413776c11Slogin { 23513776c11Slogin // 为了线程安全,这里需要对VirtioNet进行加【写锁】,以保证对设备的互斥访问。 23613776c11Slogin let mut rx_buf = self.rx_buffer.unwrap(); 23713776c11Slogin let result = f(rx_buf.packet_mut()); 23813776c11Slogin self.driver 23913776c11Slogin .inner 24013776c11Slogin .lock() 24113776c11Slogin .recycle_rx_buffer(rx_buf) 24213776c11Slogin .expect("virtio_net recv failed"); 24313776c11Slogin result 24413776c11Slogin } 24513776c11Slogin } 24613776c11Slogin 24713776c11Slogin /// @brief virtio-net 驱动的初始化与测试 248*e2841179SLoGin pub fn virtio_net<T: Transport + 'static>(transport: T, dev_id: Arc<DeviceId>) { 24913776c11Slogin let driver_net: VirtIONet<HalImpl, T, 2> = 25013776c11Slogin match VirtIONet::<HalImpl, T, 2>::new(transport, 4096) { 25113776c11Slogin Ok(net) => net, 25213776c11Slogin Err(_) => { 25313776c11Slogin kerror!("VirtIONet init failed"); 25413776c11Slogin return; 25513776c11Slogin } 25613776c11Slogin }; 25713776c11Slogin let mac = smoltcp::wire::EthernetAddress::from_bytes(&driver_net.mac_address()); 25813776c11Slogin let driver: VirtioNICDriver<T> = VirtioNICDriver::new(driver_net); 259*e2841179SLoGin let iface = VirtioInterface::new(driver, dev_id); 26006d5e247SLoGin let name = iface.name.clone(); 26113776c11Slogin // 将网卡的接口信息注册到全局的网卡接口信息表中 2620d6cf65aSLoGin NET_DRIVERS 2630d6cf65aSLoGin .write_irqsave() 2640d6cf65aSLoGin .insert(iface.nic_id(), iface.clone()); 265*e2841179SLoGin 266*e2841179SLoGin virtio_irq_manager() 267*e2841179SLoGin .register_device(iface.clone()) 268*e2841179SLoGin .expect("Register virtio net failed"); 26913776c11Slogin kinfo!( 27013776c11Slogin "Virtio-net driver init successfully!\tNetDevID: [{}], MAC: [{}]", 27106d5e247SLoGin name, 27213776c11Slogin mac 27313776c11Slogin ); 27413776c11Slogin } 27513776c11Slogin 27606d5e247SLoGin impl<T: Transport + 'static> Driver for VirtioInterface<T> { 277a03c4f9dSLoGin fn id_table(&self) -> Option<IdTable> { 278b087521eSChiichen todo!() 279b087521eSChiichen } 280b087521eSChiichen 281a03c4f9dSLoGin fn add_device(&self, _device: Arc<dyn Device>) { 282b087521eSChiichen todo!() 283b087521eSChiichen } 284b087521eSChiichen 285a03c4f9dSLoGin fn delete_device(&self, _device: &Arc<dyn Device>) { 286a03c4f9dSLoGin todo!() 287a03c4f9dSLoGin } 288a03c4f9dSLoGin 289a03c4f9dSLoGin fn devices(&self) -> alloc::vec::Vec<Arc<dyn Device>> { 290a03c4f9dSLoGin todo!() 291a03c4f9dSLoGin } 292a03c4f9dSLoGin 293c566df45SLoGin fn bus(&self) -> Option<Weak<dyn Bus>> { 294a03c4f9dSLoGin todo!() 295a03c4f9dSLoGin } 296a03c4f9dSLoGin 297c566df45SLoGin fn set_bus(&self, _bus: Option<Weak<dyn Bus>>) { 298b087521eSChiichen todo!() 299b087521eSChiichen } 300b087521eSChiichen } 301b087521eSChiichen 30206d5e247SLoGin impl<T: Transport + 'static> NetDriver for VirtioInterface<T> { 30313776c11Slogin fn mac(&self) -> smoltcp::wire::EthernetAddress { 30413776c11Slogin let mac: [u8; 6] = self.driver.inner.lock().mac_address(); 30513776c11Slogin return smoltcp::wire::EthernetAddress::from_bytes(&mac); 30613776c11Slogin } 30713776c11Slogin 30813776c11Slogin #[inline] 30913776c11Slogin fn nic_id(&self) -> usize { 31013776c11Slogin return self.iface_id; 31113776c11Slogin } 31213776c11Slogin 31313776c11Slogin #[inline] 31413776c11Slogin fn name(&self) -> String { 31513776c11Slogin return self.name.clone(); 31613776c11Slogin } 31713776c11Slogin 31813776c11Slogin fn update_ip_addrs(&self, ip_addrs: &[wire::IpCidr]) -> Result<(), SystemError> { 31913776c11Slogin if ip_addrs.len() != 1 { 32013776c11Slogin return Err(SystemError::EINVAL); 32113776c11Slogin } 32213776c11Slogin 32313776c11Slogin self.iface.lock().update_ip_addrs(|addrs| { 32413776c11Slogin let dest = addrs.iter_mut().next(); 32513776c11Slogin if let None = dest { 32613776c11Slogin addrs.push(ip_addrs[0]).expect("Push ipCidr failed: full"); 32713776c11Slogin } else { 32813776c11Slogin let dest = dest.unwrap(); 32913776c11Slogin *dest = ip_addrs[0]; 33013776c11Slogin } 33113776c11Slogin }); 33213776c11Slogin return Ok(()); 33313776c11Slogin } 33413776c11Slogin 33591e9d4abSLoGin fn poll(&self, sockets: &mut smoltcp::iface::SocketSet) -> Result<(), SystemError> { 33613776c11Slogin let timestamp: smoltcp::time::Instant = Instant::now().into(); 33713776c11Slogin let mut guard = self.iface.lock(); 33813776c11Slogin let poll_res = guard.poll(timestamp, self.driver.force_get_mut(), sockets); 33913776c11Slogin // todo: notify!!! 340971462beSGnoCiYeH // kdebug!("Virtio Interface poll:{poll_res}"); 34113776c11Slogin if poll_res { 34213776c11Slogin return Ok(()); 34313776c11Slogin } 34479a452ceShoumkh return Err(SystemError::EAGAIN_OR_EWOULDBLOCK); 34513776c11Slogin } 34613776c11Slogin 34713776c11Slogin #[inline(always)] 34813776c11Slogin fn inner_iface(&self) -> &SpinLock<smoltcp::iface::Interface> { 34913776c11Slogin return &self.iface; 35013776c11Slogin } 35113776c11Slogin // fn as_any_ref(&'static self) -> &'static dyn core::any::Any { 35213776c11Slogin // return self; 35313776c11Slogin // } 35413776c11Slogin } 35513776c11Slogin 35606d5e247SLoGin impl<T: Transport + 'static> KObject for VirtioInterface<T> { 35706d5e247SLoGin fn as_any_ref(&self) -> &dyn core::any::Any { 35806d5e247SLoGin self 35906d5e247SLoGin } 36006d5e247SLoGin 36106d5e247SLoGin fn set_inode(&self, _inode: Option<Arc<crate::filesystem::kernfs::KernFSInode>>) { 36206d5e247SLoGin todo!() 36306d5e247SLoGin } 36406d5e247SLoGin 36506d5e247SLoGin fn inode(&self) -> Option<Arc<crate::filesystem::kernfs::KernFSInode>> { 36606d5e247SLoGin todo!() 36706d5e247SLoGin } 36806d5e247SLoGin 36906d5e247SLoGin fn parent(&self) -> Option<alloc::sync::Weak<dyn KObject>> { 37006d5e247SLoGin todo!() 37106d5e247SLoGin } 37206d5e247SLoGin 37306d5e247SLoGin fn set_parent(&self, _parent: Option<alloc::sync::Weak<dyn KObject>>) { 37406d5e247SLoGin todo!() 37506d5e247SLoGin } 37606d5e247SLoGin 37706d5e247SLoGin fn kset(&self) -> Option<Arc<crate::driver::base::kset::KSet>> { 37806d5e247SLoGin todo!() 37906d5e247SLoGin } 38006d5e247SLoGin 38106d5e247SLoGin fn set_kset(&self, _kset: Option<Arc<crate::driver::base::kset::KSet>>) { 38206d5e247SLoGin todo!() 38306d5e247SLoGin } 38406d5e247SLoGin 38506d5e247SLoGin fn kobj_type(&self) -> Option<&'static dyn crate::driver::base::kobject::KObjType> { 38606d5e247SLoGin todo!() 38706d5e247SLoGin } 38806d5e247SLoGin 38906d5e247SLoGin fn name(&self) -> String { 39006d5e247SLoGin self.name.clone() 39106d5e247SLoGin } 39206d5e247SLoGin 39306d5e247SLoGin fn set_name(&self, _name: String) { 39406d5e247SLoGin todo!() 39506d5e247SLoGin } 39606d5e247SLoGin 39706d5e247SLoGin fn kobj_state( 39806d5e247SLoGin &self, 39906d5e247SLoGin ) -> crate::libs::rwlock::RwLockReadGuard<crate::driver::base::kobject::KObjectState> { 40006d5e247SLoGin todo!() 40106d5e247SLoGin } 40206d5e247SLoGin 40306d5e247SLoGin fn kobj_state_mut( 40406d5e247SLoGin &self, 40506d5e247SLoGin ) -> crate::libs::rwlock::RwLockWriteGuard<crate::driver::base::kobject::KObjectState> { 40606d5e247SLoGin todo!() 40706d5e247SLoGin } 40806d5e247SLoGin 409a03c4f9dSLoGin fn set_kobj_state(&self, _state: KObjectState) { 410a03c4f9dSLoGin todo!() 411a03c4f9dSLoGin } 412a03c4f9dSLoGin 413a03c4f9dSLoGin fn set_kobj_type(&self, _ktype: Option<&'static dyn KObjType>) { 41406d5e247SLoGin todo!() 41506d5e247SLoGin } 41606d5e247SLoGin } 41706d5e247SLoGin 41813776c11Slogin // 向编译器保证,VirtioNICDriver在线程之间是安全的. 41913776c11Slogin // 由于smoltcp只会在token内真正操作网卡设备,并且在VirtioNetToken的consume 42013776c11Slogin // 方法内,会对VirtioNet进行加【写锁】,因此,能够保证对设备操作的的互斥访问, 42113776c11Slogin // 因此VirtioNICDriver在线程之间是安全的。 42213776c11Slogin // unsafe impl<T: Transport> Sync for VirtioNICDriver<T> {} 42313776c11Slogin // unsafe impl<T: Transport> Send for VirtioNICDriver<T> {} 424